@salesforce/lds-runtime-mobile 1.303.0 → 1.305.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 CHANGED
@@ -20,7 +20,7 @@ import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrum
20
20
  import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
21
21
  import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
22
22
  import { parseAndVisit, Kind as Kind$1, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from '@luvio/graphql-parser';
23
- import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, isStoreKeyRecordViewEntity, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, getRecordId18, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion, getRecordsAdapterFactory } from '@salesforce/lds-adapters-uiapi-mobile';
23
+ import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, isStoreKeyRecordViewEntity, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, getRecordId18, getRecordsAdapterFactory, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion } from '@salesforce/lds-adapters-uiapi-mobile';
24
24
  import ldsIdempotencyWriteDisabled from '@salesforce/gate/lds.idempotencyWriteDisabled';
25
25
  import ldsBackdatingEnabled from '@salesforce/gate/lds.backdatingEnabled';
26
26
  import FIRST_DAY_OF_WEEK from '@salesforce/i18n/firstDayOfWeek';
@@ -28,6 +28,7 @@ import caseSensitiveUserId from '@salesforce/user/Id';
28
28
  import { idleDetector, getInstrumentation } from 'o11y/client';
29
29
  import ldsUseShortUrlGate from '@salesforce/gate/lds.useShortUrl';
30
30
  import { instrument as instrument$1 } from '@salesforce/lds-bindings';
31
+ import ldsAdapterO11yLoggingGate from '@salesforce/gate/lmr.ldsAdapterO11yLogging';
31
32
  import LOCALE from '@salesforce/i18n/locale';
32
33
  import CURRENCY from '@salesforce/i18n/currency';
33
34
  import TIMEZONE from '@salesforce/i18n/timeZone';
@@ -4753,12 +4754,6 @@ function hasGraphQlErrors$1(response) {
4753
4754
  }
4754
4755
 
4755
4756
  const GRAPHQL_EVAL_NAMESPACE$1 = 'graphql-eval';
4756
- function isGraphQLEvalEvent(customEvent) {
4757
- if (customEvent.namespace === GRAPHQL_EVAL_NAMESPACE$1) {
4758
- return true;
4759
- }
4760
- return false;
4761
- }
4762
4757
 
4763
4758
  function isStoreEvalSnapshot(snapshot) {
4764
4759
  return 'rebuildWithStoreEval' in snapshot;
@@ -5775,12 +5770,60 @@ class DurableDraftQueue {
5775
5770
  await this.startQueue();
5776
5771
  }
5777
5772
  }
5773
+ async updateDraftAction(action) {
5774
+ // stop queue manually
5775
+ this.stopQueueManually();
5776
+ const actionStatus = await this.statusOfAction(action.id);
5777
+ if (actionStatus === DraftActionStatus.Uploading) {
5778
+ return Promise.reject('cannot update an uploading action');
5779
+ }
5780
+ // save the action into the draft store
5781
+ await this.draftStore.writeAction(action);
5782
+ // make the handler replay these drafts on the record
5783
+ const handler = this.getHandler(action.handler);
5784
+ const queue = await this.getQueueActions();
5785
+ await handler.handleActionEnqueued(action, queue);
5786
+ // start queue safely
5787
+ return this.startQueueSafe();
5788
+ }
5789
+ async statusOfAction(actionId) {
5790
+ const queue = await this.getQueueActions();
5791
+ const actions = queue.filter((action) => action.id === actionId);
5792
+ if (actions.length === 0) {
5793
+ return Promise.reject('cannot update non-existent action');
5794
+ }
5795
+ const action = actions[0];
5796
+ return action.status;
5797
+ }
5778
5798
  replaceAction(targetActionId, sourceActionId) {
5779
5799
  return this.replaceOrMergeActions(targetActionId, sourceActionId, false);
5780
5800
  }
5781
5801
  mergeActions(targetActionId, sourceActionId) {
5782
5802
  return this.replaceOrMergeActions(targetActionId, sourceActionId, true);
5783
5803
  }
5804
+ async retryAction(actionId) {
5805
+ this.stopQueueManually();
5806
+ const actions = await this.getQueueActions();
5807
+ const target = actions[0];
5808
+ if (!target || target.id !== actionId) {
5809
+ throw Error(`Action ${actionId} not found at the head of the draft queue`);
5810
+ }
5811
+ if (!isDraftError(target)) {
5812
+ throw Error(`Action ${actionId} is not in Error state`);
5813
+ }
5814
+ let pendingAction = {
5815
+ ...target,
5816
+ status: DraftActionStatus.Pending,
5817
+ error: undefined,
5818
+ };
5819
+ await this.draftStore.writeAction(pendingAction);
5820
+ await this.notifyChangedListeners({
5821
+ type: DraftQueueEventType.ActionUpdated,
5822
+ action: pendingAction,
5823
+ });
5824
+ await this.startQueueSafe();
5825
+ return pendingAction;
5826
+ }
5784
5827
  async setMetadata(actionId, metadata) {
5785
5828
  const keys$1 = keys$6(metadata);
5786
5829
  const compatibleKeys = keys$1.filter((key) => {
@@ -6778,6 +6821,60 @@ class DraftManager {
6778
6821
  };
6779
6822
  });
6780
6823
  }
6824
+ async mergePerformQuickAction(actionId, fields) {
6825
+ if (!this.isValidFieldMap(fields)) {
6826
+ return Promise.reject('fields is not valid');
6827
+ }
6828
+ const queue = await this.draftQueue.getQueueActions();
6829
+ const actions = queue.filter((action) => action.id === actionId);
6830
+ if (actions.length === 0) {
6831
+ return Promise.reject('cannot edit non-existent action');
6832
+ }
6833
+ const action = actions[0];
6834
+ if (!this.isPerformQuickActionDraft(action, 'post')) {
6835
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
6836
+ }
6837
+ action.data.body.fields = { ...action.data.body.fields, ...fields };
6838
+ await this.draftQueue.updateDraftAction(action);
6839
+ return this.buildDraftQueueItem(action);
6840
+ }
6841
+ isValidFieldMap(fields) {
6842
+ const keys$1 = keys$6(fields);
6843
+ const validTypes = ['string', 'number', 'null', 'boolean'];
6844
+ for (let i = 0; i < keys$1.length; i++) {
6845
+ const key = keys$1[i];
6846
+ const value = fields[key];
6847
+ if (!validTypes.includes(typeof value)) {
6848
+ return false;
6849
+ }
6850
+ }
6851
+ return true;
6852
+ }
6853
+ isPerformQuickActionDraft(action, method) {
6854
+ const data = action.data;
6855
+ const isPerformQuickAction = data.basePath.startsWith('/ui-api/actions/perform-quick-action/');
6856
+ const methodMatches = data.method === method;
6857
+ const notUploading = action.status !== DraftActionStatus.Uploading;
6858
+ return isPerformQuickAction && methodMatches && notUploading;
6859
+ }
6860
+ async mergePerformUpdateRecordQuickAction(actionId, fields) {
6861
+ if (!this.isValidFieldMap(fields)) {
6862
+ return Promise.reject('fields is not valid');
6863
+ }
6864
+ const queue = await this.draftQueue.getQueueActions();
6865
+ const actions = queue.filter((action) => action.id === actionId);
6866
+ if (actions.length === 0) {
6867
+ return Promise.reject('cannot edit non-existent action');
6868
+ }
6869
+ const action = actions[0];
6870
+ if (!this.isPerformQuickActionDraft(action, 'patch')) {
6871
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
6872
+ }
6873
+ const data = action.data;
6874
+ data.body.fields = { ...data.body.fields, ...fields };
6875
+ await this.draftQueue.updateDraftAction(action);
6876
+ return this.buildDraftQueueItem(action);
6877
+ }
6781
6878
  buildDraftQueueItem(action) {
6782
6879
  const operationType = getOperationTypeFrom(action);
6783
6880
  const { id, status, timestamp, targetId, metadata } = action;
@@ -6873,6 +6970,18 @@ class DraftManager {
6873
6970
  return this.buildDraftQueueItem(updatedAction);
6874
6971
  });
6875
6972
  }
6973
+ /**
6974
+ * Retries a draft action that is in error state without any modification.
6975
+ *
6976
+ * @param actionId The id of the draft action that should be retried
6977
+ * @throws If the draft action is not at the front of the draft queue or is not
6978
+ * in error state.
6979
+ */
6980
+ async retryAction(actionId) {
6981
+ return this.draftQueue.retryAction(actionId).then((updatedAction) => {
6982
+ return this.buildDraftQueueItem(updatedAction);
6983
+ });
6984
+ }
6876
6985
  }
6877
6986
 
6878
6987
  function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
