@rhombus-std/config.json 0.0.0-alpha.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/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +88 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Thomas Butler
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @rhombus-std/config.json
|
|
2
|
+
|
|
3
|
+
JSON file configuration provider for `@rhombus-std/config` —
|
|
4
|
+
`JsonConfigurationSource`/`JsonConfigurationProvider` plus the `addJsonFile`
|
|
5
|
+
sugar bolted onto `ConfigurationBuilder`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @rhombus-std/config @rhombus-std/config.json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`@rhombus-std/config` is a peer dependency — install it alongside this package.
|
|
14
|
+
|
|
15
|
+
## Basic usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import "@rhombus-std/config.json"; // unlocks .addJsonFile() on ConfigurationBuilder
|
|
19
|
+
import { ConfigurationBuilder } from "@rhombus-std/config";
|
|
20
|
+
|
|
21
|
+
const config = new ConfigurationBuilder()
|
|
22
|
+
.addJsonFile("appsettings.json")
|
|
23
|
+
.addJsonFile("appsettings.local.json", { optional: true })
|
|
24
|
+
.build();
|
|
25
|
+
|
|
26
|
+
config.get("Server:Port");
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`optional: true` makes a missing file resolve to an empty provider instead of
|
|
30
|
+
throwing. Malformed JSON in a file that _does_ exist always throws, regardless
|
|
31
|
+
of `optional` — it only covers file absence, not file validity.
|
|
32
|
+
|
|
33
|
+
## The side-effect import requirement
|
|
34
|
+
|
|
35
|
+
`addJsonFile` isn't a method `ConfigurationBuilder` ships with — this package
|
|
36
|
+
bolts it on via TypeScript declaration merging plus a runtime prototype
|
|
37
|
+
patch. If your code calls `.addJsonFile()` but never names any other symbol
|
|
38
|
+
from `@rhombus-std/config.json` (no `JsonConfigurationSource`, no
|
|
39
|
+
`JsonConfigurationProvider`), a bundler or tree-shaker has nothing forcing it
|
|
40
|
+
to load this package's module — you must import it for its side effect
|
|
41
|
+
explicitly:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import "@rhombus-std/config.json"; // unlocks .addJsonFile() on ConfigurationBuilder
|
|
45
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IConfigurationSource, IConfigurationBuilder, IConfigurationProvider, IndexedSection } from '@rhombus-std/config.core';
|
|
2
|
+
import { ConfigurationProvider } from '@rhombus-std/config';
|
|
3
|
+
|
|
4
|
+
/** Options accepted by {@link JsonConfigurationSource}'s constructor. */
|
|
5
|
+
interface JsonConfigurationSourceOptions {
|
|
6
|
+
/**
|
|
7
|
+
* When `true`, a missing file yields an empty provider instead of
|
|
8
|
+
* throwing. Malformed JSON in a file that *does* exist always throws,
|
|
9
|
+
* regardless of this flag -- "optional" only covers file absence, not
|
|
10
|
+
* file validity.
|
|
11
|
+
*/
|
|
12
|
+
optional?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A {@link IConfigurationSource} that reads a JSON file from disk (resolved
|
|
16
|
+
* relative to `process.cwd()`) and flattens it into the case-insensitive
|
|
17
|
+
* key/value store shared by every {@link ConfigurationProvider}.
|
|
18
|
+
*/
|
|
19
|
+
declare class JsonConfigurationSource implements IConfigurationSource {
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly optional: boolean;
|
|
22
|
+
constructor(path: string, opts?: JsonConfigurationSourceOptions);
|
|
23
|
+
build(_builder: IConfigurationBuilder): IConfigurationProvider;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class JsonConfigurationProvider extends ConfigurationProvider {
|
|
27
|
+
private readonly source;
|
|
28
|
+
constructor(source: JsonConfigurationSource);
|
|
29
|
+
load(): void;
|
|
30
|
+
private flatten;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module "@rhombus-std/config/configuration-builder" {
|
|
34
|
+
interface ConfigurationBuilder<T = IndexedSection> {
|
|
35
|
+
/** Registers a {@link JsonConfigurationSource} reading `path` (resolved against `process.cwd()`). */
|
|
36
|
+
addJsonFile(path: string, opts?: JsonConfigurationSourceOptions): this;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { JsonConfigurationProvider, JsonConfigurationSource };
|
|
41
|
+
export type { JsonConfigurationSourceOptions };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { ConfigurationBuilder } from "@rhombus-std/config";
|
|
3
|
+
|
|
4
|
+
// src/json-configuration-provider.ts
|
|
5
|
+
import { ConfigurationProvider } from "@rhombus-std/config";
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
function isFileNotFound(err) {
|
|
9
|
+
return typeof err === "object" && err !== null && err.code === "ENOENT";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class JsonConfigurationProvider extends ConfigurationProvider {
|
|
13
|
+
source;
|
|
14
|
+
constructor(source) {
|
|
15
|
+
super();
|
|
16
|
+
this.source = source;
|
|
17
|
+
}
|
|
18
|
+
load() {
|
|
19
|
+
this.data.clear();
|
|
20
|
+
const resolvedPath = resolve(process.cwd(), this.source.path);
|
|
21
|
+
let raw;
|
|
22
|
+
try {
|
|
23
|
+
raw = readFileSync(resolvedPath, "utf-8");
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (isFileNotFound(err)) {
|
|
26
|
+
if (this.source.optional) {
|
|
27
|
+
this.onReload();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`JsonConfigurationProvider: config file not found: ${resolvedPath}`);
|
|
31
|
+
}
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = JSON.parse(raw);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
throw new Error(`JsonConfigurationProvider: failed to parse JSON at ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
39
|
+
}
|
|
40
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
41
|
+
throw new Error(`JsonConfigurationProvider: root must be an object or array at ${resolvedPath}`);
|
|
42
|
+
}
|
|
43
|
+
this.flatten(parsed, "");
|
|
44
|
+
this.onReload();
|
|
45
|
+
}
|
|
46
|
+
flatten(value, prefix) {
|
|
47
|
+
if (value === null || value === undefined) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
value.forEach((item, index) => {
|
|
52
|
+
this.flatten(item, prefix === "" ? String(index) : `${prefix}:${index}`);
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (typeof value === "object") {
|
|
57
|
+
for (const [key, child] of Object.entries(value)) {
|
|
58
|
+
this.flatten(child, prefix === "" ? key : `${prefix}:${key}`);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (prefix !== "") {
|
|
63
|
+
this.set(prefix, String(value));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/json-configuration-source.ts
|
|
69
|
+
class JsonConfigurationSource {
|
|
70
|
+
path;
|
|
71
|
+
optional;
|
|
72
|
+
constructor(path, opts) {
|
|
73
|
+
this.path = path;
|
|
74
|
+
this.optional = opts?.optional ?? false;
|
|
75
|
+
}
|
|
76
|
+
build(_builder) {
|
|
77
|
+
return new JsonConfigurationProvider(this);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/index.ts
|
|
82
|
+
ConfigurationBuilder.prototype.addJsonFile = function(path, opts) {
|
|
83
|
+
return this.add(new JsonConfigurationSource(path, opts));
|
|
84
|
+
};
|
|
85
|
+
export {
|
|
86
|
+
JsonConfigurationSource,
|
|
87
|
+
JsonConfigurationProvider
|
|
88
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rhombus-std/config.json",
|
|
3
|
+
"version": "0.0.0-alpha.0",
|
|
4
|
+
"description": "JSON file configuration provider for @rhombus-std/config: JsonConfigurationSource/Provider + the addJsonFile augmentation.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"configuration",
|
|
7
|
+
"config",
|
|
8
|
+
"json",
|
|
9
|
+
"ioc",
|
|
10
|
+
"typescript"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/fnioc/std.git",
|
|
16
|
+
"directory": "libraries/config.json"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"sideEffects": true,
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@rhombus-std/config.core": "0.0.0-alpha.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@rhombus-std/config": "^0.0.0-alpha.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@rhombus-std/config": "0.0.0-alpha.0"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "bun x tsc --noEmit -p tsconfig.json && bun build.ts",
|
|
47
|
+
"lint": "bun x tsc --noEmit -p tsconfig.lint.json"
|
|
48
|
+
}
|
|
49
|
+
}
|