@soda-gql/config 0.0.9 → 0.2.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.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @soda-gql/config
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@soda-gql/config.svg)](https://www.npmjs.com/package/@soda-gql/config)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Configuration management for soda-gql tooling.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ bun add -D @soda-gql/config
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ### Basic Configuration
17
+
18
+ Create a `soda-gql.config.ts` file in your project root:
19
+
20
+ ```typescript
21
+ import { defineConfig } from "@soda-gql/config";
22
+
23
+ export default defineConfig({
24
+ outdir: "./src/graphql-system",
25
+ include: ["./src/**/*.ts"],
26
+ schemas: {
27
+ default: {
28
+ schema: "./schema.graphql",
29
+ runtimeAdapter: "./src/graphql-system/runtime-adapter.ts",
30
+ scalars: "./src/graphql-system/scalars.ts",
31
+ },
32
+ },
33
+ });
34
+ ```
35
+
36
+ ### Multi-Schema Configuration
37
+
38
+ ```typescript
39
+ import { defineConfig } from "@soda-gql/config";
40
+
41
+ export default defineConfig({
42
+ outdir: "./src/graphql-system",
43
+ include: ["./src/**/*.ts"],
44
+ schemas: {
45
+ users: {
46
+ schema: "./schemas/users.graphql",
47
+ runtimeAdapter: "./src/graphql-system/users/runtime-adapter.ts",
48
+ scalars: "./src/graphql-system/users/scalars.ts",
49
+ },
50
+ products: {
51
+ schema: "./schemas/products.graphql",
52
+ runtimeAdapter: "./src/graphql-system/products/runtime-adapter.ts",
53
+ scalars: "./src/graphql-system/products/scalars.ts",
54
+ },
55
+ },
56
+ });
57
+ ```
58
+
59
+ ## Configuration Options
60
+
61
+ | Option | Type | Required | Description |
62
+ |--------|------|----------|-------------|
63
+ | `outdir` | `string` | Yes | Output directory for generated GraphQL system |
64
+ | `include` | `string[]` | Yes | Glob patterns for files to analyze |
65
+ | `exclude` | `string[]` | No | Glob patterns for files to exclude |
66
+ | `schemas` | `object` | Yes | Schema configurations (see below) |
67
+ | `analyzer` | `"ts" \| "swc"` | No | TypeScript analyzer to use (default: `"ts"`) |
68
+ | `graphqlSystemAliases` | `string[]` | No | TSConfig path aliases for GraphQL system imports |
69
+ | `styles.importExtension` | `boolean` | No | Include `.js` extensions in generated imports |
70
+
71
+ ### Schema Configuration
72
+
73
+ Each schema entry requires:
74
+
75
+ | Option | Type | Description |
76
+ |--------|------|-------------|
77
+ | `schema` | `string` | Path to GraphQL schema file |
78
+ | `runtimeAdapter` | `string` | Path to runtime adapter module |
79
+ | `scalars` | `string` | Path to scalar definitions module |
80
+
81
+ ## Config File Formats
82
+
83
+ The following config file formats are supported (searched in order):
84
+
85
+ 1. `soda-gql.config.ts` (recommended)
86
+ 2. `soda-gql.config.mts`
87
+ 3. `soda-gql.config.js`
88
+ 4. `soda-gql.config.mjs`
89
+
90
+ ## API Reference
91
+
92
+ ### `defineConfig(config)`
93
+
94
+ Type-safe configuration helper:
95
+
96
+ ```typescript
97
+ import { defineConfig } from "@soda-gql/config";
98
+
99
+ export default defineConfig({
100
+ // Configuration with full TypeScript support
101
+ });
102
+ ```
103
+
104
+ ### `loadConfig(options?)`
105
+
106
+ Programmatically load configuration:
107
+
108
+ ```typescript
109
+ import { loadConfig } from "@soda-gql/config";
110
+
111
+ const result = await loadConfig({
112
+ configPath: "./custom-config.ts", // optional
113
+ });
114
+
115
+ if (result.isOk()) {
116
+ console.log(result.value);
117
+ }
118
+ ```
119
+
120
+ ## Related Packages
121
+
122
+ - [@soda-gql/cli](../cli) - Command-line interface
123
+ - [@soda-gql/codegen](../codegen) - Code generation engine
124
+
125
+ ## License
126
+
127
+ MIT
package/dist/index.cjs CHANGED
@@ -48,7 +48,6 @@ let node_module = require("node:module");
48
48
  let node_path_posix = require("node:path/posix");
49
49
  let node_vm = require("node:vm");
50
50
  let __swc_core = require("@swc/core");
51
- let node_url = require("node:url");
52
51
 
53
52
  //#region packages/config/src/errors.ts
54
53
  const configError = ({ code, message, filePath, cause }) => ({
@@ -80,10 +79,13 @@ function defineConfig(config) {
80
79
  }
81
80
  return SodaGqlConfigContainer.create(validated.value);
82
81
  }
82
+ const InjectConfigSchema = zod.default.union([zod.default.string().min(1), zod.default.object({
83
+ scalars: zod.default.string().min(1),
84
+ adapter: zod.default.string().min(1).optional()
85
+ })]);
83
86
  const SchemaConfigSchema = (0, __soda_gql_common.defineSchemaFor)()({
84
87
  schema: zod.default.string().min(1),
85
- runtimeAdapter: zod.default.string().min(1),
86
- scalars: zod.default.string().min(1)
88
+ inject: InjectConfigSchema
87
89
  });
88
90
  const StylesConfigSchema = (0, __soda_gql_common.defineSchemaFor)()({ importExtension: zod.default.boolean().optional() });
89
91
  const SodaGqlConfigSchema = (0, __soda_gql_common.defineSchemaFor)()({
@@ -168,6 +170,23 @@ function executeConfigFile(configPath) {
168
170
  //#endregion
169
171
  //#region packages/config/src/normalize.ts
170
172
  /**
173
+ * Normalize inject config to resolved object form.
174
+ * String form is converted to object with same path for all fields.
175
+ */
176
+ function normalizeInject(inject, configDir) {
177
+ if (typeof inject === "string") {
178
+ const resolvedPath = (0, node_path.resolve)(configDir, inject);
179
+ return {
180
+ scalars: resolvedPath,
181
+ adapter: resolvedPath
182
+ };
183
+ }
184
+ return {
185
+ scalars: (0, node_path.resolve)(configDir, inject.scalars),
186
+ ...inject.adapter ? { adapter: (0, node_path.resolve)(configDir, inject.adapter) } : {}
187
+ };
188
+ }
189
+ /**
171
190
  * Resolve and normalize config with defaults.
172
191
  * Paths in the config are resolved relative to the config file's directory.
173
192
  */
@@ -184,8 +203,7 @@ function normalizeConfig(config, configPath) {
184
203
  exclude: exclude.map((pattern) => (0, node_path.resolve)(configDir, pattern)),
185
204
  schemas: Object.fromEntries(Object.entries(config.schemas).map(([name, schemaConfig]) => [name, {
186
205
  schema: (0, node_path.resolve)(configDir, schemaConfig.schema),
187
- runtimeAdapter: (0, node_path.resolve)(configDir, schemaConfig.runtimeAdapter),
188
- scalars: (0, node_path.resolve)(configDir, schemaConfig.scalars)
206
+ inject: normalizeInject(schemaConfig.inject, configDir)
189
207
  }])),
190
208
  styles: { importExtension: config.styles?.importExtension ?? false },
191
209
  plugins: config.plugins ?? {}
@@ -237,7 +255,7 @@ function loadConfig(configPath) {
237
255
  } catch (error) {
238
256
  return (0, neverthrow.err)(configError({
239
257
  code: "CONFIG_LOAD_FAILED",
240
- message: `Failed to load config: ${error}`,
258
+ message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,
241
259
  filePath: resolvedPath,
242
260
  cause: error
243
261
  }));
@@ -251,72 +269,24 @@ function loadConfigFrom(dir) {
251
269
  return loadConfig(configPath ?? undefined);
252
270
  }
253
271
 
254
- //#endregion
255
- //#region packages/config/src/test-utils.ts
256
- /**
257
- * Get project root from this package location.
258
- * packages/config/src/test-utils.ts -> project root
259
- */
260
- const getProjectRoot = () => {
261
- return (0, node_url.fileURLToPath)(new URL("../../../", require("url").pathToFileURL(__filename).href));
262
- };
263
- /**
264
- * Create temporary config file with proper formatting.
265
- * Uses template literals to support functions, regex, etc.
266
- */
267
- async function withTempConfig(config, fn) {
268
- const projectRoot = getProjectRoot();
269
- const tmpDir = (0, node_path.join)(projectRoot, "tests/.tmp/config-test", `${Date.now()}`);
270
- (0, node_fs.mkdirSync)(tmpDir, { recursive: true });
271
- const configPath = (0, node_path.join)(tmpDir, "soda-gql.config.ts");
272
- const configContent = `
273
- import { defineConfig } from "@soda-gql/config";
274
-
275
- export default defineConfig(${JSON.stringify(config, null, 2)});
276
- `.trim();
277
- (0, node_fs.writeFileSync)(configPath, configContent);
278
- return fn(configPath).finally(() => {
279
- (0, node_fs.rmSync)(tmpDir, {
280
- recursive: true,
281
- force: true
282
- });
283
- });
284
- }
285
- /**
286
- * Simple temp config creation (without auto-cleanup).
287
- */
288
- function createTempConfigFile(dir, config) {
289
- const configPath = (0, node_path.join)(dir, "soda-gql.config.ts");
290
- const configContent = `
291
- import { defineConfig } from "@soda-gql/config";
292
-
293
- export default defineConfig(${JSON.stringify(config, null, 2)});
294
- `.trim();
295
- (0, node_fs.writeFileSync)(configPath, configContent);
296
- return configPath;
297
- }
298
-
299
272
  //#endregion
300
273
  //#region packages/config/src/index.ts
301
274
  var src_exports = /* @__PURE__ */ __export({
302
275
  configError: () => configError,
303
- createTempConfigFile: () => createTempConfigFile,
304
276
  defineConfig: () => defineConfig,
305
277
  findConfigFile: () => findConfigFile,
306
278
  loadConfig: () => loadConfig,
307
279
  loadConfigFrom: () => loadConfigFrom,
308
280
  normalizeConfig: () => normalizeConfig,
309
- validateConfig: () => validateConfig,
310
- withTempConfig: () => withTempConfig
281
+ validateConfig: () => validateConfig
311
282
  });
312
283
 
313
284
  //#endregion
314
285
  exports.configError = configError;
315
- exports.createTempConfigFile = createTempConfigFile;
316
286
  exports.defineConfig = defineConfig;
317
287
  exports.findConfigFile = findConfigFile;
318
288
  exports.loadConfig = loadConfig;
319
289
  exports.loadConfigFrom = loadConfigFrom;
320
290
  exports.normalizeConfig = normalizeConfig;
321
291
  exports.validateConfig = validateConfig;
322
- exports.withTempConfig = withTempConfig;
292
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["config: SodaGqlConfig","InjectConfigSchema: z.ZodType<InjectConfig>","z","mod: { exports: unknown }","require","configModule","Script","resolved: ResolvedSodaGqlConfig"],"sources":["../src/errors.ts","../src/helper.ts","../src/evaluation.ts","../src/normalize.ts","../src/loader.ts","../src/index.ts"],"sourcesContent":["export type ConfigErrorCode = \"CONFIG_NOT_FOUND\" | \"CONFIG_LOAD_FAILED\" | \"CONFIG_VALIDATION_FAILED\" | \"CONFIG_INVALID_PATH\";\n\nexport type ConfigError = {\n readonly code: ConfigErrorCode;\n readonly message: string;\n readonly filePath?: string;\n readonly cause?: unknown;\n};\n\nexport const configError = ({\n code,\n message,\n filePath,\n cause,\n}: {\n code: ConfigErrorCode;\n message: string;\n filePath?: string;\n cause?: unknown;\n}): ConfigError => ({\n code,\n message,\n filePath,\n cause,\n});\n","import { defineSchemaFor } from \"@soda-gql/common\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport z from \"zod\";\nimport { type ConfigError, configError } from \"./errors\";\nimport type { InjectConfig, SchemaConfig, SodaGqlConfig, StylesConfig } from \"./types\";\n\n/**\n * Thin wrapper class to simplify the validation of exported value from config file.\n * As we use SWC + VM to execute the config file, the exported value is not typed.\n * This wrapper class ensures the exported value is a valid soda-gql config object.\n */\nexport class SodaGqlConfigContainer {\n private constructor(public readonly config: SodaGqlConfig) {}\n\n public static create(config: SodaGqlConfig): SodaGqlConfigContainer {\n return new SodaGqlConfigContainer(config);\n }\n}\n\n/**\n * Type-safe helper for defining soda-gql configuration.\n * Supports both static and dynamic (async) configs.\n *\n * @example Static config with object inject\n * ```ts\n * import { defineConfig } from \"@soda-gql/config\";\n *\n * export default defineConfig({\n * outdir: \"./graphql-system\",\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * inject: { scalars: \"./scalars.ts\" },\n * },\n * },\n * });\n * ```\n *\n * @example Static config with string inject (single file)\n * ```ts\n * export default defineConfig({\n * outdir: \"./graphql-system\",\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * inject: \"./inject.ts\", // exports scalar, adapter?\n * },\n * },\n * });\n * ```\n */\nexport function defineConfig(config: SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: () => SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: SodaGqlConfig | (() => SodaGqlConfig)): SodaGqlConfigContainer {\n const validated = validateConfig(typeof config === \"function\" ? config() : config);\n if (validated.isErr()) {\n throw validated.error;\n }\n return SodaGqlConfigContainer.create(validated.value);\n}\n\n// InjectConfig is a union type (string | object), so we define the schema directly\n// rather than using defineSchemaFor which requires object types\nconst InjectConfigSchema: z.ZodType<InjectConfig> = z.union([\n z.string().min(1),\n z.object({\n scalars: z.string().min(1),\n adapter: z.string().min(1).optional(),\n }),\n]);\n\nconst SchemaConfigSchema = defineSchemaFor<SchemaConfig>()({\n schema: z.string().min(1),\n inject: InjectConfigSchema,\n});\n\nconst StylesConfigSchema = defineSchemaFor<StylesConfig>()({\n importExtension: z.boolean().optional(),\n});\n\nconst SodaGqlConfigSchema = defineSchemaFor<SodaGqlConfig>()({\n analyzer: z.enum([\"ts\", \"swc\"]).optional(),\n outdir: z.string().min(1),\n graphqlSystemAliases: z.array(z.string()).optional(),\n include: z.array(z.string().min(1)),\n exclude: z.array(z.string().min(1)).optional(),\n schemas: z.record(z.string(), SchemaConfigSchema),\n styles: StylesConfigSchema.optional(),\n plugins: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport function validateConfig(config: unknown): Result<SodaGqlConfig, ConfigError> {\n const result = SodaGqlConfigSchema.safeParse(config);\n\n if (!result.success) {\n return err(\n configError({\n code: \"CONFIG_VALIDATION_FAILED\",\n message: `Invalid config: ${result.error.message}`,\n }),\n );\n }\n\n return ok(result.data satisfies SodaGqlConfig);\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path/posix\";\nimport { Script } from \"node:vm\";\nimport { resolveRelativeImportWithExistenceCheck } from \"@soda-gql/common\";\nimport { transformSync } from \"@swc/core\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport { type ConfigError, configError } from \"./errors\";\nimport { SodaGqlConfigContainer } from \"./helper\";\n// TODO: split config package into definition and evaluation parts\nimport * as configModule from \"./index\";\nimport type { SodaGqlConfig } from \"./types\";\n\n/**\n * Load and execute TypeScript config file synchronously using SWC + VM.\n */\nexport function executeConfigFile(configPath: string): Result<SodaGqlConfig, ConfigError> {\n const filePath = resolve(configPath);\n try {\n // Read the config file\n const source = readFileSync(filePath, \"utf-8\");\n\n // Transform TypeScript to CommonJS using SWC\n const result = transformSync(source, {\n filename: filePath,\n jsc: {\n parser: {\n syntax: \"typescript\",\n },\n },\n module: {\n type: \"commonjs\",\n },\n sourceMaps: false,\n minify: false,\n });\n\n // Create CommonJS context\n const mod: { exports: unknown } = { exports: {} };\n\n const requireInner = createRequire(filePath);\n const require = (specifier: string) => {\n if (specifier === \"@soda-gql/config\") {\n return configModule;\n }\n\n // Handle external modules normally\n if (!specifier.startsWith(\".\")) {\n return requireInner(specifier);\n }\n\n // Resolve relative imports with existence check\n const resolvedPath = resolveRelativeImportWithExistenceCheck({ filePath, specifier });\n if (!resolvedPath) {\n throw new Error(`Module not found: ${specifier}`);\n }\n return requireInner(resolvedPath);\n };\n\n // Execute in VM context\n new Script(result.code, { filename: filePath }).runInNewContext({\n require,\n module: mod,\n exports: mod.exports,\n __dirname: dirname(filePath),\n __filename: filePath,\n console,\n process,\n });\n\n const config =\n mod.exports &&\n typeof mod.exports === \"object\" &&\n \"default\" in mod.exports &&\n mod.exports.default instanceof SodaGqlConfigContainer\n ? mod.exports.default.config\n : null;\n\n if (!config) {\n throw new Error(\"Invalid config module\");\n }\n\n return ok(config);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n filePath: filePath,\n cause: error,\n }),\n );\n }\n}\n","import { dirname, resolve } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { ok } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport type { InjectConfig, ResolvedInjectConfig, ResolvedSodaGqlConfig, SodaGqlConfig } from \"./types\";\n\n/**\n * Normalize inject config to resolved object form.\n * String form is converted to object with same path for all fields.\n */\nfunction normalizeInject(inject: InjectConfig, configDir: string): ResolvedInjectConfig {\n if (typeof inject === \"string\") {\n const resolvedPath = resolve(configDir, inject);\n return {\n scalars: resolvedPath,\n adapter: resolvedPath,\n };\n }\n return {\n scalars: resolve(configDir, inject.scalars),\n ...(inject.adapter ? { adapter: resolve(configDir, inject.adapter) } : {}),\n };\n}\n\n/**\n * Resolve and normalize config with defaults.\n * Paths in the config are resolved relative to the config file's directory.\n */\nexport function normalizeConfig(config: SodaGqlConfig, configPath: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configDir = dirname(configPath);\n // Default analyzer to \"ts\"\n const analyzer = config.analyzer ?? \"ts\";\n\n // Default graphqlSystemAliases to [\"@/graphql-system\"]\n const graphqlSystemAliases = config.graphqlSystemAliases ?? [\"@/graphql-system\"];\n\n // Default exclude to empty array\n const exclude = config.exclude ?? [];\n\n const resolved: ResolvedSodaGqlConfig = {\n analyzer,\n outdir: resolve(configDir, config.outdir),\n graphqlSystemAliases,\n include: config.include.map((pattern) => resolve(configDir, pattern)),\n exclude: exclude.map((pattern) => resolve(configDir, pattern)),\n schemas: Object.fromEntries(\n Object.entries(config.schemas).map(([name, schemaConfig]) => [\n name,\n {\n schema: resolve(configDir, schemaConfig.schema),\n inject: normalizeInject(schemaConfig.inject, configDir),\n },\n ]),\n ),\n styles: {\n importExtension: config.styles?.importExtension ?? false,\n },\n plugins: config.plugins ?? {},\n };\n\n return ok(resolved);\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { err } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport { configError } from \"./errors\";\nimport { executeConfigFile } from \"./evaluation\";\nimport { normalizeConfig } from \"./normalize\";\nimport type { ResolvedSodaGqlConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG_FILENAMES = [\n \"soda-gql.config.ts\",\n \"soda-gql.config.mts\",\n \"soda-gql.config.js\",\n \"soda-gql.config.mjs\",\n] as const;\n\n/**\n * Find config file by walking up directory tree.\n */\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n while (currentDir !== dirname(currentDir)) {\n for (const filename of DEFAULT_CONFIG_FILENAMES) {\n const configPath = join(currentDir, filename);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n return null;\n}\n\n/**\n * Load config with Result type (for library use).\n */\nexport function loadConfig(configPath: string | undefined): Result<ResolvedSodaGqlConfig, ConfigError> {\n const resolvedPath = configPath ?? findConfigFile();\n\n if (!resolvedPath) {\n return err(configError({ code: \"CONFIG_NOT_FOUND\", message: \"Config file not found\" }));\n }\n\n try {\n const result = executeConfigFile(resolvedPath);\n if (result.isErr()) {\n return err(result.error);\n }\n return normalizeConfig(result.value, resolvedPath);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n filePath: resolvedPath,\n cause: error,\n }),\n );\n }\n}\n\n/**\n * Load config from specific directory.\n */\nexport function loadConfigFrom(dir: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configPath = findConfigFile(dir);\n return loadConfig(configPath ?? undefined);\n}\n","export type { ConfigError, ConfigErrorCode } from \"./errors\";\nexport { configError } from \"./errors\";\nexport {\n defineConfig,\n type SodaGqlConfigContainer,\n validateConfig,\n} from \"./helper\";\nexport { findConfigFile, loadConfig, loadConfigFrom } from \"./loader\";\nexport { normalizeConfig } from \"./normalize\";\nexport type {\n PluginConfig,\n ResolvedSodaGqlConfig,\n SchemaConfig,\n SodaGqlConfig,\n} from \"./types\";\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -21,10 +21,30 @@ declare const configError: ({
21
21
  }) => ConfigError;
22
22
  //#endregion
23
23
  //#region packages/config/src/types.d.ts
24
+ /**
25
+ * Injection configuration for a schema.
26
+ * Can be a string (single file) or an object with separate paths.
27
+ *
28
+ * When a string is provided, it should be a path to a file that exports:
29
+ * - `scalar` (required): Scalar type definitions
30
+ * - `adapter` (optional): Unified adapter with helpers and metadata
31
+ *
32
+ * When an object is provided, each property is a path to a separate file.
33
+ */
34
+ type InjectConfig = string | {
35
+ readonly scalars: string;
36
+ readonly adapter?: string;
37
+ };
24
38
  type SchemaConfig = {
25
39
  readonly schema: string;
26
- readonly runtimeAdapter: string;
27
- readonly scalars: string;
40
+ /**
41
+ * Injection configuration for scalars and adapter.
42
+ * Can be a single file path or an object with separate paths.
43
+ *
44
+ * @example Single file: "./inject.ts" (exports scalar, adapter?)
45
+ * @example Object: { scalars: "./scalars.ts", adapter: "./adapter.ts" }
46
+ */
47
+ readonly inject: InjectConfig;
28
48
  };
29
49
  type StylesConfig = {
30
50
  /**
@@ -86,13 +106,21 @@ type SodaGqlConfig = {
86
106
  */
87
107
  readonly plugins?: PluginConfig;
88
108
  };
109
+ type ResolvedInjectConfig = {
110
+ readonly scalars: string;
111
+ readonly adapter?: string;
112
+ };
113
+ type ResolvedSchemaConfig = {
114
+ readonly schema: string;
115
+ readonly inject: ResolvedInjectConfig;
116
+ };
89
117
  type ResolvedSodaGqlConfig = {
90
118
  readonly analyzer: "ts" | "swc";
91
119
  readonly outdir: string;
92
120
  readonly graphqlSystemAliases: readonly string[];
93
121
  readonly include: readonly string[];
94
122
  readonly exclude: readonly string[];
95
- readonly schemas: Readonly<Record<string, SchemaConfig>>;
123
+ readonly schemas: Readonly<Record<string, ResolvedSchemaConfig>>;
96
124
  readonly styles: ResolvedStylesConfig;
97
125
  readonly plugins: PluginConfig;
98
126
  };
@@ -112,7 +140,7 @@ declare class SodaGqlConfigContainer {
112
140
  * Type-safe helper for defining soda-gql configuration.
113
141
  * Supports both static and dynamic (async) configs.
114
142
  *
115
- * @example Static config
143
+ * @example Static config with object inject
116
144
  * ```ts
117
145
  * import { defineConfig } from "@soda-gql/config";
118
146
  *
@@ -122,26 +150,24 @@ declare class SodaGqlConfigContainer {
122
150
  * schemas: {
123
151
  * default: {
124
152
  * schema: "./schema.graphql",
125
- * runtimeAdapter: "./runtime-adapter.ts",
126
- * scalars: "./scalars.ts",
153
+ * inject: { scalars: "./scalars.ts" },
127
154
  * },
128
155
  * },
129
156
  * });
130
157
  * ```
131
158
  *
132
- * @example Async config
159
+ * @example Static config with string inject (single file)
133
160
  * ```ts
134
- * export default defineConfig(async () => ({
135
- * outdir: await resolveOutputDir(),
161
+ * export default defineConfig({
162
+ * outdir: "./graphql-system",
136
163
  * include: ["./src/**\/*.ts"],
137
164
  * schemas: {
138
165
  * default: {
139
166
  * schema: "./schema.graphql",
140
- * runtimeAdapter: "./runtime-adapter.ts",
141
- * scalars: "./scalars.ts",
167
+ * inject: "./inject.ts", // exports scalar, adapter?
142
168
  * },
143
169
  * },
144
- * }));
170
+ * });
145
171
  * ```
146
172
  */
147
173
  declare function defineConfig(config: SodaGqlConfig): SodaGqlConfigContainer;
@@ -170,16 +196,5 @@ declare function loadConfigFrom(dir: string): Result<ResolvedSodaGqlConfig, Conf
170
196
  */
171
197
  declare function normalizeConfig(config: SodaGqlConfig, configPath: string): Result<ResolvedSodaGqlConfig, ConfigError>;
172
198
  //#endregion
173
- //#region packages/config/src/test-utils.d.ts
174
- /**
175
- * Create temporary config file with proper formatting.
176
- * Uses template literals to support functions, regex, etc.
177
- */
178
- declare function withTempConfig<T>(config: Partial<SodaGqlConfig>, fn: (configPath: string) => Promise<T>): Promise<T>;
179
- /**
180
- * Simple temp config creation (without auto-cleanup).
181
- */
182
- declare function createTempConfigFile(dir: string, config: Partial<SodaGqlConfig>): string;
183
- //#endregion
184
- export { type ConfigError, type ConfigErrorCode, type PluginConfig, type ResolvedSodaGqlConfig, type SchemaConfig, type SodaGqlConfig, configError, createTempConfigFile, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig, withTempConfig };
199
+ export { type ConfigError, type ConfigErrorCode, type PluginConfig, type ResolvedSodaGqlConfig, type SchemaConfig, type SodaGqlConfig, type SodaGqlConfigContainer, configError, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig };
185
200
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/helper.ts","../src/loader.ts","../src/normalize.ts","../src/test-utils.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/helper.ts","../src/loader.ts","../src/normalize.ts"],"sourcesContent":[],"mappings":";;;KAAY,eAAA;KAEA,WAAA;iBACK;EAHL,SAAA,OAAA,EAAe,MAAA;EAEf,SAAA,QAAW,CAAA,EAAA,MACN;EAMJ,SAAA,KAeX,CAAA,EAAA,OAAA;CAf0B;AAAA,cAAf,WAAe,EAAA,CAAA;EAAA,IAAA;EAAA,OAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,IAAA,EAMpB,eANoB;EAAA,OAAA,EAAA,MAAA;EAMpB,QAAA,CAAA,EAAA,MAAA;EAIJ,KAAA,CAAA,EAAA,OAAA;CAKF,EAAA,GALE,WAKF;;;;;;AAxBF;AAEA;AAOA;;;;;AAMQ,KCLI,YAAA,GDKJ,MAAA,GAAA;EAIJ,SAAA,OAAA,EAAA,MAAA;EAKF,SAAA,OAAA,CAAA,EAAA,MAAA;;KCNU,YAAA;;EARA;AAQZ;AAaA;AAWA;AAKA;AAGA;;EAqC6B,SAAA,MAAA,EA5DV,YA4DU;CAAT;AAIA,KA5DR,YAAA,GA4DQ;EAIC;;AAIrB;AAMA;AAMA;;EAM6B,SAAA,eAAA,CAAA,EAAA,OAAA;CAAT;AACD,KA5EP,oBAAA,GA4EO;EACC,SAAA,eAAA,EAAA,OAAA;CAAY;KAxEpB,YAAA,GAAe;KAGf,aAAA;;ACvCZ;;;EAG+C,SAAA,QAAA,CAAA,EAAA,IAAA,GAAA,KAAA;EAAsB;AAuCrE;AACA;AAuCA;;;EAAiD,SAAA,MAAA,EAAA,MAAA;EAAM;;;;ACnFvD;AAUA;EAiBgB,SAAA,oBAAU,CAAA,EAAA,SAAA,MAAA,EAAA;EAAyC;;;;AA4BnE;;EAA2E,SAAA,OAAA,EAAA,SAAA,MAAA,EAAA;EAA9B;;;;;ACrC7C;EAAwC,SAAA,OAAA,CAAA,EAAA,SAAA,MAAA,EAAA;EAA2C;;;EAAD,SAAA,OAAA,EH2D9D,QG3D8D,CH2DrD,MG3DqD,CAAA,MAAA,EH2DtC,YG3DsC,CAAA,CAAA;;;;oBH+D9D;;;;qBAIC;;KAIT,oBAAA;;;;KAMA,oBAAA;;mBAEO;;KAIP,qBAAA;;;;;;oBAMQ,SAAS,eAAe;mBACzB;oBACC;;;;ADvHpB;AAEA;AAOA;;;AAA4B,cEEf,sBAAA,CFFe;EAAA,SAAA,MAAA,EEGkB,aFHlB;EAMpB,QAAA,WAAA,CAAA;EAIJ,OAAA,MAAA,CAAA,MAAA,EEL2B,aFK3B,CAAA,EEL2C,sBFK3C;;;;;ACTJ;AAQA;AAaA;AAWA;AAKA;AAGA;;;;;;;AAiDA;AAMA;AAMA;;;;;;;;;;ACpGA;;;;;AA0CA;AACA;AAuCgB,iBAxCA,YAAA,CAwCc,MAAA,EAxCO,aAwCP,CAAA,EAxCuB,sBAwCvB;AAA0B,iBAvCxC,YAAA,CAuCwC,MAAA,EAAA,GAAA,GAvCb,aAuCa,CAAA,EAvCG,sBAuCH;AAAe,iBAAvD,cAAA,CAAuD,MAAA,EAAA,OAAA,CAAA,EAAtB,MAAsB,CAAf,aAAe,EAAA,WAAA,CAAA;;;AF7F3D,cGUC,wBHVc,EAAA,SAAA,CAAA,oBAAA,EAAA,qBAAA,EAAA,oBAAA,EAAA,qBAAA,CAAA;AAE3B;AAOA;;AAA4B,iBGWZ,cAAA,CHXY,QAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;AAUxB,iBGkBY,UAAA,CHlBZ,UAAA,EAAA,MAAA,GAAA,SAAA,CAAA,EGkBwD,MHlBxD,CGkB+D,qBHlB/D,EGkBsF,WHlBtF,CAAA;;;;iBG8CY,cAAA,eAA6B,OAAO,uBAAuB;;;AHjE3E;AAEA;AAOA;;AAA4B,iBImBZ,eAAA,CJnBY,MAAA,EImBY,aJnBZ,EAAA,UAAA,EAAA,MAAA,CAAA,EImBgD,MJnBhD,CImBuD,qBJnBvD,EImB8E,WJnB9E,CAAA"}
package/dist/index.d.mts CHANGED
@@ -21,10 +21,30 @@ declare const configError: ({
21
21
  }) => ConfigError;
22
22
  //#endregion
23
23
  //#region packages/config/src/types.d.ts
24
+ /**
25
+ * Injection configuration for a schema.
26
+ * Can be a string (single file) or an object with separate paths.
27
+ *
28
+ * When a string is provided, it should be a path to a file that exports:
29
+ * - `scalar` (required): Scalar type definitions
30
+ * - `adapter` (optional): Unified adapter with helpers and metadata
31
+ *
32
+ * When an object is provided, each property is a path to a separate file.
33
+ */
34
+ type InjectConfig = string | {
35
+ readonly scalars: string;
36
+ readonly adapter?: string;
37
+ };
24
38
  type SchemaConfig = {
25
39
  readonly schema: string;
26
- readonly runtimeAdapter: string;
27
- readonly scalars: string;
40
+ /**
41
+ * Injection configuration for scalars and adapter.
42
+ * Can be a single file path or an object with separate paths.
43
+ *
44
+ * @example Single file: "./inject.ts" (exports scalar, adapter?)
45
+ * @example Object: { scalars: "./scalars.ts", adapter: "./adapter.ts" }
46
+ */
47
+ readonly inject: InjectConfig;
28
48
  };
29
49
  type StylesConfig = {
30
50
  /**
@@ -86,13 +106,21 @@ type SodaGqlConfig = {
86
106
  */
87
107
  readonly plugins?: PluginConfig;
88
108
  };
109
+ type ResolvedInjectConfig = {
110
+ readonly scalars: string;
111
+ readonly adapter?: string;
112
+ };
113
+ type ResolvedSchemaConfig = {
114
+ readonly schema: string;
115
+ readonly inject: ResolvedInjectConfig;
116
+ };
89
117
  type ResolvedSodaGqlConfig = {
90
118
  readonly analyzer: "ts" | "swc";
91
119
  readonly outdir: string;
92
120
  readonly graphqlSystemAliases: readonly string[];
93
121
  readonly include: readonly string[];
94
122
  readonly exclude: readonly string[];
95
- readonly schemas: Readonly<Record<string, SchemaConfig>>;
123
+ readonly schemas: Readonly<Record<string, ResolvedSchemaConfig>>;
96
124
  readonly styles: ResolvedStylesConfig;
97
125
  readonly plugins: PluginConfig;
98
126
  };
@@ -112,7 +140,7 @@ declare class SodaGqlConfigContainer {
112
140
  * Type-safe helper for defining soda-gql configuration.
113
141
  * Supports both static and dynamic (async) configs.
114
142
  *
115
- * @example Static config
143
+ * @example Static config with object inject
116
144
  * ```ts
117
145
  * import { defineConfig } from "@soda-gql/config";
118
146
  *
@@ -122,26 +150,24 @@ declare class SodaGqlConfigContainer {
122
150
  * schemas: {
123
151
  * default: {
124
152
  * schema: "./schema.graphql",
125
- * runtimeAdapter: "./runtime-adapter.ts",
126
- * scalars: "./scalars.ts",
153
+ * inject: { scalars: "./scalars.ts" },
127
154
  * },
128
155
  * },
129
156
  * });
130
157
  * ```
131
158
  *
132
- * @example Async config
159
+ * @example Static config with string inject (single file)
133
160
  * ```ts
134
- * export default defineConfig(async () => ({
135
- * outdir: await resolveOutputDir(),
161
+ * export default defineConfig({
162
+ * outdir: "./graphql-system",
136
163
  * include: ["./src/**\/*.ts"],
137
164
  * schemas: {
138
165
  * default: {
139
166
  * schema: "./schema.graphql",
140
- * runtimeAdapter: "./runtime-adapter.ts",
141
- * scalars: "./scalars.ts",
167
+ * inject: "./inject.ts", // exports scalar, adapter?
142
168
  * },
143
169
  * },
144
- * }));
170
+ * });
145
171
  * ```
146
172
  */
147
173
  declare function defineConfig(config: SodaGqlConfig): SodaGqlConfigContainer;
@@ -170,16 +196,5 @@ declare function loadConfigFrom(dir: string): Result<ResolvedSodaGqlConfig, Conf
170
196
  */
171
197
  declare function normalizeConfig(config: SodaGqlConfig, configPath: string): Result<ResolvedSodaGqlConfig, ConfigError>;
172
198
  //#endregion
173
- //#region packages/config/src/test-utils.d.ts
174
- /**
175
- * Create temporary config file with proper formatting.
176
- * Uses template literals to support functions, regex, etc.
177
- */
178
- declare function withTempConfig<T>(config: Partial<SodaGqlConfig>, fn: (configPath: string) => Promise<T>): Promise<T>;
179
- /**
180
- * Simple temp config creation (without auto-cleanup).
181
- */
182
- declare function createTempConfigFile(dir: string, config: Partial<SodaGqlConfig>): string;
183
- //#endregion
184
- export { type ConfigError, type ConfigErrorCode, type PluginConfig, type ResolvedSodaGqlConfig, type SchemaConfig, type SodaGqlConfig, configError, createTempConfigFile, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig, withTempConfig };
199
+ export { type ConfigError, type ConfigErrorCode, type PluginConfig, type ResolvedSodaGqlConfig, type SchemaConfig, type SodaGqlConfig, type SodaGqlConfigContainer, configError, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig };
185
200
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/helper.ts","../src/loader.ts","../src/normalize.ts","../src/test-utils.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/types.ts","../src/helper.ts","../src/loader.ts","../src/normalize.ts"],"sourcesContent":[],"mappings":";;;KAAY,eAAA;KAEA,WAAA;iBACK;EAHL,SAAA,OAAA,EAAe,MAAA;EAEf,SAAA,QAAW,CAAA,EAAA,MACN;EAMJ,SAAA,KAeX,CAAA,EAAA,OAAA;CAf0B;AAAA,cAAf,WAAe,EAAA,CAAA;EAAA,IAAA;EAAA,OAAA;EAAA,QAAA;EAAA;CAAA,EAAA;EAAA,IAAA,EAMpB,eANoB;EAAA,OAAA,EAAA,MAAA;EAMpB,QAAA,CAAA,EAAA,MAAA;EAIJ,KAAA,CAAA,EAAA,OAAA;CAKF,EAAA,GALE,WAKF;;;;;;AAxBF;AAEA;AAOA;;;;;AAMQ,KCLI,YAAA,GDKJ,MAAA,GAAA;EAIJ,SAAA,OAAA,EAAA,MAAA;EAKF,SAAA,OAAA,CAAA,EAAA,MAAA;;KCNU,YAAA;;EARA;AAQZ;AAaA;AAWA;AAKA;AAGA;;EAqC6B,SAAA,MAAA,EA5DV,YA4DU;CAAT;AAIA,KA5DR,YAAA,GA4DQ;EAIC;;AAIrB;AAMA;AAMA;;EAM6B,SAAA,eAAA,CAAA,EAAA,OAAA;CAAT;AACD,KA5EP,oBAAA,GA4EO;EACC,SAAA,eAAA,EAAA,OAAA;CAAY;KAxEpB,YAAA,GAAe;KAGf,aAAA;;ACvCZ;;;EAG+C,SAAA,QAAA,CAAA,EAAA,IAAA,GAAA,KAAA;EAAsB;AAuCrE;AACA;AAuCA;;;EAAiD,SAAA,MAAA,EAAA,MAAA;EAAM;;;;ACnFvD;AAUA;EAiBgB,SAAA,oBAAU,CAAA,EAAA,SAAA,MAAA,EAAA;EAAyC;;;;AA4BnE;;EAA2E,SAAA,OAAA,EAAA,SAAA,MAAA,EAAA;EAA9B;;;;;ACrC7C;EAAwC,SAAA,OAAA,CAAA,EAAA,SAAA,MAAA,EAAA;EAA2C;;;EAAD,SAAA,OAAA,EH2D9D,QG3D8D,CH2DrD,MG3DqD,CAAA,MAAA,EH2DtC,YG3DsC,CAAA,CAAA;;;;oBH+D9D;;;;qBAIC;;KAIT,oBAAA;;;;KAMA,oBAAA;;mBAEO;;KAIP,qBAAA;;;;;;oBAMQ,SAAS,eAAe;mBACzB;oBACC;;;;ADvHpB;AAEA;AAOA;;;AAA4B,cEEf,sBAAA,CFFe;EAAA,SAAA,MAAA,EEGkB,aFHlB;EAMpB,QAAA,WAAA,CAAA;EAIJ,OAAA,MAAA,CAAA,MAAA,EEL2B,aFK3B,CAAA,EEL2C,sBFK3C;;;;;ACTJ;AAQA;AAaA;AAWA;AAKA;AAGA;;;;;;;AAiDA;AAMA;AAMA;;;;;;;;;;ACpGA;;;;;AA0CA;AACA;AAuCgB,iBAxCA,YAAA,CAwCc,MAAA,EAxCO,aAwCP,CAAA,EAxCuB,sBAwCvB;AAA0B,iBAvCxC,YAAA,CAuCwC,MAAA,EAAA,GAAA,GAvCb,aAuCa,CAAA,EAvCG,sBAuCH;AAAe,iBAAvD,cAAA,CAAuD,MAAA,EAAA,OAAA,CAAA,EAAtB,MAAsB,CAAf,aAAe,EAAA,WAAA,CAAA;;;AF7F3D,cGUC,wBHVc,EAAA,SAAA,CAAA,oBAAA,EAAA,qBAAA,EAAA,oBAAA,EAAA,qBAAA,CAAA;AAE3B;AAOA;;AAA4B,iBGWZ,cAAA,CHXY,QAAA,CAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;AAUxB,iBGkBY,UAAA,CHlBZ,UAAA,EAAA,MAAA,GAAA,SAAA,CAAA,EGkBwD,MHlBxD,CGkB+D,qBHlB/D,EGkBsF,WHlBtF,CAAA;;;;iBG8CY,cAAA,eAA6B,OAAO,uBAAuB;;;AHjE3E;AAEA;AAOA;;AAA4B,iBImBZ,eAAA,CJnBY,MAAA,EImBY,aJnBZ,EAAA,UAAA,EAAA,MAAA,CAAA,EImBgD,MJnBhD,CImBuD,qBJnBvD,EImB8E,WJnB9E,CAAA"}
package/dist/index.mjs CHANGED
@@ -2,12 +2,11 @@ import { createRequire } from "node:module";
2
2
  import { defineSchemaFor, resolveRelativeImportWithExistenceCheck } from "@soda-gql/common";
3
3
  import { err, ok } from "neverthrow";
4
4
  import z from "zod";
5
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
+ import { existsSync, readFileSync } from "node:fs";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { dirname as dirname$1, resolve as resolve$1 } from "node:path/posix";
8
8
  import { Script } from "node:vm";
9
9
  import { transformSync } from "@swc/core";
10
- import { fileURLToPath } from "node:url";
11
10
 
12
11
  //#region rolldown:runtime
13
12
  var __defProp = Object.defineProperty;
@@ -56,10 +55,13 @@ function defineConfig(config) {
56
55
  }
57
56
  return SodaGqlConfigContainer.create(validated.value);
58
57
  }
58
+ const InjectConfigSchema = z.union([z.string().min(1), z.object({
59
+ scalars: z.string().min(1),
60
+ adapter: z.string().min(1).optional()
61
+ })]);
59
62
  const SchemaConfigSchema = defineSchemaFor()({
60
63
  schema: z.string().min(1),
61
- runtimeAdapter: z.string().min(1),
62
- scalars: z.string().min(1)
64
+ inject: InjectConfigSchema
63
65
  });
64
66
  const StylesConfigSchema = defineSchemaFor()({ importExtension: z.boolean().optional() });
65
67
  const SodaGqlConfigSchema = defineSchemaFor()({
@@ -144,6 +146,23 @@ function executeConfigFile(configPath) {
144
146
  //#endregion
145
147
  //#region packages/config/src/normalize.ts
146
148
  /**
149
+ * Normalize inject config to resolved object form.
150
+ * String form is converted to object with same path for all fields.
151
+ */
152
+ function normalizeInject(inject, configDir) {
153
+ if (typeof inject === "string") {
154
+ const resolvedPath = resolve(configDir, inject);
155
+ return {
156
+ scalars: resolvedPath,
157
+ adapter: resolvedPath
158
+ };
159
+ }
160
+ return {
161
+ scalars: resolve(configDir, inject.scalars),
162
+ ...inject.adapter ? { adapter: resolve(configDir, inject.adapter) } : {}
163
+ };
164
+ }
165
+ /**
147
166
  * Resolve and normalize config with defaults.
148
167
  * Paths in the config are resolved relative to the config file's directory.
149
168
  */
@@ -160,8 +179,7 @@ function normalizeConfig(config, configPath) {
160
179
  exclude: exclude.map((pattern) => resolve(configDir, pattern)),
161
180
  schemas: Object.fromEntries(Object.entries(config.schemas).map(([name, schemaConfig]) => [name, {
162
181
  schema: resolve(configDir, schemaConfig.schema),
163
- runtimeAdapter: resolve(configDir, schemaConfig.runtimeAdapter),
164
- scalars: resolve(configDir, schemaConfig.scalars)
182
+ inject: normalizeInject(schemaConfig.inject, configDir)
165
183
  }])),
166
184
  styles: { importExtension: config.styles?.importExtension ?? false },
167
185
  plugins: config.plugins ?? {}
@@ -213,7 +231,7 @@ function loadConfig(configPath) {
213
231
  } catch (error) {
214
232
  return err(configError({
215
233
  code: "CONFIG_LOAD_FAILED",
216
- message: `Failed to load config: ${error}`,
234
+ message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,
217
235
  filePath: resolvedPath,
218
236
  cause: error
219
237
  }));
@@ -227,65 +245,18 @@ function loadConfigFrom(dir) {
227
245
  return loadConfig(configPath ?? undefined);
228
246
  }
229
247
 
230
- //#endregion
231
- //#region packages/config/src/test-utils.ts
232
- /**
233
- * Get project root from this package location.
234
- * packages/config/src/test-utils.ts -> project root
235
- */
236
- const getProjectRoot = () => {
237
- return fileURLToPath(new URL("../../../", import.meta.url));
238
- };
239
- /**
240
- * Create temporary config file with proper formatting.
241
- * Uses template literals to support functions, regex, etc.
242
- */
243
- async function withTempConfig(config, fn) {
244
- const projectRoot = getProjectRoot();
245
- const tmpDir = join(projectRoot, "tests/.tmp/config-test", `${Date.now()}`);
246
- mkdirSync(tmpDir, { recursive: true });
247
- const configPath = join(tmpDir, "soda-gql.config.ts");
248
- const configContent = `
249
- import { defineConfig } from "@soda-gql/config";
250
-
251
- export default defineConfig(${JSON.stringify(config, null, 2)});
252
- `.trim();
253
- writeFileSync(configPath, configContent);
254
- return fn(configPath).finally(() => {
255
- rmSync(tmpDir, {
256
- recursive: true,
257
- force: true
258
- });
259
- });
260
- }
261
- /**
262
- * Simple temp config creation (without auto-cleanup).
263
- */
264
- function createTempConfigFile(dir, config) {
265
- const configPath = join(dir, "soda-gql.config.ts");
266
- const configContent = `
267
- import { defineConfig } from "@soda-gql/config";
268
-
269
- export default defineConfig(${JSON.stringify(config, null, 2)});
270
- `.trim();
271
- writeFileSync(configPath, configContent);
272
- return configPath;
273
- }
274
-
275
248
  //#endregion
276
249
  //#region packages/config/src/index.ts
277
250
  var src_exports = /* @__PURE__ */ __export({
278
251
  configError: () => configError,
279
- createTempConfigFile: () => createTempConfigFile,
280
252
  defineConfig: () => defineConfig,
281
253
  findConfigFile: () => findConfigFile,
282
254
  loadConfig: () => loadConfig,
283
255
  loadConfigFrom: () => loadConfigFrom,
284
256
  normalizeConfig: () => normalizeConfig,
285
- validateConfig: () => validateConfig,
286
- withTempConfig: () => withTempConfig
257
+ validateConfig: () => validateConfig
287
258
  });
288
259
 
289
260
  //#endregion
290
- export { configError, createTempConfigFile, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig, withTempConfig };
261
+ export { configError, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig };
291
262
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["config: SodaGqlConfig","resolve","mod: { exports: unknown }","configModule","dirname","resolved: ResolvedSodaGqlConfig"],"sources":["../src/errors.ts","../src/helper.ts","../src/evaluation.ts","../src/normalize.ts","../src/loader.ts","../src/test-utils.ts","../src/index.ts"],"sourcesContent":["export type ConfigErrorCode = \"CONFIG_NOT_FOUND\" | \"CONFIG_LOAD_FAILED\" | \"CONFIG_VALIDATION_FAILED\" | \"CONFIG_INVALID_PATH\";\n\nexport type ConfigError = {\n readonly code: ConfigErrorCode;\n readonly message: string;\n readonly filePath?: string;\n readonly cause?: unknown;\n};\n\nexport const configError = ({\n code,\n message,\n filePath,\n cause,\n}: {\n code: ConfigErrorCode;\n message: string;\n filePath?: string;\n cause?: unknown;\n}): ConfigError => ({\n code,\n message,\n filePath,\n cause,\n});\n","import { defineSchemaFor } from \"@soda-gql/common\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport z from \"zod\";\nimport { type ConfigError, configError } from \"./errors\";\nimport type { SchemaConfig, SodaGqlConfig, StylesConfig } from \"./types\";\n\n/**\n * Thin wrapper class to simplify the validation of exported value from config file.\n * As we use SWC + VM to execute the config file, the exported value is not typed.\n * This wrapper class ensures the exported value is a valid soda-gql config object.\n */\nexport class SodaGqlConfigContainer {\n private constructor(public readonly config: SodaGqlConfig) {}\n\n public static create(config: SodaGqlConfig): SodaGqlConfigContainer {\n return new SodaGqlConfigContainer(config);\n }\n}\n\n/**\n * Type-safe helper for defining soda-gql configuration.\n * Supports both static and dynamic (async) configs.\n *\n * @example Static config\n * ```ts\n * import { defineConfig } from \"@soda-gql/config\";\n *\n * export default defineConfig({\n * outdir: \"./graphql-system\",\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * runtimeAdapter: \"./runtime-adapter.ts\",\n * scalars: \"./scalars.ts\",\n * },\n * },\n * });\n * ```\n *\n * @example Async config\n * ```ts\n * export default defineConfig(async () => ({\n * outdir: await resolveOutputDir(),\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * runtimeAdapter: \"./runtime-adapter.ts\",\n * scalars: \"./scalars.ts\",\n * },\n * },\n * }));\n * ```\n */\nexport function defineConfig(config: SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: () => SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: SodaGqlConfig | (() => SodaGqlConfig)): SodaGqlConfigContainer {\n const validated = validateConfig(typeof config === \"function\" ? config() : config);\n if (validated.isErr()) {\n throw validated.error;\n }\n return SodaGqlConfigContainer.create(validated.value);\n}\n\nconst SchemaConfigSchema = defineSchemaFor<SchemaConfig>()({\n schema: z.string().min(1),\n runtimeAdapter: z.string().min(1),\n scalars: z.string().min(1),\n});\n\nconst StylesConfigSchema = defineSchemaFor<StylesConfig>()({\n importExtension: z.boolean().optional(),\n});\n\nconst SodaGqlConfigSchema = defineSchemaFor<SodaGqlConfig>()({\n analyzer: z.enum([\"ts\", \"swc\"]).optional(),\n outdir: z.string().min(1),\n graphqlSystemAliases: z.array(z.string()).optional(),\n include: z.array(z.string().min(1)),\n exclude: z.array(z.string().min(1)).optional(),\n schemas: z.record(z.string(), SchemaConfigSchema),\n styles: StylesConfigSchema.optional(),\n plugins: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport function validateConfig(config: unknown): Result<SodaGqlConfig, ConfigError> {\n const result = SodaGqlConfigSchema.safeParse(config);\n\n if (!result.success) {\n return err(\n configError({\n code: \"CONFIG_VALIDATION_FAILED\",\n message: `Invalid config: ${result.error.message}`,\n }),\n );\n }\n\n return ok(result.data satisfies SodaGqlConfig);\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path/posix\";\nimport { Script } from \"node:vm\";\nimport { resolveRelativeImportWithExistenceCheck } from \"@soda-gql/common\";\nimport { transformSync } from \"@swc/core\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport { type ConfigError, configError } from \"./errors\";\nimport { SodaGqlConfigContainer } from \"./helper\";\n// TODO: split config package into definition and evaluation parts\nimport * as configModule from \"./index\";\nimport type { SodaGqlConfig } from \"./types\";\n\n/**\n * Load and execute TypeScript config file synchronously using SWC + VM.\n */\nexport function executeConfigFile(configPath: string): Result<SodaGqlConfig, ConfigError> {\n const filePath = resolve(configPath);\n try {\n // Read the config file\n const source = readFileSync(filePath, \"utf-8\");\n\n // Transform TypeScript to CommonJS using SWC\n const result = transformSync(source, {\n filename: filePath,\n jsc: {\n parser: {\n syntax: \"typescript\",\n },\n },\n module: {\n type: \"commonjs\",\n },\n sourceMaps: false,\n minify: false,\n });\n\n // Create CommonJS context\n const mod: { exports: unknown } = { exports: {} };\n\n const requireInner = createRequire(filePath);\n const require = (specifier: string) => {\n if (specifier === \"@soda-gql/config\") {\n return configModule;\n }\n\n // Handle external modules normally\n if (!specifier.startsWith(\".\")) {\n return requireInner(specifier);\n }\n\n // Resolve relative imports with existence check\n const resolvedPath = resolveRelativeImportWithExistenceCheck({ filePath, specifier });\n if (!resolvedPath) {\n throw new Error(`Module not found: ${specifier}`);\n }\n return requireInner(resolvedPath);\n };\n\n // Execute in VM context\n new Script(result.code, { filename: filePath }).runInNewContext({\n require,\n module: mod,\n exports: mod.exports,\n __dirname: dirname(filePath),\n __filename: filePath,\n console,\n process,\n });\n\n const config =\n mod.exports &&\n typeof mod.exports === \"object\" &&\n \"default\" in mod.exports &&\n mod.exports.default instanceof SodaGqlConfigContainer\n ? mod.exports.default.config\n : null;\n\n if (!config) {\n throw new Error(\"Invalid config module\");\n }\n\n return ok(config);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n filePath: filePath,\n cause: error,\n }),\n );\n }\n}\n","import { dirname, resolve } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { ok } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport type { ResolvedSodaGqlConfig, SodaGqlConfig } from \"./types\";\n\n/**\n * Resolve and normalize config with defaults.\n * Paths in the config are resolved relative to the config file's directory.\n */\nexport function normalizeConfig(config: SodaGqlConfig, configPath: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configDir = dirname(configPath);\n // Default analyzer to \"ts\"\n const analyzer = config.analyzer ?? \"ts\";\n\n // Default graphqlSystemAliases to [\"@/graphql-system\"]\n const graphqlSystemAliases = config.graphqlSystemAliases ?? [\"@/graphql-system\"];\n\n // Default exclude to empty array\n const exclude = config.exclude ?? [];\n\n const resolved: ResolvedSodaGqlConfig = {\n analyzer,\n outdir: resolve(configDir, config.outdir),\n graphqlSystemAliases,\n include: config.include.map((pattern) => resolve(configDir, pattern)),\n exclude: exclude.map((pattern) => resolve(configDir, pattern)),\n schemas: Object.fromEntries(\n Object.entries(config.schemas).map(([name, schemaConfig]) => [\n name,\n {\n schema: resolve(configDir, schemaConfig.schema),\n runtimeAdapter: resolve(configDir, schemaConfig.runtimeAdapter),\n scalars: resolve(configDir, schemaConfig.scalars),\n },\n ]),\n ),\n styles: {\n importExtension: config.styles?.importExtension ?? false,\n },\n plugins: config.plugins ?? {},\n };\n\n return ok(resolved);\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { err } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport { configError } from \"./errors\";\nimport { executeConfigFile } from \"./evaluation\";\nimport { normalizeConfig } from \"./normalize\";\nimport type { ResolvedSodaGqlConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG_FILENAMES = [\n \"soda-gql.config.ts\",\n \"soda-gql.config.mts\",\n \"soda-gql.config.js\",\n \"soda-gql.config.mjs\",\n] as const;\n\n/**\n * Find config file by walking up directory tree.\n */\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n while (currentDir !== dirname(currentDir)) {\n for (const filename of DEFAULT_CONFIG_FILENAMES) {\n const configPath = join(currentDir, filename);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n return null;\n}\n\n/**\n * Load config with Result type (for library use).\n */\nexport function loadConfig(configPath: string | undefined): Result<ResolvedSodaGqlConfig, ConfigError> {\n const resolvedPath = configPath ?? findConfigFile();\n\n if (!resolvedPath) {\n return err(configError({ code: \"CONFIG_NOT_FOUND\", message: \"Config file not found\" }));\n }\n\n try {\n const result = executeConfigFile(resolvedPath);\n if (result.isErr()) {\n return err(result.error);\n }\n return normalizeConfig(result.value, resolvedPath);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error}`,\n filePath: resolvedPath,\n cause: error,\n }),\n );\n }\n}\n\n/**\n * Load config from specific directory.\n */\nexport function loadConfigFrom(dir: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configPath = findConfigFile(dir);\n return loadConfig(configPath ?? undefined);\n}\n","import { mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { SodaGqlConfig } from \"./types\";\n\n/**\n * Get project root from this package location.\n * packages/config/src/test-utils.ts -> project root\n */\nconst getProjectRoot = (): string => {\n return fileURLToPath(new URL(\"../../../\", import.meta.url));\n};\n\n/**\n * Create temporary config file with proper formatting.\n * Uses template literals to support functions, regex, etc.\n */\nexport async function withTempConfig<T>(config: Partial<SodaGqlConfig>, fn: (configPath: string) => Promise<T>): Promise<T> {\n const projectRoot = getProjectRoot();\n const tmpDir = join(projectRoot, \"tests/.tmp/config-test\", `${Date.now()}`);\n mkdirSync(tmpDir, { recursive: true });\n const configPath = join(tmpDir, \"soda-gql.config.ts\");\n\n // Generate config file using template\n const configContent = `\nimport { defineConfig } from \"@soda-gql/config\";\n\nexport default defineConfig(${JSON.stringify(config, null, 2)});\n`.trim();\n\n writeFileSync(configPath, configContent);\n\n return fn(configPath).finally(() => {\n rmSync(tmpDir, { recursive: true, force: true });\n });\n}\n\n/**\n * Simple temp config creation (without auto-cleanup).\n */\nexport function createTempConfigFile(dir: string, config: Partial<SodaGqlConfig>): string {\n const configPath = join(dir, \"soda-gql.config.ts\");\n\n // Write config as TypeScript module\n const configContent = `\nimport { defineConfig } from \"@soda-gql/config\";\n\nexport default defineConfig(${JSON.stringify(config, null, 2)});\n`.trim();\n\n writeFileSync(configPath, configContent);\n return configPath;\n}\n","export type { ConfigError, ConfigErrorCode } from \"./errors\";\nexport { configError } from \"./errors\";\nexport { defineConfig, validateConfig } from \"./helper\";\nexport {\n findConfigFile,\n loadConfig,\n loadConfigFrom,\n} from \"./loader\";\nexport { normalizeConfig } from \"./normalize\";\nexport { createTempConfigFile, withTempConfig } from \"./test-utils\";\nexport type {\n PluginConfig,\n ResolvedSodaGqlConfig,\n SchemaConfig,\n SodaGqlConfig,\n} from \"./types\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["config: SodaGqlConfig","InjectConfigSchema: z.ZodType<InjectConfig>","resolve","mod: { exports: unknown }","configModule","dirname","resolved: ResolvedSodaGqlConfig"],"sources":["../src/errors.ts","../src/helper.ts","../src/evaluation.ts","../src/normalize.ts","../src/loader.ts","../src/index.ts"],"sourcesContent":["export type ConfigErrorCode = \"CONFIG_NOT_FOUND\" | \"CONFIG_LOAD_FAILED\" | \"CONFIG_VALIDATION_FAILED\" | \"CONFIG_INVALID_PATH\";\n\nexport type ConfigError = {\n readonly code: ConfigErrorCode;\n readonly message: string;\n readonly filePath?: string;\n readonly cause?: unknown;\n};\n\nexport const configError = ({\n code,\n message,\n filePath,\n cause,\n}: {\n code: ConfigErrorCode;\n message: string;\n filePath?: string;\n cause?: unknown;\n}): ConfigError => ({\n code,\n message,\n filePath,\n cause,\n});\n","import { defineSchemaFor } from \"@soda-gql/common\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport z from \"zod\";\nimport { type ConfigError, configError } from \"./errors\";\nimport type { InjectConfig, SchemaConfig, SodaGqlConfig, StylesConfig } from \"./types\";\n\n/**\n * Thin wrapper class to simplify the validation of exported value from config file.\n * As we use SWC + VM to execute the config file, the exported value is not typed.\n * This wrapper class ensures the exported value is a valid soda-gql config object.\n */\nexport class SodaGqlConfigContainer {\n private constructor(public readonly config: SodaGqlConfig) {}\n\n public static create(config: SodaGqlConfig): SodaGqlConfigContainer {\n return new SodaGqlConfigContainer(config);\n }\n}\n\n/**\n * Type-safe helper for defining soda-gql configuration.\n * Supports both static and dynamic (async) configs.\n *\n * @example Static config with object inject\n * ```ts\n * import { defineConfig } from \"@soda-gql/config\";\n *\n * export default defineConfig({\n * outdir: \"./graphql-system\",\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * inject: { scalars: \"./scalars.ts\" },\n * },\n * },\n * });\n * ```\n *\n * @example Static config with string inject (single file)\n * ```ts\n * export default defineConfig({\n * outdir: \"./graphql-system\",\n * include: [\"./src/**\\/*.ts\"],\n * schemas: {\n * default: {\n * schema: \"./schema.graphql\",\n * inject: \"./inject.ts\", // exports scalar, adapter?\n * },\n * },\n * });\n * ```\n */\nexport function defineConfig(config: SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: () => SodaGqlConfig): SodaGqlConfigContainer;\nexport function defineConfig(config: SodaGqlConfig | (() => SodaGqlConfig)): SodaGqlConfigContainer {\n const validated = validateConfig(typeof config === \"function\" ? config() : config);\n if (validated.isErr()) {\n throw validated.error;\n }\n return SodaGqlConfigContainer.create(validated.value);\n}\n\n// InjectConfig is a union type (string | object), so we define the schema directly\n// rather than using defineSchemaFor which requires object types\nconst InjectConfigSchema: z.ZodType<InjectConfig> = z.union([\n z.string().min(1),\n z.object({\n scalars: z.string().min(1),\n adapter: z.string().min(1).optional(),\n }),\n]);\n\nconst SchemaConfigSchema = defineSchemaFor<SchemaConfig>()({\n schema: z.string().min(1),\n inject: InjectConfigSchema,\n});\n\nconst StylesConfigSchema = defineSchemaFor<StylesConfig>()({\n importExtension: z.boolean().optional(),\n});\n\nconst SodaGqlConfigSchema = defineSchemaFor<SodaGqlConfig>()({\n analyzer: z.enum([\"ts\", \"swc\"]).optional(),\n outdir: z.string().min(1),\n graphqlSystemAliases: z.array(z.string()).optional(),\n include: z.array(z.string().min(1)),\n exclude: z.array(z.string().min(1)).optional(),\n schemas: z.record(z.string(), SchemaConfigSchema),\n styles: StylesConfigSchema.optional(),\n plugins: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport function validateConfig(config: unknown): Result<SodaGqlConfig, ConfigError> {\n const result = SodaGqlConfigSchema.safeParse(config);\n\n if (!result.success) {\n return err(\n configError({\n code: \"CONFIG_VALIDATION_FAILED\",\n message: `Invalid config: ${result.error.message}`,\n }),\n );\n }\n\n return ok(result.data satisfies SodaGqlConfig);\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path/posix\";\nimport { Script } from \"node:vm\";\nimport { resolveRelativeImportWithExistenceCheck } from \"@soda-gql/common\";\nimport { transformSync } from \"@swc/core\";\nimport { err, ok, type Result } from \"neverthrow\";\nimport { type ConfigError, configError } from \"./errors\";\nimport { SodaGqlConfigContainer } from \"./helper\";\n// TODO: split config package into definition and evaluation parts\nimport * as configModule from \"./index\";\nimport type { SodaGqlConfig } from \"./types\";\n\n/**\n * Load and execute TypeScript config file synchronously using SWC + VM.\n */\nexport function executeConfigFile(configPath: string): Result<SodaGqlConfig, ConfigError> {\n const filePath = resolve(configPath);\n try {\n // Read the config file\n const source = readFileSync(filePath, \"utf-8\");\n\n // Transform TypeScript to CommonJS using SWC\n const result = transformSync(source, {\n filename: filePath,\n jsc: {\n parser: {\n syntax: \"typescript\",\n },\n },\n module: {\n type: \"commonjs\",\n },\n sourceMaps: false,\n minify: false,\n });\n\n // Create CommonJS context\n const mod: { exports: unknown } = { exports: {} };\n\n const requireInner = createRequire(filePath);\n const require = (specifier: string) => {\n if (specifier === \"@soda-gql/config\") {\n return configModule;\n }\n\n // Handle external modules normally\n if (!specifier.startsWith(\".\")) {\n return requireInner(specifier);\n }\n\n // Resolve relative imports with existence check\n const resolvedPath = resolveRelativeImportWithExistenceCheck({ filePath, specifier });\n if (!resolvedPath) {\n throw new Error(`Module not found: ${specifier}`);\n }\n return requireInner(resolvedPath);\n };\n\n // Execute in VM context\n new Script(result.code, { filename: filePath }).runInNewContext({\n require,\n module: mod,\n exports: mod.exports,\n __dirname: dirname(filePath),\n __filename: filePath,\n console,\n process,\n });\n\n const config =\n mod.exports &&\n typeof mod.exports === \"object\" &&\n \"default\" in mod.exports &&\n mod.exports.default instanceof SodaGqlConfigContainer\n ? mod.exports.default.config\n : null;\n\n if (!config) {\n throw new Error(\"Invalid config module\");\n }\n\n return ok(config);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n filePath: filePath,\n cause: error,\n }),\n );\n }\n}\n","import { dirname, resolve } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { ok } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport type { InjectConfig, ResolvedInjectConfig, ResolvedSodaGqlConfig, SodaGqlConfig } from \"./types\";\n\n/**\n * Normalize inject config to resolved object form.\n * String form is converted to object with same path for all fields.\n */\nfunction normalizeInject(inject: InjectConfig, configDir: string): ResolvedInjectConfig {\n if (typeof inject === \"string\") {\n const resolvedPath = resolve(configDir, inject);\n return {\n scalars: resolvedPath,\n adapter: resolvedPath,\n };\n }\n return {\n scalars: resolve(configDir, inject.scalars),\n ...(inject.adapter ? { adapter: resolve(configDir, inject.adapter) } : {}),\n };\n}\n\n/**\n * Resolve and normalize config with defaults.\n * Paths in the config are resolved relative to the config file's directory.\n */\nexport function normalizeConfig(config: SodaGqlConfig, configPath: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configDir = dirname(configPath);\n // Default analyzer to \"ts\"\n const analyzer = config.analyzer ?? \"ts\";\n\n // Default graphqlSystemAliases to [\"@/graphql-system\"]\n const graphqlSystemAliases = config.graphqlSystemAliases ?? [\"@/graphql-system\"];\n\n // Default exclude to empty array\n const exclude = config.exclude ?? [];\n\n const resolved: ResolvedSodaGqlConfig = {\n analyzer,\n outdir: resolve(configDir, config.outdir),\n graphqlSystemAliases,\n include: config.include.map((pattern) => resolve(configDir, pattern)),\n exclude: exclude.map((pattern) => resolve(configDir, pattern)),\n schemas: Object.fromEntries(\n Object.entries(config.schemas).map(([name, schemaConfig]) => [\n name,\n {\n schema: resolve(configDir, schemaConfig.schema),\n inject: normalizeInject(schemaConfig.inject, configDir),\n },\n ]),\n ),\n styles: {\n importExtension: config.styles?.importExtension ?? false,\n },\n plugins: config.plugins ?? {},\n };\n\n return ok(resolved);\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Result } from \"neverthrow\";\nimport { err } from \"neverthrow\";\nimport type { ConfigError } from \"./errors\";\nimport { configError } from \"./errors\";\nimport { executeConfigFile } from \"./evaluation\";\nimport { normalizeConfig } from \"./normalize\";\nimport type { ResolvedSodaGqlConfig } from \"./types\";\n\nexport const DEFAULT_CONFIG_FILENAMES = [\n \"soda-gql.config.ts\",\n \"soda-gql.config.mts\",\n \"soda-gql.config.js\",\n \"soda-gql.config.mjs\",\n] as const;\n\n/**\n * Find config file by walking up directory tree.\n */\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n while (currentDir !== dirname(currentDir)) {\n for (const filename of DEFAULT_CONFIG_FILENAMES) {\n const configPath = join(currentDir, filename);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n return null;\n}\n\n/**\n * Load config with Result type (for library use).\n */\nexport function loadConfig(configPath: string | undefined): Result<ResolvedSodaGqlConfig, ConfigError> {\n const resolvedPath = configPath ?? findConfigFile();\n\n if (!resolvedPath) {\n return err(configError({ code: \"CONFIG_NOT_FOUND\", message: \"Config file not found\" }));\n }\n\n try {\n const result = executeConfigFile(resolvedPath);\n if (result.isErr()) {\n return err(result.error);\n }\n return normalizeConfig(result.value, resolvedPath);\n } catch (error) {\n return err(\n configError({\n code: \"CONFIG_LOAD_FAILED\",\n message: `Failed to load config: ${error instanceof Error ? error.message : String(error)}`,\n filePath: resolvedPath,\n cause: error,\n }),\n );\n }\n}\n\n/**\n * Load config from specific directory.\n */\nexport function loadConfigFrom(dir: string): Result<ResolvedSodaGqlConfig, ConfigError> {\n const configPath = findConfigFile(dir);\n return loadConfig(configPath ?? undefined);\n}\n","export type { ConfigError, ConfigErrorCode } from \"./errors\";\nexport { configError } from \"./errors\";\nexport {\n defineConfig,\n type SodaGqlConfigContainer,\n validateConfig,\n} from \"./helper\";\nexport { findConfigFile, loadConfig, loadConfigFrom } from \"./loader\";\nexport { normalizeConfig } from \"./normalize\";\nexport type {\n PluginConfig,\n ResolvedSodaGqlConfig,\n SchemaConfig,\n SodaGqlConfig,\n} from \"./types\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soda-gql/config",
3
- "version": "0.0.9",
3
+ "version": "0.2.0",
4
4
  "description": "Centralized configuration loader and helpers for soda-gql tooling.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -13,12 +13,34 @@
13
13
  "email": "shota.hatada@whatasoda.me",
14
14
  "url": "https://github.com/whatasoda"
15
15
  },
16
+ "keywords": [
17
+ "graphql",
18
+ "codegen",
19
+ "zero-runtime",
20
+ "typescript",
21
+ "config"
22
+ ],
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/whatasoda/soda-gql.git",
26
+ "directory": "packages/config"
27
+ },
28
+ "homepage": "https://github.com/whatasoda/soda-gql#readme",
29
+ "bugs": {
30
+ "url": "https://github.com/whatasoda/soda-gql/issues"
31
+ },
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
16
35
  "main": "./dist/index.mjs",
17
36
  "module": "./dist/index.mjs",
18
37
  "types": "./dist/index.d.mts",
19
38
  "exports": {
39
+ "./test": {
40
+ "@soda-gql": "./@devx-test.ts"
41
+ },
20
42
  ".": {
21
- "@soda-gql": "./src/index.ts",
43
+ "@soda-gql": "./@x-index.ts",
22
44
  "types": "./dist/index.d.mts",
23
45
  "import": "./dist/index.mjs",
24
46
  "require": "./dist/index.cjs",
@@ -27,7 +49,7 @@
27
49
  "./package.json": "./package.json"
28
50
  },
29
51
  "dependencies": {
30
- "@soda-gql/common": "0.0.9",
52
+ "@soda-gql/common": "0.2.0",
31
53
  "@swc/core": "^1.10.0",
32
54
  "neverthrow": "^8.2.0",
33
55
  "zod": "^4.1.11"