@salesforce/lds-graphql-parser 1.127.0 → 1.128.1

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.
@@ -10740,745 +10740,745 @@ function dedentBlockString(blockStr) {
10740
10740
  return '"""' + body + '"""';
10741
10741
  }
10742
10742
 
10743
- /* Util Functions */
10744
- function isOperationDefinitionNode(input) {
10745
- return input.kind === 'OperationDefinition';
10746
- }
10747
- function isFragmentDefinitionNode(input) {
10748
- return input.kind === 'FragmentDefinition';
10749
- }
10750
- function isNamedTypeNode(input) {
10751
- return input.kind === 'NamedType';
10752
- }
10753
- function isListTypeNode(input) {
10754
- return input.kind === 'ListType';
10755
- }
10756
- function isNonNullTypeNode(input) {
10757
- return input.kind === 'NonNullType';
10758
- }
10759
-
10760
- const CUSTOM_DIRECTIVE_CONNECTION = 'connection';
10761
- const CUSTOM_DIRECTIVE_RESOURCE = 'resource';
10762
- const NODE_KIND_CUSTOM_FIELD_SELECTION = 'CustomFieldSelection';
10763
- const NODE_KIND_FIELD = 'Field';
10764
- const NODE_KIND_FRAGMENT_SPREAD = 'FragmentSpread';
10765
- const NODE_KIND_INLINE_FRAGMENT = 'InlineFragment';
10766
- const NODE_KIND_LIST_TYPE = 'ListType';
10767
- const NODE_KIND_NAMED_TYPE = 'NamedType';
10768
- const NODE_KIND_NON_NULL_TYPE = 'NonNullType';
10769
- const NODE_KIND_OBJECT_FIELD_SELECTION = 'ObjectFieldSelection';
10770
- const NODE_KIND_SCALAR_FIELD_SELECTION = 'ScalarFieldSelection';
10743
+ /* Util Functions */
10744
+ function isOperationDefinitionNode(input) {
10745
+ return input.kind === 'OperationDefinition';
10746
+ }
10747
+ function isFragmentDefinitionNode(input) {
10748
+ return input.kind === 'FragmentDefinition';
10749
+ }
10750
+ function isNamedTypeNode(input) {
10751
+ return input.kind === 'NamedType';
10752
+ }
10753
+ function isListTypeNode(input) {
10754
+ return input.kind === 'ListType';
10755
+ }
10756
+ function isNonNullTypeNode(input) {
10757
+ return input.kind === 'NonNullType';
10758
+ }
10759
+
10760
+ const CUSTOM_DIRECTIVE_CONNECTION = 'connection';
10761
+ const CUSTOM_DIRECTIVE_RESOURCE = 'resource';
10762
+ const NODE_KIND_CUSTOM_FIELD_SELECTION = 'CustomFieldSelection';
10763
+ const NODE_KIND_FIELD = 'Field';
10764
+ const NODE_KIND_FRAGMENT_SPREAD = 'FragmentSpread';
10765
+ const NODE_KIND_INLINE_FRAGMENT = 'InlineFragment';
10766
+ const NODE_KIND_LIST_TYPE = 'ListType';
10767
+ const NODE_KIND_NAMED_TYPE = 'NamedType';
10768
+ const NODE_KIND_NON_NULL_TYPE = 'NonNullType';
10769
+ const NODE_KIND_OBJECT_FIELD_SELECTION = 'ObjectFieldSelection';
10770
+ const NODE_KIND_SCALAR_FIELD_SELECTION = 'ScalarFieldSelection';
10771
10771
  const NODE_TYPE_CONNECTION = 'Connection';
10772
10772
 
