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