@@ -7085,6 +7194,12 @@ function getDenormalizedRecord(recordKey, durableStore) {
7085
7194
  function isStoreRecordError(storeRecord) {
7086
7195
  return storeRecord.__type === 'error';
7087
7196
  }
7197
+ function isDraftFieldPending(field) {
7198
+ return !!(field.__state && field.__state.pending === true);
7199
+ }
7200
+ function isDraftFieldMissing(field) {
7201
+ return !!(field.__state && field.__state.isMissing === true);
7202
+ }
7088
7203
 
7089
7204
  /**
7090
7205
  * Checks if a resource request is a GET method on the record endpoint
@@ -7776,12 +7891,9 @@ function applyReferenceLinksToDraft(record, draftMetadata) {
7776
7891
  }
7777
7892
  const { dataType, relationshipName, referenceToInfos } = fieldInfo;
7778
7893
  const draftFieldNode = record.fields[draftField];
7779
- // JHORST: revisit this logic
7780
7894
  // do not try to apply drafts on nodes that are pending or missing
7781
- if (draftFieldNode.__state !== undefined) {
7782
- if (draftFieldNode.__state.pending === true ||
7783
- draftFieldNode.__state.isMissing === true)
7784
- continue;
7895
+ if (isDraftFieldPending(draftFieldNode) || isDraftFieldMissing(draftFieldNode)) {
7896
+ continue;
7785
7897
  }
7786
7898
  const draftFieldValue = draftFieldNode.value;
7787
7899
  if (dataType === 'Reference' && relationshipName !== null) {
@@ -8772,7 +8884,29 @@ function isCreateContentDocumentAndVersionDraftAdapterEvent(customEvent) {
8772
8884
  return customEvent.namespace === CONTENT_DOCUMENT_AND_VERSION_NAMESPACE;
8773
8885
  }
8774
8886
 
8887
+ // so eslint doesn't complain about nimbus
8888
+ /* global __nimbus */
8775
8889
  const ContentDocumentCompositeKeyPrefix = 'UiApi::ContentDocumentCompositeRepresentation:';
8890
+ function chunkToBase64(chunk) {
8891
+ let binary = '';
8892
+ const chunkSize = 32 * 1024;
8893
+ for (let i = 0; i < chunk.length; i += chunkSize) {
8894
+ binary += String.fromCharCode.apply(null, chunk.subarray(i, i + chunkSize));
8895
+ }
8896
+ return btoa(binary);
8897
+ }
8898
+ async function streamBufferToBinaryStore(binaryStore, buffer, mimeType) {
8899
+ const uri = await binaryStore.createStream(mimeType);
8900
+ const bufferSize = 64 * 1024; // 64k buffer size
8901
+ const uint8Array = new Uint8Array(buffer);
8902
+ for (let offset = 0; offset < uint8Array.length; offset += bufferSize) {
8903
+ const chunk = uint8Array.subarray(offset, Math.min(offset + bufferSize, uint8Array.length));
8904
+ const base64Chunk = chunkToBase64(chunk);
8905
+ await binaryStore.writeToStream(uri, base64Chunk);
8906
+ }
8907
+ await binaryStore.closeStream(uri);
8908
+ return uri;
8909
+ }
8776
8910
  function createContentDocumentAndVersionDraftAdapterFactory(luvio, binaryStore, actionHandler) {
8777
8911
  const overriddenLuvio = buildLuvioOverrideForDraftAdapters(luvio, actionHandler, (key) => {
8778
8912
  // if the key is for our top-level response shape
@@ -8795,7 +8929,14 @@ function createContentDocumentAndVersionDraftAdapterFactory(luvio, binaryStore,
8795
8929
  const { fileData } = config;
8796
8930
  const { name, size, type } = fileData;
8797
8931
  const buffer = await fileData.arrayBuffer();
8798
- const uri = await binaryStore.store(new Uint8Array(buffer), type, size);
8932
+ var uri;
8933
+ // see if new chunking-api exists, if it doesnt fall back to memory-intensive mobile api
8934
+ if (!__nimbus.plugins.LdsBinaryStorePlugin.createStream) {
8935
+ uri = await binaryStore.store(new Uint8Array(buffer), type, size);
8936
+ }
8937
+ else {
8938
+ uri = await streamBufferToBinaryStore(binaryStore, buffer, type);
8939
+ }
8799
8940
  config.fileData = {
8800
8941
  isFileReference: true,
8801
8942
  handle: uri,
@@ -9634,7 +9775,7 @@ function recordLoaderFactory(query) {
9634
9775
  return new DataLoader(batchRecordQuery);
9635
9776
  }
9636
9777
 
9637
- function createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions) {
9778
+ function createContext(store, objectInfos, eventEmitter, settings, snapshot, mappedCursors = new Map(), draftFunctions) {
9638
9779
  store.query.bind(store);
9639
9780
  const query = (sql, params) => {
9640
9781
  const now = Date.now();
@@ -9661,11 +9802,19 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot, dra
9661
9802
  Record,
9662
9803
  snapshot,
9663
9804
  seenRecordIds: new Set(),
9805
+ possibleStaleRecordMap: new Map(),
9664
9806
  draftFunctions,
9807
+ mappedCursors,
9665
9808
  };
9666
9809
  }
9667
9810
 
9668
9811
  const GRAPHQL_EVAL_NAMESPACE = 'graphql-eval';
9812
+ function isGraphQLEvalEvent(customEvent) {
9813
+ if (customEvent.namespace === GRAPHQL_EVAL_NAMESPACE) {
9814
+ return true;
9815
+ }
9816
+ return false;
9817
+ }
9669
9818
 
9670
9819
  function removeUndefined(array) {
9671
9820
  return array.reduce((accu, item) => {
@@ -10272,7 +10421,6 @@ function isTodayStartOfWeek() {
10272
10421
 
10273
10422
  const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
10274
10423
  const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
10275
- const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
10276
10424
 
10277
10425
  const MultiPickListValueSeparator = ';';
10278
10426
  function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
@@ -10813,14 +10961,10 @@ function buildQuery(config) {
10813
10961
  const predicates = buildPredicates(config);
10814
10962
  const orderBy = buildOrderBy(config);
10815
10963
  const sql = `
10816
- SELECT "${config.alias}".data
10964
+ SELECT "${config.alias}".data, "${config.alias}".metadata
10817
10965
  FROM lds_data "${config.alias}" ${joins.sql}
10818
10966
  WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
10819
10967
  AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = '${config.alias}'
10820
- AND (
10821
- json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
10822
- OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
10823
- )
10824
10968
  ${predicates.sql}
10825
10969
  ${orderBy.sql}
10826
10970
  LIMIT ?
@@ -10832,7 +10976,6 @@ function buildQuery(config) {
10832
10976
  const bindings = [
10833
10977
  // bindings from predicates on joins
10834
10978
  ...joins.bindings,
10835
- config.ingestionTimestamp,
10836
10979
  // where clause and parent scope bindings
10837
10980
  ...predicates.bindings,
10838
10981
  // limit binding
@@ -10859,29 +11002,19 @@ function buildJoins(config) {
10859
11002
  if (allJoins.length === 0)
10860
11003
  return { sql, bindings };
10861
11004
  sql = allJoins.reduce((joinAccumulator, join) => {
10862
- let timestampAdded = false;
10863
11005
  const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
10864
11006
  let joined_sql;
10865
- const joinMetadataTimestamp = ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`;
10866
11007
  // predicate on a value, use the newly joined table
10867
11008
  if ('type' in condition) {
10868
11009
  const { sql, binding } = predicateToSQL(condition, join.alias);
10869
- joined_sql = ` AND ${sql}${timestampAdded ? '' : joinMetadataTimestamp}`;
11010
+ joined_sql = ` AND ${sql}`;
10870
11011
  bindings.push(...binding);
10871
- if (timestampAdded === false) {
10872
- bindings.push(config.ingestionTimestamp);
10873
- timestampAdded = true;
10874
- }
10875
11012
  }
10876
11013
  else {
10877
11014
  // predicate on a path
10878
11015
  const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
10879
11016
  const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
10880
- joined_sql = `${left} = ${right}${timestampAdded ? '' : joinMetadataTimestamp}`;
10881
- if (timestampAdded === false) {
10882
- bindings.push(config.ingestionTimestamp);
10883
- timestampAdded = true;
10884
- }
11017
+ joined_sql = `${left} = ${right}`;
10885
11018
  }
10886
11019
  conditionAccumulator += joined_sql;
10887
11020
  return conditionAccumulator;
@@ -10990,17 +11123,22 @@ function requestsDraftsField(recordFieldNode) {
10990
11123
  });
10991
11124
  return Boolean(draftsFieldSelection);
10992
11125
  }
10993
- function isRecordQuery(recordQueryField) {
10994
- if (recordQueryField !== undefined && recordQueryField.directives) {
10995
- return recordQueryField.directives.some((directive) => {
10996
- return (directive.arguments &&
10997
- directive.arguments
10998
- .map((argument) => argument.value)
10999
- .filter(isStringValueNode)
11000
- .some((categoryName) => categoryName.value === RECORD_QUERY));
11001
- });
11002
- }
11003
- return false;
11126
+ function fieldHasCategory(field, categories) {
11127
+ if (!field.directives)
11128
+ return false;
11129
+ return field.directives.some((directive) => {
11130
+ return (directive.arguments &&
11131
+ directive.arguments
11132
+ .map((argument) => argument.value)
11133
+ .filter(isStringValueNode)
11134
+ .some((categoryName) => categories.some((c) => c === categoryName.value)));
11135
+ });
11136
+ }
11137
+ function isRecordQuery(field) {
11138
+ return field !== undefined && fieldHasCategory(field, [RECORD_QUERY]);
11139
+ }
11140
+ function isChildRelationshipQuery(field) {
11141
+ return fieldHasCategory(field, [CHILD_RELATIONSHIP]);
11004
11142
  }
11005
11143
  // finds connection field with 'recordQuery' and 'childRelationship' directive.
11006
11144
  function findNearestConnection(ancestors) {
@@ -11550,11 +11688,15 @@ async function readIngestionTimestampForKey(key, query) {
11550
11688
  }
11551
11689
  return ingestionTimestamp;
11552
11690
  }
11553
- async function readPaginationMetadataForKey(key, query) {
11554
- const sql = `SELECT data FROM lds_data WHERE key=?`;
11555
- const results = await query(sql, [key + '__pagination']);
11556
- const [paginationMetadata] = results.rows.map((row) => parse$3(row[0]));
11557
- return paginationMetadata || {};
11691
+ function isObjectDefinitionNode(node) {
11692
+ const { kind } = node;
11693
+ return typeof kind === 'string' && kind === 'OperationDefinition';
11694
+ }
11695
+ function operationNodeAncestor(ancestors) {
11696
+ let operationNode = ancestors.find((a) => {
11697
+ return !(a instanceof Array) && isObjectDefinitionNode(a);
11698
+ });
11699
+ return operationNode;
11558
11700
  }
11559
11701
 
11560
11702
  function findSpanningField(name) {
@@ -11755,44 +11897,87 @@ function atobPolyfill(data) {
11755
11897
  const base64encode = typeof btoa === 'function' ? btoa : btoaPolyfill;
11756
11898
  const base64decode = typeof atob === 'function' ? atob : atobPolyfill;
11757
11899
 
11900
+ // this truthy value is used to indicate a premature end of results
11901
+ const EARLY_END = 1;
11758
11902
  function cursorResolver(source) {
11759
- return encodeV1Cursor(source.index);
11903
+ let cursor = {
11904
+ i: source.index,
11905
+ };
11906
+ if (source.earlyEnd) {
11907
+ cursor.e = EARLY_END;
11908
+ }
11909
+ return encodeV1Cursor(cursor);
11760
11910
  }
11761
11911
  function pageInfoResolver(source) {
11762
11912
  if (source.records.length === 0) {
11913
+ // we may have found no records, but if more exist we need to
11914
+ // return a valid cursor that can be passed as the next `after`
11915
+ if (source.earlyEnd) {
11916
+ return {
11917
+ startCursor: null,
11918
+ endCursor: encodeV1Cursor({
11919
+ i: source.offset,
11920
+ e: EARLY_END,
11921
+ }),
11922
+ hasNextPage: source.hasNextPage,
11923
+ };
11924
+ }
11763
11925
  return {
11764
11926
  startCursor: null,
11765
11927
  endCursor: null,
11766
- hasNextPage: false,
11928
+ hasNextPage: source.hasNextPage,
11767
11929
  };
11768
11930
  }
11769
11931
  let startIndex = source.records[0].index;
11932
+ let startCursor = {
11933
+ i: startIndex,
11934
+ };
11770
11935
  let endIndex = source.records[source.records.length - 1].index;
11936
+ let endCursor = {
11937
+ i: endIndex,
11938
+ };
11939
+ if (source.earlyEnd) {
11940
+ startCursor.e = EARLY_END;
11941
+ endCursor.e = EARLY_END;
11942
+ }
11771
11943
  return {
11772
- startCursor: encodeV1Cursor(startIndex),
11773
- endCursor: encodeV1Cursor(endIndex),
11944
+ startCursor: encodeV1Cursor(startCursor),
11945
+ endCursor: encodeV1Cursor(endCursor),
11774
11946
  hasNextPage: source.hasNextPage,
11775
11947
  };
11776
11948
  }
11777
11949
  function pageResultCountResolver(source) {
11778
11950
  return source.records.length;
11779
11951
  }
11780
- function encodeV1Cursor(index) {
11781
- return base64encode(`v1:${index}`);
11952
+ function isLocalCursor(maybeCursor) {
11953
+ return (!!maybeCursor &&
11954
+ typeof maybeCursor === 'object' &&
11955
+ 'i' in maybeCursor &&
11956
+ typeof maybeCursor.i === 'number');
11957
+ }
11958
+ function encodeV1Cursor(cursor) {
11959
+ return base64encode(stringify$3(cursor));
11782
11960
  }
11783
- const cursorRegex = /^v1:(?<index>\d+)$/;
11961
+ const CURSOR_PARSE_ERROR = 'Unable to parse cursor';
11784
11962
  function decodeV1Cursor(base64cursor) {
11785
- const cursor = base64decode(base64cursor);
11786
- if (!cursor) {
11963
+ let maybeCursor;
11964
+ try {
11965
+ const cursorString = base64decode(base64cursor);
11966
+ maybeCursor = parse$3(cursorString);
11967
+ }
11968
+ catch (error) {
11969
+ let message = CURSOR_PARSE_ERROR;
11970
+ if (error instanceof Error) {
11971
+ message += ': ' + error.message;
11972
+ }
11787
11973
  // eslint-disable-next-line @salesforce/lds/no-error-in-production
11788
- throw new Error('Unable to parse cursor');
11974
+ throw new Error(message);
11789
11975
  }
11790
- const found = cursor.match(cursorRegex);
11791
- if (!found || !found.groups) {
11976
+ if (!isLocalCursor(maybeCursor)) {
11792
11977
  // eslint-disable-next-line @salesforce/lds/no-error-in-production
11793
- throw new Error('Unable to parse cursor');
11978
+ throw new Error(CURSOR_PARSE_ERROR);
11794
11979
  }
11795
- return Number(found.groups.index);
11980
+ return maybeCursor;
11796
11981
  }
11797
11982
  /**
11798
11983
  * Check the selections for any selection matching `pageInfo { hasNextPage }`
@@ -11830,6 +12015,164 @@ function selectionIncludesHasNextPage(selections, fragments) {
11830
12015
  return false;
11831
12016
  }
11832
12017
 
12018
+ const END_CURSOR = '__END__';
12019
+ // find the closest matching cursor in the server pagination metadata
12020
+ function mapCursorValue(originalValue, paginationMetadata) {
12021
+ let mappedValue = null;
12022
+ if (!originalValue) {
12023
+ return mappedValue;
12024
+ }
12025
+ // flip the pagination metadata into an array by index.
12026
+ let cursors = [];
12027
+ for (const [cursor, index] of Object.entries(paginationMetadata)) {
12028
+ if (index === undefined)
12029
+ continue;
12030
+ cursors[index] = cursor;
12031
+ }
12032
+ let cursor = decodeV1Cursor(originalValue);
12033
+ // cursors containe 1-based indexes, adjust back to 0-based
12034
+ let index = cursor.i - 1;
12035
+ if (
12036
+ // cursor.e being truthy means we had premature end of results and
12037
+ // should pin to the last known server cursor
12038
+ !cursor.e &&
12039
+ // check that the index we have is within the bounds of known cursors
12040
+ index >= 0 &&
12041
+ index < cursors.length &&
12042
+ // and make sure the cursor is not the server end marker
12043
+ cursors[index] !== END_CURSOR) {
12044
+ mappedValue = cursors[index];
12045
+ }
12046
+ else {
12047
+ // in this case, either our local cursor is beyond the max server cursor, or
12048
+ // the local cursor precedes the max server cursor and we ran out of locally
12049
+ // cached results. either way, find the last known server cursor and map to that.
12050
+ for (let i = cursors.length; i > 0; --i) {
12051
+ let cursor = cursors[i - 1];
12052
+ if (cursor !== END_CURSOR) {
12053
+ mappedValue = cursor;
12054
+ break;
12055
+ }
12056
+ }
12057
+ }
12058
+ return mappedValue;
12059
+ }
12060
+ // map all pagination cursors in the document
12061
+ async function mapPaginationCursors(originalAST, variables, store) {
12062
+ // first pass, identify record query cache keys for reading pagination metadata
12063
+ let requiredPaginationMetadataKeys = [];
12064
+ visit(originalAST, {
12065
+ Field(node, _key, _parent, _path, ancestors) {
12066
+ // is it a record query?
12067
+ if (!isRecordQuery(node)) {
12068
+ return;
12069
+ }
12070
+ // does it have a defined `after` argument?
12071
+ let after = node.arguments &&
12072
+ node.arguments.find((a) => {
12073
+ return a.name.value === 'after';
12074
+ });
12075
+ if (after && (after.value.kind === 'StringValue' || after.value.kind === 'Variable')) {
12076
+ let operationNode = operationNodeAncestor(ancestors);
12077
+ if (!operationNode) {
12078
+ return false;
12079
+ }
12080
+ let key = buildKeyStringForRecordQuery(operationNode, variables, node.arguments || [], node.name.value);
12081
+ requiredPaginationMetadataKeys.push(key);
12082
+ }
12083
+ // don't need to descend into this node
12084
+ return false;
12085
+ },
12086
+ });
12087
+ // read pagination metadata for identified record queries
12088
+ let paginationMetadataMap = await readPaginationMetadataForKeys(requiredPaginationMetadataKeys, store.query.bind(store));
12089
+ // holds the original cursor values that were mapped back to server cursors
12090
+ let mappedCursors = new Map();
12091
+ // rewrite nodes/variables with mapped cursors now that we read the pagination metadata
12092
+ let ast = visit(originalAST, {
12093
+ Field(node, _key, _parent, _path, ancestors) {
12094
+ // is it a record query?
12095
+ if (!isRecordQuery(node)) {
12096
+ // not returning false, we might be in the parent of a record query
12097
+ return;
12098
+ }
12099
+ // does it have a defined `after` argument?
12100
+ if (!node.arguments)
12101
+ return false;
12102
+ let after = node.arguments.find((a) => {
12103
+ return a.name.value === 'after';
12104
+ });
12105
+ if (!after)
12106
+ return false;
12107
+ if (after.value.kind === 'StringValue' || after.value.kind === 'Variable') {
12108
+ let operationNode = operationNodeAncestor(ancestors);
12109
+ if (!operationNode) {
12110
+ return false;
12111
+ }
12112
+ let key = buildKeyStringForRecordQuery(operationNode, variables, node.arguments || [], node.name.value);
12113
+ // pagination metadata may be missing, e.g. due to being offline
12114
+ let paginationMetadata = paginationMetadataMap.get(key) || {};
12115
+ if (after.value.kind === 'StringValue') {
12116
+ let originalValue = after.value.value;
12117
+ mappedCursors.set(key, originalValue);
12118
+ let mappedValue = mapCursorValue(originalValue, paginationMetadata);
12119
+ if (!mappedValue) {
12120
+ // there were no results from the server, remove after argument
12121
+ return {
12122
+ ...node,
12123
+ arguments: node.arguments.filter((a) => a !== after),
12124
+ };
12125
+ }
12126
+ // return a new replacement node
12127
+ return {
12128
+ ...node,
12129
+ arguments: node.arguments.map((a) => {
12130
+ if (a !== after)
12131
+ return a;
12132
+ return {
12133
+ ...a,
12134
+ value: {
12135
+ kind: 'StringValue',
12136
+ value: mappedValue,
12137
+ },
12138
+ };
12139
+ }),
12140
+ };
12141
+ }
12142
+ else if (after.value.kind === 'Variable') {
12143
+ // rewrite the variable
12144
+ let variableName = after.value.name.value;
12145
+ let variableValue = variables[variableName];
12146
+ mappedCursors.set(key, variableValue);
12147
+ let mappedValue = mapCursorValue(variableValue, paginationMetadata);
12148
+ variables[variableName] = mappedValue;
12149
+ }
12150
+ // don't need to descend into this node
12151
+ return false;
12152
+ }
12153
+ },
12154
+ });
12155
+ return {
12156
+ ast,
12157
+ mappedCursors,
12158
+ };
12159
+ }
12160
+ async function readPaginationMetadataForKeys(keys, query) {
12161
+ let metadataMap = new Map();
12162
+ if (keys.length === 0)
12163
+ return metadataMap;
12164
+ const sql = `SELECT key, data FROM lds_data WHERE key in (${Array(keys.length)
12165
+ .fill('?')
12166
+ .join(',')})`;
12167
+ const results = await query(sql, keys.map((k) => k + '__pagination'));
12168
+ for (let row of results.rows) {
12169
+ let key = row[0].replace(/__pagination$/, '');
12170
+ let metadata = parse$3(row[1]);
12171
+ metadataMap.set(key, metadata);
12172
+ }
12173
+ return metadataMap;
12174
+ }
12175
+
11833
12176
  /*
11834
12177
  resolves connections...
11835
12178
  */
@@ -11851,8 +12194,14 @@ async function connectionResolver(obj, args, context, info) {
11851
12194
  const childRelationship = parentObjectInfo &&
11852
12195
  parentObjectInfo.childRelationships.find((rel) => rel.relationshipName === info.fieldName);
11853
12196
  // or emit/throw if we want to report it
11854
- if (!childRelationship)
11855
- return { records: [], hasNextPage: false };
12197
+ if (!childRelationship) {
12198
+ return {
12199
+ records: [],
12200
+ hasNextPage: false,
12201
+ earlyEnd: false,
12202
+ offset: 0,
12203
+ };
12204
+ }
11856
12205
  alias = childRelationship.childObjectApiName;
11857
12206
  childRelationshipFieldName = childRelationship.fieldName;
11858
12207
  }
@@ -11871,7 +12220,12 @@ async function connectionResolver(obj, args, context, info) {
11871
12220
  }
11872
12221
  let offset = 0;
11873
12222
  if (args.after) {
11874
- offset = decodeV1Cursor(args.after) + 1;
12223
+ let originalCursor = context.mappedCursors.get(queryCacheKey);
12224
+ if (!originalCursor) {
12225
+ // eslint-disable-next-line @salesforce/lds/no-error-in-production
12226
+ throw new Error('Internal Error: unable to determine `after` cursor value');
12227
+ }
12228
+ offset = decodeV1Cursor(originalCursor).i;
11875
12229
  }
11876
12230
  // if the query wants to know `hasNextPage` then we need to request 1 additional record
11877
12231
  let selections = info.fieldNodes
@@ -11880,7 +12234,7 @@ async function connectionResolver(obj, args, context, info) {
11880
12234
  let wantsHasNextPage = selectionIncludesHasNextPage(selections, info.fragments);
11881
12235
  let paginationMetadata = undefined;
11882
12236
  if (wantsHasNextPage) {
11883
- paginationMetadata = await readPaginationMetadataForKey(queryCacheKey, query);
12237
+ paginationMetadata = await readPaginationMetadataForKeys([queryCacheKey], query);
11884
12238
  }
11885
12239
  let internalLimit = limit + (wantsHasNextPage ? 1 : 0);
11886
12240
  // Alias starts as entity's ApiName
@@ -11891,36 +12245,60 @@ async function connectionResolver(obj, args, context, info) {
11891
12245
  orderBy: orderByToPredicate(args.orderBy, alias, alias, context.objectInfos),
11892
12246
  limit: internalLimit,
11893
12247
  offset,
11894
- ingestionTimestamp,
11895
12248
  };
11896
12249
  const { sql, bindings } = buildQuery(queryConfig);
11897
12250
  const results = await query(sql, bindings);
11898
12251
  let hasNextPage = false;
12252
+ let earlyEnd = false;
11899
12253
  if (wantsHasNextPage) {
11900
12254
  if (results.rows.length > limit) {
11901
12255
  // more records exist in the cache
11902
12256
  hasNextPage = true;
11903
12257
  results.rows.pop();
11904
12258
  }
11905
- else if (!paginationMetadata || paginationMetadata.__END__ === undefined) {
12259
+ else if (!paginationMetadata ||
12260
+ !paginationMetadata.has(queryCacheKey) ||
12261
+ paginationMetadata.get(queryCacheKey).__END__ === undefined) {
11906
12262
  // more records may exist on the server
11907
12263
  hasNextPage = true;
12264
+ // we hit the end of our local records, so we need to know that we
12265
+ // should start at the end of known server cursors
12266
+ if (results.rows.length < limit) {
12267
+ earlyEnd = true;
12268
+ }
11908
12269
  }
11909
12270
  }
11910
12271
  //map each sql result with the ingestion timestamp to pass it down a level
11911
- let records = results.rows
11912
- .map((row) => parse$3(row[0]))
11913
- .map((recordRepresentation, index) => {
12272
+ let records = results.rows.map((row, index) => {
12273
+ const recordMetadataResult = {
12274
+ recordRepresentation: parse$3(row[0]),
12275
+ metadata: parse$3(row[1]),
12276
+ };
12277
+ const { recordRepresentation, metadata } = recordMetadataResult;
11914
12278
  context.seenRecordIds.add(recordRepresentation.id);
12279
+ if (metadata.ingestionTimestamp < ingestionTimestamp &&
12280
+ recordRepresentation.drafts === undefined) {
12281
+ if (context.possibleStaleRecordMap.has(recordRepresentation.apiName) === false) {
12282
+ context.possibleStaleRecordMap.set(recordRepresentation.apiName, []);
12283
+ }
12284
+ const ids = context.possibleStaleRecordMap.get(recordRepresentation.apiName);
12285
+ if (ids !== undefined) {
12286
+ ids.push(recordRepresentation.id);
12287
+ context.possibleStaleRecordMap.set(recordRepresentation.apiName, ids);
12288
+ }
12289
+ }
11915
12290
  return {
11916
12291
  recordRepresentation,
11917
12292
  ingestionTimestamp,
11918
- index: index + offset,
12293
+ index: index + offset + 1,
12294
+ earlyEnd,
11919
12295
  };
11920
12296
  });
11921
12297
  return {
11922
12298
  records,
11923
12299
  hasNextPage,
12300
+ earlyEnd,
12301
+ offset,
11924
12302
  };
11925
12303
  }
11926
12304
  /**
@@ -12271,7 +12649,7 @@ function isRecordType(type) {
12271
12649
  return Boolean(interfaces.find((iface) => iface.name === 'Record'));
12272
12650
  }
12273
12651
 
12274
- var uiapiSchemaString = "scalar String\nscalar DateTime\nscalar Currency\nscalar ID\nscalar Boolean\nscalar Longitude\nscalar Float\nscalar MultiPicklist\nscalar Base64\nscalar Url\nscalar PhoneNumber\nscalar Email\nscalar TextArea\nscalar Latitude\nscalar Picklist\nscalar RichTextArea\nscalar EncryptedString\nscalar Double\nscalar Long\nscalar JSON\nscalar Time\nscalar Int\nscalar Percent\nscalar LongTextArea\nscalar IdOrRef\nscalar Date\ntype PercentAggregate implements FieldValue {\n value: Percent\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: PercentValue\n min: PercentValue\n sum: PercentValue\n}\n\ntype StringAggregate implements FieldValue {\n value: String\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: StringValue\n min: StringValue\n}\n\ntype Query {\n uiapi: UIAPI!\n setup: Setup__Setup!\n}\n\ninput EmailOperators {\n eq: Email\n ne: Email\n like: Email\n lt: Email\n gt: Email\n lte: Email\n gte: Email\n in: [Email]\n nin: [Email]\n}\n\ninput PolymorphicParentRelationshipRecordOrderBy @generic {\n RecordOrderBy: RecordOrderBy @fieldCategory\n}\n\ninput DoubleOperators {\n eq: Double\n ne: Double\n lt: Double\n gt: Double\n lte: Double\n gte: Double\n in: [Double]\n nin: [Double]\n}\n\ntype DateOnlyAggregation {\n value: Date\n format: String\n}\n\ntype RecordCreatePayload @generic {\n Record: RecordRepresentation\n}\n\ntype DateAggregate implements FieldValue {\n value: Date\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n grouping: IntValue\n max: DateValue\n min: DateValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput PolymorphicParentRelationshipGroupBy @generic {\n RecordGroupBy: RecordGroupBy @fieldCategory\n}\n\nenum GroupByFunction {\n DAY_IN_WEEK\n DAY_IN_MONTH\n DAY_IN_YEAR\n WEEK_IN_MONTH\n WEEK_IN_YEAR\n CALENDAR_MONTH\n CALENDAR_QUARTER\n CALENDAR_YEAR\n FISCAL_MONTH\n FISCAL_QUARTER\n FISCAL_YEAR\n DAY_ONLY\n HOUR_IN_DAY\n}\n\ntype RecordTypeInfo {\n available: Boolean!\n defaultRecordTypeMapping: Boolean!\n master: Boolean!\n name: String\n recordTypeId: ID\n}\n\ninput UIAPIMutationsInput {\n allOrNone: Boolean = true\n}\n\ntype BooleanValue implements FieldValue {\n value: Boolean\n displayValue: String\n}\n\ntype ReferenceToInfo {\n ApiName: String!\n nameFields: [String]!\n objectInfo: ObjectInfo\n}\n\ninterface FieldValue {\n displayValue: String\n}\n\ntype LongitudeValue implements FieldValue {\n value: Longitude\n displayValue: String\n}\n\ntype StringValue implements FieldValue {\n value: String\n displayValue: String\n label: String\n}\n\ntype IntValue implements FieldValue {\n value: Int\n displayValue: String\n format: String\n}\n\ntype UrlValue implements FieldValue {\n value: Url\n displayValue: String\n}\n\ninput IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: JoinInput\n ninq: JoinInput\n}\n\ninput Setup__SetupOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: Setup__SetupOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: Setup__SetupPolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ntype LongAggregate implements FieldValue {\n value: Long\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: LongValue\n min: LongValue\n sum: LongValue\n}\n\ntype PhoneNumberAggregate implements FieldValue {\n value: PhoneNumber\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: PhoneNumberValue\n min: PhoneNumberValue\n}\n\ninput TimeOperators {\n eq: Time\n ne: Time\n lt: Time\n gt: Time\n lte: Time\n gte: Time\n in: [Time]\n nin: [Time]\n}\n\ntype PicklistValue implements FieldValue {\n value: Picklist\n displayValue: String\n label: String\n}\n\ntype CurrencyAggregate implements FieldValue {\n value: Currency\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: CurrencyValue\n min: CurrencyValue\n sum: CurrencyValue\n}\n\ntype RelatedListInfo {\n childApiName: String!\n relatedListName: String!\n label: String!\n displayColumns: [ListColumn!]!\n orderedByInfo: [ListOrder!]!\n parentApiName: String!\n fieldApiName: String!\n}\n\ninput StringOperators {\n eq: String\n ne: String\n like: String\n lt: String\n gt: String\n lte: String\n gte: String\n in: [String]\n nin: [String]\n}\n\ntype UIAPI {\n query: RecordQuery!\n aggregate: RecordQueryAggregate!\n objectInfos(apiNames: [String], locale: String): [ObjectInfo]\n relatedListByName(parentApiName: String!, relatedListName: String!): RelatedListInfo\n}\n\ninput MultiPicklistOperators {\n eq: MultiPicklist\n ne: MultiPicklist\n includes: [MultiPicklist]\n excludes: [MultiPicklist]\n}\n\ntype DateTimeAggregate implements FieldValue {\n value: DateTime\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n dayOnly: DateOnlyAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n hourInDay: DateFunctionAggregation\n max: DateTimeValue\n min: DateTimeValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput BooleanOperators {\n eq: Boolean\n ne: Boolean\n}\n\ntype EmailAggregate implements FieldValue {\n value: Email\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: EmailValue\n min: EmailValue\n}\n\n#enum OrderByType {\n#}\n\ninput GroupByDateFunction {\n function: GroupByFunction\n}\n\ntype RichTextAreaValue implements FieldValue {\n value: RichTextArea\n displayValue: String\n}\n\ntype MultiPicklistValue implements FieldValue {\n value: MultiPicklist\n displayValue: String\n label: String\n}\n\ntype Setup__SetupEdge @generic {\n node: Setup__EntityRepresentation\n cursor: String!\n}\n\ninput DatePrimitiveOperators {\n eq: Date\n ne: Date\n lt: Date\n gt: Date\n lte: Date\n gte: Date\n in: [Date]\n nin: [Date]\n}\n\ntype TimeAggregate implements FieldValue {\n value: Time\n displayValue: String\n format: String\n hourInDay: DateFunctionAggregation\n}\n\ntype __Type {\n kind: __TypeKind!\n name: String\n description: String\n fields(includeDeprecated: Boolean = false): [__Field!]\n interfaces: [__Type!]\n possibleTypes: [__Type!]\n enumValues(includeDeprecated: Boolean = false): [__EnumValue!]\n inputFields: [__InputValue!]\n ofType: __Type\n}\n\ntype ListColumn {\n fieldApiName: String!\n label: String!\n lookupId: String\n sortable: Boolean\n}\n\ntype Setup__SetupQuery {\n recordQuery(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, scope: String, upperBound: Int): Setup__SetupConnection @fieldCategory\n}\n\ntype Setup__EntityRepresentation @generic {\n Id: ID!\n ApiName: String!\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: Setup__EntityRepresentation @fieldCategory\n polymorphicParentRelationship: Setup__SetupPolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, upperBound: Int): Setup__SetupConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype LatitudeAggregate implements FieldValue {\n value: Latitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LatitudeValue\n min: LatitudeValue\n sum: DoubleValue\n}\n\ninput CurrencyOperators {\n eq: Currency\n ne: Currency\n lt: Currency\n gt: Currency\n lte: Currency\n gte: Currency\n in: [Currency]\n nin: [Currency]\n}\n\ninput DistanceInput {\n latitude: Latitude!\n longitude: Longitude!\n}\n\nunion PolymorphicParentRelationship @generic = RecordRepresentation\n\nenum AggregateOrderByNumberFunction {\n AVG\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n SUM\n}\n\ntype LongTextAreaValue implements FieldValue {\n value: LongTextArea\n displayValue: String\n}\n\ntype LatitudeValue implements FieldValue {\n value: Latitude\n displayValue: String\n}\n\ninput OrderByClause {\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput AggregateOrderBy @generic {\n orderableNumberField: AggregateOrderByNumberClause @fieldCategory\n orderableStringField: AggregateOrderByStringClause @fieldCategory\n orderableField: NoFunctionAggregateOrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: AggregateOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipOrderBy @fieldCategory\n type: String = ORDER_BY\n}\n\ninput GroupByClause {\n group: Boolean\n}\n\ntype RecordAggregateConnection @generic {\n edges: [RecordAggregateEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LongitudeAggregate implements FieldValue {\n value: Longitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LongitudeValue\n min: LongitudeValue\n sum: DoubleValue\n}\n\ntype RecordEdge @generic {\n node: RecordRepresentation\n cursor: String!\n}\n\nunion Setup__SetupPolymorphicParentRelationship @generic = Setup__EntityRepresentation\n\ntype DateValue implements FieldValue {\n value: Date\n displayValue: String\n format: String\n}\n\ninput URLOperators {\n eq: Url\n ne: Url\n like: Url\n lt: Url\n gt: Url\n lte: Url\n gte: Url\n in: [Url]\n nin: [Url]\n}\n\ninput LongOperators {\n eq: Long\n ne: Long\n lt: Long\n gt: Long\n lte: Long\n gte: Long\n in: [Long]\n nin: [Long]\n}\n\nenum DataType {\n STRING\n TEXTAREA\n PHONE\n EMAIL\n URL\n ENCRYPTEDSTRING\n BOOLEAN\n CURRENCY\n INT\n LONG\n DOUBLE\n PERCENT\n DATETIME\n TIME\n DATE\n REFERENCE\n PICKLIST\n MULTIPICKLIST\n ADDRESS\n LOCATION\n BASE64\n COMPLEXVALUE\n COMBOBOX\n JSON\n JUNCTIONIDLIST\n ANYTYPE\n}\n\nenum NullOrder {\n FIRST\n LAST\n}\n\ntype PhoneNumberValue implements FieldValue {\n value: PhoneNumber\n displayValue: String\n}\n\n# Cannot have empty enum\n# enum RecordScope @generic {\n# }\n\ninput Setup__SetupFilter @generic {\n and: [Setup__SetupFilter]\n or: [Setup__SetupFilter]\n not: Setup__SetupFilter\n parentRelationshipRecordFilter: Setup__SetupFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: Setup__SetupPolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n Setup__IdOperator: Setup__IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype DoubleAggregate implements FieldValue {\n value: Double\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: DoubleValue\n min: DoubleValue\n sum: DoubleValue\n}\n\ntype __Field {\n name: String!\n description: String\n args: [__InputValue!]!\n type: __Type!\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ninput DateOperators {\n eq: DateInput\n ne: DateInput\n lt: DateInput\n gt: DateInput\n lte: DateInput\n gte: DateInput\n in: [DateInput]\n nin: [DateInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n}\n\ninput GeolocationInput {\n latitude: Latitude!\n longitude: Longitude!\n radius: Float!\n unit: Unit!\n}\n\ninput JoinInput {\n Record: RecordFilter @fieldCategory\n ApiName: String\n}\n\ninput TextAreaOperators {\n eq: TextArea\n ne: TextArea\n like: TextArea\n lt: TextArea\n gt: TextArea\n lte: TextArea\n gte: TextArea\n in: [TextArea]\n nin: [TextArea]\n}\n\ntype TextAreaValue implements FieldValue {\n value: TextArea\n displayValue: String\n}\n\ntype RecordUpdatePayload @generic {\n success: Boolean\n}\n\ninput PercentOperators {\n eq: Percent\n ne: Percent\n lt: Percent\n gt: Percent\n lte: Percent\n gte: Percent\n in: [Percent]\n nin: [Percent]\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordOrderBy @generic {\n Setup__SetupOrderBy: Setup__SetupOrderBy @fieldCategory\n}\n\ntype DoubleValue implements FieldValue {\n value: Double\n displayValue: String\n format: String\n}\n\ntype IDAggregate implements FieldValue {\n value: ID\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: IDValue\n min: IDValue\n}\n\ntype __InputValue {\n name: String!\n description: String\n type: __Type!\n defaultValue: String\n}\n\ntype RecordAggregateEdge @generic {\n node: RecordResult\n cursor: String!\n}\n\ntype __Directive {\n name: String\n description: String\n locations: [__DirectiveLocation!]\n args: [__InputValue!]!\n}\n\ninput RecordCreateInput @generic {\n record: RecordCreateRepresentation! @fieldCategory\n}\n\ntype ThemeInfo {\n color: String\n iconUrl: String\n}\n\ninput AggregateOrderByStringClause {\n function: AggregateOrderByStringFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype RecordDeletePayload {\n Id: ID\n}\n\ntype UrlAggregate implements FieldValue {\n value: Url\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: UrlValue\n min: UrlValue\n}\n\nenum DateLiteral {\n LAST_YEAR\n LAST_WEEK\n THIS_QUARTER\n NEXT_FISCAL_YEAR\n LAST_QUARTER\n TOMORROW\n NEXT_FISCAL_QUARTER\n YESTERDAY\n NEXT_QUARTER\n THIS_FISCAL_QUARTER\n THIS_WEEK\n LAST_MONTH\n LAST_90_DAYS\n NEXT_90_DAYS\n THIS_FISCAL_YEAR\n NEXT_WEEK\n TODAY\n NEXT_YEAR\n NEXT_MONTH\n LAST_FISCAL_QUARTER\n THIS_MONTH\n LAST_FISCAL_YEAR\n THIS_YEAR\n}\n\ntype __EnumValue {\n name: String!\n description: String\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ntype RecordRepresentation implements Record @generic {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: RecordRepresentation @fieldCategory\n polymorphicParentRelationship: PolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, upperBound: Int): RecordConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype IDValue implements FieldValue {\n value: ID\n displayValue: String\n}\n\nenum Unit {\n MI\n KM\n}\n\ninput PolymorphicParentRelationshipOrderBy @generic {\n AggregateOrderBy: AggregateOrderBy @fieldCategory\n}\n\ninput OrderByGeolocationClause {\n distance: DistanceInput\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput Setup__IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: Setup__JoinInput\n ninq: Setup__JoinInput\n}\n\nenum NullsOrder {\n FIRST\n LAST\n}\n\ntype TextAreaAggregate implements FieldValue {\n value: TextArea\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: TextAreaValue\n min: TextAreaValue\n}\n\nenum GroupByType {\n GROUP_BY\n ROLLUP\n CUBE\n}\n\nenum ResultOrder {\n ASC\n DESC\n}\n\ninput RecordOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: RecordOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ninput Setup__JoinInput {\n Record: Setup__SetupFilter @fieldCategory\n ApiName: String\n}\n\ninput PicklistOperators {\n eq: Picklist\n ne: Picklist\n in: [Picklist]\n nin: [Picklist]\n like: Picklist\n lt: Picklist\n gt: Picklist\n lte: Picklist\n gte: Picklist\n}\n\nenum ResultsOrder {\n ASC\n DESC\n}\n\ninput RecordFilter @generic {\n and: [RecordFilter]\n or: [RecordFilter]\n not: RecordFilter\n parentRelationshipRecordFilter: RecordFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: PolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n IdOperator: IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype TimeValue implements FieldValue {\n value: Time\n displayValue: String\n format: String\n}\n\ninput GeolocationOperators {\n lt: GeolocationInput\n gt: GeolocationInput\n}\n\ntype PicklistAggregate implements FieldValue {\n value: Picklist\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: PicklistValue\n min: PicklistValue\n}\n\ninput LatitudeOperators {\n eq: Latitude\n ne: Latitude\n lt: Latitude\n gt: Latitude\n lte: Latitude\n gte: Latitude\n in: [Latitude]\n nin: [Latitude]\n}\n\ninput RecordUpdateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype DateTimeValue implements FieldValue {\n value: DateTime\n displayValue: String\n format: String\n}\n\ninput RecordDeleteInput {\n Id: IdOrRef!\n}\n\nenum __DirectiveLocation {\n QUERY\n MUTATION\n FIELD\n FRAGMENT_DEFINITION\n FRAGMENT_SPREAD\n INLINE_FRAGMENT\n SCHEMA\n SCALAR\n OBJECT\n FIELD_DEFINITION\n ARGUMENT_DEFINITION\n INTERFACE\n UNION\n ENUM\n ENUM_VALUE\n INPUT_OBJECT\n INPUT_FIELD_DEFINITION\n}\n\ntype IntAggregate implements FieldValue {\n value: Int\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: IntValue\n min: IntValue\n sum: LongValue\n}\n\ntype ListOrder {\n fieldApiName: String!\n sortDirection: ResultOrder\n}\n\ntype RecordAggregate @generic {\n ApiName: String!\n BooleanAggregate: BooleanAggregate @fieldCategory\n CurrencyAggregate: CurrencyAggregate @fieldCategory\n DateAggregate: DateAggregate @fieldCategory\n DoubleAggregate: DoubleAggregate @fieldCategory\n EmailAggregate: EmailAggregate @fieldCategory\n IDAggregate: IDAggregate @fieldCategory\n IntAggregate: IntAggregate @fieldCategory\n LatitudeAggregate: LatitudeAggregate @fieldCategory\n LongitudeAggregate: LongitudeAggregate @fieldCategory\n LongAggregate: LongAggregate @fieldCategory\n PercentAggregate: PercentAggregate @fieldCategory\n PhoneNumberAggregate: PhoneNumberAggregate @fieldCategory\n PicklistAggregate: PicklistAggregate @fieldCategory\n StringAggregate: StringAggregate @fieldCategory\n TextAreaAggregate: TextAreaAggregate @fieldCategory\n TimeAggregate: TimeAggregate @fieldCategory\n UrlAggregate: UrlAggregate @fieldCategory\n}\n\ntype JSONValue implements FieldValue {\n value: JSON\n displayValue: String\n}\n\ntype EmailValue implements FieldValue {\n value: Email\n displayValue: String\n}\n\ntype Setup__Setup {\n query: Setup__SetupQuery!\n}\n\nenum AggregateOrderByStringFunction {\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n}\n\ntype LongValue implements FieldValue {\n value: Long\n displayValue: String\n format: String\n}\n\ninput DateFunctionInput {\n value: LongOperators\n convertTimezoneValue: LongOperators\n}\n\n# Mutations aren't supported yet.\n#type Mutation {\n# uiapi(input: UIAPIMutationsInput): UIAPIMutations!\n#}\n\ntype DependentField {\n controllingField: String!\n dependentFields: [String]!\n}\n\ninput LongTextAreaOperators {\n eq: LongTextArea\n ne: LongTextArea\n like: LongTextArea\n lt: LongTextArea\n gt: LongTextArea\n lte: LongTextArea\n gte: LongTextArea\n in: [LongTextArea]\n nin: [LongTextArea]\n}\n\nenum __TypeKind {\n SCALAR\n OBJECT\n INTERFACE\n UNION\n ENUM\n INPUT_OBJECT\n LIST\n NON_NULL\n}\n\ntype Setup__SetupConnection @generic {\n edges: [Setup__SetupEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype PercentValue implements FieldValue {\n value: Percent\n displayValue: String\n format: String\n}\n\ninput DateTimeOperators {\n eq: DateTimeInput\n ne: DateTimeInput\n lt: DateTimeInput\n gt: DateTimeInput\n lte: DateTimeInput\n gte: DateTimeInput\n in: [DateTimeInput]\n nin: [DateTimeInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n DAY_ONLY: DateTimeFunctionInput\n HOUR_IN_DAY: DateFunctionInput\n}\n\ninput NoFunctionAggregateOrderByClause {\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype BooleanAggregate implements FieldValue {\n value: Boolean\n displayValue: String\n grouping: IntValue\n}\n\ntype RecordQueryAggregate {\n # RecordScope is replaced with String\n recordQueryAggregate(first: Int, after: String, where: RecordFilter, orderBy: AggregateOrderBy, scope: String, groupBy: RecordGroupBy, upperBound: Int): RecordAggregateConnection @fieldCategory\n}\n\ntype RecordConnection @generic {\n edges: [RecordEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype FilteredLookupInfo {\n controllingFields: [String]!\n dependent: Boolean!\n optionalFilter: Boolean!\n}\n\ninput PhoneNumberOperators {\n eq: PhoneNumber\n ne: PhoneNumber\n like: PhoneNumber\n lt: PhoneNumber\n gt: PhoneNumber\n lte: PhoneNumber\n gte: PhoneNumber\n in: [PhoneNumber]\n nin: [PhoneNumber]\n}\n\ntype ObjectInfo {\n ApiName: String!\n childRelationships: [ChildRelationship]!\n createable: Boolean!\n custom: Boolean!\n defaultRecordTypeId: ID\n deletable: Boolean!\n dependentFields: [DependentField]!\n feedEnabled: Boolean!\n fields: [Field]!\n keyPrefix: String\n label: String\n labelPlural: String\n layoutable: Boolean!\n mruEnabled: Boolean!\n nameFields: [String]!\n queryable: Boolean!\n recordTypeInfos: [RecordTypeInfo]!\n searchable: Boolean!\n themeInfo: ThemeInfo\n updateable: Boolean!\n locale: String\n}\n\ninput LongitudeOperators {\n eq: Longitude\n ne: Longitude\n lt: Longitude\n gt: Longitude\n lte: Longitude\n gte: Longitude\n in: [Longitude]\n nin: [Longitude]\n}\n\ninput RecordCreateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype Field {\n ApiName: String!\n calculated: Boolean!\n compound: Boolean!\n compoundComponentName: String\n compoundFieldName: String\n controllerName: String\n controllingFields: [String]!\n createable: Boolean!\n custom: Boolean!\n dataType: DataType\n extraTypeInfo: FieldExtraTypeInfo\n filterable: Boolean!\n filteredLookupInfo: FilteredLookupInfo\n highScaleNumber: Boolean!\n htmlFormatted: Boolean!\n inlineHelpText: String\n label: String\n nameField: Boolean!\n polymorphicForeignKey: Boolean!\n precision: Int\n reference: Boolean!\n referenceTargetField: String\n referenceToInfos: [ReferenceToInfo]!\n relationshipName: String\n required: Boolean!\n scale: Int\n searchPrefilterable: Boolean\n sortable: Boolean!\n updateable: Boolean!\n}\n\nenum FieldExtraTypeInfo {\n IMAGE_URL\n EXTERNAL_LOOKUP\n INDIRECT_LOOKUP\n PERSONNAME\n SWITCHABLE_PERSONNAME\n PLAINTEXTAREA\n RICHTEXTAREA\n}\n\ntype RateLimit {\n cost: Long\n limit: Long\n remaining: Long\n resetAt: DateTime\n}\n\ninput DateRange {\n last_n_days: Int\n next_n_days: Int\n last_n_weeks: Int\n next_n_weeks: Int\n last_n_months: Int\n next_n_months: Int\n last_n_quarters: Int\n next_n_quarters: Int\n last_n_fiscal_quarters: Int\n next_n_fiscal_quarters: Int\n last_n_years: Int\n next_n_years: Int\n last_n_fiscal_years: Int\n next_n_fiscal_years: Int\n n_days_ago: Int\n n_weeks_ago: Int\n n_months_ago: Int\n n_quarters_ago: Int\n n_years_ago: Int\n n_fiscal_quarters_ago: Int\n n_fiscal_years_ago: Int\n}\n\ntype UIAPIMutations {\n recordCreate(input: RecordCreateInput!): RecordCreatePayload @fieldCategory\n recordDelete(input: RecordDeleteInput!): RecordDeletePayload @fieldCategory\n recordUpdate(input: RecordUpdateInput!): RecordUpdatePayload @fieldCategory\n}\n\ninput DateTimeFunctionInput {\n value: DatePrimitiveOperators\n convertTimezoneValue: DatePrimitiveOperators\n}\n\ntype Base64Value implements FieldValue {\n value: Base64\n displayValue: String\n}\n\ninput IntegerOperators {\n eq: Int\n ne: Int\n lt: Int\n gt: Int\n lte: Int\n gte: Int\n in: [Int]\n nin: [Int]\n}\n\ntype EncryptedStringValue implements FieldValue {\n value: EncryptedString\n displayValue: String\n}\n\ninterface Record {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n}\n\ninput PolymorphicParentRelationshipRecordFilter @generic {\n RecordFilter: RecordFilter @fieldCategory\n}\n\ninput AggregateOrderByNumberClause {\n function: AggregateOrderByNumberFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype __Schema {\n types: [__Type!]!\n queryType: __Type!\n mutationType: __Type\n directives: [__Directive!]!\n subscriptionType: __Type\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordFilter @generic {\n Setup__SetupFilter: Setup__SetupFilter @fieldCategory\n}\n\ntype CompoundField @generic {\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n}\n\ninput RecordUpdateInput @generic {\n Id: IdOrRef!\n record: RecordUpdateRepresentation! @fieldCategory\n}\n\ninput DateTimeInput {\n value: DateTime\n literal: DateLiteral\n range: DateRange\n}\n\ntype ChildRelationship {\n childObjectApiName: String!\n fieldName: String\n junctionIdListNames: [String]!\n junctionReferenceTo: [String]!\n relationshipName: String\n objectInfo: ObjectInfo\n}\n\ntype RecordResult @generic {\n aggregate: RecordAggregate\n}\n\ntype PageInfo {\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n endCursor: String\n}\n\ntype CurrencyValue implements FieldValue {\n value: Currency\n displayValue: String\n format: String\n}\n\ninput DateInput {\n value: Date\n literal: DateLiteral\n range: DateRange\n}\n\ninput RecordGroupBy @generic {\n groupableField: GroupByClause @fieldCategory\n groupableDateField: GroupByDateFunction @fieldCategory\n groupableParentRelationship: RecordGroupBy @fieldCategory\n groupablePolymorphicParentRelationship: PolymorphicParentRelationshipGroupBy @fieldCategory\n type: GroupByType = GROUP_BY\n}\n\ntype DateFunctionAggregation {\n value: Long\n format: String\n}\n\ntype RecordQuery {\n # scope should be type RecordScope but that's empty enum.\n recordQuery(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String, upperBound: Int): RecordConnection @fieldCategory\n}\n\ndirective @generic on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT\ndirective @fieldCategory on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE\ndirective @category(name: String!) on FIELD";
12652
+ var uiapiSchemaString = "scalar String\nscalar DateTime\nscalar Currency\nscalar ID\nscalar Boolean\nscalar Longitude\nscalar Float\nscalar MultiPicklist\nscalar Base64\nscalar Url\nscalar PhoneNumber\nscalar Email\nscalar TextArea\nscalar Latitude\nscalar Picklist\nscalar RichTextArea\nscalar EncryptedString\nscalar Double\nscalar Long\nscalar JSON\nscalar Time\nscalar Int\nscalar Percent\nscalar LongTextArea\nscalar IdOrRef\nscalar Date\ntype PercentAggregate implements FieldValue {\n value: Percent\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: PercentValue\n min: PercentValue\n sum: PercentValue\n}\n\ntype StringAggregate implements FieldValue {\n value: String\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: StringValue\n min: StringValue\n}\n\ntype Query {\n uiapi: UIAPI!\n setup: Setup__Setup!\n analytics: Analytics__Analytics!\n}\n\ninput EmailOperators {\n eq: Email\n ne: Email\n like: Email\n lt: Email\n gt: Email\n lte: Email\n gte: Email\n in: [Email]\n nin: [Email]\n}\n\ninput PolymorphicParentRelationshipRecordOrderBy @generic {\n RecordOrderBy: RecordOrderBy @fieldCategory\n}\n\ninput DoubleOperators {\n eq: Double\n ne: Double\n lt: Double\n gt: Double\n lte: Double\n gte: Double\n in: [Double]\n nin: [Double]\n}\n\ntype DateOnlyAggregation {\n value: Date\n format: String\n}\n\ntype RecordCreatePayload @generic {\n Record: RecordRepresentation\n}\n\ntype DateAggregate implements FieldValue {\n value: Date\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n grouping: IntValue\n max: DateValue\n min: DateValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput PolymorphicParentRelationshipGroupBy @generic {\n RecordGroupBy: RecordGroupBy @fieldCategory\n}\n\nenum GroupByFunction {\n DAY_IN_WEEK\n DAY_IN_MONTH\n DAY_IN_YEAR\n WEEK_IN_MONTH\n WEEK_IN_YEAR\n CALENDAR_MONTH\n CALENDAR_QUARTER\n CALENDAR_YEAR\n FISCAL_MONTH\n FISCAL_QUARTER\n FISCAL_YEAR\n DAY_ONLY\n HOUR_IN_DAY\n}\n\ntype RecordTypeInfo {\n available: Boolean!\n defaultRecordTypeMapping: Boolean!\n master: Boolean!\n name: String\n recordTypeId: ID\n}\n\ninput UIAPIMutationsInput {\n allOrNone: Boolean = true\n}\n\ntype BooleanValue implements FieldValue {\n value: Boolean\n displayValue: String\n}\n\ntype ReferenceToInfo {\n ApiName: String!\n nameFields: [String]!\n objectInfo: ObjectInfo\n}\n\ninterface FieldValue {\n displayValue: String\n}\n\ntype LongitudeValue implements FieldValue {\n value: Longitude\n displayValue: String\n}\n\ntype StringValue implements FieldValue {\n value: String\n displayValue: String\n label: String\n}\n\ntype IntValue implements FieldValue {\n value: Int\n displayValue: String\n format: String\n}\n\ntype UrlValue implements FieldValue {\n value: Url\n displayValue: String\n}\n\ninput IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: JoinInput\n ninq: JoinInput\n}\n\ninput Setup__SetupOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: Setup__SetupOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: Setup__SetupPolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ntype LongAggregate implements FieldValue {\n value: Long\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: LongValue\n min: LongValue\n sum: LongValue\n}\n\ntype PhoneNumberAggregate implements FieldValue {\n value: PhoneNumber\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: PhoneNumberValue\n min: PhoneNumberValue\n}\n\ninput TimeOperators {\n eq: Time\n ne: Time\n lt: Time\n gt: Time\n lte: Time\n gte: Time\n in: [Time]\n nin: [Time]\n}\n\ntype PicklistValue implements FieldValue {\n value: Picklist\n displayValue: String\n label: String\n}\n\ntype CurrencyAggregate implements FieldValue {\n value: Currency\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: CurrencyValue\n min: CurrencyValue\n sum: CurrencyValue\n}\n\ntype RelatedListInfo {\n childApiName: String!\n relatedListName: String!\n label: String!\n displayColumns: [ListColumn!]!\n orderedByInfo: [ListOrder!]!\n parentApiName: String!\n fieldApiName: String!\n}\n\ninput StringOperators {\n eq: String\n ne: String\n like: String\n lt: String\n gt: String\n lte: String\n gte: String\n in: [String]\n nin: [String]\n}\n\ntype UIAPI {\n query: RecordQuery!\n aggregate: RecordQueryAggregate!\n objectInfos(apiNames: [String], locale: String): [ObjectInfo]\n relatedListByName(parentApiName: String!, relatedListName: String!): RelatedListInfo\n}\n\ninput MultiPicklistOperators {\n eq: MultiPicklist\n ne: MultiPicklist\n includes: [MultiPicklist]\n excludes: [MultiPicklist]\n}\n\ntype DateTimeAggregate implements FieldValue {\n value: DateTime\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n dayOnly: DateOnlyAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n hourInDay: DateFunctionAggregation\n max: DateTimeValue\n min: DateTimeValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput BooleanOperators {\n eq: Boolean\n ne: Boolean\n}\n\ntype EmailAggregate implements FieldValue {\n value: Email\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: EmailValue\n min: EmailValue\n}\n\n#enum OrderByType {\n#}\n\ninput GroupByDateFunction {\n function: GroupByFunction\n}\n\ntype RichTextAreaValue implements FieldValue {\n value: RichTextArea\n displayValue: String\n}\n\ntype MultiPicklistValue implements FieldValue {\n value: MultiPicklist\n displayValue: String\n label: String\n}\n\ntype Setup__SetupEdge @generic {\n node: Setup__EntityRepresentation\n cursor: String!\n}\n\ninput DatePrimitiveOperators {\n eq: Date\n ne: Date\n lt: Date\n gt: Date\n lte: Date\n gte: Date\n in: [Date]\n nin: [Date]\n}\n\ntype TimeAggregate implements FieldValue {\n value: Time\n displayValue: String\n format: String\n hourInDay: DateFunctionAggregation\n}\n\ntype __Type {\n kind: __TypeKind!\n name: String\n description: String\n fields(includeDeprecated: Boolean = false): [__Field!]\n interfaces: [__Type!]\n possibleTypes: [__Type!]\n enumValues(includeDeprecated: Boolean = false): [__EnumValue!]\n inputFields: [__InputValue!]\n ofType: __Type\n}\n\ntype ListColumn {\n fieldApiName: String!\n label: String!\n lookupId: String\n sortable: Boolean\n}\n\ntype Setup__SetupQuery {\n recordQuery(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, scope: String, upperBound: Int): Setup__SetupConnection @fieldCategory\n}\n\ntype Setup__EntityRepresentation @generic {\n Id: ID!\n ApiName: String!\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: Setup__EntityRepresentation @fieldCategory\n polymorphicParentRelationship: Setup__SetupPolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, upperBound: Int): Setup__SetupConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype LatitudeAggregate implements FieldValue {\n value: Latitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LatitudeValue\n min: LatitudeValue\n sum: DoubleValue\n}\n\ninput CurrencyOperators {\n eq: Currency\n ne: Currency\n lt: Currency\n gt: Currency\n lte: Currency\n gte: Currency\n in: [Currency]\n nin: [Currency]\n}\n\ninput DistanceInput {\n latitude: Latitude!\n longitude: Longitude!\n}\n\nunion PolymorphicParentRelationship @generic = RecordRepresentation\n\nenum AggregateOrderByNumberFunction {\n AVG\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n SUM\n}\n\ntype LongTextAreaValue implements FieldValue {\n value: LongTextArea\n displayValue: String\n}\n\ntype LatitudeValue implements FieldValue {\n value: Latitude\n displayValue: String\n}\n\ninput OrderByClause {\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput AggregateOrderBy @generic {\n orderableNumberField: AggregateOrderByNumberClause @fieldCategory\n orderableStringField: AggregateOrderByStringClause @fieldCategory\n orderableField: NoFunctionAggregateOrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: AggregateOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipOrderBy @fieldCategory\n type: String = ORDER_BY\n}\n\ninput GroupByClause {\n group: Boolean\n}\n\ntype RecordAggregateConnection @generic {\n edges: [RecordAggregateEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LongitudeAggregate implements FieldValue {\n value: Longitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LongitudeValue\n min: LongitudeValue\n sum: DoubleValue\n}\n\ntype RecordEdge @generic {\n node: RecordRepresentation\n cursor: String!\n}\n\nunion Setup__SetupPolymorphicParentRelationship @generic = Setup__EntityRepresentation\n\ntype DateValue implements FieldValue {\n value: Date\n displayValue: String\n format: String\n}\n\ninput URLOperators {\n eq: Url\n ne: Url\n like: Url\n lt: Url\n gt: Url\n lte: Url\n gte: Url\n in: [Url]\n nin: [Url]\n}\n\ninput LongOperators {\n eq: Long\n ne: Long\n lt: Long\n gt: Long\n lte: Long\n gte: Long\n in: [Long]\n nin: [Long]\n}\n\nenum DataType {\n STRING\n TEXTAREA\n PHONE\n EMAIL\n URL\n ENCRYPTEDSTRING\n BOOLEAN\n CURRENCY\n INT\n LONG\n DOUBLE\n PERCENT\n DATETIME\n TIME\n DATE\n REFERENCE\n PICKLIST\n MULTIPICKLIST\n ADDRESS\n LOCATION\n BASE64\n COMPLEXVALUE\n COMBOBOX\n JSON\n JUNCTIONIDLIST\n ANYTYPE\n}\n\nenum NullOrder {\n FIRST\n LAST\n}\n\ntype PhoneNumberValue implements FieldValue {\n value: PhoneNumber\n displayValue: String\n}\n\n# Cannot have empty enum\n# enum RecordScope @generic {\n# }\n\ninput Setup__SetupFilter @generic {\n and: [Setup__SetupFilter]\n or: [Setup__SetupFilter]\n not: Setup__SetupFilter\n parentRelationshipRecordFilter: Setup__SetupFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: Setup__SetupPolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n Setup__IdOperator: Setup__IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype DoubleAggregate implements FieldValue {\n value: Double\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: DoubleValue\n min: DoubleValue\n sum: DoubleValue\n}\n\ntype __Field {\n name: String!\n description: String\n args: [__InputValue!]!\n type: __Type!\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ninput DateOperators {\n eq: DateInput\n ne: DateInput\n lt: DateInput\n gt: DateInput\n lte: DateInput\n gte: DateInput\n in: [DateInput]\n nin: [DateInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n}\n\ninput GeolocationInput {\n latitude: Latitude!\n longitude: Longitude!\n radius: Float!\n unit: Unit!\n}\n\ninput JoinInput {\n Record: RecordFilter @fieldCategory\n ApiName: String\n}\n\ninput TextAreaOperators {\n eq: TextArea\n ne: TextArea\n like: TextArea\n lt: TextArea\n gt: TextArea\n lte: TextArea\n gte: TextArea\n in: [TextArea]\n nin: [TextArea]\n}\n\ntype TextAreaValue implements FieldValue {\n value: TextArea\n displayValue: String\n}\n\ntype RecordUpdatePayload @generic {\n success: Boolean\n}\n\ninput PercentOperators {\n eq: Percent\n ne: Percent\n lt: Percent\n gt: Percent\n lte: Percent\n gte: Percent\n in: [Percent]\n nin: [Percent]\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordOrderBy @generic {\n Setup__SetupOrderBy: Setup__SetupOrderBy @fieldCategory\n}\n\ntype DoubleValue implements FieldValue {\n value: Double\n displayValue: String\n format: String\n}\n\ntype IDAggregate implements FieldValue {\n value: ID\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: IDValue\n min: IDValue\n}\n\ntype __InputValue {\n name: String!\n description: String\n type: __Type!\n defaultValue: String\n}\n\ntype RecordAggregateEdge @generic {\n node: RecordResult\n cursor: String!\n}\n\ntype __Directive {\n name: String\n description: String\n locations: [__DirectiveLocation!]\n args: [__InputValue!]!\n}\n\ninput RecordCreateInput @generic {\n record: RecordCreateRepresentation! @fieldCategory\n}\n\ntype ThemeInfo {\n color: String\n iconUrl: String\n}\n\ninput AggregateOrderByStringClause {\n function: AggregateOrderByStringFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype RecordDeletePayload {\n Id: ID\n}\n\ntype UrlAggregate implements FieldValue {\n value: Url\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: UrlValue\n min: UrlValue\n}\n\nenum DateLiteral {\n LAST_YEAR\n LAST_WEEK\n THIS_QUARTER\n NEXT_FISCAL_YEAR\n LAST_QUARTER\n TOMORROW\n NEXT_FISCAL_QUARTER\n YESTERDAY\n NEXT_QUARTER\n THIS_FISCAL_QUARTER\n THIS_WEEK\n LAST_MONTH\n LAST_90_DAYS\n NEXT_90_DAYS\n THIS_FISCAL_YEAR\n NEXT_WEEK\n TODAY\n NEXT_YEAR\n NEXT_MONTH\n LAST_FISCAL_QUARTER\n THIS_MONTH\n LAST_FISCAL_YEAR\n THIS_YEAR\n}\n\ntype __EnumValue {\n name: String!\n description: String\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ntype RecordRepresentation implements Record @generic {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: RecordRepresentation @fieldCategory\n polymorphicParentRelationship: PolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, upperBound: Int): RecordConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype IDValue implements FieldValue {\n value: ID\n displayValue: String\n}\n\nenum Unit {\n MI\n KM\n}\n\ninput PolymorphicParentRelationshipOrderBy @generic {\n AggregateOrderBy: AggregateOrderBy @fieldCategory\n}\n\ninput OrderByGeolocationClause {\n distance: DistanceInput\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput Setup__IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: Setup__JoinInput\n ninq: Setup__JoinInput\n}\n\nenum NullsOrder {\n FIRST\n LAST\n}\n\ntype TextAreaAggregate implements FieldValue {\n value: TextArea\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: TextAreaValue\n min: TextAreaValue\n}\n\nenum GroupByType {\n GROUP_BY\n ROLLUP\n CUBE\n}\n\nenum ResultOrder {\n ASC\n DESC\n}\n\ninput RecordOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: RecordOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ninput Setup__JoinInput {\n Record: Setup__SetupFilter @fieldCategory\n ApiName: String\n}\n\ninput PicklistOperators {\n eq: Picklist\n ne: Picklist\n in: [Picklist]\n nin: [Picklist]\n like: Picklist\n lt: Picklist\n gt: Picklist\n lte: Picklist\n gte: Picklist\n}\n\nenum ResultsOrder {\n ASC\n DESC\n}\n\ninput RecordFilter @generic {\n and: [RecordFilter]\n or: [RecordFilter]\n not: RecordFilter\n parentRelationshipRecordFilter: RecordFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: PolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n IdOperator: IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype TimeValue implements FieldValue {\n value: Time\n displayValue: String\n format: String\n}\n\ninput GeolocationOperators {\n lt: GeolocationInput\n gt: GeolocationInput\n}\n\ntype PicklistAggregate implements FieldValue {\n value: Picklist\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: PicklistValue\n min: PicklistValue\n}\n\ninput LatitudeOperators {\n eq: Latitude\n ne: Latitude\n lt: Latitude\n gt: Latitude\n lte: Latitude\n gte: Latitude\n in: [Latitude]\n nin: [Latitude]\n}\n\ninput RecordUpdateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype DateTimeValue implements FieldValue {\n value: DateTime\n displayValue: String\n format: String\n}\n\ninput RecordDeleteInput {\n Id: IdOrRef!\n}\n\nenum __DirectiveLocation {\n QUERY\n MUTATION\n FIELD\n FRAGMENT_DEFINITION\n FRAGMENT_SPREAD\n INLINE_FRAGMENT\n SCHEMA\n SCALAR\n OBJECT\n FIELD_DEFINITION\n ARGUMENT_DEFINITION\n INTERFACE\n UNION\n ENUM\n ENUM_VALUE\n INPUT_OBJECT\n INPUT_FIELD_DEFINITION\n}\n\ntype IntAggregate implements FieldValue {\n value: Int\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: IntValue\n min: IntValue\n sum: LongValue\n}\n\ntype ListOrder {\n fieldApiName: String!\n sortDirection: ResultOrder\n}\n\ntype RecordAggregate @generic {\n ApiName: String!\n BooleanAggregate: BooleanAggregate @fieldCategory\n CurrencyAggregate: CurrencyAggregate @fieldCategory\n DateAggregate: DateAggregate @fieldCategory\n DoubleAggregate: DoubleAggregate @fieldCategory\n EmailAggregate: EmailAggregate @fieldCategory\n IDAggregate: IDAggregate @fieldCategory\n IntAggregate: IntAggregate @fieldCategory\n LatitudeAggregate: LatitudeAggregate @fieldCategory\n LongitudeAggregate: LongitudeAggregate @fieldCategory\n LongAggregate: LongAggregate @fieldCategory\n PercentAggregate: PercentAggregate @fieldCategory\n PhoneNumberAggregate: PhoneNumberAggregate @fieldCategory\n PicklistAggregate: PicklistAggregate @fieldCategory\n StringAggregate: StringAggregate @fieldCategory\n TextAreaAggregate: TextAreaAggregate @fieldCategory\n TimeAggregate: TimeAggregate @fieldCategory\n UrlAggregate: UrlAggregate @fieldCategory\n}\n\ntype JSONValue implements FieldValue {\n value: JSON\n displayValue: String\n}\n\ntype EmailValue implements FieldValue {\n value: Email\n displayValue: String\n}\n\ntype Setup__Setup {\n query: Setup__SetupQuery!\n}\n\nenum AggregateOrderByStringFunction {\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n}\n\ntype LongValue implements FieldValue {\n value: Long\n displayValue: String\n format: String\n}\n\ninput DateFunctionInput {\n value: LongOperators\n convertTimezoneValue: LongOperators\n}\n\n# Mutations aren't supported yet.\n#type Mutation {\n# uiapi(input: UIAPIMutationsInput): UIAPIMutations!\n#}\n\ntype DependentField {\n controllingField: String!\n dependentFields: [String]!\n}\n\ninput LongTextAreaOperators {\n eq: LongTextArea\n ne: LongTextArea\n like: LongTextArea\n lt: LongTextArea\n gt: LongTextArea\n lte: LongTextArea\n gte: LongTextArea\n in: [LongTextArea]\n nin: [LongTextArea]\n}\n\nenum __TypeKind {\n SCALAR\n OBJECT\n INTERFACE\n UNION\n ENUM\n INPUT_OBJECT\n LIST\n NON_NULL\n}\n\ntype Setup__SetupConnection @generic {\n edges: [Setup__SetupEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype PercentValue implements FieldValue {\n value: Percent\n displayValue: String\n format: String\n}\n\ninput DateTimeOperators {\n eq: DateTimeInput\n ne: DateTimeInput\n lt: DateTimeInput\n gt: DateTimeInput\n lte: DateTimeInput\n gte: DateTimeInput\n in: [DateTimeInput]\n nin: [DateTimeInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n DAY_ONLY: DateTimeFunctionInput\n HOUR_IN_DAY: DateFunctionInput\n}\n\ninput NoFunctionAggregateOrderByClause {\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype BooleanAggregate implements FieldValue {\n value: Boolean\n displayValue: String\n grouping: IntValue\n}\n\ntype RecordQueryAggregate {\n # RecordScope is replaced with String\n recordQueryAggregate(first: Int, after: String, where: RecordFilter, orderBy: AggregateOrderBy, scope: String, groupBy: RecordGroupBy, upperBound: Int): RecordAggregateConnection @fieldCategory\n}\n\ntype RecordConnection @generic {\n edges: [RecordEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype FilteredLookupInfo {\n controllingFields: [String]!\n dependent: Boolean!\n optionalFilter: Boolean!\n}\n\ninput PhoneNumberOperators {\n eq: PhoneNumber\n ne: PhoneNumber\n like: PhoneNumber\n lt: PhoneNumber\n gt: PhoneNumber\n lte: PhoneNumber\n gte: PhoneNumber\n in: [PhoneNumber]\n nin: [PhoneNumber]\n}\n\ntype ObjectInfo {\n ApiName: String!\n childRelationships: [ChildRelationship]!\n createable: Boolean!\n custom: Boolean!\n defaultRecordTypeId: ID\n deletable: Boolean!\n dependentFields: [DependentField]!\n feedEnabled: Boolean!\n fields: [Field]!\n keyPrefix: String\n label: String\n labelPlural: String\n layoutable: Boolean!\n mruEnabled: Boolean!\n nameFields: [String]!\n queryable: Boolean!\n recordTypeInfos: [RecordTypeInfo]!\n searchable: Boolean!\n themeInfo: ThemeInfo\n updateable: Boolean!\n locale: String\n}\n\ninput LongitudeOperators {\n eq: Longitude\n ne: Longitude\n lt: Longitude\n gt: Longitude\n lte: Longitude\n gte: Longitude\n in: [Longitude]\n nin: [Longitude]\n}\n\ninput RecordCreateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype Field {\n ApiName: String!\n calculated: Boolean!\n compound: Boolean!\n compoundComponentName: String\n compoundFieldName: String\n controllerName: String\n controllingFields: [String]!\n createable: Boolean!\n custom: Boolean!\n dataType: DataType\n extraTypeInfo: FieldExtraTypeInfo\n filterable: Boolean!\n filteredLookupInfo: FilteredLookupInfo\n highScaleNumber: Boolean!\n htmlFormatted: Boolean!\n inlineHelpText: String\n label: String\n nameField: Boolean!\n polymorphicForeignKey: Boolean!\n precision: Int\n reference: Boolean!\n referenceTargetField: String\n referenceToInfos: [ReferenceToInfo]!\n relationshipName: String\n required: Boolean!\n scale: Int\n searchPrefilterable: Boolean\n sortable: Boolean!\n updateable: Boolean!\n}\n\nenum FieldExtraTypeInfo {\n IMAGE_URL\n EXTERNAL_LOOKUP\n INDIRECT_LOOKUP\n PERSONNAME\n SWITCHABLE_PERSONNAME\n PLAINTEXTAREA\n RICHTEXTAREA\n}\n\ntype RateLimit {\n cost: Long\n limit: Long\n remaining: Long\n resetAt: DateTime\n}\n\ninput DateRange {\n last_n_days: Int\n next_n_days: Int\n last_n_weeks: Int\n next_n_weeks: Int\n last_n_months: Int\n next_n_months: Int\n last_n_quarters: Int\n next_n_quarters: Int\n last_n_fiscal_quarters: Int\n next_n_fiscal_quarters: Int\n last_n_years: Int\n next_n_years: Int\n last_n_fiscal_years: Int\n next_n_fiscal_years: Int\n n_days_ago: Int\n n_weeks_ago: Int\n n_months_ago: Int\n n_quarters_ago: Int\n n_years_ago: Int\n n_fiscal_quarters_ago: Int\n n_fiscal_years_ago: Int\n}\n\ntype UIAPIMutations {\n recordCreate(input: RecordCreateInput!): RecordCreatePayload @fieldCategory\n recordDelete(input: RecordDeleteInput!): RecordDeletePayload @fieldCategory\n recordUpdate(input: RecordUpdateInput!): RecordUpdatePayload @fieldCategory\n}\n\ninput DateTimeFunctionInput {\n value: DatePrimitiveOperators\n convertTimezoneValue: DatePrimitiveOperators\n}\n\ntype Base64Value implements FieldValue {\n value: Base64\n displayValue: String\n}\n\ninput IntegerOperators {\n eq: Int\n ne: Int\n lt: Int\n gt: Int\n lte: Int\n gte: Int\n in: [Int]\n nin: [Int]\n}\n\ntype EncryptedStringValue implements FieldValue {\n value: EncryptedString\n displayValue: String\n}\n\ninterface Record {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n}\n\ninput PolymorphicParentRelationshipRecordFilter @generic {\n RecordFilter: RecordFilter @fieldCategory\n}\n\ninput AggregateOrderByNumberClause {\n function: AggregateOrderByNumberFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype __Schema {\n types: [__Type!]!\n queryType: __Type!\n mutationType: __Type\n directives: [__Directive!]!\n subscriptionType: __Type\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordFilter @generic {\n Setup__SetupFilter: Setup__SetupFilter @fieldCategory\n}\n\ntype CompoundField @generic {\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n}\n\ninput RecordUpdateInput @generic {\n Id: IdOrRef!\n record: RecordUpdateRepresentation! @fieldCategory\n}\n\ninput DateTimeInput {\n value: DateTime\n literal: DateLiteral\n range: DateRange\n}\n\ntype ChildRelationship {\n childObjectApiName: String!\n fieldName: String\n junctionIdListNames: [String]!\n junctionReferenceTo: [String]!\n relationshipName: String\n objectInfo: ObjectInfo\n}\n\ntype RecordResult @generic {\n aggregate: RecordAggregate\n}\n\ntype PageInfo {\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n endCursor: String\n}\n\ntype CurrencyValue implements FieldValue {\n value: Currency\n displayValue: String\n format: String\n}\n\ninput DateInput {\n value: Date\n literal: DateLiteral\n range: DateRange\n}\n\ninput RecordGroupBy @generic {\n groupableField: GroupByClause @fieldCategory\n groupableDateField: GroupByDateFunction @fieldCategory\n groupableParentRelationship: RecordGroupBy @fieldCategory\n groupablePolymorphicParentRelationship: PolymorphicParentRelationshipGroupBy @fieldCategory\n type: GroupByType = GROUP_BY\n}\n\ntype DateFunctionAggregation {\n value: Long\n format: String\n}\n\ntype RecordQuery {\n # scope should be type RecordScope but that's empty enum.\n recordQuery(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String, upperBound: Int): RecordConnection @fieldCategory\n}\n\n# add browse family schema\ntype Analytics__Analytics {\n browse(orderBy: Analytics__AnalyticsOrderBy, where: Analytics__AnalyticsFilter, assetTypes: [Analytics__AnalyticsAssetTypeSelection!]!, first: Int, after: String): Analytics__AnalyticsBrowse!\n # Add other fields here if needed\n}\n\ntype Analytics__AnalyticsBrowse {\n edges: [Analytics__AnalyticsEdge]\n totalCount: Int!\n pageResultCount: Int!\n pageInfo: PageInfo!\n}\n\ntype Analytics__AnalyticsEdge {\n node: Analytics__AnalyticsRepresentation\n cursor: String!\n}\n\ntype Analytics__AnalyticsRepresentation {\n MasterLabel: StringValue\n CreatedById: IDValue\n LastModifiedDate: DateTimeValue\n Id: ID!\n ApiName: String!\n}\n\ninput Analytics__AnalyticsOrderBy {\n MasterLabel: Analytics__OrderByInput\n Id: Analytics__OrderByInput\n ApiName: Analytics__OrderByInput\n CreatedById: Analytics__OrderByInput\n LastModifiedDate: Analytics__OrderByInput\n}\n\ninput Analytics__OrderByInput {\n MasterLabel: Analytics__OrderByEnum\n id: Analytics__OrderByEnum\n apiName: Analytics__OrderByEnum\n CreatedById: Analytics__OrderByEnum\n LastModifiedDate: Analytics__OrderByEnum\n}\n\ninput Analytics__OrderByEnum {\n order: Analytics__SortEnumType\n}\n\nenum Analytics__SortEnumType {\n ASC\n DESC\n}\n\ninput Analytics__AnalyticsFilter {\n Id: Setup__IdOperators\n MasterLabel: StringOperators\n CreatedById: Setup__IdOperators\n LastModifiedById: Setup__IdOperators\n LastModifiedDate: DateTimeOperators\n and: [Analytics__AnalyticsFilter]\n or: [Analytics__AnalyticsFilter]\n not: Analytics__AnalyticsFilter\n}\n\n# This enum type is defined dynamically on GraphQL schema\n# Includes all possible value here\nenum Analytics__AnalyticsAssetTypeSelection {\n TableauWorkbook\n AnalyticsDashboard\n AnalyticsVisualization\n Workspace\n ScopedMetric\n SemanticDataModel\n DMO\n}\n\ndirective @generic on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT\ndirective @fieldCategory on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE\ndirective @category(name: String!) on FIELD";
12275
12653
 
12276
12654
  // Define additional schema that is missing from uiapi that we use in local evaluation
12277
12655
  const additionalSchemaDefinitions = /* GraphQL */ `
@@ -12718,7 +13096,7 @@ function getTextAreaType(field) {
12718
13096
  return 'TextAreaValue';
12719
13097
  }
12720
13098
 
12721
- async function evaluate(config, observers, settings, objectInfos, store, snapshot, cache, draftFunctions) {
13099
+ async function evaluate(config, observers, settings, objectInfos, store, snapshot, cache, draftFunctions, mappedCursors) {
12722
13100
  const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, observers);
12723
13101
  // this is only wrapped in a try to execute the event after the result was returned
12724
13102
  try {
@@ -12777,7 +13155,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
12777
13155
  eventEmitter({ type: 'graphql-preconditions-met' });
12778
13156
  // create the resolver request context, runtime values and functions for
12779
13157
  // resolvers to do their job.
12780
- const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions);
13158
+ const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, mappedCursors, draftFunctions);
12781
13159
  // We're building this from scratch from each request. If this becomes a
12782
13160
  // hotspot we can pull it up and memoize it later
12783
13161
  const schema = createSchemaWithCache(objectInfos, cache);
@@ -12802,7 +13180,11 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
12802
13180
  seenRecordIds.push(queryString);
12803
13181
  });
12804
13182
  }
12805
- return { result, seenRecordIds };
13183
+ return {
13184
+ result,
13185
+ seenRecordIds,
13186
+ possibleStaleRecordMap: contextValue.possibleStaleRecordMap,
13187
+ };
12806
13188
  }
12807
13189
  finally {
12808
13190
  eventEmitter({ type: 'graphql-eval-end' });
@@ -14476,6 +14858,60 @@ function hasGraphQlErrors(response) {
14476
14858
  response.errors.length > 0);
14477
14859
  }
14478
14860
 
14861
+ const MAX_ID_CHUNK_LENGTH = 100;
14862
+ /**
14863
+ * Adapter for limiting the number of record ids to a maximum of 100 and sending them
14864
+ * out in batches to the getRecords adapter
14865
+ *
14866
+ * @param luvio
14867
+ * @returns
14868
+ */
14869
+ function batchingGetRecordsAdapterFactory(luvio) {
14870
+ const getRecordsAdapter = getRecordsAdapterFactory(luvio);
14871
+ const batchGetRecords = (config, requestContext) => {
14872
+ const seenRecords = new StoreKeySet();
14873
+ const chunks = chunkConfig(config);
14874
+ const promises = chunks.map((conf) => {
14875
+ return getRecordsAdapter(conf, requestContext);
14876
+ });
14877
+ return Promise.all(promises).then((results) => {
14878
+ const data = results.reduce((accu, item) => {
14879
+ if (item !== null && item.data !== undefined) {
14880
+ accu.results = accu.results.concat(item.data.results);
14881
+ seenRecords.merge(item.seenRecords);
14882
+ }
14883
+ return accu;
14884
+ }, { results: [] });
14885
+ return {
14886
+ data: data,
14887
+ seenRecords,
14888
+ state: 'Fulfilled',
14889
+ };
14890
+ });
14891
+ };
14892
+ return batchGetRecords;
14893
+ }
14894
+ /**
14895
+ * Given a GetRecordsConfig it will chunk it into multiple configs with a maximum of 100
14896
+ * record ids per config.
14897
+ *
14898
+ * @param config
14899
+ * @returns
14900
+ */
14901
+ function chunkConfig(config) {
14902
+ const chunks = [];
14903
+ config.records.forEach((record) => {
14904
+ const { recordIds, fields } = record;
14905
+ for (let i = 0, len = recordIds.length; i < len; i += MAX_ID_CHUNK_LENGTH) {
14906
+ const chunk = recordIds.slice(i, i + MAX_ID_CHUNK_LENGTH);
14907
+ chunks.push({
14908
+ records: [{ recordIds: chunk, fields: fields !== undefined ? fields : [] }],
14909
+ });
14910
+ }
14911
+ });
14912
+ return chunks;
14913
+ }
14914
+
14479
14915
  function getCanonicalIdFunction(luvio) {
14480
14916
  return (id) => {
14481
14917
  var _a;
@@ -14483,6 +14919,67 @@ function getCanonicalIdFunction(luvio) {
14483
14919
  };
14484
14920
  }
14485
14921
 
14922
+ function instrumentLimits(ast, variables) {
14923
+ let result = {
14924
+ rootQueryCount: 0,
14925
+ totalQueryCount: 0,
14926
+ maxChildRelationships: 0,
14927
+ requestedRecordCount: 0,
14928
+ };
14929
+ let currentChildRelationships = 0;
14930
+ let currentRootRecordCount = 0;
14931
+ let currentTotalRecordCount = 0;
14932
+ visit(ast, {
14933
+ Field: {
14934
+ enter(node) {
14935
+ if (isRecordQuery(node)) {
14936
+ ++result.rootQueryCount;
14937
+ ++result.totalQueryCount;
14938
+ currentRootRecordCount = limitForQuery(node, variables);
14939
+ currentTotalRecordCount = currentRootRecordCount;
14940
+ }
14941
+ if (isChildRelationshipQuery(node)) {
14942
+ ++currentChildRelationships;
14943
+ ++result.totalQueryCount;
14944
+ currentTotalRecordCount +=
14945
+ currentRootRecordCount * limitForQuery(node, variables);
14946
+ }
14947
+ },
14948
+ leave(node) {
14949
+ if (isRecordQuery(node)) {
14950
+ result.requestedRecordCount += currentTotalRecordCount;
14951
+ if (currentChildRelationships > result.maxChildRelationships) {
14952
+ result.maxChildRelationships = currentChildRelationships;
14953
+ }
14954
+ currentChildRelationships = 0;
14955
+ currentTotalRecordCount = 0;
14956
+ currentRootRecordCount = 0;
14957
+ }
14958
+ },
14959
+ },
14960
+ });
14961
+ return result;
14962
+ }
14963
+ function limitForQuery(field, variables) {
14964
+ let first = 10; // default if not specified
14965
+ let firstArg = field.arguments &&
14966
+ field.arguments.find((a) => {
14967
+ return a.name.value === 'first';
14968
+ });
14969
+ if (firstArg) {
14970
+ if (firstArg.value.kind === 'IntValue') {
14971
+ first = Number(firstArg.value.value);
14972
+ }
14973
+ else if (firstArg.value.kind === 'Variable') {
14974
+ let value = variables[firstArg.value.name.value];
14975
+ if (value !== undefined) {
14976
+ first = Number(value);
14977
+ }
14978
+ }
14979
+ }
14980
+ return first;
14981
+ }
14982
+
14486
14983
  function generateUniqueRecordId() {
14487
14984
  return `UiApi::GraphQLRepresentation:${Date.now() + Math.random().toFixed(5).split('.')[1]}`;
14488
14985
  }
@@ -14526,7 +15023,11 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14526
15023
  return async function draftAwareGraphQLAdapter(config, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy, requestContext = {}) {
14527
15024
  //create a copy to not accidentally modify the AST in the astResolver map of luvio
14528
15025
  const copy = parse$3(stringify$3(config.query));
15026
+ // the injected ast has extra fields needed for eval in it
14529
15027
  let injectedAST;
15028
+ // the cursor mapped ast is passed upstream so it won't reject on our local cursors
15029
+ let cursorMappedAST;
15030
+ let mappedCursors = new Map();
14530
15031
  let objectInfoNeeded = {};
14531
15032
  let unmappedDraftIDs;
14532
15033
  let internalRequestContext = {
@@ -14536,12 +15037,27 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14536
15037
  isDraftId,
14537
15038
  getCanonicalId,
14538
15039
  };
15040
+ try {
15041
+ // NB: This occurs BEFORE synthetic field injection on purpose to
15042
+ // ensure we don't charge the caller for spanning records we inject
15043
+ // on their behalf.
15044
+ const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, requestContext.eventObservers || []);
15045
+ const queryInstrumentation = instrumentLimits(copy, config.variables || {});
15046
+ eventEmitter({
15047
+ type: 'graphql-query-instrumentation',
15048
+ data: queryInstrumentation,
15049
+ });
15050
+ }
15051
+ catch (_a) {
15052
+ // ignore errors instrumenting limits
15053
+ }
14539
15054
  try {
14540
15055
  ({
14541
15056
  modifiedAST: injectedAST,
14542
15057
  objectInfos: objectInfoNeeded,
14543
15058
  unmappedDraftIDs,
14544
15059
  } = await injectSyntheticFields(copy, objectInfoService, draftFunctions, config.variables));
15060
+ ({ ast: cursorMappedAST, mappedCursors } = await mapPaginationCursors(injectedAST, config.variables || {}, store));
14545
15061
  if (config.variables) {
14546
15062
  config.variables = replaceDraftIdsInVariables(config.variables, draftFunctions, unmappedDraftIDs);
14547
15063
  }
@@ -14573,7 +15089,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14573
15089
  const nonEvaluatedSnapshot = (await luvio.applyCachePolicy(internalRequestContext, {
14574
15090
  config: {
14575
15091
  ...config,
14576
- query: injectedAST,
15092
+ query: cursorMappedAST,
14577
15093
  },
14578
15094
  luvio,
14579
15095
  gqlEval: true,
@@ -14586,12 +15102,17 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14586
15102
  : [];
14587
15103
  let gqlResult;
14588
15104
  let seenRecordIds;
15105
+ let possibleStaleRecordMap;
14589
15106
  try {
14590
- ({ result: gqlResult, seenRecordIds } = await evaluate({
15107
+ ({
15108
+ result: gqlResult,
15109
+ seenRecordIds,
15110
+ possibleStaleRecordMap,
15111
+ } = await evaluate({
14591
15112
  ...config,
14592
15113
  //need to create another copy of the ast for future writes
14593
15114
  query: parse$3(stringify$3(injectedAST)),
14594
- }, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache));
15115
+ }, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors));
14595
15116
  }
14596
15117
  catch (throwable) {
14597
15118
  const error = throwable;
@@ -14617,13 +15138,18 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14617
15138
  const seenRecords = createSeenRecords(seenRecordIds, nonEvaluatedSnapshot);
14618
15139
  const recordId = generateUniqueRecordId();
14619
15140
  const rebuildWithLocalEval = async (originalSnapshot) => {
14620
- let { result: rebuildResult, seenRecordIds } = await evaluate({
15141
+ let { result: rebuildResult, seenRecordIds, possibleStaleRecordMap, } = await evaluate({
14621
15142
  ...config,
14622
15143
  query: injectedAST,
14623
- }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions);
15144
+ }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors);
14624
15145
  if (!rebuildResult.errors) {
14625
15146
  rebuildResult = removeSyntheticFields(rebuildResult, config.query);
14626
15147
  }
15148
+ let snapshotState = 'Fulfilled';
15149
+ if (possibleStaleRecordMap.size > 0) {
15150
+ initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
15151
+ snapshotState = 'Stale';
15152
+ }
14627
15153
  if (objectsDeepEqual(rebuildResult, originalSnapshot.data)) {
14628
15154
  return originalSnapshot;
14629
15155
  }
@@ -14632,6 +15158,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14632
15158
  ...originalSnapshot,
14633
15159
  data: rebuildResult,
14634
15160
  recordId,
15161
+ state: snapshotState,
14635
15162
  seenRecords: createSeenRecords(seenRecordIds, nonEvaluatedSnapshot),
14636
15163
  rebuildWithLocalEval,
14637
15164
  };
@@ -14669,9 +15196,31 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
14669
15196
  },
14670
15197
  };
14671
15198
  }
15199
+ if (possibleStaleRecordMap.size > 0) {
15200
+ initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
15201
+ resultSnapshot.state = 'Stale';
15202
+ }
14672
15203
  return resultSnapshot;
14673
15204
  };
14674
15205
  }
15206
+ function initiateStaleRecordRefresh(luvio, keyMap) {
15207
+ const staleRecordKeys = from$1(keyMap.values())
15208
+ .flat()
15209
+ .map((id) => `UiApi::RecordRepresentation:${id}`);
15210
+ luvio.storeExpirePossibleStaleRecords(staleRecordKeys, makeGetRecordsConfig(keyMap), batchingGetRecordsAdapterFactory(luvio));
15211
+ }
15212
+ function makeGetRecordsConfig(keyMap) {
15213
+ const records = [];
15214
+ keyMap.forEach((recordIds, apiName) => {
15215
+ records.push({
15216
+ recordIds,
15217
+ fields: [`${apiName}.Id`],
15218
+ });
15219
+ });
15220
+ return {
15221
+ records,
15222
+ };
15223
+ }
14675
15224
 
14676
15225
  function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, isDraftId) {
14677
15226
  return async function environmentAwareGraphQLBatchAdapter(config, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy, requestContext = {}) {
@@ -15805,6 +16354,9 @@ class NimbusDraftQueue {
15805
16354
  mergeActions(_targetActionId, _sourceActionId) {
15806
16355
  return Promise.reject(new Error('Cannot call mergeActions from the NimbusDraftQueue'));
15807
16356
  }
16357
+ retryAction(_actionId) {
16358
+ return Promise.reject(new Error('Cannot call retryAction from the NimbusDraftQueue'));
16359
+ }
15808
16360
  setMetadata(_actionId, _metadata) {
15809
16361
  return Promise.reject(new Error('Cannot call setMetadata from the NimbusDraftQueue'));
15810
16362
  }
@@ -15818,6 +16370,9 @@ class NimbusDraftQueue {
15818
16370
  removeHandler(_id) {
15819
16371
  return Promise.reject(new Error('Cannot call setMetadata from the NimbusDraftQueue'));
15820
16372
  }
16373
+ updateDraftAction(_action) {
16374
+ return Promise.reject(new Error('Cannot call updateDraftAction from the NimbusDraftQueue'));
16375
+ }
15821
16376
  }
15822
16377
 
15823
16378
  function attachObserversToAdapterRequestContext(observers, adapterRequestContext) {
@@ -15854,6 +16409,10 @@ const O11Y_NAMESPACE_LDS_MOBILE = 'lds-mobile';
15854
16409
  /** GraphQL */
15855
16410
  const GRAPHQL_EVAL_ERROR = 'gql-eval-error';
15856
16411
  const GRAPHQL_EVAL_DB_READ_DURATION = 'gql-eval-db-read-duration';
16412
+ const GRAPHQL_EVAL_ROOT_QUERY_COUNT = 'gql-eval-root-query-count';
16413
+ const GRAPHQL_EVAL_TOTAL_QUERY_COUNT = 'gql-eval-total-query-count';
16414
+ const GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT = 'gql-eval-max-child-count';
16415
+ const GRAPHQL_EVAL_QUERY_RECORD_COUNT = 'gql-eval-query-record-count';
15857
16416
  /** Draft Queue */
15858
16417
  const DRAFT_QUEUE_STATE_STARTED = 'draft-queue-state-started';
15859
16418
  const DRAFT_QUEUE_STATE_ERROR = 'draft-queue-state-error';
@@ -15911,6 +16470,16 @@ function reportGraphqlAdapterError(errorCode) {
15911
16470
  // Increment overall count with errorCode as tag
15912
16471
  ldsMobileInstrumentation.incrementCounter(GRAPHQL_EVAL_ERROR, 1, true, { errorCode });
15913
16472
  }
16473
+ function reportGraphqlQueryInstrumentation(data) {
16474
+ const queryBuckets = [1, 2, 3, 4, 5, 10, 20, 50, 100];
16475
+ const recordBuckets = [
16476
+ 1, 5, 10, 20, 50, 100, 1000, 2000, 5000, 10000, 50000, 100000, 1000000,
16477
+ ];
16478
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_ROOT_QUERY_COUNT, data.rootQueryCount, queryBuckets);
16479
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_TOTAL_QUERY_COUNT, data.totalQueryCount, queryBuckets);
16480
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_MAX_CHILD_RELATIONSHIPS_COUNT, data.maxChildRelationships, queryBuckets);
16481
+ ldsMobileInstrumentation.bucketValue(GRAPHQL_EVAL_QUERY_RECORD_COUNT, data.requestedRecordCount, recordBuckets);
16482
+ }
15914
16483
  function reportDraftActionEvent(state) {
15915
16484
  switch (state) {
15916
16485
  case 'added':
@@ -16308,6 +16877,7 @@ class ObjectInfoService {
16308
16877
  }
16309
16878
  }
16310
16879
 
16880
+ // importing from new adapter since old adapter always forwards now and code will be removed soon
16311
16881
  function instrumentGraphQLEval(adapter) {
16312
16882
  const graphQlEvalEventObserver = {
16313
16883
  onCustomAdapterEvent: (customEvent) => {
@@ -16323,6 +16893,9 @@ function instrumentGraphQLEval(adapter) {
16323
16893
  case 'graphql-db-read':
16324
16894
  reportGraphQlEvalDbReadDuration(data.duration);
16325
16895
  break;
16896
+ case 'graphql-query-instrumentation':
16897
+ reportGraphqlQueryInstrumentation(data.data);
16898
+ break;
16326
16899
  }
16327
16900
  }
16328
16901
  },
@@ -16355,12 +16928,14 @@ function instrumentContentDocumentVersionAdapter(adapter) {
16355
16928
  };
16356
16929
  }
16357
16930
 
16358
- const GRAPHQL_ADAPTER_NAME = 'graphQL';
16931
+ const GRAPHQL_LEGACY_ADAPTER_NAME = 'graphQL';
16932
+ const GRAPHQL_ADAPTER_NAME = 'graphql';
16359
16933
  const CREATE_CONTENT_DOCUMENT_AND_VERSION_ADAPTER = 'createContentDocumentAndVersion';
16360
16934
  let reportObservers = [];
16361
16935
  function instrumentAdapter(adapter, metadata) {
16362
16936
  let instrumentedMobileAdapter = adapter;
16363
16937
  switch (metadata.name) {
16938
+ case GRAPHQL_LEGACY_ADAPTER_NAME:
16364
16939
  case GRAPHQL_ADAPTER_NAME: {
16365
16940
  instrumentedMobileAdapter = instrumentGraphQLEval(adapter);
16366
16941
  break;
@@ -16370,10 +16945,11 @@ function instrumentAdapter(adapter, metadata) {
16370
16945
  break;
16371
16946
  }
16372
16947
  }
16948
+ let instrumentationEnabled = ldsAdapterO11yLoggingGate.isOpen({ fallback: false });
16373
16949
  return instrumentAdapter$1(instrumentedMobileAdapter, metadata, {
16374
- trackL1Hits: false,
16375
- trackL2Hits: false,
16376
- trackCacheMisses: false,
16950
+ trackL1Hits: instrumentationEnabled,
16951
+ trackL2Hits: instrumentationEnabled,
16952
+ trackCacheMisses: instrumentationEnabled,
16377
16953
  reportObserver: (report) => {
16378
16954
  for (const observer of reportObservers) {
16379
16955
  observer(report);
@@ -17075,6 +17651,21 @@ const NimbusBinaryStore = {
17075
17651
  __nimbus.plugins.LdsBinaryStorePlugin.setCanonicalUrl(uri, canonicalUrl, ttlSeconds, resolve, (err) => reject(errorMessageToError(err)));
17076
17652
  });
17077
17653
  },
17654
+ createStream: function (type) {
17655
+ return new Promise((resolve, reject) => {
17656
+ __nimbus.plugins.LdsBinaryStorePlugin.createStream(type, resolve, (err) => reject(errorMessageToError(err)));
17657
+ });
17658
+ },
17659
+ writeToStream: function (uri, chunk) {
17660
+ return new Promise((resolve, reject) => {
17661
+ __nimbus.plugins.LdsBinaryStorePlugin.writeToStream(uri, chunk, resolve, (err) => reject(errorMessageToError(err)));
17662
+ });
17663
+ },
17664
+ closeStream: function (uri) {
17665
+ return new Promise((resolve, reject) => {
17666
+ __nimbus.plugins.LdsBinaryStorePlugin.closeStream(uri, resolve, (err) => reject(errorMessageToError(err)));
17667
+ });
17668
+ },
17078
17669
  };
17079
17670
 
17080
17671
  /**
@@ -18404,7 +18995,6 @@ let lazyDurableStore;
18404
18995
  let lazyNetworkAdapter;
18405
18996
  let lazyObjectInfoService;
18406
18997
  let lazyGetRecords;
18407
- // TODO [W-123]: JHORST hoist, optimize and test this function
18408
18998
  const shouldFlush = (key, value) => {
18409
18999
  if (!isStoreKeyRecordId$1(key)) {
18410
19000
  return { flushValue: true };
@@ -18578,4 +19168,4 @@ register({
18578
19168
  });
18579
19169
 
18580
19170
  export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
18581
- // version: 1.303.0-a698c7cc67
19171
+ // version: 1.305.0-ec970f4bea