diff --git a/biome.json b/biome.json
index 2cd8a697..af2ee6d7 100644
--- a/biome.json
+++ b/biome.json
@@ -1,6 +1,6 @@
{
- "root": true,
"$schema": "https://biomejs.dev/schemas/2.1.3/schema.json",
+ "root": true,
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"formatter": {
"indentStyle": "space",
@@ -31,4 +31,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index deadc3c7..533bb823 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "standard-schema",
- "description": "A standard interface for TypeScript schema validation libraries",
+ "description": "A family of specs for interoperable TypeScript",
"version": "0.0.0",
"license": "MIT",
"author": "Colin McDonnell",
diff --git a/packages/examples/json-implement.ts b/packages/examples/json-implement.ts
new file mode 100644
index 00000000..383ae19a
--- /dev/null
+++ b/packages/examples/json-implement.ts
@@ -0,0 +1,74 @@
+/**
+ * This example shows how to implement the Standard JSON Schema interface.
+ * It demonstrates creating schemas that support both validation and JSON Schema generation.
+ */
+
+import type {
+ StandardJSONSchemaV1,
+ StandardSchemaV1,
+} from "@standard-schema/spec";
+
+interface CombinedProps
+ extends StandardSchemaV1.Props,
+ StandardJSONSchemaV1.Props {}
+
+/**
+ * An interface that combines StandardJSONSchema and StandardSchema.
+ * */
+interface StandardSchemaWithJSONSchema {
+ "~standard": CombinedProps;
+}
+
+interface MySchema extends StandardSchemaWithJSONSchema {
+ type: "string";
+}
+
+export function stringWithJSON(): MySchema {
+ return {
+ type: "string",
+ "~standard": {
+ version: 1,
+ vendor: "example-lib",
+ validate(value) {
+ return typeof value === "string"
+ ? { value }
+ : { issues: [{ message: "Invalid string", path: [] }] };
+ },
+ jsonSchema: {
+ input(params) {
+ const schema: Record = {
+ type: "string",
+ };
+
+ // Add schema version based on target
+ if (params.target === "draft-2020-12") {
+ schema.$schema = "https://json-schema.org/draft/2020-12/schema";
+ } else if (params.target === "draft-07") {
+ schema.$schema = "http://json-schema.org/draft-07/schema#";
+ } else {
+ throw new Error(`Unsupported target: ${params.target}`);
+ }
+
+ return schema;
+ },
+ output(params) {
+ // input and output are the same in this example
+ return this.input(params);
+ },
+ },
+ },
+ };
+}
+
+// usage example
+const stringSchema = stringWithJSON();
+
+stringSchema["~standard"].jsonSchema.input({
+ target: "draft-2020-12",
+});
+// => { $schema: "https://json-schema.org/draft/2020-12/schema", type: "string" }
+
+stringSchema["~standard"].jsonSchema.input({
+ target: "draft-07",
+});
+// => { $schema: "http://json-schema.org/draft-07/schema#", type: "string" }
diff --git a/packages/examples/json-integrate.ts b/packages/examples/json-integrate.ts
new file mode 100644
index 00000000..40e527b1
--- /dev/null
+++ b/packages/examples/json-integrate.ts
@@ -0,0 +1,19 @@
+import type { StandardJSONSchemaV1 } from "@standard-schema/spec";
+
+// Function that accepts any compliant `StandardJSONSchemaV1`
+// and converts it to a JSON Schema.
+export function acceptSchema(schema: StandardJSONSchemaV1): unknown {
+ // do stuff, e.g.
+ return schema["~standard"].jsonSchema.input({
+ target: "draft-2020-12",
+ });
+}
+
+export function parseData(
+ schema: T,
+ data: StandardJSONSchemaV1.InferInput, // extract input type
+) {
+ // @ts-expect-error - replace doStuff with your own logic
+ const result = doStuff(schema, data);
+ return result as StandardJSONSchemaV1.InferOutput; // extract output type
+}
diff --git a/packages/examples/package.json b/packages/examples/package.json
index d09ec4bb..9f47d8bf 100644
--- a/packages/examples/package.json
+++ b/packages/examples/package.json
@@ -5,7 +5,8 @@
"scripts": {
"lint": "pnpm biome lint .",
"format": "pnpm biome format --write .",
- "check": "pnpm biome check ."
+ "check": "pnpm biome check .",
+ "build": "tsup"
},
"devDependencies": {
"@standard-schema/spec": "workspace:*",
diff --git a/packages/examples/tsconfig.json b/packages/examples/tsconfig.json
index eadec2e7..df0b3794 100644
--- a/packages/examples/tsconfig.json
+++ b/packages/examples/tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"allowImportingTsExtensions": true,
+ "customConditions": ["standard-schema-spec"],
"declaration": true,
"exactOptionalPropertyTypes": true,
"isolatedDeclarations": true,
diff --git a/packages/spec/README.md b/packages/spec/README.md
index b2d6b329..f9813ffa 100644
--- a/packages/spec/README.md
+++ b/packages/spec/README.md
@@ -3,7 +3,7 @@
Standard Schema
- A common interface for TypeScript validation libraries
+ A family of specs for interoperable TypeScript
standardschema.dev
@@ -11,40 +11,74 @@
-Standard Schema is a common interface designed to be implemented by JavaScript and TypeScript schema libraries.
+The Standard Schema project is a set of interfaces that standardize the provision and consumption of shared functionality in the TypeScript ecosystem.
-The goal is to make it easier for ecosystem tools to accept user-defined type validators, without needing to write custom logic or adapters for each supported library. And since Standard Schema is a specification, they can do so with no additional runtime dependencies. Integrate once, validate anywhere.
+Its goal is to allow tools to accept a single input that includes all the types and capabilities they needβ no library-specific adapters, no extra dependencies. The result is an ecosystem that's fair for implementers, friendly for consumers, and open for end users.
-## Who designed it?
+## The specifications
-The spec was designed by the creators of Zod, Valibot, and ArkType. Recent versions of these libraries already implement the spec (see the [full list of compatible libraries](#what-schema-libraries-implement-the-spec) below).
+The specifications can be found below in their entirety. Libraries wishing to implement a spec can copy/paste the code block below into their codebase. They're also available at `@standard-schema/spec` on [npm](https://www.npmjs.com/package/@standard-schema/spec) and [JSR](https://jsr.io/@standard-schema/spec).
-## The interface
+```ts
+// #########################
+// ### Standard Typed ###
+// #########################
+
+/** The Standard Typed interface. This is a base type extended by other specs. */
+export interface StandardTypedV1 {
+ /** The Standard properties. */
+ readonly "~standard": StandardTypedV1.Props;
+}
+
+export declare namespace StandardTypedV1 {
+ /** The Standard Typed properties interface. */
+ export interface Props {
+ /** The version number of the standard. */
+ readonly version: 1;
+ /** The vendor name of the schema library. */
+ readonly vendor: string;
+ /** Inferred types associated with the schema. */
+ readonly types?: Types | undefined;
+ }
+
+ /** The Standard Typed types interface. */
+ export interface Types {
+ /** The input type of the schema. */
+ readonly input: Input;
+ /** The output type of the schema. */
+ readonly output: Output;
+ }
-The specification consists of a single TypeScript interface `StandardSchemaV1` to be implemented by any schema library wishing to be spec-compliant.
+ /** Infers the input type of a Standard Typed. */
+ export type InferInput = NonNullable<
+ Schema["~standard"]["types"]
+ >["input"];
-This interface can be found below in its entirety. Libraries wishing to implement the spec can copy/paste the code block below into their codebase. It's also available at `@standard-schema/spec` on [npm](https://www.npmjs.com/package/@standard-schema/spec) and [JSR](https://jsr.io/@standard-schema/spec). There will be zero changes without a major version bump.
+ /** Infers the output type of a Standard Typed. */
+ export type InferOutput = NonNullable<
+ Schema["~standard"]["types"]
+ >["output"];
+}
+
+// ##########################
+// ### Standard Schema ###
+// ##########################
-```ts
/** The Standard Schema interface. */
export interface StandardSchemaV1 {
/** The Standard Schema properties. */
- readonly '~standard': StandardSchemaV1.Props;
+ readonly "~standard": StandardSchemaV1.Props;
}
export declare namespace StandardSchemaV1 {
/** The Standard Schema properties interface. */
- export interface Props {
- /** The version number of the standard. */
- readonly version: 1;
- /** The vendor name of the schema library. */
- readonly vendor: string;
+ export interface Props
+ extends StandardTypedV1.Props {
/** Validates unknown input values. */
readonly validate: (
- value: unknown
+ value: unknown,
+ options?: StandardSchemaV1.Options | undefined
) => Result