@agentshouse/mdmodel 0.1.0-c83456e1cebfb → 0.1.0-cabd61587647f
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/API.md +242 -181
- package/README.md +17 -18
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +33 -26
- package/dist/condition.d.ts +149 -0
- package/dist/condition.d.ts.map +1 -0
- package/dist/condition.js +500 -0
- package/dist/definition.d.ts +62 -24
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +703 -138
- package/dist/divide.d.ts.map +1 -1
- package/dist/divide.js +18 -8
- package/dist/document.d.ts +10 -2
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +370 -114
- package/dist/fields.d.ts +2 -0
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +7 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/links.d.ts +2 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +23 -12
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +110 -10
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +52 -30
- package/dist/references.d.ts +4 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +25 -0
- package/dist/schema.d.ts +7 -6
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +157 -31
- package/dist/types.d.ts +43 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +6 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +167 -144
- package/dist/yaml.d.ts +8 -3
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +133 -43
- package/fixtures/README.md +49 -38
- package/fixtures/cases/absent-link-dangles/context.json +1 -0
- package/fixtures/cases/absent-link-dangles/expected.json +1 -0
- package/fixtures/cases/absent-link-dangles/library/item.md +8 -0
- package/fixtures/cases/absent-link-dangles/schema.yaml +6 -0
- package/fixtures/cases/absent-optional-field/context.json +1 -0
- package/fixtures/cases/absent-optional-field/expected.json +1 -0
- package/fixtures/cases/absent-optional-field/library/companies/acme.md +4 -0
- package/fixtures/cases/absent-optional-field/library/deals/lead.md +6 -0
- package/fixtures/cases/absent-optional-field/schema.yaml +56 -0
- package/fixtures/cases/absolute-link/context.json +1 -0
- package/fixtures/cases/{missing-binary-image → absolute-link}/expected.json +1 -1
- package/fixtures/cases/absolute-link/library/item.md +8 -0
- package/fixtures/cases/absolute-link/schema.yaml +6 -0
- package/fixtures/cases/attachment-reference-any-file/context.json +1 -0
- package/fixtures/cases/attachment-reference-any-file/expected.json +1 -0
- package/fixtures/cases/attachment-reference-any-file/library/companies/acme.md +4 -0
- package/fixtures/cases/attachment-reference-any-file/library/deals/renewal.md +15 -0
- package/fixtures/cases/attachment-reference-any-file/library/places/depot.md +4 -0
- package/fixtures/cases/attachment-reference-any-file/library/products/seats.md +4 -0
- package/fixtures/cases/attachment-reference-any-file/library/products/support.md +4 -0
- package/fixtures/cases/attachment-reference-any-file/schema.yaml +32 -0
- package/fixtures/cases/attachment-reference-dangles/context.json +1 -0
- package/fixtures/cases/attachment-reference-dangles/expected.json +1 -0
- package/fixtures/cases/attachment-reference-dangles/library/companies/acme.md +4 -0
- package/fixtures/cases/attachment-reference-dangles/library/deals/renewal.md +15 -0
- package/fixtures/cases/attachment-reference-dangles/library/places/depot.md +4 -0
- package/fixtures/cases/attachment-reference-dangles/library/products/seats.md +4 -0
- package/fixtures/cases/attachment-reference-dangles/library/products/support.md +4 -0
- package/fixtures/cases/attachment-reference-dangles/schema.yaml +32 -0
- package/fixtures/cases/attachment-reference-outside/context.json +1 -0
- package/fixtures/cases/attachment-reference-outside/expected.json +6 -0
- package/fixtures/cases/attachment-reference-outside/library/companies/acme.md +4 -0
- package/fixtures/cases/attachment-reference-outside/library/deals/renewal.md +15 -0
- package/fixtures/cases/attachment-reference-outside/library/places/depot.md +4 -0
- package/fixtures/cases/attachment-reference-outside/library/products/seats.md +4 -0
- package/fixtures/cases/attachment-reference-outside/library/products/support.md +4 -0
- package/fixtures/cases/attachment-reference-outside/schema.yaml +32 -0
- package/fixtures/cases/binary-any-reference/expected.json +1 -1
- package/fixtures/cases/binary-any-reference/schema.yaml +4 -4
- package/fixtures/cases/binary-document-collision/schema.yaml +1 -2
- package/fixtures/cases/binary-image-dangles/expected.json +1 -0
- package/fixtures/cases/binary-image-dangles/schema.yaml +1 -0
- package/fixtures/cases/binary-link-dangles/expected.json +1 -0
- package/fixtures/cases/binary-link-dangles/schema.yaml +1 -0
- package/fixtures/cases/binary-link-outside-collection/schema.yaml +1 -2
- package/fixtures/cases/binary-prototype-reference/expected.json +1 -1
- package/fixtures/cases/binary-prototype-reference/schema.yaml +4 -4
- package/fixtures/cases/binary-typed-reference/expected.json +1 -1
- package/fixtures/cases/binary-typed-reference/schema.yaml +5 -5
- package/fixtures/cases/boolean-field/context.json +1 -0
- package/fixtures/cases/boolean-field/expected.json +6 -0
- package/fixtures/cases/boolean-field/library/companies/acme.md +4 -0
- package/fixtures/cases/boolean-field/library/deals/renewal.md +31 -0
- package/fixtures/cases/boolean-field/schema.yaml +56 -0
- package/fixtures/cases/bracketed-link-definition/schema.yaml +6 -6
- package/fixtures/cases/closed-nested-object/context.json +1 -0
- package/fixtures/cases/closed-nested-object/expected.json +6 -0
- package/fixtures/cases/closed-nested-object/library/companies/acme.md +4 -0
- package/fixtures/cases/closed-nested-object/library/deals/renewal.md +32 -0
- package/fixtures/cases/closed-nested-object/schema.yaml +56 -0
- package/fixtures/cases/composed-root-reference/context.json +1 -0
- package/fixtures/cases/composed-root-reference/expected.json +6 -0
- package/fixtures/cases/composed-root-reference/library/a.md +5 -0
- package/fixtures/cases/composed-root-reference/schema.yaml +13 -0
- package/fixtures/cases/date-time-format/context.json +1 -0
- package/fixtures/cases/date-time-format/expected.json +6 -0
- package/fixtures/cases/date-time-format/library/companies/acme.md +4 -0
- package/fixtures/cases/date-time-format/library/deals/renewal.md +31 -0
- package/fixtures/cases/date-time-format/schema.yaml +56 -0
- package/fixtures/cases/declared-binary-links/schema.yaml +1 -2
- package/fixtures/cases/default-unfilled/context.json +1 -0
- package/fixtures/cases/default-unfilled/expected.json +6 -0
- package/fixtures/cases/default-unfilled/library/companies/acme.md +4 -0
- package/fixtures/cases/default-unfilled/library/deals/renewal.md +29 -0
- package/fixtures/cases/default-unfilled/schema.yaml +56 -0
- package/fixtures/cases/defs-pattern/context.json +1 -0
- package/fixtures/cases/defs-pattern/expected.json +6 -0
- package/fixtures/cases/defs-pattern/library/companies/acme.md +4 -0
- package/fixtures/cases/defs-pattern/library/deals/renewal.md +31 -0
- package/fixtures/cases/defs-pattern/schema.yaml +56 -0
- package/fixtures/cases/dependent-rule/context.json +1 -0
- package/fixtures/cases/dependent-rule/expected.json +6 -0
- package/fixtures/cases/dependent-rule/library/companies/acme.md +4 -0
- package/fixtures/cases/dependent-rule/library/deals/renewal.md +30 -0
- package/fixtures/cases/dependent-rule/schema.yaml +56 -0
- package/fixtures/cases/duplicate-link-definition/schema.yaml +6 -6
- package/fixtures/cases/email-format/context.json +1 -0
- package/fixtures/cases/email-format/expected.json +6 -0
- package/fixtures/cases/email-format/library/companies/acme.md +4 -0
- package/fixtures/cases/email-format/library/deals/renewal.md +31 -0
- package/fixtures/cases/email-format/schema.yaml +56 -0
- package/fixtures/cases/fenced-link-definition/schema.yaml +6 -6
- package/fixtures/cases/field-enum/expected.json +2 -2
- package/fixtures/cases/field-enum/schema.yaml +7 -7
- package/fixtures/cases/frontmatter-schema/schema.yaml +3 -4
- package/fixtures/cases/integer-field/context.json +1 -0
- package/fixtures/cases/integer-field/expected.json +6 -0
- package/fixtures/cases/integer-field/library/companies/acme.md +4 -0
- package/fixtures/cases/integer-field/library/deals/renewal.md +31 -0
- package/fixtures/cases/integer-field/schema.yaml +56 -0
- package/fixtures/cases/interrupted-link-definition/schema.yaml +1 -2
- package/fixtures/cases/json-schema-constructs/context.json +1 -0
- package/fixtures/cases/json-schema-constructs/expected.json +1 -0
- package/fixtures/cases/json-schema-constructs/library/companies/acme.md +4 -0
- package/fixtures/cases/json-schema-constructs/library/deals/renewal.md +31 -0
- package/fixtures/cases/json-schema-constructs/schema.yaml +56 -0
- package/fixtures/cases/list-of-objects-closed/context.json +1 -0
- package/fixtures/cases/list-of-objects-closed/expected.json +6 -0
- package/fixtures/cases/list-of-objects-closed/library/companies/acme.md +4 -0
- package/fixtures/cases/list-of-objects-closed/library/deals/renewal.md +32 -0
- package/fixtures/cases/list-of-objects-closed/schema.yaml +56 -0
- package/fixtures/cases/list-of-objects-item/context.json +1 -0
- package/fixtures/cases/list-of-objects-item/expected.json +6 -0
- package/fixtures/cases/list-of-objects-item/library/companies/acme.md +4 -0
- package/fixtures/cases/list-of-objects-item/library/deals/renewal.md +31 -0
- package/fixtures/cases/list-of-objects-item/schema.yaml +56 -0
- package/fixtures/cases/list-of-objects-reference/context.json +1 -0
- package/fixtures/cases/list-of-objects-reference/expected.json +6 -0
- package/fixtures/cases/list-of-objects-reference/library/companies/acme.md +4 -0
- package/fixtures/cases/list-of-objects-reference/library/deals/renewal.md +14 -0
- package/fixtures/cases/list-of-objects-reference/library/places/depot.md +4 -0
- package/fixtures/cases/list-of-objects-reference/library/products/seats.md +4 -0
- package/fixtures/cases/list-of-objects-reference/library/products/support.md +4 -0
- package/fixtures/cases/list-of-objects-reference/schema.yaml +32 -0
- package/fixtures/cases/list-size/context.json +1 -0
- package/fixtures/cases/list-size/expected.json +6 -0
- package/fixtures/cases/list-size/library/companies/acme.md +4 -0
- package/fixtures/cases/list-size/library/deals/renewal.md +31 -0
- package/fixtures/cases/list-size/schema.yaml +56 -0
- package/fixtures/cases/long-fence-link-definition/schema.yaml +1 -2
- package/fixtures/cases/malformed-definition/expected.json +2 -2
- package/fixtures/cases/malformed-definition/schema.yaml +3 -4
- package/fixtures/cases/member-document/schema.yaml +5 -5
- package/fixtures/cases/missing-required-field/expected.json +2 -2
- package/fixtures/cases/missing-required-field/schema.yaml +7 -7
- package/fixtures/cases/missing-section-item-kind/expected.json +2 -2
- package/fixtures/cases/missing-section-item-kind/schema.yaml +6 -6
- package/fixtures/cases/misspelled-key/context.json +1 -0
- package/fixtures/cases/misspelled-key/expected.json +6 -0
- package/fixtures/cases/misspelled-key/library/companies/acme.md +4 -0
- package/fixtures/cases/misspelled-key/library/deals/renewal.md +32 -0
- package/fixtures/cases/misspelled-key/schema.yaml +56 -0
- package/fixtures/cases/nested-defs/context.json +1 -0
- package/fixtures/cases/nested-defs/expected.json +6 -0
- package/fixtures/cases/nested-defs/library/deal.md +6 -0
- package/fixtures/cases/nested-defs/schema.yaml +11 -0
- package/fixtures/cases/nested-object-reference/context.json +1 -0
- package/fixtures/cases/nested-object-reference/expected.json +6 -0
- package/fixtures/cases/nested-object-reference/library/companies/acme.md +4 -0
- package/fixtures/cases/nested-object-reference/library/deals/renewal.md +14 -0
- package/fixtures/cases/nested-object-reference/library/places/depot.md +4 -0
- package/fixtures/cases/nested-object-reference/library/products/seats.md +4 -0
- package/fixtures/cases/nested-object-reference/library/products/support.md +4 -0
- package/fixtures/cases/nested-object-reference/schema.yaml +32 -0
- package/fixtures/cases/nested-reference/context.json +1 -0
- package/fixtures/cases/nested-reference/expected.json +1 -0
- package/fixtures/cases/nested-reference/library/companies/acme.md +4 -0
- package/fixtures/cases/nested-reference/library/deals/renewal.md +15 -0
- package/fixtures/cases/nested-reference/library/places/depot.md +4 -0
- package/fixtures/cases/nested-reference/library/products/seats.md +4 -0
- package/fixtures/cases/nested-reference/library/products/support.md +4 -0
- package/fixtures/cases/nested-reference/schema.yaml +32 -0
- package/fixtures/cases/nested-required-field/context.json +1 -0
- package/fixtures/cases/nested-required-field/expected.json +6 -0
- package/fixtures/cases/nested-required-field/library/companies/acme.md +4 -0
- package/fixtures/cases/nested-required-field/library/deals/renewal.md +30 -0
- package/fixtures/cases/nested-required-field/schema.yaml +56 -0
- package/fixtures/cases/null-refused/context.json +1 -0
- package/fixtures/cases/null-refused/expected.json +6 -0
- package/fixtures/cases/null-refused/library/companies/acme.md +4 -0
- package/fixtures/cases/null-refused/library/deals/renewal.md +31 -0
- package/fixtures/cases/null-refused/schema.yaml +56 -0
- package/fixtures/cases/numeric-range/context.json +1 -0
- package/fixtures/cases/numeric-range/expected.json +6 -0
- package/fixtures/cases/numeric-range/library/companies/acme.md +4 -0
- package/fixtures/cases/numeric-range/library/deals/renewal.md +31 -0
- package/fixtures/cases/numeric-range/schema.yaml +56 -0
- package/fixtures/cases/one-of-variant/context.json +1 -0
- package/fixtures/cases/one-of-variant/expected.json +6 -0
- package/fixtures/cases/one-of-variant/library/companies/acme.md +4 -0
- package/fixtures/cases/one-of-variant/library/deals/renewal.md +31 -0
- package/fixtures/cases/one-of-variant/schema.yaml +56 -0
- package/fixtures/cases/open-map-value/context.json +1 -0
- package/fixtures/cases/open-map-value/expected.json +6 -0
- package/fixtures/cases/open-map-value/library/companies/acme.md +4 -0
- package/fixtures/cases/open-map-value/library/deals/renewal.md +31 -0
- package/fixtures/cases/open-map-value/schema.yaml +56 -0
- package/fixtures/cases/other-room-reference/context.json +1 -0
- package/fixtures/cases/other-room-reference/expected.json +6 -0
- package/fixtures/cases/other-room-reference/library/companies/acme.md +4 -0
- package/fixtures/cases/other-room-reference/library/deals/renewal.md +14 -0
- package/fixtures/cases/other-room-reference/library/places/depot.md +4 -0
- package/fixtures/cases/other-room-reference/library/products/seats.md +4 -0
- package/fixtures/cases/other-room-reference/library/products/support.md +4 -0
- package/fixtures/cases/other-room-reference/schema.yaml +32 -0
- package/fixtures/cases/paragraph-link-definition/schema.yaml +1 -2
- package/fixtures/cases/prototype-field/expected.json +1 -1
- package/fixtures/cases/prototype-field/schema.yaml +6 -6
- package/fixtures/cases/quoted-link-definition/library/notes/draft.md +1 -1
- package/fixtures/cases/quoted-link-definition/schema.yaml +1 -2
- package/fixtures/cases/referenced-missing-file/schema.yaml +11 -10
- package/fixtures/cases/remote-ref/context.json +1 -0
- package/fixtures/cases/remote-ref/expected.json +5 -0
- package/fixtures/cases/remote-ref/schema.yaml +3 -0
- package/fixtures/cases/second-member-document/expected.json +2 -2
- package/fixtures/cases/second-member-document/schema.yaml +4 -5
- package/fixtures/cases/section-item-enum/schema.yaml +3 -4
- package/fixtures/cases/section-item-kind/schema.yaml +3 -4
- package/fixtures/cases/section-items/library/page.md +14 -0
- package/fixtures/cases/section-items/schema.yaml +10 -8
- package/fixtures/cases/section-reference-path/schema.yaml +3 -4
- package/fixtures/cases/section-reference-type/schema.yaml +3 -4
- package/fixtures/cases/shortcut-reference-link/library/item.md +1 -1
- package/fixtures/cases/shortcut-reference-link/schema.yaml +6 -6
- package/fixtures/cases/string-length/context.json +1 -0
- package/fixtures/cases/string-length/expected.json +6 -0
- package/fixtures/cases/string-length/library/companies/acme.md +4 -0
- package/fixtures/cases/string-length/library/deals/renewal.md +31 -0
- package/fixtures/cases/string-length/schema.yaml +56 -0
- package/fixtures/cases/structured-section/schema.yaml +7 -7
- package/fixtures/cases/submission-keys/schema.yaml +4 -4
- package/fixtures/cases/text-field-kind/expected.json +2 -2
- package/fixtures/cases/text-field-kind/schema.yaml +4 -4
- package/fixtures/cases/truncated-link-definition/library/notes/draft.md +1 -1
- package/fixtures/cases/truncated-link-definition/schema.yaml +1 -2
- package/fixtures/cases/types-folder-content/schema.yaml +4 -4
- package/fixtures/cases/undeclared-field/expected.json +1 -1
- package/fixtures/cases/undeclared-field/schema.yaml +6 -6
- package/fixtures/cases/unevaluated-items-closed/context.json +1 -0
- package/fixtures/cases/unevaluated-items-closed/expected.json +6 -0
- package/fixtures/cases/unevaluated-items-closed/library/trip.md +6 -0
- package/fixtures/cases/unevaluated-items-closed/schema.yaml +10 -0
- package/fixtures/cases/unknown-type/expected.json +1 -1
- package/fixtures/cases/unknown-type/schema.yaml +3 -4
- package/fixtures/cases/unlisted-reference-type/expected.json +2 -2
- package/fixtures/cases/unlisted-reference-type/schema.yaml +3 -4
- package/fixtures/cases/unresolved-link/library/item.md +1 -1
- package/fixtures/cases/unresolved-link/schema.yaml +6 -6
- package/fixtures/cases/valid-typed-document/schema.yaml +16 -15
- package/fixtures/cases/wide-item-fence-link/schema.yaml +1 -2
- package/fixtures/division.json +1 -1
- package/fixtures/projection.json +33 -1
- package/package.json +4 -2
- package/fixtures/cases/missing-binary-image/schema.yaml +0 -2
- package/fixtures/cases/missing-binary-link/expected.json +0 -5
- package/fixtures/cases/missing-binary-link/schema.yaml +0 -2
- /package/fixtures/cases/{missing-binary-image → binary-image-dangles}/context.json +0 -0
- /package/fixtures/cases/{missing-binary-image → binary-image-dangles}/library/notes/draft.md +0 -0
- /package/fixtures/cases/{missing-binary-link → binary-link-dangles}/context.json +0 -0
- /package/fixtures/cases/{missing-binary-link → binary-link-dangles}/library/notes/draft.md +0 -0
package/dist/validate.js
CHANGED
|
@@ -1,54 +1,59 @@
|
|
|
1
|
-
import { readSchema } from './definition.js';
|
|
1
|
+
import { ATTACHMENT, BUILT_IN_TYPE, readSchema } from './definition.js';
|
|
2
2
|
import { parse } from './document.js';
|
|
3
|
-
import { MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD } from './fields.js';
|
|
4
3
|
import { hrefOccurrences, linkInventory } from './links.js';
|
|
5
4
|
import { classifyHref } from './paths.js';
|
|
5
|
+
import { references } from './references.js';
|
|
6
6
|
import { refusal } from './refuse.js';
|
|
7
|
-
import {
|
|
7
|
+
import { fitsItem, frontmatterRefusal } from './schema.js';
|
|
8
8
|
import { headingSpans, listItems } from './sections.js';
|
|
9
9
|
import { bodyAfterFrontmatter, bodyStartOf } from './yaml.js';
|
|
10
|
-
const MEMBER_SPEC = { kind: 'string', required: false };
|
|
11
10
|
function refuse(file, rule, extra) {
|
|
12
11
|
return { verdict: 'refuse', ...refusal(file, rule, extra) };
|
|
13
12
|
}
|
|
14
13
|
function instanceType(document) {
|
|
15
14
|
const raw = document.fields.type;
|
|
16
15
|
if (raw === undefined || raw === null)
|
|
17
|
-
return
|
|
16
|
+
return BUILT_IN_TYPE;
|
|
18
17
|
if (typeof raw !== 'string' || raw === '')
|
|
19
18
|
return null;
|
|
20
19
|
return raw;
|
|
21
20
|
}
|
|
22
|
-
function
|
|
23
|
-
if (
|
|
24
|
-
return
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (spec.kind === 'reference')
|
|
32
|
-
return spec.to;
|
|
33
|
-
if (spec.kind === 'list' && spec.of.kind === 'reference')
|
|
34
|
-
return spec.of.to;
|
|
35
|
-
return null;
|
|
21
|
+
function reaches(reference, typeOf, binary) {
|
|
22
|
+
if (reference.target === null)
|
|
23
|
+
return false;
|
|
24
|
+
if (reference.to.includes(ATTACHMENT))
|
|
25
|
+
return true;
|
|
26
|
+
if (binary(reference.target))
|
|
27
|
+
return false;
|
|
28
|
+
const held = typeOf(reference.target);
|
|
29
|
+
return held === undefined || reference.to.includes(held);
|
|
36
30
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
if (resolved.kind !== 'path' || binaryTargets.has(resolved.path))
|
|
31
|
+
function missing(reference, typeOf, binary) {
|
|
32
|
+
if (reference.to.includes(ATTACHMENT) || reference.target === null)
|
|
40
33
|
return false;
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
return typeOf(reference.target) === undefined && !binary(reference.target);
|
|
35
|
+
}
|
|
36
|
+
export function resolves(reference, typeOf, binary) {
|
|
37
|
+
return reaches(reference, typeOf, binary) && !missing(reference, typeOf, binary);
|
|
43
38
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
function usesIn(content) {
|
|
40
|
+
let held;
|
|
41
|
+
return () => {
|
|
42
|
+
if (held !== undefined)
|
|
43
|
+
return held;
|
|
44
|
+
const bodyStart = bodyStartOf(content);
|
|
45
|
+
held = linkInventory(content.slice(bodyStart)).uses.map((use) => ({
|
|
46
|
+
...use,
|
|
47
|
+
start: bodyStart + use.start,
|
|
48
|
+
end: bodyStart + use.end,
|
|
49
|
+
}));
|
|
50
|
+
return held;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function itemHrefs(content, items, uses) {
|
|
47
54
|
const hrefs = [];
|
|
48
55
|
for (const item of items) {
|
|
49
|
-
const link = uses.find((use) =>
|
|
50
|
-
bodyStart + use.end === item.end &&
|
|
51
|
-
content[item.start] === '[');
|
|
56
|
+
const link = uses().find((use) => use.start === item.start && use.end === item.end && content[item.start] === '[');
|
|
52
57
|
if (link === undefined)
|
|
53
58
|
return null;
|
|
54
59
|
hrefs.push(link.destination.href);
|
|
@@ -65,137 +70,155 @@ export function verify(schema) {
|
|
|
65
70
|
...(read.location === undefined ? {} : { location: read.location }),
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
|
-
function
|
|
69
|
-
if (
|
|
70
|
-
return
|
|
71
|
-
|
|
73
|
+
function structure(file, content, document, definition) {
|
|
74
|
+
if (definition === undefined)
|
|
75
|
+
return { refusal: refuse(file, 'unknown-type', { location: '/type' }) };
|
|
76
|
+
const fieldFailure = frontmatterRefusal(definition, document.fields);
|
|
77
|
+
if (fieldFailure !== undefined) {
|
|
78
|
+
return { refusal: refuse(file, fieldFailure.rule, { location: fieldFailure.location }) };
|
|
79
|
+
}
|
|
80
|
+
const spans = headingSpans(content, bodyStartOf(content));
|
|
81
|
+
const uses = usesIn(content);
|
|
82
|
+
const sections = [];
|
|
83
|
+
for (const [name, spec] of Object.entries(definition.sections)) {
|
|
84
|
+
const occurrences = spans.filter((one) => one.name === name);
|
|
85
|
+
if (occurrences.length === 0 && spec.required)
|
|
86
|
+
return { refusal: refuse(file, 'required-section', { location: name }) };
|
|
87
|
+
if (spec.kind !== 'list')
|
|
88
|
+
continue;
|
|
89
|
+
for (const span of occurrences) {
|
|
90
|
+
const items = listItems(content, span.bodyStart, span.bodyEnd);
|
|
91
|
+
if (items === null ||
|
|
92
|
+
items.some((item) => !fitsItem(definition, name, content.slice(item.start, item.end))))
|
|
93
|
+
return { refusal: refuse(file, 'structured-section', { location: name }) };
|
|
94
|
+
if (spec.items.reference === undefined)
|
|
95
|
+
continue;
|
|
96
|
+
const hrefs = itemHrefs(content, items, uses);
|
|
97
|
+
if (hrefs === null)
|
|
98
|
+
return { refusal: refuse(file, 'structured-section', { location: name }) };
|
|
99
|
+
sections.push({ section: name, to: spec.items.reference, hrefs });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { sections };
|
|
72
103
|
}
|
|
73
|
-
|
|
104
|
+
function linked(file, content) {
|
|
105
|
+
return hrefOccurrences(bodyAfterFrontmatter(content)).every((occurrence) => classifyHref(file, occurrence.href).kind !== 'invalid');
|
|
106
|
+
}
|
|
107
|
+
function reached(file, href, to) {
|
|
108
|
+
const resolved = classifyHref(file, href);
|
|
109
|
+
return { target: resolved.kind === 'path' ? resolved.path : null, to };
|
|
110
|
+
}
|
|
111
|
+
function definitionOf(document, model) {
|
|
112
|
+
const kind = instanceType(document);
|
|
113
|
+
return kind === null || !Object.hasOwn(model.types, kind) ? undefined : model.types[kind];
|
|
114
|
+
}
|
|
115
|
+
export function checkDocument(file, content, model) {
|
|
116
|
+
const parsed = parse(content, file);
|
|
117
|
+
if (!parsed.ok)
|
|
118
|
+
return { ok: false };
|
|
119
|
+
const document = parsed.document;
|
|
120
|
+
const type = document.type ?? BUILT_IN_TYPE;
|
|
121
|
+
if (instanceType(document) === BUILT_IN_TYPE)
|
|
122
|
+
return { ok: true, type, typed: false, references: [] };
|
|
123
|
+
const definition = definitionOf(document, model);
|
|
124
|
+
const read = structure(file, content, document, definition);
|
|
125
|
+
if ('refusal' in read || definition === undefined || !linked(file, content))
|
|
126
|
+
return { ok: false };
|
|
127
|
+
return {
|
|
128
|
+
ok: true,
|
|
129
|
+
type,
|
|
130
|
+
typed: true,
|
|
131
|
+
references: [
|
|
132
|
+
...references(document, definition).map(({ value, to }) => reached(file, value, to)),
|
|
133
|
+
...read.sections.flatMap(({ to, hrefs }) => hrefs.map((href) => reached(file, href, to))),
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export function sectionReferences(file, content, definition) {
|
|
138
|
+
const referring = (name) => {
|
|
139
|
+
const spec = Object.hasOwn(definition.sections, name) ? definition.sections[name] : undefined;
|
|
140
|
+
return spec?.kind === 'list' ? spec.items.reference : undefined;
|
|
141
|
+
};
|
|
142
|
+
if (!Object.keys(definition.sections).some((name) => referring(name) !== undefined))
|
|
143
|
+
return [];
|
|
144
|
+
const uses = usesIn(content);
|
|
145
|
+
const found = [];
|
|
146
|
+
for (const span of headingSpans(content, bodyStartOf(content))) {
|
|
147
|
+
const to = referring(span.name);
|
|
148
|
+
if (to === undefined)
|
|
149
|
+
continue;
|
|
150
|
+
const items = listItems(content, span.bodyStart, span.bodyEnd);
|
|
151
|
+
const hrefs = items === null ? null : itemHrefs(content, items, uses);
|
|
152
|
+
for (const href of hrefs ?? [])
|
|
153
|
+
found.push(reached(file, href, to));
|
|
154
|
+
}
|
|
155
|
+
return found;
|
|
156
|
+
}
|
|
157
|
+
export function* validating(library, context = { binaryTargets: [] }, model = { types: {} }) {
|
|
74
158
|
const binaryTargets = new Set(context.binaryTargets);
|
|
159
|
+
const binary = (path) => binaryTargets.has(path);
|
|
75
160
|
const files = Object.keys(library).sort();
|
|
161
|
+
const types = new Map();
|
|
162
|
+
const typeOf = (path) => types.get(path);
|
|
76
163
|
const documents = new Map();
|
|
77
164
|
for (const file of files) {
|
|
78
165
|
if (binaryTargets.has(file))
|
|
79
166
|
return refuse(file, 'binary-target-document');
|
|
80
167
|
const parsed = parse(library[file], file);
|
|
81
|
-
documents.set(file, parsed);
|
|
82
168
|
if (!parsed.ok)
|
|
83
169
|
return { verdict: 'refuse', ...parsed.refusal };
|
|
170
|
+
types.set(file, parsed.document.type ?? BUILT_IN_TYPE);
|
|
171
|
+
if (instanceType(parsed.document) !== BUILT_IN_TYPE)
|
|
172
|
+
documents.set(file, parsed.document);
|
|
173
|
+
yield file;
|
|
84
174
|
}
|
|
85
|
-
const definitions = new Map(Object.entries(model.types));
|
|
86
175
|
const sectionReferences = new Map();
|
|
87
|
-
for (const file of
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
continue;
|
|
94
|
-
const definition = kind === null ? undefined : definitions.get(kind);
|
|
95
|
-
if (definition === undefined)
|
|
96
|
-
return refuse(file, 'unknown-type', { location: 'type' });
|
|
97
|
-
const fields = declaredFields(definition);
|
|
98
|
-
const fieldFailure = validateFields(fields, parsed.document.fields);
|
|
99
|
-
if (fieldFailure !== undefined) {
|
|
100
|
-
return refuse(file, fieldFailure.rule, { location: fieldFailure.field });
|
|
101
|
-
}
|
|
102
|
-
const declared = new Set(Object.keys(fields));
|
|
103
|
-
const undeclared = Object.keys(parsed.document.fields).find((name) => !['type', SITE_FIELD, RECEIVED_FIELD].includes(name) && !declared.has(name));
|
|
104
|
-
if (undeclared !== undefined)
|
|
105
|
-
return refuse(file, 'undeclared-field', { location: undeclared });
|
|
106
|
-
const content = library[file];
|
|
107
|
-
const spans = headingSpans(content, bodyStartOf(content));
|
|
108
|
-
const references = [];
|
|
109
|
-
for (const [name, spec] of Object.entries(definition.sections)) {
|
|
110
|
-
const occurrences = spans.filter((one) => one.name === name);
|
|
111
|
-
if (occurrences.length === 0 && spec.required)
|
|
112
|
-
return refuse(file, 'required-section', { location: name });
|
|
113
|
-
if (spec.kind !== 'list')
|
|
114
|
-
continue;
|
|
115
|
-
for (const span of occurrences) {
|
|
116
|
-
const items = listItems(content, span.bodyStart, span.bodyEnd);
|
|
117
|
-
if (items === null ||
|
|
118
|
-
items.some((item) => !fitsKind(spec.of, content.slice(item.start, item.end))))
|
|
119
|
-
return refuse(file, 'structured-section', { location: name });
|
|
120
|
-
if (spec.of.kind !== 'reference')
|
|
121
|
-
continue;
|
|
122
|
-
const hrefs = itemHrefs(content, items);
|
|
123
|
-
if (hrefs === null)
|
|
124
|
-
return refuse(file, 'structured-section', { location: name });
|
|
125
|
-
references.push({ section: name, to: spec.of.to, hrefs });
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
sectionReferences.set(file, references);
|
|
176
|
+
for (const [file, document] of documents) {
|
|
177
|
+
const read = structure(file, library[file], document, definitionOf(document, model));
|
|
178
|
+
if ('refusal' in read)
|
|
179
|
+
return read.refusal;
|
|
180
|
+
sectionReferences.set(file, read.sections);
|
|
181
|
+
yield file;
|
|
129
182
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
for (const [name, spec] of Object.entries(definition.fields)) {
|
|
141
|
-
const targets = referenceTargets(spec, parsed.document.fields[name]);
|
|
142
|
-
const expected = expectedReferenceType(spec);
|
|
143
|
-
if (expected === null)
|
|
144
|
-
continue;
|
|
145
|
-
for (const target of targets) {
|
|
146
|
-
if (!reaches(file, target, expected, documents, binaryTargets))
|
|
147
|
-
return refuse(file, 'unresolved-reference', { location: name });
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
const body = bodyAfterFrontmatter(library[file]);
|
|
151
|
-
for (const occurrence of hrefOccurrences(body)) {
|
|
152
|
-
const resolved = classifyHref(file, occurrence.href);
|
|
153
|
-
if (resolved.kind === 'skip')
|
|
154
|
-
continue;
|
|
155
|
-
if (resolved.kind === 'invalid' ||
|
|
156
|
-
(!documents.has(resolved.path) && !binaryTargets.has(resolved.path))) {
|
|
157
|
-
return refuse(file, 'unresolved-link');
|
|
158
|
-
}
|
|
183
|
+
let least;
|
|
184
|
+
for (const [file, document] of documents) {
|
|
185
|
+
const definition = definitionOf(document, model);
|
|
186
|
+
const fields = references(document, definition).map(({ pointer, value, to }) => ({
|
|
187
|
+
reference: reached(file, value, to),
|
|
188
|
+
location: pointer,
|
|
189
|
+
}));
|
|
190
|
+
for (const { reference, location } of fields) {
|
|
191
|
+
if (!reaches(reference, typeOf, binary))
|
|
192
|
+
return refuse(file, 'unresolved-reference', { location });
|
|
159
193
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
194
|
+
if (!linked(file, library[file]))
|
|
195
|
+
return refuse(file, 'unresolved-link');
|
|
196
|
+
const sections = sectionReferences
|
|
197
|
+
.get(file)
|
|
198
|
+
.flatMap(({ section, to, hrefs }) => hrefs.map((href) => ({ reference: reached(file, href, to), location: section })));
|
|
199
|
+
for (const { reference, location } of sections) {
|
|
200
|
+
if (!reaches(reference, typeOf, binary))
|
|
201
|
+
return refuse(file, 'unresolved-reference', { location });
|
|
165
202
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
for (const file of files) {
|
|
169
|
-
const parsed = documents.get(file);
|
|
170
|
-
if (parsed === undefined || !parsed.ok)
|
|
171
|
-
continue;
|
|
172
|
-
const kind = instanceType(parsed.document);
|
|
173
|
-
if (kind === null || kind === 'any')
|
|
174
|
-
continue;
|
|
175
|
-
const definition = definitions.get(kind);
|
|
176
|
-
if (definition === undefined)
|
|
177
|
-
continue;
|
|
178
|
-
for (const [name, spec] of Object.entries(definition.fields)) {
|
|
179
|
-
const expected = expectedReferenceType(spec);
|
|
180
|
-
if (expected === null)
|
|
203
|
+
for (const { reference } of [...fields, ...sections]) {
|
|
204
|
+
if (!missing(reference, typeOf, binary))
|
|
181
205
|
continue;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
continue;
|
|
188
|
-
const referrers = missing.get(resolved.path) ?? [];
|
|
189
|
-
referrers.push(file);
|
|
190
|
-
missing.set(resolved.path, referrers);
|
|
191
|
-
}
|
|
206
|
+
const path = reference.target;
|
|
207
|
+
if (least === undefined || path < least.path)
|
|
208
|
+
least = { path, referrers: [] };
|
|
209
|
+
if (path === least.path && least.referrers.at(-1) !== file)
|
|
210
|
+
least.referrers.push(file);
|
|
192
211
|
}
|
|
212
|
+
yield file;
|
|
193
213
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const path = missingPaths[0];
|
|
197
|
-
const referrers = [...new Set(missing.get(path) ?? [])].sort();
|
|
198
|
-
return refuse(path, 'referenced-missing-file', { referrers });
|
|
199
|
-
}
|
|
214
|
+
if (least !== undefined)
|
|
215
|
+
return refuse(least.path, 'referenced-missing-file', { referrers: least.referrers });
|
|
200
216
|
return { verdict: 'accept' };
|
|
201
217
|
}
|
|
218
|
+
export function validate(library, context = { binaryTargets: [] }, model = { types: {} }) {
|
|
219
|
+
const steps = validating(library, context, model);
|
|
220
|
+
let step = steps.next();
|
|
221
|
+
while (step.done !== true)
|
|
222
|
+
step = steps.next();
|
|
223
|
+
return step.value;
|
|
224
|
+
}
|
package/dist/yaml.d.ts
CHANGED
|
@@ -16,8 +16,7 @@ export type YamlSeq = {
|
|
|
16
16
|
};
|
|
17
17
|
export type YamlEntry = {
|
|
18
18
|
readonly key: string;
|
|
19
|
-
readonly
|
|
20
|
-
readonly keyEnd: number;
|
|
19
|
+
readonly after: number;
|
|
21
20
|
readonly value: YamlNode;
|
|
22
21
|
};
|
|
23
22
|
export type YamlMap = {
|
|
@@ -32,7 +31,13 @@ export declare function parseYamlMapping(text: string, start: number, end: numbe
|
|
|
32
31
|
export declare function jsValue(node: YamlNode): unknown;
|
|
33
32
|
export declare function mapEntry(map: YamlMap, key: string): YamlEntry | undefined;
|
|
34
33
|
export declare function isPlainSafe(text: string): boolean;
|
|
35
|
-
export
|
|
34
|
+
export type FrontmatterValue = string | number | boolean | null | readonly FrontmatterValue[] | {
|
|
35
|
+
readonly [name: string]: FrontmatterValue;
|
|
36
|
+
};
|
|
37
|
+
export declare function plain(value: unknown): value is Record<string, unknown>;
|
|
38
|
+
export declare function frontmatterValue(value: unknown): value is FrontmatterValue;
|
|
39
|
+
export declare function serializeJs(value: FrontmatterValue): string;
|
|
40
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
36
41
|
export declare function serializeKey(name: string): string;
|
|
37
42
|
export declare function bodyStartAfterYaml(content: string, yamlEnd: number): number;
|
|
38
43
|
export declare function bodyStartOf(content: string): number;
|
package/dist/yaml.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAGlC;CACF;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"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"}
|
package/dist/yaml.js
CHANGED
|
@@ -84,6 +84,30 @@ export function interpretPlain(text) {
|
|
|
84
84
|
return Number(text);
|
|
85
85
|
return text;
|
|
86
86
|
}
|
|
87
|
+
const ESCAPES = {
|
|
88
|
+
b: '\b',
|
|
89
|
+
f: '\f',
|
|
90
|
+
n: '\n',
|
|
91
|
+
r: '\r',
|
|
92
|
+
t: '\t',
|
|
93
|
+
'"': '"',
|
|
94
|
+
'/': '/',
|
|
95
|
+
'\\': '\\',
|
|
96
|
+
};
|
|
97
|
+
function parseEscape(c) {
|
|
98
|
+
c.i += 1;
|
|
99
|
+
const escaped = peek(c);
|
|
100
|
+
const held = ESCAPES[escaped];
|
|
101
|
+
if (held !== undefined) {
|
|
102
|
+
c.i += 1;
|
|
103
|
+
return held;
|
|
104
|
+
}
|
|
105
|
+
const hex = c.text.slice(c.i + 1, c.i + 5);
|
|
106
|
+
if (escaped !== 'u' || c.i + 5 > c.end || !/^[0-9A-Fa-f]{4}$/.test(hex))
|
|
107
|
+
throw new YamlError(c.i);
|
|
108
|
+
c.i += 5;
|
|
109
|
+
return String.fromCharCode(Number.parseInt(hex, 16));
|
|
110
|
+
}
|
|
87
111
|
function parseQuoted(c) {
|
|
88
112
|
const quote = peek(c);
|
|
89
113
|
const start = c.i;
|
|
@@ -91,31 +115,19 @@ function parseQuoted(c) {
|
|
|
91
115
|
let out = '';
|
|
92
116
|
while (c.i < c.end) {
|
|
93
117
|
const ch = peek(c);
|
|
118
|
+
if (quote === "'" && ch === "'" && c.i + 1 < c.end && c.text[c.i + 1] === "'") {
|
|
119
|
+
out += "'";
|
|
120
|
+
c.i += 2;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
94
123
|
if (ch === quote) {
|
|
95
124
|
c.i += 1;
|
|
96
125
|
return scalar(out, start, c.i);
|
|
97
126
|
}
|
|
98
127
|
if (ch === '\n' || ch === '\r')
|
|
99
128
|
throw new YamlError(c.i);
|
|
100
|
-
if (quote === "'" && ch === "'" && c.text[c.i + 1] === "'") {
|
|
101
|
-
out += "'";
|
|
102
|
-
c.i += 2;
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
129
|
if (quote === '"' && ch === '\\') {
|
|
106
|
-
|
|
107
|
-
const escaped = peek(c);
|
|
108
|
-
if (escaped === 'n')
|
|
109
|
-
out += '\n';
|
|
110
|
-
else if (escaped === 't')
|
|
111
|
-
out += '\t';
|
|
112
|
-
else if (escaped === '"')
|
|
113
|
-
out += '"';
|
|
114
|
-
else if (escaped === '\\')
|
|
115
|
-
out += '\\';
|
|
116
|
-
else
|
|
117
|
-
throw new YamlError(c.i);
|
|
118
|
-
c.i += 1;
|
|
130
|
+
out += parseEscape(c);
|
|
119
131
|
continue;
|
|
120
132
|
}
|
|
121
133
|
out += ch;
|
|
@@ -208,11 +220,12 @@ function parseFlowMap(c) {
|
|
|
208
220
|
if (peek(c) !== ':')
|
|
209
221
|
throw new YamlError(c.i);
|
|
210
222
|
c.i += 1;
|
|
223
|
+
const after = c.i;
|
|
211
224
|
const value = parseFlowValue(c);
|
|
212
225
|
if (seen.has(key.name))
|
|
213
226
|
throw new YamlError(key.start);
|
|
214
227
|
seen.add(key.name);
|
|
215
|
-
entries.push({ key: key.name,
|
|
228
|
+
entries.push({ key: key.name, after, value });
|
|
216
229
|
skipFlowSpace(c);
|
|
217
230
|
if (peek(c) === ',') {
|
|
218
231
|
c.i += 1;
|
|
@@ -254,6 +267,7 @@ function parseFlowSeq(c) {
|
|
|
254
267
|
throw new YamlError(c.i);
|
|
255
268
|
}
|
|
256
269
|
function parseValue(c, parentKeyIndent) {
|
|
270
|
+
const at = c.i;
|
|
257
271
|
skipSpaces(c);
|
|
258
272
|
if (peek(c) === '#')
|
|
259
273
|
skipToEol(c);
|
|
@@ -262,10 +276,12 @@ function parseValue(c, parentKeyIndent) {
|
|
|
262
276
|
skipEol(c);
|
|
263
277
|
skipBlankAndComments(c);
|
|
264
278
|
if (c.i >= c.end)
|
|
265
|
-
return scalar(null,
|
|
279
|
+
return scalar(null, at, at);
|
|
266
280
|
const nextIndent = indentAt(c);
|
|
281
|
+
if (nextIndent === parentKeyIndent && seqAhead(c))
|
|
282
|
+
return parseBlockSeq(c, nextIndent);
|
|
267
283
|
if (nextIndent <= parentKeyIndent)
|
|
268
|
-
return scalar(null,
|
|
284
|
+
return scalar(null, at, at);
|
|
269
285
|
if (peek(c) === '-')
|
|
270
286
|
return parseBlockSeq(c, nextIndent);
|
|
271
287
|
if (peek(c) === '[')
|
|
@@ -282,6 +298,43 @@ function parseValue(c, parentKeyIndent) {
|
|
|
282
298
|
throw new YamlError(c.i);
|
|
283
299
|
return parseScalar(c, false);
|
|
284
300
|
}
|
|
301
|
+
function seqAhead(c) {
|
|
302
|
+
const next = c.text[c.i + 1];
|
|
303
|
+
return peek(c) === '-' && (next === ' ' || next === '\n' || next === '\r' || c.i + 1 >= c.end);
|
|
304
|
+
}
|
|
305
|
+
function mappingAhead(c) {
|
|
306
|
+
const start = c.i;
|
|
307
|
+
try {
|
|
308
|
+
if (peek(c) === '{' || peek(c) === '[')
|
|
309
|
+
return false;
|
|
310
|
+
parseKey(c);
|
|
311
|
+
skipSpaces(c);
|
|
312
|
+
if (peek(c) !== ':')
|
|
313
|
+
return false;
|
|
314
|
+
const next = c.text[c.i + 1];
|
|
315
|
+
return next === ' ' || next === '\n' || next === '\r' || c.i + 1 >= c.end;
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
if (error instanceof YamlError)
|
|
319
|
+
return false;
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
finally {
|
|
323
|
+
c.i = start;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function lineStartOf(c) {
|
|
327
|
+
let j = c.i;
|
|
328
|
+
while (j > 0 && c.text[j - 1] !== '\n' && c.text[j - 1] !== '\r')
|
|
329
|
+
j -= 1;
|
|
330
|
+
return j;
|
|
331
|
+
}
|
|
332
|
+
function parseSeqItem(c, indent) {
|
|
333
|
+
skipSpaces(c);
|
|
334
|
+
if (peek(c) !== '#' && peek(c) !== '\n' && peek(c) !== '\r' && c.i < c.end && mappingAhead(c))
|
|
335
|
+
return parseBlockMap(c, c.i - lineStartOf(c), true);
|
|
336
|
+
return parseValue(c, indent);
|
|
337
|
+
}
|
|
285
338
|
function parseBlockSeq(c, indent) {
|
|
286
339
|
const start = c.i;
|
|
287
340
|
const items = [];
|
|
@@ -295,35 +348,41 @@ function parseBlockSeq(c, indent) {
|
|
|
295
348
|
if (peek(c) !== '-')
|
|
296
349
|
break;
|
|
297
350
|
c.i += 1;
|
|
298
|
-
|
|
299
|
-
|
|
351
|
+
const item = parseSeqItem(c, indent);
|
|
352
|
+
items.push(item);
|
|
353
|
+
end = item.end;
|
|
300
354
|
}
|
|
301
355
|
return { kind: 'seq', items, start, end };
|
|
302
356
|
}
|
|
303
|
-
function parseBlockMap(c, indent) {
|
|
357
|
+
function parseBlockMap(c, indent, inline = false) {
|
|
304
358
|
const start = c.i;
|
|
305
359
|
const entries = [];
|
|
306
360
|
const seen = new Set();
|
|
307
361
|
let end = start;
|
|
362
|
+
let first = inline;
|
|
308
363
|
while (c.i < c.end) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
364
|
+
if (!first) {
|
|
365
|
+
skipBlankAndComments(c);
|
|
366
|
+
if (c.i >= c.end)
|
|
367
|
+
break;
|
|
368
|
+
if (indentAt(c) < indent)
|
|
369
|
+
break;
|
|
370
|
+
if (indentAt(c) > indent)
|
|
371
|
+
throw new YamlError(c.i);
|
|
372
|
+
}
|
|
373
|
+
first = false;
|
|
316
374
|
const key = parseKey(c);
|
|
317
375
|
skipSpaces(c);
|
|
318
376
|
if (peek(c) !== ':')
|
|
319
377
|
throw new YamlError(c.i);
|
|
320
378
|
c.i += 1;
|
|
379
|
+
const after = c.i;
|
|
321
380
|
const value = parseValue(c, indent);
|
|
322
381
|
if (seen.has(key.name))
|
|
323
382
|
throw new YamlError(key.start);
|
|
324
383
|
seen.add(key.name);
|
|
325
|
-
entries.push({ key: key.name,
|
|
326
|
-
end =
|
|
384
|
+
entries.push({ key: key.name, after, value });
|
|
385
|
+
end = value.end;
|
|
327
386
|
}
|
|
328
387
|
return { kind: 'map', entries, start, end };
|
|
329
388
|
}
|
|
@@ -369,20 +428,45 @@ export function isPlainSafe(text) {
|
|
|
369
428
|
return false;
|
|
370
429
|
return true;
|
|
371
430
|
}
|
|
431
|
+
export function plain(value) {
|
|
432
|
+
if (!isRecord(value))
|
|
433
|
+
return false;
|
|
434
|
+
const prototype = Object.getPrototypeOf(value);
|
|
435
|
+
return prototype === Object.prototype || prototype === null;
|
|
436
|
+
}
|
|
437
|
+
function listed(value) {
|
|
438
|
+
const keys = Object.keys(value);
|
|
439
|
+
return keys.length === value.length && keys.every((key, index) => key === String(index));
|
|
440
|
+
}
|
|
441
|
+
function heldWithin(value, within) {
|
|
442
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
443
|
+
return true;
|
|
444
|
+
if (typeof value === 'number')
|
|
445
|
+
return Number.isFinite(value);
|
|
446
|
+
if (typeof value !== 'object' || within.includes(value))
|
|
447
|
+
return false;
|
|
448
|
+
const path = [...within, value];
|
|
449
|
+
const held = (item) => heldWithin(item, path);
|
|
450
|
+
if (Array.isArray(value))
|
|
451
|
+
return listed(value) && value.every(held);
|
|
452
|
+
return plain(value) && Object.values(value).every(held);
|
|
453
|
+
}
|
|
454
|
+
export function frontmatterValue(value) {
|
|
455
|
+
return heldWithin(value, []);
|
|
456
|
+
}
|
|
372
457
|
export function serializeJs(value) {
|
|
373
|
-
if (value === null)
|
|
374
|
-
return 'null';
|
|
375
|
-
if (value === true)
|
|
376
|
-
return 'true';
|
|
377
|
-
if (value === false)
|
|
378
|
-
return 'false';
|
|
379
|
-
if (typeof value === 'number' && Number.isFinite(value))
|
|
380
|
-
return JSON.stringify(value);
|
|
381
458
|
if (typeof value === 'string')
|
|
382
459
|
return isPlainSafe(value) ? value : JSON.stringify(value);
|
|
460
|
+
if (value === null || typeof value !== 'object')
|
|
461
|
+
return JSON.stringify(value);
|
|
383
462
|
if (Array.isArray(value))
|
|
384
463
|
return `[${value.map(serializeJs).join(', ')}]`;
|
|
385
|
-
|
|
464
|
+
return `{${Object.entries(value)
|
|
465
|
+
.map(([key, held]) => `${serializeKey(key)}: ${serializeJs(held)}`)
|
|
466
|
+
.join(', ')}}`;
|
|
467
|
+
}
|
|
468
|
+
export function isRecord(value) {
|
|
469
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
386
470
|
}
|
|
387
471
|
export function serializeKey(name) {
|
|
388
472
|
return isPlainSafe(name) || /^[A-Za-z][A-Za-z0-9_-]*$/.test(name) ? name : JSON.stringify(name);
|
|
@@ -429,7 +513,13 @@ export function equalValue(left, right) {
|
|
|
429
513
|
if (left === right)
|
|
430
514
|
return true;
|
|
431
515
|
if (Array.isArray(left) && Array.isArray(right)) {
|
|
432
|
-
return (left.length === right.length &&
|
|
516
|
+
return (left.length === right.length &&
|
|
517
|
+
Array.from(left).every((item, index) => equalValue(item, right[index])));
|
|
518
|
+
}
|
|
519
|
+
if (isRecord(left) && isRecord(right)) {
|
|
520
|
+
const keys = Object.keys(left);
|
|
521
|
+
return (keys.length === Object.keys(right).length &&
|
|
522
|
+
keys.every((key) => Object.hasOwn(right, key) && equalValue(left[key], right[key])));
|
|
433
523
|
}
|
|
434
524
|
return false;
|
|
435
525
|
}
|