nitro-graphql 1.4.4 → 1.5.0

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.
@@ -49,50 +49,78 @@ async function scanGraphql(nitro) {
49
49
  async function scanResolvers(nitro) {
50
50
  const files = await scanFiles(nitro, "graphql", "**/*.resolver.{ts,js}");
51
51
  const exportName = [];
52
- for (const file of files) {
52
+ const VALID_DEFINE_FUNCTIONS = [
53
+ "defineResolver",
54
+ "defineQuery",
55
+ "defineMutation",
56
+ "defineType",
57
+ "defineSubscription",
58
+ "defineDirective"
59
+ ];
60
+ for (const file of files) try {
53
61
  const fileContent = await readFile(file.fullPath, "utf-8");
54
62
  const parsed = await parseAsync(file.fullPath, fileContent);
55
63
  const exports = {
56
64
  imports: [],
57
65
  specifier: file.fullPath
58
66
  };
59
- for (const node of parsed.program.body) if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
60
- for (const decl of node.declaration.declarations) if (decl.type === "VariableDeclarator" && decl.init && decl.id.type === "Identifier") {
61
- if (decl.init && decl.init.type === "CallExpression") {
62
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineResolver") exports.imports.push({
63
- name: decl.id.name,
64
- type: "resolver",
65
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
66
- });
67
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineQuery") exports.imports.push({
68
- name: decl.id.name,
69
- type: "query",
70
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
71
- });
72
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineMutation") exports.imports.push({
73
- name: decl.id.name,
74
- type: "mutation",
75
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
76
- });
77
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineType") exports.imports.push({
78
- name: decl.id.name,
79
- type: "type",
80
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
81
- });
82
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineSubscription") exports.imports.push({
83
- name: decl.id.name,
84
- type: "subscription",
85
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
86
- });
87
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
88
- name: decl.id.name,
89
- type: "directive",
90
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
91
- });
67
+ let hasDefaultExport = false;
68
+ let hasNamedExport = false;
69
+ const namedExports = [];
70
+ for (const node of parsed.program.body) {
71
+ if (node.type === "ExportDefaultDeclaration") hasDefaultExport = true;
72
+ if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
73
+ for (const decl of node.declaration.declarations) if (decl.type === "VariableDeclarator" && decl.init && decl.id.type === "Identifier") {
74
+ hasNamedExport = true;
75
+ namedExports.push(decl.id.name);
76
+ if (decl.init && decl.init.type === "CallExpression") {
77
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineResolver") exports.imports.push({
78
+ name: decl.id.name,
79
+ type: "resolver",
80
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
81
+ });
82
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineQuery") exports.imports.push({
83
+ name: decl.id.name,
84
+ type: "query",
85
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
86
+ });
87
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineMutation") exports.imports.push({
88
+ name: decl.id.name,
89
+ type: "mutation",
90
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
91
+ });
92
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineType") exports.imports.push({
93
+ name: decl.id.name,
94
+ type: "type",
95
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
96
+ });
97
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineSubscription") exports.imports.push({
98
+ name: decl.id.name,
99
+ type: "subscription",
100
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
101
+ });
102
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
103
+ name: decl.id.name,
104
+ type: "directive",
105
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
106
+ });
107
+ }
92
108
  }
93
109
  }
94
110
  }
111
+ if (nitro.options.dev) {
112
+ const relPath = relative(nitro.options.rootDir, file.fullPath);
113
+ if (hasDefaultExport && !hasNamedExport) nitro.logger.warn(`[nitro-graphql] ${relPath}: Using default export instead of named export. Resolvers must use named exports like "export const myResolver = defineQuery(...)". Default exports are not detected.`);
114
+ if (exports.imports.length === 0 && hasNamedExport) {
115
+ const validFunctions = VALID_DEFINE_FUNCTIONS.join(", ");
116
+ nitro.logger.warn(`[nitro-graphql] ${relPath}: File has named exports [${namedExports.join(", ")}] but none use the required define functions (${validFunctions}). Exports will not be registered.`);
117
+ }
118
+ if (!hasDefaultExport && !hasNamedExport) nitro.logger.warn(`[nitro-graphql] ${relPath}: No exports found. Resolver files must export resolvers using defineResolver, defineQuery, defineMutation, etc.`);
119
+ }
95
120
  if (exports.imports.length > 0) exportName.push(exports);
121
+ } catch (error) {
122
+ const relPath = relative(nitro.options.rootDir, file.fullPath);
123
+ nitro.logger.error(`[nitro-graphql] Failed to parse resolver file ${relPath}:`, error);
96
124
  }
97
125
  return exportName;
98
126
  }
@@ -143,9 +171,7 @@ async function scanDocs(nitro) {
143
171
  const relativePath = f.path;
144
172
  for (const pattern of externalPatterns) {
145
173
  const clientDirPattern = `${nitro.graphql.dir.client}/`;
146
- const patternDir = pattern.replace(/* @__PURE__ */ new RegExp(`^${clientDirPattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), "").split("/")[0];
147
- const fileDir = relativePath.split("/")[0];
148
- if (patternDir === fileDir) return false;
174
+ if (pattern.replace(/* @__PURE__ */ new RegExp(`^${clientDirPattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), "").split("/")[0] === relativePath.split("/")[0]) return false;
149
175
  }
150
176
  return true;
151
177
  }).map((f) => f.fullPath);
@@ -21,7 +21,7 @@ function pluginContent(_schema, _documents, _config, _info) {
21
21
  };
22
22
  }
