@maroonedog/luq 2.1.0 → 2.3.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.
Files changed (161) hide show
  1. package/README.md +92 -430
  2. package/dist/builder/builder-surface.types.d.ts +1 -0
  3. package/dist/builder/compile-declarations.d.ts +7 -1
  4. package/dist/builder/compile-declarations.js +18 -8
  5. package/dist/builder/compile-declarations.mjs +18 -8
  6. package/dist/builder/create-builder.js +8 -0
  7. package/dist/builder/create-builder.mjs +8 -0
  8. package/dist/builder/create-field-builder.js +13 -1
  9. package/dist/builder/create-field-builder.mjs +13 -1
  10. package/dist/builder/declared-calls-store.d.ts +9 -0
  11. package/dist/builder/declared-calls-store.js +19 -0
  12. package/dist/builder/declared-calls-store.mjs +15 -0
  13. package/dist/builder/field-builder.types.d.ts +13 -0
  14. package/dist/builder/field-declared-calls.types.d.ts +6 -0
  15. package/dist/builder/field-declared-calls.types.js +2 -0
  16. package/dist/builder/field-declared-calls.types.mjs +1 -0
  17. package/dist/builder/field-entry.types.d.ts +9 -3
  18. package/dist/builder/field-options.types.d.ts +26 -0
  19. package/dist/chain/bundle-paths.types.d.ts +23 -0
  20. package/dist/chain/bundle-paths.types.js +2 -0
  21. package/dist/chain/bundle-paths.types.mjs +1 -0
  22. package/dist/chain/chain-method.types.d.ts +8 -3
  23. package/dist/chain/chain-node-store.d.ts +5 -0
  24. package/dist/chain/chain-node-store.js +15 -0
  25. package/dist/chain/chain-node-store.mjs +11 -0
  26. package/dist/chain/collect-field-rules.d.ts +13 -2
  27. package/dist/chain/collect-field-rules.js +10 -3
  28. package/dist/chain/collect-field-rules.mjs +10 -3
  29. package/dist/chain/create-chain-node.js +19 -9
  30. package/dist/chain/create-chain-node.mjs +19 -9
  31. package/dist/chain/declaration-recorder.port.d.ts +31 -0
  32. package/dist/chain/declaration-recorder.port.js +17 -0
  33. package/dist/chain/declaration-recorder.port.mjs +13 -0
  34. package/dist/chain/declared-call.types.d.ts +15 -0
  35. package/dist/chain/declared-call.types.js +2 -0
  36. package/dist/chain/declared-call.types.mjs +1 -0
  37. package/dist/chain/index.d.ts +3 -1
  38. package/dist/chain/resolve-args.types.d.ts +4 -2
  39. package/dist/compile/compile-array-node.d.ts +0 -7
  40. package/dist/compile/compile-array-node.js +5 -0
  41. package/dist/compile/compile-array-node.mjs +5 -0
  42. package/dist/compile/compile-field.d.ts +1 -0
  43. package/dist/compile/compile-field.js +13 -2
  44. package/dist/compile/compile-field.mjs +13 -2
  45. package/dist/compile/compile-schema.js +4 -0
  46. package/dist/compile/compile-schema.mjs +4 -0
  47. package/dist/compile/group-array-fields.d.ts +1 -0
  48. package/dist/compile/split-rules-by-kind.js +27 -7
  49. package/dist/compile/split-rules-by-kind.mjs +27 -7
  50. package/dist/compile/validation-plan.types.d.ts +36 -0
  51. package/dist/core/type-erasure.d.ts +36 -30
  52. package/dist/core/type-erasure.js +36 -30
  53. package/dist/core/type-erasure.mjs +36 -30
  54. package/dist/json-schema/build-from-schema.js +8 -1
  55. package/dist/json-schema/build-from-schema.mjs +8 -1
  56. package/dist/json-schema/declare-additional-properties.d.ts +7 -7
  57. package/dist/json-schema/declare-additional-properties.js +7 -7
  58. package/dist/json-schema/declare-additional-properties.mjs +7 -7
  59. package/dist/json-schema/declare-object-keywords.js +4 -4
  60. package/dist/json-schema/declare-object-keywords.mjs +4 -4
  61. package/dist/json-schema/flatten-schema.js +1 -1
  62. package/dist/json-schema/flatten-schema.mjs +1 -1
  63. package/dist/json-schema/follow-json-pointer.d.ts +7 -6
  64. package/dist/json-schema/follow-json-pointer.js +24 -24
  65. package/dist/json-schema/follow-json-pointer.mjs +24 -24
  66. package/dist/json-schema/ref-resolution-error.js +3 -3
  67. package/dist/json-schema/ref-resolution-error.mjs +3 -3
  68. package/dist/json-schema/schema-registry.js +12 -11
  69. package/dist/json-schema/schema-registry.mjs +12 -11
  70. package/dist/json-schema/uri-reference.js +12 -12
  71. package/dist/json-schema/uri-reference.mjs +12 -12
  72. package/dist/path/create-value-writer.js +12 -12
  73. package/dist/path/create-value-writer.mjs +12 -12
  74. package/dist/path/reserved-segment.d.ts +16 -16
  75. package/dist/path/reserved-segment.js +17 -21
  76. package/dist/path/reserved-segment.mjs +17 -21
  77. package/dist/plugin-kit/marker.types.d.ts +18 -0
  78. package/dist/plugins/index.generated.d.ts +1 -0
  79. package/dist/plugins/index.generated.js +6 -4
  80. package/dist/plugins/index.generated.mjs +3 -2
  81. package/dist/plugins/manifest.generated.js +3 -2
  82. package/dist/plugins/manifest.generated.mjs +3 -2
  83. package/dist/plugins/object-additional-properties/select-additional-keys.d.ts +8 -8
  84. package/dist/plugins/object-additional-properties/select-additional-keys.js +16 -16
  85. package/dist/plugins/object-additional-properties/select-additional-keys.mjs +16 -16
  86. package/dist/plugins/stitch/stitch.d.ts +24 -8
  87. package/dist/plugins/stitch-with/index.d.ts +2 -0
  88. package/dist/plugins/stitch-with/index.js +5 -0
  89. package/dist/plugins/stitch-with/index.mjs +1 -0
  90. package/dist/plugins/stitch-with/stitch-with.d.ts +12 -0
  91. package/dist/plugins/stitch-with/stitch-with.js +92 -0
  92. package/dist/plugins/stitch-with/stitch-with.mjs +89 -0
  93. package/dist/plugins/stitchWith.d.ts +1 -0
  94. package/dist/plugins/stitchWith.js +2 -0
  95. package/dist/plugins/stitchWith.mjs +1 -0
  96. package/dist/plugins/string-min/string-min.js +19 -3
  97. package/dist/plugins/string-min/string-min.mjs +20 -4
  98. package/dist/presets/index.d.ts +1 -0
  99. package/dist/presets/index.js +9 -0
  100. package/dist/presets/index.mjs +1 -0
  101. package/dist/presets/presets.d.ts +164 -0
  102. package/dist/presets/presets.js +79 -0
  103. package/dist/presets/presets.mjs +76 -0
  104. package/dist/runtime/create-field-validator.js +22 -8
  105. package/dist/runtime/create-field-validator.mjs +22 -8
  106. package/dist/runtime/create-validator.js +38 -8
  107. package/dist/runtime/create-validator.mjs +38 -8
  108. package/dist/runtime/field-rule-context.d.ts +32 -0
  109. package/dist/runtime/field-rule-context.js +48 -0
  110. package/dist/runtime/field-rule-context.mjs +44 -0
  111. package/dist/runtime/index-stack.d.ts +29 -4
  112. package/dist/runtime/index-stack.js +76 -15
  113. package/dist/runtime/index-stack.mjs +76 -15
  114. package/dist/runtime/output-writer.js +5 -1
  115. package/dist/runtime/output-writer.mjs +5 -1
  116. package/dist/runtime/run-array-node.js +22 -10
  117. package/dist/runtime/run-array-node.mjs +22 -10
  118. package/dist/runtime/run-field.js +47 -18
  119. package/dist/runtime/run-field.mjs +47 -18
  120. package/dist/runtime/run-plan.js +5 -1
  121. package/dist/runtime/run-plan.mjs +5 -1
  122. package/dist/standard-schema/assemble-json-schema.d.ts +4 -0
  123. package/dist/standard-schema/assemble-json-schema.js +95 -0
  124. package/dist/standard-schema/assemble-json-schema.mjs +92 -0
  125. package/dist/standard-schema/declaration-recorder.d.ts +6 -0
  126. package/dist/standard-schema/declaration-recorder.js +30 -0
  127. package/dist/standard-schema/declaration-recorder.mjs +27 -0
  128. package/dist/standard-schema/declarations-unavailable-error.d.ts +4 -0
  129. package/dist/standard-schema/declarations-unavailable-error.js +32 -0
  130. package/dist/standard-schema/declarations-unavailable-error.mjs +28 -0
  131. package/dist/standard-schema/emit-field-schema.d.ts +9 -0
  132. package/dist/standard-schema/emit-field-schema.js +68 -0
  133. package/dist/standard-schema/emit-field-schema.mjs +65 -0
  134. package/dist/standard-schema/index.d.ts +5 -0
  135. package/dist/standard-schema/index.js +9 -1
  136. package/dist/standard-schema/index.mjs +4 -0
  137. package/dist/standard-schema/json-schema-target.d.ts +6 -0
  138. package/dist/standard-schema/json-schema-target.js +44 -0
  139. package/dist/standard-schema/json-schema-target.mjs +39 -0
  140. package/dist/standard-schema/plugin-keyword-map.d.ts +3 -0
  141. package/dist/standard-schema/plugin-keyword-map.js +93 -0
  142. package/dist/standard-schema/plugin-keyword-map.mjs +90 -0
  143. package/dist/standard-schema/split-issue-path.d.ts +6 -4
  144. package/dist/standard-schema/split-issue-path.js +15 -13
  145. package/dist/standard-schema/split-issue-path.mjs +15 -13
  146. package/dist/standard-schema/standard-schema.types.d.ts +8 -7
  147. package/dist/standard-schema/standard-schema.types.js +6 -6
  148. package/dist/standard-schema/standard-schema.types.mjs +6 -6
  149. package/dist/standard-schema/to-standard-json-schema.d.ts +19 -0
  150. package/dist/standard-schema/to-standard-json-schema.js +36 -0
  151. package/dist/standard-schema/to-standard-json-schema.mjs +33 -0
  152. package/dist/standard-schema/to-standard-schema.d.ts +16 -15
  153. package/dist/standard-schema/to-standard-schema.js +15 -22
  154. package/dist/standard-schema/to-standard-schema.mjs +15 -22
  155. package/dist/standard-schema/unrepresentable-rule-error.d.ts +15 -0
  156. package/dist/standard-schema/unrepresentable-rule-error.js +43 -0
  157. package/dist/standard-schema/unrepresentable-rule-error.mjs +38 -0
  158. package/dist/types/index.d.ts +19 -7
  159. package/dist/types/index.js +7 -7
  160. package/dist/types/index.mjs +7 -7
  161. package/package.json +35 -19
