Skip to content

Commit 5d661ec

Browse files
committed
fix: update plugin name
use static pluginName not the class name to avoid preferences being saved with minified ClassName keys see issue #238 for more details
1 parent a34e581 commit 5d661ec

File tree

10 files changed

+98
-83
lines changed

10 files changed

+98
-83
lines changed

ember-headless-table/src/-private/-type-tests/plugins-accessors.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-nocheck
12
import { BasePlugin, meta, options, preferences } from 'ember-headless-table/plugins';
23
import { expectTypeOf } from 'expect-type';
34

@@ -39,7 +40,7 @@ interface SignatureA {
3940
}
4041

4142
class SimplePlugin<Signature = SignatureA> extends BasePlugin<Signature> {
42-
name = 'my-test-plugin';
43+
pluginName = 'my-test-plugin';
4344
}
4445

4546
// Options

ember-headless-table/src/-private/interfaces/plugins.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type DataTypeOf<T> = T extends Table<infer DataType> ? DataType : T;
1717
*/
1818
export type PluginClass<PluginType> = PluginType & {
1919
new: (...args: unknown[]) => PluginType;
20+
pluginName?: string;
2021
features?: string[];
2122
requires?: string[];
2223
};
@@ -85,7 +86,7 @@ export interface Plugin<Signature = unknown> {
8586
* - only one plugin of the same name is allowed
8687
* - the name is used for storing preferences / serializable information
8788
*/
88-
name: string;
89+
pluginName?: string;
8990

9091
/**
9192
* Some plugins may require that other plugins be present.

ember-headless-table/src/plugins/-private/base.ts

+59-46
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
ColumnOptionsFor,
1414
OptionsFor,
1515
Plugin,
16+
PluginClass,
1617
RowMetaFor,
1718
TableMetaFor,
1819
} from '#interfaces';
@@ -121,7 +122,7 @@ export abstract class BasePlugin<Signature = unknown> implements Plugin<Signatur
121122
row?: Constructor<RowMetaFor<Signature>>;
122123
};
123124

124-
abstract name: string;
125+
static pluginName: string;
125126
static features?: string[];
126127
static requires?: string[];
127128
}
@@ -151,17 +152,17 @@ export const preferences = {
151152
* (though, if other plugins can guess how the underlying plugin access
152153
* works, they can access this data, too. No security guaranteed)
153154
*/
154-
forColumn<P extends BasePlugin<any>, Data = unknown>(column: Column<Data>, klass: Class<P>) {
155+
forColumn<Data = unknown>(column: Column<Data>, klass: PluginClass<any>) {
155156
return {
156157
/**
157158
* delete an entry on the underlying `Map` used for this column-plugin pair
158159
*/
159160
delete(key: string) {
160161
let prefs = column.table.preferences;
161-
let existing = prefs.storage.forPlugin(klass.name);
162-
let columnPrefs = existing.forColumn(column.key);
162+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
163+
let columnPrefs = existing?.forColumn(column.key);
163164

164-
columnPrefs.delete(key);
165+
columnPrefs?.delete(key);
165166

166167
return prefs.persist();
167168
},
@@ -170,20 +171,20 @@ export const preferences = {
170171
*/
171172
get(key: string) {
172173
let prefs = column.table.preferences;
173-
let existing = prefs.storage.forPlugin(klass.name);
174-
let columnPrefs = existing.forColumn(column.key);
174+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
175+
let columnPrefs = existing?.forColumn(column.key);
175176

176-
return columnPrefs.get(key);
177+
return columnPrefs?.get(key);
177178
},
178179
/**
179180
* set an entry on the underlying `Map` used for this column-plugin pair
180181
*/
181182
set(key: string, value: unknown) {
182183
let prefs = column.table.preferences;
183-
let existing = prefs.storage.forPlugin(klass.name);
184-
let columnPrefs = existing.forColumn(column.key);
184+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
185+
let columnPrefs = existing?.forColumn(column.key);
185186

186-
columnPrefs.set(key, value);
187+
columnPrefs?.set(key, value);
187188

188189
prefs.persist();
189190
},
@@ -196,7 +197,7 @@ export const preferences = {
196197
* returns an object for bulk updating preferences data
197198
* for all columns (scoped to key and table)
198199
*/
199-
forAllColumns<P extends BasePlugin<any>, Data = unknown>(table: Table<Data>, klass: Class<P>) {
200+
forAllColumns<Data = unknown>(table: Table<Data>, klass: PluginClass<any>) {
200201
return {
201202
/**
202203
* delete an entry on every column in the underlying column `Map` for this table-plugin pair
@@ -206,10 +207,10 @@ export const preferences = {
206207

207208
for (let column of table.columns) {
208209
let prefs = column.table.preferences;
209-
let existing = prefs.storage.forPlugin(klass.name);
210-
let columnPrefs = existing.forColumn(column.key);
210+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
211+
let columnPrefs = existing?.forColumn(column.key);
211212

212-
columnPrefs.delete(key);
213+
columnPrefs?.delete(key);
213214
}
214215

215216
return tablePrefs.persist();
@@ -227,16 +228,16 @@ export const preferences = {
227228
* (though, if other plugins can guess how the underlying plugin access
228229
* works, they can access this data, too. No security guaranteed)
229230
*/
230-
forTable<P extends BasePlugin<any>, Data = unknown>(table: Table<Data>, klass: Class<P>) {
231+
forTable<Data = unknown>(table: Table<Data>, klass: PluginClass<any>) {
231232
return {
232233
/**
233234
* delete an entry on the underlying `Map` used for this table-plugin pair
234235
*/
235236
delete(key: string) {
236237
let prefs = table.preferences;
237-
let existing = prefs.storage.forPlugin(klass.name);
238+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
238239

239-
existing.table.delete(key);
240+
existing?.table.delete(key);
240241

241242
return prefs.persist();
242243
},
@@ -245,18 +246,18 @@ export const preferences = {
245246
*/
246247
get(key: string) {
247248
let prefs = table.preferences;
248-
let existing = prefs.storage.forPlugin(klass.name);
249+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
249250

250-
return existing.table.get(key);
251+
return existing?.table.get(key);
251252
},
252253
/**
253254
* set an entry on the underlying `Map` used for this table-plugin pair
254255
*/
255256
set(key: string, value: unknown) {
256257
let prefs = table.preferences;
257-
let existing = prefs.storage.forPlugin(klass.name);
258+
let existing = klass.pluginName ? prefs.storage.forPlugin(klass.pluginName) : null;
258259

259-
existing.table.set(key, value);
260+
existing?.table.set(key, value);
260261

261262
return prefs.persist();
262263
},
@@ -297,7 +298,7 @@ function columnsFor<DataType = any>(
297298

298299
if (requester) {
299300
assert(
300-
`[${requester.name}] requested columns from the table, but the plugin, ${requester.name}, ` +
301+
`[${requester.pluginName}] requested columns from the table, but the plugin, ${requester.pluginName}, ` +
301302
`is not used in this table`,
302303
table.plugins.some((plugin) => plugin instanceof (requester as Class<Plugin>))
303304
);
@@ -313,7 +314,7 @@ function columnsFor<DataType = any>(
313314
if (reordering && reordering.constructor === requester) {
314315
if (visibility) {
315316
assert(
316-
`<#${visibility.name}> defined a 'columns' property, but did not return valid data.`,
317+
`<#${visibility.pluginName}> defined a 'columns' property, but did not return valid data.`,
317318
visibility.columns && Array.isArray(visibility.columns)
318319
);
319320

@@ -325,7 +326,7 @@ function columnsFor<DataType = any>(
325326

326327
if (reordering) {
327328
assert(
328-
`<#${reordering.name}> defined a 'columns' property, but did not return valid data.`,
329+
`<#${reordering.pluginName}> defined a 'columns' property, but did not return valid data.`,
329330
reordering.columns && Array.isArray(reordering.columns)
330331
);
331332

@@ -334,7 +335,7 @@ function columnsFor<DataType = any>(
334335

335336
if (visibility) {
336337
assert(
337-
`<#${visibility.name}> defined a 'columns' property, but did not return valid data.`,
338+
`<#${visibility.pluginName}> defined a 'columns' property, but did not return valid data.`,
338339
visibility.columns && Array.isArray(visibility.columns)
339340
);
340341

@@ -343,7 +344,7 @@ function columnsFor<DataType = any>(
343344

344345
if (sizing) {
345346
assert(
346-
`<#${sizing.name}> defined a 'columns' property, but did not return valid data.`,
347+
`<#${sizing.pluginName}> defined a 'columns' property, but did not return valid data.`,
347348
sizing.columns && Array.isArray(sizing.columns)
348349
);
349350

@@ -359,7 +360,7 @@ function columnsFor<DataType = any>(
359360

360361
if (reordering) {
361362
assert(
362-
`<#${reordering.name}> defined a 'columns' property, but did not return valid data.`,
363+
`<#${reordering.pluginName}> defined a 'columns' property, but did not return valid data.`,
363364
reordering.columns && Array.isArray(reordering.columns)
364365
);
365366

@@ -368,7 +369,7 @@ function columnsFor<DataType = any>(
368369

369370
if (visibility) {
370371
assert(
371-
`<#${visibility.name}> defined a 'columns' property, but did not return valid data.`,
372+
`<#${visibility.pluginName}> defined a 'columns' property, but did not return valid data.`,
372373
visibility.columns && Array.isArray(visibility.columns)
373374
);
374375

@@ -377,7 +378,7 @@ function columnsFor<DataType = any>(
377378

378379
if (sizing) {
379380
assert(
380-
`<#${sizing.name}> defined a 'columns' property, but did not return valid data.`,
381+
`<#${sizing.pluginName}> defined a 'columns' property, but did not return valid data.`,
381382
sizing.columns && Array.isArray(sizing.columns)
382383
);
383384

@@ -489,16 +490,19 @@ export const meta = {
489490
*/
490491
forColumn<P extends BasePlugin<any>, Data = unknown>(
491492
column: Column<Data>,
492-
klass: Class<P>
493+
klass: PluginClass<any>
493494
): ColumnMetaFor<SignatureFrom<P>> {
494495
let columnMeta = column.table[COLUMN_META_KEY];
495496

496497
return getPluginInstance(columnMeta, column, klass, () => {
497498
let plugin = column.table.pluginOf(klass);
498499

499-
assert(`[${klass.name}] cannot get plugin instance of unregistered plugin class`, plugin);
500-
assert(`<#${plugin.name}> plugin does not have meta specified`, plugin.meta);
501-
assert(`<#${plugin.name}> plugin does not specify column meta`, plugin.meta.column);
500+
assert(
501+
`[${klass.pluginName}] cannot get plugin instance of unregistered plugin class`,
502+
plugin
503+
);
504+
assert(`<#${klass.pluginName}> plugin does not have meta specified`, plugin.meta);
505+
assert(`<#${klass.pluginName}> plugin does not specify column meta`, plugin.meta.column);
502506

503507
return new plugin.meta.column(column);
504508
});
@@ -514,16 +518,21 @@ export const meta = {
514518
*/
515519
forRow<P extends BasePlugin<any>, Data = unknown>(
516520
row: Row<Data>,
517-
klass: Class<P>
521+
klass: PluginClass<any>
518522
): RowMetaFor<SignatureFrom<P>> {
519523
let rowMeta = row.table[ROW_META_KEY];
520524

521525
return getPluginInstance(rowMeta, row, klass, () => {
522526
let plugin = row.table.pluginOf(klass);
523527

524-
assert(`[${klass.name}] cannot get plugin instance of unregistered plugin class`, plugin);
525-
assert(`<#${plugin.name}> plugin does not have meta specified`, plugin.meta);
526-
assert(`<#${plugin.name}> plugin does not specify row meta`, plugin.meta.row);
528+
assert(
529+
`[${klass.pluginName}] cannot get plugin instance of unregistered plugin class`,
530+
plugin
531+
);
532+
533+
assert(`<#${klass.pluginName}> plugin does not have meta specified`, plugin.meta);
534+
535+
assert(`<#${klass.pluginName}> plugin does not specify row meta`, plugin.meta.row);
527536

528537
return new plugin.meta.row(row);
529538
});
@@ -537,23 +546,27 @@ export const meta = {
537546
*/
538547
forTable<P extends BasePlugin<any>, Data = unknown>(
539548
table: Table<Data>,
540-
klass: Class<P>
549+
klass: PluginClass<any>
541550
): TableMetaFor<SignatureFrom<P>> {
542551
let tableMeta = table[TABLE_META_KEY];
543552

544553
return getPluginInstance(tableMeta, klass, () => {
545554
let plugin = table.pluginOf(klass);
546555

547-
assert(`[${klass.name}] cannot get plugin instance of unregistered plugin class`, plugin);
548-
assert(`<#${plugin.name}> plugin does not have meta specified`, plugin.meta);
549-
assert(`<#${plugin.name}> plugin does not specify table meta`, plugin.meta.table);
550556
assert(
551-
`<#${plugin.name}> plugin already exists for the table. ` +
557+
`[${klass.pluginName}] cannot get plugin instance of unregistered plugin class`,
558+
plugin
559+
);
560+
assert(`<#${klass.pluginName}> plugin does not have meta specified`, plugin.meta);
561+
assert(`<#${klass.pluginName}> plugin does not specify table meta`, plugin.meta.table);
562+
assert(
563+
`<#${klass.pluginName}> plugin already exists for the table. ` +
552564
`A plugin may only be instantiated once per table.`,
565+
553566
![...tableMeta.keys()].includes(klass)
554567
);
555568

556-
return new plugin.meta.table(table);
569+
return plugin?.meta?.table && new plugin.meta.table(table);
557570
});
558571
},
559572

@@ -662,7 +675,7 @@ export const options = {
662675
*/
663676
forTable<P extends BasePlugin<any>, Data = unknown>(
664677
table: Table<Data>,
665-
klass: Class<P>
678+
klass: PluginClass<any>
666679
): Partial<OptionsFor<SignatureFrom<P>>> {
667680
let normalized = normalizePluginsConfig(table?.config?.plugins);
668681
let tuple = normalized?.find((option) => option[0] === klass);
@@ -678,7 +691,7 @@ export const options = {
678691

679692
forColumn<P extends BasePlugin<any>, Data = unknown>(
680693
column: Column<Data>,
681-
klass: Class<P>
694+
klass: PluginClass<any>
682695
): Partial<ColumnOptionsFor<SignatureFrom<P>>> {
683696
let tuple = column.config.pluginOptions?.find((option) => option[0] === klass);
684697
let t = tuple as [unknown, () => ColumnOptionsFor<SignatureFrom<P>>];

ember-headless-table/src/plugins/column-reordering/plugin.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface Signature {
3131
}
3232

3333
export class ColumnReordering extends BasePlugin<Signature> {
34-
name = 'column-reordering';
34+
static pluginName = 'column-reordering';
3535
static features = ['columnOrder'];
3636

3737
meta = {

ember-headless-table/src/plugins/column-resizing/plugin.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ interface Signature {
8181
* but a plugin can have a "Meta" for each column
8282
*/
8383
export class ColumnResizing extends BasePlugin<Signature> {
84-
name = 'column-resizing';
84+
static pluginName = 'column-resizing';
8585
static features = ['columnWidth'];
8686

8787
meta = {
@@ -270,7 +270,7 @@ export class TableMeta {
270270
}
271271

272272
get isResizable() {
273-
return this.options?.enabled ?? true;
273+
return this.options?.['enabled'] ?? true;
274274
}
275275

276276
get defaultColumnWidth() {
@@ -307,7 +307,7 @@ export class TableMeta {
307307
let tablePrefs = this.table.preferences;
308308

309309
for (let column of visibleColumnMetas) {
310-
let existing = tablePrefs.storage.forPlugin('ColumnResizing');
310+
let existing = tablePrefs.storage.forPlugin(ColumnResizing.pluginName);
311311
let columnPrefs = existing.forColumn(column.key);
312312

313313
columnPrefs.set('width', column.width.toString());
@@ -362,7 +362,7 @@ export class TableMeta {
362362
* options
363363
*/
364364
let isDraggingRight = delta > 0;
365-
let position = this.options?.handlePosition ?? 'left';
365+
let position = this.options?.['handlePosition'] ?? 'left';
366366

367367
let growingColumn: Column | null | undefined;
368368

0 commit comments

Comments
 (0)