@xyd-js/gql 0.1.0-xyd.6 → 0.1.0-xyd.66

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.
Files changed (89) hide show
  1. package/CHANGELOG.md +561 -0
  2. package/LICENSE +21 -0
  3. package/TODO.md +8 -0
  4. package/__fixtures__/-1.opendocs.docs-nested/input.graphql +66 -0
  5. package/__fixtures__/-1.opendocs.docs-nested/output.json +554 -0
  6. package/__fixtures__/-1.opendocs.flat/input.graphql +19 -0
  7. package/__fixtures__/-1.opendocs.flat/output.json +243 -0
  8. package/__fixtures__/-1.opendocs.scopes/input.graphql +33 -0
  9. package/__fixtures__/-1.opendocs.scopes/output.json +378 -0
  10. package/__fixtures__/-1.opendocs.sidebar/input.graphql +44 -0
  11. package/__fixtures__/-1.opendocs.sort/input.graphql +92 -0
  12. package/__fixtures__/-1.opendocs.sort/output.json +1078 -0
  13. package/__fixtures__/-1.opendocs.sort+group/input.graphql +111 -0
  14. package/__fixtures__/-1.opendocs.sort+group/output.json +1114 -0
  15. package/__fixtures__/-1.opendocs.sort+group+path/input.graphql +118 -0
  16. package/__fixtures__/-1.opendocs.sort+group+path/output.json +1114 -0
  17. package/__fixtures__/-2.complex.github/input.graphql +69424 -0
  18. package/__fixtures__/-2.complex.github/output.json +269874 -0
  19. package/__fixtures__/-2.complex.livesession/input.graphql +23 -0
  20. package/__fixtures__/-2.complex.livesession/output.json +302 -0
  21. package/__fixtures__/-2.complex.monday/input.graphql +6089 -0
  22. package/__fixtures__/-2.complex.monday/output.json +1 -0
  23. package/__fixtures__/-3.array-non-null-return/input.graphql +9 -0
  24. package/__fixtures__/-3.array-non-null-return/output.json +151 -0
  25. package/__fixtures__/1.basic/input.graphql +118 -0
  26. package/__fixtures__/1.basic/output.json +630 -0
  27. package/__fixtures__/2.circular/input.graphql +17 -0
  28. package/__fixtures__/2.circular/output.json +248 -0
  29. package/__fixtures__/3.opendocs/input.graphql +27 -0
  30. package/__fixtures__/3.opendocs/output.json +338 -0
  31. package/__fixtures__/4.union/input.graphql +19 -0
  32. package/__fixtures__/4.union/output.json +344 -0
  33. package/__fixtures__/5.flat/input.graphql +27 -0
  34. package/__fixtures__/5.flat/output.json +383 -0
  35. package/__fixtures__/6.default-values/input.graphql +47 -0
  36. package/__fixtures__/6.default-values/output.json +655 -0
  37. package/__fixtures__/7.type-args/input.graphql +19 -0
  38. package/__fixtures__/7.type-args/output.json +301 -0
  39. package/__fixtures__/8.default-sort/input.graphql +60 -0
  40. package/__fixtures__/8.default-sort/output.json +1078 -0
  41. package/__tests__/gqlSchemaToReferences.test.ts +109 -0
  42. package/__tests__/utils.ts +45 -0
  43. package/declarations.d.ts +4 -0
  44. package/dist/index.d.ts +17 -1
  45. package/dist/index.js +1334 -19871
  46. package/dist/index.js.map +1 -1
  47. package/dist/opendocs.graphql +56 -0
  48. package/package.json +7 -9
  49. package/src/context.ts +17 -0
  50. package/src/converters/gql-arg.ts +51 -0
  51. package/src/converters/gql-enum.ts +27 -0
  52. package/src/converters/gql-field.ts +164 -0
  53. package/src/converters/gql-input.ts +34 -0
  54. package/src/converters/gql-interface.ts +35 -0
  55. package/src/converters/gql-mutation.ts +36 -0
  56. package/src/converters/gql-object.ts +83 -0
  57. package/src/converters/gql-operation.ts +128 -0
  58. package/src/converters/gql-query.ts +36 -0
  59. package/src/converters/gql-sample.ts +159 -0
  60. package/src/converters/gql-scalar.ts +16 -0
  61. package/src/converters/gql-subscription.ts +36 -0
  62. package/src/converters/gql-types.ts +195 -0
  63. package/src/converters/gql-union.ts +40 -0
  64. package/src/gql-core.ts +362 -0
  65. package/src/opendocs.graphql +56 -0
  66. package/src/opendocs.ts +253 -0
  67. package/src/schema.ts +253 -67
  68. package/src/types.ts +103 -0
  69. package/src/utils.ts +21 -96
  70. package/tsconfig.json +1 -1
  71. package/tsup.config.ts +15 -1
  72. package/vitest.config.ts +15 -1
  73. package/examples/basic/index.ts +0 -12
  74. package/examples/basic/schema.graphqls +0 -89
  75. package/examples/basic/todo-app.graphqls +0 -184
  76. package/examples/graphql-types/graphql-types.0.basic.graphqls +0 -28
  77. package/examples/nested/nested-arg.0.not-required.graphqls +0 -8
  78. package/examples/nested/nested-arg.0.required.graphqls +0 -8
  79. package/examples/nested/nested-arg.1.deep.graphqls +0 -12
  80. package/src/hydration/README.md +0 -1
  81. package/src/hydration/gql-arg.ts +0 -53
  82. package/src/hydration/gql-field.ts +0 -206
  83. package/src/hydration/gql-input.ts +0 -67
  84. package/src/hydration/gql-object.ts +0 -35
  85. package/src/hydration/gql-types.ts +0 -50
  86. package/src/samples/index.ts +0 -95
  87. package/test/graphql-types.0.test.ts +0 -125
  88. package/test/nested-arg.0.test.ts +0 -208
  89. package/test/nested-arg.1.test.ts +0 -19
