@salesforce/lds-runtime-mobile 1.292.0 → 1.294.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 +298 -195
- package/package.json +16 -16
- package/sfdc/main.js +298 -195
package/dist/main.js
CHANGED
|
@@ -52,7 +52,7 @@ import ldsMetadataRefreshEnabled from '@salesforce/gate/lds.metadataRefreshEnabl
|
|
|
52
52
|
const { parse: parse$6, stringify: stringify$6 } = JSON;
|
|
53
53
|
const { join: join$2, push: push$2, unshift } = Array.prototype;
|
|
54
54
|
const { isArray: isArray$5 } = Array;
|
|
55
|
-
const { entries: entries$
|
|
55
|
+
const { entries: entries$5, keys: keys$8 } = Object;
|
|
56
56
|
|
|
57
57
|
const UI_API_BASE_URI = '/services/data/v62.0/ui-api';
|
|
58
58
|
|
|
@@ -364,7 +364,7 @@ function getFulfillingRequest(inflightRequests, resourceRequest) {
|
|
|
364
364
|
if (fulfill === undefined) {
|
|
365
365
|
return null;
|
|
366
366
|
}
|
|
367
|
-
const handlersMap = entries$
|
|
367
|
+
const handlersMap = entries$5(inflightRequests);
|
|
368
368
|
for (let i = 0, len = handlersMap.length; i < len; i += 1) {
|
|
369
369
|
const [transactionKey, handlers] = handlersMap[i];
|
|
370
370
|
// check fulfillment against only the first handler ([0]) because it's equal or
|
|
@@ -7177,7 +7177,7 @@ function isArrayLike(x) {
|
|
|
7177
7177
|
(x.length === 0 || (x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1))));
|
|
7178
7178
|
}
|
|
7179
7179
|
|
|
7180
|
-
const { create: create$4, keys: keys$4, values: values$2, entries: entries$
|
|
7180
|
+
const { create: create$4, keys: keys$4, values: values$2, entries: entries$4, assign: assign$4 } = Object;
|
|
7181
7181
|
const { stringify: stringify$4, parse: parse$4 } = JSON;
|
|
7182
7182
|
const { isArray: isArray$2, from: from$2 } = Array;
|
|
7183
7183
|
|
|
@@ -7925,7 +7925,7 @@ function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draf
|
|
|
7925
7925
|
}
|
|
7926
7926
|
else {
|
|
7927
7927
|
//`field` match the filedInfo's apiName
|
|
7928
|
-
for (const [op, value] of entries$
|
|
7928
|
+
for (const [op, value] of entries$4(where[field])) {
|
|
7929
7929
|
const operator = operatorToSql(op);
|
|
7930
7930
|
/**
|
|
7931
7931
|
Two types ID processing might be needed. Draft ID swapping is optional, which depends on DraftFunctions existence.
|
|
@@ -8384,6 +8384,7 @@ function buildQuery(config) {
|
|
|
8384
8384
|
${predicates.sql}
|
|
8385
8385
|
${orderBy.sql}
|
|
8386
8386
|
LIMIT ?
|
|
8387
|
+
OFFSET ?
|
|
8387
8388
|
`
|
|
8388
8389
|
.split('\n')
|
|
8389
8390
|
.map((line) => line.trim())
|
|
@@ -8396,6 +8397,7 @@ function buildQuery(config) {
|
|
|
8396
8397
|
...predicates.bindings,
|
|
8397
8398
|
// limit binding
|
|
8398
8399
|
config.limit || 10,
|
|
8400
|
+
config.offset || 0,
|
|
8399
8401
|
];
|
|
8400
8402
|
return { sql: sql.trim(), bindings };
|
|
8401
8403
|
}
|
|
@@ -9113,32 +9115,6 @@ async function readIngestionTimestampForKey(key, query) {
|
|
|
9113
9115
|
return ingestionTimestamp;
|
|
9114
9116
|
}
|
|
9115
9117
|
|
|
9116
|
-
// Code lifted from https://github.com/MaxArt2501/base64-js/blob/master/base64.js
|
|
9117
|
-
// base64 character set, plus padding character (=)
|
|
9118
|
-
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
9119
|
-
function btoaPolyfill(input) {
|
|
9120
|
-
let bitmap, a, b, c;
|
|
9121
|
-
let result = '', i = 0;
|
|
9122
|
-
const rest = input.length % 3; // To determine the final padding
|
|
9123
|
-
for (; i < input.length;) {
|
|
9124
|
-
if ((a = input.charCodeAt(i++)) > 255 ||
|
|
9125
|
-
(b = input.charCodeAt(i++)) > 255 ||
|
|
9126
|
-
(c = input.charCodeAt(i++)) > 255) {
|
|
9127
|
-
throw new TypeError('Failed base64ToAscii encoding: The string to be encoded contains characters outside of the Latin1 range. ' +
|
|
9128
|
-
input);
|
|
9129
|
-
}
|
|
9130
|
-
bitmap = (a << 16) | (b << 8) | c;
|
|
9131
|
-
result +=
|
|
9132
|
-
b64.charAt((bitmap >> 18) & 63) +
|
|
9133
|
-
b64.charAt((bitmap >> 12) & 63) +
|
|
9134
|
-
b64.charAt((bitmap >> 6) & 63) +
|
|
9135
|
-
b64.charAt(bitmap & 63);
|
|
9136
|
-
}
|
|
9137
|
-
// If there's need of padding, replace the last 'A's with equal signs
|
|
9138
|
-
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
9139
|
-
}
|
|
9140
|
-
const base64encode = typeof btoa === 'function' ? btoa : btoaPolyfill;
|
|
9141
|
-
|
|
9142
9118
|
function findSpanningField(name) {
|
|
9143
9119
|
return (field) => {
|
|
9144
9120
|
return (field.apiName === name ||
|
|
@@ -9285,9 +9261,228 @@ function scopeToPredicates(scope = '', settings) {
|
|
|
9285
9261
|
];
|
|
9286
9262
|
}
|
|
9287
9263
|
|
|
9288
|
-
|
|
9289
|
-
|
|
9264
|
+
// Code lifted from https://github.com/MaxArt2501/base64-js/blob/master/base64.js
|
|
9265
|
+
// base64 character set, plus padding character (=)
|
|
9266
|
+
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
9267
|
+
const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;
|
|
9268
|
+
function btoaPolyfill(input) {
|
|
9269
|
+
let bitmap, a, b, c;
|
|
9270
|
+
let result = '', i = 0;
|
|
9271
|
+
const rest = input.length % 3; // To determine the final padding
|
|
9272
|
+
for (; i < input.length;) {
|
|
9273
|
+
if ((a = input.charCodeAt(i++)) > 255 ||
|
|
9274
|
+
(b = input.charCodeAt(i++)) > 255 ||
|
|
9275
|
+
(c = input.charCodeAt(i++)) > 255) {
|
|
9276
|
+
throw new TypeError('Failed base64ToAscii encoding: The string to be encoded contains characters outside of the Latin1 range. ' +
|
|
9277
|
+
input);
|
|
9278
|
+
}
|
|
9279
|
+
bitmap = (a << 16) | (b << 8) | c;
|
|
9280
|
+
result +=
|
|
9281
|
+
b64.charAt((bitmap >> 18) & 63) +
|
|
9282
|
+
b64.charAt((bitmap >> 12) & 63) +
|
|
9283
|
+
b64.charAt((bitmap >> 6) & 63) +
|
|
9284
|
+
b64.charAt(bitmap & 63);
|
|
9285
|
+
}
|
|
9286
|
+
// If there's need of padding, replace the last 'A's with equal signs
|
|
9287
|
+
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
9288
|
+
}
|
|
9289
|
+
function atobPolyfill(data) {
|
|
9290
|
+
// atob can work with strings with whitespaces, even inside the encoded part,
|
|
9291
|
+
// but only \t, \n, \f, \r and ' ', which can be stripped.
|
|
9292
|
+
let string = String(data).replace(/[\t\n\f\r ]+/g, '');
|
|
9293
|
+
if (!b64re.test(string))
|
|
9294
|
+
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
|
9295
|
+
// Adding the padding if missing, for semplicity
|
|
9296
|
+
string += '=='.slice(2 - (string.length & 3));
|
|
9297
|
+
var bitmap, result = '', r1, r2, i = 0;
|
|
9298
|
+
for (; i < string.length;) {
|
|
9299
|
+
bitmap =
|
|
9300
|
+
(b64.indexOf(string.charAt(i++)) << 18) |
|
|
9301
|
+
(b64.indexOf(string.charAt(i++)) << 12) |
|
|
9302
|
+
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
|
|
9303
|
+
(r2 = b64.indexOf(string.charAt(i++)));
|
|
9304
|
+
result +=
|
|
9305
|
+
r1 === 64
|
|
9306
|
+
? String.fromCharCode((bitmap >> 16) & 255)
|
|
9307
|
+
: r2 === 64
|
|
9308
|
+
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
|
|
9309
|
+
: String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
|
|
9310
|
+
}
|
|
9311
|
+
return result;
|
|
9312
|
+
}
|
|
9313
|
+
const base64encode = typeof btoa === 'function' ? btoa : btoaPolyfill;
|
|
9314
|
+
const base64decode = typeof atob === 'function' ? atob : atobPolyfill;
|
|
9315
|
+
|
|
9316
|
+
function cursorResolver(source) {
|
|
9317
|
+
return encodeV1Cursor(source.index);
|
|
9318
|
+
}
|
|
9319
|
+
function pageInfoResolver(source) {
|
|
9320
|
+
if (source.length === 0) {
|
|
9321
|
+
return {
|
|
9322
|
+
startCursor: null,
|
|
9323
|
+
endCursor: null,
|
|
9324
|
+
};
|
|
9325
|
+
}
|
|
9326
|
+
let startIndex = source[0].index;
|
|
9327
|
+
let endIndex = source[source.length - 1].index;
|
|
9328
|
+
return {
|
|
9329
|
+
startCursor: encodeV1Cursor(startIndex),
|
|
9330
|
+
endCursor: encodeV1Cursor(endIndex),
|
|
9331
|
+
};
|
|
9332
|
+
}
|
|
9333
|
+
function pageResultCountResolver(source) {
|
|
9334
|
+
return source.length;
|
|
9335
|
+
}
|
|
9336
|
+
function encodeV1Cursor(index) {
|
|
9337
|
+
return base64encode(`v1:${index}`);
|
|
9338
|
+
}
|
|
9339
|
+
const cursorRegex = /^v1:(?<index>\d+)$/;
|
|
9340
|
+
function decodeV1Cursor(base64cursor) {
|
|
9341
|
+
const cursor = base64decode(base64cursor);
|
|
9342
|
+
if (!cursor) {
|
|
9343
|
+
// eslint-disable-next-line @salesforce/lds/no-error-in-production
|
|
9344
|
+
throw new Error('Unable to parse cursor');
|
|
9345
|
+
}
|
|
9346
|
+
const found = cursor.match(cursorRegex);
|
|
9347
|
+
if (!found || !found.groups) {
|
|
9348
|
+
// eslint-disable-next-line @salesforce/lds/no-error-in-production
|
|
9349
|
+
throw new Error('Unable to parse cursor');
|
|
9350
|
+
}
|
|
9351
|
+
return Number(found.groups.index);
|
|
9352
|
+
}
|
|
9353
|
+
|
|
9354
|
+
/*
|
|
9355
|
+
resolves connections...
|
|
9356
|
+
*/
|
|
9357
|
+
async function connectionResolver(obj, args, context, info) {
|
|
9358
|
+
let { recordRepresentation: parentRecord, ingestionTimestamp = 0 } = obj;
|
|
9359
|
+
if (!parentRecord && excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
9360
|
+
// at our record query we fetch each ingestion time stamp and pass it down to each lower resolver to query against
|
|
9361
|
+
ingestionTimestamp = await fetchIngestionTimeStampFromDatabase(info.fieldName, info, args, context.query);
|
|
9362
|
+
}
|
|
9363
|
+
const { query, objectInfos, draftFunctions } = context;
|
|
9364
|
+
let joins = [];
|
|
9365
|
+
let alias = info.fieldName;
|
|
9366
|
+
let childRelationshipFieldName = undefined;
|
|
9367
|
+
if (parentRecord) {
|
|
9368
|
+
context.seenRecordIds.add(parentRecord.id);
|
|
9369
|
+
const parentApiName = parentRecord.apiName;
|
|
9370
|
+
const parentObjectInfo = objectInfos[parentApiName];
|
|
9371
|
+
const childRelationship = parentObjectInfo &&
|
|
9372
|
+
parentObjectInfo.childRelationships.find((rel) => rel.relationshipName === info.fieldName);
|
|
9373
|
+
// or emit/throw if we want to report it
|
|
9374
|
+
if (!childRelationship)
|
|
9375
|
+
return [];
|
|
9376
|
+
alias = childRelationship.childObjectApiName;
|
|
9377
|
+
childRelationshipFieldName = childRelationship.fieldName;
|
|
9378
|
+
}
|
|
9379
|
+
// Alias starts as entity's ApiName
|
|
9380
|
+
const predicates = [
|
|
9381
|
+
...filterToPredicates(args.where, alias, alias, context.objectInfos, joins, draftFunctions),
|
|
9382
|
+
...scopeToPredicates(args.scope, context.settings),
|
|
9383
|
+
...childRelationshipToPredicates(childRelationshipFieldName, parentRecord ? parentRecord.id : undefined),
|
|
9384
|
+
];
|
|
9385
|
+
const scopeJoins = scopeToJoins(args.scope, context.settings);
|
|
9386
|
+
joins.push(...scopeJoins);
|
|
9387
|
+
let offset = 0;
|
|
9388
|
+
if (args.after) {
|
|
9389
|
+
offset = decodeV1Cursor(args.after) + 1;
|
|
9390
|
+
}
|
|
9391
|
+
// Alias starts as entity's ApiName
|
|
9392
|
+
const queryConfig = {
|
|
9393
|
+
alias,
|
|
9394
|
+
joins,
|
|
9395
|
+
predicates,
|
|
9396
|
+
orderBy: orderByToPredicate(args.orderBy, alias, alias, context.objectInfos),
|
|
9397
|
+
limit: args.first,
|
|
9398
|
+
offset: offset,
|
|
9399
|
+
ingestionTimestamp,
|
|
9400
|
+
};
|
|
9401
|
+
const { sql, bindings } = buildQuery(queryConfig);
|
|
9402
|
+
const results = await query(sql, bindings);
|
|
9403
|
+
//map each sql result with the ingestion timestamp to pass it down a level
|
|
9404
|
+
return results.rows
|
|
9405
|
+
.map((row) => parse$4(row[0]))
|
|
9406
|
+
.map((recordRepresentation, index) => {
|
|
9407
|
+
context.seenRecordIds.add(recordRepresentation.id);
|
|
9408
|
+
return {
|
|
9409
|
+
recordRepresentation,
|
|
9410
|
+
ingestionTimestamp,
|
|
9411
|
+
index: index + offset,
|
|
9412
|
+
};
|
|
9413
|
+
});
|
|
9414
|
+
}
|
|
9415
|
+
/**
|
|
9416
|
+
* Converts a childRelationship into a predicate
|
|
9417
|
+
* @param childRelationshipFieldName Reference ID field name to its parent record. A defined `childRelationshipFieldName` string indicates that a child relationship exists
|
|
9418
|
+
* and a relationship predicate needs to be put into place. For example, `ServiceAppointment` has a child relationship `ServiceResources`, whose entity name is `AssignedResource`.
|
|
9419
|
+
* Once the parent `ServiceAppointment` record comes back, its child connection starts to resolve. Child `AssignedResource` record needs to reference to parent Id using field `ServiceAppointmentId`.
|
|
9420
|
+
* @param parentId prarent record Id
|
|
9421
|
+
* @returns predicate array consists at most 1 predicate
|
|
9422
|
+
*/
|
|
9423
|
+
function childRelationshipToPredicates(childRelationshipFieldName, parentId) {
|
|
9424
|
+
const predicates = [];
|
|
9425
|
+
if (childRelationshipFieldName !== undefined && parentId !== undefined) {
|
|
9426
|
+
predicates.push({
|
|
9427
|
+
type: PredicateType.single,
|
|
9428
|
+
leftPath: `$.fields.${childRelationshipFieldName}.value`,
|
|
9429
|
+
operator: '=',
|
|
9430
|
+
value: parentId,
|
|
9431
|
+
});
|
|
9432
|
+
}
|
|
9433
|
+
return predicates;
|
|
9434
|
+
}
|
|
9435
|
+
/**
|
|
9436
|
+
* fetches a query level ingestion time stamp from the L2 cache
|
|
9437
|
+
* if no query has been seen then the timestamp is 0
|
|
9438
|
+
* @param apiName
|
|
9439
|
+
* @param info
|
|
9440
|
+
* @param args
|
|
9441
|
+
* @param query
|
|
9442
|
+
* @returns
|
|
9443
|
+
*/
|
|
9444
|
+
async function fetchIngestionTimeStampFromDatabase(apiName, info, args, query) {
|
|
9445
|
+
const { operation, variableValues } = info;
|
|
9446
|
+
// if we cannot find the query key in the database then default to 0 as we assume we have not seen the query
|
|
9447
|
+
// and all the data is not stale
|
|
9448
|
+
let ingestionTimestamp = 0;
|
|
9449
|
+
if (info.fieldNodes.length > 0 && info.fieldNodes[0].arguments !== undefined) {
|
|
9450
|
+
const key = buildKeyStringForRecordQuery(operation,
|
|
9451
|
+
// join varables passed from query to the argument variables given from the AST
|
|
9452
|
+
{ ...variableValues, ...args }, info.fieldNodes[0].arguments, apiName);
|
|
9453
|
+
return readIngestionTimestampForKey(key, query);
|
|
9454
|
+
}
|
|
9455
|
+
return ingestionTimestamp;
|
|
9456
|
+
}
|
|
9457
|
+
/**
|
|
9458
|
+
* Builds the top level record query key based on AST data
|
|
9459
|
+
* @param operation
|
|
9460
|
+
* @param variables
|
|
9461
|
+
* @param argumentNodes
|
|
9462
|
+
* @param currentFieldName
|
|
9463
|
+
* @returns
|
|
9464
|
+
*/
|
|
9465
|
+
function buildKeyStringForRecordQuery(operation, variables, argumentNodes, currentFieldName) {
|
|
9466
|
+
const queryKey = buildQueryTypeStringKey({
|
|
9467
|
+
luvio: {},
|
|
9468
|
+
keyPrefix: 'UiApi',
|
|
9469
|
+
schemaName: 'uiapi',
|
|
9470
|
+
queryTypeName: 'Query',
|
|
9471
|
+
operationNode: operation,
|
|
9472
|
+
variables,
|
|
9473
|
+
fragmentMap: {},
|
|
9474
|
+
});
|
|
9475
|
+
const filteredArgumentNodes = assign$4([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
|
|
9476
|
+
const argumentString = filteredArgumentNodes.length > 0
|
|
9477
|
+
? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
|
|
9478
|
+
: '';
|
|
9479
|
+
return `${queryKey}__uiapi__query__${currentFieldName}${argumentString}`;
|
|
9480
|
+
}
|
|
9481
|
+
|
|
9482
|
+
function passThroughResolver(source) {
|
|
9483
|
+
return source;
|
|
9290
9484
|
}
|
|
9485
|
+
|
|
9291
9486
|
/**
|
|
9292
9487
|
*
|
|
9293
9488
|
* @param schema GraphQL Schema generated from ObjectInfos
|
|
@@ -9320,13 +9515,13 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9320
9515
|
}
|
|
9321
9516
|
if (type.name === 'Query') {
|
|
9322
9517
|
for (const field of fields) {
|
|
9323
|
-
field.resolve =
|
|
9518
|
+
field.resolve = passThroughResolver;
|
|
9324
9519
|
}
|
|
9325
9520
|
}
|
|
9326
9521
|
if (type.name === 'UIAPI') {
|
|
9327
9522
|
for (const field of fields) {
|
|
9328
9523
|
if (field.name === 'query') {
|
|
9329
|
-
field.resolve =
|
|
9524
|
+
field.resolve = passThroughResolver;
|
|
9330
9525
|
}
|
|
9331
9526
|
else {
|
|
9332
9527
|
const fieldName = field.name;
|
|
@@ -9353,23 +9548,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9353
9548
|
// Fields of the `RecordQuery` type are the record queries for the entity types
|
|
9354
9549
|
// supported for the org
|
|
9355
9550
|
for (const recordQuery of fields) {
|
|
9356
|
-
recordQuery.resolve =
|
|
9357
|
-
const { name: currentFieldName } = recordQuery;
|
|
9358
|
-
let ingestionTimestamp = 0;
|
|
9359
|
-
if (excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
9360
|
-
// at our record query we fetch each ingestion time stamp and pass it down to each lower resolver to query against
|
|
9361
|
-
ingestionTimestamp = await fetchIngestionTimeStampFromDatabase(currentFieldName, info, args, query);
|
|
9362
|
-
}
|
|
9363
|
-
// In the SF schema, the relevant arguments are passed into RecordQuery fields, but actually used
|
|
9364
|
-
// down in the edge resolvers. For this resolver, we can just return what was passed in
|
|
9365
|
-
// to make it available to the next execution step
|
|
9366
|
-
return {
|
|
9367
|
-
parentArgs: args,
|
|
9368
|
-
parentRecord: record,
|
|
9369
|
-
currentFieldName,
|
|
9370
|
-
ingestionTimestamp,
|
|
9371
|
-
};
|
|
9372
|
-
};
|
|
9551
|
+
recordQuery.resolve = connectionResolver;
|
|
9373
9552
|
}
|
|
9374
9553
|
}
|
|
9375
9554
|
if (type.name.endsWith('Connection')) {
|
|
@@ -9390,7 +9569,13 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9390
9569
|
for (const field of fields) {
|
|
9391
9570
|
switch (field.name) {
|
|
9392
9571
|
case 'edges':
|
|
9393
|
-
field.resolve =
|
|
9572
|
+
field.resolve = passThroughResolver;
|
|
9573
|
+
break;
|
|
9574
|
+
case 'pageInfo':
|
|
9575
|
+
field.resolve = pageInfoResolver;
|
|
9576
|
+
break;
|
|
9577
|
+
case 'pageResultCount':
|
|
9578
|
+
field.resolve = pageResultCountResolver;
|
|
9394
9579
|
break;
|
|
9395
9580
|
default:
|
|
9396
9581
|
field.resolve = defaultFieldResolver;
|
|
@@ -9413,17 +9598,10 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9413
9598
|
// }
|
|
9414
9599
|
for (const field of fields) {
|
|
9415
9600
|
if (field.name === 'node') {
|
|
9416
|
-
field.resolve =
|
|
9417
|
-
const { record, ingestionTimestamp } = obj;
|
|
9418
|
-
const recordRepresentation = parse$4(record);
|
|
9419
|
-
seenRecordIds.add(recordRepresentation.id);
|
|
9420
|
-
return { recordRepresentation, ingestionTimestamp };
|
|
9421
|
-
};
|
|
9601
|
+
field.resolve = passThroughResolver;
|
|
9422
9602
|
}
|
|
9423
9603
|
else if (field.name === 'cursor') {
|
|
9424
|
-
field.resolve =
|
|
9425
|
-
return base64encode(`v1:${index}`);
|
|
9426
|
-
};
|
|
9604
|
+
field.resolve = cursorResolver;
|
|
9427
9605
|
}
|
|
9428
9606
|
}
|
|
9429
9607
|
}
|
|
@@ -9538,16 +9716,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9538
9716
|
else if (isObjectType(recordFieldType) &&
|
|
9539
9717
|
field.type.name.endsWith('Connection')) {
|
|
9540
9718
|
// spanning field to a connection
|
|
9541
|
-
field.resolve =
|
|
9542
|
-
seenRecordIds.add(recordRepresentation.id);
|
|
9543
|
-
const { name: currentFieldName } = field;
|
|
9544
|
-
return {
|
|
9545
|
-
parentArgs: args,
|
|
9546
|
-
parentRecord: recordRepresentation,
|
|
9547
|
-
currentFieldName,
|
|
9548
|
-
ingestionTimestamp,
|
|
9549
|
-
};
|
|
9550
|
-
};
|
|
9719
|
+
field.resolve = connectionResolver;
|
|
9551
9720
|
}
|
|
9552
9721
|
else {
|
|
9553
9722
|
field.resolve = function recordFieldResolver({ recordRepresentation: record, }) {
|
|
@@ -9602,123 +9771,10 @@ _, { objectInfos }) {
|
|
|
9602
9771
|
}
|
|
9603
9772
|
return null;
|
|
9604
9773
|
}
|
|
9605
|
-
async function connectionEdgeResolver(obj, _args, context) {
|
|
9606
|
-
const { parentArgs = {}, parentRecord, currentFieldName, ingestionTimestamp } = obj;
|
|
9607
|
-
const { query, objectInfos, draftFunctions } = context;
|
|
9608
|
-
let joins = [];
|
|
9609
|
-
let alias = currentFieldName;
|
|
9610
|
-
let childRelationshipFieldName = undefined;
|
|
9611
|
-
if (parentRecord.id) {
|
|
9612
|
-
const parentApiName = parentRecord.apiName;
|
|
9613
|
-
const parentObjectInfo = objectInfos[parentApiName];
|
|
9614
|
-
const childRelationship = parentObjectInfo &&
|
|
9615
|
-
parentObjectInfo.childRelationships.find((rel) => rel.relationshipName === currentFieldName);
|
|
9616
|
-
// or emit/throw if we want to report it
|
|
9617
|
-
if (!childRelationship)
|
|
9618
|
-
return [];
|
|
9619
|
-
alias = childRelationship.childObjectApiName;
|
|
9620
|
-
childRelationshipFieldName = childRelationship.fieldName;
|
|
9621
|
-
}
|
|
9622
|
-
// Alias starts as entity's ApiName
|
|
9623
|
-
const predicates = [
|
|
9624
|
-
...filterToPredicates(parentArgs.where, alias, alias, context.objectInfos, joins, draftFunctions),
|
|
9625
|
-
...scopeToPredicates(parentArgs.scope, context.settings),
|
|
9626
|
-
...childRelationshipToPredicates(childRelationshipFieldName, parentRecord.id),
|
|
9627
|
-
];
|
|
9628
|
-
const scopeJoins = scopeToJoins(parentArgs.scope, context.settings);
|
|
9629
|
-
joins.push(...scopeJoins);
|
|
9630
|
-
// Alias starts as entity's ApiName
|
|
9631
|
-
const queryConfig = {
|
|
9632
|
-
alias,
|
|
9633
|
-
joins,
|
|
9634
|
-
predicates,
|
|
9635
|
-
orderBy: orderByToPredicate(parentArgs.orderBy, alias, alias, context.objectInfos),
|
|
9636
|
-
limit: parentArgs.first,
|
|
9637
|
-
ingestionTimestamp,
|
|
9638
|
-
};
|
|
9639
|
-
const { sql, bindings } = buildQuery(queryConfig);
|
|
9640
|
-
const results = await query(sql, bindings);
|
|
9641
|
-
//map each sql result with the ingestion timestamp to pass it down a level
|
|
9642
|
-
return results.rows
|
|
9643
|
-
.map((row) => row[0])
|
|
9644
|
-
.map((record, index) => {
|
|
9645
|
-
return {
|
|
9646
|
-
record,
|
|
9647
|
-
ingestionTimestamp,
|
|
9648
|
-
index,
|
|
9649
|
-
};
|
|
9650
|
-
});
|
|
9651
|
-
}
|
|
9652
|
-
/**
|
|
9653
|
-
* Converts a childRelationship into a predicate
|
|
9654
|
-
* @param childRelationshipFieldName Reference ID field name to its parent record. A defined `childRelationshipFieldName` string indicates that a child relationship exists
|
|
9655
|
-
* and a relationship predicate needs to be put into place. For example, `ServiceAppointment` has a child relationship `ServiceResources`, whose entity name is `AssignedResource`.
|
|
9656
|
-
* Once the parent `ServiceAppointment` record comes back, its child connection starts to resolve. Child `AssignedResource` record needs to reference to parent Id using field `ServiceAppointmentId`.
|
|
9657
|
-
* @param parentId prarent record Id
|
|
9658
|
-
* @returns predicate array consists at most 1 predicate
|
|
9659
|
-
*/
|
|
9660
|
-
function childRelationshipToPredicates(childRelationshipFieldName, parentId) {
|
|
9661
|
-
const predicates = [];
|
|
9662
|
-
if (childRelationshipFieldName !== undefined && parentId !== undefined) {
|
|
9663
|
-
predicates.push({
|
|
9664
|
-
type: PredicateType.single,
|
|
9665
|
-
leftPath: `$.fields.${childRelationshipFieldName}.value`,
|
|
9666
|
-
operator: '=',
|
|
9667
|
-
value: parentId,
|
|
9668
|
-
});
|
|
9669
|
-
}
|
|
9670
|
-
return predicates;
|
|
9671
|
-
}
|
|
9672
9774
|
function isRecordType(type) {
|
|
9673
9775
|
const interfaces = type.getInterfaces();
|
|
9674
9776
|
return Boolean(interfaces.find((iface) => iface.name === 'Record'));
|
|
9675
9777
|
}
|
|
9676
|
-
/**
|
|
9677
|
-
* Builds the top level record query key based on AST data
|
|
9678
|
-
* @param operation
|
|
9679
|
-
* @param variables
|
|
9680
|
-
* @param argumentNodes
|
|
9681
|
-
* @param currentFieldName
|
|
9682
|
-
* @returns
|
|
9683
|
-
*/
|
|
9684
|
-
function buildKeyStringForRecordQuery(operation, variables, argumentNodes, currentFieldName) {
|
|
9685
|
-
const queryKey = buildQueryTypeStringKey({
|
|
9686
|
-
luvio: {},
|
|
9687
|
-
keyPrefix: 'UiApi',
|
|
9688
|
-
schemaName: 'uiapi',
|
|
9689
|
-
queryTypeName: 'Query',
|
|
9690
|
-
operationNode: operation,
|
|
9691
|
-
variables,
|
|
9692
|
-
fragmentMap: {},
|
|
9693
|
-
});
|
|
9694
|
-
const filteredArgumentNodes = assign$4([], argumentNodes).filter((node) => node.name.value !== 'first' && node.name.value !== 'after');
|
|
9695
|
-
const argumentString = filteredArgumentNodes.length > 0
|
|
9696
|
-
? '__' + serializeFieldArguments(filteredArgumentNodes, variables)
|
|
9697
|
-
: '';
|
|
9698
|
-
return `${queryKey}__uiapi__query__${currentFieldName}${argumentString}`;
|
|
9699
|
-
}
|
|
9700
|
-
/**
|
|
9701
|
-
* fetches a query level ingestion time stamp from the L2 cache
|
|
9702
|
-
* if no query has been seen then the timestamp is 0
|
|
9703
|
-
* @param apiName
|
|
9704
|
-
* @param info
|
|
9705
|
-
* @param args
|
|
9706
|
-
* @param query
|
|
9707
|
-
* @returns
|
|
9708
|
-
*/
|
|
9709
|
-
async function fetchIngestionTimeStampFromDatabase(apiName, info, args, query) {
|
|
9710
|
-
const { operation, variableValues } = info;
|
|
9711
|
-
// if we cannot find the query key in the database then default to 0 as we assume we have not seen the query
|
|
9712
|
-
// and all the data is not stale
|
|
9713
|
-
let ingestionTimestamp = 0;
|
|
9714
|
-
if (info.fieldNodes.length > 0 && info.fieldNodes[0].arguments !== undefined) {
|
|
9715
|
-
const key = buildKeyStringForRecordQuery(operation,
|
|
9716
|
-
// join varables passed from query to the argument variables given from the AST
|
|
9717
|
-
{ ...variableValues, ...args }, info.fieldNodes[0].arguments, apiName);
|
|
9718
|
-
return readIngestionTimestampForKey(key, query);
|
|
9719
|
-
}
|
|
9720
|
-
return ingestionTimestamp;
|
|
9721
|
-
}
|
|
9722
9778
|
|
|
9723
9779
|
var uiapiSchemaString = "scalar String\nscalar DateTime\nscalar Currency\nscalar ID\nscalar Boolean\nscalar Longitude\nscalar Float\nscalar MultiPicklist\nscalar Base64\nscalar Url\nscalar PhoneNumber\nscalar Email\nscalar TextArea\nscalar Latitude\nscalar Picklist\nscalar RichTextArea\nscalar EncryptedString\nscalar Double\nscalar Long\nscalar JSON\nscalar Time\nscalar Int\nscalar Percent\nscalar LongTextArea\nscalar IdOrRef\nscalar Date\ntype PercentAggregate implements FieldValue {\n value: Percent\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: PercentValue\n min: PercentValue\n sum: PercentValue\n}\n\ntype StringAggregate implements FieldValue {\n value: String\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: StringValue\n min: StringValue\n}\n\ntype Query {\n uiapi: UIAPI!\n setup: Setup__Setup!\n}\n\ninput EmailOperators {\n eq: Email\n ne: Email\n like: Email\n lt: Email\n gt: Email\n lte: Email\n gte: Email\n in: [Email]\n nin: [Email]\n}\n\ninput PolymorphicParentRelationshipRecordOrderBy @generic {\n RecordOrderBy: RecordOrderBy @fieldCategory\n}\n\ninput DoubleOperators {\n eq: Double\n ne: Double\n lt: Double\n gt: Double\n lte: Double\n gte: Double\n in: [Double]\n nin: [Double]\n}\n\ntype DateOnlyAggregation {\n value: Date\n format: String\n}\n\ntype RecordCreatePayload @generic {\n Record: RecordRepresentation\n}\n\ntype DateAggregate implements FieldValue {\n value: Date\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n grouping: IntValue\n max: DateValue\n min: DateValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput PolymorphicParentRelationshipGroupBy @generic {\n RecordGroupBy: RecordGroupBy @fieldCategory\n}\n\nenum GroupByFunction {\n DAY_IN_WEEK\n DAY_IN_MONTH\n DAY_IN_YEAR\n WEEK_IN_MONTH\n WEEK_IN_YEAR\n CALENDAR_MONTH\n CALENDAR_QUARTER\n CALENDAR_YEAR\n FISCAL_MONTH\n FISCAL_QUARTER\n FISCAL_YEAR\n DAY_ONLY\n HOUR_IN_DAY\n}\n\ntype RecordTypeInfo {\n available: Boolean!\n defaultRecordTypeMapping: Boolean!\n master: Boolean!\n name: String\n recordTypeId: ID\n}\n\ninput UIAPIMutationsInput {\n allOrNone: Boolean = true\n}\n\ntype BooleanValue implements FieldValue {\n value: Boolean\n displayValue: String\n}\n\ntype ReferenceToInfo {\n ApiName: String!\n nameFields: [String]!\n objectInfo: ObjectInfo\n}\n\ninterface FieldValue {\n displayValue: String\n}\n\ntype LongitudeValue implements FieldValue {\n value: Longitude\n displayValue: String\n}\n\ntype StringValue implements FieldValue {\n value: String\n displayValue: String\n label: String\n}\n\ntype IntValue implements FieldValue {\n value: Int\n displayValue: String\n format: String\n}\n\ntype UrlValue implements FieldValue {\n value: Url\n displayValue: String\n}\n\ninput IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: JoinInput\n ninq: JoinInput\n}\n\ninput Setup__SetupOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: Setup__SetupOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: Setup__SetupPolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ntype LongAggregate implements FieldValue {\n value: Long\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: LongValue\n min: LongValue\n sum: LongValue\n}\n\ntype PhoneNumberAggregate implements FieldValue {\n value: PhoneNumber\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: PhoneNumberValue\n min: PhoneNumberValue\n}\n\ninput TimeOperators {\n eq: Time\n ne: Time\n lt: Time\n gt: Time\n lte: Time\n gte: Time\n in: [Time]\n nin: [Time]\n}\n\ntype PicklistValue implements FieldValue {\n value: Picklist\n displayValue: String\n label: String\n}\n\ntype CurrencyAggregate implements FieldValue {\n value: Currency\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: CurrencyValue\n min: CurrencyValue\n sum: CurrencyValue\n}\n\ntype RelatedListInfo {\n childApiName: String!\n relatedListName: String!\n label: String!\n displayColumns: [ListColumn!]!\n orderedByInfo: [ListOrder!]!\n parentApiName: String!\n fieldApiName: String!\n}\n\ninput StringOperators {\n eq: String\n ne: String\n like: String\n lt: String\n gt: String\n lte: String\n gte: String\n in: [String]\n nin: [String]\n}\n\ntype UIAPI {\n query: RecordQuery!\n aggregate: RecordQueryAggregate!\n objectInfos(apiNames: [String], locale: String): [ObjectInfo]\n relatedListByName(parentApiName: String!, relatedListName: String!): RelatedListInfo\n}\n\ninput MultiPicklistOperators {\n eq: MultiPicklist\n ne: MultiPicklist\n includes: [MultiPicklist]\n excludes: [MultiPicklist]\n}\n\ntype DateTimeAggregate implements FieldValue {\n value: DateTime\n displayValue: String\n calendarMonth: DateFunctionAggregation\n calendarQuarter: DateFunctionAggregation\n calendarYear: DateFunctionAggregation\n count: LongValue\n countDistinct: LongValue\n dayInMonth: DateFunctionAggregation\n dayInWeek: DateFunctionAggregation\n dayInYear: DateFunctionAggregation\n dayOnly: DateOnlyAggregation\n fiscalMonth: DateFunctionAggregation\n fiscalQuarter: DateFunctionAggregation\n fiscalYear: DateFunctionAggregation\n format: String\n hourInDay: DateFunctionAggregation\n max: DateTimeValue\n min: DateTimeValue\n weekInMonth: DateFunctionAggregation\n weekInYear: DateFunctionAggregation\n}\n\ninput BooleanOperators {\n eq: Boolean\n ne: Boolean\n}\n\ntype EmailAggregate implements FieldValue {\n value: Email\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: EmailValue\n min: EmailValue\n}\n\n#enum OrderByType {\n#}\n\ninput GroupByDateFunction {\n function: GroupByFunction\n}\n\ntype RichTextAreaValue implements FieldValue {\n value: RichTextArea\n displayValue: String\n}\n\ntype MultiPicklistValue implements FieldValue {\n value: MultiPicklist\n displayValue: String\n label: String\n}\n\ntype Setup__SetupEdge @generic {\n node: Setup__EntityRepresentation\n cursor: String!\n}\n\ninput DatePrimitiveOperators {\n eq: Date\n ne: Date\n lt: Date\n gt: Date\n lte: Date\n gte: Date\n in: [Date]\n nin: [Date]\n}\n\ntype TimeAggregate implements FieldValue {\n value: Time\n displayValue: String\n format: String\n hourInDay: DateFunctionAggregation\n}\n\ntype __Type {\n kind: __TypeKind!\n name: String\n description: String\n fields(includeDeprecated: Boolean = false): [__Field!]\n interfaces: [__Type!]\n possibleTypes: [__Type!]\n enumValues(includeDeprecated: Boolean = false): [__EnumValue!]\n inputFields: [__InputValue!]\n ofType: __Type\n}\n\ntype ListColumn {\n fieldApiName: String!\n label: String!\n lookupId: String\n sortable: Boolean\n}\n\ntype Setup__SetupQuery {\n recordQuery(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, scope: String, upperBound: Int): Setup__SetupConnection @fieldCategory\n}\n\ntype Setup__EntityRepresentation @generic {\n Id: ID!\n ApiName: String!\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: Setup__EntityRepresentation @fieldCategory\n polymorphicParentRelationship: Setup__SetupPolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: Setup__SetupFilter, orderBy: Setup__SetupOrderBy, upperBound: Int): Setup__SetupConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype LatitudeAggregate implements FieldValue {\n value: Latitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LatitudeValue\n min: LatitudeValue\n sum: DoubleValue\n}\n\ninput CurrencyOperators {\n eq: Currency\n ne: Currency\n lt: Currency\n gt: Currency\n lte: Currency\n gte: Currency\n in: [Currency]\n nin: [Currency]\n}\n\ninput DistanceInput {\n latitude: Latitude!\n longitude: Longitude!\n}\n\nunion PolymorphicParentRelationship @generic = RecordRepresentation\n\nenum AggregateOrderByNumberFunction {\n AVG\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n SUM\n}\n\ntype LongTextAreaValue implements FieldValue {\n value: LongTextArea\n displayValue: String\n}\n\ntype LatitudeValue implements FieldValue {\n value: Latitude\n displayValue: String\n}\n\ninput OrderByClause {\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput AggregateOrderBy @generic {\n orderableNumberField: AggregateOrderByNumberClause @fieldCategory\n orderableStringField: AggregateOrderByStringClause @fieldCategory\n orderableField: NoFunctionAggregateOrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: AggregateOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipOrderBy @fieldCategory\n type: String = ORDER_BY\n}\n\ninput GroupByClause {\n group: Boolean\n}\n\ntype RecordAggregateConnection @generic {\n edges: [RecordAggregateEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LongitudeAggregate implements FieldValue {\n value: Longitude\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n max: LongitudeValue\n min: LongitudeValue\n sum: DoubleValue\n}\n\ntype RecordEdge @generic {\n node: RecordRepresentation\n cursor: String!\n}\n\nunion Setup__SetupPolymorphicParentRelationship @generic = Setup__EntityRepresentation\n\ntype DateValue implements FieldValue {\n value: Date\n displayValue: String\n format: String\n}\n\ninput URLOperators {\n eq: Url\n ne: Url\n like: Url\n lt: Url\n gt: Url\n lte: Url\n gte: Url\n in: [Url]\n nin: [Url]\n}\n\ninput LongOperators {\n eq: Long\n ne: Long\n lt: Long\n gt: Long\n lte: Long\n gte: Long\n in: [Long]\n nin: [Long]\n}\n\nenum DataType {\n STRING\n TEXTAREA\n PHONE\n EMAIL\n URL\n ENCRYPTEDSTRING\n BOOLEAN\n CURRENCY\n INT\n LONG\n DOUBLE\n PERCENT\n DATETIME\n TIME\n DATE\n REFERENCE\n PICKLIST\n MULTIPICKLIST\n ADDRESS\n LOCATION\n BASE64\n COMPLEXVALUE\n COMBOBOX\n JSON\n JUNCTIONIDLIST\n ANYTYPE\n}\n\nenum NullOrder {\n FIRST\n LAST\n}\n\ntype PhoneNumberValue implements FieldValue {\n value: PhoneNumber\n displayValue: String\n}\n\n# Cannot have empty enum\n# enum RecordScope @generic {\n# }\n\ninput Setup__SetupFilter @generic {\n and: [Setup__SetupFilter]\n or: [Setup__SetupFilter]\n not: Setup__SetupFilter\n parentRelationshipRecordFilter: Setup__SetupFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: Setup__SetupPolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n Setup__IdOperator: Setup__IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype DoubleAggregate implements FieldValue {\n value: Double\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n max: DoubleValue\n min: DoubleValue\n sum: DoubleValue\n}\n\ntype __Field {\n name: String!\n description: String\n args: [__InputValue!]!\n type: __Type!\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ninput DateOperators {\n eq: DateInput\n ne: DateInput\n lt: DateInput\n gt: DateInput\n lte: DateInput\n gte: DateInput\n in: [DateInput]\n nin: [DateInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n}\n\ninput GeolocationInput {\n latitude: Latitude!\n longitude: Longitude!\n radius: Float!\n unit: Unit!\n}\n\ninput JoinInput {\n Record: RecordFilter @fieldCategory\n ApiName: String\n}\n\ninput TextAreaOperators {\n eq: TextArea\n ne: TextArea\n like: TextArea\n lt: TextArea\n gt: TextArea\n lte: TextArea\n gte: TextArea\n in: [TextArea]\n nin: [TextArea]\n}\n\ntype TextAreaValue implements FieldValue {\n value: TextArea\n displayValue: String\n}\n\ntype RecordUpdatePayload @generic {\n success: Boolean\n}\n\ninput PercentOperators {\n eq: Percent\n ne: Percent\n lt: Percent\n gt: Percent\n lte: Percent\n gte: Percent\n in: [Percent]\n nin: [Percent]\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordOrderBy @generic {\n Setup__SetupOrderBy: Setup__SetupOrderBy @fieldCategory\n}\n\ntype DoubleValue implements FieldValue {\n value: Double\n displayValue: String\n format: String\n}\n\ntype IDAggregate implements FieldValue {\n value: ID\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: IDValue\n min: IDValue\n}\n\ntype __InputValue {\n name: String!\n description: String\n type: __Type!\n defaultValue: String\n}\n\ntype RecordAggregateEdge @generic {\n node: RecordResult\n cursor: String!\n}\n\ntype __Directive {\n name: String\n description: String\n locations: [__DirectiveLocation!]\n args: [__InputValue!]!\n}\n\ninput RecordCreateInput @generic {\n record: RecordCreateRepresentation! @fieldCategory\n}\n\ntype ThemeInfo {\n color: String\n iconUrl: String\n}\n\ninput AggregateOrderByStringClause {\n function: AggregateOrderByStringFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype RecordDeletePayload {\n Id: ID\n}\n\ntype UrlAggregate implements FieldValue {\n value: Url\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: UrlValue\n min: UrlValue\n}\n\nenum DateLiteral {\n LAST_YEAR\n LAST_WEEK\n THIS_QUARTER\n NEXT_FISCAL_YEAR\n LAST_QUARTER\n TOMORROW\n NEXT_FISCAL_QUARTER\n YESTERDAY\n NEXT_QUARTER\n THIS_FISCAL_QUARTER\n THIS_WEEK\n LAST_MONTH\n LAST_90_DAYS\n NEXT_90_DAYS\n THIS_FISCAL_YEAR\n NEXT_WEEK\n TODAY\n NEXT_YEAR\n NEXT_MONTH\n LAST_FISCAL_QUARTER\n THIS_MONTH\n LAST_FISCAL_YEAR\n THIS_YEAR\n}\n\ntype __EnumValue {\n name: String!\n description: String\n isDeprecated: Boolean!\n deprecationReason: String\n}\n\ntype RecordRepresentation implements Record @generic {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n parentRelationship: RecordRepresentation @fieldCategory\n polymorphicParentRelationship: PolymorphicParentRelationship @fieldCategory\n childRelationship(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, upperBound: Int): RecordConnection @fieldCategory\n CompoundField: CompoundField @fieldCategory\n}\n\ntype IDValue implements FieldValue {\n value: ID\n displayValue: String\n}\n\nenum Unit {\n MI\n KM\n}\n\ninput PolymorphicParentRelationshipOrderBy @generic {\n AggregateOrderBy: AggregateOrderBy @fieldCategory\n}\n\ninput OrderByGeolocationClause {\n distance: DistanceInput\n order: ResultOrder\n nulls: NullOrder\n}\n\ninput Setup__IdOperators {\n eq: ID\n ne: ID\n lt: ID\n gt: ID\n lte: ID\n gte: ID\n in: [ID]\n nin: [ID]\n inq: Setup__JoinInput\n ninq: Setup__JoinInput\n}\n\nenum NullsOrder {\n FIRST\n LAST\n}\n\ntype TextAreaAggregate implements FieldValue {\n value: TextArea\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n max: TextAreaValue\n min: TextAreaValue\n}\n\nenum GroupByType {\n GROUP_BY\n ROLLUP\n CUBE\n}\n\nenum ResultOrder {\n ASC\n DESC\n}\n\ninput RecordOrderBy @generic {\n orderableField: OrderByClause @fieldCategory\n orderableGeolocationField: OrderByGeolocationClause @fieldCategory\n orderableParentRelationship: RecordOrderBy @fieldCategory\n orderablePolymorphicParentRelationship: PolymorphicParentRelationshipRecordOrderBy @fieldCategory\n}\n\ninput Setup__JoinInput {\n Record: Setup__SetupFilter @fieldCategory\n ApiName: String\n}\n\ninput PicklistOperators {\n eq: Picklist\n ne: Picklist\n in: [Picklist]\n nin: [Picklist]\n like: Picklist\n lt: Picklist\n gt: Picklist\n lte: Picklist\n gte: Picklist\n}\n\nenum ResultsOrder {\n ASC\n DESC\n}\n\ninput RecordFilter @generic {\n and: [RecordFilter]\n or: [RecordFilter]\n not: RecordFilter\n parentRelationshipRecordFilter: RecordFilter @fieldCategory\n polymorphicParentRelationshipRecordFilter: PolymorphicParentRelationshipRecordFilter @fieldCategory\n IntegerOperator: IntegerOperators @fieldCategory\n LongOperator: LongOperators @fieldCategory\n StringOperator: StringOperators @fieldCategory\n DoubleOperator: DoubleOperators @fieldCategory\n PercentOperator: PercentOperators @fieldCategory\n LongitudeOperator: LongitudeOperators @fieldCategory\n LatitudeOperator: LatitudeOperators @fieldCategory\n EmailOperator: EmailOperators @fieldCategory\n TextAreaOperator: TextAreaOperators @fieldCategory\n LongTextAreaOperator: LongTextAreaOperators @fieldCategory\n URLOperator: URLOperators @fieldCategory\n PhoneNumberOperator: PhoneNumberOperators @fieldCategory\n BooleanOperator: BooleanOperators @fieldCategory\n IdOperator: IdOperators @fieldCategory\n CurrencyOperator: CurrencyOperators @fieldCategory\n TimeOperator: TimeOperators @fieldCategory\n DateOperator: DateOperators @fieldCategory\n DateTimeOperator: DateTimeOperators @fieldCategory\n PicklistOperator: PicklistOperators @fieldCategory\n MultiPicklistOperator: MultiPicklistOperators @fieldCategory\n GeolocationOperator: GeolocationOperators @fieldCategory\n}\n\ntype TimeValue implements FieldValue {\n value: Time\n displayValue: String\n format: String\n}\n\ninput GeolocationOperators {\n lt: GeolocationInput\n gt: GeolocationInput\n}\n\ntype PicklistAggregate implements FieldValue {\n value: Picklist\n displayValue: String\n count: LongValue\n countDistinct: LongValue\n grouping: IntValue\n label: String\n max: PicklistValue\n min: PicklistValue\n}\n\ninput LatitudeOperators {\n eq: Latitude\n ne: Latitude\n lt: Latitude\n gt: Latitude\n lte: Latitude\n gte: Latitude\n in: [Latitude]\n nin: [Latitude]\n}\n\ninput RecordUpdateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype DateTimeValue implements FieldValue {\n value: DateTime\n displayValue: String\n format: String\n}\n\ninput RecordDeleteInput {\n Id: IdOrRef!\n}\n\nenum __DirectiveLocation {\n QUERY\n MUTATION\n FIELD\n FRAGMENT_DEFINITION\n FRAGMENT_SPREAD\n INLINE_FRAGMENT\n SCHEMA\n SCALAR\n OBJECT\n FIELD_DEFINITION\n ARGUMENT_DEFINITION\n INTERFACE\n UNION\n ENUM\n ENUM_VALUE\n INPUT_OBJECT\n INPUT_FIELD_DEFINITION\n}\n\ntype IntAggregate implements FieldValue {\n value: Int\n displayValue: String\n avg: DoubleValue\n count: LongValue\n countDistinct: LongValue\n format: String\n grouping: IntValue\n max: IntValue\n min: IntValue\n sum: LongValue\n}\n\ntype ListOrder {\n fieldApiName: String!\n sortDirection: ResultOrder\n}\n\ntype RecordAggregate @generic {\n ApiName: String!\n BooleanAggregate: BooleanAggregate @fieldCategory\n CurrencyAggregate: CurrencyAggregate @fieldCategory\n DateAggregate: DateAggregate @fieldCategory\n DoubleAggregate: DoubleAggregate @fieldCategory\n EmailAggregate: EmailAggregate @fieldCategory\n IDAggregate: IDAggregate @fieldCategory\n IntAggregate: IntAggregate @fieldCategory\n LatitudeAggregate: LatitudeAggregate @fieldCategory\n LongitudeAggregate: LongitudeAggregate @fieldCategory\n LongAggregate: LongAggregate @fieldCategory\n PercentAggregate: PercentAggregate @fieldCategory\n PhoneNumberAggregate: PhoneNumberAggregate @fieldCategory\n PicklistAggregate: PicklistAggregate @fieldCategory\n StringAggregate: StringAggregate @fieldCategory\n TextAreaAggregate: TextAreaAggregate @fieldCategory\n TimeAggregate: TimeAggregate @fieldCategory\n UrlAggregate: UrlAggregate @fieldCategory\n}\n\ntype JSONValue implements FieldValue {\n value: JSON\n displayValue: String\n}\n\ntype EmailValue implements FieldValue {\n value: Email\n displayValue: String\n}\n\ntype Setup__Setup {\n query: Setup__SetupQuery!\n}\n\nenum AggregateOrderByStringFunction {\n COUNT\n COUNT_DISTINCT\n MAX\n MIN\n}\n\ntype LongValue implements FieldValue {\n value: Long\n displayValue: String\n format: String\n}\n\ninput DateFunctionInput {\n value: LongOperators\n convertTimezoneValue: LongOperators\n}\n\n# Mutations aren't supported yet.\n#type Mutation {\n# uiapi(input: UIAPIMutationsInput): UIAPIMutations!\n#}\n\ntype DependentField {\n controllingField: String!\n dependentFields: [String]!\n}\n\ninput LongTextAreaOperators {\n eq: LongTextArea\n ne: LongTextArea\n like: LongTextArea\n lt: LongTextArea\n gt: LongTextArea\n lte: LongTextArea\n gte: LongTextArea\n in: [LongTextArea]\n nin: [LongTextArea]\n}\n\nenum __TypeKind {\n SCALAR\n OBJECT\n INTERFACE\n UNION\n ENUM\n INPUT_OBJECT\n LIST\n NON_NULL\n}\n\ntype Setup__SetupConnection @generic {\n edges: [Setup__SetupEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype PercentValue implements FieldValue {\n value: Percent\n displayValue: String\n format: String\n}\n\ninput DateTimeOperators {\n eq: DateTimeInput\n ne: DateTimeInput\n lt: DateTimeInput\n gt: DateTimeInput\n lte: DateTimeInput\n gte: DateTimeInput\n in: [DateTimeInput]\n nin: [DateTimeInput]\n DAY_IN_WEEK: DateFunctionInput\n DAY_IN_MONTH: DateFunctionInput\n DAY_IN_YEAR: DateFunctionInput\n WEEK_IN_MONTH: DateFunctionInput\n WEEK_IN_YEAR: DateFunctionInput\n CALENDAR_MONTH: DateFunctionInput\n CALENDAR_QUARTER: DateFunctionInput\n CALENDAR_YEAR: DateFunctionInput\n FISCAL_MONTH: DateFunctionInput\n FISCAL_QUARTER: DateFunctionInput\n FISCAL_YEAR: DateFunctionInput\n DAY_ONLY: DateTimeFunctionInput\n HOUR_IN_DAY: DateFunctionInput\n}\n\ninput NoFunctionAggregateOrderByClause {\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype BooleanAggregate implements FieldValue {\n value: Boolean\n displayValue: String\n grouping: IntValue\n}\n\ntype RecordQueryAggregate {\n # RecordScope is replaced with String\n recordQueryAggregate(first: Int, after: String, where: RecordFilter, orderBy: AggregateOrderBy, scope: String, groupBy: RecordGroupBy, upperBound: Int): RecordAggregateConnection @fieldCategory\n}\n\ntype RecordConnection @generic {\n edges: [RecordEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n pageResultCount: Int!\n}\n\ntype FilteredLookupInfo {\n controllingFields: [String]!\n dependent: Boolean!\n optionalFilter: Boolean!\n}\n\ninput PhoneNumberOperators {\n eq: PhoneNumber\n ne: PhoneNumber\n like: PhoneNumber\n lt: PhoneNumber\n gt: PhoneNumber\n lte: PhoneNumber\n gte: PhoneNumber\n in: [PhoneNumber]\n nin: [PhoneNumber]\n}\n\ntype ObjectInfo {\n ApiName: String!\n childRelationships: [ChildRelationship]!\n createable: Boolean!\n custom: Boolean!\n defaultRecordTypeId: ID\n deletable: Boolean!\n dependentFields: [DependentField]!\n feedEnabled: Boolean!\n fields: [Field]!\n keyPrefix: String\n label: String\n labelPlural: String\n layoutable: Boolean!\n mruEnabled: Boolean!\n nameFields: [String]!\n queryable: Boolean!\n recordTypeInfos: [RecordTypeInfo]!\n searchable: Boolean!\n themeInfo: ThemeInfo\n updateable: Boolean!\n locale: String\n}\n\ninput LongitudeOperators {\n eq: Longitude\n ne: Longitude\n lt: Longitude\n gt: Longitude\n lte: Longitude\n gte: Longitude\n in: [Longitude]\n nin: [Longitude]\n}\n\ninput RecordCreateRepresentation @generic {\n Int: Int @fieldCategory\n String: String @fieldCategory\n Boolean: Boolean @fieldCategory\n ID: IdOrRef @fieldCategory\n DateTime: DateTime @fieldCategory\n Time: Time @fieldCategory\n Date: Date @fieldCategory\n TextArea: TextArea @fieldCategory\n LongTextArea: LongTextArea @fieldCategory\n RichTextArea: RichTextArea @fieldCategory\n PhoneNumber: PhoneNumber @fieldCategory\n Email: Email @fieldCategory\n Url: Url @fieldCategory\n EncryptedString: EncryptedString @fieldCategory\n Currency: Currency @fieldCategory\n Longitude: Longitude @fieldCategory\n Latitude: Latitude @fieldCategory\n Picklist: Picklist @fieldCategory\n MultiPicklist: MultiPicklist @fieldCategory\n Long: Long @fieldCategory\n Double: Double @fieldCategory\n Percent: Percent @fieldCategory\n Base64: Base64 @fieldCategory\n JSON: JSON @fieldCategory\n}\n\ntype Field {\n ApiName: String!\n calculated: Boolean!\n compound: Boolean!\n compoundComponentName: String\n compoundFieldName: String\n controllerName: String\n controllingFields: [String]!\n createable: Boolean!\n custom: Boolean!\n dataType: DataType\n extraTypeInfo: FieldExtraTypeInfo\n filterable: Boolean!\n filteredLookupInfo: FilteredLookupInfo\n highScaleNumber: Boolean!\n htmlFormatted: Boolean!\n inlineHelpText: String\n label: String\n nameField: Boolean!\n polymorphicForeignKey: Boolean!\n precision: Int\n reference: Boolean!\n referenceTargetField: String\n referenceToInfos: [ReferenceToInfo]!\n relationshipName: String\n required: Boolean!\n scale: Int\n searchPrefilterable: Boolean\n sortable: Boolean!\n updateable: Boolean!\n}\n\nenum FieldExtraTypeInfo {\n IMAGE_URL\n EXTERNAL_LOOKUP\n INDIRECT_LOOKUP\n PERSONNAME\n SWITCHABLE_PERSONNAME\n PLAINTEXTAREA\n RICHTEXTAREA\n}\n\ntype RateLimit {\n cost: Long\n limit: Long\n remaining: Long\n resetAt: DateTime\n}\n\ninput DateRange {\n last_n_days: Int\n next_n_days: Int\n last_n_weeks: Int\n next_n_weeks: Int\n last_n_months: Int\n next_n_months: Int\n last_n_quarters: Int\n next_n_quarters: Int\n last_n_fiscal_quarters: Int\n next_n_fiscal_quarters: Int\n last_n_years: Int\n next_n_years: Int\n last_n_fiscal_years: Int\n next_n_fiscal_years: Int\n n_days_ago: Int\n n_weeks_ago: Int\n n_months_ago: Int\n n_quarters_ago: Int\n n_years_ago: Int\n n_fiscal_quarters_ago: Int\n n_fiscal_years_ago: Int\n}\n\ntype UIAPIMutations {\n recordCreate(input: RecordCreateInput!): RecordCreatePayload @fieldCategory\n recordDelete(input: RecordDeleteInput!): RecordDeletePayload @fieldCategory\n recordUpdate(input: RecordUpdateInput!): RecordUpdatePayload @fieldCategory\n}\n\ninput DateTimeFunctionInput {\n value: DatePrimitiveOperators\n convertTimezoneValue: DatePrimitiveOperators\n}\n\ntype Base64Value implements FieldValue {\n value: Base64\n displayValue: String\n}\n\ninput IntegerOperators {\n eq: Int\n ne: Int\n lt: Int\n gt: Int\n lte: Int\n gte: Int\n in: [Int]\n nin: [Int]\n}\n\ntype EncryptedStringValue implements FieldValue {\n value: EncryptedString\n displayValue: String\n}\n\ninterface Record {\n Id: ID!\n ApiName: String!\n WeakEtag: Long!\n DisplayValue: String\n LastModifiedById: IDValue\n LastModifiedDate: DateTimeValue\n SystemModstamp: DateTimeValue\n RecordTypeId(fallback: Boolean): IDValue\n}\n\ninput PolymorphicParentRelationshipRecordFilter @generic {\n RecordFilter: RecordFilter @fieldCategory\n}\n\ninput AggregateOrderByNumberClause {\n function: AggregateOrderByNumberFunction\n order: ResultsOrder\n nulls: NullsOrder\n}\n\ntype __Schema {\n types: [__Type!]!\n queryType: __Type!\n mutationType: __Type\n directives: [__Directive!]!\n subscriptionType: __Type\n}\n\ninput Setup__SetupPolymorphicParentRelationshipRecordFilter @generic {\n Setup__SetupFilter: Setup__SetupFilter @fieldCategory\n}\n\ntype CompoundField @generic {\n IntValue: IntValue @fieldCategory\n StringValue: StringValue @fieldCategory\n BooleanValue: BooleanValue @fieldCategory\n IDValue: IDValue @fieldCategory\n DateTimeValue: DateTimeValue @fieldCategory\n TimeValue: TimeValue @fieldCategory\n DateValue: DateValue @fieldCategory\n TextAreaValue: TextAreaValue @fieldCategory\n LongTextAreaValue: LongTextAreaValue @fieldCategory\n RichTextAreaValue: RichTextAreaValue @fieldCategory\n PhoneNumberValue: PhoneNumberValue @fieldCategory\n EmailValue: EmailValue @fieldCategory\n UrlValue: UrlValue @fieldCategory\n EncryptedStringValue: EncryptedStringValue @fieldCategory\n CurrencyValue: CurrencyValue @fieldCategory\n LongitudeValue: LongitudeValue @fieldCategory\n LatitudeValue: LatitudeValue @fieldCategory\n PicklistValue: PicklistValue @fieldCategory\n MultiPicklistValue: MultiPicklistValue @fieldCategory\n LongValue: LongValue @fieldCategory\n DoubleValue: DoubleValue @fieldCategory\n PercentValue: PercentValue @fieldCategory\n Base64Value: Base64Value @fieldCategory\n JSONValue: JSONValue @fieldCategory\n}\n\ninput RecordUpdateInput @generic {\n Id: IdOrRef!\n record: RecordUpdateRepresentation! @fieldCategory\n}\n\ninput DateTimeInput {\n value: DateTime\n literal: DateLiteral\n range: DateRange\n}\n\ntype ChildRelationship {\n childObjectApiName: String!\n fieldName: String\n junctionIdListNames: [String]!\n junctionReferenceTo: [String]!\n relationshipName: String\n objectInfo: ObjectInfo\n}\n\ntype RecordResult @generic {\n aggregate: RecordAggregate\n}\n\ntype PageInfo {\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n endCursor: String\n}\n\ntype CurrencyValue implements FieldValue {\n value: Currency\n displayValue: String\n format: String\n}\n\ninput DateInput {\n value: Date\n literal: DateLiteral\n range: DateRange\n}\n\ninput RecordGroupBy @generic {\n groupableField: GroupByClause @fieldCategory\n groupableDateField: GroupByDateFunction @fieldCategory\n groupableParentRelationship: RecordGroupBy @fieldCategory\n groupablePolymorphicParentRelationship: PolymorphicParentRelationshipGroupBy @fieldCategory\n type: GroupByType = GROUP_BY\n}\n\ntype DateFunctionAggregation {\n value: Long\n format: String\n}\n\ntype RecordQuery {\n # scope should be type RecordScope but that's empty enum.\n recordQuery(first: Int, after: String, where: RecordFilter, orderBy: RecordOrderBy, scope: String, upperBound: Int): RecordConnection @fieldCategory\n}\n\ndirective @generic on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT\ndirective @fieldCategory on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE\ndirective @category(name: String!) on FIELD";
|
|
9724
9780
|
|
|
@@ -9904,7 +9960,7 @@ function createNewRecordQuery(schema, objectInfo, objectInfoMap) {
|
|
|
9904
9960
|
// handles child relationship
|
|
9905
9961
|
const { spanningRecordConnections, typedScalars: spanningConnectionTypedScalars } = makeSpanningRecordConnections(schema, childRelationships, objectInfoMap, parentRelationshipFields);
|
|
9906
9962
|
typedScalars = new Set([...typedScalars, ...spanningConnectionTypedScalars]);
|
|
9907
|
-
const recordQueries = `${apiName}(first: Int, where: ${apiName}_Filter, orderBy: ${apiName}_OrderBy, scope: SupportedScopes): ${apiName}Connection\n`;
|
|
9963
|
+
const recordQueries = `${apiName}(first: Int, after: String, where: ${apiName}_Filter, orderBy: ${apiName}_OrderBy, scope: SupportedScopes): ${apiName}Connection\n`;
|
|
9908
9964
|
const isServiceAppointment = apiName === 'ServiceAppointment';
|
|
9909
9965
|
const recordConnections = /* GraphQL */ `
|
|
9910
9966
|
${isServiceAppointment ? `scalar ${apiName.toUpperCase()}_SCOPE` : ''}
|
|
@@ -9926,6 +9982,7 @@ function createNewRecordQuery(schema, objectInfo, objectInfoMap) {
|
|
|
9926
9982
|
edges: [${apiName}Edge]
|
|
9927
9983
|
pageInfo: PageInfo!
|
|
9928
9984
|
totalCount: Int!
|
|
9985
|
+
pageResultCount: Int!
|
|
9929
9986
|
}
|
|
9930
9987
|
|
|
9931
9988
|
type ${apiName}Edge {
|
|
@@ -10007,7 +10064,7 @@ function makeSpanningRecordConnections(schema, childRelationships, objectInfoMap
|
|
|
10007
10064
|
}
|
|
10008
10065
|
if (objectInfoMap[childObjectApiName] !== undefined &&
|
|
10009
10066
|
!existingParentRelationships.has(relationshipName)) {
|
|
10010
|
-
spanningRecordConnections += `${relationshipName}(first: Int, where: ${childObjectApiName}_Filter, orderBy: ${childObjectApiName}_OrderBy, scope: SupportedScopes): ${childObjectApiName}Connection \n`;
|
|
10067
|
+
spanningRecordConnections += `${relationshipName}(first: Int, after: String, where: ${childObjectApiName}_Filter, orderBy: ${childObjectApiName}_OrderBy, scope: SupportedScopes): ${childObjectApiName}Connection \n`;
|
|
10011
10068
|
// if the record type has already been extended then these additional scalars have already been added
|
|
10012
10069
|
// to add them again would throw an error
|
|
10013
10070
|
const filterScalarType = schema.getType(`${childObjectApiName}_Filter`);
|
|
@@ -11820,7 +11877,7 @@ function createFieldNode(nameValue, selectionSet) {
|
|
|
11820
11877
|
*/
|
|
11821
11878
|
|
|
11822
11879
|
|
|
11823
|
-
const { keys: keys$3, values: values$1, create: create$3, assign: assign$3, freeze } = Object;
|
|
11880
|
+
const { keys: keys$3, values: values$1, create: create$3, assign: assign$3, freeze, entries: entries$3 } = Object;
|
|
11824
11881
|
const { stringify: stringify$3, parse: parse$3 } = JSON;
|
|
11825
11882
|
const { shift } = Array.prototype;
|
|
11826
11883
|
const { isArray: isArray$1, from: from$1 } = Array;
|
|
@@ -13227,7 +13284,7 @@ function getDenormalizedKey(originalKey, recordId, luvio) {
|
|
|
13227
13284
|
}
|
|
13228
13285
|
return keyBuilderRecord(luvio, { recordId });
|
|
13229
13286
|
}
|
|
13230
|
-
function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecords, getStoreMetadata, getStore) {
|
|
13287
|
+
function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecords, getStoreMetadata, getStore, sqlStore) {
|
|
13231
13288
|
const getEntries = function (entries, segment) {
|
|
13232
13289
|
// this HOF only inspects records in the default segment
|
|
13233
13290
|
if (segment !== DefaultDurableSegment) {
|
|
@@ -13289,7 +13346,10 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
13289
13346
|
});
|
|
13290
13347
|
};
|
|
13291
13348
|
const denormalizeEntries = function (entries) {
|
|
13349
|
+
let hasEntries = false;
|
|
13350
|
+
let hasMetadata = false;
|
|
13292
13351
|
const putEntries = create$3(null);
|
|
13352
|
+
const putMetadata = create$3(null);
|
|
13293
13353
|
const keys$1 = keys$3(entries);
|
|
13294
13354
|
const putRecords = {};
|
|
13295
13355
|
const putRecordViews = {};
|
|
@@ -13332,6 +13392,7 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
13332
13392
|
putRecords[recordId] = true;
|
|
13333
13393
|
}
|
|
13334
13394
|
if (isStoreRecordError(record)) {
|
|
13395
|
+
hasEntries = true;
|
|
13335
13396
|
putEntries[recordKey] = value;
|
|
13336
13397
|
continue;
|
|
13337
13398
|
}
|
|
@@ -13344,24 +13405,43 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
13344
13405
|
}
|
|
13345
13406
|
const denormalizedRecord = buildDurableRecordRepresentation(record, storeRecords, recordEntries, store);
|
|
13346
13407
|
if (denormalizedRecord !== undefined) {
|
|
13408
|
+
hasEntries = true;
|
|
13347
13409
|
putEntries[recordKey] = {
|
|
13348
13410
|
data: denormalizedRecord,
|
|
13349
13411
|
metadata,
|
|
13350
13412
|
};
|
|
13413
|
+
// if undefined then it is pending
|
|
13414
|
+
// we should still update metadata on pending records
|
|
13415
|
+
}
|
|
13416
|
+
else {
|
|
13417
|
+
hasMetadata = true;
|
|
13418
|
+
metadata.expirationTimestamp = metadata.ingestionTimestamp;
|
|
13419
|
+
putMetadata[recordKey] = {
|
|
13420
|
+
metadata,
|
|
13421
|
+
};
|
|
13351
13422
|
}
|
|
13352
13423
|
}
|
|
13353
13424
|
else {
|
|
13425
|
+
hasEntries = true;
|
|
13354
13426
|
putEntries[key] = value;
|
|
13355
13427
|
}
|
|
13356
13428
|
}
|
|
13357
|
-
return putEntries;
|
|
13429
|
+
return { putEntries, putMetadata, hasEntries, hasMetadata };
|
|
13358
13430
|
};
|
|
13359
13431
|
const setEntries = function (entries, segment) {
|
|
13360
13432
|
if (segment !== DefaultDurableSegment) {
|
|
13361
13433
|
return durableStore.setEntries(entries, segment);
|
|
13362
13434
|
}
|
|
13363
|
-
const putEntries = denormalizeEntries(entries);
|
|
13364
|
-
|
|
13435
|
+
const { putEntries, putMetadata, hasEntries, hasMetadata } = denormalizeEntries(entries);
|
|
13436
|
+
const promises = [
|
|
13437
|
+
hasEntries ? durableStore.setEntries(putEntries, segment) : undefined,
|
|
13438
|
+
];
|
|
13439
|
+
if (sqlStore !== undefined && sqlStore.isBatchUpdateSupported()) {
|
|
13440
|
+
promises.push(hasMetadata && sqlStore !== undefined
|
|
13441
|
+
? durableStore.setMetadata(putMetadata, segment)
|
|
13442
|
+
: undefined);
|
|
13443
|
+
}
|
|
13444
|
+
return Promise.all(promises).then(() => { });
|
|
13365
13445
|
};
|
|
13366
13446
|
const batchOperations = function (operations) {
|
|
13367
13447
|
const operationsWithDenormedRecords = [];
|
|
@@ -13378,10 +13458,20 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
13378
13458
|
// this is determined by the plugin supporting update batch calls before it gets to this HOF.
|
|
13379
13459
|
// so we only need to check one entry to confirm this for performance
|
|
13380
13460
|
if (firstEntry.data !== undefined) {
|
|
13461
|
+
const { putEntries, putMetadata, hasMetadata } = denormalizeEntries(operation.entries);
|
|
13381
13462
|
operationsWithDenormedRecords.push({
|
|
13382
13463
|
...operation,
|
|
13383
|
-
entries:
|
|
13464
|
+
entries: putEntries,
|
|
13384
13465
|
});
|
|
13466
|
+
if (hasMetadata &&
|
|
13467
|
+
sqlStore !== undefined &&
|
|
13468
|
+
sqlStore.isBatchUpdateSupported() === true) {
|
|
13469
|
+
operationsWithDenormedRecords.push({
|
|
13470
|
+
...operation,
|
|
13471
|
+
entries: putMetadata,
|
|
13472
|
+
type: 'setMetadata',
|
|
13473
|
+
});
|
|
13474
|
+
}
|
|
13385
13475
|
}
|
|
13386
13476
|
else {
|
|
13387
13477
|
operationsWithDenormedRecords.push(operation);
|
|
@@ -13393,10 +13483,20 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
13393
13483
|
operationsWithDenormedRecords.push(operation);
|
|
13394
13484
|
continue;
|
|
13395
13485
|
}
|
|
13486
|
+
const { putEntries, putMetadata, hasMetadata } = denormalizeEntries(operation.entries);
|
|
13396
13487
|
operationsWithDenormedRecords.push({
|
|
13397
13488
|
...operation,
|
|
13398
|
-
entries:
|
|
13489
|
+
entries: putEntries,
|
|
13399
13490
|
});
|
|
13491
|
+
if (hasMetadata &&
|
|
13492
|
+
sqlStore !== undefined &&
|
|
13493
|
+
sqlStore.isBatchUpdateSupported() === true) {
|
|
13494
|
+
operationsWithDenormedRecords.push({
|
|
13495
|
+
...operation,
|
|
13496
|
+
entries: putMetadata,
|
|
13497
|
+
type: 'setMetadata',
|
|
13498
|
+
});
|
|
13499
|
+
}
|
|
13400
13500
|
}
|
|
13401
13501
|
return durableStore.batchOperations(operationsWithDenormedRecords);
|
|
13402
13502
|
};
|
|
@@ -16521,6 +16621,9 @@ class NimbusSqliteStore {
|
|
|
16521
16621
|
isEvalSupported() {
|
|
16522
16622
|
return true;
|
|
16523
16623
|
}
|
|
16624
|
+
isBatchUpdateSupported() {
|
|
16625
|
+
return this.supportsBatchUpdates;
|
|
16626
|
+
}
|
|
16524
16627
|
query(sql, params) {
|
|
16525
16628
|
return new Promise((resolve, reject) => {
|
|
16526
16629
|
this.plugin.query(sql, params, (result) => {
|
|
@@ -18208,7 +18311,7 @@ function getRuntime() {
|
|
|
18208
18311
|
let getIngestRecords;
|
|
18209
18312
|
let getIngestMetadata;
|
|
18210
18313
|
let getIngestStore;
|
|
18211
|
-
const recordDenormingStore = makeRecordDenormalizingDurableStore(lazyLuvio, lazyBaseDurableStore, () => (getIngestRecords !== undefined ? getIngestRecords() : {}), () => (getIngestMetadata !== undefined ? getIngestMetadata() : {}), () => (getIngestStore !== undefined ? getIngestStore() : undefined));
|
|
18314
|
+
const recordDenormingStore = makeRecordDenormalizingDurableStore(lazyLuvio, lazyBaseDurableStore, () => (getIngestRecords !== undefined ? getIngestRecords() : {}), () => (getIngestMetadata !== undefined ? getIngestMetadata() : {}), () => (getIngestStore !== undefined ? getIngestStore() : undefined), lazyBaseDurableStore);
|
|
18212
18315
|
const baseEnv = new Environment(store, lazyNetworkAdapter);
|
|
18213
18316
|
const gqlEnv = makeEnvironmentGraphqlAware(baseEnv);
|
|
18214
18317
|
const durableEnv = makeDurable(gqlEnv, {
|
|
@@ -18321,4 +18424,4 @@ register({
|
|
|
18321
18424
|
});
|
|
18322
18425
|
|
|
18323
18426
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
18324
|
-
// version: 1.
|
|
18427
|
+
// version: 1.294.0-06a44f23f
|