@salesforce/lds-runtime-mobile 1.242.0 → 1.243.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/main.js +199 -131
  2. package/package.json +3 -3
  3. package/sfdc/main.js +199 -131
package/dist/main.js CHANGED
@@ -554,6 +554,9 @@ function handleDurableStoreRejection(instrument) {
554
554
  }
555
555
 
556
556
  function isStoreEntryError(storeRecord) {
557
+ if (!storeRecord || typeof storeRecord !== 'object') {
558
+ return false;
559
+ }
557
560
  return storeRecord.__type === 'error';
558
561
  }
559
562
 
@@ -6108,9 +6111,6 @@ class AbstractResourceRequestActionHandler {
6108
6111
  }
6109
6112
  async buildPendingAction(request, queue) {
6110
6113
  const targetId = await this.getIdFromRequest(request);
6111
- if (targetId === undefined) {
6112
- return Promise.reject(new Error('Cannot determine target id from the resource request'));
6113
- }
6114
6114
  const tag = this.buildTagForTargetId(targetId);
6115
6115
  const handlerActions = queue.filter((x) => x.handler === this.handlerId);
6116
6116
  if (request.method === 'post' && actionsForTag(tag, handlerActions).length > 0) {
@@ -8161,6 +8161,10 @@ function isOperationDefinitionNode(node) {
8161
8161
  return node.kind === 'OperationDefinition';
8162
8162
  }
8163
8163
 
8164
+ const POLYMORPHIC_PARENT_RELATIONSHIP = 'polymorphicParentRelationship';
8165
+ const PARENT_RELATIONSHIP = 'parentRelationship';
8166
+ const CHILD_RELATIONSHIP = 'childRelationship';
8167
+ const RECORD_QUERY = 'recordQuery';
8164
8168
  function requestsDraftsField(recordFieldNode) {
8165
8169
  if (!recordFieldNode.selectionSet)
8166
8170
  return false;
@@ -8176,18 +8180,41 @@ function isRecordQuery(recordQueryField) {
8176
8180
  directive.arguments
8177
8181
  .map((argument) => argument.value)
8178
8182
  .filter(isStringValueNode)
8179
- .some((categoryName) => categoryName.value === 'recordQuery'));
8183
+ .some((categoryName) => categoryName.value === RECORD_QUERY));
8180
8184
  });
8181
8185
  }
8182
8186
  return false;
8183
8187
  }
