mailschema 0.1.0 → 0.1.2

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 CHANGED
@@ -1,31 +1,65 @@
1
- # MailSchema
1
+ # MailSchema for JavaScript
2
2
 
3
- JSON Schemas, TypeScript definitions and validation tools for the MailSchema Registry.
3
+ [![npm](https://img.shields.io/npm/v/mailschema)](https://www.npmjs.com/package/mailschema)
4
+ [![CI](https://github.com/mailschema/javascript/actions/workflows/test.yml/badge.svg)](https://github.com/mailschema/javascript/actions/workflows/test.yml)
4
5
 
5
- Prepare a new interaction type, amend an existing definition, or declare an implementation's supported operations. This package checks the Registry contribution format. It does not implement email delivery, authorization or the draft Mail Action Protocol wire format.
6
+ Validate Mail Action Protocol documents and MailSchema Registry contributions without making a network request.
7
+
8
+ [Specification](https://mailschema.org/specification/) · [Registry](https://mailschema.org/registry/) · [Tools](https://mailschema.org/tools/) · [Source](https://github.com/mailschema/javascript)
9
+
10
+ ## Install
6
11
 
7
12
  ```sh
8
13
  npm install mailschema
9
- npx mailschema check contribution.json
10
- npx mailschema schema > contribution.schema.json
11
14
  ```
12
15
 
13
- Node.js 22 or newer. The JavaScript API is ESM; the CLI reads a local JSON file of at most 256 KiB and does not upload or modify it.
16
+ Node.js 22 or newer is required. The package is ESM and includes TypeScript declarations.
17
+
18
+ ## Validate MAP documents
19
+
20
+ ```js
21
+ import { assertMapDocument, assertContentReviewRequest, getMapSchema } from 'mailschema';
22
+
23
+ assertMapDocument(description);
24
+ assertContentReviewRequest(request);
25
+ const mapSchema = getMapSchema();
26
+ ```
27
+
28
+ The CLI performs the same checks against local JSON files:
29
+
30
+ ```sh
31
+ npx mailschema check description.json --map
32
+ npx mailschema check request.json --content-review
33
+ ```
34
+
35
+ ## Work with Registry data
14
36
 
15
37
  ```js
16
- import { assertContribution, contributionErrors, getContributionSchema } from 'mailschema';
38
+ import {
39
+ assertContribution,
40
+ contributionErrors,
41
+ getContributionSchema,
42
+ referenceErrors,
43
+ } from 'mailschema';
17
44
 
18
45
  const errors = contributionErrors(candidate);
19
46
  if (errors.length) console.error(errors);
20
47
  else assertContribution(candidate);
21
48
 
22
- const schema = getContributionSchema(); // Independent copy, JSON Schema Draft 2020-12.
49
+ const schema = getContributionSchema();
50
+ const referenceProblems = referenceErrors(candidate, catalog);
23
51
  ```
24
52
 
25
- Use `assertTypeRecord(value)` or `mailschema check record.json --record` for expanded Registry records. `getRecordSchema()` returns the equivalent schema. The raw contribution schema is also exported as `mailschema/contribution.schema.json`.
53
+ `assertTypeRecord`, `getRecordSchema` and `mailschema check record.json --record` handle expanded Registry records. Reference checks use a catalogue supplied by the caller; the package never fetches one automatically.
54
+
55
+ Raw Draft 2020-12 schemas are exported as:
56
+
57
+ - `mailschema/map-0.1.schema.json`
58
+ - `mailschema/content-review-0.1.schema.json`
59
+ - `mailschema/contribution.schema.json`
26
60
 
27
- For a structurally valid contribution, `referenceErrors(contribution, catalog)` checks references against a supplied catalogue: current amendment bases, existing type names, exact implementation records, versions, profiles and operations. The catalogue contains `types` and `snapshots` arrays of `{ record, digest }` entries. It is never fetched automatically.
61
+ ## Trust boundary
28
62
 
29
- `Contribution`, `TypeRecord`, `TypeDefinition`, `Implementation`, `Party` and `CatalogView` are exported TypeScript types. Successful validation does not verify a contributor's identity, establish product compatibility or accept a submission. Full repository review also checks competing amendments and contribution identifiers.
63
+ A valid document is structured input. Validation does not authenticate a service, grant authority, approve an action or establish product conformance. Implementations must apply their own endpoint trust, credentials, permissions and policy before executing a request.
30
64
 
31
- Package version `0.1.0` is independent of any specification version. MIT licensed.
65
+ The CLI reads one local file of at most 256 KiB and does not upload or modify it. Package versions and MAP profile versions advance independently. MIT licensed.
@@ -3,15 +3,19 @@ import { open } from 'node:fs/promises';
3
3
  import { parseArgs } from 'node:util';
4
4
  import {
5
5
  assertContribution,
6
+ assertContentReviewRequest,
7
+ assertMapDocument,
6
8
  assertTypeRecord,
9
+ getContentReviewSchema,
7
10
  getContributionSchema,
11
+ getMapSchema,
8
12
  getRecordSchema,
9
- } from './dist/index.js';
13
+ } from '../dist/index.js';
10
14
 
11
15
  const help = `MailSchema contribution tools
12
16
 
13
- mailschema check <file.json> [--record]
14
- mailschema schema [--record]
17
+ mailschema check <file.json> [--record | --map | --content-review]
18
+ mailschema schema [--record | --map | --content-review]
15
19
 
16
20
  Checks JSON structure and required fields locally. Registry references and
17
21
  editorial acceptance are separate checks. No files are uploaded or changed.`;
@@ -19,13 +23,37 @@ editorial acceptance are separate checks. No files are uploaded or changed.`;
19
23
  try {
20
24
  const { values, positionals } = parseArgs({
21
25
  allowPositionals: true,
22
- options: { record: { type: 'boolean' }, help: { type: 'boolean', short: 'h' } },
26
+ options: {
27
+ record: { type: 'boolean' },
28
+ map: { type: 'boolean' },
29
+ 'content-review': { type: 'boolean' },
30
+ help: { type: 'boolean', short: 'h' },
31
+ },
23
32
  });
24
33
  const [command, path, ...extra] = positionals;
34
+ const formats = [values.record, values.map, values['content-review']].filter(Boolean);
35
+ if (formats.length > 1) throw new Error('Choose only one document format.');
36
+ const selected = values['content-review']
37
+ ? 'Content Review request'
38
+ : values.map
39
+ ? 'MAP document'
40
+ : values.record
41
+ ? 'type record'
42
+ : 'contribution';
25
43
  if (values.help || !command) console.log(help);
26
44
  else if (command === 'schema' && !path && !extra.length)
27
45
  console.log(
28
- JSON.stringify(values.record ? getRecordSchema() : getContributionSchema(), null, 2),
46
+ JSON.stringify(
47
+ values['content-review']
48
+ ? getContentReviewSchema()
49
+ : values.map
50
+ ? getMapSchema()
51
+ : values.record
52
+ ? getRecordSchema()
53
+ : getContributionSchema(),
54
+ null,
55
+ 2,
56
+ ),
29
57
  );
30
58
  else if (command === 'check' && path && !extra.length) {
31
59
  const file = await open(path, 'r');
@@ -41,11 +69,11 @@ try {
41
69
  } finally {
42
70
  await file.close();
43
71
  }
44
- if (values.record) assertTypeRecord(value);
72
+ if (values['content-review']) assertContentReviewRequest(value);
73
+ else if (values.map) assertMapDocument(value);
74
+ else if (values.record) assertTypeRecord(value);
45
75
  else assertContribution(value);
46
- console.log(
47
- 'Valid MailSchema ' + (values.record ? 'type record' : 'contribution') + ' structure.',
48
- );
76
+ console.log(`Valid MailSchema ${selected}.`);
49
77
  } else throw new Error(help);
50
78
  } catch (error) {
51
79
  console.error(error instanceof Error ? error.message : String(error));
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mailschema.org/schemas/content-review-0.1.schema.json",
4
+ "title": "Content Review 0.1 MAP request",
5
+ "allOf": [
6
+ { "$ref": "https://mailschema.org/schemas/map-0.1.schema.json#/$defs/request" },
7
+ {
8
+ "type": "object",
9
+ "properties": {
10
+ "type": {
11
+ "type": "object",
12
+ "properties": {
13
+ "id": { "const": "https://mailschema.org/types/content-review" },
14
+ "version": { "const": "0.1" },
15
+ "recordDigest": {
16
+ "const": "sha-256:0e6365df1bf904f2475f972ec66a5561edc0bfaae69fd7a1b41f53b40bf8ac1c"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ },
22
+ {
23
+ "oneOf": [
24
+ {
25
+ "type": "object",
26
+ "properties": {
27
+ "operation": { "const": "request-changes" },
28
+ "input": {
29
+ "type": "object",
30
+ "additionalProperties": false,
31
+ "properties": {
32
+ "feedback": { "type": "string", "minLength": 1, "maxLength": 12000 }
33
+ },
34
+ "required": ["feedback"]
35
+ }
36
+ }
37
+ },
38
+ {
39
+ "type": "object",
40
+ "properties": {
41
+ "operation": { "const": "approve" },
42
+ "input": {
43
+ "type": "object",
44
+ "additionalProperties": false,
45
+ "maxProperties": 0
46
+ }
47
+ }
48
+ }
49
+ ]
50
+ }
51
+ ]
52
+ }