@slicemachine/manager 0.24.14-alpha.jp-update-cr-links.2 → 0.24.14-alpha.jp-update-cr-links.4

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.
@@ -81,61 +81,56 @@ class CustomTypesManager extends BaseManager.BaseManager {
81
81
  };
82
82
  }
83
83
  updateCRCustomType(args) {
84
- const { customType: customTypeArg, previousPath, newPath } = args;
85
- let customType = customTypeArg;
86
- if (typeof customTypeArg === "object") {
87
- customType = { ...customTypeArg };
88
- }
84
+ const { previousPath, newPath } = args;
85
+ let changed = false;
86
+ const customType = shallowClone(args.customType);
89
87
  const [previousId] = previousPath;
90
88
  const [newId] = newPath;
91
- if (!previousId || !newId) {
92
- return customType;
93
- }
94
- if (typeof customType === "string") {
95
- if (customType === previousId && customType !== newId) {
96
- return newId;
97
- }
98
- return customType;
99
- }
100
- if (customType.id === previousId && customType.id !== newId) {
101
- customType.id = newId;
89
+ if (!previousId || !newId || typeof customType === "string") {
90
+ return { changed, customType };
102
91
  }
103
92
  if (customType.fields) {
104
- return {
105
- ...customType,
106
- fields: customType.fields.map((field) => {
107
- const previousId2 = previousPath[1];
108
- const newId2 = newPath[1];
109
- if (!previousId2 || !newId2) {
110
- return field;
111
- }
112
- if (typeof field === "string") {
113
- if (field === previousId2 && field !== newId2) {
114
- return newId2;
115
- }
116
- return field;
117
- }
118
- if (field.id === previousId2 && field.id !== newId2) {
119
- field.id = newId2;
93
+ const newFields = customType.fields.map((fieldArg) => {
94
+ const field = shallowClone(fieldArg);
95
+ const previousId2 = previousPath[1];
96
+ const newId2 = newPath[1];
97
+ if (!previousId2 || !newId2) {
98
+ return field;
99
+ }
100
+ if (typeof field === "string") {
101
+ if (field === previousId2 && field !== newId2) {
102
+ changed = true;
103
+ return newId2;
120
104
  }
121
- return {
122
- ...field,
123
- customtypes: field.customtypes.map((customType2) => {
124
- return this.updateCRCustomType({
125
- customType: customType2,
126
- previousPath,
127
- newPath
128
- // TODO: Fix types. The second level customtypes are not typed
129
- // the same as the first level customtypes. Although it won't
130
- // matter at runtime.
131
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- -
132
- });
133
- })
134
- };
135
- })
105
+ return field;
106
+ }
107
+ if (field.id === previousId2 && field.id !== newId2) {
108
+ changed = true;
109
+ field.id = newId2;
110
+ }
111
+ return {
112
+ ...field,
113
+ customtypes: field.customtypes.map((customType2) => {
114
+ const { customType: newCustomType, changed: hasChanged } = this.updateCRCustomType({
115
+ customType: customType2,
116
+ previousPath,
117
+ newPath
118
+ // TODO: Fix types. The second level customtypes are not typed
119
+ // the same as the first level customtypes. Although it won't
120
+ // matter at runtime.
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- -
122
+ });
123
+ changed || (changed = hasChanged);
124
+ return newCustomType;
125
+ })
126
+ };
127
+ });
128
+ return {
129
+ changed,
130
+ customType: { ...customType, fields: newFields }
136
131
  };
137
132
  }
138
- return { ...customType };
133
+ return { changed, customType };
139
134
  }
140
135
  /**
141
136
  * Map over the custom types of a Content Relationship Link and update the API
@@ -143,56 +138,69 @@ class CustomTypesManager extends BaseManager.BaseManager {
143
138
  */
144
139
  updateCRCustomTypes(args) {
145
140
  const { customTypes, ...updateMeta } = args;
146
- return customTypes.map((customType) => {
147
- return this.updateCRCustomType({ customType, ...updateMeta });
141
+ let changed = false;
142
+ const newCustomTypes = customTypes.map((customType) => {
143
+ const { customType: newCustomType, changed: hasChanged } = this.updateCRCustomType({ customType, ...updateMeta });
144
+ changed || (changed = hasChanged);
145
+ return newCustomType;
148
146
  });
147
+ return { customTypes: newCustomTypes, changed };
149
148
  }
150
149
  /**
151
- * Update the Content Relationship API IDs that were changed during the custom
152
- * type update. The change is determined by the `previousPath` and `newPath`
153
- * properties.
150
+ * Update the Content Relationship API IDs of a single field. The change is
151
+ * determined by the `previousPath` and `newPath` properties.
154
152
  */
155
153
  updateFieldContentRelationships(args) {
156
154
  var _a, _b;
157
155
  const { field, ...updateMeta } = args;
158
156
  if (field.type !== "Link" || ((_a = field.config) == null ? void 0 : _a.select) !== "document" || !((_b = field.config) == null ? void 0 : _b.customtypes)) {
159
- return field;
157
+ return { field, changed: false };
160
158
  }
159
+ const { customTypes: newCustomTypes, changed } = this.updateCRCustomTypes({
160
+ ...updateMeta,
161
+ customTypes: field.config.customtypes
162
+ });
161
163
  return {
162
- ...field,
163
- config: {
164
- ...field.config,
165
- customtypes: this.updateCRCustomTypes({
166
- ...updateMeta,
167
- customTypes: field.config.customtypes.slice()
168
- })
169
- }
164
+ field: {
165
+ ...field,
166
+ config: { ...field.config, customtypes: newCustomTypes }
167
+ },
168
+ changed
170
169
  };
171
170
  }
172
- async updateCustomType(args) {
171
+ /**
172
+ * Update the Content Relationship API IDs for all existing custom types and
173
+ * slices. The change is determined by properties inside the `updateMeta`
174
+ * property.
175
+ */
176
+ async updateContentRelationships(args) {
173
177
  assertPluginsInitialized.assertPluginsInitialized(this.sliceMachinePluginRunner);
174
- const hookResult = await this.sliceMachinePluginRunner.callHook("custom-type:update", args);
175
178
  const { model, updateMeta } = args;
176
179
  if (updateMeta == null ? void 0 : updateMeta.fieldIdChanged) {
177
180
  let { previousPath, newPath } = updateMeta.fieldIdChanged;
181
+ const crUpdatesPromises = [];
178
182
  if (previousPath.join(".") !== newPath.join(".")) {
179
183
  previousPath = [model.id, ...previousPath];
180
184
  newPath = [model.id, ...newPath];
181
185
  const customTypes = await this.readAllCustomTypes();
182
186
  for (const customType of customTypes.models) {
187
+ let hasChangedCustomType = false;
183
188
  const updatedCustomTypeModel = customtypes.traverseCustomType({
184
189
  customType: customType.model,
185
190
  onField: ({ field }) => {
186
- return this.updateFieldContentRelationships({
191
+ const { field: updatedField, changed } = this.updateFieldContentRelationships({
187
192
  field,
188
193
  previousPath,
189
194
  newPath
190
195
  });
196
+ hasChangedCustomType || (hasChangedCustomType = changed);
197
+ return updatedField;
191
198
  }
192
199
  });
193
- const hookResult2 = await this.sliceMachinePluginRunner.callHook("custom-type:update", { model: updatedCustomTypeModel });
194
- if (hookResult2.errors.length > 0) {
195
- return { errors: hookResult2.errors };
200
+ if (hasChangedCustomType) {
201
+ crUpdatesPromises.push(this.sliceMachinePluginRunner.callHook("custom-type:update", {
202
+ model: updatedCustomTypeModel
203
+ }));
196
204
  }
197
205
  }
198
206
  const { libraries } = await this.slices.readAllSliceLibraries();
@@ -201,25 +209,45 @@ class CustomTypesManager extends BaseManager.BaseManager {
201
209
  libraryID: library.libraryID
202
210
  });
203
211
  for (const slice of slices.models) {
212
+ let hasChangedSlice = false;
204
213
  const updatedSliceModel = customtypes.traverseSharedSlice({
205
214
  path: ["."],
206
215
  slice: slice.model,
207
216
  onField: ({ field }) => {
208
- return this.updateFieldContentRelationships({
217
+ const { field: updatedField, changed } = this.updateFieldContentRelationships({
209
218
  field,
210
219
  previousPath,
211
220
  newPath
212
221
  });
222
+ hasChangedSlice || (hasChangedSlice = changed);
223
+ return updatedField;
213
224
  }
214
225
  });
215
- const hookResult2 = await this.sliceMachinePluginRunner.callHook("slice:update", { libraryID: library.libraryID, model: updatedSliceModel });
216
- if (hookResult2.errors.length > 0) {
217
- return { errors: hookResult2.errors };
226
+ if (hasChangedSlice) {
227
+ crUpdatesPromises.push(this.sliceMachinePluginRunner.callHook("slice:update", {
228
+ libraryID: library.libraryID,
229
+ model: updatedSliceModel
230
+ }));
218
231
  }
219
232
  }
220
233
  }
234
+ const crUpdatesResults = await Promise.all(crUpdatesPromises);
235
+ if (crUpdatesResults.some((result) => result.errors.length > 0)) {
236
+ return {
237
+ errors: crUpdatesResults.flatMap((result) => result.errors)
238
+ };
239
+ }
221
240
  }
222
241
  }
242
+ return { errors: [] };
243
+ }
244
+ async updateCustomType(args) {
245
+ var _a;
246
+ assertPluginsInitialized.assertPluginsInitialized(this.sliceMachinePluginRunner);
247
+ const hookResult = await this.sliceMachinePluginRunner.callHook("custom-type:update", args);
248
+ if ((_a = args.updateMeta) == null ? void 0 : _a.fieldIdChanged) {
249
+ await this.updateContentRelationships(args);
250
+ }
223
251
  return { errors: hookResult.errors };
224
252
  }
225
253
  async renameCustomType(args) {
@@ -366,5 +394,11 @@ const InferSliceResponse = index.default.object({
366
394
  }),
367
395
  langSmithUrl: index.default.string().url().optional()
368
396
  });
397
+ function shallowClone(value) {
398
+ if (typeof value === "object") {
399
+ return { ...value };
400
+ }
401
+ return value;
402
+ }
369
403
  exports.CustomTypesManager = CustomTypesManager;
370
404
  //# sourceMappingURL=CustomTypesManager.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"CustomTypesManager.cjs","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLink,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypeUpdateMeta = {\n\tpreviousPath: string[];\n\tnewPath: string[];\n};\ntype CRCustomTypes = NonNullable<NonNullable<Link[\"config\"]>[\"customtypes\"]>;\ntype CRCustomType = NonNullable<CRCustomTypes>[number];\n\nexport class CustomTypesManager extends BaseManager {\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tprivate updateCRCustomType(\n\t\targs: { customType: CRCustomType } & CustomTypeUpdateMeta,\n\t): CRCustomType {\n\t\tconst { customType: customTypeArg, previousPath, newPath } = args;\n\n\t\tlet customType = customTypeArg;\n\t\tif (typeof customTypeArg === \"object\") {\n\t\t\tcustomType = { ...customTypeArg };\n\t\t}\n\n\t\tconst [previousId] = previousPath;\n\t\tconst [newId] = newPath;\n\n\t\tif (!previousId || !newId) {\n\t\t\treturn customType;\n\t\t}\n\n\t\tif (typeof customType === \"string\") {\n\t\t\tif (customType === previousId && customType !== newId) {\n\t\t\t\treturn newId; // update to new api id\n\t\t\t}\n\n\t\t\treturn customType;\n\t\t}\n\n\t\tif (customType.id === previousId && customType.id !== newId) {\n\t\t\tcustomType.id = newId; // update to new api id\n\t\t}\n\n\t\tif (customType.fields) {\n\t\t\treturn {\n\t\t\t\t...customType,\n\t\t\t\tfields: customType.fields.map((field) => {\n\t\t\t\t\tconst previousId = previousPath[1];\n\t\t\t\t\tconst newId = newPath[1];\n\n\t\t\t\t\tif (!previousId || !newId) {\n\t\t\t\t\t\treturn field;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typeof field === \"string\") {\n\t\t\t\t\t\tif (field === previousId && field !== newId) {\n\t\t\t\t\t\t\treturn newId; // update to new api id\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn field;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (field.id === previousId && field.id !== newId) {\n\t\t\t\t\t\tfield.id = newId; // update to new api id\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...field,\n\t\t\t\t\t\tcustomtypes: field.customtypes.map((customType) => {\n\t\t\t\t\t\t\treturn this.updateCRCustomType({\n\t\t\t\t\t\t\t\tcustomType,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t// TODO: Fix types. The second level customtypes are not typed\n\t\t\t\t\t\t\t\t// the same as the first level customtypes. Although it won't\n\t\t\t\t\t\t\t\t// matter at runtime.\n\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- -\n\t\t\t\t\t\t\t}) as any;\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\treturn { ...customType };\n\t}\n\n\t/**\n\t * Map over the custom types of a Content Relationship Link and update the API\n\t * IDs that were changed during the custom type update.\n\t */\n\tprivate updateCRCustomTypes(\n\t\targs: { customTypes: CRCustomTypes } & CustomTypeUpdateMeta,\n\t): CRCustomTypes {\n\t\tconst { customTypes, ...updateMeta } = args;\n\n\t\treturn customTypes.map((customType) => {\n\t\t\treturn this.updateCRCustomType({ customType, ...updateMeta });\n\t\t});\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs that were changed during the custom\n\t * type update. The change is determined by the `previousPath` and `newPath`\n\t * properties.\n\t */\n\tprivate updateFieldContentRelationships<\n\t\tT extends UID | NestableWidget | Group | NestedGroup,\n\t>(args: { field: T } & CustomTypeUpdateMeta): T {\n\t\tconst { field, ...updateMeta } = args;\n\t\tif (\n\t\t\tfield.type !== \"Link\" ||\n\t\t\tfield.config?.select !== \"document\" ||\n\t\t\t!field.config?.customtypes\n\t\t) {\n\t\t\treturn field; // not a content relationship field\n\t\t}\n\n\t\treturn {\n\t\t\t...field,\n\t\t\tconfig: {\n\t\t\t\t...field.config,\n\t\t\t\tcustomtypes: this.updateCRCustomTypes({\n\t\t\t\t\t...updateMeta,\n\t\t\t\t\tcustomTypes: field.config.customtypes.slice(),\n\t\t\t\t}),\n\t\t\t},\n\t\t};\n\t}\n\n\tasync updateCustomType(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\targs,\n\t\t);\n\n\t\tconst { model, updateMeta } = args;\n\n\t\tif (updateMeta?.fieldIdChanged) {\n\t\t\tlet { previousPath, newPath } = updateMeta.fieldIdChanged;\n\n\t\t\tif (previousPath.join(\".\") !== newPath.join(\".\")) {\n\t\t\t\tpreviousPath = [model.id, ...previousPath];\n\t\t\t\tnewPath = [model.id, ...newPath];\n\n\t\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t\t// any custom type and update them to use the new one.\n\t\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\t\tfor (const customType of customTypes.models) {\n\t\t\t\t\tconst updatedCustomTypeModel = traverseCustomType({\n\t\t\t\t\t\tcustomType: customType.model,\n\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\treturn this.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\t\t\"custom-type:update\",\n\t\t\t\t\t\t{ model: updatedCustomTypeModel },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (hookResult.errors.length > 0) {\n\t\t\t\t\t\treturn { errors: hookResult.errors };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\t\tfor (const library of libraries) {\n\t\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (const slice of slices.models) {\n\t\t\t\t\t\tconst updatedSliceModel = traverseSharedSlice({\n\t\t\t\t\t\t\tpath: [\".\"],\n\t\t\t\t\t\t\tslice: slice.model,\n\t\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\t\treturn this.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\t\t\t\"slice:update\",\n\t\t\t\t\t\t\t{ libraryID: library.libraryID, model: updatedSliceModel },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (hookResult.errors.length > 0) {\n\t\t\t\t\t\t\treturn { errors: hookResult.errors };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: hookResult.errors };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice({\n\t\timageUrl,\n\t}: {\n\t\timageUrl: string;\n\t}): Promise<InferSliceResponse> {\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst headers = {\n\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t};\n\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\t\tconst searchParams = new URLSearchParams({\n\t\t\trepository,\n\t\t});\n\n\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\turl.search = searchParams.toString();\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\n\t\treturn InferSliceResponse.parse(json);\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n"],"names":["BaseManager","assertPluginsInitialized","errors","decodeHookResult","t","CustomType","previousId","newId","customType","traverseCustomType","hookResult","traverseSharedSlice","prismicCustomTypesClient","API_ENDPOINTS","fetch","SLICE_MACHINE_USER_AGENT","UnauthorizedError","z","SharedSlice"],"mappings":"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"}
1
+ {"version":3,"file":"CustomTypesManager.cjs","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLink,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CRCustomTypes = NonNullable<NonNullable<Link[\"config\"]>[\"customtypes\"]>;\ntype CRCustomType = NonNullable<CRCustomTypes>[number];\ntype CustomTypeFieldIdChangedMeta = NonNullable<\n\tNonNullable<CustomTypeUpdateHookData[\"updateMeta\"]>[\"fieldIdChanged\"]\n>;\n\nexport class CustomTypesManager extends BaseManager {\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tprivate updateCRCustomType(\n\t\targs: { customType: CRCustomType } & CustomTypeFieldIdChangedMeta,\n\t): { customType: CRCustomType; changed: boolean } {\n\t\tconst { previousPath, newPath } = args;\n\n\t\tlet changed = false;\n\t\tconst customType = shallowClone(args.customType);\n\n\t\tconst [previousId] = previousPath;\n\t\tconst [newId] = newPath;\n\n\t\tif (!previousId || !newId || typeof customType === \"string\") {\n\t\t\treturn { changed, customType };\n\t\t}\n\n\t\tif (customType.fields) {\n\t\t\tconst newFields = customType.fields.map((fieldArg) => {\n\t\t\t\tconst field = shallowClone(fieldArg);\n\n\t\t\t\tconst previousId = previousPath[1];\n\t\t\t\tconst newId = newPath[1];\n\n\t\t\t\tif (!previousId || !newId) {\n\t\t\t\t\treturn field;\n\t\t\t\t}\n\n\t\t\t\tif (typeof field === \"string\") {\n\t\t\t\t\tif (field === previousId && field !== newId) {\n\t\t\t\t\t\t// We have reached a field id that matches the id that was renamed,\n\t\t\t\t\t\t// so we update it new one. The field is a string, so return the new\n\t\t\t\t\t\t// id.\n\t\t\t\t\t\tchanged = true;\n\n\t\t\t\t\t\treturn newId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn field;\n\t\t\t\t}\n\n\t\t\t\tif (field.id === previousId && field.id !== newId) {\n\t\t\t\t\t// We have reached a field id that matches the id that was renamed,\n\t\t\t\t\t// so we update it new one.\n\t\t\t\t\t// Since field is not a string, we don't exit, as we might have\n\t\t\t\t\t// something to update further down in customtypes.\n\t\t\t\t\tchanged = true;\n\n\t\t\t\t\tfield.id = newId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...field,\n\t\t\t\t\tcustomtypes: field.customtypes.map((customType) => {\n\t\t\t\t\t\tconst { customType: newCustomType, changed: hasChanged } =\n\t\t\t\t\t\t\tthis.updateCRCustomType({\n\t\t\t\t\t\t\t\tcustomType,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t// TODO: Fix types. The second level customtypes are not typed\n\t\t\t\t\t\t\t\t// the same as the first level customtypes. Although it won't\n\t\t\t\t\t\t\t\t// matter at runtime.\n\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- -\n\t\t\t\t\t\t\t}) as any;\n\n\t\t\t\t\t\tchanged ||= hasChanged;\n\n\t\t\t\t\t\treturn newCustomType;\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tchanged,\n\t\t\t\tcustomType: { ...customType, fields: newFields },\n\t\t\t};\n\t\t}\n\n\t\treturn { changed, customType };\n\t}\n\n\t/**\n\t * Map over the custom types of a Content Relationship Link and update the API\n\t * IDs that were changed during the custom type update.\n\t */\n\tprivate updateCRCustomTypes(\n\t\targs: { customTypes: CRCustomTypes } & CustomTypeFieldIdChangedMeta,\n\t): { customTypes: CRCustomTypes; changed: boolean } {\n\t\tconst { customTypes, ...updateMeta } = args;\n\n\t\tlet changed = false;\n\n\t\tconst newCustomTypes = customTypes.map((customType) => {\n\t\t\tconst { customType: newCustomType, changed: hasChanged } =\n\t\t\t\tthis.updateCRCustomType({ customType, ...updateMeta });\n\n\t\t\tchanged ||= hasChanged;\n\n\t\t\treturn newCustomType;\n\t\t});\n\n\t\treturn { customTypes: newCustomTypes, changed };\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs of a single field. The change is\n\t * determined by the `previousPath` and `newPath` properties.\n\t */\n\tprivate updateFieldContentRelationships<\n\t\tT extends UID | NestableWidget | Group | NestedGroup,\n\t>(\n\t\targs: { field: T } & CustomTypeFieldIdChangedMeta,\n\t): { field: T; changed: boolean } {\n\t\tconst { field, ...updateMeta } = args;\n\t\tif (\n\t\t\tfield.type !== \"Link\" ||\n\t\t\tfield.config?.select !== \"document\" ||\n\t\t\t!field.config?.customtypes\n\t\t) {\n\t\t\t// not a content relationship field\n\t\t\treturn { field, changed: false };\n\t\t}\n\n\t\tconst { customTypes: newCustomTypes, changed } = this.updateCRCustomTypes({\n\t\t\t...updateMeta,\n\t\t\tcustomTypes: field.config.customtypes,\n\t\t});\n\n\t\treturn {\n\t\t\tfield: {\n\t\t\t\t...field,\n\t\t\t\tconfig: { ...field.config, customtypes: newCustomTypes },\n\t\t\t},\n\t\t\tchanged,\n\t\t};\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs for all existing custom types and\n\t * slices. The change is determined by properties inside the `updateMeta`\n\t * property.\n\t */\n\tprivate async updateContentRelationships(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, updateMeta } = args;\n\n\t\tif (updateMeta?.fieldIdChanged) {\n\t\t\tlet { previousPath, newPath } = updateMeta.fieldIdChanged;\n\t\t\tconst crUpdatesPromises: Promise<{ errors: HookError[] }>[] = [];\n\n\t\t\tif (previousPath.join(\".\") !== newPath.join(\".\")) {\n\t\t\t\tpreviousPath = [model.id, ...previousPath];\n\t\t\t\tnewPath = [model.id, ...newPath];\n\n\t\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t\t// any custom type and update them to use the new one.\n\t\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\t\tfor (const customType of customTypes.models) {\n\t\t\t\t\tlet hasChangedCustomType = false;\n\n\t\t\t\t\tconst updatedCustomTypeModel = traverseCustomType({\n\t\t\t\t\t\tcustomType: customType.model,\n\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\tconst { field: updatedField, changed } =\n\t\t\t\t\t\t\t\tthis.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thasChangedCustomType ||= changed;\n\n\t\t\t\t\t\t\treturn updatedField;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tif (hasChangedCustomType) {\n\t\t\t\t\t\tcrUpdatesPromises.push(\n\t\t\t\t\t\t\tthis.sliceMachinePluginRunner.callHook(\"custom-type:update\", {\n\t\t\t\t\t\t\t\tmodel: updatedCustomTypeModel,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\t\tfor (const library of libraries) {\n\t\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (const slice of slices.models) {\n\t\t\t\t\t\tlet hasChangedSlice = false;\n\n\t\t\t\t\t\tconst updatedSliceModel = traverseSharedSlice({\n\t\t\t\t\t\t\tpath: [\".\"],\n\t\t\t\t\t\t\tslice: slice.model,\n\t\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\t\tconst { field: updatedField, changed } =\n\t\t\t\t\t\t\t\t\tthis.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\thasChangedSlice ||= changed;\n\n\t\t\t\t\t\t\t\treturn updatedField;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (hasChangedSlice) {\n\t\t\t\t\t\t\tcrUpdatesPromises.push(\n\t\t\t\t\t\t\t\tthis.sliceMachinePluginRunner.callHook(\"slice:update\", {\n\t\t\t\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t\t\t\t\tmodel: updatedSliceModel,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process all the Content Relationship updates at once.\n\t\t\t\tconst crUpdatesResults = await Promise.all(crUpdatesPromises);\n\n\t\t\t\tif (crUpdatesResults.some((result) => result.errors.length > 0)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terrors: crUpdatesResults.flatMap((result) => result.errors),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync updateCustomType(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\targs,\n\t\t);\n\n\t\tif (args.updateMeta?.fieldIdChanged) {\n\t\t\tawait this.updateContentRelationships(args);\n\t\t}\n\n\t\treturn { errors: hookResult.errors };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice({\n\t\timageUrl,\n\t}: {\n\t\timageUrl: string;\n\t}): Promise<InferSliceResponse> {\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst headers = {\n\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t};\n\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\t\tconst searchParams = new URLSearchParams({\n\t\t\trepository,\n\t\t});\n\n\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\turl.search = searchParams.toString();\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\n\t\treturn InferSliceResponse.parse(json);\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n\nfunction shallowClone<T>(value: T): T {\n\tif (typeof value === \"object\") {\n\t\treturn { ...value };\n\t}\n\n\treturn value;\n}\n"],"names":["BaseManager","assertPluginsInitialized","errors","decodeHookResult","t","CustomType","previousId","newId","customType","traverseCustomType","traverseSharedSlice","prismicCustomTypesClient","API_ENDPOINTS","fetch","SLICE_MACHINE_USER_AGENT","UnauthorizedError","z","SharedSlice"],"mappings":"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"}
@@ -58,11 +58,16 @@ export declare class CustomTypesManager extends BaseManager {
58
58
  */
59
59
  private updateCRCustomTypes;
60
60
  /**
61
- * Update the Content Relationship API IDs that were changed during the custom
62
- * type update. The change is determined by the `previousPath` and `newPath`
63
- * properties.
61
+ * Update the Content Relationship API IDs of a single field. The change is
62
+ * determined by the `previousPath` and `newPath` properties.
64
63
  */
65
64
  private updateFieldContentRelationships;
65
+ /**
66
+ * Update the Content Relationship API IDs for all existing custom types and
67
+ * slices. The change is determined by properties inside the `updateMeta`
68
+ * property.
69
+ */
70
+ private updateContentRelationships;
66
71
  updateCustomType(args: CustomTypeUpdateHookData): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>>;
67
72
  renameCustomType(args: CustomTypeRenameHookData): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>>;
68
73
  deleteCustomType(args: CustomTypesMachineManagerDeleteCustomTypeArgs): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType>;
@@ -61,61 +61,56 @@ class CustomTypesManager extends BaseManager {
61
61
  };
62
62
  }
63
63
  updateCRCustomType(args) {
64
- const { customType: customTypeArg, previousPath, newPath } = args;
65
- let customType = customTypeArg;
66
- if (typeof customTypeArg === "object") {
67
- customType = { ...customTypeArg };
68
- }
64
+ const { previousPath, newPath } = args;
65
+ let changed = false;
66
+ const customType = shallowClone(args.customType);
69
67
  const [previousId] = previousPath;
70
68
  const [newId] = newPath;
71
- if (!previousId || !newId) {
72
- return customType;
73
- }
74
- if (typeof customType === "string") {
75
- if (customType === previousId && customType !== newId) {
76
- return newId;
77
- }
78
- return customType;
79
- }
80
- if (customType.id === previousId && customType.id !== newId) {
81
- customType.id = newId;
69
+ if (!previousId || !newId || typeof customType === "string") {
70
+ return { changed, customType };
82
71
  }
83
72
  if (customType.fields) {
84
- return {
85
- ...customType,
86
- fields: customType.fields.map((field) => {
87
- const previousId2 = previousPath[1];
88
- const newId2 = newPath[1];
89
- if (!previousId2 || !newId2) {
90
- return field;
91
- }
92
- if (typeof field === "string") {
93
- if (field === previousId2 && field !== newId2) {
94
- return newId2;
95
- }
96
- return field;
97
- }
98
- if (field.id === previousId2 && field.id !== newId2) {
99
- field.id = newId2;
73
+ const newFields = customType.fields.map((fieldArg) => {
74
+ const field = shallowClone(fieldArg);
75
+ const previousId2 = previousPath[1];
76
+ const newId2 = newPath[1];
77
+ if (!previousId2 || !newId2) {
78
+ return field;
79
+ }
80
+ if (typeof field === "string") {
81
+ if (field === previousId2 && field !== newId2) {
82
+ changed = true;
83
+ return newId2;
100
84
  }
101
- return {
102
- ...field,
103
- customtypes: field.customtypes.map((customType2) => {
104
- return this.updateCRCustomType({
105
- customType: customType2,
106
- previousPath,
107
- newPath
108
- // TODO: Fix types. The second level customtypes are not typed
109
- // the same as the first level customtypes. Although it won't
110
- // matter at runtime.
111
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- -
112
- });
113
- })
114
- };
115
- })
85
+ return field;
86
+ }
87
+ if (field.id === previousId2 && field.id !== newId2) {
88
+ changed = true;
89
+ field.id = newId2;
90
+ }
91
+ return {
92
+ ...field,
93
+ customtypes: field.customtypes.map((customType2) => {
94
+ const { customType: newCustomType, changed: hasChanged } = this.updateCRCustomType({
95
+ customType: customType2,
96
+ previousPath,
97
+ newPath
98
+ // TODO: Fix types. The second level customtypes are not typed
99
+ // the same as the first level customtypes. Although it won't
100
+ // matter at runtime.
101
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- -
102
+ });
103
+ changed || (changed = hasChanged);
104
+ return newCustomType;
105
+ })
106
+ };
107
+ });
108
+ return {
109
+ changed,
110
+ customType: { ...customType, fields: newFields }
116
111
  };
117
112
  }
118
- return { ...customType };
113
+ return { changed, customType };
119
114
  }
120
115
  /**
121
116
  * Map over the custom types of a Content Relationship Link and update the API
@@ -123,56 +118,69 @@ class CustomTypesManager extends BaseManager {
123
118
  */
124
119
  updateCRCustomTypes(args) {
125
120
  const { customTypes, ...updateMeta } = args;
126
- return customTypes.map((customType) => {
127
- return this.updateCRCustomType({ customType, ...updateMeta });
121
+ let changed = false;
122
+ const newCustomTypes = customTypes.map((customType) => {
123
+ const { customType: newCustomType, changed: hasChanged } = this.updateCRCustomType({ customType, ...updateMeta });
124
+ changed || (changed = hasChanged);
125
+ return newCustomType;
128
126
  });
127
+ return { customTypes: newCustomTypes, changed };
129
128
  }
130
129
  /**
131
- * Update the Content Relationship API IDs that were changed during the custom
132
- * type update. The change is determined by the `previousPath` and `newPath`
133
- * properties.
130
+ * Update the Content Relationship API IDs of a single field. The change is
131
+ * determined by the `previousPath` and `newPath` properties.
134
132
  */
135
133
  updateFieldContentRelationships(args) {
136
134
  var _a, _b;
137
135
  const { field, ...updateMeta } = args;
138
136
  if (field.type !== "Link" || ((_a = field.config) == null ? void 0 : _a.select) !== "document" || !((_b = field.config) == null ? void 0 : _b.customtypes)) {
139
- return field;
137
+ return { field, changed: false };
140
138
  }
139
+ const { customTypes: newCustomTypes, changed } = this.updateCRCustomTypes({
140
+ ...updateMeta,
141
+ customTypes: field.config.customtypes
142
+ });
141
143
  return {
142
- ...field,
143
- config: {
144
- ...field.config,
145
- customtypes: this.updateCRCustomTypes({
146
- ...updateMeta,
147
- customTypes: field.config.customtypes.slice()
148
- })
149
- }
144
+ field: {
145
+ ...field,
146
+ config: { ...field.config, customtypes: newCustomTypes }
147
+ },
148
+ changed
150
149
  };
151
150
  }
152
- async updateCustomType(args) {
151
+ /**
152
+ * Update the Content Relationship API IDs for all existing custom types and
153
+ * slices. The change is determined by properties inside the `updateMeta`
154
+ * property.
155
+ */
156
+ async updateContentRelationships(args) {
153
157
  assertPluginsInitialized(this.sliceMachinePluginRunner);
154
- const hookResult = await this.sliceMachinePluginRunner.callHook("custom-type:update", args);
155
158
  const { model, updateMeta } = args;
156
159
  if (updateMeta == null ? void 0 : updateMeta.fieldIdChanged) {
157
160
  let { previousPath, newPath } = updateMeta.fieldIdChanged;
161
+ const crUpdatesPromises = [];
158
162
  if (previousPath.join(".") !== newPath.join(".")) {
159
163
  previousPath = [model.id, ...previousPath];
160
164
  newPath = [model.id, ...newPath];
161
165
  const customTypes = await this.readAllCustomTypes();
162
166
  for (const customType of customTypes.models) {
167
+ let hasChangedCustomType = false;
163
168
  const updatedCustomTypeModel = traverseCustomType({
164
169
  customType: customType.model,
165
170
  onField: ({ field }) => {
166
- return this.updateFieldContentRelationships({
171
+ const { field: updatedField, changed } = this.updateFieldContentRelationships({
167
172
  field,
168
173
  previousPath,
169
174
  newPath
170
175
  });
176
+ hasChangedCustomType || (hasChangedCustomType = changed);
177
+ return updatedField;
171
178
  }
172
179
  });
173
- const hookResult2 = await this.sliceMachinePluginRunner.callHook("custom-type:update", { model: updatedCustomTypeModel });
174
- if (hookResult2.errors.length > 0) {
175
- return { errors: hookResult2.errors };
180
+ if (hasChangedCustomType) {
181
+ crUpdatesPromises.push(this.sliceMachinePluginRunner.callHook("custom-type:update", {
182
+ model: updatedCustomTypeModel
183
+ }));
176
184
  }
177
185
  }
178
186
  const { libraries } = await this.slices.readAllSliceLibraries();
@@ -181,25 +189,45 @@ class CustomTypesManager extends BaseManager {
181
189
  libraryID: library.libraryID
182
190
  });
183
191
  for (const slice of slices.models) {
192
+ let hasChangedSlice = false;
184
193
  const updatedSliceModel = traverseSharedSlice({
185
194
  path: ["."],
186
195
  slice: slice.model,
187
196
  onField: ({ field }) => {
188
- return this.updateFieldContentRelationships({
197
+ const { field: updatedField, changed } = this.updateFieldContentRelationships({
189
198
  field,
190
199
  previousPath,
191
200
  newPath
192
201
  });
202
+ hasChangedSlice || (hasChangedSlice = changed);
203
+ return updatedField;
193
204
  }
194
205
  });
195
- const hookResult2 = await this.sliceMachinePluginRunner.callHook("slice:update", { libraryID: library.libraryID, model: updatedSliceModel });
196
- if (hookResult2.errors.length > 0) {
197
- return { errors: hookResult2.errors };
206
+ if (hasChangedSlice) {
207
+ crUpdatesPromises.push(this.sliceMachinePluginRunner.callHook("slice:update", {
208
+ libraryID: library.libraryID,
209
+ model: updatedSliceModel
210
+ }));
198
211
  }
199
212
  }
200
213
  }
214
+ const crUpdatesResults = await Promise.all(crUpdatesPromises);
215
+ if (crUpdatesResults.some((result) => result.errors.length > 0)) {
216
+ return {
217
+ errors: crUpdatesResults.flatMap((result) => result.errors)
218
+ };
219
+ }
201
220
  }
202
221
  }
222
+ return { errors: [] };
223
+ }
224
+ async updateCustomType(args) {
225
+ var _a;
226
+ assertPluginsInitialized(this.sliceMachinePluginRunner);
227
+ const hookResult = await this.sliceMachinePluginRunner.callHook("custom-type:update", args);
228
+ if ((_a = args.updateMeta) == null ? void 0 : _a.fieldIdChanged) {
229
+ await this.updateContentRelationships(args);
230
+ }
203
231
  return { errors: hookResult.errors };
204
232
  }
205
233
  async renameCustomType(args) {
@@ -346,6 +374,12 @@ const InferSliceResponse = z.object({
346
374
  }),
347
375
  langSmithUrl: z.string().url().optional()
348
376
  });
377
+ function shallowClone(value) {
378
+ if (typeof value === "object") {
379
+ return { ...value };
380
+ }
381
+ return value;
382
+ }
349
383
  export {
350
384
  CustomTypesManager
351
385
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CustomTypesManager.js","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLink,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypeUpdateMeta = {\n\tpreviousPath: string[];\n\tnewPath: string[];\n};\ntype CRCustomTypes = NonNullable<NonNullable<Link[\"config\"]>[\"customtypes\"]>;\ntype CRCustomType = NonNullable<CRCustomTypes>[number];\n\nexport class CustomTypesManager extends BaseManager {\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tprivate updateCRCustomType(\n\t\targs: { customType: CRCustomType } & CustomTypeUpdateMeta,\n\t): CRCustomType {\n\t\tconst { customType: customTypeArg, previousPath, newPath } = args;\n\n\t\tlet customType = customTypeArg;\n\t\tif (typeof customTypeArg === \"object\") {\n\t\t\tcustomType = { ...customTypeArg };\n\t\t}\n\n\t\tconst [previousId] = previousPath;\n\t\tconst [newId] = newPath;\n\n\t\tif (!previousId || !newId) {\n\t\t\treturn customType;\n\t\t}\n\n\t\tif (typeof customType === \"string\") {\n\t\t\tif (customType === previousId && customType !== newId) {\n\t\t\t\treturn newId; // update to new api id\n\t\t\t}\n\n\t\t\treturn customType;\n\t\t}\n\n\t\tif (customType.id === previousId && customType.id !== newId) {\n\t\t\tcustomType.id = newId; // update to new api id\n\t\t}\n\n\t\tif (customType.fields) {\n\t\t\treturn {\n\t\t\t\t...customType,\n\t\t\t\tfields: customType.fields.map((field) => {\n\t\t\t\t\tconst previousId = previousPath[1];\n\t\t\t\t\tconst newId = newPath[1];\n\n\t\t\t\t\tif (!previousId || !newId) {\n\t\t\t\t\t\treturn field;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typeof field === \"string\") {\n\t\t\t\t\t\tif (field === previousId && field !== newId) {\n\t\t\t\t\t\t\treturn newId; // update to new api id\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn field;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (field.id === previousId && field.id !== newId) {\n\t\t\t\t\t\tfield.id = newId; // update to new api id\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...field,\n\t\t\t\t\t\tcustomtypes: field.customtypes.map((customType) => {\n\t\t\t\t\t\t\treturn this.updateCRCustomType({\n\t\t\t\t\t\t\t\tcustomType,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t// TODO: Fix types. The second level customtypes are not typed\n\t\t\t\t\t\t\t\t// the same as the first level customtypes. Although it won't\n\t\t\t\t\t\t\t\t// matter at runtime.\n\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- -\n\t\t\t\t\t\t\t}) as any;\n\t\t\t\t\t\t}),\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\treturn { ...customType };\n\t}\n\n\t/**\n\t * Map over the custom types of a Content Relationship Link and update the API\n\t * IDs that were changed during the custom type update.\n\t */\n\tprivate updateCRCustomTypes(\n\t\targs: { customTypes: CRCustomTypes } & CustomTypeUpdateMeta,\n\t): CRCustomTypes {\n\t\tconst { customTypes, ...updateMeta } = args;\n\n\t\treturn customTypes.map((customType) => {\n\t\t\treturn this.updateCRCustomType({ customType, ...updateMeta });\n\t\t});\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs that were changed during the custom\n\t * type update. The change is determined by the `previousPath` and `newPath`\n\t * properties.\n\t */\n\tprivate updateFieldContentRelationships<\n\t\tT extends UID | NestableWidget | Group | NestedGroup,\n\t>(args: { field: T } & CustomTypeUpdateMeta): T {\n\t\tconst { field, ...updateMeta } = args;\n\t\tif (\n\t\t\tfield.type !== \"Link\" ||\n\t\t\tfield.config?.select !== \"document\" ||\n\t\t\t!field.config?.customtypes\n\t\t) {\n\t\t\treturn field; // not a content relationship field\n\t\t}\n\n\t\treturn {\n\t\t\t...field,\n\t\t\tconfig: {\n\t\t\t\t...field.config,\n\t\t\t\tcustomtypes: this.updateCRCustomTypes({\n\t\t\t\t\t...updateMeta,\n\t\t\t\t\tcustomTypes: field.config.customtypes.slice(),\n\t\t\t\t}),\n\t\t\t},\n\t\t};\n\t}\n\n\tasync updateCustomType(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\targs,\n\t\t);\n\n\t\tconst { model, updateMeta } = args;\n\n\t\tif (updateMeta?.fieldIdChanged) {\n\t\t\tlet { previousPath, newPath } = updateMeta.fieldIdChanged;\n\n\t\t\tif (previousPath.join(\".\") !== newPath.join(\".\")) {\n\t\t\t\tpreviousPath = [model.id, ...previousPath];\n\t\t\t\tnewPath = [model.id, ...newPath];\n\n\t\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t\t// any custom type and update them to use the new one.\n\t\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\t\tfor (const customType of customTypes.models) {\n\t\t\t\t\tconst updatedCustomTypeModel = traverseCustomType({\n\t\t\t\t\t\tcustomType: customType.model,\n\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\treturn this.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\t\t\"custom-type:update\",\n\t\t\t\t\t\t{ model: updatedCustomTypeModel },\n\t\t\t\t\t);\n\n\t\t\t\t\tif (hookResult.errors.length > 0) {\n\t\t\t\t\t\treturn { errors: hookResult.errors };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\t\tfor (const library of libraries) {\n\t\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (const slice of slices.models) {\n\t\t\t\t\t\tconst updatedSliceModel = traverseSharedSlice({\n\t\t\t\t\t\t\tpath: [\".\"],\n\t\t\t\t\t\t\tslice: slice.model,\n\t\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\t\treturn this.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\t\t\t\"slice:update\",\n\t\t\t\t\t\t\t{ libraryID: library.libraryID, model: updatedSliceModel },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (hookResult.errors.length > 0) {\n\t\t\t\t\t\t\treturn { errors: hookResult.errors };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: hookResult.errors };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice({\n\t\timageUrl,\n\t}: {\n\t\timageUrl: string;\n\t}): Promise<InferSliceResponse> {\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst headers = {\n\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t};\n\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\t\tconst searchParams = new URLSearchParams({\n\t\t\trepository,\n\t\t});\n\n\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\turl.search = searchParams.toString();\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\n\t\treturn InferSliceResponse.parse(json);\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n"],"names":["errors","previousId","newId","customType","hookResult"],"mappings":"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"}
1
+ {"version":3,"file":"CustomTypesManager.js","sources":["../../../../src/managers/customTypes/CustomTypesManager.ts"],"sourcesContent":["import * as t from \"io-ts\";\nimport * as prismicCustomTypesClient from \"@prismicio/custom-types-client\";\nimport {\n\tCustomType,\n\tGroup,\n\tLink,\n\tNestableWidget,\n\tNestedGroup,\n\tSharedSlice,\n\tUID,\n\ttraverseCustomType,\n\ttraverseSharedSlice,\n} from \"@prismicio/types-internal/lib/customtypes\";\nimport {\n\tCallHookReturnType,\n\tCustomTypeCreateHook,\n\tCustomTypeCreateHookData,\n\tCustomTypeReadHookData,\n\tCustomTypeRenameHook,\n\tCustomTypeRenameHookData,\n\tCustomTypeUpdateHook,\n\tCustomTypeUpdateHookData,\n\tHookError,\n} from \"@slicemachine/plugin-kit\";\nimport { z } from \"zod\";\n\nimport { DecodeError } from \"../../lib/DecodeError\";\nimport { assertPluginsInitialized } from \"../../lib/assertPluginsInitialized\";\nimport { decodeHookResult } from \"../../lib/decodeHookResult\";\nimport fetch from \"../../lib/fetch\";\n\nimport { OnlyHookErrors } from \"../../types\";\nimport { API_ENDPOINTS } from \"../../constants/API_ENDPOINTS\";\nimport { SLICE_MACHINE_USER_AGENT } from \"../../constants/SLICE_MACHINE_USER_AGENT\";\nimport { UnauthorizedError } from \"../../errors\";\n\nimport { BaseManager } from \"../BaseManager\";\nimport { CustomTypeFormat } from \"./types\";\n\ntype SliceMachineManagerReadCustomTypeLibraryReturnType = {\n\tids: string[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CustomTypesManagerReadAllCustomTypesArgs = {\n\tformat: CustomTypeFormat;\n};\n\ntype SliceMachineManagerReadAllCustomTypeReturnType = {\n\tmodels: { model: CustomType }[];\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerReadCustomTypeReturnType = {\n\tmodel: CustomType | undefined;\n\terrors: (DecodeError | HookError)[];\n};\n\ntype SliceMachineManagerPushCustomTypeArgs = {\n\tid: string;\n\tuserAgent?: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n};\n\ntype SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType = {\n\t// TODO\n\tmocksConfig?: Record<string, unknown>;\n\terrors: HookError[];\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgs = {\n\tcustomTypeID: string;\n\t// TODO\n\tmocksConfig: Record<string, unknown>;\n};\n\ntype SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType = {\n\terrors: HookError[];\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeArgs = {\n\tid: string;\n};\n\ntype CustomTypesMachineManagerDeleteCustomTypeReturnType = {\n\terrors: (DecodeError | HookError)[];\n};\n\ntype CRCustomTypes = NonNullable<NonNullable<Link[\"config\"]>[\"customtypes\"]>;\ntype CRCustomType = NonNullable<CRCustomTypes>[number];\ntype CustomTypeFieldIdChangedMeta = NonNullable<\n\tNonNullable<CustomTypeUpdateHookData[\"updateMeta\"]>[\"fieldIdChanged\"]\n>;\n\nexport class CustomTypesManager extends BaseManager {\n\tasync readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type-library:read\",\n\t\t\tundefined,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tids: t.array(t.string),\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tids: data[0]?.ids || [],\n\t\t\terrors,\n\t\t};\n\t}\n\n\tasync readAllCustomTypes(\n\t\targs?: CustomTypesManagerReadAllCustomTypesArgs,\n\t): Promise<SliceMachineManagerReadAllCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst res: SliceMachineManagerReadAllCustomTypeReturnType = {\n\t\t\tmodels: [],\n\t\t\terrors: [],\n\t\t};\n\n\t\tconst { ids, errors } = await this.readCustomTypeLibrary();\n\t\tres.errors = [...res.errors, ...errors];\n\n\t\tif (ids) {\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst { model, errors } = await this.readCustomType({ id });\n\t\t\t\tres.errors = [...res.errors, ...errors];\n\n\t\t\t\tif (model && (!args || args.format === model.format)) {\n\t\t\t\t\tres.models.push({ model });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn res;\n\t}\n\n\tasync createCustomType(\n\t\targs: CustomTypeCreateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeCreateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:create\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync readCustomType(\n\t\targs: CustomTypeReadHookData,\n\t): Promise<SliceMachineManagerReadCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:read\",\n\t\t\targs,\n\t\t);\n\t\tconst { data, errors } = decodeHookResult(\n\t\t\tt.type({\n\t\t\t\tmodel: CustomType,\n\t\t\t}),\n\t\t\thookResult,\n\t\t);\n\n\t\treturn {\n\t\t\tmodel: data[0]?.model,\n\t\t\terrors,\n\t\t};\n\t}\n\n\tprivate updateCRCustomType(\n\t\targs: { customType: CRCustomType } & CustomTypeFieldIdChangedMeta,\n\t): { customType: CRCustomType; changed: boolean } {\n\t\tconst { previousPath, newPath } = args;\n\n\t\tlet changed = false;\n\t\tconst customType = shallowClone(args.customType);\n\n\t\tconst [previousId] = previousPath;\n\t\tconst [newId] = newPath;\n\n\t\tif (!previousId || !newId || typeof customType === \"string\") {\n\t\t\treturn { changed, customType };\n\t\t}\n\n\t\tif (customType.fields) {\n\t\t\tconst newFields = customType.fields.map((fieldArg) => {\n\t\t\t\tconst field = shallowClone(fieldArg);\n\n\t\t\t\tconst previousId = previousPath[1];\n\t\t\t\tconst newId = newPath[1];\n\n\t\t\t\tif (!previousId || !newId) {\n\t\t\t\t\treturn field;\n\t\t\t\t}\n\n\t\t\t\tif (typeof field === \"string\") {\n\t\t\t\t\tif (field === previousId && field !== newId) {\n\t\t\t\t\t\t// We have reached a field id that matches the id that was renamed,\n\t\t\t\t\t\t// so we update it new one. The field is a string, so return the new\n\t\t\t\t\t\t// id.\n\t\t\t\t\t\tchanged = true;\n\n\t\t\t\t\t\treturn newId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn field;\n\t\t\t\t}\n\n\t\t\t\tif (field.id === previousId && field.id !== newId) {\n\t\t\t\t\t// We have reached a field id that matches the id that was renamed,\n\t\t\t\t\t// so we update it new one.\n\t\t\t\t\t// Since field is not a string, we don't exit, as we might have\n\t\t\t\t\t// something to update further down in customtypes.\n\t\t\t\t\tchanged = true;\n\n\t\t\t\t\tfield.id = newId;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\t...field,\n\t\t\t\t\tcustomtypes: field.customtypes.map((customType) => {\n\t\t\t\t\t\tconst { customType: newCustomType, changed: hasChanged } =\n\t\t\t\t\t\t\tthis.updateCRCustomType({\n\t\t\t\t\t\t\t\tcustomType,\n\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t// TODO: Fix types. The second level customtypes are not typed\n\t\t\t\t\t\t\t\t// the same as the first level customtypes. Although it won't\n\t\t\t\t\t\t\t\t// matter at runtime.\n\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any -- -\n\t\t\t\t\t\t\t}) as any;\n\n\t\t\t\t\t\tchanged ||= hasChanged;\n\n\t\t\t\t\t\treturn newCustomType;\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tchanged,\n\t\t\t\tcustomType: { ...customType, fields: newFields },\n\t\t\t};\n\t\t}\n\n\t\treturn { changed, customType };\n\t}\n\n\t/**\n\t * Map over the custom types of a Content Relationship Link and update the API\n\t * IDs that were changed during the custom type update.\n\t */\n\tprivate updateCRCustomTypes(\n\t\targs: { customTypes: CRCustomTypes } & CustomTypeFieldIdChangedMeta,\n\t): { customTypes: CRCustomTypes; changed: boolean } {\n\t\tconst { customTypes, ...updateMeta } = args;\n\n\t\tlet changed = false;\n\n\t\tconst newCustomTypes = customTypes.map((customType) => {\n\t\t\tconst { customType: newCustomType, changed: hasChanged } =\n\t\t\t\tthis.updateCRCustomType({ customType, ...updateMeta });\n\n\t\t\tchanged ||= hasChanged;\n\n\t\t\treturn newCustomType;\n\t\t});\n\n\t\treturn { customTypes: newCustomTypes, changed };\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs of a single field. The change is\n\t * determined by the `previousPath` and `newPath` properties.\n\t */\n\tprivate updateFieldContentRelationships<\n\t\tT extends UID | NestableWidget | Group | NestedGroup,\n\t>(\n\t\targs: { field: T } & CustomTypeFieldIdChangedMeta,\n\t): { field: T; changed: boolean } {\n\t\tconst { field, ...updateMeta } = args;\n\t\tif (\n\t\t\tfield.type !== \"Link\" ||\n\t\t\tfield.config?.select !== \"document\" ||\n\t\t\t!field.config?.customtypes\n\t\t) {\n\t\t\t// not a content relationship field\n\t\t\treturn { field, changed: false };\n\t\t}\n\n\t\tconst { customTypes: newCustomTypes, changed } = this.updateCRCustomTypes({\n\t\t\t...updateMeta,\n\t\t\tcustomTypes: field.config.customtypes,\n\t\t});\n\n\t\treturn {\n\t\t\tfield: {\n\t\t\t\t...field,\n\t\t\t\tconfig: { ...field.config, customtypes: newCustomTypes },\n\t\t\t},\n\t\t\tchanged,\n\t\t};\n\t}\n\n\t/**\n\t * Update the Content Relationship API IDs for all existing custom types and\n\t * slices. The change is determined by properties inside the `updateMeta`\n\t * property.\n\t */\n\tprivate async updateContentRelationships(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, updateMeta } = args;\n\n\t\tif (updateMeta?.fieldIdChanged) {\n\t\t\tlet { previousPath, newPath } = updateMeta.fieldIdChanged;\n\t\t\tconst crUpdatesPromises: Promise<{ errors: HookError[] }>[] = [];\n\n\t\t\tif (previousPath.join(\".\") !== newPath.join(\".\")) {\n\t\t\t\tpreviousPath = [model.id, ...previousPath];\n\t\t\t\tnewPath = [model.id, ...newPath];\n\n\t\t\t\t// Find existing content relationships that link to the renamed field id in\n\t\t\t\t// any custom type and update them to use the new one.\n\t\t\t\tconst customTypes = await this.readAllCustomTypes();\n\n\t\t\t\tfor (const customType of customTypes.models) {\n\t\t\t\t\tlet hasChangedCustomType = false;\n\n\t\t\t\t\tconst updatedCustomTypeModel = traverseCustomType({\n\t\t\t\t\t\tcustomType: customType.model,\n\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\tconst { field: updatedField, changed } =\n\t\t\t\t\t\t\t\tthis.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thasChangedCustomType ||= changed;\n\n\t\t\t\t\t\t\treturn updatedField;\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tif (hasChangedCustomType) {\n\t\t\t\t\t\tcrUpdatesPromises.push(\n\t\t\t\t\t\t\tthis.sliceMachinePluginRunner.callHook(\"custom-type:update\", {\n\t\t\t\t\t\t\t\tmodel: updatedCustomTypeModel,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Find existing slice with content relationships that link to the renamed\n\t\t\t\t// field id in all libraries and update them to use the new one.\n\t\t\t\tconst { libraries } = await this.slices.readAllSliceLibraries();\n\n\t\t\t\tfor (const library of libraries) {\n\t\t\t\t\tconst slices = await this.slices.readAllSlicesForLibrary({\n\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (const slice of slices.models) {\n\t\t\t\t\t\tlet hasChangedSlice = false;\n\n\t\t\t\t\t\tconst updatedSliceModel = traverseSharedSlice({\n\t\t\t\t\t\t\tpath: [\".\"],\n\t\t\t\t\t\t\tslice: slice.model,\n\t\t\t\t\t\t\tonField: ({ field }) => {\n\t\t\t\t\t\t\t\tconst { field: updatedField, changed } =\n\t\t\t\t\t\t\t\t\tthis.updateFieldContentRelationships({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tpreviousPath,\n\t\t\t\t\t\t\t\t\t\tnewPath,\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\thasChangedSlice ||= changed;\n\n\t\t\t\t\t\t\t\treturn updatedField;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (hasChangedSlice) {\n\t\t\t\t\t\t\tcrUpdatesPromises.push(\n\t\t\t\t\t\t\t\tthis.sliceMachinePluginRunner.callHook(\"slice:update\", {\n\t\t\t\t\t\t\t\t\tlibraryID: library.libraryID,\n\t\t\t\t\t\t\t\t\tmodel: updatedSliceModel,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process all the Content Relationship updates at once.\n\t\t\t\tconst crUpdatesResults = await Promise.all(crUpdatesPromises);\n\n\t\t\t\tif (crUpdatesResults.some((result) => result.errors.length > 0)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\terrors: crUpdatesResults.flatMap((result) => result.errors),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { errors: [] };\n\t}\n\n\tasync updateCustomType(\n\t\targs: CustomTypeUpdateHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:update\",\n\t\t\targs,\n\t\t);\n\n\t\tif (args.updateMeta?.fieldIdChanged) {\n\t\t\tawait this.updateContentRelationships(args);\n\t\t}\n\n\t\treturn { errors: hookResult.errors };\n\t}\n\n\tasync renameCustomType(\n\t\targs: CustomTypeRenameHookData,\n\t): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeRenameHook>>> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:rename\",\n\t\t\targs,\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync deleteCustomType(\n\t\targs: CustomTypesMachineManagerDeleteCustomTypeArgs,\n\t): Promise<CustomTypesMachineManagerDeleteCustomTypeReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst { model, errors: readCustomTypeErrors } = await this.readCustomType({\n\t\t\tid: args.id,\n\t\t});\n\n\t\tif (model) {\n\t\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\t\"custom-type:delete\",\n\t\t\t\t{ model },\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\terrors: readCustomTypeErrors,\n\t\t\t};\n\t\t}\n\t}\n\n\tasync pushCustomType(\n\t\targs: SliceMachineManagerPushCustomTypeArgs,\n\t): Promise<void> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\t// TODO: Handle errors\n\t\tconst { model } = await this.readCustomType({ id: args.id });\n\n\t\tif (model) {\n\t\t\t// TODO: Create a single shared client.\n\t\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\t\trepositoryName,\n\t\t\t\ttoken: authenticationToken,\n\t\t\t\tfetch,\n\t\t\t\tfetchOptions: {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": args.userAgent || SLICE_MACHINE_USER_AGENT,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\t// Check if Custom Type already exists on the repository.\n\t\t\t\tawait client.getCustomTypeByID(args.id);\n\n\t\t\t\t// If it exists on the repository, update it.\n\t\t\t\tawait client.updateCustomType(model);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof prismicCustomTypesClient.NotFoundError) {\n\t\t\t\t\t// If it doesn't exist on the repository, insert it.\n\t\t\t\t\tawait client.insertCustomType(model);\n\t\t\t\t} else if (error instanceof prismicCustomTypesClient.ForbiddenError) {\n\t\t\t\t\tthrow new UnauthorizedError(\n\t\t\t\t\t\t\"You do not have access to push types to this Prismic repository.\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync readCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerReadCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerReadCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:read\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tassetID: \"mocks.config.json\",\n\t\t\t},\n\t\t);\n\t\tconst data = hookResult.data[0]?.data;\n\n\t\t// TODO: Validate the returned data.\n\n\t\tif (data) {\n\t\t\treturn {\n\t\t\t\tmocksConfig: JSON.parse(data.toString()),\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tmocksConfig: undefined,\n\t\t\t\terrors: hookResult.errors,\n\t\t\t};\n\t\t}\n\t}\n\n\t// TODO: Remove\n\tasync updateCustomTypeMocksConfig(\n\t\targs: SliceMachineManagerUpdateCustomTypeMocksConfigArgs,\n\t): Promise<SliceMachineManagerUpdateCustomTypeMocksConfigArgsReturnType> {\n\t\tassertPluginsInitialized(this.sliceMachinePluginRunner);\n\n\t\tconst hookResult = await this.sliceMachinePluginRunner.callHook(\n\t\t\t\"custom-type:asset:update\",\n\t\t\t{\n\t\t\t\tcustomTypeID: args.customTypeID,\n\t\t\t\tasset: {\n\t\t\t\t\tid: \"mocks.config.json\",\n\t\t\t\t\tdata: Buffer.from(JSON.stringify(args.mocksConfig, null, \"\\t\")),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\terrors: hookResult.errors,\n\t\t};\n\t}\n\n\tasync fetchRemoteCustomTypes(): Promise<CustomType[]> {\n\t\tconst authenticationToken = await this.user.getAuthenticationToken();\n\t\tconst repositoryName = await this.project.getResolvedRepositoryName();\n\n\t\tconst client = prismicCustomTypesClient.createClient({\n\t\t\tendpoint: API_ENDPOINTS.PrismicModels,\n\t\t\trepositoryName,\n\t\t\ttoken: authenticationToken,\n\t\t\tfetch,\n\t\t\tfetchOptions: {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": SLICE_MACHINE_USER_AGENT,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\treturn await client.getAllCustomTypes();\n\t}\n\n\tasync inferSlice({\n\t\timageUrl,\n\t}: {\n\t\timageUrl: string;\n\t}): Promise<InferSliceResponse> {\n\t\tconst authToken = await this.user.getAuthenticationToken();\n\t\tconst headers = {\n\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t};\n\n\t\tconst repository = await this.project.getResolvedRepositoryName();\n\t\tconst searchParams = new URLSearchParams({\n\t\t\trepository,\n\t\t});\n\n\t\tconst url = new URL(\"./slices/infer\", API_ENDPOINTS.CustomTypeService);\n\t\turl.search = searchParams.toString();\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: headers,\n\t\t\tbody: JSON.stringify({ imageUrl }),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to infer slice: ${response.statusText}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\n\t\treturn InferSliceResponse.parse(json);\n\t}\n}\n\ntype InferSliceResponse = z.infer<typeof InferSliceResponse>;\n\nconst InferSliceResponse = z.object({\n\tslice: z.custom().transform((value, ctx) => {\n\t\tconst result = SharedSlice.decode(value);\n\t\tif (result._tag === \"Right\") {\n\t\t\treturn result.right;\n\t\t}\n\t\tctx.addIssue({\n\t\t\tcode: z.ZodIssueCode.custom,\n\t\t\tmessage: `Invalid shared slice: ${JSON.stringify(value, null, 2)}`,\n\t\t});\n\n\t\treturn z.NEVER;\n\t}),\n\tlangSmithUrl: z.string().url().optional(),\n});\n\nfunction shallowClone<T>(value: T): T {\n\tif (typeof value === \"object\") {\n\t\treturn { ...value };\n\t}\n\n\treturn value;\n}\n"],"names":["errors","previousId","newId","customType"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slicemachine/manager",
3
- "version": "0.24.14-alpha.jp-update-cr-links.2",
3
+ "version": "0.24.14-alpha.jp-update-cr-links.4",
4
4
  "description": "Manage all aspects of a Slice Machine project.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -70,7 +70,7 @@
70
70
  "@prismicio/mocks": "2.13.0",
71
71
  "@prismicio/types-internal": "3.10.0-alpha.0",
72
72
  "@segment/analytics-node": "^2.1.2",
73
- "@slicemachine/plugin-kit": "0.4.76-alpha.jp-update-cr-links.2",
73
+ "@slicemachine/plugin-kit": "0.4.76-alpha.jp-update-cr-links.4",
74
74
  "cookie": "^1.0.1",
75
75
  "cors": "^2.8.5",
76
76
  "execa": "^7.1.1",
@@ -89,12 +89,11 @@ type CustomTypesMachineManagerDeleteCustomTypeReturnType = {
89
89
  errors: (DecodeError | HookError)[];
90
90
  };
91
91
 
92
- type CustomTypeUpdateMeta = {
93
- previousPath: string[];
94
- newPath: string[];
95
- };
96
92
  type CRCustomTypes = NonNullable<NonNullable<Link["config"]>["customtypes"]>;
97
93
  type CRCustomType = NonNullable<CRCustomTypes>[number];
94
+ type CustomTypeFieldIdChangedMeta = NonNullable<
95
+ NonNullable<CustomTypeUpdateHookData["updateMeta"]>["fieldIdChanged"]
96
+ >;
98
97
 
99
98
  export class CustomTypesManager extends BaseManager {
100
99
  async readCustomTypeLibrary(): Promise<SliceMachineManagerReadCustomTypeLibraryReturnType> {
@@ -182,61 +181,59 @@ export class CustomTypesManager extends BaseManager {
182
181
  }
183
182
 
184
183
  private updateCRCustomType(
185
- args: { customType: CRCustomType } & CustomTypeUpdateMeta,
186
- ): CRCustomType {
187
- const { customType: customTypeArg, previousPath, newPath } = args;
184
+ args: { customType: CRCustomType } & CustomTypeFieldIdChangedMeta,
185
+ ): { customType: CRCustomType; changed: boolean } {
186
+ const { previousPath, newPath } = args;
188
187
 
189
- let customType = customTypeArg;
190
- if (typeof customTypeArg === "object") {
191
- customType = { ...customTypeArg };
192
- }
188
+ let changed = false;
189
+ const customType = shallowClone(args.customType);
193
190
 
194
191
  const [previousId] = previousPath;
195
192
  const [newId] = newPath;
196
193
 
197
- if (!previousId || !newId) {
198
- return customType;
194
+ if (!previousId || !newId || typeof customType === "string") {
195
+ return { changed, customType };
199
196
  }
200
197
 
201
- if (typeof customType === "string") {
202
- if (customType === previousId && customType !== newId) {
203
- return newId; // update to new api id
204
- }
198
+ if (customType.fields) {
199
+ const newFields = customType.fields.map((fieldArg) => {
200
+ const field = shallowClone(fieldArg);
205
201
 
206
- return customType;
207
- }
202
+ const previousId = previousPath[1];
203
+ const newId = newPath[1];
208
204
 
209
- if (customType.id === previousId && customType.id !== newId) {
210
- customType.id = newId; // update to new api id
211
- }
205
+ if (!previousId || !newId) {
206
+ return field;
207
+ }
212
208
 
213
- if (customType.fields) {
214
- return {
215
- ...customType,
216
- fields: customType.fields.map((field) => {
217
- const previousId = previousPath[1];
218
- const newId = newPath[1];
209
+ if (typeof field === "string") {
210
+ if (field === previousId && field !== newId) {
211
+ // We have reached a field id that matches the id that was renamed,
212
+ // so we update it new one. The field is a string, so return the new
213
+ // id.
214
+ changed = true;
219
215
 
220
- if (!previousId || !newId) {
221
- return field;
216
+ return newId;
222
217
  }
223
218
 
224
- if (typeof field === "string") {
225
- if (field === previousId && field !== newId) {
226
- return newId; // update to new api id
227
- }
219
+ return field;
220
+ }
228
221
 
229
- return field;
230
- }
222
+ if (field.id === previousId && field.id !== newId) {
223
+ // We have reached a field id that matches the id that was renamed,
224
+ // so we update it new one.
225
+ // Since field is not a string, we don't exit, as we might have
226
+ // something to update further down in customtypes.
227
+ changed = true;
231
228
 
232
- if (field.id === previousId && field.id !== newId) {
233
- field.id = newId; // update to new api id
234
- }
229
+ field.id = newId;
230
+ }
235
231
 
236
- return {
237
- ...field,
238
- customtypes: field.customtypes.map((customType) => {
239
- return this.updateCRCustomType({
232
+ return {
233
+ ...field,
234
+ customtypes: field.customtypes.map((customType) => {
235
+ const { customType: newCustomType, changed: hasChanged } =
236
+ this.updateCRCustomType({
240
237
  customType,
241
238
  previousPath,
242
239
  newPath,
@@ -245,13 +242,21 @@ export class CustomTypesManager extends BaseManager {
245
242
  // matter at runtime.
246
243
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- -
247
244
  }) as any;
248
- }),
249
- };
250
- }),
245
+
246
+ changed ||= hasChanged;
247
+
248
+ return newCustomType;
249
+ }),
250
+ };
251
+ });
252
+
253
+ return {
254
+ changed,
255
+ customType: { ...customType, fields: newFields },
251
256
  };
252
257
  }
253
258
 
254
- return { ...customType };
259
+ return { changed, customType };
255
260
  }
256
261
 
257
262
  /**
@@ -259,58 +264,72 @@ export class CustomTypesManager extends BaseManager {
259
264
  * IDs that were changed during the custom type update.
260
265
  */
261
266
  private updateCRCustomTypes(
262
- args: { customTypes: CRCustomTypes } & CustomTypeUpdateMeta,
263
- ): CRCustomTypes {
267
+ args: { customTypes: CRCustomTypes } & CustomTypeFieldIdChangedMeta,
268
+ ): { customTypes: CRCustomTypes; changed: boolean } {
264
269
  const { customTypes, ...updateMeta } = args;
265
270
 
266
- return customTypes.map((customType) => {
267
- return this.updateCRCustomType({ customType, ...updateMeta });
271
+ let changed = false;
272
+
273
+ const newCustomTypes = customTypes.map((customType) => {
274
+ const { customType: newCustomType, changed: hasChanged } =
275
+ this.updateCRCustomType({ customType, ...updateMeta });
276
+
277
+ changed ||= hasChanged;
278
+
279
+ return newCustomType;
268
280
  });
281
+
282
+ return { customTypes: newCustomTypes, changed };
269
283
  }
270
284
 
271
285
  /**
272
- * Update the Content Relationship API IDs that were changed during the custom
273
- * type update. The change is determined by the `previousPath` and `newPath`
274
- * properties.
286
+ * Update the Content Relationship API IDs of a single field. The change is
287
+ * determined by the `previousPath` and `newPath` properties.
275
288
  */
276
289
  private updateFieldContentRelationships<
277
290
  T extends UID | NestableWidget | Group | NestedGroup,
278
- >(args: { field: T } & CustomTypeUpdateMeta): T {
291
+ >(
292
+ args: { field: T } & CustomTypeFieldIdChangedMeta,
293
+ ): { field: T; changed: boolean } {
279
294
  const { field, ...updateMeta } = args;
280
295
  if (
281
296
  field.type !== "Link" ||
282
297
  field.config?.select !== "document" ||
283
298
  !field.config?.customtypes
284
299
  ) {
285
- return field; // not a content relationship field
300
+ // not a content relationship field
301
+ return { field, changed: false };
286
302
  }
287
303
 
304
+ const { customTypes: newCustomTypes, changed } = this.updateCRCustomTypes({
305
+ ...updateMeta,
306
+ customTypes: field.config.customtypes,
307
+ });
308
+
288
309
  return {
289
- ...field,
290
- config: {
291
- ...field.config,
292
- customtypes: this.updateCRCustomTypes({
293
- ...updateMeta,
294
- customTypes: field.config.customtypes.slice(),
295
- }),
310
+ field: {
311
+ ...field,
312
+ config: { ...field.config, customtypes: newCustomTypes },
296
313
  },
314
+ changed,
297
315
  };
298
316
  }
299
317
 
300
- async updateCustomType(
318
+ /**
319
+ * Update the Content Relationship API IDs for all existing custom types and
320
+ * slices. The change is determined by properties inside the `updateMeta`
321
+ * property.
322
+ */
323
+ private async updateContentRelationships(
301
324
  args: CustomTypeUpdateHookData,
302
325
  ): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {
303
326
  assertPluginsInitialized(this.sliceMachinePluginRunner);
304
327
 
305
- const hookResult = await this.sliceMachinePluginRunner.callHook(
306
- "custom-type:update",
307
- args,
308
- );
309
-
310
328
  const { model, updateMeta } = args;
311
329
 
312
330
  if (updateMeta?.fieldIdChanged) {
313
331
  let { previousPath, newPath } = updateMeta.fieldIdChanged;
332
+ const crUpdatesPromises: Promise<{ errors: HookError[] }>[] = [];
314
333
 
315
334
  if (previousPath.join(".") !== newPath.join(".")) {
316
335
  previousPath = [model.id, ...previousPath];
@@ -321,24 +340,30 @@ export class CustomTypesManager extends BaseManager {
321
340
  const customTypes = await this.readAllCustomTypes();
322
341
 
323
342
  for (const customType of customTypes.models) {
343
+ let hasChangedCustomType = false;
344
+
324
345
  const updatedCustomTypeModel = traverseCustomType({
325
346
  customType: customType.model,
326
347
  onField: ({ field }) => {
327
- return this.updateFieldContentRelationships({
328
- field,
329
- previousPath,
330
- newPath,
331
- });
348
+ const { field: updatedField, changed } =
349
+ this.updateFieldContentRelationships({
350
+ field,
351
+ previousPath,
352
+ newPath,
353
+ });
354
+
355
+ hasChangedCustomType ||= changed;
356
+
357
+ return updatedField;
332
358
  },
333
359
  });
334
360
 
335
- const hookResult = await this.sliceMachinePluginRunner.callHook(
336
- "custom-type:update",
337
- { model: updatedCustomTypeModel },
338
- );
339
-
340
- if (hookResult.errors.length > 0) {
341
- return { errors: hookResult.errors };
361
+ if (hasChangedCustomType) {
362
+ crUpdatesPromises.push(
363
+ this.sliceMachinePluginRunner.callHook("custom-type:update", {
364
+ model: updatedCustomTypeModel,
365
+ }),
366
+ );
342
367
  }
343
368
  }
344
369
 
@@ -352,31 +377,64 @@ export class CustomTypesManager extends BaseManager {
352
377
  });
353
378
 
354
379
  for (const slice of slices.models) {
380
+ let hasChangedSlice = false;
381
+
355
382
  const updatedSliceModel = traverseSharedSlice({
356
383
  path: ["."],
357
384
  slice: slice.model,
358
385
  onField: ({ field }) => {
359
- return this.updateFieldContentRelationships({
360
- field,
361
- previousPath,
362
- newPath,
363
- });
386
+ const { field: updatedField, changed } =
387
+ this.updateFieldContentRelationships({
388
+ field,
389
+ previousPath,
390
+ newPath,
391
+ });
392
+
393
+ hasChangedSlice ||= changed;
394
+
395
+ return updatedField;
364
396
  },
365
397
  });
366
398
 
367
- const hookResult = await this.sliceMachinePluginRunner.callHook(
368
- "slice:update",
369
- { libraryID: library.libraryID, model: updatedSliceModel },
370
- );
371
-
372
- if (hookResult.errors.length > 0) {
373
- return { errors: hookResult.errors };
399
+ if (hasChangedSlice) {
400
+ crUpdatesPromises.push(
401
+ this.sliceMachinePluginRunner.callHook("slice:update", {
402
+ libraryID: library.libraryID,
403
+ model: updatedSliceModel,
404
+ }),
405
+ );
374
406
  }
375
407
  }
376
408
  }
409
+
410
+ // Process all the Content Relationship updates at once.
411
+ const crUpdatesResults = await Promise.all(crUpdatesPromises);
412
+
413
+ if (crUpdatesResults.some((result) => result.errors.length > 0)) {
414
+ return {
415
+ errors: crUpdatesResults.flatMap((result) => result.errors),
416
+ };
417
+ }
377
418
  }
378
419
  }
379
420
 
421
+ return { errors: [] };
422
+ }
423
+
424
+ async updateCustomType(
425
+ args: CustomTypeUpdateHookData,
426
+ ): Promise<OnlyHookErrors<CallHookReturnType<CustomTypeUpdateHook>>> {
427
+ assertPluginsInitialized(this.sliceMachinePluginRunner);
428
+
429
+ const hookResult = await this.sliceMachinePluginRunner.callHook(
430
+ "custom-type:update",
431
+ args,
432
+ );
433
+
434
+ if (args.updateMeta?.fieldIdChanged) {
435
+ await this.updateContentRelationships(args);
436
+ }
437
+
380
438
  return { errors: hookResult.errors };
381
439
  }
382
440
 
@@ -591,3 +649,11 @@ const InferSliceResponse = z.object({
591
649
  }),
592
650
  langSmithUrl: z.string().url().optional(),
593
651
  });
652
+
653
+ function shallowClone<T>(value: T): T {
654
+ if (typeof value === "object") {
655
+ return { ...value };
656
+ }
657
+
658
+ return value;
659
+ }