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

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