@oh-my-pi/omptype 17.2.15 → 17.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [17.3.0] - 2026-08-13
6
+
7
+ ### Added
8
+
9
+ - Added `type.withJsonSchema(schema, json)` to wrap a validation-only schema, ensuring JSON Schema emission yields the provided `json` verbatim even when nested inside objects, arrays, or unions. Schemas with defaults or output-changing morphs are rejected to prevent transformed outputs from being discarded.
10
+
5
11
  ## [17.2.10] - 2026-08-06
6
12
 
7
13
  ### Changed
package/dist/js/type.js CHANGED
@@ -2852,6 +2852,38 @@ function naryStatics(resolve) {
2852
2852
  return makeType(parseDef(def), [], {});
2853
2853
  }
2854
2854
  type.raw = raw;
2855
+ /**
2856
+ * Return a validation-only schema that emits `json` verbatim — even when
2857
+ * embedded in an object, array, or union.
2858
+ *
2859
+ * A `.toJsonSchema()` method override cannot survive nesting: a parent schema
2860
+ * emits each child's IR directly and never calls the child's method, so the
2861
+ * override silently disappears from the wire schema. This stores the override
2862
+ * on the IR instead.
2863
+ *
2864
+ * # Errors
2865
+ *
2866
+ * Throws when `schema` has a default or output-changing morph/pipe. A refine
2867
+ * can preserve validation and the input value, but silently discarding a
2868
+ * transformed output would violate the returned {@link Type}.
2869
+ */
2870
+ function withJsonSchema(schema, json) {
2871
+ const internal = schema;
2872
+ if (internal.hasDefault || hasMorph(internal.ir) || internal[kSteps].some(step => step.kind === "pipe")) {
2873
+ throw new OmpTypeError("type.withJsonSchema cannot wrap schemas with defaults or output-changing morphs");
2874
+ }
2875
+ return makeType({
2876
+ k: "refine",
2877
+ base: { k: "unknown" },
2878
+ pred: value => {
2879
+ const result = schema(value);
2880
+ return result instanceof OmpErrors ? result : true;
2881
+ },
2882
+ expected: schema.expression,
2883
+ json: { ...json },
2884
+ }, [], {});
2885
+ }
2886
+ type.withJsonSchema = withJsonSchema;
2855
2887
  })(type || (type = {}));
2856
2888
  // Reserved words cannot be declared as namespace bindings, but ArkType exposes
2857
2889
  // them as runtime keyword properties.
@@ -496,6 +496,22 @@ export declare namespace type {
496
496
  export function generic(...parameters: readonly GenericParameterSpec[]): GenericBuilder;
497
497
  /** Untyped builder for runtime-assembled definitions. */
498
498
  export function raw(def: unknown): BaseType;
499
+ /**
500
+ * Return a validation-only schema that emits `json` verbatim — even when
501
+ * embedded in an object, array, or union.
502
+ *
503
+ * A `.toJsonSchema()` method override cannot survive nesting: a parent schema
504
+ * emits each child's IR directly and never calls the child's method, so the
505
+ * override silently disappears from the wire schema. This stores the override
506
+ * on the IR instead.
507
+ *
508
+ * # Errors
509
+ *
510
+ * Throws when `schema` has a default or output-changing morph/pipe. A refine
511
+ * can preserve validation and the input value, but silently discarding a
512
+ * transformed output would violate the returned {@link Type}.
513
+ */
514
+ export function withJsonSchema<t, i = t>(schema: Type<t, i>, json: Record<string, unknown>): Type<t, i>;
499
515
  export {};
500
516
  }
501
517
  export interface ScopeOptions {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/omptype",
4
- "version": "17.2.15",
4
+ "version": "17.3.0",
5
5
  "description": "ArkType-compatible runtime schema validation with lazy JIT compilation",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
package/src/type.ts CHANGED
@@ -3675,6 +3675,42 @@ export namespace type {
3675
3675
  export function raw(def: unknown): BaseType {
3676
3676
  return makeType(parseDef(def), [], {}) as unknown as BaseType;
3677
3677
  }
3678
+
3679
+ /**
3680
+ * Return a validation-only schema that emits `json` verbatim — even when
3681
+ * embedded in an object, array, or union.
3682
+ *
3683
+ * A `.toJsonSchema()` method override cannot survive nesting: a parent schema
3684
+ * emits each child's IR directly and never calls the child's method, so the
3685
+ * override silently disappears from the wire schema. This stores the override
3686
+ * on the IR instead.
3687
+ *
3688
+ * # Errors
3689
+ *
3690
+ * Throws when `schema` has a default or output-changing morph/pipe. A refine
3691
+ * can preserve validation and the input value, but silently discarding a
3692
+ * transformed output would violate the returned {@link Type}.
3693
+ */
3694
+ export function withJsonSchema<t, i = t>(schema: Type<t, i>, json: Record<string, unknown>): Type<t, i> {
3695
+ const internal = schema as unknown as InternalType;
3696
+ if (internal.hasDefault || hasMorph(internal.ir) || internal[kSteps].some(step => step.kind === "pipe")) {
3697
+ throw new OmpTypeError("type.withJsonSchema cannot wrap schemas with defaults or output-changing morphs");
3698
+ }
3699
+ return makeType<t, i>(
3700
+ {
3701
+ k: "refine",
3702
+ base: { k: "unknown" },
3703
+ pred: value => {
3704
+ const result = schema(value);
3705
+ return result instanceof OmpErrors ? result : true;
3706
+ },
3707
+ expected: schema.expression,
3708
+ json: { ...json },
3709
+ },
3710
+ [],
3711
+ {},
3712
+ );
3713
+ }
3678
3714
  }
3679
3715
 
3680
3716
  // Reserved words cannot be declared as namespace bindings, but ArkType exposes