@slicemachine/manager 0.24.14-alpha.jp-update-cr-links-unit.10 → 0.24.14-alpha.jp-update-cr-links-remove-recursion.11

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.
@@ -188,6 +188,141 @@ export class CustomTypesManager extends BaseManager {
188
188
  };
189
189
  }
190
190
 
191
+ private updateCRCustomType(
192
+ args: { customType: CrCustomType } & CustomTypeFieldIdChangedMeta,
193
+ ): CrCustomType {
194
+ const [previousCustomTypeId, previousFieldId] = args.previousPath;
195
+ const [newCustomTypeId, newFieldId] = args.newPath;
196
+
197
+ if (!previousCustomTypeId || !newCustomTypeId) {
198
+ throw new Error(
199
+ "Could not find a customtype id in previousPath and/or newPath, which should not be possible.",
200
+ );
201
+ }
202
+
203
+ if (!previousFieldId || !newFieldId) {
204
+ throw new Error(
205
+ "Could not find a field id in previousPath and/or newPath, which should not be possible.",
206
+ );
207
+ }
208
+
209
+ const customType = shallowCloneIfObject(args.customType);
210
+
211
+ if (typeof customType === "string" || !customType.fields) {
212
+ return customType;
213
+ }
214
+
215
+ const matchedCustomTypeId = customType.id === previousCustomTypeId;
216
+
217
+ const newFields = customType.fields.map((fieldArg) => {
218
+ const nestedField = shallowCloneIfObject(fieldArg);
219
+
220
+ if (typeof nestedField === "string") {
221
+ if (
222
+ matchedCustomTypeId &&
223
+ nestedField === previousFieldId &&
224
+ nestedField !== newFieldId
225
+ ) {
226
+ // We have reached a field id that matches the id that was renamed,
227
+ // so we update it new one. The field is a string, so return the new
228
+ // id.
229
+ return newFieldId;
230
+ }
231
+
232
+ return nestedField;
233
+ }
234
+
235
+ if (
236
+ matchedCustomTypeId &&
237
+ nestedField.id === previousFieldId &&
238
+ nestedField.id !== newFieldId
239
+ ) {
240
+ // We have reached a field id that matches the id that was renamed,
241
+ // so we update it new one.
242
+ // Since field is not a string, we don't exit, as we might have
243
+ // something to update further down in customtypes.
244
+ nestedField.id = newFieldId;
245
+ }
246
+
247
+ return {
248
+ ...nestedField,
249
+ customtypes: nestedField.customtypes.map((customTypeArg) => {
250
+ const customTypeField = shallowCloneIfObject(customTypeArg);
251
+
252
+ if (typeof customTypeField === "string" || !customTypeField.fields) {
253
+ return customTypeField;
254
+ }
255
+
256
+ const matchedNestedCustomTypeId =
257
+ customTypeField.id === previousCustomTypeId;
258
+
259
+ return {
260
+ ...customTypeField,
261
+ fields: customTypeField.fields.map((fieldArg) => {
262
+ const nestedCustomTypeField = shallowCloneIfObject(fieldArg);
263
+
264
+ if (
265
+ matchedNestedCustomTypeId &&
266
+ nestedCustomTypeField === previousFieldId &&
267
+ nestedCustomTypeField !== newFieldId
268
+ ) {
269
+ // Matches the previous id, so we update it and return because
270
+ // it's the last level.
271
+ return newFieldId;
272
+ }
273
+
274
+ return nestedCustomTypeField;
275
+ }),
276
+ };
277
+ }),
278
+ };
279
+ });
280
+
281
+ return { ...customType, fields: newFields };
282
+ }
283
+
284
+ /**
285
+ * Map over the custom types of a Content Relationship Link and update the API
286
+ * IDs that were changed during the custom type update.
287
+ */
288
+ private updateCRCustomTypes(
289
+ args: { customTypes: CrCustomTypes } & CustomTypeFieldIdChangedMeta,
290
+ ): CrCustomTypes {
291
+ const { customTypes, ...updateMeta } = args;
292
+
293
+ return customTypes.map((customType) => {
294
+ return this.updateCRCustomType({ customType, ...updateMeta });
295
+ });
296
+ }
297
+
298
+ /**
299
+ * Update the Content Relationship API IDs of a single field. The change is
300
+ * determined by the `previousPath` and `newPath` properties.
301
+ */
302
+ private updateFieldContentRelationships<
303
+ T extends UID | NestableWidget | Group | NestedGroup,
304
+ >(args: { field: T } & CustomTypeFieldIdChangedMeta): T {
305
+ const { field, ...updateMeta } = args;
306
+ if (
307
+ field.type !== "Link" ||
308
+ field.config?.select !== "document" ||
309
+ !field.config?.customtypes
310
+ ) {
311
+ // not a content relationship field
312
+ return field;
313
+ }
314
+
315
+ const newCustomTypes = this.updateCRCustomTypes({
316
+ ...updateMeta,
317
+ customTypes: field.config.customtypes,
318
+ });
319
+
320
+ return {
321
+ ...field,
322
+ config: { ...field.config, customtypes: newCustomTypes },
323
+ };
324
+ }
325
+
191
326
  /**
192
327
  * Update the Content Relationship API IDs for all existing custom types and
193
328
  * slices. The change is determined by properties inside the `updateMeta`
@@ -213,19 +348,24 @@ export class CustomTypesManager extends BaseManager {
213
348
  // any custom type and update them to use the new one.
214
349
  const customTypes = await this.readAllCustomTypes();
215
350
 
216
- updateCustomTypeContentRelationships({
217
- models: customTypes.models,
218
- onUpdate: (model) => {
219
- pushIfDefined(
220
- crUpdates,
221
- this.sliceMachinePluginRunner?.callHook("custom-type:update", {
222
- model,
223
- }),
224
- );
225
- },
226
- previousPath,
227
- newPath,
228
- });
351
+ for (const customType of customTypes.models) {
352
+ const updatedCustomTypeModel = traverseCustomType({
353
+ customType: customType.model,
354
+ onField: ({ field }) => {
355
+ return this.updateFieldContentRelationships({
356
+ field,
357
+ previousPath,
358
+ newPath,
359
+ });
360
+ },
361
+ });
362
+
363
+ crUpdates.push(
364
+ this.sliceMachinePluginRunner.callHook("custom-type:update", {
365
+ model: updatedCustomTypeModel,
366
+ }),
367
+ );
368
+ }
229
369
 
230
370
  // Find existing slice with content relationships that link to the renamed
231
371
  // field id in all libraries and update them to use the new one.
@@ -236,20 +376,26 @@ export class CustomTypesManager extends BaseManager {
236
376
  libraryID: library.libraryID,
237
377
  });
238
378
 
239
- updateSharedSliceContentRelationships({
240
- models: slices.models,
241
- onUpdate: (model) => {
242
- pushIfDefined(
243
- crUpdates,
244
- this.sliceMachinePluginRunner?.callHook("slice:update", {
245
- libraryID: library.libraryID,
246
- model,
247
- }),
248
- );
249
- },
250
- previousPath,
251
- newPath,
252
- });
379
+ for (const slice of slices.models) {
380
+ const updatedSliceModel = traverseSharedSlice({
381
+ path: ["."],
382
+ slice: slice.model,
383
+ onField: ({ field }) => {
384
+ return this.updateFieldContentRelationships({
385
+ field,
386
+ previousPath,
387
+ newPath,
388
+ });
389
+ },
390
+ });
391
+
392
+ crUpdates.push(
393
+ this.sliceMachinePluginRunner.callHook("slice:update", {
394
+ libraryID: library.libraryID,
395
+ model: updatedSliceModel,
396
+ }),
397
+ );
398
+ }
253
399
  }
254
400
 
255
401
  // Process all the Content Relationship updates at once.
@@ -495,196 +641,6 @@ const InferSliceResponse = z.object({
495
641
  langSmithUrl: z.string().url().optional(),
496
642
  });
497
643
 
498
- function updateCRCustomType(
499
- args: { customType: CrCustomType } & CustomTypeFieldIdChangedMeta,
500
- ): CrCustomType {
501
- const { previousPath, newPath } = args;
502
-
503
- const customType = shallowCloneIfObject(args.customType);
504
-
505
- const [previousCustomTypeId, previousFieldId] = previousPath;
506
- const [newCustomTypeId, newFieldId] = newPath;
507
-
508
- if (!previousCustomTypeId || !newCustomTypeId) {
509
- throw new Error(
510
- "Didn't find any customtype id, which should not be possible.",
511
- );
512
- }
513
-
514
- if (!previousFieldId || !newFieldId) {
515
- throw new Error("Didn't find any field id, which should not be possible.");
516
- }
517
-
518
- if (typeof customType === "string") {
519
- return customType; // we don't support custom type id renaming
520
- }
521
-
522
- const matchedCustomTypeId = customType.id === previousCustomTypeId;
523
-
524
- if (customType.fields) {
525
- const newFields = customType.fields.map((fieldArg) => {
526
- const nestedField = shallowCloneIfObject(fieldArg);
527
-
528
- if (typeof nestedField === "string") {
529
- if (
530
- matchedCustomTypeId &&
531
- nestedField === previousFieldId &&
532
- nestedField !== newFieldId
533
- ) {
534
- // We have reached a field id that matches the id that was renamed,
535
- // so we update it new one. The field is a string, so return the new
536
- // id.
537
- return newFieldId;
538
- }
539
-
540
- return nestedField;
541
- }
542
-
543
- if (nestedField.id === previousFieldId) {
544
- if (matchedCustomTypeId && nestedField.id !== newFieldId) {
545
- // We have reached a field id that matches the id that was renamed,
546
- // so we update it new one.
547
- // Since field is not a string, we don't exit, as we might have
548
- // something to update further down in customtypes.
549
- nestedField.id = newFieldId;
550
- }
551
- }
552
-
553
- return {
554
- ...nestedField,
555
- customtypes: nestedField.customtypes.map((customTypeArg) => {
556
- const customTypeField = shallowCloneIfObject(customTypeArg);
557
-
558
- if (typeof customTypeField === "string") {
559
- return customTypeField; // we don't support custom type id renaming
560
- }
561
-
562
- const matchedNestedCustomTypeId =
563
- customTypeField.id === previousCustomTypeId;
564
-
565
- if (customTypeField.fields) {
566
- return {
567
- ...customTypeField,
568
- fields: customTypeField.fields.map((fieldArg) => {
569
- const nestedCustomTypeField = shallowCloneIfObject(fieldArg);
570
-
571
- if (
572
- matchedNestedCustomTypeId &&
573
- nestedCustomTypeField === previousFieldId &&
574
- nestedCustomTypeField !== newFieldId
575
- ) {
576
- // Matches the previous id, so we update it and return because
577
- // it's the last level.
578
- return newFieldId;
579
- }
580
-
581
- return nestedCustomTypeField;
582
- }),
583
- };
584
- }
585
-
586
- return customTypeField;
587
- }),
588
- };
589
- });
590
-
591
- return { ...customType, fields: newFields };
592
- }
593
-
594
- return customType;
595
- }
596
-
597
- /**
598
- * Map over the custom types of a Content Relationship Link and update the API
599
- * IDs that were changed during the custom type update.
600
- */
601
- function updateCRCustomTypes(
602
- args: { customTypes: CrCustomTypes } & CustomTypeFieldIdChangedMeta,
603
- ): CrCustomTypes {
604
- const { customTypes, ...updateMeta } = args;
605
-
606
- return customTypes.map((customType) => {
607
- return updateCRCustomType({ customType, ...updateMeta });
608
- });
609
- }
610
-
611
- /**
612
- * Update the Content Relationship API IDs of a single field. The change is
613
- * determined by the `previousPath` and `newPath` properties.
614
- */
615
- function updateFieldContentRelationships<
616
- T extends UID | NestableWidget | Group | NestedGroup,
617
- >(args: { field: T } & CustomTypeFieldIdChangedMeta): T {
618
- const { field, ...updateMeta } = args;
619
- if (
620
- field.type !== "Link" ||
621
- field.config?.select !== "document" ||
622
- !field.config?.customtypes
623
- ) {
624
- // not a content relationship field
625
- return field;
626
- }
627
-
628
- const newCustomTypes = updateCRCustomTypes({
629
- ...updateMeta,
630
- customTypes: field.config.customtypes,
631
- });
632
-
633
- return {
634
- ...field,
635
- config: { ...field.config, customtypes: newCustomTypes },
636
- };
637
- }
638
-
639
- export function updateCustomTypeContentRelationships(
640
- args: {
641
- models: { model: CustomType }[];
642
- onUpdate: (model: CustomType) => void;
643
- } & CustomTypeFieldIdChangedMeta,
644
- ): void {
645
- const { models, previousPath, newPath, onUpdate } = args;
646
-
647
- for (const customType of models) {
648
- const updatedCustomTypeModel = traverseCustomType({
649
- customType: customType.model,
650
- onField: ({ field }) => {
651
- return updateFieldContentRelationships({
652
- field,
653
- previousPath,
654
- newPath,
655
- });
656
- },
657
- });
658
-
659
- onUpdate(updatedCustomTypeModel);
660
- }
661
- }
662
-
663
- export function updateSharedSliceContentRelationships(
664
- args: {
665
- models: { model: SharedSlice }[];
666
- onUpdate: (model: SharedSlice) => void;
667
- } & CustomTypeFieldIdChangedMeta,
668
- ): void {
669
- const { models, previousPath, newPath, onUpdate } = args;
670
-
671
- for (const slice of models) {
672
- const updatedSliceModel = traverseSharedSlice({
673
- path: ["."],
674
- slice: slice.model,
675
- onField: ({ field }) => {
676
- return updateFieldContentRelationships({
677
- field,
678
- previousPath,
679
- newPath,
680
- });
681
- },
682
- });
683
-
684
- onUpdate(updatedSliceModel);
685
- }
686
- }
687
-
688
644
  function shallowCloneIfObject<T>(value: T): T {
689
645
  if (typeof value === "object") {
690
646
  return { ...value };
@@ -692,9 +648,3 @@ function shallowCloneIfObject<T>(value: T): T {
692
648
 
693
649
  return value;
694
650
  }
695
-
696
- function pushIfDefined<T>(array: T[], value: T | undefined) {
697
- if (value) {
698
- array.push(value);
699
- }
700
- }