@@ -1,4 +1,4 @@
1
- /** 仕様の StandardSchemaV1Input Output を型として運ぶ。 */
1
+ /** The spec's StandardSchemaV1, carrying Input and Output as types. */
2
2
  export interface StandardSchemaV1<Input = unknown, Output = Input> {
3
3
  readonly "~standard": StandardSchemaProps<Input, Output>;
4
4
  }
@@ -7,8 +7,8 @@ export interface StandardSchemaProps<Input = unknown, Output = Input> {
7
7
  readonly vendor: string;
8
8
  readonly validate: (value: unknown, options?: StandardSchemaOptions | undefined) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;
9
9
  /**
10
- * 実行時には存在しない。型を運ぶためだけのメンバーで、仕様がそう定めている。
11
- * InferInput / InferOutput はここから読む。
10
+ * Absent at run time. The spec defines it as a type-only member, and it is
11
+ * what InferInput / InferOutput read.
12
12
  */
13
13
  readonly types?: StandardSchemaTypes<Input, Output> | undefined;
14
14
  }
@@ -25,8 +25,9 @@ export interface StandardSchemaFailure {
25
25
  readonly issues: readonly StandardSchemaIssue[];
26
26
  }
27
27
  /**
28
- * path は仕様上 optional。Luq は必ず入れる (root への issue は空配列)。
29
- * 省略と「ルートを指す」を呼び出し側が区別できるようにするため。
28
+ * The spec makes path optional; it is always present here, with an issue on
29
+ * the root carrying the empty list. That keeps "omitted" distinguishable from
30
+ * "points at the root" on the consuming side.
30
31
  */
