@o3co/ts.hocon 1.10.0 → 1.11.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.ja.md +129 -1
- package/README.md +90 -2
- package/dist/adapters/env.cjs +98 -28
- package/dist/adapters/env.d.cts +16 -1
- package/dist/adapters/env.d.ts +16 -1
- package/dist/adapters/env.js +98 -27
- package/dist/adapters/jsonc.cjs +120 -17
- package/dist/adapters/jsonc.d.cts +24 -4
- package/dist/adapters/jsonc.d.ts +24 -4
- package/dist/adapters/jsonc.js +120 -16
- package/dist/adapters/properties.cjs +87 -24
- package/dist/adapters/properties.d.cts +6 -1
- package/dist/adapters/properties.d.ts +6 -1
- package/dist/adapters/properties.js +87 -23
- package/dist/adapters/toml.cjs +79 -20
- package/dist/adapters/toml.d.cts +1 -1
- package/dist/adapters/toml.d.ts +1 -1
- package/dist/adapters/toml.js +79 -19
- package/dist/adapters/yaml.cjs +100 -24
- package/dist/adapters/yaml.d.cts +10 -2
- package/dist/adapters/yaml.d.ts +10 -2
- package/dist/adapters/yaml.js +100 -23
- package/dist/{config-PdhVgeLS.d.cts → config-Dlq6rF3w.d.cts} +47 -1
- package/dist/{config-PdhVgeLS.d.ts → config-Dlq6rF3w.d.ts} +47 -1
- package/dist/index.cjs +104 -22
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +111 -22
- package/dist/zod.cjs +100 -20
- package/dist/zod.d.cts +1 -1
- package/dist/zod.d.ts +1 -1
- package/dist/zod.js +107 -20
- package/package.json +58 -22
package/dist/zod.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/coerce.ts
|
|
2
9
|
var DECIMAL_NUMBER_RE = /^-?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
3
10
|
function isHoconWs(cp) {
|
|
@@ -643,6 +650,7 @@ function isFileNotFoundError(e) {
|
|
|
643
650
|
// src/internal/resolver/include-loader.ts
|
|
644
651
|
import { createRequire } from "module";
|
|
645
652
|
import * as nodePath from "path";
|
|
653
|
+
import { pathToFileURL } from "url";
|
|
646
654
|
|
|
647
655
|
// src/internal/lexer/lexer.ts
|
|
648
656
|
function isHoconWhitespace(ch) {
|
|
@@ -1485,25 +1493,39 @@ function parseTokens(tokens) {
|
|
|
1485
1493
|
return new Parser(tokens).parse();
|
|
1486
1494
|
}
|
|
1487
1495
|
|
|
1496
|
+
// src/internal/strip-bom.ts
|
|
1497
|
+
function stripBom(input) {
|
|
1498
|
+
return input.charCodeAt(0) === 65279 ? input.slice(1) : input;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1488
1501
|
// src/internal/properties/properties.ts
|
|
1489
1502
|
function parseProperties(input) {
|
|
1490
1503
|
const pairs = [];
|
|
1491
|
-
for (const { text, line } of logicalLines(input)) {
|
|
1504
|
+
for (const { text, line } of logicalLines(stripBom(input))) {
|
|
1492
1505
|
const [rawKey, rawValue] = splitKeyValue(text);
|
|
1493
1506
|
const key = unescapeProps(rawKey, line);
|
|
1494
1507
|
if (key === "") continue;
|
|
1495
|
-
pairs.push([key, unescapeProps(rawValue, line)]);
|
|
1508
|
+
pairs.push([key.split("."), unescapeProps(rawValue, line)]);
|
|
1496
1509
|
}
|
|
1497
1510
|
return nestPairs(pairs);
|
|
1498
1511
|
}
|
|
1499
1512
|
function nestPairs(pairs) {
|
|
1500
1513
|
const root = /* @__PURE__ */ Object.create(null);
|
|
1501
|
-
const sorted = [...pairs].sort(([a], [b]) => a
|
|
1502
|
-
for (const [
|
|
1503
|
-
setNested(root,
|
|
1514
|
+
const sorted = [...pairs].sort(([a], [b]) => compareSegments(a, b));
|
|
1515
|
+
for (const [segments, value] of sorted) {
|
|
1516
|
+
setNested(root, segments, value);
|
|
1504
1517
|
}
|
|
1505
1518
|
return root;
|
|
1506
1519
|
}
|
|
1520
|
+
function compareSegments(a, b) {
|
|
1521
|
+
const n = Math.min(a.length, b.length);
|
|
1522
|
+
for (let i = 0; i < n; i++) {
|
|
1523
|
+
const x = a[i];
|
|
1524
|
+
const y = b[i];
|
|
1525
|
+
if (x !== y) return x < y ? -1 : 1;
|
|
1526
|
+
}
|
|
1527
|
+
return a.length - b.length;
|
|
1528
|
+
}
|
|
1507
1529
|
function logicalLines(input) {
|
|
1508
1530
|
const natural = input.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
|
|
1509
1531
|
const out = [];
|
|
@@ -1590,19 +1612,16 @@ function unescapeProps(s, line) {
|
|
|
1590
1612
|
}
|
|
1591
1613
|
return out;
|
|
1592
1614
|
}
|
|
1593
|
-
var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
1594
1615
|
function setNested(obj, segments, value) {
|
|
1595
1616
|
let current = obj;
|
|
1596
1617
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
1597
1618
|
const seg = segments[i];
|
|
1598
|
-
if (seg === void 0 || DANGEROUS_KEYS.has(seg)) return;
|
|
1599
1619
|
if (!(seg in current) || typeof current[seg] !== "object" || current[seg] === null) {
|
|
1600
1620
|
current[seg] = /* @__PURE__ */ Object.create(null);
|
|
1601
1621
|
}
|
|
1602
1622
|
current = current[seg];
|
|
1603
1623
|
}
|
|
1604
1624
|
const last = segments[segments.length - 1];
|
|
1605
|
-
if (last === void 0 || DANGEROUS_KEYS.has(last)) return;
|
|
1606
1625
|
if (typeof current[last] === "object" && current[last] !== null) return;
|
|
1607
1626
|
current[last] = value;
|
|
1608
1627
|
}
|
|
@@ -1623,7 +1642,22 @@ function recordToHoconValue(obj) {
|
|
|
1623
1642
|
}
|
|
1624
1643
|
|
|
1625
1644
|
// src/internal/resolver/include-loader.ts
|
|
1626
|
-
var _require
|
|
1645
|
+
var _require;
|
|
1646
|
+
function getRequire() {
|
|
1647
|
+
if (_require === void 0) {
|
|
1648
|
+
_require = pickRequire(
|
|
1649
|
+
typeof __require === "function" ? __require : void 0,
|
|
1650
|
+
import.meta.url
|
|
1651
|
+
);
|
|
1652
|
+
}
|
|
1653
|
+
return _require;
|
|
1654
|
+
}
|
|
1655
|
+
function pickRequire(candidate, metaUrl) {
|
|
1656
|
+
if (typeof candidate?.resolve === "function") {
|
|
1657
|
+
return candidate;
|
|
1658
|
+
}
|
|
1659
|
+
return createRequire(metaUrl ?? pathToFileURL(nodePath.join(process.cwd(), "noop.js")));
|
|
1660
|
+
}
|
|
1627
1661
|
function isPnpPath(p) {
|
|
1628
1662
|
return p.includes(".yarn/cache") || p.includes(".pnp.cjs") || p.includes(".pnp.loader");
|
|
1629
1663
|
}
|
|
@@ -1679,7 +1713,7 @@ function defaultPackageResolver(identifier, file, includingFile, baseDir, resolv
|
|
|
1679
1713
|
const from = resolveFrom ? Array.isArray(resolveFrom) ? resolveFrom : [resolveFrom] : baseDir ? [baseDir] : includingFile ? [nodePath.dirname(includingFile)] : [process.cwd()];
|
|
1680
1714
|
let resolved;
|
|
1681
1715
|
try {
|
|
1682
|
-
resolved =
|
|
1716
|
+
resolved = getRequire().resolve(`${identifier}/${file}`, { paths: from });
|
|
1683
1717
|
} catch {
|
|
1684
1718
|
throw new PackageLookupError(
|
|
1685
1719
|
`include package("${identifier}", "${file}"): module not found (starting from: ${from.join(", ")})`,
|
|
@@ -2729,10 +2763,10 @@ var Config = class _Config {
|
|
|
2729
2763
|
}
|
|
2730
2764
|
if (v.kind === "object") {
|
|
2731
2765
|
const converted = numericObjectToArray(v);
|
|
2732
|
-
if (converted !== null) return converted.map(hoconToJs);
|
|
2766
|
+
if (converted !== null) return converted.map((item) => hoconToJs(item));
|
|
2733
2767
|
}
|
|
2734
2768
|
if (v.kind !== "array") throw new ConfigError(`expected array at ${path2}`, path2);
|
|
2735
|
-
return v.items.map(hoconToJs);
|
|
2769
|
+
return v.items.map((item) => hoconToJs(item));
|
|
2736
2770
|
}
|
|
2737
2771
|
has(path2) {
|
|
2738
2772
|
return this.lookupNode(path2) !== void 0;
|
|
@@ -2860,8 +2894,52 @@ var Config = class _Config {
|
|
|
2860
2894
|
originDescription: this._originDescription
|
|
2861
2895
|
});
|
|
2862
2896
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2897
|
+
/**
|
|
2898
|
+
* The whole config as plain JS data: objects, arrays, strings, numbers,
|
|
2899
|
+
* booleans and `null`.
|
|
2900
|
+
*
|
|
2901
|
+
* Keys are reproduced exactly as the config carries them, `__proto__`,
|
|
2902
|
+
* `constructor` and `prototype` included: each is defined as an **own data
|
|
2903
|
+
* property**, so the returned object's prototype is always
|
|
2904
|
+
* `Object.prototype`, and this call writes nothing to the global one.
|
|
2905
|
+
*
|
|
2906
|
+
* ### Passing the result to other code
|
|
2907
|
+
*
|
|
2908
|
+
* A config file — especially a `.properties` file or an env namespace you
|
|
2909
|
+
* merged in — can therefore hand you an own `__proto__` key, and what happens
|
|
2910
|
+
* next depends entirely on how the consumer copies it:
|
|
2911
|
+
*
|
|
2912
|
+
* ```ts
|
|
2913
|
+
* const data = cfg.toObject()
|
|
2914
|
+
* { ...data } // safe — own properties are copied as data
|
|
2915
|
+
* structuredClone(data) // safe
|
|
2916
|
+
* Object.assign({}, data) // NOT safe — [[Set]] on the {} target hits
|
|
2917
|
+
* // Object.prototype's __proto__ setter: the key
|
|
2918
|
+
* // vanishes and config data becomes the result's
|
|
2919
|
+
* // prototype
|
|
2920
|
+
* deepMerge({}, data) // NOT safe — a naive recursive merge reads
|
|
2921
|
+
* // target['__proto__'], gets Object.prototype,
|
|
2922
|
+
* // and writes to it: global pollution
|
|
2923
|
+
* for (const k in data) … // prefer Object.entries / Object.keys
|
|
2924
|
+
* ```
|
|
2925
|
+
*
|
|
2926
|
+
* Those two hazards come from the **destination** object's prototype, so no
|
|
2927
|
+
* option here can disarm them — copy with spread or `structuredClone` instead.
|
|
2928
|
+
*
|
|
2929
|
+
* What `{ nullPrototype: true }` does give you is a result that inherits
|
|
2930
|
+
* nothing: every object comes back with a `null` prototype, so reading
|
|
2931
|
+
* `x.__proto__`, `x.constructor` or `x.toString` yields config data or
|
|
2932
|
+
* `undefined` rather than something from `Object.prototype`, and code that
|
|
2933
|
+
* merges *into* this object cannot climb out of it. Keys are all still
|
|
2934
|
+
* present. The trade-off is the usual one for prototype-less objects: not
|
|
2935
|
+
* `instanceof Object`, and no `hasOwnProperty` of their own.
|
|
2936
|
+
*
|
|
2937
|
+
* Numbers follow the JS number model, so an integer wider than 2^53 rounds
|
|
2938
|
+
* here even when the config holds it exactly — read those with
|
|
2939
|
+
* {@link Config.getString} instead.
|
|
2940
|
+
*/
|
|
2941
|
+
toObject(opts) {
|
|
2942
|
+
return hoconToJs(this.root, opts?.nullPrototype === true);
|
|
2865
2943
|
}
|
|
2866
2944
|
/**
|
|
2867
2945
|
* @internal Test-only: renders this resolved Config's value tree as canonical
|
|
@@ -2973,16 +3051,25 @@ function scalarToJs(raw, valueType) {
|
|
|
2973
3051
|
return raw;
|
|
2974
3052
|
}
|
|
2975
3053
|
}
|
|
2976
|
-
function hoconToJs(v) {
|
|
3054
|
+
function hoconToJs(v, nullPrototype = false) {
|
|
2977
3055
|
switch (v.kind) {
|
|
2978
3056
|
case "scalar":
|
|
2979
3057
|
return scalarToJs(v.raw, v.valueType);
|
|
2980
3058
|
case "array":
|
|
2981
|
-
return v.items.map(hoconToJs);
|
|
3059
|
+
return v.items.map((item) => hoconToJs(item, nullPrototype));
|
|
2982
3060
|
case "object": {
|
|
2983
|
-
const
|
|
2984
|
-
|
|
2985
|
-
|
|
3061
|
+
const entries = Array.from(v.fields, ([k, val]) => [k, hoconToJs(val, nullPrototype)]);
|
|
3062
|
+
if (nullPrototype) {
|
|
3063
|
+
const obj = /* @__PURE__ */ Object.create(null);
|
|
3064
|
+
for (const [k, val] of entries) Object.defineProperty(obj, k, {
|
|
3065
|
+
value: val,
|
|
3066
|
+
writable: true,
|
|
3067
|
+
enumerable: true,
|
|
3068
|
+
configurable: true
|
|
3069
|
+
});
|
|
3070
|
+
return obj;
|
|
3071
|
+
}
|
|
3072
|
+
return Object.fromEntries(entries);
|
|
2986
3073
|
}
|
|
2987
3074
|
}
|
|
2988
3075
|
}
|
|
@@ -3173,7 +3260,7 @@ function coerceValue(value, schema) {
|
|
|
3173
3260
|
const obj = value;
|
|
3174
3261
|
const result = { ...obj };
|
|
3175
3262
|
for (const key of Object.keys(shape)) {
|
|
3176
|
-
if (key
|
|
3263
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
3177
3264
|
result[key] = coerceValue(obj[key], shape[key]);
|
|
3178
3265
|
}
|
|
3179
3266
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@o3co/ts.hocon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Full Lightbend HOCON spec-compliant parser and config library for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hocon",
|
|
@@ -13,39 +13,74 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"require": {
|
|
21
|
+
"types": "./dist/index.d.cts",
|
|
22
|
+
"default": "./dist/index.cjs"
|
|
23
|
+
}
|
|
19
24
|
},
|
|
20
25
|
"./zod": {
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./dist/zod.d.ts",
|
|
28
|
+
"default": "./dist/zod.js"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/zod.d.cts",
|
|
32
|
+
"default": "./dist/zod.cjs"
|
|
33
|
+
}
|
|
24
34
|
},
|
|
25
35
|
"./adapters/properties": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/adapters/properties.d.ts",
|
|
38
|
+
"default": "./dist/adapters/properties.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/adapters/properties.d.cts",
|
|
42
|
+
"default": "./dist/adapters/properties.cjs"
|
|
43
|
+
}
|
|
29
44
|
},
|
|
30
45
|
"./adapters/env": {
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/adapters/env.d.ts",
|
|
48
|
+
"default": "./dist/adapters/env.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/adapters/env.d.cts",
|
|
52
|
+
"default": "./dist/adapters/env.cjs"
|
|
53
|
+
}
|
|
34
54
|
},
|
|
35
55
|
"./adapters/jsonc": {
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./dist/adapters/jsonc.d.ts",
|
|
58
|
+
"default": "./dist/adapters/jsonc.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./dist/adapters/jsonc.d.cts",
|
|
62
|
+
"default": "./dist/adapters/jsonc.cjs"
|
|
63
|
+
}
|
|
39
64
|
},
|
|
40
65
|
"./adapters/toml": {
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
66
|
+
"import": {
|
|
67
|
+
"types": "./dist/adapters/toml.d.ts",
|
|
68
|
+
"default": "./dist/adapters/toml.js"
|
|
69
|
+
},
|
|
70
|
+
"require": {
|
|
71
|
+
"types": "./dist/adapters/toml.d.cts",
|
|
72
|
+
"default": "./dist/adapters/toml.cjs"
|
|
73
|
+
}
|
|
44
74
|
},
|
|
45
75
|
"./adapters/yaml": {
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
76
|
+
"import": {
|
|
77
|
+
"types": "./dist/adapters/yaml.d.ts",
|
|
78
|
+
"default": "./dist/adapters/yaml.js"
|
|
79
|
+
},
|
|
80
|
+
"require": {
|
|
81
|
+
"types": "./dist/adapters/yaml.d.cts",
|
|
82
|
+
"default": "./dist/adapters/yaml.cjs"
|
|
83
|
+
}
|
|
49
84
|
}
|
|
50
85
|
},
|
|
51
86
|
"main": "./dist/index.cjs",
|
|
@@ -95,6 +130,7 @@
|
|
|
95
130
|
"bugs": "https://github.com/o3co/ts.hocon/issues",
|
|
96
131
|
"scripts": {
|
|
97
132
|
"build": "tsup",
|
|
133
|
+
"smoke": "tsup && node tools/smoke-entrypoints.mjs",
|
|
98
134
|
"test": "vitest run",
|
|
99
135
|
"test:watch": "vitest",
|
|
100
136
|
"typecheck": "tsc --noEmit",
|