23
23
  async function generateTypes(selectFremework, schema, config = {}, outputPath) {
24
- const defaultConfig = {
24
+ const mergedConfig = defu$1({
25
25
  scalars: {
26
26
  DateTime: DateTimeResolver.extensions.codegenScalarType,
27
27
  DateTimeISO: DateTimeISOResolver.extensions.codegenScalarType,
@@ -43,8 +43,7 @@ async function generateTypes(selectFremework, schema, config = {}, outputPath) {
43
43
  declarationKind: "interface",
44
44
  enumsAsTypes: true,
45
45
  ...config.federation?.enabled && { federation: true }
46
- };
47
- const mergedConfig = defu$1(defaultConfig, config.codegen?.server);
46
+ }, config.codegen?.server);
48
47
  return await codegen({
49
48
  filename: outputPath || "types.generated.ts",
50
49
  schema: parse(printSchemaWithDirectives(schema)),
@@ -61,7 +61,7 @@ function generateExternalOfetchClient(clientDir, serviceName, endpoint) {
61
61
  if (!existsSync(serviceDir)) mkdirSync(serviceDir, { recursive: true });
62
62
  if (!existsSync(ofetchPath)) {
63
63
  const capitalizedServiceName = serviceName.charAt(0).toUpperCase() + serviceName.slice(1);
64
- const ofetchContent = `// This file is auto-generated once by nitro-graphql for quick start
64
+ writeFileSync(ofetchPath, `// This file is auto-generated once by nitro-graphql for quick start
65
65
  // You can modify this file according to your needs
66
66
  import type { Sdk, Requester } from './sdk'
67
67
  import { getSdk } from './sdk'
@@ -83,8 +83,7 @@ export function create${capitalizedServiceName}GraphQLClient(endpoint: string =
83
83
  }
84
84
  }
85
85
 
86
- export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedServiceName}GraphQLClient())`;
87
- writeFileSync(ofetchPath, ofetchContent, "utf-8");
86
+ export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedServiceName}GraphQLClient())`, "utf-8");
88
87
  }
89
88
  }
90
89
  /**
@@ -251,8 +250,7 @@ async function generateMainClientTypes(nitro) {
251
250
  return;
252
251
  }
253
252
  const graphqlString = readFileSync(schemaFilePath, "utf-8");
254
- const schema = nitro.options.graphql?.federation?.enabled === true ? buildSubgraphSchema([{ typeDefs: parse(graphqlString) }]) : buildSchema(graphqlString);
255
- const types = await generateClientTypes(schema, loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {});
253
+ const types = await generateClientTypes(nitro.options.graphql?.federation?.enabled === true ? buildSubgraphSchema([{ typeDefs: parse(graphqlString) }]) : buildSchema(graphqlString), loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {});
256
254
  if (types === false) return;
257
255
  const clientTypesPath = resolve(nitro.options.buildDir, "types", "nitro-graphql-client.d.ts");
258
256
  const defaultServiceDir = resolve(nitro.graphql.clientDir, "default");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "1.4.4",
4
+ "version": "1.5.0",
5
5
  "description": "GraphQL integration for Nitro",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
@@ -78,13 +78,13 @@
78
78
  }
79
79
  },
80
80
  "dependencies": {
81
- "@apollo/subgraph": "^2.11.2",
81
+ "@apollo/subgraph": "^2.11.3",
82
82
  "@graphql-codegen/core": "^5.0.0",
83
83
  "@graphql-codegen/import-types-preset": "^3.0.1",
84
- "@graphql-codegen/typescript": "^5.0.1",
84
+ "@graphql-codegen/typescript": "^5.0.2",
85
85
  "@graphql-codegen/typescript-generic-sdk": "^4.0.2",
86
- "@graphql-codegen/typescript-operations": "^5.0.1",
87
- "@graphql-codegen/typescript-resolvers": "^5.0.1",
86
+ "@graphql-codegen/typescript-operations": "^5.0.2",
87
+ "@graphql-codegen/typescript-resolvers": "^5.1.0",
88
88
  "@graphql-tools/graphql-file-loader": "^8.1.2",
89
89
  "@graphql-tools/load": "^8.1.2",
90
90
  "@graphql-tools/load-files": "^7.0.1",
@@ -96,27 +96,27 @@
96
96
  "consola": "^3.4.2",
97
97
  "defu": "^6.1.4",
98
98
  "graphql-config": "^5.1.5",
99
- "graphql-scalars": "^1.24.2",
99
+ "graphql-scalars": "^1.25.0",
100
100
  "knitwork": "^1.2.0",
101
101
  "ohash": "^2.0.11",
102
- "oxc-parser": "^0.93.0",
102
+ "oxc-parser": "^0.95.0",
103
103
  "pathe": "^2.0.3",
104
104
  "tinyglobby": "^0.2.15"
105
105
  },
106
106
  "devDependencies": {
107
- "@antfu/eslint-config": "^5.4.1",
108
- "@nuxt/kit": "^4.1.2",
109
- "@nuxt/schema": "^4.1.2",
110
- "@types/node": "^24.6.2",
111
- "bumpp": "^10.2.3",
107
+ "@antfu/eslint-config": "^6.0.0",
108
+ "@nuxt/kit": "^4.1.3",
109
+ "@nuxt/schema": "^4.1.3",
110
+ "@types/node": "^24.9.1",
111
+ "bumpp": "^10.3.1",
112
112
  "changelogen": "^0.6.2",
113
113
  "crossws": "0.3.5",
114
- "eslint": "^9.37.0",
114
+ "eslint": "^9.38.0",
115
115
  "graphql": "16.11.0",
116
116
  "graphql-yoga": "^5.16.0",
117
117
  "h3": "1.15.3",
118
- "nitropack": "^2.12.6",
119
- "tsdown": "^0.15.6",
118
+ "nitropack": "^2.12.7",
119
+ "tsdown": "^0.15.9",
120
120
  "typescript": "^5.9.3"
121
121
  },
122
122
  "resolutions": {