@uniformdev/canvas 19.49.1 → 19.49.4-alpha.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -285,6 +285,7 @@ __export(src_exports, {
285
285
  ATTRIBUTE_PLACEHOLDER: () => ATTRIBUTE_PLACEHOLDER,
286
286
  ApiClientError: () => import_api9.ApiClientError,
287
287
  BatchEntry: () => BatchEntry,
288
+ CANVAS_BLOCK_PARAM_TYPE: () => CANVAS_BLOCK_PARAM_TYPE,
288
289
  CANVAS_DRAFT_STATE: () => CANVAS_DRAFT_STATE,
289
290
  CANVAS_EDITOR_STATE: () => CANVAS_EDITOR_STATE,
290
291
  CANVAS_ENRICHMENT_TAG_PARAM: () => CANVAS_ENRICHMENT_TAG_PARAM,
@@ -331,6 +332,7 @@ __export(src_exports, {
331
332
  bindVariables: () => bindVariables,
332
333
  bindVariablesToObject: () => bindVariablesToObject,
333
334
  compose: () => compose,
335
+ convertEntryToPutEntry: () => convertEntryToPutEntry,
334
336
  createBatchEnhancer: () => createBatchEnhancer,
335
337
  createCanvasChannel: () => createCanvasChannel,
336
338
  createEventBus: () => createEventBus,
@@ -339,14 +341,20 @@ __export(src_exports, {
339
341
  createVariableReference: () => createVariableReference,
340
342
  enhance: () => enhance,
341
343
  extractLocales: () => extractLocales,
344
+ generateComponentPlaceholderId: () => generateComponentPlaceholderId,
342
345
  generateHash: () => generateHash,
346
+ getBlockValue: () => getBlockValue,
343
347
  getChannelName: () => getChannelName,
344
348
  getComponentJsonPointer: () => getComponentJsonPointer,
345
349
  getComponentPath: () => getComponentPath,
346
350
  getParameterAttributes: () => getParameterAttributes,
351
+ getPropertiesValue: () => getPropertiesValue,
347
352
  isAddComponentMessage: () => isAddComponentMessage,
353
+ isComponentActionMessage: () => isComponentActionMessage,
354
+ isComponentPlaceholderId: () => isComponentPlaceholderId,
348
355
  isDismissPlaceholderMessage: () => isDismissPlaceholderMessage,
349
356
  isMovingComponentMessage: () => isMovingComponentMessage,
357
+ isOpenParameterEditorMessage: () => isOpenParameterEditorMessage,
350
358
  isReadyMessage: () => isReadyMessage,
351
359
  isReportRenderedCompositionsMessage: () => isReportRenderedCompositionsMessage,
352
360
  isSelectComponentMessage: () => isSelectComponentMessage,
@@ -354,6 +362,7 @@ __export(src_exports, {
354
362
  isSystemComponentDefinition: () => isSystemComponentDefinition,
355
363
  isTriggerCompositionActionMessage: () => isTriggerCompositionActionMessage,
356
364
  isUpdateComponentParameterMessage: () => isUpdateComponentParameterMessage,
365
+ isUpdateComponentReferencesMessage: () => isUpdateComponentReferencesMessage,
357
366
  isUpdateCompositionInternalMessage: () => isUpdateCompositionInternalMessage,
358
367
  isUpdateCompositionMessage: () => isUpdateCompositionMessage,
359
368
  isUpdateContextualEditingStateInternalMessage: () => isUpdateContextualEditingStateInternalMessage,
@@ -365,7 +374,8 @@ __export(src_exports, {
365
374
  parseVariableExpression: () => parseVariableExpression,
366
375
  subscribeToComposition: () => subscribeToComposition,
367
376
  unstable_CompositionRelationshipClient: () => unstable_CompositionRelationshipClient,
368
- walkComponentTree: () => walkComponentTree
377
+ walkComponentTree: () => walkComponentTree,
378
+ walkNodeTree: () => walkNodeTree
369
379
  });
370
380
  module.exports = __toCommonJS(src_exports);
371
381
 
@@ -1023,13 +1033,93 @@ function isPromise(obj) {
1023
1033
  return !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
1024
1034
  }
1025
1035
 
1026
- // src/enhancement/walkComponentTree.ts
1027
- function walkComponentTree(component, visitor, initialContext) {
1028
- var _a;
1036
+ // src/enhancement/getComponentPath.ts
1037
+ function getComponentPath(ancestorsAndSelf) {
1038
+ const path = [];
1039
+ for (let i = ancestorsAndSelf.length - 1; i >= 0; i--) {
1040
+ const currentLocation = ancestorsAndSelf[i];
1041
+ const parentLocation = ancestorsAndSelf[i + 1];
1042
+ if ("type" in currentLocation && currentLocation.type !== "slot") {
1043
+ if (currentLocation.type === "block") {
1044
+ const { fieldName, blockIndex } = currentLocation;
1045
+ if (fieldName && blockIndex !== void 0) {
1046
+ const noun = parentLocation && "type" in parentLocation && parentLocation.type === "block" ? "fields" : "parameters";
1047
+ path.push(`${noun}.${fieldName}.value[${blockIndex}]`);
1048
+ }
1049
+ } else {
1050
+ }
1051
+ continue;
1052
+ }
1053
+ const { parentSlot, parentSlotIndex } = currentLocation;
1054
+ if (parentSlot && parentSlotIndex !== void 0) {
1055
+ path.push(`${parentSlot}[${parentSlotIndex}]`);
1056
+ }
1057
+ }
1058
+ return `.${path.join(".")}`;
1059
+ }
1060
+
1061
+ // src/utils/constants.ts
1062
+ var CANVAS_PERSONALIZE_TYPE = "$personalization";
1063
+ var CANVAS_TEST_TYPE = "$test";
1064
+ var CANVAS_LOCALIZATION_TYPE = "$localization";
1065
+ var CANVAS_INTENT_TAG_PARAM = "intentTag";
1066
+ var CANVAS_LOCALE_TAG_PARAM = "locale";
1067
+ var CANVAS_BLOCK_PARAM_TYPE = "$block";
1068
+ var CANVAS_PERSONALIZE_SLOT = "pz";
1069
+ var CANVAS_TEST_SLOT = "test";
1070
+ var CANVAS_LOCALIZATION_SLOT = "localized";
1071
+ var CANVAS_DRAFT_STATE = 0;
1072
+ var CANVAS_PUBLISHED_STATE = 64;
1073
+ var CANVAS_EDITOR_STATE = 63;
1074
+ var CANVAS_PERSONALIZATION_PARAM = "$pzCrit";
1075
+ var CANVAS_TEST_VARIANT_PARAM = "$tstVrnt";
1076
+ var CANVAS_ENRICHMENT_TAG_PARAM = "$enr";
1077
+ var IN_CONTEXT_EDITOR_QUERY_STRING_PARAM = "is_incontext_editing_mode";
1078
+ var IN_CONTEXT_EDITOR_PLAYGROUND_QUERY_STRING_PARAM = "is_incontext_editing_playground";
1079
+ var IN_CONTEXT_EDITOR_CONFIG_CHECK_QUERY_STRING_PARAM = "is_config_check";
1080
+ var IN_CONTEXT_EDITOR_COMPONENT_START_ROLE = "uniform-component-start";
1081
+ var IN_CONTEXT_EDITOR_COMPONENT_END_ROLE = "uniform-component-end";
1082
+ var IN_CONTEXT_EDITOR_EMBED_SCRIPT_ID = "uniform-canvas-preview-script";
1083
+ var IS_RENDERED_BY_UNIFORM_ATTRIBUTE = "data-is-rendered-by-uniform";
1084
+ var PLACEHOLDER_ID = "placeholder";
1085
+ var EMPTY_COMPOSITION = {
1086
+ _id: "_empty_composition_id",
1087
+ _name: "An empty composition used for contextual editing",
1088
+ type: "_empty_composition_type"
1089
+ };
1090
+ var EDGE_MIN_CACHE_TTL = 15;
1091
+ var EDGE_MAX_CACHE_TTL = 600;
1092
+ var EDGE_DEFAULT_CACHE_TTL = 30;
1093
+ var EDGE_CACHE_DISABLED = -1;
1094
+ var EDGE_MIN_L2_CACHE_TTL_IN_HOURS = 1;
1095
+ var EDGE_MAX_L2_CACHE_TTL_IN_HOURS = 4 * 7 * 24;
1096
+ var EDGE_DEFAULT_L2_CACHE_TTL_IN_HOURS = 24;
1097
+
1098
+ // src/utils/entryConverter.ts
1099
+ function convertEntryToPutEntry(entry) {
1100
+ return {
1101
+ entry: {
1102
+ type: entry.entry.type,
1103
+ _dataResources: entry.entry._dataResources,
1104
+ _id: entry.entry._id,
1105
+ _slug: entry.entry._slug,
1106
+ fields: entry.entry.fields
1107
+ },
1108
+ state: entry.state,
1109
+ projectId: entry.projectId
1110
+ };
1111
+ }
1112
+ function getPropertiesValue(entity) {
1113
+ return "parameters" in entity && entity.parameters ? entity.parameters : "fields" in entity && entity.fields ? entity.fields : void 0;
1114
+ }
1115
+
1116
+ // src/enhancement/walkNodeTree.ts
1117
+ function walkNodeTree(node, visitor, options) {
1118
+ var _a, _b;
1029
1119
  const componentQueue = [
1030
1120
  {
1031
- ancestorsAndSelf: [{ component, parentSlot: void 0, parentSlotIndex: void 0 }],
1032
- context: initialContext
1121
+ ancestorsAndSelf: Array.isArray(node) ? node : [{ node, type: "root" }],
1122
+ context: options == null ? void 0 : options.initialContext
1033
1123
  }
1034
1124
  ];
1035
1125
  const childContexts = /* @__PURE__ */ new Map();
@@ -1039,81 +1129,182 @@ function walkComponentTree(component, visitor, initialContext) {
1039
1129
  continue;
1040
1130
  const currentComponent = currentQueueEntry.ancestorsAndSelf[0];
1041
1131
  let visitDescendants = true;
1042
- let descendantContext = (_a = childContexts.get(currentComponent.component)) != null ? _a : currentQueueEntry.context;
1043
- visitor(
1044
- currentComponent.component,
1045
- currentQueueEntry.ancestorsAndSelf,
1046
- {
1047
- replaceComponent: (replacementComponent) => {
1048
- Object.assign(currentComponent.component, replacementComponent);
1049
- const propertiesToCheck = [
1050
- "parameters",
1051
- "variant",
1052
- "slots",
1053
- "data",
1054
- "_pattern",
1055
- "_patternError"
1056
- ];
1057
- propertiesToCheck.forEach((property) => {
1058
- if (!replacementComponent[property]) {
1059
- delete currentComponent.component[property];
1132
+ let descendantContext = (_a = childContexts.get(currentComponent.node)) != null ? _a : currentQueueEntry.context;
1133
+ let visitorInfo;
1134
+ if (currentComponent.type === "root" || currentComponent.type === "slot") {
1135
+ visitorInfo = {
1136
+ type: "component",
1137
+ node: currentComponent.node,
1138
+ ancestorsAndSelf: currentQueueEntry.ancestorsAndSelf,
1139
+ actions: {
1140
+ replace: (replacementComponent) => {
1141
+ Object.assign(currentComponent.node, replacementComponent);
1142
+ const propertiesToCheck = [
1143
+ "parameters",
1144
+ "variant",
1145
+ "slots",
1146
+ "data",
1147
+ "_pattern",
1148
+ "_patternError",
1149
+ "_dataResources",
1150
+ "_overridability",
1151
+ "_overrides",
1152
+ "_patternDataResources"
1153
+ ];
1154
+ propertiesToCheck.forEach((property) => {
1155
+ if (!replacementComponent[property]) {
1156
+ delete currentComponent.node[property];
1157
+ }
1158
+ });
1159
+ },
1160
+ remove: () => {
1161
+ const currentComponentLocation = currentQueueEntry.ancestorsAndSelf[0];
1162
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1163
+ if (currentComponentLocation.type === "root") {
1164
+ throw new Error("Unable to delete root node.");
1060
1165
  }
1061
- });
1062
- },
1063
- removeComponent: () => {
1064
- const { parentSlot, parentSlotIndex } = currentQueueEntry.ancestorsAndSelf[0];
1065
- const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1066
- if (parentSlot && typeof parentSlotIndex !== "undefined") {
1067
- parentComponent.component.slots[parentSlot].splice(parentSlotIndex, 1);
1068
- } else {
1069
- throw new Error("Unable to delete composition.");
1166
+ if (currentComponentLocation.type === "slot") {
1167
+ const { parentSlot, parentSlotIndex } = currentComponentLocation;
1168
+ parentComponent.node.slots[parentSlot].splice(parentSlotIndex, 1);
1169
+ } else {
1170
+ throw new Error("Unknown node type");
1171
+ }
1172
+ },
1173
+ insertAfter: (nodes) => {
1174
+ const nodesToInsert = Array.isArray(nodes) ? nodes : [nodes];
1175
+ const currentNodeInfo = currentQueueEntry.ancestorsAndSelf[0];
1176
+ if (currentNodeInfo.type === "root") {
1177
+ throw new Error("Unable to insert after root node.");
1178
+ }
1179
+ if (currentNodeInfo.type === "slot") {
1180
+ const { parentSlot, parentSlotIndex } = currentNodeInfo;
1181
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1182
+ if (parentSlot && typeof parentSlotIndex !== "undefined") {
1183
+ parentComponent.node.slots[parentSlot].splice(
1184
+ parentSlotIndex + 1,
1185
+ 0,
1186
+ ...nodesToInsert
1187
+ );
1188
+ componentQueue.unshift(
1189
+ ...nodesToInsert.map((enqueueingComponent) => ({
1190
+ type: "slot",
1191
+ ancestorsAndSelf: [
1192
+ {
1193
+ type: "slot",
1194
+ node: enqueueingComponent,
1195
+ parentSlot,
1196
+ get parentSlotIndex() {
1197
+ return parentComponent.node.slots[parentSlot].findIndex(
1198
+ (x) => x === enqueueingComponent
1199
+ );
1200
+ }
1201
+ },
1202
+ // slice removes 'self' since we are inserting a peer of self
1203
+ ...currentQueueEntry.ancestorsAndSelf.slice(1)
1204
+ ],
1205
+ context: descendantContext
1206
+ }))
1207
+ );
1208
+ }
1209
+ } else {
1210
+ throw new Error("Unknown type");
1211
+ }
1212
+ },
1213
+ stopProcessingDescendants() {
1214
+ visitDescendants = false;
1215
+ },
1216
+ setDescendantsContext(context) {
1217
+ descendantContext = context;
1218
+ },
1219
+ setChildContext(child, context) {
1220
+ childContexts.set(child, context);
1070
1221
  }
1071
1222
  },
1072
- insertAfter: (components) => {
1073
- const componentsToInsert = Array.isArray(components) ? components : [components];
1074
- const { parentSlot, parentSlotIndex } = currentQueueEntry.ancestorsAndSelf[0];
1075
- const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1076
- if (parentSlot && typeof parentSlotIndex !== "undefined") {
1077
- parentComponent.component.slots[parentSlot].splice(
1078
- parentSlotIndex + 1,
1079
- 0,
1080
- ...componentsToInsert
1081
- );
1082
- componentQueue.unshift(
1083
- ...componentsToInsert.map((enqueueingComponent) => ({
1084
- ancestorsAndSelf: [
1085
- {
1086
- component: enqueueingComponent,
1087
- parentSlot,
1088
- get parentSlotIndex() {
1089
- return parentComponent.component.slots[parentSlot].findIndex(
1090
- (x) => x === enqueueingComponent
1091
- );
1092
- }
1093
- },
1094
- ...currentQueueEntry.ancestorsAndSelf
1095
- ],
1096
- context: descendantContext
1097
- }))
1098
- );
1099
- } else {
1100
- throw new Error("Unable to insert after a component not in a slot.");
1223
+ context: descendantContext
1224
+ };
1225
+ } else {
1226
+ visitorInfo = {
1227
+ type: "entry",
1228
+ node: currentComponent.node,
1229
+ ancestorsAndSelf: currentQueueEntry.ancestorsAndSelf,
1230
+ actions: {
1231
+ replace: (replacementNode) => {
1232
+ Object.assign(currentComponent.node, replacementNode);
1233
+ const propertiesToCheck = ["fields", "_dataResources", "_author"];
1234
+ propertiesToCheck.forEach((property) => {
1235
+ if (!replacementNode[property]) {
1236
+ delete currentComponent.node[property];
1237
+ }
1238
+ });
1239
+ },
1240
+ remove: () => {
1241
+ const currentComponentLocation = currentQueueEntry.ancestorsAndSelf[0];
1242
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1243
+ if (currentComponentLocation.type === "block") {
1244
+ const { fieldName, blockIndex } = currentComponentLocation;
1245
+ const blockValue = getBlockValue(parentComponent.node, fieldName);
1246
+ blockValue.splice(blockIndex, 1);
1247
+ if (blockValue.length === 0) {
1248
+ const properties2 = getPropertiesValue(parentComponent.node);
1249
+ delete properties2[fieldName];
1250
+ }
1251
+ } else {
1252
+ throw new Error("Unknown node type");
1253
+ }
1254
+ },
1255
+ insertAfter: (nodes) => {
1256
+ const currentNodeInfo = currentQueueEntry.ancestorsAndSelf[0];
1257
+ if (currentNodeInfo.type !== "block") {
1258
+ throw new Error("Unknown type");
1259
+ }
1260
+ const { fieldName, blockIndex } = currentNodeInfo;
1261
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1262
+ const nodesToInsert = Array.isArray(nodes) ? nodes : [nodes];
1263
+ if (fieldName && typeof blockIndex !== "undefined") {
1264
+ getPropertiesValue(parentComponent.node)[fieldName].value.splice(
1265
+ blockIndex + 1,
1266
+ 0,
1267
+ ...nodesToInsert
1268
+ );
1269
+ componentQueue.unshift(
1270
+ ...nodesToInsert.map((enqueueingComponent) => ({
1271
+ ancestorsAndSelf: [
1272
+ {
1273
+ type: "block",
1274
+ node: enqueueingComponent,
1275
+ fieldName,
1276
+ get blockIndex() {
1277
+ const parentArray = getPropertiesValue(parentComponent.node)[fieldName].value;
1278
+ return parentArray.findIndex((x) => x === enqueueingComponent);
1279
+ }
1280
+ },
1281
+ // slice removes 'self' since we are inserting a peer of self
1282
+ ...currentQueueEntry.ancestorsAndSelf.slice(1)
1283
+ ],
1284
+ context: descendantContext
1285
+ }))
1286
+ );
1287
+ }
1288
+ },
1289
+ stopProcessingDescendants() {
1290
+ visitDescendants = false;
1291
+ },
1292
+ setDescendantsContext(context) {
1293
+ descendantContext = context;
1294
+ },
1295
+ setChildContext(child, context) {
1296
+ childContexts.set(child, context);
1101
1297
  }
1102
1298
  },
1103
- stopProcessingDescendants() {
1104
- visitDescendants = false;
1105
- },
1106
- setDescendantsContext(context) {
1107
- descendantContext = context;
1108
- },
1109
- setChildContext(child, context) {
1110
- childContexts.set(child, context);
1111
- }
1112
- },
1113
- descendantContext
1114
- );
1115
- const slots = currentComponent.component.slots;
1116
- if (visitDescendants && slots) {
1299
+ context: descendantContext
1300
+ };
1301
+ }
1302
+ visitor(visitorInfo);
1303
+ if (!visitDescendants) {
1304
+ continue;
1305
+ }
1306
+ const slots = "slots" in currentComponent.node && currentComponent.node.slots;
1307
+ if (slots) {
1117
1308
  const slotKeys = Object.keys(slots);
1118
1309
  for (let slotIndex = slotKeys.length - 1; slotIndex >= 0; slotIndex--) {
1119
1310
  const slotKey = slotKeys[slotIndex];
@@ -1123,10 +1314,11 @@ function walkComponentTree(component, visitor, initialContext) {
1123
1314
  componentQueue.push({
1124
1315
  ancestorsAndSelf: [
1125
1316
  {
1126
- component: enqueueingComponent,
1317
+ type: "slot",
1318
+ node: enqueueingComponent,
1127
1319
  parentSlot: slotKey,
1128
1320
  get parentSlotIndex() {
1129
- return currentComponent.component.slots[slotKey].findIndex(
1321
+ return currentComponent.node.slots[slotKey].findIndex(
1130
1322
  (x) => x === enqueueingComponent
1131
1323
  );
1132
1324
  }
@@ -1138,27 +1330,44 @@ function walkComponentTree(component, visitor, initialContext) {
1138
1330
  }
1139
1331
  }
1140
1332
  }
1141
- } while (componentQueue.length > 0);
1142
- }
1143
- function getComponentPath(ancestorsAndSelf) {
1144
- const path = [];
1145
- for (let i = ancestorsAndSelf.length - 1; i >= 0; i--) {
1146
- const { parentSlot, parentSlotIndex } = ancestorsAndSelf[i];
1147
- if (parentSlot && parentSlotIndex !== void 0) {
1148
- path.push(`${parentSlot}[${parentSlotIndex}]`);
1333
+ const properties = getPropertiesValue(currentComponent.node);
1334
+ if (properties) {
1335
+ const propertyEntries = Object.entries(properties);
1336
+ for (let propIndex = propertyEntries.length - 1; propIndex >= 0; propIndex--) {
1337
+ const [propKey, propObject] = propertyEntries[propIndex];
1338
+ if (propObject.type !== CANVAS_BLOCK_PARAM_TYPE)
1339
+ continue;
1340
+ const blocks = (_b = propObject.value) != null ? _b : [];
1341
+ for (let blockIndex = blocks.length - 1; blockIndex >= 0; blockIndex--) {
1342
+ const enqueueingBlock = blocks[blockIndex];
1343
+ componentQueue.push({
1344
+ ancestorsAndSelf: [
1345
+ {
1346
+ type: "block",
1347
+ node: enqueueingBlock,
1348
+ fieldName: propKey,
1349
+ get blockIndex() {
1350
+ return getBlockValue(currentComponent.node, propKey).findIndex(
1351
+ (x) => x === enqueueingBlock
1352
+ );
1353
+ }
1354
+ },
1355
+ ...currentQueueEntry.ancestorsAndSelf
1356
+ ],
1357
+ context: descendantContext
1358
+ });
1359
+ }
1360
+ }
1149
1361
  }
1150
- }
1151
- return `.${path.join(".")}`;
1362
+ } while (componentQueue.length > 0);
1152
1363
  }
1153
- function getComponentJsonPointer(ancestorsAndSelf, { withSlots = false } = {}) {
1154
- const path = [];
1155
- for (let i = ancestorsAndSelf.length - 1; i >= 0; i--) {
1156
- const { parentSlot, parentSlotIndex } = ancestorsAndSelf[i];
1157
- if (parentSlot && parentSlotIndex !== void 0) {
1158
- path.push(`${parentSlot}/${parentSlotIndex}`);
1159
- }
1364
+ function getBlockValue(component, parameterName) {
1365
+ var _a;
1366
+ const parameter = (_a = getPropertiesValue(component)) == null ? void 0 : _a[parameterName];
1367
+ if ((parameter == null ? void 0 : parameter.value) && parameter.type === CANVAS_BLOCK_PARAM_TYPE && Array.isArray(parameter.value)) {
1368
+ return parameter.value;
1160
1369
  }
1161
- return withSlots ? `/slots/${path.join("/slots/")}` : `/${path.join("/")}`;
1370
+ return [];
1162
1371
  }
1163
1372
 
1164
1373
  // src/enhancement/enhance.ts
@@ -1178,19 +1387,21 @@ async function enhance({
1178
1387
  const promises = [];
1179
1388
  const usedComponentEnhancers = /* @__PURE__ */ new Set();
1180
1389
  const usedParameterEnhancers = /* @__PURE__ */ new Set();
1181
- walkComponentTree(composition, (currentComponent, componentContext) => {
1390
+ walkNodeTree(composition, ({ type, node, ancestorsAndSelf, actions }) => {
1182
1391
  var _a;
1183
- Object.entries((_a = currentComponent.parameters) != null ? _a : {}).forEach(([paramName, paramValue]) => {
1184
- const enhancer = enhancers.resolveParameterEnhancer(currentComponent, paramName, paramValue);
1392
+ if (type !== "component") {
1393
+ actions.stopProcessingDescendants();
1394
+ return;
1395
+ }
1396
+ Object.entries((_a = node.parameters) != null ? _a : {}).forEach(([paramName, paramValue]) => {
1397
+ const enhancer = enhancers.resolveParameterEnhancer(node, paramName, paramValue);
1185
1398
  if (enhancer) {
1186
1399
  usedParameterEnhancers.add(enhancer);
1187
- promises.push(
1188
- enhanceParameter(currentComponent, componentContext, paramName, paramValue, enhancer, context)
1189
- );
1400
+ promises.push(enhanceParameter(node, ancestorsAndSelf, paramName, paramValue, enhancer, context));
1190
1401
  }
1191
1402
  });
1192
- const componentEnhancers = enhancers.resolveComponentEnhancers(currentComponent);
1193
- promises.push(enhanceComponent(currentComponent, componentContext, componentEnhancers, context));
1403
+ const componentEnhancers = enhancers.resolveComponentEnhancers(node);
1404
+ promises.push(enhanceComponent(node, ancestorsAndSelf, componentEnhancers, context));
1194
1405
  usedComponentEnhancers.add(componentEnhancers);
1195
1406
  });
1196
1407
  promises.push(
@@ -1408,41 +1619,30 @@ var EnhancerBuilder = class {
1408
1619
  }
1409
1620
  };
1410
1621
 
1411
- // src/utils/constants.ts
1412
- var CANVAS_PERSONALIZE_TYPE = "$personalization";
1413
- var CANVAS_TEST_TYPE = "$test";
1414
- var CANVAS_LOCALIZATION_TYPE = "$localization";
1415
- var CANVAS_INTENT_TAG_PARAM = "intentTag";
1416
- var CANVAS_LOCALE_TAG_PARAM = "locale";
1417
- var CANVAS_PERSONALIZE_SLOT = "pz";
1418
- var CANVAS_TEST_SLOT = "test";
1419
- var CANVAS_LOCALIZATION_SLOT = "localized";
1420
- var CANVAS_DRAFT_STATE = 0;
1421
- var CANVAS_PUBLISHED_STATE = 64;
1422
- var CANVAS_EDITOR_STATE = 63;
1423
- var CANVAS_PERSONALIZATION_PARAM = "$pzCrit";
1424
- var CANVAS_TEST_VARIANT_PARAM = "$tstVrnt";
1425
- var CANVAS_ENRICHMENT_TAG_PARAM = "$enr";
1426
- var IN_CONTEXT_EDITOR_QUERY_STRING_PARAM = "is_incontext_editing_mode";
1427
- var IN_CONTEXT_EDITOR_PLAYGROUND_QUERY_STRING_PARAM = "is_incontext_editing_playground";
1428
- var IN_CONTEXT_EDITOR_CONFIG_CHECK_QUERY_STRING_PARAM = "is_config_check";
1429
- var IN_CONTEXT_EDITOR_COMPONENT_START_ROLE = "uniform-component-start";
1430
- var IN_CONTEXT_EDITOR_COMPONENT_END_ROLE = "uniform-component-end";
1431
- var IN_CONTEXT_EDITOR_EMBED_SCRIPT_ID = "uniform-canvas-preview-script";
1432
- var IS_RENDERED_BY_UNIFORM_ATTRIBUTE = "data-is-rendered-by-uniform";
1433
- var PLACEHOLDER_ID = "placeholder";
1434
- var EMPTY_COMPOSITION = {
1435
- _id: "_empty_composition_id",
1436
- _name: "An empty composition used for contextual editing",
1437
- type: "_empty_composition_type"
1438
- };
1439
- var EDGE_MIN_CACHE_TTL = 15;
1440
- var EDGE_MAX_CACHE_TTL = 600;
1441
- var EDGE_DEFAULT_CACHE_TTL = 30;
1442
- var EDGE_CACHE_DISABLED = -1;
1443
- var EDGE_MIN_L2_CACHE_TTL_IN_HOURS = 1;
1444
- var EDGE_MAX_L2_CACHE_TTL_IN_HOURS = 4 * 7 * 24;
1445
- var EDGE_DEFAULT_L2_CACHE_TTL_IN_HOURS = 24;
1622
+ // src/enhancement/getComponentJsonPointer.ts
1623
+ function getComponentJsonPointer(ancestorsAndSelf) {
1624
+ const path = [];
1625
+ for (let i = ancestorsAndSelf.length - 1; i >= 0; i--) {
1626
+ const currentLocation = ancestorsAndSelf[i];
1627
+ const parentLocation = ancestorsAndSelf[i + 1];
1628
+ if ("type" in currentLocation && currentLocation.type !== "slot") {
1629
+ if (currentLocation.type === "block") {
1630
+ const { fieldName: parameterName, blockIndex } = currentLocation;
1631
+ if (parameterName && blockIndex !== void 0) {
1632
+ const noun = parentLocation && "type" in parentLocation && parentLocation.type === "block" ? "fields" : "parameters";
1633
+ path.push(`${noun}/${parameterName}/value/${blockIndex}`);
1634
+ }
1635
+ } else {
1636
+ }
1637
+ continue;
1638
+ }
1639
+ const { parentSlot, parentSlotIndex } = currentLocation;
1640
+ if (parentSlot && parentSlotIndex !== void 0) {
1641
+ path.push(`slots/${parentSlot}/${parentSlotIndex}`);
1642
+ }
1643
+ }
1644
+ return `/${path.join("/")}`;
1645
+ }
1446
1646
 
1447
1647
  // src/enhancement/localize.ts
1448
1648
  function extractLocales({ component }) {
@@ -1463,22 +1663,26 @@ function localize({
1463
1663
  composition,
1464
1664
  locale
1465
1665
  }) {
1466
- walkComponentTree(composition, (currentComponent, _componentContext, actions) => {
1467
- if (currentComponent.type === CANVAS_LOCALIZATION_TYPE) {
1468
- const locales = extractLocales({ component: currentComponent });
1469
- const resolvedLocale = typeof locale === "string" ? locale : locale({ component: currentComponent, locales });
1666
+ walkNodeTree(composition, ({ type, node, actions }) => {
1667
+ if (type !== "component") {
1668
+ actions.stopProcessingDescendants();
1669
+ return;
1670
+ }
1671
+ if (node.type === CANVAS_LOCALIZATION_TYPE) {
1672
+ const locales = extractLocales({ component: node });
1673
+ const resolvedLocale = typeof locale === "string" ? locale : locale({ component: node, locales });
1470
1674
  let replaceComponent;
1471
1675
  if (resolvedLocale) {
1472
1676
  replaceComponent = locales[resolvedLocale];
1473
1677
  }
1474
1678
  if (replaceComponent == null ? void 0 : replaceComponent.length) {
1475
1679
  const [first, ...rest] = replaceComponent;
1476
- actions.replaceComponent(first);
1680
+ actions.replace(first);
1477
1681
  if (rest.length) {
1478
1682
  actions.insertAfter(rest);
1479
1683
  }
1480
1684
  } else {
1481
- actions.removeComponent();
1685
+ actions.remove();
1482
1686
  }
1483
1687
  }
1484
1688
  });
@@ -1511,6 +1715,124 @@ var UniqueBatchEntries = class {
1511
1715
  }
1512
1716
  };
1513
1717
 
1718
+ // src/enhancement/walkComponentTree.ts
1719
+ function walkComponentTree(component, visitor, initialContext) {
1720
+ var _a;
1721
+ const componentQueue = [
1722
+ {
1723
+ ancestorsAndSelf: [{ component, parentSlot: void 0, parentSlotIndex: void 0 }],
1724
+ context: initialContext
1725
+ }
1726
+ ];
1727
+ const childContexts = /* @__PURE__ */ new Map();
1728
+ do {
1729
+ const currentQueueEntry = componentQueue.pop();
1730
+ if (!currentQueueEntry)
1731
+ continue;
1732
+ const currentComponent = currentQueueEntry.ancestorsAndSelf[0];
1733
+ let visitDescendants = true;
1734
+ let descendantContext = (_a = childContexts.get(currentComponent.component)) != null ? _a : currentQueueEntry.context;
1735
+ visitor(
1736
+ currentComponent.component,
1737
+ currentQueueEntry.ancestorsAndSelf,
1738
+ {
1739
+ replaceComponent: (replacementComponent) => {
1740
+ Object.assign(currentComponent.component, replacementComponent);
1741
+ const propertiesToCheck = [
1742
+ "parameters",
1743
+ "variant",
1744
+ "slots",
1745
+ "data",
1746
+ "_pattern",
1747
+ "_patternError"
1748
+ ];
1749
+ propertiesToCheck.forEach((property) => {
1750
+ if (!replacementComponent[property]) {
1751
+ delete currentComponent.component[property];
1752
+ }
1753
+ });
1754
+ },
1755
+ removeComponent: () => {
1756
+ const { parentSlot, parentSlotIndex } = currentQueueEntry.ancestorsAndSelf[0];
1757
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1758
+ if (parentSlot && typeof parentSlotIndex !== "undefined") {
1759
+ parentComponent.component.slots[parentSlot].splice(parentSlotIndex, 1);
1760
+ } else {
1761
+ throw new Error("Unable to delete composition.");
1762
+ }
1763
+ },
1764
+ insertAfter: (components) => {
1765
+ const componentsToInsert = Array.isArray(components) ? components : [components];
1766
+ const { parentSlot, parentSlotIndex } = currentQueueEntry.ancestorsAndSelf[0];
1767
+ const parentComponent = currentQueueEntry.ancestorsAndSelf[1];
1768
+ if (parentSlot && typeof parentSlotIndex !== "undefined") {
1769
+ parentComponent.component.slots[parentSlot].splice(
1770
+ parentSlotIndex + 1,
1771
+ 0,
1772
+ ...componentsToInsert
1773
+ );
1774
+ componentQueue.unshift(
1775
+ ...componentsToInsert.map((enqueueingComponent) => ({
1776
+ ancestorsAndSelf: [
1777
+ {
1778
+ component: enqueueingComponent,
1779
+ parentSlot,
1780
+ get parentSlotIndex() {
1781
+ return parentComponent.component.slots[parentSlot].findIndex(
1782
+ (x) => x === enqueueingComponent
1783
+ );
1784
+ }
1785
+ },
1786
+ ...currentQueueEntry.ancestorsAndSelf
1787
+ ],
1788
+ context: descendantContext
1789
+ }))
1790
+ );
1791
+ } else {
1792
+ throw new Error("Unable to insert after a component not in a slot.");
1793
+ }
1794
+ },
1795
+ stopProcessingDescendants() {
1796
+ visitDescendants = false;
1797
+ },
1798
+ setDescendantsContext(context) {
1799
+ descendantContext = context;
1800
+ },
1801
+ setChildContext(child, context) {
1802
+ childContexts.set(child, context);
1803
+ }
1804
+ },
1805
+ descendantContext
1806
+ );
1807
+ const slots = currentComponent.component.slots;
1808
+ if (visitDescendants && slots) {
1809
+ const slotKeys = Object.keys(slots);
1810
+ for (let slotIndex = slotKeys.length - 1; slotIndex >= 0; slotIndex--) {
1811
+ const slotKey = slotKeys[slotIndex];
1812
+ const components = slots[slotKey];
1813
+ for (let componentIndex = components.length - 1; componentIndex >= 0; componentIndex--) {
1814
+ const enqueueingComponent = components[componentIndex];
1815
+ componentQueue.push({
1816
+ ancestorsAndSelf: [
1817
+ {
1818
+ component: enqueueingComponent,
1819
+ parentSlot: slotKey,
1820
+ get parentSlotIndex() {
1821
+ return currentComponent.component.slots[slotKey].findIndex(
1822
+ (x) => x === enqueueingComponent
1823
+ );
1824
+ }
1825
+ },
1826
+ ...currentQueueEntry.ancestorsAndSelf
1827
+ ],
1828
+ context: descendantContext
1829
+ });
1830
+ }
1831
+ }
1832
+ }
1833
+ } while (componentQueue.length > 0);
1834
+ }
1835
+
1514
1836
  // src/utils/hash.ts
1515
1837
  var generateHash = ({
1516
1838
  composition,
@@ -1536,6 +1858,9 @@ var isSelectComponentMessage = (message) => {
1536
1858
  var isReadyMessage = (message) => {
1537
1859
  return message.type === "ready";
1538
1860
  };
1861
+ var isComponentActionMessage = (message) => {
1862
+ return message.type === "trigger-component-action";
1863
+ };
1539
1864
  var isUpdateCompositionMessage = (message) => {
1540
1865
  return message.type === "update-composition";
1541
1866
  };
@@ -1569,6 +1894,12 @@ var isReportRenderedCompositionsMessage = (message) => {
1569
1894
  var isSelectParameterMessage = (message) => {
1570
1895
  return message.type === "select-parameter";
1571
1896
  };
1897
+ var isOpenParameterEditorMessage = (message) => {
1898
+ return message.type === "open-parameter-editor";
1899
+ };
1900
+ var isUpdateComponentReferencesMessage = (message) => {
1901
+ return message.type === "update-component-references";
1902
+ };
1572
1903
  var createCanvasChannel = ({
1573
1904
  listenTo,
1574
1905
  broadcastTo
@@ -1629,6 +1960,13 @@ var createCanvasChannel = ({
1629
1960
  };
1630
1961
  postMessage(message);
1631
1962
  };
1963
+ const triggerComponentAction = (options) => {
1964
+ const message = {
1965
+ ...options,
1966
+ type: "trigger-component-action"
1967
+ };
1968
+ postMessage(message);
1969
+ };
1632
1970
  const addComponent = (options) => {
1633
1971
  const message = {
1634
1972
  ...options,
@@ -1671,12 +2009,7 @@ var createCanvasChannel = ({
1671
2009
  };
1672
2010
  postMessage(message);
1673
2011
  };
1674
- const updateContextualEditingStateInternal = (options) => {
1675
- const message = {
1676
- ...options,
1677
- type: "update-contextual-editing-state-internal"
1678
- };
1679
- postMessage(message);
2012
+ const updateContextualEditingStateInternal = () => {
1680
2013
  };
1681
2014
  const reportRenderedCompositions = (options) => {
1682
2015
  const message = {
@@ -1692,12 +2025,26 @@ var createCanvasChannel = ({
1692
2025
  };
1693
2026
  postMessage(message);
1694
2027
  };
2028
+ const openParameterEditor = (options) => {
2029
+ const message = {
2030
+ ...options,
2031
+ type: "open-parameter-editor"
2032
+ };
2033
+ postMessage(message);
2034
+ };
1695
2035
  const editorStateUpdated = () => {
1696
2036
  const message = {
1697
2037
  type: "editor-state-updated"
1698
2038
  };
1699
2039
  postMessage(message);
1700
2040
  };
2041
+ const updateComponentReferences = (options) => {
2042
+ const message = {
2043
+ ...options,
2044
+ type: "update-component-references"
2045
+ };
2046
+ postMessage(message);
2047
+ };
1701
2048
  const messageEventListener = (event) => {
1702
2049
  if (typeof event.data !== "string") {
1703
2050
  return;
@@ -1727,6 +2074,7 @@ var createCanvasChannel = ({
1727
2074
  return {
1728
2075
  ready,
1729
2076
  destroy,
2077
+ triggerComponentAction,
1730
2078
  selectComponent,
1731
2079
  updateComposition,
1732
2080
  updateCompositionInternal,
@@ -1739,8 +2087,10 @@ var createCanvasChannel = ({
1739
2087
  updatePreviewSettings,
1740
2088
  updateContextualEditingStateInternal,
1741
2089
  selectParameter,
2090
+ openParameterEditor,
1742
2091
  reportRenderedCompositions,
1743
- editorStateUpdated
2092
+ editorStateUpdated,
2093
+ updateComponentReferences
1744
2094
  };
1745
2095
  };
1746
2096
 
@@ -1931,6 +2281,17 @@ function mapSlotToTestVariations(slot) {
1931
2281
  });
1932
2282
  }
1933
2283
 
2284
+ // src/utils/placeholder.ts
2285
+ var isComponentPlaceholderId = (id) => {
2286
+ if (id === PLACEHOLDER_ID) {
2287
+ return true;
2288
+ }
2289
+ return id == null ? void 0 : id.startsWith(PLACEHOLDER_ID);
2290
+ };
2291
+ var generateComponentPlaceholderId = (randomId) => {
2292
+ return `${PLACEHOLDER_ID}_${randomId}`;
2293
+ };
2294
+
1934
2295
  // src/utils/variables/parseVariableExpression.ts
1935
2296
  var escapeCharacter = "\\";
1936
2297
  var variablePrefix = "${";
@@ -2066,7 +2427,15 @@ function bindVariablesToObjectRecursive({
2066
2427
  boundCount += bindResult.boundCount;
2067
2428
  draft[property] = bindResult.result;
2068
2429
  if (bindResult.errors) {
2069
- errors.push(...bindResult.errors.map((e) => `${currentObjectPath}: ${e}`));
2430
+ errors.push(
2431
+ ...bindResult.errors.map((e) => {
2432
+ if (typeof e === "string") {
2433
+ return `${currentObjectPath}: ${e}`;
2434
+ }
2435
+ e.message = `${currentObjectPath}: ${e.message}`;
2436
+ return e;
2437
+ })
2438
+ );
2070
2439
  }
2071
2440
  }
2072
2441
  return;
@@ -2118,6 +2487,7 @@ var CanvasClientError = import_api9.ApiClientError;
2118
2487
  ATTRIBUTE_PLACEHOLDER,
2119
2488
  ApiClientError,
2120
2489
  BatchEntry,
2490
+ CANVAS_BLOCK_PARAM_TYPE,
2121
2491
  CANVAS_DRAFT_STATE,
2122
2492
  CANVAS_EDITOR_STATE,
2123
2493
  CANVAS_ENRICHMENT_TAG_PARAM,
@@ -2164,6 +2534,7 @@ var CanvasClientError = import_api9.ApiClientError;
2164
2534
  bindVariables,
2165
2535
  bindVariablesToObject,
2166
2536
  compose,
2537
+ convertEntryToPutEntry,
2167
2538
  createBatchEnhancer,
2168
2539
  createCanvasChannel,
2169
2540
  createEventBus,
@@ -2172,14 +2543,20 @@ var CanvasClientError = import_api9.ApiClientError;
2172
2543
  createVariableReference,
2173
2544
  enhance,
2174
2545
  extractLocales,
2546
+ generateComponentPlaceholderId,
2175
2547
  generateHash,
2548
+ getBlockValue,
2176
2549
  getChannelName,
2177
2550
  getComponentJsonPointer,
2178
2551
  getComponentPath,
2179
2552
  getParameterAttributes,
2553
+ getPropertiesValue,
2180
2554
  isAddComponentMessage,
2555
+ isComponentActionMessage,
2556
+ isComponentPlaceholderId,
2181
2557
  isDismissPlaceholderMessage,
2182
2558
  isMovingComponentMessage,
2559
+ isOpenParameterEditorMessage,
2183
2560
  isReadyMessage,
2184
2561
  isReportRenderedCompositionsMessage,
2185
2562
  isSelectComponentMessage,
@@ -2187,6 +2564,7 @@ var CanvasClientError = import_api9.ApiClientError;
2187
2564
  isSystemComponentDefinition,
2188
2565
  isTriggerCompositionActionMessage,
2189
2566
  isUpdateComponentParameterMessage,
2567
+ isUpdateComponentReferencesMessage,
2190
2568
  isUpdateCompositionInternalMessage,
2191
2569
  isUpdateCompositionMessage,
2192
2570
  isUpdateContextualEditingStateInternalMessage,
@@ -2198,5 +2576,6 @@ var CanvasClientError = import_api9.ApiClientError;
2198
2576
  parseVariableExpression,
2199
2577
  subscribeToComposition,
2200
2578
  unstable_CompositionRelationshipClient,
2201
- walkComponentTree
2579
+ walkComponentTree,
2580
+ walkNodeTree
2202
2581
  });