@o3co/ts.hocon 1.14.1 → 1.14.2

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 CHANGED
@@ -249,7 +249,7 @@ const app = validate(cfg, Schema)
249
249
  const port = getValidated(cfg, 'server.port', z.number().int())
250
250
  ```
251
251
 
252
- スキーマが数値や真偽値を求める位置では文字列を変換するので、`PORT=8081` のとき `port = ${?PORT}` は `z.number()` を通ります。変換はスキーマに沿って、object・array・record(各値)・tuple・union・pipe(入力側のスキーマ)・lazy と、optional / nullable / default / prefault / nonoptional / catch / readonly の各ラッパーの中まで届きます。数値や真偽値の literal にも変換します(`z.literal(1)` に対する `"1"`)。object の `catchall` と intersection の中には届きません。`z.discriminatedUnion` は discriminator が選ぶ option に従って変換します。それ以外の union は、値をそのまま受け入れる option があれば変換せず(`z.union([z.number(), z.string()])` では `"5"` は文字列のまま)、なければ変換後の値を受け入れる最初の option に従って変換します(`z.union([z.number(), z.literal('auto')])` では `"8081"` は 8081)。その option を探すために option を順に試すので、深く再帰する通常の union は検証が遅くなります。そこでは `z.discriminatedUnion` を使ってください。
252
+ スキーマが数値や真偽値を求める位置では文字列を変換するので、`PORT=8081` のとき `port = ${?PORT}` は `z.number()` を通ります。変換はスキーマに沿って、object・array・record(各値)・tuple・union・pipe(入力側のスキーマ)・lazy・intersection(両側が受け入れる最初の形。元の値、片側向けの変換、両側向けの変換の順)・object の `catchall` と、optional / nullable / default / prefault / nonoptional / success / catch / readonly の各ラッパーの中まで届きます。数値や真偽値の literal と、数値の enum の値にも変換します(`z.literal(1)` や `z.enum({ A: 1 })` に対する `"1"`)。`z.discriminatedUnion` は discriminator が選ぶ option に従って変換します。それ以外の union は、値をそのまま受け入れる option があれば変換せず(`z.union([z.number(), z.string()])` では `"5"` は文字列のまま)、なければ変換後の値を受け入れる最初の option に従って変換します(`z.union([z.number(), z.literal('auto')])` では `"8081"` は 8081)。その option を探すために option を順に試すので、深く再帰する通常の union は検証が遅くなります。そこでは `z.discriminatedUnion` を使ってください。
253
253
 
254
254
  HOCON の duration と byte size は文字列(`30m`、`64KiB`)なので、`z.number()` では通りません。`hocon.duration(unit?)` / `hocon.bytes(unit?)` マーカーは `getDuration()` / `getBytes()` と同じ規則で読み、指定した単位の数値を返します(既定は `ms` / `B`。単位のない数値は getter と同じ意味)。範囲や整数のチェックは、マーカーを数値スキーマに pipe して書きます:
255
255
 
package/README.md CHANGED
@@ -250,7 +250,7 @@ const app = validate(cfg, Schema)
250
250
  const port = getValidated(cfg, 'server.port', z.number().int())
251
251
  ```
252
252
 
253
- A string is coerced where the schema expects a number or a boolean, so `port = ${?PORT}` with `PORT=8081` validates against `z.number()`. The coercion follows the schema through objects, arrays, records (each value), tuples, unions, pipes (by the input schema), lazy schemas and the optional / nullable / default / prefault / nonoptional / catch / readonly wrappers, and turns a string into a number or boolean literal (`"1"` for `z.literal(1)`). It does not walk an object's `catchall` or an intersection. A `z.discriminatedUnion` coerces by the option the discriminator picks. Any other union takes the value as it is when an option accepts it, so `z.union([z.number(), z.string()])` keeps `"5"` a string, and coerces it otherwise, by the first option that accepts the coerced value (`z.union([z.number(), z.literal('auto')])` reads `"8081"` as 8081). Finding that option tries the options in turn, so a deeply recursive plain union validates slowly; prefer `z.discriminatedUnion` there.
253
+ A string is coerced where the schema expects a number or a boolean, so `port = ${?PORT}` with `PORT=8081` validates against `z.number()`. The coercion follows the schema through objects, arrays, records (each value), tuples, unions, pipes (by the input schema), lazy schemas, intersections (the first form both sides accept: as it is, coerced for one side, or for both), an object's `catchall` and the optional / nullable / default / prefault / nonoptional / success / catch / readonly wrappers, and turns a string into a number or boolean literal or a numeric enum value (`"1"` for `z.literal(1)` or `z.enum({ A: 1 })`). A `z.discriminatedUnion` coerces by the option the discriminator picks. Any other union takes the value as it is when an option accepts it, so `z.union([z.number(), z.string()])` keeps `"5"` a string, and coerces it otherwise, by the first option that accepts the coerced value (`z.union([z.number(), z.literal('auto')])` reads `"8081"` as 8081). Finding that option tries the options in turn, so a deeply recursive plain union validates slowly; prefer `z.discriminatedUnion` there.
254
254
 
