prefix-safe-json 0.5.4 → 0.6.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.md +36 -10
- package/dist/guard/typed-ai-sdk.d.ts +43 -0
- package/dist/guard/typed-ai-sdk.d.ts.map +1 -0
- package/dist/guard/typed-ai-sdk.js +56 -0
- package/dist/guard/typed-ai-sdk.js.map +1 -0
- package/dist/standard-schema.d.ts +2 -0
- package/dist/standard-schema.d.ts.map +1 -1
- package/dist/standard-schema.js +1 -0
- package/dist/standard-schema.js.map +1 -1
- package/dist/validation/standard-schema-validator.d.ts +3 -2
- package/dist/validation/standard-schema-validator.d.ts.map +1 -1
- package/dist/validation/standard-schema-validator.js +41 -1
- package/dist/validation/standard-schema-validator.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,11 @@ pnpm add prefix-safe-json ai zod
|
|
|
18
18
|
# or: npm install prefix-safe-json ai zod
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
Try a runnable comparison first: [download the six-SDK trial ZIP](https://github.com/canblmz1/prefix-safe-json/releases/download/v0.5.4/prefix-safe-json-0.5.4-trials.zip),
|
|
22
|
+
extract it, then run `node scripts/try-npm-demo.mjs tanstack` with Node 22+.
|
|
23
|
+
It uses published packages, authored streams and harmless counters; no API key
|
|
24
|
+
or repository build is needed. [Choose another SDK](examples/README.md).
|
|
25
|
+
|
|
21
26
|
## Safe execution example
|
|
22
27
|
|
|
23
28
|
```javascript
|
|
@@ -30,7 +35,7 @@ import {
|
|
|
30
35
|
} from "prefix-safe-json";
|
|
31
36
|
import { fromStandardSchema } from "prefix-safe-json/standard-schema";
|
|
32
37
|
|
|
33
|
-
const writeFileSchema = z.object({ path: z.string(), content: z.string() });
|
|
38
|
+
const writeFileSchema = z.object({ path: z.string(), content: z.string() }).strict();
|
|
34
39
|
|
|
35
40
|
const tools = createAiSdkExecutionLock({
|
|
36
41
|
write_file: {
|
|
@@ -52,7 +57,8 @@ const { decisions, diagnostics } = guard.finish();
|
|
|
52
57
|
for (const decision of decisions) {
|
|
53
58
|
const authority = guard.takeDecision(decision.internalId);
|
|
54
59
|
if (authority) {
|
|
55
|
-
|
|
60
|
+
const input = writeFileSchema.parse(authority.value);
|
|
61
|
+
await writeFile(input.path, input.content);
|
|
56
62
|
} else {
|
|
57
63
|
console.warn(`skipped ${decision.name}: ${decision.action} (${decision.reason})`);
|
|
58
64
|
}
|
|
@@ -66,6 +72,16 @@ if (decisions.length === 0 && diagnostics.length > 0) {
|
|
|
66
72
|
|
|
67
73
|
Using `jsonSchema()` from `ai` instead of Zod? Give the guard the raw schema inside it: `schemas: { write_file: writeFileSchema.jsonSchema }`. The wrapper itself is refused at construction, because it would otherwise validate nothing.
|
|
68
74
|
|
|
75
|
+
## Typed inputs and a complete agent loop
|
|
76
|
+
|
|
77
|
+
Experimental `createTypedAiSdkExecutionGuard` in
|
|
78
|
+
`prefix-safe-json/standard-schema` requires **PSJ 0.6.0+**.
|
|
79
|
+
The [strict TypeScript agent-loop example](examples/typed-agent-loop/) checks
|
|
80
|
+
inferred raw inputs, matching result IDs and a final model answer, plus four
|
|
81
|
+
refusal/error scenarios. It runs against the actual tarball without an API
|
|
82
|
+
key. The caller owns dispatch and continuation. Schema transformations,
|
|
83
|
+
defaults and removed keys are refused; [validation details](docs/VALIDATION.md#typed-raw-input-guard).
|
|
84
|
+
|
|
69
85
|
## When this adds value
|
|
70
86
|
|
|
71
87
|
Use PSJ when your application owns tool dispatch and needs original-stream
|
|
@@ -93,10 +109,18 @@ checkout without model requests or tool dispatch.
|
|
|
93
109
|
## Run a standalone npm demo
|
|
94
110
|
|
|
95
111
|
To try it without cloning this repository, download the
|
|
96
|
-
[
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
[six-SDK trial ZIP](https://github.com/canblmz1/prefix-safe-json/releases/download/v0.5.4/prefix-safe-json-0.5.4-trials.zip)
|
|
113
|
+
and extract it. With Node 22+ and npm, run this from the extracted directory:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
node scripts/try-npm-demo.mjs tanstack
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Choose `ai-sdk`, `openai`, `anthropic`, `langchain`, `openrouter` or `tanstack`.
|
|
120
|
+
Every example installs published PSJ `0.5.4`; no API key or repository build
|
|
121
|
+
is needed. The ZIP contains example sources, the launcher and licenses;
|
|
122
|
+
dependencies are downloaded from npm. See the [trial index](examples/README.md)
|
|
123
|
+
for the SDK versions and checks. The earlier dated downloads remain unchanged.
|
|
100
124
|
|
|
101
125
|
With Node 22+ and npm, you can run the published-package demo from this checkout
|
|
102
126
|
without installing the repository's development dependencies:
|
|
@@ -118,7 +142,7 @@ npm ls prefix-safe-json ai zod
|
|
|
118
142
|
npm start
|
|
119
143
|
```
|
|
120
144
|
|
|
121
|
-
The current checkout pins `prefix-safe-json@0.5.
|
|
145
|
+
The current checkout pins `prefix-safe-json@0.5.4`, `ai@7.0.77`, and `zod@4.4.3`.
|
|
122
146
|
It needs no repository build, workspace aliases, or API key. It drives real
|
|
123
147
|
`streamText().fullStream` using the SDK's official `MockLanguageModelV4` and
|
|
124
148
|
imports the installed package's public entry point and `standard-schema`
|
|
@@ -175,9 +199,11 @@ call IDs, while invalid batches cause zero effects and no continuation request.
|
|
|
175
199
|
It uses authored SSE through the installed SDK; no live model call is made.
|
|
176
200
|
|
|
177
201
|
Using TanStack AI with OpenRouter? Run `node scripts/try-npm-demo.mjs tanstack`
|
|
178
|
-
for the [
|
|
179
|
-
|
|
180
|
-
|
|
202
|
+
for the [installed-package comparison](examples/tanstack-consumer/README.md).
|
|
203
|
+
It checks raw native finish reasons, usage trailers and paired results using
|
|
204
|
+
published PSJ `0.5.4`, harmless counters and authored SSE. The
|
|
205
|
+
[native-first standalone trial](https://gist.github.com/canblmz1/ba1e62d792da37d3f420c328f56d81be)
|
|
206
|
+
also offers a PSJ-free baseline and an optional comparison from npm or source.
|
|
181
207
|
|
|
182
208
|
## Why parse success is not enough
|
|
183
209
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ExecutionGuardOptions, AiSdkExecutionGuard } from "./types.js";
|
|
2
|
+
import type { ExecuteDecision } from "../gate/types.js";
|
|
3
|
+
import type { JsonValue } from "../types.js";
|
|
4
|
+
import { type StandardSchemaV1Like } from "../validation/standard-schema-validator.js";
|
|
5
|
+
/** @public (Experimental) Synchronous Standard Schema input registry. */
|
|
6
|
+
export type ToolInputSchemas = Record<string, StandardSchemaV1Like>;
|
|
7
|
+
type SchemaOutput<T> = T extends {
|
|
8
|
+
readonly "~standard": {
|
|
9
|
+
readonly types?: {
|
|
10
|
+
readonly output: infer Output;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
} ? Output : unknown;
|
|
14
|
+
/**
|
|
15
|
+
* @public (Experimental)
|
|
16
|
+
* A discriminated union of registered tool names and their validated raw
|
|
17
|
+
* inputs. Schema outputs that change the raw JSON value are refused at runtime.
|
|
18
|
+
*/
|
|
19
|
+
export type TypedExecuteDecision<TSchemas extends ToolInputSchemas> = {
|
|
20
|
+
[Name in keyof TSchemas & string]: Omit<ExecuteDecision, "name" | "value"> & {
|
|
21
|
+
readonly name: Name;
|
|
22
|
+
readonly value: SchemaOutput<TSchemas[Name]> & JsonValue;
|
|
23
|
+
};
|
|
24
|
+
}[keyof TSchemas & string];
|
|
25
|
+
/** @public (Experimental) Typed authority consumption; snapshots remain observations. */
|
|
26
|
+
export type TypedAiSdkExecutionGuard<TSchemas extends ToolInputSchemas> = Omit<AiSdkExecutionGuard, "takeDecision"> & {
|
|
27
|
+
takeDecision(internalId: string): TypedExecuteDecision<TSchemas> | undefined;
|
|
28
|
+
};
|
|
29
|
+
/** @public (Experimental) Only registered, unchanged schema inputs can execute. */
|
|
30
|
+
export interface TypedAiSdkExecutionGuardOptions<TSchemas extends ToolInputSchemas> extends Omit<ExecutionGuardOptions, "schemas" | "validators"> {
|
|
31
|
+
readonly inputSchemas: TSchemas;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @public (Experimental)
|
|
35
|
+
* Retains Standard Schema output types without substituting transformed
|
|
36
|
+
* values for raw arguments. Validation is synchronous and must preserve JSON
|
|
37
|
+
* structure (including keys); use strict or passthrough object schemas.
|
|
38
|
+
* Unknown tool names receive no authority. Existing untyped guard behavior
|
|
39
|
+
* and fromStandardSchema's validation-only semantics are unchanged.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createTypedAiSdkExecutionGuard<const TSchemas extends ToolInputSchemas>(options: TypedAiSdkExecutionGuardOptions<TSchemas>): TypedAiSdkExecutionGuard<TSchemas>;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=typed-ai-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-ai-sdk.d.ts","sourceRoot":"","sources":["../../src/guard/typed-ai-sdk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAiC,KAAK,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAEtH,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAEpE,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS;IAC/B,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CAC9E,GAAG,MAAM,GAAG,OAAO,CAAC;AAErB;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,CAAC,QAAQ,SAAS,gBAAgB,IAAI;KACnE,IAAI,IAAI,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;QAC3E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;QACpB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC;KAC1D;CACF,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC;AAE3B,yFAAyF;AACzF,MAAM,MAAM,wBAAwB,CAAC,QAAQ,SAAS,gBAAgB,IAAI,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,GAAG;IACpH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;CAC9E,CAAC;AAEF,mFAAmF;AACnF,MAAM,WAAW,+BAA+B,CAAC,QAAQ,SAAS,gBAAgB,CAChF,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,YAAY,CAAC;IAC7D,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EACpF,OAAO,EAAE,+BAA+B,CAAC,QAAQ,CAAC,GACjD,wBAAwB,CAAC,QAAQ,CAAC,CA6CpC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createAiSdkExecutionGuard } from "./ai-sdk.js";
|
|
2
|
+
import { createStandardSchemaValidator } from "../validation/standard-schema-validator.js";
|
|
3
|
+
/**
|
|
4
|
+
* @public (Experimental)
|
|
5
|
+
* Retains Standard Schema output types without substituting transformed
|
|
6
|
+
* values for raw arguments. Validation is synchronous and must preserve JSON
|
|
7
|
+
* structure (including keys); use strict or passthrough object schemas.
|
|
8
|
+
* Unknown tool names receive no authority. Existing untyped guard behavior
|
|
9
|
+
* and fromStandardSchema's validation-only semantics are unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export function createTypedAiSdkExecutionGuard(options) {
|
|
12
|
+
// Extra properties survive structural typing and object spreads. Never
|
|
13
|
+
// silently ignore a caller's additional validation policy at runtime.
|
|
14
|
+
if ("schemas" in options || "validators" in options) {
|
|
15
|
+
throw new Error("createTypedAiSdkExecutionGuard: use inputSchemas only; schemas and validators cannot be combined with the typed guard.");
|
|
16
|
+
}
|
|
17
|
+
// Snapshot the registry: later caller mutations cannot change which names
|
|
18
|
+
// are allowed without changing the validators already held by the gate.
|
|
19
|
+
const validators = Object.fromEntries(Object.entries(options.inputSchemas).map(([name, schema]) => [name, createStandardSchemaValidator(schema, true)]));
|
|
20
|
+
const names = new Set(Object.keys(validators));
|
|
21
|
+
const guard = createAiSdkExecutionGuard({
|
|
22
|
+
validators, limits: options.limits, parserOptions: options.parserOptions,
|
|
23
|
+
});
|
|
24
|
+
const registered = (decision) => decision.name !== undefined && names.has(decision.name);
|
|
25
|
+
const observe = (decision) => {
|
|
26
|
+
if (decision.action !== "execute" || registered(decision))
|
|
27
|
+
return decision;
|
|
28
|
+
const { value: _value, ...rest } = decision;
|
|
29
|
+
return { ...rest, action: "reject", executable: false, reason: "schema_invalid" };
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
push: part => guard.push(part),
|
|
33
|
+
snapshot: () => guard.snapshot().map(observe),
|
|
34
|
+
finish(meta) {
|
|
35
|
+
const final = guard.finish(meta);
|
|
36
|
+
const unknown = final.decisions.filter(d => !registered(d));
|
|
37
|
+
return {
|
|
38
|
+
decisions: final.decisions.map(observe),
|
|
39
|
+
diagnostics: [...final.diagnostics, ...unknown.map(d => ({
|
|
40
|
+
code: "E_UNREGISTERED_TOOL", severity: "error",
|
|
41
|
+
internalId: d.internalId,
|
|
42
|
+
message: "Typed guard has no input schema for this tool name.",
|
|
43
|
+
}))],
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
takeDecision(internalId) {
|
|
47
|
+
const decision = guard.takeDecision(internalId);
|
|
48
|
+
if (!decision || !registered(decision) || decision.evidence.schemaValid !== true)
|
|
49
|
+
return undefined;
|
|
50
|
+
// The registered validator checked the schema AND equality with raw
|
|
51
|
+
// input, and the underlying gate has consumed authority exactly once.
|
|
52
|
+
return decision;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=typed-ai-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-ai-sdk.js","sourceRoot":"","sources":["../../src/guard/typed-ai-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { fromStandardSchema } from "./validation/standard-schema-validator.js";
|
|
2
|
+
export { createTypedAiSdkExecutionGuard } from "./guard/typed-ai-sdk.js";
|
|
3
|
+
export type { ToolInputSchemas, TypedExecuteDecision, TypedAiSdkExecutionGuard, TypedAiSdkExecutionGuardOptions, } from "./guard/typed-ai-sdk.js";
|
|
2
4
|
//# sourceMappingURL=standard-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC"}
|
|
1
|
+
{"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,yBAAyB,CAAC"}
|
package/dist/standard-schema.js
CHANGED
|
@@ -8,4 +8,5 @@
|
|
|
8
8
|
// property the spec itself defines. See docs/VALIDATION.md.
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
10
|
export { fromStandardSchema } from "./validation/standard-schema-validator.js";
|
|
11
|
+
export { createTypedAiSdkExecutionGuard } from "./guard/typed-ai-sdk.js";
|
|
11
12
|
//# sourceMappingURL=standard-schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema.js","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,EAAE;AACF,mEAAmE;AACnE,4EAA4E;AAC5E,yEAAyE;AACzE,uEAAuE;AACvE,4DAA4D;AAC5D,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC"}
|
|
1
|
+
{"version":3,"file":"standard-schema.js","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,EAAE;AACF,mEAAmE;AACnE,4EAA4E;AAC5E,yEAAyE;AACzE,uEAAuE;AACvE,4DAA4D;AAC5D,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -6,7 +6,7 @@ import type { ToolInputValidator } from "./types.js";
|
|
|
6
6
|
* - just its documented shape, which Zod 4+, Valibot, ArkType, and others
|
|
7
7
|
* already implement without any package of ours needing to know that.
|
|
8
8
|
*/
|
|
9
|
-
interface StandardSchemaV1Like {
|
|
9
|
+
export interface StandardSchemaV1Like {
|
|
10
10
|
readonly "~standard": {
|
|
11
11
|
readonly version: 1;
|
|
12
12
|
readonly vendor: string;
|
|
@@ -37,5 +37,6 @@ interface StandardSchemaV1Like {
|
|
|
37
37
|
* `docs/VALIDATION.md#the-standard-schema-transformation-boundary`.
|
|
38
38
|
*/
|
|
39
39
|
export declare function fromStandardSchema(schema: StandardSchemaV1Like): ToolInputValidator;
|
|
40
|
-
|
|
40
|
+
/** @internal Typed guards additionally require an unchanged JSON output. */
|
|
41
|
+
export declare function createStandardSchemaValidator(schema: StandardSchemaV1Like, unchangedOutput?: boolean): ToolInputValidator;
|
|
41
42
|
//# sourceMappingURL=standard-schema-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema-validator.d.ts","sourceRoot":"","sources":["../../src/validation/standard-schema-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,YAAY,CAAC;AAE3E;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"standard-schema-validator.d.ts","sourceRoot":"","sources":["../../src/validation/standard-schema-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAwB,MAAM,YAAY,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;KAChD,CAAC;CACH;AA6FD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,kBAAkB,CAEnF;AAED,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,oBAAoB,EAAE,eAAe,UAAQ,GAAG,kBAAkB,CAuDvH"}
|
|
@@ -90,12 +90,22 @@ function assertStandardSchemaV1(schema) {
|
|
|
90
90
|
* `docs/VALIDATION.md#the-standard-schema-transformation-boundary`.
|
|
91
91
|
*/
|
|
92
92
|
export function fromStandardSchema(schema) {
|
|
93
|
+
return createStandardSchemaValidator(schema);
|
|
94
|
+
}
|
|
95
|
+
/** @internal Typed guards additionally require an unchanged JSON output. */
|
|
96
|
+
export function createStandardSchemaValidator(schema, unchangedOutput = false) {
|
|
93
97
|
assertStandardSchemaV1(schema);
|
|
94
98
|
const standard = schema["~standard"];
|
|
95
99
|
return {
|
|
96
100
|
validate(value) {
|
|
97
|
-
|
|
101
|
+
// A typed boundary validates a copy: defaults/coercions or a mutating
|
|
102
|
+
// validator must never alter the raw value against which we compare.
|
|
103
|
+
const candidate = unchangedOutput ? structuredClone(value) : value;
|
|
104
|
+
const result = standard.validate(candidate);
|
|
98
105
|
if (isThenable(result)) {
|
|
106
|
+
// Reject synchronously, but also observe an eventual async rejection
|
|
107
|
+
// so a misconfigured validator cannot cause an unhandled rejection.
|
|
108
|
+
void Promise.resolve(result).catch(() => undefined);
|
|
99
109
|
throw new Error("prefix-safe-json: fromStandardSchema() only supports synchronous Standard Schema validators. " +
|
|
100
110
|
"This schema's validate() returned a Promise - implement ToolInputValidator directly if you " +
|
|
101
111
|
"need async validation, and resolve it before the call reaches this coordinator.");
|
|
@@ -124,8 +134,38 @@ export function fromStandardSchema(schema) {
|
|
|
124
134
|
'"value" nor "issues" - not a valid Standard Schema SuccessResult or FailureResult. Received: ' +
|
|
125
135
|
describeForError(result));
|
|
126
136
|
}
|
|
137
|
+
if (unchangedOutput && !sameJsonValue(value, result.value)) {
|
|
138
|
+
return { valid: false, errors: ["Typed input validation must preserve the raw JSON value; transformations, defaults and removed keys are not accepted."] };
|
|
139
|
+
}
|
|
127
140
|
return { valid: true };
|
|
128
141
|
},
|
|
129
142
|
};
|
|
130
143
|
}
|
|
144
|
+
/** Compare JSON structure without depending on object property order. */
|
|
145
|
+
function sameJsonValue(raw, output) {
|
|
146
|
+
const pending = [[raw, output]];
|
|
147
|
+
while (pending.length > 0) {
|
|
148
|
+
const [left, right] = pending.pop();
|
|
149
|
+
if (Object.is(left, right))
|
|
150
|
+
continue;
|
|
151
|
+
if (!isRecord(left) || !isRecord(right))
|
|
152
|
+
return false;
|
|
153
|
+
if (Array.isArray(left) !== Array.isArray(right))
|
|
154
|
+
return false;
|
|
155
|
+
const prototype = Object.getPrototypeOf(right);
|
|
156
|
+
if (prototype !== null && prototype !== Object.prototype && prototype !== Array.prototype)
|
|
157
|
+
return false;
|
|
158
|
+
const keys = Object.keys(left);
|
|
159
|
+
if (keys.length !== Object.keys(right).length)
|
|
160
|
+
return false;
|
|
161
|
+
if (Array.isArray(left) && left.length !== right["length"])
|
|
162
|
+
return false;
|
|
163
|
+
for (const key of keys) {
|
|
164
|
+
if (!Object.hasOwn(right, key))
|
|
165
|
+
return false;
|
|
166
|
+
pending.push([left[key], right[key]]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
131
171
|
//# sourceMappingURL=standard-schema-validator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard-schema-validator.js","sourceRoot":"","sources":["../../src/validation/standard-schema-validator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"standard-schema-validator.js","sourceRoot":"","sources":["../../src/validation/standard-schema-validator.ts"],"names":[],"mappings":"AAyBA,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU,CAAC;AACjH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,OAAO,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,OAAgB;IACzC,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAE,OAAgC,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,WAAW,CAAC,KAA4B;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1G,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,sBAAsB,CAAC,MAAe;IAC7C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,wFAAwF;YACtF,iFAAiF;YACjF,gBAAgB,CAAC,MAAM,CAAC,CAC3B,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAI,MAAmC,CAAC,WAAW,CAAC,CAAC;IACnE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,iGAAiG;YAC/F,gBAAgB,CAAC,QAAQ,CAAC,CAC7B,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,uGAAuG;YACrG,6BAA6B,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CACrE,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,uGAAuG;YACrG,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CACpC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,iGAAiG;YAC/F,aAAa,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CACrD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA4B;IAC7D,OAAO,6BAA6B,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,6BAA6B,CAAC,MAA4B,EAAE,eAAe,GAAG,KAAK;IACjG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO;QACL,QAAQ,CAAC,KAAc;YACrB,sEAAsE;YACtE,qEAAqE;YACrE,MAAM,SAAS,GAAY,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC5E,MAAM,MAAM,GAAY,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,qEAAqE;gBACrE,oEAAoE;gBACpE,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACpD,MAAM,IAAI,KAAK,CACb,+FAA+F;oBAC7F,6FAA6F;oBAC7F,iFAAiF,CACpF,CAAC;YACJ,CAAC;YACD,qEAAqE;YACrE,sEAAsE;YACtE,6DAA6D;YAC7D,6DAA6D;YAC7D,kEAAkE;YAClE,mEAAmE;YACnE,qEAAqE;YACrE,4CAA4C;YAC5C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,6FAA6F;oBAC3F,oEAAoE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CACjG,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CACb,2FAA2F;wBACzF,wEAAwE,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAC5G,CAAC;gBACJ,CAAC;gBACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAG,MAAM,CAAC,MAAkC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/F,CAAC;YACD,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,6FAA6F;oBAC3F,+FAA+F;oBAC/F,gBAAgB,CAAC,MAAM,CAAC,CAC3B,CAAC;YACJ,CAAC;YACD,IAAI,eAAe,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,uHAAuH,CAAC,EAAE,CAAC;YAC7J,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,aAAa,CAAC,GAAY,EAAE,MAAe;IAClD,MAAM,OAAO,GAA8B,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,EAAwB,CAAC;QAC1D,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;YAAE,SAAS;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACtD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,KAAK,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QACxG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACzE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED