@theholocron/datapad 5.0.0-alpha.9 → 5.0.0-alpha.90
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 +16 -0
- package/dist/index.d.mts +33 -3
- package/dist/index.mjs +24 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -51,6 +51,22 @@ Loads the first `<name>.config.<ext>` found in `cwd`. Probe order is
|
|
|
51
51
|
file"; a file that exists but cannot be parsed / loaded / has no default
|
|
52
52
|
export throws `ConfigFileError`.
|
|
53
53
|
|
|
54
|
+
### `loadConfigFromContent<T>({ dir, content, name, extension })`
|
|
55
|
+
|
|
56
|
+
Loads config from content that didn't come from a file already on disk —
|
|
57
|
+
writes it to `<dir>/<name>.config.<extension>` first, then loads it through
|
|
58
|
+
the exact same internals `loadConfigFile` uses for a file it discovered
|
|
59
|
+
itself. `dir` matters: it's what upward `node_modules` resolution sees, so
|
|
60
|
+
content that does `import { defineConfig } from "@theholocron/cli"` only
|
|
61
|
+
resolves if `dir` sits under a tree where that package is a real
|
|
62
|
+
dependency. Callers own creating and cleaning up `dir`. Returns
|
|
63
|
+
`{ config, filepath }`; throws `ConfigFileError` the same way
|
|
64
|
+
`loadConfigFile` does on a parse/load failure.
|
|
65
|
+
|
|
66
|
+
Built for `@theholocron/sentinel`'s `validateConfig()` — it fetches a
|
|
67
|
+
repo's `holocron.config.*` from GitHub's API, not a local checkout, but
|
|
68
|
+
still needs the fetched content to execute as a real module.
|
|
69
|
+
|
|
54
70
|
### `loadLayered<T>({ cwd, name, fallback?, extensions? })`
|
|
55
71
|
|
|
56
72
|
`<name>.config.*` layered over the `[fallback.key]` of
|
package/dist/index.d.mts
CHANGED
|
@@ -31,8 +31,10 @@ declare class ConfigFileError extends Error {
|
|
|
31
31
|
//#endregion
|
|
32
32
|
//#region src/load.d.ts
|
|
33
33
|
/**
|
|
34
|
-
* Discover and load `<name>.config.*` files
|
|
35
|
-
*
|
|
34
|
+
* Discover and load `<name>.config.*` files, or load one from content that
|
|
35
|
+
* didn't come from a file at all ({@link loadConfigFromContent}).
|
|
36
|
+
* Holocron-agnostic — no schema, no validation, no defaults. Consumers
|
|
37
|
+
* layer those on top.
|
|
36
38
|
*
|
|
37
39
|
* Probe order is **TS-first**: `.ts` → `.js` → `.mjs` → `.cjs` → `.json`.
|
|
38
40
|
* TS is loaded through `tsx`'s `tsImport` (a runtime dependency) so a
|
|
@@ -84,6 +86,34 @@ interface LayeredResult<T> {
|
|
|
84
86
|
* when neither source resolves.
|
|
85
87
|
*/
|
|
86
88
|
declare function loadLayered<T>(opts: LoadLayeredOptions): Promise<LayeredResult<T> | null>;
|
|
89
|
+
interface LoadConfigFromContentOptions {
|
|
90
|
+
/**
|
|
91
|
+
* Directory to write `<name>.config.<extension>` into before loading —
|
|
92
|
+
* this is what upward `node_modules` resolution sees, so a config that
|
|
93
|
+
* does `import { defineConfig } from "@theholocron/cli"` only resolves
|
|
94
|
+
* if `dir` sits under a tree where that package is a real dependency.
|
|
95
|
+
* Callers own creating and cleaning up `dir` — this function only
|
|
96
|
+
* writes the one file into it.
|
|
97
|
+
*/
|
|
98
|
+
dir: string;
|
|
99
|
+
/** Raw file content — not necessarily sourced from a local file at all (a network fetch, a git blob, …). */
|
|
100
|
+
content: string;
|
|
101
|
+
/** Base name — `"holocron"` writes `holocron.config.<extension>`. */
|
|
102
|
+
name: string;
|
|
103
|
+
/** Which of `DEFAULT_EXTENSIONS` `content` is — determines how it's interpreted (ts/js/mjs/cjs parsed as a module, json as `JSON.parse`). */
|
|
104
|
+
extension: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Load config from content that didn't come from a file already on disk —
|
|
108
|
+
* writes it to `<dir>/<name>.config.<extension>` first, then loads it
|
|
109
|
+
* through the exact same path {@link loadConfigFile} uses for a file it
|
|
110
|
+
* discovered itself. Exists because sourcing config content from somewhere
|
|
111
|
+
* other than the local filesystem (a GitHub API fetch, for one — see
|
|
112
|
+
* `@theholocron/sentinel`) doesn't change what loading it correctly means:
|
|
113
|
+
* a `.ts` config still needs real module resolution, `defineConfig` import
|
|
114
|
+
* included, not a re-implemented parser.
|
|
115
|
+
*/
|
|
116
|
+
declare function loadConfigFromContent<T>(opts: LoadConfigFromContentOptions): Promise<Loaded<T>>;
|
|
87
117
|
//#endregion
|
|
88
118
|
//#region src/merge.d.ts
|
|
89
119
|
/**
|
|
@@ -98,4 +128,4 @@ declare function loadLayered<T>(opts: LoadLayeredOptions): Promise<LayeredResult
|
|
|
98
128
|
*/
|
|
99
129
|
declare function mergeConfig<T>(base: T, override: unknown): T;
|
|
100
130
|
//#endregion
|
|
101
|
-
export { ConfigFileError, DEFAULT_EXTENSIONS, type LayeredResult, type LoadConfigFileOptions, type LoadLayeredOptions, type Loaded, createDefineConfig, loadConfigFile, loadLayered, mergeConfig };
|
|
131
|
+
export { ConfigFileError, DEFAULT_EXTENSIONS, type LayeredResult, type LoadConfigFileOptions, type LoadConfigFromContentOptions, type LoadLayeredOptions, type Loaded, createDefineConfig, loadConfigFile, loadConfigFromContent, loadLayered, mergeConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, stat } from "node:fs/promises";
|
|
1
|
+
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
//#region src/define.ts
|
|
@@ -65,8 +65,10 @@ function isPlainObject(value) {
|
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region src/load.ts
|
|
67
67
|
/**
|
|
68
|
-
* Discover and load `<name>.config.*` files
|
|
69
|
-
*
|
|
68
|
+
* Discover and load `<name>.config.*` files, or load one from content that
|
|
69
|
+
* didn't come from a file at all ({@link loadConfigFromContent}).
|
|
70
|
+
* Holocron-agnostic — no schema, no validation, no defaults. Consumers
|
|
71
|
+
* layer those on top.
|
|
70
72
|
*
|
|
71
73
|
* Probe order is **TS-first**: `.ts` → `.js` → `.mjs` → `.cjs` → `.json`.
|
|
72
74
|
* TS is loaded through `tsx`'s `tsImport` (a runtime dependency) so a
|
|
@@ -127,6 +129,24 @@ async function loadLayered(opts) {
|
|
|
127
129
|
sources
|
|
128
130
|
};
|
|
129
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Load config from content that didn't come from a file already on disk —
|
|
134
|
+
* writes it to `<dir>/<name>.config.<extension>` first, then loads it
|
|
135
|
+
* through the exact same path {@link loadConfigFile} uses for a file it
|
|
136
|
+
* discovered itself. Exists because sourcing config content from somewhere
|
|
137
|
+
* other than the local filesystem (a GitHub API fetch, for one — see
|
|
138
|
+
* `@theholocron/sentinel`) doesn't change what loading it correctly means:
|
|
139
|
+
* a `.ts` config still needs real module resolution, `defineConfig` import
|
|
140
|
+
* included, not a re-implemented parser.
|
|
141
|
+
*/
|
|
142
|
+
async function loadConfigFromContent(opts) {
|
|
143
|
+
const filepath = join(opts.dir, `${opts.name}.config.${opts.extension}`);
|
|
144
|
+
await writeFile(filepath, opts.content, "utf8");
|
|
145
|
+
return {
|
|
146
|
+
config: await loadFile(filepath, opts.extension),
|
|
147
|
+
filepath
|
|
148
|
+
};
|
|
149
|
+
}
|
|
130
150
|
async function loadFile(filepath, ext) {
|
|
131
151
|
if (ext === "json") return loadJson(filepath);
|
|
132
152
|
return extractDefault(filepath, ext === "ts" ? await importTs(filepath) : await importModule(filepath));
|
|
@@ -188,4 +208,4 @@ async function isFile(path) {
|
|
|
188
208
|
}
|
|
189
209
|
const message = (err) => err instanceof Error ? err.message : String(err);
|
|
190
210
|
//#endregion
|
|
191
|
-
export { ConfigFileError, DEFAULT_EXTENSIONS, createDefineConfig, loadConfigFile, loadLayered, mergeConfig };
|
|
211
|
+
export { ConfigFileError, DEFAULT_EXTENSIONS, createDefineConfig, loadConfigFile, loadConfigFromContent, loadLayered, mergeConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/datapad",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.90",
|
|
4
4
|
"description": "Generic config-file loading for Holocron — discover, load (JSON/JS/TS/ESM/CJS), and merge <name>.config.* files with a typed defineConfig.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"config",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"tsx": "4.23.12"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@theholocron/eslint-config": "^8.
|
|
39
|
-
"@theholocron/tsconfig": "^8.
|
|
40
|
-
"@theholocron/tsdown-config": "^8.
|
|
41
|
-
"@theholocron/vitest-config": "^8.
|
|
38
|
+
"@theholocron/eslint-config": "^8.6.0",
|
|
39
|
+
"@theholocron/tsconfig": "^8.4.5",
|
|
40
|
+
"@theholocron/tsdown-config": "^8.4.5",
|
|
41
|
+
"@theholocron/vitest-config": "^8.4.5",
|
|
42
42
|
"@types/node": "^26",
|
|
43
43
|
"@vitest/coverage-v8": "^4.1.11",
|
|
44
44
|
"@vitest/eslint-plugin": "^1.6.27",
|