@knapsack/design-token-utils 5.0.0--canary.6593.4738696.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.lintstagedrc.mjs +2 -2
- package/CHANGELOG.md +164 -0
- package/dist/collections/token-collection-utils.d.ts +13 -2
- package/dist/collections/token-collection-utils.d.ts.map +1 -1
- package/dist/collections/token-collection-utils.js +26 -2
- package/dist/collections/token-collection-utils.js.map +1 -1
- package/dist/converters/asset-converters/android/android-asset-converters.d.ts +1 -1
- package/dist/converters/asset-converters/android/android-asset-converters.d.ts.map +1 -1
- package/dist/converters/asset-converters/convert-token-data-to-files.js +12 -13
- package/dist/converters/asset-converters/convert-token-data-to-files.js.map +1 -1
- package/dist/converters/asset-converters/ios/ios-asset-converters.d.ts +1 -1
- package/dist/converters/asset-converters/ios/ios-asset-converters.d.ts.map +1 -1
- package/dist/converters/asset-converters/ios/ios-asset-converters.js +1 -2
- package/dist/converters/asset-converters/ios/ios-asset-converters.js.map +1 -1
- package/dist/converters/asset-converters/web/web-asset-converter-utils.d.ts +1 -1
- package/dist/converters/asset-converters/web/web-asset-converter-utils.d.ts.map +1 -1
- package/dist/converters/asset-converters/web/web-asset-converters.d.ts +1 -1
- package/dist/converters/asset-converters/web/web-asset-converters.d.ts.map +1 -1
- package/dist/converters/asset-converters/web/web-asset-converters.js.map +1 -1
- package/dist/converters/combined-converters.d.ts +1 -1
- package/dist/converters/combined-converters.d.ts.map +1 -1
- package/dist/converters/ks-figma-vars-to-spec/ks-figma-vars-to-spec.d.ts +4 -4
- package/dist/converters/ks-figma-vars-to-spec/ks-figma-vars-to-spec.d.ts.map +1 -1
- package/dist/converters/ks-figma-vars-to-spec/ks-figma-vars-to-spec.js +31 -2
- package/dist/converters/ks-figma-vars-to-spec/ks-figma-vars-to-spec.js.map +1 -1
- package/dist/converters/ks-figma-vars-to-spec/utils.d.ts +1 -1
- package/dist/converters/ks-figma-vars-to-spec/utils.d.ts.map +1 -1
- package/dist/converters/ks-figma-vars-to-spec/utils.js +1 -2
- package/dist/converters/ks-figma-vars-to-spec/utils.js.map +1 -1
- package/dist/converters/sd-src-to-ks-data/sd-src-to-ks-data.d.ts +1 -1
- package/dist/converters/sd-src-to-ks-data/sd-src-to-ks-data.d.ts.map +1 -1
- package/dist/converters/sd-src-to-ks-data/sd-src-to-ks-data.js +1 -2
- package/dist/converters/sd-src-to-ks-data/sd-src-to-ks-data.js.map +1 -1
- package/dist/converters/sd-src-to-spec-src/convert-sd-to-token-src.d.ts +1 -1
- package/dist/converters/sd-src-to-spec-src/convert-sd-to-token-src.d.ts.map +1 -1
- package/dist/converters/spec-src-to-sd-src/spec-src-to-sd-src.d.ts +1 -1
- package/dist/converters/spec-src-to-sd-src/spec-src-to-sd-src.d.ts.map +1 -1
- package/dist/converters/spec-src-to-studio-src/spec-src-to-studio-src.d.ts +2 -2
- package/dist/converters/spec-src-to-studio-src/spec-src-to-studio-src.d.ts.map +1 -1
- package/dist/converters/spec-src-to-studio-src/spec-src-to-studio-src.js.map +1 -1
- package/dist/converters/spec-src-to-token-data/convert-src-to-token-data.d.ts +1 -1
- package/dist/converters/spec-src-to-token-data/convert-src-to-token-data.d.ts.map +1 -1
- package/dist/converters/spec-src-to-token-data/convert-src-to-token-data.js +102 -55
- package/dist/converters/spec-src-to-token-data/convert-src-to-token-data.js.map +1 -1
- package/dist/converters/spec-src-to-token-data/utils.d.ts +1 -1
- package/dist/converters/spec-src-to-token-data/utils.d.ts.map +1 -1
- package/dist/converters/studio-src-to-sd-src/token-studio-to-sd-src.d.ts +3 -3
- package/dist/converters/studio-src-to-sd-src/token-studio-to-sd-src.d.ts.map +1 -1
- package/dist/converters/studio-src-to-spec-src/studio-src-to-spec-src.d.ts +3 -3
- package/dist/converters/studio-src-to-spec-src/studio-src-to-spec-src.d.ts.map +1 -1
- package/dist/converters/studio-src-to-spec-src/test-fixtures/set-override-basic.d.ts +1 -1
- package/dist/converters/studio-src-to-spec-src/test-fixtures/set-override-basic.d.ts.map +1 -1
- package/dist/converters/studio-src-to-spec-src/test-fixtures/sibling-refs.d.ts +1 -1
- package/dist/converters/studio-src-to-spec-src/test-fixtures/sibling-refs.d.ts.map +1 -1
- package/dist/formats/format-utils.d.ts +1 -1
- package/dist/formats/format-utils.d.ts.map +1 -1
- package/dist/formats/ks-figma-vars/ks-figma-vars.format.d.ts +1 -1
- package/dist/formats/ks-figma-vars/ks-figma-vars.format.d.ts.map +1 -1
- package/dist/formats/style-dictionary-format/style-dictionary-format.d.ts +2 -2
- package/dist/formats/style-dictionary-format/style-dictionary-format.d.ts.map +1 -1
- package/dist/formats/style-dictionary-format/style-dictionary-format.js.map +1 -1
- package/dist/formats/token-spec-format/token-spec-format.d.ts +2 -2
- package/dist/formats/token-spec-format/token-spec-format.d.ts.map +1 -1
- package/dist/formats/tokens-studio-format/tokens-studio-format.d.ts +2 -2
- package/dist/formats/tokens-studio-format/tokens-studio-format.d.ts.map +1 -1
- package/dist/formats/tokens-studio-format/tokens-studio-types.d.ts.map +1 -1
- package/dist/formats/tokens-studio-format/tokens-studio-types.js.map +1 -1
- package/dist/tests-fixtures/index.d.ts +1 -1
- package/dist/tests-fixtures/index.d.ts.map +1 -1
- package/dist/tests-fixtures/index.js.map +1 -1
- package/dist/tests-fixtures/token-fixtures.d.ts +1 -1
- package/dist/tests-fixtures/token-fixtures.d.ts.map +1 -1
- package/dist/token-src-updater/token-src-updater.d.ts +1 -1
- package/dist/token-src-updater/token-src-updater.d.ts.map +1 -1
- package/dist/token-src-updater/token-src-updater.js +561 -576
- package/dist/token-src-updater/token-src-updater.js.map +1 -1
- package/dist/token-src-value-info/token-src-value-info.d.ts +1 -1
- package/dist/token-src-value-info/token-src-value-info.d.ts.map +1 -1
- package/dist/token-types.d.ts +3 -3
- package/dist/token-types.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -5
- package/dist/utils.js.map +1 -1
- package/package.json +17 -20
- package/vitest.config.ts +7 -0
- package/.eslintrc.cjs +0 -8
- package/ava.config.cjs +0 -3
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _TokenSrcUpdater_instances, _TokenSrcUpdater__src, _TokenSrcUpdater_prefix, _TokenSrcUpdater_dataIsStale, _TokenSrcUpdater__data, _TokenSrcUpdater_src_set, _TokenSrcUpdater_assertIdDoesNotHavePrefixes;
|
|
13
1
|
import { produce } from 'immer';
|
|
14
2
|
import loSetWith from 'lodash/setWith.js';
|
|
15
3
|
import loGet from 'lodash/get.js';
|
|
@@ -108,539 +96,48 @@ function makeTokenSrc({ tokenId, tokenSrcValueInfo, description: $description, }
|
|
|
108
96
|
*
|
|
109
97
|
*/
|
|
110
98
|
export class TokenSrcUpdater {
|
|
99
|
+
// Actual src
|
|
100
|
+
#_src = {};
|
|
101
|
+
// Hide at runtime
|
|
102
|
+
// eslint-disable-next-line no-unused-private-class-members -- Reserved for future use
|
|
103
|
+
#prefix = undefined;
|
|
104
|
+
#dataIsStale = true;
|
|
105
|
+
#_data = undefined;
|
|
106
|
+
/**
|
|
107
|
+
* This is the group key that all collections are nested under.
|
|
108
|
+
* Convenient prop instead of `this.data.globalConfig?.collectionsParentKey`
|
|
109
|
+
*/
|
|
110
|
+
collectionsParentKey;
|
|
111
|
+
/**
|
|
112
|
+
* Set src should also process/set data. Remember: external cannot set
|
|
113
|
+
*/
|
|
114
|
+
set #src(newSrc) {
|
|
115
|
+
this.#_src = newSrc;
|
|
116
|
+
this.#dataIsStale = true;
|
|
117
|
+
this.collectionsParentKey =
|
|
118
|
+
newSrc?.$extensions?.['cloud.knapsack']?.global?.collectionsParentKey ||
|
|
119
|
+
'';
|
|
120
|
+
}
|
|
111
121
|
/**
|
|
112
122
|
* Getter for #_src. Remember: external CAN get (the whole point)
|
|
113
123
|
*/
|
|
114
124
|
get src() {
|
|
115
|
-
return
|
|
125
|
+
return this.#_src;
|
|
116
126
|
}
|
|
117
127
|
/**
|
|
118
128
|
* Calculate `TokenDataSummary` from current `src`
|
|
119
129
|
*/
|
|
120
130
|
get data() {
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
if (this.#dataIsStale || !this.#_data) {
|
|
132
|
+
this.#_data = convertTokenGroupToData(this.src);
|
|
133
|
+
this.#dataIsStale = false;
|
|
124
134
|
}
|
|
125
|
-
return
|
|
135
|
+
return this.#_data;
|
|
126
136
|
}
|
|
127
137
|
constructor({ src, prefix }) {
|
|
128
|
-
_TokenSrcUpdater_instances.add(this);
|
|
129
|
-
// Actual src
|
|
130
|
-
_TokenSrcUpdater__src.set(this, {});
|
|
131
|
-
// Hide at runtime
|
|
132
|
-
_TokenSrcUpdater_prefix.set(this, undefined);
|
|
133
|
-
_TokenSrcUpdater_dataIsStale.set(this, true);
|
|
134
|
-
_TokenSrcUpdater__data.set(this, undefined);
|
|
135
|
-
/**
|
|
136
|
-
* Ensures that `id` does not start with the Collection Parent Key nor
|
|
137
|
-
* a Collection ID (if present)
|
|
138
|
-
*/
|
|
139
|
-
_TokenSrcUpdater_assertIdDoesNotHavePrefixes.set(this, ({ id, collectionId, }) => {
|
|
140
|
-
const prefix = collectionId
|
|
141
|
-
? `${this.collectionsParentKey}.${collectionId}`
|
|
142
|
-
: this.collectionsParentKey;
|
|
143
|
-
if (id === null || id === void 0 ? void 0 : id.startsWith(prefix)) {
|
|
144
|
-
throw new Error(`ID "${id}" should not start with "${prefix}"`);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
/**
|
|
148
|
-
* Collection operations
|
|
149
|
-
*/
|
|
150
|
-
this.collection = {
|
|
151
|
-
/**
|
|
152
|
-
* Collection -> Create
|
|
153
|
-
*/
|
|
154
|
-
create: ({ collectionId, excludeInitialMode, }) => {
|
|
155
|
-
if (this.data.collectionsById[collectionId]) {
|
|
156
|
-
throw new Error(`Collection ${collectionId} already exists.`);
|
|
157
|
-
}
|
|
158
|
-
this.createGroup({
|
|
159
|
-
groupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
160
|
-
groupData: {
|
|
161
|
-
config: {
|
|
162
|
-
collectionInfo: {
|
|
163
|
-
type: 'collection',
|
|
164
|
-
modes: excludeInitialMode ? [] : [{ id: 'default' }],
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
return { collectionId };
|
|
170
|
-
},
|
|
171
|
-
/**
|
|
172
|
-
* Collection -> Rename
|
|
173
|
-
*/
|
|
174
|
-
rename: ({ collectionId, newName, }) => {
|
|
175
|
-
this.renameGroup({
|
|
176
|
-
originalGroupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
177
|
-
destinationGroupId: `${this.collectionsParentKey}.${newName}`,
|
|
178
|
-
});
|
|
179
|
-
},
|
|
180
|
-
/**
|
|
181
|
-
* Collection -> Delete
|
|
182
|
-
*/
|
|
183
|
-
delete: ({ collectionId }) => {
|
|
184
|
-
if (collectionId.startsWith(`${this.collectionsParentKey}.`)) {
|
|
185
|
-
throw new Error(`Collection IDs should not start with ${this.collectionsParentKey} - those are Group IDs.`);
|
|
186
|
-
}
|
|
187
|
-
this.deleteGroup({
|
|
188
|
-
groupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
189
|
-
});
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
/**
|
|
193
|
-
* Collection -> Mode operations
|
|
194
|
-
*/
|
|
195
|
-
this.mode = {
|
|
196
|
-
/**
|
|
197
|
-
* Collection -> Mode -> Create
|
|
198
|
-
*/
|
|
199
|
-
create: ({ collectionId, modeId, }) => {
|
|
200
|
-
var _a;
|
|
201
|
-
const { groupId, modes } = this.data.collectionsById[collectionId];
|
|
202
|
-
const colGroup = this.data.groupsById[groupId];
|
|
203
|
-
this.updateGroup({
|
|
204
|
-
groupId,
|
|
205
|
-
groupData: {
|
|
206
|
-
config: {
|
|
207
|
-
...colGroup.groupConfig,
|
|
208
|
-
collectionInfo: {
|
|
209
|
-
...(((_a = colGroup.groupConfig) === null || _a === void 0 ? void 0 : _a.collectionInfo) || {}),
|
|
210
|
-
type: 'collection',
|
|
211
|
-
modes: [
|
|
212
|
-
...modes,
|
|
213
|
-
{
|
|
214
|
-
id: modeId,
|
|
215
|
-
},
|
|
216
|
-
],
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
},
|
|
222
|
-
/**
|
|
223
|
-
* Collection -> Mode -> Rename
|
|
224
|
-
* @TODO: ensure new Mode ID does not already exist
|
|
225
|
-
*/
|
|
226
|
-
rename: ({ collectionId, modeId, newModeId, }) => {
|
|
227
|
-
// Why use produce here instead of just calling rename() on a loop?
|
|
228
|
-
// If we can run multiple operations in a single Immer produce(), it prevents
|
|
229
|
-
// thrashing the this.src object and thus unnecessary updates.
|
|
230
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater_instances, produce(this.src, (draft) => {
|
|
231
|
-
var _a;
|
|
232
|
-
// Why not just use the processed this.data which is easier to look up on?
|
|
233
|
-
// The answer is that the returned object we get here will need to be
|
|
234
|
-
// modified within this Immer produce() anyway, so we might as well just
|
|
235
|
-
// use the this.src directly.
|
|
236
|
-
const originalColData = loGet(draft, [
|
|
237
|
-
this.collectionsParentKey,
|
|
238
|
-
collectionId,
|
|
239
|
-
'$extensions',
|
|
240
|
-
'cloud.knapsack',
|
|
241
|
-
]);
|
|
242
|
-
const colInfo = (_a = originalColData === null || originalColData === void 0 ? void 0 : originalColData.group) === null || _a === void 0 ? void 0 : _a.collectionInfo;
|
|
243
|
-
if (!colInfo || colInfo.type !== 'collection')
|
|
244
|
-
throw new Error('Not a Collection');
|
|
245
|
-
const { modes = [] } = colInfo;
|
|
246
|
-
const originalMode = modes === null || modes === void 0 ? void 0 : modes.find((m) => m.id === modeId);
|
|
247
|
-
if (!originalMode)
|
|
248
|
-
throw new Error('Mode not found');
|
|
249
|
-
// Find every single token with the mode name and change its modes. Use
|
|
250
|
-
// this.data for much easier looping here.
|
|
251
|
-
this.data.collectionsById[collectionId].vars.forEach((varObj) => {
|
|
252
|
-
if (!varObj.modesById[modeId])
|
|
253
|
-
return;
|
|
254
|
-
// Get original mode data
|
|
255
|
-
const original = loGet(draft, `${varObj.groupId}.${originalMode.id}`);
|
|
256
|
-
// If values for mode in var not found, don't do anything
|
|
257
|
-
if (!original) {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
// Set new Mode key and value
|
|
261
|
-
loSetWith(draft, ensureTokenPath(`${varObj.groupId}.${newModeId}`), original, Object);
|
|
262
|
-
// Now nuke the old Mode within the Var group
|
|
263
|
-
loUnset(draft, `${varObj.groupId}.${originalMode.id}`); // remove old mode
|
|
264
|
-
});
|
|
265
|
-
// Finally update the name of mode within the collection group modes array
|
|
266
|
-
originalMode.id = newModeId;
|
|
267
|
-
}), "a", _TokenSrcUpdater_src_set);
|
|
268
|
-
},
|
|
269
|
-
/**
|
|
270
|
-
* Collection -> Mode -> Delete
|
|
271
|
-
*/
|
|
272
|
-
delete: ({ collectionId, modeId, }) => {
|
|
273
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater_instances, produce(this.src, (draft) => {
|
|
274
|
-
var _a;
|
|
275
|
-
const originalColData = loGet(draft, [
|
|
276
|
-
this.collectionsParentKey,
|
|
277
|
-
collectionId,
|
|
278
|
-
'$extensions',
|
|
279
|
-
'cloud.knapsack',
|
|
280
|
-
]);
|
|
281
|
-
const colInfo = (_a = originalColData === null || originalColData === void 0 ? void 0 : originalColData.group) === null || _a === void 0 ? void 0 : _a.collectionInfo;
|
|
282
|
-
if (!colInfo || colInfo.type !== 'collection')
|
|
283
|
-
throw new Error('Not a Collection');
|
|
284
|
-
const { modes = [] } = colInfo;
|
|
285
|
-
const originalMode = modes === null || modes === void 0 ? void 0 : modes.find((m) => m.id === modeId);
|
|
286
|
-
if (!originalMode)
|
|
287
|
-
throw new Error('Mode not found');
|
|
288
|
-
// Find every single token with the mode name and change its modes. Use
|
|
289
|
-
// this.data for much easier looping here.
|
|
290
|
-
this.data.collectionsById[collectionId].vars.forEach((varObj) => {
|
|
291
|
-
if (!varObj.modesById[modeId])
|
|
292
|
-
return;
|
|
293
|
-
// Nuke the old Mode within the Var group
|
|
294
|
-
loUnset(draft, `${varObj.groupId}.${originalMode.id}`); // remove old mode
|
|
295
|
-
});
|
|
296
|
-
// Finally update the name of mode within the collection group modes array
|
|
297
|
-
loRemove(modes, (mode) => mode.id === modeId);
|
|
298
|
-
}), "a", _TokenSrcUpdater_src_set);
|
|
299
|
-
},
|
|
300
|
-
reorder: ({ collectionId, modeId, index, }) => {
|
|
301
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater_instances, produce(this.src, (draft) => {
|
|
302
|
-
var _a;
|
|
303
|
-
const originalColData = loGet(draft, [
|
|
304
|
-
this.collectionsParentKey,
|
|
305
|
-
collectionId,
|
|
306
|
-
'$extensions',
|
|
307
|
-
'cloud.knapsack',
|
|
308
|
-
]);
|
|
309
|
-
const colInfo = (_a = originalColData === null || originalColData === void 0 ? void 0 : originalColData.group) === null || _a === void 0 ? void 0 : _a.collectionInfo;
|
|
310
|
-
if (!colInfo || colInfo.type !== 'collection')
|
|
311
|
-
throw new Error('Not a Collection');
|
|
312
|
-
const { modes = [] } = colInfo;
|
|
313
|
-
const originalMode = modes === null || modes === void 0 ? void 0 : modes.find((m) => m.id === modeId);
|
|
314
|
-
if (!originalMode)
|
|
315
|
-
throw new Error('Mode not found');
|
|
316
|
-
const fromIndex = modes.findIndex((m) => m.id === modeId);
|
|
317
|
-
const [theModeToMove] = modes.splice(fromIndex, 1);
|
|
318
|
-
modes.splice(index, 0, theModeToMove);
|
|
319
|
-
}), "a", _TokenSrcUpdater_src_set);
|
|
320
|
-
},
|
|
321
|
-
};
|
|
322
|
-
/**
|
|
323
|
-
* Collection -> Collection Group operations
|
|
324
|
-
*/
|
|
325
|
-
this.collectionGroup = {
|
|
326
|
-
/**
|
|
327
|
-
* Collection -> Collection Group -> Create
|
|
328
|
-
*/
|
|
329
|
-
create: ({ collectionId, groupId, parentGroupId, }) => {
|
|
330
|
-
if (parentGroupId) {
|
|
331
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, { id: parentGroupId, collectionId });
|
|
332
|
-
}
|
|
333
|
-
if (this.data.collectionsById[collectionId].groupIds.indexOf(groupId) !== -1) {
|
|
334
|
-
throw new Error(`Group ${groupId} already exists in ${collectionId}.`);
|
|
335
|
-
}
|
|
336
|
-
this.createGroup({
|
|
337
|
-
groupId,
|
|
338
|
-
});
|
|
339
|
-
return {
|
|
340
|
-
groupId,
|
|
341
|
-
};
|
|
342
|
-
},
|
|
343
|
-
/**
|
|
344
|
-
* Collection -> Collection Group -> Rename
|
|
345
|
-
*/
|
|
346
|
-
rename: ({ collectionId, collectionGroupId, name, }) => {
|
|
347
|
-
assertDotlessId(name);
|
|
348
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, {
|
|
349
|
-
id: collectionGroupId,
|
|
350
|
-
collectionId,
|
|
351
|
-
});
|
|
352
|
-
const originalGroupId = `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`;
|
|
353
|
-
const destinationGroupId = originalGroupId
|
|
354
|
-
.split('.')
|
|
355
|
-
// replace the last segment of the ID with the new name
|
|
356
|
-
.map((chunk, i, arr) => (i === arr.length - 1 ? name : chunk))
|
|
357
|
-
.join('.');
|
|
358
|
-
this.renameGroup({
|
|
359
|
-
originalGroupId,
|
|
360
|
-
destinationGroupId,
|
|
361
|
-
});
|
|
362
|
-
},
|
|
363
|
-
/**
|
|
364
|
-
* Collection -> Collection Group -> Delete
|
|
365
|
-
*/
|
|
366
|
-
delete: ({ collectionId, collectionGroupId, }) => {
|
|
367
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, {
|
|
368
|
-
id: collectionGroupId,
|
|
369
|
-
collectionId,
|
|
370
|
-
});
|
|
371
|
-
this.deleteGroup({
|
|
372
|
-
groupId: `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`,
|
|
373
|
-
});
|
|
374
|
-
},
|
|
375
|
-
/**
|
|
376
|
-
* Collection -> Collection Group -> Move
|
|
377
|
-
*/
|
|
378
|
-
move: ({ collectionId, collectionGroupId, newParentCollectionId, newParentCollectionGroupId, }) => {
|
|
379
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, {
|
|
380
|
-
id: collectionGroupId,
|
|
381
|
-
collectionId,
|
|
382
|
-
});
|
|
383
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, {
|
|
384
|
-
id: newParentCollectionGroupId,
|
|
385
|
-
collectionId,
|
|
386
|
-
});
|
|
387
|
-
const originalGroupId = `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`;
|
|
388
|
-
const finalSegment = originalGroupId.split('.').at(-1);
|
|
389
|
-
if (!finalSegment)
|
|
390
|
-
throw new Error('Cannot extract final segment.');
|
|
391
|
-
const destinationCollectionId = newParentCollectionId !== null && newParentCollectionId !== void 0 ? newParentCollectionId : collectionId;
|
|
392
|
-
// Empty string newParentCollectionGroupId means move to root of collection
|
|
393
|
-
const destinationCollectionGroupId = newParentCollectionGroupId === ''
|
|
394
|
-
? ''
|
|
395
|
-
: `.${newParentCollectionGroupId}`;
|
|
396
|
-
const destinationGroupId = `${this.collectionsParentKey}.${destinationCollectionId}${destinationCollectionGroupId}.${finalSegment}`;
|
|
397
|
-
this.renameGroup({
|
|
398
|
-
originalGroupId,
|
|
399
|
-
destinationGroupId,
|
|
400
|
-
});
|
|
401
|
-
},
|
|
402
|
-
/**
|
|
403
|
-
* CONVERT vanilla group to collection group
|
|
404
|
-
*/
|
|
405
|
-
convert: ({ currentGroupId, collectionId, newParentCollectionGroupId, }) => {
|
|
406
|
-
// Get the vanilla group data
|
|
407
|
-
const vanillaGroup = this.data.groupsById[currentGroupId];
|
|
408
|
-
// Create var with default value for each mode
|
|
409
|
-
try {
|
|
410
|
-
// Quick validation that mode we'll be adding later exists
|
|
411
|
-
const modeId = this.data.collectionsById[collectionId].modes[0].id;
|
|
412
|
-
if (!modeId)
|
|
413
|
-
throw new Error('Collection must have at least one mode');
|
|
414
|
-
// Make first collection group
|
|
415
|
-
this.collectionGroup.create({
|
|
416
|
-
collectionId,
|
|
417
|
-
groupId: `collections.${collectionId}.${newParentCollectionGroupId}.${vanillaGroup.id}`,
|
|
418
|
-
});
|
|
419
|
-
// Recursively dive through token group. NOTE: Only a function definition,
|
|
420
|
-
// actually called below.
|
|
421
|
-
const dive = (group) => {
|
|
422
|
-
// Now loop all children, creating var for each
|
|
423
|
-
group.children.tokenIds.forEach((tokenId) => {
|
|
424
|
-
this.var.create({
|
|
425
|
-
collectionId,
|
|
426
|
-
groupId: newParentCollectionGroupId,
|
|
427
|
-
varId: tokenId,
|
|
428
|
-
varType: this.data.tokensById[tokenId].type,
|
|
429
|
-
});
|
|
430
|
-
const tokenData = this.data.tokensById[tokenId];
|
|
431
|
-
const tokenSrcValueInfo = getTokenSrcInfo(tokenData);
|
|
432
|
-
// Set the default value for the var for *first* mode
|
|
433
|
-
this.var.setModeValue({
|
|
434
|
-
collectionId,
|
|
435
|
-
varId: `${newParentCollectionGroupId}.${tokenId}`,
|
|
436
|
-
modeId,
|
|
437
|
-
tokenSrcValueInfo,
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
// Yay recursion!
|
|
441
|
-
group.children.groupIds.forEach((subGroupId) => {
|
|
442
|
-
this.collectionGroup.create({
|
|
443
|
-
collectionId,
|
|
444
|
-
groupId: `collections.${collectionId}.${newParentCollectionGroupId}.${subGroupId}`,
|
|
445
|
-
});
|
|
446
|
-
dive(this.data.groupsById[subGroupId]);
|
|
447
|
-
});
|
|
448
|
-
};
|
|
449
|
-
// Kick off the call to the above
|
|
450
|
-
dive(vanillaGroup);
|
|
451
|
-
// Nuke the original vanilla group
|
|
452
|
-
this.deleteGroup({
|
|
453
|
-
groupId: currentGroupId,
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
catch (e) {
|
|
457
|
-
if (e instanceof Error) {
|
|
458
|
-
// @TODO: roll back any changes from the try above
|
|
459
|
-
throw new Error(`Error converting vanilla group to collection group: ${e.message}`);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
},
|
|
463
|
-
};
|
|
464
|
-
/**
|
|
465
|
-
* Var operations
|
|
466
|
-
*/
|
|
467
|
-
this.var = {
|
|
468
|
-
/**
|
|
469
|
-
* Var -> Create
|
|
470
|
-
*/
|
|
471
|
-
create: ({ collectionId, groupId, varId, varType, }) => {
|
|
472
|
-
__classPrivateFieldGet(this, _TokenSrcUpdater_assertIdDoesNotHavePrefixes, "f").call(this, {
|
|
473
|
-
id: groupId,
|
|
474
|
-
collectionId,
|
|
475
|
-
});
|
|
476
|
-
const newVarId = groupId ? `${groupId}.${varId}` : varId;
|
|
477
|
-
const fullGroupId = `${this.collectionsParentKey}.${collectionId}.${newVarId}`;
|
|
478
|
-
// This is pretty fast
|
|
479
|
-
const existingVar = loGet(this.src, fullGroupId);
|
|
480
|
-
if (existingVar) {
|
|
481
|
-
console.log(`Var ${newVarId} already exists in ${collectionId}. Skipping.`);
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
this.createGroup({
|
|
485
|
-
groupId: fullGroupId,
|
|
486
|
-
groupData: {
|
|
487
|
-
type: varType,
|
|
488
|
-
config: {
|
|
489
|
-
collectionInfo: {
|
|
490
|
-
type: 'var',
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
},
|
|
494
|
-
});
|
|
495
|
-
},
|
|
496
|
-
/**
|
|
497
|
-
* Var -> Rename
|
|
498
|
-
*/
|
|
499
|
-
rename: ({ collectionId, varId, newVarId, }) => {
|
|
500
|
-
this.renameGroup({
|
|
501
|
-
originalGroupId: `${this.collectionsParentKey}.${collectionId}.${varId}`,
|
|
502
|
-
destinationGroupId: `${this.collectionsParentKey}.${collectionId}.${newVarId}`,
|
|
503
|
-
});
|
|
504
|
-
},
|
|
505
|
-
/**
|
|
506
|
-
* Var -> Delete
|
|
507
|
-
*/
|
|
508
|
-
delete: ({ collectionId, varId, }) => {
|
|
509
|
-
this.deleteGroup({
|
|
510
|
-
groupId: `${this.collectionsParentKey}.${collectionId}.${varId}`,
|
|
511
|
-
});
|
|
512
|
-
},
|
|
513
|
-
/**
|
|
514
|
-
* Var -> Move/Rename (moving groups is the same as renaming)
|
|
515
|
-
* @TODO: needs work around existing Var groups
|
|
516
|
-
*/
|
|
517
|
-
move: ({ collectionId, varId, newParentGroupId, }) => {
|
|
518
|
-
const varGroupPath = `${this.collectionsParentKey}.${collectionId}.${varId}`;
|
|
519
|
-
const lastPart = varGroupPath.split('.').at(-1);
|
|
520
|
-
const destinationGroupId = `${this.collectionsParentKey}.${collectionId}.${newParentGroupId}.${lastPart}`;
|
|
521
|
-
this.renameGroup({
|
|
522
|
-
originalGroupId: varGroupPath,
|
|
523
|
-
destinationGroupId,
|
|
524
|
-
});
|
|
525
|
-
},
|
|
526
|
-
/**
|
|
527
|
-
* Var -> setDescription
|
|
528
|
-
*/
|
|
529
|
-
setDescription: ({ collectionId, varId, description, }) => {
|
|
530
|
-
const groupId = `${this.collectionsParentKey}.${collectionId}.${varId}`;
|
|
531
|
-
this.updateGroup({
|
|
532
|
-
groupId,
|
|
533
|
-
groupData: {
|
|
534
|
-
description,
|
|
535
|
-
},
|
|
536
|
-
});
|
|
537
|
-
},
|
|
538
|
-
/**
|
|
539
|
-
* Var -> setModeValue
|
|
540
|
-
*/
|
|
541
|
-
/**
|
|
542
|
-
* Set one or many var mode values
|
|
543
|
-
*/
|
|
544
|
-
setModeValue: (modeVals) => {
|
|
545
|
-
// Do everything inside a single Immer produce for batch efficiency
|
|
546
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater_instances, produce(this.src, (draft) => {
|
|
547
|
-
// Force the incoming args to be an array so we can handle one or many
|
|
548
|
-
castArray(modeVals).forEach((val) => {
|
|
549
|
-
var _a, _b;
|
|
550
|
-
const { collectionId, varId, modeId, tokenSrcValueInfo, skipRefExistsCheck, } = val;
|
|
551
|
-
const { vars } = this.data.collectionsById[collectionId];
|
|
552
|
-
const varValue = vars.find((v) => v.id === varId);
|
|
553
|
-
if (!varValue) {
|
|
554
|
-
throw new Error(`Var ${varId} does not exist in collection ${collectionId}`);
|
|
555
|
-
}
|
|
556
|
-
const tokenId = `${this.collectionsParentKey}.${collectionId}.${varId}.${modeId}`;
|
|
557
|
-
// Handle the different kinds of tokenSrcValueInfo: var refs and static
|
|
558
|
-
switch (tokenSrcValueInfo.kind) {
|
|
559
|
-
case 'ref': {
|
|
560
|
-
const { isVarRef, referencedTokenId } = tokenSrcValueInfo;
|
|
561
|
-
// Note that there are TWO kinds of "refs": referencing another var
|
|
562
|
-
// (and all its modes therein) and just referencing a vanilla token.
|
|
563
|
-
if (isVarRef) {
|
|
564
|
-
if (!skipRefExistsCheck) {
|
|
565
|
-
const ref = this.data.groupsById[referencedTokenId];
|
|
566
|
-
if (!ref) {
|
|
567
|
-
throw new Error(`No ref exists for "${referencedTokenId}"`);
|
|
568
|
-
}
|
|
569
|
-
if (((_b = (_a = ref.groupConfig) === null || _a === void 0 ? void 0 : _a.collectionInfo) === null || _b === void 0 ? void 0 : _b.type) !== 'var') {
|
|
570
|
-
throw new Error(`Referenced token "${referencedTokenId}" is not a var`);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
// This is the fancypants ref to a whole collections var
|
|
574
|
-
const tokenSrc = {
|
|
575
|
-
$extensions: {
|
|
576
|
-
'cloud.knapsack': {
|
|
577
|
-
group: {
|
|
578
|
-
collectionInfo: {
|
|
579
|
-
type: 'var-ref',
|
|
580
|
-
referencedId: referencedTokenId,
|
|
581
|
-
},
|
|
582
|
-
},
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
};
|
|
586
|
-
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
587
|
-
// @ts-expect-error - force removing key that should not exist
|
|
588
|
-
delete newTokenSrc.$value;
|
|
589
|
-
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
590
|
-
break;
|
|
591
|
-
}
|
|
592
|
-
// Cannot call another produce function within a produce
|
|
593
|
-
// this.updateToken({
|
|
594
|
-
// tokenId,
|
|
595
|
-
// tokenSrcValueInfo,
|
|
596
|
-
// });
|
|
597
|
-
// @TODO: find a way to call this.updateToken() instead of repeating below
|
|
598
|
-
// This is the vanilla token ref
|
|
599
|
-
const tokenSrc = makeTokenSrc({
|
|
600
|
-
tokenId,
|
|
601
|
-
tokenSrcValueInfo,
|
|
602
|
-
});
|
|
603
|
-
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
604
|
-
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
605
|
-
break;
|
|
606
|
-
}
|
|
607
|
-
case 'static': {
|
|
608
|
-
// Cannot call another function that uses produce
|
|
609
|
-
// this.updateToken({
|
|
610
|
-
// tokenId,
|
|
611
|
-
// tokenSrcValueInfo,
|
|
612
|
-
// });
|
|
613
|
-
// @TODO: find a way to call this.updateToken() instead of repeating below
|
|
614
|
-
const tokenSrc = makeTokenSrc({
|
|
615
|
-
tokenId,
|
|
616
|
-
tokenSrcValueInfo,
|
|
617
|
-
});
|
|
618
|
-
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
619
|
-
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
620
|
-
break;
|
|
621
|
-
}
|
|
622
|
-
default: {
|
|
623
|
-
const _exhaustiveCheck = tokenSrcValueInfo;
|
|
624
|
-
throw new Error(`Unhandled kind: ${JSON.stringify(tokenSrcValueInfo)}`);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
// Token Mode Values should not have $type since the $type of the Mode is
|
|
628
|
-
// set within the Var object above. This just guarantees $type is not set.
|
|
629
|
-
loUnset(draft, `${tokenId}.$type`);
|
|
630
|
-
});
|
|
631
|
-
}), "a", _TokenSrcUpdater_src_set);
|
|
632
|
-
},
|
|
633
|
-
/**
|
|
634
|
-
* Var -> unsetModeValue
|
|
635
|
-
*/
|
|
636
|
-
unsetModeValue: ({ collectionId, varId, modeId, }) => {
|
|
637
|
-
const tokenId = `${this.collectionsParentKey}.${collectionId}.${varId}.${modeId}`;
|
|
638
|
-
this.deleteToken({ tokenId });
|
|
639
|
-
},
|
|
640
|
-
};
|
|
641
138
|
this.collectionsParentKey = '';
|
|
642
|
-
|
|
643
|
-
|
|
139
|
+
this.#src = src;
|
|
140
|
+
this.#prefix = prefix;
|
|
644
141
|
}
|
|
645
142
|
/**
|
|
646
143
|
* Single Token operations
|
|
@@ -655,9 +152,9 @@ export class TokenSrcUpdater {
|
|
|
655
152
|
description,
|
|
656
153
|
});
|
|
657
154
|
// Reminder: mutate draft within produce(). Do NOT return.
|
|
658
|
-
|
|
155
|
+
this.#src = produce(this.src, (draft) => {
|
|
659
156
|
loSetWith(draft, ensureTokenPath(tokenId), tokenSrc, Object);
|
|
660
|
-
})
|
|
157
|
+
});
|
|
661
158
|
}
|
|
662
159
|
/**
|
|
663
160
|
* Simple token data updates (value, description, etc)
|
|
@@ -669,10 +166,10 @@ export class TokenSrcUpdater {
|
|
|
669
166
|
description,
|
|
670
167
|
});
|
|
671
168
|
// Reminder: mutate draft within produce(). Do NOT return.
|
|
672
|
-
|
|
169
|
+
this.#src = produce(this.src, (draft) => {
|
|
673
170
|
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
674
171
|
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
675
|
-
})
|
|
172
|
+
});
|
|
676
173
|
}
|
|
677
174
|
/**
|
|
678
175
|
* Remove token at dot.path. If other things ref it, update those to original
|
|
@@ -709,7 +206,6 @@ export class TokenSrcUpdater {
|
|
|
709
206
|
// ];
|
|
710
207
|
// @TODO: probably need to sort this by precedence of reference
|
|
711
208
|
const tokensWithRefToDeletedTokens = this.data.tokens.filter((token) => {
|
|
712
|
-
var _a;
|
|
713
209
|
switch (token.type) {
|
|
714
210
|
case 'shadow': {
|
|
715
211
|
if (token.kind === 'static') {
|
|
@@ -763,7 +259,7 @@ export class TokenSrcUpdater {
|
|
|
763
259
|
case 'fontWeight':
|
|
764
260
|
case 'cubicBezier':
|
|
765
261
|
case 'string': {
|
|
766
|
-
return
|
|
262
|
+
return token?.references?.some((refStack) => {
|
|
767
263
|
// First ref in stack is **direct** reference to deleted token
|
|
768
264
|
const mostImmediateRef = refStack.at(0);
|
|
769
265
|
// Make TS happy that it's not undefined
|
|
@@ -795,7 +291,7 @@ export class TokenSrcUpdater {
|
|
|
795
291
|
return x;
|
|
796
292
|
}
|
|
797
293
|
// Reminder: mutate draft within produce(). Do NOT return.
|
|
798
|
-
|
|
294
|
+
this.#src = produce(this.src, (draft) => {
|
|
799
295
|
// Update these tokens to use original token value.
|
|
800
296
|
tokensWithRefToDeletedTokens.forEach((tokenWithRef) => {
|
|
801
297
|
switch (tokenWithRef.type) {
|
|
@@ -846,7 +342,7 @@ export class TokenSrcUpdater {
|
|
|
846
342
|
deletedTokens.forEach((deletedToken) => {
|
|
847
343
|
loUnset(draft, deletedToken.id);
|
|
848
344
|
});
|
|
849
|
-
})
|
|
345
|
+
});
|
|
850
346
|
// Return deleted tokens for any callee that wants verification
|
|
851
347
|
return deletedTokens;
|
|
852
348
|
}
|
|
@@ -877,15 +373,14 @@ export class TokenSrcUpdater {
|
|
|
877
373
|
: { $type: undefined }),
|
|
878
374
|
});
|
|
879
375
|
// Reminder: mutate draft within produce(). Do NOT return.
|
|
880
|
-
|
|
376
|
+
this.#src = produce(this.src, (draft) => {
|
|
881
377
|
loSetWith(draft, ensureTokenPath(destinationTokenId), tokenProcessed, Object);
|
|
882
|
-
})
|
|
378
|
+
});
|
|
883
379
|
const tokensWithRefToRenamedToken = this.data.tokens.filter((token) => {
|
|
884
|
-
|
|
885
|
-
return (_a = token === null || token === void 0 ? void 0 : token.references) === null || _a === void 0 ? void 0 : _a.some((refStack) => refStack.at(0) === originalTokenId);
|
|
380
|
+
return token?.references?.some((refStack) => refStack.at(0) === originalTokenId);
|
|
886
381
|
});
|
|
887
382
|
// Reminder: mutate draft within produce(). Do NOT return.
|
|
888
|
-
|
|
383
|
+
this.#src = produce(this.src, (draft) => {
|
|
889
384
|
tokensWithRefToRenamedToken.forEach((token) => {
|
|
890
385
|
// @TODO: handle token values other than just strings; `color`, for
|
|
891
386
|
// instance, is a string.
|
|
@@ -895,7 +390,7 @@ export class TokenSrcUpdater {
|
|
|
895
390
|
loSetWith(draft, ensureTokenPath(`${token.id}.$value`), newVal, Object);
|
|
896
391
|
});
|
|
897
392
|
loUnset(draft, originalTokenId);
|
|
898
|
-
})
|
|
393
|
+
});
|
|
899
394
|
// Return original and new token name for any callee that wants verification
|
|
900
395
|
return {
|
|
901
396
|
originalTokenId,
|
|
@@ -907,19 +402,19 @@ export class TokenSrcUpdater {
|
|
|
907
402
|
*/
|
|
908
403
|
createGroup({ groupId, groupData, }) {
|
|
909
404
|
const srcGroup = {
|
|
910
|
-
...(
|
|
405
|
+
...(groupData?.description
|
|
911
406
|
? { $description: groupData.description }
|
|
912
407
|
: {}),
|
|
913
|
-
$type:
|
|
408
|
+
$type: groupData?.type || undefined,
|
|
914
409
|
};
|
|
915
|
-
if (groupData
|
|
410
|
+
if (groupData?.config) {
|
|
916
411
|
srcGroup.$extensions = {
|
|
917
412
|
'cloud.knapsack': {
|
|
918
413
|
group: groupData.config,
|
|
919
414
|
},
|
|
920
415
|
};
|
|
921
416
|
}
|
|
922
|
-
|
|
417
|
+
this.#src = produce(this.src, (draft) => {
|
|
923
418
|
// What existed prior, spread to ensure COPY of object
|
|
924
419
|
const originalSrcGroup = { ...loGet(draft, groupId, {}) };
|
|
925
420
|
// Merge new into what existed already, but remove empty key/values
|
|
@@ -933,7 +428,7 @@ export class TokenSrcUpdater {
|
|
|
933
428
|
// brackets to delimit object nesting. Thus splitting the groupId by dots
|
|
934
429
|
// into an array means we can support square brackets in path names.
|
|
935
430
|
ensureTokenPath(groupId), mergedSrcGroup, Object);
|
|
936
|
-
})
|
|
431
|
+
});
|
|
937
432
|
}
|
|
938
433
|
/**
|
|
939
434
|
* Update token fields, like description and type
|
|
@@ -944,21 +439,21 @@ export class TokenSrcUpdater {
|
|
|
944
439
|
...(groupData.description ? { $description: groupData.description } : {}),
|
|
945
440
|
$type: groupData.type,
|
|
946
441
|
};
|
|
947
|
-
if (groupData
|
|
442
|
+
if (groupData?.config) {
|
|
948
443
|
newSrcGroup.$extensions = {
|
|
949
444
|
'cloud.knapsack': {
|
|
950
445
|
group: groupData.config,
|
|
951
446
|
},
|
|
952
447
|
};
|
|
953
448
|
}
|
|
954
|
-
|
|
449
|
+
this.#src = produce(this.src, (draft) => {
|
|
955
450
|
// What existed prior, spread to ensure COPY of object
|
|
956
451
|
const originalSrcGroup = { ...loGet(draft, groupId, {}) };
|
|
957
452
|
// Merge new into what existed already, but remove empty key/values
|
|
958
453
|
const mergedSrcGroup = removeUndefinedProps(loMerge(originalSrcGroup, newSrcGroup));
|
|
959
454
|
// Set it
|
|
960
455
|
loSetWith(draft, ensureTokenPath(groupId), mergedSrcGroup, Object);
|
|
961
|
-
})
|
|
456
|
+
});
|
|
962
457
|
}
|
|
963
458
|
/**
|
|
964
459
|
* Removing a group nukes all tokens within
|
|
@@ -972,15 +467,14 @@ export class TokenSrcUpdater {
|
|
|
972
467
|
this.deleteToken({
|
|
973
468
|
tokenId: this.data.tokens.flatMap(({ id }) => id.startsWith(`${groupId}.`) ? id : []),
|
|
974
469
|
});
|
|
975
|
-
|
|
470
|
+
this.#src = produce(this.src, (draft) => {
|
|
976
471
|
loUnset(draft, groupId);
|
|
977
|
-
})
|
|
472
|
+
});
|
|
978
473
|
}
|
|
979
474
|
/**
|
|
980
475
|
* Renaming a group utilizes prior methods
|
|
981
476
|
*/
|
|
982
477
|
renameGroup({ originalGroupId, destinationGroupId, }) {
|
|
983
|
-
var _a;
|
|
984
478
|
const existingGroup = loGet(this.src, originalGroupId);
|
|
985
479
|
const destinationGroup = loGet(this.src, destinationGroupId);
|
|
986
480
|
if (destinationGroup) {
|
|
@@ -1016,18 +510,17 @@ export class TokenSrcUpdater {
|
|
|
1016
510
|
}
|
|
1017
511
|
: {}),
|
|
1018
512
|
...('$type' in existingGroup ? { type: existingGroup.$type } : {}),
|
|
1019
|
-
config:
|
|
513
|
+
config: this.data.groupsById[originalGroupId]?.groupConfig,
|
|
1020
514
|
},
|
|
1021
515
|
});
|
|
1022
516
|
// Dig through all token values and replace references from the old group ID
|
|
1023
517
|
// to the new
|
|
1024
518
|
this.data.groups.forEach((group) => {
|
|
1025
|
-
var _a, _b, _c, _d;
|
|
1026
519
|
// We're only looking for var-refs
|
|
1027
|
-
if (
|
|
520
|
+
if (group?.groupConfig?.collectionInfo?.type !== 'var-ref')
|
|
1028
521
|
return;
|
|
1029
522
|
// And the referenced ID does NOT match, skip
|
|
1030
|
-
if (
|
|
523
|
+
if (group?.groupConfig?.collectionInfo?.referencedId !== originalGroupId)
|
|
1031
524
|
return;
|
|
1032
525
|
// We are a var-ref and it's referencing the group ID that just changed
|
|
1033
526
|
// i.e. 'collections.brand.color.primary.modeA'
|
|
@@ -1051,24 +544,23 @@ export class TokenSrcUpdater {
|
|
|
1051
544
|
// Finally we delete the original group. Note: we're using produce() here
|
|
1052
545
|
// directly instead of calling this.deleteGroup() due to how Immer holds onto
|
|
1053
546
|
// the proxy. This apparently keeps it in the same tick.
|
|
1054
|
-
|
|
547
|
+
this.#src = produce(this.src, (draft) => {
|
|
1055
548
|
loUnset(draft, originalGroupId);
|
|
1056
|
-
})
|
|
549
|
+
});
|
|
1057
550
|
}
|
|
1058
551
|
setCollectionsParentKey({ collectionsParentKey, }) {
|
|
1059
|
-
|
|
1060
|
-
var _a, _b, _c;
|
|
552
|
+
this.#src = produce(this.src, (draft) => {
|
|
1061
553
|
draft.$extensions = {
|
|
1062
554
|
...(draft.$extensions || {}),
|
|
1063
555
|
'cloud.knapsack': {
|
|
1064
|
-
...(
|
|
556
|
+
...(draft.$extensions?.['cloud.knapsack'] || {}),
|
|
1065
557
|
global: {
|
|
1066
|
-
...(
|
|
558
|
+
...(draft.$extensions?.['cloud.knapsack']?.global || {}),
|
|
1067
559
|
collectionsParentKey,
|
|
1068
560
|
},
|
|
1069
561
|
},
|
|
1070
562
|
};
|
|
1071
|
-
})
|
|
563
|
+
});
|
|
1072
564
|
// Update the instance property to match the new value
|
|
1073
565
|
this.collectionsParentKey = collectionsParentKey;
|
|
1074
566
|
if (collectionsParentKey) {
|
|
@@ -1077,13 +569,506 @@ export class TokenSrcUpdater {
|
|
|
1077
569
|
});
|
|
1078
570
|
}
|
|
1079
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Ensures that `id` does not start with the Collection Parent Key nor
|
|
574
|
+
* a Collection ID (if present)
|
|
575
|
+
*/
|
|
576
|
+
#assertIdDoesNotHavePrefixes = ({ id, collectionId, }) => {
|
|
577
|
+
const prefix = collectionId
|
|
578
|
+
? `${this.collectionsParentKey}.${collectionId}`
|
|
579
|
+
: this.collectionsParentKey;
|
|
580
|
+
if (id?.startsWith(prefix)) {
|
|
581
|
+
throw new Error(`ID "${id}" should not start with "${prefix}"`);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Collection operations
|
|
586
|
+
*/
|
|
587
|
+
collection = {
|
|
588
|
+
/**
|
|
589
|
+
* Collection -> Create
|
|
590
|
+
*/
|
|
591
|
+
create: ({ collectionId, excludeInitialMode, }) => {
|
|
592
|
+
if (this.data.collectionsById[collectionId]) {
|
|
593
|
+
throw new Error(`Collection ${collectionId} already exists.`);
|
|
594
|
+
}
|
|
595
|
+
this.createGroup({
|
|
596
|
+
groupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
597
|
+
groupData: {
|
|
598
|
+
config: {
|
|
599
|
+
collectionInfo: {
|
|
600
|
+
type: 'collection',
|
|
601
|
+
modes: excludeInitialMode ? [] : [{ id: 'default' }],
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
return { collectionId };
|
|
607
|
+
},
|
|
608
|
+
/**
|
|
609
|
+
* Collection -> Rename
|
|
610
|
+
*/
|
|
611
|
+
rename: ({ collectionId, newName, }) => {
|
|
612
|
+
this.renameGroup({
|
|
613
|
+
originalGroupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
614
|
+
destinationGroupId: `${this.collectionsParentKey}.${newName}`,
|
|
615
|
+
});
|
|
616
|
+
},
|
|
617
|
+
/**
|
|
618
|
+
* Collection -> Delete
|
|
619
|
+
*/
|
|
620
|
+
delete: ({ collectionId }) => {
|
|
621
|
+
if (collectionId.startsWith(`${this.collectionsParentKey}.`)) {
|
|
622
|
+
throw new Error(`Collection IDs should not start with ${this.collectionsParentKey} - those are Group IDs.`);
|
|
623
|
+
}
|
|
624
|
+
this.deleteGroup({
|
|
625
|
+
groupId: `${this.collectionsParentKey}.${collectionId}`,
|
|
626
|
+
});
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
/**
|
|
630
|
+
* Collection -> Mode operations
|
|
631
|
+
*/
|
|
632
|
+
mode = {
|
|
633
|
+
/**
|
|
634
|
+
* Collection -> Mode -> Create
|
|
635
|
+
*/
|
|
636
|
+
create: ({ collectionId, modeId, }) => {
|
|
637
|
+
const { groupId, modes } = this.data.collectionsById[collectionId];
|
|
638
|
+
const colGroup = this.data.groupsById[groupId];
|
|
639
|
+
this.updateGroup({
|
|
640
|
+
groupId,
|
|
641
|
+
groupData: {
|
|
642
|
+
config: {
|
|
643
|
+
...colGroup.groupConfig,
|
|
644
|
+
collectionInfo: {
|
|
645
|
+
...(colGroup.groupConfig?.collectionInfo || {}),
|
|
646
|
+
type: 'collection',
|
|
647
|
+
modes: [
|
|
648
|
+
...modes,
|
|
649
|
+
{
|
|
650
|
+
id: modeId,
|
|
651
|
+
},
|
|
652
|
+
],
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
});
|
|
657
|
+
},
|
|
658
|
+
/**
|
|
659
|
+
* Collection -> Mode -> Rename
|
|
660
|
+
* @TODO: ensure new Mode ID does not already exist
|
|
661
|
+
*/
|
|
662
|
+
rename: ({ collectionId, modeId, newModeId, }) => {
|
|
663
|
+
// Why use produce here instead of just calling rename() on a loop?
|
|
664
|
+
// If we can run multiple operations in a single Immer produce(), it prevents
|
|
665
|
+
// thrashing the this.src object and thus unnecessary updates.
|
|
666
|
+
this.#src = produce(this.src, (draft) => {
|
|
667
|
+
// Why not just use the processed this.data which is easier to look up on?
|
|
668
|
+
// The answer is that the returned object we get here will need to be
|
|
669
|
+
// modified within this Immer produce() anyway, so we might as well just
|
|
670
|
+
// use the this.src directly.
|
|
671
|
+
const originalColData = loGet(draft, [
|
|
672
|
+
this.collectionsParentKey,
|
|
673
|
+
collectionId,
|
|
674
|
+
'$extensions',
|
|
675
|
+
'cloud.knapsack',
|
|
676
|
+
]);
|
|
677
|
+
const colInfo = originalColData?.group?.collectionInfo;
|
|
678
|
+
if (!colInfo || colInfo.type !== 'collection')
|
|
679
|
+
throw new Error('Not a Collection');
|
|
680
|
+
const { modes = [] } = colInfo;
|
|
681
|
+
const originalMode = modes?.find((m) => m.id === modeId);
|
|
682
|
+
if (!originalMode)
|
|
683
|
+
throw new Error('Mode not found');
|
|
684
|
+
// Find every single token with the mode name and change its modes. Use
|
|
685
|
+
// this.data for much easier looping here.
|
|
686
|
+
this.data.collectionsById[collectionId].vars.forEach((varObj) => {
|
|
687
|
+
if (!varObj.modesById[modeId])
|
|
688
|
+
return;
|
|
689
|
+
// Get original mode data
|
|
690
|
+
const original = loGet(draft, `${varObj.groupId}.${originalMode.id}`);
|
|
691
|
+
// If values for mode in var not found, don't do anything
|
|
692
|
+
if (!original) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
// Set new Mode key and value
|
|
696
|
+
loSetWith(draft, ensureTokenPath(`${varObj.groupId}.${newModeId}`), original, Object);
|
|
697
|
+
// Now nuke the old Mode within the Var group
|
|
698
|
+
loUnset(draft, `${varObj.groupId}.${originalMode.id}`); // remove old mode
|
|
699
|
+
});
|
|
700
|
+
// Finally update the name of mode within the collection group modes array
|
|
701
|
+
originalMode.id = newModeId;
|
|
702
|
+
});
|
|
703
|
+
},
|
|
704
|
+
/**
|
|
705
|
+
* Collection -> Mode -> Delete
|
|
706
|
+
*/
|
|
707
|
+
delete: ({ collectionId, modeId, }) => {
|
|
708
|
+
this.#src = produce(this.src, (draft) => {
|
|
709
|
+
const originalColData = loGet(draft, [
|
|
710
|
+
this.collectionsParentKey,
|
|
711
|
+
collectionId,
|
|
712
|
+
'$extensions',
|
|
713
|
+
'cloud.knapsack',
|
|
714
|
+
]);
|
|
715
|
+
const colInfo = originalColData?.group?.collectionInfo;
|
|
716
|
+
if (!colInfo || colInfo.type !== 'collection')
|
|
717
|
+
throw new Error('Not a Collection');
|
|
718
|
+
const { modes = [] } = colInfo;
|
|
719
|
+
const originalMode = modes?.find((m) => m.id === modeId);
|
|
720
|
+
if (!originalMode)
|
|
721
|
+
throw new Error('Mode not found');
|
|
722
|
+
// Find every single token with the mode name and change its modes. Use
|
|
723
|
+
// this.data for much easier looping here.
|
|
724
|
+
this.data.collectionsById[collectionId].vars.forEach((varObj) => {
|
|
725
|
+
if (!varObj.modesById[modeId])
|
|
726
|
+
return;
|
|
727
|
+
// Nuke the old Mode within the Var group
|
|
728
|
+
loUnset(draft, `${varObj.groupId}.${originalMode.id}`); // remove old mode
|
|
729
|
+
});
|
|
730
|
+
// Finally update the name of mode within the collection group modes array
|
|
731
|
+
loRemove(modes, (mode) => mode.id === modeId);
|
|
732
|
+
});
|
|
733
|
+
},
|
|
734
|
+
reorder: ({ collectionId, modeId, index, }) => {
|
|
735
|
+
this.#src = produce(this.src, (draft) => {
|
|
736
|
+
const originalColData = loGet(draft, [
|
|
737
|
+
this.collectionsParentKey,
|
|
738
|
+
collectionId,
|
|
739
|
+
'$extensions',
|
|
740
|
+
'cloud.knapsack',
|
|
741
|
+
]);
|
|
742
|
+
const colInfo = originalColData?.group?.collectionInfo;
|
|
743
|
+
if (!colInfo || colInfo.type !== 'collection')
|
|
744
|
+
throw new Error('Not a Collection');
|
|
745
|
+
const { modes = [] } = colInfo;
|
|
746
|
+
const originalMode = modes?.find((m) => m.id === modeId);
|
|
747
|
+
if (!originalMode)
|
|
748
|
+
throw new Error('Mode not found');
|
|
749
|
+
const fromIndex = modes.findIndex((m) => m.id === modeId);
|
|
750
|
+
const [theModeToMove] = modes.splice(fromIndex, 1);
|
|
751
|
+
modes.splice(index, 0, theModeToMove);
|
|
752
|
+
});
|
|
753
|
+
},
|
|
754
|
+
};
|
|
755
|
+
/**
|
|
756
|
+
* Collection -> Collection Group operations
|
|
757
|
+
*/
|
|
758
|
+
collectionGroup = {
|
|
759
|
+
/**
|
|
760
|
+
* Collection -> Collection Group -> Create
|
|
761
|
+
*/
|
|
762
|
+
create: ({ collectionId, groupId, parentGroupId, }) => {
|
|
763
|
+
if (parentGroupId) {
|
|
764
|
+
this.#assertIdDoesNotHavePrefixes({ id: parentGroupId, collectionId });
|
|
765
|
+
}
|
|
766
|
+
if (this.data.collectionsById[collectionId].groupIds.indexOf(groupId) !== -1) {
|
|
767
|
+
throw new Error(`Group ${groupId} already exists in ${collectionId}.`);
|
|
768
|
+
}
|
|
769
|
+
this.createGroup({
|
|
770
|
+
groupId,
|
|
771
|
+
});
|
|
772
|
+
return {
|
|
773
|
+
groupId,
|
|
774
|
+
};
|
|
775
|
+
},
|
|
776
|
+
/**
|
|
777
|
+
* Collection -> Collection Group -> Rename
|
|
778
|
+
*/
|
|
779
|
+
rename: ({ collectionId, collectionGroupId, name, }) => {
|
|
780
|
+
assertDotlessId(name);
|
|
781
|
+
this.#assertIdDoesNotHavePrefixes({
|
|
782
|
+
id: collectionGroupId,
|
|
783
|
+
collectionId,
|
|
784
|
+
});
|
|
785
|
+
const originalGroupId = `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`;
|
|
786
|
+
const destinationGroupId = originalGroupId
|
|
787
|
+
.split('.')
|
|
788
|
+
// replace the last segment of the ID with the new name
|
|
789
|
+
.map((chunk, i, arr) => (i === arr.length - 1 ? name : chunk))
|
|
790
|
+
.join('.');
|
|
791
|
+
this.renameGroup({
|
|
792
|
+
originalGroupId,
|
|
793
|
+
destinationGroupId,
|
|
794
|
+
});
|
|
795
|
+
},
|
|
796
|
+
/**
|
|
797
|
+
* Collection -> Collection Group -> Delete
|
|
798
|
+
*/
|
|
799
|
+
delete: ({ collectionId, collectionGroupId, }) => {
|
|
800
|
+
this.#assertIdDoesNotHavePrefixes({
|
|
801
|
+
id: collectionGroupId,
|
|
802
|
+
collectionId,
|
|
803
|
+
});
|
|
804
|
+
this.deleteGroup({
|
|
805
|
+
groupId: `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`,
|
|
806
|
+
});
|
|
807
|
+
},
|
|
808
|
+
/**
|
|
809
|
+
* Collection -> Collection Group -> Move
|
|
810
|
+
*/
|
|
811
|
+
move: ({ collectionId, collectionGroupId, newParentCollectionId, newParentCollectionGroupId, }) => {
|
|
812
|
+
this.#assertIdDoesNotHavePrefixes({
|
|
813
|
+
id: collectionGroupId,
|
|
814
|
+
collectionId,
|
|
815
|
+
});
|
|
816
|
+
this.#assertIdDoesNotHavePrefixes({
|
|
817
|
+
id: newParentCollectionGroupId,
|
|
818
|
+
collectionId,
|
|
819
|
+
});
|
|
820
|
+
const originalGroupId = `${this.collectionsParentKey}.${collectionId}.${collectionGroupId}`;
|
|
821
|
+
const finalSegment = originalGroupId.split('.').at(-1);
|
|
822
|
+
if (!finalSegment)
|
|
823
|
+
throw new Error('Cannot extract final segment.');
|
|
824
|
+
const destinationCollectionId = newParentCollectionId ?? collectionId;
|
|
825
|
+
// Empty string newParentCollectionGroupId means move to root of collection
|
|
826
|
+
const destinationCollectionGroupId = newParentCollectionGroupId === ''
|
|
827
|
+
? ''
|
|
828
|
+
: `.${newParentCollectionGroupId}`;
|
|
829
|
+
const destinationGroupId = `${this.collectionsParentKey}.${destinationCollectionId}${destinationCollectionGroupId}.${finalSegment}`;
|
|
830
|
+
this.renameGroup({
|
|
831
|
+
originalGroupId,
|
|
832
|
+
destinationGroupId,
|
|
833
|
+
});
|
|
834
|
+
},
|
|
835
|
+
/**
|
|
836
|
+
* CONVERT vanilla group to collection group
|
|
837
|
+
*/
|
|
838
|
+
convert: ({ currentGroupId, collectionId, newParentCollectionGroupId, }) => {
|
|
839
|
+
// Get the vanilla group data
|
|
840
|
+
const vanillaGroup = this.data.groupsById[currentGroupId];
|
|
841
|
+
// Create var with default value for each mode
|
|
842
|
+
try {
|
|
843
|
+
// Quick validation that mode we'll be adding later exists
|
|
844
|
+
const modeId = this.data.collectionsById[collectionId].modes[0].id;
|
|
845
|
+
if (!modeId)
|
|
846
|
+
throw new Error('Collection must have at least one mode');
|
|
847
|
+
// Make first collection group
|
|
848
|
+
this.collectionGroup.create({
|
|
849
|
+
collectionId,
|
|
850
|
+
groupId: `collections.${collectionId}.${newParentCollectionGroupId}.${vanillaGroup.id}`,
|
|
851
|
+
});
|
|
852
|
+
// Recursively dive through token group. NOTE: Only a function definition,
|
|
853
|
+
// actually called below.
|
|
854
|
+
const dive = (group) => {
|
|
855
|
+
// Now loop all children, creating var for each
|
|
856
|
+
group.children.tokenIds.forEach((tokenId) => {
|
|
857
|
+
this.var.create({
|
|
858
|
+
collectionId,
|
|
859
|
+
groupId: newParentCollectionGroupId,
|
|
860
|
+
varId: tokenId,
|
|
861
|
+
varType: this.data.tokensById[tokenId].type,
|
|
862
|
+
});
|
|
863
|
+
const tokenData = this.data.tokensById[tokenId];
|
|
864
|
+
const tokenSrcValueInfo = getTokenSrcInfo(tokenData);
|
|
865
|
+
// Set the default value for the var for *first* mode
|
|
866
|
+
this.var.setModeValue({
|
|
867
|
+
collectionId,
|
|
868
|
+
varId: `${newParentCollectionGroupId}.${tokenId}`,
|
|
869
|
+
modeId,
|
|
870
|
+
tokenSrcValueInfo,
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
// Yay recursion!
|
|
874
|
+
group.children.groupIds.forEach((subGroupId) => {
|
|
875
|
+
this.collectionGroup.create({
|
|
876
|
+
collectionId,
|
|
877
|
+
groupId: `collections.${collectionId}.${newParentCollectionGroupId}.${subGroupId}`,
|
|
878
|
+
});
|
|
879
|
+
dive(this.data.groupsById[subGroupId]);
|
|
880
|
+
});
|
|
881
|
+
};
|
|
882
|
+
// Kick off the call to the above
|
|
883
|
+
dive(vanillaGroup);
|
|
884
|
+
// Nuke the original vanilla group
|
|
885
|
+
this.deleteGroup({
|
|
886
|
+
groupId: currentGroupId,
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
catch (e) {
|
|
890
|
+
if (e instanceof Error) {
|
|
891
|
+
// @TODO: roll back any changes from the try above
|
|
892
|
+
throw new Error(`Error converting vanilla group to collection group: ${e.message}`);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
},
|
|
896
|
+
};
|
|
897
|
+
/**
|
|
898
|
+
* Var operations
|
|
899
|
+
*/
|
|
900
|
+
var = {
|
|
901
|
+
/**
|
|
902
|
+
* Var -> Create
|
|
903
|
+
*/
|
|
904
|
+
create: ({ collectionId, groupId, varId, varType, }) => {
|
|
905
|
+
this.#assertIdDoesNotHavePrefixes({
|
|
906
|
+
id: groupId,
|
|
907
|
+
collectionId,
|
|
908
|
+
});
|
|
909
|
+
const newVarId = groupId ? `${groupId}.${varId}` : varId;
|
|
910
|
+
const fullGroupId = `${this.collectionsParentKey}.${collectionId}.${newVarId}`;
|
|
911
|
+
// This is pretty fast
|
|
912
|
+
const existingVar = loGet(this.src, fullGroupId);
|
|
913
|
+
if (existingVar) {
|
|
914
|
+
console.log(`Var ${newVarId} already exists in ${collectionId}. Skipping.`);
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
this.createGroup({
|
|
918
|
+
groupId: fullGroupId,
|
|
919
|
+
groupData: {
|
|
920
|
+
type: varType,
|
|
921
|
+
config: {
|
|
922
|
+
collectionInfo: {
|
|
923
|
+
type: 'var',
|
|
924
|
+
},
|
|
925
|
+
},
|
|
926
|
+
},
|
|
927
|
+
});
|
|
928
|
+
},
|
|
929
|
+
/**
|
|
930
|
+
* Var -> Rename
|
|
931
|
+
*/
|
|
932
|
+
rename: ({ collectionId, varId, newVarId, }) => {
|
|
933
|
+
this.renameGroup({
|
|
934
|
+
originalGroupId: `${this.collectionsParentKey}.${collectionId}.${varId}`,
|
|
935
|
+
destinationGroupId: `${this.collectionsParentKey}.${collectionId}.${newVarId}`,
|
|
936
|
+
});
|
|
937
|
+
},
|
|
938
|
+
/**
|
|
939
|
+
* Var -> Delete
|
|
940
|
+
*/
|
|
941
|
+
delete: ({ collectionId, varId, }) => {
|
|
942
|
+
this.deleteGroup({
|
|
943
|
+
groupId: `${this.collectionsParentKey}.${collectionId}.${varId}`,
|
|
944
|
+
});
|
|
945
|
+
},
|
|
946
|
+
/**
|
|
947
|
+
* Var -> Move/Rename (moving groups is the same as renaming)
|
|
948
|
+
* @TODO: needs work around existing Var groups
|
|
949
|
+
*/
|
|
950
|
+
move: ({ collectionId, varId, newParentGroupId, }) => {
|
|
951
|
+
const varGroupPath = `${this.collectionsParentKey}.${collectionId}.${varId}`;
|
|
952
|
+
const lastPart = varGroupPath.split('.').at(-1);
|
|
953
|
+
const destinationGroupId = `${this.collectionsParentKey}.${collectionId}.${newParentGroupId}.${lastPart}`;
|
|
954
|
+
this.renameGroup({
|
|
955
|
+
originalGroupId: varGroupPath,
|
|
956
|
+
destinationGroupId,
|
|
957
|
+
});
|
|
958
|
+
},
|
|
959
|
+
/**
|
|
960
|
+
* Var -> setDescription
|
|
961
|
+
*/
|
|
962
|
+
setDescription: ({ collectionId, varId, description, }) => {
|
|
963
|
+
const groupId = `${this.collectionsParentKey}.${collectionId}.${varId}`;
|
|
964
|
+
this.updateGroup({
|
|
965
|
+
groupId,
|
|
966
|
+
groupData: {
|
|
967
|
+
description,
|
|
968
|
+
},
|
|
969
|
+
});
|
|
970
|
+
},
|
|
971
|
+
/**
|
|
972
|
+
* Var -> setModeValue
|
|
973
|
+
*/
|
|
974
|
+
/**
|
|
975
|
+
* Set one or many var mode values
|
|
976
|
+
*/
|
|
977
|
+
setModeValue: (modeVals) => {
|
|
978
|
+
// Do everything inside a single Immer produce for batch efficiency
|
|
979
|
+
this.#src = produce(this.src, (draft) => {
|
|
980
|
+
// Force the incoming args to be an array so we can handle one or many
|
|
981
|
+
castArray(modeVals).forEach((val) => {
|
|
982
|
+
const { collectionId, varId, modeId, tokenSrcValueInfo, skipRefExistsCheck, } = val;
|
|
983
|
+
const { vars } = this.data.collectionsById[collectionId];
|
|
984
|
+
const varValue = vars.find((v) => v.id === varId);
|
|
985
|
+
if (!varValue) {
|
|
986
|
+
throw new Error(`Var ${varId} does not exist in collection ${collectionId}`);
|
|
987
|
+
}
|
|
988
|
+
const tokenId = `${this.collectionsParentKey}.${collectionId}.${varId}.${modeId}`;
|
|
989
|
+
// Handle the different kinds of tokenSrcValueInfo: var refs and static
|
|
990
|
+
switch (tokenSrcValueInfo.kind) {
|
|
991
|
+
case 'ref': {
|
|
992
|
+
const { isVarRef, referencedTokenId } = tokenSrcValueInfo;
|
|
993
|
+
// Note that there are TWO kinds of "refs": referencing another var
|
|
994
|
+
// (and all its modes therein) and just referencing a vanilla token.
|
|
995
|
+
if (isVarRef) {
|
|
996
|
+
if (!skipRefExistsCheck) {
|
|
997
|
+
const ref = this.data.groupsById[referencedTokenId];
|
|
998
|
+
if (!ref) {
|
|
999
|
+
throw new Error(`No ref exists for "${referencedTokenId}"`);
|
|
1000
|
+
}
|
|
1001
|
+
if (ref.groupConfig?.collectionInfo?.type !== 'var') {
|
|
1002
|
+
throw new Error(`Referenced token "${referencedTokenId}" is not a var`);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
// This is the fancypants ref to a whole collections var
|
|
1006
|
+
const tokenSrc = {
|
|
1007
|
+
$extensions: {
|
|
1008
|
+
'cloud.knapsack': {
|
|
1009
|
+
group: {
|
|
1010
|
+
collectionInfo: {
|
|
1011
|
+
type: 'var-ref',
|
|
1012
|
+
referencedId: referencedTokenId,
|
|
1013
|
+
},
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
},
|
|
1017
|
+
};
|
|
1018
|
+
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
1019
|
+
// @ts-expect-error - force removing key that should not exist
|
|
1020
|
+
delete newTokenSrc.$value;
|
|
1021
|
+
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
1022
|
+
break;
|
|
1023
|
+
}
|
|
1024
|
+
// Cannot call another produce function within a produce
|
|
1025
|
+
// this.updateToken({
|
|
1026
|
+
// tokenId,
|
|
1027
|
+
// tokenSrcValueInfo,
|
|
1028
|
+
// });
|
|
1029
|
+
// @TODO: find a way to call this.updateToken() instead of repeating below
|
|
1030
|
+
// This is the vanilla token ref
|
|
1031
|
+
const tokenSrc = makeTokenSrc({
|
|
1032
|
+
tokenId,
|
|
1033
|
+
tokenSrcValueInfo,
|
|
1034
|
+
});
|
|
1035
|
+
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
1036
|
+
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
case 'static': {
|
|
1040
|
+
// Cannot call another function that uses produce
|
|
1041
|
+
// this.updateToken({
|
|
1042
|
+
// tokenId,
|
|
1043
|
+
// tokenSrcValueInfo,
|
|
1044
|
+
// });
|
|
1045
|
+
// @TODO: find a way to call this.updateToken() instead of repeating below
|
|
1046
|
+
const tokenSrc = makeTokenSrc({
|
|
1047
|
+
tokenId,
|
|
1048
|
+
tokenSrcValueInfo,
|
|
1049
|
+
});
|
|
1050
|
+
const newTokenSrc = loMerge(loGet(draft, tokenId, {}), tokenSrc);
|
|
1051
|
+
loSetWith(draft, ensureTokenPath(tokenId), newTokenSrc, Object);
|
|
1052
|
+
break;
|
|
1053
|
+
}
|
|
1054
|
+
default: {
|
|
1055
|
+
const _exhaustiveCheck = tokenSrcValueInfo;
|
|
1056
|
+
throw new Error(`Unhandled kind: ${JSON.stringify(tokenSrcValueInfo)}`);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
// Token Mode Values should not have $type since the $type of the Mode is
|
|
1060
|
+
// set within the Var object above. This just guarantees $type is not set.
|
|
1061
|
+
loUnset(draft, `${tokenId}.$type`);
|
|
1062
|
+
});
|
|
1063
|
+
});
|
|
1064
|
+
},
|
|
1065
|
+
/**
|
|
1066
|
+
* Var -> unsetModeValue
|
|
1067
|
+
*/
|
|
1068
|
+
unsetModeValue: ({ collectionId, varId, modeId, }) => {
|
|
1069
|
+
const tokenId = `${this.collectionsParentKey}.${collectionId}.${varId}.${modeId}`;
|
|
1070
|
+
this.deleteToken({ tokenId });
|
|
1071
|
+
},
|
|
1072
|
+
};
|
|
1080
1073
|
}
|
|
1081
|
-
_TokenSrcUpdater__src = new WeakMap(), _TokenSrcUpdater_prefix = new WeakMap(), _TokenSrcUpdater_dataIsStale = new WeakMap(), _TokenSrcUpdater__data = new WeakMap(), _TokenSrcUpdater_assertIdDoesNotHavePrefixes = new WeakMap(), _TokenSrcUpdater_instances = new WeakSet(), _TokenSrcUpdater_src_set = function _TokenSrcUpdater_src_set(newSrc) {
|
|
1082
|
-
var _a, _b, _c;
|
|
1083
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater__src, newSrc, "f");
|
|
1084
|
-
__classPrivateFieldSet(this, _TokenSrcUpdater_dataIsStale, true, "f");
|
|
1085
|
-
this.collectionsParentKey =
|
|
1086
|
-
((_c = (_b = (_a = newSrc === null || newSrc === void 0 ? void 0 : newSrc.$extensions) === null || _a === void 0 ? void 0 : _a['cloud.knapsack']) === null || _b === void 0 ? void 0 : _b.global) === null || _c === void 0 ? void 0 : _c.collectionsParentKey) ||
|
|
1087
|
-
'';
|
|
1088
|
-
};
|
|
1089
1074
|
//# sourceMappingURL=token-src-updater.js.map
|