31
32
  export interface StandardSchemaIssue {
32
33
  readonly message: string;
@@ -38,8 +39,8 @@ export interface StandardSchemaPathSegment {
38
39
  export type InferStandardInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
39
40
  export type InferStandardOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
40
41
  /**
41
- * validate の第2引数。仕様が定めているので受ける。
42
- * libraryOptions はベンダーごとの追加パラメータで、Luq はまだ何も定義していない。
42
+ * validate's second parameter, declared because the spec defines it.
43
+ * libraryOptions is the per-vendor extension point, and none is defined yet.
43
44
  */
44
45
  export interface StandardSchemaOptions {
45
46
  readonly libraryOptions?: Record<string, unknown> | undefined;
@@ -2,12 +2,12 @@
2
2
  // ===========================================================================
3
3
  // L10 src/standard-schema/standard-schema.types.ts
4
4
  //
5
- // Standard Schema v1 の型を自前で宣言する。@standard-schema/spec に依存しない。
6
- // 仕様が「型だけのパッケージなので inline してよい」と明示しており、依存を
7
- // 足せば利用者の node_modules に1つ増える一方で、得るものは何も無いため。
8
- // 形が仕様からずれていないことは test/type/standard-schema/ が固定する。
5
+ // Declares the Standard Schema v1 types here rather than depending on the
6
+ // spec package. The spec explicitly permits inlining, being types only, and a
7
+ // dependency would add an entry to every user's node_modules for nothing.
8
+ // Type tests pin the shape against the spec so it cannot drift.
9
9
  //
10
- // この層が L10 なのは、Validator (L6) の上に載る変換であり、コアの誰も
11
- // これを import しないから。import の向きは L6 -> L10 ではなく L10 -> L6。
10
+ // This is the outermost layer because it is a view laid over the validator and
11
+ // nothing in the core imports it. The import direction runs inwards only.
12
12
  // ===========================================================================
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,12 +1,12 @@
1
1
  // ===========================================================================
2
2
  // L10 src/standard-schema/standard-schema.types.ts
3
3
  //
4
- // Standard Schema v1 の型を自前で宣言する。@standard-schema/spec に依存しない。
5
- // 仕様が「型だけのパッケージなので inline してよい」と明示しており、依存を
6
- // 足せば利用者の node_modules に1つ増える一方で、得るものは何も無いため。
7
- // 形が仕様からずれていないことは test/type/standard-schema/ が固定する。
4
+ // Declares the Standard Schema v1 types here rather than depending on the
5
+ // spec package. The spec explicitly permits inlining, being types only, and a
6
+ // dependency would add an entry to every user's node_modules for nothing.
7
+ // Type tests pin the shape against the spec so it cannot drift.
8
8
  //
9
- // この層が L10 なのは、Validator (L6) の上に載る変換であり、コアの誰も
10
- // これを import しないから。import の向きは L6 -> L10 ではなく L10 -> L6。
9
+ // This is the outermost layer because it is a view laid over the validator and
10
+ // nothing in the core imports it. The import direction runs inwards only.
11
11
  // ===========================================================================
12
12
  export {};
@@ -0,0 +1,19 @@
1
+ import type { Validator } from "../builder/validator.types";
2
+ import { type StandardLuqSchema } from "./to-standard-schema";
3
+ /** The spec's Options: target is required, libraryOptions is vendor-defined. */
4
+ export interface JsonSchemaOptions {
5
+ readonly target: string;
6
+ readonly libraryOptions?: Record<string, unknown> | undefined;
7
+ }
8
+ interface JsonSchemaConverter {
9
+ readonly input: (options: JsonSchemaOptions) => Record<string, unknown>;
10
+ readonly output: (options: JsonSchemaOptions) => Record<string, unknown>;
11
+ }
12
+ /** A `~standard` carrying both validate and jsonSchema. */
13
+ export type StandardJsonSchemaLuqSchema<T extends object, TParsed = T> = StandardLuqSchema<T, TParsed> & {
14
+ readonly "~standard": StandardLuqSchema<T, TParsed>["~standard"] & {
15
+ readonly jsonSchema: JsonSchemaConverter;
16
+ };
17
+ };
18
+ export declare function toStandardJsonSchema<T extends object, TParsed = T>(validator: Validator<T, TParsed>): StandardJsonSchemaLuqSchema<T, TParsed>;
19
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toStandardJsonSchema = toStandardJsonSchema;
4
+ const declared_calls_store_1 = require("../builder/declared-calls-store");
5
+ const assemble_json_schema_1 = require("./assemble-json-schema");
6
+ const json_schema_target_1 = require("./json-schema-target");
7
+ const declarations_unavailable_error_1 = require("./declarations-unavailable-error");
8
+ const unrepresentable_rule_error_1 = require("./unrepresentable-rule-error");
9
+ const to_standard_schema_1 = require("./to-standard-schema");
10
+ const declaration_recorder_1 = require("./declaration-recorder");
11
+ // At module scope, not inside the export: this has to be in place before any
12
+ // build() runs, and a chain that already ran cannot be asked again.
13
+ (0, declaration_recorder_1.installJsonSchemaDeclarationRecorder)();
14
+ function toStandardJsonSchema(validator) {
15
+ const declared = (0, declared_calls_store_1.readDeclaredCalls)(validator);
16
+ const emit = (options) => {
17
+ // Refuse an unsupported target before writing anything. Same order even
18
+ // when there is nothing to write, or a wrong target passes as an empty
19
+ // schema instead of an error.
20
+ const schemaUri = (0, json_schema_target_1.resolveJsonSchemaTarget)(options.target);
21
+ if (declared === undefined)
22
+ throw new declarations_unavailable_error_1.DeclarationsUnavailableError();
23
+ return {
24
+ $schema: schemaUri,
25
+ ...(0, assemble_json_schema_1.assembleJsonSchema)(declared, (0, unrepresentable_rule_error_1.readUnrepresentablePolicy)(options.libraryOptions)),
26
+ };
27
+ };
28
+ const standard = (0, to_standard_schema_1.toStandardSchema)(validator);
29
+ return {
30
+ ...standard,
31
+ "~standard": {
32
+ ...standard["~standard"],
33
+ jsonSchema: { input: emit, output: emit },
34
+ },
35
+ };
36
+ }
@@ -0,0 +1,33 @@
1
+ import { readDeclaredCalls } from "../builder/declared-calls-store.mjs";
2
+ import { assembleJsonSchema } from "./assemble-json-schema.mjs";
3
+ import { resolveJsonSchemaTarget } from "./json-schema-target.mjs";
4
+ import { DeclarationsUnavailableError } from "./declarations-unavailable-error.mjs";
5
+ import { readUnrepresentablePolicy } from "./unrepresentable-rule-error.mjs";
6
+ import { toStandardSchema } from "./to-standard-schema.mjs";
7
+ import { installJsonSchemaDeclarationRecorder } from "./declaration-recorder.mjs";
8
+ // At module scope, not inside the export: this has to be in place before any
9
+ // build() runs, and a chain that already ran cannot be asked again.
10
+ installJsonSchemaDeclarationRecorder();
11
+ export function toStandardJsonSchema(validator) {
12
+ const declared = readDeclaredCalls(validator);
13
+ const emit = (options) => {
14
+ // Refuse an unsupported target before writing anything. Same order even
15
+ // when there is nothing to write, or a wrong target passes as an empty
16
+ // schema instead of an error.
17
+ const schemaUri = resolveJsonSchemaTarget(options.target);
18
+ if (declared === undefined)
19
+ throw new DeclarationsUnavailableError();
20
+ return {
21
+ $schema: schemaUri,
22
+ ...assembleJsonSchema(declared, readUnrepresentablePolicy(options.libraryOptions)),
23
+ };
24
+ };
25
+ const standard = toStandardSchema(validator);
26
+ return {
27
+ ...standard,
28
+ "~standard": {
29
+ ...standard["~standard"],
30
+ jsonSchema: { input: emit, output: emit },
31
+ },
32
+ };
33
+ }
@@ -1,22 +1,22 @@
1
1
  import type { Validator } from "../builder/validator.types";
2
2
  import type { StandardSchemaOptions, StandardSchemaResult } from "./standard-schema.types";
3
3
  /**
4
- * 仕様の Props validate Promise を返すことも許すが、Luq は必ず同期で返す。
5
- * ここで同期に絞っておくと、消費側が `await` も型の絞り込みも書かずに済む。
6
- * 狭めた型は広い型に代入できるので、StandardSchemaV1 としての互換は保たれる
7
- * (test/type/standard-schema/ AssignableToSpec がそれを固定している)。
4
+ * The spec allows validate to return a Promise; this one never does. Pinning
5
+ * it to synchronous here spares consumers both the `await` and the narrowing.
6
+ * A narrower type is still assignable to the wider one, so compatibility with
7
+ * StandardSchemaV1 holds — and a type test pins that.
8
8
  */
9
9
  interface SynchronousStandardProps<T extends object, TParsed> {
10
10
  readonly version: 1;
11
11
  readonly vendor: string;
12
12
  /**
13
- * 第2引数 options は仕様にある。Luq は今のところ読まないが、**受けること
14
- * 自体に意味がある**: 引数の少ない関数は多い方に代入できてしまうので、
15
- * 書かないと「仕様に合っている」と型が言うのに消費側の options が黙って
16
- * 捨てられる。受けた上で無視しているのだと分かる形にしてある。
13
+ * The second parameter is in the spec and is deliberately declared even
14
+ * though nothing reads it yet. **Declaring it is the point**: a function
15
+ * with fewer parameters is assignable to one with more, so leaving it out
16
+ * would let the type claim conformance while a consumer's options were
17
+ * silently discarded. Written this way, ignoring them is visible.
17
18
  *
18
- * libraryOptions に何を入れるかはベンダーごとの取り決めで、Luq はまだ
19
- * 何も定義していない。定義したらここで読む。
19
+ * What goes in libraryOptions is per-vendor, and none is defined yet.
20
20
  */
21
21
  readonly validate: (value: unknown, options?: StandardSchemaOptions | undefined) => StandardSchemaResult<TParsed>;
22
22
  readonly types?: {
@@ -25,17 +25,18 @@ interface SynchronousStandardProps<T extends object, TParsed> {
25
25
  } | undefined;
26
26
  }
27
27
  /**
28
- * Standard Schema としての Luq バリデータ。
28
+ * A Luq validator seen as a Standard Schema.
29
29
  *
30
- * Input `.for<T>()` に渡した型、Output transform 適用後の型。
31
- * 推論ではなく宣言から来るので、InferInput が利用者の書いた型そのものを指す。
30
+ * Input is the type given to `.for<T>()`; Output is that type after
31
+ * transforms. Both come from the declaration rather than from inference, so
32
+ * InferInput names the very type the caller wrote.
32
33
  */
33
34
  export type StandardLuqSchema<T extends object, TParsed = T> = Validator<T, TParsed> & {
34
35
  readonly "~standard": SynchronousStandardProps<T, TParsed>;
35
36
  };
36
37
  /**
37
- * 元の Validator のメンバー (validate / parse / pick / pickAll) はそのまま残る。
38
- * 返り値は Validator でもあるので、片方のためにもう片方を諦める必要は無い。
38
+ * The original validator's members stay. What comes back is still a
39
+ * Validator, so neither face has to be given up for the other.
39
40
  */
40
41
  export declare function toStandardSchema<T extends object, TParsed = T>(validator: Validator<T, TParsed>): StandardLuqSchema<T, TParsed>;
41
42
  export {};
@@ -2,21 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toStandardSchema = toStandardSchema;
4
4
  const split_issue_path_1 = require("./split-issue-path");
5
- /** package.json name と揃える。消費側がエラー表示に使う。 */
5
+ /** Matches the package name. Consumers show it in error output. */
6
6
  const VENDOR = "luq";
7
7
  const COLLECT_EVERY_ISSUE = {
8
8
  abortEarly: false,
9
9
  abortEarlyOnEachField: false,
10
10
  };
11
11
  /**
12
- * 元の Validator のメンバー (validate / parse / pick / pickAll) はそのまま残る。
13
- * 返り値は Validator でもあるので、片方のためにもう片方を諦める必要は無い。
12
+ * The original validator's members stay. What comes back is still a
13
+ * Validator, so neither face has to be given up for the other.
14
14
  */
15
15
  function toStandardSchema(validator) {
16
- // アサーションを書かずに組み立てる。src/core/type-erasure.ts
17
- // 「型を破ってよい唯一の場所」で、ここはその場所ではない。
18
- // 各メンバーを明示的に写すので、Validator に新しいメンバーが増えたときは
19
- // ここがコンパイルエラーになる — 黙って落ちるより良い。
16
+ // Assembled without a type assertion; this is not a file allowed to write
17
+ // one. Copying each member by name means a new member on Validator breaks
18
+ // the build here, which beats being dropped in silence.
20
19
  const props = {
21
20
  version: 1,
22
21
  vendor: VENDOR,
@@ -36,25 +35,19 @@ function toStandardSchema(validator) {
36
35
  };
37
36
  }
38
37
  /**
39
- * code severity は仕様に置き場所が無いので落ちる。message Luq
40
- * 組み立て済みのものをそのまま渡す。
38
+ * code and severity have nowhere to go in the spec, so they are dropped. The
39
+ * message is passed through as already composed.
41
40
  */
42
41
  function toStandardIssue(issue) {
43
42
  return { message: issue.message, path: (0, split_issue_path_1.splitIssuePath)(issue.path) };
44
43
  }
45
44
  // ---------------------------------------------------------------------------
46
- // なぜコアの build() ~standard を常に生やさないのか(実測に基づく判断)
45
+ // Why build() does not simply put ~standard on every validator.
47
46
  //
48
- // core-only gzip 7,420 B
49
- // core + standard-schema gzip 7,732 B (+312 B)
50
- // six-plugin gzip 8,373 B
51
- // six-plugin + standard-schema gzip 8,692 B (+319 B)
52
- //
53
- // コアに同梱すると、Standard Schema を使わない利用者も 312 B を払う。中核が
54
- // 7,420 B なので 4.2% にあたり、「使った分しか入らない」という約束と噛み合わない。
55
- // サブパスにしておけば import しない限り 0 B で、tRPC などに渡したい人だけが払う。
56
- //
57
- // 代償は、利用者が toStandardSchema() で1回包む必要があること。build() が
58
- // 直接 ~standard を持つほうが体験は良いが、その体験のために全員に課金する形に
59
- // なるので取らなかった。将来コアに入れるなら、この 312 B が判断材料になる。
47
+ // It would be the nicer experience — no wrapping call — but it bills everyone
48
+ // for it, including the majority who never hand a validator to a spec
49
+ // consumer. Measured against the core bundle the surcharge was a few percent,
50
+ // which does not fit "you only ship what you used". As a subpath it costs
51
+ // nothing until imported. Re-measure before revisiting the decision; the
52
+ // figures live with the size budget, not here.
60
53
  // ---------------------------------------------------------------------------
@@ -1,19 +1,18 @@
1
1
  import { splitIssuePath } from "./split-issue-path.mjs";
2
- /** package.json name と揃える。消費側がエラー表示に使う。 */
2
+ /** Matches the package name. Consumers show it in error output. */
3
3
  const VENDOR = "luq";
4
4
  const COLLECT_EVERY_ISSUE = {
5
5
  abortEarly: false,
6
6
  abortEarlyOnEachField: false,
7
7
  };
8
8
  /**
9
- * 元の Validator のメンバー (validate / parse / pick / pickAll) はそのまま残る。
10
- * 返り値は Validator でもあるので、片方のためにもう片方を諦める必要は無い。
9
+ * The original validator's members stay. What comes back is still a
10
+ * Validator, so neither face has to be given up for the other.
11
11
  */
12
12
  export function toStandardSchema(validator) {
13
- // アサーションを書かずに組み立てる。src/core/type-erasure.ts
14
- // 「型を破ってよい唯一の場所」で、ここはその場所ではない。
15
- // 各メンバーを明示的に写すので、Validator に新しいメンバーが増えたときは
16
- // ここがコンパイルエラーになる — 黙って落ちるより良い。
13
+ // Assembled without a type assertion; this is not a file allowed to write
14
+ // one. Copying each member by name means a new member on Validator breaks
15
+ // the build here, which beats being dropped in silence.
17
16
  const props = {
18
17
  version: 1,
19
18
  vendor: VENDOR,
@@ -33,25 +32,19 @@ export function toStandardSchema(validator) {
33
32
  };
34
33
  }
35
34
  /**
36
- * code severity は仕様に置き場所が無いので落ちる。message Luq
37
- * 組み立て済みのものをそのまま渡す。
35
+ * code and severity have nowhere to go in the spec, so they are dropped. The
36
+ * message is passed through as already composed.
38
37
  */
39
38
  function toStandardIssue(issue) {
40
39
  return { message: issue.message, path: splitIssuePath(issue.path) };
41
40
  }
42
41
  // ---------------------------------------------------------------------------
43
- // なぜコアの build() ~standard を常に生やさないのか(実測に基づく判断)
42
+ // Why build() does not simply put ~standard on every validator.
44
43
  //
45
- // core-only gzip 7,420 B
46
- // core + standard-schema gzip 7,732 B (+312 B)
47
- // six-plugin gzip 8,373 B
48
- // six-plugin + standard-schema gzip 8,692 B (+319 B)
49
- //
50
- // コアに同梱すると、Standard Schema を使わない利用者も 312 B を払う。中核が
51
- // 7,420 B なので 4.2% にあたり、「使った分しか入らない」という約束と噛み合わない。
52
- // サブパスにしておけば import しない限り 0 B で、tRPC などに渡したい人だけが払う。
53
- //
54
- // 代償は、利用者が toStandardSchema() で1回包む必要があること。build() が
55
- // 直接 ~standard を持つほうが体験は良いが、その体験のために全員に課金する形に
56
- // なるので取らなかった。将来コアに入れるなら、この 312 B が判断材料になる。
44
+ // It would be the nicer experience — no wrapping call — but it bills everyone
45
+ // for it, including the majority who never hand a validator to a spec
46
+ // consumer. Measured against the core bundle the surcharge was a few percent,
47
+ // which does not fit "you only ship what you used". As a subpath it costs
48
+ // nothing until imported. Re-measure before revisiting the decision; the
49
+ // figures live with the size budget, not here.
57
50
  // ---------------------------------------------------------------------------
@@ -0,0 +1,15 @@
1
+ export declare class UnrepresentableRuleError extends Error {
2
+ readonly fieldPath: string;
3
+ readonly pluginName: string;
4
+ readonly reason: string;
5
+ constructor(fieldPath: string, pluginName: string, reason: string);
6
+ }
7
+ /** What to do with an unwritable declaration. Defaults to "throw". */
8
+ export type UnrepresentablePolicy = "throw" | "omit";
9
+ /**
10
+ * Reads the policy out of `libraryOptions`.
11
+ *
12
+ * An unrecognised value falls to throw. A misspelled `omit` landing on the
13
+ * strict side is correct; landing on the lax side is an incident.
14
+ */
15
+ export declare function readUnrepresentablePolicy(libraryOptions: Record<string, unknown> | undefined): UnrepresentablePolicy;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ // ===========================================================================
3
+ // L10 src/standard-schema/unrepresentable-rule-error.ts
4
+ //
5
+ // Meeting a declaration that cannot be written as JSON Schema throws, by
6
+ // default.
7
+ //
8
+ // Dropping it silently is not on offer. What comes out of here gets USED FOR
9
+ // VALIDATION by whoever receives it, so dropping a `.custom()` produces a
10
+ // schema that admits values it must not — with no trace of the omission. The
11
+ // missing constraint is discovered by the incident it causes.
12
+ //
13
+ // Anyone for whom dropping is fine — emitting for documentation or for a form
14
+ // layout rather than for validation — can ask for it explicitly through
15
+ // libraryOptions, which the spec provides for exactly this kind of agreement.
16
+ // The point is that the lax choice is never the default, and that having made
17
+ // it stays visible in the caller's code.
18
+ // ===========================================================================
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.UnrepresentableRuleError = void 0;
21
+ exports.readUnrepresentablePolicy = readUnrepresentablePolicy;
22
+ class UnrepresentableRuleError extends Error {
23
+ constructor(fieldPath, pluginName, reason) {
24
+ super(`"${fieldPath}" declares ${pluginName}, which Luq cannot express in ` +
25
+ `JSON Schema: ${reason}. Pass ` +
26
+ `libraryOptions: { unrepresentable: "omit" } to drop it instead — ` +
27
+ `the emitted schema then accepts values this validator rejects.`);
28
+ this.fieldPath = fieldPath;
29
+ this.pluginName = pluginName;
30
+ this.reason = reason;
31
+ this.name = "UnrepresentableRuleError";
32
+ }
33
+ }
34
+ exports.UnrepresentableRuleError = UnrepresentableRuleError;
35
+ /**
36
+ * Reads the policy out of `libraryOptions`.
37
+ *
38
+ * An unrecognised value falls to throw. A misspelled `omit` landing on the
39
+ * strict side is correct; landing on the lax side is an incident.
40
+ */
41
+ function readUnrepresentablePolicy(libraryOptions) {
42
+ return libraryOptions?.["unrepresentable"] === "omit" ? "omit" : "throw";
43
+ }
@@ -0,0 +1,38 @@
1
+ // ===========================================================================
2
+ // L10 src/standard-schema/unrepresentable-rule-error.ts
3
+ //
4
+ // Meeting a declaration that cannot be written as JSON Schema throws, by
5
+ // default.
6
+ //
7
+ // Dropping it silently is not on offer. What comes out of here gets USED FOR
8
+ // VALIDATION by whoever receives it, so dropping a `.custom()` produces a
9
+ // schema that admits values it must not — with no trace of the omission. The
10
+ // missing constraint is discovered by the incident it causes.
11
+ //
12
+ // Anyone for whom dropping is fine — emitting for documentation or for a form
13
+ // layout rather than for validation — can ask for it explicitly through
14
+ // libraryOptions, which the spec provides for exactly this kind of agreement.
15
+ // The point is that the lax choice is never the default, and that having made
16
+ // it stays visible in the caller's code.
17
+ // ===========================================================================
18
+ export class UnrepresentableRuleError extends Error {
19
+ constructor(fieldPath, pluginName, reason) {
20
+ super(`"${fieldPath}" declares ${pluginName}, which Luq cannot express in ` +
21
+ `JSON Schema: ${reason}. Pass ` +
22
+ `libraryOptions: { unrepresentable: "omit" } to drop it instead — ` +
23
+ `the emitted schema then accepts values this validator rejects.`);
24
+ this.fieldPath = fieldPath;
25
+ this.pluginName = pluginName;
26
+ this.reason = reason;
27
+ this.name = "UnrepresentableRuleError";
28
+ }
29
+ }
30
+ /**
31
+ * Reads the policy out of `libraryOptions`.
32
+ *
33
+ * An unrecognised value falls to throw. A misspelled `omit` landing on the
34
+ * strict side is correct; landing on the lax side is an incident.
35
+ */
36
+ export function readUnrepresentablePolicy(libraryOptions) {
37
+ return libraryOptions?.["unrepresentable"] === "omit" ? "omit" : "throw";
38
+ }
@@ -43,6 +43,18 @@ export type CheckOutcome = {
43
43
  };
44
44
  export declare const PASS: CheckOutcome;
45
45
  export declare function fail(detail: IssueDetail): CheckOutcome;
46
+ /**
47
+ * What a cross-field check may answer: a boolean, or a boolean with a message.
48
+ *
49
+ * It lives at the bottom layer because the chain layer needs it to build the
50
+ * caller-facing type of `stitch`. Left in the plugin, that would be an import
51
+ * running outward from the chain, which no layer may do. The plugin's
52
+ * `StitchOutcome` is an alias of this one, so the public name is unchanged.
53
+ */
54
+ export interface CrossFieldOutcome {
55
+ readonly valid: boolean;
56
+ readonly message?: string;
57
+ }
46
58
  export interface ArrayItemContext {
47
59
  readonly index: number;
48
60
  readonly item: unknown;
@@ -67,14 +79,14 @@ export declare function isArray(value: unknown): value is readonly unknown[];
67
79
  export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
68
80
  export declare function isStringArray(value: unknown): value is readonly string[];
69
81
  /**
70
- * 文字列の長さをコードポイントで数える。
82
+ * Counts a string's length in code points.
71
83
  *
72
- * `.length` UTF-16 のコード単位を数えるので、絵文字や星域文字が 2 と数えられる。
73
- * JSON Schema §6.3.1 minLength / maxLength をコードポイントで数えると定めており、
74
- * 利用者が「3文字」と書くときに期待するのもコードポイントのほう。
84
+ * `.length` counts UTF-16 code units, so an emoji or any astral character
85
+ * counts as two. JSON Schema §6.3.1 defines minLength / maxLength in code
86
+ * points, and code points are also what someone writing "three characters"
87
+ * means.
75
88
  *
76
- * 1.x `.length` を使っていた (docs/legacy-spec/plugin-catalog-core.md
77
- * 「暗黙の挙動で、まわりに落ちるテストがある。明示的な決定にすべき」と記録している)。
78
- * ここでその決定をした。星域文字を含む文字列では 1.x と判定が変わる。
89
+ * This is a deliberate decision, not an inherited one: strings containing
90
+ * astral characters are judged differently than under the legacy `.length`.
79
91
  */
80
92
  export declare function countCodePoints(value: string): number;
@@ -28,15 +28,15 @@ function isStringArray(value) {
28
28
  return isArray(value) && value.every(isString);
29
29
  }
30
30
  /**
31
- * 文字列の長さをコードポイントで数える。
31
+ * Counts a string's length in code points.
32
32
  *
33
- * `.length` UTF-16 のコード単位を数えるので、絵文字や星域文字が 2 と数えられる。
34
- * JSON Schema §6.3.1 minLength / maxLength をコードポイントで数えると定めており、
35
- * 利用者が「3文字」と書くときに期待するのもコードポイントのほう。
33
+ * `.length` counts UTF-16 code units, so an emoji or any astral character
34
+ * counts as two. JSON Schema §6.3.1 defines minLength / maxLength in code
35
+ * points, and code points are also what someone writing "three characters"
36
+ * means.
36
37
  *
37
- * 1.x `.length` を使っていた (docs/legacy-spec/plugin-catalog-core.md
38
- * 「暗黙の挙動で、まわりに落ちるテストがある。明示的な決定にすべき」と記録している)。
39
- * ここでその決定をした。星域文字を含む文字列では 1.x と判定が変わる。
38
+ * This is a deliberate decision, not an inherited one: strings containing
39
+ * astral characters are judged differently than under the legacy `.length`.
40
40
  */
41
41
  function countCodePoints(value) {
42
42
  let count = 0;
@@ -18,15 +18,15 @@ export function isStringArray(value) {
18
18
  return isArray(value) && value.every(isString);
19
19
  }
20
20
  /**
21
- * 文字列の長さをコードポイントで数える。
21
+ * Counts a string's length in code points.
22
22
  *
23
- * `.length` UTF-16 のコード単位を数えるので、絵文字や星域文字が 2 と数えられる。
24
- * JSON Schema §6.3.1 minLength / maxLength をコードポイントで数えると定めており、
25
- * 利用者が「3文字」と書くときに期待するのもコードポイントのほう。
23
+ * `.length` counts UTF-16 code units, so an emoji or any astral character
24
+ * counts as two. JSON Schema §6.3.1 defines minLength / maxLength in code
25
+ * points, and code points are also what someone writing "three characters"
26
+ * means.
26
27
  *
27
- * 1.x `.length` を使っていた (docs/legacy-spec/plugin-catalog-core.md
28
- * 「暗黙の挙動で、まわりに落ちるテストがある。明示的な決定にすべき」と記録している)。
29
- * ここでその決定をした。星域文字を含む文字列では 1.x と判定が変わる。
28
+ * This is a deliberate decision, not an inherited one: strings containing
29
+ * astral characters are judged differently than under the legacy `.length`.
30
30
  */
31
31
  export function countCodePoints(value) {
32
32
  let count = 0;