@optique/config 1.0.0-dev.566 → 1.0.0-dev.569
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +43 -37
- package/dist/index.js +43 -37
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -21,7 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
const
|
|
24
|
+
const node_fs = __toESM(require("node:fs"));
|
|
25
25
|
const node_path = __toESM(require("node:path"));
|
|
26
26
|
const __optique_core_annotations = __toESM(require("@optique/core/annotations"));
|
|
27
27
|
const __optique_core_message = __toESM(require("@optique/core/message"));
|
|
@@ -89,15 +89,18 @@ function isErrnoException(error) {
|
|
|
89
89
|
* Validates raw data against a Standard Schema and returns the validated value.
|
|
90
90
|
* @internal
|
|
91
91
|
*/
|
|
92
|
-
|
|
93
|
-
const validation = schema["~standard"].validate(rawData);
|
|
94
|
-
const validationResult = validation instanceof Promise ? await validation : validation;
|
|
92
|
+
function processValidationResult(validationResult) {
|
|
95
93
|
if (validationResult.issues) {
|
|
96
94
|
const firstIssue = validationResult.issues[0];
|
|
97
95
|
throw new Error(`Config validation failed: ${firstIssue?.message ?? "Unknown error"}`);
|
|
98
96
|
}
|
|
99
97
|
return validationResult.value;
|
|
100
98
|
}
|
|
99
|
+
function validateWithSchema(schema, rawData) {
|
|
100
|
+
const validation = schema["~standard"].validate(rawData);
|
|
101
|
+
if (validation instanceof Promise) return validation.then((result) => processValidationResult(result));
|
|
102
|
+
return processValidationResult(validation);
|
|
103
|
+
}
|
|
101
104
|
/**
|
|
102
105
|
* Creates a config context for use with Optique parsers.
|
|
103
106
|
*
|
|
@@ -131,43 +134,13 @@ function createConfigContext(options) {
|
|
|
131
134
|
id: contextId,
|
|
132
135
|
schema: options.schema,
|
|
133
136
|
mode: "dynamic",
|
|
134
|
-
|
|
137
|
+
getAnnotations(parsed, runtimeOptions) {
|
|
135
138
|
if (!parsed) return {};
|
|
136
139
|
const opts = runtimeOptions;
|
|
137
140
|
if (!opts || !opts.getConfigPath && !opts.load) throw new TypeError("Either getConfigPath or load must be provided in the runner options when using ConfigContext.");
|
|
138
|
-
let configData;
|
|
139
|
-
let configMeta;
|
|
140
141
|
const parsedValue = parsed;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
configData = await validateWithSchema(options.schema, loaded.config);
|
|
144
|
-
configMeta = loaded.meta;
|
|
145
|
-
} else if (opts.getConfigPath) {
|
|
146
|
-
const configPath = opts.getConfigPath(parsedValue);
|
|
147
|
-
if (configPath) {
|
|
148
|
-
const absoluteConfigPath = (0, node_path.resolve)(configPath);
|
|
149
|
-
const singleFileMeta = {
|
|
150
|
-
configDir: (0, node_path.dirname)(absoluteConfigPath),
|
|
151
|
-
configPath: absoluteConfigPath
|
|
152
|
-
};
|
|
153
|
-
try {
|
|
154
|
-
const contents = await (0, node_fs_promises.readFile)(absoluteConfigPath);
|
|
155
|
-
let rawData;
|
|
156
|
-
if (options.fileParser) rawData = options.fileParser(contents);
|
|
157
|
-
else {
|
|
158
|
-
const text = new TextDecoder().decode(contents);
|
|
159
|
-
rawData = JSON.parse(text);
|
|
160
|
-
}
|
|
161
|
-
configData = await validateWithSchema(options.schema, rawData);
|
|
162
|
-
configMeta = singleFileMeta;
|
|
163
|
-
} catch (error) {
|
|
164
|
-
if (isErrnoException(error) && error.code === "ENOENT") configData = void 0;
|
|
165
|
-
else if (error instanceof SyntaxError) throw new Error(`Failed to parse config file ${absoluteConfigPath}: ${error.message}`);
|
|
166
|
-
else throw error;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (configData !== void 0 && configData !== null) {
|
|
142
|
+
const buildAnnotations = (configData, configMeta) => {
|
|
143
|
+
if (configData === void 0 || configData === null) return {};
|
|
171
144
|
setActiveConfig(contextId, configData);
|
|
172
145
|
if (configMeta !== void 0) {
|
|
173
146
|
setActiveConfigMeta(contextId, configMeta);
|
|
@@ -177,6 +150,39 @@ function createConfigContext(options) {
|
|
|
177
150
|
} };
|
|
178
151
|
}
|
|
179
152
|
return { [contextId]: { data: configData } };
|
|
153
|
+
};
|
|
154
|
+
const validateAndBuildAnnotations = (rawData, configMeta) => {
|
|
155
|
+
const validated = validateWithSchema(options.schema, rawData);
|
|
156
|
+
if (validated instanceof Promise) return validated.then((configData) => buildAnnotations(configData, configMeta));
|
|
157
|
+
return buildAnnotations(validated, configMeta);
|
|
158
|
+
};
|
|
159
|
+
if (opts.load) {
|
|
160
|
+
const loaded = opts.load(parsedValue);
|
|
161
|
+
if (loaded instanceof Promise) return loaded.then(({ config, meta }) => validateAndBuildAnnotations(config, meta));
|
|
162
|
+
return validateAndBuildAnnotations(loaded.config, loaded.meta);
|
|
163
|
+
}
|
|
164
|
+
if (opts.getConfigPath) {
|
|
165
|
+
const configPath = opts.getConfigPath(parsedValue);
|
|
166
|
+
if (!configPath) return {};
|
|
167
|
+
const absoluteConfigPath = (0, node_path.resolve)(configPath);
|
|
168
|
+
const singleFileMeta = {
|
|
169
|
+
configDir: (0, node_path.dirname)(absoluteConfigPath),
|
|
170
|
+
configPath: absoluteConfigPath
|
|
171
|
+
};
|
|
172
|
+
try {
|
|
173
|
+
const contents = (0, node_fs.readFileSync)(absoluteConfigPath);
|
|
174
|
+
let rawData;
|
|
175
|
+
if (options.fileParser) rawData = options.fileParser(contents);
|
|
176
|
+
else {
|
|
177
|
+
const text = new TextDecoder().decode(contents);
|
|
178
|
+
rawData = JSON.parse(text);
|
|
179
|
+
}
|
|
180
|
+
return validateAndBuildAnnotations(rawData, singleFileMeta);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (isErrnoException(error) && error.code === "ENOENT") return {};
|
|
183
|
+
if (error instanceof SyntaxError) throw new Error(`Failed to parse config file ${absoluteConfigPath}: ${error.message}`);
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
180
186
|
}
|
|
181
187
|
return {};
|
|
182
188
|
},
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, resolve } from "node:path";
|
|
3
3
|
import { annotationKey, getAnnotations } from "@optique/core/annotations";
|
|
4
4
|
import { message } from "@optique/core/message";
|
|
@@ -66,15 +66,18 @@ function isErrnoException(error) {
|
|
|
66
66
|
* Validates raw data against a Standard Schema and returns the validated value.
|
|
67
67
|
* @internal
|
|
68
68
|
*/
|
|
69
|
-
|
|
70
|
-
const validation = schema["~standard"].validate(rawData);
|
|
71
|
-
const validationResult = validation instanceof Promise ? await validation : validation;
|
|
69
|
+
function processValidationResult(validationResult) {
|
|
72
70
|
if (validationResult.issues) {
|
|
73
71
|
const firstIssue = validationResult.issues[0];
|
|
74
72
|
throw new Error(`Config validation failed: ${firstIssue?.message ?? "Unknown error"}`);
|
|
75
73
|
}
|
|
76
74
|
return validationResult.value;
|
|
77
75
|
}
|
|
76
|
+
function validateWithSchema(schema, rawData) {
|
|
77
|
+
const validation = schema["~standard"].validate(rawData);
|
|
78
|
+
if (validation instanceof Promise) return validation.then((result) => processValidationResult(result));
|
|
79
|
+
return processValidationResult(validation);
|
|
80
|
+
}
|
|
78
81
|
/**
|
|
79
82
|
* Creates a config context for use with Optique parsers.
|
|
80
83
|
*
|
|
@@ -108,43 +111,13 @@ function createConfigContext(options) {
|
|
|
108
111
|
id: contextId,
|
|
109
112
|
schema: options.schema,
|
|
110
113
|
mode: "dynamic",
|
|
111
|
-
|
|
114
|
+
getAnnotations(parsed, runtimeOptions) {
|
|
112
115
|
if (!parsed) return {};
|
|
113
116
|
const opts = runtimeOptions;
|
|
114
117
|
if (!opts || !opts.getConfigPath && !opts.load) throw new TypeError("Either getConfigPath or load must be provided in the runner options when using ConfigContext.");
|
|
115
|
-
let configData;
|
|
116
|
-
let configMeta;
|
|
117
118
|
const parsedValue = parsed;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
configData = await validateWithSchema(options.schema, loaded.config);
|
|
121
|
-
configMeta = loaded.meta;
|
|
122
|
-
} else if (opts.getConfigPath) {
|
|
123
|
-
const configPath = opts.getConfigPath(parsedValue);
|
|
124
|
-
if (configPath) {
|
|
125
|
-
const absoluteConfigPath = resolve(configPath);
|
|
126
|
-
const singleFileMeta = {
|
|
127
|
-
configDir: dirname(absoluteConfigPath),
|
|
128
|
-
configPath: absoluteConfigPath
|
|
129
|
-
};
|
|
130
|
-
try {
|
|
131
|
-
const contents = await readFile(absoluteConfigPath);
|
|
132
|
-
let rawData;
|
|
133
|
-
if (options.fileParser) rawData = options.fileParser(contents);
|
|
134
|
-
else {
|
|
135
|
-
const text = new TextDecoder().decode(contents);
|
|
136
|
-
rawData = JSON.parse(text);
|
|
137
|
-
}
|
|
138
|
-
configData = await validateWithSchema(options.schema, rawData);
|
|
139
|
-
configMeta = singleFileMeta;
|
|
140
|
-
} catch (error) {
|
|
141
|
-
if (isErrnoException(error) && error.code === "ENOENT") configData = void 0;
|
|
142
|
-
else if (error instanceof SyntaxError) throw new Error(`Failed to parse config file ${absoluteConfigPath}: ${error.message}`);
|
|
143
|
-
else throw error;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (configData !== void 0 && configData !== null) {
|
|
119
|
+
const buildAnnotations = (configData, configMeta) => {
|
|
120
|
+
if (configData === void 0 || configData === null) return {};
|
|
148
121
|
setActiveConfig(contextId, configData);
|
|
149
122
|
if (configMeta !== void 0) {
|
|
150
123
|
setActiveConfigMeta(contextId, configMeta);
|
|
@@ -154,6 +127,39 @@ function createConfigContext(options) {
|
|
|
154
127
|
} };
|
|
155
128
|
}
|
|
156
129
|
return { [contextId]: { data: configData } };
|
|
130
|
+
};
|
|
131
|
+
const validateAndBuildAnnotations = (rawData, configMeta) => {
|
|
132
|
+
const validated = validateWithSchema(options.schema, rawData);
|
|
133
|
+
if (validated instanceof Promise) return validated.then((configData) => buildAnnotations(configData, configMeta));
|
|
134
|
+
return buildAnnotations(validated, configMeta);
|
|
135
|
+
};
|
|
136
|
+
if (opts.load) {
|
|
137
|
+
const loaded = opts.load(parsedValue);
|
|
138
|
+
if (loaded instanceof Promise) return loaded.then(({ config, meta }) => validateAndBuildAnnotations(config, meta));
|
|
139
|
+
return validateAndBuildAnnotations(loaded.config, loaded.meta);
|
|
140
|
+
}
|
|
141
|
+
if (opts.getConfigPath) {
|
|
142
|
+
const configPath = opts.getConfigPath(parsedValue);
|
|
143
|
+
if (!configPath) return {};
|
|
144
|
+
const absoluteConfigPath = resolve(configPath);
|
|
145
|
+
const singleFileMeta = {
|
|
146
|
+
configDir: dirname(absoluteConfigPath),
|
|
147
|
+
configPath: absoluteConfigPath
|
|
148
|
+
};
|
|
149
|
+
try {
|
|
150
|
+
const contents = readFileSync(absoluteConfigPath);
|
|
151
|
+
let rawData;
|
|
152
|
+
if (options.fileParser) rawData = options.fileParser(contents);
|
|
153
|
+
else {
|
|
154
|
+
const text = new TextDecoder().decode(contents);
|
|
155
|
+
rawData = JSON.parse(text);
|
|
156
|
+
}
|
|
157
|
+
return validateAndBuildAnnotations(rawData, singleFileMeta);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (isErrnoException(error) && error.code === "ENOENT") return {};
|
|
160
|
+
if (error instanceof SyntaxError) throw new Error(`Failed to parse config file ${absoluteConfigPath}: ${error.message}`);
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
157
163
|
}
|
|
158
164
|
return {};
|
|
159
165
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/config",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.569+2ac8093c",
|
|
4
4
|
"description": "Configuration file support for Optique with Standard Schema validation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@standard-schema/spec": "^1.1.0"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@optique/core": "1.0.0-dev.
|
|
62
|
+
"@optique/core": "1.0.0-dev.569+2ac8093c"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@standard-schema/spec": "^1.1.0",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"tsdown": "^0.13.0",
|
|
68
68
|
"typescript": "^5.8.3",
|
|
69
69
|
"zod": "^3.25.0 || ^4.0.0",
|
|
70
|
-
"@optique/env": "1.0.0-dev.
|
|
70
|
+
"@optique/env": "1.0.0-dev.569+2ac8093c"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
73
|
"build": "tsdown",
|