@stroc/core 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +19 -2
- package/dist/src/dagjson.d.ts +27 -0
- package/dist/src/dagjson.d.ts.map +1 -0
- package/dist/src/dagjson.js +123 -0
- package/dist/src/dagjson.js.map +1 -0
- package/dist/src/hash.d.ts +5 -0
- package/dist/src/hash.d.ts.map +1 -0
- package/dist/src/hash.js +40 -0
- package/dist/src/hash.js.map +1 -0
- package/dist/src/ids.d.ts +6 -0
- package/dist/src/ids.d.ts.map +1 -0
- package/dist/src/ids.js +30 -0
- package/dist/src/ids.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/language.d.ts +3 -0
- package/dist/src/language.d.ts.map +1 -0
- package/dist/src/language.js +32 -0
- package/dist/src/language.js.map +1 -0
- package/dist/src/markup.d.ts +40 -0
- package/dist/src/markup.d.ts.map +1 -0
- package/dist/src/markup.js +275 -0
- package/dist/src/markup.js.map +1 -0
- package/dist/src/text.d.ts +10 -0
- package/dist/src/text.d.ts.map +1 -0
- package/dist/src/text.js +83 -0
- package/dist/src/text.js.map +1 -0
- package/dist/src/types.d.ts +37 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +4 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/validate.d.ts +18 -0
- package/dist/src/validate.d.ts.map +1 -0
- package/dist/src/validate.js +292 -0
- package/dist/src/validate.js.map +1 -0
- package/package.json +58 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2026 Got Choices Foundation
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @stroc/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Types, validation, canonical encoding and CIDs for Stroc documents. No Node or DOM APIs: runs in
|
|
4
|
+
browsers, Node and React Native.
|
|
5
|
+
|
|
6
|
+
```js
|
|
7
|
+
import { validateDocument, documentCid, verifyDocument } from '@stroc/core'
|
|
8
|
+
|
|
9
|
+
const { valid, problems } = validateDocument(doc)
|
|
10
|
+
const { cid, bytes } = await documentCid(doc) // DAG-JSON, SHA-256, CIDv1
|
|
11
|
+
const check = await verifyDocument(receivedBytes, cid) // hashes the bytes as received
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
SHA-256 is pure JavaScript by default; an app may install a native one with `setSha256` (checked
|
|
15
|
+
against known digests first).
|
|
16
|
+
|
|
17
|
+
Part of [Stroc](https://github.com/gotchoices/stroc), a format for structured legal documents
|
|
18
|
+
identified by content (IPLD CIDs). The format is specified in
|
|
19
|
+
[docs/Specification.md](https://github.com/gotchoices/stroc/blob/main/docs/Specification.md).
|
|
20
|
+
MIT license.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import type { Problem, StrocDocument } from './types.js';
|
|
3
|
+
import { type ValidationResult } from './validate.js';
|
|
4
|
+
export declare const DAG_JSON_CODE: 297;
|
|
5
|
+
export declare function encodeDagJson(value: unknown): Uint8Array;
|
|
6
|
+
export declare function computeCid(bytes: Uint8Array): Promise<CID>;
|
|
7
|
+
export declare function cidOfValue(value: unknown): Promise<CID>;
|
|
8
|
+
export interface DocumentCidResult {
|
|
9
|
+
cid?: CID;
|
|
10
|
+
bytes?: Uint8Array;
|
|
11
|
+
validation: ValidationResult;
|
|
12
|
+
}
|
|
13
|
+
export declare function documentCid(doc: unknown): Promise<DocumentCidResult>;
|
|
14
|
+
export interface VerifyResult {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
document?: StrocDocument;
|
|
17
|
+
problems: Problem[];
|
|
18
|
+
validation?: ValidationResult;
|
|
19
|
+
}
|
|
20
|
+
export declare function verifyDocument(bytes: Uint8Array, claimed: CID | string): Promise<VerifyResult>;
|
|
21
|
+
export declare function decodeDagJson(bytes: Uint8Array): unknown;
|
|
22
|
+
export declare function fromPlain(value: unknown): {
|
|
23
|
+
value: unknown;
|
|
24
|
+
problems: Problem[];
|
|
25
|
+
};
|
|
26
|
+
export declare function toPlain(value: unknown): unknown;
|
|
27
|
+
//# sourceMappingURL=dagjson.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagjson.d.ts","sourceRoot":"","sources":["../../src/dagjson.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAGtC,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EAAuC,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE1F,eAAO,MAAM,aAAa,KAAe,CAAA;AAGzC,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAExD;AAGD,wBAAsB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAEhE;AAGD,wBAAsB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAE7D;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAID,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAK1E;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAA;IACX,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAID,wBAAsB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA4BpG;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAExD;AAUD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CA0BjF;AAGD,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAU/C"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Canonical encoding, CIDs and verification (Specification: Content ID Generation, Verification)
|
|
2
|
+
import { CID } from 'multiformats/cid';
|
|
3
|
+
import { sha256 } from './hash.js';
|
|
4
|
+
import * as dagJson from '@ipld/dag-json';
|
|
5
|
+
import { validateDocument, checkDocumentLink } from './validate.js';
|
|
6
|
+
export const DAG_JSON_CODE = dagJson.code;
|
|
7
|
+
// Canonical DAG-JSON bytes of any value in the data model. Does not validate.
|
|
8
|
+
export function encodeDagJson(value) {
|
|
9
|
+
return dagJson.encode(value);
|
|
10
|
+
}
|
|
11
|
+
// The CID of some bytes, as a DAG-JSON block.
|
|
12
|
+
export async function computeCid(bytes) {
|
|
13
|
+
return CID.create(1, dagJson.code, await sha256.digest(bytes));
|
|
14
|
+
}
|
|
15
|
+
// The CID of any value (for example an app's data object), encoded as DAG-JSON. Does not validate.
|
|
16
|
+
export async function cidOfValue(value) {
|
|
17
|
+
return computeCid(encodeDagJson(value));
|
|
18
|
+
}
|
|
19
|
+
// Validate a document and, if valid, encode it and compute its CID. Nothing is altered first:
|
|
20
|
+
// a document that is not already canonical is reported, not fixed.
|
|
21
|
+
export async function documentCid(doc) {
|
|
22
|
+
const validation = validateDocument(doc);
|
|
23
|
+
if (!validation.valid)
|
|
24
|
+
return { validation };
|
|
25
|
+
const bytes = encodeDagJson(doc);
|
|
26
|
+
return { cid: await computeCid(bytes), bytes, validation };
|
|
27
|
+
}
|
|
28
|
+
// Verify received bytes against a claimed CID: hash exactly what was received, require canonical
|
|
29
|
+
// DAG-JSON, then validate. Never normalizes.
|
|
30
|
+
export async function verifyDocument(bytes, claimed) {
|
|
31
|
+
const fail = (code, message) => ({ ok: false, problems: [{ path: [], code, message }] });
|
|
32
|
+
let cid;
|
|
33
|
+
try {
|
|
34
|
+
cid = typeof claimed === 'string' ? CID.parse(claimed) : claimed;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return fail('bad-cid', `"${String(claimed)}" is not a CID`);
|
|
38
|
+
}
|
|
39
|
+
const linkError = checkDocumentLink(cid);
|
|
40
|
+
if (linkError)
|
|
41
|
+
return fail('bad-cid', `the claimed CID ${linkError}`);
|
|
42
|
+
const actual = await computeCid(bytes);
|
|
43
|
+
if (!actual.equals(cid))
|
|
44
|
+
return fail('cid-mismatch', `content hashes to ${actual}, not ${cid}`);
|
|
45
|
+
let value;
|
|
46
|
+
try {
|
|
47
|
+
value = dagJson.decode(bytes);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return fail('bad-encoding', `not valid DAG-JSON: ${err.message}`);
|
|
51
|
+
}
|
|
52
|
+
const reencoded = dagJson.encode(value);
|
|
53
|
+
if (!sameBytes(reencoded, bytes))
|
|
54
|
+
return fail('not-canonical', 'not canonical DAG-JSON (key order, spacing or number form differs)');
|
|
55
|
+
const validation = validateDocument(value);
|
|
56
|
+
return {
|
|
57
|
+
ok: validation.valid,
|
|
58
|
+
document: validation.valid ? value : undefined,
|
|
59
|
+
problems: validation.problems,
|
|
60
|
+
validation,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function decodeDagJson(bytes) {
|
|
64
|
+
return dagJson.decode(bytes);
|
|
65
|
+
}
|
|
66
|
+
function sameBytes(a, b) {
|
|
67
|
+
if (a.length !== b.length)
|
|
68
|
+
return false;
|
|
69
|
+
for (let i = 0; i < a.length; i++)
|
|
70
|
+
if (a[i] !== b[i])
|
|
71
|
+
return false;
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
// Convert a plain value parsed from JSON or YAML into the data model: every {"/": "<cid>"} becomes
|
|
75
|
+
// a link. Malformed link objects are reported and left as they are (validation will reject them).
|
|
76
|
+
export function fromPlain(value) {
|
|
77
|
+
const problems = [];
|
|
78
|
+
const walk = (v, at) => {
|
|
79
|
+
if (Array.isArray(v))
|
|
80
|
+
return v.map((x, i) => walk(x, [...at, i]));
|
|
81
|
+
if (typeof v === 'object' && v !== null && !CID.asCID(v)) {
|
|
82
|
+
const obj = v;
|
|
83
|
+
if ('/' in obj) {
|
|
84
|
+
if (Object.keys(obj).length === 1 && typeof obj['/'] === 'string') {
|
|
85
|
+
try {
|
|
86
|
+
return CID.parse(obj['/']);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
const linkText = obj['/'];
|
|
90
|
+
problems.push({ path: at, code: 'bad-link', message: /\.(ya?ml|json)$/i.test(linkText)
|
|
91
|
+
? `"${linkText}" is a file, not a CID: run \`stroc link\` to replace it with that file's CID`
|
|
92
|
+
: `"${linkText}" is not a CID` });
|
|
93
|
+
return v;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
problems.push({ path: at, code: 'bad-link', message: 'a link must be written {"/": "<cid>"} with no other keys' });
|
|
97
|
+
return v;
|
|
98
|
+
}
|
|
99
|
+
const out = {};
|
|
100
|
+
for (const [k, x] of Object.entries(obj))
|
|
101
|
+
out[k] = walk(x, [...at, k]);
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
return v;
|
|
105
|
+
};
|
|
106
|
+
return { value: walk(value, []), problems };
|
|
107
|
+
}
|
|
108
|
+
// Convert from the data model to plain JSON/YAML values: every link becomes {"/": "<cid>"}.
|
|
109
|
+
export function toPlain(value) {
|
|
110
|
+
const cid = CID.asCID(value);
|
|
111
|
+
if (cid)
|
|
112
|
+
return { '/': cid.toString() };
|
|
113
|
+
if (Array.isArray(value))
|
|
114
|
+
return value.map(toPlain);
|
|
115
|
+
if (typeof value === 'object' && value !== null) {
|
|
116
|
+
const out = {};
|
|
117
|
+
for (const [k, x] of Object.entries(value))
|
|
118
|
+
out[k] = toPlain(x);
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=dagjson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagjson.js","sourceRoot":"","sources":["../../src/dagjson.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type Sha256 = (bytes: Uint8Array) => Uint8Array | Promise<Uint8Array>;
|
|
2
|
+
export declare const sha256: import("multiformats/hashes/hasher").Hasher<"sha2-256", 18>;
|
|
3
|
+
export declare function setSha256(fn: Sha256): Promise<void>;
|
|
4
|
+
export declare function resetSha256(): void;
|
|
5
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/hash.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AAI5E,eAAO,MAAM,MAAM,6DAAwF,CAAA;AAe3G,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASzD;AAGD,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/dist/src/hash.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// SHA-256 for CIDs. The default is pure JavaScript (@noble/hashes), so hashing works the same in
|
|
2
|
+
// browsers, Node and React Native (Hermes has no WebCrypto). An app may supply its own
|
|
3
|
+
// implementation (for example a native module on a phone) with setSha256; it is checked against
|
|
4
|
+
// known digests first, because a wrong implementation would silently produce wrong CIDs.
|
|
5
|
+
import { from } from 'multiformats/hashes/hasher';
|
|
6
|
+
import { sha256 as nobleSha256 } from '@noble/hashes/sha2.js';
|
|
7
|
+
let current = nobleSha256;
|
|
8
|
+
export const sha256 = from({ name: 'sha2-256', code: 0x12, encode: (input) => current(input) });
|
|
9
|
+
const ascii = (s) => Uint8Array.from(s, c => c.charCodeAt(0));
|
|
10
|
+
const hex = (b) => Array.from(b, x => x.toString(16).padStart(2, '0')).join('');
|
|
11
|
+
// FIPS 180-2 test vectors, and a large input checked against the built-in implementation (which
|
|
12
|
+
// exercises block handling the short vectors do not).
|
|
13
|
+
const VECTORS = [
|
|
14
|
+
[ascii(''), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'],
|
|
15
|
+
[ascii('abc'), 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'],
|
|
16
|
+
[ascii('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'), '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'],
|
|
17
|
+
];
|
|
18
|
+
// Use a different SHA-256 implementation from now on. Rejects (and keeps the current one) if it
|
|
19
|
+
// does not produce correct digests.
|
|
20
|
+
export async function setSha256(fn) {
|
|
21
|
+
const big = Uint8Array.from({ length: 1000003 }, (_, i) => (i * 31 + 7) & 255);
|
|
22
|
+
const cases = [...VECTORS, [big, hex(nobleSha256(big))]];
|
|
23
|
+
for (const [input, expected] of cases) {
|
|
24
|
+
let got;
|
|
25
|
+
try {
|
|
26
|
+
got = hex(await fn(input));
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new Error(`SHA-256 implementation failed its self-test: ${err.message}`);
|
|
30
|
+
}
|
|
31
|
+
if (got !== expected)
|
|
32
|
+
throw new Error(`SHA-256 implementation failed its self-test (input of ${input.length} bytes)`);
|
|
33
|
+
}
|
|
34
|
+
current = fn;
|
|
35
|
+
}
|
|
36
|
+
// Go back to the built-in pure-JavaScript implementation.
|
|
37
|
+
export function resetSha256() {
|
|
38
|
+
current = nobleSha256;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/hash.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,uFAAuF;AACvF,gGAAgG;AAChG,yFAAyF;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAI7D,IAAI,OAAO,GAAW,WAAW,CAAA;AAEjC,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,KAAiB,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AAE3G,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;AACrE,MAAM,GAAG,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAE3F,gGAAgG;AAChG,sDAAsD;AACtD,MAAM,OAAO,GAA2B;IACtC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,kEAAkE,CAAC;IAC/E,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,kEAAkE,CAAC;IAClF,CAAC,KAAK,CAAC,0DAA0D,CAAC,EAAE,kEAAkE,CAAC;CACxI,CAAA;AAED,gGAAgG;AAChG,oCAAoC;AACpC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAU;IACxC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAS,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;IAChF,MAAM,KAAK,GAA2B,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAChF,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;QACtC,IAAI,GAAW,CAAA;QACf,IAAI,CAAC;YAAC,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;QAAC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YAAC,MAAM,IAAI,KAAK,CAAC,gDAAiD,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QAAC,CAAC;QAC5I,IAAI,GAAG,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,KAAK,CAAC,MAAM,SAAS,CAAC,CAAA;IACvH,CAAC;IACD,OAAO,GAAG,EAAE,CAAA;AACd,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,WAAW;IACzB,OAAO,GAAG,WAAW,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const MAX_ID_LENGTH = 64;
|
|
2
|
+
export declare function isValidId(value: string): boolean;
|
|
3
|
+
export declare function suggestId(title: string): string;
|
|
4
|
+
export declare function isDomain(value: string): boolean;
|
|
5
|
+
export declare function looksLikeDomain(value: string): boolean;
|
|
6
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/ids.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhD;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW/C;AAMD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/C;AAGD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
package/dist/src/ids.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Section ids and parameter keys (Specification: Section Ids)
|
|
2
|
+
const ID_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
3
|
+
export const MAX_ID_LENGTH = 64;
|
|
4
|
+
export function isValidId(value) {
|
|
5
|
+
return value.length <= MAX_ID_LENGTH && ID_PATTERN.test(value);
|
|
6
|
+
}
|
|
7
|
+
// Propose an id from a title: "Cure of Default" -> "cure-of-default".
|
|
8
|
+
export function suggestId(title) {
|
|
9
|
+
const base = title
|
|
10
|
+
.normalize('NFKD')
|
|
11
|
+
.replace(/[̀-ͯ]/g, '')
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
14
|
+
.replace(/^-+|-+$/g, '')
|
|
15
|
+
.replace(/^[0-9-]+/, '')
|
|
16
|
+
.slice(0, MAX_ID_LENGTH)
|
|
17
|
+
.replace(/-+$/, '');
|
|
18
|
+
return base || 'section';
|
|
19
|
+
}
|
|
20
|
+
// A domain `author` (Specification: Author): lowercase ASCII labels separated by dots, at least
|
|
21
|
+
// one dot, the last label alphabetic or an IDNA (xn--) label.
|
|
22
|
+
const DOMAIN_PATTERN = /^(?=.{4,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+([a-z]{2,63}|xn--[a-z0-9-]{1,59})$/;
|
|
23
|
+
export function isDomain(value) {
|
|
24
|
+
return DOMAIN_PATTERN.test(value);
|
|
25
|
+
}
|
|
26
|
+
// True when the value would be a domain if written in lowercase (for lint advice).
|
|
27
|
+
export function looksLikeDomain(value) {
|
|
28
|
+
return !isDomain(value) && isDomain(value.toLowerCase());
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/ids.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAE9D,MAAM,UAAU,GAAG,+BAA+B,CAAA;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AAE/B,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,KAAK,CAAC,MAAM,IAAI,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAChE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,KAAK;SACf,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACrB,OAAO,IAAI,IAAI,SAAS,CAAA;AAC1B,CAAC;AAED,gGAAgG;AAChG,8DAA8D;AAC9D,MAAM,cAAc,GAAG,yFAAyF,CAAA;AAEhH,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACnC,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './text.js';
|
|
3
|
+
export * from './ids.js';
|
|
4
|
+
export * from './language.js';
|
|
5
|
+
export * from './markup.js';
|
|
6
|
+
export * from './validate.js';
|
|
7
|
+
export * from './dagjson.js';
|
|
8
|
+
export { setSha256, resetSha256, type Sha256 } from './hash.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './text.js';
|
|
3
|
+
export * from './ids.js';
|
|
4
|
+
export * from './language.js';
|
|
5
|
+
export * from './markup.js';
|
|
6
|
+
export * from './validate.js';
|
|
7
|
+
export * from './dagjson.js';
|
|
8
|
+
export { setSha256, resetSha256 } from './hash.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,WAAW,EAAe,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/language.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE3D;AAGD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYpE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// BCP 47 language tags in canonical case (Specification: Field Definitions)
|
|
2
|
+
//
|
|
3
|
+
// Checks well-formedness of the common subset: language, extended language, script, region,
|
|
4
|
+
// variants, extensions and private use. The primary language must be 2-3 letters; longer ones
|
|
5
|
+
// are grammatical but unregistered, and usually a mistake such as "english". Canonical case:
|
|
6
|
+
// language lowercase, script title case, region uppercase, everything else lowercase.
|
|
7
|
+
const SUBTAG_RULES = /^([a-z]{2,3}(-[a-z]{3}){0,3})(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?(-([a-z0-9]{5,8}|[0-9][a-z0-9]{3}))*(-[a-wy-z0-9](-[a-z0-9]{2,8})+)*(-x(-[a-z0-9]{1,8})+)?$/;
|
|
8
|
+
export function isCanonicalLanguageTag(tag) {
|
|
9
|
+
return SUBTAG_RULES.test(tag);
|
|
10
|
+
}
|
|
11
|
+
// The canonical-case spelling of a tag, or undefined if it is not well formed in any case.
|
|
12
|
+
export function canonicalLanguageTag(tag) {
|
|
13
|
+
const parts = tag.split(/[-_]/);
|
|
14
|
+
let seenSingleton = false;
|
|
15
|
+
const fixed = parts.map((p, i) => {
|
|
16
|
+
if (i === 0)
|
|
17
|
+
return p.toLowerCase();
|
|
18
|
+
if (seenSingleton)
|
|
19
|
+
return p.toLowerCase();
|
|
20
|
+
if (p.length === 1) {
|
|
21
|
+
seenSingleton = true;
|
|
22
|
+
return p.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
if (p.length === 4 && /^[a-zA-Z]{4}$/.test(p))
|
|
25
|
+
return p[0].toUpperCase() + p.slice(1).toLowerCase();
|
|
26
|
+
if (p.length === 2 && /^[a-zA-Z]{2}$/.test(p))
|
|
27
|
+
return p.toUpperCase();
|
|
28
|
+
return p.toLowerCase();
|
|
29
|
+
}).join('-');
|
|
30
|
+
return isCanonicalLanguageTag(fixed) ? fixed : undefined;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=language.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/language.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,4FAA4F;AAC5F,8FAA8F;AAC9F,6FAA6F;AAC7F,sFAAsF;AAEtF,MAAM,YAAY,GAAG,kKAAkK,CAAA;AAEvL,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/B,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC/B,IAAI,aAAa,GAAG,KAAK,CAAA;IACzB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC/B,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QACnC,IAAI,aAAa;YAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QACzC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,aAAa,GAAG,IAAI,CAAC;YAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QAAC,CAAC;QACpE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACnG,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QACrE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;IACxB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACZ,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type EmphasisTag = 'b' | 'i' | 'u';
|
|
2
|
+
export type MarkupNode = {
|
|
3
|
+
type: 'text';
|
|
4
|
+
value: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'emphasis';
|
|
7
|
+
tag: EmphasisTag;
|
|
8
|
+
children: MarkupNode[];
|
|
9
|
+
offset: number;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'ref';
|
|
12
|
+
path: string[];
|
|
13
|
+
offset: number;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'param';
|
|
16
|
+
key: string;
|
|
17
|
+
offset: number;
|
|
18
|
+
};
|
|
19
|
+
export interface MarkupIssue {
|
|
20
|
+
code: string;
|
|
21
|
+
message: string;
|
|
22
|
+
offset: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ParsedMarkup {
|
|
25
|
+
nodes: MarkupNode[];
|
|
26
|
+
issues: MarkupIssue[];
|
|
27
|
+
}
|
|
28
|
+
export declare function parseMarkup(text: string): ParsedMarkup;
|
|
29
|
+
export declare function canonicalMarkup(input: string | MarkupNode[]): string;
|
|
30
|
+
export declare function findReferences(nodes: MarkupNode[]): {
|
|
31
|
+
path: string[];
|
|
32
|
+
offset: number;
|
|
33
|
+
}[];
|
|
34
|
+
export declare function findParams(nodes: MarkupNode[]): {
|
|
35
|
+
key: string;
|
|
36
|
+
offset: number;
|
|
37
|
+
}[];
|
|
38
|
+
export declare function markupToPlainText(nodes: MarkupNode[]): string;
|
|
39
|
+
export declare function escapeMarkupText(value: string): string;
|
|
40
|
+
//# sourceMappingURL=markup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markup.d.ts","sourceRoot":"","sources":["../../src/markup.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAKzC,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAElD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,MAAM,EAAE,WAAW,EAAE,CAAA;CACtB;AAqFD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAoCtD;AAiDD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,MAAM,CAiDpE;AAGD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAQxF;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAQjF;AAGD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,CAM7D;AAGD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|