nitro-graphql 2.0.0-beta.30 → 2.0.0-beta.32
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 +3 -3
- package/dist/codegen/client-types.d.mts +13 -0
- package/dist/codegen/client-types.mjs +176 -0
- package/dist/codegen/external-types.d.mts +12 -0
- package/dist/codegen/external-types.mjs +129 -0
- package/dist/codegen/index.d.mts +25 -0
- package/dist/codegen/index.mjs +38 -0
- package/dist/codegen/server-types.d.mts +13 -0
- package/dist/codegen/server-types.mjs +76 -0
- package/dist/codegen/validation.d.mts +13 -0
- package/dist/codegen/validation.mjs +96 -0
- package/dist/config/defaults.mjs +36 -0
- package/dist/constants.mjs +91 -0
- package/dist/define.d.mts +3 -3
- package/dist/define.mjs +3 -3
- package/dist/ecosystem/nuxt.mjs +3 -3
- package/dist/rollup.d.mts +7 -7
- package/dist/rollup.mjs +73 -73
- package/dist/routes/apollo-server.d.mts +2 -2
- package/dist/routes/debug.d.mts +2 -2
- package/dist/routes/graphql-yoga.d.mts +2 -2
- package/dist/routes/health.d.mts +2 -2
- package/dist/setup/file-watcher.mjs +80 -0
- package/dist/setup/rollup-integration.mjs +90 -0
- package/dist/setup/scaffold-generator.mjs +109 -0
- package/dist/setup/ts-config.mjs +69 -0
- package/dist/setup.d.mts +2 -2
- package/dist/setup.mjs +127 -290
- package/dist/types/index.d.mts +1 -1
- package/dist/utils/client-codegen.d.mts +1 -1
- package/dist/utils/client-codegen.mjs +5 -2
- package/dist/utils/directive-parser.d.mts +2 -1
- package/dist/utils/directive-parser.mjs +4 -2
- package/dist/utils/file-generator.mjs +1 -1
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +12 -11
- package/dist/utils/path-resolver.d.mts +2 -2
- package/dist/utils/path-resolver.mjs +2 -2
- package/dist/utils/server-codegen.mjs +4 -1
- package/dist/utils/type-generation.d.mts +6 -12
- package/dist/utils/type-generation.mjs +6 -419
- package/package.json +10 -4
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { CHUNK_NAME_RESOLVERS, CHUNK_NAME_SCHEMAS, CHUNK_PATH_GRAPHQL, CHUNK_PATH_UNKNOWN, GRAPHQL_EXTENSIONS, RESOLVER_EXTENSIONS } from "../constants.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/setup/rollup-integration.ts
|
|
4
|
+
/**
|
|
5
|
+
* Setup Rollup/Rolldown chunking configuration for GraphQL files
|
|
6
|
+
* Creates separate chunks for schemas and resolvers to optimize bundle size
|
|
7
|
+
*/
|
|
8
|
+
function setupRollupChunking(nitro) {
|
|
9
|
+
nitro.hooks.hook("rollup:before", (_, rollupConfig) => {
|
|
10
|
+
const manualChunks = rollupConfig.output?.manualChunks;
|
|
11
|
+
const chunkFiles = rollupConfig.output?.chunkFileNames;
|
|
12
|
+
if (!rollupConfig.output.inlineDynamicImports) {
|
|
13
|
+
rollupConfig.output.manualChunks = (id, _meta) => {
|
|
14
|
+
if (isGraphQLFile(id)) return getSchemaChunkName(id);
|
|
15
|
+
if (isResolverFile(id)) return getResolverChunkName(id);
|
|
16
|
+
if (typeof manualChunks === "function") return manualChunks(id, meta);
|
|
17
|
+
};
|
|
18
|
+
rollupConfig.output.advancedChunks = {
|
|
19
|
+
groups: [{
|
|
20
|
+
name: CHUNK_NAME_SCHEMAS,
|
|
21
|
+
test: /* @__PURE__ */ new RegExp(`\\.(${GRAPHQL_EXTENSIONS.map((e) => e.slice(1)).join("|")})$`)
|
|
22
|
+
}, {
|
|
23
|
+
name: CHUNK_NAME_RESOLVERS,
|
|
24
|
+
test: /\.resolver\.(ts|js)$/
|
|
25
|
+
}],
|
|
26
|
+
minSize: 0,
|
|
27
|
+
minShareCount: 1
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
rollupConfig.output.chunkFileNames = (chunkInfo) => {
|
|
31
|
+
if (chunkInfo.moduleIds && chunkInfo.moduleIds.some((id) => isGraphQLFile(id) || isResolverFile(id))) return CHUNK_PATH_GRAPHQL;
|
|
32
|
+
if (typeof chunkFiles === "function") return chunkFiles(chunkInfo);
|
|
33
|
+
return CHUNK_PATH_UNKNOWN;
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if a file is a GraphQL schema file
|
|
39
|
+
*/
|
|
40
|
+
function isGraphQLFile(id) {
|
|
41
|
+
return GRAPHQL_EXTENSIONS.some((ext) => id.endsWith(ext));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a file is a resolver file
|
|
45
|
+
*/
|
|
46
|
+
function isResolverFile(id) {
|
|
47
|
+
return RESOLVER_EXTENSIONS.some((ext) => id.endsWith(ext));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get chunk name for GraphQL schema files
|
|
51
|
+
* All schemas are bundled into a single chunk since GraphQL server
|
|
52
|
+
* merges them at runtime anyway - no benefit from separate chunks
|
|
53
|
+
*/
|
|
54
|
+
function getSchemaChunkName(_id) {
|
|
55
|
+
return CHUNK_NAME_SCHEMAS;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get chunk name for resolver files
|
|
59
|
+
* All resolvers are bundled into a single chunk since GraphQL server
|
|
60
|
+
* requires all resolvers to be registered at startup - no runtime lazy loading
|
|
61
|
+
*/
|
|
62
|
+
function getResolverChunkName(_id) {
|
|
63
|
+
return CHUNK_NAME_RESOLVERS;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Configure external dependencies for Rollup
|
|
67
|
+
* Marks codegen and federation packages as external
|
|
68
|
+
*/
|
|
69
|
+
function setupRollupExternals(nitro) {
|
|
70
|
+
nitro.hooks.hook("rollup:before", (_, rollupConfig) => {
|
|
71
|
+
rollupConfig.external = rollupConfig.external || [];
|
|
72
|
+
const allExternals = [...["oxc-parser", "@oxc-parser"]];
|
|
73
|
+
if (!nitro.options.graphql?.federation?.enabled) allExternals.push(...[
|
|
74
|
+
"@apollo/subgraph",
|
|
75
|
+
"@apollo/federation-internals",
|
|
76
|
+
"@apollo/cache-control-types"
|
|
77
|
+
]);
|
|
78
|
+
if (Array.isArray(rollupConfig.external)) rollupConfig.external.push(...allExternals);
|
|
79
|
+
else if (typeof rollupConfig.external === "function") {
|
|
80
|
+
const originalExternal = rollupConfig.external;
|
|
81
|
+
rollupConfig.external = (id, parent, isResolved) => {
|
|
82
|
+
if (allExternals.some((external) => id.includes(external))) return true;
|
|
83
|
+
return originalExternal(id, parent, isResolved);
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
export { setupRollupChunking, setupRollupExternals };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { FILE_CONFIG_TS, FILE_CONTEXT_DTS, FILE_CONTEXT_TS, FILE_GRAPHQL_CONFIG, FILE_SCHEMA_TS, LOG_TAG } from "../constants.mjs";
|
|
2
|
+
import { relativeWithDot } from "../utils/index.mjs";
|
|
3
|
+
import { writeFileIfNotExists } from "../utils/file-generator.mjs";
|
|
4
|
+
import { getDefaultPaths, getScaffoldConfig, resolveFilePath, shouldGenerateScaffold } from "../utils/path-resolver.mjs";
|
|
5
|
+
import consola from "consola";
|
|
6
|
+
import { join, resolve } from "pathe";
|
|
7
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
8
|
+
|
|
9
|
+
//#region src/setup/scaffold-generator.ts
|
|
10
|
+
const logger = consola.withTag(LOG_TAG);
|
|
11
|
+
/**
|
|
12
|
+
* Generate all scaffold files based on configuration
|
|
13
|
+
* Can be disabled via: scaffold: false or scaffold.enabled: false
|
|
14
|
+
*/
|
|
15
|
+
function generateScaffoldFiles(nitro) {
|
|
16
|
+
if (!shouldGenerateScaffold(nitro)) {
|
|
17
|
+
logger.info("Scaffold file generation is disabled (library mode)");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const placeholders = getDefaultPaths(nitro);
|
|
21
|
+
const scaffoldConfig = getScaffoldConfig(nitro);
|
|
22
|
+
generateGraphQLConfig(nitro, scaffoldConfig, placeholders);
|
|
23
|
+
generateServerScaffoldFiles(nitro, scaffoldConfig, placeholders);
|
|
24
|
+
checkOldContextFile(nitro);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate graphql.config.ts for IDE tooling support
|
|
28
|
+
*/
|
|
29
|
+
function generateGraphQLConfig(nitro, scaffoldConfig, placeholders) {
|
|
30
|
+
const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, FILE_GRAPHQL_CONFIG, placeholders);
|
|
31
|
+
if (!graphqlConfigPath) return;
|
|
32
|
+
writeFileIfNotExists(graphqlConfigPath, `import type { IGraphQLConfig } from 'graphql-config'
|
|
33
|
+
|
|
34
|
+
export default <IGraphQLConfig> {
|
|
35
|
+
projects: {
|
|
36
|
+
default: {
|
|
37
|
+
schema: [
|
|
38
|
+
'${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.buildDir, "schema.graphql"))}',
|
|
39
|
+
],
|
|
40
|
+
documents: [
|
|
41
|
+
'${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.clientDir, "**/*.{graphql,js,ts,jsx,tsx}"))}',
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}`, FILE_GRAPHQL_CONFIG);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate server-side scaffold files (schema.ts, config.ts, context.d.ts)
|
|
49
|
+
*/
|
|
50
|
+
function generateServerScaffoldFiles(nitro, scaffoldConfig, placeholders) {
|
|
51
|
+
const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
|
|
52
|
+
const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
|
|
53
|
+
const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.d.ts", placeholders);
|
|
54
|
+
if (serverSchemaPath || serverConfigPath || serverContextPath) {
|
|
55
|
+
if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
if (serverSchemaPath) writeFileIfNotExists(serverSchemaPath, `export default defineSchema({
|
|
58
|
+
|
|
59
|
+
})
|
|
60
|
+
`, `server ${FILE_SCHEMA_TS}`);
|
|
61
|
+
if (serverConfigPath) writeFileIfNotExists(serverConfigPath, `// Example GraphQL config file please change it to your needs
|
|
62
|
+
// import * as tables from '../drizzle/schema/index'
|
|
63
|
+
// import { useDatabase } from '../utils/useDb'
|
|
64
|
+
import { defineGraphQLConfig } from 'nitro-graphql/define'
|
|
65
|
+
|
|
66
|
+
export default defineGraphQLConfig({
|
|
67
|
+
// graphql-yoga example config
|
|
68
|
+
// context: () => {
|
|
69
|
+
// return {
|
|
70
|
+
// context: {
|
|
71
|
+
// useDatabase,
|
|
72
|
+
// tables,
|
|
73
|
+
// },
|
|
74
|
+
// }
|
|
75
|
+
// },
|
|
76
|
+
})
|
|
77
|
+
`, `server ${FILE_CONFIG_TS}`);
|
|
78
|
+
if (serverContextPath) writeFileIfNotExists(serverContextPath, `// Example context definition - please change it to your needs
|
|
79
|
+
// import type { Database } from '../utils/useDb'
|
|
80
|
+
|
|
81
|
+
declare module 'nitro/h3' {
|
|
82
|
+
interface H3EventContext {
|
|
83
|
+
// Add your custom context properties here
|
|
84
|
+
// useDatabase: () => Database
|
|
85
|
+
// tables: typeof import('../drizzle/schema')
|
|
86
|
+
// auth?: {
|
|
87
|
+
// user?: {
|
|
88
|
+
// id: string
|
|
89
|
+
// role: 'admin' | 'user'
|
|
90
|
+
// }
|
|
91
|
+
// }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {}
|
|
96
|
+
`, `server ${FILE_CONTEXT_DTS}`);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check for old context.ts file and warn users to migrate to context.d.ts
|
|
100
|
+
*/
|
|
101
|
+
function checkOldContextFile(nitro) {
|
|
102
|
+
if (existsSync(join(nitro.graphql.serverDir, FILE_CONTEXT_TS))) {
|
|
103
|
+
logger.warn(`Found ${FILE_CONTEXT_TS} file. Please rename it to ${FILE_CONTEXT_DTS} for type-only definitions.`);
|
|
104
|
+
logger.info(`The context file should now be ${FILE_CONTEXT_DTS} instead of ${FILE_CONTEXT_TS}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
export { generateScaffoldFiles };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { relativeWithDot } from "../utils/index.mjs";
|
|
2
|
+
import { getDefaultPaths, getTypesConfig, resolveFilePath } from "../utils/path-resolver.mjs";
|
|
3
|
+
import { dirname, join, resolve } from "pathe";
|
|
4
|
+
|
|
5
|
+
//#region src/setup/ts-config.ts
|
|
6
|
+
/**
|
|
7
|
+
* Setup TypeScript path aliases for GraphQL types
|
|
8
|
+
* Called via nitro:config hook to extend tsconfig.json
|
|
9
|
+
*/
|
|
10
|
+
function setupTypeScriptPaths(nitro, types) {
|
|
11
|
+
const tsconfigDir = dirname(resolve(nitro.options.buildDir, nitro.options.typescript.tsconfigPath));
|
|
12
|
+
types.tsConfig ||= {};
|
|
13
|
+
types.tsConfig.compilerOptions ??= {};
|
|
14
|
+
types.tsConfig.compilerOptions.paths ??= {};
|
|
15
|
+
types.tsConfig.include = types.tsConfig.include || [];
|
|
16
|
+
const placeholders = getDefaultPaths(nitro);
|
|
17
|
+
const typesConfig = getTypesConfig(nitro);
|
|
18
|
+
setupServerTypesPath(nitro, types, tsconfigDir, placeholders, typesConfig);
|
|
19
|
+
setupClientTypesPath(nitro, types, tsconfigDir, placeholders, typesConfig);
|
|
20
|
+
setupSchemaPath(nitro, types, tsconfigDir);
|
|
21
|
+
setupExternalServicePaths(nitro, types, tsconfigDir, placeholders, typesConfig);
|
|
22
|
+
types.tsConfig.include.push(relativeWithDot(tsconfigDir, join(placeholders.typesDir, "graphql.d.ts")));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Setup #graphql/server path alias
|
|
26
|
+
*/
|
|
27
|
+
function setupServerTypesPath(nitro, types, tsconfigDir, placeholders, typesConfig) {
|
|
28
|
+
const serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
|
|
29
|
+
if (serverTypesPath) {
|
|
30
|
+
types.tsConfig.compilerOptions.paths["#graphql/server"] = [relativeWithDot(tsconfigDir, serverTypesPath)];
|
|
31
|
+
types.tsConfig.include.push(relativeWithDot(tsconfigDir, serverTypesPath));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Setup #graphql/client path alias
|
|
36
|
+
*/
|
|
37
|
+
function setupClientTypesPath(nitro, types, tsconfigDir, placeholders, typesConfig) {
|
|
38
|
+
const clientTypesPath = resolveFilePath(typesConfig.client, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client.d.ts", placeholders);
|
|
39
|
+
if (clientTypesPath) {
|
|
40
|
+
types.tsConfig.compilerOptions.paths["#graphql/client"] = [relativeWithDot(tsconfigDir, clientTypesPath)];
|
|
41
|
+
types.tsConfig.include.push(relativeWithDot(tsconfigDir, clientTypesPath));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Setup #graphql/schema path alias
|
|
46
|
+
*/
|
|
47
|
+
function setupSchemaPath(nitro, types, tsconfigDir) {
|
|
48
|
+
types.tsConfig.compilerOptions.paths["#graphql/schema"] = [relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, "schema.ts"))];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Setup #graphql/client/{serviceName} path aliases for external services
|
|
52
|
+
*/
|
|
53
|
+
function setupExternalServicePaths(nitro, types, tsconfigDir, placeholders, typesConfig) {
|
|
54
|
+
if (!nitro.options.graphql?.externalServices?.length) return;
|
|
55
|
+
for (const service of nitro.options.graphql.externalServices) {
|
|
56
|
+
const servicePlaceholders = {
|
|
57
|
+
...placeholders,
|
|
58
|
+
serviceName: service.name
|
|
59
|
+
};
|
|
60
|
+
const externalTypesPath = resolveFilePath(service.paths?.types ?? typesConfig.external, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client-{serviceName}.d.ts", servicePlaceholders);
|
|
61
|
+
if (externalTypesPath) {
|
|
62
|
+
types.tsConfig.compilerOptions.paths[`#graphql/client/${service.name}`] = [relativeWithDot(tsconfigDir, externalTypesPath)];
|
|
63
|
+
types.tsConfig.include.push(relativeWithDot(tsconfigDir, externalTypesPath));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { setupTypeScriptPaths };
|
package/dist/setup.d.mts
CHANGED
|
@@ -3,8 +3,8 @@ import { Nitro } from "nitro/types";
|
|
|
3
3
|
//#region src/setup.d.ts
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Main setup function for nitro-graphql
|
|
7
|
+
* Coordinates all initialization steps for the module
|
|
8
8
|
*/
|
|
9
9
|
declare function setupNitroGraphQL(nitro: Nitro): Promise<void>;
|
|
10
10
|
//#endregion
|