255
255
  Durations and byte sizes are strings in HOCON (`30m`, `64KiB`), so `z.number()` refuses them. The `hocon.duration(unit?)` and `hocon.bytes(unit?)` markers read them with the same rules as `getDuration()` / `getBytes()` and give a number in the requested unit (default `ms` / `B`; a plain number keeps the getters' meaning). Pipe the marker into a number schema for range and integer checks:
256
256
 
package/dist/zod.cjs CHANGED
@@ -27,8 +27,11 @@ function parseValue(value, schema) {
27
27
  let result;
28
28
  try {
29
29
  result = schema.safeParse(coerced);
30
- } catch (e) {
31
- throw new _zod2.z.ZodError(refused);
30
+ } catch (err) {
31
+ if (err instanceof _zod2.z.core.$ZodAsyncError || _optionalChain([err, 'optionalAccess', _ => _.constructor, 'optionalAccess', _2 => _2.name]) === "$ZodAsyncError") {
32
+ throw new _zod2.z.ZodError(refused);
33
+ }
34
+ throw err;
32
35
  }
33
36
  if (result.success) throw new _zod2.z.ZodError(refused);
34
37
  throw new _zod2.z.ZodError([...refused, ...withoutPrototypeKeyIssues(result.error.issues)]);
@@ -126,24 +129,24 @@ var hocon = {
126
129
  };
127
130
  function getDefType(schema) {
128
131
  const zod = schema._zod;
129
- return _optionalChain([zod, 'optionalAccess', _ => _.def, 'optionalAccess', _2 => _2.type]);
132
+ return _optionalChain([zod, 'optionalAccess', _3 => _3.def, 'optionalAccess', _4 => _4.type]);
130
133
  }
131
134
  function getDef(schema) {
132
- return _optionalChain([schema, 'access', _3 => _3._zod, 'optionalAccess', _4 => _4.def]);
135
+ return _optionalChain([schema, 'access', _5 => _5._zod, 'optionalAccess', _6 => _6.def]);
133
136
  }
134
137
  function getInnerSchema(schema) {
135
- const def = _optionalChain([schema, 'access', _5 => _5._zod, 'optionalAccess', _6 => _6.def]);
136
- return _nullishCoalesce(_optionalChain([def, 'optionalAccess', _7 => _7.innerType]), () => ( _optionalChain([def, 'optionalAccess', _8 => _8.schema])));
138
+ const def = _optionalChain([schema, 'access', _7 => _7._zod, 'optionalAccess', _8 => _8.def]);
139
+ return _nullishCoalesce(_optionalChain([def, 'optionalAccess', _9 => _9.innerType]), () => ( _optionalChain([def, 'optionalAccess', _10 => _10.schema])));
137
140
  }
138
141
  function getObjectShape(schema) {
139
- const shape = _optionalChain([schema, 'access', _9 => _9._zod, 'optionalAccess', _10 => _10.def, 'optionalAccess', _11 => _11.shape]);
142
+ const shape = _optionalChain([schema, 'access', _11 => _11._zod, 'optionalAccess', _12 => _12.def, 'optionalAccess', _13 => _13.shape]);
140
143
  return typeof shape === "object" && shape !== null ? shape : void 0;
141
144
  }
142
145
  function getPropValues(schema) {
143
- return _optionalChain([schema, 'access', _12 => _12._zod, 'optionalAccess', _13 => _13.propValues]);
146
+ return _optionalChain([schema, 'access', _14 => _14._zod, 'optionalAccess', _15 => _15.propValues]);
144
147
  }
145
148
  function getArrayElement(schema) {
146
- return _optionalChain([schema, 'access', _14 => _14._zod, 'optionalAccess', _15 => _15.def, 'optionalAccess', _16 => _16.element]);
149
+ return _optionalChain([schema, 'access', _16 => _16._zod, 'optionalAccess', _17 => _17.def, 'optionalAccess', _18 => _18.element]);
147
150
  }
148
151
  function parseWithSchema(input, schema, opts) {
149
152
  const config = _chunkOUPKYWL3cjs.parse.call(void 0, input, opts);
@@ -170,8 +173,12 @@ function coerceValue(value, schema) {
170
173
  return coerced !== void 0 ? coerced : value;
171
174
  }
172
175
  return value;
176
+ case "enum": {
177
+ const values = schema._zod.values;
178
+ return coerceToLiteral(value, values);
179
+ }
173
180
  case "literal": {
174
- const values = _optionalChain([getDef, 'call', _17 => _17(schema), 'optionalAccess', _18 => _18.values]);
181
+ const values = _optionalChain([getDef, 'call', _19 => _19(schema), 'optionalAccess', _20 => _20.values]);
175
182
  return values ? coerceToLiteral(value, new Set(values)) : value;
176
183
  }
177
184
  case "object": {
@@ -185,8 +192,23 @@ function coerceValue(value, schema) {
185
192
  result[key] = coerceValue(obj[key], shape[key]);
186
193
  }
187
194
  }
195
+ const catchall = _optionalChain([getDef, 'call', _21 => _21(schema), 'optionalAccess', _22 => _22.catchall]);
196
+ if (catchall) {
197
+ for (const key of Object.keys(obj)) {
198
+ if (!Object.prototype.hasOwnProperty.call(shape, key)) result[key] = coerceValue(obj[key], catchall);
199
+ }
200
+ }
188
201
  return result;
189
202
  }
203
+ case "intersection": {
204
+ if (accepts(schema, value)) return value;
205
+ const def = getDef(schema);
206
+ const forLeft = coerceValue(value, def.left);
207
+ if (accepts(schema, forLeft)) return forLeft;
208
+ const forRight = coerceValue(value, def.right);
209
+ if (accepts(schema, forRight)) return forRight;
210
+ return coerceValue(forLeft, def.right);
211
+ }
190
212
  case "array": {
191
213
  if (!Array.isArray(value)) return value;
192
214
  const elementSchema = getArrayElement(schema);
@@ -195,7 +217,7 @@ function coerceValue(value, schema) {
195
217
  }
196
218
  case "record": {
197
219
  if (typeof value !== "object" || Array.isArray(value)) return value;
198
- const valueSchema = _optionalChain([getDef, 'call', _19 => _19(schema), 'optionalAccess', _20 => _20.valueType]);
220
+ const valueSchema = _optionalChain([getDef, 'call', _23 => _23(schema), 'optionalAccess', _24 => _24.valueType]);
199
221
  if (!valueSchema) return value;
200
222
  const result = {};
201
223
  for (const [key, item] of Object.entries(value)) result[key] = coerceValue(item, valueSchema);
@@ -204,8 +226,8 @@ function coerceValue(value, schema) {
204
226
  case "tuple": {
205
227
  if (!Array.isArray(value)) return value;
206
228
  const def = getDef(schema);
207
- const items = _nullishCoalesce(_optionalChain([def, 'optionalAccess', _21 => _21.items]), () => ( []));
208
- const rest = _optionalChain([def, 'optionalAccess', _22 => _22.rest]);
229
+ const items = _nullishCoalesce(_optionalChain([def, 'optionalAccess', _25 => _25.items]), () => ( []));
230
+ const rest = _optionalChain([def, 'optionalAccess', _26 => _26.rest]);
209
231
  return value.map((item, i) => {
210
232
  const itemSchema = i < items.length ? items[i] : rest;
211
233
  return itemSchema ? coerceValue(item, itemSchema) : item;
@@ -214,11 +236,11 @@ function coerceValue(value, schema) {
214
236
  case "union":
215
237
  return coerceUnion(value, schema);
216
238
  case "pipe": {
217
- const input = _optionalChain([getDef, 'call', _23 => _23(schema), 'optionalAccess', _24 => _24.in]);
239
+ const input = _optionalChain([getDef, 'call', _27 => _27(schema), 'optionalAccess', _28 => _28.in]);
218
240
  return input ? coerceValue(value, input) : value;
219
241
  }
220
242
  case "lazy": {
221
- const getter = _optionalChain([getDef, 'call', _25 => _25(schema), 'optionalAccess', _26 => _26.getter]);
243
+ const getter = _optionalChain([getDef, 'call', _29 => _29(schema), 'optionalAccess', _30 => _30.getter]);
222
244
  return getter ? coerceValue(value, getter()) : value;
223
245
  }
224
246
  case "optional":
@@ -226,6 +248,7 @@ function coerceValue(value, schema) {
226
248
  case "default":
227
249
  case "prefault":
228
250
  case "nonoptional":
251
+ case "success":
229
252
  case "catch":
230
253
  case "readonly": {
231
254
  const inner = getInnerSchema(schema);
@@ -237,13 +260,13 @@ function coerceValue(value, schema) {
237
260
  }
238
261
  function coerceUnion(value, schema) {
239
262
  const def = getDef(schema);
240
- const options = _nullishCoalesce(_optionalChain([def, 'optionalAccess', _27 => _27.options]), () => ( []));
241
- const discriminator = _optionalChain([def, 'optionalAccess', _28 => _28.discriminator]);
263
+ const options = _nullishCoalesce(_optionalChain([def, 'optionalAccess', _31 => _31.options]), () => ( []));
264
+ const discriminator = _optionalChain([def, 'optionalAccess', _32 => _32.discriminator]);
242
265
  if (discriminator !== void 0) {
243
266
  if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
244
267
  const tag = Object.prototype.hasOwnProperty.call(value, discriminator) ? value[discriminator] : void 0;
245
- const tagsOf = (o) => _optionalChain([getPropValues, 'call', _29 => _29(o), 'optionalAccess', _30 => _30[discriminator]]);
246
- const option = _nullishCoalesce(options.find((o) => _optionalChain([tagsOf, 'call', _31 => _31(o), 'optionalAccess', _32 => _32.has, 'call', _33 => _33(tag)])), () => ( options.find((o) => {
268
+ const tagsOf = (o) => _optionalChain([getPropValues, 'call', _33 => _33(o), 'optionalAccess', _34 => _34[discriminator]]);
269
+ const option = _nullishCoalesce(options.find((o) => _optionalChain([tagsOf, 'call', _35 => _35(o), 'optionalAccess', _36 => _36.has, 'call', _37 => _37(tag)])), () => ( options.find((o) => {
247
270
  const tags = tagsOf(o);
248
271
  return tags !== void 0 && tags.has(coerceToLiteral(tag, tags));
249
272
  })));
@@ -267,7 +290,7 @@ function coerceToLiteral(value, literals) {
267
290
  function accepts(schema, value) {
268
291
  try {
269
292
  return schema.safeParse(value).success;
270
- } catch (e2) {
293
+ } catch (e) {
271
294
  return false;
272
295
  }
273
296
  }
package/dist/zod.d.cts CHANGED
@@ -4,10 +4,12 @@ import { C as Config, D as DurationUnit, B as ByteUnit, b as Period, a as ParseO
4
4
  /**
5
5
  * The whole config, validated against `schema`. HOCON strings are coerced
6
6
  * where the schema expects a number or a boolean (`"8080"` → 8080), through
7
- * objects, arrays, records, tuples, unions, pipes (by their input schema), lazy
8
- * schemas and optional / nullable / default / prefault / nonoptional / catch /
9
- * readonly wrappers; a union coerces by the option that takes the value (see
10
- * the README). Unit values go through the {@link hocon} markers.
7
+ * objects (and their catchall), arrays, records, tuples, unions,
8
+ * intersections, pipes (by their input schema), lazy schemas, numeric literals
9
+ * and enums, and optional / nullable / default / prefault / nonoptional /
10
+ * success / catch / readonly wrappers; a union coerces by the option that
11
+ * takes the value (see the README). Unit values go through the {@link hocon}
12
+ * markers.
11
13
  *
12
14
  * An object key named `__proto__`, `constructor` or `prototype` anywhere in
13
15
  * the value is refused with a `ZodError` issue at the object that holds it
package/dist/zod.d.ts CHANGED
@@ -4,10 +4,12 @@ import { C as Config, D as DurationUnit, B as ByteUnit, b as Period, a as ParseO
4
4
  /**
5
5
  * The whole config, validated against `schema`. HOCON strings are coerced
6
6
  * where the schema expects a number or a boolean (`"8080"` → 8080), through
7
- * objects, arrays, records, tuples, unions, pipes (by their input schema), lazy
8
- * schemas and optional / nullable / default / prefault / nonoptional / catch /
9
- * readonly wrappers; a union coerces by the option that takes the value (see
10
- * the README). Unit values go through the {@link hocon} markers.
7
+ * objects (and their catchall), arrays, records, tuples, unions,
8
+ * intersections, pipes (by their input schema), lazy schemas, numeric literals
9
+ * and enums, and optional / nullable / default / prefault / nonoptional /
10
+ * success / catch / readonly wrappers; a union coerces by the option that
11
+ * takes the value (see the README). Unit values go through the {@link hocon}
12
+ * markers.
11
13
  *
12
14
  * An object key named `__proto__`, `constructor` or `prototype` anywhere in
13
15
  * the value is refused with a `ZodError` issue at the object that holds it
package/dist/zod.js CHANGED
@@ -27,8 +27,11 @@ function parseValue(value, schema) {
27
27
  let result;
28
28
  try {
29
29
  result = schema.safeParse(coerced);
30
- } catch {
31
- throw new z.ZodError(refused);
30
+ } catch (err) {
31
+ if (err instanceof z.core.$ZodAsyncError || err?.constructor?.name === "$ZodAsyncError") {
32
+ throw new z.ZodError(refused);
33
+ }
34
+ throw err;
32
35
  }
33
36
  if (result.success) throw new z.ZodError(refused);
34
37
  throw new z.ZodError([...refused, ...withoutPrototypeKeyIssues(result.error.issues)]);
@@ -170,6 +173,10 @@ function coerceValue(value, schema) {
170
173
  return coerced !== void 0 ? coerced : value;
171
174
  }
172
175
  return value;
176
+ case "enum": {
177
+ const values = schema._zod.values;
178
+ return coerceToLiteral(value, values);
179
+ }
173
180
  case "literal": {
174
181
  const values = getDef(schema)?.values;
175
182
  return values ? coerceToLiteral(value, new Set(values)) : value;
@@ -185,8 +192,23 @@ function coerceValue(value, schema) {
185
192
  result[key] = coerceValue(obj[key], shape[key]);
186
193
  }
187
194
  }
195
+ const catchall = getDef(schema)?.catchall;
196
+ if (catchall) {
197
+ for (const key of Object.keys(obj)) {
198
+ if (!Object.prototype.hasOwnProperty.call(shape, key)) result[key] = coerceValue(obj[key], catchall);
199
+ }
200
+ }
188
201
  return result;
189
202
  }
203
+ case "intersection": {
204
+ if (accepts(schema, value)) return value;
205
+ const def = getDef(schema);
206
+ const forLeft = coerceValue(value, def.left);
207
+ if (accepts(schema, forLeft)) return forLeft;
208
+ const forRight = coerceValue(value, def.right);
209
+ if (accepts(schema, forRight)) return forRight;
210
+ return coerceValue(forLeft, def.right);
211
+ }
190
212
  case "array": {
191
213
  if (!Array.isArray(value)) return value;
192
214
  const elementSchema = getArrayElement(schema);
@@ -226,6 +248,7 @@ function coerceValue(value, schema) {
226
248
  case "default":
227
249
  case "prefault":
228
250
  case "nonoptional":
251
+ case "success":
229
252
  case "catch":
230
253
  case "readonly": {
231
254
  const inner = getInnerSchema(schema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o3co/ts.hocon",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "description": "Full Lightbend HOCON spec-compliant parser and config library for TypeScript",
5
5
  "keywords": [
6
6
  "hocon",