8184
- // finds field with 'recordQuery' and 'childRelationship' directive
8185
- function findNearestRecordQuery(ancestors) {
8186
- const recordQueryAncester = findNearestAncesterPath(ancestors, true).node;
8187
- return recordQueryAncester === undefined ? undefined : recordQueryAncester;
8188
+ // finds connection field with 'recordQuery' and 'childRelationship' directive.
8189
+ function findNearestConnection(ancestors) {
8190
+ const connectionAncestor = findNearestAncesterPath(ancestors, true).node;
8191
+ return connectionAncestor === undefined ? undefined : connectionAncestor;
8192
+ }
8193
+ // convinient method to find nearest connection with its path
8194
+ function findNearestConnectionWithPath(ancestors) {
8195
+ const closestAncestorPath = findNearestAncesterPath(ancestors, true);
8196
+ let connection = undefined;
8197
+ let connectionPath = undefined;
8198
+ if (closestAncestorPath.parentIndex > 0) {
8199
+ const connectionAncestor = closestAncestorPath.node;
8200
+ const connectionAncestors = ancestors.slice(0, closestAncestorPath.parentIndex);
8201
+ connection =
8202
+ connectionAncestor === undefined ? undefined : connectionAncestor;
8203
+ if (connection !== undefined) {
8204
+ const ancesterPath = findAncesterPath(connectionAncestors);
8205
+ connectionPath =
8206
+ ancesterPath === ''
8207
+ ? connection.name.value
8208
+ : `${ancesterPath}#${connection.name.value}`;
8209
+ }
8210
+ }
8211
+ return {
8212
+ connection,
8213
+ path: connectionPath,
8214
+ };
8188
8215
  }
8189
- // finds cloeset ancester. If 'parentRelationship' is allowed, it could be 'InlineFragmentNode' since it inherits the 'parent' relationship. 'InlineFragmentNode' makes sure that only one 'apiName' returns when tree is traversed.
8190
- function findNearestAncesterPath(ancestors, recordQueryOnly) {
8216
+ // finds closest ancestor. If node with 'parentRelationship' is the ancester, the end result could be 'InlineFragmentNode' since it inherits the 'parent' relationship. 'InlineFragmentNode' makes sure that only one 'apiName' returns when tree is traversed.
8217
+ function findNearestAncesterPath(ancestors, connectionOnly) {
8191
8218
  let recordQueryPath = { node: undefined, parentIndex: -1 };
8192
8219
  let relationship = '';
8193
8220
  for (let i = ancestors.length - 1; i >= 0; i--) {
@@ -8201,9 +8228,11 @@ function findNearestAncesterPath(ancestors, recordQueryOnly) {
8201
8228
  continue;
8202
8229
  for (let arg of directive.arguments) {
8203
8230
  if (arg.value &&
8204
- (arg.value.value === 'recordQuery' ||
8205
- arg.value.value === 'childRelationship' ||
8206
- (!recordQueryOnly && arg.value.value === 'parentRelationship'))) {
8231
+ (arg.value.value === RECORD_QUERY ||
8232
+ arg.value.value === CHILD_RELATIONSHIP ||
8233
+ (!connectionOnly &&
8234
+ (arg.value.value === PARENT_RELATIONSHIP ||
8235
+ arg.value.value === POLYMORPHIC_PARENT_RELATIONSHIP)))) {
8207
8236
  recordQueryPath = { node: node, parentIndex: i };
8208
8237
  relationship = arg.value.value;
8209
8238
  break;
@@ -8218,17 +8247,19 @@ function findNearestAncesterPath(ancestors, recordQueryOnly) {
8218
8247
  //checks if nearest ancester could be an inline fragment
8219
8248
  if (recordQueryPath.node !== undefined &&
8220
8249
  recordQueryPath.node.selectionSet &&
8221
- relationship === 'parentRelationship') {
8222
- //
8223
- if (recordQueryPath.node.selectionSet.selections.every(isInlineFragmentNode)) {
8224
- //
8225
- const inlineFragmentLoc = recordQueryPath.parentIndex + 2;
8226
- if (inlineFragmentLoc < ancestors.length && ancestors[inlineFragmentLoc]) {
8250
+ (relationship === PARENT_RELATIONSHIP || relationship === POLYMORPHIC_PARENT_RELATIONSHIP)) {
8251
+ // InlineFragment is usually 3 steps aways from its FieldNode parent within ancester hierarchy if it exists. The below search
8252
+ // is applied to adapt to future AST structure change
8253
+ let parentIndex = recordQueryPath.parentIndex + 1;
8254
+ while (parentIndex < ancestors.length) {
8255
+ if (isInlineFragmentNode(ancestors[parentIndex])) {
8227
8256
  recordQueryPath = {
8228
- node: ancestors[inlineFragmentLoc],
8229
- parentIndex: inlineFragmentLoc,
8257
+ node: ancestors[parentIndex],
8258
+ parentIndex,
8230
8259
  };
8260
+ break;
8231
8261
  }
8262
+ parentIndex++;
8232
8263
  }
8233
8264
  }
8234
8265
  return recordQueryPath;
@@ -8252,7 +8283,7 @@ function findAncesterPath(ancesters) {
8252
8283
  ? sectionPath
8253
8284
  : sectionPath === ''
8254
8285
  ? path
8255
- : `${sectionPath}_${path}`;
8286
+ : `${sectionPath}#${path}`;
8256
8287
  }
8257
8288
  }
8258
8289
  boundaryIndex = parentIndex;
@@ -8310,9 +8341,9 @@ function getRelation(node) {
8310
8341
  const relationships = args
8311
8342
  .map((arg) => arg.value)
8312
8343
  .filter(isStringValueNode)
8313
- .filter((valueNode) => valueNode.value === 'childRelationship' ||
8314
- valueNode.value === 'parentRelationship' ||
8315
- valueNode.value === 'polymorphicParentRelationship')
8344
+ .filter((valueNode) => valueNode.value === CHILD_RELATIONSHIP ||
8345
+ valueNode.value === PARENT_RELATIONSHIP ||
8346
+ valueNode.value === POLYMORPHIC_PARENT_RELATIONSHIP)
8316
8347
  .map((relationshipNode) => relationshipNode.value);
8317
8348
  if (relationships.length > 0) {
8318
8349
  return relationships[0];
@@ -8369,8 +8400,8 @@ function isFieldSpanning(node, parentNode) {
8369
8400
  */
8370
8401
  function isParentRelationship(node) {
8371
8402
  return (node &&
8372
- (isRelationship(node, 'parentRelationship') ||
8373
- isRelationship(node, 'polymorphicParentRelationship')));
8403
+ (isRelationship(node, PARENT_RELATIONSHIP) ||
8404
+ isRelationship(node, POLYMORPHIC_PARENT_RELATIONSHIP)));
8374
8405
  }
8375
8406
  /*
8376
8407
  checks if the InlineFragment spans
@@ -9462,7 +9493,7 @@ const parentRelationshipDirective = {
9462
9493
  },
9463
9494
  value: {
9464
9495
  kind: Kind.STRING,
9465
- value: 'parentRelationship',
9496
+ value: PARENT_RELATIONSHIP,
9466
9497
  block: false,
9467
9498
  },
9468
9499
  },
@@ -9476,7 +9507,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9476
9507
  // example 2 'ServiceAppointment' -> ['Owner']; 'Owner' -> ['User', 'Group']
9477
9508
  const objectNodeInfoTree = {};
9478
9509
  // save the field path to apiName map
9479
- // example 1: 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment_Account' -> ['Account']; 'ServiceAppointment_Account_Owner' -> ['User']
9510
+ // example 1: 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment#ccount' -> ['Account']; 'ServiceAppointment#Account#Owner' -> ['User']
9480
9511
  const pathToObjectApiNamesMap = {};
9481
9512
  let startNodes = new Set();
9482
9513
  let totalNodes = new Set();
@@ -9491,11 +9522,11 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9491
9522
  visit(originalAST, {
9492
9523
  Argument: {
9493
9524
  enter(node, key, parent, path, ancestors) {
9494
- const recordQueryNode = findNearestRecordQuery(ancestors);
9495
- if (!recordQueryNode)
9525
+ const { connection: recordConnectionNode, path: ancesterPath } = findNearestConnectionWithPath(ancestors);
9526
+ if (!recordConnectionNode || !ancesterPath)
9496
9527
  return;
9497
- if (!objectNodeInfoTree[recordQueryNode.name.value]) {
9498
- objectNodeInfoTree[recordQueryNode.name.value] = [];
9528
+ if (!objectNodeInfoTree[ancesterPath]) {
9529
+ objectNodeInfoTree[ancesterPath] = [];
9499
9530
  }
9500
9531
  switch (node.name.value) {
9501
9532
  case 'orderBy':
@@ -9503,12 +9534,12 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9503
9534
  if (node.value.kind !== 'ObjectValue') {
9504
9535
  return;
9505
9536
  }
9506
- totalNodes.add(recordQueryNode.name.value);
9537
+ totalNodes.add(ancesterPath);
9507
9538
  // 'childRelationship' node is not taken as the startNode of the 'NodeInfoTree' graph. The field scanning will construct the graph which lead here.
9508
- if (isRecordQuery(recordQueryNode)) {
9509
- startNodes.add(recordQueryNode.name.value);
9539
+ if (isRecordQuery(recordConnectionNode)) {
9540
+ startNodes.add(recordConnectionNode.name.value);
9510
9541
  }
9511
- growObjectFieldTree(objectNodeInfoTree, recordQueryNode.name.value, node.value, totalNodes, startNodes);
9542
+ growObjectFieldTree(objectNodeInfoTree, ancesterPath, node.value, totalNodes, startNodes);
9512
9543
  break;
9513
9544
  case 'scope':
9514
9545
  if (!isScopeArgumentNodeWithType(node, 'ASSIGNEDTOME', variables)) {
@@ -9523,17 +9554,16 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9523
9554
  name: 'ServiceResources',
9524
9555
  });
9525
9556
  }
9526
- if (objectNodeInfoTree['ServiceResources'] === undefined) {
9527
- objectNodeInfoTree['ServiceResources'] = [];
9528
- }
9529
- if (!objectNodeInfoTree['ServiceResources'].some((child) => child.name === 'ServiceResource')) {
9530
- objectNodeInfoTree['ServiceResources'].push({
9531
- relation: 'parent',
9532
- name: 'ServiceResource',
9533
- });
9557
+ if (objectNodeInfoTree['ServiceAppointment#ServiceResources'] === undefined) {
9558
+ objectNodeInfoTree['ServiceAppointment#ServiceResources'] = [
9559
+ {
9560
+ relation: 'parent',
9561
+ name: 'ServiceResource',
9562
+ },
9563
+ ];
9534
9564
  }
9535
- if (objectNodeInfoTree['ServiceResource'] === undefined) {
9536
- objectNodeInfoTree['ServiceResource'] = [];
9565
+ if (objectNodeInfoTree['ServiceAppointment#ServiceResources#ServiceResource'] === undefined) {
9566
+ objectNodeInfoTree['ServiceAppointment#ServiceResources#ServiceResource'] = [];
9537
9567
  }
9538
9568
  break;
9539
9569
  default:
@@ -9547,7 +9577,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9547
9577
  return;
9548
9578
  if (!node.selectionSet)
9549
9579
  return;
9550
- const recordQueryField = findNearestRecordQuery(ancestors);
9580
+ const recordQueryField = findNearestConnection(ancestors);
9551
9581
  //only injects fields for 'recordQuery' field. ignores the 'childRelationship' field since it will be traversed as the child of the 'recordQuery'
9552
9582
  if (isRecordQuery(recordQueryField) && recordQueryField) {
9553
9583
  totalNodes.add(recordQueryField.name.value);
@@ -9564,7 +9594,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9564
9594
  visit(originalAST, {
9565
9595
  Argument: {
9566
9596
  leave(node, key, parent, path, ancestors) {
9567
- const recordQueryField = findNearestRecordQuery(ancestors);
9597
+ const recordQueryField = findNearestConnection(ancestors);
9568
9598
  if (!recordQueryField)
9569
9599
  return;
9570
9600
  const ancestorPath = findAncesterPath(ancestors);
@@ -9612,7 +9642,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9612
9642
  case 'where': {
9613
9643
  inlineFragmentSelections[ancestorPath] = [
9614
9644
  ...inlineFragmentSelections[ancestorPath],
9615
- ...injectFilter(node, idState, ancestorPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, recordReferenceNode),
9645
+ ...injectFilter(node, idState, ancestorPath, false, objectInfos, pathToObjectApiNamesMap, draftFunctions, recordReferenceNode),
9616
9646
  ];
9617
9647
  break;
9618
9648
  }
@@ -9628,7 +9658,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9628
9658
  if (!node.selectionSet)
9629
9659
  return;
9630
9660
  // it could be 'recordQuery' or 'childRelationship'
9631
- const recordQueryField = findNearestRecordQuery(ancestors);
9661
+ const recordQueryField = findNearestConnection(ancestors);
9632
9662
  if (!recordQueryField)
9633
9663
  return;
9634
9664
  const ancestorPath = findAncesterPath(ancestors);
@@ -9640,7 +9670,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9640
9670
  spanningSelections.push(selection);
9641
9671
  }
9642
9672
  }
9643
- const injectedFields = injectFields(spanningSelections, node, ancestors, objectInfos, pathToObjectApiNamesMap);
9673
+ const injectedFields = injectFields(spanningSelections, node, ancestorPath, ancestors, objectInfos, pathToObjectApiNamesMap);
9644
9674
  const mergedInjectedFields = mergeSelectionNodes(inlineFragmentSelections[ancestorPath], injectedFields);
9645
9675
  inlineFragmentSelections[ancestorPath] = mergedInjectedFields;
9646
9676
  },
@@ -9653,7 +9683,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9653
9683
  // removes 'ServicesResources' query field node if 'assignedtome' scope shows up
9654
9684
  if (assignedtomeQueryFieldNode !== undefined &&
9655
9685
  node.name.value === 'ServiceResources') {
9656
- const serviceResourcesAncestor = findNearestRecordQuery(ancestors);
9686
+ const serviceResourcesAncestor = findNearestConnection(ancestors);
9657
9687
  if (serviceResourcesAncestor === assignedtomeQueryFieldNode) {
9658
9688
  return null;
9659
9689
  }
@@ -9662,7 +9692,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9662
9692
  return;
9663
9693
  if (!node.selectionSet)
9664
9694
  return;
9665
- const recordQueryField = findNearestRecordQuery(ancestors);
9695
+ const recordQueryField = findNearestConnection(ancestors);
9666
9696
  if (!recordQueryField)
9667
9697
  return;
9668
9698
  const ancestorPath = findAncesterPath(ancestors);
@@ -9865,15 +9895,16 @@ function growObjectFieldTree(tree, parentNode, entryNode, totalNodes, startNodes
9865
9895
  }
9866
9896
  // example: 'Account'
9867
9897
  const childNode = objectFieldNode.name.value;
9898
+ const childNodepath = `${parentNode}#${childNode}`;
9868
9899
  if (!tree[parentNode].some((child) => child.name === childNode)) {
9869
9900
  tree[parentNode].push({
9870
9901
  relation: 'parent',
9871
9902
  name: childNode,
9872
9903
  });
9873
- totalNodes.add(childNode);
9904
+ totalNodes.add(childNodepath);
9874
9905
  }
9875
9906
  // recursively go to deeper level of filter.
9876
- growObjectFieldTree(tree, childNode, objectFieldNode.value, totalNodes, startNodes);
9907
+ growObjectFieldTree(tree, childNodepath, objectFieldNode.value, totalNodes, startNodes);
9877
9908
  }
9878
9909
  }
9879
9910
  }
@@ -9908,19 +9939,20 @@ function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNode
9908
9939
  }
9909
9940
  if (!tree[parentSectionPath].some((field) => field.name === fieldName)) {
9910
9941
  tree[parentSectionPath].push({
9911
- relation: relationType === 'parentRelationship' ||
9912
- relationType === 'polymorphicParentRelationship'
9942
+ relation: relationType === PARENT_RELATIONSHIP ||
9943
+ relationType === POLYMORPHIC_PARENT_RELATIONSHIP
9913
9944
  ? 'parent'
9914
9945
  : 'child',
9915
9946
  name: fieldName,
9916
9947
  });
9917
- totalNodes.add(fieldName);
9948
+ totalNodes.add(`${parentSectionPath}#${fieldName}`);
9918
9949
  }
9919
9950
  if (entryNode.selectionSet && entryNode.selectionSet.selections) {
9920
9951
  const childNodes = entryNode.selectionSet.selections.filter(isFieldOrInlineFragmentNode);
9921
9952
  // recursively build the traversal tree
9922
9953
  for (const child of childNodes) {
9923
- growFieldTree(tree, fieldName, child, entryNode, totalNodes, startNodes);
9954
+ const path = `${parentSectionPath}#${fieldName}`;
9955
+ growFieldTree(tree, path, child, entryNode, totalNodes, startNodes);
9924
9956
  }
9925
9957
  }
9926
9958
  }
@@ -9950,23 +9982,23 @@ function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNode
9950
9982
  }
9951
9983
  if (!tree[parentSectionPath].some((field) => field.name === conditionName)) {
9952
9984
  tree[parentSectionPath].push({
9953
- relation: relationType === 'parentRelationship' ||
9954
- relationType === 'polymorphicParentRelationship'
9985
+ relation: relationType === PARENT_RELATIONSHIP ||
9986
+ relationType === POLYMORPHIC_PARENT_RELATIONSHIP
9955
9987
  ? 'parent'
9956
9988
  : 'child',
9957
9989
  name: conditionName,
9958
9990
  });
9959
- totalNodes.add(conditionName);
9991
+ const path = `${parentSectionPath}#${conditionName}`;
9992
+ totalNodes.add(path);
9960
9993
  }
9961
9994
  }
9962
9995
  }
9963
9996
  // dive deep immediately for 'InlineFragment'
9964
9997
  const childNodes = entryNode.selectionSet.selections.filter(isFieldOrInlineFragmentNode);
9998
+ const path = `${parentSectionPath}${entryNode.typeCondition ? '#' + entryNode.typeCondition.name.value : ''}`;
9965
9999
  // Navigates into InLineFragment
9966
10000
  for (const child of childNodes) {
9967
- growFieldTree(tree, entryNode.typeCondition
9968
- ? entryNode.typeCondition.name.value
9969
- : parentSectionPath, child, entryNode, totalNodes, startNodes);
10001
+ growFieldTree(tree, path, child, entryNode, totalNodes, startNodes);
9970
10002
  }
9971
10003
  }
9972
10004
  }
@@ -10010,7 +10042,7 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10010
10042
  }
10011
10043
  const validObjectInfoNodes = [];
10012
10044
  let updatedObjectInfoMap = {};
10013
- // InlineFragment and polymorphic field support fits into this scenario pathToObjectApiNamesMap Entry: 'ServiceAppointment_Owner' -> ['User', 'Group']; ServiceAppointment_Owner_User' -> ['User']
10045
+ // InlineFragment and polymorphic field support fits into this scenario pathToObjectApiNamesMap Entry: 'ServiceAppointment#Owner' -> ['User', 'Group']; ServiceAppointment#Owner#User' -> ['User']
10014
10046
  if (objectInfoApiNames.length > 0 &&
10015
10047
  nodesAtSameLevel.length > 0 &&
10016
10048
  objectInfoApiNames.includes(nodesAtSameLevel[0].name)) {
@@ -10022,7 +10054,7 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10022
10054
  // eslint-disable-next-line
10023
10055
  throw new Error(`Condition ${field.name} does not exists for ${parentPath}`);
10024
10056
  }
10025
- const path = `${parentPath}_${field.name}`;
10057
+ const path = `${parentPath}#${field.name}`;
10026
10058
  pathToObjectApiNamesMap[path] = [field.name];
10027
10059
  }
10028
10060
  validObjectInfoNodes.push(...nodesAtSameLevel);
@@ -10038,7 +10070,7 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10038
10070
  let apiNames = [];
10039
10071
  for (const nodeInfo of nodesAtSameLevel) {
10040
10072
  const field = nodeInfo.name;
10041
- const path = `${parentPath}_${field}`;
10073
+ const path = `${parentPath}#${field}`;
10042
10074
  // Handle 'parentRelationship'
10043
10075
  if (nodeInfo.relation === 'parent') {
10044
10076
  const relationshipId = referenceIdFieldForRelationship(field);
@@ -10056,12 +10088,12 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10056
10088
  }
10057
10089
  }
10058
10090
  // This is a polymorphic field
10059
- if (fieldDefinition.referenceToInfos.length > 1 && objectInfotree[field]) {
10091
+ if (fieldDefinition.referenceToInfos.length > 1 && objectInfotree[path]) {
10060
10092
  // Fields needs to expand and heterogenous entity ObjectInfo needs to be fetched
10061
- const referencedNodeInfos = objectInfotree[field];
10093
+ const referencedNodeInfos = objectInfotree[path];
10062
10094
  const requestedApiNames = referencedNodeInfos.map((referenceNodeInfo) => referenceNodeInfo.name);
10063
10095
  // Fetches requested ObjectInfo only. Some entity's relation field could define more than 6 references. Only references show up in query need to be handled.
10064
- if (requestedApiNames.length > 0 && objectInfotree[field]) {
10096
+ if (requestedApiNames.length > 0 && objectInfotree[path]) {
10065
10097
  fieldDefinition.referenceToInfos
10066
10098
  .filter((referenceToInfo) => requestedApiNames.includes(referenceToInfo.apiName))
10067
10099
  .forEach((ref) => {
@@ -10121,8 +10153,8 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10121
10153
  }
10122
10154
  for (const nodeInfo of validObjectInfoNodes) {
10123
10155
  const field = nodeInfo.name;
10124
- const subLevelFields = objectInfotree[field];
10125
- const path = `${parentPath}_${field}`;
10156
+ const path = `${parentPath}#${field}`;
10157
+ const subLevelFields = objectInfotree[path];
10126
10158
  if (subLevelFields && subLevelFields.length > 0) {
10127
10159
  const subObjectInfos = await fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, updatedObjectInfoMap, subLevelFields, path, objectInfoService);
10128
10160
  updatedObjectInfoMap = { ...updatedObjectInfoMap, ...subObjectInfos };
@@ -10139,27 +10171,29 @@ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectI
10139
10171
  * 'path' and 'queryNode' is 1 level above the 'filterNode'
10140
10172
  * @param filterNode filter node which needs to be injected. For example, 'State' ObjectFieldNode within filter 'where: { State: { eq: "Nova Scotia" }}'
10141
10173
  * @param idState ID state will be updated to determine if the ID fields in AST need to be swapped. The swapping happens later.
10142
- * @param path path to the current filterNode's parent. For example, path could be 'ServiceApointment' when filterNode is 'State'. If the path does not exist in 'pathToObjectApiNamesMap', parent node is not an field of relationship or recordQuery
10174
+ * @param parentPath path to the current filterNode's parent. For example, path could be 'ServiceApointment' when filterNode is 'State'. If the path does not exist in 'pathToObjectApiNamesMap', parent node is not an field of relationship or recordQuery
10175
+ * @param isParentPolymorphic true if parent points to a polymorphic field.
10143
10176
  * @param queryNode referece FieldNode which provides the information if 'filterNode' exist in it nor not.
10144
10177
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10145
10178
  * @param pathToObjectApiNamesMap map used to locate the ObjectInfo. The key is path to a field, value is the ObjectInfo's apiName array. In the case of polymorphic fields, the apiName array have 2 or more elements. For example, 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment_Account' -> ['Account'], 'ServiceAppointment_Owner' -> ['User', 'Group'].
10146
10179
  * @param draftFunctions functions for working with record ids that may be draft-created ids
10147
10180
  * @returns an array of nodes with injected fields
10148
10181
  */
10149
- function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode) {
10182
+ function injectFilter(filterNode, idState, parentPath, isParentPolymorphic, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode) {
10150
10183
  const injectedSelections = [];
10184
+ let isPolymorphicField = false;
10151
10185
  switch (filterNode.kind) {
10152
10186
  case Kind.ARGUMENT:
10153
10187
  if (filterNode.value.kind !== 'ObjectValue')
10154
10188
  return [];
10155
10189
  filterNode.value.fields.forEach((objectFieldNode) => {
10156
- let subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10190
+ let subResults = injectFilter(objectFieldNode, idState, parentPath, isParentPolymorphic, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10157
10191
  for (const subResult of subResults) {
10158
10192
  mergeOrAddToGroup(injectedSelections, subResult);
10159
10193
  }
10160
10194
  // multiple Ids might need to be swapped. remember their paths for faster write.
10161
10195
  if (idState.swapNeeded) {
10162
- idState.paths.push(path);
10196
+ idState.paths.push(parentPath);
10163
10197
  }
10164
10198
  });
10165
10199
  return injectedSelections;
@@ -10168,7 +10202,7 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10168
10202
  case Kind.LIST: {
10169
10203
  filterNode.value.values.filter(isObjectValueNode).forEach((objectValueNode) => {
10170
10204
  objectValueNode.fields.forEach((objectFieldNode) => {
10171
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10205
+ const subResults = injectFilter(objectFieldNode, idState, parentPath, isParentPolymorphic, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10172
10206
  for (const subResult of subResults) {
10173
10207
  mergeOrAddToGroup(injectedSelections, subResult);
10174
10208
  }
@@ -10179,7 +10213,7 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10179
10213
  case Kind.OBJECT: {
10180
10214
  if (filterNode.name.value === 'not') {
10181
10215
  filterNode.value.fields.forEach((objectFieldNode) => {
10182
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10216
+ const subResults = injectFilter(objectFieldNode, idState, parentPath, isParentPolymorphic, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10183
10217
  for (const subResult of subResults) {
10184
10218
  mergeOrAddToGroup(injectedSelections, subResult);
10185
10219
  }
@@ -10189,15 +10223,15 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10189
10223
  let apiNames = [];
10190
10224
  let isScalarField = false;
10191
10225
  //It is possible that this is a polymorphic field
10192
- apiNames = pathToObjectApiNamesMap[path];
10193
- // example: path: 'ServiceAppointment_LastModifiedDate'; filterNode: '{eq: {literal: LAST_WEEK}}'. queryNode: 'LastModifedDate { value}' FilterNode's parent has been verifed as a valid node
10226
+ apiNames = pathToObjectApiNamesMap[parentPath];
10227
+ // example: path: 'ServiceAppointment#LastModifiedDate'; filterNode: '{eq: {literal: LAST_WEEK}}'. queryNode: 'LastModifedDate { value}' FilterNode's parent has been verifed as a valid node
10194
10228
  if (apiNames === undefined) {
10195
10229
  isScalarField = true;
10196
10230
  }
10197
10231
  else {
10198
10232
  if (apiNames.some((apiName) => objectInfos[apiName] === undefined)) {
10199
10233
  // eslint-disable-next-line
10200
- throw new Error(`ObjectInfo is missing for ${path}`);
10234
+ throw new Error(`ObjectInfo is missing for ${parentPath}`);
10201
10235
  }
10202
10236
  }
10203
10237
  if (isScalarField) {
@@ -10221,21 +10255,17 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10221
10255
  let isSpanning = false;
10222
10256
  // if true, current node is a polymorphic concrete type node. For example, field node `User` under `Owner`
10223
10257
  let isInlineFragment = false;
10224
- let isPolymorphicField = false;
10225
10258
  let isTypeNameExisting = false;
10226
10259
  let curPath;
10227
10260
  let fieldName = filterNode.name.value;
10228
- curPath = `${path}_${fieldName}`;
10261
+ curPath = `${parentPath}#${fieldName}`;
10229
10262
  if (pathToObjectApiNamesMap[curPath] &&
10230
10263
  pathToObjectApiNamesMap[curPath].length > 0) {
10231
10264
  isSpanning = true;
10232
- if (pathToObjectApiNamesMap[curPath].length === 1 &&
10233
- pathToObjectApiNamesMap[path] &&
10234
- pathToObjectApiNamesMap[path].length >= 1 &&
10235
- pathToObjectApiNamesMap[path].includes(pathToObjectApiNamesMap[curPath][0])) {
10236
- isInlineFragment = isPolymorphicFieldPath(path, pathToObjectApiNamesMap);
10237
- }
10238
- isPolymorphicField = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap);
10265
+ isInlineFragment =
10266
+ isParentPolymorphic &&
10267
+ pathToObjectApiNamesMap[curPath].length === 1;
10268
+ isPolymorphicField = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
10239
10269
  }
10240
10270
  // When filter node is at InLineFragment Level(a concrete entity of polymorphic field), query node is one level up. For example, ObjectFieldNode is ...{User:{...}}, queryNode is Owner:[User]
10241
10271
  if (isInlineFragment) {
@@ -10281,7 +10311,7 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10281
10311
  }
10282
10312
  const objectInfoName = pathToObjectApiNamesMap[curPath] !== undefined
10283
10313
  ? pathToObjectApiNamesMap[curPath][0]
10284
- : pathToObjectApiNamesMap[path][0];
10314
+ : pathToObjectApiNamesMap[parentPath][0];
10285
10315
  const isIdField = isFieldAnIdField(filterNode.name.value, objectInfos[objectInfoName]);
10286
10316
  if (!isIdField) {
10287
10317
  let subSelectionNodes = [];
@@ -10293,7 +10323,7 @@ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNam
10293
10323
  updateIDInfo(subFieldNode, idState, draftFunctions);
10294
10324
  }
10295
10325
  // try injecting the fields within predicate no matter it has relation or not.
10296
- let subResults = injectFilter(subFieldNode, idState, curPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10326
+ let subResults = injectFilter(subFieldNode, idState, curPath, isPolymorphicField, objectInfos, pathToObjectApiNamesMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10297
10327
  subSelectionNodes = subSelectionNodes.concat(subResults);
10298
10328
  });
10299
10329
  if (!subFieldsHasId) {
@@ -10454,15 +10484,43 @@ function mergeOrAddToGroup(group, element) {
10454
10484
  }
10455
10485
  group.push(element);
10456
10486
  }
10457
- // checks if the path points to a polymorphic field. If path points to a polymorphic field, its entry within `pathToObjectApiNamesMap` has the format {"Path" : ["elem1", "elem2"]}.
10458
- // There must be also two entries pointing to concrete polymorphic field path. The two entries are like {"Path_elem1" : ["elem1"]} and {"Path_elem2" : ["elem2"]}
10459
- // For example ServiceAppointment_Owner' --> ['User', 'Group']; 'ServiceAppointment_Owner_User' --> ['User'], 'ServiceAppointment_Owner_Group' --> ['Group']
10460
- function isPolymorphicFieldPath(path, pathToObjectApiNamesMap) {
10461
- const apiName = pathToObjectApiNamesMap[path][0];
10462
- const apiNamesAtChildPath = pathToObjectApiNamesMap[`${path}_${apiName}`];
10463
- return (apiNamesAtChildPath !== undefined &&
10464
- apiNamesAtChildPath.length === 1 &&
10465
- apiNamesAtChildPath[0] === apiName);
10487
+ // checks if the path points to a polymorphic field. For example, for the below `pathToObjectApiNamesMap`
10488
+ // {
10489
+ // 'ServiceAppointment' -> ['ServiceAppointment']
10490
+ // 'ServiceAppointment#Owner' --> ['User'],
10491
+ // 'ServiceAppointment#Owner#User' --> ['User']
10492
+ // }
10493
+ // path `ServiceAppointment#Owner` points to a polymorphic field, but path `ServiceAppointment#Owner#User` does not.
10494
+ function isPolymorphicFieldPath(path, pathToObjectApiNamesMap, objectInfos) {
10495
+ const lastSegmentIndex = path.lastIndexOf('#');
10496
+ if (lastSegmentIndex < 0) {
10497
+ return false;
10498
+ }
10499
+ const lastSegment = path.slice(lastSegmentIndex + 1);
10500
+ const parentApiPath = path.slice(0, lastSegmentIndex);
10501
+ if (pathToObjectApiNamesMap[parentApiPath] === undefined) {
10502
+ return false;
10503
+ }
10504
+ const parentObjectApiNames = pathToObjectApiNamesMap[parentApiPath];
10505
+ // If the last segment is a Polymorphic field, its immediate parent is a concrete object entity, which has 1 objectApiName mapped to the parent path in `pathToObjectApiNamesMap`.
10506
+ // For example, we like to check if `ServiceAppointment#Owner` path is polymorphic. The last segment is `Owner` and its parent `ServiceAppointment` has one element (which is also `ServiceAppointment`) array as its value.
10507
+ // Below are the entries in `pathToObjectApiNamesMap`
10508
+ // {
10509
+ // `ServiceAppointmen`t: [`ServiceAppointment`],
10510
+ // `ServiceAppointment#Owner`: [`User`, `Group`],
10511
+ // `ServiceAppointment#Owner#User`: [`User`],
10512
+ // `ServiceAppointment#Owner#Group`: [`Group`],
10513
+ // }
10514
+ if (parentObjectApiNames.length !== 1) {
10515
+ return false;
10516
+ }
10517
+ const parentObjectInfo = objectInfos[parentObjectApiNames[0]];
10518
+ const relationshipField = referenceIdFieldForRelationship(lastSegment);
10519
+ let fieldDefinition = parentObjectInfo.fields[relationshipField];
10520
+ if (fieldDefinition === undefined) {
10521
+ return false;
10522
+ }
10523
+ return fieldDefinition.polymorphicForeignKey;
10466
10524
  }
10467
10525
  function isFieldAnIdField(fieldName, objectInfo) {
10468
10526
  if (fieldName === 'Id')
@@ -10516,10 +10574,10 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
10516
10574
  * @param parentNode parent node of param 1
10517
10575
  * @param ancestors ancester of param 1
10518
10576
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10519
- * @param pathToObjectApiNamesMap map used to locate the ObjectInfo. The key is path to a field, value is the ObjectInfo's apiName array. In the case of polymorphic fields, the apiName array have 2 or more elements. For example, 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment_Account' -> ['Account'], 'ServiceAppointment_Owner' -> ['User', 'Group'].
10577
+ * @param pathToObjectApiNamesMap map used to locate the ObjectInfo. The key is path to a field, value is the ObjectInfo's apiName array. In the case of polymorphic fields, the apiName array have 2 or more elements. For example, 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment#Account' -> ['Account'], 'ServiceAppointment#Owner' -> ['User', 'Group'].
10520
10578
  * @return injected SelectionNodes used to construct the InlineFragment.
10521
10579
  */
10522
- function injectFields(selections, parentNode, ancestors, objectInfos, pathToObjectApiNamesMap) {
10580
+ function injectFields(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap) {
10523
10581
  /**
10524
10582
  * 1 parentship can return 2 FieldNode which need to be flattened
10525
10583
  * Concact: { ** Contact { ** ContactId {
@@ -10537,6 +10595,10 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10537
10595
  if (!selection.selectionSet) {
10538
10596
  return selection;
10539
10597
  }
10598
+ const segment = isFieldNode(selection)
10599
+ ? selection.name.value
10600
+ : selection.typeCondition.name.value;
10601
+ const curPath = `${parentPath}#${segment}`;
10540
10602
  const spanningSubSelections = [];
10541
10603
  for (const subSelection of selection.selectionSet.selections) {
10542
10604
  if (isFieldSpanning(subSelection, selection)) {
@@ -10544,7 +10606,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10544
10606
  }
10545
10607
  }
10546
10608
  // Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
10547
- const subInjectedSelections = injectFields(spanningSubSelections, selection, ancestors, objectInfos, pathToObjectApiNamesMap);
10609
+ const subInjectedSelections = injectFields(spanningSubSelections, selection, curPath, ancestors, objectInfos, pathToObjectApiNamesMap);
10548
10610
  if (!selection.selectionSet) {
10549
10611
  return selection;
10550
10612
  }
@@ -10587,7 +10649,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10587
10649
  }
10588
10650
  }
10589
10651
  // For polymorphic fields, the Id field is excluded.
10590
- const excludeId = selection.selectionSet.selections.every(isInlineFragmentNode);
10652
+ const excludeId = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
10591
10653
  const idSelection = [];
10592
10654
  if (!excludeId && !hasIdAlready) {
10593
10655
  idSelection.push({
@@ -10598,8 +10660,8 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10598
10660
  },
10599
10661
  });
10600
10662
  }
10601
- // Inject '__typename' for polymorphic fields. '__typename' field acts as a reference to concrete type of a polymorphic field and is used to match JSON response with AST node. For more detail,
10602
- // please reference 'removeSyntheticFields'.
10663
+ // Inject '__typename' for InlineFragment. '__typename' field acts as a reference to concrete type of a polymorphic field or a standard field in the returned GQL response, which equals to
10664
+ // `typedCondition` of the InlineFragment in the query AST. It is used to match JSON response with AST node. For more detail, please reference 'removeSyntheticFields'.
10603
10665
  if (isInlineFragmentNode(selection) &&
10604
10666
  !selection.selectionSet.selections.find((selection) => isFieldNode(selection) && selection.name.value === '__typename')) {
10605
10667
  idSelection.push({
@@ -10633,7 +10695,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10633
10695
  if (isFieldNode(parentNode) && parentNode.selectionSet && parentNode.name.value === 'node') {
10634
10696
  if (parentNode.selectionSet.selections
10635
10697
  .filter(isFieldOrInlineFragmentNode)
10636
- .some((selectionNode) => isRelationship(selectionNode, 'childRelationship'))) {
10698
+ .some((selectionNode) => isRelationship(selectionNode, CHILD_RELATIONSHIP))) {
10637
10699
  if (!parentNode.selectionSet.selections
10638
10700
  .filter(isFieldNode)
10639
10701
  .some((sibling) => sibling.name.value === 'Id')) {
@@ -10652,7 +10714,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObje
10652
10714
  if (parentInfo.parentIndex >= 0) {
10653
10715
  // example node { TimeSheetEntries { edges { node { Id }}}}
10654
10716
  const parent = parentInfo.node;
10655
- if (isRelationship(parent, 'childRelationship')) {
10717
+ if (isRelationship(parent, CHILD_RELATIONSHIP)) {
10656
10718
  const unVisitedAncestors = ancestors.slice(0, parentInfo.parentIndex);
10657
10719
  // path : "TimeSheet"
10658
10720
  const grandParentPath = findAncesterPath(unVisitedAncestors);
@@ -10781,7 +10843,7 @@ const assignedToMeFragmentSelections = [
10781
10843
  },
10782
10844
  value: {
10783
10845
  kind: 'StringValue',
10784
- value: 'childRelationship',
10846
+ value: CHILD_RELATIONSHIP,
10785
10847
  block: false,
10786
10848
  },
10787
10849
  },
@@ -10873,7 +10935,7 @@ const assignedToMeFragmentSelections = [
10873
10935
  },
10874
10936
  value: {
10875
10937
  kind: 'StringValue',
10876
- value: 'parentRelationship',
10938
+ value: PARENT_RELATIONSHIP,
10877
10939
  block: false,
10878
10940
  },
10879
10941
  },
@@ -11010,7 +11072,9 @@ function handleNonArrayJsonProperty(selection, fieldName, jsonInput, jsonOutput)
11010
11072
  jsonOutput[fieldName] = null;
11011
11073
  return;
11012
11074
  }
11013
- jsonOutput[fieldName] = {};
11075
+ if (jsonOutput[fieldName] === undefined) {
11076
+ jsonOutput[fieldName] = {};
11077
+ }
11014
11078
  createUserJsonOutput(selection, jsonInput[fieldName], jsonOutput[fieldName]);
11015
11079
  }
11016
11080
  else {
@@ -11057,7 +11121,7 @@ const RECORD_ENDPOINT_REGEX$1 = /^\/ui-api\/records\/?(([a-zA-Z0-9]+))?$/;
11057
11121
  function getRecordIdFromRecordRequest(request) {
11058
11122
  const { method, basePath } = request;
11059
11123
  if (basePath === undefined) {
11060
- return undefined;
11124
+ throw Error(`Could not determine record id from request without a basePath`);
11061
11125
  }
11062
11126
  let recordId = '';
11063
11127
  switch (method) {
@@ -11066,13 +11130,13 @@ function getRecordIdFromRecordRequest(request) {
11066
11130
  case 'delete': {
11067
11131
  const matches = basePath.match(RECORD_ENDPOINT_REGEX$1);
11068
11132
  if (!matches || matches.length !== 3) {
11069
- return undefined;
11133
+ throw Error(`Could not determine record id from request path ${basePath}`);
11070
11134
  }
11071
11135
  recordId = matches[2];
11072
11136
  break;
11073
11137
  }
11074
11138
  default: {
11075
- return undefined;
11139
+ throw Error(`Could not determine record id from request type `);
11076
11140
  }
11077
11141
  }
11078
11142
  return recordId;
@@ -11928,7 +11992,7 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
11928
11992
  if (request.method === 'post') {
11929
11993
  const apiName = request.body.apiName;
11930
11994
  if (apiName === undefined) {
11931
- return undefined;
11995
+ throw Error('Could not determine api name from request body');
11932
11996
  }
11933
11997
  return this.recordService.synthesizeId(apiName);
11934
11998
  }
@@ -12643,11 +12707,11 @@ class UiApiDraftRecordService {
12643
12707
  const objectInfo = await getAdapterData(this.objectInfoAdapter, {
12644
12708
  objectApiName: apiName,
12645
12709
  });
12646
- if (objectInfo === undefined) {
12647
- return undefined;
12710
+ if (objectInfo === undefined || objectInfo.keyPrefix === null) {
12711
+ throw Error(`Could not find or fetch object info for ${apiName}`);
12648
12712
  }
12649
12713
  if (objectInfo.keyPrefix === null) {
12650
- return undefined;
12714
+ throw Error(`Could not find key prefix for ${apiName}. Cannot synthesize id.`);
12651
12715
  }
12652
12716
  return this.generateId(objectInfo.keyPrefix);
12653
12717
  }
@@ -12723,7 +12787,7 @@ class QuickActionExecutionRepresentationHandler extends AbstractResourceRequestA
12723
12787
  getIdFromRequest(request) {
12724
12788
  const apiName = request.body.apiName;
12725
12789
  if (typeof apiName !== 'string') {
12726
- throw Error('expected api name not found');
12790
+ throw Error('expected api name not found in request body');
12727
12791
  }
12728
12792
  const id = this.draftRecordService.synthesizeId(apiName);
12729
12793
  return Promise.resolve(id);
@@ -13185,16 +13249,18 @@ class ContentDocumentCompositeRepresentationActionHandler extends AbstractResour
13185
13249
  // remember ContentDocument ID
13186
13250
  pendingAction.metadata[CONTENT_DOCUMENT_DRAFT_ID_KEY] = targetId;
13187
13251
  // generate and remember ContentVersion ID
13188
- const contentVersionId = await this.draftRecordService.synthesizeId(CONTENT_VERSION_API_NAME);
13189
- if (contentVersionId === undefined) {
13252
+ const contentVersionId = await this.draftRecordService
13253
+ .synthesizeId(CONTENT_VERSION_API_NAME)
13254
+ .catch(() => {
13190
13255
  return Promise.reject(new DraftSynthesisError('Cannot generate local ContentVersion synthetic id', 'CANNOT_GENERATE_ID'));
13191
- }
13256
+ });
13192
13257
  pendingAction.metadata[CONTENT_VERSION_DRAFT_ID_KEY] = contentVersionId;
13193
13258
  // generate and remember ContentDocumentLink ID
13194
- const contentDocumentLinkId = await this.draftRecordService.synthesizeId(CONTENT_DOCUMENT_LINK_API_NAME);
13195
- if (contentDocumentLinkId === undefined) {
13259
+ const contentDocumentLinkId = await this.draftRecordService
13260
+ .synthesizeId(CONTENT_DOCUMENT_LINK_API_NAME)
13261
+ .catch(() => {
13196
13262
  return Promise.reject(new DraftSynthesisError('Cannot generate local ContentDocumentLink synthetic id', 'CANNOT_GENERATE_ID'));
13197
- }
13263
+ });
13198
13264
  pendingAction.metadata[CONTENT_DOCUMENT_LINK_DRAFT_ID_KEY] = contentDocumentLinkId;
13199
13265
  // assert that object infos and references exist
13200
13266
  const metaDataResult = await this.draftRecordService.getRecordDraftMetadata(targetId, pendingAction);
@@ -13223,8 +13289,7 @@ class ContentDocumentCompositeRepresentationActionHandler extends AbstractResour
13223
13289
  return false;
13224
13290
  }
13225
13291
  async getIdFromRequest(_request) {
13226
- const id = this.draftRecordService.synthesizeId(CONTENT_DOCUMENT_API_NAME);
13227
- return id;
13292
+ return this.draftRecordService.synthesizeId(CONTENT_DOCUMENT_API_NAME);
13228
13293
  }
13229
13294
  getIdFromResponseBody(responseBody) {
13230
13295
  return responseBody.contentDocument.id;
@@ -16182,6 +16247,9 @@ class PrimingSession extends EventEmitter {
16182
16247
  this.ldsRecordRefresher = config.ldsRecordRefresher;
16183
16248
  this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
16184
16249
  this.useBatchGQL = ldsPrimingGraphqlBatch.isOpen({ fallback: false });
16250
+ if (this.useBatchGQL) {
16251
+ this.batchSize = this.batchSize / DEFAULT_GQL_QUERY_BATCH_SIZE;
16252
+ }
16185
16253
  this.conflictPool = new ConflictPool(config.store, this.objectInfoLoader);
16186
16254
  }
16187
16255
  // function that enqueues priming work
@@ -17046,4 +17114,4 @@ register({
17046
17114
  });
17047
17115
 
17048
17116
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
17049
- // version: 1.242.0-57237c3b6
17117
+ // version: 1.243.0-87f38263e