@salesforce/lds-runtime-mobile 1.280.0 → 1.282.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 +289 -166
- package/package.json +18 -18
- package/sfdc/main.js +289 -166
package/dist/main.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { withRegistration, register } from '@salesforce/lds-default-luvio';
|
|
19
19
|
import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrumentLuvio, setLdsAdaptersUiapiInstrumentation, setLdsNetworkAdapterInstrumentation } from '@salesforce/lds-instrumentation';
|
|
20
|
-
import { HttpStatusCode, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
|
|
20
|
+
import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
|
|
21
21
|
import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
|
|
22
22
|
import { parseAndVisit, Kind, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from '@luvio/graphql-parser';
|
|
23
23
|
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion, getRecordsAdapterFactory } from '@salesforce/lds-adapters-uiapi';
|
|
@@ -1019,7 +1019,9 @@ function isUnfulfilledSnapshot$1(cachedSnapshotResult) {
|
|
|
1019
1019
|
* @param durableStore A DurableStore implementation
|
|
1020
1020
|
* @param instrumentation An instrumentation function implementation
|
|
1021
1021
|
*/
|
|
1022
|
-
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, }) {
|
|
1022
|
+
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, disableDeepFreeze = false, }) {
|
|
1023
|
+
// runtimes can choose to disable deepFreeze, e.g. headless mobile runtime
|
|
1024
|
+
setBypassDeepFreeze(disableDeepFreeze);
|
|
1023
1025
|
let stagingStore = null;
|
|
1024
1026
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
1025
1027
|
const mergeKeysPromiseMap = new Map();
|
|
@@ -7967,6 +7969,9 @@ function sanitizePredicateIDValue(value, draftFunction) {
|
|
|
7967
7969
|
if (isArray$2(value)) {
|
|
7968
7970
|
return value.map((singleValue) => sanitizePredicateIDValue(singleValue, draftFunction));
|
|
7969
7971
|
}
|
|
7972
|
+
else if (typeof value === 'string' && value === '') {
|
|
7973
|
+
return value;
|
|
7974
|
+
}
|
|
7970
7975
|
else {
|
|
7971
7976
|
const coercedId = getRecordId18(value);
|
|
7972
7977
|
if (coercedId !== undefined) {
|
|
@@ -8657,24 +8662,36 @@ function findAncesterPath(ancesters) {
|
|
|
8657
8662
|
}
|
|
8658
8663
|
return path;
|
|
8659
8664
|
}
|
|
8665
|
+
function isCategoryDirective(node) {
|
|
8666
|
+
return node.name.value === 'category';
|
|
8667
|
+
}
|
|
8660
8668
|
/**
|
|
8661
8669
|
* checks if the 'SelectionNode' has the potential to have relationship(parent or child) with its ancestor.
|
|
8662
8670
|
* @param node
|
|
8663
8671
|
* @returns
|
|
8664
8672
|
*/
|
|
8665
8673
|
function isCapableRelationship(node) {
|
|
8666
|
-
if (
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
return
|
|
8676
|
-
|
|
8677
|
-
|
|
8674
|
+
if (isFieldNode(node)) {
|
|
8675
|
+
if (node.directives !== undefined) {
|
|
8676
|
+
const argNodes = node.directives
|
|
8677
|
+
.flatMap((directive) => {
|
|
8678
|
+
if (isCategoryDirective(directive) === false)
|
|
8679
|
+
return undefined;
|
|
8680
|
+
return directive.arguments;
|
|
8681
|
+
})
|
|
8682
|
+
.filter((x) => x);
|
|
8683
|
+
return argNodes.some((argument) => {
|
|
8684
|
+
if (argument.name.value !== 'name')
|
|
8685
|
+
return false;
|
|
8686
|
+
if (argument.value.kind !== 'StringValue')
|
|
8687
|
+
return false;
|
|
8688
|
+
return (argument.value.value === PARENT_RELATIONSHIP ||
|
|
8689
|
+
argument.value.value === CHILD_RELATIONSHIP ||
|
|
8690
|
+
argument.value.value === POLYMORPHIC_PARENT_RELATIONSHIP);
|
|
8691
|
+
});
|
|
8692
|
+
}
|
|
8693
|
+
}
|
|
8694
|
+
return isInlineFragmentNode(node);
|
|
8678
8695
|
}
|
|
8679
8696
|
/**
|
|
8680
8697
|
* checks if the 'ArgumentNode' is a specific scope type
|
|
@@ -9412,6 +9429,12 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9412
9429
|
break;
|
|
9413
9430
|
case 'LastModifiedDate':
|
|
9414
9431
|
field.resolve = ({ recordRepresentation: record }) => {
|
|
9432
|
+
// In UIAPI record reps, LastModifiedDate might be present as a field,
|
|
9433
|
+
// which will include both the value and displayValue
|
|
9434
|
+
if (record.fields['LastModifiedDate']) {
|
|
9435
|
+
return record.fields['LastModifiedDate'];
|
|
9436
|
+
}
|
|
9437
|
+
// If the field is not present, just return the value of the root property
|
|
9415
9438
|
return record.lastModifiedDate
|
|
9416
9439
|
? { value: record.lastModifiedDate }
|
|
9417
9440
|
: null;
|
|
@@ -9539,7 +9562,6 @@ _, { objectInfos }) {
|
|
|
9539
9562
|
}
|
|
9540
9563
|
}
|
|
9541
9564
|
}
|
|
9542
|
-
// TODO [W-14660068]: composite name fields
|
|
9543
9565
|
return null;
|
|
9544
9566
|
}
|
|
9545
9567
|
async function connectionEdgeResolver(obj, _args, context) {
|
|
@@ -10603,6 +10625,9 @@ function growObjectFieldTree(tree, parentNode, entryNode, totalNodes, startNodes
|
|
|
10603
10625
|
}
|
|
10604
10626
|
});
|
|
10605
10627
|
}
|
|
10628
|
+
function isNodeOrEdges(node) {
|
|
10629
|
+
return isFieldNode(node) && (node.name.value === 'node' || node.name.value === 'edges');
|
|
10630
|
+
}
|
|
10606
10631
|
/**
|
|
10607
10632
|
* Build a relationship tree from the top FieldNode 'node'
|
|
10608
10633
|
* @param tree
|
|
@@ -10613,7 +10638,7 @@ function growObjectFieldTree(tree, parentNode, entryNode, totalNodes, startNodes
|
|
|
10613
10638
|
* @param startNodes
|
|
10614
10639
|
*/
|
|
10615
10640
|
function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNodes, startNodes) {
|
|
10616
|
-
if (isCapableRelationship(entryNode)) {
|
|
10641
|
+
if (isCapableRelationship(entryNode) || isNodeOrEdges(entryNode)) {
|
|
10617
10642
|
if (isFieldNode(entryNode)) {
|
|
10618
10643
|
const relationType = getRelation(entryNode);
|
|
10619
10644
|
const fieldName = entryNode.name.value;
|
|
@@ -11200,6 +11225,131 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
|
|
|
11200
11225
|
}
|
|
11201
11226
|
}
|
|
11202
11227
|
}
|
|
11228
|
+
function findIdFieldNode(node) {
|
|
11229
|
+
if (node.selectionSet === undefined)
|
|
11230
|
+
return false;
|
|
11231
|
+
return node.selectionSet.selections.some((selection) => {
|
|
11232
|
+
if (isFieldNode(selection)) {
|
|
11233
|
+
return selection.name.value === 'Id';
|
|
11234
|
+
}
|
|
11235
|
+
return false;
|
|
11236
|
+
});
|
|
11237
|
+
}
|
|
11238
|
+
/**
|
|
11239
|
+
* 1 parentship can return 2 FieldNode which need to be flattened
|
|
11240
|
+
* Concact: { ** Contact { ** ContactId {
|
|
11241
|
+
* Name: { ** Id ** value
|
|
11242
|
+
* value ** } ** }
|
|
11243
|
+
* } **
|
|
11244
|
+
* }
|
|
11245
|
+
* `parentRelationships` is a 2-dimensional array. 1 element at the top level of the array is an array of injected fields(which could has 2 elements) for
|
|
11246
|
+
* one field(`Contact`, for example), For example, `Contact` field could map to field `Contact { Id }` and `ContactId { value }` which are injected.
|
|
11247
|
+
* `Account` field could map to field `Account { Id }` and `AccountID { value }`.
|
|
11248
|
+
* Returned `parentRelationships` would look like [ [`Contact { Id }`, `ContactId { value }`], [`Account { Id }`, `AccountId { value }`]]. It needs to
|
|
11249
|
+
* be flattened to [`Contact { Id }`, `ContactId { value }`, `Account { Id }`, `AccountId { value }`]
|
|
11250
|
+
*/
|
|
11251
|
+
function injectParentRelationships(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap) {
|
|
11252
|
+
let parentInjectedNodes = [];
|
|
11253
|
+
for (let i = 0, len = selections.length; i < len; i++) {
|
|
11254
|
+
const selection = selections[i];
|
|
11255
|
+
// have to wrap in the if statement to make rollup happy :(
|
|
11256
|
+
if (isFieldOrInlineFragmentNode(selection)) {
|
|
11257
|
+
if (selection.selectionSet === undefined) {
|
|
11258
|
+
parentInjectedNodes.push(selection);
|
|
11259
|
+
continue;
|
|
11260
|
+
}
|
|
11261
|
+
const segment = isFieldNode(selection)
|
|
11262
|
+
? selection.name.value
|
|
11263
|
+
: selection.typeCondition.name.value;
|
|
11264
|
+
const curPath = `${parentPath}#${segment}`;
|
|
11265
|
+
const spanningSubSelections = [];
|
|
11266
|
+
for (const subSelection of selection.selectionSet.selections) {
|
|
11267
|
+
if (isFieldSpanning(subSelection, selection)) {
|
|
11268
|
+
spanningSubSelections.push(subSelection);
|
|
11269
|
+
}
|
|
11270
|
+
}
|
|
11271
|
+
// Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
|
|
11272
|
+
const subInjectedSelections = injectFields(spanningSubSelections, selection, curPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11273
|
+
const hasIdNode = findIdFieldNode(selection);
|
|
11274
|
+
// For InlineFragment like '... on User', do not create relationship. Relationship is handled at the upper level.
|
|
11275
|
+
if (isFieldNode(selection)) {
|
|
11276
|
+
const fieldName = selection.name.value;
|
|
11277
|
+
const relationshipId = referenceIdFieldForRelationship(fieldName);
|
|
11278
|
+
// check if relation field like 'AccountId' does exist in query
|
|
11279
|
+
const existingRelationFields = [parentNode]
|
|
11280
|
+
.filter(isFieldOrInlineFragmentNode)
|
|
11281
|
+
.reduce(extractSelections, [])
|
|
11282
|
+
.filter(isFieldNode)
|
|
11283
|
+
.filter((subNode) => subNode.name.value === relationshipId);
|
|
11284
|
+
if (existingRelationFields.length === 0) {
|
|
11285
|
+
parentInjectedNodes.push(createFieldNode(relationshipId, FieldValueNodeSelectionSet));
|
|
11286
|
+
}
|
|
11287
|
+
}
|
|
11288
|
+
// For polymorphic fields, the Id field is excluded.
|
|
11289
|
+
const excludeId = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
|
|
11290
|
+
const idSelection = [];
|
|
11291
|
+
if (!excludeId && hasIdNode === false) {
|
|
11292
|
+
idSelection.push(createFieldNode('Id'));
|
|
11293
|
+
}
|
|
11294
|
+
// 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
|
|
11295
|
+
// `typedCondition` of the InlineFragment in the query AST. It is used to match JSON response with AST node. For more detail, please reference 'removeSyntheticFields'.
|
|
11296
|
+
if (isInlineFragmentNode(selection) &&
|
|
11297
|
+
!selection.selectionSet.selections.find((selection) => isFieldNode(selection) && selection.name.value === '__typename')) {
|
|
11298
|
+
idSelection.push(createFieldNode('__typename'));
|
|
11299
|
+
}
|
|
11300
|
+
// 'ServiceAppointment' --> 'Contact' --> 'Id', Inject 'Contact' with Id. 'Id' field is at the sub level.
|
|
11301
|
+
if (idSelection.length > 0 || subInjectedSelections.length > 0) {
|
|
11302
|
+
parentInjectedNodes.push({
|
|
11303
|
+
...selection,
|
|
11304
|
+
selectionSet: {
|
|
11305
|
+
kind: Kind.SELECTION_SET,
|
|
11306
|
+
selections: [...idSelection, ...subInjectedSelections],
|
|
11307
|
+
},
|
|
11308
|
+
});
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
return parentInjectedNodes;
|
|
11313
|
+
}
|
|
11314
|
+
/**
|
|
11315
|
+
* Find any name fields needed for the DisplayValue field
|
|
11316
|
+
* @param param0
|
|
11317
|
+
* @param parentNode
|
|
11318
|
+
* @param objectInfos
|
|
11319
|
+
* @returns
|
|
11320
|
+
*/
|
|
11321
|
+
function injectFieldsForDisplayValue(topNode, parentNode, objectInfos) {
|
|
11322
|
+
const { selectionSet } = topNode;
|
|
11323
|
+
if (selectionSet === undefined)
|
|
11324
|
+
return [];
|
|
11325
|
+
let displayValueNameFields = [];
|
|
11326
|
+
const { selections } = selectionSet;
|
|
11327
|
+
// see if node selection has DisplayValue and needs to inject
|
|
11328
|
+
let displayValue;
|
|
11329
|
+
for (let i = 0, len = selections.length; i < len; i++) {
|
|
11330
|
+
const node = selections[i];
|
|
11331
|
+
if (isFieldNode(node) && node.name.value === 'DisplayValue') {
|
|
11332
|
+
displayValue = node;
|
|
11333
|
+
break;
|
|
11334
|
+
}
|
|
11335
|
+
if (isInlineFragmentNode(node)) {
|
|
11336
|
+
const name = node.typeCondition !== undefined ? node.typeCondition.name : parentNode.name;
|
|
11337
|
+
displayValueNameFields = injectFieldsForDisplayValue(node, { ...parentNode, name }, objectInfos);
|
|
11338
|
+
}
|
|
11339
|
+
}
|
|
11340
|
+
if (displayValue !== undefined) {
|
|
11341
|
+
const apiName = parentNode.name.value;
|
|
11342
|
+
const objectInfo = objectInfos[apiName];
|
|
11343
|
+
if (objectInfo !== undefined &&
|
|
11344
|
+
objectInfo.nameFields !== undefined &&
|
|
11345
|
+
objectInfo.nameFields.length > 0) {
|
|
11346
|
+
displayValueNameFields = objectInfo.nameFields.map((fieldName) => {
|
|
11347
|
+
return createFieldNode(fieldName, FieldValueNodeSelectionSet);
|
|
11348
|
+
});
|
|
11349
|
+
}
|
|
11350
|
+
}
|
|
11351
|
+
return displayValueNameFields;
|
|
11352
|
+
}
|
|
11203
11353
|
/**
|
|
11204
11354
|
* injects fields under query
|
|
11205
11355
|
* @param selections selection nodes need to be injected.
|
|
@@ -11210,160 +11360,67 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
|
|
|
11210
11360
|
* @return injected SelectionNodes used to construct the InlineFragment.
|
|
11211
11361
|
*/
|
|
11212
11362
|
function injectFields(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap) {
|
|
11213
|
-
|
|
11214
|
-
* 1 parentship can return 2 FieldNode which need to be flattened
|
|
11215
|
-
* Concact: { ** Contact { ** ContactId {
|
|
11216
|
-
* Name: { ** Id ** value
|
|
11217
|
-
* value ** } ** }
|
|
11218
|
-
* } **
|
|
11219
|
-
* }
|
|
11220
|
-
* `parentRelationships` is a 2-dimensional array. 1 element at the top level of the array is an array of injected fields(which could has 2 elements) for
|
|
11221
|
-
* one field(`Contact`, for example), For example, `Contact` field could map to field `Contact { Id }` and `ContactId { value }` which are injected.
|
|
11222
|
-
* `Account` field could map to field `Account { Id }` and `AccountID { value }`.
|
|
11223
|
-
* Returned `parentRelationships` would look like [ [`Contact { Id }`, `ContactId { value }`], [`Account { Id }`, `AccountId { value }`]]. It needs to
|
|
11224
|
-
* be flattened to [`Contact { Id }`, `ContactId { value }`, `Account { Id }`, `AccountId { value }`]
|
|
11225
|
-
*/
|
|
11226
|
-
const parentRelaltionships = selections.filter(isFieldOrInlineFragmentNode).map((selection) => {
|
|
11227
|
-
if (!selection.selectionSet) {
|
|
11228
|
-
return selection;
|
|
11229
|
-
}
|
|
11230
|
-
const segment = isFieldNode(selection)
|
|
11231
|
-
? selection.name.value
|
|
11232
|
-
: selection.typeCondition.name.value;
|
|
11233
|
-
const curPath = `${parentPath}#${segment}`;
|
|
11234
|
-
const spanningSubSelections = [];
|
|
11235
|
-
for (const subSelection of selection.selectionSet.selections) {
|
|
11236
|
-
if (isFieldSpanning(subSelection, selection)) {
|
|
11237
|
-
spanningSubSelections.push(subSelection);
|
|
11238
|
-
}
|
|
11239
|
-
}
|
|
11240
|
-
// Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
|
|
11241
|
-
const subInjectedSelections = injectFields(spanningSubSelections, selection, curPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11242
|
-
if (!selection.selectionSet) {
|
|
11243
|
-
return selection;
|
|
11244
|
-
}
|
|
11245
|
-
const hasIdAlready = selection.selectionSet.selections
|
|
11246
|
-
.filter(isFieldNode)
|
|
11247
|
-
.find((s) => s.name.value === 'Id');
|
|
11248
|
-
// For InlineFragment like '... on User', do not create relationship. Relationship is handled at the upper level.
|
|
11249
|
-
let injectedRelationshipField = [];
|
|
11250
|
-
if (isFieldNode(selection)) {
|
|
11251
|
-
const fieldName = selection.name.value;
|
|
11252
|
-
const relationshipId = referenceIdFieldForRelationship(fieldName);
|
|
11253
|
-
// check if relation field like 'AccountId' does exist in query
|
|
11254
|
-
const existingRelationFields = [parentNode]
|
|
11255
|
-
.filter(isFieldOrInlineFragmentNode)
|
|
11256
|
-
.reduce(extractSelections, [])
|
|
11257
|
-
.filter(isFieldNode)
|
|
11258
|
-
.filter((subNode) => subNode.name.value === relationshipId);
|
|
11259
|
-
if (existingRelationFields.length === 0) {
|
|
11260
|
-
injectedRelationshipField = [
|
|
11261
|
-
createFieldNode(relationshipId, FieldValueNodeSelectionSet),
|
|
11262
|
-
];
|
|
11263
|
-
}
|
|
11264
|
-
}
|
|
11265
|
-
// For polymorphic fields, the Id field is excluded.
|
|
11266
|
-
const excludeId = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
|
|
11267
|
-
const idSelection = [];
|
|
11268
|
-
if (!excludeId && !hasIdAlready) {
|
|
11269
|
-
idSelection.push(createFieldNode('Id'));
|
|
11270
|
-
}
|
|
11271
|
-
// 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
|
|
11272
|
-
// `typedCondition` of the InlineFragment in the query AST. It is used to match JSON response with AST node. For more detail, please reference 'removeSyntheticFields'.
|
|
11273
|
-
if (isInlineFragmentNode(selection) &&
|
|
11274
|
-
!selection.selectionSet.selections.find((selection) => isFieldNode(selection) && selection.name.value === '__typename')) {
|
|
11275
|
-
idSelection.push(createFieldNode('__typename'));
|
|
11276
|
-
}
|
|
11277
|
-
// 'ServiceAppointment' --> 'Contact' --> 'Id', Inject 'Contact' with Id. 'Id' field is at the sub level.
|
|
11278
|
-
const injectedSelectionIdField = idSelection.length > 0 || subInjectedSelections.length > 0
|
|
11279
|
-
? [
|
|
11280
|
-
{
|
|
11281
|
-
...selection,
|
|
11282
|
-
selectionSet: {
|
|
11283
|
-
kind: Kind.SELECTION_SET,
|
|
11284
|
-
selections: [...idSelection, ...subInjectedSelections],
|
|
11285
|
-
},
|
|
11286
|
-
},
|
|
11287
|
-
]
|
|
11288
|
-
: [];
|
|
11289
|
-
return [...injectedSelectionIdField, ...injectedRelationshipField];
|
|
11290
|
-
});
|
|
11291
|
-
// injects Id if the parent of the 'childRelationship' does not contain an Id field. The logic here only deals with 'parentNode'
|
|
11292
|
-
const idForChildRelationship = [];
|
|
11363
|
+
const parentRelaltionships = injectParentRelationships(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11293
11364
|
// inject related field for the parent of the 'childRelationship'.
|
|
11294
11365
|
const relatedIdForChildRelationship = [];
|
|
11295
11366
|
// injected fields for DisplayValue
|
|
11296
11367
|
let displayValueNameFields = [];
|
|
11368
|
+
let rootQueryIdField = [];
|
|
11297
11369
|
// injects 'childRelatiship' at the 'node' level, it does not matter if the 'selections' is empty or not.
|
|
11298
11370
|
// the operation happens at the same level as the 'childRelationship' field.
|
|
11299
|
-
if (isFieldNode(parentNode) &&
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
}
|
|
11308
|
-
}
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
relatedIdForChildRelationship.push(createFieldNode(injectedParentFieldName, FieldValueNodeSelectionSet));
|
|
11336
|
-
}
|
|
11371
|
+
if (isFieldNode(parentNode) &&
|
|
11372
|
+
parentNode.selectionSet !== undefined &&
|
|
11373
|
+
(parentNode.name.value === 'node' || isCapableRelationship(parentNode))) {
|
|
11374
|
+
//check if the root query has the Id and inject if it needed
|
|
11375
|
+
if (parentNode.name.value === 'node') {
|
|
11376
|
+
const idNode = findIdFieldNode(parentNode);
|
|
11377
|
+
if (idNode === false) {
|
|
11378
|
+
rootQueryIdField.push(createFieldNode('Id'));
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
11381
|
+
// example { node { Id } }. The operation happens at the 'edges' -> 'node' level of the 'childRelationship' field
|
|
11382
|
+
const parentInfo = findNearestAncesterPath(ancestors, true);
|
|
11383
|
+
if (parentInfo.parentIndex >= 0) {
|
|
11384
|
+
// example node { TimeSheetEntries { edges { node { Id }}}}
|
|
11385
|
+
const parent = parentNode.name.value === 'node' ? parentInfo.node : parentNode;
|
|
11386
|
+
if (isRelationship(parent, CHILD_RELATIONSHIP)) {
|
|
11387
|
+
const unVisitedAncestors = ancestors.slice(0, parentInfo.parentIndex);
|
|
11388
|
+
// path : "TimeSheet"
|
|
11389
|
+
const grandParentPath = findAncesterPath(unVisitedAncestors);
|
|
11390
|
+
if (pathToObjectApiNamesMap &&
|
|
11391
|
+
pathToObjectApiNamesMap[grandParentPath] &&
|
|
11392
|
+
objectInfos &&
|
|
11393
|
+
objectInfos[pathToObjectApiNamesMap[grandParentPath][0]]) {
|
|
11394
|
+
const grandParentObjectInfo = objectInfos[pathToObjectApiNamesMap[grandParentPath][0]];
|
|
11395
|
+
// exmaple "TimeSheetEntries"
|
|
11396
|
+
const parentFieldName = parent.name.value;
|
|
11397
|
+
const targetRelationship = grandParentObjectInfo.childRelationships.find((childRelationship) => {
|
|
11398
|
+
return childRelationship.relationshipName === parentFieldName;
|
|
11399
|
+
});
|
|
11400
|
+
if (targetRelationship !== undefined) {
|
|
11401
|
+
const injectedParentFieldName = targetRelationship.fieldName;
|
|
11402
|
+
if (!parentNode.selectionSet.selections
|
|
11403
|
+
.filter(isFieldNode)
|
|
11404
|
+
.some((sibling) => sibling.name.value === injectedParentFieldName)) {
|
|
11405
|
+
// example: TimeSheetId { value }
|
|
11406
|
+
relatedIdForChildRelationship.push(createFieldNode(injectedParentFieldName, FieldValueNodeSelectionSet));
|
|
11337
11407
|
}
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
|
|
11345
|
-
if (isFieldNode(node) && node.name.value === 'DisplayValue') {
|
|
11346
|
-
displayValue = node;
|
|
11347
|
-
break;
|
|
11348
|
-
}
|
|
11349
|
-
}
|
|
11350
|
-
if (displayValue !== undefined) {
|
|
11351
|
-
const apiName = parent.name.value;
|
|
11352
|
-
const objectInfo = objectInfos[apiName];
|
|
11353
|
-
if (objectInfo !== undefined &&
|
|
11354
|
-
objectInfo.nameFields !== undefined &&
|
|
11355
|
-
objectInfo.nameFields.length > 0) {
|
|
11356
|
-
displayValueNameFields = objectInfo.nameFields.map((fieldName) => {
|
|
11357
|
-
return createFieldNode(fieldName, FieldValueNodeSelectionSet);
|
|
11358
|
-
});
|
|
11408
|
+
displayValueNameFields.push(...injectFieldsForDisplayValue(parentNode, {
|
|
11409
|
+
...parent,
|
|
11410
|
+
name: {
|
|
11411
|
+
...parent.name,
|
|
11412
|
+
value: targetRelationship.childObjectApiName,
|
|
11413
|
+
},
|
|
11414
|
+
}, objectInfos));
|
|
11359
11415
|
}
|
|
11360
11416
|
}
|
|
11361
11417
|
}
|
|
11418
|
+
displayValueNameFields.push(...injectFieldsForDisplayValue(parentNode, parent, objectInfos));
|
|
11362
11419
|
}
|
|
11363
11420
|
}
|
|
11364
11421
|
return [
|
|
11422
|
+
...rootQueryIdField,
|
|
11365
11423
|
...flat(parentRelaltionships),
|
|
11366
|
-
...idForChildRelationship,
|
|
11367
11424
|
...relatedIdForChildRelationship,
|
|
11368
11425
|
...displayValueNameFields,
|
|
11369
11426
|
];
|
|
@@ -12135,6 +12192,60 @@ function replayDraftsOnRecord(record, draftMetadata) {
|
|
|
12135
12192
|
}
|
|
12136
12193
|
return recursivelyApplyDraftsToRecord(baseRecord, draftMetadata, draftMetadata.recordOperations);
|
|
12137
12194
|
}
|
|
12195
|
+
/**
|
|
12196
|
+
* checks if updated fields are apart of the compound Name field
|
|
12197
|
+
* will generate a compound Name field if it is not already apart of the draft
|
|
12198
|
+
* @param record
|
|
12199
|
+
* @param draftFields
|
|
12200
|
+
* @param apiName
|
|
12201
|
+
* @param objectInfos
|
|
12202
|
+
* @returns
|
|
12203
|
+
*/
|
|
12204
|
+
function compoundNameFieldFromDraftUpdates(record, draftFields, apiName, objectInfos) {
|
|
12205
|
+
let updatedNameFields = {};
|
|
12206
|
+
const objectInfo = objectInfos.get(apiName);
|
|
12207
|
+
if (draftFields['Name'] !== undefined ||
|
|
12208
|
+
objectInfo === undefined ||
|
|
12209
|
+
objectInfo.nameFields === undefined ||
|
|
12210
|
+
objectInfo.nameFields.length === 0) {
|
|
12211
|
+
return updatedNameFields;
|
|
12212
|
+
}
|
|
12213
|
+
const nameField = objectInfo.nameFields.find((x) => x === 'Name');
|
|
12214
|
+
if (nameField === undefined) {
|
|
12215
|
+
return updatedNameFields;
|
|
12216
|
+
}
|
|
12217
|
+
const { compound, updateable } = objectInfo.fields[nameField];
|
|
12218
|
+
if (objectInfo.nameFields.length <= 1 && compound === false && updateable === true) {
|
|
12219
|
+
return updatedNameFields;
|
|
12220
|
+
}
|
|
12221
|
+
let changedNameFields = {};
|
|
12222
|
+
const filteredNameFields = objectInfo.nameFields.filter((x) => x !== 'Name');
|
|
12223
|
+
for (let i = 0, len = filteredNameFields.length; i < len; i++) {
|
|
12224
|
+
const fieldName = filteredNameFields[i];
|
|
12225
|
+
const fieldValue = draftFields[fieldName];
|
|
12226
|
+
if (fieldValue !== undefined) {
|
|
12227
|
+
changedNameFields[fieldName] = fieldValue;
|
|
12228
|
+
}
|
|
12229
|
+
}
|
|
12230
|
+
if (keys$3(changedNameFields).length > 0) {
|
|
12231
|
+
const newNameValue = filteredNameFields
|
|
12232
|
+
.map((key) => {
|
|
12233
|
+
if (changedNameFields[key] !== undefined) {
|
|
12234
|
+
return changedNameFields[key];
|
|
12235
|
+
}
|
|
12236
|
+
else if (record.fields[key] !== undefined) {
|
|
12237
|
+
return record.fields[key].value;
|
|
12238
|
+
}
|
|
12239
|
+
else {
|
|
12240
|
+
return '';
|
|
12241
|
+
}
|
|
12242
|
+
})
|
|
12243
|
+
.join(' ')
|
|
12244
|
+
.trim();
|
|
12245
|
+
updatedNameFields['Name'] = newNameValue;
|
|
12246
|
+
}
|
|
12247
|
+
return updatedNameFields;
|
|
12248
|
+
}
|
|
12138
12249
|
function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations) {
|
|
12139
12250
|
const { luvio, objectInfos, userId, formatDisplayValue, referencedRecords } = draftMetadata;
|
|
12140
12251
|
if (recordOperations.length === 0) {
|
|
@@ -12194,8 +12305,15 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
|
|
|
12194
12305
|
record.drafts.deleted = true;
|
|
12195
12306
|
}
|
|
12196
12307
|
// 'lastModifiedById' and 'lastModifiedDate' are modified in 'delete' and 'update' action
|
|
12197
|
-
const
|
|
12308
|
+
const draftOperationFields = draftActionType === 'delete' ? {} : draftOperation.fields;
|
|
12198
12309
|
const apiName = draftOperation.apiName;
|
|
12310
|
+
const injectedCompoundNameField = compoundNameFieldFromDraftUpdates(record, draftOperationFields, apiName, objectInfos);
|
|
12311
|
+
// inject the compound Name field into the DraftOperation so on broadcast it doesnt try to
|
|
12312
|
+
// synthesize the Name field a second time when the durable store change notifier is triggered
|
|
12313
|
+
if (keys$3(injectedCompoundNameField).length > 0 && draftActionType === 'update') {
|
|
12314
|
+
draftOperation.fields['Name'] = injectedCompoundNameField['Name'];
|
|
12315
|
+
}
|
|
12316
|
+
const fields = { ...draftOperationFields, ...injectedCompoundNameField };
|
|
12199
12317
|
// automaticlly add 'lastModifiedById' and 'lastModifiedByDate' and use an internal draft field copy since it is mutable
|
|
12200
12318
|
const internalFields = {
|
|
12201
12319
|
...fields,
|
|
@@ -15996,9 +16114,9 @@ function instrumentAdapter(adapter, metadata) {
|
|
|
15996
16114
|
}
|
|
15997
16115
|
}
|
|
15998
16116
|
return instrumentAdapter$1(instrumentedMobileAdapter, metadata, {
|
|
15999
|
-
trackL1Hits:
|
|
16000
|
-
trackL2Hits:
|
|
16001
|
-
trackCacheMisses:
|
|
16117
|
+
trackL1Hits: false,
|
|
16118
|
+
trackL2Hits: false,
|
|
16119
|
+
trackCacheMisses: false,
|
|
16002
16120
|
reportObserver: (report) => {
|
|
16003
16121
|
for (const observer of reportObservers) {
|
|
16004
16122
|
observer(report);
|
|
@@ -16887,13 +17005,13 @@ function mergeRecord(existingRecord, incomingRecord, objectInfo) {
|
|
|
16887
17005
|
// since none of the changed fields are part of the incoming record
|
|
16888
17006
|
if (missingFields.every((field) => {
|
|
16889
17007
|
const referenceFieldName = findReferenceFieldForSpanningField(field, objectInfo);
|
|
16890
|
-
if (referenceFieldName
|
|
16891
|
-
return (incomingRecord.fields[referenceFieldName].value ===
|
|
16892
|
-
existingRecord.fields[referenceFieldName].value);
|
|
16893
|
-
}
|
|
16894
|
-
else {
|
|
17008
|
+
if (referenceFieldName === undefined) {
|
|
16895
17009
|
return false;
|
|
16896
17010
|
}
|
|
17011
|
+
return (existingRecord.fields[referenceFieldName] &&
|
|
17012
|
+
incomingRecord.fields[referenceFieldName] &&
|
|
17013
|
+
incomingRecord.fields[referenceFieldName].value ===
|
|
17014
|
+
existingRecord.fields[referenceFieldName].value);
|
|
16897
17015
|
})) {
|
|
16898
17016
|
return {
|
|
16899
17017
|
ok: true,
|
|
@@ -17772,6 +17890,9 @@ class LdsPrimingRecordRefresher {
|
|
|
17772
17890
|
optionalFields: value.fields.map((f) => `${_apiName}.${f}`),
|
|
17773
17891
|
},
|
|
17774
17892
|
],
|
|
17893
|
+
}, {
|
|
17894
|
+
cachePolicy: { type: 'no-cache' },
|
|
17895
|
+
priority: 'background',
|
|
17775
17896
|
}));
|
|
17776
17897
|
});
|
|
17777
17898
|
const promiseResults = await allSettled(promises);
|
|
@@ -17876,6 +17997,8 @@ function getRuntime() {
|
|
|
17876
17997
|
const durableEnv = makeDurable(gqlEnv, {
|
|
17877
17998
|
durableStore: recordDenormingStore,
|
|
17878
17999
|
enableDurableMetadataRefresh: ldsMetadataRefreshEnabled.isOpen({ fallback: false }),
|
|
18000
|
+
// disable luvio deep freeze in headless environments
|
|
18001
|
+
disableDeepFreeze: typeof window === 'undefined',
|
|
17879
18002
|
});
|
|
17880
18003
|
getIngestRecords = durableEnv.getIngestStagingStoreRecords;
|
|
17881
18004
|
getIngestMetadata = durableEnv.getIngestStagingStoreMetadata;
|
|
@@ -17981,4 +18104,4 @@ register({
|
|
|
17981
18104
|
});
|
|
17982
18105
|
|
|
17983
18106
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
17984
|
-
// version: 1.
|
|
18107
|
+
// version: 1.282.0-f3e0ca0c7
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.282.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,25 +32,25 @@
|
|
|
32
32
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-mobile"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@salesforce/lds-adapters-uiapi": "^1.
|
|
36
|
-
"@salesforce/lds-bindings": "^1.
|
|
37
|
-
"@salesforce/lds-instrumentation": "^1.
|
|
38
|
-
"@salesforce/lds-priming": "^1.
|
|
35
|
+
"@salesforce/lds-adapters-uiapi": "^1.282.0",
|
|
36
|
+
"@salesforce/lds-bindings": "^1.282.0",
|
|
37
|
+
"@salesforce/lds-instrumentation": "^1.282.0",
|
|
38
|
+
"@salesforce/lds-priming": "^1.282.0",
|
|
39
39
|
"@salesforce/user": "0.0.21",
|
|
40
40
|
"o11y": "244.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@salesforce/lds-adapters-graphql": "^1.
|
|
44
|
-
"@salesforce/lds-drafts": "^1.
|
|
45
|
-
"@salesforce/lds-drafts-adapters-uiapi": "^1.
|
|
46
|
-
"@salesforce/lds-graphql-eval": "^1.
|
|
47
|
-
"@salesforce/lds-network-adapter": "^1.
|
|
48
|
-
"@salesforce/lds-network-nimbus": "^1.
|
|
49
|
-
"@salesforce/lds-store-binary": "^1.
|
|
50
|
-
"@salesforce/lds-store-nimbus": "^1.
|
|
51
|
-
"@salesforce/lds-store-sql": "^1.
|
|
52
|
-
"@salesforce/lds-utils-adapters": "^1.
|
|
53
|
-
"@salesforce/nimbus-plugin-lds": "^1.
|
|
43
|
+
"@salesforce/lds-adapters-graphql": "^1.282.0",
|
|
44
|
+
"@salesforce/lds-drafts": "^1.282.0",
|
|
45
|
+
"@salesforce/lds-drafts-adapters-uiapi": "^1.282.0",
|
|
46
|
+
"@salesforce/lds-graphql-eval": "^1.282.0",
|
|
47
|
+
"@salesforce/lds-network-adapter": "^1.282.0",
|
|
48
|
+
"@salesforce/lds-network-nimbus": "^1.282.0",
|
|
49
|
+
"@salesforce/lds-store-binary": "^1.282.0",
|
|
50
|
+
"@salesforce/lds-store-nimbus": "^1.282.0",
|
|
51
|
+
"@salesforce/lds-store-sql": "^1.282.0",
|
|
52
|
+
"@salesforce/lds-utils-adapters": "^1.282.0",
|
|
53
|
+
"@salesforce/nimbus-plugin-lds": "^1.282.0",
|
|
54
54
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
55
55
|
"wait-for-expect": "^3.0.2"
|
|
56
56
|
},
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"path": "./dist/main.js",
|
|
60
60
|
"maxSize": {
|
|
61
61
|
"none": "800 kB",
|
|
62
|
-
"min": "
|
|
62
|
+
"min": "321 kB",
|
|
63
63
|
"compressed": "150 kB"
|
|
64
64
|
}
|
|
65
65
|
},
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"path": "./sfdc/main.js",
|
|
68
68
|
"maxSize": {
|
|
69
69
|
"none": "800 kB",
|
|
70
|
-
"min": "
|
|
70
|
+
"min": "321 kB",
|
|
71
71
|
"compressed": "150 kB"
|
|
72
72
|
}
|
|
73
73
|
}
|
package/sfdc/main.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { withRegistration, register } from 'native/ldsEngineMobile';
|
|
19
19
|
import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrumentLuvio, setLdsAdaptersUiapiInstrumentation, setLdsNetworkAdapterInstrumentation } from 'force/ldsInstrumentation';
|
|
20
|
-
import { HttpStatusCode, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from 'force/luvioEngine';
|
|
20
|
+
import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from 'force/luvioEngine';
|
|
21
21
|
import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
|
|
22
22
|
import { parseAndVisit, Kind, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from 'force/ldsGraphqlParser';
|
|
23
23
|
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion, getRecordsAdapterFactory } from 'force/ldsAdaptersUiapi';
|
|
@@ -1019,7 +1019,9 @@ function isUnfulfilledSnapshot$1(cachedSnapshotResult) {
|
|
|
1019
1019
|
* @param durableStore A DurableStore implementation
|
|
1020
1020
|
* @param instrumentation An instrumentation function implementation
|
|
1021
1021
|
*/
|
|
1022
|
-
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, }) {
|
|
1022
|
+
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, disableDeepFreeze = false, }) {
|
|
1023
|
+
// runtimes can choose to disable deepFreeze, e.g. headless mobile runtime
|
|
1024
|
+
setBypassDeepFreeze(disableDeepFreeze);
|
|
1023
1025
|
let stagingStore = null;
|
|
1024
1026
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
1025
1027
|
const mergeKeysPromiseMap = new Map();
|
|
@@ -7967,6 +7969,9 @@ function sanitizePredicateIDValue(value, draftFunction) {
|
|
|
7967
7969
|
if (isArray$2(value)) {
|
|
7968
7970
|
return value.map((singleValue) => sanitizePredicateIDValue(singleValue, draftFunction));
|
|
7969
7971
|
}
|
|
7972
|
+
else if (typeof value === 'string' && value === '') {
|
|
7973
|
+
return value;
|
|
7974
|
+
}
|
|
7970
7975
|
else {
|
|
7971
7976
|
const coercedId = getRecordId18(value);
|
|
7972
7977
|
if (coercedId !== undefined) {
|
|
@@ -8657,24 +8662,36 @@ function findAncesterPath(ancesters) {
|
|
|
8657
8662
|
}
|
|
8658
8663
|
return path;
|
|
8659
8664
|
}
|
|
8665
|
+
function isCategoryDirective(node) {
|
|
8666
|
+
return node.name.value === 'category';
|
|
8667
|
+
}
|
|
8660
8668
|
/**
|
|
8661
8669
|
* checks if the 'SelectionNode' has the potential to have relationship(parent or child) with its ancestor.
|
|
8662
8670
|
* @param node
|
|
8663
8671
|
* @returns
|
|
8664
8672
|
*/
|
|
8665
8673
|
function isCapableRelationship(node) {
|
|
8666
|
-
if (
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
return
|
|
8676
|
-
|
|
8677
|
-
|
|
8674
|
+
if (isFieldNode(node)) {
|
|
8675
|
+
if (node.directives !== undefined) {
|
|
8676
|
+
const argNodes = node.directives
|
|
8677
|
+
.flatMap((directive) => {
|
|
8678
|
+
if (isCategoryDirective(directive) === false)
|
|
8679
|
+
return undefined;
|
|
8680
|
+
return directive.arguments;
|
|
8681
|
+
})
|
|
8682
|
+
.filter((x) => x);
|
|
8683
|
+
return argNodes.some((argument) => {
|
|
8684
|
+
if (argument.name.value !== 'name')
|
|
8685
|
+
return false;
|
|
8686
|
+
if (argument.value.kind !== 'StringValue')
|
|
8687
|
+
return false;
|
|
8688
|
+
return (argument.value.value === PARENT_RELATIONSHIP ||
|
|
8689
|
+
argument.value.value === CHILD_RELATIONSHIP ||
|
|
8690
|
+
argument.value.value === POLYMORPHIC_PARENT_RELATIONSHIP);
|
|
8691
|
+
});
|
|
8692
|
+
}
|
|
8693
|
+
}
|
|
8694
|
+
return isInlineFragmentNode(node);
|
|
8678
8695
|
}
|
|
8679
8696
|
/**
|
|
8680
8697
|
* checks if the 'ArgumentNode' is a specific scope type
|
|
@@ -9412,6 +9429,12 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9412
9429
|
break;
|
|
9413
9430
|
case 'LastModifiedDate':
|
|
9414
9431
|
field.resolve = ({ recordRepresentation: record }) => {
|
|
9432
|
+
// In UIAPI record reps, LastModifiedDate might be present as a field,
|
|
9433
|
+
// which will include both the value and displayValue
|
|
9434
|
+
if (record.fields['LastModifiedDate']) {
|
|
9435
|
+
return record.fields['LastModifiedDate'];
|
|
9436
|
+
}
|
|
9437
|
+
// If the field is not present, just return the value of the root property
|
|
9415
9438
|
return record.lastModifiedDate
|
|
9416
9439
|
? { value: record.lastModifiedDate }
|
|
9417
9440
|
: null;
|
|
@@ -9539,7 +9562,6 @@ _, { objectInfos }) {
|
|
|
9539
9562
|
}
|
|
9540
9563
|
}
|
|
9541
9564
|
}
|
|
9542
|
-
// TODO [W-14660068]: composite name fields
|
|
9543
9565
|
return null;
|
|
9544
9566
|
}
|
|
9545
9567
|
async function connectionEdgeResolver(obj, _args, context) {
|
|
@@ -10603,6 +10625,9 @@ function growObjectFieldTree(tree, parentNode, entryNode, totalNodes, startNodes
|
|
|
10603
10625
|
}
|
|
10604
10626
|
});
|
|
10605
10627
|
}
|
|
10628
|
+
function isNodeOrEdges(node) {
|
|
10629
|
+
return isFieldNode(node) && (node.name.value === 'node' || node.name.value === 'edges');
|
|
10630
|
+
}
|
|
10606
10631
|
/**
|
|
10607
10632
|
* Build a relationship tree from the top FieldNode 'node'
|
|
10608
10633
|
* @param tree
|
|
@@ -10613,7 +10638,7 @@ function growObjectFieldTree(tree, parentNode, entryNode, totalNodes, startNodes
|
|
|
10613
10638
|
* @param startNodes
|
|
10614
10639
|
*/
|
|
10615
10640
|
function growFieldTree(tree, parentSectionPath, entryNode, parentNode, totalNodes, startNodes) {
|
|
10616
|
-
if (isCapableRelationship(entryNode)) {
|
|
10641
|
+
if (isCapableRelationship(entryNode) || isNodeOrEdges(entryNode)) {
|
|
10617
10642
|
if (isFieldNode(entryNode)) {
|
|
10618
10643
|
const relationType = getRelation(entryNode);
|
|
10619
10644
|
const fieldName = entryNode.name.value;
|
|
@@ -11200,6 +11225,131 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
|
|
|
11200
11225
|
}
|
|
11201
11226
|
}
|
|
11202
11227
|
}
|
|
11228
|
+
function findIdFieldNode(node) {
|
|
11229
|
+
if (node.selectionSet === undefined)
|
|
11230
|
+
return false;
|
|
11231
|
+
return node.selectionSet.selections.some((selection) => {
|
|
11232
|
+
if (isFieldNode(selection)) {
|
|
11233
|
+
return selection.name.value === 'Id';
|
|
11234
|
+
}
|
|
11235
|
+
return false;
|
|
11236
|
+
});
|
|
11237
|
+
}
|
|
11238
|
+
/**
|
|
11239
|
+
* 1 parentship can return 2 FieldNode which need to be flattened
|
|
11240
|
+
* Concact: { ** Contact { ** ContactId {
|
|
11241
|
+
* Name: { ** Id ** value
|
|
11242
|
+
* value ** } ** }
|
|
11243
|
+
* } **
|
|
11244
|
+
* }
|
|
11245
|
+
* `parentRelationships` is a 2-dimensional array. 1 element at the top level of the array is an array of injected fields(which could has 2 elements) for
|
|
11246
|
+
* one field(`Contact`, for example), For example, `Contact` field could map to field `Contact { Id }` and `ContactId { value }` which are injected.
|
|
11247
|
+
* `Account` field could map to field `Account { Id }` and `AccountID { value }`.
|
|
11248
|
+
* Returned `parentRelationships` would look like [ [`Contact { Id }`, `ContactId { value }`], [`Account { Id }`, `AccountId { value }`]]. It needs to
|
|
11249
|
+
* be flattened to [`Contact { Id }`, `ContactId { value }`, `Account { Id }`, `AccountId { value }`]
|
|
11250
|
+
*/
|
|
11251
|
+
function injectParentRelationships(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap) {
|
|
11252
|
+
let parentInjectedNodes = [];
|
|
11253
|
+
for (let i = 0, len = selections.length; i < len; i++) {
|
|
11254
|
+
const selection = selections[i];
|
|
11255
|
+
// have to wrap in the if statement to make rollup happy :(
|
|
11256
|
+
if (isFieldOrInlineFragmentNode(selection)) {
|
|
11257
|
+
if (selection.selectionSet === undefined) {
|
|
11258
|
+
parentInjectedNodes.push(selection);
|
|
11259
|
+
continue;
|
|
11260
|
+
}
|
|
11261
|
+
const segment = isFieldNode(selection)
|
|
11262
|
+
? selection.name.value
|
|
11263
|
+
: selection.typeCondition.name.value;
|
|
11264
|
+
const curPath = `${parentPath}#${segment}`;
|
|
11265
|
+
const spanningSubSelections = [];
|
|
11266
|
+
for (const subSelection of selection.selectionSet.selections) {
|
|
11267
|
+
if (isFieldSpanning(subSelection, selection)) {
|
|
11268
|
+
spanningSubSelections.push(subSelection);
|
|
11269
|
+
}
|
|
11270
|
+
}
|
|
11271
|
+
// Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
|
|
11272
|
+
const subInjectedSelections = injectFields(spanningSubSelections, selection, curPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11273
|
+
const hasIdNode = findIdFieldNode(selection);
|
|
11274
|
+
// For InlineFragment like '... on User', do not create relationship. Relationship is handled at the upper level.
|
|
11275
|
+
if (isFieldNode(selection)) {
|
|
11276
|
+
const fieldName = selection.name.value;
|
|
11277
|
+
const relationshipId = referenceIdFieldForRelationship(fieldName);
|
|
11278
|
+
// check if relation field like 'AccountId' does exist in query
|
|
11279
|
+
const existingRelationFields = [parentNode]
|
|
11280
|
+
.filter(isFieldOrInlineFragmentNode)
|
|
11281
|
+
.reduce(extractSelections, [])
|
|
11282
|
+
.filter(isFieldNode)
|
|
11283
|
+
.filter((subNode) => subNode.name.value === relationshipId);
|
|
11284
|
+
if (existingRelationFields.length === 0) {
|
|
11285
|
+
parentInjectedNodes.push(createFieldNode(relationshipId, FieldValueNodeSelectionSet));
|
|
11286
|
+
}
|
|
11287
|
+
}
|
|
11288
|
+
// For polymorphic fields, the Id field is excluded.
|
|
11289
|
+
const excludeId = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
|
|
11290
|
+
const idSelection = [];
|
|
11291
|
+
if (!excludeId && hasIdNode === false) {
|
|
11292
|
+
idSelection.push(createFieldNode('Id'));
|
|
11293
|
+
}
|
|
11294
|
+
// 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
|
|
11295
|
+
// `typedCondition` of the InlineFragment in the query AST. It is used to match JSON response with AST node. For more detail, please reference 'removeSyntheticFields'.
|
|
11296
|
+
if (isInlineFragmentNode(selection) &&
|
|
11297
|
+
!selection.selectionSet.selections.find((selection) => isFieldNode(selection) && selection.name.value === '__typename')) {
|
|
11298
|
+
idSelection.push(createFieldNode('__typename'));
|
|
11299
|
+
}
|
|
11300
|
+
// 'ServiceAppointment' --> 'Contact' --> 'Id', Inject 'Contact' with Id. 'Id' field is at the sub level.
|
|
11301
|
+
if (idSelection.length > 0 || subInjectedSelections.length > 0) {
|
|
11302
|
+
parentInjectedNodes.push({
|
|
11303
|
+
...selection,
|
|
11304
|
+
selectionSet: {
|
|
11305
|
+
kind: Kind.SELECTION_SET,
|
|
11306
|
+
selections: [...idSelection, ...subInjectedSelections],
|
|
11307
|
+
},
|
|
11308
|
+
});
|
|
11309
|
+
}
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
return parentInjectedNodes;
|
|
11313
|
+
}
|
|
11314
|
+
/**
|
|
11315
|
+
* Find any name fields needed for the DisplayValue field
|
|
11316
|
+
* @param param0
|
|
11317
|
+
* @param parentNode
|
|
11318
|
+
* @param objectInfos
|
|
11319
|
+
* @returns
|
|
11320
|
+
*/
|
|
11321
|
+
function injectFieldsForDisplayValue(topNode, parentNode, objectInfos) {
|
|
11322
|
+
const { selectionSet } = topNode;
|
|
11323
|
+
if (selectionSet === undefined)
|
|
11324
|
+
return [];
|
|
11325
|
+
let displayValueNameFields = [];
|
|
11326
|
+
const { selections } = selectionSet;
|
|
11327
|
+
// see if node selection has DisplayValue and needs to inject
|
|
11328
|
+
let displayValue;
|
|
11329
|
+
for (let i = 0, len = selections.length; i < len; i++) {
|
|
11330
|
+
const node = selections[i];
|
|
11331
|
+
if (isFieldNode(node) && node.name.value === 'DisplayValue') {
|
|
11332
|
+
displayValue = node;
|
|
11333
|
+
break;
|
|
11334
|
+
}
|
|
11335
|
+
if (isInlineFragmentNode(node)) {
|
|
11336
|
+
const name = node.typeCondition !== undefined ? node.typeCondition.name : parentNode.name;
|
|
11337
|
+
displayValueNameFields = injectFieldsForDisplayValue(node, { ...parentNode, name }, objectInfos);
|
|
11338
|
+
}
|
|
11339
|
+
}
|
|
11340
|
+
if (displayValue !== undefined) {
|
|
11341
|
+
const apiName = parentNode.name.value;
|
|
11342
|
+
const objectInfo = objectInfos[apiName];
|
|
11343
|
+
if (objectInfo !== undefined &&
|
|
11344
|
+
objectInfo.nameFields !== undefined &&
|
|
11345
|
+
objectInfo.nameFields.length > 0) {
|
|
11346
|
+
displayValueNameFields = objectInfo.nameFields.map((fieldName) => {
|
|
11347
|
+
return createFieldNode(fieldName, FieldValueNodeSelectionSet);
|
|
11348
|
+
});
|
|
11349
|
+
}
|
|
11350
|
+
}
|
|
11351
|
+
return displayValueNameFields;
|
|
11352
|
+
}
|
|
11203
11353
|
/**
|
|
11204
11354
|
* injects fields under query
|
|
11205
11355
|
* @param selections selection nodes need to be injected.
|
|
@@ -11210,160 +11360,67 @@ function updateIDInfo(fieldNode, idState, draftFunctions) {
|
|
|
11210
11360
|
* @return injected SelectionNodes used to construct the InlineFragment.
|
|
11211
11361
|
*/
|
|
11212
11362
|
function injectFields(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap) {
|
|
11213
|
-
|
|
11214
|
-
* 1 parentship can return 2 FieldNode which need to be flattened
|
|
11215
|
-
* Concact: { ** Contact { ** ContactId {
|
|
11216
|
-
* Name: { ** Id ** value
|
|
11217
|
-
* value ** } ** }
|
|
11218
|
-
* } **
|
|
11219
|
-
* }
|
|
11220
|
-
* `parentRelationships` is a 2-dimensional array. 1 element at the top level of the array is an array of injected fields(which could has 2 elements) for
|
|
11221
|
-
* one field(`Contact`, for example), For example, `Contact` field could map to field `Contact { Id }` and `ContactId { value }` which are injected.
|
|
11222
|
-
* `Account` field could map to field `Account { Id }` and `AccountID { value }`.
|
|
11223
|
-
* Returned `parentRelationships` would look like [ [`Contact { Id }`, `ContactId { value }`], [`Account { Id }`, `AccountId { value }`]]. It needs to
|
|
11224
|
-
* be flattened to [`Contact { Id }`, `ContactId { value }`, `Account { Id }`, `AccountId { value }`]
|
|
11225
|
-
*/
|
|
11226
|
-
const parentRelaltionships = selections.filter(isFieldOrInlineFragmentNode).map((selection) => {
|
|
11227
|
-
if (!selection.selectionSet) {
|
|
11228
|
-
return selection;
|
|
11229
|
-
}
|
|
11230
|
-
const segment = isFieldNode(selection)
|
|
11231
|
-
? selection.name.value
|
|
11232
|
-
: selection.typeCondition.name.value;
|
|
11233
|
-
const curPath = `${parentPath}#${segment}`;
|
|
11234
|
-
const spanningSubSelections = [];
|
|
11235
|
-
for (const subSelection of selection.selectionSet.selections) {
|
|
11236
|
-
if (isFieldSpanning(subSelection, selection)) {
|
|
11237
|
-
spanningSubSelections.push(subSelection);
|
|
11238
|
-
}
|
|
11239
|
-
}
|
|
11240
|
-
// Handles multiple level field injection like 'ServiceAppointment' --> 'Account' --> 'Owner'
|
|
11241
|
-
const subInjectedSelections = injectFields(spanningSubSelections, selection, curPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11242
|
-
if (!selection.selectionSet) {
|
|
11243
|
-
return selection;
|
|
11244
|
-
}
|
|
11245
|
-
const hasIdAlready = selection.selectionSet.selections
|
|
11246
|
-
.filter(isFieldNode)
|
|
11247
|
-
.find((s) => s.name.value === 'Id');
|
|
11248
|
-
// For InlineFragment like '... on User', do not create relationship. Relationship is handled at the upper level.
|
|
11249
|
-
let injectedRelationshipField = [];
|
|
11250
|
-
if (isFieldNode(selection)) {
|
|
11251
|
-
const fieldName = selection.name.value;
|
|
11252
|
-
const relationshipId = referenceIdFieldForRelationship(fieldName);
|
|
11253
|
-
// check if relation field like 'AccountId' does exist in query
|
|
11254
|
-
const existingRelationFields = [parentNode]
|
|
11255
|
-
.filter(isFieldOrInlineFragmentNode)
|
|
11256
|
-
.reduce(extractSelections, [])
|
|
11257
|
-
.filter(isFieldNode)
|
|
11258
|
-
.filter((subNode) => subNode.name.value === relationshipId);
|
|
11259
|
-
if (existingRelationFields.length === 0) {
|
|
11260
|
-
injectedRelationshipField = [
|
|
11261
|
-
createFieldNode(relationshipId, FieldValueNodeSelectionSet),
|
|
11262
|
-
];
|
|
11263
|
-
}
|
|
11264
|
-
}
|
|
11265
|
-
// For polymorphic fields, the Id field is excluded.
|
|
11266
|
-
const excludeId = isPolymorphicFieldPath(curPath, pathToObjectApiNamesMap, objectInfos);
|
|
11267
|
-
const idSelection = [];
|
|
11268
|
-
if (!excludeId && !hasIdAlready) {
|
|
11269
|
-
idSelection.push(createFieldNode('Id'));
|
|
11270
|
-
}
|
|
11271
|
-
// 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
|
|
11272
|
-
// `typedCondition` of the InlineFragment in the query AST. It is used to match JSON response with AST node. For more detail, please reference 'removeSyntheticFields'.
|
|
11273
|
-
if (isInlineFragmentNode(selection) &&
|
|
11274
|
-
!selection.selectionSet.selections.find((selection) => isFieldNode(selection) && selection.name.value === '__typename')) {
|
|
11275
|
-
idSelection.push(createFieldNode('__typename'));
|
|
11276
|
-
}
|
|
11277
|
-
// 'ServiceAppointment' --> 'Contact' --> 'Id', Inject 'Contact' with Id. 'Id' field is at the sub level.
|
|
11278
|
-
const injectedSelectionIdField = idSelection.length > 0 || subInjectedSelections.length > 0
|
|
11279
|
-
? [
|
|
11280
|
-
{
|
|
11281
|
-
...selection,
|
|
11282
|
-
selectionSet: {
|
|
11283
|
-
kind: Kind.SELECTION_SET,
|
|
11284
|
-
selections: [...idSelection, ...subInjectedSelections],
|
|
11285
|
-
},
|
|
11286
|
-
},
|
|
11287
|
-
]
|
|
11288
|
-
: [];
|
|
11289
|
-
return [...injectedSelectionIdField, ...injectedRelationshipField];
|
|
11290
|
-
});
|
|
11291
|
-
// injects Id if the parent of the 'childRelationship' does not contain an Id field. The logic here only deals with 'parentNode'
|
|
11292
|
-
const idForChildRelationship = [];
|
|
11363
|
+
const parentRelaltionships = injectParentRelationships(selections, parentNode, parentPath, ancestors, objectInfos, pathToObjectApiNamesMap);
|
|
11293
11364
|
// inject related field for the parent of the 'childRelationship'.
|
|
11294
11365
|
const relatedIdForChildRelationship = [];
|
|
11295
11366
|
// injected fields for DisplayValue
|
|
11296
11367
|
let displayValueNameFields = [];
|
|
11368
|
+
let rootQueryIdField = [];
|
|
11297
11369
|
// injects 'childRelatiship' at the 'node' level, it does not matter if the 'selections' is empty or not.
|
|
11298
11370
|
// the operation happens at the same level as the 'childRelationship' field.
|
|
11299
|
-
if (isFieldNode(parentNode) &&
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
}
|
|
11308
|
-
}
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
relatedIdForChildRelationship.push(createFieldNode(injectedParentFieldName, FieldValueNodeSelectionSet));
|
|
11336
|
-
}
|
|
11371
|
+
if (isFieldNode(parentNode) &&
|
|
11372
|
+
parentNode.selectionSet !== undefined &&
|
|
11373
|
+
(parentNode.name.value === 'node' || isCapableRelationship(parentNode))) {
|
|
11374
|
+
//check if the root query has the Id and inject if it needed
|
|
11375
|
+
if (parentNode.name.value === 'node') {
|
|
11376
|
+
const idNode = findIdFieldNode(parentNode);
|
|
11377
|
+
if (idNode === false) {
|
|
11378
|
+
rootQueryIdField.push(createFieldNode('Id'));
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
11381
|
+
// example { node { Id } }. The operation happens at the 'edges' -> 'node' level of the 'childRelationship' field
|
|
11382
|
+
const parentInfo = findNearestAncesterPath(ancestors, true);
|
|
11383
|
+
if (parentInfo.parentIndex >= 0) {
|
|
11384
|
+
// example node { TimeSheetEntries { edges { node { Id }}}}
|
|
11385
|
+
const parent = parentNode.name.value === 'node' ? parentInfo.node : parentNode;
|
|
11386
|
+
if (isRelationship(parent, CHILD_RELATIONSHIP)) {
|
|
11387
|
+
const unVisitedAncestors = ancestors.slice(0, parentInfo.parentIndex);
|
|
11388
|
+
// path : "TimeSheet"
|
|
11389
|
+
const grandParentPath = findAncesterPath(unVisitedAncestors);
|
|
11390
|
+
if (pathToObjectApiNamesMap &&
|
|
11391
|
+
pathToObjectApiNamesMap[grandParentPath] &&
|
|
11392
|
+
objectInfos &&
|
|
11393
|
+
objectInfos[pathToObjectApiNamesMap[grandParentPath][0]]) {
|
|
11394
|
+
const grandParentObjectInfo = objectInfos[pathToObjectApiNamesMap[grandParentPath][0]];
|
|
11395
|
+
// exmaple "TimeSheetEntries"
|
|
11396
|
+
const parentFieldName = parent.name.value;
|
|
11397
|
+
const targetRelationship = grandParentObjectInfo.childRelationships.find((childRelationship) => {
|
|
11398
|
+
return childRelationship.relationshipName === parentFieldName;
|
|
11399
|
+
});
|
|
11400
|
+
if (targetRelationship !== undefined) {
|
|
11401
|
+
const injectedParentFieldName = targetRelationship.fieldName;
|
|
11402
|
+
if (!parentNode.selectionSet.selections
|
|
11403
|
+
.filter(isFieldNode)
|
|
11404
|
+
.some((sibling) => sibling.name.value === injectedParentFieldName)) {
|
|
11405
|
+
// example: TimeSheetId { value }
|
|
11406
|
+
relatedIdForChildRelationship.push(createFieldNode(injectedParentFieldName, FieldValueNodeSelectionSet));
|
|
11337
11407
|
}
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
|
|
11345
|
-
if (isFieldNode(node) && node.name.value === 'DisplayValue') {
|
|
11346
|
-
displayValue = node;
|
|
11347
|
-
break;
|
|
11348
|
-
}
|
|
11349
|
-
}
|
|
11350
|
-
if (displayValue !== undefined) {
|
|
11351
|
-
const apiName = parent.name.value;
|
|
11352
|
-
const objectInfo = objectInfos[apiName];
|
|
11353
|
-
if (objectInfo !== undefined &&
|
|
11354
|
-
objectInfo.nameFields !== undefined &&
|
|
11355
|
-
objectInfo.nameFields.length > 0) {
|
|
11356
|
-
displayValueNameFields = objectInfo.nameFields.map((fieldName) => {
|
|
11357
|
-
return createFieldNode(fieldName, FieldValueNodeSelectionSet);
|
|
11358
|
-
});
|
|
11408
|
+
displayValueNameFields.push(...injectFieldsForDisplayValue(parentNode, {
|
|
11409
|
+
...parent,
|
|
11410
|
+
name: {
|
|
11411
|
+
...parent.name,
|
|
11412
|
+
value: targetRelationship.childObjectApiName,
|
|
11413
|
+
},
|
|
11414
|
+
}, objectInfos));
|
|
11359
11415
|
}
|
|
11360
11416
|
}
|
|
11361
11417
|
}
|
|
11418
|
+
displayValueNameFields.push(...injectFieldsForDisplayValue(parentNode, parent, objectInfos));
|
|
11362
11419
|
}
|
|
11363
11420
|
}
|
|
11364
11421
|
return [
|
|
11422
|
+
...rootQueryIdField,
|
|
11365
11423
|
...flat(parentRelaltionships),
|
|
11366
|
-
...idForChildRelationship,
|
|
11367
11424
|
...relatedIdForChildRelationship,
|
|
11368
11425
|
...displayValueNameFields,
|
|
11369
11426
|
];
|
|
@@ -12135,6 +12192,60 @@ function replayDraftsOnRecord(record, draftMetadata) {
|
|
|
12135
12192
|
}
|
|
12136
12193
|
return recursivelyApplyDraftsToRecord(baseRecord, draftMetadata, draftMetadata.recordOperations);
|
|
12137
12194
|
}
|
|
12195
|
+
/**
|
|
12196
|
+
* checks if updated fields are apart of the compound Name field
|
|
12197
|
+
* will generate a compound Name field if it is not already apart of the draft
|
|
12198
|
+
* @param record
|
|
12199
|
+
* @param draftFields
|
|
12200
|
+
* @param apiName
|
|
12201
|
+
* @param objectInfos
|
|
12202
|
+
* @returns
|
|
12203
|
+
*/
|
|
12204
|
+
function compoundNameFieldFromDraftUpdates(record, draftFields, apiName, objectInfos) {
|
|
12205
|
+
let updatedNameFields = {};
|
|
12206
|
+
const objectInfo = objectInfos.get(apiName);
|
|
12207
|
+
if (draftFields['Name'] !== undefined ||
|
|
12208
|
+
objectInfo === undefined ||
|
|
12209
|
+
objectInfo.nameFields === undefined ||
|
|
12210
|
+
objectInfo.nameFields.length === 0) {
|
|
12211
|
+
return updatedNameFields;
|
|
12212
|
+
}
|
|
12213
|
+
const nameField = objectInfo.nameFields.find((x) => x === 'Name');
|
|
12214
|
+
if (nameField === undefined) {
|
|
12215
|
+
return updatedNameFields;
|
|
12216
|
+
}
|
|
12217
|
+
const { compound, updateable } = objectInfo.fields[nameField];
|
|
12218
|
+
if (objectInfo.nameFields.length <= 1 && compound === false && updateable === true) {
|
|
12219
|
+
return updatedNameFields;
|
|
12220
|
+
}
|
|
12221
|
+
let changedNameFields = {};
|
|
12222
|
+
const filteredNameFields = objectInfo.nameFields.filter((x) => x !== 'Name');
|
|
12223
|
+
for (let i = 0, len = filteredNameFields.length; i < len; i++) {
|
|
12224
|
+
const fieldName = filteredNameFields[i];
|
|
12225
|
+
const fieldValue = draftFields[fieldName];
|
|
12226
|
+
if (fieldValue !== undefined) {
|
|
12227
|
+
changedNameFields[fieldName] = fieldValue;
|
|
12228
|
+
}
|
|
12229
|
+
}
|
|
12230
|
+
if (keys$3(changedNameFields).length > 0) {
|
|
12231
|
+
const newNameValue = filteredNameFields
|
|
12232
|
+
.map((key) => {
|
|
12233
|
+
if (changedNameFields[key] !== undefined) {
|
|
12234
|
+
return changedNameFields[key];
|
|
12235
|
+
}
|
|
12236
|
+
else if (record.fields[key] !== undefined) {
|
|
12237
|
+
return record.fields[key].value;
|
|
12238
|
+
}
|
|
12239
|
+
else {
|
|
12240
|
+
return '';
|
|
12241
|
+
}
|
|
12242
|
+
})
|
|
12243
|
+
.join(' ')
|
|
12244
|
+
.trim();
|
|
12245
|
+
updatedNameFields['Name'] = newNameValue;
|
|
12246
|
+
}
|
|
12247
|
+
return updatedNameFields;
|
|
12248
|
+
}
|
|
12138
12249
|
function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations) {
|
|
12139
12250
|
const { luvio, objectInfos, userId, formatDisplayValue, referencedRecords } = draftMetadata;
|
|
12140
12251
|
if (recordOperations.length === 0) {
|
|
@@ -12194,8 +12305,15 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
|
|
|
12194
12305
|
record.drafts.deleted = true;
|
|
12195
12306
|
}
|
|
12196
12307
|
// 'lastModifiedById' and 'lastModifiedDate' are modified in 'delete' and 'update' action
|
|
12197
|
-
const
|
|
12308
|
+
const draftOperationFields = draftActionType === 'delete' ? {} : draftOperation.fields;
|
|
12198
12309
|
const apiName = draftOperation.apiName;
|
|
12310
|
+
const injectedCompoundNameField = compoundNameFieldFromDraftUpdates(record, draftOperationFields, apiName, objectInfos);
|
|
12311
|
+
// inject the compound Name field into the DraftOperation so on broadcast it doesnt try to
|
|
12312
|
+
// synthesize the Name field a second time when the durable store change notifier is triggered
|
|
12313
|
+
if (keys$3(injectedCompoundNameField).length > 0 && draftActionType === 'update') {
|
|
12314
|
+
draftOperation.fields['Name'] = injectedCompoundNameField['Name'];
|
|
12315
|
+
}
|
|
12316
|
+
const fields = { ...draftOperationFields, ...injectedCompoundNameField };
|
|
12199
12317
|
// automaticlly add 'lastModifiedById' and 'lastModifiedByDate' and use an internal draft field copy since it is mutable
|
|
12200
12318
|
const internalFields = {
|
|
12201
12319
|
...fields,
|
|
@@ -15996,9 +16114,9 @@ function instrumentAdapter(adapter, metadata) {
|
|
|
15996
16114
|
}
|
|
15997
16115
|
}
|
|
15998
16116
|
return instrumentAdapter$1(instrumentedMobileAdapter, metadata, {
|
|
15999
|
-
trackL1Hits:
|
|
16000
|
-
trackL2Hits:
|
|
16001
|
-
trackCacheMisses:
|
|
16117
|
+
trackL1Hits: false,
|
|
16118
|
+
trackL2Hits: false,
|
|
16119
|
+
trackCacheMisses: false,
|
|
16002
16120
|
reportObserver: (report) => {
|
|
16003
16121
|
for (const observer of reportObservers) {
|
|
16004
16122
|
observer(report);
|
|
@@ -16887,13 +17005,13 @@ function mergeRecord(existingRecord, incomingRecord, objectInfo) {
|
|
|
16887
17005
|
// since none of the changed fields are part of the incoming record
|
|
16888
17006
|
if (missingFields.every((field) => {
|
|
16889
17007
|
const referenceFieldName = findReferenceFieldForSpanningField(field, objectInfo);
|
|
16890
|
-
if (referenceFieldName
|
|
16891
|
-
return (incomingRecord.fields[referenceFieldName].value ===
|
|
16892
|
-
existingRecord.fields[referenceFieldName].value);
|
|
16893
|
-
}
|
|
16894
|
-
else {
|
|
17008
|
+
if (referenceFieldName === undefined) {
|
|
16895
17009
|
return false;
|
|
16896
17010
|
}
|
|
17011
|
+
return (existingRecord.fields[referenceFieldName] &&
|
|
17012
|
+
incomingRecord.fields[referenceFieldName] &&
|
|
17013
|
+
incomingRecord.fields[referenceFieldName].value ===
|
|
17014
|
+
existingRecord.fields[referenceFieldName].value);
|
|
16897
17015
|
})) {
|
|
16898
17016
|
return {
|
|
16899
17017
|
ok: true,
|
|
@@ -17772,6 +17890,9 @@ class LdsPrimingRecordRefresher {
|
|
|
17772
17890
|
optionalFields: value.fields.map((f) => `${_apiName}.${f}`),
|
|
17773
17891
|
},
|
|
17774
17892
|
],
|
|
17893
|
+
}, {
|
|
17894
|
+
cachePolicy: { type: 'no-cache' },
|
|
17895
|
+
priority: 'background',
|
|
17775
17896
|
}));
|
|
17776
17897
|
});
|
|
17777
17898
|
const promiseResults = await allSettled(promises);
|
|
@@ -17876,6 +17997,8 @@ function getRuntime() {
|
|
|
17876
17997
|
const durableEnv = makeDurable(gqlEnv, {
|
|
17877
17998
|
durableStore: recordDenormingStore,
|
|
17878
17999
|
enableDurableMetadataRefresh: ldsMetadataRefreshEnabled.isOpen({ fallback: false }),
|
|
18000
|
+
// disable luvio deep freeze in headless environments
|
|
18001
|
+
disableDeepFreeze: typeof window === 'undefined',
|
|
17879
18002
|
});
|
|
17880
18003
|
getIngestRecords = durableEnv.getIngestStagingStoreRecords;
|
|
17881
18004
|
getIngestMetadata = durableEnv.getIngestStagingStoreMetadata;
|
|
@@ -17981,4 +18104,4 @@ register({
|
|
|
17981
18104
|
});
|
|
17982
18105
|
|
|
17983
18106
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
17984
|
-
// version: 1.
|
|
18107
|
+
// version: 1.282.0-f3e0ca0c7
|