@salesforce/lds-adapters-graphql 1.136.6 → 1.136.8

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.
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { deepFreeze, StoreKeyMap } from '@luvio/engine';
8
8
  import { register } from '@salesforce/lds-default-luvio';
9
- import { astResolver } from '@luvio/graphql-parser';
9
+ import { Kind, astResolver } from '@luvio/graphql-parser';
10
10
  import { graphqlAdapterFactory } from '@salesforce/lds-adapters-uiapi';
11
11
  import { createIngestRecordWithFields, keyBuilderRecord } from '@salesforce/lds-adapters-uiapi';
12
12
 
@@ -1403,10 +1403,14 @@ function validate(ast, variables) {
1403
1403
  }
1404
1404
 
1405
1405
  let storeEval = undefined;
1406
+ let draftFunctions = undefined;
1406
1407
  const configuration = {
1407
1408
  setStoreEval: function (storeEvalArg) {
1408
1409
  storeEval = storeEvalArg;
1409
1410
  },
1411
+ setDraftFunctions: function (draftFuncs) {
1412
+ draftFunctions = draftFuncs;
1413
+ },
1410
1414
  };
1411
1415
 
1412
1416
  const assignedToMe = {
@@ -1492,6 +1496,78 @@ function shouldInjectFields(ast) {
1492
1496
  function injectFieldsGQL(ast) {
1493
1497
  return injectScopeFields(ast);
1494
1498
  }
1499
+ function swapIdsOfDocumentNode(documentnode, draftFunctions) {
1500
+ const recordNodes = findRecordSelections(documentnode);
1501
+ recordNodes.forEach((recordConnection) => {
1502
+ swapIdsOfFieldNode(recordConnection, draftFunctions);
1503
+ });
1504
+ return documentnode;
1505
+ }
1506
+ function swapIdsOfFieldNode(selectionNode, draftFunctions) {
1507
+ if (isCustomFieldNode(selectionNode) &&
1508
+ selectionNode.type === 'Connection' &&
1509
+ selectionNode.arguments !== undefined &&
1510
+ selectionNode.arguments.some((argment) => argment.name === 'where')) {
1511
+ const swappedArguments = selectionNode.arguments.map((argument) => {
1512
+ if (argument.name === 'where') {
1513
+ return {
1514
+ ...argument,
1515
+ value: swapIdsOfValueNode(argument.value, draftFunctions.isDraftId, draftFunctions.getCanonicalId),
1516
+ };
1517
+ }
1518
+ else {
1519
+ return argument;
1520
+ }
1521
+ });
1522
+ selectionNode.arguments = swappedArguments;
1523
+ }
1524
+ if (selectionNode.luvioSelections !== undefined) {
1525
+ for (const childSelectionNode of selectionNode.luvioSelections) {
1526
+ if (isCustomFieldNode(childSelectionNode) ||
1527
+ isObjectFieldSelection(childSelectionNode)) {
1528
+ swapIdsOfFieldNode(childSelectionNode, draftFunctions);
1529
+ }
1530
+ }
1531
+ }
1532
+ }
1533
+ function swapIdsOfValueNode(valueNode, isDraftId, idMapper) {
1534
+ switch (valueNode.kind) {
1535
+ case Kind.OBJECT: {
1536
+ const swappedObjectValueNode = {};
1537
+ for (const key of keys(valueNode.fields)) {
1538
+ swappedObjectValueNode[key] = swapIdsOfValueNode(valueNode.fields[key], isDraftId, idMapper);
1539
+ }
1540
+ return {
1541
+ kind: 'ObjectValue',
1542
+ fields: swappedObjectValueNode,
1543
+ };
1544
+ }
1545
+ case Kind.LIST: {
1546
+ const listValueNodes = [];
1547
+ for (const child of valueNode.values) {
1548
+ listValueNodes.push(swapIdsOfValueNode(child, isDraftId, idMapper));
1549
+ }
1550
+ return {
1551
+ kind: 'ListValue',
1552
+ values: listValueNodes,
1553
+ };
1554
+ }
1555
+ case Kind.STRING: {
1556
+ if (!isDraftId(valueNode.value)) {
1557
+ return valueNode;
1558
+ }
1559
+ return {
1560
+ kind: 'StringValue',
1561
+ value: idMapper(valueNode.value),
1562
+ block: false,
1563
+ };
1564
+ }
1565
+ default:
1566
+ return {
1567
+ ...valueNode,
1568
+ };
1569
+ }
1570
+ }
1495
1571
  function injectScopeFields(ast) {
1496
1572
  const modifiedDocumentNode = {
1497
1573
  kind: 'Document',
@@ -2073,6 +2149,34 @@ function buildNetworkSnapshotCachePolicy(context, coercedAdapterRequestContext)
2073
2149
  }
2074
2150
  return buildNetworkSnapshot(luvio, config, fragment, dispatchOptions);
2075
2151
  }
2152
+ const replaceDraftIdsInVariables = (variables, draftFunctions) => {
2153
+ const replace = (object) => {
2154
+ if (typeof object === 'string') {
2155
+ if (!draftFunctions.isDraftId(object)) {
2156
+ return object;
2157
+ }
2158
+ return draftFunctions.getCanonicalId(object);
2159
+ }
2160
+ else if (isArray(object)) {
2161
+ return object.map(replace);
2162
+ }
2163
+ else if (typeof object === 'object' && object !== null) {
2164
+ let source = object;
2165
+ return keys(source).reduce((acc, key) => {
2166
+ acc[key] = replace(source[key]);
2167
+ return acc;
2168
+ }, {});
2169
+ }
2170
+ else {
2171
+ return object;
2172
+ }
2173
+ };
2174
+ let newVariables = keys(variables).reduce((acc, key) => {
2175
+ acc[key] = replace(variables[key]);
2176
+ return acc;
2177
+ }, {});
2178
+ return newVariables;
2179
+ };
2076
2180
  const graphQLAdapterFactory = (luvio) => {
2077
2181
  const uiApiGraphQLAdapter = graphqlAdapterFactory(luvio);
2078
2182
  function graphql(untrustedConfig, requestContext) {
@@ -2103,9 +2207,17 @@ const graphQLAdapterFactory = (luvio) => {
2103
2207
  const validatedConfigWithInjection = fieldInjectionRequired
2104
2208
  ? graphqlConfigWithInjectedAST(validatedConfig)
2105
2209
  : validatedConfig;
2106
- const fragment = createFragment(luvio, validatedConfigWithInjection.query, variables);
2210
+ const sanitizedConfig = draftFunctions !== undefined
2211
+ ? sanitizeConfig(validatedConfigWithInjection, draftFunctions)
2212
+ : validatedConfigWithInjection;
2213
+ if (sanitizedConfig.variables && draftFunctions !== undefined) {
2214
+ const variablesWithSwappedDraftIds = replaceDraftIdsInVariables(sanitizedConfig.variables, draftFunctions);
2215
+ sanitizedConfig.variables = variablesWithSwappedDraftIds;
2216
+ validatedConfig.variables = variablesWithSwappedDraftIds;
2217
+ }
2218
+ const fragment = createFragment(luvio, sanitizedConfig.query, sanitizedConfig.variables);
2107
2219
  const context = {
2108
- config: validatedConfigWithInjection,
2220
+ config: sanitizedConfig,
2109
2221
  fragment,
2110
2222
  luvio,
2111
2223
  };
@@ -2114,7 +2226,7 @@ const graphQLAdapterFactory = (luvio) => {
2114
2226
  const observers = requestContext && requestContext.eventObservers
2115
2227
  ? requestContext.eventObservers
2116
2228
  : [];
2117
- // uses the original ast to do the eval to avoid fields not needed by users
2229
+ // uses the original ast to do the eval to avoid fields not needed by users. The draftID swapping happens when filters transform to predicates.
2118
2230
  return storeEval(validatedConfig, snapshotOrPromiseFromCachePolicy, observers);
2119
2231
  }
2120
2232
  return snapshotOrPromiseFromCachePolicy;
@@ -2131,7 +2243,16 @@ function graphqlConfigWithInjectedAST(graphqlConfig) {
2131
2243
  query: modifiedAST,
2132
2244
  };
2133
2245
  }
2246
+ function sanitizeConfig(graphqlConfig, draftFunctions) {
2247
+ const { query } = graphqlConfig;
2248
+ const astCopy = parse(stringify(query));
2249
+ const modifiedAST = swapIdsOfDocumentNode(astCopy, draftFunctions);
2250
+ return {
2251
+ ...graphqlConfig,
2252
+ query: modifiedAST,
2253
+ };
2254
+ }
2134
2255
  // make sure to register the configuration whenever this module loads
2135
2256
  register({ id: '@salesforce/lds-adapters-graphql', configuration });
2136
2257
 
2137
- export { adapterName, buildCachedSnapshot, keyBuilder as connectionKeyBuilder, graphQLAdapterFactory, namespace, representationName };
2258
+ export { adapterName, buildCachedSnapshot, keyBuilder as connectionKeyBuilder, graphQLAdapterFactory, graphqlConfigWithInjectedAST, namespace, replaceDraftIdsInVariables, representationName, sanitizeConfig };
@@ -1,7 +1,9 @@
1
- import type { StoreEval } from '@salesforce/lds-graphql-eval';
1
+ import type { StoreEval, DraftFunctions } from '@salesforce/lds-graphql-eval';
2
2
  export declare let storeEval: StoreEval<unknown> | undefined;
3
+ export declare let draftFunctions: DraftFunctions | undefined;
3
4
  export declare const configuration: {
4
5
  setStoreEval: (storeEvalArg: typeof storeEval) => void;
6
+ setDraftFunctions: (draftFuncs: typeof draftFunctions) => void;
5
7
  };
6
8
  export type Registration = {
7
9
  id: '@salesforce/lds-adapters-graphql';
@@ -2,6 +2,7 @@ import type { AdapterFactory, Luvio, ReaderFragment, Snapshot, StoreLookup } fro
2
2
  import type { LuvioDocumentNode } from '@luvio/graphql-parser';
3
3
  import type { GraphQLVariables } from './type/Variable';
4
4
  import type { Registration } from './configuration';
5
+ import type { DraftFunctions } from '@salesforce/lds-graphql-eval';
5
6
  export { namespace, representationName } from './util/adapter';
6
7
  export declare const adapterName = "graphQL";
7
8
  interface GraphQLConfig {
@@ -15,6 +16,9 @@ type BuildSnapshotContext = {
15
16
  luvio: Luvio;
16
17
  };
17
18
  export declare function buildCachedSnapshot(context: BuildSnapshotContext, storeLookup: StoreLookup<unknown>): Promise<Snapshot<unknown, unknown>> | Snapshot<unknown, any>;
19
+ export declare const replaceDraftIdsInVariables: (variables: Record<string, any>, draftFunctions: DraftFunctions) => Record<string, any>;
18
20
  export declare const graphQLAdapterFactory: AdapterFactory<GraphQLConfig, unknown>;
21
+ export declare function graphqlConfigWithInjectedAST(graphqlConfig: GraphQLConfig): GraphQLConfig;
22
+ export declare function sanitizeConfig(graphqlConfig: GraphQLConfig, draftFunctions: DraftFunctions): GraphQLConfig;
19
23
  export type { Registration };
20
24
  export { keyBuilder as connectionKeyBuilder } from './custom/connection';
@@ -1,6 +1,9 @@
1
1
  import type { LuvioDocumentNode, LuvioSelectionNode, LuvioSelectionObjectFieldNode, LuvioSelectionScalarFieldNode, LuvioSelectionCustomFieldNode, LuvioDefinitionNode, LuvioOperationDefinitionNode } from '@luvio/graphql-parser';
2
+ import type { DraftFunctions } from '@salesforce/lds-graphql-eval';
2
3
  export declare function shouldInjectFields(ast: LuvioDocumentNode): boolean;
3
4
  export declare function injectFieldsGQL(ast: LuvioDocumentNode): LuvioDocumentNode;
5
+ export declare function swapIdsOfDocumentNode(documentnode: LuvioDocumentNode, draftFunctions: DraftFunctions): LuvioDocumentNode;
6
+ export declare function mergeSelectionNodes(group1: LuvioSelectionNode[], group2: LuvioSelectionNode[]): LuvioSelectionNode[];
4
7
  export declare function findRecordSelections(document: LuvioDocumentNode): LuvioSelectionCustomFieldNode[];
5
8
  export declare function isOperationDefinition(node: LuvioDefinitionNode): node is LuvioOperationDefinitionNode;
6
9
  export declare function isObjectFieldSelection(node: LuvioSelectionNode | undefined): node is LuvioSelectionObjectFieldNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-adapters-graphql",
3
- "version": "1.136.6",
3
+ "version": "1.136.8",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "Wire adapter for GraphQL API endpoint",
6
6
  "main": "dist/es/es2018/graphql-service.js",
@@ -63,9 +63,9 @@
63
63
  {
64
64
  "path": "./sfdc/index.js",
65
65
  "maxSize": {
66
- "none": "84 kB",
67
- "min": "38.5 kB",
68
- "compressed": "12.5 kB"
66
+ "none": "86 kB",
67
+ "min": "40 kB",
68
+ "compressed": "13.5 kB"
69
69
  }
70
70
  }
71
71
  ],
package/sfdc/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  import { createLDSAdapter, createWireAdapterConstructor, createInstrumentedAdapter, createImperativeAdapter } from 'force/ldsBindings';
16
16
  import { register, withDefaultLuvio } from 'force/ldsEngine';
17
17
  import { deepFreeze, StoreKeyMap } from 'force/luvioEngine';
18
- import { astResolver } from 'force/ldsGraphqlParser';
18
+ import { Kind, astResolver } from 'force/ldsGraphqlParser';
19
19
  import { graphqlAdapterFactory } from 'force/ldsAdaptersUiapiGraphql';
20
20
  import { createIngestRecordWithFields, keyBuilderRecord } from 'force/ldsAdaptersUiapi';
21
21
 
@@ -1412,10 +1412,14 @@ function validate(ast, variables) {
1412
1412
  }
1413
1413
 
1414
1414
  let storeEval = undefined;
1415
+ let draftFunctions = undefined;
1415
1416
  const configuration = {
1416
1417
  setStoreEval: function (storeEvalArg) {
1417
1418
  storeEval = storeEvalArg;
1418
1419
  },
1420
+ setDraftFunctions: function (draftFuncs) {
1421
+ draftFunctions = draftFuncs;
1422
+ },
1419
1423
  };
1420
1424
 
1421
1425
  const assignedToMe = {
@@ -1501,6 +1505,78 @@ function shouldInjectFields(ast) {
1501
1505
  function injectFieldsGQL(ast) {
1502
1506
  return injectScopeFields(ast);
1503
1507
  }
1508
+ function swapIdsOfDocumentNode(documentnode, draftFunctions) {
1509
+ const recordNodes = findRecordSelections(documentnode);
1510
+ recordNodes.forEach((recordConnection) => {
1511
+ swapIdsOfFieldNode(recordConnection, draftFunctions);
1512
+ });
1513
+ return documentnode;
1514
+ }
1515
+ function swapIdsOfFieldNode(selectionNode, draftFunctions) {
1516
+ if (isCustomFieldNode(selectionNode) &&
1517
+ selectionNode.type === 'Connection' &&
1518
+ selectionNode.arguments !== undefined &&
1519
+ selectionNode.arguments.some((argment) => argment.name === 'where')) {
1520
+ const swappedArguments = selectionNode.arguments.map((argument) => {
1521
+ if (argument.name === 'where') {
1522
+ return {
1523
+ ...argument,
1524
+ value: swapIdsOfValueNode(argument.value, draftFunctions.isDraftId, draftFunctions.getCanonicalId),
1525
+ };
1526
+ }
1527
+ else {
1528
+ return argument;
1529
+ }
1530
+ });
1531
+ selectionNode.arguments = swappedArguments;
1532
+ }
1533
+ if (selectionNode.luvioSelections !== undefined) {
1534
+ for (const childSelectionNode of selectionNode.luvioSelections) {
1535
+ if (isCustomFieldNode(childSelectionNode) ||
1536
+ isObjectFieldSelection(childSelectionNode)) {
1537
+ swapIdsOfFieldNode(childSelectionNode, draftFunctions);
1538
+ }
1539
+ }
1540
+ }
1541
+ }
1542
+ function swapIdsOfValueNode(valueNode, isDraftId, idMapper) {
1543
+ switch (valueNode.kind) {
1544
+ case Kind.OBJECT: {
1545
+ const swappedObjectValueNode = {};
1546
+ for (const key of keys(valueNode.fields)) {
1547
+ swappedObjectValueNode[key] = swapIdsOfValueNode(valueNode.fields[key], isDraftId, idMapper);
1548
+ }
1549
+ return {
1550
+ kind: 'ObjectValue',
1551
+ fields: swappedObjectValueNode,
1552
+ };
1553
+ }
1554
+ case Kind.LIST: {
1555
+ const listValueNodes = [];
1556
+ for (const child of valueNode.values) {
1557
+ listValueNodes.push(swapIdsOfValueNode(child, isDraftId, idMapper));
1558
+ }
1559
+ return {
1560
+ kind: 'ListValue',
1561
+ values: listValueNodes,
1562
+ };
1563
+ }
1564
+ case Kind.STRING: {
1565
+ if (!isDraftId(valueNode.value)) {
1566
+ return valueNode;
1567
+ }
1568
+ return {
1569
+ kind: 'StringValue',
1570
+ value: idMapper(valueNode.value),
1571
+ block: false,
1572
+ };
1573
+ }
1574
+ default:
1575
+ return {
1576
+ ...valueNode,
1577
+ };
1578
+ }
1579
+ }
1504
1580
  function injectScopeFields(ast) {
1505
1581
  const modifiedDocumentNode = {
1506
1582
  kind: 'Document',
@@ -2082,6 +2158,34 @@ function buildNetworkSnapshotCachePolicy(context, coercedAdapterRequestContext)
2082
2158
  }
2083
2159
  return buildNetworkSnapshot(luvio, config, fragment, dispatchOptions);
2084
2160
  }
2161
+ const replaceDraftIdsInVariables = (variables, draftFunctions) => {
2162
+ const replace = (object) => {
2163
+ if (typeof object === 'string') {
2164
+ if (!draftFunctions.isDraftId(object)) {
2165
+ return object;
2166
+ }
2167
+ return draftFunctions.getCanonicalId(object);
2168
+ }
2169
+ else if (isArray(object)) {
2170
+ return object.map(replace);
2171
+ }
2172
+ else if (typeof object === 'object' && object !== null) {
2173
+ let source = object;
2174
+ return keys(source).reduce((acc, key) => {
2175
+ acc[key] = replace(source[key]);
2176
+ return acc;
2177
+ }, {});
2178
+ }
2179
+ else {
2180
+ return object;
2181
+ }
2182
+ };
2183
+ let newVariables = keys(variables).reduce((acc, key) => {
2184
+ acc[key] = replace(variables[key]);
2185
+ return acc;
2186
+ }, {});
2187
+ return newVariables;
2188
+ };
2085
2189
  const graphQLAdapterFactory = (luvio) => {
2086
2190
  const uiApiGraphQLAdapter = graphqlAdapterFactory(luvio);
2087
2191
  function graphql(untrustedConfig, requestContext) {
@@ -2112,9 +2216,17 @@ const graphQLAdapterFactory = (luvio) => {
2112
2216
  const validatedConfigWithInjection = fieldInjectionRequired
2113
2217
  ? graphqlConfigWithInjectedAST(validatedConfig)
2114
2218
  : validatedConfig;
2115
- const fragment = createFragment(luvio, validatedConfigWithInjection.query, variables);
2219
+ const sanitizedConfig = draftFunctions !== undefined
2220
+ ? sanitizeConfig(validatedConfigWithInjection, draftFunctions)
2221
+ : validatedConfigWithInjection;
2222
+ if (sanitizedConfig.variables && draftFunctions !== undefined) {
2223
+ const variablesWithSwappedDraftIds = replaceDraftIdsInVariables(sanitizedConfig.variables, draftFunctions);
2224
+ sanitizedConfig.variables = variablesWithSwappedDraftIds;
2225
+ validatedConfig.variables = variablesWithSwappedDraftIds;
2226
+ }
2227
+ const fragment = createFragment(luvio, sanitizedConfig.query, sanitizedConfig.variables);
2116
2228
  const context = {
2117
- config: validatedConfigWithInjection,
2229
+ config: sanitizedConfig,
2118
2230
  fragment,
2119
2231
  luvio,
2120
2232
  };
@@ -2123,7 +2235,7 @@ const graphQLAdapterFactory = (luvio) => {
2123
2235
  const observers = requestContext && requestContext.eventObservers
2124
2236
  ? requestContext.eventObservers
2125
2237
  : [];
2126
- // uses the original ast to do the eval to avoid fields not needed by users
2238
+ // uses the original ast to do the eval to avoid fields not needed by users. The draftID swapping happens when filters transform to predicates.
2127
2239
  return storeEval(validatedConfig, snapshotOrPromiseFromCachePolicy, observers);
2128
2240
  }
2129
2241
  return snapshotOrPromiseFromCachePolicy;
@@ -2140,6 +2252,15 @@ function graphqlConfigWithInjectedAST(graphqlConfig) {
2140
2252
  query: modifiedAST,
2141
2253
  };
2142
2254
  }
2255
+ function sanitizeConfig(graphqlConfig, draftFunctions) {
2256
+ const { query } = graphqlConfig;
2257
+ const astCopy = parse(stringify(query));
2258
+ const modifiedAST = swapIdsOfDocumentNode(astCopy, draftFunctions);
2259
+ return {
2260
+ ...graphqlConfig,
2261
+ query: modifiedAST,
2262
+ };
2263
+ }
2143
2264
  // make sure to register the configuration whenever this module loads
2144
2265
  register({ id: '@salesforce/lds-adapters-graphql', configuration });
2145
2266
 
@@ -2159,4 +2280,4 @@ withDefaultLuvio((luvio) => {
2159
2280
  });
2160
2281
 
2161
2282
  export { graphQL, graphQLImperative, unstable_graphQL_imperative };
2162
- // version: 1.136.6-acf28210f
2283
+ // version: 1.136.8-449f5be71