@constructive-io/graphql-codegen 3.0.4 → 3.1.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.
- package/README.md +4 -0
- package/cli/index.js +4 -1
- package/cli/shared.d.ts +1 -0
- package/cli/shared.js +8 -0
- package/core/codegen/client.d.ts +11 -1
- package/core/codegen/client.js +63 -248
- package/core/codegen/index.js +3 -1
- package/core/codegen/orm/client-generator.d.ts +5 -2
- package/core/codegen/orm/client-generator.js +28 -289
- package/core/codegen/templates/client.browser.ts +265 -0
- package/core/codegen/templates/client.node.ts +350 -0
- package/core/codegen/templates/orm-client.ts +158 -0
- package/core/codegen/templates/select-types.ts +116 -0
- package/core/introspect/fetch-schema.js +10 -3
- package/esm/cli/index.js +4 -1
- package/esm/cli/shared.d.ts +1 -0
- package/esm/cli/shared.js +8 -0
- package/esm/core/codegen/client.d.ts +11 -1
- package/esm/core/codegen/client.js +31 -249
- package/esm/core/codegen/index.js +3 -1
- package/esm/core/codegen/orm/client-generator.d.ts +5 -2
- package/esm/core/codegen/orm/client-generator.js +28 -289
- package/esm/core/introspect/fetch-schema.js +10 -3
- package/esm/types/config.d.ts +8 -0
- package/esm/types/config.js +1 -0
- package/package.json +5 -5
- package/types/config.d.ts +8 -0
- package/types/config.js +1 -0
- package/core/codegen/orm/query-builder.d.ts +0 -85
- package/core/codegen/orm/query-builder.js +0 -485
- package/esm/core/codegen/orm/query-builder.d.ts +0 -85
- package/esm/core/codegen/orm/query-builder.js +0 -441
- /package/core/codegen/{orm → templates}/query-builder.ts +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Fetch GraphQL schema introspection from an endpoint
|
|
3
3
|
*/
|
|
4
4
|
import dns from 'node:dns';
|
|
5
|
-
import { Agent } from 'undici';
|
|
5
|
+
import { Agent, fetch } from 'undici';
|
|
6
6
|
import { SCHEMA_INTROSPECTION_QUERY } from './schema-query';
|
|
7
7
|
/**
|
|
8
8
|
* Check if a hostname is localhost or a localhost subdomain
|
|
@@ -20,7 +20,14 @@ function createLocalhostAgent() {
|
|
|
20
20
|
connect: {
|
|
21
21
|
lookup(hostname, opts, cb) {
|
|
22
22
|
if (isLocalhostHostname(hostname)) {
|
|
23
|
-
|
|
23
|
+
// When opts.all is true, callback expects an array of {address, family} objects
|
|
24
|
+
// When opts.all is false/undefined, callback expects (err, address, family)
|
|
25
|
+
if (opts.all) {
|
|
26
|
+
cb(null, [{ address: '127.0.0.1', family: 4 }]);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
cb(null, '127.0.0.1', 4);
|
|
30
|
+
}
|
|
24
31
|
return;
|
|
25
32
|
}
|
|
26
33
|
dns.lookup(hostname, opts, cb);
|
|
@@ -59,7 +66,7 @@ export async function fetchSchema(options) {
|
|
|
59
66
|
// Create abort controller for timeout
|
|
60
67
|
const controller = new AbortController();
|
|
61
68
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
62
|
-
// Build fetch options
|
|
69
|
+
// Build fetch options using undici's RequestInit type
|
|
63
70
|
const fetchOptions = {
|
|
64
71
|
method: 'POST',
|
|
65
72
|
headers: requestHeaders,
|
package/esm/types/config.d.ts
CHANGED
|
@@ -223,6 +223,14 @@ export interface GraphQLSDKConfigTarget {
|
|
|
223
223
|
* @default false
|
|
224
224
|
*/
|
|
225
225
|
reactQuery?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Generate browser-compatible code using native fetch
|
|
228
|
+
* When true (default), uses native W3C fetch API (works in browsers and Node.js)
|
|
229
|
+
* When false, uses undici fetch with dispatcher support for localhost DNS resolution
|
|
230
|
+
* (Node.js only - enables proper *.localhost subdomain resolution on macOS)
|
|
231
|
+
* @default true
|
|
232
|
+
*/
|
|
233
|
+
browserCompatible?: boolean;
|
|
226
234
|
/**
|
|
227
235
|
* Query key generation configuration
|
|
228
236
|
* Controls how query keys are structured for cache management
|
package/esm/types/config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-codegen",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "GraphQL SDK generator for Constructive databases with React Query hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"scripts": {
|
|
36
36
|
"clean": "makage clean",
|
|
37
37
|
"prepack": "npm run build",
|
|
38
|
-
"copy:
|
|
39
|
-
"build": "makage build && npm run copy:
|
|
40
|
-
"build:dev": "makage build --dev && npm run copy:
|
|
38
|
+
"copy:templates": "mkdir -p dist/core/codegen/templates && cp src/core/codegen/templates/*.ts dist/core/codegen/templates/",
|
|
39
|
+
"build": "makage build && npm run copy:templates",
|
|
40
|
+
"build:dev": "makage build --dev && npm run copy:templates",
|
|
41
41
|
"dev": "ts-node ./src/index.ts",
|
|
42
42
|
"lint": "eslint . --fix",
|
|
43
43
|
"fmt": "oxfmt --write .",
|
|
@@ -99,5 +99,5 @@
|
|
|
99
99
|
"tsx": "^4.21.0",
|
|
100
100
|
"typescript": "^5.9.3"
|
|
101
101
|
},
|
|
102
|
-
"gitHead": "
|
|
102
|
+
"gitHead": "03cfe7dad85283c7364bc38261136933a20ba73d"
|
|
103
103
|
}
|
package/types/config.d.ts
CHANGED
|
@@ -223,6 +223,14 @@ export interface GraphQLSDKConfigTarget {
|
|
|
223
223
|
* @default false
|
|
224
224
|
*/
|
|
225
225
|
reactQuery?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Generate browser-compatible code using native fetch
|
|
228
|
+
* When true (default), uses native W3C fetch API (works in browsers and Node.js)
|
|
229
|
+
* When false, uses undici fetch with dispatcher support for localhost DNS resolution
|
|
230
|
+
* (Node.js only - enables proper *.localhost subdomain resolution on macOS)
|
|
231
|
+
* @default true
|
|
232
|
+
*/
|
|
233
|
+
browserCompatible?: boolean;
|
|
226
234
|
/**
|
|
227
235
|
* Query key generation configuration
|
|
228
236
|
* Controls how query keys are structured for cache management
|
package/types/config.js
CHANGED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Builder - Builds and executes GraphQL operations
|
|
3
|
-
*
|
|
4
|
-
* This is the RUNTIME code that gets copied to generated output.
|
|
5
|
-
* It uses gql-ast to build GraphQL documents programmatically.
|
|
6
|
-
*
|
|
7
|
-
* NOTE: This file is read at codegen time and written to output.
|
|
8
|
-
* Any changes here will affect all generated ORM clients.
|
|
9
|
-
*/
|
|
10
|
-
import type { FieldNode } from 'graphql';
|
|
11
|
-
import { OrmClient, QueryResult } from './client';
|
|
12
|
-
export interface QueryBuilderConfig {
|
|
13
|
-
client: OrmClient;
|
|
14
|
-
operation: 'query' | 'mutation';
|
|
15
|
-
operationName: string;
|
|
16
|
-
fieldName: string;
|
|
17
|
-
document: string;
|
|
18
|
-
variables?: Record<string, unknown>;
|
|
19
|
-
}
|
|
20
|
-
export declare class QueryBuilder<TResult> {
|
|
21
|
-
private config;
|
|
22
|
-
constructor(config: QueryBuilderConfig);
|
|
23
|
-
/**
|
|
24
|
-
* Execute the query and return a discriminated union result
|
|
25
|
-
* Use result.ok to check success, or .unwrap() to throw on error
|
|
26
|
-
*/
|
|
27
|
-
execute(): Promise<QueryResult<TResult>>;
|
|
28
|
-
/**
|
|
29
|
-
* Execute and unwrap the result, throwing GraphQLRequestError on failure
|
|
30
|
-
* @throws {GraphQLRequestError} If the query returns errors
|
|
31
|
-
*/
|
|
32
|
-
unwrap(): Promise<TResult>;
|
|
33
|
-
/**
|
|
34
|
-
* Execute and unwrap, returning defaultValue on error instead of throwing
|
|
35
|
-
*/
|
|
36
|
-
unwrapOr<D>(defaultValue: D): Promise<TResult | D>;
|
|
37
|
-
/**
|
|
38
|
-
* Execute and unwrap, calling onError callback on failure
|
|
39
|
-
*/
|
|
40
|
-
unwrapOrElse<D>(onError: (errors: import('./client').GraphQLError[]) => D): Promise<TResult | D>;
|
|
41
|
-
toGraphQL(): string;
|
|
42
|
-
getVariables(): Record<string, unknown> | undefined;
|
|
43
|
-
}
|
|
44
|
-
export declare function buildSelections(select: Record<string, unknown> | undefined): FieldNode[];
|
|
45
|
-
export declare function buildFindManyDocument<TSelect, TWhere>(operationName: string, queryField: string, select: TSelect, args: {
|
|
46
|
-
where?: TWhere;
|
|
47
|
-
orderBy?: string[];
|
|
48
|
-
first?: number;
|
|
49
|
-
last?: number;
|
|
50
|
-
after?: string;
|
|
51
|
-
before?: string;
|
|
52
|
-
offset?: number;
|
|
53
|
-
}, filterTypeName: string, orderByTypeName: string): {
|
|
54
|
-
document: string;
|
|
55
|
-
variables: Record<string, unknown>;
|
|
56
|
-
};
|
|
57
|
-
export declare function buildFindFirstDocument<TSelect, TWhere>(operationName: string, queryField: string, select: TSelect, args: {
|
|
58
|
-
where?: TWhere;
|
|
59
|
-
}, filterTypeName: string): {
|
|
60
|
-
document: string;
|
|
61
|
-
variables: Record<string, unknown>;
|
|
62
|
-
};
|
|
63
|
-
export declare function buildCreateDocument<TSelect, TData>(operationName: string, mutationField: string, entityField: string, select: TSelect, data: TData, inputTypeName: string): {
|
|
64
|
-
document: string;
|
|
65
|
-
variables: Record<string, unknown>;
|
|
66
|
-
};
|
|
67
|
-
export declare function buildUpdateDocument<TSelect, TWhere extends {
|
|
68
|
-
id: string;
|
|
69
|
-
}, TData>(operationName: string, mutationField: string, entityField: string, select: TSelect, where: TWhere, data: TData, inputTypeName: string): {
|
|
70
|
-
document: string;
|
|
71
|
-
variables: Record<string, unknown>;
|
|
72
|
-
};
|
|
73
|
-
export declare function buildDeleteDocument<TWhere extends {
|
|
74
|
-
id: string;
|
|
75
|
-
}>(operationName: string, mutationField: string, entityField: string, where: TWhere, inputTypeName: string): {
|
|
76
|
-
document: string;
|
|
77
|
-
variables: Record<string, unknown>;
|
|
78
|
-
};
|
|
79
|
-
export declare function buildCustomDocument<TSelect, TArgs>(operationType: 'query' | 'mutation', operationName: string, fieldName: string, select: TSelect, args: TArgs, variableDefinitions: Array<{
|
|
80
|
-
name: string;
|
|
81
|
-
type: string;
|
|
82
|
-
}>): {
|
|
83
|
-
document: string;
|
|
84
|
-
variables: Record<string, unknown>;
|
|
85
|
-
};
|
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Query Builder - Builds and executes GraphQL operations
|
|
4
|
-
*
|
|
5
|
-
* This is the RUNTIME code that gets copied to generated output.
|
|
6
|
-
* It uses gql-ast to build GraphQL documents programmatically.
|
|
7
|
-
*
|
|
8
|
-
* NOTE: This file is read at codegen time and written to output.
|
|
9
|
-
* Any changes here will affect all generated ORM clients.
|
|
10
|
-
*/
|
|
11
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
-
}
|
|
17
|
-
Object.defineProperty(o, k2, desc);
|
|
18
|
-
}) : (function(o, m, k, k2) {
|
|
19
|
-
if (k2 === undefined) k2 = k;
|
|
20
|
-
o[k2] = m[k];
|
|
21
|
-
}));
|
|
22
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
-
}) : function(o, v) {
|
|
25
|
-
o["default"] = v;
|
|
26
|
-
});
|
|
27
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
-
var ownKeys = function(o) {
|
|
29
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
-
var ar = [];
|
|
31
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
-
return ar;
|
|
33
|
-
};
|
|
34
|
-
return ownKeys(o);
|
|
35
|
-
};
|
|
36
|
-
return function (mod) {
|
|
37
|
-
if (mod && mod.__esModule) return mod;
|
|
38
|
-
var result = {};
|
|
39
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
-
__setModuleDefault(result, mod);
|
|
41
|
-
return result;
|
|
42
|
-
};
|
|
43
|
-
})();
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.QueryBuilder = void 0;
|
|
46
|
-
exports.buildSelections = buildSelections;
|
|
47
|
-
exports.buildFindManyDocument = buildFindManyDocument;
|
|
48
|
-
exports.buildFindFirstDocument = buildFindFirstDocument;
|
|
49
|
-
exports.buildCreateDocument = buildCreateDocument;
|
|
50
|
-
exports.buildUpdateDocument = buildUpdateDocument;
|
|
51
|
-
exports.buildDeleteDocument = buildDeleteDocument;
|
|
52
|
-
exports.buildCustomDocument = buildCustomDocument;
|
|
53
|
-
const t = __importStar(require("gql-ast"));
|
|
54
|
-
const graphql_web_1 = require("@0no-co/graphql.web");
|
|
55
|
-
const client_1 = require("./client");
|
|
56
|
-
class QueryBuilder {
|
|
57
|
-
config;
|
|
58
|
-
constructor(config) {
|
|
59
|
-
this.config = config;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Execute the query and return a discriminated union result
|
|
63
|
-
* Use result.ok to check success, or .unwrap() to throw on error
|
|
64
|
-
*/
|
|
65
|
-
async execute() {
|
|
66
|
-
return this.config.client.execute(this.config.document, this.config.variables);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Execute and unwrap the result, throwing GraphQLRequestError on failure
|
|
70
|
-
* @throws {GraphQLRequestError} If the query returns errors
|
|
71
|
-
*/
|
|
72
|
-
async unwrap() {
|
|
73
|
-
const result = await this.execute();
|
|
74
|
-
if (!result.ok) {
|
|
75
|
-
throw new client_1.GraphQLRequestError(result.errors, result.data);
|
|
76
|
-
}
|
|
77
|
-
return result.data;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Execute and unwrap, returning defaultValue on error instead of throwing
|
|
81
|
-
*/
|
|
82
|
-
async unwrapOr(defaultValue) {
|
|
83
|
-
const result = await this.execute();
|
|
84
|
-
if (!result.ok) {
|
|
85
|
-
return defaultValue;
|
|
86
|
-
}
|
|
87
|
-
return result.data;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Execute and unwrap, calling onError callback on failure
|
|
91
|
-
*/
|
|
92
|
-
async unwrapOrElse(onError) {
|
|
93
|
-
const result = await this.execute();
|
|
94
|
-
if (!result.ok) {
|
|
95
|
-
return onError(result.errors);
|
|
96
|
-
}
|
|
97
|
-
return result.data;
|
|
98
|
-
}
|
|
99
|
-
toGraphQL() {
|
|
100
|
-
return this.config.document;
|
|
101
|
-
}
|
|
102
|
-
getVariables() {
|
|
103
|
-
return this.config.variables;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.QueryBuilder = QueryBuilder;
|
|
107
|
-
// ============================================================================
|
|
108
|
-
// Selection Builders
|
|
109
|
-
// ============================================================================
|
|
110
|
-
function buildSelections(select) {
|
|
111
|
-
if (!select) {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
const fields = [];
|
|
115
|
-
for (const [key, value] of Object.entries(select)) {
|
|
116
|
-
if (value === false || value === undefined) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
if (value === true) {
|
|
120
|
-
fields.push(t.field({ name: key }));
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (typeof value === 'object' && value !== null) {
|
|
124
|
-
const nested = value;
|
|
125
|
-
if (nested.select) {
|
|
126
|
-
const nestedSelections = buildSelections(nested.select);
|
|
127
|
-
const isConnection = nested.connection === true ||
|
|
128
|
-
nested.first !== undefined ||
|
|
129
|
-
nested.filter !== undefined;
|
|
130
|
-
const args = buildArgs([
|
|
131
|
-
buildOptionalArg('first', nested.first),
|
|
132
|
-
nested.filter
|
|
133
|
-
? t.argument({ name: 'filter', value: buildValueAst(nested.filter) })
|
|
134
|
-
: null,
|
|
135
|
-
buildEnumListArg('orderBy', nested.orderBy),
|
|
136
|
-
]);
|
|
137
|
-
if (isConnection) {
|
|
138
|
-
fields.push(t.field({
|
|
139
|
-
name: key,
|
|
140
|
-
args,
|
|
141
|
-
selectionSet: t.selectionSet({
|
|
142
|
-
selections: buildConnectionSelections(nestedSelections),
|
|
143
|
-
}),
|
|
144
|
-
}));
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
fields.push(t.field({
|
|
148
|
-
name: key,
|
|
149
|
-
args,
|
|
150
|
-
selectionSet: t.selectionSet({ selections: nestedSelections }),
|
|
151
|
-
}));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return fields;
|
|
157
|
-
}
|
|
158
|
-
// ============================================================================
|
|
159
|
-
// Document Builders
|
|
160
|
-
// ============================================================================
|
|
161
|
-
function buildFindManyDocument(operationName, queryField, select, args, filterTypeName, orderByTypeName) {
|
|
162
|
-
const selections = select
|
|
163
|
-
? buildSelections(select)
|
|
164
|
-
: [t.field({ name: 'id' })];
|
|
165
|
-
const variableDefinitions = [];
|
|
166
|
-
const queryArgs = [];
|
|
167
|
-
const variables = {};
|
|
168
|
-
addVariable({ varName: 'where', argName: 'filter', typeName: filterTypeName, value: args.where }, variableDefinitions, queryArgs, variables);
|
|
169
|
-
addVariable({
|
|
170
|
-
varName: 'orderBy',
|
|
171
|
-
typeName: '[' + orderByTypeName + '!]',
|
|
172
|
-
value: args.orderBy?.length ? args.orderBy : undefined,
|
|
173
|
-
}, variableDefinitions, queryArgs, variables);
|
|
174
|
-
addVariable({ varName: 'first', typeName: 'Int', value: args.first }, variableDefinitions, queryArgs, variables);
|
|
175
|
-
addVariable({ varName: 'last', typeName: 'Int', value: args.last }, variableDefinitions, queryArgs, variables);
|
|
176
|
-
addVariable({ varName: 'after', typeName: 'Cursor', value: args.after }, variableDefinitions, queryArgs, variables);
|
|
177
|
-
addVariable({ varName: 'before', typeName: 'Cursor', value: args.before }, variableDefinitions, queryArgs, variables);
|
|
178
|
-
addVariable({ varName: 'offset', typeName: 'Int', value: args.offset }, variableDefinitions, queryArgs, variables);
|
|
179
|
-
const document = t.document({
|
|
180
|
-
definitions: [
|
|
181
|
-
t.operationDefinition({
|
|
182
|
-
operation: 'query',
|
|
183
|
-
name: operationName + 'Query',
|
|
184
|
-
variableDefinitions: variableDefinitions.length ? variableDefinitions : undefined,
|
|
185
|
-
selectionSet: t.selectionSet({
|
|
186
|
-
selections: [
|
|
187
|
-
t.field({
|
|
188
|
-
name: queryField,
|
|
189
|
-
args: queryArgs.length ? queryArgs : undefined,
|
|
190
|
-
selectionSet: t.selectionSet({
|
|
191
|
-
selections: buildConnectionSelections(selections),
|
|
192
|
-
}),
|
|
193
|
-
}),
|
|
194
|
-
],
|
|
195
|
-
}),
|
|
196
|
-
}),
|
|
197
|
-
],
|
|
198
|
-
});
|
|
199
|
-
return { document: (0, graphql_web_1.print)(document), variables };
|
|
200
|
-
}
|
|
201
|
-
function buildFindFirstDocument(operationName, queryField, select, args, filterTypeName) {
|
|
202
|
-
const selections = select
|
|
203
|
-
? buildSelections(select)
|
|
204
|
-
: [t.field({ name: 'id' })];
|
|
205
|
-
const variableDefinitions = [];
|
|
206
|
-
const queryArgs = [];
|
|
207
|
-
const variables = {};
|
|
208
|
-
// Always add first: 1 for findFirst
|
|
209
|
-
addVariable({ varName: 'first', typeName: 'Int', value: 1 }, variableDefinitions, queryArgs, variables);
|
|
210
|
-
addVariable({ varName: 'where', argName: 'filter', typeName: filterTypeName, value: args.where }, variableDefinitions, queryArgs, variables);
|
|
211
|
-
const document = t.document({
|
|
212
|
-
definitions: [
|
|
213
|
-
t.operationDefinition({
|
|
214
|
-
operation: 'query',
|
|
215
|
-
name: operationName + 'Query',
|
|
216
|
-
variableDefinitions,
|
|
217
|
-
selectionSet: t.selectionSet({
|
|
218
|
-
selections: [
|
|
219
|
-
t.field({
|
|
220
|
-
name: queryField,
|
|
221
|
-
args: queryArgs,
|
|
222
|
-
selectionSet: t.selectionSet({
|
|
223
|
-
selections: [
|
|
224
|
-
t.field({
|
|
225
|
-
name: 'nodes',
|
|
226
|
-
selectionSet: t.selectionSet({ selections }),
|
|
227
|
-
}),
|
|
228
|
-
],
|
|
229
|
-
}),
|
|
230
|
-
}),
|
|
231
|
-
],
|
|
232
|
-
}),
|
|
233
|
-
}),
|
|
234
|
-
],
|
|
235
|
-
});
|
|
236
|
-
return { document: (0, graphql_web_1.print)(document), variables };
|
|
237
|
-
}
|
|
238
|
-
function buildCreateDocument(operationName, mutationField, entityField, select, data, inputTypeName) {
|
|
239
|
-
const selections = select
|
|
240
|
-
? buildSelections(select)
|
|
241
|
-
: [t.field({ name: 'id' })];
|
|
242
|
-
return {
|
|
243
|
-
document: buildInputMutationDocument({
|
|
244
|
-
operationName,
|
|
245
|
-
mutationField,
|
|
246
|
-
inputTypeName,
|
|
247
|
-
resultSelections: [
|
|
248
|
-
t.field({
|
|
249
|
-
name: entityField,
|
|
250
|
-
selectionSet: t.selectionSet({ selections }),
|
|
251
|
-
}),
|
|
252
|
-
],
|
|
253
|
-
}),
|
|
254
|
-
variables: {
|
|
255
|
-
input: {
|
|
256
|
-
[entityField]: data,
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function buildUpdateDocument(operationName, mutationField, entityField, select, where, data, inputTypeName) {
|
|
262
|
-
const selections = select
|
|
263
|
-
? buildSelections(select)
|
|
264
|
-
: [t.field({ name: 'id' })];
|
|
265
|
-
return {
|
|
266
|
-
document: buildInputMutationDocument({
|
|
267
|
-
operationName,
|
|
268
|
-
mutationField,
|
|
269
|
-
inputTypeName,
|
|
270
|
-
resultSelections: [
|
|
271
|
-
t.field({
|
|
272
|
-
name: entityField,
|
|
273
|
-
selectionSet: t.selectionSet({ selections }),
|
|
274
|
-
}),
|
|
275
|
-
],
|
|
276
|
-
}),
|
|
277
|
-
variables: {
|
|
278
|
-
input: {
|
|
279
|
-
id: where.id,
|
|
280
|
-
patch: data,
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
function buildDeleteDocument(operationName, mutationField, entityField, where, inputTypeName) {
|
|
286
|
-
return {
|
|
287
|
-
document: buildInputMutationDocument({
|
|
288
|
-
operationName,
|
|
289
|
-
mutationField,
|
|
290
|
-
inputTypeName,
|
|
291
|
-
resultSelections: [
|
|
292
|
-
t.field({
|
|
293
|
-
name: entityField,
|
|
294
|
-
selectionSet: t.selectionSet({
|
|
295
|
-
selections: [t.field({ name: 'id' })],
|
|
296
|
-
}),
|
|
297
|
-
}),
|
|
298
|
-
],
|
|
299
|
-
}),
|
|
300
|
-
variables: {
|
|
301
|
-
input: {
|
|
302
|
-
id: where.id,
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
function buildCustomDocument(operationType, operationName, fieldName, select, args, variableDefinitions) {
|
|
308
|
-
let actualSelect = select;
|
|
309
|
-
let isConnection = false;
|
|
310
|
-
if (select && typeof select === 'object' && 'select' in select) {
|
|
311
|
-
const wrapper = select;
|
|
312
|
-
if (wrapper.select) {
|
|
313
|
-
actualSelect = wrapper.select;
|
|
314
|
-
isConnection = wrapper.connection === true;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
const selections = actualSelect
|
|
318
|
-
? buildSelections(actualSelect)
|
|
319
|
-
: [];
|
|
320
|
-
const variableDefs = variableDefinitions.map((definition) => t.variableDefinition({
|
|
321
|
-
variable: t.variable({ name: definition.name }),
|
|
322
|
-
type: (0, graphql_web_1.parseType)(definition.type),
|
|
323
|
-
}));
|
|
324
|
-
const fieldArgs = variableDefinitions.map((definition) => t.argument({
|
|
325
|
-
name: definition.name,
|
|
326
|
-
value: t.variable({ name: definition.name }),
|
|
327
|
-
}));
|
|
328
|
-
const fieldSelections = isConnection
|
|
329
|
-
? buildConnectionSelections(selections)
|
|
330
|
-
: selections;
|
|
331
|
-
const document = t.document({
|
|
332
|
-
definitions: [
|
|
333
|
-
t.operationDefinition({
|
|
334
|
-
operation: operationType,
|
|
335
|
-
name: operationName,
|
|
336
|
-
variableDefinitions: variableDefs.length ? variableDefs : undefined,
|
|
337
|
-
selectionSet: t.selectionSet({
|
|
338
|
-
selections: [
|
|
339
|
-
t.field({
|
|
340
|
-
name: fieldName,
|
|
341
|
-
args: fieldArgs.length ? fieldArgs : undefined,
|
|
342
|
-
selectionSet: fieldSelections.length
|
|
343
|
-
? t.selectionSet({ selections: fieldSelections })
|
|
344
|
-
: undefined,
|
|
345
|
-
}),
|
|
346
|
-
],
|
|
347
|
-
}),
|
|
348
|
-
}),
|
|
349
|
-
],
|
|
350
|
-
});
|
|
351
|
-
return {
|
|
352
|
-
document: (0, graphql_web_1.print)(document),
|
|
353
|
-
variables: (args ?? {}),
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
// ============================================================================
|
|
357
|
-
// Helper Functions
|
|
358
|
-
// ============================================================================
|
|
359
|
-
function buildArgs(args) {
|
|
360
|
-
return args.filter((arg) => arg !== null);
|
|
361
|
-
}
|
|
362
|
-
function buildOptionalArg(name, value) {
|
|
363
|
-
if (value === undefined) {
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
const valueNode = typeof value === 'number'
|
|
367
|
-
? t.intValue({ value: value.toString() })
|
|
368
|
-
: t.stringValue({ value });
|
|
369
|
-
return t.argument({ name, value: valueNode });
|
|
370
|
-
}
|
|
371
|
-
function buildEnumListArg(name, values) {
|
|
372
|
-
if (!values || values.length === 0) {
|
|
373
|
-
return null;
|
|
374
|
-
}
|
|
375
|
-
return t.argument({
|
|
376
|
-
name,
|
|
377
|
-
value: t.listValue({
|
|
378
|
-
values: values.map((value) => buildEnumValue(value)),
|
|
379
|
-
}),
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
function buildEnumValue(value) {
|
|
383
|
-
return {
|
|
384
|
-
kind: 'EnumValue',
|
|
385
|
-
value,
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
function buildPageInfoSelections() {
|
|
389
|
-
return [
|
|
390
|
-
t.field({ name: 'hasNextPage' }),
|
|
391
|
-
t.field({ name: 'hasPreviousPage' }),
|
|
392
|
-
t.field({ name: 'startCursor' }),
|
|
393
|
-
t.field({ name: 'endCursor' }),
|
|
394
|
-
];
|
|
395
|
-
}
|
|
396
|
-
function buildConnectionSelections(nodeSelections) {
|
|
397
|
-
return [
|
|
398
|
-
t.field({
|
|
399
|
-
name: 'nodes',
|
|
400
|
-
selectionSet: t.selectionSet({ selections: nodeSelections }),
|
|
401
|
-
}),
|
|
402
|
-
t.field({ name: 'totalCount' }),
|
|
403
|
-
t.field({
|
|
404
|
-
name: 'pageInfo',
|
|
405
|
-
selectionSet: t.selectionSet({ selections: buildPageInfoSelections() }),
|
|
406
|
-
}),
|
|
407
|
-
];
|
|
408
|
-
}
|
|
409
|
-
function buildInputMutationDocument(config) {
|
|
410
|
-
const document = t.document({
|
|
411
|
-
definitions: [
|
|
412
|
-
t.operationDefinition({
|
|
413
|
-
operation: 'mutation',
|
|
414
|
-
name: config.operationName + 'Mutation',
|
|
415
|
-
variableDefinitions: [
|
|
416
|
-
t.variableDefinition({
|
|
417
|
-
variable: t.variable({ name: 'input' }),
|
|
418
|
-
type: (0, graphql_web_1.parseType)(config.inputTypeName + '!'),
|
|
419
|
-
}),
|
|
420
|
-
],
|
|
421
|
-
selectionSet: t.selectionSet({
|
|
422
|
-
selections: [
|
|
423
|
-
t.field({
|
|
424
|
-
name: config.mutationField,
|
|
425
|
-
args: [
|
|
426
|
-
t.argument({
|
|
427
|
-
name: 'input',
|
|
428
|
-
value: t.variable({ name: 'input' }),
|
|
429
|
-
}),
|
|
430
|
-
],
|
|
431
|
-
selectionSet: t.selectionSet({
|
|
432
|
-
selections: config.resultSelections,
|
|
433
|
-
}),
|
|
434
|
-
}),
|
|
435
|
-
],
|
|
436
|
-
}),
|
|
437
|
-
}),
|
|
438
|
-
],
|
|
439
|
-
});
|
|
440
|
-
return (0, graphql_web_1.print)(document);
|
|
441
|
-
}
|
|
442
|
-
function addVariable(spec, definitions, args, variables) {
|
|
443
|
-
if (spec.value === undefined)
|
|
444
|
-
return;
|
|
445
|
-
definitions.push(t.variableDefinition({
|
|
446
|
-
variable: t.variable({ name: spec.varName }),
|
|
447
|
-
type: (0, graphql_web_1.parseType)(spec.typeName),
|
|
448
|
-
}));
|
|
449
|
-
args.push(t.argument({
|
|
450
|
-
name: spec.argName ?? spec.varName,
|
|
451
|
-
value: t.variable({ name: spec.varName }),
|
|
452
|
-
}));
|
|
453
|
-
variables[spec.varName] = spec.value;
|
|
454
|
-
}
|
|
455
|
-
function buildValueAst(value) {
|
|
456
|
-
if (value === null) {
|
|
457
|
-
return t.nullValue();
|
|
458
|
-
}
|
|
459
|
-
if (typeof value === 'boolean') {
|
|
460
|
-
return t.booleanValue({ value });
|
|
461
|
-
}
|
|
462
|
-
if (typeof value === 'number') {
|
|
463
|
-
return Number.isInteger(value)
|
|
464
|
-
? t.intValue({ value: value.toString() })
|
|
465
|
-
: t.floatValue({ value: value.toString() });
|
|
466
|
-
}
|
|
467
|
-
if (typeof value === 'string') {
|
|
468
|
-
return t.stringValue({ value });
|
|
469
|
-
}
|
|
470
|
-
if (Array.isArray(value)) {
|
|
471
|
-
return t.listValue({
|
|
472
|
-
values: value.map((item) => buildValueAst(item)),
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
if (typeof value === 'object' && value !== null) {
|
|
476
|
-
const obj = value;
|
|
477
|
-
return t.objectValue({
|
|
478
|
-
fields: Object.entries(obj).map(([key, val]) => t.objectField({
|
|
479
|
-
name: key,
|
|
480
|
-
value: buildValueAst(val),
|
|
481
|
-
})),
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
throw new Error('Unsupported value type: ' + typeof value);
|
|
485
|
-
}
|