@@ -0,0 +1,36 @@
1
+ import type {GraphQLSchema} from "graphql";
2
+ import {OperationTypeNode} from "graphql";
3
+
4
+ import {Reference, ReferenceType} from "@xyd-js/uniform";
5
+
6
+ import type {GQLSchemaToReferencesOptions} from "../types";
7
+ import {filterFieldsByRegions} from "../utils";
8
+ import {gqlOperationToUniformRef} from "./gql-operation";
9
+
10
+ export function graphqlQueriesToUniformReferences(
11
+ schema: GraphQLSchema,
12
+ options?: GQLSchemaToReferencesOptions,
13
+ ): Reference[] {
14
+ const references: Reference[] = []
15
+
16
+ const queries = schema.getRootType(OperationTypeNode.QUERY)
17
+ const queryFields = queries?.getFields?.()
18
+
19
+ if (queryFields) {
20
+ // Filter query fields based on regions if provided
21
+ const filteredQueryFields = filterFieldsByRegions(
22
+ queryFields,
23
+ "query",
24
+ options?.regions
25
+ );
26
+
27
+ references.push(...gqlOperationToUniformRef(
28
+ ReferenceType.GRAPHQL_QUERY,
29
+ filteredQueryFields,
30
+ schema,
31
+ options
32
+ ))
33
+ }
34
+
35
+ return references;
36
+ }
@@ -0,0 +1,159 @@
1
+ import {
2
+ Kind,
3
+ print,
4
+ OperationTypeNode,
5
+ ASTNode,
6
+ ArgumentNode,
7
+ TypeNode,
8
+ ValueNode,
9
+ VariableDefinitionNode,
10
+ } from 'graphql';
11
+
12
+ import {
13
+ DefinitionProperty,
14
+ ReferenceType
15
+ } from "@xyd-js/uniform";
16
+
17
+ const operationTypeToTypeNode = {
18
+ [ReferenceType.GRAPHQL_QUERY]: OperationTypeNode.QUERY,
19
+ [ReferenceType.GRAPHQL_MUTATION]: OperationTypeNode.MUTATION,
20
+ [ReferenceType.GRAPHQL_SUBSCRIPTION]: OperationTypeNode.SUBSCRIPTION,
21
+ }
22
+
23
+ // simpleGraphqlExample is a helper function to create a simple GraphQL example query or mutation.
24
+ export function simpleGraphqlExample(
25
+ operationType: ReferenceType.GRAPHQL_QUERY | ReferenceType.GRAPHQL_MUTATION | ReferenceType.GRAPHQL_SUBSCRIPTION,
26
+ operationName: string,
27
+ args: DefinitionProperty[],
28
+ returns: DefinitionProperty[],
29
+ ) {
30
+ // Filter required arguments or take first one if no required args
31
+ const requiredArgs = args.filter(arg => arg.meta?.some(m => m.name === 'required' && m.value === 'true'));
32
+ const selectedArgs = requiredArgs.length > 0 ? requiredArgs : args.slice(0, 1);
33
+
34
+ let hasArgVars = false
35
+
36
+ const argDefaults = selectedArgs.reduce<Record<string, ArgumentNode>>((acc, arg) => {
37
+ if (operationType != ReferenceType.GRAPHQL_QUERY) {
38
+ return acc; // Skip for mutations, as we use variables
39
+ }
40
+
41
+ let defaultValue: string = ""
42
+
43
+ const getDefaultValue = arg.meta?.find(m => m.name === 'defaults')?.value
44
+ if (getDefaultValue && typeof getDefaultValue !== 'string') {
45
+ defaultValue = JSON.stringify(getDefaultValue)
46
+ }
47
+
48
+ let sampleValue: ValueNode | undefined = undefined;
49
+
50
+ switch (arg.context?.graphqlTypeFlat) {
51
+ case 'String':
52
+ sampleValue = {kind: Kind.STRING, value: defaultValue || `example-${arg.name}`};
53
+ break;
54
+ case 'Int':
55
+ case 'Float':
56
+ sampleValue = {kind: Kind.INT, value: defaultValue || '0'};
57
+ break;
58
+ case 'Boolean':
59
+ sampleValue = {kind: Kind.BOOLEAN, value: defaultValue === 'true'};
60
+ break;
61
+ }
62
+
63
+ // For queries, use direct values; for mutations, use variables
64
+ if (sampleValue) {
65
+ return {
66
+ ...acc,
67
+ [arg.name]: {
68
+ kind: Kind.ARGUMENT,
69
+ name: {kind: Kind.NAME, value: arg.name},
70
+ value: sampleValue
71
+ }
72
+ };
73
+ }
74
+
75
+ return acc;
76
+ }, {});
77
+
78
+ const allDefaultArgs = Object.keys(argDefaults).length === selectedArgs.length
79
+
80
+ const argumentsList: ArgumentNode[] = selectedArgs.map(arg => {
81
+ if (allDefaultArgs) {
82
+ return argDefaults[arg.name]
83
+ }
84
+
85
+ hasArgVars = true
86
+
87
+ return {
88
+ kind: Kind.ARGUMENT,
89
+ name: {kind: Kind.NAME, value: arg.name},
90
+ value: {
91
+ kind: Kind.VARIABLE,
92
+ name: {kind: Kind.NAME, value: arg.name}
93
+ }
94
+ };
95
+ });
96
+
97
+ const queryAST: ASTNode = {
98
+ kind: Kind.DOCUMENT,
99
+ definitions: [
100
+ {
101
+ kind: Kind.OPERATION_DEFINITION,
102
+ operation: operationTypeToTypeNode[operationType],
103
+ name: hasArgVars ? {
104
+ kind: Kind.NAME,
105
+ value: operationName
106
+ } : undefined,
107
+ variableDefinitions: hasArgVars ? selectedArgs.map(variableDefinitions) : [],
108
+ selectionSet: {
109
+ kind: Kind.SELECTION_SET,
110
+ selections: [
111
+ {
112
+ kind: Kind.FIELD,
113
+ name: {kind: Kind.NAME, value: operationName},
114
+ arguments: argumentsList,
115
+ selectionSet: {
116
+ kind: Kind.SELECTION_SET,
117
+ selections: [
118
+ {kind: Kind.FIELD, name: {kind: Kind.NAME, value: `# ${operationName} fields`}}
119
+ ]
120
+ }
121
+ }
122
+ ]
123
+ }
124
+ }
125
+ ]
126
+ } as const;
127
+
128
+ const sampleText = print(queryAST);
129
+
130
+ return sampleText;
131
+ }
132
+
133
+ function variableDefinitions(arg: DefinitionProperty): VariableDefinitionNode {
134
+ const hasDefault = arg.meta?.some(m => m.name === 'defaults');
135
+ let defaultValue: string = ""
136
+
137
+ const getDefaultValue = arg.meta?.find(m => m.name === 'defaults')?.value
138
+ if (getDefaultValue && typeof getDefaultValue !== 'string') {
139
+ defaultValue = JSON.stringify(getDefaultValue)
140
+ }
141
+
142
+ return {
143
+ kind: Kind.VARIABLE_DEFINITION,
144
+ variable: {
145
+ kind: Kind.VARIABLE,
146
+ name: {kind: Kind.NAME, value: arg.name}
147
+ },
148
+ type: {
149
+ kind: Kind.NAMED_TYPE,
150
+ name: {kind: Kind.NAME, value: arg.type}
151
+ },
152
+ ...(hasDefault && defaultValue ? {
153
+ defaultValue: {
154
+ kind: Kind.STRING,
155
+ value: defaultValue
156
+ }
157
+ } : {})
158
+ };
159
+ }
@@ -0,0 +1,16 @@
1
+ import {GraphQLScalarType} from "@graphql-markdown/types";
2
+
3
+ import type {Reference} from "@xyd-js/uniform";
4
+
5
+ import {uniformify} from "../gql-core";
6
+ import {Context} from "../context";
7
+
8
+ // gqlScalarToUniformRef is a helper function to convert a GraphQL scalar type into a 'uniform' reference.
9
+ export function gqlScalarToUniformRef(ctx: Context, gqlType: GraphQLScalarType): Reference {
10
+ return uniformify(
11
+ ctx,
12
+ gqlType,
13
+ [],
14
+ []
15
+ )
16
+ }
@@ -0,0 +1,36 @@
1
+ import type {GraphQLSchema} from "graphql";
2
+ import {OperationTypeNode} from "graphql";
3
+
4
+ import {Reference, ReferenceType} from "@xyd-js/uniform";
5
+
6
+ import type {GQLSchemaToReferencesOptions} from "../types";
7
+ import {filterFieldsByRegions} from "../utils";
8
+ import {gqlOperationToUniformRef} from "./gql-operation";
9
+
10
+ export function graphqlSubscriptionsToUniformReferences(
11
+ schema: GraphQLSchema,
12
+ options?: GQLSchemaToReferencesOptions,
13
+ ) {
14
+ const references: Reference[] = []
15
+
16
+ const mutations = schema.getRootType(OperationTypeNode.SUBSCRIPTION)
17
+ const mutationFields = mutations?.getFields?.()
18
+
19
+ if (mutationFields) {
20
+ // Filter mutation fields based on regions if provided
21
+ const filteredMutationFields = filterFieldsByRegions(
22
+ mutationFields,
23
+ "mutation",
24
+ options?.regions
25
+ );
26
+
27
+ references.push(...gqlOperationToUniformRef(
28
+ ReferenceType.GRAPHQL_SUBSCRIPTION,
29
+ filteredMutationFields,
30
+ schema,
31
+ options,
32
+ ))
33
+ }
34
+
35
+ return references;
36
+ }
@@ -0,0 +1,195 @@
1
+ import type {
2
+ GraphQLEnumType,
3
+ GraphQLInputObjectType,
4
+ GraphQLInterfaceType,
5
+ GraphQLObjectType,
6
+ GraphQLScalarType,
7
+ GraphQLSchema,
8
+ GraphQLUnionType,
9
+ GraphQLNamedType,
10
+ } from "graphql";
11
+ import {
12
+ isIntrospectionType,
13
+ isSpecifiedScalarType
14
+ } from "graphql";
15
+
16
+ import {Reference} from "@xyd-js/uniform";
17
+
18
+ import {GQLSchemaToReferencesOptions, NestedGraphqlType} from "../types";
19
+ import {gqlObjectToUniformRef} from "./gql-object";
20
+ import {gqlInputToUniformRef} from "./gql-input";
21
+ import {gqlEnumToUniformRef} from "./gql-enum";
22
+ import {gqlScalarToUniformRef} from "./gql-scalar";
23
+ import {gqlUnionToUniformRef} from "./gql-union";
24
+ import {gqlInterfaceToUniformRef} from "./gql-interface";
25
+ import {Context} from "../context";
26
+
27
+ // TODO: missing types like interfaces, fragments.
28
+ export function graphqlTypesToUniformReferences(
29
+ schema: GraphQLSchema,
30
+ options?: GQLSchemaToReferencesOptions,
31
+ ): Reference[] {
32
+ const references: Reference[] = []
33
+ const typeMap = schema.getTypeMap();
34
+
35
+ const sharedProcessedTypes = new Set<NestedGraphqlType>();
36
+
37
+ for (const gqlType of Object.values(typeMap)) {
38
+ const builtInType = isSpecifiedScalarType(gqlType) ||
39
+ isIntrospectionType(gqlType) ||
40
+ gqlType.name === "Mutation" ||
41
+ gqlType.name === "Query" ||
42
+ gqlType.name === "Subscription" ||
43
+ isInternalOpenDocsType(gqlType)
44
+
45
+ if (builtInType) {
46
+ continue;
47
+ }
48
+
49
+ let ref: Reference | null = null
50
+
51
+ let flat = false;
52
+ if (options?.flat) {
53
+ flat = true;
54
+ }
55
+
56
+ switch (gqlType.constructor.name) {
57
+ case 'GraphQLObjectType': {
58
+ const type = gqlType as GraphQLObjectType;
59
+ const regionKey = `object.${type.name}`;
60
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
61
+
62
+ ref = gqlObjectToUniformRef(
63
+ new Context(
64
+ sharedProcessedTypes,
65
+ options,
66
+ {
67
+ flat,
68
+ },
69
+ schema
70
+ ),
71
+ type,
72
+
73
+ )
74
+ }
75
+ break
76
+ }
77
+
78
+ case 'GraphQLInputObjectType': {
79
+ const type = gqlType as GraphQLInputObjectType;
80
+ const regionKey = `input.${type.name}`;
81
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
82
+ ref = gqlInputToUniformRef(
83
+ new Context(
84
+ sharedProcessedTypes,
85
+ options,
86
+ {
87
+ flat,
88
+ },
89
+ schema
90
+ ),
91
+ type
92
+ )
93
+ }
94
+ break
95
+ }
96
+
97
+ case 'GraphQLEnumType': {
98
+ const type = gqlType as GraphQLEnumType;
99
+ const regionKey = `enum.${type.name}`;
100
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
101
+ ref = gqlEnumToUniformRef(
102
+ new Context(
103
+ new Set(),
104
+ options,
105
+ {},
106
+ schema
107
+ ),
108
+ type
109
+ )
110
+ }
111
+ break
112
+ }
113
+
114
+ case 'GraphQLScalarType': {
115
+ const type = gqlType as GraphQLScalarType;
116
+ const regionKey = `scalar.${type.name}`;
117
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
118
+ ref = gqlScalarToUniformRef(
119
+ new Context(
120
+ new Set(),
121
+ options,
122
+ {},
123
+ schema
124
+ ),
125
+ type
126
+ )
127
+ }
128
+ break
129
+ }
130
+
131
+ case 'GraphQLUnionType': {
132
+ const type = gqlType as GraphQLUnionType;
133
+ const regionKey = `union.${type.name}`;
134
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
135
+ ref = gqlUnionToUniformRef(
136
+ new Context(
137
+ sharedProcessedTypes,
138
+ options,
139
+ {
140
+ flat,
141
+ flatArg: flat || false
142
+ },
143
+ schema
144
+ ),
145
+ type,
146
+ )
147
+ }
148
+
149
+ break
150
+ }
151
+
152
+ case 'GraphQLInterfaceType': {
153
+ const type = gqlType as GraphQLInterfaceType;
154
+ const regionKey = `interface.${type.name}`;
155
+ if (!options?.regions || !options?.regions?.length || options.regions.includes(regionKey)) {
156
+ ref = gqlInterfaceToUniformRef(
157
+ new Context(
158
+ new Set(),
159
+ options,
160
+ {
161
+ flat
162
+ },
163
+ schema
164
+ ),
165
+ type,
166
+ )
167
+ }
168
+ break
169
+ }
170
+
171
+ default: {
172
+ console.debug(`Unsupported type: ${gqlType.constructor.name}`)
173
+ }
174
+ }
175
+
176
+ if (ref) {
177
+ references.push(ref);
178
+ }
179
+ }
180
+
181
+ return references;
182
+ }
183
+
184
+ function isInternalOpenDocsType(type: GraphQLNamedType): boolean {
185
+ const internalTypes = [
186
+ 'OpenDocsScope',
187
+ 'OpenDocsSidebarItemType',
188
+ 'OpenDocsPage',
189
+ 'OpenDocsExampleInput',
190
+ 'OpenDocsSortInput',
191
+ 'OpenDocsSortStackInput'
192
+
193
+ ]
194
+ return internalTypes.includes(type.name)
195
+ }
@@ -0,0 +1,40 @@
1
+ import {GraphQLUnionType} from "graphql";
2
+
3
+ import {Definition, DefinitionProperty, Reference} from "@xyd-js/uniform";
4
+
5
+ import {gqlObjectToUniformDefinitionProperty} from "./gql-object";
6
+ import {uniformify} from "../gql-core";
7
+ import {Context} from "../context";
8
+
9
+ export function gqlUnionToUniformRef(ctx: Context, unionType: GraphQLUnionType): Reference {
10
+ const properties = gqlUnionToUniformDefinitionProperties(ctx, unionType)
11
+
12
+ const definitions: Definition[] = [
13
+ {
14
+ title: "Possible types",
15
+ properties,
16
+ }
17
+ ]
18
+
19
+ return uniformify(
20
+ ctx,
21
+ unionType,
22
+ definitions,
23
+ []
24
+ )
25
+ }
26
+
27
+ export function gqlUnionToUniformDefinitionProperties(
28
+ ctx: Context,
29
+ unionType: GraphQLUnionType
30
+ ): DefinitionProperty[] {
31
+ return unionType.getTypes().map(type => {
32
+ if (type.constructor.name === "GraphQLObjectType") {
33
+ return gqlObjectToUniformDefinitionProperty(
34
+ ctx,
35
+ type,
36
+ )
37
+ }
38
+ return []
39
+ }).flat()
40
+ }