diff --git a/Cargo.lock b/Cargo.lock index 9bc2100..b3698fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,78 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "libc" +version = "0.2.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" + [[package]] name = "mailschema" -version = "0.2.1" +version = "0.3.0" dependencies = [ "serde_json", + "sha2", ] [[package]] @@ -81,6 +142,17 @@ dependencies = [ "zmij", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "syn" version = "3.0.6" @@ -92,12 +164,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "unicode-ident" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "zmij" version = "1.0.23" diff --git a/Cargo.toml b/Cargo.toml index 6274631..c24310e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,18 @@ [package] name = "mailschema" -version = "0.2.1" +version = "0.3.0" edition = "2021" rust-version = "1.70" -description = "Embedded Mail Action Protocol 0.2 core artifacts and MailSchema Registry schemas" +description = "Embedded Mail Action Protocol 0.3 artifacts: the profile record, context and schemas" homepage = "https://mailschema.org/tools" repository = "https://github.com/mailschema/rust" documentation = "https://docs.rs/mailschema" license = "MIT" readme = "README.md" -keywords = ["email", "schema", "json-schema", "agents"] +keywords = ["email", "mail-action-protocol", "json-schema", "agents"] categories = ["data-structures", "email"] -include = ["src/**", "schemas/**", "contexts/**", "Cargo.toml", "README.md", "LICENSE"] +include = ["src/**", "artifacts/**", "Cargo.toml", "README.md", "LICENSE"] [dev-dependencies] serde_json = "1" +sha2 = "0.10" diff --git a/README.md b/README.md index bd60308..152cb41 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,16 @@ -# MailSchema for Rust +# mailschema -[![crates.io](https://img.shields.io/crates/v/mailschema)](https://crates.io/crates/mailschema) -[![CI](https://github.com/mailschema/rust/actions/workflows/test.yml/badge.svg)](https://github.com/mailschema/rust/actions/workflows/test.yml) - -The Mail Action Protocol 0.2 core artifacts and the MailSchema Registry schemas, embedded without runtime dependencies, filesystem access or network calls. - -[Specification](https://mailschema.org/specification) · [Registry](https://mailschema.org/registry) · [Tools](https://mailschema.org/tools) · [Source](https://github.com/mailschema/rust) - -## Install +The [Mail Action Protocol](https://mailschema.org) 0.3 artifacts for Rust, embedded byte for byte as mailschema.org publishes them: the profile record, the JSON-LD context, and the core, type contract and implementation record schemas. The profile record binds the context and the first two schemas by SHA-256. No runtime dependencies, filesystem access or network calls. ```toml [dependencies] -mailschema = "0.2" +mailschema = "0.3" ``` -Rust 1.70 or newer is required. - -## Use an artifact - ```rust -use mailschema::{Schema, MAP_CONTEXT, MAP_PROFILE, MAP_SCHEMA}; - -assert_eq!(Schema::Map.as_str(), MAP_SCHEMA); -assert!(MAP_CONTEXT.contains("MailAction")); +let schema: serde_json::Value = serde_json::from_str(mailschema::CORE_SCHEMA)?; ``` -`MAP_SCHEMA`, `MAP_CONTEXT`, `CONTRACT_FORMAT_SCHEMA` and `FORMS_SCHEMA` are byte-identical to the files the [profile record](https://mailschema.org/profiles/map/0.2.json) binds by SHA-256. `CONTRIBUTION_SCHEMA` and `RECORD_SCHEMA` describe Registry files. Parse them with your JSON library and pass the schemas to a Draft 2020-12 validator; the crate does not choose a validation engine. Type contracts are not bundled: a client obtains them from the [Registry catalogue](https://mailschema.org/registry/catalog.json) by digest. - -## Trust boundary +The constants are `PROFILE_RECORD`, `CONTEXT_DOCUMENT`, `CORE_SCHEMA`, `CONTRACT_SCHEMA` and `IMPLEMENTATION_SCHEMA`, with `PROFILE` and `CONTEXT` naming the profile and context. Schema validation alone does not establish a valid description; see the [specification](https://mailschema.org/specification/core). -A valid document is structured input. Schema validation does not authenticate a service, grant authority or establish product conformance. Package versions and MAP profile versions advance independently. MIT licensed. +Source: [mailschema/rust](https://github.com/mailschema/rust). License: MIT. diff --git a/UPSTREAM.md b/UPSTREAM.md index 59424a3..c651686 100644 --- a/UPSTREAM.md +++ b/UPSTREAM.md @@ -1,13 +1,13 @@ # Release provenance -Version `0.2.1` derives from [`mailschema/mailschema@db99c15`](https://github.com/mailschema/mailschema/commit/db99c1582f68b3cd3e80d5fe6c029c8535bf470c). +Version `0.3.0` derives from [`mailschema/mailschema@2c26469`](https://github.com/mailschema/mailschema/commit/2c26469209070f04ff9f8ec29e1387b8699a46a0). Its sources, tests and bundled files are prepared from that commit by `npm run packages:prepare`. -The bundled files are exact projections of that source commit and do not independently define MAP: +The bundled MAP 0.3 artifacts are exact copies of that commit's files and do not independently define MAP: -- MAP 0.2 core schema: `732d60fcb758d945dc15c57d885c9d1c0c76423a7439096d9755e8ec9830836a` -- MAP 0.2 JSON-LD context: `dfed0189524d7d16d31ed3d8af97e9a0c458200c4c034b413f9d14fa35b60257` -- Type contract format: `e030007cc034662c9d9d448a8a035aff3106cfb96fb60e6aa9f92b99b25df0b9` -- Form fields block: `3a976b93a057380e3630ca05e77e221a43a98559fb7fda8066299ec4bf2a8f9e` -- Contribution schema: `a8a241b4837971a6251bcc135c704283536f4fb825fbbaedaf1598c6e688d564` +- profile (`artifacts/profile.json`): `d9481627f855c127a4f5d6ddb7f3b699f66f6475bc8672d609f5b499f83d1a0f` +- context (`artifacts/context.jsonld`): `a51490d1fe8af695c14ea508aad88fd0429d18564791b6b52f3ab07d5c51aab3` +- core-schema (`artifacts/core.schema.json`): `0ad09a6955a47e7a2c1c1eec0747a3e0b15c08a79860e90ce4e65da11983aeb3` +- contract-schema (`artifacts/contract.schema.json`): `86bf057529c4fd2c7f0a880825774afeed31e9f7ba1d99760858a585fe28d18d` +- implementation-schema (`artifacts/implementation.schema.json`): `c62acc3ebb9f384c8fba7be353ab1905b65883ac2b16b147fd98485eec643396` -The canonical artifacts live in the main MailSchema repository. This repository owns the Rust crate surface and its release history. +The canonical artifacts live in the main MailSchema repository. This repository owns the Rust crate and its release history. diff --git a/artifacts/context.jsonld b/artifacts/context.jsonld new file mode 100644 index 0000000..28c9635 --- /dev/null +++ b/artifacts/context.jsonld @@ -0,0 +1,50 @@ +{ + "@context": { + "@version": 1.1, + "@protected": true, + "@vocab": "https://mailschema.org/vocab/map/0.3#", + "MailAction": "https://mailschema.org/vocab/map/0.3#MailAction", + "profile": { + "@id": "profile", + "@type": "@id" + }, + "type": { + "@id": "type", + "@type": "@json" + }, + "service": { + "@id": "service", + "@type": "@json" + }, + "subject": { + "@id": "subject", + "@type": "@json" + }, + "terms": { + "@id": "terms", + "@type": "@json" + }, + "details": { + "@id": "details", + "@type": "@json" + }, + "operations": { + "@id": "operations", + "@type": "@json" + }, + "human": { + "@id": "human", + "@type": "@json" + }, + "recipient": "recipient", + "inLanguage": "inLanguage", + "issuedAt": { + "@id": "issuedAt", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + }, + "expiresAt": { + "@id": "expiresAt", + "@type": "http://www.w3.org/2001/XMLSchema#dateTime" + } + } +} diff --git a/artifacts/contract.schema.json b/artifacts/contract.schema.json new file mode 100644 index 0000000..b050127 --- /dev/null +++ b/artifacts/contract.schema.json @@ -0,0 +1,206 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mailschema.org/artifacts/map-0.3/schemas/contract.schema.json", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "version", + "profile", + "name", + "summary", + "requirements", + "detailsSchema", + "operations" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://", + "maxLength": 2048 + }, + "version": { + "type": "string", + "minLength": 1, + "maxLength": 64 + }, + "profile": { + "const": "https://mailschema.org/profiles/map/0.3" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "summary": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "requirements": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "minItems": 1, + "maxItems": 64 + }, + "detailsSchema": { + "type": "object" + }, + "operations": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "name", + "semantics", + "effects", + "bindings", + "actors", + "exactTerms", + "inputSchema", + "outcomes" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z][a-z0-9-]{0,63}$" + }, + "name": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "semantics": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + }, + "effects": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "minItems": 1, + "maxItems": 32, + "uniqueItems": true + }, + "bindings": { + "type": "array", + "items": { + "enum": [ + "credential", + "capability" + ] + }, + "minItems": 1, + "maxItems": 2, + "uniqueItems": true + }, + "actors": { + "type": "array", + "items": { + "enum": [ + "human", + "agent" + ] + }, + "minItems": 1, + "maxItems": 2, + "uniqueItems": true + }, + "exactTerms": { + "type": "boolean" + }, + "inputSchema": { + "type": [ + "object", + "null" + ] + }, + "outcomes": { + "type": "object", + "minProperties": 1, + "propertyNames": { + "pattern": "^[a-z][a-z0-9-]{0,63}$" + }, + "additionalProperties": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + } + }, + "capability": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "maxLifetimeSeconds" + ], + "properties": { + "kind": { + "enum": [ + "refusal", + "protective-report", + "address-confirmation" + ] + }, + "maxLifetimeSeconds": { + "type": "integer", + "minimum": 1, + "maximum": 604800 + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "bindings": { + "contains": { + "const": "capability" + }, + "type": "array" + } + } + }, + "then": { + "required": [ + "capability" + ], + "properties": { + "inputSchema": { + "type": "null" + }, + "exactTerms": { + "const": true + } + } + }, + "else": { + "not": { + "required": [ + "capability" + ] + } + } + } + ] + }, + "minItems": 1, + "maxItems": 32 + } + } +} diff --git a/artifacts/core.schema.json b/artifacts/core.schema.json new file mode 100644 index 0000000..b0ebbfc --- /dev/null +++ b/artifacts/core.schema.json @@ -0,0 +1,210 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mailschema.org/artifacts/map-0.3/schemas/core.schema.json", + "title": "MAP 0.3 description shape; semantic checks in Core are additionally required", + "type": "object", + "additionalProperties": false, + "required": [ + "@context", + "@type", + "@id", + "profile", + "type", + "issuedAt", + "expiresAt", + "inLanguage", + "service", + "recipient", + "subject", + "terms", + "details", + "operations", + "human" + ], + "properties": { + "@context": { + "const": "https://mailschema.org/contexts/map-0.3.jsonld" + }, + "@type": { + "const": "MailAction" + }, + "@id": { + "type": "string", + "minLength": 1, + "format": "uri", + "maxLength": 2048 + }, + "profile": { + "const": "https://mailschema.org/profiles/map/0.3" + }, + "type": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "version", + "contractDigest" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://", + "maxLength": 2048 + }, + "version": { + "type": "string", + "minLength": 1, + "maxLength": 64 + }, + "contractDigest": { + "type": "string", + "minLength": 1, + "pattern": "^sha-256:[0-9a-f]{64}$" + } + } + }, + "issuedAt": { + "type": "string", + "minLength": 1, + "format": "date-time", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\dZ$" + }, + "expiresAt": { + "type": "string", + "minLength": 1, + "format": "date-time", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\dZ$" + }, + "inLanguage": { + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "service": { + "type": "object", + "additionalProperties": false, + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://(?![0-9.]+(:[0-9]+)?$)[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(:[0-9]{1,5})?$", + "maxLength": 2048 + }, + "tenant": { + "type": "string", + "minLength": 1, + "format": "uri", + "maxLength": 2048 + } + } + }, + "recipient": { + "type": "string", + "minLength": 1, + "maxLength": 320 + }, + "subject": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "title" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "maxLength": 2048 + }, + "title": { + "type": "string", + "minLength": 1, + "maxLength": 2048 + } + } + }, + "terms": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "version" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "maxLength": 2048 + }, + "version": { + "type": "string", + "minLength": 1, + "pattern": "^[ -~]+$", + "maxLength": 1024 + } + } + }, + "details": { + "type": "object" + }, + "operations": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "pattern": "^[a-z][a-z0-9-]{0,63}$" + }, + "capability": { + "type": "object", + "additionalProperties": false, + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://[^/?#@]+([/?][^#]*)?$", + "maxLength": 4096 + } + } + } + } + }, + "minItems": 1, + "maxItems": 32 + }, + "human": { + "type": "object", + "additionalProperties": false, + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://[^/?#@]+([/?][^#]*)?$", + "maxLength": 4096 + } + } + } + } +} diff --git a/artifacts/implementation.schema.json b/artifacts/implementation.schema.json new file mode 100644 index 0000000..f6d2310 --- /dev/null +++ b/artifacts/implementation.schema.json @@ -0,0 +1,173 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mailschema.org/artifacts/map-0.3/schemas/implementation.schema.json", + "title": "MAP implementation record", + "type": "object", + "additionalProperties": false, + "required": [ + "service", + "maintainer", + "type", + "operations", + "binding", + "status", + "documentation", + "evidence" + ], + "dependentRequired": { + "artifact": ["format"], + "format": ["artifact"] + }, + "properties": { + "service": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "maintainer": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "url" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + } + } + }, + "type": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "version", + "contractDigest" + ], + "properties": { + "id": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "version": { + "type": "string", + "minLength": 1 + }, + "contractDigest": { + "type": "string", + "pattern": "^sha-256:[0-9a-f]{64}$" + } + } + }, + "operations": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "binding": { + "type": "string", + "format": "uri", + "pattern": "^https://", + "description": "Identifier of the binding specification or documented service binding. It is not a request destination. Clients must explicitly support it." + }, + "artifact": { + "type": "object", + "additionalProperties": false, + "required": [ + "url", + "digest", + "digestMode" + ], + "properties": { + "url": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "digest": { + "type": "string", + "pattern": "^sha-256:[0-9a-f]{64}$" + }, + "digestMode": { + "enum": [ + "canonical-json", + "bytes" + ], + "description": "canonical-json hashes the RFC 8785 representation; bytes hashes the exact downloaded artifact. Both use SHA-256." + } + } + }, + "format": { + "type": "string", + "minLength": 1 + }, + "status": { + "enum": [ + "Draft", + "Experimental", + "Stable", + "Deprecated", + "Superseded" + ] + }, + "documentation": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "evidence": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "url", + "summary" + ], + "properties": { + "kind": { + "enum": [ + "declaration", + "test-report" + ] + }, + "url": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + }, + "summary": { + "type": "string", + "minLength": 1 + } + } + } + }, + "successor": { + "type": "string", + "minLength": 1, + "format": "uri", + "pattern": "^https://" + } + } +} diff --git a/artifacts/profile.json b/artifacts/profile.json new file mode 100644 index 0000000..ff28124 --- /dev/null +++ b/artifacts/profile.json @@ -0,0 +1,27 @@ +{ + "id": "https://mailschema.org/profiles/map/0.3", + "name": "Mail Action Protocol 0.3", + "status": "working-draft", + "description": "An action description carried in Structured Email. A trusted service binding maps each decision to the service's existing operations, and the service enforces permission and exact terms. Types are defined by digest-bound contracts.", + "context": "https://mailschema.org/contexts/map-0.3.jsonld", + "schema": "https://mailschema.org/artifacts/map-0.3/schemas/core.schema.json", + "contractFormat": "https://mailschema.org/artifacts/map-0.3/schemas/contract.schema.json", + "specification": "https://mailschema.org/specification/core", + "artifacts": { + "context": { + "url": "https://mailschema.org/contexts/map-0.3.jsonld", + "sha256": "a51490d1fe8af695c14ea508aad88fd0429d18564791b6b52f3ab07d5c51aab3" + }, + "schema": { + "url": "https://mailschema.org/artifacts/map-0.3/schemas/core.schema.json", + "sha256": "0ad09a6955a47e7a2c1c1eec0747a3e0b15c08a79860e90ce4e65da11983aeb3" + }, + "contractFormat": { + "url": "https://mailschema.org/artifacts/map-0.3/schemas/contract.schema.json", + "sha256": "86bf057529c4fd2c7f0a880825774afeed31e9f7ba1d99760858a585fe28d18d" + }, + "conformance": { + "url": "https://github.com/mailschema/mailschema/blob/main/conformance/map-0.3/README.md" + } + } +} diff --git a/contexts/map-0.2.jsonld b/contexts/map-0.2.jsonld deleted file mode 100644 index c97aca3..0000000 --- a/contexts/map-0.2.jsonld +++ /dev/null @@ -1,91 +0,0 @@ -{ - "@context": { - "@version": 1.1, - "map": "https://mailschema.org/ns/map#", - "schema": "https://schema.org/", - "MailAction": "map:MailAction", - "profile": { - "@id": "map:profile", - "@type": "@id" - }, - "type": { - "@id": "map:interactionType", - "@context": { - "id": { - "@id": "map:id", - "@type": "@id" - } - } - }, - "version": "schema:version", - "contractDigest": "map:contractDigest", - "describedAt": { - "@id": "schema:dateCreated", - "@type": "http://www.w3.org/2001/XMLSchema#dateTime" - }, - "expiresAt": { - "@id": "schema:expires", - "@type": "http://www.w3.org/2001/XMLSchema#dateTime" - }, - "service": { - "@id": "schema:provider", - "@context": { - "id": { - "@id": "map:id", - "@type": "@id" - } - } - }, - "name": "schema:name", - "authority": "map:authority", - "onBehalfOf": { - "@id": "map:onBehalfOf", - "@context": { - "id": { - "@id": "map:id", - "@type": "@id" - } - } - }, - "resource": { - "@id": "map:resource", - "@type": "@id" - }, - "execution": "map:execution", - "url": { - "@id": "schema:url", - "@type": "@id" - }, - "resultUrlTemplate": "map:resultUrlTemplate", - "resultRetentionSeconds": "map:resultRetentionSeconds", - "humanUrl": { - "@id": "map:humanUrl", - "@type": "@id" - }, - "target": { - "@id": "schema:object", - "@context": { - "id": { - "@id": "map:id", - "@type": "@id" - } - } - }, - "recipient": "schema:recipient", - "details": { - "@id": "map:details", - "@type": "@json" - }, - "revision": "schema:version", - "title": "schema:name", - "digest": "map:digest", - "operations": { - "@id": "schema:potentialAction", - "@container": "@set", - "@context": { - "id": "map:operationId" - } - }, - "description": "schema:description" - } -} diff --git a/schemas/contribution.schema.json b/schemas/contribution.schema.json deleted file mode 100644 index 6b7742a..0000000 --- a/schemas/contribution.schema.json +++ /dev/null @@ -1,874 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "MailSchema contribution format", - "description": "Repository contribution data. This is not a MAP message or wire representation.", - "$defs": { - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "slug": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 500, - "pattern": "\\S" - }, - "category": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "status": { - "enum": ["Draft", "Proposal", "Reuse assessment"] - }, - "version": { - "anyOf": [ - { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - { - "type": "null" - } - ] - }, - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "overview": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "target": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "operations": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["id", "name", "description"] - }, - "minItems": 1, - "maxItems": 100 - }, - "inputs": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "results": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "permissions": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "humanRoute": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "example": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "steps": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 1, - "maxItems": 100 - }, - "exception": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["title", "steps", "exception"] - }, - "references": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["title", "href", "description"] - }, - "minItems": 1, - "maxItems": 100 - }, - "openQuestions": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 0, - "maxItems": 100 - }, - "maintainers": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "minItems": 1, - "maxItems": 100 - }, - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "pattern": "^/specification/(?:[a-z0-9-]+/)*$", - "maxLength": 300 - } - }, - "required": ["label", "href"] - } - }, - "required": [ - "slug", - "name", - "summary", - "category", - "status", - "version", - "profile", - "overview", - "target", - "operations", - "inputs", - "results", - "permissions", - "humanRoute", - "example", - "references", - "openQuestions", - "maintainers" - ], - "allOf": [ - { - "if": { - "properties": { - "status": { - "const": "Draft" - } - }, - "required": ["status"] - }, - "then": { - "required": ["definition"], - "properties": { - "version": { - "type": "string" - } - } - } - } - ] - }, - "record": { - "type": "object", - "additionalProperties": false, - "properties": { - "slug": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 500, - "pattern": "\\S" - }, - "category": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "status": { - "enum": ["Draft", "Proposal", "Reuse assessment"] - }, - "version": { - "anyOf": [ - { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - { - "type": "null" - } - ] - }, - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "overview": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "target": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "operations": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["id", "name", "description"] - }, - "minItems": 1, - "maxItems": 100 - }, - "inputs": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "results": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "permissions": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "humanRoute": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "example": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "steps": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 1, - "maxItems": 100 - }, - "exception": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["title", "steps", "exception"] - }, - "references": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["title", "href", "description"] - }, - "minItems": 1, - "maxItems": 100 - }, - "openQuestions": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 0, - "maxItems": 100 - }, - "maintainers": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "minItems": 1, - "maxItems": 100 - }, - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "pattern": "^/specification/(?:[a-z0-9-]+/)*$", - "maxLength": 300 - } - }, - "required": ["label", "href"] - }, - "origin": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "contributors": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "minItems": 1, - "maxItems": 100 - }, - "history": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "contributionId": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - } - }, - "required": ["label", "description"] - }, - "minItems": 1, - "maxItems": 100 - } - }, - "required": [ - "slug", - "name", - "summary", - "category", - "status", - "version", - "profile", - "overview", - "target", - "operations", - "inputs", - "results", - "permissions", - "humanRoute", - "example", - "references", - "openQuestions", - "maintainers", - "origin", - "contributors", - "history" - ], - "allOf": [ - { - "if": { - "properties": { - "status": { - "const": "Draft" - } - }, - "required": ["status"] - }, - "then": { - "required": ["definition"], - "properties": { - "version": { - "type": "string" - } - } - } - } - ] - } - }, - "oneOf": [ - { - "type": "object", - "additionalProperties": false, - "properties": { - "format": { - "const": "mailschema-contribution/1" - }, - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "contributor": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "source": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "kind": { - "const": "new-type" - }, - "record": { - "$ref": "#/$defs/definition" - } - }, - "required": ["format", "id", "contributor", "summary", "kind", "record"] - }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "format": { - "const": "mailschema-contribution/1" - }, - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "contributor": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "source": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "kind": { - "const": "amendment" - }, - "baseDigest": { - "type": "string", - "pattern": "^[a-f0-9]{64}$" - }, - "record": { - "$ref": "#/$defs/definition" - } - }, - "required": ["format", "id", "contributor", "summary", "kind", "baseDigest", "record"] - }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "format": { - "const": "mailschema-contribution/1" - }, - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "contributor": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "source": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "kind": { - "const": "implementation" - }, - "type": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "typeVersion": { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - "typeDigest": { - "type": "string", - "pattern": "^[a-f0-9]{64}$" - }, - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "product": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": ["name"] - }, - "operations": { - "type": "array", - "items": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "minItems": 1, - "maxItems": 100 - }, - "evidence": { - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "enum": ["declaration", "test-report"] - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "reproduction": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "results": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": ["kind"], - "allOf": [ - { - "if": { - "properties": { - "kind": { - "const": "test-report" - } - }, - "required": ["kind"] - }, - "then": { - "required": ["url", "reproduction", "results"] - } - } - ] - } - }, - "required": [ - "format", - "id", - "contributor", - "summary", - "kind", - "type", - "typeVersion", - "typeDigest", - "profile", - "product", - "operations", - "evidence" - ] - } - ] -} diff --git a/schemas/forms-0.1.schema.json b/schemas/forms-0.1.schema.json deleted file mode 100644 index 88f680b..0000000 --- a/schemas/forms-0.1.schema.json +++ /dev/null @@ -1,329 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://mailschema.org/schemas/forms-0.1.schema.json", - "title": "MailSchema form fields 0.1", - "description": "Shared, immutable blocks for types that collect values: a closed subset of JSON Schema based on Model Context Protocol elicitation, with HTML autofill field names.", - "$defs": { - "fieldName": { - "type": "string", - "pattern": "^[a-z][A-Za-z0-9]{0,63}$" - }, - "text": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "[^\\t\\n\\u000b\\f\\r \\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]" - }, - "autocomplete": { - "type": "string", - "maxLength": 200, - "pattern": "^(?:section-[a-z0-9-]+ )?(?:(?:shipping|billing) )?(?:(?:home|work|mobile|fax|pager) )?[a-z][a-z0-9-]*$", - "not": { - "pattern": "(?:^| )(?:current-password|new-password|one-time-code|cc-[a-z-]+)$" - } - }, - "choice": { - "type": "object", - "additionalProperties": false, - "properties": { - "const": { - "type": "string", - "minLength": 1, - "maxLength": 200 - }, - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "[^\\t\\n\\u000b\\f\\r \\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]" - } - }, - "required": ["const", "title"] - }, - "choices": { - "type": "array", - "items": { - "$ref": "#/$defs/choice" - }, - "minItems": 1, - "maxItems": 100 - }, - "textField": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "string" - }, - "title": { - "$ref": "#/$defs/text" - }, - "description": { - "$ref": "#/$defs/text" - }, - "minLength": { - "type": "integer", - "minimum": 0, - "maximum": 12000 - }, - "maxLength": { - "type": "integer", - "minimum": 1, - "maximum": 12000 - }, - "format": { - "enum": ["email", "uri", "date", "date-time"] - }, - "default": { - "type": "string", - "maxLength": 12000 - }, - "autocomplete": { - "$ref": "#/$defs/autocomplete" - } - }, - "required": ["type", "title"] - }, - "numberField": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "enum": ["number", "integer"] - }, - "title": { - "$ref": "#/$defs/text" - }, - "description": { - "$ref": "#/$defs/text" - }, - "minimum": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "maximum": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "default": { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - "autocomplete": { - "$ref": "#/$defs/autocomplete" - } - }, - "required": ["type", "title"] - }, - "booleanField": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "boolean" - }, - "title": { - "$ref": "#/$defs/text" - }, - "description": { - "$ref": "#/$defs/text" - }, - "default": { - "type": "boolean" - } - }, - "required": ["type", "title"] - }, - "choiceField": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "string" - }, - "title": { - "$ref": "#/$defs/text" - }, - "description": { - "$ref": "#/$defs/text" - }, - "oneOf": { - "$ref": "#/$defs/choices" - }, - "default": { - "type": "string", - "maxLength": 200 - }, - "autocomplete": { - "$ref": "#/$defs/autocomplete" - } - }, - "required": ["type", "title", "oneOf"] - }, - "choicesField": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "array" - }, - "title": { - "$ref": "#/$defs/text" - }, - "description": { - "$ref": "#/$defs/text" - }, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "anyOf": { - "$ref": "#/$defs/choices" - } - }, - "required": ["anyOf"] - }, - "minItems": { - "type": "integer", - "minimum": 0, - "maximum": 100 - }, - "maxItems": { - "type": "integer", - "minimum": 1, - "maximum": 100 - }, - "uniqueItems": { - "const": true - }, - "default": { - "type": "array", - "items": { - "type": "string", - "maxLength": 200 - }, - "maxItems": 100, - "uniqueItems": true - } - }, - "required": ["type", "title", "items", "uniqueItems"] - }, - "fields": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "object" - }, - "properties": { - "type": "object", - "minProperties": 1, - "maxProperties": 50, - "propertyNames": { - "$ref": "#/$defs/fieldName" - }, - "additionalProperties": { - "oneOf": [ - { - "$ref": "#/$defs/textField" - }, - { - "$ref": "#/$defs/numberField" - }, - { - "$ref": "#/$defs/booleanField" - }, - { - "$ref": "#/$defs/choiceField" - }, - { - "$ref": "#/$defs/choicesField" - } - ] - } - }, - "required": { - "type": "array", - "items": { - "$ref": "#/$defs/fieldName" - }, - "uniqueItems": true, - "maxItems": 50 - } - }, - "required": ["type", "properties"] - }, - "choiceFields": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "const": "object" - }, - "properties": { - "type": "object", - "minProperties": 1, - "maxProperties": 50, - "propertyNames": { - "$ref": "#/$defs/fieldName" - }, - "additionalProperties": { - "oneOf": [ - { - "$ref": "#/$defs/booleanField" - }, - { - "$ref": "#/$defs/choiceField" - }, - { - "$ref": "#/$defs/choicesField" - } - ] - } - }, - "required": { - "type": "array", - "items": { - "$ref": "#/$defs/fieldName" - }, - "uniqueItems": true, - "maxItems": 50 - } - }, - "required": ["type", "properties"] - }, - "fieldValues": { - "type": "object", - "maxProperties": 50, - "propertyNames": { - "$ref": "#/$defs/fieldName" - }, - "additionalProperties": { - "anyOf": [ - { - "type": "string", - "maxLength": 12000 - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "array", - "items": { - "type": "string", - "maxLength": 200 - }, - "maxItems": 100, - "uniqueItems": true - } - ] - } - } - } -} diff --git a/schemas/map-0.2.schema.json b/schemas/map-0.2.schema.json deleted file mode 100644 index a87b566..0000000 --- a/schemas/map-0.2.schema.json +++ /dev/null @@ -1,1033 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://mailschema.org/schemas/map-0.2.schema.json", - "title": "Mail Action Protocol 0.2", - "description": "Description, request, result and problem documents for MAP 0.2: a type-agnostic core whose types are defined by digest-bound contracts, with credential or possession authority over HTTPS.", - "oneOf": [ - { - "$ref": "#/$defs/description" - }, - { - "$ref": "#/$defs/request" - }, - { - "$ref": "#/$defs/result" - }, - { - "$ref": "#/$defs/problem" - } - ], - "$defs": { - "profile": { - "const": "https://mailschema.org/profiles/map/0.2" - }, - "nonBlank": { - "type": "string", - "pattern": "[^\\t\\n\\u000b\\f\\r \\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]" - }, - "dateTime": { - "type": "string", - "pattern": "^(?:[0-9]{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12][0-9]|3[01])|(?:0[469]|11)-(?:0[1-9]|[12][0-9]|30)|02-(?:0[1-9]|1[0-9]|2[0-8]))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:[02468][048]|[13579][26])00)-02-29)T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]{1,3})?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$" - }, - "date": { - "type": "string", - "pattern": "^(?:[0-9]{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12][0-9]|3[01])|(?:0[469]|11)-(?:0[1-9]|[12][0-9]|30)|02-(?:0[1-9]|1[0-9]|2[0-8]))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:[02468][048]|[13579][26])00)-02-29)$" - }, - "identifier": { - "type": "string", - "pattern": "^[A-Za-z][A-Za-z0-9+.-]*:(?:[A-Za-z0-9._~:/?#@!$&'()*+,;=-]|%[0-9A-Fa-f]{2})+$", - "maxLength": 2048 - }, - "httpsIdentifier": { - "type": "string", - "pattern": "^https://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)*[A-Za-z](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?::(?:[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?(?:[/?#](?:[A-Za-z0-9._~:/?#@!$&'()*+,;=-]|%[0-9A-Fa-f]{2})*)?$", - "maxLength": 2048 - }, - "httpsTarget": { - "type": "string", - "pattern": "^https://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)*[A-Za-z](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?::(?:[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?(?:[/?](?:[A-Za-z0-9._~:/?@!$&'()*+,;=-]|%[0-9A-Fa-f]{2})*)?$", - "maxLength": 2048 - }, - "httpsOrigin": { - "type": "string", - "pattern": "^https://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)*[A-Za-z](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?::(?:[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$", - "maxLength": 300 - }, - "urlTemplate": { - "type": "string", - "pattern": "^https://(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\\.)*[A-Za-z](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?::(?:[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?[/?](?:[A-Za-z0-9._~:/?@!$&'()*+,;=-]|%[0-9A-Fa-f]{2})*\\{requestId\\}(?:[A-Za-z0-9._~:/?#@!$&'()*+,;=-]|%[0-9A-Fa-f]{2})*$", - "maxLength": 2048 - }, - "address": { - "type": "string", - "pattern": "^(?:[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]|[^\\u0000-\\u00a0\\u1680\\u2000-\\u200f\\u2028-\\u202f\\u205f-\\u206f\\u3000\\ufeff])+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$", - "maxLength": 320 - }, - "uuidUrn": { - "type": "string", - "pattern": "^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - }, - "digest": { - "type": "string", - "pattern": "^sha-256:[a-f0-9]{64}$" - }, - "contractDigest": { - "type": "string", - "pattern": "^sha-256:[a-f0-9]{64}$" - }, - "typeReference": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/identifier" - }, - "version": { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - "contractDigest": { - "$ref": "#/$defs/contractDigest" - } - }, - "required": ["id", "version", "contractDigest"] - }, - "token": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "target": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/identifier" - }, - "revision": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "title": { - "type": "string", - "minLength": 1, - "maxLength": 500 - }, - "digest": { - "$ref": "#/$defs/digest" - } - }, - "required": ["id", "revision", "digest"] - }, - "operation": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/token" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 2000 - } - }, - "required": ["id", "name", "description"] - }, - "description": { - "type": "object", - "additionalProperties": false, - "properties": { - "@context": { - "const": "https://mailschema.org/contexts/map-0.2.jsonld" - }, - "@type": { - "const": "MailAction" - }, - "@id": { - "$ref": "#/$defs/uuidUrn" - }, - "profile": { - "$ref": "#/$defs/profile" - }, - "type": { - "$ref": "#/$defs/typeReference" - }, - "describedAt": { - "$ref": "#/$defs/dateTime" - }, - "expiresAt": { - "$ref": "#/$defs/dateTime" - }, - "service": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/httpsIdentifier" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "authority": { - "enum": ["credential", "possession"] - }, - "onBehalfOf": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/identifier" - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240 - } - }, - "required": ["id", "name"] - }, - "resource": { - "$ref": "#/$defs/httpsTarget" - }, - "execution": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "$ref": "#/$defs/httpsTarget" - }, - "resultUrlTemplate": { - "$ref": "#/$defs/urlTemplate" - }, - "resultRetentionSeconds": { - "type": "integer", - "minimum": 300, - "maximum": 31536000 - } - }, - "required": ["url", "resultUrlTemplate", "resultRetentionSeconds"] - }, - "humanUrl": { - "$ref": "#/$defs/httpsIdentifier" - } - }, - "required": ["id", "name", "authority", "execution", "humanUrl"] - }, - "recipient": { - "$ref": "#/$defs/address" - }, - "target": { - "$ref": "#/$defs/target" - }, - "details": { - "type": "object", - "maxProperties": 100, - "propertyNames": { - "$ref": "#/$defs/detailsKey" - }, - "additionalProperties": { - "$ref": "#/$defs/detailsValue" - } - }, - "operations": { - "type": "array", - "items": { - "$ref": "#/$defs/operation" - }, - "minItems": 1, - "maxItems": 100 - } - }, - "required": [ - "@context", - "@type", - "@id", - "profile", - "type", - "describedAt", - "expiresAt", - "service", - "target", - "operations" - ], - "allOf": [ - { - "if": { - "type": "object", - "properties": { - "service": { - "type": "object", - "properties": { - "authority": { - "const": "credential" - } - } - } - } - }, - "then": { - "type": "object", - "properties": { - "service": { - "type": "object", - "required": ["resource"] - } - }, - "not": { - "required": ["recipient"] - } - }, - "else": { - "type": "object", - "properties": { - "service": { - "type": "object", - "properties": { - "resource": false, - "onBehalfOf": false - } - } - }, - "required": ["recipient"] - } - } - ] - }, - "request": { - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "const": "MapRequest" - }, - "profile": { - "$ref": "#/$defs/profile" - }, - "requestId": { - "$ref": "#/$defs/uuidUrn" - }, - "interactionId": { - "$ref": "#/$defs/uuidUrn" - }, - "descriptionDigest": { - "$ref": "#/$defs/digest" - }, - "type": { - "$ref": "#/$defs/typeReference" - }, - "operation": { - "$ref": "#/$defs/token" - }, - "input": { - "type": "object", - "maxProperties": 100 - } - }, - "required": [ - "kind", - "profile", - "requestId", - "interactionId", - "descriptionDigest", - "type", - "operation", - "input" - ] - }, - "result": { - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "const": "MapResult" - }, - "profile": { - "$ref": "#/$defs/profile" - }, - "requestId": { - "$ref": "#/$defs/uuidUrn" - }, - "interactionId": { - "$ref": "#/$defs/uuidUrn" - }, - "descriptionDigest": { - "$ref": "#/$defs/digest" - }, - "type": { - "$ref": "#/$defs/typeReference" - }, - "operation": { - "$ref": "#/$defs/token" - }, - "state": { - "enum": ["accepted", "completed", "failed", "pending", "approval-required"] - }, - "target": { - "$ref": "#/$defs/target" - }, - "recordedAt": { - "$ref": "#/$defs/dateTime" - }, - "resultUrl": { - "$ref": "#/$defs/httpsIdentifier" - }, - "actor": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "approvalUrl": { - "$ref": "#/$defs/httpsIdentifier" - }, - "reason": { - "$ref": "#/$defs/token" - }, - "output": { - "type": "object", - "maxProperties": 100 - } - }, - "required": [ - "kind", - "profile", - "requestId", - "interactionId", - "descriptionDigest", - "type", - "operation", - "state", - "target", - "recordedAt", - "resultUrl", - "output" - ], - "allOf": [ - { - "if": { - "type": "object", - "properties": { - "state": { - "const": "approval-required" - } - } - }, - "then": { - "type": "object", - "required": ["approvalUrl"] - }, - "else": { - "type": "object", - "not": { - "required": ["approvalUrl"] - } - } - }, - { - "if": { - "type": "object", - "properties": { - "state": { - "const": "failed" - } - } - }, - "then": { - "type": "object", - "required": ["reason"] - }, - "else": { - "type": "object", - "not": { - "required": ["reason"] - } - } - } - ] - }, - "problem": { - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "enum": [ - "https://mailschema.org/problems/refused", - "https://mailschema.org/problems/authentication-required", - "https://mailschema.org/problems/result-not-found", - "https://mailschema.org/problems/stale-target", - "https://mailschema.org/problems/expired-interaction", - "https://mailschema.org/problems/invalid-request", - "https://mailschema.org/problems/unsupported-type", - "https://mailschema.org/problems/unsupported-operation", - "https://mailschema.org/problems/idempotency-conflict", - "https://mailschema.org/problems/request-in-progress", - "https://mailschema.org/problems/already-decided" - ] - }, - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240 - }, - "status": { - "type": "integer", - "minimum": 400, - "maximum": 599 - }, - "detail": { - "type": "string", - "minLength": 1, - "maxLength": 4000 - }, - "instance": { - "$ref": "#/$defs/identifier" - }, - "profile": { - "$ref": "#/$defs/profile" - }, - "requestId": { - "$ref": "#/$defs/uuidUrn" - }, - "interactionId": { - "$ref": "#/$defs/uuidUrn" - }, - "code": { - "enum": [ - "refused", - "result-not-found", - "stale-target", - "expired-interaction", - "invalid-request", - "unsupported-type", - "unsupported-operation", - "idempotency-conflict", - "request-in-progress", - "already-decided" - ] - }, - "target": { - "$ref": "#/$defs/target" - }, - "errors": { - "type": "array", - "minItems": 1, - "maxItems": 100, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "detail": { - "type": "string", - "minLength": 1, - "maxLength": 2000 - }, - "pointer": { - "type": "string", - "pattern": "^(?:/(?:[^~/]|~[01])*)*$", - "maxLength": 1000 - } - }, - "required": ["detail", "pointer"] - } - } - }, - "required": ["type", "title", "status", "detail"], - "dependentRequired": { - "instance": ["profile", "requestId", "code"], - "profile": ["instance", "requestId", "code"], - "requestId": ["instance", "profile", "code"], - "interactionId": ["instance", "profile", "requestId", "code"], - "code": ["instance", "profile", "requestId"] - }, - "allOf": [ - { - "if": { - "properties": { - "type": { - "enum": [ - "https://mailschema.org/problems/result-not-found", - "https://mailschema.org/problems/stale-target", - "https://mailschema.org/problems/expired-interaction", - "https://mailschema.org/problems/unsupported-type", - "https://mailschema.org/problems/unsupported-operation", - "https://mailschema.org/problems/idempotency-conflict", - "https://mailschema.org/problems/request-in-progress", - "https://mailschema.org/problems/already-decided" - ] - } - }, - "required": ["type"] - }, - "then": { - "required": ["code"] - } - }, - { - "if": { - "required": ["errors"] - }, - "then": { - "properties": { - "code": { - "const": "invalid-request" - } - }, - "required": ["code"] - } - }, - { - "if": { - "properties": { - "code": { - "not": { - "const": "result-not-found" - } - } - }, - "required": ["code"] - }, - "then": { - "required": ["interactionId"] - } - }, - { - "if": { - "properties": { - "code": { - "const": "invalid-request" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/invalid-request" - }, - "status": { - "const": 400 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "refused" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/refused" - }, - "status": { - "const": 403 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "result-not-found" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/result-not-found" - }, - "status": { - "const": 404 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "stale-target" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/stale-target" - }, - "status": { - "const": 409 - } - }, - "required": ["target"] - } - }, - { - "if": { - "properties": { - "code": { - "const": "idempotency-conflict" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/idempotency-conflict" - }, - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "request-in-progress" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/request-in-progress" - }, - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "already-decided" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/already-decided" - }, - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "expired-interaction" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/expired-interaction" - }, - "status": { - "const": 410 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "unsupported-type" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/unsupported-type" - }, - "status": { - "const": 422 - } - } - } - }, - { - "if": { - "properties": { - "code": { - "const": "unsupported-operation" - } - }, - "required": ["code"] - }, - "then": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/unsupported-operation" - }, - "status": { - "const": 422 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/invalid-request" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 400 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/authentication-required" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 401 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/refused" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 403 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/result-not-found" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 404 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/stale-target" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/idempotency-conflict" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/request-in-progress" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/already-decided" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 409 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/expired-interaction" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 410 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/unsupported-type" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 422 - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "https://mailschema.org/problems/unsupported-operation" - } - }, - "required": ["type"] - }, - "then": { - "properties": { - "status": { - "const": 422 - } - } - } - } - ] - }, - "detailsKey": { - "type": "string", - "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$" - }, - "detailsValue": { - "anyOf": [ - { - "type": "string", - "maxLength": 12000 - }, - { - "type": "integer", - "minimum": -9007199254740991, - "maximum": 9007199254740991 - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "type": "array", - "maxItems": 100, - "items": { - "$ref": "#/$defs/detailsValue" - } - }, - { - "type": "object", - "maxProperties": 100, - "propertyNames": { - "$ref": "#/$defs/detailsKey" - }, - "additionalProperties": { - "$ref": "#/$defs/detailsValue" - } - } - ] - } - } -} diff --git a/schemas/record.schema.json b/schemas/record.schema.json deleted file mode 100644 index 2161d0d..0000000 --- a/schemas/record.schema.json +++ /dev/null @@ -1,664 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "slug": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 500, - "pattern": "\\S" - }, - "category": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "status": { - "enum": [ - "Draft", - "Proposal", - "Reuse assessment" - ] - }, - "version": { - "anyOf": [ - { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - { - "type": "null" - } - ] - }, - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "overview": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "target": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "operations": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "id", - "name", - "description" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "inputs": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "results": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "permissions": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "humanRoute": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "example": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "steps": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 1, - "maxItems": 100 - }, - "exception": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "title", - "steps", - "exception" - ] - }, - "references": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "title", - "href", - "description" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "openQuestions": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 0, - "maxItems": 100 - }, - "maintainers": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": [ - "name" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "pattern": "^/specification/(?:[a-z0-9-]+/)*$", - "maxLength": 300 - } - }, - "required": [ - "label", - "href" - ] - } - }, - "required": [ - "slug", - "name", - "summary", - "category", - "status", - "version", - "profile", - "overview", - "target", - "operations", - "inputs", - "results", - "permissions", - "humanRoute", - "example", - "references", - "openQuestions", - "maintainers" - ], - "allOf": [ - { - "if": { - "properties": { - "status": { - "const": "Draft" - } - }, - "required": [ - "status" - ] - }, - "then": { - "required": [ - "definition" - ], - "properties": { - "version": { - "type": "string" - } - } - } - } - ] - }, - "record": { - "type": "object", - "additionalProperties": false, - "properties": { - "slug": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "summary": { - "type": "string", - "minLength": 1, - "maxLength": 500, - "pattern": "\\S" - }, - "category": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "status": { - "enum": [ - "Draft", - "Proposal", - "Reuse assessment" - ] - }, - "version": { - "anyOf": [ - { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - { - "type": "null" - } - ] - }, - "profile": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "overview": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "target": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "operations": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "id", - "name", - "description" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "inputs": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "results": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "permissions": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "humanRoute": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "example": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "steps": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 1, - "maxItems": 100 - }, - "exception": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "title", - "steps", - "exception" - ] - }, - "references": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "title": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - } - }, - "required": [ - "title", - "href", - "description" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "openQuestions": { - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "minItems": 0, - "maxItems": 100 - }, - "maintainers": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": [ - "name" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "definition": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "href": { - "type": "string", - "pattern": "^/specification/(?:[a-z0-9-]+/)*$", - "maxLength": 300 - } - }, - "required": [ - "label", - "href" - ] - }, - "origin": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "contributors": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "url": { - "type": "string", - "format": "uri", - "pattern": "^https://", - "maxLength": 2048 - } - }, - "required": [ - "name" - ] - }, - "minItems": 1, - "maxItems": 100 - }, - "history": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": { - "type": "string", - "minLength": 1, - "maxLength": 240, - "pattern": "\\S" - }, - "description": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "\\S" - }, - "contributionId": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - } - }, - "required": [ - "label", - "description" - ] - }, - "minItems": 1, - "maxItems": 100 - } - }, - "required": [ - "slug", - "name", - "summary", - "category", - "status", - "version", - "profile", - "overview", - "target", - "operations", - "inputs", - "results", - "permissions", - "humanRoute", - "example", - "references", - "openQuestions", - "maintainers", - "origin", - "contributors", - "history" - ], - "allOf": [ - { - "if": { - "properties": { - "status": { - "const": "Draft" - } - }, - "required": [ - "status" - ] - }, - "then": { - "required": [ - "definition" - ], - "properties": { - "version": { - "type": "string" - } - } - } - } - ] - } - }, - "$ref": "#/$defs/record" -} diff --git a/schemas/type-contract-0.2.schema.json b/schemas/type-contract-0.2.schema.json deleted file mode 100644 index 1fe14b2..0000000 --- a/schemas/type-contract-0.2.schema.json +++ /dev/null @@ -1,179 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://mailschema.org/schemas/type-contract-0.2.schema.json", - "title": "MailSchema type contract for MAP 0.2", - "description": "A versioned interaction contract: the details, inputs, results, authority, repeatability and consequences of each operation, with every schema it depends on pinned by digest.", - "type": "object", - "additionalProperties": false, - "properties": { - "kind": { - "const": "MapTypeContract" - }, - "id": { - "type": "string", - "pattern": "^https://mailschema\\.org/types/[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 2048 - }, - "version": { - "type": "string", - "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[a-zA-Z0-9.-]+)?$", - "maxLength": 80 - }, - "profile": { - "const": "https://mailschema.org/profiles/map/0.2" - }, - "target": { - "$ref": "#/$defs/prose" - }, - "dependencies": { - "type": "array", - "minItems": 1, - "maxItems": 20, - "items": { - "$ref": "#/$defs/schemaReference" - } - }, - "detailsSchema": { - "type": "object" - }, - "requestSchema": { - "$ref": "#/$defs/schemaReference" - }, - "operations": { - "type": "array", - "minItems": 1, - "maxItems": 100, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "id": { - "$ref": "#/$defs/token" - }, - "effect": { - "$ref": "#/$defs/prose" - }, - "authority": { - "type": "array", - "items": { - "enum": ["credential", "possession"] - }, - "minItems": 1, - "maxItems": 2, - "uniqueItems": true - }, - "consequences": { - "type": "array", - "items": { - "enum": [ - "refusal", - "protection", - "record", - "disclosure", - "commitment", - "authorization", - "assertion" - ] - }, - "minItems": 1, - "maxItems": 7, - "uniqueItems": true - }, - "repeatable": { - "type": "boolean" - }, - "fieldBindings": { - "type": "array", - "minItems": 1, - "maxItems": 10, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "input": { - "$ref": "#/$defs/pointer" - }, - "fields": { - "$ref": "#/$defs/pointer" - } - }, - "required": ["input", "fields"] - } - }, - "results": { - "type": "array", - "minItems": 1, - "maxItems": 5, - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "state": { - "enum": ["accepted", "completed", "failed", "pending", "approval-required"] - }, - "reasons": { - "type": "array", - "items": { - "$ref": "#/$defs/token" - }, - "minItems": 1, - "maxItems": 20, - "uniqueItems": true - }, - "outputSchema": { - "type": "object" - } - }, - "required": ["state", "outputSchema"] - } - } - }, - "required": ["id", "effect", "authority", "consequences", "results"] - } - } - }, - "required": [ - "kind", - "id", - "version", - "profile", - "target", - "dependencies", - "requestSchema", - "operations" - ], - "$defs": { - "prose": { - "type": "string", - "minLength": 1, - "maxLength": 12000, - "pattern": "[^\\t\\n\\u000b\\f\\r \\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]" - }, - "token": { - "type": "string", - "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$", - "maxLength": 100 - }, - "pointer": { - "type": "string", - "pattern": "^(?:/(?:[^~/]|~[01])*)+$", - "maxLength": 1000 - }, - "schemaReference": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "pattern": "^https://mailschema\\.org/schemas/[a-z0-9.-]+\\.json$", - "maxLength": 2048 - }, - "canonicalDigest": { - "type": "string", - "pattern": "^sha-256:[a-f0-9]{64}$" - } - }, - "required": ["url", "canonicalDigest"] - } - } -} diff --git a/src/lib.rs b/src/lib.rs index ce9707c..9843978 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,78 +1,47 @@ -//! The Mail Action Protocol 0.2 core artifacts and the MailSchema Registry schemas. -//! -//! The MAP 0.2 core schema, JSON-LD context, type contract format and form fields -//! block are embedded exactly as the profile record binds them by SHA-256. Type -//! contracts are not bundled: clients obtain them from the Registry catalogue by -//! digest. The Registry schemas describe contribution files and expanded type -//! records; pass them to a JSON Schema validator with format checking enabled. +//! The Mail Action Protocol 0.3 artifacts, byte for byte as mailschema.org publishes them: the +//! profile record, the JSON-LD context, and the core, type contract and implementation record +//! schemas. The profile record binds the context and the first two schemas by SHA-256. //! Nothing here needs filesystem or network access. -/// The MAP profile whose core artifacts this crate carries. -pub const MAP_PROFILE: &str = "https://mailschema.org/profiles/map/0.2"; +/// The MAP profile these artifacts define. +pub const PROFILE: &str = "https://mailschema.org/profiles/map/0.3"; -/// The MAP 0.2 core schema: descriptions, requests, results and problems. -pub const MAP_SCHEMA: &str = include_str!("../schemas/map-0.2.schema.json"); +/// The JSON-LD context every MAP 0.3 description names. +pub const CONTEXT: &str = "https://mailschema.org/contexts/map-0.3.jsonld"; -/// The MAP 0.2 JSON-LD context. -pub const MAP_CONTEXT: &str = include_str!("../contexts/map-0.2.jsonld"); +/// The profile record. +pub const PROFILE_RECORD: &str = include_str!("../artifacts/profile.json"); -/// The type contract format every MAP 0.2 contract follows. -pub const CONTRACT_FORMAT_SCHEMA: &str = include_str!("../schemas/type-contract-0.2.schema.json"); +/// The JSON-LD context document. +pub const CONTEXT_DOCUMENT: &str = include_str!("../artifacts/context.jsonld"); -/// The form fields block contracts pin. -pub const FORMS_SCHEMA: &str = include_str!("../schemas/forms-0.1.schema.json"); +/// The schema of a MAP 0.3 description. +pub const CORE_SCHEMA: &str = include_str!("../artifacts/core.schema.json"); -/// Schema for new types, amendments and implementation declarations. -pub const CONTRIBUTION_SCHEMA: &str = include_str!("../schemas/contribution.schema.json"); +/// The schema every type contract follows. +pub const CONTRACT_SCHEMA: &str = include_str!("../artifacts/contract.schema.json"); -/// Schema for expanded Registry records, including attribution and history. -pub const RECORD_SCHEMA: &str = include_str!("../schemas/record.schema.json"); - -/// The embedded JSON Schema documents. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Schema { - Map, - ContractFormat, - Forms, - Contribution, - Record, -} - -impl Schema { - /// Return the embedded JSON text for this schema. - pub const fn as_str(self) -> &'static str { - match self { - Self::Map => MAP_SCHEMA, - Self::ContractFormat => CONTRACT_FORMAT_SCHEMA, - Self::Forms => FORMS_SCHEMA, - Self::Contribution => CONTRIBUTION_SCHEMA, - Self::Record => RECORD_SCHEMA, - } - } -} +/// The schema of a Registry implementation record. +pub const IMPLEMENTATION_SCHEMA: &str = include_str!("../artifacts/implementation.schema.json"); #[cfg(test)] mod tests { use super::*; + use sha2::{Digest, Sha256}; #[test] - fn embeds_standalone_draft_2020_12_documents() { - for schema in [ - Schema::Map, - Schema::ContractFormat, - Schema::Forms, - Schema::Contribution, - Schema::Record, + fn profile_record_binds_the_bundled_bytes() { + let record: serde_json::Value = serde_json::from_str(PROFILE_RECORD).unwrap(); + assert_eq!(record["id"], PROFILE); + assert_eq!(record["context"], CONTEXT); + for (key, bytes) in [ + ("context", CONTEXT_DOCUMENT), + ("schema", CORE_SCHEMA), + ("contractFormat", CONTRACT_SCHEMA), ] { - let value: serde_json::Value = serde_json::from_str(schema.as_str()).unwrap(); - assert_eq!(value["$schema"], "https://json-schema.org/draft/2020-12/schema"); + let digest = format!("{:x}", Sha256::digest(bytes.as_bytes())); + assert_eq!(record["artifacts"][key]["sha256"], digest, "{key}"); } - let map: serde_json::Value = serde_json::from_str(MAP_SCHEMA).unwrap(); - assert_eq!(map["$id"], "https://mailschema.org/schemas/map-0.2.schema.json"); - let context: serde_json::Value = serde_json::from_str(MAP_CONTEXT).unwrap(); - assert_eq!(context["@context"]["MailAction"], "map:MailAction"); - let record: serde_json::Value = serde_json::from_str(RECORD_SCHEMA).unwrap(); - assert_eq!(record["$ref"], "#/$defs/record"); - assert_eq!(MAP_PROFILE, "https://mailschema.org/profiles/map/0.2"); + serde_json::from_str::(IMPLEMENTATION_SCHEMA).unwrap(); } }