@luvio/graphql-parser 0.138.1 → 0.138.3

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