@salesforce/lds-runtime-mobile 1.239.0 → 1.241.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 +70 -66
  2. package/package.json +1 -1
  3. package/sfdc/main.js +70 -66
package/dist/main.js CHANGED
@@ -9494,7 +9494,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9494
9494
  const objectNodeInfoTree = {};
9495
9495
  // save the field path to apiName map
9496
9496
  // example 1: 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment_Account' -> ['Account']; 'ServiceAppointment_Account_Owner' -> ['User']
9497
- const objectInfoApiMap = {};
9497
+ const pathToObjectApiNamesMap = {};
9498
9498
  let startNodes = new Set();
9499
9499
  let totalNodes = new Set();
9500
9500
  let objectInfos = {};
@@ -9575,7 +9575,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9575
9575
  },
9576
9576
  });
9577
9577
  if (objectInfoService && startNodes.size > 0) {
9578
- objectInfos = await resolveObjectInfos(objectNodeInfoTree, objectInfoApiMap, startNodes, objectInfoService);
9578
+ objectInfos = await resolveObjectInfos(objectNodeInfoTree, pathToObjectApiNamesMap, startNodes, objectInfoService);
9579
9579
  }
9580
9580
  // read pass; gather whats needed
9581
9581
  visit(originalAST, {
@@ -9588,8 +9588,8 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9588
9588
  if (!inlineFragmentSelections[ancestorPath]) {
9589
9589
  inlineFragmentSelections[ancestorPath] = [];
9590
9590
  }
9591
- const recordQueryApiName = objectInfoApiMap[ancestorPath]
9592
- ? objectInfoApiMap[ancestorPath][0]
9591
+ const recordQueryApiName = pathToObjectApiNamesMap[ancestorPath]
9592
+ ? pathToObjectApiNamesMap[ancestorPath][0]
9593
9593
  : recordQueryField.name.value;
9594
9594
  // The record node acts as the reference. The duplicated field in the record node is not injected
9595
9595
  const recordReferenceNode = [recordQueryField]
@@ -9603,7 +9603,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9603
9603
  case 'scope':
9604
9604
  // Hanle 'MINE' field
9605
9605
  if (isScopeArgumentNodeWithType(node, 'MINE', variables)) {
9606
- if (isMineScopeAvailable(ancestorPath, objectInfoApiMap, objectInfos)) {
9606
+ if (isMineScopeAvailable(ancestorPath, pathToObjectApiNamesMap, objectInfos)) {
9607
9607
  // 'typeConditon' is added when the 'InlineFragmentNode' is appended at the write pass
9608
9608
  inlineFragmentSelections[ancestorPath].push(...mineFragmentSelections);
9609
9609
  }
@@ -9629,7 +9629,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9629
9629
  case 'where': {
9630
9630
  inlineFragmentSelections[ancestorPath] = [
9631
9631
  ...inlineFragmentSelections[ancestorPath],
9632
- ...injectFilter(node, idState, ancestorPath, objectInfos, objectInfoApiMap, draftFunctions, recordReferenceNode),
9632
+ ...injectFilter(node, idState, ancestorPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, recordReferenceNode),
9633
9633
  ];
9634
9634
  break;
9635
9635
  }
@@ -9657,7 +9657,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9657
9657
  spanningSelections.push(selection);
9658
9658
  }
9659
9659
  }
9660
- const injectedFields = injectFields(spanningSelections, node, ancestors, objectInfos, objectInfoApiMap);
9660
+ const injectedFields = injectFields(spanningSelections, node, ancestors, objectInfos, pathToObjectApiNamesMap);
9661
9661
  const mergedInjectedFields = mergeSelectionNodes(inlineFragmentSelections[ancestorPath], injectedFields);
9662
9662
  inlineFragmentSelections[ancestorPath] = mergedInjectedFields;
9663
9663
  },
@@ -9688,8 +9688,8 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9688
9688
  return;
9689
9689
  //const recordQueryPath = findAncesterPath(ancestors);
9690
9690
  // 'apiName' has to be at index 0 since 'node' record type could only be of 'recordQuery' or 'childRelationship'. They can not have the 'InlineFragmentNode' as its children.
9691
- const recordQueryApiName = objectInfoApiMap[ancestorPath]
9692
- ? objectInfoApiMap[ancestorPath][0]
9691
+ const recordQueryApiName = pathToObjectApiNamesMap[ancestorPath]
9692
+ ? pathToObjectApiNamesMap[ancestorPath][0]
9693
9693
  : recordQueryField.name.value;
9694
9694
  const nodeWithFragments = {
9695
9695
  ...node,
@@ -9726,7 +9726,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9726
9726
  if (node.name.value === 'where') {
9727
9727
  const ancestorPath = findAncesterPath(ancestors);
9728
9728
  if (idState.paths.includes(ancestorPath)) {
9729
- const apiName = objectInfoApiMap[ancestorPath][0];
9729
+ const apiName = pathToObjectApiNamesMap[ancestorPath][0];
9730
9730
  const objectInfo = objectInfos[apiName];
9731
9731
  const swappedIdFilter = swapIdField(node.value, objectInfo, false, idState, draftFunctions);
9732
9732
  return {
@@ -9792,8 +9792,8 @@ function swapIdField(filterFields, objectInfo, swapped, idState, draftFunctions)
9792
9792
  };
9793
9793
  }
9794
9794
  }
9795
- function isMineScopeAvailable(apiNamePath, objectInfoApiMap, objectInfos) {
9796
- const apiName = objectInfoApiMap[apiNamePath];
9795
+ function isMineScopeAvailable(apiNamePath, pathToObjectApiNamesMap, objectInfos) {
9796
+ const apiName = pathToObjectApiNamesMap[apiNamePath];
9797
9797
  if (!apiName)
9798
9798
  return false;
9799
9799
  const objectInfo = objectInfos[apiName[0]];
@@ -9995,7 +9995,7 @@ function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNode
9995
9995
  * @param startNodes start nodes of the tree. It can be used to fetch ObjectInfo immediately
9996
9996
  * @param path
9997
9997
  */
9998
- async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes, objectInfoService) {
9998
+ async function resolveObjectInfos(objectInfotree, pathToObjectApiNamesMap, startNodes, objectInfoService) {
9999
9999
  let objectInfos;
10000
10000
  try {
10001
10001
  objectInfos = await objectInfoService.getObjectInfos(Array.from(startNodes));
@@ -10009,9 +10009,9 @@ async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes,
10009
10009
  throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
10010
10010
  }
10011
10011
  for (const startNode of startNodes) {
10012
- objectInfoApiMap[startNode] = [startNode];
10012
+ pathToObjectApiNamesMap[startNode] = [startNode];
10013
10013
  const children = objectInfotree[startNode];
10014
- const subObjectInfoMap = await fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfos, children, startNode, objectInfoService);
10014
+ const subObjectInfoMap = await fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectInfos, children, startNode, objectInfoService);
10015
10015
  objectInfos = { ...objectInfos, ...subObjectInfoMap };
10016
10016
  }
10017
10017
  return objectInfos;
@@ -10019,15 +10019,15 @@ async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes,
10019
10019
  // example 1: 'parentPath': 'ServiceAppointment', 'nodesAtSameLevel': ['Account']
10020
10020
  // example 2: 'parentPath': 'ServiceAppointment', 'nodesAtSameLevel': ['Owner'], this example has 2 apiName for the node 'Owner'
10021
10021
  // example 3: 'parentPath': 'ServiceAppointment_Owner', 'nodesAtSameLevel': ['User', 'Group']
10022
- async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap, nodesAtSameLevel, parentPath, objectInfoService) {
10023
- const objectInfoApiNames = objectInfoApiMap[parentPath];
10022
+ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectInfoMap, nodesAtSameLevel, parentPath, objectInfoService) {
10023
+ const objectInfoApiNames = pathToObjectApiNamesMap[parentPath];
10024
10024
  if (!objectInfoApiNames) {
10025
10025
  // eslint-disable-next-line
10026
10026
  throw new Error(`Object Info does not exist for ${parentPath}`);
10027
10027
  }
10028
10028
  const validObjectInfoNodes = [];
10029
10029
  let updatedObjectInfoMap = {};
10030
- // InlineFragment and polymorphic field support fits into this scenario ObjectInfoApiMap Entry: 'ServiceAppointment_Owner' -> ['User', 'Group']; ServiceAppointment_Owner_User' -> ['User']
10030
+ // InlineFragment and polymorphic field support fits into this scenario pathToObjectApiNamesMap Entry: 'ServiceAppointment_Owner' -> ['User', 'Group']; ServiceAppointment_Owner_User' -> ['User']
10031
10031
  if (objectInfoApiNames.length > 0 &&
10032
10032
  nodesAtSameLevel.length > 0 &&
10033
10033
  objectInfoApiNames.includes(nodesAtSameLevel[0].name)) {
@@ -10040,7 +10040,7 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10040
10040
  throw new Error(`Condition ${field.name} does not exists for ${parentPath}`);
10041
10041
  }
10042
10042
  const path = `${parentPath}_${field.name}`;
10043
- objectInfoApiMap[path] = [field.name];
10043
+ pathToObjectApiNamesMap[path] = [field.name];
10044
10044
  }
10045
10045
  validObjectInfoNodes.push(...nodesAtSameLevel);
10046
10046
  updatedObjectInfoMap = { ...objectInfoMap };
@@ -10082,12 +10082,12 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10082
10082
  fieldDefinition.referenceToInfos
10083
10083
  .filter((referenceToInfo) => requestedApiNames.includes(referenceToInfo.apiName))
10084
10084
  .forEach((ref) => {
10085
- if (!objectInfoApiMap[path]) {
10086
- objectInfoApiMap[path] = [];
10085
+ if (!pathToObjectApiNamesMap[path]) {
10086
+ pathToObjectApiNamesMap[path] = [];
10087
10087
  }
10088
10088
  // 'ServiceAppointment_Owner' ->['User', 'Group']
10089
- if (!objectInfoApiMap[path].includes(ref.apiName)) {
10090
- objectInfoApiMap[path].push(ref.apiName);
10089
+ if (!pathToObjectApiNamesMap[path].includes(ref.apiName)) {
10090
+ pathToObjectApiNamesMap[path].push(ref.apiName);
10091
10091
  }
10092
10092
  if (!apiNames.includes(ref.apiName)) {
10093
10093
  apiNames.push(ref.apiName);
@@ -10097,11 +10097,11 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10097
10097
  }
10098
10098
  else if (fieldDefinition.referenceToInfos.length === 1) {
10099
10099
  const ref = fieldDefinition.referenceToInfos[0];
10100
- if (!objectInfoApiMap[path]) {
10101
- objectInfoApiMap[path] = [];
10100
+ if (!pathToObjectApiNamesMap[path]) {
10101
+ pathToObjectApiNamesMap[path] = [];
10102
10102
  }
10103
- if (!objectInfoApiMap[path].includes(ref.apiName)) {
10104
- objectInfoApiMap[path].push(ref.apiName);
10103
+ if (!pathToObjectApiNamesMap[path].includes(ref.apiName)) {
10104
+ pathToObjectApiNamesMap[path].push(ref.apiName);
10105
10105
  }
10106
10106
  if (!apiNames.includes(ref.apiName)) {
10107
10107
  apiNames.push(ref.apiName);
@@ -10112,11 +10112,11 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10112
10112
  // handles 'childRelationship'
10113
10113
  const childRelationship = parentObjectInfo.childRelationships.find((childRelationship) => childRelationship.relationshipName === field);
10114
10114
  if (childRelationship) {
10115
- if (!objectInfoApiMap[path]) {
10116
- objectInfoApiMap[path] = [];
10115
+ if (!pathToObjectApiNamesMap[path]) {
10116
+ pathToObjectApiNamesMap[path] = [];
10117
10117
  }
10118
- if (!objectInfoApiMap[path].includes(childRelationship.childObjectApiName)) {
10119
- objectInfoApiMap[path].push(childRelationship.childObjectApiName);
10118
+ if (!pathToObjectApiNamesMap[path].includes(childRelationship.childObjectApiName)) {
10119
+ pathToObjectApiNamesMap[path].push(childRelationship.childObjectApiName);
10120
10120
  }
10121
10121
  if (!apiNames.includes(childRelationship.childObjectApiName)) {
10122
10122
  apiNames.push(childRelationship.childObjectApiName);
@@ -10141,7 +10141,7 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10141
10141
  const subLevelFields = objectInfotree[field];
10142
10142
  const path = `${parentPath}_${field}`;
10143
10143
  if (subLevelFields && subLevelFields.length > 0) {
10144
- const subObjectInfos = await fetchObjectInfos(objectInfotree, objectInfoApiMap, updatedObjectInfoMap, subLevelFields, path, objectInfoService);
10144
+ const subObjectInfos = await fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, updatedObjectInfoMap, subLevelFields, path, objectInfoService);
10145
10145
  updatedObjectInfoMap = { ...updatedObjectInfoMap, ...subObjectInfos };
10146
10146
  }
10147
10147
  }
@@ -10156,21 +10156,21 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10156
10156
  * 'path' and 'queryNode' is 1 level above the 'filterNode'
10157
10157
  * @param filterNode filter node which needs to be injected. For example, 'State' ObjectFieldNode within filter 'where: { State: { eq: "Nova Scotia" }}'
10158
10158
  * @param idState ID state will be updated to determine if the ID fields in AST need to be swapped. The swapping happens later.
10159
- * @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 'objectInfoApiMap', parent node is not an field of relationship or recordQuery
10159
+ * @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
10160
10160
  * @param queryNode referece FieldNode which provides the information if 'filterNode' exist in it nor not.
10161
10161
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10162
- * @param objectInfoApiMap 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'].
10162
+ * @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'].
10163
10163
  * @param draftFunctions functions for working with record ids that may be draft-created ids
10164
10164
  * @returns an array of nodes with injected fields
10165
10165
  */
10166
- function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode) {
10166
+ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode) {
10167
10167
  const injectedSelections = [];
10168
10168
  switch (filterNode.kind) {
10169
10169
  case Kind.ARGUMENT:
10170
10170
  if (filterNode.value.kind !== 'ObjectValue')
10171
10171
  return [];
10172
10172
  filterNode.value.fields.forEach((objectFieldNode) => {
10173
- let subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10173
+ let subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10174
10174
  for (const subResult of subResults) {
10175
10175
  mergeOrAddToGroup(injectedSelections, subResult);
10176
10176
  }
@@ -10185,7 +10185,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10185
10185
  case Kind.LIST: {
10186
10186
  filterNode.value.values.filter(isObjectValueNode).forEach((objectValueNode) => {
10187
10187
  objectValueNode.fields.forEach((objectFieldNode) => {
10188
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10188
+ const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10189
10189
  for (const subResult of subResults) {
10190
10190
  mergeOrAddToGroup(injectedSelections, subResult);
10191
10191
  }
@@ -10196,7 +10196,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10196
10196
  case Kind.OBJECT: {
10197
10197
  if (filterNode.name.value === 'not') {
10198
10198
  filterNode.value.fields.forEach((objectFieldNode) => {
10199
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10199
+ const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10200
10200
  for (const subResult of subResults) {
10201
10201
  mergeOrAddToGroup(injectedSelections, subResult);
10202
10202
  }
@@ -10206,7 +10206,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10206
10206
  let apiNames = [];
10207
10207
  let isScalarField = false;
10208
10208
  //It is possible that this is a polymorphic field
10209
- apiNames = objectInfoApiMap[path];
10209
+ apiNames = pathToObjectApiNamesMap[path];
10210
10210
  // example: path: 'ServiceAppointment_LastModifiedDate'; filterNode: '{eq: {literal: LAST_WEEK}}'. queryNode: 'LastModifedDate { value}' FilterNode's parent has been verifed as a valid node
10211
10211
  if (apiNames === undefined) {
10212
10212
  isScalarField = true;
@@ -10236,29 +10236,23 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10236
10236
  }
10237
10237
  });
10238
10238
  let isSpanning = false;
10239
+ // if true, current node is a polymorphic concrete type node. For example, field node `User` under `Owner`
10239
10240
  let isInlineFragment = false;
10240
10241
  let isPolymorphicField = false;
10241
10242
  let isTypeNameExisting = false;
10242
10243
  let curPath;
10243
10244
  let fieldName = filterNode.name.value;
10244
10245
  curPath = `${path}_${fieldName}`;
10245
- if (objectInfoApiMap[curPath] && objectInfoApiMap[curPath].length > 0) {
10246
+ if (pathToObjectApiNamesMap[curPath] &&
10247
+ pathToObjectApiNamesMap[curPath].length > 0) {
10246
10248
  isSpanning = true;
10247
- if (objectInfoApiMap[curPath].length === 1) {
10248
- if (objectInfoApiMap[path] &&
10249
- objectInfoApiMap[path].length >= 1 &&
10250
- objectInfoApiMap[path].includes(objectInfoApiMap[curPath][0])) {
10251
- isInlineFragment = true;
10252
- }
10253
- }
10254
- // Checks if the current filter node is a polymorphic field. 'ServiceAppointment_Owner' --> ['User']; 'ServiceAppointment_Owner_User' --> ['User']
10255
- const childApiName = objectInfoApiMap[curPath][0];
10256
- const trialApiNames = objectInfoApiMap[`${curPath}_${childApiName}`];
10257
- if (trialApiNames !== undefined &&
10258
- trialApiNames.length === 1 &&
10259
- trialApiNames[0] === childApiName) {
10260
- isPolymorphicField = true;
10249
+ if (pathToObjectApiNamesMap[curPath].length === 1 &&
10250
+ pathToObjectApiNamesMap[path] &&
10251
+ pathToObjectApiNamesMap[path].length >= 1 &&
10252
+ pathToObjectApiNamesMap[path].includes(pathToObjectApiNamesMap[curPath][0])) {
10253
+ isInlineFragment = isPolymorphicFieldPath(path, pathToObjectApiNamesMap);
10261
10254
  }
10255
+ isPolymorphicField = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap);
10262
10256
  }
10263
10257
  // 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]
10264
10258
  if (isInlineFragment) {
@@ -10302,9 +10296,9 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10302
10296
  throw new Error(`Field ${fieldName} does not exist in ${apiNames[0]}`);
10303
10297
  }
10304
10298
  }
10305
- const objectInfoName = objectInfoApiMap[curPath] !== undefined
10306
- ? objectInfoApiMap[curPath][0]
10307
- : objectInfoApiMap[path][0];
10299
+ const objectInfoName = pathToObjectApiNamesMap[curPath] !== undefined
10300
+ ? pathToObjectApiNamesMap[curPath][0]
10301
+ : pathToObjectApiNamesMap[path][0];
10308
10302
  const isIdField = isFieldAnIdField(filterNode.name.value, objectInfos[objectInfoName]);
10309
10303
  if (!isIdField) {
10310
10304
  let subSelectionNodes = [];
@@ -10316,7 +10310,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10316
10310
  updateIDInfo(subFieldNode, idState, draftFunctions);
10317
10311
  }
10318
10312
  // try injecting the fields within predicate no matter it has relation or not.
10319
- let subResults = injectFilter(subFieldNode, idState, curPath, objectInfos, objectInfoApiMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10313
+ let subResults = injectFilter(subFieldNode, idState, curPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10320
10314
  subSelectionNodes = subSelectionNodes.concat(subResults);
10321
10315
  });
10322
10316
  if (!subFieldsHasId) {
@@ -10477,6 +10471,16 @@ function mergeOrAddToGroup(group, element) {
10477
10471
  }
10478
10472
  group.push(element);
10479
10473
  }
10474
+ // 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"]}.
10475
+ // There must be also two entries pointing to concrete polymorphic field path. The two entries are like {"Path_elem1" : ["elem1"]} and {"Path_elem2" : ["elem2"]}
10476
+ // For example ServiceAppointment_Owner' --> ['User', 'Group']; 'ServiceAppointment_Owner_User' --> ['User'], 'ServiceAppointment_Owner_Group' --> ['Group']
10477
+ function isPolymorphicFieldPath(path, pathToObjectApiNamesMap) {
10478
+ const apiName = pathToObjectApiNamesMap[path][0];
10479
+ const apiNamesAtChildPath = pathToObjectApiNamesMap[`${path}_${apiName}`];
10480
+ return (apiNamesAtChildPath !== undefined &&
10481
+ apiNamesAtChildPath.length === 1 &&
10482
+ apiNamesAtChildPath[0] === apiName);
10483
+ }
10480
10484
  function isFieldAnIdField(fieldName, objectInfo) {
10481
10485
  if (fieldName === 'Id')
10482
10486
  return true;
@@ -10529,10 +10533,10 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
10529
10533
  * @param parentNode parent node of param 1
10530
10534
  * @param ancestors ancester of param 1
10531
10535
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10532
- * @param objectInfoApiMap 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'].
10536
+ * @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'].
10533
10537
  * @return injected SelectionNodes used to construct the InlineFragment.
10534
10538
  */
10535
- function injectFields(selections, parentNode, ancestors, objectInfos, objectInfoApiMap) {
10539
+ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObjectApiNamesMap) {
10536
10540
  /**
10537
10541
  * 1 parentship can return 2 FieldNode which need to be flattened
10538
10542
  * Concact: { ** Contact { ** ContactId {
@@ -10557,7 +10561,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, objectInfo
10557
10561
  }
10558
10562
  }
10559
10563
  // Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
10560
- const subInjectedSelections = injectFields(spanningSubSelections, selection, ancestors, objectInfos, objectInfoApiMap);
10564
+ const subInjectedSelections = injectFields(spanningSubSelections, selection, ancestors, objectInfos, pathToObjectApiNamesMap);
10561
10565
  if (!selection.selectionSet) {
10562
10566
  return selection;
10563
10567
  }
@@ -10669,11 +10673,11 @@ function injectFields(selections, parentNode, ancestors, objectInfos, objectInfo
10669
10673
  const unVisitedAncestors = ancestors.slice(0, parentInfo.parentIndex);
10670
10674
  // path : "TimeSheet"
10671
10675
  const grandParentPath = findAncesterPath(unVisitedAncestors);
10672
- if (objectInfoApiMap &&
10673
- objectInfoApiMap[grandParentPath] &&
10676
+ if (pathToObjectApiNamesMap &&
10677
+ pathToObjectApiNamesMap[grandParentPath] &&
10674
10678
  objectInfos &&
10675
- objectInfos[objectInfoApiMap[grandParentPath][0]]) {
10676
- const grandParentObjectInfo = objectInfos[objectInfoApiMap[grandParentPath][0]];
10679
+ objectInfos[pathToObjectApiNamesMap[grandParentPath][0]]) {
10680
+ const grandParentObjectInfo = objectInfos[pathToObjectApiNamesMap[grandParentPath][0]];
10677
10681
  // exmaple "TimeSheetEntries"
10678
10682
  const parentFieldName = parent.name.value;
10679
10683
  const targetRelationship = grandParentObjectInfo.childRelationships.find((childRelationship) => {
@@ -17059,4 +17063,4 @@ register({
17059
17063
  });
17060
17064
 
17061
17065
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
17062
- // version: 1.239.0-6c531185a
17066
+ // version: 1.241.0-b14b649d4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-mobile",
3
- "version": "1.239.0",
3
+ "version": "1.241.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS runtime for mobile/hybrid environments.",
6
6
  "main": "dist/main.js",
package/sfdc/main.js CHANGED
@@ -9494,7 +9494,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9494
9494
  const objectNodeInfoTree = {};
9495
9495
  // save the field path to apiName map
9496
9496
  // example 1: 'ServiceAppointment' -> ['ServiceAppointment']; 'ServiceAppointment_Account' -> ['Account']; 'ServiceAppointment_Account_Owner' -> ['User']
9497
- const objectInfoApiMap = {};
9497
+ const pathToObjectApiNamesMap = {};
9498
9498
  let startNodes = new Set();
9499
9499
  let totalNodes = new Set();
9500
9500
  let objectInfos = {};
@@ -9575,7 +9575,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9575
9575
  },
9576
9576
  });
9577
9577
  if (objectInfoService && startNodes.size > 0) {
9578
- objectInfos = await resolveObjectInfos(objectNodeInfoTree, objectInfoApiMap, startNodes, objectInfoService);
9578
+ objectInfos = await resolveObjectInfos(objectNodeInfoTree, pathToObjectApiNamesMap, startNodes, objectInfoService);
9579
9579
  }
9580
9580
  // read pass; gather whats needed
9581
9581
  visit(originalAST, {
@@ -9588,8 +9588,8 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9588
9588
  if (!inlineFragmentSelections[ancestorPath]) {
9589
9589
  inlineFragmentSelections[ancestorPath] = [];
9590
9590
  }
9591
- const recordQueryApiName = objectInfoApiMap[ancestorPath]
9592
- ? objectInfoApiMap[ancestorPath][0]
9591
+ const recordQueryApiName = pathToObjectApiNamesMap[ancestorPath]
9592
+ ? pathToObjectApiNamesMap[ancestorPath][0]
9593
9593
  : recordQueryField.name.value;
9594
9594
  // The record node acts as the reference. The duplicated field in the record node is not injected
9595
9595
  const recordReferenceNode = [recordQueryField]
@@ -9603,7 +9603,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9603
9603
  case 'scope':
9604
9604
  // Hanle 'MINE' field
9605
9605
  if (isScopeArgumentNodeWithType(node, 'MINE', variables)) {
9606
- if (isMineScopeAvailable(ancestorPath, objectInfoApiMap, objectInfos)) {
9606
+ if (isMineScopeAvailable(ancestorPath, pathToObjectApiNamesMap, objectInfos)) {
9607
9607
  // 'typeConditon' is added when the 'InlineFragmentNode' is appended at the write pass
9608
9608
  inlineFragmentSelections[ancestorPath].push(...mineFragmentSelections);
9609
9609
  }
@@ -9629,7 +9629,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9629
9629
  case 'where': {
9630
9630
  inlineFragmentSelections[ancestorPath] = [
9631
9631
  ...inlineFragmentSelections[ancestorPath],
9632
- ...injectFilter(node, idState, ancestorPath, objectInfos, objectInfoApiMap, draftFunctions, recordReferenceNode),
9632
+ ...injectFilter(node, idState, ancestorPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, recordReferenceNode),
9633
9633
  ];
9634
9634
  break;
9635
9635
  }
@@ -9657,7 +9657,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9657
9657
  spanningSelections.push(selection);
9658
9658
  }
9659
9659
  }
9660
- const injectedFields = injectFields(spanningSelections, node, ancestors, objectInfos, objectInfoApiMap);
9660
+ const injectedFields = injectFields(spanningSelections, node, ancestors, objectInfos, pathToObjectApiNamesMap);
9661
9661
  const mergedInjectedFields = mergeSelectionNodes(inlineFragmentSelections[ancestorPath], injectedFields);
9662
9662
  inlineFragmentSelections[ancestorPath] = mergedInjectedFields;
9663
9663
  },
@@ -9688,8 +9688,8 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9688
9688
  return;
9689
9689
  //const recordQueryPath = findAncesterPath(ancestors);
9690
9690
  // 'apiName' has to be at index 0 since 'node' record type could only be of 'recordQuery' or 'childRelationship'. They can not have the 'InlineFragmentNode' as its children.
9691
- const recordQueryApiName = objectInfoApiMap[ancestorPath]
9692
- ? objectInfoApiMap[ancestorPath][0]
9691
+ const recordQueryApiName = pathToObjectApiNamesMap[ancestorPath]
9692
+ ? pathToObjectApiNamesMap[ancestorPath][0]
9693
9693
  : recordQueryField.name.value;
9694
9694
  const nodeWithFragments = {
9695
9695
  ...node,
@@ -9726,7 +9726,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
9726
9726
  if (node.name.value === 'where') {
9727
9727
  const ancestorPath = findAncesterPath(ancestors);
9728
9728
  if (idState.paths.includes(ancestorPath)) {
9729
- const apiName = objectInfoApiMap[ancestorPath][0];
9729
+ const apiName = pathToObjectApiNamesMap[ancestorPath][0];
9730
9730
  const objectInfo = objectInfos[apiName];
9731
9731
  const swappedIdFilter = swapIdField(node.value, objectInfo, false, idState, draftFunctions);
9732
9732
  return {
@@ -9792,8 +9792,8 @@ function swapIdField(filterFields, objectInfo, swapped, idState, draftFunctions)
9792
9792
  };
9793
9793
  }
9794
9794
  }
9795
- function isMineScopeAvailable(apiNamePath, objectInfoApiMap, objectInfos) {
9796
- const apiName = objectInfoApiMap[apiNamePath];
9795
+ function isMineScopeAvailable(apiNamePath, pathToObjectApiNamesMap, objectInfos) {
9796
+ const apiName = pathToObjectApiNamesMap[apiNamePath];
9797
9797
  if (!apiName)
9798
9798
  return false;
9799
9799
  const objectInfo = objectInfos[apiName[0]];
@@ -9995,7 +9995,7 @@ function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNode
9995
9995
  * @param startNodes start nodes of the tree. It can be used to fetch ObjectInfo immediately
9996
9996
  * @param path
9997
9997
  */
9998
- async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes, objectInfoService) {
9998
+ async function resolveObjectInfos(objectInfotree, pathToObjectApiNamesMap, startNodes, objectInfoService) {
9999
9999
  let objectInfos;
10000
10000
  try {
10001
10001
  objectInfos = await objectInfoService.getObjectInfos(Array.from(startNodes));
@@ -10009,9 +10009,9 @@ async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes,
10009
10009
  throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
10010
10010
  }
10011
10011
  for (const startNode of startNodes) {
10012
- objectInfoApiMap[startNode] = [startNode];
10012
+ pathToObjectApiNamesMap[startNode] = [startNode];
10013
10013
  const children = objectInfotree[startNode];
10014
- const subObjectInfoMap = await fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfos, children, startNode, objectInfoService);
10014
+ const subObjectInfoMap = await fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectInfos, children, startNode, objectInfoService);
10015
10015
  objectInfos = { ...objectInfos, ...subObjectInfoMap };
10016
10016
  }
10017
10017
  return objectInfos;
@@ -10019,15 +10019,15 @@ async function resolveObjectInfos(objectInfotree, objectInfoApiMap, startNodes,
10019
10019
  // example 1: 'parentPath': 'ServiceAppointment', 'nodesAtSameLevel': ['Account']
10020
10020
  // example 2: 'parentPath': 'ServiceAppointment', 'nodesAtSameLevel': ['Owner'], this example has 2 apiName for the node 'Owner'
10021
10021
  // example 3: 'parentPath': 'ServiceAppointment_Owner', 'nodesAtSameLevel': ['User', 'Group']
10022
- async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap, nodesAtSameLevel, parentPath, objectInfoService) {
10023
- const objectInfoApiNames = objectInfoApiMap[parentPath];
10022
+ async function fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, objectInfoMap, nodesAtSameLevel, parentPath, objectInfoService) {
10023
+ const objectInfoApiNames = pathToObjectApiNamesMap[parentPath];
10024
10024
  if (!objectInfoApiNames) {
10025
10025
  // eslint-disable-next-line
10026
10026
  throw new Error(`Object Info does not exist for ${parentPath}`);
10027
10027
  }
10028
10028
  const validObjectInfoNodes = [];
10029
10029
  let updatedObjectInfoMap = {};
10030
- // InlineFragment and polymorphic field support fits into this scenario ObjectInfoApiMap Entry: 'ServiceAppointment_Owner' -> ['User', 'Group']; ServiceAppointment_Owner_User' -> ['User']
10030
+ // InlineFragment and polymorphic field support fits into this scenario pathToObjectApiNamesMap Entry: 'ServiceAppointment_Owner' -> ['User', 'Group']; ServiceAppointment_Owner_User' -> ['User']
10031
10031
  if (objectInfoApiNames.length > 0 &&
10032
10032
  nodesAtSameLevel.length > 0 &&
10033
10033
  objectInfoApiNames.includes(nodesAtSameLevel[0].name)) {
@@ -10040,7 +10040,7 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10040
10040
  throw new Error(`Condition ${field.name} does not exists for ${parentPath}`);
10041
10041
  }
10042
10042
  const path = `${parentPath}_${field.name}`;
10043
- objectInfoApiMap[path] = [field.name];
10043
+ pathToObjectApiNamesMap[path] = [field.name];
10044
10044
  }
10045
10045
  validObjectInfoNodes.push(...nodesAtSameLevel);
10046
10046
  updatedObjectInfoMap = { ...objectInfoMap };
@@ -10082,12 +10082,12 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10082
10082
  fieldDefinition.referenceToInfos
10083
10083
  .filter((referenceToInfo) => requestedApiNames.includes(referenceToInfo.apiName))
10084
10084
  .forEach((ref) => {
10085
- if (!objectInfoApiMap[path]) {
10086
- objectInfoApiMap[path] = [];
10085
+ if (!pathToObjectApiNamesMap[path]) {
10086
+ pathToObjectApiNamesMap[path] = [];
10087
10087
  }
10088
10088
  // 'ServiceAppointment_Owner' ->['User', 'Group']
10089
- if (!objectInfoApiMap[path].includes(ref.apiName)) {
10090
- objectInfoApiMap[path].push(ref.apiName);
10089
+ if (!pathToObjectApiNamesMap[path].includes(ref.apiName)) {
10090
+ pathToObjectApiNamesMap[path].push(ref.apiName);
10091
10091
  }
10092
10092
  if (!apiNames.includes(ref.apiName)) {
10093
10093
  apiNames.push(ref.apiName);
@@ -10097,11 +10097,11 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10097
10097
  }
10098
10098
  else if (fieldDefinition.referenceToInfos.length === 1) {
10099
10099
  const ref = fieldDefinition.referenceToInfos[0];
10100
- if (!objectInfoApiMap[path]) {
10101
- objectInfoApiMap[path] = [];
10100
+ if (!pathToObjectApiNamesMap[path]) {
10101
+ pathToObjectApiNamesMap[path] = [];
10102
10102
  }
10103
- if (!objectInfoApiMap[path].includes(ref.apiName)) {
10104
- objectInfoApiMap[path].push(ref.apiName);
10103
+ if (!pathToObjectApiNamesMap[path].includes(ref.apiName)) {
10104
+ pathToObjectApiNamesMap[path].push(ref.apiName);
10105
10105
  }
10106
10106
  if (!apiNames.includes(ref.apiName)) {
10107
10107
  apiNames.push(ref.apiName);
@@ -10112,11 +10112,11 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10112
10112
  // handles 'childRelationship'
10113
10113
  const childRelationship = parentObjectInfo.childRelationships.find((childRelationship) => childRelationship.relationshipName === field);
10114
10114
  if (childRelationship) {
10115
- if (!objectInfoApiMap[path]) {
10116
- objectInfoApiMap[path] = [];
10115
+ if (!pathToObjectApiNamesMap[path]) {
10116
+ pathToObjectApiNamesMap[path] = [];
10117
10117
  }
10118
- if (!objectInfoApiMap[path].includes(childRelationship.childObjectApiName)) {
10119
- objectInfoApiMap[path].push(childRelationship.childObjectApiName);
10118
+ if (!pathToObjectApiNamesMap[path].includes(childRelationship.childObjectApiName)) {
10119
+ pathToObjectApiNamesMap[path].push(childRelationship.childObjectApiName);
10120
10120
  }
10121
10121
  if (!apiNames.includes(childRelationship.childObjectApiName)) {
10122
10122
  apiNames.push(childRelationship.childObjectApiName);
@@ -10141,7 +10141,7 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10141
10141
  const subLevelFields = objectInfotree[field];
10142
10142
  const path = `${parentPath}_${field}`;
10143
10143
  if (subLevelFields && subLevelFields.length > 0) {
10144
- const subObjectInfos = await fetchObjectInfos(objectInfotree, objectInfoApiMap, updatedObjectInfoMap, subLevelFields, path, objectInfoService);
10144
+ const subObjectInfos = await fetchObjectInfos(objectInfotree, pathToObjectApiNamesMap, updatedObjectInfoMap, subLevelFields, path, objectInfoService);
10145
10145
  updatedObjectInfoMap = { ...updatedObjectInfoMap, ...subObjectInfos };
10146
10146
  }
10147
10147
  }
@@ -10156,21 +10156,21 @@ async function fetchObjectInfos(objectInfotree, objectInfoApiMap, objectInfoMap,
10156
10156
  * 'path' and 'queryNode' is 1 level above the 'filterNode'
10157
10157
  * @param filterNode filter node which needs to be injected. For example, 'State' ObjectFieldNode within filter 'where: { State: { eq: "Nova Scotia" }}'
10158
10158
  * @param idState ID state will be updated to determine if the ID fields in AST need to be swapped. The swapping happens later.
10159
- * @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 'objectInfoApiMap', parent node is not an field of relationship or recordQuery
10159
+ * @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
10160
10160
  * @param queryNode referece FieldNode which provides the information if 'filterNode' exist in it nor not.
10161
10161
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10162
- * @param objectInfoApiMap 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'].
10162
+ * @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'].
10163
10163
  * @param draftFunctions functions for working with record ids that may be draft-created ids
10164
10164
  * @returns an array of nodes with injected fields
10165
10165
  */
10166
- function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode) {
10166
+ function injectFilter(filterNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode) {
10167
10167
  const injectedSelections = [];
10168
10168
  switch (filterNode.kind) {
10169
10169
  case Kind.ARGUMENT:
10170
10170
  if (filterNode.value.kind !== 'ObjectValue')
10171
10171
  return [];
10172
10172
  filterNode.value.fields.forEach((objectFieldNode) => {
10173
- let subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10173
+ let subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10174
10174
  for (const subResult of subResults) {
10175
10175
  mergeOrAddToGroup(injectedSelections, subResult);
10176
10176
  }
@@ -10185,7 +10185,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10185
10185
  case Kind.LIST: {
10186
10186
  filterNode.value.values.filter(isObjectValueNode).forEach((objectValueNode) => {
10187
10187
  objectValueNode.fields.forEach((objectFieldNode) => {
10188
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10188
+ const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10189
10189
  for (const subResult of subResults) {
10190
10190
  mergeOrAddToGroup(injectedSelections, subResult);
10191
10191
  }
@@ -10196,7 +10196,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10196
10196
  case Kind.OBJECT: {
10197
10197
  if (filterNode.name.value === 'not') {
10198
10198
  filterNode.value.fields.forEach((objectFieldNode) => {
10199
- const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, objectInfoApiMap, draftFunctions, queryNode);
10199
+ const subResults = injectFilter(objectFieldNode, idState, path, objectInfos, pathToObjectApiNamesMap, draftFunctions, queryNode);
10200
10200
  for (const subResult of subResults) {
10201
10201
  mergeOrAddToGroup(injectedSelections, subResult);
10202
10202
  }
@@ -10206,7 +10206,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10206
10206
  let apiNames = [];
10207
10207
  let isScalarField = false;
10208
10208
  //It is possible that this is a polymorphic field
10209
- apiNames = objectInfoApiMap[path];
10209
+ apiNames = pathToObjectApiNamesMap[path];
10210
10210
  // example: path: 'ServiceAppointment_LastModifiedDate'; filterNode: '{eq: {literal: LAST_WEEK}}'. queryNode: 'LastModifedDate { value}' FilterNode's parent has been verifed as a valid node
10211
10211
  if (apiNames === undefined) {
10212
10212
  isScalarField = true;
@@ -10236,29 +10236,23 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10236
10236
  }
10237
10237
  });
10238
10238
  let isSpanning = false;
10239
+ // if true, current node is a polymorphic concrete type node. For example, field node `User` under `Owner`
10239
10240
  let isInlineFragment = false;
10240
10241
  let isPolymorphicField = false;
10241
10242
  let isTypeNameExisting = false;
10242
10243
  let curPath;
10243
10244
  let fieldName = filterNode.name.value;
10244
10245
  curPath = `${path}_${fieldName}`;
10245
- if (objectInfoApiMap[curPath] && objectInfoApiMap[curPath].length > 0) {
10246
+ if (pathToObjectApiNamesMap[curPath] &&
10247
+ pathToObjectApiNamesMap[curPath].length > 0) {
10246
10248
  isSpanning = true;
10247
- if (objectInfoApiMap[curPath].length === 1) {
10248
- if (objectInfoApiMap[path] &&
10249
- objectInfoApiMap[path].length >= 1 &&
10250
- objectInfoApiMap[path].includes(objectInfoApiMap[curPath][0])) {
10251
- isInlineFragment = true;
10252
- }
10253
- }
10254
- // Checks if the current filter node is a polymorphic field. 'ServiceAppointment_Owner' --> ['User']; 'ServiceAppointment_Owner_User' --> ['User']
10255
- const childApiName = objectInfoApiMap[curPath][0];
10256
- const trialApiNames = objectInfoApiMap[`${curPath}_${childApiName}`];
10257
- if (trialApiNames !== undefined &&
10258
- trialApiNames.length === 1 &&
10259
- trialApiNames[0] === childApiName) {
10260
- isPolymorphicField = true;
10249
+ if (pathToObjectApiNamesMap[curPath].length === 1 &&
10250
+ pathToObjectApiNamesMap[path] &&
10251
+ pathToObjectApiNamesMap[path].length >= 1 &&
10252
+ pathToObjectApiNamesMap[path].includes(pathToObjectApiNamesMap[curPath][0])) {
10253
+ isInlineFragment = isPolymorphicFieldPath(path, pathToObjectApiNamesMap);
10261
10254
  }
10255
+ isPolymorphicField = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap);
10262
10256
  }
10263
10257
  // 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]
10264
10258
  if (isInlineFragment) {
@@ -10302,9 +10296,9 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10302
10296
  throw new Error(`Field ${fieldName} does not exist in ${apiNames[0]}`);
10303
10297
  }
10304
10298
  }
10305
- const objectInfoName = objectInfoApiMap[curPath] !== undefined
10306
- ? objectInfoApiMap[curPath][0]
10307
- : objectInfoApiMap[path][0];
10299
+ const objectInfoName = pathToObjectApiNamesMap[curPath] !== undefined
10300
+ ? pathToObjectApiNamesMap[curPath][0]
10301
+ : pathToObjectApiNamesMap[path][0];
10308
10302
  const isIdField = isFieldAnIdField(filterNode.name.value, objectInfos[objectInfoName]);
10309
10303
  if (!isIdField) {
10310
10304
  let subSelectionNodes = [];
@@ -10316,7 +10310,7 @@ function injectFilter(filterNode, idState, path, objectInfos, objectInfoApiMap,
10316
10310
  updateIDInfo(subFieldNode, idState, draftFunctions);
10317
10311
  }
10318
10312
  // try injecting the fields within predicate no matter it has relation or not.
10319
- let subResults = injectFilter(subFieldNode, idState, curPath, objectInfos, objectInfoApiMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10313
+ let subResults = injectFilter(subFieldNode, idState, curPath, objectInfos, pathToObjectApiNamesMap, draftFunctions, existingFields ? existingFields[0] : undefined);
10320
10314
  subSelectionNodes = subSelectionNodes.concat(subResults);
10321
10315
  });
10322
10316
  if (!subFieldsHasId) {
@@ -10477,6 +10471,16 @@ function mergeOrAddToGroup(group, element) {
10477
10471
  }
10478
10472
  group.push(element);
10479
10473
  }
10474
+ // 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"]}.
10475
+ // There must be also two entries pointing to concrete polymorphic field path. The two entries are like {"Path_elem1" : ["elem1"]} and {"Path_elem2" : ["elem2"]}
10476
+ // For example ServiceAppointment_Owner' --> ['User', 'Group']; 'ServiceAppointment_Owner_User' --> ['User'], 'ServiceAppointment_Owner_Group' --> ['Group']
10477
+ function isPolymorphicFieldPath(path, pathToObjectApiNamesMap) {
10478
+ const apiName = pathToObjectApiNamesMap[path][0];
10479
+ const apiNamesAtChildPath = pathToObjectApiNamesMap[`${path}_${apiName}`];
10480
+ return (apiNamesAtChildPath !== undefined &&
10481
+ apiNamesAtChildPath.length === 1 &&
10482
+ apiNamesAtChildPath[0] === apiName);
10483
+ }
10480
10484
  function isFieldAnIdField(fieldName, objectInfo) {
10481
10485
  if (fieldName === 'Id')
10482
10486
  return true;
@@ -10529,10 +10533,10 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
10529
10533
  * @param parentNode parent node of param 1
10530
10534
  * @param ancestors ancester of param 1
10531
10535
  * @param objectInfos ObjectInfo map used in injection. If ObjectInfo misses or field does not exist in ObjectInfo, the error will be thrown
10532
- * @param objectInfoApiMap 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'].
10536
+ * @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'].
10533
10537
  * @return injected SelectionNodes used to construct the InlineFragment.
10534
10538
  */
10535
- function injectFields(selections, parentNode, ancestors, objectInfos, objectInfoApiMap) {
10539
+ function injectFields(selections, parentNode, ancestors, objectInfos, pathToObjectApiNamesMap) {
10536
10540
  /**
10537
10541
  * 1 parentship can return 2 FieldNode which need to be flattened
10538
10542
  * Concact: { ** Contact { ** ContactId {
@@ -10557,7 +10561,7 @@ function injectFields(selections, parentNode, ancestors, objectInfos, objectInfo
10557
10561
  }
10558
10562
  }
10559
10563
  // Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
10560
- const subInjectedSelections = injectFields(spanningSubSelections, selection, ancestors, objectInfos, objectInfoApiMap);
10564
+ const subInjectedSelections = injectFields(spanningSubSelections, selection, ancestors, objectInfos, pathToObjectApiNamesMap);
10561
10565
  if (!selection.selectionSet) {
10562
10566
  return selection;
10563
10567
  }
@@ -10669,11 +10673,11 @@ function injectFields(selections, parentNode, ancestors, objectInfos, objectInfo
10669
10673
  const unVisitedAncestors = ancestors.slice(0, parentInfo.parentIndex);
10670
10674
  // path : "TimeSheet"
10671
10675
  const grandParentPath = findAncesterPath(unVisitedAncestors);
10672
- if (objectInfoApiMap &&
10673
- objectInfoApiMap[grandParentPath] &&
10676
+ if (pathToObjectApiNamesMap &&
10677
+ pathToObjectApiNamesMap[grandParentPath] &&
10674
10678
  objectInfos &&
10675
- objectInfos[objectInfoApiMap[grandParentPath][0]]) {
10676
- const grandParentObjectInfo = objectInfos[objectInfoApiMap[grandParentPath][0]];
10679
+ objectInfos[pathToObjectApiNamesMap[grandParentPath][0]]) {
10680
+ const grandParentObjectInfo = objectInfos[pathToObjectApiNamesMap[grandParentPath][0]];
10677
10681
  // exmaple "TimeSheetEntries"
10678
10682
  const parentFieldName = parent.name.value;
10679
10683
  const targetRelationship = grandParentObjectInfo.childRelationships.find((childRelationship) => {
@@ -17059,4 +17063,4 @@ register({
17059
17063
  });
17060
17064
 
17061
17065
  export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
17062
- // version: 1.239.0-6c531185a
17066
+ // version: 1.241.0-b14b649d4