@salesforce/lds-runtime-mobile 1.153.0 → 1.155.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 +243 -34
- package/package.json +5 -5
- package/sfdc/main.js +243 -34
package/dist/main.js
CHANGED
|
@@ -521,7 +521,7 @@ function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
|
521
521
|
const DefaultDurableSegment = 'DEFAULT';
|
|
522
522
|
const RedirectDurableSegment = 'REDIRECT_KEYS';
|
|
523
523
|
|
|
524
|
-
const { keys: keys$6, create: create$5, assign: assign$
|
|
524
|
+
const { keys: keys$6, create: create$5, assign: assign$5, freeze: freeze$1 } = Object;
|
|
525
525
|
|
|
526
526
|
//Durable store error instrumentation key
|
|
527
527
|
const DURABLE_STORE_ERROR = 'durable-store-error';
|
|
@@ -4892,7 +4892,7 @@ function createDraftSynthesisErrorResponse(message = 'failed to synthesize draft
|
|
|
4892
4892
|
return new DraftErrorFetchResponse(HttpStatusCode.BadRequest, error);
|
|
4893
4893
|
}
|
|
4894
4894
|
|
|
4895
|
-
const { keys: keys$4, create: create$4, assign: assign$
|
|
4895
|
+
const { keys: keys$4, create: create$4, assign: assign$4, values: values$2 } = Object;
|
|
4896
4896
|
const { stringify: stringify$4, parse: parse$4 } = JSON;
|
|
4897
4897
|
const { isArray: isArray$3 } = Array;
|
|
4898
4898
|
|
|
@@ -6471,6 +6471,104 @@ function isEntryDurableRecordRepresentation(entry, key) {
|
|
|
6471
6471
|
entry.data.__type === undefined);
|
|
6472
6472
|
}
|
|
6473
6473
|
|
|
6474
|
+
function serializeFieldArguments(argumentNodes, variables) {
|
|
6475
|
+
const mutableArgumentNodes = Object.assign([], argumentNodes);
|
|
6476
|
+
return `args__(${mutableArgumentNodes
|
|
6477
|
+
.sort((a, b) => {
|
|
6478
|
+
const aName = a.name.value.toUpperCase();
|
|
6479
|
+
const bName = b.name.value.toUpperCase();
|
|
6480
|
+
return aName < bName ? -1 : aName > bName ? 1 : 0;
|
|
6481
|
+
})
|
|
6482
|
+
.map((node) => serializeArgNode(node, variables))
|
|
6483
|
+
.join('::')})`;
|
|
6484
|
+
}
|
|
6485
|
+
function serializeArgNode(argumentNode, variables) {
|
|
6486
|
+
const argName = argumentNode.name.value;
|
|
6487
|
+
return `${argName}:${serializeValueNode(argumentNode.value, variables)}`;
|
|
6488
|
+
}
|
|
6489
|
+
function serializeValueNode(valueNode, variables) {
|
|
6490
|
+
switch (valueNode.kind) {
|
|
6491
|
+
case 'BooleanValue':
|
|
6492
|
+
return valueNode.value + '';
|
|
6493
|
+
case 'IntValue':
|
|
6494
|
+
case 'FloatValue':
|
|
6495
|
+
case 'EnumValue':
|
|
6496
|
+
case 'StringValue':
|
|
6497
|
+
return valueNode.value;
|
|
6498
|
+
case 'ListValue': {
|
|
6499
|
+
const mutableValueNodeList = Object.assign([], valueNode.values);
|
|
6500
|
+
return mutableValueNodeList
|
|
6501
|
+
.sort((a, b) => {
|
|
6502
|
+
const aVal = serializeValueNode(a, variables).toUpperCase();
|
|
6503
|
+
const bVal = serializeValueNode(b, variables).toUpperCase();
|
|
6504
|
+
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
|
|
6505
|
+
})
|
|
6506
|
+
.map((val, i) => `${serializeValueNode(val, variables)}[${i}]`)
|
|
6507
|
+
.join(',');
|
|
6508
|
+
}
|
|
6509
|
+
case 'Variable': {
|
|
6510
|
+
const variableValue = variables[valueNode.name.value];
|
|
6511
|
+
return typeof variableValue === 'string'
|
|
6512
|
+
? variableValue
|
|
6513
|
+
: JSON.stringify(variableValue);
|
|
6514
|
+
}
|
|
6515
|
+
case 'NullValue':
|
|
6516
|
+
return 'null';
|
|
6517
|
+
case 'ObjectValue': {
|
|
6518
|
+
const mutableFieldNodeList = Object.assign([], valueNode.fields);
|
|
6519
|
+
return mutableFieldNodeList
|
|
6520
|
+
.sort((a, b) => {
|
|
6521
|
+
const aName = a.name.value.toUpperCase();
|
|
6522
|
+
const bName = b.name.value.toUpperCase();
|
|
6523
|
+
return aName < bName ? -1 : aName > bName ? 1 : 0;
|
|
6524
|
+
})
|
|
6525
|
+
.map((field) => field.name.value + ':' + serializeValueNode(field.value, variables))
|
|
6526
|
+
.join(',');
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
|
|
6531
|
+
function serializeOperationNode(operationNode, variables, fragmentMap) {
|
|
6532
|
+
return `${serializeSelectionSet(operationNode.selectionSet, variables, fragmentMap)}`;
|
|
6533
|
+
}
|
|
6534
|
+
function serializeSelectionSet(selectionSetNode, variables, fragmentMap) {
|
|
6535
|
+
return `${selectionSetNode.selections
|
|
6536
|
+
.map((selection) => serializeSelectionNode(selection, variables, fragmentMap))
|
|
6537
|
+
.join()}`;
|
|
6538
|
+
}
|
|
6539
|
+
/**
|
|
6540
|
+
*
|
|
6541
|
+
* @description This function takes a GraphQL SelectionNode from an AST and serializes it in a stable way, so we can
|
|
6542
|
+
* use it for property names and Store keys.
|
|
6543
|
+
* @param selectionNode
|
|
6544
|
+
* @param variables
|
|
6545
|
+
* @param fragmentMap
|
|
6546
|
+
* @returns string
|
|
6547
|
+
*/
|
|
6548
|
+
function serializeSelectionNode(selectionNode, variables, fragmentMap) {
|
|
6549
|
+
switch (selectionNode.kind) {
|
|
6550
|
+
case 'Field': {
|
|
6551
|
+
const hasArguments = selectionNode.arguments !== undefined && selectionNode.arguments.length > 0;
|
|
6552
|
+
const argumentSuffix = hasArguments
|
|
6553
|
+
? `__${serializeFieldArguments(selectionNode.arguments, variables)}`
|
|
6554
|
+
: '';
|
|
6555
|
+
return `${selectionNode.name.value}${argumentSuffix}`;
|
|
6556
|
+
}
|
|
6557
|
+
case 'FragmentSpread': {
|
|
6558
|
+
const fragment = fragmentMap[selectionNode.name.value];
|
|
6559
|
+
return fragment === undefined
|
|
6560
|
+
? selectionNode.name.value
|
|
6561
|
+
: serializeSelectionSet(fragment.selectionSet, variables, fragmentMap);
|
|
6562
|
+
}
|
|
6563
|
+
case 'InlineFragment':
|
|
6564
|
+
return serializeSelectionSet(selectionNode.selectionSet, variables, fragmentMap);
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
function buildQueryTypeStringKey(args) {
|
|
6568
|
+
const { keyPrefix, schemaName, queryTypeName, operationNode, variables, fragmentMap } = args;
|
|
6569
|
+
return `${keyPrefix}::${schemaName}::${queryTypeName}[${serializeOperationNode(operationNode, variables, fragmentMap)}]`;
|
|
6570
|
+
}
|
|
6571
|
+
|
|
6474
6572
|
/**
|
|
6475
6573
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
6476
6574
|
* All rights reserved.
|
|
@@ -6604,7 +6702,7 @@ function isArrayLike(x) {
|
|
|
6604
6702
|
(x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1))));
|
|
6605
6703
|
}
|
|
6606
6704
|
|
|
6607
|
-
const { create: create$3, keys: keys$3, values: values$1, entries: entries$2 } = Object;
|
|
6705
|
+
const { create: create$3, keys: keys$3, values: values$1, entries: entries$2, assign: assign$3 } = Object;
|
|
6608
6706
|
const { stringify: stringify$3, parse: parse$3 } = JSON;
|
|
6609
6707
|
const { isArray: isArray$2 } = Array;
|
|
6610
6708
|
|
|
@@ -7048,6 +7146,10 @@ function dateRangesFrom(dateRange, input, dateFunction) {
|
|
|
7048
7146
|
}
|
|
7049
7147
|
}
|
|
7050
7148
|
|
|
7149
|
+
const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
|
|
7150
|
+
const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
|
|
7151
|
+
const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
|
|
7152
|
+
|
|
7051
7153
|
const MultiPickListValueSeparator = ';';
|
|
7052
7154
|
function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
|
|
7053
7155
|
if (!where)
|
|
@@ -7109,7 +7211,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
7109
7211
|
return [
|
|
7110
7212
|
{
|
|
7111
7213
|
alias: childAlias,
|
|
7112
|
-
leftPath:
|
|
7214
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
7113
7215
|
operator: '=',
|
|
7114
7216
|
value: entityName,
|
|
7115
7217
|
dataType: 'String',
|
|
@@ -7570,11 +7672,18 @@ function buildQuery(config) {
|
|
|
7570
7672
|
const joins = buildJoins(config);
|
|
7571
7673
|
const predicates = buildPredicates(config);
|
|
7572
7674
|
const orderBy = buildOrderBy(config);
|
|
7675
|
+
const staleRecordsSql = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
7676
|
+
? `AND (
|
|
7677
|
+
json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
|
|
7678
|
+
OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
|
|
7679
|
+
)`
|
|
7680
|
+
: '';
|
|
7573
7681
|
const sql = `
|
|
7574
7682
|
SELECT "${config.alias}".data
|
|
7575
7683
|
FROM lds_data "${config.alias}" ${joins.sql}
|
|
7576
7684
|
WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
|
|
7577
|
-
AND json_extract("${config.alias}".data, '
|
|
7685
|
+
AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = ?
|
|
7686
|
+
${staleRecordsSql}
|
|
7578
7687
|
${predicates.sql}
|
|
7579
7688
|
${orderBy.sql}
|
|
7580
7689
|
LIMIT ?
|
|
@@ -7587,6 +7696,7 @@ function buildQuery(config) {
|
|
|
7587
7696
|
...joins.bindings,
|
|
7588
7697
|
// the api name for the main record type
|
|
7589
7698
|
config.alias,
|
|
7699
|
+
...(excludeStaleRecordsGate.isOpen({ fallback: false }) ? [config.ingestionTimestamp] : []),
|
|
7590
7700
|
// where clause and parent scope bindings
|
|
7591
7701
|
...predicates.bindings,
|
|
7592
7702
|
// limit binding
|
|
@@ -7612,19 +7722,33 @@ function buildJoins(config) {
|
|
|
7612
7722
|
if (allJoins.length === 0)
|
|
7613
7723
|
return { sql, bindings };
|
|
7614
7724
|
sql = allJoins.reduce((joinAccumulator, join) => {
|
|
7725
|
+
let timestampAdded = false;
|
|
7615
7726
|
const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
|
|
7616
7727
|
let joined_sql;
|
|
7728
|
+
const joinMetadataTimestamp = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
7729
|
+
? ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`
|
|
7730
|
+
: '';
|
|
7617
7731
|
// predicate on a value, use the newly joined table
|
|
7618
7732
|
if ('type' in condition) {
|
|
7619
7733
|
const { sql, binding } = predicateToSQL(condition, join.alias);
|
|
7620
|
-
joined_sql = ` AND ${sql}`;
|
|
7734
|
+
joined_sql = ` AND ${sql}${timestampAdded ? '' : joinMetadataTimestamp}`;
|
|
7621
7735
|
bindings.push(...binding);
|
|
7736
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
7737
|
+
timestampAdded === false) {
|
|
7738
|
+
bindings.push(config.ingestionTimestamp);
|
|
7739
|
+
timestampAdded = true;
|
|
7740
|
+
}
|
|
7622
7741
|
}
|
|
7623
7742
|
else {
|
|
7624
7743
|
// predicate on a path
|
|
7625
7744
|
const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
|
|
7626
7745
|
const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
|
|
7627
|
-
joined_sql = `${left} = ${right}`;
|
|
7746
|
+
joined_sql = `${left} = ${right}${timestampAdded ? '' : joinMetadataTimestamp}`;
|
|
7747
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
7748
|
+
timestampAdded === false) {
|
|
7749
|
+
bindings.push(config.ingestionTimestamp);
|
|
7750
|
+
timestampAdded = true;
|
|
7751
|
+
}
|
|
7628
7752
|
}
|
|
7629
7753
|
conditionAccumulator += joined_sql;
|
|
7630
7754
|
return conditionAccumulator;
|
|
@@ -8303,7 +8427,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
|
|
|
8303
8427
|
function pathForKey(key) {
|
|
8304
8428
|
switch (key) {
|
|
8305
8429
|
case 'ApiName':
|
|
8306
|
-
return
|
|
8430
|
+
return JSON_EXTRACT_PATH_INGESTION_APINAME;
|
|
8307
8431
|
case 'WeakEtag':
|
|
8308
8432
|
return '$.weakEtag';
|
|
8309
8433
|
case 'Id':
|
|
@@ -8325,7 +8449,7 @@ function scopeToJoins(scope = '', settings) {
|
|
|
8325
8449
|
{
|
|
8326
8450
|
type: PredicateType.single,
|
|
8327
8451
|
alias: 'ServiceAppointment_AssignedResource',
|
|
8328
|
-
leftPath:
|
|
8452
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
8329
8453
|
operator: '=',
|
|
8330
8454
|
value: 'AssignedResource',
|
|
8331
8455
|
dataType: 'String',
|
|
@@ -8346,7 +8470,7 @@ function scopeToJoins(scope = '', settings) {
|
|
|
8346
8470
|
{
|
|
8347
8471
|
type: PredicateType.single,
|
|
8348
8472
|
alias: 'ServiceAppointment_AssignedResource_ServiceResource',
|
|
8349
|
-
leftPath:
|
|
8473
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
8350
8474
|
operator: '=',
|
|
8351
8475
|
value: 'ServiceResource',
|
|
8352
8476
|
dataType: 'String',
|
|
@@ -8451,14 +8575,21 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8451
8575
|
// Fields of the `RecordQuery` type are the record queries for the entity types
|
|
8452
8576
|
// supported for the org
|
|
8453
8577
|
for (const recordQuery of fields) {
|
|
8454
|
-
recordQuery.resolve = function recordConnectionResolver(record, args) {
|
|
8578
|
+
recordQuery.resolve = async function recordConnectionResolver(record, args, { query }, info) {
|
|
8579
|
+
const { name: currentFieldName } = recordQuery;
|
|
8580
|
+
let ingestionTimestamp = 0;
|
|
8581
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
8582
|
+
// at our record query we fetch each ingestion time stamp and pass it down to each lower resolver to query against
|
|
8583
|
+
ingestionTimestamp = await fetchIngestionTimeStampFromDatabase(currentFieldName, info, args, query);
|
|
8584
|
+
}
|
|
8455
8585
|
// In the SF schema, the relevant arguments are passed into RecordQuery fields, but actually used
|
|
8456
8586
|
// down in the edge resolvers. For this resolver, we can just return what was passed in
|
|
8457
8587
|
// to make it available to the next execution step
|
|
8458
8588
|
return {
|
|
8459
8589
|
parentArgs: args,
|
|
8460
8590
|
parentRecord: record,
|
|
8461
|
-
currentFieldName
|
|
8591
|
+
currentFieldName,
|
|
8592
|
+
ingestionTimestamp,
|
|
8462
8593
|
};
|
|
8463
8594
|
};
|
|
8464
8595
|
}
|
|
@@ -8504,10 +8635,11 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8504
8635
|
// }
|
|
8505
8636
|
for (const field of fields) {
|
|
8506
8637
|
if (field.name === 'node') {
|
|
8507
|
-
field.resolve = function nodeResolver(
|
|
8638
|
+
field.resolve = function nodeResolver(obj, _args, { seenRecordIds }) {
|
|
8639
|
+
const { record, ingestionTimestamp } = obj;
|
|
8508
8640
|
const recordRepresentation = parse$3(record);
|
|
8509
8641
|
seenRecordIds.add(recordRepresentation.id);
|
|
8510
|
-
return recordRepresentation;
|
|
8642
|
+
return { recordRepresentation, ingestionTimestamp };
|
|
8511
8643
|
};
|
|
8512
8644
|
}
|
|
8513
8645
|
}
|
|
@@ -8530,40 +8662,40 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8530
8662
|
for (const field of fields) {
|
|
8531
8663
|
switch (field.name) {
|
|
8532
8664
|
case 'Id':
|
|
8533
|
-
field.resolve = (record) => record.id;
|
|
8665
|
+
field.resolve = ({ recordRepresentation: record }) => record.id;
|
|
8534
8666
|
break;
|
|
8535
8667
|
case 'ApiName':
|
|
8536
|
-
field.resolve = (record) => record.apiName;
|
|
8668
|
+
field.resolve = ({ recordRepresentation: record }) => record.apiName;
|
|
8537
8669
|
break;
|
|
8538
8670
|
case 'WeakEtag':
|
|
8539
|
-
field.resolve = (record) => record.weakEtag;
|
|
8671
|
+
field.resolve = ({ recordRepresentation: record }) => record.weakEtag;
|
|
8540
8672
|
break;
|
|
8541
8673
|
case '_drafts':
|
|
8542
|
-
field.resolve = (record) => {
|
|
8674
|
+
field.resolve = ({ recordRepresentation: record, }) => {
|
|
8543
8675
|
return record.drafts ? record.drafts : null;
|
|
8544
8676
|
};
|
|
8545
8677
|
break;
|
|
8546
8678
|
case 'LastModifiedById':
|
|
8547
|
-
field.resolve = (record) => {
|
|
8679
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8548
8680
|
return record.lastModifiedById
|
|
8549
8681
|
? { value: record.lastModifiedById }
|
|
8550
8682
|
: null;
|
|
8551
8683
|
};
|
|
8552
8684
|
break;
|
|
8553
8685
|
case 'LastModifiedDate':
|
|
8554
|
-
field.resolve = (record) => {
|
|
8686
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8555
8687
|
return record.lastModifiedDate
|
|
8556
8688
|
? { value: record.lastModifiedDate }
|
|
8557
8689
|
: null;
|
|
8558
8690
|
};
|
|
8559
8691
|
break;
|
|
8560
8692
|
case 'SystemModstamp':
|
|
8561
|
-
field.resolve = (record) => {
|
|
8693
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8562
8694
|
return record.systemModstamp ? { value: record.systemModstamp } : null;
|
|
8563
8695
|
};
|
|
8564
8696
|
break;
|
|
8565
8697
|
case 'RecordTypeId':
|
|
8566
|
-
field.resolve = (record) => {
|
|
8698
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8567
8699
|
return record.recordTypeId ? { value: record.recordTypeId } : null;
|
|
8568
8700
|
};
|
|
8569
8701
|
break;
|
|
@@ -8575,7 +8707,17 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8575
8707
|
.getInterfaces()
|
|
8576
8708
|
.find((iface) => iface.name === 'Record')) ||
|
|
8577
8709
|
(recordFieldType && recordFieldType.name === 'Record')) {
|
|
8578
|
-
field.resolve = function relationResolver(
|
|
8710
|
+
field.resolve = async function relationResolver(obj, _args, { Record, seenRecordIds }) {
|
|
8711
|
+
const fetchRecordOrNull = async (key) => {
|
|
8712
|
+
const recordRepresentation = await Record.load(key);
|
|
8713
|
+
return recordRepresentation !== null
|
|
8714
|
+
? {
|
|
8715
|
+
recordRepresentation,
|
|
8716
|
+
ingestionTimestamp,
|
|
8717
|
+
}
|
|
8718
|
+
: null;
|
|
8719
|
+
};
|
|
8720
|
+
const { recordRepresentation: record, ingestionTimestamp } = obj;
|
|
8579
8721
|
const fieldName = field.name.endsWith('__r')
|
|
8580
8722
|
? field.name.replace('__r', '__c')
|
|
8581
8723
|
: field.name;
|
|
@@ -8585,26 +8727,28 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8585
8727
|
if (!id)
|
|
8586
8728
|
return null;
|
|
8587
8729
|
if (id['__ref'] !== undefined) {
|
|
8588
|
-
return
|
|
8730
|
+
return fetchRecordOrNull(record.fields[`${field.name}Id`].value);
|
|
8589
8731
|
}
|
|
8590
8732
|
seenRecordIds.add(id);
|
|
8591
|
-
return
|
|
8733
|
+
return fetchRecordOrNull(id);
|
|
8592
8734
|
};
|
|
8593
8735
|
}
|
|
8594
8736
|
else if (isObjectType(recordFieldType) &&
|
|
8595
8737
|
field.type.name.endsWith('Connection')) {
|
|
8596
8738
|
// spanning field to a connection
|
|
8597
|
-
field.resolve = (
|
|
8598
|
-
seenRecordIds.add(
|
|
8739
|
+
field.resolve = async ({ recordRepresentation, ingestionTimestamp }, args, { seenRecordIds }) => {
|
|
8740
|
+
seenRecordIds.add(recordRepresentation.id);
|
|
8741
|
+
const { name: currentFieldName } = field;
|
|
8599
8742
|
return {
|
|
8600
8743
|
parentArgs: args,
|
|
8601
|
-
parentRecord:
|
|
8602
|
-
currentFieldName
|
|
8744
|
+
parentRecord: recordRepresentation,
|
|
8745
|
+
currentFieldName,
|
|
8746
|
+
ingestionTimestamp,
|
|
8603
8747
|
};
|
|
8604
8748
|
};
|
|
8605
8749
|
}
|
|
8606
8750
|
else {
|
|
8607
|
-
field.resolve = function recordFieldResolver(record) {
|
|
8751
|
+
field.resolve = function recordFieldResolver({ recordRepresentation: record, }) {
|
|
8608
8752
|
return record.fields[field.name] || null;
|
|
8609
8753
|
};
|
|
8610
8754
|
}
|
|
@@ -8616,7 +8760,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8616
8760
|
if (recordInterface !== undefined && baseRecord !== undefined) {
|
|
8617
8761
|
// Applys 'resolveType' of GraphQLInterfaceType to 'Record' interface. Since all the heterogenous types are named as 'apiName', the type with same name as the loaded record 'apiName' property is the type wanted.
|
|
8618
8762
|
// GraphQL executor would match InLineFragment' condition with type and keeps the deeper level field resolving going.
|
|
8619
|
-
recordInterface.resolveType = function (value) {
|
|
8763
|
+
recordInterface.resolveType = function ({ recordRepresentation: value, }) {
|
|
8620
8764
|
const targetType = polyTypes.find((type) => type.name === value.apiName);
|
|
8621
8765
|
return targetType === undefined ? baseRecord : targetType;
|
|
8622
8766
|
};
|
|
@@ -8624,7 +8768,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8624
8768
|
return schema;
|
|
8625
8769
|
}
|
|
8626
8770
|
async function connectionEdgeResolver(obj, _args, context) {
|
|
8627
|
-
const { parentArgs = {}, parentRecord, currentFieldName } = obj;
|
|
8771
|
+
const { parentArgs = {}, parentRecord, currentFieldName, ingestionTimestamp } = obj;
|
|
8628
8772
|
const { query, objectInfos, draftFunctions } = context;
|
|
8629
8773
|
let joins = [];
|
|
8630
8774
|
let alias = currentFieldName;
|
|
@@ -8655,10 +8799,19 @@ async function connectionEdgeResolver(obj, _args, context) {
|
|
|
8655
8799
|
predicates,
|
|
8656
8800
|
orderBy: orderByToPredicate(parentArgs.orderBy, alias, alias, context.objectInfos),
|
|
8657
8801
|
limit: parentArgs.first,
|
|
8802
|
+
ingestionTimestamp,
|
|
8658
8803
|
};
|
|
8659
8804
|
const { sql, bindings } = buildQuery(queryConfig);
|
|
8660
8805
|
const results = await query(sql, bindings);
|
|
8661
|
-
|
|
8806
|
+
//map each sql result with the ingestion timestamp to pass it down a level
|
|
8807
|
+
return results.rows
|
|
8808
|
+
.map((row) => row[0])
|
|
8809
|
+
.map((record) => {
|
|
8810
|
+
return {
|
|
8811
|
+
record,
|
|
8812
|
+
ingestionTimestamp,
|
|
8813
|
+
};
|
|
8814
|
+
});
|
|
8662
8815
|
}
|
|
8663
8816
|
/**
|
|
8664
8817
|
* Converts a childRelationship into a predicate
|
|
@@ -8684,6 +8837,62 @@ function isRecordType(type) {
|
|
|
8684
8837
|
const interfaces = type.getInterfaces();
|
|
8685
8838
|
return Boolean(interfaces.find((iface) => iface.name === 'Record'));
|
|
8686
8839
|
}
|
|
8840
|
+
/**
|
|
8841
|
+
* Builds the top level record query key based on AST data
|
|
8842
|
+
* @param operation
|
|
8843
|
+
* @param variables
|
|
8844
|
+
* @param argumentNodes
|
|
8845
|
+
* @param currentFieldName
|
|
8846
|
+
* @returns
|
|
8847
|
+
*/
|
|
8848
|
+
function buildKeyStringForRecordQuery(operation, variables, argumentNodes, currentFieldName) {
|
|
8849
|
+
const queryKey = buildQueryTypeStringKey({
|
|
8850
|
+
luvio: {},
|
|
8851
|
+
keyPrefix: 'UiApi',
|
|
8852
|
+
schemaName: 'uiapi',
|
|
8853
|
+
queryTypeName: 'Query',
|
|
8854
|
+
operationNode: operation,
|
|
8855
|
+
variables,
|
|
8856
|
+
fragmentMap: {},
|
|
8857
|
+
});
|
|
8858
|
+
const filteredArgumentNodes = assign$3([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
|
|
8859
|
+
const argumentString = filteredArgumentNodes.length > 0
|
|
8860
|
+
? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
|
|
8861
|
+
: '';
|
|
8862
|
+
return `${queryKey}__uiapi__query__${currentFieldName}${argumentString}`;
|
|
8863
|
+
}
|
|
8864
|
+
/**
|
|
8865
|
+
* fetches a query level ingestion time stamp from the L2 cache
|
|
8866
|
+
* if no query has been seen then the timestamp is 0
|
|
8867
|
+
* @param apiName
|
|
8868
|
+
* @param info
|
|
8869
|
+
* @param args
|
|
8870
|
+
* @param query
|
|
8871
|
+
* @returns
|
|
8872
|
+
*/
|
|
8873
|
+
async function fetchIngestionTimeStampFromDatabase(apiName, info, args, query) {
|
|
8874
|
+
const { operation, variableValues } = info;
|
|
8875
|
+
// if we cannot find the query key in the database then default to 0 as we assume we have not seen the query
|
|
8876
|
+
// and all the data is not stale
|
|
8877
|
+
let ingestionTimestamp = 0;
|
|
8878
|
+
if (info.fieldNodes.length > 0 && info.fieldNodes[0].arguments !== undefined) {
|
|
8879
|
+
const key = buildKeyStringForRecordQuery(operation,
|
|
8880
|
+
// join varables passed from query to the argument variables given from the AST
|
|
8881
|
+
{ ...variableValues, ...args }, info.fieldNodes[0].arguments, apiName);
|
|
8882
|
+
const sql = `
|
|
8883
|
+
SELECT json_extract(metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}')
|
|
8884
|
+
FROM lds_data
|
|
8885
|
+
WHERE key IS ?
|
|
8886
|
+
`;
|
|
8887
|
+
const results = await query(sql, [key]);
|
|
8888
|
+
const [timestamp] = results.rows.map((row) => row[0]);
|
|
8889
|
+
if (timestamp !== null && typeof timestamp === 'number') {
|
|
8890
|
+
//go back 10 ms to adjust for margin of error when top level query is stored and when raml objects are stored
|
|
8891
|
+
ingestionTimestamp = timestamp - 10;
|
|
8892
|
+
}
|
|
8893
|
+
}
|
|
8894
|
+
return ingestionTimestamp;
|
|
8895
|
+
}
|
|
8687
8896
|
|
|
8688
8897
|
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 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 rateLimit: RateLimit\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 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\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\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]): [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\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 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 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\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 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\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 LAST\n FIRST\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\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\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\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\ntype ThemeInfo {\n color: String\n iconUrl: String\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 THIS_WEEK\n THIS_FISCAL_QUARTER\n NEXT_YEAR\n TODAY\n LAST_WEEK\n LAST_YEAR\n YESTERDAY\n NEXT_MONTH\n NEXT_FISCAL_YEAR\n NEXT_WEEK\n NEXT_90_DAYS\n LAST_FISCAL_QUARTER\n LAST_FISCAL_YEAR\n THIS_YEAR\n THIS_MONTH\n THIS_QUARTER\n LAST_90_DAYS\n NEXT_FISCAL_QUARTER\n THIS_FISCAL_YEAR\n TOMORROW\n NEXT_QUARTER\n LAST_MONTH\n LAST_QUARTER\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): RecordConnection @fieldCategory\n}\n\ntype IDValue implements FieldValue {\n value: ID\n displayValue: String\n}\n\nenum Unit {\n MI\n KM\n}\n\ninput OrderByGeolocationClause {\n distance: DistanceInput\n order: ResultOrder\n nulls: NullOrder\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 DESC\n ASC\n}\n\ninput RecordOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: RecordOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ninput PicklistOperators {\n eq: Picklist\n ne: Picklist\n in: [Picklist]\n nin: [Picklist]\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\ntype DateTimeValue implements FieldValue {\n value: DateTime\n displayValue: String\n format: String\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 LongValue implements FieldValue {\n value: Long\n displayValue: String\n format: String\n}\n\ninput DateFunctionInput {\n value: LongOperators\n convertTimezoneValue: LongOperators\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 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\ntype BooleanAggregate implements FieldValue {\n value: Boolean\n displayValue: String\n grouping: IntValue\n}\n\ntype RecordQueryAggregate {\n recordQueryAggregate(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String, groupBy: RecordGroupBy): RecordAggregateConnection @fieldCategory\n}\n\ntype RecordConnection @generic {\n edges: [RecordEdge]\n pageInfo: PageInfo!\n totalCount: 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}\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\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\ninput DateTimeFunctionInput {\n value: DateTimePrimitiveOperators\n convertTimezoneValue: DateTimePrimitiveOperators\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\ntype __Schema {\n types: [__Type!]!\n queryType: __Type!\n mutationType: __Type\n directives: [__Directive!]!\n subscriptionType: __Type\n}\n\ninput DateTimeInput {\n value: DateTime\n literal: DateLiteral\n range: DateRange\n}\n\ninput DateTimePrimitiveOperators {\n eq: DateTime\n ne: DateTime\n lt: DateTime\n gt: DateTime\n lte: DateTime\n gte: DateTime\n in: [DateTime]\n nin: [DateTime]\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 it cannot currently be used\n recordQuery(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String): 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 on FIELD\n\n\n\n\n\n\n\n";
|
|
8689
8898
|
|
|
@@ -15767,4 +15976,4 @@ register({
|
|
|
15767
15976
|
});
|
|
15768
15977
|
|
|
15769
15978
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15770
|
-
// version: 1.
|
|
15979
|
+
// version: 1.155.0-96e212d1e
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.155.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
{
|
|
58
58
|
"path": "./dist/main.js",
|
|
59
59
|
"maxSize": {
|
|
60
|
-
"none": "
|
|
61
|
-
"min": "
|
|
60
|
+
"none": "700 kB",
|
|
61
|
+
"min": "280 kB",
|
|
62
62
|
"compressed": "110 kB"
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"path": "./sfdc/main.js",
|
|
67
67
|
"maxSize": {
|
|
68
|
-
"none": "
|
|
69
|
-
"min": "
|
|
68
|
+
"none": "700 kB",
|
|
69
|
+
"min": "280 kB",
|
|
70
70
|
"compressed": "110 kB"
|
|
71
71
|
}
|
|
72
72
|
}
|
package/sfdc/main.js
CHANGED
|
@@ -521,7 +521,7 @@ function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
|
521
521
|
const DefaultDurableSegment = 'DEFAULT';
|
|
522
522
|
const RedirectDurableSegment = 'REDIRECT_KEYS';
|
|
523
523
|
|
|
524
|
-
const { keys: keys$6, create: create$5, assign: assign$
|
|
524
|
+
const { keys: keys$6, create: create$5, assign: assign$5, freeze: freeze$1 } = Object;
|
|
525
525
|
|
|
526
526
|
//Durable store error instrumentation key
|
|
527
527
|
const DURABLE_STORE_ERROR = 'durable-store-error';
|
|
@@ -4892,7 +4892,7 @@ function createDraftSynthesisErrorResponse(message = 'failed to synthesize draft
|
|
|
4892
4892
|
return new DraftErrorFetchResponse(HttpStatusCode.BadRequest, error);
|
|
4893
4893
|
}
|
|
4894
4894
|
|
|
4895
|
-
const { keys: keys$4, create: create$4, assign: assign$
|
|
4895
|
+
const { keys: keys$4, create: create$4, assign: assign$4, values: values$2 } = Object;
|
|
4896
4896
|
const { stringify: stringify$4, parse: parse$4 } = JSON;
|
|
4897
4897
|
const { isArray: isArray$3 } = Array;
|
|
4898
4898
|
|
|
@@ -6471,6 +6471,104 @@ function isEntryDurableRecordRepresentation(entry, key) {
|
|
|
6471
6471
|
entry.data.__type === undefined);
|
|
6472
6472
|
}
|
|
6473
6473
|
|
|
6474
|
+
function serializeFieldArguments(argumentNodes, variables) {
|
|
6475
|
+
const mutableArgumentNodes = Object.assign([], argumentNodes);
|
|
6476
|
+
return `args__(${mutableArgumentNodes
|
|
6477
|
+
.sort((a, b) => {
|
|
6478
|
+
const aName = a.name.value.toUpperCase();
|
|
6479
|
+
const bName = b.name.value.toUpperCase();
|
|
6480
|
+
return aName < bName ? -1 : aName > bName ? 1 : 0;
|
|
6481
|
+
})
|
|
6482
|
+
.map((node) => serializeArgNode(node, variables))
|
|
6483
|
+
.join('::')})`;
|
|
6484
|
+
}
|
|
6485
|
+
function serializeArgNode(argumentNode, variables) {
|
|
6486
|
+
const argName = argumentNode.name.value;
|
|
6487
|
+
return `${argName}:${serializeValueNode(argumentNode.value, variables)}`;
|
|
6488
|
+
}
|
|
6489
|
+
function serializeValueNode(valueNode, variables) {
|
|
6490
|
+
switch (valueNode.kind) {
|
|
6491
|
+
case 'BooleanValue':
|
|
6492
|
+
return valueNode.value + '';
|
|
6493
|
+
case 'IntValue':
|
|
6494
|
+
case 'FloatValue':
|
|
6495
|
+
case 'EnumValue':
|
|
6496
|
+
case 'StringValue':
|
|
6497
|
+
return valueNode.value;
|
|
6498
|
+
case 'ListValue': {
|
|
6499
|
+
const mutableValueNodeList = Object.assign([], valueNode.values);
|
|
6500
|
+
return mutableValueNodeList
|
|
6501
|
+
.sort((a, b) => {
|
|
6502
|
+
const aVal = serializeValueNode(a, variables).toUpperCase();
|
|
6503
|
+
const bVal = serializeValueNode(b, variables).toUpperCase();
|
|
6504
|
+
return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
|
|
6505
|
+
})
|
|
6506
|
+
.map((val, i) => `${serializeValueNode(val, variables)}[${i}]`)
|
|
6507
|
+
.join(',');
|
|
6508
|
+
}
|
|
6509
|
+
case 'Variable': {
|
|
6510
|
+
const variableValue = variables[valueNode.name.value];
|
|
6511
|
+
return typeof variableValue === 'string'
|
|
6512
|
+
? variableValue
|
|
6513
|
+
: JSON.stringify(variableValue);
|
|
6514
|
+
}
|
|
6515
|
+
case 'NullValue':
|
|
6516
|
+
return 'null';
|
|
6517
|
+
case 'ObjectValue': {
|
|
6518
|
+
const mutableFieldNodeList = Object.assign([], valueNode.fields);
|
|
6519
|
+
return mutableFieldNodeList
|
|
6520
|
+
.sort((a, b) => {
|
|
6521
|
+
const aName = a.name.value.toUpperCase();
|
|
6522
|
+
const bName = b.name.value.toUpperCase();
|
|
6523
|
+
return aName < bName ? -1 : aName > bName ? 1 : 0;
|
|
6524
|
+
})
|
|
6525
|
+
.map((field) => field.name.value + ':' + serializeValueNode(field.value, variables))
|
|
6526
|
+
.join(',');
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
|
|
6531
|
+
function serializeOperationNode(operationNode, variables, fragmentMap) {
|
|
6532
|
+
return `${serializeSelectionSet(operationNode.selectionSet, variables, fragmentMap)}`;
|
|
6533
|
+
}
|
|
6534
|
+
function serializeSelectionSet(selectionSetNode, variables, fragmentMap) {
|
|
6535
|
+
return `${selectionSetNode.selections
|
|
6536
|
+
.map((selection) => serializeSelectionNode(selection, variables, fragmentMap))
|
|
6537
|
+
.join()}`;
|
|
6538
|
+
}
|
|
6539
|
+
/**
|
|
6540
|
+
*
|
|
6541
|
+
* @description This function takes a GraphQL SelectionNode from an AST and serializes it in a stable way, so we can
|
|
6542
|
+
* use it for property names and Store keys.
|
|
6543
|
+
* @param selectionNode
|
|
6544
|
+
* @param variables
|
|
6545
|
+
* @param fragmentMap
|
|
6546
|
+
* @returns string
|
|
6547
|
+
*/
|
|
6548
|
+
function serializeSelectionNode(selectionNode, variables, fragmentMap) {
|
|
6549
|
+
switch (selectionNode.kind) {
|
|
6550
|
+
case 'Field': {
|
|
6551
|
+
const hasArguments = selectionNode.arguments !== undefined && selectionNode.arguments.length > 0;
|
|
6552
|
+
const argumentSuffix = hasArguments
|
|
6553
|
+
? `__${serializeFieldArguments(selectionNode.arguments, variables)}`
|
|
6554
|
+
: '';
|
|
6555
|
+
return `${selectionNode.name.value}${argumentSuffix}`;
|
|
6556
|
+
}
|
|
6557
|
+
case 'FragmentSpread': {
|
|
6558
|
+
const fragment = fragmentMap[selectionNode.name.value];
|
|
6559
|
+
return fragment === undefined
|
|
6560
|
+
? selectionNode.name.value
|
|
6561
|
+
: serializeSelectionSet(fragment.selectionSet, variables, fragmentMap);
|
|
6562
|
+
}
|
|
6563
|
+
case 'InlineFragment':
|
|
6564
|
+
return serializeSelectionSet(selectionNode.selectionSet, variables, fragmentMap);
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
function buildQueryTypeStringKey(args) {
|
|
6568
|
+
const { keyPrefix, schemaName, queryTypeName, operationNode, variables, fragmentMap } = args;
|
|
6569
|
+
return `${keyPrefix}::${schemaName}::${queryTypeName}[${serializeOperationNode(operationNode, variables, fragmentMap)}]`;
|
|
6570
|
+
}
|
|
6571
|
+
|
|
6474
6572
|
/**
|
|
6475
6573
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
6476
6574
|
* All rights reserved.
|
|
@@ -6604,7 +6702,7 @@ function isArrayLike(x) {
|
|
|
6604
6702
|
(x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1))));
|
|
6605
6703
|
}
|
|
6606
6704
|
|
|
6607
|
-
const { create: create$3, keys: keys$3, values: values$1, entries: entries$2 } = Object;
|
|
6705
|
+
const { create: create$3, keys: keys$3, values: values$1, entries: entries$2, assign: assign$3 } = Object;
|
|
6608
6706
|
const { stringify: stringify$3, parse: parse$3 } = JSON;
|
|
6609
6707
|
const { isArray: isArray$2 } = Array;
|
|
6610
6708
|
|
|
@@ -7048,6 +7146,10 @@ function dateRangesFrom(dateRange, input, dateFunction) {
|
|
|
7048
7146
|
}
|
|
7049
7147
|
}
|
|
7050
7148
|
|
|
7149
|
+
const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
|
|
7150
|
+
const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
|
|
7151
|
+
const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
|
|
7152
|
+
|
|
7051
7153
|
const MultiPickListValueSeparator = ';';
|
|
7052
7154
|
function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
|
|
7053
7155
|
if (!where)
|
|
@@ -7109,7 +7211,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
7109
7211
|
return [
|
|
7110
7212
|
{
|
|
7111
7213
|
alias: childAlias,
|
|
7112
|
-
leftPath:
|
|
7214
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
7113
7215
|
operator: '=',
|
|
7114
7216
|
value: entityName,
|
|
7115
7217
|
dataType: 'String',
|
|
@@ -7570,11 +7672,18 @@ function buildQuery(config) {
|
|
|
7570
7672
|
const joins = buildJoins(config);
|
|
7571
7673
|
const predicates = buildPredicates(config);
|
|
7572
7674
|
const orderBy = buildOrderBy(config);
|
|
7675
|
+
const staleRecordsSql = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
7676
|
+
? `AND (
|
|
7677
|
+
json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
|
|
7678
|
+
OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
|
|
7679
|
+
)`
|
|
7680
|
+
: '';
|
|
7573
7681
|
const sql = `
|
|
7574
7682
|
SELECT "${config.alias}".data
|
|
7575
7683
|
FROM lds_data "${config.alias}" ${joins.sql}
|
|
7576
7684
|
WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
|
|
7577
|
-
AND json_extract("${config.alias}".data, '
|
|
7685
|
+
AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = ?
|
|
7686
|
+
${staleRecordsSql}
|
|
7578
7687
|
${predicates.sql}
|
|
7579
7688
|
${orderBy.sql}
|
|
7580
7689
|
LIMIT ?
|
|
@@ -7587,6 +7696,7 @@ function buildQuery(config) {
|
|
|
7587
7696
|
...joins.bindings,
|
|
7588
7697
|
// the api name for the main record type
|
|
7589
7698
|
config.alias,
|
|
7699
|
+
...(excludeStaleRecordsGate.isOpen({ fallback: false }) ? [config.ingestionTimestamp] : []),
|
|
7590
7700
|
// where clause and parent scope bindings
|
|
7591
7701
|
...predicates.bindings,
|
|
7592
7702
|
// limit binding
|
|
@@ -7612,19 +7722,33 @@ function buildJoins(config) {
|
|
|
7612
7722
|
if (allJoins.length === 0)
|
|
7613
7723
|
return { sql, bindings };
|
|
7614
7724
|
sql = allJoins.reduce((joinAccumulator, join) => {
|
|
7725
|
+
let timestampAdded = false;
|
|
7615
7726
|
const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
|
|
7616
7727
|
let joined_sql;
|
|
7728
|
+
const joinMetadataTimestamp = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
7729
|
+
? ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`
|
|
7730
|
+
: '';
|
|
7617
7731
|
// predicate on a value, use the newly joined table
|
|
7618
7732
|
if ('type' in condition) {
|
|
7619
7733
|
const { sql, binding } = predicateToSQL(condition, join.alias);
|
|
7620
|
-
joined_sql = ` AND ${sql}`;
|
|
7734
|
+
joined_sql = ` AND ${sql}${timestampAdded ? '' : joinMetadataTimestamp}`;
|
|
7621
7735
|
bindings.push(...binding);
|
|
7736
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
7737
|
+
timestampAdded === false) {
|
|
7738
|
+
bindings.push(config.ingestionTimestamp);
|
|
7739
|
+
timestampAdded = true;
|
|
7740
|
+
}
|
|
7622
7741
|
}
|
|
7623
7742
|
else {
|
|
7624
7743
|
// predicate on a path
|
|
7625
7744
|
const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
|
|
7626
7745
|
const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
|
|
7627
|
-
joined_sql = `${left} = ${right}`;
|
|
7746
|
+
joined_sql = `${left} = ${right}${timestampAdded ? '' : joinMetadataTimestamp}`;
|
|
7747
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
7748
|
+
timestampAdded === false) {
|
|
7749
|
+
bindings.push(config.ingestionTimestamp);
|
|
7750
|
+
timestampAdded = true;
|
|
7751
|
+
}
|
|
7628
7752
|
}
|
|
7629
7753
|
conditionAccumulator += joined_sql;
|
|
7630
7754
|
return conditionAccumulator;
|
|
@@ -8303,7 +8427,7 @@ function orderByToPredicate(orderBy, recordType, alias, objectInfoMap, joins) {
|
|
|
8303
8427
|
function pathForKey(key) {
|
|
8304
8428
|
switch (key) {
|
|
8305
8429
|
case 'ApiName':
|
|
8306
|
-
return
|
|
8430
|
+
return JSON_EXTRACT_PATH_INGESTION_APINAME;
|
|
8307
8431
|
case 'WeakEtag':
|
|
8308
8432
|
return '$.weakEtag';
|
|
8309
8433
|
case 'Id':
|
|
@@ -8325,7 +8449,7 @@ function scopeToJoins(scope = '', settings) {
|
|
|
8325
8449
|
{
|
|
8326
8450
|
type: PredicateType.single,
|
|
8327
8451
|
alias: 'ServiceAppointment_AssignedResource',
|
|
8328
|
-
leftPath:
|
|
8452
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
8329
8453
|
operator: '=',
|
|
8330
8454
|
value: 'AssignedResource',
|
|
8331
8455
|
dataType: 'String',
|
|
@@ -8346,7 +8470,7 @@ function scopeToJoins(scope = '', settings) {
|
|
|
8346
8470
|
{
|
|
8347
8471
|
type: PredicateType.single,
|
|
8348
8472
|
alias: 'ServiceAppointment_AssignedResource_ServiceResource',
|
|
8349
|
-
leftPath:
|
|
8473
|
+
leftPath: JSON_EXTRACT_PATH_INGESTION_APINAME,
|
|
8350
8474
|
operator: '=',
|
|
8351
8475
|
value: 'ServiceResource',
|
|
8352
8476
|
dataType: 'String',
|
|
@@ -8451,14 +8575,21 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8451
8575
|
// Fields of the `RecordQuery` type are the record queries for the entity types
|
|
8452
8576
|
// supported for the org
|
|
8453
8577
|
for (const recordQuery of fields) {
|
|
8454
|
-
recordQuery.resolve = function recordConnectionResolver(record, args) {
|
|
8578
|
+
recordQuery.resolve = async function recordConnectionResolver(record, args, { query }, info) {
|
|
8579
|
+
const { name: currentFieldName } = recordQuery;
|
|
8580
|
+
let ingestionTimestamp = 0;
|
|
8581
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
8582
|
+
// at our record query we fetch each ingestion time stamp and pass it down to each lower resolver to query against
|
|
8583
|
+
ingestionTimestamp = await fetchIngestionTimeStampFromDatabase(currentFieldName, info, args, query);
|
|
8584
|
+
}
|
|
8455
8585
|
// In the SF schema, the relevant arguments are passed into RecordQuery fields, but actually used
|
|
8456
8586
|
// down in the edge resolvers. For this resolver, we can just return what was passed in
|
|
8457
8587
|
// to make it available to the next execution step
|
|
8458
8588
|
return {
|
|
8459
8589
|
parentArgs: args,
|
|
8460
8590
|
parentRecord: record,
|
|
8461
|
-
currentFieldName
|
|
8591
|
+
currentFieldName,
|
|
8592
|
+
ingestionTimestamp,
|
|
8462
8593
|
};
|
|
8463
8594
|
};
|
|
8464
8595
|
}
|
|
@@ -8504,10 +8635,11 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8504
8635
|
// }
|
|
8505
8636
|
for (const field of fields) {
|
|
8506
8637
|
if (field.name === 'node') {
|
|
8507
|
-
field.resolve = function nodeResolver(
|
|
8638
|
+
field.resolve = function nodeResolver(obj, _args, { seenRecordIds }) {
|
|
8639
|
+
const { record, ingestionTimestamp } = obj;
|
|
8508
8640
|
const recordRepresentation = parse$3(record);
|
|
8509
8641
|
seenRecordIds.add(recordRepresentation.id);
|
|
8510
|
-
return recordRepresentation;
|
|
8642
|
+
return { recordRepresentation, ingestionTimestamp };
|
|
8511
8643
|
};
|
|
8512
8644
|
}
|
|
8513
8645
|
}
|
|
@@ -8530,40 +8662,40 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8530
8662
|
for (const field of fields) {
|
|
8531
8663
|
switch (field.name) {
|
|
8532
8664
|
case 'Id':
|
|
8533
|
-
field.resolve = (record) => record.id;
|
|
8665
|
+
field.resolve = ({ recordRepresentation: record }) => record.id;
|
|
8534
8666
|
break;
|
|
8535
8667
|
case 'ApiName':
|
|
8536
|
-
field.resolve = (record) => record.apiName;
|
|
8668
|
+
field.resolve = ({ recordRepresentation: record }) => record.apiName;
|
|
8537
8669
|
break;
|
|
8538
8670
|
case 'WeakEtag':
|
|
8539
|
-
field.resolve = (record) => record.weakEtag;
|
|
8671
|
+
field.resolve = ({ recordRepresentation: record }) => record.weakEtag;
|
|
8540
8672
|
break;
|
|
8541
8673
|
case '_drafts':
|
|
8542
|
-
field.resolve = (record) => {
|
|
8674
|
+
field.resolve = ({ recordRepresentation: record, }) => {
|
|
8543
8675
|
return record.drafts ? record.drafts : null;
|
|
8544
8676
|
};
|
|
8545
8677
|
break;
|
|
8546
8678
|
case 'LastModifiedById':
|
|
8547
|
-
field.resolve = (record) => {
|
|
8679
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8548
8680
|
return record.lastModifiedById
|
|
8549
8681
|
? { value: record.lastModifiedById }
|
|
8550
8682
|
: null;
|
|
8551
8683
|
};
|
|
8552
8684
|
break;
|
|
8553
8685
|
case 'LastModifiedDate':
|
|
8554
|
-
field.resolve = (record) => {
|
|
8686
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8555
8687
|
return record.lastModifiedDate
|
|
8556
8688
|
? { value: record.lastModifiedDate }
|
|
8557
8689
|
: null;
|
|
8558
8690
|
};
|
|
8559
8691
|
break;
|
|
8560
8692
|
case 'SystemModstamp':
|
|
8561
|
-
field.resolve = (record) => {
|
|
8693
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8562
8694
|
return record.systemModstamp ? { value: record.systemModstamp } : null;
|
|
8563
8695
|
};
|
|
8564
8696
|
break;
|
|
8565
8697
|
case 'RecordTypeId':
|
|
8566
|
-
field.resolve = (record) => {
|
|
8698
|
+
field.resolve = ({ recordRepresentation: record }) => {
|
|
8567
8699
|
return record.recordTypeId ? { value: record.recordTypeId } : null;
|
|
8568
8700
|
};
|
|
8569
8701
|
break;
|
|
@@ -8575,7 +8707,17 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8575
8707
|
.getInterfaces()
|
|
8576
8708
|
.find((iface) => iface.name === 'Record')) ||
|
|
8577
8709
|
(recordFieldType && recordFieldType.name === 'Record')) {
|
|
8578
|
-
field.resolve = function relationResolver(
|
|
8710
|
+
field.resolve = async function relationResolver(obj, _args, { Record, seenRecordIds }) {
|
|
8711
|
+
const fetchRecordOrNull = async (key) => {
|
|
8712
|
+
const recordRepresentation = await Record.load(key);
|
|
8713
|
+
return recordRepresentation !== null
|
|
8714
|
+
? {
|
|
8715
|
+
recordRepresentation,
|
|
8716
|
+
ingestionTimestamp,
|
|
8717
|
+
}
|
|
8718
|
+
: null;
|
|
8719
|
+
};
|
|
8720
|
+
const { recordRepresentation: record, ingestionTimestamp } = obj;
|
|
8579
8721
|
const fieldName = field.name.endsWith('__r')
|
|
8580
8722
|
? field.name.replace('__r', '__c')
|
|
8581
8723
|
: field.name;
|
|
@@ -8585,26 +8727,28 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8585
8727
|
if (!id)
|
|
8586
8728
|
return null;
|
|
8587
8729
|
if (id['__ref'] !== undefined) {
|
|
8588
|
-
return
|
|
8730
|
+
return fetchRecordOrNull(record.fields[`${field.name}Id`].value);
|
|
8589
8731
|
}
|
|
8590
8732
|
seenRecordIds.add(id);
|
|
8591
|
-
return
|
|
8733
|
+
return fetchRecordOrNull(id);
|
|
8592
8734
|
};
|
|
8593
8735
|
}
|
|
8594
8736
|
else if (isObjectType(recordFieldType) &&
|
|
8595
8737
|
field.type.name.endsWith('Connection')) {
|
|
8596
8738
|
// spanning field to a connection
|
|
8597
|
-
field.resolve = (
|
|
8598
|
-
seenRecordIds.add(
|
|
8739
|
+
field.resolve = async ({ recordRepresentation, ingestionTimestamp }, args, { seenRecordIds }) => {
|
|
8740
|
+
seenRecordIds.add(recordRepresentation.id);
|
|
8741
|
+
const { name: currentFieldName } = field;
|
|
8599
8742
|
return {
|
|
8600
8743
|
parentArgs: args,
|
|
8601
|
-
parentRecord:
|
|
8602
|
-
currentFieldName
|
|
8744
|
+
parentRecord: recordRepresentation,
|
|
8745
|
+
currentFieldName,
|
|
8746
|
+
ingestionTimestamp,
|
|
8603
8747
|
};
|
|
8604
8748
|
};
|
|
8605
8749
|
}
|
|
8606
8750
|
else {
|
|
8607
|
-
field.resolve = function recordFieldResolver(record) {
|
|
8751
|
+
field.resolve = function recordFieldResolver({ recordRepresentation: record, }) {
|
|
8608
8752
|
return record.fields[field.name] || null;
|
|
8609
8753
|
};
|
|
8610
8754
|
}
|
|
@@ -8616,7 +8760,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8616
8760
|
if (recordInterface !== undefined && baseRecord !== undefined) {
|
|
8617
8761
|
// Applys 'resolveType' of GraphQLInterfaceType to 'Record' interface. Since all the heterogenous types are named as 'apiName', the type with same name as the loaded record 'apiName' property is the type wanted.
|
|
8618
8762
|
// GraphQL executor would match InLineFragment' condition with type and keeps the deeper level field resolving going.
|
|
8619
|
-
recordInterface.resolveType = function (value) {
|
|
8763
|
+
recordInterface.resolveType = function ({ recordRepresentation: value, }) {
|
|
8620
8764
|
const targetType = polyTypes.find((type) => type.name === value.apiName);
|
|
8621
8765
|
return targetType === undefined ? baseRecord : targetType;
|
|
8622
8766
|
};
|
|
@@ -8624,7 +8768,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
8624
8768
|
return schema;
|
|
8625
8769
|
}
|
|
8626
8770
|
async function connectionEdgeResolver(obj, _args, context) {
|
|
8627
|
-
const { parentArgs = {}, parentRecord, currentFieldName } = obj;
|
|
8771
|
+
const { parentArgs = {}, parentRecord, currentFieldName, ingestionTimestamp } = obj;
|
|
8628
8772
|
const { query, objectInfos, draftFunctions } = context;
|
|
8629
8773
|
let joins = [];
|
|
8630
8774
|
let alias = currentFieldName;
|
|
@@ -8655,10 +8799,19 @@ async function connectionEdgeResolver(obj, _args, context) {
|
|
|
8655
8799
|
predicates,
|
|
8656
8800
|
orderBy: orderByToPredicate(parentArgs.orderBy, alias, alias, context.objectInfos),
|
|
8657
8801
|
limit: parentArgs.first,
|
|
8802
|
+
ingestionTimestamp,
|
|
8658
8803
|
};
|
|
8659
8804
|
const { sql, bindings } = buildQuery(queryConfig);
|
|
8660
8805
|
const results = await query(sql, bindings);
|
|
8661
|
-
|
|
8806
|
+
//map each sql result with the ingestion timestamp to pass it down a level
|
|
8807
|
+
return results.rows
|
|
8808
|
+
.map((row) => row[0])
|
|
8809
|
+
.map((record) => {
|
|
8810
|
+
return {
|
|
8811
|
+
record,
|
|
8812
|
+
ingestionTimestamp,
|
|
8813
|
+
};
|
|
8814
|
+
});
|
|
8662
8815
|
}
|
|
8663
8816
|
/**
|
|
8664
8817
|
* Converts a childRelationship into a predicate
|
|
@@ -8684,6 +8837,62 @@ function isRecordType(type) {
|
|
|
8684
8837
|
const interfaces = type.getInterfaces();
|
|
8685
8838
|
return Boolean(interfaces.find((iface) => iface.name === 'Record'));
|
|
8686
8839
|
}
|
|
8840
|
+
/**
|
|
8841
|
+
* Builds the top level record query key based on AST data
|
|
8842
|
+
* @param operation
|
|
8843
|
+
* @param variables
|
|
8844
|
+
* @param argumentNodes
|
|
8845
|
+
* @param currentFieldName
|
|
8846
|
+
* @returns
|
|
8847
|
+
*/
|
|
8848
|
+
function buildKeyStringForRecordQuery(operation, variables, argumentNodes, currentFieldName) {
|
|
8849
|
+
const queryKey = buildQueryTypeStringKey({
|
|
8850
|
+
luvio: {},
|
|
8851
|
+
keyPrefix: 'UiApi',
|
|
8852
|
+
schemaName: 'uiapi',
|
|
8853
|
+
queryTypeName: 'Query',
|
|
8854
|
+
operationNode: operation,
|
|
8855
|
+
variables,
|
|
8856
|
+
fragmentMap: {},
|
|
8857
|
+
});
|
|
8858
|
+
const filteredArgumentNodes = assign$3([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
|
|
8859
|
+
const argumentString = filteredArgumentNodes.length > 0
|
|
8860
|
+
? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
|
|
8861
|
+
: '';
|
|
8862
|
+
return `${queryKey}__uiapi__query__${currentFieldName}${argumentString}`;
|
|
8863
|
+
}
|
|
8864
|
+
/**
|
|
8865
|
+
* fetches a query level ingestion time stamp from the L2 cache
|
|
8866
|
+
* if no query has been seen then the timestamp is 0
|
|
8867
|
+
* @param apiName
|
|
8868
|
+
* @param info
|
|
8869
|
+
* @param args
|
|
8870
|
+
* @param query
|
|
8871
|
+
* @returns
|
|
8872
|
+
*/
|
|
8873
|
+
async function fetchIngestionTimeStampFromDatabase(apiName, info, args, query) {
|
|
8874
|
+
const { operation, variableValues } = info;
|
|
8875
|
+
// if we cannot find the query key in the database then default to 0 as we assume we have not seen the query
|
|
8876
|
+
// and all the data is not stale
|
|
8877
|
+
let ingestionTimestamp = 0;
|
|
8878
|
+
if (info.fieldNodes.length > 0 && info.fieldNodes[0].arguments !== undefined) {
|
|
8879
|
+
const key = buildKeyStringForRecordQuery(operation,
|
|
8880
|
+
// join varables passed from query to the argument variables given from the AST
|
|
8881
|
+
{ ...variableValues, ...args }, info.fieldNodes[0].arguments, apiName);
|
|
8882
|
+
const sql = `
|
|
8883
|
+
SELECT json_extract(metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}')
|
|
8884
|
+
FROM lds_data
|
|
8885
|
+
WHERE key IS ?
|
|
8886
|
+
`;
|
|
8887
|
+
const results = await query(sql, [key]);
|
|
8888
|
+
const [timestamp] = results.rows.map((row) => row[0]);
|
|
8889
|
+
if (timestamp !== null && typeof timestamp === 'number') {
|
|
8890
|
+
//go back 10 ms to adjust for margin of error when top level query is stored and when raml objects are stored
|
|
8891
|
+
ingestionTimestamp = timestamp - 10;
|
|
8892
|
+
}
|
|
8893
|
+
}
|
|
8894
|
+
return ingestionTimestamp;
|
|
8895
|
+
}
|
|
8687
8896
|
|
|
8688
8897
|
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 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 rateLimit: RateLimit\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 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\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\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]): [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\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 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 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\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 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\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 LAST\n FIRST\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\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\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\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\ntype ThemeInfo {\n color: String\n iconUrl: String\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 THIS_WEEK\n THIS_FISCAL_QUARTER\n NEXT_YEAR\n TODAY\n LAST_WEEK\n LAST_YEAR\n YESTERDAY\n NEXT_MONTH\n NEXT_FISCAL_YEAR\n NEXT_WEEK\n NEXT_90_DAYS\n LAST_FISCAL_QUARTER\n LAST_FISCAL_YEAR\n THIS_YEAR\n THIS_MONTH\n THIS_QUARTER\n LAST_90_DAYS\n NEXT_FISCAL_QUARTER\n THIS_FISCAL_YEAR\n TOMORROW\n NEXT_QUARTER\n LAST_MONTH\n LAST_QUARTER\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): RecordConnection @fieldCategory\n}\n\ntype IDValue implements FieldValue {\n value: ID\n displayValue: String\n}\n\nenum Unit {\n MI\n KM\n}\n\ninput OrderByGeolocationClause {\n distance: DistanceInput\n order: ResultOrder\n nulls: NullOrder\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 DESC\n ASC\n}\n\ninput RecordOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: RecordOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ninput PicklistOperators {\n eq: Picklist\n ne: Picklist\n in: [Picklist]\n nin: [Picklist]\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\ntype DateTimeValue implements FieldValue {\n value: DateTime\n displayValue: String\n format: String\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 LongValue implements FieldValue {\n value: Long\n displayValue: String\n format: String\n}\n\ninput DateFunctionInput {\n value: LongOperators\n convertTimezoneValue: LongOperators\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 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\ntype BooleanAggregate implements FieldValue {\n value: Boolean\n displayValue: String\n grouping: IntValue\n}\n\ntype RecordQueryAggregate {\n recordQueryAggregate(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String, groupBy: RecordGroupBy): RecordAggregateConnection @fieldCategory\n}\n\ntype RecordConnection @generic {\n edges: [RecordEdge]\n pageInfo: PageInfo!\n totalCount: 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}\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\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\ninput DateTimeFunctionInput {\n value: DateTimePrimitiveOperators\n convertTimezoneValue: DateTimePrimitiveOperators\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\ntype __Schema {\n types: [__Type!]!\n queryType: __Type!\n mutationType: __Type\n directives: [__Directive!]!\n subscriptionType: __Type\n}\n\ninput DateTimeInput {\n value: DateTime\n literal: DateLiteral\n range: DateRange\n}\n\ninput DateTimePrimitiveOperators {\n eq: DateTime\n ne: DateTime\n lt: DateTime\n gt: DateTime\n lte: DateTime\n gte: DateTime\n in: [DateTime]\n nin: [DateTime]\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 it cannot currently be used\n recordQuery(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String): 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 on FIELD\n\n\n\n\n\n\n\n";
|
|
8689
8898
|
|
|
@@ -15767,4 +15976,4 @@ register({
|
|
|
15767
15976
|
});
|
|
15768
15977
|
|
|
15769
15978
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15770
|
-
// version: 1.
|
|
15979
|
+
// version: 1.155.0-96e212d1e
|