@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 +127 -0
- package/dist/index.cjs +26 -56
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +39 -24
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +39 -24
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +27 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +25 -3
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# @soda-gql/config
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@soda-gql/config)
|
|
4
|
+
[](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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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,
|
|
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
|
-
*
|
|
126
|
-
* scalars: "./scalars.ts",
|
|
153
|
+
* inject: { scalars: "./scalars.ts" },
|
|
127
154
|
* },
|
|
128
155
|
* },
|
|
129
156
|
* });
|
|
130
157
|
* ```
|
|
131
158
|
*
|
|
132
|
-
* @example
|
|
159
|
+
* @example Static config with string inject (single file)
|
|
133
160
|
* ```ts
|
|
134
|
-
* export default defineConfig(
|
|
135
|
-
* outdir:
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
package/dist/index.d.cts.map
CHANGED
|
@@ -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"
|
|
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
|
-
|
|
27
|
-
|
|
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,
|
|
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
|
-
*
|
|
126
|
-
* scalars: "./scalars.ts",
|
|
153
|
+
* inject: { scalars: "./scalars.ts" },
|
|
127
154
|
* },
|
|
128
155
|
* },
|
|
129
156
|
* });
|
|
130
157
|
* ```
|
|
131
158
|
*
|
|
132
|
-
* @example
|
|
159
|
+
* @example Static config with string inject (single file)
|
|
133
160
|
* ```ts
|
|
134
|
-
* export default defineConfig(
|
|
135
|
-
* outdir:
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
package/dist/index.d.mts.map
CHANGED
|
@@ -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"
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
261
|
+
export { configError, defineConfig, findConfigFile, loadConfig, loadConfigFrom, normalizeConfig, validateConfig };
|
|
291
262
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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
|
|
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": "
|
|
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
|
|
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"
|