@salesforce/lds-runtime-mobile 1.315.0 → 1.317.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 +1450 -683
- package/dist/types/draftsAdapters/AbstractResourceRequestActionHandler.d.ts +71 -0
- package/dist/types/draftsAdapters/ContentDocumentCompositeRepresentation/ContentDocumentCompositeRepresentationActionHandler.d.ts +2 -2
- package/dist/types/draftsAdapters/IdempotentWrite.d.ts +33 -0
- package/dist/types/draftsAdapters/QuickActionExecutionRepresentation/QuickActionExecutionRepresentationHandler.d.ts +1 -1
- package/dist/types/draftsAdapters/QuickActionExecutionRepresentation/UpdateRecordQuickActionExecutionRepresentationHandler.d.ts +1 -1
- package/dist/types/draftsAdapters/RecordRepresentation/actionHandlers/UiApiRecordActionHandler.d.ts +1 -1
- package/dist/types/instrumentation/metrics.d.ts +3 -2
- package/dist/types/sideEffects/SideEffectService.d.ts +27 -0
- package/dist/types/sideEffects/SideEffectStore.d.ts +14 -0
- package/dist/types/sideEffects/index.d.ts +2 -0
- package/dist/types/sideEffects/sideEffectEnvironment.d.ts +3 -0
- package/dist/types/sideEffects/sideEffects.d.ts +31 -0
- package/dist/types/utils/ObjectInfoService.d.ts +1 -0
- package/dist/types/utils/language.d.ts +2 -2
- package/package.json +16 -16
- package/sfdc/main.js +1450 -683
- package/sfdc/types/draftsAdapters/AbstractResourceRequestActionHandler.d.ts +71 -0
- package/sfdc/types/draftsAdapters/ContentDocumentCompositeRepresentation/ContentDocumentCompositeRepresentationActionHandler.d.ts +2 -2
- package/sfdc/types/draftsAdapters/IdempotentWrite.d.ts +33 -0
- package/sfdc/types/draftsAdapters/QuickActionExecutionRepresentation/QuickActionExecutionRepresentationHandler.d.ts +1 -1
- package/sfdc/types/draftsAdapters/QuickActionExecutionRepresentation/UpdateRecordQuickActionExecutionRepresentationHandler.d.ts +1 -1
- package/sfdc/types/draftsAdapters/RecordRepresentation/actionHandlers/UiApiRecordActionHandler.d.ts +1 -1
- package/sfdc/types/instrumentation/metrics.d.ts +3 -2
- package/sfdc/types/sideEffects/SideEffectService.d.ts +27 -0
- package/sfdc/types/sideEffects/SideEffectStore.d.ts +14 -0
- package/sfdc/types/sideEffects/index.d.ts +2 -0
- package/sfdc/types/sideEffects/sideEffectEnvironment.d.ts +3 -0
- package/sfdc/types/sideEffects/sideEffects.d.ts +31 -0
- package/sfdc/types/utils/ObjectInfoService.d.ts +1 -0
- package/sfdc/types/utils/language.d.ts +2 -2
package/dist/main.js
CHANGED
|
@@ -21,8 +21,9 @@ import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKe
|
|
|
21
21
|
import { RECORD_ID_PREFIX as RECORD_ID_PREFIX$1, RECORD_FIELDS_KEY_JUNCTION as RECORD_FIELDS_KEY_JUNCTION$1, keyBuilderRecord, extractRecordIdFromStoreKey as extractRecordIdFromStoreKey$1, isStoreKeyRecordViewEntity as isStoreKeyRecordViewEntity$1, RECORD_REPRESENTATION_NAME as RECORD_REPRESENTATION_NAME$1, configuration, buildRecordRepKeyFromId as buildRecordRepKeyFromId$1, getRecordId18 as getRecordId18$1, getRecordsAdapterFactory as getRecordsAdapterFactory$1, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion } from '@salesforce/lds-adapters-uiapi';
|
|
22
22
|
import ldsIdempotencyWriteDisabled from '@salesforce/gate/lds.idempotencyWriteDisabled';
|
|
23
23
|
import ldsBackdatingEnabled from '@salesforce/gate/lds.backdatingEnabled';
|
|
24
|
-
import { Kind as Kind$1, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$8, extendSchema, isScalarType, print } from '@luvio/graphql-parser';
|
|
24
|
+
import { Kind as Kind$1, buildSchema, isObjectType, defaultFieldResolver, visit as visit$1, execute, parse as parse$8, extendSchema, isScalarType, print } from '@luvio/graphql-parser';
|
|
25
25
|
import FIRST_DAY_OF_WEEK from '@salesforce/i18n/firstDayOfWeek';
|
|
26
|
+
import graphqQueryFieldLimit from '@salesforce/gate/lmr.graphqQueryFieldLimit';
|
|
26
27
|
import caseSensitiveUserId from '@salesforce/user/Id';
|
|
27
28
|
import { idleDetector, getInstrumentation } from 'o11y/client';
|
|
28
29
|
import ldsUseShortUrlGate from '@salesforce/gate/lds.useShortUrl';
|
|
@@ -52,7 +53,7 @@ import graphqlL2AdapterGate from '@salesforce/gate/lmr.graphqlL2Adapter';
|
|
|
52
53
|
|
|
53
54
|
const { parse: parse$7, stringify: stringify$7 } = JSON;
|
|
54
55
|
const { join: join$2, push: push$3, unshift } = Array.prototype;
|
|
55
|
-
const { isArray: isArray$
|
|
56
|
+
const { isArray: isArray$6 } = Array;
|
|
56
57
|
const { entries: entries$6, keys: keys$9 } = Object;
|
|
57
58
|
|
|
58
59
|
const UI_API_BASE_URI = '/services/data/v63.0/ui-api';
|
|
@@ -277,7 +278,7 @@ const getRecordDispatcher = (req) => {
|
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
280
|
const recordId = urlParams.recordId;
|
|
280
|
-
const fieldsArray = fields !== undefined && isArray$
|
|
281
|
+
const fieldsArray = fields !== undefined && isArray$6(fields) ? fields : [];
|
|
281
282
|
const optionalFieldsArray = optionalFields !== undefined && Array.isArray(optionalFields)
|
|
282
283
|
? optionalFields
|
|
283
284
|
: [];
|
|
@@ -1843,7 +1844,7 @@ var QueueOperationType;
|
|
|
1843
1844
|
|
|
1844
1845
|
const { keys: keys$7, create: create$7, assign: assign$7, values: values$4 } = Object;
|
|
1845
1846
|
const { stringify: stringify$6, parse: parse$6 } = JSON;
|
|
1846
|
-
const { isArray: isArray$
|
|
1847
|
+
const { isArray: isArray$5 } = Array;
|
|
1847
1848
|
|
|
1848
1849
|
const DraftIdMappingKeyPrefix240 = 'DraftIdMapping::';
|
|
1849
1850
|
const DRAFT_ID_MAPPINGS_SEGMENT = 'DRAFT_ID_MAPPINGS';
|
|
@@ -2123,6 +2124,11 @@ class DurableDraftQueue {
|
|
|
2123
2124
|
this.userState = DraftQueueState.Stopped;
|
|
2124
2125
|
this.uploadingActionId = undefined;
|
|
2125
2126
|
this.timeoutHandler = undefined;
|
|
2127
|
+
this.logger = typeof __nimbus !== 'undefined' &&
|
|
2128
|
+
__nimbus.plugins !== undefined &&
|
|
2129
|
+
__nimbus.plugins.JSLoggerPlugin !== undefined
|
|
2130
|
+
? __nimbus.plugins.JSLoggerPlugin
|
|
2131
|
+
: undefined;
|
|
2126
2132
|
this.handlers = {};
|
|
2127
2133
|
this.draftStore = draftStore;
|
|
2128
2134
|
this.workerPool = new AsyncWorkerPool(1);
|
|
@@ -2163,12 +2169,13 @@ class DurableDraftQueue {
|
|
|
2163
2169
|
await this.notifyChangedListeners({
|
|
2164
2170
|
type: DraftQueueEventType.QueueStateChanged,
|
|
2165
2171
|
state: this.state,
|
|
2172
|
+
draftCount: this.draftStore.getCount(),
|
|
2166
2173
|
});
|
|
2167
2174
|
const result = await this.processNextAction();
|
|
2168
2175
|
switch (result) {
|
|
2169
2176
|
case ProcessActionResult.BLOCKED_ON_ERROR:
|
|
2170
2177
|
this.state = DraftQueueState.Error;
|
|
2171
|
-
return Promise.reject();
|
|
2178
|
+
return Promise.reject('Unable to start queue - first action is in error state');
|
|
2172
2179
|
default:
|
|
2173
2180
|
return Promise.resolve();
|
|
2174
2181
|
}
|
|
@@ -2179,16 +2186,22 @@ class DurableDraftQueue {
|
|
|
2179
2186
|
// Do nothing if the queue state is already stopped
|
|
2180
2187
|
return Promise.resolve();
|
|
2181
2188
|
}
|
|
2182
|
-
this.stopQueueManually();
|
|
2189
|
+
this.stopQueueManually(false);
|
|
2183
2190
|
return this.notifyChangedListeners({
|
|
2184
2191
|
type: DraftQueueEventType.QueueStateChanged,
|
|
2185
2192
|
state: DraftQueueState.Stopped,
|
|
2193
|
+
draftCount: this.draftStore.getCount(),
|
|
2186
2194
|
});
|
|
2187
2195
|
}
|
|
2188
2196
|
/**
|
|
2189
2197
|
* Used to stop the queue within DraftQueue without user interaction
|
|
2190
2198
|
*/
|
|
2191
|
-
stopQueueManually() {
|
|
2199
|
+
stopQueueManually(internalReason) {
|
|
2200
|
+
if (this.logger) {
|
|
2201
|
+
this.logger.logInfo(internalReason
|
|
2202
|
+
? 'Draft queue stopped for internal reason'
|
|
2203
|
+
: 'Draft queue stopped by app');
|
|
2204
|
+
}
|
|
2192
2205
|
if (this.timeoutHandler) {
|
|
2193
2206
|
clearTimeout(this.timeoutHandler);
|
|
2194
2207
|
this.timeoutHandler = undefined;
|
|
@@ -2198,9 +2211,6 @@ class DurableDraftQueue {
|
|
|
2198
2211
|
async getQueueActions() {
|
|
2199
2212
|
const drafts = (await this.draftStore.getAllDrafts());
|
|
2200
2213
|
const queue = [];
|
|
2201
|
-
if (drafts === undefined) {
|
|
2202
|
-
return queue;
|
|
2203
|
-
}
|
|
2204
2214
|
drafts.forEach((draft) => {
|
|
2205
2215
|
if (draft.id === this.uploadingActionId) {
|
|
2206
2216
|
draft.status = DraftActionStatus.Uploading;
|
|
@@ -2231,6 +2241,7 @@ class DurableDraftQueue {
|
|
|
2231
2241
|
await this.notifyChangedListeners({
|
|
2232
2242
|
type: DraftQueueEventType.ActionAdded,
|
|
2233
2243
|
action: pendingAction,
|
|
2244
|
+
draftCount: this.draftStore.getCount(),
|
|
2234
2245
|
});
|
|
2235
2246
|
await handler.handleActionEnqueued(pendingAction, queue);
|
|
2236
2247
|
if (this.state === DraftQueueState.Started) {
|
|
@@ -2263,6 +2274,7 @@ class DurableDraftQueue {
|
|
|
2263
2274
|
await this.notifyChangedListeners({
|
|
2264
2275
|
type: DraftQueueEventType.ActionCompleted,
|
|
2265
2276
|
action,
|
|
2277
|
+
draftCount: this.draftStore.getCount(),
|
|
2266
2278
|
});
|
|
2267
2279
|
if (this.state === DraftQueueState.Started) {
|
|
2268
2280
|
this.processNextAction();
|
|
@@ -2312,6 +2324,7 @@ class DurableDraftQueue {
|
|
|
2312
2324
|
await this.notifyChangedListeners({
|
|
2313
2325
|
type: DraftQueueEventType.ActionFailed,
|
|
2314
2326
|
action: action,
|
|
2327
|
+
draftCount: this.draftStore.getCount(),
|
|
2315
2328
|
});
|
|
2316
2329
|
return ProcessActionResult.BLOCKED_ON_ERROR;
|
|
2317
2330
|
}
|
|
@@ -2328,6 +2341,7 @@ class DurableDraftQueue {
|
|
|
2328
2341
|
await this.notifyChangedListeners({
|
|
2329
2342
|
type: DraftQueueEventType.ActionUploading,
|
|
2330
2343
|
action: { ...action, status: DraftActionStatus.Uploading },
|
|
2344
|
+
draftCount: this.draftStore.getCount(),
|
|
2331
2345
|
});
|
|
2332
2346
|
return this.handle(action);
|
|
2333
2347
|
}
|
|
@@ -2349,6 +2363,7 @@ class DurableDraftQueue {
|
|
|
2349
2363
|
return this.notifyChangedListeners({
|
|
2350
2364
|
type: DraftQueueEventType.ActionFailed,
|
|
2351
2365
|
action: errorAction,
|
|
2366
|
+
draftCount: this.draftStore.getCount(),
|
|
2352
2367
|
});
|
|
2353
2368
|
}
|
|
2354
2369
|
async notifyChangedListeners(event) {
|
|
@@ -2395,6 +2410,7 @@ class DurableDraftQueue {
|
|
|
2395
2410
|
await this.notifyChangedListeners({
|
|
2396
2411
|
type: DraftQueueEventType.ActionDeleted,
|
|
2397
2412
|
action,
|
|
2413
|
+
draftCount: this.draftStore.getCount(),
|
|
2398
2414
|
});
|
|
2399
2415
|
if (this.userState === DraftQueueState.Started &&
|
|
2400
2416
|
this.state !== DraftQueueState.Started &&
|
|
@@ -2404,7 +2420,7 @@ class DurableDraftQueue {
|
|
|
2404
2420
|
}
|
|
2405
2421
|
async updateDraftAction(action) {
|
|
2406
2422
|
// stop queue manually
|
|
2407
|
-
this.stopQueueManually();
|
|
2423
|
+
this.stopQueueManually(true);
|
|
2408
2424
|
const actionStatus = await this.statusOfAction(action.id);
|
|
2409
2425
|
if (actionStatus === DraftActionStatus.Uploading) {
|
|
2410
2426
|
return Promise.reject('cannot update an uploading action');
|
|
@@ -2434,7 +2450,7 @@ class DurableDraftQueue {
|
|
|
2434
2450
|
return this.replaceOrMergeActions(targetActionId, sourceActionId, true);
|
|
2435
2451
|
}
|
|
2436
2452
|
async retryAction(actionId) {
|
|
2437
|
-
this.stopQueueManually();
|
|
2453
|
+
this.stopQueueManually(true);
|
|
2438
2454
|
const actions = await this.getQueueActions();
|
|
2439
2455
|
const target = actions[0];
|
|
2440
2456
|
if (!target || target.id !== actionId) {
|
|
@@ -2452,6 +2468,7 @@ class DurableDraftQueue {
|
|
|
2452
2468
|
await this.notifyChangedListeners({
|
|
2453
2469
|
type: DraftQueueEventType.ActionUpdated,
|
|
2454
2470
|
action: pendingAction,
|
|
2471
|
+
draftCount: this.draftStore.getCount(),
|
|
2455
2472
|
});
|
|
2456
2473
|
await this.startQueueSafe();
|
|
2457
2474
|
return pendingAction;
|
|
@@ -2477,6 +2494,7 @@ class DurableDraftQueue {
|
|
|
2477
2494
|
await this.notifyChangedListeners({
|
|
2478
2495
|
type: DraftQueueEventType.ActionUpdated,
|
|
2479
2496
|
action: action,
|
|
2497
|
+
draftCount: this.draftStore.getCount(),
|
|
2480
2498
|
});
|
|
2481
2499
|
return action;
|
|
2482
2500
|
}
|
|
@@ -2484,6 +2502,7 @@ class DurableDraftQueue {
|
|
|
2484
2502
|
await this.notifyChangedListeners({
|
|
2485
2503
|
type: DraftQueueEventType.QueueStateChanged,
|
|
2486
2504
|
state: DraftQueueState.Waiting,
|
|
2505
|
+
draftCount: this.draftStore.getCount(),
|
|
2487
2506
|
});
|
|
2488
2507
|
this.timeoutHandler = setTimeout(() => {
|
|
2489
2508
|
if (this.state !== DraftQueueState.Stopped) {
|
|
@@ -2542,7 +2561,7 @@ class DurableDraftQueue {
|
|
|
2542
2561
|
if (this.replacingAction !== undefined) {
|
|
2543
2562
|
throw Error('Cannot replace/merge actions while a replace/merge action operation is in progress.');
|
|
2544
2563
|
}
|
|
2545
|
-
this.stopQueueManually();
|
|
2564
|
+
this.stopQueueManually(true);
|
|
2546
2565
|
const promise = this.getActionsForReplaceOrMerge(targetActionId, sourceActionId).then(async ({ target, source }) => {
|
|
2547
2566
|
// put in a try/finally block so we don't leave this.replacingAction
|
|
2548
2567
|
// indefinitely set
|
|
@@ -2558,6 +2577,7 @@ class DurableDraftQueue {
|
|
|
2558
2577
|
await this.notifyChangedListeners({
|
|
2559
2578
|
type: DraftQueueEventType.ActionUpdated,
|
|
2560
2579
|
action: updatedTarget,
|
|
2580
|
+
draftCount: this.draftStore.getCount(),
|
|
2561
2581
|
});
|
|
2562
2582
|
// remove the source from queue
|
|
2563
2583
|
await this.removeDraftAction(sourceActionId);
|
|
@@ -2696,6 +2716,9 @@ class DurableDraftStore {
|
|
|
2696
2716
|
};
|
|
2697
2717
|
return this.enqueueAction(action);
|
|
2698
2718
|
}
|
|
2719
|
+
getCount() {
|
|
2720
|
+
return keys$7(this.draftStore).length;
|
|
2721
|
+
}
|
|
2699
2722
|
/**
|
|
2700
2723
|
* Runs a write operation against the draft store, if the initial
|
|
2701
2724
|
* revive is still in progress, the action gets enqueued to run once the
|
|
@@ -2739,23 +2762,15 @@ class DurableDraftStore {
|
|
|
2739
2762
|
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
2740
2763
|
const entry = durableEntries[keys$1[i]];
|
|
2741
2764
|
const action = entry.data;
|
|
2742
|
-
if (
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
return Promise.reject('Unexpected draft action version found in the durable store');
|
|
2749
|
-
}
|
|
2750
|
-
}
|
|
2751
|
-
draftStore[action.id] = action;
|
|
2752
|
-
}
|
|
2753
|
-
else {
|
|
2754
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
2755
|
-
const err = new Error('Expected draft action to be defined in the durable store');
|
|
2756
|
-
return Promise.reject(err);
|
|
2765
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2766
|
+
// the `version` property was introduced in 242, we should assert version
|
|
2767
|
+
// exists once we are sure there are no durable stores that contain
|
|
2768
|
+
// versionless actions
|
|
2769
|
+
if (action.version && action.version !== '242.0.0') {
|
|
2770
|
+
return Promise.reject('Unexpected draft action version found in the durable store');
|
|
2757
2771
|
}
|
|
2758
2772
|
}
|
|
2773
|
+
draftStore[action.id] = action;
|
|
2759
2774
|
}
|
|
2760
2775
|
return this.runQueuedOperations();
|
|
2761
2776
|
})
|
|
@@ -2791,494 +2806,6 @@ class DurableDraftStore {
|
|
|
2791
2806
|
}
|
|
2792
2807
|
}
|
|
2793
2808
|
|
|
2794
|
-
const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
|
|
2795
|
-
const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
|
2796
|
-
const ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED = 'IDEMPOTENCY_FEATURE_NOT_ENABLED';
|
|
2797
|
-
const ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED = 'IDEMPOTENCY_NOT_SUPPORTED';
|
|
2798
|
-
const ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER = 'IDEMPOTENCY_KEY_USED_DIFFERENT_USER';
|
|
2799
|
-
const ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST = 'IDEMPOTENCY_CONCURRENT_REQUEST';
|
|
2800
|
-
const ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED = 'IDEMPOTENCY_KEY_ALREADY_USED';
|
|
2801
|
-
const ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR = 'IDEMPOTENCY_BACKEND_OPERATION_ERROR';
|
|
2802
|
-
/**
|
|
2803
|
-
* Get the retry after in milliseconds from the response headers, undefined if not specified.
|
|
2804
|
-
* The header could have two different format.
|
|
2805
|
-
* Retry-After: <http-date>, like Wed, 21 Oct 2015 07:28:00 GMT
|
|
2806
|
-
* Retry-After: <delay-seconds>, like 1.5s
|
|
2807
|
-
* @param headers http headers
|
|
2808
|
-
* @returns the time to delat in millisconds.
|
|
2809
|
-
*/
|
|
2810
|
-
function getRetryAfterInMs(headers) {
|
|
2811
|
-
const retryAfterHeader = headers && headers[HTTP_HEADER_RETRY_AFTER];
|
|
2812
|
-
if (retryAfterHeader === undefined) {
|
|
2813
|
-
return undefined;
|
|
2814
|
-
}
|
|
2815
|
-
const delayInSecond = parseFloat(retryAfterHeader);
|
|
2816
|
-
if (retryAfterHeader === delayInSecond.toString()) {
|
|
2817
|
-
return Math.round(delayInSecond * 1000);
|
|
2818
|
-
}
|
|
2819
|
-
const delayUntilDateTime = Date.parse(retryAfterHeader);
|
|
2820
|
-
if (isNaN(delayUntilDateTime)) {
|
|
2821
|
-
return undefined;
|
|
2822
|
-
}
|
|
2823
|
-
return delayUntilDateTime - Date.now();
|
|
2824
|
-
}
|
|
2825
|
-
|
|
2826
|
-
const DEFAULT_FIELD_LAST_MODIFIED_DATE$1 = 'LastModifiedDate';
|
|
2827
|
-
const DEFAULT_FIELD_CREATED_DATE$1 = 'CreatedDate';
|
|
2828
|
-
class AbstractResourceRequestActionHandler {
|
|
2829
|
-
constructor(draftQueue, networkAdapter, getLuvio) {
|
|
2830
|
-
this.draftQueue = draftQueue;
|
|
2831
|
-
this.networkAdapter = networkAdapter;
|
|
2832
|
-
this.getLuvio = getLuvio;
|
|
2833
|
-
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
2834
|
-
// ids and canonical ids for the current session. Having a local copy of
|
|
2835
|
-
// these mappings is necessary to avoid a race condition between publishing
|
|
2836
|
-
// new mappings to the durable store and those mappings being loaded into
|
|
2837
|
-
// the luvio store redirect table, during which a new draft might be enqueued
|
|
2838
|
-
// which would not see a necessary mapping.
|
|
2839
|
-
this.ephemeralRedirects = {};
|
|
2840
|
-
// determined by Server setup.
|
|
2841
|
-
this.isIdempotencySupported = true;
|
|
2842
|
-
// idempotency write flag set by lds
|
|
2843
|
-
this.isLdsIdempotencyWriteDisabled = ldsIdempotencyWriteDisabled.isOpen({
|
|
2844
|
-
fallback: false,
|
|
2845
|
-
});
|
|
2846
|
-
this.isBackdatingEnabled = ldsBackdatingEnabled.isOpen({ fallback: false });
|
|
2847
|
-
}
|
|
2848
|
-
enqueue(data) {
|
|
2849
|
-
return this.draftQueue.enqueue(this.handlerId, data);
|
|
2850
|
-
}
|
|
2851
|
-
async handleAction(action, actionCompleted, actionErrored) {
|
|
2852
|
-
const { data: request } = action;
|
|
2853
|
-
// no context is stored in draft action
|
|
2854
|
-
try {
|
|
2855
|
-
const response = await this.networkAdapter(request, {});
|
|
2856
|
-
if (response.ok) {
|
|
2857
|
-
await actionCompleted({
|
|
2858
|
-
...action,
|
|
2859
|
-
response,
|
|
2860
|
-
status: DraftActionStatus.Completed,
|
|
2861
|
-
});
|
|
2862
|
-
return ProcessActionResult.ACTION_SUCCEEDED;
|
|
2863
|
-
}
|
|
2864
|
-
let shouldRetry = false;
|
|
2865
|
-
let retryDelayInMs = undefined;
|
|
2866
|
-
let actionDataChanged = false;
|
|
2867
|
-
let updatedAction = action;
|
|
2868
|
-
if (request && request.headers && request.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
2869
|
-
const status = response.status;
|
|
2870
|
-
switch (status) {
|
|
2871
|
-
case 408 /* IdempotentWriteSpecificHttpStatusCode.RequestTimeout */:
|
|
2872
|
-
case 503 /* IdempotentWriteSpecificHttpStatusCode.ServiceUnavailable */:
|
|
2873
|
-
retryDelayInMs = getRetryAfterInMs(response.headers);
|
|
2874
|
-
shouldRetry = true;
|
|
2875
|
-
break;
|
|
2876
|
-
case HttpStatusCode.ServerError: {
|
|
2877
|
-
shouldRetry = true;
|
|
2878
|
-
if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR)) {
|
|
2879
|
-
this.isIdempotencySupported = false;
|
|
2880
|
-
retryDelayInMs = 0;
|
|
2881
|
-
actionDataChanged = true;
|
|
2882
|
-
}
|
|
2883
|
-
break;
|
|
2884
|
-
}
|
|
2885
|
-
case 409 /* IdempotentWriteSpecificHttpStatusCode.Conflict */: {
|
|
2886
|
-
if (this.isUiApiErrors(response.body)) {
|
|
2887
|
-
const errorCode = response.body[0].errorCode;
|
|
2888
|
-
if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER)) {
|
|
2889
|
-
retryDelayInMs = 0;
|
|
2890
|
-
actionDataChanged = true;
|
|
2891
|
-
}
|
|
2892
|
-
else if (errorCode === ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST) {
|
|
2893
|
-
retryDelayInMs = getRetryAfterInMs(response.headers);
|
|
2894
|
-
}
|
|
2895
|
-
shouldRetry = true;
|
|
2896
|
-
}
|
|
2897
|
-
break;
|
|
2898
|
-
}
|
|
2899
|
-
case HttpStatusCode.BadRequest: {
|
|
2900
|
-
if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED, ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED)) {
|
|
2901
|
-
retryDelayInMs = 0;
|
|
2902
|
-
actionDataChanged = true;
|
|
2903
|
-
shouldRetry = true;
|
|
2904
|
-
}
|
|
2905
|
-
break;
|
|
2906
|
-
}
|
|
2907
|
-
case 422 /* IdempotentWriteSpecificHttpStatusCode.UnProcessableEntity */: {
|
|
2908
|
-
if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED)) {
|
|
2909
|
-
retryDelayInMs = 0;
|
|
2910
|
-
actionDataChanged = true;
|
|
2911
|
-
shouldRetry = true;
|
|
2912
|
-
}
|
|
2913
|
-
break;
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
}
|
|
2917
|
-
if (this.isBackdatingEnabled &&
|
|
2918
|
-
response.status === HttpStatusCode.BadRequest &&
|
|
2919
|
-
this.isBackdatingError(response.body, action)) {
|
|
2920
|
-
updatedAction.timestamp = Date.now();
|
|
2921
|
-
updatedAction.data.body.fields = {
|
|
2922
|
-
...updatedAction.data.body.fields,
|
|
2923
|
-
LastModifiedDate: new Date(updatedAction.timestamp).toISOString(),
|
|
2924
|
-
};
|
|
2925
|
-
if (this.hasIdempotencySupport() &&
|
|
2926
|
-
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
2927
|
-
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
2928
|
-
}
|
|
2929
|
-
shouldRetry = true;
|
|
2930
|
-
actionDataChanged = true;
|
|
2931
|
-
}
|
|
2932
|
-
await actionErrored(shouldRetry
|
|
2933
|
-
? updatedAction
|
|
2934
|
-
: {
|
|
2935
|
-
...updatedAction,
|
|
2936
|
-
error: response,
|
|
2937
|
-
status: DraftActionStatus.Error,
|
|
2938
|
-
}, shouldRetry, retryDelayInMs, actionDataChanged);
|
|
2939
|
-
return ProcessActionResult.ACTION_ERRORED;
|
|
2940
|
-
}
|
|
2941
|
-
catch (e) {
|
|
2942
|
-
await actionErrored(action, true);
|
|
2943
|
-
return ProcessActionResult.NETWORK_ERROR;
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
// true if response is an idempotency server error. updates or deletes idempotency key if the reponse is idempotency related error. Idempotency related error is in format of UiApiError array.
|
|
2947
|
-
handleIdempotencyServerError(responseBody, action, updateIdempotencyKey, ...targetErrorCodes) {
|
|
2948
|
-
if (this.isUiApiErrors(responseBody)) {
|
|
2949
|
-
const errorCode = responseBody[0].errorCode;
|
|
2950
|
-
if (targetErrorCodes.includes(errorCode)) {
|
|
2951
|
-
action.data.headers = action.data.headers || {};
|
|
2952
|
-
if (updateIdempotencyKey) {
|
|
2953
|
-
action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
2954
|
-
}
|
|
2955
|
-
else {
|
|
2956
|
-
delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
|
|
2957
|
-
}
|
|
2958
|
-
return true;
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
return false;
|
|
2962
|
-
}
|
|
2963
|
-
// checks if the body is an array of UiApiError. Sometimes the body has `enhancedErrorType` field as an error indicator(one example is the field validation failure). In such case Action being processed updates to an Error Action.
|
|
2964
|
-
isUiApiErrors(body) {
|
|
2965
|
-
return body !== undefined && isArray$4(body) && body.length > 0 && body[0].errorCode;
|
|
2966
|
-
}
|
|
2967
|
-
isBackdatingError(body, action) {
|
|
2968
|
-
if (body.enhancedErrorType &&
|
|
2969
|
-
body.enhancedErrorType === 'RecordError' &&
|
|
2970
|
-
body.output &&
|
|
2971
|
-
body.output.errors &&
|
|
2972
|
-
isArray$4(body.output.errors) &&
|
|
2973
|
-
body.output.errors.length > 0 &&
|
|
2974
|
-
action.data.body &&
|
|
2975
|
-
action.data.body.fields &&
|
|
2976
|
-
action.data.body.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE$1]) {
|
|
2977
|
-
return body.output.errors.some((error) => error.errorCode === 'CollisionDetectedException');
|
|
2978
|
-
}
|
|
2979
|
-
return false;
|
|
2980
|
-
}
|
|
2981
|
-
async buildPendingAction(request, queue) {
|
|
2982
|
-
const targetId = await this.getIdFromRequest(request);
|
|
2983
|
-
const tag = this.buildTagForTargetId(targetId);
|
|
2984
|
-
const handlerActions = queue.filter((x) => x.handler === this.handlerId);
|
|
2985
|
-
if (request.method === 'post' && actionsForTag(tag, handlerActions).length > 0) {
|
|
2986
|
-
return Promise.reject(new Error('Cannot enqueue a POST draft action with an existing tag'));
|
|
2987
|
-
}
|
|
2988
|
-
if (deleteActionsForTag(tag, handlerActions).length > 0) {
|
|
2989
|
-
return Promise.reject(new Error('Cannot enqueue a draft action for a deleted record'));
|
|
2990
|
-
}
|
|
2991
|
-
return {
|
|
2992
|
-
handler: this.handlerId,
|
|
2993
|
-
targetId,
|
|
2994
|
-
tag,
|
|
2995
|
-
data: request,
|
|
2996
|
-
status: DraftActionStatus.Pending,
|
|
2997
|
-
id: generateUniqueDraftActionId(queue.map((x) => x.id)),
|
|
2998
|
-
timestamp: Date.now(),
|
|
2999
|
-
metadata: {},
|
|
3000
|
-
version: '242.0.0',
|
|
3001
|
-
};
|
|
3002
|
-
}
|
|
3003
|
-
async handleActionEnqueued(_action) { }
|
|
3004
|
-
handleActionRemoved(action) {
|
|
3005
|
-
return this.reingestRecord(action);
|
|
3006
|
-
}
|
|
3007
|
-
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
3008
|
-
const queueOperations = [];
|
|
3009
|
-
const redirects = this.getRedirectMappings(action);
|
|
3010
|
-
if (redirects !== undefined) {
|
|
3011
|
-
const { length } = queue;
|
|
3012
|
-
for (let i = 0; i < length; i++) {
|
|
3013
|
-
const queueAction = queue[i];
|
|
3014
|
-
// if this queueAction is the action that is completing we can move on,
|
|
3015
|
-
// it is about to be deleted and won't have the draft ID in it
|
|
3016
|
-
if (queueAction.id === action.id) {
|
|
3017
|
-
continue;
|
|
3018
|
-
}
|
|
3019
|
-
if (isResourceRequestAction(queueAction)) {
|
|
3020
|
-
let queueOperationMutated = false;
|
|
3021
|
-
let updatedActionTag = undefined;
|
|
3022
|
-
let updatedActionTargetId = undefined;
|
|
3023
|
-
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
3024
|
-
let { basePath, body } = queueActionRequest;
|
|
3025
|
-
let stringifiedBody = stringify$6(body);
|
|
3026
|
-
// for each redirected ID/key we loop over the operation to see if it needs
|
|
3027
|
-
// to be updated
|
|
3028
|
-
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
3029
|
-
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
3030
|
-
basePath = basePath.replace(draftId, canonicalId);
|
|
3031
|
-
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
3032
|
-
queueOperationMutated = true;
|
|
3033
|
-
}
|
|
3034
|
-
// if the action is performed on a previous draft id, we need to replace the action
|
|
3035
|
-
// with a new one at the updated canonical key
|
|
3036
|
-
if (queueActionTag === draftKey) {
|
|
3037
|
-
updatedActionTag = canonicalKey;
|
|
3038
|
-
updatedActionTargetId = canonicalId;
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
if (queueOperationMutated) {
|
|
3042
|
-
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
3043
|
-
const updatedAction = {
|
|
3044
|
-
...queueAction,
|
|
3045
|
-
tag: updatedActionTag,
|
|
3046
|
-
targetId: updatedActionTargetId,
|
|
3047
|
-
data: {
|
|
3048
|
-
...queueActionRequest,
|
|
3049
|
-
basePath: basePath,
|
|
3050
|
-
body: parse$6(stringifiedBody),
|
|
3051
|
-
},
|
|
3052
|
-
};
|
|
3053
|
-
// item needs to be replaced with a new item at the new record key
|
|
3054
|
-
queueOperations.push({
|
|
3055
|
-
type: QueueOperationType.Delete,
|
|
3056
|
-
id: queueActionId,
|
|
3057
|
-
});
|
|
3058
|
-
queueOperations.push({
|
|
3059
|
-
type: QueueOperationType.Add,
|
|
3060
|
-
action: updatedAction,
|
|
3061
|
-
});
|
|
3062
|
-
}
|
|
3063
|
-
else {
|
|
3064
|
-
const updatedAction = {
|
|
3065
|
-
...queueAction,
|
|
3066
|
-
data: {
|
|
3067
|
-
...queueActionRequest,
|
|
3068
|
-
basePath: basePath,
|
|
3069
|
-
body: parse$6(stringifiedBody),
|
|
3070
|
-
},
|
|
3071
|
-
};
|
|
3072
|
-
// item needs to be updated
|
|
3073
|
-
queueOperations.push({
|
|
3074
|
-
type: QueueOperationType.Update,
|
|
3075
|
-
id: queueActionId,
|
|
3076
|
-
action: updatedAction,
|
|
3077
|
-
});
|
|
3078
|
-
}
|
|
3079
|
-
}
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
// delete completed action
|
|
3084
|
-
queueOperations.push({
|
|
3085
|
-
type: QueueOperationType.Delete,
|
|
3086
|
-
id: action.id,
|
|
3087
|
-
});
|
|
3088
|
-
return queueOperations;
|
|
3089
|
-
}
|
|
3090
|
-
getRedirectMappings(action) {
|
|
3091
|
-
if (action.data.method !== 'post') {
|
|
3092
|
-
return undefined;
|
|
3093
|
-
}
|
|
3094
|
-
const body = action.response.body;
|
|
3095
|
-
const canonicalId = this.getIdFromResponseBody(body);
|
|
3096
|
-
const draftId = action.targetId;
|
|
3097
|
-
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
3098
|
-
this.ephemeralRedirects[draftId] = canonicalId;
|
|
3099
|
-
}
|
|
3100
|
-
return [
|
|
3101
|
-
{
|
|
3102
|
-
draftId,
|
|
3103
|
-
canonicalId,
|
|
3104
|
-
draftKey: this.buildTagForTargetId(draftId),
|
|
3105
|
-
canonicalKey: this.buildTagForTargetId(canonicalId),
|
|
3106
|
-
},
|
|
3107
|
-
];
|
|
3108
|
-
}
|
|
3109
|
-
async handleActionCompleted(action, queueOperations, allHandlers) {
|
|
3110
|
-
const { data: request, tag } = action;
|
|
3111
|
-
const { method } = request;
|
|
3112
|
-
if (method === 'delete') {
|
|
3113
|
-
return this.evictKey(tag);
|
|
3114
|
-
}
|
|
3115
|
-
const recordsToIngest = [];
|
|
3116
|
-
recordsToIngest.push({
|
|
3117
|
-
response: action.response.body,
|
|
3118
|
-
synchronousIngest: this.synchronousIngest.bind(this),
|
|
3119
|
-
buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
|
|
3120
|
-
});
|
|
3121
|
-
const recordsNeedingReplay = queueOperations.filter((x) => x.type === QueueOperationType.Update);
|
|
3122
|
-
for (const recordNeedingReplay of recordsNeedingReplay) {
|
|
3123
|
-
const { action } = recordNeedingReplay;
|
|
3124
|
-
if (isResourceRequestAction(action)) {
|
|
3125
|
-
// We can't assume the queue operation is for our handler, have to find the handler.
|
|
3126
|
-
const handler = allHandlers.find((h) => h.handlerId === action.handler);
|
|
3127
|
-
if (handler !== undefined) {
|
|
3128
|
-
const record = await handler.getDataForAction(action);
|
|
3129
|
-
if (record !== undefined) {
|
|
3130
|
-
recordsToIngest.push({
|
|
3131
|
-
response: record,
|
|
3132
|
-
synchronousIngest: handler.synchronousIngest.bind(handler),
|
|
3133
|
-
buildCacheKeysForResponse: handler.buildCacheKeysFromResponse.bind(handler),
|
|
3134
|
-
});
|
|
3135
|
-
}
|
|
3136
|
-
}
|
|
3137
|
-
}
|
|
3138
|
-
}
|
|
3139
|
-
await this.ingestResponses(recordsToIngest, action);
|
|
3140
|
-
}
|
|
3141
|
-
handleReplaceAction(targetAction, sourceAction) {
|
|
3142
|
-
//reject if the action to replace is a POST action
|
|
3143
|
-
const pendingAction = targetAction;
|
|
3144
|
-
if (pendingAction.data.method === 'post') {
|
|
3145
|
-
throw Error('Cannot replace a POST action');
|
|
3146
|
-
}
|
|
3147
|
-
if (this.isActionOfType(targetAction) &&
|
|
3148
|
-
this.isActionOfType(sourceAction)) {
|
|
3149
|
-
targetAction.status = DraftActionStatus.Pending;
|
|
3150
|
-
targetAction.data = sourceAction.data;
|
|
3151
|
-
return targetAction;
|
|
3152
|
-
}
|
|
3153
|
-
else {
|
|
3154
|
-
throw Error('Incompatible Action types to replace one another');
|
|
3155
|
-
}
|
|
3156
|
-
}
|
|
3157
|
-
mergeActions(targetAction, sourceAction) {
|
|
3158
|
-
const { id: targetId, data: targetData, metadata: targetMetadata, timestamp: targetTimestamp, } = targetAction;
|
|
3159
|
-
const { method: targetMethod, body: targetBody } = targetData;
|
|
3160
|
-
const { data: sourceData, metadata: sourceMetadata } = sourceAction;
|
|
3161
|
-
const { method: sourceMethod, body: sourceBody } = sourceData;
|
|
3162
|
-
if (targetMethod.toLowerCase() === 'delete' || sourceMethod.toLowerCase() === 'delete') {
|
|
3163
|
-
throw Error('Cannot merge DELETE actions.');
|
|
3164
|
-
}
|
|
3165
|
-
if (targetMethod.toLowerCase() === 'patch' && sourceMethod.toLowerCase() === 'post') {
|
|
3166
|
-
// overlaying a POST over a PATCH is not supported
|
|
3167
|
-
throw Error('Cannot merge a POST action over top of a PATCH action.');
|
|
3168
|
-
}
|
|
3169
|
-
// overlay top-level properties, maintain target's timestamp and id
|
|
3170
|
-
const merged = {
|
|
3171
|
-
...targetAction,
|
|
3172
|
-
...sourceAction,
|
|
3173
|
-
timestamp: targetTimestamp,
|
|
3174
|
-
id: targetId,
|
|
3175
|
-
};
|
|
3176
|
-
// overlay data
|
|
3177
|
-
// NOTE: we stick to the target's ResourceRequest properties (except body
|
|
3178
|
-
// which is merged) because we don't want to overwrite a POST with a PATCH
|
|
3179
|
-
// (all other cases should be fine or wouldn't have passed pre-requisites)
|
|
3180
|
-
merged.data = {
|
|
3181
|
-
...targetData,
|
|
3182
|
-
body: this.mergeRequestBody(targetBody, sourceBody),
|
|
3183
|
-
};
|
|
3184
|
-
// Updates Idempotency key if target has one
|
|
3185
|
-
if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
3186
|
-
merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
3187
|
-
}
|
|
3188
|
-
// overlay metadata
|
|
3189
|
-
merged.metadata = { ...targetMetadata, ...sourceMetadata };
|
|
3190
|
-
// put status back to pending to auto upload if queue is active and targed is at the head.
|
|
3191
|
-
merged.status = DraftActionStatus.Pending;
|
|
3192
|
-
return merged;
|
|
3193
|
-
}
|
|
3194
|
-
shouldDeleteActionByTagOnRemoval(action) {
|
|
3195
|
-
return action.data.method === 'post';
|
|
3196
|
-
}
|
|
3197
|
-
updateMetadata(_existingMetadata, incomingMetadata) {
|
|
3198
|
-
return incomingMetadata;
|
|
3199
|
-
}
|
|
3200
|
-
isActionOfType(action) {
|
|
3201
|
-
return action.handler === this.handlerId;
|
|
3202
|
-
}
|
|
3203
|
-
async reingestRecord(action) {
|
|
3204
|
-
const record = await this.getDataForAction(action);
|
|
3205
|
-
if (record !== undefined) {
|
|
3206
|
-
await this.ingestResponses([
|
|
3207
|
-
{
|
|
3208
|
-
response: record,
|
|
3209
|
-
synchronousIngest: this.synchronousIngest.bind(this),
|
|
3210
|
-
buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
|
|
3211
|
-
},
|
|
3212
|
-
], action);
|
|
3213
|
-
}
|
|
3214
|
-
else {
|
|
3215
|
-
await this.evictKey(action.tag);
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
// Given an action for this handler this method should return the draft IDs.
|
|
3219
|
-
// Most of the time it will simply be the targetId, but certain handlers might
|
|
3220
|
-
// have multiple draft-created IDs so they would override this to return them.
|
|
3221
|
-
getDraftIdsFromAction(action) {
|
|
3222
|
-
return [action.targetId];
|
|
3223
|
-
}
|
|
3224
|
-
hasIdempotencySupport() {
|
|
3225
|
-
return this.isIdempotencySupported && !this.isLdsIdempotencyWriteDisabled;
|
|
3226
|
-
}
|
|
3227
|
-
async ingestResponses(responses, action) {
|
|
3228
|
-
const luvio = this.getLuvio();
|
|
3229
|
-
await luvio.handleSuccessResponse(() => {
|
|
3230
|
-
if (action.status === DraftActionStatus.Completed) {
|
|
3231
|
-
const mappings = this.getRedirectMappings(action);
|
|
3232
|
-
if (mappings) {
|
|
3233
|
-
mappings.forEach((mapping) => {
|
|
3234
|
-
luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
|
|
3235
|
-
});
|
|
3236
|
-
}
|
|
3237
|
-
}
|
|
3238
|
-
for (const entry of responses) {
|
|
3239
|
-
const { response, synchronousIngest } = entry;
|
|
3240
|
-
synchronousIngest(response, action);
|
|
3241
|
-
}
|
|
3242
|
-
return luvio.storeBroadcast();
|
|
3243
|
-
},
|
|
3244
|
-
// getTypeCacheKeysRecord uses the response, not the full path factory
|
|
3245
|
-
// so 2nd parameter will be unused
|
|
3246
|
-
() => {
|
|
3247
|
-
const keySet = new StoreKeyMap();
|
|
3248
|
-
for (const entry of responses) {
|
|
3249
|
-
const { response, buildCacheKeysForResponse } = entry;
|
|
3250
|
-
const set = buildCacheKeysForResponse(response);
|
|
3251
|
-
for (const key of set.keys()) {
|
|
3252
|
-
const value = set.get(key);
|
|
3253
|
-
if (value !== undefined) {
|
|
3254
|
-
keySet.set(key, value);
|
|
3255
|
-
}
|
|
3256
|
-
}
|
|
3257
|
-
}
|
|
3258
|
-
return keySet;
|
|
3259
|
-
});
|
|
3260
|
-
}
|
|
3261
|
-
async evictKey(key) {
|
|
3262
|
-
const luvio = this.getLuvio();
|
|
3263
|
-
await luvio.handleSuccessResponse(() => {
|
|
3264
|
-
luvio.storeEvict(key);
|
|
3265
|
-
return luvio.storeBroadcast();
|
|
3266
|
-
}, () => {
|
|
3267
|
-
return new StoreKeyMap();
|
|
3268
|
-
});
|
|
3269
|
-
}
|
|
3270
|
-
}
|
|
3271
|
-
function actionsForTag(tag, queue) {
|
|
3272
|
-
return queue.filter((action) => action.tag === tag);
|
|
3273
|
-
}
|
|
3274
|
-
function deleteActionsForTag(tag, queue) {
|
|
3275
|
-
return queue.filter((action) => action.tag === tag && action.data.method === 'delete');
|
|
3276
|
-
}
|
|
3277
|
-
function isResourceRequestAction(action) {
|
|
3278
|
-
const dataAsAny = action.data;
|
|
3279
|
-
return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
|
|
3280
|
-
}
|
|
3281
|
-
|
|
3282
2809
|
/**
|
|
3283
2810
|
* Denotes what kind of operation a DraftQueueItem represents.
|
|
3284
2811
|
*/
|
|
@@ -3314,7 +2841,7 @@ var DraftQueueOperationType;
|
|
|
3314
2841
|
* @param action
|
|
3315
2842
|
*/
|
|
3316
2843
|
function getOperationTypeFrom(action) {
|
|
3317
|
-
if (isResourceRequestAction(action)) {
|
|
2844
|
+
if (isResourceRequestAction$1(action)) {
|
|
3318
2845
|
if (action.data !== undefined && action.data.method !== undefined) {
|
|
3319
2846
|
switch (action.data.method) {
|
|
3320
2847
|
case 'put':
|
|
@@ -3499,16 +3026,17 @@ class DraftManager {
|
|
|
3499
3026
|
return Promise.reject('cannot edit incompatible action type or uploading actions');
|
|
3500
3027
|
}
|
|
3501
3028
|
action.data.body.fields = { ...action.data.body.fields, ...fields };
|
|
3029
|
+
action.status = DraftActionStatus.Pending;
|
|
3502
3030
|
await this.draftQueue.updateDraftAction(action);
|
|
3503
3031
|
return this.buildDraftQueueItem(action);
|
|
3504
3032
|
}
|
|
3505
3033
|
isValidFieldMap(fields) {
|
|
3506
3034
|
const keys$1 = keys$7(fields);
|
|
3507
|
-
const validTypes = ['string', 'number', '
|
|
3035
|
+
const validTypes = ['string', 'number', 'boolean'];
|
|
3508
3036
|
for (let i = 0; i < keys$1.length; i++) {
|
|
3509
3037
|
const key = keys$1[i];
|
|
3510
3038
|
const value = fields[key];
|
|
3511
|
-
if (!validTypes.includes(typeof value)) {
|
|
3039
|
+
if (!validTypes.includes(typeof value) && value !== null) {
|
|
3512
3040
|
return false;
|
|
3513
3041
|
}
|
|
3514
3042
|
}
|
|
@@ -3536,6 +3064,7 @@ class DraftManager {
|
|
|
3536
3064
|
}
|
|
3537
3065
|
const data = action.data;
|
|
3538
3066
|
data.body.fields = { ...data.body.fields, ...fields };
|
|
3067
|
+
action.status = DraftActionStatus.Pending;
|
|
3539
3068
|
await this.draftQueue.updateDraftAction(action);
|
|
3540
3069
|
return this.buildDraftQueueItem(action);
|
|
3541
3070
|
}
|
|
@@ -3553,7 +3082,7 @@ class DraftManager {
|
|
|
3553
3082
|
if (isDraftError(action)) {
|
|
3554
3083
|
// We should always return an array, if the body is just a dictionary,
|
|
3555
3084
|
// stick it in an array
|
|
3556
|
-
const body = isArray$
|
|
3085
|
+
const body = isArray$5(action.error.body) ? action.error.body : [action.error.body];
|
|
3557
3086
|
const bodyString = stringify$6(body);
|
|
3558
3087
|
item.error = {
|
|
3559
3088
|
status: action.error.status || 0,
|
|
@@ -3652,6 +3181,10 @@ class DraftManager {
|
|
|
3652
3181
|
});
|
|
3653
3182
|
}
|
|
3654
3183
|
}
|
|
3184
|
+
function isResourceRequestAction$1(action) {
|
|
3185
|
+
const dataAsAny = action.data;
|
|
3186
|
+
return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
|
|
3187
|
+
}
|
|
3655
3188
|
|
|
3656
3189
|
function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
|
|
3657
3190
|
const draftMetadata = {};
|
|
@@ -3779,8 +3312,8 @@ function objectsDeepEqual(lhs, rhs) {
|
|
|
3779
3312
|
|
|
3780
3313
|
const { keys: keys$6, values: values$3, create: create$6, assign: assign$6, freeze: freeze$2, entries: entries$5 } = Object;
|
|
3781
3314
|
const { stringify: stringify$5, parse: parse$5 } = JSON;
|
|
3782
|
-
const { shift } = Array.prototype;
|
|
3783
|
-
const { isArray: isArray$
|
|
3315
|
+
const { shift: shift$1 } = Array.prototype;
|
|
3316
|
+
const { isArray: isArray$4, from: from$3 } = Array;
|
|
3784
3317
|
|
|
3785
3318
|
/**
|
|
3786
3319
|
* Retrieves a denormalized record from the store
|
|
@@ -4008,7 +3541,7 @@ function isRequestForGetRecords(request) {
|
|
|
4008
3541
|
*/
|
|
4009
3542
|
function extractRecordIdsFromResourceRequest(request) {
|
|
4010
3543
|
const ids = request.urlParams['recordIds'];
|
|
4011
|
-
if (isArray$
|
|
3544
|
+
if (isArray$4(ids) === false) {
|
|
4012
3545
|
return undefined;
|
|
4013
3546
|
}
|
|
4014
3547
|
return ids;
|
|
@@ -4179,6 +3712,499 @@ function makeEnvironmentUiApiRecordDraftAware(luvio, options, env) {
|
|
|
4179
3712
|
return create$6(adapterSpecificEnvironments, {});
|
|
4180
3713
|
}
|
|
4181
3714
|
|
|
3715
|
+
const { keys: keys$5, create: create$5, assign: assign$5, entries: entries$4 } = Object;
|
|
3716
|
+
const { stringify: stringify$4, parse: parse$4 } = JSON;
|
|
3717
|
+
const { push: push$2, join: join$1, slice: slice$1, shift } = Array.prototype;
|
|
3718
|
+
const { isArray: isArray$3, from: from$2 } = Array;
|
|
3719
|
+
|
|
3720
|
+
const HTTP_HEADER_RETRY_AFTER = 'Retry-After';
|
|
3721
|
+
const HTTP_HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
|
3722
|
+
const ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED = 'IDEMPOTENCY_FEATURE_NOT_ENABLED';
|
|
3723
|
+
const ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED = 'IDEMPOTENCY_NOT_SUPPORTED';
|
|
3724
|
+
const ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER = 'IDEMPOTENCY_KEY_USED_DIFFERENT_USER';
|
|
3725
|
+
const ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST = 'IDEMPOTENCY_CONCURRENT_REQUEST';
|
|
3726
|
+
const ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED = 'IDEMPOTENCY_KEY_ALREADY_USED';
|
|
3727
|
+
const ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR = 'IDEMPOTENCY_BACKEND_OPERATION_ERROR';
|
|
3728
|
+
/**
|
|
3729
|
+
* Get the retry after in milliseconds from the response headers, undefined if not specified.
|
|
3730
|
+
* The header could have two different format.
|
|
3731
|
+
* Retry-After: <http-date>, like Wed, 21 Oct 2015 07:28:00 GMT
|
|
3732
|
+
* Retry-After: <delay-seconds>, like 1.5s
|
|
3733
|
+
* @param headers http headers
|
|
3734
|
+
* @returns the time to delat in millisconds.
|
|
3735
|
+
*/
|
|
3736
|
+
function getRetryAfterInMs(headers) {
|
|
3737
|
+
const retryAfterHeader = headers && headers[HTTP_HEADER_RETRY_AFTER];
|
|
3738
|
+
if (retryAfterHeader === undefined) {
|
|
3739
|
+
return undefined;
|
|
3740
|
+
}
|
|
3741
|
+
const delayInSecond = parseFloat(retryAfterHeader);
|
|
3742
|
+
if (retryAfterHeader === delayInSecond.toString()) {
|
|
3743
|
+
return Math.round(delayInSecond * 1000);
|
|
3744
|
+
}
|
|
3745
|
+
const delayUntilDateTime = Date.parse(retryAfterHeader);
|
|
3746
|
+
if (isNaN(delayUntilDateTime)) {
|
|
3747
|
+
return undefined;
|
|
3748
|
+
}
|
|
3749
|
+
return delayUntilDateTime - Date.now();
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
const DEFAULT_FIELD_LAST_MODIFIED_DATE$1 = 'LastModifiedDate';
|
|
3753
|
+
const DEFAULT_FIELD_CREATED_DATE$1 = 'CreatedDate';
|
|
3754
|
+
class AbstractResourceRequestActionHandler {
|
|
3755
|
+
constructor(draftQueue, networkAdapter, getLuvio) {
|
|
3756
|
+
this.draftQueue = draftQueue;
|
|
3757
|
+
this.networkAdapter = networkAdapter;
|
|
3758
|
+
this.getLuvio = getLuvio;
|
|
3759
|
+
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
3760
|
+
// ids and canonical ids for the current session. Having a local copy of
|
|
3761
|
+
// these mappings is necessary to avoid a race condition between publishing
|
|
3762
|
+
// new mappings to the durable store and those mappings being loaded into
|
|
3763
|
+
// the luvio store redirect table, during which a new draft might be enqueued
|
|
3764
|
+
// which would not see a necessary mapping.
|
|
3765
|
+
this.ephemeralRedirects = {};
|
|
3766
|
+
// determined by Server setup.
|
|
3767
|
+
this.isIdempotencySupported = true;
|
|
3768
|
+
// idempotency write flag set by lds
|
|
3769
|
+
this.isLdsIdempotencyWriteDisabled = ldsIdempotencyWriteDisabled.isOpen({
|
|
3770
|
+
fallback: false,
|
|
3771
|
+
});
|
|
3772
|
+
this.isBackdatingEnabled = ldsBackdatingEnabled.isOpen({ fallback: false });
|
|
3773
|
+
}
|
|
3774
|
+
enqueue(data) {
|
|
3775
|
+
return this.draftQueue.enqueue(this.handlerId, data);
|
|
3776
|
+
}
|
|
3777
|
+
async handleAction(action, actionCompleted, actionErrored) {
|
|
3778
|
+
const { data: request } = action;
|
|
3779
|
+
// no context is stored in draft action
|
|
3780
|
+
try {
|
|
3781
|
+
const response = await this.networkAdapter(request, {});
|
|
3782
|
+
if (response.ok) {
|
|
3783
|
+
await actionCompleted({
|
|
3784
|
+
...action,
|
|
3785
|
+
response,
|
|
3786
|
+
status: DraftActionStatus.Completed,
|
|
3787
|
+
});
|
|
3788
|
+
return ProcessActionResult.ACTION_SUCCEEDED;
|
|
3789
|
+
}
|
|
3790
|
+
let shouldRetry = false;
|
|
3791
|
+
let retryDelayInMs = undefined;
|
|
3792
|
+
let actionDataChanged = false;
|
|
3793
|
+
let updatedAction = action;
|
|
3794
|
+
if (request && request.headers && request.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
3795
|
+
const status = response.status;
|
|
3796
|
+
switch (status) {
|
|
3797
|
+
case 408 /* IdempotentWriteSpecificHttpStatusCode.RequestTimeout */:
|
|
3798
|
+
case 503 /* IdempotentWriteSpecificHttpStatusCode.ServiceUnavailable */:
|
|
3799
|
+
retryDelayInMs = getRetryAfterInMs(response.headers);
|
|
3800
|
+
shouldRetry = true;
|
|
3801
|
+
break;
|
|
3802
|
+
case HttpStatusCode.ServerError: {
|
|
3803
|
+
shouldRetry = true;
|
|
3804
|
+
if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_BACKEND_OPERATION_ERROR)) {
|
|
3805
|
+
this.isIdempotencySupported = false;
|
|
3806
|
+
retryDelayInMs = 0;
|
|
3807
|
+
actionDataChanged = true;
|
|
3808
|
+
}
|
|
3809
|
+
break;
|
|
3810
|
+
}
|
|
3811
|
+
case 409 /* IdempotentWriteSpecificHttpStatusCode.Conflict */: {
|
|
3812
|
+
if (this.isUiApiErrors(response.body)) {
|
|
3813
|
+
const errorCode = response.body[0].errorCode;
|
|
3814
|
+
if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_USED_DIFFERENT_USER)) {
|
|
3815
|
+
retryDelayInMs = 0;
|
|
3816
|
+
actionDataChanged = true;
|
|
3817
|
+
}
|
|
3818
|
+
else if (errorCode === ERROR_CODE_IDEMPOTENCY_CONCURRENT_REQUEST) {
|
|
3819
|
+
retryDelayInMs = getRetryAfterInMs(response.headers);
|
|
3820
|
+
}
|
|
3821
|
+
shouldRetry = true;
|
|
3822
|
+
}
|
|
3823
|
+
break;
|
|
3824
|
+
}
|
|
3825
|
+
case HttpStatusCode.BadRequest: {
|
|
3826
|
+
if (this.handleIdempotencyServerError(response.body, updatedAction, false, ERROR_CODE_IDEMPOTENCY_FEATURE_NOT_ENABLED, ERROR_CODE_IDEMPOTENCY_NOT_SUPPORTED)) {
|
|
3827
|
+
retryDelayInMs = 0;
|
|
3828
|
+
actionDataChanged = true;
|
|
3829
|
+
shouldRetry = true;
|
|
3830
|
+
}
|
|
3831
|
+
break;
|
|
3832
|
+
}
|
|
3833
|
+
case 422 /* IdempotentWriteSpecificHttpStatusCode.UnProcessableEntity */: {
|
|
3834
|
+
if (this.handleIdempotencyServerError(response.body, updatedAction, true, ERROR_CODE_IDEMPOTENCY_KEY_ALREADY_USED)) {
|
|
3835
|
+
retryDelayInMs = 0;
|
|
3836
|
+
actionDataChanged = true;
|
|
3837
|
+
shouldRetry = true;
|
|
3838
|
+
}
|
|
3839
|
+
break;
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
if (this.isBackdatingEnabled &&
|
|
3844
|
+
response.status === HttpStatusCode.BadRequest &&
|
|
3845
|
+
this.isBackdatingError(response.body, action)) {
|
|
3846
|
+
updatedAction.timestamp = Date.now();
|
|
3847
|
+
updatedAction.data.body.fields = {
|
|
3848
|
+
...updatedAction.data.body.fields,
|
|
3849
|
+
LastModifiedDate: new Date(updatedAction.timestamp).toISOString(),
|
|
3850
|
+
};
|
|
3851
|
+
if (this.hasIdempotencySupport() &&
|
|
3852
|
+
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
3853
|
+
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
3854
|
+
}
|
|
3855
|
+
shouldRetry = true;
|
|
3856
|
+
actionDataChanged = true;
|
|
3857
|
+
}
|
|
3858
|
+
await actionErrored(shouldRetry
|
|
3859
|
+
? updatedAction
|
|
3860
|
+
: {
|
|
3861
|
+
...updatedAction,
|
|
3862
|
+
error: response,
|
|
3863
|
+
status: DraftActionStatus.Error,
|
|
3864
|
+
}, shouldRetry, retryDelayInMs, actionDataChanged);
|
|
3865
|
+
return ProcessActionResult.ACTION_ERRORED;
|
|
3866
|
+
}
|
|
3867
|
+
catch (e) {
|
|
3868
|
+
await actionErrored(action, true);
|
|
3869
|
+
return ProcessActionResult.NETWORK_ERROR;
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
// true if response is an idempotency server error. updates or deletes idempotency key if the reponse is idempotency related error. Idempotency related error is in format of UiApiError array.
|
|
3873
|
+
handleIdempotencyServerError(responseBody, action, updateIdempotencyKey, ...targetErrorCodes) {
|
|
3874
|
+
if (this.isUiApiErrors(responseBody)) {
|
|
3875
|
+
const errorCode = responseBody[0].errorCode;
|
|
3876
|
+
if (targetErrorCodes.includes(errorCode)) {
|
|
3877
|
+
action.data.headers = action.data.headers || {};
|
|
3878
|
+
if (updateIdempotencyKey) {
|
|
3879
|
+
action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
3880
|
+
}
|
|
3881
|
+
else {
|
|
3882
|
+
delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
|
|
3883
|
+
}
|
|
3884
|
+
return true;
|
|
3885
|
+
}
|
|
3886
|
+
}
|
|
3887
|
+
return false;
|
|
3888
|
+
}
|
|
3889
|
+
// checks if the body is an array of UiApiError. Sometimes the body has `enhancedErrorType` field as an error indicator(one example is the field validation failure). In such case Action being processed updates to an Error Action.
|
|
3890
|
+
isUiApiErrors(body) {
|
|
3891
|
+
return body !== undefined && isArray$3(body) && body.length > 0 && body[0].errorCode;
|
|
3892
|
+
}
|
|
3893
|
+
isBackdatingError(body, action) {
|
|
3894
|
+
if (body.enhancedErrorType &&
|
|
3895
|
+
body.enhancedErrorType === 'RecordError' &&
|
|
3896
|
+
body.output &&
|
|
3897
|
+
body.output.errors &&
|
|
3898
|
+
isArray$3(body.output.errors) &&
|
|
3899
|
+
body.output.errors.length > 0 &&
|
|
3900
|
+
action.data.body &&
|
|
3901
|
+
action.data.body.fields &&
|
|
3902
|
+
action.data.body.fields[DEFAULT_FIELD_LAST_MODIFIED_DATE$1]) {
|
|
3903
|
+
return body.output.errors.some((error) => error.errorCode === 'CollisionDetectedException');
|
|
3904
|
+
}
|
|
3905
|
+
return false;
|
|
3906
|
+
}
|
|
3907
|
+
async buildPendingAction(request, queue) {
|
|
3908
|
+
const targetId = await this.getIdFromRequest(request);
|
|
3909
|
+
const tag = this.buildTagForTargetId(targetId);
|
|
3910
|
+
const handlerActions = queue.filter((x) => x.handler === this.handlerId);
|
|
3911
|
+
if (request.method === 'post' && actionsForTag(tag, handlerActions).length > 0) {
|
|
3912
|
+
return Promise.reject(new Error('Cannot enqueue a POST draft action with an existing tag'));
|
|
3913
|
+
}
|
|
3914
|
+
if (deleteActionsForTag(tag, handlerActions).length > 0) {
|
|
3915
|
+
return Promise.reject(new Error('Cannot enqueue a draft action for a deleted record'));
|
|
3916
|
+
}
|
|
3917
|
+
return {
|
|
3918
|
+
handler: this.handlerId,
|
|
3919
|
+
targetId,
|
|
3920
|
+
tag,
|
|
3921
|
+
data: request,
|
|
3922
|
+
status: DraftActionStatus.Pending,
|
|
3923
|
+
id: generateUniqueDraftActionId(queue.map((x) => x.id)),
|
|
3924
|
+
timestamp: Date.now(),
|
|
3925
|
+
metadata: {},
|
|
3926
|
+
version: '242.0.0',
|
|
3927
|
+
};
|
|
3928
|
+
}
|
|
3929
|
+
async handleActionEnqueued(_action) { }
|
|
3930
|
+
handleActionRemoved(action) {
|
|
3931
|
+
return this.reingestRecord(action);
|
|
3932
|
+
}
|
|
3933
|
+
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
3934
|
+
const queueOperations = [];
|
|
3935
|
+
const redirects = this.getRedirectMappings(action);
|
|
3936
|
+
if (redirects !== undefined) {
|
|
3937
|
+
const { length } = queue;
|
|
3938
|
+
for (let i = 0; i < length; i++) {
|
|
3939
|
+
const queueAction = queue[i];
|
|
3940
|
+
// if this queueAction is the action that is completing we can move on,
|
|
3941
|
+
// it is about to be deleted and won't have the draft ID in it
|
|
3942
|
+
if (queueAction.id === action.id) {
|
|
3943
|
+
continue;
|
|
3944
|
+
}
|
|
3945
|
+
if (isResourceRequestAction(queueAction)) {
|
|
3946
|
+
let queueOperationMutated = false;
|
|
3947
|
+
let updatedActionTag = undefined;
|
|
3948
|
+
let updatedActionTargetId = undefined;
|
|
3949
|
+
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
3950
|
+
let { basePath, body } = queueActionRequest;
|
|
3951
|
+
let stringifiedBody = stringify$4(body);
|
|
3952
|
+
// for each redirected ID/key we loop over the operation to see if it needs
|
|
3953
|
+
// to be updated
|
|
3954
|
+
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
3955
|
+
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
3956
|
+
basePath = basePath.replace(draftId, canonicalId);
|
|
3957
|
+
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
3958
|
+
queueOperationMutated = true;
|
|
3959
|
+
}
|
|
3960
|
+
// if the action is performed on a previous draft id, we need to replace the action
|
|
3961
|
+
// with a new one at the updated canonical key
|
|
3962
|
+
if (queueActionTag === draftKey) {
|
|
3963
|
+
updatedActionTag = canonicalKey;
|
|
3964
|
+
updatedActionTargetId = canonicalId;
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
if (queueOperationMutated) {
|
|
3968
|
+
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
3969
|
+
const updatedAction = {
|
|
3970
|
+
...queueAction,
|
|
3971
|
+
tag: updatedActionTag,
|
|
3972
|
+
targetId: updatedActionTargetId,
|
|
3973
|
+
data: {
|
|
3974
|
+
...queueActionRequest,
|
|
3975
|
+
basePath: basePath,
|
|
3976
|
+
body: parse$4(stringifiedBody),
|
|
3977
|
+
},
|
|
3978
|
+
};
|
|
3979
|
+
// item needs to be replaced with a new item at the new record key
|
|
3980
|
+
queueOperations.push({
|
|
3981
|
+
type: QueueOperationType.Delete,
|
|
3982
|
+
id: queueActionId,
|
|
3983
|
+
});
|
|
3984
|
+
queueOperations.push({
|
|
3985
|
+
type: QueueOperationType.Add,
|
|
3986
|
+
action: updatedAction,
|
|
3987
|
+
});
|
|
3988
|
+
}
|
|
3989
|
+
else {
|
|
3990
|
+
const updatedAction = {
|
|
3991
|
+
...queueAction,
|
|
3992
|
+
data: {
|
|
3993
|
+
...queueActionRequest,
|
|
3994
|
+
basePath: basePath,
|
|
3995
|
+
body: parse$4(stringifiedBody),
|
|
3996
|
+
},
|
|
3997
|
+
};
|
|
3998
|
+
// item needs to be updated
|
|
3999
|
+
queueOperations.push({
|
|
4000
|
+
type: QueueOperationType.Update,
|
|
4001
|
+
id: queueActionId,
|
|
4002
|
+
action: updatedAction,
|
|
4003
|
+
});
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
// delete completed action
|
|
4010
|
+
queueOperations.push({
|
|
4011
|
+
type: QueueOperationType.Delete,
|
|
4012
|
+
id: action.id,
|
|
4013
|
+
});
|
|
4014
|
+
return queueOperations;
|
|
4015
|
+
}
|
|
4016
|
+
getRedirectMappings(action) {
|
|
4017
|
+
if (action.data.method !== 'post') {
|
|
4018
|
+
return undefined;
|
|
4019
|
+
}
|
|
4020
|
+
const body = action.response.body;
|
|
4021
|
+
const canonicalId = this.getIdFromResponseBody(body);
|
|
4022
|
+
const draftId = action.targetId;
|
|
4023
|
+
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
4024
|
+
this.ephemeralRedirects[draftId] = canonicalId;
|
|
4025
|
+
}
|
|
4026
|
+
return [
|
|
4027
|
+
{
|
|
4028
|
+
draftId,
|
|
4029
|
+
canonicalId,
|
|
4030
|
+
draftKey: this.buildTagForTargetId(draftId),
|
|
4031
|
+
canonicalKey: this.buildTagForTargetId(canonicalId),
|
|
4032
|
+
},
|
|
4033
|
+
];
|
|
4034
|
+
}
|
|
4035
|
+
async handleActionCompleted(action, queueOperations, allHandlers) {
|
|
4036
|
+
const { data: request, tag } = action;
|
|
4037
|
+
const { method } = request;
|
|
4038
|
+
if (method === 'delete') {
|
|
4039
|
+
return this.evictKey(tag);
|
|
4040
|
+
}
|
|
4041
|
+
const recordsToIngest = [];
|
|
4042
|
+
recordsToIngest.push({
|
|
4043
|
+
response: action.response.body,
|
|
4044
|
+
synchronousIngest: this.synchronousIngest.bind(this),
|
|
4045
|
+
buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
|
|
4046
|
+
});
|
|
4047
|
+
const recordsNeedingReplay = queueOperations.filter((x) => x.type === QueueOperationType.Update);
|
|
4048
|
+
for (const recordNeedingReplay of recordsNeedingReplay) {
|
|
4049
|
+
const { action } = recordNeedingReplay;
|
|
4050
|
+
if (isResourceRequestAction(action)) {
|
|
4051
|
+
// We can't assume the queue operation is for our handler, have to find the handler.
|
|
4052
|
+
const handler = allHandlers.find((h) => h.handlerId === action.handler);
|
|
4053
|
+
if (handler !== undefined) {
|
|
4054
|
+
const record = await handler.getDataForAction(action);
|
|
4055
|
+
if (record !== undefined) {
|
|
4056
|
+
recordsToIngest.push({
|
|
4057
|
+
response: record,
|
|
4058
|
+
synchronousIngest: handler.synchronousIngest.bind(handler),
|
|
4059
|
+
buildCacheKeysForResponse: handler.buildCacheKeysFromResponse.bind(handler),
|
|
4060
|
+
});
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
await this.ingestResponses(recordsToIngest, action);
|
|
4066
|
+
}
|
|
4067
|
+
handleReplaceAction(targetAction, sourceAction) {
|
|
4068
|
+
//reject if the action to replace is a POST action
|
|
4069
|
+
const pendingAction = targetAction;
|
|
4070
|
+
if (pendingAction.data.method === 'post') {
|
|
4071
|
+
throw Error('Cannot replace a POST action');
|
|
4072
|
+
}
|
|
4073
|
+
if (this.isActionOfType(targetAction) &&
|
|
4074
|
+
this.isActionOfType(sourceAction)) {
|
|
4075
|
+
targetAction.status = DraftActionStatus.Pending;
|
|
4076
|
+
targetAction.data = sourceAction.data;
|
|
4077
|
+
return targetAction;
|
|
4078
|
+
}
|
|
4079
|
+
else {
|
|
4080
|
+
throw Error('Incompatible Action types to replace one another');
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
mergeActions(targetAction, sourceAction) {
|
|
4084
|
+
const { id: targetId, data: targetData, metadata: targetMetadata, timestamp: targetTimestamp, } = targetAction;
|
|
4085
|
+
const { method: targetMethod, body: targetBody } = targetData;
|
|
4086
|
+
const { data: sourceData, metadata: sourceMetadata } = sourceAction;
|
|
4087
|
+
const { method: sourceMethod, body: sourceBody } = sourceData;
|
|
4088
|
+
if (targetMethod.toLowerCase() === 'delete' || sourceMethod.toLowerCase() === 'delete') {
|
|
4089
|
+
throw Error('Cannot merge DELETE actions.');
|
|
4090
|
+
}
|
|
4091
|
+
if (targetMethod.toLowerCase() === 'patch' && sourceMethod.toLowerCase() === 'post') {
|
|
4092
|
+
// overlaying a POST over a PATCH is not supported
|
|
4093
|
+
throw Error('Cannot merge a POST action over top of a PATCH action.');
|
|
4094
|
+
}
|
|
4095
|
+
// overlay top-level properties, maintain target's timestamp and id
|
|
4096
|
+
const merged = {
|
|
4097
|
+
...targetAction,
|
|
4098
|
+
...sourceAction,
|
|
4099
|
+
timestamp: targetTimestamp,
|
|
4100
|
+
id: targetId,
|
|
4101
|
+
};
|
|
4102
|
+
// overlay data
|
|
4103
|
+
// NOTE: we stick to the target's ResourceRequest properties (except body
|
|
4104
|
+
// which is merged) because we don't want to overwrite a POST with a PATCH
|
|
4105
|
+
// (all other cases should be fine or wouldn't have passed pre-requisites)
|
|
4106
|
+
merged.data = {
|
|
4107
|
+
...targetData,
|
|
4108
|
+
body: this.mergeRequestBody(targetBody, sourceBody),
|
|
4109
|
+
};
|
|
4110
|
+
// Updates Idempotency key if target has one
|
|
4111
|
+
if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
4112
|
+
merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
4113
|
+
}
|
|
4114
|
+
// overlay metadata
|
|
4115
|
+
merged.metadata = { ...targetMetadata, ...sourceMetadata };
|
|
4116
|
+
// put status back to pending to auto upload if queue is active and targed is at the head.
|
|
4117
|
+
merged.status = DraftActionStatus.Pending;
|
|
4118
|
+
return merged;
|
|
4119
|
+
}
|
|
4120
|
+
shouldDeleteActionByTagOnRemoval(action) {
|
|
4121
|
+
return action.data.method === 'post';
|
|
4122
|
+
}
|
|
4123
|
+
updateMetadata(_existingMetadata, incomingMetadata) {
|
|
4124
|
+
return incomingMetadata;
|
|
4125
|
+
}
|
|
4126
|
+
isActionOfType(action) {
|
|
4127
|
+
return action.handler === this.handlerId;
|
|
4128
|
+
}
|
|
4129
|
+
async reingestRecord(action) {
|
|
4130
|
+
const record = await this.getDataForAction(action);
|
|
4131
|
+
if (record !== undefined) {
|
|
4132
|
+
await this.ingestResponses([
|
|
4133
|
+
{
|
|
4134
|
+
response: record,
|
|
4135
|
+
synchronousIngest: this.synchronousIngest.bind(this),
|
|
4136
|
+
buildCacheKeysForResponse: this.buildCacheKeysFromResponse.bind(this),
|
|
4137
|
+
},
|
|
4138
|
+
], action);
|
|
4139
|
+
}
|
|
4140
|
+
else {
|
|
4141
|
+
await this.evictKey(action.tag);
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
// Given an action for this handler this method should return the draft IDs.
|
|
4145
|
+
// Most of the time it will simply be the targetId, but certain handlers might
|
|
4146
|
+
// have multiple draft-created IDs so they would override this to return them.
|
|
4147
|
+
getDraftIdsFromAction(action) {
|
|
4148
|
+
return [action.targetId];
|
|
4149
|
+
}
|
|
4150
|
+
hasIdempotencySupport() {
|
|
4151
|
+
return this.isIdempotencySupported && !this.isLdsIdempotencyWriteDisabled;
|
|
4152
|
+
}
|
|
4153
|
+
async ingestResponses(responses, action) {
|
|
4154
|
+
const luvio = this.getLuvio();
|
|
4155
|
+
await luvio.handleSuccessResponse(() => {
|
|
4156
|
+
if (action.status === DraftActionStatus.Completed) {
|
|
4157
|
+
const mappings = this.getRedirectMappings(action);
|
|
4158
|
+
if (mappings) {
|
|
4159
|
+
mappings.forEach((mapping) => {
|
|
4160
|
+
luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
|
|
4161
|
+
});
|
|
4162
|
+
}
|
|
4163
|
+
}
|
|
4164
|
+
for (const entry of responses) {
|
|
4165
|
+
const { response, synchronousIngest } = entry;
|
|
4166
|
+
synchronousIngest(response, action);
|
|
4167
|
+
}
|
|
4168
|
+
return luvio.storeBroadcast();
|
|
4169
|
+
},
|
|
4170
|
+
// getTypeCacheKeysRecord uses the response, not the full path factory
|
|
4171
|
+
// so 2nd parameter will be unused
|
|
4172
|
+
() => {
|
|
4173
|
+
const keySet = new StoreKeyMap();
|
|
4174
|
+
for (const entry of responses) {
|
|
4175
|
+
const { response, buildCacheKeysForResponse } = entry;
|
|
4176
|
+
const set = buildCacheKeysForResponse(response);
|
|
4177
|
+
for (const key of set.keys()) {
|
|
4178
|
+
const value = set.get(key);
|
|
4179
|
+
if (value !== undefined) {
|
|
4180
|
+
keySet.set(key, value);
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4184
|
+
return keySet;
|
|
4185
|
+
});
|
|
4186
|
+
}
|
|
4187
|
+
async evictKey(key) {
|
|
4188
|
+
const luvio = this.getLuvio();
|
|
4189
|
+
await luvio.handleSuccessResponse(() => {
|
|
4190
|
+
luvio.storeEvict(key);
|
|
4191
|
+
return luvio.storeBroadcast();
|
|
4192
|
+
}, () => {
|
|
4193
|
+
return new StoreKeyMap();
|
|
4194
|
+
});
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
function actionsForTag(tag, queue) {
|
|
4198
|
+
return queue.filter((action) => action.tag === tag);
|
|
4199
|
+
}
|
|
4200
|
+
function deleteActionsForTag(tag, queue) {
|
|
4201
|
+
return queue.filter((action) => action.tag === tag && action.data.method === 'delete');
|
|
4202
|
+
}
|
|
4203
|
+
function isResourceRequestAction(action) {
|
|
4204
|
+
const dataAsAny = action.data;
|
|
4205
|
+
return (dataAsAny !== undefined && dataAsAny.method !== undefined && dataAsAny.body !== undefined);
|
|
4206
|
+
}
|
|
4207
|
+
|
|
4182
4208
|
function clone(obj) {
|
|
4183
4209
|
return parse$5(stringify$5(obj));
|
|
4184
4210
|
}
|
|
@@ -4295,7 +4321,7 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
|
|
|
4295
4321
|
return record;
|
|
4296
4322
|
}
|
|
4297
4323
|
// remove the next item from the front of the queue
|
|
4298
|
-
const draftOperation = shift.call(recordOperations);
|
|
4324
|
+
const draftOperation = shift$1.call(recordOperations);
|
|
4299
4325
|
if (draftOperation === undefined) {
|
|
4300
4326
|
return record;
|
|
4301
4327
|
}
|
|
@@ -4314,6 +4340,7 @@ function recursivelyApplyDraftsToRecord(record, draftMetadata, recordOperations)
|
|
|
4314
4340
|
edited: false,
|
|
4315
4341
|
deleted: false,
|
|
4316
4342
|
serverValues: {},
|
|
4343
|
+
serverRootValues: undefined,
|
|
4317
4344
|
draftActionIds: [draftOperation.draftActionId],
|
|
4318
4345
|
latestDraftActionId: draftOperation.draftActionId,
|
|
4319
4346
|
};
|
|
@@ -4581,6 +4608,7 @@ function buildSyntheticRecordRepresentation(luvio, createOperation, userId, obje
|
|
|
4581
4608
|
edited: false,
|
|
4582
4609
|
deleted: false,
|
|
4583
4610
|
serverValues: {},
|
|
4611
|
+
serverRootValues: undefined,
|
|
4584
4612
|
draftActionIds: [draftActionId],
|
|
4585
4613
|
latestDraftActionId: draftActionId,
|
|
4586
4614
|
},
|
|
@@ -5244,12 +5272,12 @@ function buildAdapterValidationConfig(displayName, paramsMeta) {
|
|
|
5244
5272
|
}
|
|
5245
5273
|
const keyPrefix = 'UiApi';
|
|
5246
5274
|
|
|
5247
|
-
const { assign: assign$
|
|
5275
|
+
const { assign: assign$4, create: create$4, freeze: freeze$1, isFrozen, keys: keys$4 } = Object;
|
|
5248
5276
|
const { hasOwnProperty } = Object.prototype;
|
|
5249
5277
|
const { split, endsWith } = String.prototype;
|
|
5250
5278
|
const { isArray: isArray$2 } = Array;
|
|
5251
|
-
const { concat, filter, includes, push: push$
|
|
5252
|
-
const { parse: parse$
|
|
5279
|
+
const { concat, filter, includes, push: push$1, reduce } = Array.prototype;
|
|
5280
|
+
const { parse: parse$3, stringify: stringify$3 } = JSON;
|
|
5253
5281
|
|
|
5254
5282
|
function isString(value) {
|
|
5255
5283
|
return typeof value === 'string';
|
|
@@ -5273,7 +5301,7 @@ function dedupe(value) {
|
|
|
5273
5301
|
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
5274
5302
|
result[value[i]] = true;
|
|
5275
5303
|
}
|
|
5276
|
-
return keys$
|
|
5304
|
+
return keys$4(result);
|
|
5277
5305
|
}
|
|
5278
5306
|
/**
|
|
5279
5307
|
* @param source The array of string to filter
|
|
@@ -5417,7 +5445,7 @@ function getFieldApiNamesArray(value, options = { onlyQualifiedFieldNames: false
|
|
|
5417
5445
|
}
|
|
5418
5446
|
return undefined;
|
|
5419
5447
|
}
|
|
5420
|
-
push$
|
|
5448
|
+
push$1.call(array, apiName);
|
|
5421
5449
|
}
|
|
5422
5450
|
if (array.length === 0) {
|
|
5423
5451
|
return undefined;
|
|
@@ -6872,14 +6900,14 @@ const getTypeCacheKeys$1u = (rootKeySet, luvio, input, _fullPathFactory) => {
|
|
|
6872
6900
|
mergeable: true,
|
|
6873
6901
|
});
|
|
6874
6902
|
const input_childRelationships = input.childRelationships;
|
|
6875
|
-
const input_childRelationships_keys = keys$
|
|
6903
|
+
const input_childRelationships_keys = keys$4(input_childRelationships);
|
|
6876
6904
|
const input_childRelationships_length = input_childRelationships_keys.length;
|
|
6877
6905
|
for (let i = 0; i < input_childRelationships_length; i++) {
|
|
6878
6906
|
const key = input_childRelationships_keys[i];
|
|
6879
6907
|
getTypeCacheKeys$1t(rootKeySet, luvio, input_childRelationships[key], () => rootKey + '__childRelationships' + '__' + key);
|
|
6880
6908
|
}
|
|
6881
6909
|
const input_fields = input.fields;
|
|
6882
|
-
const field_values = keys$
|
|
6910
|
+
const field_values = keys$4(input_fields);
|
|
6883
6911
|
const input_fields_length = field_values.length;
|
|
6884
6912
|
for (let i = 0; i < input_fields_length; i++) {
|
|
6885
6913
|
const field_value = input_fields[field_values[i]];
|
|
@@ -7335,7 +7363,7 @@ function convertRecordFieldsArrayToTrie(fields, optionalFields = []) {
|
|
|
7335
7363
|
function createPathSelection(propertyName, fieldDefinition) {
|
|
7336
7364
|
const fieldsSelection = [];
|
|
7337
7365
|
const { children } = fieldDefinition;
|
|
7338
|
-
const childrenKeys = keys$
|
|
7366
|
+
const childrenKeys = keys$4(children);
|
|
7339
7367
|
for (let i = 0, len = childrenKeys.length; i < len; i += 1) {
|
|
7340
7368
|
const childKey = childrenKeys[i];
|
|
7341
7369
|
const childFieldDefinition = children[childKey];
|
|
@@ -7373,7 +7401,7 @@ function createPathSelection(propertyName, fieldDefinition) {
|
|
|
7373
7401
|
],
|
|
7374
7402
|
};
|
|
7375
7403
|
}
|
|
7376
|
-
push$
|
|
7404
|
+
push$1.call(fieldsSelection, fieldSelection);
|
|
7377
7405
|
}
|
|
7378
7406
|
return {
|
|
7379
7407
|
kind: 'Object',
|
|
@@ -7386,7 +7414,7 @@ function createPathSelection(propertyName, fieldDefinition) {
|
|
|
7386
7414
|
*/
|
|
7387
7415
|
function createPathSelectionFromValue(fields) {
|
|
7388
7416
|
const fieldsSelections = [];
|
|
7389
|
-
const fieldNames = keys$
|
|
7417
|
+
const fieldNames = keys$4(fields);
|
|
7390
7418
|
for (let i = 0, len = fieldNames.length; i < len; i++) {
|
|
7391
7419
|
const fieldName = fieldNames[i];
|
|
7392
7420
|
const { value: fieldValue } = fields[fieldName];
|
|
@@ -7421,7 +7449,7 @@ function createPathSelectionFromValue(fields) {
|
|
|
7421
7449
|
selections: [DISPLAY_VALUE_SELECTION, SCALAR_VALUE_SELECTION],
|
|
7422
7450
|
};
|
|
7423
7451
|
}
|
|
7424
|
-
push$
|
|
7452
|
+
push$1.call(fieldsSelections, fieldSelection);
|
|
7425
7453
|
}
|
|
7426
7454
|
return {
|
|
7427
7455
|
kind: 'Object',
|
|
@@ -7431,7 +7459,7 @@ function createPathSelectionFromValue(fields) {
|
|
|
7431
7459
|
}
|
|
7432
7460
|
function extractRecordFieldsRecursively(record) {
|
|
7433
7461
|
const fields = [];
|
|
7434
|
-
const fieldNames = keys$
|
|
7462
|
+
const fieldNames = keys$4(record.fields);
|
|
7435
7463
|
for (let i = 0, len = fieldNames.length; i < len; i++) {
|
|
7436
7464
|
const fieldName = fieldNames[i];
|
|
7437
7465
|
const { value: fieldValue } = record.fields[fieldName];
|
|
@@ -7440,10 +7468,10 @@ function extractRecordFieldsRecursively(record) {
|
|
|
7440
7468
|
for (let j = 0, len = spanningRecordFields.length; j < len; j++) {
|
|
7441
7469
|
spanningRecordFields[j] = `${fieldName}.${spanningRecordFields[j]}`;
|
|
7442
7470
|
}
|
|
7443
|
-
push$
|
|
7471
|
+
push$1.apply(fields, spanningRecordFields);
|
|
7444
7472
|
}
|
|
7445
7473
|
else {
|
|
7446
|
-
push$
|
|
7474
|
+
push$1.call(fields, fieldName);
|
|
7447
7475
|
}
|
|
7448
7476
|
}
|
|
7449
7477
|
return fields;
|
|
@@ -9390,7 +9418,7 @@ function mergePendingFields(newRecord, oldRecord) {
|
|
|
9390
9418
|
// RecordRepresentationNormalized['fields'] to include `pending:true` property
|
|
9391
9419
|
const mergedFields = { ...newRecord.fields };
|
|
9392
9420
|
const merged = { ...newRecord, fields: mergedFields };
|
|
9393
|
-
const existingFields = keys$
|
|
9421
|
+
const existingFields = keys$4(oldRecord.fields);
|
|
9394
9422
|
for (let i = 0, len = existingFields.length; i < len; i += 1) {
|
|
9395
9423
|
const spanningFieldName = existingFields[i];
|
|
9396
9424
|
if (newRecord.fields[spanningFieldName] === undefined) {
|
|
@@ -9513,7 +9541,7 @@ function merge$1(existing, incoming, luvio, _path, recordConflictMap) {
|
|
|
9513
9541
|
if (isGraphNode(node)) {
|
|
9514
9542
|
const dependencies = node.retrieve();
|
|
9515
9543
|
if (dependencies !== null) {
|
|
9516
|
-
const depKeys = keys$
|
|
9544
|
+
const depKeys = keys$4(dependencies);
|
|
9517
9545
|
for (let i = 0, len = depKeys.length; i < len; i++) {
|
|
9518
9546
|
luvio.storeEvict(depKeys[i]);
|
|
9519
9547
|
}
|
|
@@ -9671,14 +9699,14 @@ fieldNode) {
|
|
|
9671
9699
|
let fields = [];
|
|
9672
9700
|
const fieldSubtries = [];
|
|
9673
9701
|
if (fieldsTrie) {
|
|
9674
|
-
push$
|
|
9702
|
+
push$1.call(fieldSubtries, fieldsTrie);
|
|
9675
9703
|
}
|
|
9676
9704
|
if (optionalFieldsTrie) {
|
|
9677
|
-
push$
|
|
9705
|
+
push$1.call(fieldSubtries, optionalFieldsTrie);
|
|
9678
9706
|
}
|
|
9679
9707
|
for (let i = 0; i < fieldSubtries.length; i++) {
|
|
9680
9708
|
const subtrie = fieldSubtries[i];
|
|
9681
|
-
const fieldNames = keys$
|
|
9709
|
+
const fieldNames = keys$4(subtrie.children);
|
|
9682
9710
|
for (let i = 0; i < fieldNames.length; i++) {
|
|
9683
9711
|
const fieldName = fieldNames[i];
|
|
9684
9712
|
const childTrie = subtrie.children[fieldName];
|
|
@@ -9802,13 +9830,13 @@ function isExternalLookupFieldKey(spanningNode) {
|
|
|
9802
9830
|
return endsWith.call(spanningNode.scalar('apiName'), CUSTOM_EXTERNAL_OBJECT_FIELD_SUFFIX);
|
|
9803
9831
|
}
|
|
9804
9832
|
function convertTrieToFields(root) {
|
|
9805
|
-
if (keys$
|
|
9833
|
+
if (keys$4(root.children).length === 0) {
|
|
9806
9834
|
return [];
|
|
9807
9835
|
}
|
|
9808
9836
|
return convertTrieToFieldsRecursively(root);
|
|
9809
9837
|
}
|
|
9810
9838
|
function convertTrieToFieldsRecursively(root) {
|
|
9811
|
-
const childKeys = keys$
|
|
9839
|
+
const childKeys = keys$4(root.children);
|
|
9812
9840
|
if (childKeys.length === 0) {
|
|
9813
9841
|
if (root.name === '') {
|
|
9814
9842
|
return [];
|
|
@@ -9845,7 +9873,7 @@ const getObjectNameFromField = (field) => {
|
|
|
9845
9873
|
function mergeFieldsTries(rootA, rootB) {
|
|
9846
9874
|
const rootAchildren = rootA.children;
|
|
9847
9875
|
const rootBchildren = rootB.children;
|
|
9848
|
-
const childBKeys = keys$
|
|
9876
|
+
const childBKeys = keys$4(rootBchildren);
|
|
9849
9877
|
for (let i = 0, len = childBKeys.length; i < len; i++) {
|
|
9850
9878
|
const childBKey = childBKeys[i];
|
|
9851
9879
|
if (rootAchildren[childBKey] === undefined) {
|
|
@@ -10012,8 +10040,8 @@ function isSuperRecordFieldTrie(a, b) {
|
|
|
10012
10040
|
}
|
|
10013
10041
|
const childrenA = a.children;
|
|
10014
10042
|
const childrenB = b.children;
|
|
10015
|
-
const childKeysA = keys$
|
|
10016
|
-
const childKeysB = keys$
|
|
10043
|
+
const childKeysA = keys$4(childrenA);
|
|
10044
|
+
const childKeysB = keys$4(childrenB);
|
|
10017
10045
|
const childKeysBLength = childKeysB.length;
|
|
10018
10046
|
if (childKeysBLength > childKeysA.length) {
|
|
10019
10047
|
return false;
|
|
@@ -10067,9 +10095,9 @@ function fulfill(existing, incoming) {
|
|
|
10067
10095
|
return false;
|
|
10068
10096
|
}
|
|
10069
10097
|
}
|
|
10070
|
-
const headersKeys = keys$
|
|
10098
|
+
const headersKeys = keys$4(headers);
|
|
10071
10099
|
const headersKeyLength = headersKeys.length;
|
|
10072
|
-
if (headersKeyLength !== keys$
|
|
10100
|
+
if (headersKeyLength !== keys$4(existingHeaders).length) {
|
|
10073
10101
|
return false;
|
|
10074
10102
|
}
|
|
10075
10103
|
for (let i = 0, len = headersKeyLength; i < len; i++) {
|
|
@@ -10698,7 +10726,7 @@ function buildNetworkSnapshot$h(luvio, config, serverRequestCount = 0, options)
|
|
|
10698
10726
|
|
|
10699
10727
|
// iterate through the map to build configs for network calls
|
|
10700
10728
|
function resolveConflict(luvio, map) {
|
|
10701
|
-
const ids = keys$
|
|
10729
|
+
const ids = keys$4(map.conflicts);
|
|
10702
10730
|
if (ids.length === 0) {
|
|
10703
10731
|
instrumentation.recordConflictsResolved(map.serverRequestCount);
|
|
10704
10732
|
return;
|
|
@@ -10714,7 +10742,7 @@ function resolveConflict(luvio, map) {
|
|
|
10714
10742
|
else {
|
|
10715
10743
|
const records = reduce.call(ids, (acc, id) => {
|
|
10716
10744
|
const { trackedFields } = map.conflicts[id];
|
|
10717
|
-
push$
|
|
10745
|
+
push$1.call(acc, {
|
|
10718
10746
|
recordIds: [id],
|
|
10719
10747
|
optionalFields: convertTrieToFields(trackedFields),
|
|
10720
10748
|
});
|
|
@@ -12145,18 +12173,18 @@ function listFields(luvio, { fields = [], optionalFields = [], sortBy, }, listIn
|
|
|
12145
12173
|
return {
|
|
12146
12174
|
getRecordSelectionFieldSets() {
|
|
12147
12175
|
const optionalPlusDefaultFields = { ...optionalFields_ };
|
|
12148
|
-
const fields = keys$
|
|
12176
|
+
const fields = keys$4(defaultFields_);
|
|
12149
12177
|
for (let i = 0; i < fields.length; ++i) {
|
|
12150
12178
|
const field = fields[i];
|
|
12151
12179
|
if (!fields_[field] && !defaultServerFieldStatus.missingFields[field]) {
|
|
12152
12180
|
optionalPlusDefaultFields[field] = true;
|
|
12153
12181
|
}
|
|
12154
12182
|
}
|
|
12155
|
-
return [keys$
|
|
12183
|
+
return [keys$4(fields_).sort(), keys$4(optionalPlusDefaultFields).sort()];
|
|
12156
12184
|
},
|
|
12157
12185
|
processRecords(records) {
|
|
12158
12186
|
const { missingFields } = defaultServerFieldStatus;
|
|
12159
|
-
const fields = keys$
|
|
12187
|
+
const fields = keys$4(missingFields);
|
|
12160
12188
|
for (let i = 0; i < fields.length; ++i) {
|
|
12161
12189
|
const field = fields[i], splitField = field.split('.').slice(1);
|
|
12162
12190
|
for (let i = 0; i < records.length; ++i) {
|
|
@@ -15636,7 +15664,7 @@ function getRecordId18Array(value) {
|
|
|
15636
15664
|
if (apiName === undefined) {
|
|
15637
15665
|
return undefined;
|
|
15638
15666
|
}
|
|
15639
|
-
push$
|
|
15667
|
+
push$1.call(array, apiName);
|
|
15640
15668
|
}
|
|
15641
15669
|
if (array.length === 0) {
|
|
15642
15670
|
return undefined;
|
|
@@ -16112,15 +16140,15 @@ function buildRecordUiSelector(recordDefs, layoutTypes, modes, recordOptionalFie
|
|
|
16112
16140
|
name: mode,
|
|
16113
16141
|
fragment: layoutSelections$2,
|
|
16114
16142
|
};
|
|
16115
|
-
push$
|
|
16143
|
+
push$1.call(modeSelections, modeSel);
|
|
16116
16144
|
}
|
|
16117
|
-
push$
|
|
16145
|
+
push$1.call(layoutTypeSelections, sel);
|
|
16118
16146
|
}
|
|
16119
16147
|
const recordLayoutSelections = [];
|
|
16120
16148
|
const recordSelections = [];
|
|
16121
16149
|
for (let i = 0, len = recordDefs.length; i < len; i += 1) {
|
|
16122
16150
|
const { recordId, recordData } = recordDefs[i];
|
|
16123
|
-
push$
|
|
16151
|
+
push$1.call(recordLayoutSelections, {
|
|
16124
16152
|
kind: 'Object',
|
|
16125
16153
|
name: recordData.apiName,
|
|
16126
16154
|
required: false,
|
|
@@ -16129,7 +16157,7 @@ function buildRecordUiSelector(recordDefs, layoutTypes, modes, recordOptionalFie
|
|
|
16129
16157
|
});
|
|
16130
16158
|
const optionalFields = recordOptionalFields[recordId];
|
|
16131
16159
|
const fields = extractFields(recordData);
|
|
16132
|
-
push$
|
|
16160
|
+
push$1.call(recordSelections, {
|
|
16133
16161
|
kind: 'Link',
|
|
16134
16162
|
name: recordId,
|
|
16135
16163
|
fragment: {
|
|
@@ -16251,7 +16279,7 @@ function getMissingRecordLookupFields(record, objectInfo) {
|
|
|
16251
16279
|
const lookupFields = {};
|
|
16252
16280
|
const { apiName, fields: recordFields } = record;
|
|
16253
16281
|
const { fields: objectInfoFields } = objectInfo;
|
|
16254
|
-
const objectInfoFieldNames = keys$
|
|
16282
|
+
const objectInfoFieldNames = keys$4(objectInfoFields);
|
|
16255
16283
|
for (let i = 0, len = objectInfoFieldNames.length; i < len; i += 1) {
|
|
16256
16284
|
const fieldName = objectInfoFieldNames[i];
|
|
16257
16285
|
const field = objectInfoFields[fieldName];
|
|
@@ -16270,12 +16298,12 @@ function getMissingRecordLookupFields(record, objectInfo) {
|
|
|
16270
16298
|
const nameField = `${apiName}.${relationshipName}.${getNameField(objectInfo, fieldName)}`;
|
|
16271
16299
|
lookupFields[nameField] = true;
|
|
16272
16300
|
}
|
|
16273
|
-
return keys$
|
|
16301
|
+
return keys$4(lookupFields);
|
|
16274
16302
|
}
|
|
16275
16303
|
function getRecordUiMissingRecordLookupFields(recordUi) {
|
|
16276
16304
|
const { records, objectInfos } = recordUi;
|
|
16277
16305
|
const recordLookupFields = {};
|
|
16278
|
-
const recordIds = keys$
|
|
16306
|
+
const recordIds = keys$4(records);
|
|
16279
16307
|
for (let i = 0, len = recordIds.length; i < len; i += 1) {
|
|
16280
16308
|
const recordId = recordIds[i];
|
|
16281
16309
|
const recordData = records[recordId];
|
|
@@ -16313,19 +16341,19 @@ function buildCachedSelectorKey(key) {
|
|
|
16313
16341
|
}
|
|
16314
16342
|
function eachLayout(recordUi, cb) {
|
|
16315
16343
|
const { layouts } = recordUi;
|
|
16316
|
-
const layoutApiNames = keys$
|
|
16344
|
+
const layoutApiNames = keys$4(layouts);
|
|
16317
16345
|
for (let a = 0, len = layoutApiNames.length; a < len; a += 1) {
|
|
16318
16346
|
const apiName = layoutApiNames[a];
|
|
16319
16347
|
const apiNameData = layouts[apiName];
|
|
16320
|
-
const recordTypeIds = keys$
|
|
16348
|
+
const recordTypeIds = keys$4(apiNameData);
|
|
16321
16349
|
for (let b = 0, recordTypeIdsLen = recordTypeIds.length; b < recordTypeIdsLen; b += 1) {
|
|
16322
16350
|
const recordTypeId = recordTypeIds[b];
|
|
16323
16351
|
const recordTypeData = apiNameData[recordTypeId];
|
|
16324
|
-
const layoutTypes = keys$
|
|
16352
|
+
const layoutTypes = keys$4(recordTypeData);
|
|
16325
16353
|
for (let c = 0, layoutTypesLen = layoutTypes.length; c < layoutTypesLen; c += 1) {
|
|
16326
16354
|
const layoutType = layoutTypes[c];
|
|
16327
16355
|
const layoutTypeData = recordTypeData[layoutType];
|
|
16328
|
-
const modes = keys$
|
|
16356
|
+
const modes = keys$4(layoutTypeData);
|
|
16329
16357
|
for (let d = 0, modesLen = modes.length; d < modesLen; d += 1) {
|
|
16330
16358
|
const mode = modes[d];
|
|
16331
16359
|
const layout = layoutTypeData[mode];
|
|
@@ -16340,7 +16368,7 @@ function collectRecordDefs(resp, recordIds) {
|
|
|
16340
16368
|
for (let i = 0, len = recordIds.length; i < len; i += 1) {
|
|
16341
16369
|
const recordId = recordIds[i];
|
|
16342
16370
|
const recordData = resp.records[recordId];
|
|
16343
|
-
push$
|
|
16371
|
+
push$1.call(recordDefs, {
|
|
16344
16372
|
recordId,
|
|
16345
16373
|
recordData,
|
|
16346
16374
|
recordTypeId: getRecordTypeId$2(recordData),
|
|
@@ -16401,7 +16429,7 @@ function prepareRequest$3(luvio, config) {
|
|
|
16401
16429
|
// we have to run ingest code and look at the resulting snapshot's seenRecords.
|
|
16402
16430
|
function getCacheKeys(keySet, luvio, config, key, originalResponseBody) {
|
|
16403
16431
|
const { recordIds, layoutTypes, modes } = config;
|
|
16404
|
-
const responseBody = parse$
|
|
16432
|
+
const responseBody = parse$3(stringify$3(originalResponseBody));
|
|
16405
16433
|
eachLayout(responseBody, (apiName, recordTypeId, layout) => {
|
|
16406
16434
|
if (layout.id === null) {
|
|
16407
16435
|
return;
|
|
@@ -16531,14 +16559,14 @@ function buildNetworkSnapshot$e(luvio, config, dispatchContext) {
|
|
|
16531
16559
|
function publishDependencies(luvio, recordIds, depKeys) {
|
|
16532
16560
|
for (let i = 0, len = recordIds.length; i < len; i += 1) {
|
|
16533
16561
|
const recordDepKey = dependencyKeyBuilder({ recordId: recordIds[i] });
|
|
16534
|
-
const dependencies = create$
|
|
16562
|
+
const dependencies = create$4(null);
|
|
16535
16563
|
for (let j = 0, len = depKeys.length; j < len; j++) {
|
|
16536
16564
|
dependencies[depKeys[j]] = true;
|
|
16537
16565
|
}
|
|
16538
16566
|
const node = luvio.getNode(recordDepKey);
|
|
16539
16567
|
if (isGraphNode(node)) {
|
|
16540
16568
|
const recordDeps = node.retrieve();
|
|
16541
|
-
assign$
|
|
16569
|
+
assign$4(dependencies, recordDeps);
|
|
16542
16570
|
}
|
|
16543
16571
|
luvio.storePublish(recordDepKey, dependencies);
|
|
16544
16572
|
}
|
|
@@ -16656,7 +16684,7 @@ function refresh(luvio, config) {
|
|
|
16656
16684
|
}
|
|
16657
16685
|
if (isUnfulfilledSnapshot$1(snapshot)) {
|
|
16658
16686
|
if (process.env.NODE_ENV !== 'production') {
|
|
16659
|
-
throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$
|
|
16687
|
+
throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$4(snapshot.missingPaths)}`);
|
|
16660
16688
|
}
|
|
16661
16689
|
}
|
|
16662
16690
|
const { data } = snapshot;
|
|
@@ -16703,7 +16731,7 @@ function processRecordUiRepresentation(luvio, refresh, recordId, modes, snapshot
|
|
|
16703
16731
|
}
|
|
16704
16732
|
if (isUnfulfilledSnapshot$1(snapshot)) {
|
|
16705
16733
|
if (process.env.NODE_ENV !== 'production') {
|
|
16706
|
-
throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$
|
|
16734
|
+
throw new Error(`RecordUi adapter resolved with a snapshot with missing data, missingPaths: ${keys$4(snapshot.missingPaths)}`);
|
|
16707
16735
|
}
|
|
16708
16736
|
}
|
|
16709
16737
|
const { data } = snapshot;
|
|
@@ -16732,11 +16760,11 @@ const recordLayoutFragmentSelector = [
|
|
|
16732
16760
|
function getFieldsFromLayoutMap(layoutMap, objectInfo) {
|
|
16733
16761
|
let fields = [];
|
|
16734
16762
|
let optionalFields = [];
|
|
16735
|
-
const layoutTypes = keys$
|
|
16763
|
+
const layoutTypes = keys$4(layoutMap);
|
|
16736
16764
|
for (let i = 0, layoutTypesLen = layoutTypes.length; i < layoutTypesLen; i += 1) {
|
|
16737
16765
|
const layoutType = layoutTypes[i];
|
|
16738
16766
|
const modesMap = layoutMap[layoutType];
|
|
16739
|
-
const modes = keys$
|
|
16767
|
+
const modes = keys$4(modesMap);
|
|
16740
16768
|
for (let m = 0, modesLen = modes.length; m < modesLen; m += 1) {
|
|
16741
16769
|
const mode = modes[m];
|
|
16742
16770
|
const { fields: modeFields, optionalFields: modeOptionalFields } = getQualifiedFieldApiNamesFromLayout(modesMap[mode], objectInfo);
|
|
@@ -16772,7 +16800,7 @@ function getRecordForLayoutableEntities(luvio, refresh, recordId, layoutMap, obj
|
|
|
16772
16800
|
return getRecord(luvio, refresh, recordId, [], implicitFields);
|
|
16773
16801
|
}
|
|
16774
16802
|
function getRecordForNonLayoutableEntities(luvio, adapterContext, refresh, recordId, objectInfo, configOptionalFields, configFields) {
|
|
16775
|
-
const fields = keys$
|
|
16803
|
+
const fields = keys$4(configFields ? configFields : {}).map((key) => `${objectInfo.apiName}.${key}`);
|
|
16776
16804
|
// W-12697744
|
|
16777
16805
|
// Set the implicit fields received from the server in adapter context
|
|
16778
16806
|
// This ensures that the implicit fields are available when data is read locally or from durable store
|
|
@@ -17011,7 +17039,7 @@ function makeRecordLayoutMap(luvio, config, apiName, recordTypeId, layoutTypes,
|
|
|
17011
17039
|
}
|
|
17012
17040
|
const { layoutType, mode, snapshot } = container;
|
|
17013
17041
|
if (wrapper.layoutMap[layoutType] === undefined) {
|
|
17014
|
-
wrapper.layoutMap = assign$
|
|
17042
|
+
wrapper.layoutMap = assign$4({}, wrapper.layoutMap, {
|
|
17015
17043
|
[layoutType]: {},
|
|
17016
17044
|
});
|
|
17017
17045
|
}
|
|
@@ -17747,7 +17775,7 @@ function typeCheckConfig$9(untrustedConfig) {
|
|
|
17747
17775
|
}
|
|
17748
17776
|
}
|
|
17749
17777
|
if (records.length > 0) {
|
|
17750
|
-
assign$
|
|
17778
|
+
assign$4(config, { records });
|
|
17751
17779
|
}
|
|
17752
17780
|
}
|
|
17753
17781
|
return config;
|
|
@@ -42813,6 +42841,599 @@ var Kind = Object.freeze({
|
|
|
42813
42841
|
* The enum type representing the possible kind values of AST nodes.
|
|
42814
42842
|
*/
|
|
42815
42843
|
|
|
42844
|
+
function invariant(condition, message) {
|
|
42845
|
+
var booleanCondition = Boolean(condition); // istanbul ignore else (See transformation done in './resources/inlineInvariant.js')
|
|
42846
|
+
|
|
42847
|
+
if (!booleanCondition) {
|
|
42848
|
+
throw new Error(message != null ? message : 'Unexpected invariant triggered.');
|
|
42849
|
+
}
|
|
42850
|
+
}
|
|
42851
|
+
|
|
42852
|
+
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
|
|
42853
|
+
var nodejsCustomInspectSymbol = typeof Symbol === 'function' && typeof Symbol.for === 'function' ? Symbol.for('nodejs.util.inspect.custom') : undefined;
|
|
42854
|
+
var nodejsCustomInspectSymbol$1 = nodejsCustomInspectSymbol;
|
|
42855
|
+
|
|
42856
|
+
/**
|
|
42857
|
+
* The `defineInspect()` function defines `inspect()` prototype method as alias of `toJSON`
|
|
42858
|
+
*/
|
|
42859
|
+
|
|
42860
|
+
function defineInspect(classObject) {
|
|
42861
|
+
var fn = classObject.prototype.toJSON;
|
|
42862
|
+
typeof fn === 'function' || invariant(0);
|
|
42863
|
+
classObject.prototype.inspect = fn; // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2317')
|
|
42864
|
+
|
|
42865
|
+
if (nodejsCustomInspectSymbol$1) {
|
|
42866
|
+
classObject.prototype[nodejsCustomInspectSymbol$1] = fn;
|
|
42867
|
+
}
|
|
42868
|
+
}
|
|
42869
|
+
|
|
42870
|
+
/**
|
|
42871
|
+
* Contains a range of UTF-8 character offsets and token references that
|
|
42872
|
+
* identify the region of the source from which the AST derived.
|
|
42873
|
+
*/
|
|
42874
|
+
var Location = /*#__PURE__*/function () {
|
|
42875
|
+
/**
|
|
42876
|
+
* The character offset at which this Node begins.
|
|
42877
|
+
*/
|
|
42878
|
+
|
|
42879
|
+
/**
|
|
42880
|
+
* The character offset at which this Node ends.
|
|
42881
|
+
*/
|
|
42882
|
+
|
|
42883
|
+
/**
|
|
42884
|
+
* The Token at which this Node begins.
|
|
42885
|
+
*/
|
|
42886
|
+
|
|
42887
|
+
/**
|
|
42888
|
+
* The Token at which this Node ends.
|
|
42889
|
+
*/
|
|
42890
|
+
|
|
42891
|
+
/**
|
|
42892
|
+
* The Source document the AST represents.
|
|
42893
|
+
*/
|
|
42894
|
+
function Location(startToken, endToken, source) {
|
|
42895
|
+
this.start = startToken.start;
|
|
42896
|
+
this.end = endToken.end;
|
|
42897
|
+
this.startToken = startToken;
|
|
42898
|
+
this.endToken = endToken;
|
|
42899
|
+
this.source = source;
|
|
42900
|
+
}
|
|
42901
|
+
|
|
42902
|
+
var _proto = Location.prototype;
|
|
42903
|
+
|
|
42904
|
+
_proto.toJSON = function toJSON() {
|
|
42905
|
+
return {
|
|
42906
|
+
start: this.start,
|
|
42907
|
+
end: this.end
|
|
42908
|
+
};
|
|
42909
|
+
};
|
|
42910
|
+
|
|
42911
|
+
return Location;
|
|
42912
|
+
}(); // Print a simplified form when appearing in `inspect` and `util.inspect`.
|
|
42913
|
+
|
|
42914
|
+
defineInspect(Location);
|
|
42915
|
+
/**
|
|
42916
|
+
* Represents a range of characters represented by a lexical token
|
|
42917
|
+
* within a Source.
|
|
42918
|
+
*/
|
|
42919
|
+
|
|
42920
|
+
var Token = /*#__PURE__*/function () {
|
|
42921
|
+
/**
|
|
42922
|
+
* The kind of Token.
|
|
42923
|
+
*/
|
|
42924
|
+
|
|
42925
|
+
/**
|
|
42926
|
+
* The character offset at which this Node begins.
|
|
42927
|
+
*/
|
|
42928
|
+
|
|
42929
|
+
/**
|
|
42930
|
+
* The character offset at which this Node ends.
|
|
42931
|
+
*/
|
|
42932
|
+
|
|
42933
|
+
/**
|
|
42934
|
+
* The 1-indexed line number on which this Token appears.
|
|
42935
|
+
*/
|
|
42936
|
+
|
|
42937
|
+
/**
|
|
42938
|
+
* The 1-indexed column number at which this Token begins.
|
|
42939
|
+
*/
|
|
42940
|
+
|
|
42941
|
+
/**
|
|
42942
|
+
* For non-punctuation tokens, represents the interpreted value of the token.
|
|
42943
|
+
*/
|
|
42944
|
+
|
|
42945
|
+
/**
|
|
42946
|
+
* Tokens exist as nodes in a double-linked-list amongst all tokens
|
|
42947
|
+
* including ignored tokens. <SOF> is always the first node and <EOF>
|
|
42948
|
+
* the last.
|
|
42949
|
+
*/
|
|
42950
|
+
function Token(kind, start, end, line, column, prev, value) {
|
|
42951
|
+
this.kind = kind;
|
|
42952
|
+
this.start = start;
|
|
42953
|
+
this.end = end;
|
|
42954
|
+
this.line = line;
|
|
42955
|
+
this.column = column;
|
|
42956
|
+
this.value = value;
|
|
42957
|
+
this.prev = prev;
|
|
42958
|
+
this.next = null;
|
|
42959
|
+
}
|
|
42960
|
+
|
|
42961
|
+
var _proto2 = Token.prototype;
|
|
42962
|
+
|
|
42963
|
+
_proto2.toJSON = function toJSON() {
|
|
42964
|
+
return {
|
|
42965
|
+
kind: this.kind,
|
|
42966
|
+
value: this.value,
|
|
42967
|
+
line: this.line,
|
|
42968
|
+
column: this.column
|
|
42969
|
+
};
|
|
42970
|
+
};
|
|
42971
|
+
|
|
42972
|
+
return Token;
|
|
42973
|
+
}(); // Print a simplified form when appearing in `inspect` and `util.inspect`.
|
|
42974
|
+
|
|
42975
|
+
defineInspect(Token);
|
|
42976
|
+
/**
|
|
42977
|
+
* @internal
|
|
42978
|
+
*/
|
|
42979
|
+
|
|
42980
|
+
function isNode(maybeNode) {
|
|
42981
|
+
return maybeNode != null && typeof maybeNode.kind === 'string';
|
|
42982
|
+
}
|
|
42983
|
+
/**
|
|
42984
|
+
* The list of all possible AST node types.
|
|
42985
|
+
*/
|
|
42986
|
+
|
|
42987
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
42988
|
+
var MAX_ARRAY_LENGTH = 10;
|
|
42989
|
+
var MAX_RECURSIVE_DEPTH = 2;
|
|
42990
|
+
/**
|
|
42991
|
+
* Used to print values in error messages.
|
|
42992
|
+
*/
|
|
42993
|
+
|
|
42994
|
+
function inspect(value) {
|
|
42995
|
+
return formatValue(value, []);
|
|
42996
|
+
}
|
|
42997
|
+
|
|
42998
|
+
function formatValue(value, seenValues) {
|
|
42999
|
+
switch (_typeof(value)) {
|
|
43000
|
+
case 'string':
|
|
43001
|
+
return JSON.stringify(value);
|
|
43002
|
+
|
|
43003
|
+
case 'function':
|
|
43004
|
+
return value.name ? "[function ".concat(value.name, "]") : '[function]';
|
|
43005
|
+
|
|
43006
|
+
case 'object':
|
|
43007
|
+
if (value === null) {
|
|
43008
|
+
return 'null';
|
|
43009
|
+
}
|
|
43010
|
+
|
|
43011
|
+
return formatObjectValue(value, seenValues);
|
|
43012
|
+
|
|
43013
|
+
default:
|
|
43014
|
+
return String(value);
|
|
43015
|
+
}
|
|
43016
|
+
}
|
|
43017
|
+
|
|
43018
|
+
function formatObjectValue(value, previouslySeenValues) {
|
|
43019
|
+
if (previouslySeenValues.indexOf(value) !== -1) {
|
|
43020
|
+
return '[Circular]';
|
|
43021
|
+
}
|
|
43022
|
+
|
|
43023
|
+
var seenValues = [].concat(previouslySeenValues, [value]);
|
|
43024
|
+
var customInspectFn = getCustomFn(value);
|
|
43025
|
+
|
|
43026
|
+
if (customInspectFn !== undefined) {
|
|
43027
|
+
var customValue = customInspectFn.call(value); // check for infinite recursion
|
|
43028
|
+
|
|
43029
|
+
if (customValue !== value) {
|
|
43030
|
+
return typeof customValue === 'string' ? customValue : formatValue(customValue, seenValues);
|
|
43031
|
+
}
|
|
43032
|
+
} else if (Array.isArray(value)) {
|
|
43033
|
+
return formatArray(value, seenValues);
|
|
43034
|
+
}
|
|
43035
|
+
|
|
43036
|
+
return formatObject(value, seenValues);
|
|
43037
|
+
}
|
|
43038
|
+
|
|
43039
|
+
function formatObject(object, seenValues) {
|
|
43040
|
+
var keys = Object.keys(object);
|
|
43041
|
+
|
|
43042
|
+
if (keys.length === 0) {
|
|
43043
|
+
return '{}';
|
|
43044
|
+
}
|
|
43045
|
+
|
|
43046
|
+
if (seenValues.length > MAX_RECURSIVE_DEPTH) {
|
|
43047
|
+
return '[' + getObjectTag(object) + ']';
|
|
43048
|
+
}
|
|
43049
|
+
|
|
43050
|
+
var properties = keys.map(function (key) {
|
|
43051
|
+
var value = formatValue(object[key], seenValues);
|
|
43052
|
+
return key + ': ' + value;
|
|
43053
|
+
});
|
|
43054
|
+
return '{ ' + properties.join(', ') + ' }';
|
|
43055
|
+
}
|
|
43056
|
+
|
|
43057
|
+
function formatArray(array, seenValues) {
|
|
43058
|
+
if (array.length === 0) {
|
|
43059
|
+
return '[]';
|
|
43060
|
+
}
|
|
43061
|
+
|
|
43062
|
+
if (seenValues.length > MAX_RECURSIVE_DEPTH) {
|
|
43063
|
+
return '[Array]';
|
|
43064
|
+
}
|
|
43065
|
+
|
|
43066
|
+
var len = Math.min(MAX_ARRAY_LENGTH, array.length);
|
|
43067
|
+
var remaining = array.length - len;
|
|
43068
|
+
var items = [];
|
|
43069
|
+
|
|
43070
|
+
for (var i = 0; i < len; ++i) {
|
|
43071
|
+
items.push(formatValue(array[i], seenValues));
|
|
43072
|
+
}
|
|
43073
|
+
|
|
43074
|
+
if (remaining === 1) {
|
|
43075
|
+
items.push('... 1 more item');
|
|
43076
|
+
} else if (remaining > 1) {
|
|
43077
|
+
items.push("... ".concat(remaining, " more items"));
|
|
43078
|
+
}
|
|
43079
|
+
|
|
43080
|
+
return '[' + items.join(', ') + ']';
|
|
43081
|
+
}
|
|
43082
|
+
|
|
43083
|
+
function getCustomFn(object) {
|
|
43084
|
+
var customInspectFn = object[String(nodejsCustomInspectSymbol$1)];
|
|
43085
|
+
|
|
43086
|
+
if (typeof customInspectFn === 'function') {
|
|
43087
|
+
return customInspectFn;
|
|
43088
|
+
}
|
|
43089
|
+
|
|
43090
|
+
if (typeof object.inspect === 'function') {
|
|
43091
|
+
return object.inspect;
|
|
43092
|
+
}
|
|
43093
|
+
}
|
|
43094
|
+
|
|
43095
|
+
function getObjectTag(object) {
|
|
43096
|
+
var tag = Object.prototype.toString.call(object).replace(/^\[object /, '').replace(/]$/, '');
|
|
43097
|
+
|
|
43098
|
+
if (tag === 'Object' && typeof object.constructor === 'function') {
|
|
43099
|
+
var name = object.constructor.name;
|
|
43100
|
+
|
|
43101
|
+
if (typeof name === 'string' && name !== '') {
|
|
43102
|
+
return name;
|
|
43103
|
+
}
|
|
43104
|
+
}
|
|
43105
|
+
|
|
43106
|
+
return tag;
|
|
43107
|
+
}
|
|
43108
|
+
|
|
43109
|
+
/**
|
|
43110
|
+
* A visitor is provided to visit, it contains the collection of
|
|
43111
|
+
* relevant functions to be called during the visitor's traversal.
|
|
43112
|
+
*/
|
|
43113
|
+
|
|
43114
|
+
var QueryDocumentKeys = {
|
|
43115
|
+
Name: [],
|
|
43116
|
+
Document: ['definitions'],
|
|
43117
|
+
OperationDefinition: ['name', 'variableDefinitions', 'directives', 'selectionSet'],
|
|
43118
|
+
VariableDefinition: ['variable', 'type', 'defaultValue', 'directives'],
|
|
43119
|
+
Variable: ['name'],
|
|
43120
|
+
SelectionSet: ['selections'],
|
|
43121
|
+
Field: ['alias', 'name', 'arguments', 'directives', 'selectionSet'],
|
|
43122
|
+
Argument: ['name', 'value'],
|
|
43123
|
+
FragmentSpread: ['name', 'directives'],
|
|
43124
|
+
InlineFragment: ['typeCondition', 'directives', 'selectionSet'],
|
|
43125
|
+
FragmentDefinition: ['name', // Note: fragment variable definitions are experimental and may be changed
|
|
43126
|
+
// or removed in the future.
|
|
43127
|
+
'variableDefinitions', 'typeCondition', 'directives', 'selectionSet'],
|
|
43128
|
+
IntValue: [],
|
|
43129
|
+
FloatValue: [],
|
|
43130
|
+
StringValue: [],
|
|
43131
|
+
BooleanValue: [],
|
|
43132
|
+
NullValue: [],
|
|
43133
|
+
EnumValue: [],
|
|
43134
|
+
ListValue: ['values'],
|
|
43135
|
+
ObjectValue: ['fields'],
|
|
43136
|
+
ObjectField: ['name', 'value'],
|
|
43137
|
+
Directive: ['name', 'arguments'],
|
|
43138
|
+
NamedType: ['name'],
|
|
43139
|
+
ListType: ['type'],
|
|
43140
|
+
NonNullType: ['type'],
|
|
43141
|
+
SchemaDefinition: ['description', 'directives', 'operationTypes'],
|
|
43142
|
+
OperationTypeDefinition: ['type'],
|
|
43143
|
+
ScalarTypeDefinition: ['description', 'name', 'directives'],
|
|
43144
|
+
ObjectTypeDefinition: ['description', 'name', 'interfaces', 'directives', 'fields'],
|
|
43145
|
+
FieldDefinition: ['description', 'name', 'arguments', 'type', 'directives'],
|
|
43146
|
+
InputValueDefinition: ['description', 'name', 'type', 'defaultValue', 'directives'],
|
|
43147
|
+
InterfaceTypeDefinition: ['description', 'name', 'interfaces', 'directives', 'fields'],
|
|
43148
|
+
UnionTypeDefinition: ['description', 'name', 'directives', 'types'],
|
|
43149
|
+
EnumTypeDefinition: ['description', 'name', 'directives', 'values'],
|
|
43150
|
+
EnumValueDefinition: ['description', 'name', 'directives'],
|
|
43151
|
+
InputObjectTypeDefinition: ['description', 'name', 'directives', 'fields'],
|
|
43152
|
+
DirectiveDefinition: ['description', 'name', 'arguments', 'locations'],
|
|
43153
|
+
SchemaExtension: ['directives', 'operationTypes'],
|
|
43154
|
+
ScalarTypeExtension: ['name', 'directives'],
|
|
43155
|
+
ObjectTypeExtension: ['name', 'interfaces', 'directives', 'fields'],
|
|
43156
|
+
InterfaceTypeExtension: ['name', 'interfaces', 'directives', 'fields'],
|
|
43157
|
+
UnionTypeExtension: ['name', 'directives', 'types'],
|
|
43158
|
+
EnumTypeExtension: ['name', 'directives', 'values'],
|
|
43159
|
+
InputObjectTypeExtension: ['name', 'directives', 'fields']
|
|
43160
|
+
};
|
|
43161
|
+
var BREAK = Object.freeze({});
|
|
43162
|
+
/**
|
|
43163
|
+
* visit() will walk through an AST using a depth-first traversal, calling
|
|
43164
|
+
* the visitor's enter function at each node in the traversal, and calling the
|
|
43165
|
+
* leave function after visiting that node and all of its child nodes.
|
|
43166
|
+
*
|
|
43167
|
+
* By returning different values from the enter and leave functions, the
|
|
43168
|
+
* behavior of the visitor can be altered, including skipping over a sub-tree of
|
|
43169
|
+
* the AST (by returning false), editing the AST by returning a value or null
|
|
43170
|
+
* to remove the value, or to stop the whole traversal by returning BREAK.
|
|
43171
|
+
*
|
|
43172
|
+
* When using visit() to edit an AST, the original AST will not be modified, and
|
|
43173
|
+
* a new version of the AST with the changes applied will be returned from the
|
|
43174
|
+
* visit function.
|
|
43175
|
+
*
|
|
43176
|
+
* const editedAST = visit(ast, {
|
|
43177
|
+
* enter(node, key, parent, path, ancestors) {
|
|
43178
|
+
* // @return
|
|
43179
|
+
* // undefined: no action
|
|
43180
|
+
* // false: skip visiting this node
|
|
43181
|
+
* // visitor.BREAK: stop visiting altogether
|
|
43182
|
+
* // null: delete this node
|
|
43183
|
+
* // any value: replace this node with the returned value
|
|
43184
|
+
* },
|
|
43185
|
+
* leave(node, key, parent, path, ancestors) {
|
|
43186
|
+
* // @return
|
|
43187
|
+
* // undefined: no action
|
|
43188
|
+
* // false: no action
|
|
43189
|
+
* // visitor.BREAK: stop visiting altogether
|
|
43190
|
+
* // null: delete this node
|
|
43191
|
+
* // any value: replace this node with the returned value
|
|
43192
|
+
* }
|
|
43193
|
+
* });
|
|
43194
|
+
*
|
|
43195
|
+
* Alternatively to providing enter() and leave() functions, a visitor can
|
|
43196
|
+
* instead provide functions named the same as the kinds of AST nodes, or
|
|
43197
|
+
* enter/leave visitors at a named key, leading to four permutations of the
|
|
43198
|
+
* visitor API:
|
|
43199
|
+
*
|
|
43200
|
+
* 1) Named visitors triggered when entering a node of a specific kind.
|
|
43201
|
+
*
|
|
43202
|
+
* visit(ast, {
|
|
43203
|
+
* Kind(node) {
|
|
43204
|
+
* // enter the "Kind" node
|
|
43205
|
+
* }
|
|
43206
|
+
* })
|
|
43207
|
+
*
|
|
43208
|
+
* 2) Named visitors that trigger upon entering and leaving a node of
|
|
43209
|
+
* a specific kind.
|
|
43210
|
+
*
|
|
43211
|
+
* visit(ast, {
|
|
43212
|
+
* Kind: {
|
|
43213
|
+
* enter(node) {
|
|
43214
|
+
* // enter the "Kind" node
|
|
43215
|
+
* }
|
|
43216
|
+
* leave(node) {
|
|
43217
|
+
* // leave the "Kind" node
|
|
43218
|
+
* }
|
|
43219
|
+
* }
|
|
43220
|
+
* })
|
|
43221
|
+
*
|
|
43222
|
+
* 3) Generic visitors that trigger upon entering and leaving any node.
|
|
43223
|
+
*
|
|
43224
|
+
* visit(ast, {
|
|
43225
|
+
* enter(node) {
|
|
43226
|
+
* // enter any node
|
|
43227
|
+
* },
|
|
43228
|
+
* leave(node) {
|
|
43229
|
+
* // leave any node
|
|
43230
|
+
* }
|
|
43231
|
+
* })
|
|
43232
|
+
*
|
|
43233
|
+
* 4) Parallel visitors for entering and leaving nodes of a specific kind.
|
|
43234
|
+
*
|
|
43235
|
+
* visit(ast, {
|
|
43236
|
+
* enter: {
|
|
43237
|
+
* Kind(node) {
|
|
43238
|
+
* // enter the "Kind" node
|
|
43239
|
+
* }
|
|
43240
|
+
* },
|
|
43241
|
+
* leave: {
|
|
43242
|
+
* Kind(node) {
|
|
43243
|
+
* // leave the "Kind" node
|
|
43244
|
+
* }
|
|
43245
|
+
* }
|
|
43246
|
+
* })
|
|
43247
|
+
*/
|
|
43248
|
+
|
|
43249
|
+
function visit(root, visitor) {
|
|
43250
|
+
var visitorKeys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : QueryDocumentKeys;
|
|
43251
|
+
|
|
43252
|
+
/* eslint-disable no-undef-init */
|
|
43253
|
+
var stack = undefined;
|
|
43254
|
+
var inArray = Array.isArray(root);
|
|
43255
|
+
var keys = [root];
|
|
43256
|
+
var index = -1;
|
|
43257
|
+
var edits = [];
|
|
43258
|
+
var node = undefined;
|
|
43259
|
+
var key = undefined;
|
|
43260
|
+
var parent = undefined;
|
|
43261
|
+
var path = [];
|
|
43262
|
+
var ancestors = [];
|
|
43263
|
+
var newRoot = root;
|
|
43264
|
+
/* eslint-enable no-undef-init */
|
|
43265
|
+
|
|
43266
|
+
do {
|
|
43267
|
+
index++;
|
|
43268
|
+
var isLeaving = index === keys.length;
|
|
43269
|
+
var isEdited = isLeaving && edits.length !== 0;
|
|
43270
|
+
|
|
43271
|
+
if (isLeaving) {
|
|
43272
|
+
key = ancestors.length === 0 ? undefined : path[path.length - 1];
|
|
43273
|
+
node = parent;
|
|
43274
|
+
parent = ancestors.pop();
|
|
43275
|
+
|
|
43276
|
+
if (isEdited) {
|
|
43277
|
+
if (inArray) {
|
|
43278
|
+
node = node.slice();
|
|
43279
|
+
} else {
|
|
43280
|
+
var clone = {};
|
|
43281
|
+
|
|
43282
|
+
for (var _i2 = 0, _Object$keys2 = Object.keys(node); _i2 < _Object$keys2.length; _i2++) {
|
|
43283
|
+
var k = _Object$keys2[_i2];
|
|
43284
|
+
clone[k] = node[k];
|
|
43285
|
+
}
|
|
43286
|
+
|
|
43287
|
+
node = clone;
|
|
43288
|
+
}
|
|
43289
|
+
|
|
43290
|
+
var editOffset = 0;
|
|
43291
|
+
|
|
43292
|
+
for (var ii = 0; ii < edits.length; ii++) {
|
|
43293
|
+
var editKey = edits[ii][0];
|
|
43294
|
+
var editValue = edits[ii][1];
|
|
43295
|
+
|
|
43296
|
+
if (inArray) {
|
|
43297
|
+
editKey -= editOffset;
|
|
43298
|
+
}
|
|
43299
|
+
|
|
43300
|
+
if (inArray && editValue === null) {
|
|
43301
|
+
node.splice(editKey, 1);
|
|
43302
|
+
editOffset++;
|
|
43303
|
+
} else {
|
|
43304
|
+
node[editKey] = editValue;
|
|
43305
|
+
}
|
|
43306
|
+
}
|
|
43307
|
+
}
|
|
43308
|
+
|
|
43309
|
+
index = stack.index;
|
|
43310
|
+
keys = stack.keys;
|
|
43311
|
+
edits = stack.edits;
|
|
43312
|
+
inArray = stack.inArray;
|
|
43313
|
+
stack = stack.prev;
|
|
43314
|
+
} else {
|
|
43315
|
+
key = parent ? inArray ? index : keys[index] : undefined;
|
|
43316
|
+
node = parent ? parent[key] : newRoot;
|
|
43317
|
+
|
|
43318
|
+
if (node === null || node === undefined) {
|
|
43319
|
+
continue;
|
|
43320
|
+
}
|
|
43321
|
+
|
|
43322
|
+
if (parent) {
|
|
43323
|
+
path.push(key);
|
|
43324
|
+
}
|
|
43325
|
+
}
|
|
43326
|
+
|
|
43327
|
+
var result = void 0;
|
|
43328
|
+
|
|
43329
|
+
if (!Array.isArray(node)) {
|
|
43330
|
+
if (!isNode(node)) {
|
|
43331
|
+
throw new Error("Invalid AST Node: ".concat(inspect(node), "."));
|
|
43332
|
+
}
|
|
43333
|
+
|
|
43334
|
+
var visitFn = getVisitFn(visitor, node.kind, isLeaving);
|
|
43335
|
+
|
|
43336
|
+
if (visitFn) {
|
|
43337
|
+
result = visitFn.call(visitor, node, key, parent, path, ancestors);
|
|
43338
|
+
|
|
43339
|
+
if (result === BREAK) {
|
|
43340
|
+
break;
|
|
43341
|
+
}
|
|
43342
|
+
|
|
43343
|
+
if (result === false) {
|
|
43344
|
+
if (!isLeaving) {
|
|
43345
|
+
path.pop();
|
|
43346
|
+
continue;
|
|
43347
|
+
}
|
|
43348
|
+
} else if (result !== undefined) {
|
|
43349
|
+
edits.push([key, result]);
|
|
43350
|
+
|
|
43351
|
+
if (!isLeaving) {
|
|
43352
|
+
if (isNode(result)) {
|
|
43353
|
+
node = result;
|
|
43354
|
+
} else {
|
|
43355
|
+
path.pop();
|
|
43356
|
+
continue;
|
|
43357
|
+
}
|
|
43358
|
+
}
|
|
43359
|
+
}
|
|
43360
|
+
}
|
|
43361
|
+
}
|
|
43362
|
+
|
|
43363
|
+
if (result === undefined && isEdited) {
|
|
43364
|
+
edits.push([key, node]);
|
|
43365
|
+
}
|
|
43366
|
+
|
|
43367
|
+
if (isLeaving) {
|
|
43368
|
+
path.pop();
|
|
43369
|
+
} else {
|
|
43370
|
+
var _visitorKeys$node$kin;
|
|
43371
|
+
|
|
43372
|
+
stack = {
|
|
43373
|
+
inArray: inArray,
|
|
43374
|
+
index: index,
|
|
43375
|
+
keys: keys,
|
|
43376
|
+
edits: edits,
|
|
43377
|
+
prev: stack
|
|
43378
|
+
};
|
|
43379
|
+
inArray = Array.isArray(node);
|
|
43380
|
+
keys = inArray ? node : (_visitorKeys$node$kin = visitorKeys[node.kind]) !== null && _visitorKeys$node$kin !== void 0 ? _visitorKeys$node$kin : [];
|
|
43381
|
+
index = -1;
|
|
43382
|
+
edits = [];
|
|
43383
|
+
|
|
43384
|
+
if (parent) {
|
|
43385
|
+
ancestors.push(parent);
|
|
43386
|
+
}
|
|
43387
|
+
|
|
43388
|
+
parent = node;
|
|
43389
|
+
}
|
|
43390
|
+
} while (stack !== undefined);
|
|
43391
|
+
|
|
43392
|
+
if (edits.length !== 0) {
|
|
43393
|
+
newRoot = edits[edits.length - 1][1];
|
|
43394
|
+
}
|
|
43395
|
+
|
|
43396
|
+
return newRoot;
|
|
43397
|
+
}
|
|
43398
|
+
/**
|
|
43399
|
+
* Given a visitor instance, if it is leaving or not, and a node kind, return
|
|
43400
|
+
* the function the visitor runtime should call.
|
|
43401
|
+
*/
|
|
43402
|
+
|
|
43403
|
+
function getVisitFn(visitor, kind, isLeaving) {
|
|
43404
|
+
var kindVisitor = visitor[kind];
|
|
43405
|
+
|
|
43406
|
+
if (kindVisitor) {
|
|
43407
|
+
if (!isLeaving && typeof kindVisitor === 'function') {
|
|
43408
|
+
// { Kind() {} }
|
|
43409
|
+
return kindVisitor;
|
|
43410
|
+
}
|
|
43411
|
+
|
|
43412
|
+
var kindSpecificVisitor = isLeaving ? kindVisitor.leave : kindVisitor.enter;
|
|
43413
|
+
|
|
43414
|
+
if (typeof kindSpecificVisitor === 'function') {
|
|
43415
|
+
// { Kind: { enter() {}, leave() {} } }
|
|
43416
|
+
return kindSpecificVisitor;
|
|
43417
|
+
}
|
|
43418
|
+
} else {
|
|
43419
|
+
var specificVisitor = isLeaving ? visitor.leave : visitor.enter;
|
|
43420
|
+
|
|
43421
|
+
if (specificVisitor) {
|
|
43422
|
+
if (typeof specificVisitor === 'function') {
|
|
43423
|
+
// { enter() {}, leave() {} }
|
|
43424
|
+
return specificVisitor;
|
|
43425
|
+
}
|
|
43426
|
+
|
|
43427
|
+
var specificKindVisitor = specificVisitor[kind];
|
|
43428
|
+
|
|
43429
|
+
if (typeof specificKindVisitor === 'function') {
|
|
43430
|
+
// { enter: { Kind() {} }, leave: { Kind() {} } }
|
|
43431
|
+
return specificKindVisitor;
|
|
43432
|
+
}
|
|
43433
|
+
}
|
|
43434
|
+
}
|
|
43435
|
+
}
|
|
43436
|
+
|
|
42816
43437
|
/**
|
|
42817
43438
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
42818
43439
|
* All rights reserved.
|
|
@@ -42955,8 +43576,8 @@ function isArrayLike(x) {
|
|
|
42955
43576
|
(x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1))));
|
|
42956
43577
|
}
|
|
42957
43578
|
|
|
42958
|
-
const { create: create$
|
|
42959
|
-
const { stringify: stringify$
|
|
43579
|
+
const { create: create$3, keys: keys$3, values: values$2, entries: entries$3, assign: assign$3 } = Object;
|
|
43580
|
+
const { stringify: stringify$2, parse: parse$2 } = JSON;
|
|
42960
43581
|
const { isArray: isArray$1, from: from$1 } = Array;
|
|
42961
43582
|
|
|
42962
43583
|
function recordLoaderFactory(query) {
|
|
@@ -42968,7 +43589,7 @@ function recordLoaderFactory(query) {
|
|
|
42968
43589
|
rows.forEach((row) => {
|
|
42969
43590
|
if (!row[0])
|
|
42970
43591
|
return null;
|
|
42971
|
-
const record = parse$
|
|
43592
|
+
const record = parse$2(row[0]);
|
|
42972
43593
|
if (record.id === id) {
|
|
42973
43594
|
foundRow = record;
|
|
42974
43595
|
}
|
|
@@ -43327,11 +43948,11 @@ function dateTimePredicate(input, operator, field, alias) {
|
|
|
43327
43948
|
return dateTimeRange(range, operator, field, alias);
|
|
43328
43949
|
}
|
|
43329
43950
|
// eslint-disable-next-line @salesforce/lds/no-error-in-production
|
|
43330
|
-
throw new Error(`Where filter ${stringify$
|
|
43951
|
+
throw new Error(`Where filter ${stringify$2(input)} is not supported`);
|
|
43331
43952
|
}
|
|
43332
43953
|
function dateTimeRange(input, op, field, alias) {
|
|
43333
43954
|
const dateFunction = field.dataType === 'DateTime' ? 'datetime' : 'date';
|
|
43334
|
-
const key = keys$
|
|
43955
|
+
const key = keys$3(input)[0];
|
|
43335
43956
|
let operator = op;
|
|
43336
43957
|
if (operator === '=')
|
|
43337
43958
|
operator = 'BETWEEN';
|
|
@@ -43631,7 +44252,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
43631
44252
|
if (!where)
|
|
43632
44253
|
return [];
|
|
43633
44254
|
let predicates = [];
|
|
43634
|
-
const fields = keys$
|
|
44255
|
+
const fields = keys$3(where);
|
|
43635
44256
|
for (const field of fields) {
|
|
43636
44257
|
if (field === 'and' || field === 'or') {
|
|
43637
44258
|
predicates.push(processCompoundPredicate(field, where[field], recordType, alias, objectInfoMap, joins));
|
|
@@ -43656,8 +44277,12 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
43656
44277
|
// handles spanning field filter. For example, for 'OwnerId' field within 'Account' objectInfo, both 'OwnerId' and 'Owner' can be
|
|
43657
44278
|
// treated as reference type, while 'Owner' field spanns since it equals to 'relationshipName'
|
|
43658
44279
|
if (fieldInfo.dataType === 'Reference' && fieldInfo.relationshipName === field) {
|
|
44280
|
+
let leftPath = `$.fields.${fieldInfo.apiName}.value`;
|
|
44281
|
+
if (fieldInfo.apiName === 'RecordTypeId') {
|
|
44282
|
+
leftPath = '$.recordTypeId';
|
|
44283
|
+
}
|
|
43659
44284
|
const path = {
|
|
43660
|
-
leftPath:
|
|
44285
|
+
leftPath: leftPath,
|
|
43661
44286
|
rightPath: `$.id`,
|
|
43662
44287
|
};
|
|
43663
44288
|
const childAlias = `${alias}_${field}`;
|
|
@@ -43680,7 +44305,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
43680
44305
|
}
|
|
43681
44306
|
else {
|
|
43682
44307
|
// @W-12618378 polymorphic query sometimes does not work as expected on server. The GQL on certain entities could fail.
|
|
43683
|
-
const entityNames = keys$
|
|
44308
|
+
const entityNames = keys$3(where[field]);
|
|
43684
44309
|
const polyPredicatesGroups = entityNames
|
|
43685
44310
|
.filter((entityName) => fieldInfo.referenceToInfos.some((referenceInfo) => referenceInfo.apiName === entityName))
|
|
43686
44311
|
.map((entityName) => {
|
|
@@ -43710,7 +44335,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
43710
44335
|
}
|
|
43711
44336
|
else {
|
|
43712
44337
|
//`field` match the filedInfo's apiName
|
|
43713
|
-
for (const [op, value] of entries$
|
|
44338
|
+
for (const [op, value] of entries$3(where[field])) {
|
|
43714
44339
|
const operator = operatorToSql(op);
|
|
43715
44340
|
/**
|
|
43716
44341
|
Two types ID processing might be needed. Draft ID swapping is optional, which depends on DraftFunctions existence.
|
|
@@ -44284,6 +44909,12 @@ function isObjectValueNode(node) {
|
|
|
44284
44909
|
function isStringValueNode(node) {
|
|
44285
44910
|
return node.kind === Kind$1.STRING;
|
|
44286
44911
|
}
|
|
44912
|
+
function isIntValueNode(node) {
|
|
44913
|
+
return node.kind === Kind$1.INT;
|
|
44914
|
+
}
|
|
44915
|
+
function isVariableNode(node) {
|
|
44916
|
+
return node.kind === Kind$1.VARIABLE;
|
|
44917
|
+
}
|
|
44287
44918
|
function isFieldNode(node) {
|
|
44288
44919
|
return node !== undefined && node.kind !== undefined ? node.kind === 'Field' : false;
|
|
44289
44920
|
}
|
|
@@ -44875,7 +45506,7 @@ function depth(json, currentLevel = 0) {
|
|
|
44875
45506
|
if (typeof json !== 'object') {
|
|
44876
45507
|
return currentLevel;
|
|
44877
45508
|
}
|
|
44878
|
-
const keys$1 = keys$
|
|
45509
|
+
const keys$1 = keys$3(json);
|
|
44879
45510
|
if (keys$1.length === 0)
|
|
44880
45511
|
return 0;
|
|
44881
45512
|
const depths = keys$1.map((key) => {
|
|
@@ -44928,7 +45559,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
|
|
|
44928
45559
|
return predicates;
|
|
44929
45560
|
const isSpanning = depth(orderBy) > 2;
|
|
44930
45561
|
if (isSpanning) {
|
|
44931
|
-
const keys$1 = keys$
|
|
45562
|
+
const keys$1 = keys$3(orderBy);
|
|
44932
45563
|
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
44933
45564
|
const key = keys$1[i];
|
|
44934
45565
|
const parentFields = objectInfoMap[recordType].fields;
|
|
@@ -44958,7 +45589,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
|
|
|
44958
45589
|
}
|
|
44959
45590
|
}
|
|
44960
45591
|
else {
|
|
44961
|
-
const keys$1 = keys$
|
|
45592
|
+
const keys$1 = keys$3(orderBy);
|
|
44962
45593
|
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
44963
45594
|
const key = keys$1[i];
|
|
44964
45595
|
if (!objectInfoMap[recordType])
|
|
@@ -45173,14 +45804,14 @@ function isLocalCursor(maybeCursor) {
|
|
|
45173
45804
|
typeof maybeCursor.i === 'number');
|
|
45174
45805
|
}
|
|
45175
45806
|
function encodeV1Cursor(cursor) {
|
|
45176
|
-
return base64encode(stringify$
|
|
45807
|
+
return base64encode(stringify$2(cursor));
|
|
45177
45808
|
}
|
|
45178
45809
|
const CURSOR_PARSE_ERROR = 'Unable to parse cursor';
|
|
45179
45810
|
function decodeV1Cursor(base64cursor) {
|
|
45180
45811
|
let maybeCursor;
|
|
45181
45812
|
try {
|
|
45182
45813
|
const cursorString = base64decode(base64cursor);
|
|
45183
|
-
maybeCursor = parse$
|
|
45814
|
+
maybeCursor = parse$2(cursorString);
|
|
45184
45815
|
}
|
|
45185
45816
|
catch (error) {
|
|
45186
45817
|
let message = CURSOR_PARSE_ERROR;
|
|
@@ -45278,7 +45909,7 @@ function mapCursorValue(originalValue, paginationMetadata) {
|
|
|
45278
45909
|
async function mapPaginationCursors(originalAST, variables, store) {
|
|
45279
45910
|
// first pass, identify record query cache keys for reading pagination metadata
|
|
45280
45911
|
let requiredPaginationMetadataKeys = [];
|
|
45281
|
-
visit(originalAST, {
|
|
45912
|
+
visit$1(originalAST, {
|
|
45282
45913
|
Field(node, _key, _parent, _path, ancestors) {
|
|
45283
45914
|
// is it a record query?
|
|
45284
45915
|
if (!isRecordQuery(node)) {
|
|
@@ -45306,7 +45937,7 @@ async function mapPaginationCursors(originalAST, variables, store) {
|
|
|
45306
45937
|
// holds the original cursor values that were mapped back to server cursors
|
|
45307
45938
|
let mappedCursors = new Map();
|
|
45308
45939
|
// rewrite nodes/variables with mapped cursors now that we read the pagination metadata
|
|
45309
|
-
let ast = visit(originalAST, {
|
|
45940
|
+
let ast = visit$1(originalAST, {
|
|
45310
45941
|
Field(node, _key, _parent, _path, ancestors) {
|
|
45311
45942
|
// is it a record query?
|
|
45312
45943
|
if (!isRecordQuery(node)) {
|
|
@@ -45384,7 +46015,7 @@ async function readPaginationMetadataForKeys(keys, query) {
|
|
|
45384
46015
|
const results = await query(sql, keys.map((k) => k + '__pagination'));
|
|
45385
46016
|
for (let row of results.rows) {
|
|
45386
46017
|
let key = row[0].replace(/__pagination$/, '');
|
|
45387
|
-
let metadata = parse$
|
|
46018
|
+
let metadata = parse$2(row[1]);
|
|
45388
46019
|
metadataMap.set(key, metadata);
|
|
45389
46020
|
}
|
|
45390
46021
|
return metadataMap;
|
|
@@ -45488,8 +46119,8 @@ async function connectionResolver(obj, args, context, info) {
|
|
|
45488
46119
|
//map each sql result with the ingestion timestamp to pass it down a level
|
|
45489
46120
|
let records = results.rows.map((row, index) => {
|
|
45490
46121
|
const recordMetadataResult = {
|
|
45491
|
-
recordRepresentation: parse$
|
|
45492
|
-
metadata: parse$
|
|
46122
|
+
recordRepresentation: parse$2(row[0]),
|
|
46123
|
+
metadata: parse$2(row[1]),
|
|
45493
46124
|
};
|
|
45494
46125
|
const { recordRepresentation, metadata } = recordMetadataResult;
|
|
45495
46126
|
context.seenRecordIds.add(recordRepresentation.id);
|
|
@@ -45562,7 +46193,7 @@ function buildKeyStringForRecordQuery(operation, variables, argumentNodes, curre
|
|
|
45562
46193
|
variables,
|
|
45563
46194
|
fragmentMap: {},
|
|
45564
46195
|
});
|
|
45565
|
-
const filteredArgumentNodes = assign$
|
|
46196
|
+
const filteredArgumentNodes = assign$3([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
|
|
45566
46197
|
const argumentString = filteredArgumentNodes.length > 0
|
|
45567
46198
|
? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
|
|
45568
46199
|
: '';
|
|
@@ -45977,7 +46608,7 @@ function generateRecordQueries(schema, objectInfoMap) {
|
|
|
45977
46608
|
// use a set to not allow duplicate scalars causing error(s)
|
|
45978
46609
|
let addedTypedScalars = new Set();
|
|
45979
46610
|
let allPolymorphicFieldTypeNames = new Set();
|
|
45980
|
-
for (const name of keys$
|
|
46611
|
+
for (const name of keys$3(objectInfoMap)) {
|
|
45981
46612
|
const objectInfo = objectInfoMap[name];
|
|
45982
46613
|
const { apiName } = objectInfo;
|
|
45983
46614
|
const type = schema.getType(apiName);
|
|
@@ -46104,7 +46735,7 @@ function extendExistingRecordType(schema, type, objectInfo, objectInfoMap) {
|
|
|
46104
46735
|
// use a set to not allow duplicate scalars causing error(s)
|
|
46105
46736
|
let typedScalars = new Set();
|
|
46106
46737
|
let parentRelationshipFields = new Set();
|
|
46107
|
-
const existingFields = keys$
|
|
46738
|
+
const existingFields = keys$3(type.getFields());
|
|
46108
46739
|
const missingFields = values$2(objectInfo.fields).filter((field) => {
|
|
46109
46740
|
return (existingFields.includes(field.apiName) === false ||
|
|
46110
46741
|
(field.relationshipName !== null && field.referenceToInfos.length > 0));
|
|
@@ -46321,7 +46952,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
|
|
|
46321
46952
|
const operationNode = getOperationFromDocument(config.query);
|
|
46322
46953
|
let topLevelQueries = [];
|
|
46323
46954
|
// assume that 'config.query' has required injected fields.
|
|
46324
|
-
const modifiedAST = visit(config.query, {
|
|
46955
|
+
const modifiedAST = visit$1(config.query, {
|
|
46325
46956
|
Field: {
|
|
46326
46957
|
leave(node) {
|
|
46327
46958
|
if (node.name.value !== `node`)
|
|
@@ -46461,7 +47092,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
|
|
|
46461
47092
|
unmappedDraftIDs: new Set(),
|
|
46462
47093
|
};
|
|
46463
47094
|
let assignedtomeQueryFieldNode = undefined;
|
|
46464
|
-
visit(originalAST, {
|
|
47095
|
+
visit$1(originalAST, {
|
|
46465
47096
|
Argument: {
|
|
46466
47097
|
enter(node, key, parent, path, ancestors) {
|
|
46467
47098
|
const { connection: recordConnectionNode, path: ancesterPath } = findNearestConnectionWithPath(ancestors);
|
|
@@ -46533,7 +47164,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
|
|
|
46533
47164
|
objectInfos = await resolveObjectInfos(objectNodeInfoTree, pathToObjectApiNamesMap, startNodes, objectInfoService);
|
|
46534
47165
|
}
|
|
46535
47166
|
// read pass; gather whats needed
|
|
46536
|
-
visit(originalAST, {
|
|
47167
|
+
visit$1(originalAST, {
|
|
46537
47168
|
Argument: {
|
|
46538
47169
|
leave(node, key, parent, path, ancestors) {
|
|
46539
47170
|
const recordQueryField = findNearestConnection(ancestors);
|
|
@@ -46618,7 +47249,7 @@ async function injectSyntheticFields(originalAST, objectInfoService, draftFuncti
|
|
|
46618
47249
|
},
|
|
46619
47250
|
});
|
|
46620
47251
|
// write pass; inject whats needed
|
|
46621
|
-
const modifiedAST = visit(originalAST, {
|
|
47252
|
+
const modifiedAST = visit$1(originalAST, {
|
|
46622
47253
|
Field: {
|
|
46623
47254
|
leave(node, key, parent, path, ancestors) {
|
|
46624
47255
|
// removes 'ServicesResources' query field node if 'assignedtome' scope shows up
|
|
@@ -46963,7 +47594,7 @@ async function resolveObjectInfos(objectInfotree, pathToObjectApiNamesMap, start
|
|
|
46963
47594
|
// eslint-disable-next-line
|
|
46964
47595
|
throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
|
|
46965
47596
|
}
|
|
46966
|
-
if (keys$
|
|
47597
|
+
if (keys$3(objectInfos).length < startNodes.size) {
|
|
46967
47598
|
// eslint-disable-next-line
|
|
46968
47599
|
throw new Error(`Unable to resolve ObjectInfo(s) for ${Array.from(startNodes)}`);
|
|
46969
47600
|
}
|
|
@@ -47904,7 +48535,7 @@ function removeSyntheticFields(result, query) {
|
|
|
47904
48535
|
output.data.uiapi = { ...output.data.uiapi };
|
|
47905
48536
|
output.data.uiapi.query = { ...output.data.uiapi.query };
|
|
47906
48537
|
const outputApiParent = output.data.uiapi.query;
|
|
47907
|
-
const keys$1 = keys$
|
|
48538
|
+
const keys$1 = keys$3(nodeJson);
|
|
47908
48539
|
keys$1.forEach((recordName) => {
|
|
47909
48540
|
const outputApi = {};
|
|
47910
48541
|
// Each connectionSelection's maps its name or alias to one of returned records. The record name could be `apiName' or alias
|
|
@@ -47924,7 +48555,7 @@ function removeSyntheticFields(result, query) {
|
|
|
47924
48555
|
* @param jsonOutput JsonObject which will be populated with properties. It would only contains properties defined in 'FieldNode'
|
|
47925
48556
|
*/
|
|
47926
48557
|
function createUserJsonOutput(selection, jsonInput, jsonOutput) {
|
|
47927
|
-
const keys$1 = keys$
|
|
48558
|
+
const keys$1 = keys$3(jsonInput);
|
|
47928
48559
|
if (selection.selectionSet) {
|
|
47929
48560
|
createjsonOutput(selection.selectionSet.selections, jsonInput, jsonOutput);
|
|
47930
48561
|
}
|
|
@@ -47933,7 +48564,7 @@ function createUserJsonOutput(selection, jsonInput, jsonOutput) {
|
|
|
47933
48564
|
}
|
|
47934
48565
|
}
|
|
47935
48566
|
function createjsonOutput(selections, jsonInput, jsonOutput) {
|
|
47936
|
-
const keys$1 = keys$
|
|
48567
|
+
const keys$1 = keys$3(jsonInput);
|
|
47937
48568
|
selections.filter(isFieldNode).forEach((subSelection) => {
|
|
47938
48569
|
const fieldName = subSelection.alias ? subSelection.alias.value : subSelection.name.value;
|
|
47939
48570
|
if (keys$1.includes(fieldName)) {
|
|
@@ -48035,8 +48666,9 @@ function createErrorSnapshot(result, snapshot) {
|
|
|
48035
48666
|
},
|
|
48036
48667
|
};
|
|
48037
48668
|
}
|
|
48038
|
-
function createLocalEvalSnapshot(data, seenRecords, recordId, rebuildWithLocalEval) {
|
|
48669
|
+
function createLocalEvalSnapshot(data, seenRecords, recordId, rebuildWithLocalEval, refresh) {
|
|
48039
48670
|
return {
|
|
48671
|
+
refresh,
|
|
48040
48672
|
recordId,
|
|
48041
48673
|
variables: {},
|
|
48042
48674
|
seenRecords,
|
|
@@ -48147,7 +48779,7 @@ function instrumentLimits(ast, variables) {
|
|
|
48147
48779
|
let currentChildRelationships = 0;
|
|
48148
48780
|
let currentRootRecordCount = 0;
|
|
48149
48781
|
let currentTotalRecordCount = 0;
|
|
48150
|
-
visit(ast, {
|
|
48782
|
+
visit$1(ast, {
|
|
48151
48783
|
Field: {
|
|
48152
48784
|
enter(node) {
|
|
48153
48785
|
if (isRecordQuery(node)) {
|
|
@@ -48198,6 +48830,95 @@ function limitForQuery(field, variables) {
|
|
|
48198
48830
|
return first;
|
|
48199
48831
|
}
|
|
48200
48832
|
|
|
48833
|
+
const MAX_RECORD_QUERY_FIELD_COUNT = 100;
|
|
48834
|
+
const MAX_RECORD_QUERY_LIMIT = 200;
|
|
48835
|
+
function enforceFieldLimitOnAST(ast, variables, enforcedLimits = {
|
|
48836
|
+
maxFieldCount: MAX_RECORD_QUERY_FIELD_COUNT,
|
|
48837
|
+
maxRecordLimit: MAX_RECORD_QUERY_LIMIT,
|
|
48838
|
+
}) {
|
|
48839
|
+
const { maxFieldCount, maxRecordLimit } = enforcedLimits;
|
|
48840
|
+
const documentNode = visit(ast, {
|
|
48841
|
+
Field(node) {
|
|
48842
|
+
// is it a record query?
|
|
48843
|
+
if (!isRecordQuery(node)) {
|
|
48844
|
+
return;
|
|
48845
|
+
}
|
|
48846
|
+
// check to see that we have the `first` argument defined
|
|
48847
|
+
if (node.arguments === undefined)
|
|
48848
|
+
return false;
|
|
48849
|
+
let first = node.arguments.find((node) => {
|
|
48850
|
+
return node.name.value === 'first';
|
|
48851
|
+
});
|
|
48852
|
+
if (first === undefined)
|
|
48853
|
+
return false;
|
|
48854
|
+
if (isIntValueNode(first.value) || isVariableNode(first.value)) {
|
|
48855
|
+
// total number of requested fields in a record query
|
|
48856
|
+
const fieldCount = findRecordQueryNodeFieldCount(node);
|
|
48857
|
+
if (isIntValueNode(first.value)) {
|
|
48858
|
+
const originalValue = Number(first.value.value);
|
|
48859
|
+
if (isNaN(originalValue))
|
|
48860
|
+
return false;
|
|
48861
|
+
// if the `first` value is already less than the `maxRecordLimit`
|
|
48862
|
+
// or the field count is less than `maxFieldCount` then
|
|
48863
|
+
// there is no need to update the argument node value
|
|
48864
|
+
if (originalValue <= maxRecordLimit || fieldCount <= maxFieldCount)
|
|
48865
|
+
return false;
|
|
48866
|
+
// else we cap the truncated limit
|
|
48867
|
+
return {
|
|
48868
|
+
...node,
|
|
48869
|
+
arguments: node.arguments.map((argument) => {
|
|
48870
|
+
if (argument !== first)
|
|
48871
|
+
return argument;
|
|
48872
|
+
return {
|
|
48873
|
+
...argument,
|
|
48874
|
+
value: {
|
|
48875
|
+
kind: Kind.INT,
|
|
48876
|
+
value: maxRecordLimit,
|
|
48877
|
+
},
|
|
48878
|
+
};
|
|
48879
|
+
}),
|
|
48880
|
+
};
|
|
48881
|
+
}
|
|
48882
|
+
else if (isVariableNode(first.value) && variables !== undefined) {
|
|
48883
|
+
const variableName = first.value.name.value;
|
|
48884
|
+
// ensure the variable is a number
|
|
48885
|
+
const variableValue = Number(variables[variableName]);
|
|
48886
|
+
if (isNaN(variableValue))
|
|
48887
|
+
return;
|
|
48888
|
+
// if the variable is less than the `maxRecordLimit` or
|
|
48889
|
+
// field count is less then `maxFieldCount`
|
|
48890
|
+
// then there is no need to alter the variable
|
|
48891
|
+
if (variableValue <= maxRecordLimit || fieldCount <= maxFieldCount)
|
|
48892
|
+
return;
|
|
48893
|
+
// else we update the variable to the truncated limited
|
|
48894
|
+
variables[variableName] = maxRecordLimit;
|
|
48895
|
+
}
|
|
48896
|
+
}
|
|
48897
|
+
},
|
|
48898
|
+
});
|
|
48899
|
+
return documentNode;
|
|
48900
|
+
}
|
|
48901
|
+
/**
|
|
48902
|
+
* Count all the requested fields to be returned in the users request
|
|
48903
|
+
* @param recordQueryNode
|
|
48904
|
+
* @returns
|
|
48905
|
+
*/
|
|
48906
|
+
function findRecordQueryNodeFieldCount(recordQueryNode) {
|
|
48907
|
+
if (recordQueryNode.selectionSet === undefined)
|
|
48908
|
+
return 0;
|
|
48909
|
+
const edges = recordQueryNode.selectionSet.selections.filter(isFieldNode).find((node) => {
|
|
48910
|
+
return node.name.value === 'edges';
|
|
48911
|
+
});
|
|
48912
|
+
if (edges === undefined || edges.selectionSet === undefined)
|
|
48913
|
+
return 0;
|
|
48914
|
+
const node = edges.selectionSet.selections.filter(isFieldNode).find((node) => {
|
|
48915
|
+
return node.name.value === 'node';
|
|
48916
|
+
});
|
|
48917
|
+
if (node === undefined || node.selectionSet === undefined)
|
|
48918
|
+
return 0;
|
|
48919
|
+
return node.selectionSet.selections.length || 0;
|
|
48920
|
+
}
|
|
48921
|
+
|
|
48201
48922
|
function generateUniqueRecordId() {
|
|
48202
48923
|
return `UiApi::GraphQLRepresentation:${Date.now() + Math.random().toFixed(5).split('.')[1]}`;
|
|
48203
48924
|
}
|
|
@@ -48219,7 +48940,7 @@ const replaceDraftIdsInVariables = (variables, draftFunctions, unmappedDraftIDs)
|
|
|
48219
48940
|
}
|
|
48220
48941
|
else if (typeof object === 'object' && object !== null) {
|
|
48221
48942
|
let source = object;
|
|
48222
|
-
return keys$
|
|
48943
|
+
return keys$3(source).reduce((acc, key) => {
|
|
48223
48944
|
acc[key] = replace(source[key]);
|
|
48224
48945
|
return acc;
|
|
48225
48946
|
}, {});
|
|
@@ -48228,7 +48949,7 @@ const replaceDraftIdsInVariables = (variables, draftFunctions, unmappedDraftIDs)
|
|
|
48228
48949
|
return object;
|
|
48229
48950
|
}
|
|
48230
48951
|
};
|
|
48231
|
-
let newVariables = keys$
|
|
48952
|
+
let newVariables = keys$3(variables).reduce((acc, key) => {
|
|
48232
48953
|
acc[key] = replace(variables[key]);
|
|
48233
48954
|
return acc;
|
|
48234
48955
|
}, {});
|
|
@@ -48240,7 +48961,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48240
48961
|
const getCanonicalId = getCanonicalIdFunction(luvio);
|
|
48241
48962
|
return async function draftAwareGraphQLAdapter(config, requestContext = {}) {
|
|
48242
48963
|
//create a copy to not accidentally modify the AST in the astResolver map of luvio
|
|
48243
|
-
const copy = parse$
|
|
48964
|
+
const copy = parse$2(stringify$2(config.query));
|
|
48244
48965
|
// the injected ast has extra fields needed for eval in it
|
|
48245
48966
|
let injectedAST;
|
|
48246
48967
|
// the cursor mapped ast is passed upstream so it won't reject on our local cursors
|
|
@@ -48255,11 +48976,11 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48255
48976
|
isDraftId,
|
|
48256
48977
|
getCanonicalId,
|
|
48257
48978
|
};
|
|
48979
|
+
const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, requestContext.eventObservers || []);
|
|
48258
48980
|
try {
|
|
48259
48981
|
// NB: This occurs BEFORE synthetic field injection on purpose to
|
|
48260
48982
|
// ensure we don't charge the caller for spanning records we inject
|
|
48261
48983
|
// on their behalf.
|
|
48262
|
-
const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, requestContext.eventObservers || []);
|
|
48263
48984
|
const queryInstrumentation = instrumentLimits(copy, config.variables || {});
|
|
48264
48985
|
eventEmitter({
|
|
48265
48986
|
type: 'graphql-query-instrumentation',
|
|
@@ -48269,12 +48990,17 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48269
48990
|
catch (_a) {
|
|
48270
48991
|
// ignore errors instrumenting limits
|
|
48271
48992
|
}
|
|
48993
|
+
let fieldLimitedAST = copy;
|
|
48994
|
+
if (graphqQueryFieldLimit.isOpen({ fallback: true })) {
|
|
48995
|
+
// enfore server field count limits on the AST
|
|
48996
|
+
fieldLimitedAST = enforceFieldLimitOnAST(copy, config.variables || {});
|
|
48997
|
+
}
|
|
48272
48998
|
try {
|
|
48273
48999
|
({
|
|
48274
49000
|
modifiedAST: injectedAST,
|
|
48275
49001
|
objectInfos: objectInfoNeeded,
|
|
48276
49002
|
unmappedDraftIDs,
|
|
48277
|
-
} = await injectSyntheticFields(
|
|
49003
|
+
} = await injectSyntheticFields(fieldLimitedAST, objectInfoService, draftFunctions, config.variables));
|
|
48278
49004
|
({ ast: cursorMappedAST, mappedCursors } = await mapPaginationCursors(injectedAST, config.variables || {}, store));
|
|
48279
49005
|
if (config.variables) {
|
|
48280
49006
|
config.variables = replaceDraftIdsInVariables(config.variables, draftFunctions, unmappedDraftIDs);
|
|
@@ -48329,7 +49055,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48329
49055
|
} = await evaluate({
|
|
48330
49056
|
...config,
|
|
48331
49057
|
//need to create another copy of the ast for future writes
|
|
48332
|
-
query: parse$
|
|
49058
|
+
query: parse$2(stringify$2(injectedAST)),
|
|
48333
49059
|
}, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors));
|
|
48334
49060
|
}
|
|
48335
49061
|
catch (throwable) {
|
|
@@ -48391,7 +49117,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48391
49117
|
// the error is network error or 504), otherwise we spread over
|
|
48392
49118
|
// the non-eval'ed snapshot (which will be either Fulfilled or Stale)
|
|
48393
49119
|
const resultSnapshot = nonEvaluatedSnapshot.state === 'Error'
|
|
48394
|
-
? createLocalEvalSnapshot(gqlResult, seenRecords, recordId, rebuildWithLocalEval)
|
|
49120
|
+
? createLocalEvalSnapshot(gqlResult, seenRecords, recordId, rebuildWithLocalEval, nonEvaluatedSnapshot.refresh)
|
|
48395
49121
|
: {
|
|
48396
49122
|
...nonEvaluatedSnapshot,
|
|
48397
49123
|
data: gqlResult,
|
|
@@ -48414,6 +49140,9 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
48414
49140
|
},
|
|
48415
49141
|
};
|
|
48416
49142
|
}
|
|
49143
|
+
if (refresh === undefined) {
|
|
49144
|
+
eventEmitter({ type: 'graphql-luvio-refresh-undefined' });
|
|
49145
|
+
}
|
|
48417
49146
|
if (possibleStaleRecordMap.size > 0) {
|
|
48418
49147
|
initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
|
|
48419
49148
|
resultSnapshot.state = 'Stale';
|
|
@@ -48442,7 +49171,7 @@ function makeGetRecordsConfig(keyMap) {
|
|
|
48442
49171
|
|
|
48443
49172
|
function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, isDraftId, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy) {
|
|
48444
49173
|
return async function environmentAwareGraphQLBatchAdapter(config, requestContext = {}) {
|
|
48445
|
-
const batchQueryCopy = config.batchQuery.map((query) => parse$
|
|
49174
|
+
const batchQueryCopy = config.batchQuery.map((query) => parse$2(stringify$2(query)));
|
|
48446
49175
|
let injectedBatchQuery = [];
|
|
48447
49176
|
const getCanonicalId = getCanonicalIdFunction(luvio);
|
|
48448
49177
|
const draftFunctions = {
|
|
@@ -48666,14 +49395,14 @@ const recordIdGenerator = (id) => {
|
|
|
48666
49395
|
*/
|
|
48667
49396
|
|
|
48668
49397
|
|
|
48669
|
-
const { keys: keys$
|
|
48670
|
-
const { stringify: stringify$
|
|
48671
|
-
const { push
|
|
49398
|
+
const { keys: keys$2, create: create$2, assign: assign$2, entries: entries$2 } = Object;
|
|
49399
|
+
const { stringify: stringify$1, parse: parse$1 } = JSON;
|
|
49400
|
+
const { push, join, slice } = Array.prototype;
|
|
48672
49401
|
const { isArray, from } = Array;
|
|
48673
49402
|
|
|
48674
49403
|
function ldsParamsToString(params) {
|
|
48675
|
-
const returnParams = create$
|
|
48676
|
-
const keys$1 = keys$
|
|
49404
|
+
const returnParams = create$2(null);
|
|
49405
|
+
const keys$1 = keys$2(params);
|
|
48677
49406
|
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
48678
49407
|
const key = keys$1[i];
|
|
48679
49408
|
const value = params[key];
|
|
@@ -48690,8 +49419,8 @@ function ldsParamsToString(params) {
|
|
|
48690
49419
|
else {
|
|
48691
49420
|
returnParams[key] = `${value}`;
|
|
48692
49421
|
}
|
|
48693
|
-
if (isObject(value) === true && keys$
|
|
48694
|
-
returnParams[key] = stringify$
|
|
49422
|
+
if (isObject(value) === true && keys$2(value).length > 0) {
|
|
49423
|
+
returnParams[key] = stringify$1(value);
|
|
48695
49424
|
}
|
|
48696
49425
|
}
|
|
48697
49426
|
return returnParams;
|
|
@@ -48750,13 +49479,13 @@ function stringifyIfPresent(value) {
|
|
|
48750
49479
|
if (value === undefined || value === null) {
|
|
48751
49480
|
return null;
|
|
48752
49481
|
}
|
|
48753
|
-
return stringify$
|
|
49482
|
+
return stringify$1(value);
|
|
48754
49483
|
}
|
|
48755
49484
|
function parseIfPresent(value) {
|
|
48756
49485
|
if (value === undefined || value === null || value === '') {
|
|
48757
49486
|
return null;
|
|
48758
49487
|
}
|
|
48759
|
-
return parse$
|
|
49488
|
+
return parse$1(value);
|
|
48760
49489
|
}
|
|
48761
49490
|
function buildNimbusNetworkPluginRequest(resourceRequest, resourceRequestContext) {
|
|
48762
49491
|
const { basePath, baseUri, method, headers, queryParams, body } = resourceRequest;
|
|
@@ -48847,10 +49576,10 @@ class ScopedFields {
|
|
|
48847
49576
|
fields.forEach(this.addField, this);
|
|
48848
49577
|
}
|
|
48849
49578
|
toQueryParameterValue() {
|
|
48850
|
-
const joinedFields = join
|
|
49579
|
+
const joinedFields = join.call(Object.keys(this.fields), SEPARATOR_BETWEEN_FIELDS);
|
|
48851
49580
|
return this.isUnScoped()
|
|
48852
49581
|
? joinedFields
|
|
48853
|
-
: join
|
|
49582
|
+
: join.call([this.scope, joinedFields], SEPARATOR_BETWEEN_SCOPE_AND_FIELDS);
|
|
48854
49583
|
}
|
|
48855
49584
|
toQueryParams() {
|
|
48856
49585
|
return this.isUnScoped() ? Object.keys(this.fields) : this.toQueryParameterValue();
|
|
@@ -48918,7 +49647,7 @@ class ScopedFieldsCollection {
|
|
|
48918
49647
|
if (chunk !== undefined)
|
|
48919
49648
|
result.push(chunk);
|
|
48920
49649
|
}
|
|
48921
|
-
return join
|
|
49650
|
+
return join.call(result, SEPARATOR_BETWEEN_SCOPES);
|
|
48922
49651
|
}
|
|
48923
49652
|
/**
|
|
48924
49653
|
* split the ScopedFields into multiple ScopedFields
|
|
@@ -49091,12 +49820,12 @@ function buildAggregateUiUrl(params, resourceRequest) {
|
|
|
49091
49820
|
optionalFields,
|
|
49092
49821
|
};
|
|
49093
49822
|
const queryString = [];
|
|
49094
|
-
for (const [key, value] of entries$
|
|
49823
|
+
for (const [key, value] of entries$2(mergedParams)) {
|
|
49095
49824
|
if (value !== undefined) {
|
|
49096
49825
|
queryString.push(`${key}=${isArray(value) ? value.join(',') : value}`);
|
|
49097
49826
|
}
|
|
49098
49827
|
}
|
|
49099
|
-
return `${resourceRequest.baseUri}${resourceRequest.basePath}?${join
|
|
49828
|
+
return `${resourceRequest.baseUri}${resourceRequest.basePath}?${join.call(queryString, '&')}`;
|
|
49100
49829
|
}
|
|
49101
49830
|
function shouldUseAggregateUiForFields(fieldsArray, optionalFieldsArray, maxLengthPerChunk) {
|
|
49102
49831
|
return fieldsArray.length + optionalFieldsArray.length >= maxLengthPerChunk;
|
|
@@ -49107,7 +49836,7 @@ function isSpanningRecord(fieldValue) {
|
|
|
49107
49836
|
function mergeRecordFields(first, second) {
|
|
49108
49837
|
const { fields: targetFields } = first;
|
|
49109
49838
|
const { fields: sourceFields } = second;
|
|
49110
|
-
const fieldNames = keys$
|
|
49839
|
+
const fieldNames = keys$2(sourceFields);
|
|
49111
49840
|
for (let i = 0, len = fieldNames.length; i < len; i += 1) {
|
|
49112
49841
|
const fieldName = fieldNames[i];
|
|
49113
49842
|
const sourceField = sourceFields[fieldName];
|
|
@@ -49205,7 +49934,7 @@ function buildCompositeRequestByFields(referenceId, resourceRequest, recordsComp
|
|
|
49205
49934
|
const url = buildAggregateUiUrl({
|
|
49206
49935
|
fields: fieldChunk,
|
|
49207
49936
|
}, resourceRequest);
|
|
49208
|
-
push
|
|
49937
|
+
push.call(compositeRequest, {
|
|
49209
49938
|
url,
|
|
49210
49939
|
referenceId: `${referenceId}_fields_${i}`,
|
|
49211
49940
|
});
|
|
@@ -49220,7 +49949,7 @@ function buildCompositeRequestByFields(referenceId, resourceRequest, recordsComp
|
|
|
49220
49949
|
const url = buildAggregateUiUrl({
|
|
49221
49950
|
optionalFields: fieldChunk,
|
|
49222
49951
|
}, resourceRequest);
|
|
49223
|
-
push
|
|
49952
|
+
push.call(compositeRequest, {
|
|
49224
49953
|
url,
|
|
49225
49954
|
referenceId: `${referenceId}_optionalFields_${i}`,
|
|
49226
49955
|
});
|
|
@@ -49260,8 +49989,8 @@ function getMaxLengthPerChunkAllowed(request) {
|
|
|
49260
49989
|
// Too much work to get exact length of the final url, so use stringified json to get the rough length.
|
|
49261
49990
|
const roughUrlLengthWithoutFieldsAndOptionFields = request.basePath.length +
|
|
49262
49991
|
request.baseUri.length +
|
|
49263
|
-
(request.urlParams ? stringify$
|
|
49264
|
-
stringify$
|
|
49992
|
+
(request.urlParams ? stringify$1(request.urlParams).length : 0) +
|
|
49993
|
+
stringify$1({ ...request.queryParams, fields: {}, optionalFields: {} }).length;
|
|
49265
49994
|
// MAX_URL_LENGTH - full lenght without fields, optionalFields
|
|
49266
49995
|
return MAX_URL_LENGTH - roughUrlLengthWithoutFieldsAndOptionFields;
|
|
49267
49996
|
}
|
|
@@ -49271,7 +50000,7 @@ function calculateEstimatedTotalUrlLength(request) {
|
|
|
49271
50000
|
const { baseUri, basePath, queryParams } = request;
|
|
49272
50001
|
let url = `${baseUri}${basePath}`;
|
|
49273
50002
|
if (queryParams) {
|
|
49274
|
-
const queryParamString = entries$
|
|
50003
|
+
const queryParamString = entries$2(queryParams)
|
|
49275
50004
|
.map(([key, value]) => `${key}=${value}`)
|
|
49276
50005
|
.join('&');
|
|
49277
50006
|
if (queryParamString) {
|
|
@@ -49484,10 +50213,6 @@ function makeNetworkAdapterChunkRecordFields(networkAdapter, instrumentationSink
|
|
|
49484
50213
|
}, networkAdapter);
|
|
49485
50214
|
}
|
|
49486
50215
|
|
|
49487
|
-
const { keys: keys$2, create: create$2, assign: assign$2, entries: entries$2 } = Object;
|
|
49488
|
-
const { stringify: stringify$1, parse: parse$1 } = JSON;
|
|
49489
|
-
const { push, join, slice } = Array.prototype;
|
|
49490
|
-
|
|
49491
50216
|
// so eslint doesn't complain about nimbus
|
|
49492
50217
|
/* global __nimbus */
|
|
49493
50218
|
/**
|
|
@@ -49503,10 +50228,10 @@ class NimbusDraftQueue {
|
|
|
49503
50228
|
if (callProxyMethod === undefined) {
|
|
49504
50229
|
return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
|
|
49505
50230
|
}
|
|
49506
|
-
const serializedAction = stringify$
|
|
50231
|
+
const serializedAction = stringify$4([handlerId, data]);
|
|
49507
50232
|
return new Promise((resolve, reject) => {
|
|
49508
50233
|
callProxyMethod('enqueue', serializedAction, (serializedActionResponse) => {
|
|
49509
|
-
const response = parse$
|
|
50234
|
+
const response = parse$4(serializedActionResponse);
|
|
49510
50235
|
resolve(response);
|
|
49511
50236
|
}, (errorMessage) => {
|
|
49512
50237
|
reject(new Error(errorMessage));
|
|
@@ -49527,8 +50252,8 @@ class NimbusDraftQueue {
|
|
|
49527
50252
|
return Promise.reject(new Error('callProxyMethod not defined on the nimbus plugin'));
|
|
49528
50253
|
}
|
|
49529
50254
|
return new Promise((resolve, reject) => {
|
|
49530
|
-
callProxyMethod('getQueueActions', stringify$
|
|
49531
|
-
resolve(parse$
|
|
50255
|
+
callProxyMethod('getQueueActions', stringify$4([]), (serializedQueue) => {
|
|
50256
|
+
resolve(parse$4(serializedQueue));
|
|
49532
50257
|
}, (errorMessage) => {
|
|
49533
50258
|
reject(new Error(errorMessage));
|
|
49534
50259
|
});
|
|
@@ -49539,17 +50264,17 @@ class NimbusDraftQueue {
|
|
|
49539
50264
|
if (callProxyMethod === undefined) {
|
|
49540
50265
|
return Promise.reject('callProxyMethod not defined on the nimbus plugin');
|
|
49541
50266
|
}
|
|
49542
|
-
const stringifiedArgs = stringify$
|
|
50267
|
+
const stringifiedArgs = stringify$4([action]);
|
|
49543
50268
|
return new Promise((resolve, reject) => {
|
|
49544
50269
|
callProxyMethod('getDataForAction', stringifiedArgs, (data) => {
|
|
49545
50270
|
if (data === undefined) {
|
|
49546
50271
|
resolve(undefined);
|
|
49547
50272
|
}
|
|
49548
50273
|
else {
|
|
49549
|
-
resolve(parse$
|
|
50274
|
+
resolve(parse$4(data));
|
|
49550
50275
|
}
|
|
49551
50276
|
}, (serializedError) => {
|
|
49552
|
-
reject(parse$
|
|
50277
|
+
reject(parse$4(serializedError));
|
|
49553
50278
|
});
|
|
49554
50279
|
});
|
|
49555
50280
|
}
|
|
@@ -49619,7 +50344,7 @@ function normalizeError(err) {
|
|
|
49619
50344
|
else if (typeof err === 'string') {
|
|
49620
50345
|
return new Error(err);
|
|
49621
50346
|
}
|
|
49622
|
-
return new Error(stringify$
|
|
50347
|
+
return new Error(stringify$4(err));
|
|
49623
50348
|
}
|
|
49624
50349
|
|
|
49625
50350
|
const O11Y_NAMESPACE_LDS_MOBILE = 'lds-mobile';
|
|
@@ -49631,6 +50356,7 @@ const GRAPHQL_EVAL_ROOT_QUERY_COUNT = 'gql-eval-root-query-count';
|
|
|
49631
50356
|
const GRAPHQL_EVAL_TOTAL_QUERY_COUNT = 'gql-eval-total-query-count';
|
|
49632
50357
|
const GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT = 'gql-eval-max-child-count';
|
|
49633
50358
|
const GRAPHQL_EVAL_QUERY_RECORD_COUNT = 'gql-eval-query-record-count';
|
|
50359
|
+
const GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED = 'gql-snapshot-refresh-undefined';
|
|
49634
50360
|
/** Draft Queue */
|
|
49635
50361
|
const DRAFT_QUEUE_STATE_STARTED = 'draft-queue-state-started';
|
|
49636
50362
|
const DRAFT_QUEUE_STATE_ERROR = 'draft-queue-state-error';
|
|
@@ -49657,6 +50383,11 @@ const GRAPHQL_SQL_EVAL_PRECONDITION_ERROR = 'gql-sql-pre-eval-error';
|
|
|
49657
50383
|
const GRAPHQL_CREATE_SNAPSHOT_ERROR = 'gql-create-snapshot-error';
|
|
49658
50384
|
const DRAFT_AWARE_CREATE_CONTENT_DOCUMENT_AND_VERSION_ERROR = 'draft-aware-create-content-document-and-version-error';
|
|
49659
50385
|
const ldsMobileInstrumentation = getInstrumentation(O11Y_NAMESPACE_LDS_MOBILE);
|
|
50386
|
+
const nimbusLogger = typeof __nimbus !== 'undefined' &&
|
|
50387
|
+
__nimbus.plugins !== undefined &&
|
|
50388
|
+
__nimbus.plugins.JSLoggerPlugin !== undefined
|
|
50389
|
+
? __nimbus.plugins.JSLoggerPlugin
|
|
50390
|
+
: undefined;
|
|
49660
50391
|
function reportGraphqlQueryParseError(err) {
|
|
49661
50392
|
const error = normalizeError(err);
|
|
49662
50393
|
const errorCode = GRAPHQL_QUERY_PARSE_ERROR;
|
|
@@ -49698,7 +50429,13 @@ function reportGraphqlQueryInstrumentation(data) {
|
|
|
49698
50429
|
ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT, data.maxChildRelationships, queryBuckets);
|
|
49699
50430
|
ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_QUERY_RECORD_COUNT, data.requestedRecordCount, recordBuckets);
|
|
49700
50431
|
}
|
|
49701
|
-
function
|
|
50432
|
+
function incrementGraphQLRefreshUndfined() {
|
|
50433
|
+
ldsMobileInstrumentation.incrementCounter(GRAPHQL_SNAPSHOT_REFRESH_UNDEFINED);
|
|
50434
|
+
}
|
|
50435
|
+
function reportDraftActionEvent(state, draftCount, message) {
|
|
50436
|
+
if (nimbusLogger) {
|
|
50437
|
+
nimbusLogger.logInfo(`Draft action event: ${state}, depth: ${draftCount}${message ? `, message: ${message}` : ''}`);
|
|
50438
|
+
}
|
|
49702
50439
|
switch (state) {
|
|
49703
50440
|
case 'added':
|
|
49704
50441
|
ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_ACTION_ADDED);
|
|
@@ -49720,7 +50457,10 @@ function reportDraftActionEvent(state) {
|
|
|
49720
50457
|
break;
|
|
49721
50458
|
}
|
|
49722
50459
|
}
|
|
49723
|
-
function reportDraftQueueState(state) {
|
|
50460
|
+
function reportDraftQueueState(state, draftCount) {
|
|
50461
|
+
if (nimbusLogger) {
|
|
50462
|
+
nimbusLogger.logInfo(`Draft state changed: ${state}, depth: ${draftCount}`);
|
|
50463
|
+
}
|
|
49724
50464
|
switch (state) {
|
|
49725
50465
|
case 'started':
|
|
49726
50466
|
ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_STATE_STARTED);
|
|
@@ -49814,53 +50554,73 @@ const withInstrumentation = (operation, config) => {
|
|
|
49814
50554
|
* A HOF that returns an instrumented DraftQueue
|
|
49815
50555
|
*/
|
|
49816
50556
|
function instrumentDraftQueue(queue) {
|
|
49817
|
-
|
|
50557
|
+
const mergeActions = function (targetActionId, sourceActionId) {
|
|
50558
|
+
return withInstrumentation(() => queue.mergeActions(targetActionId, sourceActionId), {
|
|
50559
|
+
metricName: DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS,
|
|
50560
|
+
tags: {},
|
|
50561
|
+
logError: false,
|
|
50562
|
+
});
|
|
50563
|
+
};
|
|
50564
|
+
const overriddenQueue = create$5(queue, { mergeActions: { value: mergeActions } });
|
|
50565
|
+
overriddenQueue.registerOnChangedListener((draftQueueEvent) => {
|
|
49818
50566
|
switch (draftQueueEvent.type) {
|
|
49819
|
-
case DraftQueueEventType.QueueStateChanged:
|
|
50567
|
+
case DraftQueueEventType.QueueStateChanged: {
|
|
49820
50568
|
switch (draftQueueEvent.state) {
|
|
49821
50569
|
case DraftQueueState.Error:
|
|
49822
|
-
reportDraftQueueState('error');
|
|
50570
|
+
reportDraftQueueState('error', draftQueueEvent.draftCount);
|
|
49823
50571
|
break;
|
|
49824
50572
|
case DraftQueueState.Started:
|
|
49825
|
-
reportDraftQueueState('started');
|
|
50573
|
+
reportDraftQueueState('started', draftQueueEvent.draftCount);
|
|
49826
50574
|
break;
|
|
49827
50575
|
case DraftQueueState.Stopped:
|
|
49828
|
-
reportDraftQueueState('stopped');
|
|
50576
|
+
reportDraftQueueState('stopped', draftQueueEvent.draftCount);
|
|
49829
50577
|
break;
|
|
49830
50578
|
case DraftQueueState.Waiting:
|
|
49831
|
-
reportDraftQueueState('waiting');
|
|
50579
|
+
reportDraftQueueState('waiting', draftQueueEvent.draftCount);
|
|
49832
50580
|
break;
|
|
49833
50581
|
}
|
|
49834
50582
|
break;
|
|
50583
|
+
}
|
|
49835
50584
|
case DraftQueueEventType.ActionAdded:
|
|
49836
|
-
reportDraftActionEvent('added');
|
|
50585
|
+
reportDraftActionEvent('added', draftQueueEvent.draftCount);
|
|
49837
50586
|
break;
|
|
49838
50587
|
case DraftQueueEventType.ActionUploading:
|
|
49839
|
-
reportDraftActionEvent('uploading');
|
|
50588
|
+
reportDraftActionEvent('uploading', draftQueueEvent.draftCount);
|
|
49840
50589
|
break;
|
|
49841
50590
|
case DraftQueueEventType.ActionCompleted:
|
|
49842
|
-
reportDraftActionEvent('completed');
|
|
50591
|
+
reportDraftActionEvent('completed', draftQueueEvent.draftCount);
|
|
49843
50592
|
break;
|
|
49844
50593
|
case DraftQueueEventType.ActionDeleted:
|
|
49845
|
-
reportDraftActionEvent('deleted');
|
|
50594
|
+
reportDraftActionEvent('deleted', draftQueueEvent.draftCount);
|
|
49846
50595
|
break;
|
|
49847
50596
|
case DraftQueueEventType.ActionFailed:
|
|
49848
|
-
|
|
50597
|
+
{
|
|
50598
|
+
const failedEvent = draftQueueEvent;
|
|
50599
|
+
const failureMessage = obtainFailureMessage(failedEvent.action.error);
|
|
50600
|
+
reportDraftActionEvent('failed', draftQueueEvent.draftCount, failureMessage);
|
|
50601
|
+
}
|
|
49849
50602
|
break;
|
|
49850
50603
|
case DraftQueueEventType.ActionUpdated:
|
|
49851
|
-
reportDraftActionEvent('updated');
|
|
50604
|
+
reportDraftActionEvent('updated', draftQueueEvent.draftCount);
|
|
49852
50605
|
break;
|
|
49853
50606
|
}
|
|
49854
50607
|
return Promise.resolve();
|
|
49855
50608
|
});
|
|
49856
|
-
|
|
49857
|
-
|
|
49858
|
-
|
|
49859
|
-
|
|
49860
|
-
|
|
49861
|
-
|
|
49862
|
-
|
|
49863
|
-
|
|
50609
|
+
return overriddenQueue;
|
|
50610
|
+
}
|
|
50611
|
+
function obtainFailureMessage(error) {
|
|
50612
|
+
if (error instanceof Error) {
|
|
50613
|
+
return error.message;
|
|
50614
|
+
}
|
|
50615
|
+
else if (typeof error === 'string') {
|
|
50616
|
+
return error;
|
|
50617
|
+
}
|
|
50618
|
+
else if (error.status && error.statusText) {
|
|
50619
|
+
return `status=${error.status}-${error.statusText}`;
|
|
50620
|
+
}
|
|
50621
|
+
else {
|
|
50622
|
+
return JSON.stringify(error);
|
|
50623
|
+
}
|
|
49864
50624
|
}
|
|
49865
50625
|
|
|
49866
50626
|
// so eslint doesn't complain about nimbus
|
|
@@ -49939,7 +50699,7 @@ function enableObjectInfoCaching(env, ensureObjectInfoCached) {
|
|
|
49939
50699
|
function dataIsObjectInfo(key, data) {
|
|
49940
50700
|
return incomingObjectInfos.has(key);
|
|
49941
50701
|
}
|
|
49942
|
-
return create$
|
|
50702
|
+
return create$5(env, {
|
|
49943
50703
|
handleSuccessResponse: { value: handleSuccessResponse },
|
|
49944
50704
|
storePublish: { value: storePublish },
|
|
49945
50705
|
});
|
|
@@ -50040,8 +50800,8 @@ class ObjectInfoService {
|
|
|
50040
50800
|
}
|
|
50041
50801
|
};
|
|
50042
50802
|
// Local in-memory cache for apiName to key prefixes
|
|
50043
|
-
this.apiNameToKeyPrefixMemoryCache = create$
|
|
50044
|
-
this.keyPrefixToApiNameMemoryCache = create$
|
|
50803
|
+
this.apiNameToKeyPrefixMemoryCache = create$5(null);
|
|
50804
|
+
this.keyPrefixToApiNameMemoryCache = create$5(null);
|
|
50045
50805
|
}
|
|
50046
50806
|
/**
|
|
50047
50807
|
* Size of return map not necessarily correlated with number of inputs. The
|
|
@@ -50066,6 +50826,10 @@ class ObjectInfoService {
|
|
|
50066
50826
|
}
|
|
50067
50827
|
return objectInfos;
|
|
50068
50828
|
}
|
|
50829
|
+
async getObjectInfo(apiName) {
|
|
50830
|
+
const map = await this.getObjectInfos([apiName]);
|
|
50831
|
+
return map[apiName];
|
|
50832
|
+
}
|
|
50069
50833
|
async getObjectInfoDirectory() {
|
|
50070
50834
|
const snapshot = await this.getObjectInfoDirectoryAdapter({});
|
|
50071
50835
|
if (!snapshot ||
|
|
@@ -50114,6 +50878,9 @@ function instrumentGraphQLEval(adapter) {
|
|
|
50114
50878
|
case 'graphql-query-instrumentation':
|
|
50115
50879
|
reportGraphqlQueryInstrumentation(data.data);
|
|
50116
50880
|
break;
|
|
50881
|
+
case 'graphql-luvio-refresh-undefined':
|
|
50882
|
+
incrementGraphQLRefreshUndfined();
|
|
50883
|
+
break;
|
|
50117
50884
|
}
|
|
50118
50885
|
}
|
|
50119
50886
|
},
|
|
@@ -50185,8 +50952,8 @@ function registerReportObserver(reportObserver) {
|
|
|
50185
50952
|
const index = reportObservers.indexOf(reportObserver);
|
|
50186
50953
|
if (index > -1) {
|
|
50187
50954
|
reportObservers = [
|
|
50188
|
-
...slice.call(reportObservers, 0, index),
|
|
50189
|
-
...slice.call(reportObservers, index + 1),
|
|
50955
|
+
...slice$1.call(reportObservers, 0, index),
|
|
50956
|
+
...slice$1.call(reportObservers, index + 1),
|
|
50190
50957
|
];
|
|
50191
50958
|
}
|
|
50192
50959
|
};
|
|
@@ -50826,7 +51593,7 @@ function makeEnvironmentGraphqlAware(environment) {
|
|
|
50826
51593
|
}
|
|
50827
51594
|
return environment.applyCachePolicy(luvio, adapterRequestContext, buildSnapshotContext, localBuildCachedSnapshot, buildNetworkSnapshot);
|
|
50828
51595
|
};
|
|
50829
|
-
return create$
|
|
51596
|
+
return create$5(environment, {
|
|
50830
51597
|
rebuildSnapshot: { value: rebuildSnapshot },
|
|
50831
51598
|
applyCachePolicy: { value: applyCachePolicy },
|
|
50832
51599
|
setDefaultCachePolicy: { value: environment.setDefaultCachePolicy.bind(environment) },
|
|
@@ -52104,7 +52871,7 @@ async function aggressiveTrim(data, deallocateFn, options = {}) {
|
|
|
52104
52871
|
const batchSize = options.batchSize !== undefined ? options.batchSize : DEFAULT_MAX_BATCH_SIZE;
|
|
52105
52872
|
let deallocatedCount = 0;
|
|
52106
52873
|
const { pendingTrimKeys, retainedIds, storeRecords } = data;
|
|
52107
|
-
const storeKeyLength = keys$
|
|
52874
|
+
const storeKeyLength = keys$5(storeRecords).length;
|
|
52108
52875
|
if (storeKeyLength <= maxStoreRecords) {
|
|
52109
52876
|
return { deallocatedCount, trimKeysSkipped: pendingTrimKeys };
|
|
52110
52877
|
}
|
|
@@ -52172,7 +52939,7 @@ function setupObserver() {
|
|
|
52172
52939
|
registerReportObserver((report) => {
|
|
52173
52940
|
__nimbus.plugins.LdsObserverPlugin.logAdapterExecution({
|
|
52174
52941
|
name: report.adapterName,
|
|
52175
|
-
serializedConfig: stringify$
|
|
52942
|
+
serializedConfig: stringify$4(report.config),
|
|
52176
52943
|
status: report.result,
|
|
52177
52944
|
duration: report.executionTime,
|
|
52178
52945
|
});
|
|
@@ -52335,7 +53102,7 @@ function stripMetaschemaFromFieldNode(fieldNode) {
|
|
|
52335
53102
|
return fieldNode;
|
|
52336
53103
|
}
|
|
52337
53104
|
function stripDocumentOfMetaschema(documentNode) {
|
|
52338
|
-
return visit(documentNode, {
|
|
53105
|
+
return visit$1(documentNode, {
|
|
52339
53106
|
Field(node) {
|
|
52340
53107
|
return stripMetaschemaFromFieldNode(node);
|
|
52341
53108
|
},
|
|
@@ -52840,7 +53607,7 @@ const shouldFlush = (key, value) => {
|
|
|
52840
53607
|
if (value && typeof value === 'object') {
|
|
52841
53608
|
const fields = value.fields;
|
|
52842
53609
|
if (fields && typeof fields === 'object') {
|
|
52843
|
-
const keys = keys$
|
|
53610
|
+
const keys = keys$5(fields);
|
|
52844
53611
|
for (const key of keys) {
|
|
52845
53612
|
const field = fields[key];
|
|
52846
53613
|
if (fields && field.__state && field.__state.pending === true) {
|
|
@@ -53009,4 +53776,4 @@ register({
|
|
|
53009
53776
|
});
|
|
53010
53777
|
|
|
53011
53778
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
53012
|
-
// version: 1.
|
|
53779
|
+
// version: 1.317.0-374876d2a3
|