@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.
- package/dist/main.js +70 -66
- package/package.json +1 -1
- 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
|
|
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,
|
|
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 =
|
|
9592
|
-
?
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
9692
|
-
?
|
|
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 =
|
|
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,
|
|
9796
|
-
const apiName =
|
|
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,
|
|
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
|
-
|
|
10012
|
+
pathToObjectApiNamesMap[startNode] = [startNode];
|
|
10013
10013
|
const children = objectInfotree[startNode];
|
|
10014
|
-
const subObjectInfoMap = await fetchObjectInfos(objectInfotree,
|
|
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,
|
|
10023
|
-
const objectInfoApiNames =
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
10086
|
-
|
|
10085
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10086
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10087
10087
|
}
|
|
10088
10088
|
// 'ServiceAppointment_Owner' ->['User', 'Group']
|
|
10089
|
-
if (!
|
|
10090
|
-
|
|
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 (!
|
|
10101
|
-
|
|
10100
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10101
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10102
10102
|
}
|
|
10103
|
-
if (!
|
|
10104
|
-
|
|
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 (!
|
|
10116
|
-
|
|
10115
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10116
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10117
10117
|
}
|
|
10118
|
-
if (!
|
|
10119
|
-
|
|
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,
|
|
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 '
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
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 (
|
|
10246
|
+
if (pathToObjectApiNamesMap[curPath] &&
|
|
10247
|
+
pathToObjectApiNamesMap[curPath].length > 0) {
|
|
10246
10248
|
isSpanning = true;
|
|
10247
|
-
if (
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
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 =
|
|
10306
|
-
?
|
|
10307
|
-
:
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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 (
|
|
10673
|
-
|
|
10676
|
+
if (pathToObjectApiNamesMap &&
|
|
10677
|
+
pathToObjectApiNamesMap[grandParentPath] &&
|
|
10674
10678
|
objectInfos &&
|
|
10675
|
-
objectInfos[
|
|
10676
|
-
const grandParentObjectInfo = objectInfos[
|
|
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.
|
|
17066
|
+
// version: 1.241.0-b14b649d4
|
package/package.json
CHANGED
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
|
|
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,
|
|
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 =
|
|
9592
|
-
?
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
9692
|
-
?
|
|
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 =
|
|
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,
|
|
9796
|
-
const apiName =
|
|
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,
|
|
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
|
-
|
|
10012
|
+
pathToObjectApiNamesMap[startNode] = [startNode];
|
|
10013
10013
|
const children = objectInfotree[startNode];
|
|
10014
|
-
const subObjectInfoMap = await fetchObjectInfos(objectInfotree,
|
|
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,
|
|
10023
|
-
const objectInfoApiNames =
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
10086
|
-
|
|
10085
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10086
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10087
10087
|
}
|
|
10088
10088
|
// 'ServiceAppointment_Owner' ->['User', 'Group']
|
|
10089
|
-
if (!
|
|
10090
|
-
|
|
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 (!
|
|
10101
|
-
|
|
10100
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10101
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10102
10102
|
}
|
|
10103
|
-
if (!
|
|
10104
|
-
|
|
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 (!
|
|
10116
|
-
|
|
10115
|
+
if (!pathToObjectApiNamesMap[path]) {
|
|
10116
|
+
pathToObjectApiNamesMap[path] = [];
|
|
10117
10117
|
}
|
|
10118
|
-
if (!
|
|
10119
|
-
|
|
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,
|
|
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 '
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
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 (
|
|
10246
|
+
if (pathToObjectApiNamesMap[curPath] &&
|
|
10247
|
+
pathToObjectApiNamesMap[curPath].length > 0) {
|
|
10246
10248
|
isSpanning = true;
|
|
10247
|
-
if (
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
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 =
|
|
10306
|
-
?
|
|
10307
|
-
:
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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 (
|
|
10673
|
-
|
|
10676
|
+
if (pathToObjectApiNamesMap &&
|
|
10677
|
+
pathToObjectApiNamesMap[grandParentPath] &&
|
|
10674
10678
|
objectInfos &&
|
|
10675
|
-
objectInfos[
|
|
10676
|
-
const grandParentObjectInfo = objectInfos[
|
|
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.
|
|
17066
|
+
// version: 1.241.0-b14b649d4
|