nitro-graphql 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ecosystem/nuxt.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +127 -12
- package/dist/rollup.js +25 -1
- package/dist/routes/apollo-server.js +11 -6
- package/dist/routes/graphql-yoga.d.ts +2 -2
- package/dist/routes/graphql-yoga.js +9 -3
- package/dist/routes/health.d.ts +2 -2
- package/dist/types/index.d.ts +2 -1
- package/dist/utils/define.d.ts +52 -1
- package/dist/utils/define.js +33 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +28 -2
- package/package.json +1 -1
package/dist/ecosystem/nuxt.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _nuxt_schema0 from "@nuxt/schema";
|
|
2
2
|
|
|
3
3
|
//#region src/ecosystem/nuxt.d.ts
|
|
4
4
|
interface ModuleOptions {}
|
|
5
|
-
declare const _default:
|
|
5
|
+
declare const _default: _nuxt_schema0.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ModuleOptions, _default as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "./types/standard-schema.js";
|
|
2
2
|
import { CodegenClientConfig, CodegenServerConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions } from "./types/index.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as nitropack3 from "nitropack";
|
|
4
4
|
|
|
5
5
|
//#region src/index.d.ts
|
|
6
|
-
declare const _default:
|
|
6
|
+
declare const _default: nitropack3.NitroModule;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { CodegenClientConfig, CodegenServerConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, StandardSchemaV1, _default as default };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { relativeWithDot, scanDocs, scanResolvers, scanSchemas } from "./utils/index.js";
|
|
1
|
+
import { relativeWithDot, scanDirectives, scanDocs, scanResolvers, scanSchemas } from "./utils/index.js";
|
|
2
2
|
import { clientTypeGeneration, serverTypeGeneration } from "./utils/type-generation.js";
|
|
3
3
|
import { rollupConfig } from "./rollup.js";
|
|
4
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
6
7
|
import { watch } from "chokidar";
|
|
7
8
|
import consola from "consola";
|
|
@@ -62,7 +63,7 @@ var src_default = defineNitroModule({
|
|
|
62
63
|
const watcher = watch(watchDirs, {
|
|
63
64
|
persistent: true,
|
|
64
65
|
ignoreInitial: true,
|
|
65
|
-
ignored: nitro.options.ignore
|
|
66
|
+
ignored: [...nitro.options.ignore, "**/server/graphql/_directives.graphql"]
|
|
66
67
|
}).on("all", async (event, path) => {
|
|
67
68
|
if (path.endsWith(".graphql") || path.endsWith(".gql")) await clientTypeGeneration(nitro);
|
|
68
69
|
});
|
|
@@ -78,11 +79,115 @@ var src_default = defineNitroModule({
|
|
|
78
79
|
nitro.scanDocuments = docs;
|
|
79
80
|
const resolvers = await scanResolvers(nitro);
|
|
80
81
|
nitro.scanResolvers = resolvers;
|
|
82
|
+
const directives = await scanDirectives(nitro);
|
|
83
|
+
nitro.scanDirectives = directives;
|
|
84
|
+
if (directives.length > 0) {
|
|
85
|
+
const directiveSchemas = [];
|
|
86
|
+
for (const dir of directives) for (const _imp of dir.imports) {
|
|
87
|
+
const fileContent = await readFile(dir.specifier, "utf-8");
|
|
88
|
+
const nameMatch = fileContent.match(/name:\s*['"`](\w+)['"`]/);
|
|
89
|
+
const locationsMatch = fileContent.match(/locations:\s*\[([\s\S]*?)\]/);
|
|
90
|
+
const argsMatch = fileContent.match(/args:\s*\{([\s\S]*?)\}\s*,\s*(?:description|transformer)/);
|
|
91
|
+
if (nameMatch && locationsMatch) {
|
|
92
|
+
const name = nameMatch[1];
|
|
93
|
+
const locations = locationsMatch?.[1]?.split(",").map((l) => l.trim().replace(/['"`]/g, "")).filter(Boolean).join(" | ") || "";
|
|
94
|
+
let args = "";
|
|
95
|
+
if (argsMatch && argsMatch[1] && argsMatch[1].trim()) {
|
|
96
|
+
const argDefs = [];
|
|
97
|
+
const argMatches = argsMatch[1].matchAll(/(\w+):\s*\{([^}]+)\}/g);
|
|
98
|
+
for (const argMatch of argMatches) {
|
|
99
|
+
const argName = argMatch[1];
|
|
100
|
+
const argBody = argMatch[2];
|
|
101
|
+
const typeMatch = argBody?.match(/type:\s*['"`](\[[\w!]+\]|\w+)['"`]/);
|
|
102
|
+
const type = typeMatch ? typeMatch[1] : "String";
|
|
103
|
+
const defaultMatch = argBody?.match(/defaultValue:\s*(['"`]([^'"`]+)['"`]|(\d+)|true|false)/);
|
|
104
|
+
let defaultValue = "";
|
|
105
|
+
if (defaultMatch) {
|
|
106
|
+
const value = defaultMatch[2] || defaultMatch[3] || defaultMatch[1]?.replace(/['"`]/g, "");
|
|
107
|
+
if (type === "String") defaultValue = ` = "${value}"`;
|
|
108
|
+
else if (type === "Int" || type === "Float") defaultValue = ` = ${value}`;
|
|
109
|
+
else if (type === "Boolean") defaultValue = ` = ${value}`;
|
|
110
|
+
}
|
|
111
|
+
argDefs.push(`${argName}: ${type}${defaultValue}`);
|
|
112
|
+
}
|
|
113
|
+
if (argDefs.length > 0) args = `(${argDefs.join(", ")})`;
|
|
114
|
+
}
|
|
115
|
+
directiveSchemas.push(`directive @${name}${args} on ${locations}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (directiveSchemas.length > 0) {
|
|
119
|
+
const directivesPath = resolve(nitro.graphql.serverDir, "_directives.graphql");
|
|
120
|
+
const content = `# WARNING: This file is auto-generated by nitro-graphql
|
|
121
|
+
# Do not modify this file directly. It will be overwritten.
|
|
122
|
+
# To define custom directives, create .directive.ts files using defineDirective()
|
|
123
|
+
|
|
124
|
+
${directiveSchemas.join("\n\n")}`;
|
|
125
|
+
let shouldWrite = true;
|
|
126
|
+
if (existsSync(directivesPath)) {
|
|
127
|
+
const existingContent = readFileSync(directivesPath, "utf-8");
|
|
128
|
+
shouldWrite = existingContent !== content;
|
|
129
|
+
}
|
|
130
|
+
if (shouldWrite) writeFileSync(directivesPath, content, "utf-8");
|
|
131
|
+
if (!nitro.scanSchemas.includes(directivesPath)) nitro.scanSchemas.push(directivesPath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
81
134
|
nitro.hooks.hook("dev:start", async () => {
|
|
82
135
|
const schemas$1 = await scanSchemas(nitro);
|
|
83
136
|
nitro.scanSchemas = schemas$1;
|
|
84
137
|
const resolvers$1 = await scanResolvers(nitro);
|
|
85
138
|
nitro.scanResolvers = resolvers$1;
|
|
139
|
+
const directives$1 = await scanDirectives(nitro);
|
|
140
|
+
nitro.scanDirectives = directives$1;
|
|
141
|
+
if (directives$1.length > 0) {
|
|
142
|
+
const directiveSchemas = [];
|
|
143
|
+
for (const dir of directives$1) for (const _imp of dir.imports) {
|
|
144
|
+
const fileContent = await readFile(dir.specifier, "utf-8");
|
|
145
|
+
const nameMatch = fileContent.match(/name:\s*['"`](\w+)['"`]/);
|
|
146
|
+
const locationsMatch = fileContent.match(/locations:\s*\[([\s\S]*?)\]/);
|
|
147
|
+
const argsMatch = fileContent.match(/args:\s*\{([\s\S]*?)\}\s*,\s*(?:description|transformer)/);
|
|
148
|
+
if (nameMatch && locationsMatch) {
|
|
149
|
+
const name = nameMatch[1];
|
|
150
|
+
const locations = locationsMatch?.[1]?.split(",").map((l) => l.trim().replace(/['"`]/g, "")).filter(Boolean).join(" | ") || "";
|
|
151
|
+
let args = "";
|
|
152
|
+
if (argsMatch && argsMatch[1] && argsMatch[1].trim()) {
|
|
153
|
+
const argDefs = [];
|
|
154
|
+
const argMatches = argsMatch[1].matchAll(/(\w+):\s*\{([^}]+)\}/g);
|
|
155
|
+
for (const argMatch of argMatches) {
|
|
156
|
+
const argName = argMatch[1];
|
|
157
|
+
const argBody = argMatch[2];
|
|
158
|
+
const typeMatch = argBody?.match(/type:\s*['"`](\[?\w+!?\]?)['"`]/);
|
|
159
|
+
const type = typeMatch ? typeMatch[1] : "String";
|
|
160
|
+
const defaultMatch = argBody?.match(/defaultValue:\s*(['"`]([^'"`]+)['"`]|(\d+)|true|false)/);
|
|
161
|
+
let defaultValue = "";
|
|
162
|
+
if (defaultMatch) {
|
|
163
|
+
const value = defaultMatch[2] || defaultMatch[3] || defaultMatch[1]?.replace(/['"`]/g, "");
|
|
164
|
+
if (type === "String") defaultValue = ` = "${value}"`;
|
|
165
|
+
else if (type === "Int" || type === "Float") defaultValue = ` = ${value}`;
|
|
166
|
+
else if (type === "Boolean") defaultValue = ` = ${value}`;
|
|
167
|
+
}
|
|
168
|
+
argDefs.push(`${argName}: ${type}${defaultValue}`);
|
|
169
|
+
}
|
|
170
|
+
if (argDefs.length > 0) args = `(${argDefs.join(", ")})`;
|
|
171
|
+
}
|
|
172
|
+
directiveSchemas.push(`directive @${name}${args} on ${locations}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (directiveSchemas.length > 0) {
|
|
176
|
+
const directivesPath = resolve(nitro.graphql.serverDir, "_directives.graphql");
|
|
177
|
+
const content = `# WARNING: This file is auto-generated by nitro-graphql
|
|
178
|
+
# Do not modify this file directly. It will be overwritten.
|
|
179
|
+
# To define custom directives, create .directive.ts files using defineDirective()
|
|
180
|
+
|
|
181
|
+
${directiveSchemas.join("\n\n")}`;
|
|
182
|
+
let shouldWrite = true;
|
|
183
|
+
if (existsSync(directivesPath)) {
|
|
184
|
+
const existingContent = readFileSync(directivesPath, "utf-8");
|
|
185
|
+
shouldWrite = existingContent !== content;
|
|
186
|
+
}
|
|
187
|
+
if (shouldWrite) writeFileSync(directivesPath, content, "utf-8");
|
|
188
|
+
if (!nitro.scanSchemas.includes(directivesPath)) nitro.scanSchemas.push(directivesPath);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
86
191
|
const docs$1 = await scanDocs(nitro);
|
|
87
192
|
nitro.scanDocuments = docs$1;
|
|
88
193
|
});
|
|
@@ -125,7 +230,8 @@ var src_default = defineNitroModule({
|
|
|
125
230
|
"defineSubscription",
|
|
126
231
|
"defineType",
|
|
127
232
|
"defineGraphQLConfig",
|
|
128
|
-
"defineSchema"
|
|
233
|
+
"defineSchema",
|
|
234
|
+
"defineDirective"
|
|
129
235
|
]
|
|
130
236
|
});
|
|
131
237
|
}
|
|
@@ -195,17 +301,26 @@ export default defineGraphQLConfig({
|
|
|
195
301
|
// },
|
|
196
302
|
})
|
|
197
303
|
`, "utf-8");
|
|
198
|
-
if (!existsSync(join(nitro.graphql.serverDir, "context.
|
|
199
|
-
import type {
|
|
200
|
-
|
|
201
|
-
export interface ExtendedH3EventContext extends OriginalH3EventContext {
|
|
202
|
-
// useDatabase: () => Database
|
|
203
|
-
// tables: typeof import('~~/server/drizzle/schema/index')
|
|
204
|
-
}
|
|
304
|
+
if (!existsSync(join(nitro.graphql.serverDir, "context.ts"))) writeFileSync(join(nitro.graphql.serverDir, "context.ts"), `// Example context definition - please change it to your needs
|
|
305
|
+
// import type { Database } from '../utils/useDb'
|
|
205
306
|
|
|
206
307
|
declare module 'h3' {
|
|
207
|
-
interface H3EventContext
|
|
308
|
+
interface H3EventContext {
|
|
309
|
+
// Add your custom context properties here
|
|
310
|
+
// useDatabase: () => Database
|
|
311
|
+
// tables: typeof import('../drizzle/schema')
|
|
312
|
+
// auth?: {
|
|
313
|
+
// user?: {
|
|
314
|
+
// id: string
|
|
315
|
+
// role: 'admin' | 'user'
|
|
316
|
+
// }
|
|
317
|
+
// }
|
|
318
|
+
}
|
|
208
319
|
}`, "utf-8");
|
|
320
|
+
if (existsSync(join(nitro.graphql.serverDir, "context.d.ts"))) {
|
|
321
|
+
consola.warn("nitro-graphql: Found context.d.ts file. Please rename it to context.ts for the new structure.");
|
|
322
|
+
consola.info("The context file should now be context.ts instead of context.d.ts");
|
|
323
|
+
}
|
|
209
324
|
}
|
|
210
325
|
});
|
|
211
326
|
|
package/dist/rollup.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getImportId, scanGraphql } from "./utils/index.js";
|
|
2
2
|
import { clientTypeGeneration, serverTypeGeneration } from "./utils/type-generation.js";
|
|
3
|
-
import { resolve } from "pathe";
|
|
4
3
|
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { resolve } from "pathe";
|
|
5
5
|
import { parse } from "graphql";
|
|
6
6
|
import { genImport } from "knitwork";
|
|
7
7
|
|
|
@@ -9,6 +9,7 @@ import { genImport } from "knitwork";
|
|
|
9
9
|
async function rollupConfig(app) {
|
|
10
10
|
virtualSchemas(app);
|
|
11
11
|
virtualResolvers(app);
|
|
12
|
+
virtualDirectives(app);
|
|
12
13
|
getGraphQLConfig(app);
|
|
13
14
|
app.hooks.hook("rollup:before", (nitro, rollupConfig$1) => {
|
|
14
15
|
rollupConfig$1.plugins = rollupConfig$1.plugins || [];
|
|
@@ -85,6 +86,29 @@ function virtualResolvers(app) {
|
|
|
85
86
|
return code;
|
|
86
87
|
};
|
|
87
88
|
}
|
|
89
|
+
function virtualDirectives(app) {
|
|
90
|
+
const getDirectives = () => {
|
|
91
|
+
const directives = [...app.scanDirectives || []];
|
|
92
|
+
return directives;
|
|
93
|
+
};
|
|
94
|
+
app.options.virtual ??= {};
|
|
95
|
+
app.options.virtual["#nitro-internal-virtual/server-directives"] = () => {
|
|
96
|
+
const imports = getDirectives();
|
|
97
|
+
const importsContent = [...imports.map(({ specifier, imports: imports$1, options }) => {
|
|
98
|
+
return genImport(specifier, imports$1, options);
|
|
99
|
+
})];
|
|
100
|
+
const data = imports.map(({ imports: imports$1 }) => imports$1.map((i) => `{ directive: ${i.as} }`).join(",\n")).filter(Boolean).join(",\n");
|
|
101
|
+
const content = [
|
|
102
|
+
"export const directives = [",
|
|
103
|
+
data,
|
|
104
|
+
"]",
|
|
105
|
+
""
|
|
106
|
+
];
|
|
107
|
+
content.unshift(...importsContent);
|
|
108
|
+
const code = content.join("\n");
|
|
109
|
+
return code;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
88
112
|
function getGraphQLConfig(app) {
|
|
89
113
|
const configPath = resolve(app.graphql.serverDir, "config.ts");
|
|
90
114
|
app.options.virtual ??= {};
|
|
@@ -2,21 +2,27 @@ import { startServerAndCreateH3Handler } from "../utils/apollo.js";
|
|
|
2
2
|
import defu from "defu";
|
|
3
3
|
import { mergeResolvers, mergeTypeDefs } from "@graphql-tools/merge";
|
|
4
4
|
import { importedConfig } from "#nitro-internal-virtual/graphql-config";
|
|
5
|
+
import { directives } from "#nitro-internal-virtual/server-directives";
|
|
5
6
|
import { resolvers } from "#nitro-internal-virtual/server-resolvers";
|
|
6
7
|
import { schemas } from "#nitro-internal-virtual/server-schemas";
|
|
7
8
|
import { ApolloServer } from "@apollo/server";
|
|
8
9
|
import { ApolloServerPluginLandingPageLocalDefault } from "@apollo/server/plugin/landingPage/default";
|
|
10
|
+
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
9
11
|
|
|
10
12
|
//#region src/routes/apollo-server.ts
|
|
11
13
|
function createMergedSchema() {
|
|
12
14
|
try {
|
|
13
|
-
const mergedSchemas = schemas.map((schema) => schema.def).join("\n\n");
|
|
15
|
+
const mergedSchemas = schemas.map((schema$1) => schema$1.def).join("\n\n");
|
|
14
16
|
const typeDefs = mergeTypeDefs([mergedSchemas]);
|
|
15
17
|
const mergedResolvers = mergeResolvers(resolvers.map((r) => r.resolver));
|
|
16
|
-
|
|
18
|
+
let schema = makeExecutableSchema({
|
|
17
19
|
typeDefs,
|
|
18
20
|
resolvers: mergedResolvers
|
|
19
|
-
};
|
|
21
|
+
});
|
|
22
|
+
if (directives && directives.length > 0) {
|
|
23
|
+
for (const { directive } of directives) if (directive.transformer) schema = directive.transformer(schema);
|
|
24
|
+
}
|
|
25
|
+
return schema;
|
|
20
26
|
} catch (error) {
|
|
21
27
|
console.error("Schema merge error:", error);
|
|
22
28
|
throw error;
|
|
@@ -25,10 +31,9 @@ function createMergedSchema() {
|
|
|
25
31
|
let apolloServer = null;
|
|
26
32
|
function createApolloServer() {
|
|
27
33
|
if (!apolloServer) {
|
|
28
|
-
const
|
|
34
|
+
const schema = createMergedSchema();
|
|
29
35
|
apolloServer = new ApolloServer(defu({
|
|
30
|
-
|
|
31
|
-
resolvers: mergedResolvers,
|
|
36
|
+
schema,
|
|
32
37
|
introspection: true,
|
|
33
38
|
plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })]
|
|
34
39
|
}, importedConfig));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h31 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/graphql-yoga.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h31.EventHandler<h31.EventHandlerRequest, Promise<Response>>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import defu from "defu";
|
|
2
2
|
import { mergeResolvers, mergeTypeDefs } from "@graphql-tools/merge";
|
|
3
3
|
import { importedConfig } from "#nitro-internal-virtual/graphql-config";
|
|
4
|
+
import { directives } from "#nitro-internal-virtual/server-directives";
|
|
4
5
|
import { resolvers } from "#nitro-internal-virtual/server-resolvers";
|
|
5
6
|
import { schemas } from "#nitro-internal-virtual/server-schemas";
|
|
7
|
+
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
6
8
|
import { defineEventHandler, toWebRequest } from "h3";
|
|
7
|
-
import {
|
|
9
|
+
import { createYoga } from "graphql-yoga";
|
|
8
10
|
|
|
9
11
|
//#region src/routes/graphql-yoga.ts
|
|
10
12
|
const apolloSandboxHtml = `<!DOCTYPE html>
|
|
@@ -26,13 +28,17 @@ new window.EmbeddedSandbox({
|
|
|
26
28
|
</html>`;
|
|
27
29
|
function createMergedSchema() {
|
|
28
30
|
try {
|
|
29
|
-
const mergedSchemas = schemas.map((schema) => schema.def).join("\n\n");
|
|
31
|
+
const mergedSchemas = schemas.map((schema$1) => schema$1.def).join("\n\n");
|
|
30
32
|
const typeDefs = mergeTypeDefs([mergedSchemas]);
|
|
31
33
|
const mergedResolvers = mergeResolvers(resolvers.map((r) => r.resolver));
|
|
32
|
-
|
|
34
|
+
let schema = makeExecutableSchema({
|
|
33
35
|
typeDefs,
|
|
34
36
|
resolvers: mergedResolvers
|
|
35
37
|
});
|
|
38
|
+
if (directives && directives.length > 0) {
|
|
39
|
+
for (const { directive } of directives) if (directive.transformer) schema = directive.transformer(schema);
|
|
40
|
+
}
|
|
41
|
+
return schema;
|
|
36
42
|
} catch (error) {
|
|
37
43
|
console.error("Schema merge error:", error);
|
|
38
44
|
throw error;
|
package/dist/routes/health.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h34 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/health.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h34.EventHandler<h34.EventHandlerRequest, Promise<{
|
|
5
5
|
status: string;
|
|
6
6
|
message: string;
|
|
7
7
|
timestamp: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ type CodegenClientConfig = TypeScriptPluginConfig & TypeScriptDocumentsPluginCon
|
|
|
20
20
|
interface IESMImport {
|
|
21
21
|
name: string;
|
|
22
22
|
as?: string;
|
|
23
|
-
type: 'resolver' | 'query' | 'mutation' | 'type' | 'subscription';
|
|
23
|
+
type: 'resolver' | 'query' | 'mutation' | 'type' | 'subscription' | 'directive';
|
|
24
24
|
}
|
|
25
25
|
interface GenImport {
|
|
26
26
|
specifier: string;
|
|
@@ -32,6 +32,7 @@ declare module 'nitropack/types' {
|
|
|
32
32
|
scanSchemas: string[];
|
|
33
33
|
scanDocuments: string[];
|
|
34
34
|
scanResolvers: GenImport[];
|
|
35
|
+
scanDirectives: GenImport[];
|
|
35
36
|
graphql: {
|
|
36
37
|
buildDir: string;
|
|
37
38
|
watchDirs: string[];
|
package/dist/utils/define.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GraphQLSchema } from "graphql";
|
|
1
2
|
import { ApolloServerOptions } from "@apollo/server";
|
|
2
3
|
import { H3Event } from "h3";
|
|
3
4
|
import { YogaServerOptions } from "graphql-yoga";
|
|
@@ -17,5 +18,55 @@ declare function defineSubscription(resolvers?: Resolvers['Subscription']): Reso
|
|
|
17
18
|
declare function defineType(resolvers: Resolvers): Resolvers;
|
|
18
19
|
type DefineServerConfig<T extends NPMConfig = NPMConfig> = T['framework'] extends 'graphql-yoga' ? Partial<YogaServerOptions<H3Event, Partial<H3Event>>> : T['framework'] extends 'apollo-server' ? Partial<ApolloServerOptions<H3Event>> : Partial<YogaServerOptions<H3Event, Partial<H3Event>>> | Partial<ApolloServerOptions<H3Event>>;
|
|
19
20
|
declare function defineGraphQLConfig<T extends NPMConfig = NPMConfig>(config: Partial<DefineServerConfig<T>>): Partial<DefineServerConfig<T>>;
|
|
21
|
+
type DirectiveLocationName = 'QUERY' | 'MUTATION' | 'SUBSCRIPTION' | 'FIELD' | 'FRAGMENT_DEFINITION' | 'FRAGMENT_SPREAD' | 'INLINE_FRAGMENT' | 'VARIABLE_DEFINITION' | 'SCHEMA' | 'SCALAR' | 'OBJECT' | 'FIELD_DEFINITION' | 'ARGUMENT_DEFINITION' | 'INTERFACE' | 'UNION' | 'ENUM' | 'ENUM_VALUE' | 'INPUT_OBJECT' | 'INPUT_FIELD_DEFINITION';
|
|
22
|
+
type GraphQLScalarType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'JSON' | 'DateTime';
|
|
23
|
+
type GraphQLBaseType = GraphQLScalarType | (string & {});
|
|
24
|
+
type GraphQLArgumentType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'JSON' | 'DateTime' | 'String!' | 'Int!' | 'Float!' | 'Boolean!' | 'ID!' | 'JSON!' | 'DateTime!' | '[String]' | '[String!]' | '[String]!' | '[String!]!' | '[Int]' | '[Int!]' | '[Int]!' | '[Int!]!' | '[Float]' | '[Float!]' | '[Float]!' | '[Float!]!' | '[Boolean]' | '[Boolean!]' | '[Boolean]!' | '[Boolean!]!' | '[ID]' | '[ID!]' | '[ID]!' | '[ID!]!' | '[JSON]' | '[JSON!]' | '[JSON]!' | '[JSON!]!' | '[DateTime]' | '[DateTime!]' | '[DateTime]!' | '[DateTime!]!' | (string & {});
|
|
25
|
+
interface DirectiveArgument<T extends GraphQLArgumentType = GraphQLArgumentType> {
|
|
26
|
+
/**
|
|
27
|
+
* GraphQL type for the argument
|
|
28
|
+
* @example 'String', 'Int!', '[String!]!', 'DateTime', 'JSON'
|
|
29
|
+
*/
|
|
30
|
+
type: T;
|
|
31
|
+
defaultValue?: any;
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
interface DirectiveArg {
|
|
35
|
+
type: GraphQLArgumentType;
|
|
36
|
+
defaultValue?: any;
|
|
37
|
+
description?: string;
|
|
38
|
+
}
|
|
39
|
+
interface DirectiveDefinition {
|
|
40
|
+
name: string;
|
|
41
|
+
locations: DirectiveLocationName[];
|
|
42
|
+
args?: Record<string, DirectiveArg>;
|
|
43
|
+
description?: string;
|
|
44
|
+
isRepeatable?: boolean;
|
|
45
|
+
transformer?: (schema: GraphQLSchema) => GraphQLSchema;
|
|
46
|
+
}
|
|
47
|
+
interface DefineDirectiveConfig {
|
|
48
|
+
name: string;
|
|
49
|
+
locations: ReadonlyArray<DirectiveLocationName>;
|
|
50
|
+
args?: Record<string, {
|
|
51
|
+
type: GraphQLArgumentType;
|
|
52
|
+
defaultValue?: any;
|
|
53
|
+
description?: string;
|
|
54
|
+
}>;
|
|
55
|
+
description?: string;
|
|
56
|
+
isRepeatable?: boolean;
|
|
57
|
+
transformer?: (schema: GraphQLSchema) => GraphQLSchema;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Helper function to create directive arguments with proper type inference
|
|
61
|
+
* @example
|
|
62
|
+
* args: {
|
|
63
|
+
* myArg: arg('String!', { defaultValue: 'hello' })
|
|
64
|
+
* }
|
|
65
|
+
*/
|
|
66
|
+
declare function arg<T extends GraphQLArgumentType>(type: T, options?: {
|
|
67
|
+
defaultValue?: any;
|
|
68
|
+
description?: string;
|
|
69
|
+
}): DirectiveArgument<T>;
|
|
70
|
+
declare function defineDirective(config: DefineDirectiveConfig): DirectiveDefinition;
|
|
20
71
|
//#endregion
|
|
21
|
-
export { DefineServerConfig, ResolverQuery, defineGraphQLConfig, defineMutation, defineQuery, defineResolver, defineSchema, defineSubscription, defineType };
|
|
72
|
+
export { DefineDirectiveConfig, DefineServerConfig, DirectiveArgument, DirectiveDefinition, GraphQLArgumentType, GraphQLBaseType, GraphQLScalarType, ResolverQuery, arg, defineDirective, defineGraphQLConfig, defineMutation, defineQuery, defineResolver, defineSchema, defineSubscription, defineType };
|
package/dist/utils/define.js
CHANGED
|
@@ -20,6 +20,38 @@ function defineType(resolvers) {
|
|
|
20
20
|
function defineGraphQLConfig(config) {
|
|
21
21
|
return config;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Helper function to create directive arguments with proper type inference
|
|
25
|
+
* @example
|
|
26
|
+
* args: {
|
|
27
|
+
* myArg: arg('String!', { defaultValue: 'hello' })
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
function arg(type, options) {
|
|
31
|
+
return {
|
|
32
|
+
type,
|
|
33
|
+
...options
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function defineDirective(config) {
|
|
37
|
+
const args = config.args ? Object.entries(config.args).map(([name, arg$1]) => {
|
|
38
|
+
const defaultValue = arg$1.defaultValue !== void 0 ? ` = ${JSON.stringify(arg$1.defaultValue)}` : "";
|
|
39
|
+
return `${name}: ${arg$1.type}${defaultValue}`;
|
|
40
|
+
}).join(", ") : "";
|
|
41
|
+
const argsString = args ? `(${args})` : "";
|
|
42
|
+
const locations = config.locations.join(" | ");
|
|
43
|
+
const schemaDefinition = `directive @${config.name}${argsString} on ${locations}`;
|
|
44
|
+
Object.defineProperty(config, "__schema", {
|
|
45
|
+
value: schemaDefinition,
|
|
46
|
+
enumerable: false,
|
|
47
|
+
configurable: false,
|
|
48
|
+
writable: false
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
...config,
|
|
52
|
+
locations: [...config.locations]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
23
55
|
|
|
24
56
|
//#endregion
|
|
25
|
-
export { defineGraphQLConfig, defineMutation, defineQuery, defineResolver, defineSchema, defineSubscription, defineType };
|
|
57
|
+
export { arg, defineDirective, defineGraphQLConfig, defineMutation, defineQuery, defineResolver, defineSchema, defineSubscription, defineType };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ declare function getImportId(p: string, lazy?: boolean): string;
|
|
|
7
7
|
declare function relativeWithDot(from: string, to: string): string;
|
|
8
8
|
declare function scanGraphql(nitro: Nitro): Promise<string[]>;
|
|
9
9
|
declare function scanResolvers(nitro: Nitro): Promise<GenImport[]>;
|
|
10
|
-
declare function scanDirectives(nitro: Nitro): Promise<
|
|
10
|
+
declare function scanDirectives(nitro: Nitro): Promise<GenImport[]>;
|
|
11
11
|
declare function scanTypeDefs(nitro: Nitro): Promise<string[]>;
|
|
12
12
|
declare function scanSchemas(nitro: Nitro): Promise<string[]>;
|
|
13
13
|
declare function scanDocs(nitro: Nitro): Promise<string[]>;
|
package/dist/utils/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { join, relative } from "pathe";
|
|
2
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join, relative } from "pathe";
|
|
3
3
|
import { hash } from "ohash";
|
|
4
4
|
import { parseAsync } from "oxc-parser";
|
|
5
5
|
import { glob } from "tinyglobby";
|
|
@@ -56,6 +56,11 @@ async function scanResolvers(nitro) {
|
|
|
56
56
|
type: "subscription",
|
|
57
57
|
as: `_${hash(decl.id.name + file.path).replace(/-/g, "").slice(0, 6)}`
|
|
58
58
|
});
|
|
59
|
+
if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
|
|
60
|
+
name: decl.id.name,
|
|
61
|
+
type: "directive",
|
|
62
|
+
as: `_${hash(decl.id.name + file.path).replace(/-/g, "").slice(0, 6)}`
|
|
63
|
+
});
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
}
|
|
@@ -65,7 +70,28 @@ async function scanResolvers(nitro) {
|
|
|
65
70
|
}
|
|
66
71
|
async function scanDirectives(nitro) {
|
|
67
72
|
const files = await scanFiles(nitro, "graphql", "**/*.directive.{ts,js}");
|
|
68
|
-
|
|
73
|
+
const exportName = [];
|
|
74
|
+
for (const file of files) {
|
|
75
|
+
const fileContent = await readFile(file.fullPath, "utf-8");
|
|
76
|
+
const parsed = await parseAsync(file.fullPath, fileContent);
|
|
77
|
+
const exports = {
|
|
78
|
+
imports: [],
|
|
79
|
+
specifier: file.fullPath
|
|
80
|
+
};
|
|
81
|
+
for (const node of parsed.program.body) if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
|
|
82
|
+
for (const decl of node.declaration.declarations) if (decl.type === "VariableDeclarator" && decl.init && decl.id.type === "Identifier") {
|
|
83
|
+
if (decl.init && decl.init.type === "CallExpression") {
|
|
84
|
+
if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
|
|
85
|
+
name: decl.id.name,
|
|
86
|
+
type: "directive",
|
|
87
|
+
as: `_${hash(decl.id.name + file.path).replace(/-/g, "").slice(0, 6)}`
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (exports.imports.length > 0) exportName.push(exports);
|
|
93
|
+
}
|
|
94
|
+
return exportName;
|
|
69
95
|
}
|
|
70
96
|
async function scanTypeDefs(nitro) {
|
|
71
97
|
const files = await scanFiles(nitro, "graphql", "**/*.typedef.{ts,js}");
|