10773
- function transform$b(node, transformState) {
10774
- switch (node.kind) {
10775
- case 'Variable':
10776
- transformState.variablesUsed[node.name.value] = true;
10777
- return {
10778
- kind: 'Variable',
10779
- name: node.name.value,
10780
- };
10781
- case 'IntValue':
10782
- return {
10783
- kind: 'IntValue',
10784
- value: node.value,
10785
- };
10786
- case 'FloatValue':
10787
- return {
10788
- kind: 'FloatValue',
10789
- value: node.value,
10790
- };
10791
- case 'StringValue':
10792
- return {
10793
- kind: 'StringValue',
10794
- value: node.value,
10795
- };
10796
- case 'BooleanValue':
10797
- return {
10798
- kind: 'BooleanValue',
10799
- value: node.value,
10800
- };
10801
- case 'EnumValue':
10802
- return {
10803
- kind: 'EnumValue',
10804
- value: node.value,
10805
- };
10806
- case 'NullValue':
10807
- return {
10808
- kind: 'NullValue',
10809
- };
10810
- case 'ListValue': {
10811
- const values = [];
10812
- for (var index = 0; index < node.values.length; index++) {
10813
- const value = transform$b(node.values[index], transformState);
10814
- values.push(value);
10815
- }
10816
- return {
10817
- kind: 'ListValue',
10818
- values: values,
10819
- };
10820
- }
10821
- case 'ObjectValue': {
10822
- const { fields } = node;
10823
- const result = {};
10824
- fields.forEach((field) => {
10825
- const name = field.name.value;
10826
- const value = transform$b(field.value, transformState);
10827
- result[name] = value;
10828
- });
10829
- return {
10830
- kind: 'ObjectValue',
10831
- fields: result,
10832
- };
10833
- }
10834
- default:
10835
- throw new Error('Unsupported ValueNode kind');
10836
- }
10837
- }
10838
-
10839
- function transform$a(node, transformState) {
10840
- const { kind, name: { value: nodeName }, value: nodeValue, } = node;
10841
- const valueNode = transform$b(nodeValue, transformState);
10842
- return {
10843
- kind,
10844
- name: nodeName,
10845
- value: valueNode,
10846
- };
10847
- }
10848
-
10849
- function transform$9(node, transformState) {
10850
- const { kind, name: { value: nodeName }, arguments: nodeArguments, } = node;
10851
- const ret = {
10852
- kind,
10853
- name: nodeName,
10854
- };
10855
- if (nodeArguments !== undefined && nodeArguments.length > 0) {
10856
- let returnArguments = [];
10857
- for (var index = 0; index < nodeArguments.length; index++) {
10858
- const argumentNode = nodeArguments[index];
10859
- const value = transform$a(argumentNode, transformState);
10860
- returnArguments.push(value);
10861
- }
10862
- ret.arguments = returnArguments;
10863
- }
10864
- return ret;
10865
- }
10866
- function isCustomDirective$1(node) {
10867
- return (node.name.value === CUSTOM_DIRECTIVE_CONNECTION ||
10868
- node.name.value === CUSTOM_DIRECTIVE_RESOURCE);
10869
- }
10870
-
10871
- function transform$8(node, transformState) {
10872
- const { name, alias, arguments: fieldArgs, selectionSet, directives } = node;
10873
- let luvioNode = {
10874
- kind: NODE_KIND_OBJECT_FIELD_SELECTION,
10875
- name: name.value,
10876
- luvioSelections: [],
10877
- };
10878
- if (selectionSet === undefined || selectionSet.selections.length === 0) {
10879
- luvioNode = {
10880
- kind: NODE_KIND_SCALAR_FIELD_SELECTION,
10881
- name: name.value,
10882
- };
10883
- }
10884
- else {
10885
- // object or custom field node
10886
- if (directives !== undefined && directives.length > 0) {
10887
- const customDirectiveNode = directives.find(isCustomDirective$1);
10888
- if (customDirectiveNode === undefined) {
10889
- // transform non client-side directives
10890
- luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10891
- }
10892
- else {
10893
- if (customDirectiveNode.name.value === CUSTOM_DIRECTIVE_CONNECTION) {
10894
- luvioNode = {
10895
- kind: NODE_KIND_CUSTOM_FIELD_SELECTION,
10896
- name: name.value,
10897
- type: NODE_TYPE_CONNECTION,
10898
- luvioSelections: [],
10899
- };
10900
- }
10901
- else if (customDirectiveNode.name.value === CUSTOM_DIRECTIVE_RESOURCE) {
10902
- luvioNode = {
10903
- kind: NODE_KIND_CUSTOM_FIELD_SELECTION,
10904
- name: name.value,
10905
- type: customDirectiveNode.arguments[0].value.value,
10906
- luvioSelections: [],
10907
- };
10908
- }
10909
- }
10910
- }
10911
- if (fieldArgs !== undefined && fieldArgs.length > 0) {
10912
- const returnArguments = [];
10913
- for (var index = 0; index < fieldArgs.length; index++) {
10914
- const value = transform$a(fieldArgs[index], transformState);
10915
- returnArguments.push(value);
10916
- }
10917
- luvioNode.arguments = returnArguments;
10918
- }
10919
- }
10920
- if (alias !== undefined) {
10921
- luvioNode.alias = alias.value;
10922
- }
10923
- return luvioNode;
10924
- }
10925
-
10926
- function transform$7(node, transformState) {
10927
- const { kind, name: { value }, directives, } = node;
10928
- const luvioNode = {
10929
- kind,
10930
- name: value,
10931
- };
10932
- if (directives !== undefined && directives.length > 0) {
10933
- luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10934
- }
10935
- return luvioNode;
10936
- }
10937
-
10938
- function transform$6(node, transformState) {
10939
- const { kind: nodeKind, typeCondition, directives } = node;
10940
- const luvioNode = {
10941
- kind: nodeKind,
10942
- luvioSelections: [],
10943
- };
10944
- if (typeCondition !== undefined) {
10945
- luvioNode.typeCondition = {
10946
- kind: typeCondition.kind,
10947
- name: typeCondition.name.value,
10948
- };
10949
- }
10950
- if (directives !== undefined && directives.length > 0) {
10951
- luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10952
- }
10953
- return luvioNode;
10954
- }
10955
-
10956
- function selectionSetVisitor(ast, luvioSelectionPath, transformState) {
10957
- const visitor = {
10958
- enter(node) {
10959
- let selectionNode;
10960
- switch (node.kind) {
10961
- case NODE_KIND_FIELD: {
10962
- const fieldNode = transform$8(node, transformState);
10963
- selectionNode = fieldNode;
10964
- break;
10965
- }
10966
- case NODE_KIND_FRAGMENT_SPREAD:
10967
- selectionNode = transform$7(node, transformState);
10968
- break;
10969
- case NODE_KIND_INLINE_FRAGMENT:
10970
- selectionNode = transform$6(node, transformState);
10971
- break;
10972
- }
10973
- if (selectionNode !== undefined) {
10974
- const parentNode = luvioSelectionPath[luvioSelectionPath.length - 1];
10975
- if (parentNode.kind === NODE_KIND_OBJECT_FIELD_SELECTION ||
10976
- parentNode.kind === NODE_KIND_CUSTOM_FIELD_SELECTION ||
10977
- parentNode.kind === NODE_KIND_INLINE_FRAGMENT) {
10978
- parentNode.luvioSelections.push(selectionNode);
10979
- }
10980
- luvioSelectionPath.push(selectionNode);
10981
- }
10982
- },
10983
- leave(node) {
10984
- switch (node.kind) {
10985
- case NODE_KIND_FIELD:
10986
- case NODE_KIND_FRAGMENT_SPREAD:
10987
- case NODE_KIND_INLINE_FRAGMENT:
10988
- luvioSelectionPath.pop();
10989
- break;
10990
- }
10991
- },
10992
- };
10993
- visit(ast, visitor);
10994
- }
10995
-
10996
- function transform$5(node) {
10997
- if (isNamedTypeNode(node)) {
10998
- return {
10999
- kind: NODE_KIND_NAMED_TYPE,
11000
- name: node.name.value,
11001
- };
11002
- }
11003
- else if (isListTypeNode(node)) {
11004
- return {
11005
- kind: NODE_KIND_LIST_TYPE,
11006
- type: transform$5(node.type),
11007
- };
11008
- }
11009
- else if (isNonNullTypeNode(node)) {
11010
- if (isNamedTypeNode(node.type)) {
11011
- return {
11012
- kind: NODE_KIND_NON_NULL_TYPE,
11013
- type: {
11014
- kind: NODE_KIND_NAMED_TYPE,
11015
- name: node.type.name.value,
11016
- },
11017
- };
11018
- }
11019
- else if (isListTypeNode(node.type)) {
11020
- return {
11021
- kind: NODE_KIND_NON_NULL_TYPE,
11022
- type: {
11023
- kind: NODE_KIND_LIST_TYPE,
11024
- type: transform$5(node.type.type),
11025
- },
11026
- };
11027
- }
11028
- else {
11029
- throw new Error('Unsupported NonNullTypeNode');
11030
- }
11031
- }
11032
- else {
11033
- throw new Error('Unsupported TypeNode');
11034
- }
11035
- }
11036
-
11037
- function transform$4(variableDefinitions, transformState) {
11038
- const { kind, variable: { kind: variableKind, name: { value: variableName }, }, type, defaultValue, } = variableDefinitions;
11039
- const ret = {
11040
- kind,
11041
- variable: {
11042
- kind: variableKind,
11043
- name: variableName,
11044
- },
11045
- type: transform$5(type),
11046
- };
11047
- if (defaultValue !== undefined) {
11048
- const value = transform$b(defaultValue, transformState);
11049
- ret.defaultValue = value;
11050
- }
11051
- // TODO: transform directives
11052
- return ret;
11053
- }
11054
-
11055
- function validateVariables(variableDefinitions, transformState) {
11056
- if (process.env.NODE_ENV === 'production') {
11057
- throw new ReferenceError("Do not call this function in production becuase we don't want to break existing uses. Other environments are okay because we want to catch errors early.");
11058
- }
11059
- const variablesDefined = {};
11060
- if (variableDefinitions !== undefined) {
11061
- for (let i = 0, len = variableDefinitions.length; i < len; i++) {
11062
- const definedVariableName = variableDefinitions[i].variable.name.value;
11063
- variablesDefined[definedVariableName] = true;
11064
- if (transformState.variablesUsed[definedVariableName] === undefined) {
11065
- throw new Error(`Variable $${definedVariableName} was defined but never used.`);
11066
- }
11067
- }
11068
- }
11069
- const usedVariableKeys = Object.keys(transformState.variablesUsed);
11070
- for (let i = 0, len = usedVariableKeys.length; i < len; i++) {
11071
- if (variablesDefined[usedVariableKeys[i]] !== true) {
11072
- throw new Error(`Variable $${usedVariableKeys[i]} was used but never defined.`);
11073
- }
11074
- }
11075
- }
11076
- function transform$3(node) {
11077
- const queryRoot = {
11078
- kind: 'ObjectFieldSelection',
11079
- name: 'query',
11080
- luvioSelections: [],
11081
- };
11082
- const currentNodePath = [queryRoot];
11083
- const transformState = {
11084
- variablesUsed: {},
11085
- };
11086
- selectionSetVisitor(node, currentNodePath, transformState);
11087
- const operationDefinition = {
11088
- kind: 'OperationDefinition',
11089
- operation: 'query',
11090
- luvioSelections: queryRoot.luvioSelections,
11091
- };
11092
- if (node.name !== undefined) {
11093
- operationDefinition.name = node.name.value;
11094
- }
11095
- const { variableDefinitions, directives } = node;
11096
- if (variableDefinitions !== undefined && variableDefinitions.length > 0) {
11097
- operationDefinition.variableDefinitions = variableDefinitions.map((variableDefinition) => transform$4(variableDefinition, transformState));
11098
- }
11099
- if (directives !== undefined && directives.length > 0) {
11100
- operationDefinition.directives = directives.map((node) => transform$9(node, transformState));
11101
- }
11102
- if (process.env.NODE_ENV !== 'production') {
11103
- validateVariables(variableDefinitions, transformState);
11104
- }
11105
- return operationDefinition;
11106
- }
11107
-
11108
- function transform$2(node) {
11109
- const { operation } = node;
11110
- if (operation === 'query') {
11111
- return transform$3(node);
11112
- }
11113
- throw new Error(`Unsupported ${operation} operation. Only query operation is supported`);
11114
- }
11115
-
11116
- function transform$1(node) {
11117
- const { kind: nodeKind, name: { value: nodeName }, typeCondition: { kind: typeKind, name: { value: typeName }, }, directives, } = node;
11118
- // dummy root node
11119
- const fragmentRoot = {
11120
- kind: NODE_KIND_OBJECT_FIELD_SELECTION,
11121
- name: 'fragment',
11122
- luvioSelections: [],
11123
- };
11124
- const currentNodePath = [fragmentRoot];
11125
- const transformState = { variablesUsed: {} };
11126
- selectionSetVisitor(node, currentNodePath, transformState);
11127
- const luvioNode = {
11128
- kind: nodeKind,
11129
- name: nodeName,
11130
- typeCondition: {
11131
- kind: typeKind,
11132
- name: typeName,
11133
- },
11134
- luvioSelections: fragmentRoot.luvioSelections,
11135
- };
11136
- if (directives !== undefined && directives.length > 0) {
11137
- luvioNode.directives = directives.map((node) => transform$9(node, transformState));
11138
- }
11139
- return luvioNode;
11140
- }
11141
-
11142
- function transform(root) {
11143
- const { kind, definitions } = root;
11144
- const luvioDefinitions = [];
11145
- for (let i = 0; i < definitions.length; i++) {
11146
- const definition = definitions[i];
11147
- if (isOperationDefinitionNode(definition)) {
11148
- luvioDefinitions.push(transform$2(definition));
11149
- }
11150
- else if (isFragmentDefinitionNode(definition)) {
11151
- luvioDefinitions.push(transform$1(definition));
11152
- }
11153
- else {
11154
- if (process.env.NODE_ENV !== 'production') {
11155
- throw new Error(`Unsupported ${definition.kind} definition. Only OperationDefinition and FragmentDefinition are supported in a GraphQL Document`);
11156
- }
11157
- }
11158
- }
11159
- return {
11160
- kind,
11161
- definitions: luvioDefinitions,
11162
- };
11163
- }
11164
-
11165
- /**
11166
- * we should look into optimizing this before it turns into a memory hog
11167
- * weakmaps, or limiting the size of the cache, or something
11168
- */
11169
- const docMap = new Map();
11170
- /**
11171
- * Opaque reference map to return keys to userland
11172
- * As a user shouldn't have access to the Document
11173
- */
11174
- const referenceMap = new WeakMap();
11175
- /**
11176
- * Strips characters that are not significant to the validity or execution
11177
- * of a GraphQL document:
11178
- * - UnicodeBOM
11179
- * - WhiteSpace
11180
- * - LineTerminator
11181
- * - Comment
11182
- * - Comma
11183
- * - BlockString indentation
11184
- */
11185
- function operationKeyBuilder(inputString) {
11186
- return stripIgnoredCharacters(inputString);
11187
- }
11188
- /**
11189
- * Returns document node if cached or else update the cache and return the document node
11190
- * @param inputString - operation string
11191
- * @returns DocumentNode
11192
- */
11193
- function parseDocument(inputString) {
11194
- const operationKey = operationKeyBuilder(inputString);
11195
- const cachedDoc = docMap.get(operationKey);
11196
- if (cachedDoc !== undefined) {
11197
- return cachedDoc;
11198
- }
11199
- // parse throws an GraphQLError in case of invalid query, should this be in try/catch?
11200
- const parsedDoc = parse(inputString, { noLocation: true });
11201
- if (!parsedDoc || parsedDoc.kind !== 'Document') {
11202
- if (process.env.NODE_ENV !== 'production') {
11203
- throw new Error('Invalid graphql doc');
11204
- }
11205
- return null;
11206
- }
11207
- docMap.set(operationKey, parsedDoc);
11208
- return parsedDoc;
11209
- }
11210
- /**
11211
- * If the input string has fragment substitution
11212
- * Insert the fragments AST to the query document node
11213
- */
11214
- function insertFragments(doc, fragments) {
11215
- fragments.forEach((fragment) => {
11216
- // @ts-ignore
11217
- // graphql describes definitions as "readonly"
11218
- // so we aren't supposed to mutate the document node
11219
- // but instead of parsing the fragment again, we substitute it's definition in the document node
11220
- doc.definitions.push(fragment);
11221
- });
11222
- return doc;
11223
- }
11224
- function updateReferenceMapWithKnownKey(doc, key) {
11225
- referenceMap.set(key, doc);
11226
- }
11227
- function updateReferenceMapAndGetKey(doc) {
11228
- // the key is a String object so that legacy locker does not replace its identity.
11229
- const key = new String();
11230
- updateReferenceMapWithKnownKey(doc, key);
11231
- return key;
11232
- }
11233
- /**
11234
- * Insert string and fragment substitutions with the actual nodes
11235
- * @param inputString
11236
- * @param substitutions - string | fragment DocumentNode
11237
- * @returns { operation string, fragment docs [] }
11238
- */
11239
- function processSubstitutions(inputString, substitutions) {
11240
- let outputString = '';
11241
- const fragments = [];
11242
- const subLength = substitutions.length;
11243
- for (let i = 0; i < subLength; i++) {
11244
- const substitution = substitutions[i];
11245
- outputString += inputString[i];
11246
- if (typeof substitution === 'string' || typeof substitution === 'number') {
11247
- outputString += substitution;
11248
- }
11249
- else if (typeof substitution === 'object') {
11250
- const doc = referenceMap.get(substitution);
11251
- if (doc === undefined) {
11252
- if (process.env.NODE_ENV !== 'production') {
11253
- throw new Error('Invalid substitution fragment');
11254
- }
11255
- return null;
11256
- }
11257
- for (const def of doc.definitions) {
11258
- fragments.push(def);
11259
- }
11260
- }
11261
- else {
11262
- if (process.env.NODE_ENV !== 'production') {
11263
- throw new Error('Unsupported substitution type');
11264
- }
11265
- return null;
11266
- }
11267
- }
11268
- return {
11269
- operationString: outputString + inputString[subLength],
11270
- fragments,
11271
- };
11272
- }
11273
- /**
11274
- *
11275
- * @param astReference - ast reference passed from user land
11276
- */
11277
- const astResolver = function (astReference) {
11278
- return referenceMap.get(astReference);
11279
- };
11280
- /**
11281
- *
11282
- * @param literals - operation query string
11283
- * @param subs - all other substitutions
11284
- * @returns an opaque reference to the parsed document
11285
- */
11286
- function gql(literals, ...subs) {
11287
- let inputString;
11288
- let inputSubstitutionFragments;
11289
- if (!literals) {
11290
- if (process.env.NODE_ENV !== 'production') {
11291
- throw new Error('Invalid query');
11292
- }
11293
- return null;
11294
- }
11295
- else if (typeof literals === 'string') {
11296
- inputString = literals.trim();
11297
- inputSubstitutionFragments = [];
11298
- }
11299
- else {
11300
- // called as template literal
11301
- const sub = processSubstitutions(literals, subs);
11302
- // if invalid fragment references found
11303
- if (sub === null) {
11304
- return null;
11305
- }
11306
- const { operationString, fragments } = sub;
11307
- inputString = operationString.trim();
11308
- inputSubstitutionFragments = fragments;
11309
- }
11310
- if (inputString.length === 0) {
11311
- if (process.env.NODE_ENV !== 'production') {
11312
- throw new Error('Invalid query');
11313
- }
11314
- return null;
11315
- }
11316
- const document = parseDocument(inputString);
11317
- if (document === null) {
11318
- return null;
11319
- }
11320
- if (inputSubstitutionFragments.length === 0) {
11321
- return updateReferenceMapAndGetKey(document);
11322
- }
11323
- return updateReferenceMapAndGetKey(insertFragments(document, inputSubstitutionFragments));
11324
- }
11325
-
11326
- const DIRECTIVE_RECORD_QUERY_CATEGORY = {
11327
- kind: 'Directive',
11328
- name: {
11329
- kind: 'Name',
11330
- value: 'category',
11331
- },
11332
- arguments: [
11333
- {
11334
- kind: 'Argument',
11335
- name: {
11336
- kind: 'Name',
11337
- value: 'name',
11338
- },
11339
- value: {
11340
- kind: 'StringValue',
11341
- value: 'recordQuery',
11342
- block: false,
11343
- },
11344
- },
11345
- ],
11346
- };
11347
- const DIRECTIVE_CHILD_RELATIONSHIP_CATEGORY = {
11348
- kind: 'Directive',
11349
- name: {
11350
- kind: 'Name',
11351
- value: 'category',
11352
- },
11353
- arguments: [
11354
- {
11355
- kind: 'Argument',
11356
- name: {
11357
- kind: 'Name',
11358
- value: 'name',
11359
- },
11360
- value: {
11361
- kind: 'StringValue',
11362
- value: 'childRelationship',
11363
- block: false,
11364
- },
11365
- },
11366
- ],
11367
- };
11368
- const DIRECTIVE_PARENT_CATEGORY = {
11369
- kind: 'Directive',
11370
- name: {
11371
- kind: 'Name',
11372
- value: 'category',
11373
- },
11374
- arguments: [
11375
- {
11376
- kind: 'Argument',
11377
- name: {
11378
- kind: 'Name',
11379
- value: 'name',
11380
- },
11381
- value: {
11382
- kind: 'StringValue',
11383
- value: 'parentRelationship',
11384
- block: false,
11385
- },
11386
- },
11387
- ],
11388
- };
11389
- function substituteDirectives(directives, index, selection, parentNode) {
11390
- if (directives[index].name.value === CUSTOM_DIRECTIVE_CONNECTION) {
11391
- if (parentNode !== undefined &&
11392
- parentNode.kind === 'Field' &&
11393
- parentNode.name.value === 'uiapi') {
11394
- // @ts-ignore - Document is read only
11395
- directives[index] = DIRECTIVE_RECORD_QUERY_CATEGORY;
11396
- }
11397
- else {
11398
- // @ts-ignore - Document is read only
11399
- directives[index] = DIRECTIVE_CHILD_RELATIONSHIP_CATEGORY;
11400
- }
11401
- }
11402
- else if (directives[index].name.value === CUSTOM_DIRECTIVE_RESOURCE) {
11403
- // node gets its type from @category recordQuery or @category childRelationship
11404
- if (selection.kind === 'Field' && selection.name.value === 'node') {
11405
- // @ts-ignore - Document is read only
11406
- directives.splice(index, 1);
11407
- }
11408
- else {
11409
- // @ts-ignore - Document is read only
11410
- directives[index] = DIRECTIVE_PARENT_CATEGORY;
11411
- }
11412
- }
11413
- }
11414
- /**
11415
- * Returns true if the directive node is of legacy type
11416
- * @param node : Directive node
11417
- * @returns
11418
- */
11419
- function isCustomDirective(node) {
11420
- return (node.name.value === CUSTOM_DIRECTIVE_CONNECTION ||
11421
- node.name.value === CUSTOM_DIRECTIVE_RESOURCE);
11422
- }
11423
- /**
11424
- * Traverses a selection and it's nested selections,
11425
- * to find any legacy custom directives and substitute them with metaschema directives
11426
- * @param node - SelectionNode
11427
- * @returns void
11428
- */
11429
- function traverseSelection(node, parentNode) {
11430
- if (node === undefined || node.kind === 'FragmentSpread' || node.selectionSet === undefined) {
11431
- return;
11432
- }
11433
- const { selectionSet } = node;
11434
- for (const selection of selectionSet.selections) {
11435
- replaceCustomDirectives(selection, parentNode);
11436
- traverseSelection(selection, node);
11437
- }
11438
- }
11439
- function replaceCustomDirectives(selection, parentNode) {
11440
- const { directives } = selection;
11441
- if (directives !== undefined && directives.length > 0) {
11442
- // we follow this pattern instead of map to preserve the order of directives
11443
- // order of directives may be significant as per graphql spec
11444
- const index = directives.findIndex(isCustomDirective);
11445
- if (index !== -1) {
11446
- substituteDirectives(directives, index, selection, parentNode);
11447
- }
11448
- }
11449
- }
11450
- /**
11451
- * Accepts a document node and replaces the legacy custom directives with metaschema directives "in-place"
11452
- * @param doc
11453
- */
11454
- function metaschemaMapper(doc) {
11455
- // this method is only callable for Executable definitions
11456
- // such as Operations and Fragments
11457
- // so we have to explicitly cast the definitions for ts
11458
- const { definitions } = doc;
11459
- for (const def of definitions) {
11460
- const { selectionSet } = def;
11461
- // This is just iterating through the top level 'Query' operations. There should never be any custom
11462
- // directives at this level, as RecordQuery is actually a field lower in the schema. So we can skip looking for them.
11463
- selectionSet.selections.forEach((selection) => {
11464
- traverseSelection(selection);
11465
- });
11466
- }
11467
- }
11468
-
11469
- /**
11470
- * @deprecated In favor of gql tagged template literal
11471
- */
11472
- function parseAndVisit(source) {
11473
- const ast = parse(source, { noLocation: true });
11474
- const luvioDocumentNode = transform(ast);
11475
- // In-place substitution of metaschema annotations
11476
- metaschemaMapper(ast);
11477
- // Set the AST reference map with LuvioDocumentNode as the key
11478
- // ASTResolver will resolve it to metaschema mapped AST
11479
- updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
11480
- return luvioDocumentNode;
10773
+ function transform$b(node, transformState) {
10774
+ switch (node.kind) {
10775
+ case 'Variable':
10776
+ transformState.variablesUsed[node.name.value] = true;
10777
+ return {
10778
+ kind: 'Variable',
10779
+ name: node.name.value,
10780
+ };
10781
+ case 'IntValue':
10782
+ return {
10783
+ kind: 'IntValue',
10784
+ value: node.value,
10785
+ };
10786
+ case 'FloatValue':
10787
+ return {
10788
+ kind: 'FloatValue',
10789
+ value: node.value,
10790
+ };
10791
+ case 'StringValue':
10792
+ return {
10793
+ kind: 'StringValue',
10794
+ value: node.value,
10795
+ };
10796
+ case 'BooleanValue':
10797
+ return {
10798
+ kind: 'BooleanValue',
10799
+ value: node.value,
10800
+ };
10801
+ case 'EnumValue':
10802
+ return {
10803
+ kind: 'EnumValue',
10804
+ value: node.value,
10805
+ };
10806
+ case 'NullValue':
10807
+ return {
10808
+ kind: 'NullValue',
10809
+ };
10810
+ case 'ListValue': {
10811
+ const values = [];
10812
+ for (var index = 0; index < node.values.length; index++) {
10813
+ const value = transform$b(node.values[index], transformState);
10814
+ values.push(value);
10815
+ }
10816
+ return {
10817
+ kind: 'ListValue',
10818
+ values: values,
10819
+ };
10820
+ }
10821
+ case 'ObjectValue': {
10822
+ const { fields } = node;
10823
+ const result = {};
10824
+ fields.forEach((field) => {
10825
+ const name = field.name.value;
10826
+ const value = transform$b(field.value, transformState);
10827
+ result[name] = value;
10828
+ });
10829
+ return {
10830
+ kind: 'ObjectValue',
10831
+ fields: result,
10832
+ };
10833
+ }
10834
+ default:
10835
+ throw new Error('Unsupported ValueNode kind');
10836
+ }
10837
+ }
10838
+
10839
+ function transform$a(node, transformState) {
10840
+ const { kind, name: { value: nodeName }, value: nodeValue, } = node;
10841
+ const valueNode = transform$b(nodeValue, transformState);
10842
+ return {
10843
+ kind,
10844
+ name: nodeName,
10845
+ value: valueNode,
10846
+ };
10847
+ }
10848
+
10849
+ function transform$9(node, transformState) {
10850
+ const { kind, name: { value: nodeName }, arguments: nodeArguments, } = node;
10851
+ const ret = {
10852
+ kind,
10853
+ name: nodeName,
10854
+ };
10855
+ if (nodeArguments !== undefined && nodeArguments.length > 0) {
10856
+ let returnArguments = [];
10857
+ for (var index = 0; index < nodeArguments.length; index++) {
10858
+ const argumentNode = nodeArguments[index];
10859
+ const value = transform$a(argumentNode, transformState);
10860
+ returnArguments.push(value);
10861
+ }
10862
+ ret.arguments = returnArguments;
10863
+ }
10864
+ return ret;
10865
+ }
10866
+ function isCustomDirective$1(node) {
10867
+ return (node.name.value === CUSTOM_DIRECTIVE_CONNECTION ||
10868
+ node.name.value === CUSTOM_DIRECTIVE_RESOURCE);
10869
+ }
10870
+
10871
+ function transform$8(node, transformState) {
10872
+ const { name, alias, arguments: fieldArgs, selectionSet, directives } = node;
10873
+ let luvioNode = {
10874
+ kind: NODE_KIND_OBJECT_FIELD_SELECTION,
10875
+ name: name.value,
10876
+ luvioSelections: [],
10877
+ };
10878
+ if (selectionSet === undefined || selectionSet.selections.length === 0) {
10879
+ luvioNode = {
10880
+ kind: NODE_KIND_SCALAR_FIELD_SELECTION,
10881
+ name: name.value,
10882
+ };
10883
+ }
10884
+ else {
10885
+ // object or custom field node
10886
+ if (directives !== undefined && directives.length > 0) {
10887
+ const customDirectiveNode = directives.find(isCustomDirective$1);
10888
+ if (customDirectiveNode === undefined) {
10889
+ // transform non client-side directives
10890
+ luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10891
+ }
10892
+ else {
10893
+ if (customDirectiveNode.name.value === CUSTOM_DIRECTIVE_CONNECTION) {
10894
+ luvioNode = {
10895
+ kind: NODE_KIND_CUSTOM_FIELD_SELECTION,
10896
+ name: name.value,
10897
+ type: NODE_TYPE_CONNECTION,
10898
+ luvioSelections: [],
10899
+ };
10900
+ }
10901
+ else if (customDirectiveNode.name.value === CUSTOM_DIRECTIVE_RESOURCE) {
10902
+ luvioNode = {
10903
+ kind: NODE_KIND_CUSTOM_FIELD_SELECTION,
10904
+ name: name.value,
10905
+ type: customDirectiveNode.arguments[0].value.value,
10906
+ luvioSelections: [],
10907
+ };
10908
+ }
10909
+ }
10910
+ }
10911
+ if (fieldArgs !== undefined && fieldArgs.length > 0) {
10912
+ const returnArguments = [];
10913
+ for (var index = 0; index < fieldArgs.length; index++) {
10914
+ const value = transform$a(fieldArgs[index], transformState);
10915
+ returnArguments.push(value);
10916
+ }
10917
+ luvioNode.arguments = returnArguments;
10918
+ }
10919
+ }
10920
+ if (alias !== undefined) {
10921
+ luvioNode.alias = alias.value;
10922
+ }
10923
+ return luvioNode;
10924
+ }
10925
+
10926
+ function transform$7(node, transformState) {
10927
+ const { kind, name: { value }, directives, } = node;
10928
+ const luvioNode = {
10929
+ kind,
10930
+ name: value,
10931
+ };
10932
+ if (directives !== undefined && directives.length > 0) {
10933
+ luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10934
+ }
10935
+ return luvioNode;
10936
+ }
10937
+
10938
+ function transform$6(node, transformState) {
10939
+ const { kind: nodeKind, typeCondition, directives } = node;
10940
+ const luvioNode = {
10941
+ kind: nodeKind,
10942
+ luvioSelections: [],
10943
+ };
10944
+ if (typeCondition !== undefined) {
10945
+ luvioNode.typeCondition = {
10946
+ kind: typeCondition.kind,
10947
+ name: typeCondition.name.value,
10948
+ };
10949
+ }
10950
+ if (directives !== undefined && directives.length > 0) {
10951
+ luvioNode.directives = directives.map((directive) => transform$9(directive, transformState));
10952
+ }
10953
+ return luvioNode;
10954
+ }
10955
+
10956
+ function selectionSetVisitor(ast, luvioSelectionPath, transformState) {
10957
+ const visitor = {
10958
+ enter(node) {
10959
+ let selectionNode;
10960
+ switch (node.kind) {
10961
+ case NODE_KIND_FIELD: {
10962
+ const fieldNode = transform$8(node, transformState);
10963
+ selectionNode = fieldNode;
10964
+ break;
10965
+ }
10966
+ case NODE_KIND_FRAGMENT_SPREAD:
10967
+ selectionNode = transform$7(node, transformState);
10968
+ break;
10969
+ case NODE_KIND_INLINE_FRAGMENT:
10970
+ selectionNode = transform$6(node, transformState);
10971
+ break;
10972
+ }
10973
+ if (selectionNode !== undefined) {
10974
+ const parentNode = luvioSelectionPath[luvioSelectionPath.length - 1];
10975
+ if (parentNode.kind === NODE_KIND_OBJECT_FIELD_SELECTION ||
10976
+ parentNode.kind === NODE_KIND_CUSTOM_FIELD_SELECTION ||
10977
+ parentNode.kind === NODE_KIND_INLINE_FRAGMENT) {
10978
+ parentNode.luvioSelections.push(selectionNode);
10979
+ }
10980
+ luvioSelectionPath.push(selectionNode);
10981
+ }
10982
+ },
10983
+ leave(node) {
10984
+ switch (node.kind) {
10985
+ case NODE_KIND_FIELD:
10986
+ case NODE_KIND_FRAGMENT_SPREAD:
10987
+ case NODE_KIND_INLINE_FRAGMENT:
10988
+ luvioSelectionPath.pop();
10989
+ break;
10990
+ }
10991
+ },
10992
+ };
10993
+ visit(ast, visitor);
10994
+ }
10995
+
10996
+ function transform$5(node) {
10997
+ if (isNamedTypeNode(node)) {
10998
+ return {
10999
+ kind: NODE_KIND_NAMED_TYPE,
11000
+ name: node.name.value,
11001
+ };
11002
+ }
11003
+ else if (isListTypeNode(node)) {
11004
+ return {
11005
+ kind: NODE_KIND_LIST_TYPE,
11006
+ type: transform$5(node.type),
11007
+ };
11008
+ }
11009
+ else if (isNonNullTypeNode(node)) {
11010
+ if (isNamedTypeNode(node.type)) {
11011
+ return {
11012
+ kind: NODE_KIND_NON_NULL_TYPE,
11013
+ type: {
11014
+ kind: NODE_KIND_NAMED_TYPE,
11015
+ name: node.type.name.value,
11016
+ },
11017
+ };
11018
+ }
11019
+ else if (isListTypeNode(node.type)) {
11020
+ return {
11021
+ kind: NODE_KIND_NON_NULL_TYPE,
11022
+ type: {
11023
+ kind: NODE_KIND_LIST_TYPE,
11024
+ type: transform$5(node.type.type),
11025
+ },
11026
+ };
11027
+ }
11028
+ else {
11029
+ throw new Error('Unsupported NonNullTypeNode');
11030
+ }
11031
+ }
11032
+ else {
11033
+ throw new Error('Unsupported TypeNode');
11034
+ }
11035
+ }
11036
+
11037
+ function transform$4(variableDefinitions, transformState) {
11038
+ const { kind, variable: { kind: variableKind, name: { value: variableName }, }, type, defaultValue, } = variableDefinitions;
11039
+ const ret = {
11040
+ kind,
11041
+ variable: {
11042
+ kind: variableKind,
11043
+ name: variableName,
11044
+ },
11045
+ type: transform$5(type),
11046
+ };
11047
+ if (defaultValue !== undefined) {
11048
+ const value = transform$b(defaultValue, transformState);
11049
+ ret.defaultValue = value;
11050
+ }
11051
+ // TODO: transform directives
11052
+ return ret;
11053
+ }
11054
+
11055
+ function validateVariables(variableDefinitions, transformState) {
11056
+ if (process.env.NODE_ENV === 'production') {
11057
+ throw new ReferenceError("Do not call this function in production becuase we don't want to break existing uses. Other environments are okay because we want to catch errors early.");
11058
+ }
11059
+ const variablesDefined = {};
11060
+ if (variableDefinitions !== undefined) {
11061
+ for (let i = 0, len = variableDefinitions.length; i < len; i++) {
11062
+ const definedVariableName = variableDefinitions[i].variable.name.value;
11063
+ variablesDefined[definedVariableName] = true;
11064
+ if (transformState.variablesUsed[definedVariableName] === undefined) {
11065
+ throw new Error(`Variable $${definedVariableName} was defined but never used.`);
11066
+ }
11067
+ }
11068
+ }
11069
+ const usedVariableKeys = Object.keys(transformState.variablesUsed);
11070
+ for (let i = 0, len = usedVariableKeys.length; i < len; i++) {
11071
+ if (variablesDefined[usedVariableKeys[i]] !== true) {
11072
+ throw new Error(`Variable $${usedVariableKeys[i]} was used but never defined.`);
11073
+ }
11074
+ }
11075
+ }
11076
+ function transform$3(node) {
11077
+ const queryRoot = {
11078
+ kind: 'ObjectFieldSelection',
11079
+ name: 'query',
11080
+ luvioSelections: [],
11081
+ };
11082
+ const currentNodePath = [queryRoot];
11083
+ const transformState = {
11084
+ variablesUsed: {},
11085
+ };
11086
+ selectionSetVisitor(node, currentNodePath, transformState);
11087
+ const operationDefinition = {
11088
+ kind: 'OperationDefinition',
11089
+ operation: 'query',
11090
+ luvioSelections: queryRoot.luvioSelections,
11091
+ };
11092
+ if (node.name !== undefined) {
11093
+ operationDefinition.name = node.name.value;
11094
+ }
11095
+ const { variableDefinitions, directives } = node;
11096
+ if (variableDefinitions !== undefined && variableDefinitions.length > 0) {
11097
+ operationDefinition.variableDefinitions = variableDefinitions.map((variableDefinition) => transform$4(variableDefinition, transformState));
11098
+ }
11099
+ if (directives !== undefined && directives.length > 0) {
11100
+ operationDefinition.directives = directives.map((node) => transform$9(node, transformState));
11101
+ }
11102
+ if (process.env.NODE_ENV !== 'production') {
11103
+ validateVariables(variableDefinitions, transformState);
11104
+ }
11105
+ return operationDefinition;
11106
+ }
11107
+
11108
+ function transform$2(node) {
11109
+ const { operation } = node;
11110
+ if (operation === 'query') {
11111
+ return transform$3(node);
11112
+ }
11113
+ throw new Error(`Unsupported ${operation} operation. Only query operation is supported`);
11114
+ }
11115
+
11116
+ function transform$1(node) {
11117
+ const { kind: nodeKind, name: { value: nodeName }, typeCondition: { kind: typeKind, name: { value: typeName }, }, directives, } = node;
11118
+ // dummy root node
11119
+ const fragmentRoot = {
11120
+ kind: NODE_KIND_OBJECT_FIELD_SELECTION,
11121
+ name: 'fragment',
11122
+ luvioSelections: [],
11123
+ };
11124
+ const currentNodePath = [fragmentRoot];
11125
+ const transformState = { variablesUsed: {} };
11126
+ selectionSetVisitor(node, currentNodePath, transformState);
11127
+ const luvioNode = {
11128
+ kind: nodeKind,
11129
+ name: nodeName,
11130
+ typeCondition: {
11131
+ kind: typeKind,
11132
+ name: typeName,
11133
+ },
11134
+ luvioSelections: fragmentRoot.luvioSelections,
11135
+ };
11136
+ if (directives !== undefined && directives.length > 0) {
11137
+ luvioNode.directives = directives.map((node) => transform$9(node, transformState));
11138
+ }
11139
+ return luvioNode;
11140
+ }
11141
+
11142
+ function transform(root) {
11143
+ const { kind, definitions } = root;
11144
+ const luvioDefinitions = [];
11145
+ for (let i = 0; i < definitions.length; i++) {
11146
+ const definition = definitions[i];
11147
+ if (isOperationDefinitionNode(definition)) {
11148
+ luvioDefinitions.push(transform$2(definition));
11149
+ }
11150
+ else if (isFragmentDefinitionNode(definition)) {
11151
+ luvioDefinitions.push(transform$1(definition));
11152
+ }
11153
+ else {
11154
+ if (process.env.NODE_ENV !== 'production') {
11155
+ throw new Error(`Unsupported ${definition.kind} definition. Only OperationDefinition and FragmentDefinition are supported in a GraphQL Document`);
11156
+ }
11157
+ }
11158
+ }
11159
+ return {
11160
+ kind,
11161
+ definitions: luvioDefinitions,
11162
+ };
11163
+ }
11164
+
11165
+ /**
11166
+ * we should look into optimizing this before it turns into a memory hog
11167
+ * weakmaps, or limiting the size of the cache, or something
11168
+ */
11169
+ const docMap = new Map();
11170
+ /**
11171
+ * Opaque reference map to return keys to userland
11172
+ * As a user shouldn't have access to the Document
11173
+ */
11174
+ const referenceMap = new WeakMap();
11175
+ /**
11176
+ * Strips characters that are not significant to the validity or execution
11177
+ * of a GraphQL document:
11178
+ * - UnicodeBOM
11179
+ * - WhiteSpace
11180
+ * - LineTerminator
11181
+ * - Comment
11182
+ * - Comma
11183
+ * - BlockString indentation
11184
+ */
11185
+ function operationKeyBuilder(inputString) {
11186
+ return stripIgnoredCharacters(inputString);
11187
+ }
11188
+ /**
11189
+ * Returns document node if cached or else update the cache and return the document node
11190
+ * @param inputString - operation string
11191
+ * @returns DocumentNode
11192
+ */
11193
+ function parseDocument(inputString) {
11194
+ const operationKey = operationKeyBuilder(inputString);
11195
+ const cachedDoc = docMap.get(operationKey);
11196
+ if (cachedDoc !== undefined) {
11197
+ return cachedDoc;
11198
+ }
11199
+ // parse throws an GraphQLError in case of invalid query, should this be in try/catch?
11200
+ const parsedDoc = parse(inputString, { noLocation: true });
11201
+ if (!parsedDoc || parsedDoc.kind !== 'Document') {
11202
+ if (process.env.NODE_ENV !== 'production') {
11203
+ throw new Error('Invalid graphql doc');
11204
+ }
11205
+ return null;
11206
+ }
11207
+ docMap.set(operationKey, parsedDoc);
11208
+ return parsedDoc;
11209
+ }
11210
+ /**
11211
+ * If the input string has fragment substitution
11212
+ * Insert the fragments AST to the query document node
11213
+ */
11214
+ function insertFragments(doc, fragments) {
11215
+ fragments.forEach((fragment) => {
11216
+ // @ts-ignore
11217
+ // graphql describes definitions as "readonly"
11218
+ // so we aren't supposed to mutate the document node
11219
+ // but instead of parsing the fragment again, we substitute it's definition in the document node
11220
+ doc.definitions.push(fragment);
11221
+ });
11222
+ return doc;
11223
+ }
11224
+ function updateReferenceMapWithKnownKey(doc, key) {
11225
+ referenceMap.set(key, doc);
11226
+ }
11227
+ function updateReferenceMapAndGetKey(doc) {
11228
+ // the key is a String object so that legacy locker does not replace its identity.
11229
+ const key = new String();
11230
+ updateReferenceMapWithKnownKey(doc, key);
11231
+ return key;
11232
+ }
11233
+ /**
11234
+ * Insert string and fragment substitutions with the actual nodes
11235
+ * @param inputString
11236
+ * @param substitutions - string | fragment DocumentNode
11237
+ * @returns { operation string, fragment docs [] }
11238
+ */
11239
+ function processSubstitutions(inputString, substitutions) {
11240
+ let outputString = '';
11241
+ const fragments = [];
11242
+ const subLength = substitutions.length;
11243
+ for (let i = 0; i < subLength; i++) {
11244
+ const substitution = substitutions[i];
11245
+ outputString += inputString[i];
11246
+ if (typeof substitution === 'string' || typeof substitution === 'number') {
11247
+ outputString += substitution;
11248
+ }
11249
+ else if (typeof substitution === 'object') {
11250
+ const doc = referenceMap.get(substitution);
11251
+ if (doc === undefined) {
11252
+ if (process.env.NODE_ENV !== 'production') {
11253
+ throw new Error('Invalid substitution fragment');
11254
+ }
11255
+ return null;
11256
+ }
11257
+ for (const def of doc.definitions) {
11258
+ fragments.push(def);
11259
+ }
11260
+ }
11261
+ else {
11262
+ if (process.env.NODE_ENV !== 'production') {
11263
+ throw new Error('Unsupported substitution type');
11264
+ }
11265
+ return null;
11266
+ }
11267
+ }
11268
+ return {
11269
+ operationString: outputString + inputString[subLength],
11270
+ fragments,
11271
+ };
11272
+ }
11273
+ /**
11274
+ *
11275
+ * @param astReference - ast reference passed from user land
11276
+ */
11277
+ const astResolver = function (astReference) {
11278
+ return referenceMap.get(astReference);
11279
+ };
11280
+ /**
11281
+ *
11282
+ * @param literals - operation query string
11283
+ * @param subs - all other substitutions
11284
+ * @returns an opaque reference to the parsed document
11285
+ */
11286
+ function gql(literals, ...subs) {
11287
+ let inputString;
11288
+ let inputSubstitutionFragments;
11289
+ if (!literals) {
11290
+ if (process.env.NODE_ENV !== 'production') {
11291
+ throw new Error('Invalid query');
11292
+ }
11293
+ return null;
11294
+ }
11295
+ else if (typeof literals === 'string') {
11296
+ inputString = literals.trim();
11297
+ inputSubstitutionFragments = [];
11298
+ }
11299
+ else {
11300
+ // called as template literal
11301
+ const sub = processSubstitutions(literals, subs);
11302
+ // if invalid fragment references found
11303
+ if (sub === null) {
11304
+ return null;
11305
+ }
11306
+ const { operationString, fragments } = sub;
11307
+ inputString = operationString.trim();
11308
+ inputSubstitutionFragments = fragments;
11309
+ }
11310
+ if (inputString.length === 0) {
11311
+ if (process.env.NODE_ENV !== 'production') {
11312
+ throw new Error('Invalid query');
11313
+ }
11314
+ return null;
11315
+ }
11316
+ const document = parseDocument(inputString);
11317
+ if (document === null) {
11318
+ return null;
11319
+ }
11320
+ if (inputSubstitutionFragments.length === 0) {
11321
+ return updateReferenceMapAndGetKey(document);
11322
+ }
11323
+ return updateReferenceMapAndGetKey(insertFragments(document, inputSubstitutionFragments));
11324
+ }
11325
+
11326
+ const DIRECTIVE_RECORD_QUERY_CATEGORY = {
11327
+ kind: 'Directive',
11328
+ name: {
11329
+ kind: 'Name',
11330
+ value: 'category',
11331
+ },
11332
+ arguments: [
11333
+ {
11334
+ kind: 'Argument',
11335
+ name: {
11336
+ kind: 'Name',
11337
+ value: 'name',
11338
+ },
11339
+ value: {
11340
+ kind: 'StringValue',
11341
+ value: 'recordQuery',
11342
+ block: false,
11343
+ },
11344
+ },
11345
+ ],
11346
+ };
11347
+ const DIRECTIVE_CHILD_RELATIONSHIP_CATEGORY = {
11348
+ kind: 'Directive',
11349
+ name: {
11350
+ kind: 'Name',
11351
+ value: 'category',
11352
+ },
11353
+ arguments: [
11354
+ {
11355
+ kind: 'Argument',
11356
+ name: {
11357
+ kind: 'Name',
11358
+ value: 'name',
11359
+ },
11360
+ value: {
11361
+ kind: 'StringValue',
11362
+ value: 'childRelationship',
11363
+ block: false,
11364
+ },
11365
+ },
11366
+ ],
11367
+ };
11368
+ const DIRECTIVE_PARENT_CATEGORY = {
11369
+ kind: 'Directive',
11370
+ name: {
11371
+ kind: 'Name',
11372
+ value: 'category',
11373
+ },
11374
+ arguments: [
11375
+ {
11376
+ kind: 'Argument',
11377
+ name: {
11378
+ kind: 'Name',
11379
+ value: 'name',
11380
+ },
11381
+ value: {
11382
+ kind: 'StringValue',
11383
+ value: 'parentRelationship',
11384
+ block: false,
11385
+ },
11386
+ },
11387
+ ],
11388
+ };
11389
+ function substituteDirectives(directives, index, selection, parentNode) {
11390
+ if (directives[index].name.value === CUSTOM_DIRECTIVE_CONNECTION) {
11391
+ if (parentNode !== undefined &&
11392
+ parentNode.kind === 'Field' &&
11393
+ parentNode.name.value === 'uiapi') {
11394
+ // @ts-ignore - Document is read only
11395
+ directives[index] = DIRECTIVE_RECORD_QUERY_CATEGORY;
11396
+ }
11397
+ else {
11398
+ // @ts-ignore - Document is read only
11399
+ directives[index] = DIRECTIVE_CHILD_RELATIONSHIP_CATEGORY;
11400
+ }
11401
+ }
11402
+ else if (directives[index].name.value === CUSTOM_DIRECTIVE_RESOURCE) {
11403
+ // node gets its type from @category recordQuery or @category childRelationship
11404
+ if (selection.kind === 'Field' && selection.name.value === 'node') {
11405
+ // @ts-ignore - Document is read only
11406
+ directives.splice(index, 1);
11407
+ }
11408
+ else {
11409
+ // @ts-ignore - Document is read only
11410
+ directives[index] = DIRECTIVE_PARENT_CATEGORY;
11411
+ }
11412
+ }
11413
+ }
11414
+ /**
11415
+ * Returns true if the directive node is of legacy type
11416
+ * @param node : Directive node
11417
+ * @returns
11418
+ */
11419
+ function isCustomDirective(node) {
11420
+ return (node.name.value === CUSTOM_DIRECTIVE_CONNECTION ||
11421
+ node.name.value === CUSTOM_DIRECTIVE_RESOURCE);
11422
+ }
11423
+ /**
11424
+ * Traverses a selection and it's nested selections,
11425
+ * to find any legacy custom directives and substitute them with metaschema directives
11426
+ * @param node - SelectionNode
11427
+ * @returns void
11428
+ */
11429
+ function traverseSelection(node, parentNode) {
11430
+ if (node === undefined || node.kind === 'FragmentSpread' || node.selectionSet === undefined) {
11431
+ return;
11432
+ }
11433
+ const { selectionSet } = node;
11434
+ for (const selection of selectionSet.selections) {
11435
+ replaceCustomDirectives(selection, parentNode);
11436
+ traverseSelection(selection, node);
11437
+ }
11438
+ }
11439
+ function replaceCustomDirectives(selection, parentNode) {
11440
+ const { directives } = selection;
11441
+ if (directives !== undefined && directives.length > 0) {
11442
+ // we follow this pattern instead of map to preserve the order of directives
11443
+ // order of directives may be significant as per graphql spec
11444
+ const index = directives.findIndex(isCustomDirective);
11445
+ if (index !== -1) {
11446
+ substituteDirectives(directives, index, selection, parentNode);
11447
+ }
11448
+ }
11449
+ }
11450
+ /**
11451
+ * Accepts a document node and replaces the legacy custom directives with metaschema directives "in-place"
11452
+ * @param doc
11453
+ */
11454
+ function metaschemaMapper(doc) {
11455
+ // this method is only callable for Executable definitions
11456
+ // such as Operations and Fragments
11457
+ // so we have to explicitly cast the definitions for ts
11458
+ const { definitions } = doc;
11459
+ for (const def of definitions) {
11460
+ const { selectionSet } = def;
11461
+ // This is just iterating through the top level 'Query' operations. There should never be any custom
11462
+ // directives at this level, as RecordQuery is actually a field lower in the schema. So we can skip looking for them.
11463
+ selectionSet.selections.forEach((selection) => {
11464
+ traverseSelection(selection);
11465
+ });
11466
+ }
11467
+ }
11468
+
11469
+ /**
11470
+ * @deprecated In favor of gql tagged template literal
11471
+ */
11472
+ function parseAndVisit(source) {
11473
+ const ast = parse(source, { noLocation: true });
11474
+ const luvioDocumentNode = transform(ast);
11475
+ // In-place substitution of metaschema annotations
11476
+ metaschemaMapper(ast);
11477
+ // Set the AST reference map with LuvioDocumentNode as the key
11478
+ // ASTResolver will resolve it to metaschema mapped AST
11479
+ updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
11480
+ return luvioDocumentNode;
11481
11481
  }
11482
11482
 
11483
11483
  export { Kind, astResolver, buildSchema, defaultFieldResolver, execute, gql, isObjectType, parse, parseAndVisit, print, visit };
11484
- // version: 1.127.0-48f9732df
11484
+ // version: 1.128.1-55cd38df6