@krantho/seo 0.0.0-stage → 1.0.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 +21 -0
- package/dist/archetypes/define-archetype.d.ts +23 -0
- package/dist/archetypes/define-archetype.d.ts.map +1 -0
- package/dist/archetypes/define-archetype.js +51 -0
- package/dist/archetypes/define-archetype.js.map +1 -0
- package/dist/archetypes/index.d.ts +4 -0
- package/dist/archetypes/index.d.ts.map +1 -0
- package/dist/archetypes/index.js +3 -0
- package/dist/archetypes/index.js.map +1 -0
- package/dist/archetypes/presets.d.ts +21 -0
- package/dist/archetypes/presets.d.ts.map +1 -0
- package/dist/archetypes/presets.js +42 -0
- package/dist/archetypes/presets.js.map +1 -0
- package/dist/archetypes/types.d.ts +20 -0
- package/dist/archetypes/types.d.ts.map +1 -0
- package/dist/archetypes/types.js +2 -0
- package/dist/archetypes/types.js.map +1 -0
- package/dist/catalog/auto-mappings.d.ts +39 -0
- package/dist/catalog/auto-mappings.d.ts.map +1 -0
- package/dist/catalog/auto-mappings.js +64 -0
- package/dist/catalog/auto-mappings.js.map +1 -0
- package/dist/catalog/index.d.ts +7 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +4 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/properties.d.ts +9 -0
- package/dist/catalog/properties.d.ts.map +1 -0
- package/dist/catalog/properties.js +630 -0
- package/dist/catalog/properties.js.map +1 -0
- package/dist/catalog/property-atoms.d.ts +53 -0
- package/dist/catalog/property-atoms.d.ts.map +1 -0
- package/dist/catalog/property-atoms.js +170 -0
- package/dist/catalog/property-atoms.js.map +1 -0
- package/dist/catalog/types.d.ts +53 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/catalog/types.js +423 -0
- package/dist/catalog/types.js.map +1 -0
- package/dist/create-seo.d.ts +70 -0
- package/dist/create-seo.d.ts.map +1 -0
- package/dist/create-seo.js +137 -0
- package/dist/create-seo.js.map +1 -0
- package/dist/decorators/breadcrumb.d.ts +12 -0
- package/dist/decorators/breadcrumb.d.ts.map +1 -0
- package/dist/decorators/breadcrumb.js +36 -0
- package/dist/decorators/breadcrumb.js.map +1 -0
- package/dist/decorators/index.d.ts +8 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +13 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/nodes.d.ts +12 -0
- package/dist/decorators/nodes.d.ts.map +1 -0
- package/dist/decorators/nodes.js +29 -0
- package/dist/decorators/nodes.js.map +1 -0
- package/dist/decorators/page.d.ts +13 -0
- package/dist/decorators/page.d.ts.map +1 -0
- package/dist/decorators/page.js +68 -0
- package/dist/decorators/page.js.map +1 -0
- package/dist/decorators/registry.d.ts +11 -0
- package/dist/decorators/registry.d.ts.map +1 -0
- package/dist/decorators/registry.js +29 -0
- package/dist/decorators/registry.js.map +1 -0
- package/dist/decorators/sequence.d.ts +8 -0
- package/dist/decorators/sequence.d.ts.map +1 -0
- package/dist/decorators/sequence.js +22 -0
- package/dist/decorators/sequence.js.map +1 -0
- package/dist/decorators/types.d.ts +30 -0
- package/dist/decorators/types.d.ts.map +1 -0
- package/dist/decorators/types.js +2 -0
- package/dist/decorators/types.js.map +1 -0
- package/dist/define-seo.d.ts +21 -0
- package/dist/define-seo.d.ts.map +1 -0
- package/dist/define-seo.js +31 -0
- package/dist/define-seo.js.map +1 -0
- package/dist/graph/build-entity.d.ts +47 -0
- package/dist/graph/build-entity.d.ts.map +1 -0
- package/dist/graph/build-entity.js +69 -0
- package/dist/graph/build-entity.js.map +1 -0
- package/dist/graph/compose-from-config.d.ts +89 -0
- package/dist/graph/compose-from-config.d.ts.map +1 -0
- package/dist/graph/compose-from-config.js +189 -0
- package/dist/graph/compose-from-config.js.map +1 -0
- package/dist/graph/compose-graph.d.ts +40 -0
- package/dist/graph/compose-graph.d.ts.map +1 -0
- package/dist/graph/compose-graph.js +30 -0
- package/dist/graph/compose-graph.js.map +1 -0
- package/dist/graph/effective-config.d.ts +36 -0
- package/dist/graph/effective-config.d.ts.map +1 -0
- package/dist/graph/effective-config.js +84 -0
- package/dist/graph/effective-config.js.map +1 -0
- package/dist/graph/id-conventions.d.ts +47 -0
- package/dist/graph/id-conventions.d.ts.map +1 -0
- package/dist/graph/id-conventions.js +78 -0
- package/dist/graph/id-conventions.js.map +1 -0
- package/dist/graph/index.d.ts +9 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/resolve-properties.d.ts +36 -0
- package/dist/graph/resolve-properties.d.ts.map +1 -0
- package/dist/graph/resolve-properties.js +141 -0
- package/dist/graph/resolve-properties.js.map +1 -0
- package/dist/graph/resolve-references.d.ts +14 -0
- package/dist/graph/resolve-references.d.ts.map +1 -0
- package/dist/graph/resolve-references.js +49 -0
- package/dist/graph/resolve-references.js.map +1 -0
- package/dist/graph/typed-value.d.ts +7 -0
- package/dist/graph/typed-value.d.ts.map +1 -0
- package/dist/graph/typed-value.js +43 -0
- package/dist/graph/typed-value.js.map +1 -0
- package/dist/graph/types.d.ts +34 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +2 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/graph/value-scope.d.ts +19 -0
- package/dist/graph/value-scope.d.ts.map +1 -0
- package/dist/graph/value-scope.js +30 -0
- package/dist/graph/value-scope.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/json-ld.d.ts +24 -0
- package/dist/json-ld.d.ts.map +1 -0
- package/dist/json-ld.js +24 -0
- package/dist/json-ld.js.map +1 -0
- package/dist/profiles/bing.d.ts +10 -0
- package/dist/profiles/bing.d.ts.map +1 -0
- package/dist/profiles/bing.js +13 -0
- package/dist/profiles/bing.js.map +1 -0
- package/dist/profiles/check.d.ts +11 -0
- package/dist/profiles/check.d.ts.map +1 -0
- package/dist/profiles/check.js +66 -0
- package/dist/profiles/check.js.map +1 -0
- package/dist/profiles/eligibility.d.ts +26 -0
- package/dist/profiles/eligibility.d.ts.map +1 -0
- package/dist/profiles/eligibility.js +49 -0
- package/dist/profiles/eligibility.js.map +1 -0
- package/dist/profiles/google.d.ts +4 -0
- package/dist/profiles/google.d.ts.map +1 -0
- package/dist/profiles/google.js +387 -0
- package/dist/profiles/google.js.map +1 -0
- package/dist/profiles/index.d.ts +10 -0
- package/dist/profiles/index.d.ts.map +1 -0
- package/dist/profiles/index.js +13 -0
- package/dist/profiles/index.js.map +1 -0
- package/dist/profiles/registry.d.ts +16 -0
- package/dist/profiles/registry.d.ts.map +1 -0
- package/dist/profiles/registry.js +66 -0
- package/dist/profiles/registry.js.map +1 -0
- package/dist/profiles/types.d.ts +29 -0
- package/dist/profiles/types.d.ts.map +1 -0
- package/dist/profiles/types.js +2 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/seo-graph.d.ts +39 -0
- package/dist/seo-graph.d.ts.map +1 -0
- package/dist/seo-graph.js +34 -0
- package/dist/seo-graph.js.map +1 -0
- package/dist/types/built-in/content.d.ts +12 -0
- package/dist/types/built-in/content.d.ts.map +1 -0
- package/dist/types/built-in/content.js +79 -0
- package/dist/types/built-in/content.js.map +1 -0
- package/dist/types/built-in/events.d.ts +23 -0
- package/dist/types/built-in/events.d.ts.map +1 -0
- package/dist/types/built-in/events.js +93 -0
- package/dist/types/built-in/events.js.map +1 -0
- package/dist/types/built-in/index.d.ts +4 -0
- package/dist/types/built-in/index.d.ts.map +1 -0
- package/dist/types/built-in/index.js +26 -0
- package/dist/types/built-in/index.js.map +1 -0
- package/dist/types/built-in/media.d.ts +21 -0
- package/dist/types/built-in/media.d.ts.map +1 -0
- package/dist/types/built-in/media.js +104 -0
- package/dist/types/built-in/media.js.map +1 -0
- package/dist/types/built-in/site.d.ts +14 -0
- package/dist/types/built-in/site.d.ts.map +1 -0
- package/dist/types/built-in/site.js +35 -0
- package/dist/types/built-in/site.js.map +1 -0
- package/dist/types/context.d.ts +26 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +44 -0
- package/dist/types/context.js.map +1 -0
- package/dist/types/definition.d.ts +58 -0
- package/dist/types/definition.d.ts.map +1 -0
- package/dist/types/definition.js +2 -0
- package/dist/types/definition.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/registry.d.ts +14 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +37 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/values.d.ts +23 -0
- package/dist/types/values.d.ts.map +1 -0
- package/dist/types/values.js +52 -0
- package/dist/types/values.js.map +1 -0
- package/dist/validate/check-terms.d.ts +15 -0
- package/dist/validate/check-terms.d.ts.map +1 -0
- package/dist/validate/check-terms.js +42 -0
- package/dist/validate/check-terms.js.map +1 -0
- package/dist/validate/check-value.d.ts +19 -0
- package/dist/validate/check-value.d.ts.map +1 -0
- package/dist/validate/check-value.js +77 -0
- package/dist/validate/check-value.js.map +1 -0
- package/dist/validate/graph-nodes.d.ts +22 -0
- package/dist/validate/graph-nodes.d.ts.map +1 -0
- package/dist/validate/graph-nodes.js +50 -0
- package/dist/validate/graph-nodes.js.map +1 -0
- package/dist/validate/index.d.ts +4 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +2 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/types.d.ts +22 -0
- package/dist/validate/types.d.ts.map +1 -0
- package/dist/validate/types.js +2 -0
- package/dist/validate/types.js.map +1 -0
- package/dist/validate/validate-graph.d.ts +18 -0
- package/dist/validate/validate-graph.d.ts.map +1 -0
- package/dist/validate/validate-graph.js +109 -0
- package/dist/validate/validate-graph.js.map +1 -0
- package/dist/vocabulary/datatypes.d.ts +7 -0
- package/dist/vocabulary/datatypes.d.ts.map +1 -0
- package/dist/vocabulary/datatypes.js +46 -0
- package/dist/vocabulary/datatypes.js.map +1 -0
- package/dist/vocabulary/index.d.ts +5 -0
- package/dist/vocabulary/index.d.ts.map +1 -0
- package/dist/vocabulary/index.js +4 -0
- package/dist/vocabulary/index.js.map +1 -0
- package/dist/vocabulary/schemaorg.generated.d.ts +4 -0
- package/dist/vocabulary/schemaorg.generated.d.ts.map +1 -0
- package/dist/vocabulary/schemaorg.generated.js +3038 -0
- package/dist/vocabulary/schemaorg.generated.js.map +1 -0
- package/dist/vocabulary/types.d.ts +38 -0
- package/dist/vocabulary/types.d.ts.map +1 -0
- package/dist/vocabulary/types.js +2 -0
- package/dist/vocabulary/types.js.map +1 -0
- package/dist/vocabulary/vocabulary.d.ts +28 -0
- package/dist/vocabulary/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary/vocabulary.js +89 -0
- package/dist/vocabulary/vocabulary.js.map +1 -0
- package/package.json +40 -3
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACvE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** How serious a finding is: errors make a graph non-conformant */
|
|
2
|
+
export type FindingSeverity = 'error' | 'warning' | 'info';
|
|
3
|
+
/** What a finding is about */
|
|
4
|
+
export type FindingCode = 'unresolved-reference' | 'duplicate-id' | 'missing-type' | 'unknown-type' | 'unknown-property' | 'property-not-in-domain' | 'value-out-of-range' | 'superseded-term' | 'retired-term' | 'pending-term' | 'profile-required' | 'profile-recommended' | 'profile-retired-feature' | 'profile-restricted-feature';
|
|
5
|
+
/** One result of validating a structured-data graph */
|
|
6
|
+
export interface Finding {
|
|
7
|
+
severity: FindingSeverity;
|
|
8
|
+
code: FindingCode;
|
|
9
|
+
/** The rule set that raised it: `schema.org` for the vocabulary, or a reader profile id */
|
|
10
|
+
profile: string;
|
|
11
|
+
/** The `@id` of the node the finding is about, when it has one */
|
|
12
|
+
nodeId?: string | undefined;
|
|
13
|
+
/** The node's type */
|
|
14
|
+
type?: string | undefined;
|
|
15
|
+
property?: string | undefined;
|
|
16
|
+
message: string;
|
|
17
|
+
/** Documentation the rule comes from */
|
|
18
|
+
source?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** A JSON-LD node: an object with `@type`, `@id` and properties */
|
|
21
|
+
export type GraphNode = Readonly<Record<string, unknown>>;
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validate/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE1D,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GACnB,sBAAsB,GACtB,cAAc,GACd,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,wBAAwB,GACxB,oBAAoB,GACpB,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,qBAAqB,GACrB,yBAAyB,GACzB,4BAA4B,CAAA;AAEhC,uDAAuD;AACvD,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,eAAe,CAAA;IACzB,IAAI,EAAE,WAAW,CAAA;IACjB,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B;AAED,mEAAmE;AACnE,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/validate/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JsonLdGraph } from '../graph/types.js';
|
|
2
|
+
import type { Finding, GraphNode } from './types.js';
|
|
3
|
+
/** What a graph is validated against beyond the Schema.org vocabulary */
|
|
4
|
+
export interface ValidateGraphOptions {
|
|
5
|
+
/** Reader profiles whose rules apply too, by id (`google`, `bing`, a site's own) */
|
|
6
|
+
readonly profiles?: readonly string[] | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Validate a JSON-LD graph against the pinned Schema.org vocabulary: every
|
|
10
|
+
* reference resolves within the graph to a node of a type the property
|
|
11
|
+
* accepts, no `@id` is defined twice, every node has a known, current type,
|
|
12
|
+
* every property is known, current and used on a type it belongs to, and
|
|
13
|
+
* every value is in the property's range. Superseded and retired terms are
|
|
14
|
+
* errors; pending terms are information. The rules of each requested reader
|
|
15
|
+
* profile are checked on every top-level node as well (see `profileFindings`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateGraph(graph: JsonLdGraph | GraphNode, options?: ValidateGraphOptions): Finding[];
|
|
18
|
+
//# sourceMappingURL=validate-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-graph.d.ts","sourceRoot":"","sources":["../../src/validate/validate-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQpD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAoFpD,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CAClD;AAUD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,EAC9B,OAAO,GAAE,oBAAyB,GACjC,OAAO,EAAE,CAgBX"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { profileFindings } from '../profiles/check.js';
|
|
2
|
+
import { getProfile } from '../profiles/registry.js';
|
|
3
|
+
import { getVocabularyProperty, getVocabularyType, isPropertyOfType } from '../vocabulary/index.js';
|
|
4
|
+
import { termFindings } from './check-terms.js';
|
|
5
|
+
import { valueFindings } from './check-value.js';
|
|
6
|
+
import { allNodes, asList, idOf, propertyEntries, topLevelNodes, typesOf } from './graph-nodes.js';
|
|
7
|
+
function contextOf(node) {
|
|
8
|
+
return { nodeId: idOf(node), type: typesOf(node).join(', ') || undefined };
|
|
9
|
+
}
|
|
10
|
+
/** Every node defined twice under one `@id`, and the definitions by `@id` */
|
|
11
|
+
function indexDefinitions(nodes) {
|
|
12
|
+
const definitions = new Map();
|
|
13
|
+
const findings = [];
|
|
14
|
+
for (const node of nodes) {
|
|
15
|
+
const id = idOf(node);
|
|
16
|
+
if (id === undefined)
|
|
17
|
+
continue;
|
|
18
|
+
if (definitions.has(id)) {
|
|
19
|
+
const message = `"${id}" is defined by more than one node.`;
|
|
20
|
+
findings.push({
|
|
21
|
+
...contextOf(node),
|
|
22
|
+
severity: 'error',
|
|
23
|
+
code: 'duplicate-id',
|
|
24
|
+
profile: 'schema.org',
|
|
25
|
+
message,
|
|
26
|
+
});
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
definitions.set(id, node);
|
|
30
|
+
}
|
|
31
|
+
return { definitions, findings };
|
|
32
|
+
}
|
|
33
|
+
/** The node's types: present, known to the vocabulary, and current */
|
|
34
|
+
function typeFindings(node) {
|
|
35
|
+
const context = contextOf(node);
|
|
36
|
+
const types = typesOf(node);
|
|
37
|
+
if (types.length === 0) {
|
|
38
|
+
const message = 'A node has no "@type".';
|
|
39
|
+
return [{ ...context, severity: 'error', code: 'missing-type', profile: 'schema.org', message }];
|
|
40
|
+
}
|
|
41
|
+
return types.flatMap((type) => {
|
|
42
|
+
if (getVocabularyType(type))
|
|
43
|
+
return termFindings('Type', type, context);
|
|
44
|
+
const message = `Type "${type}" is not in the Schema.org vocabulary.`;
|
|
45
|
+
return [{ ...context, severity: 'error', code: 'unknown-type', profile: 'schema.org', message }];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/** One property of a node: known, current, used on a type it belongs to, values in range */
|
|
49
|
+
function propertyFindings(node, property, value, definitions) {
|
|
50
|
+
const context = { ...contextOf(node), property };
|
|
51
|
+
if (!getVocabularyProperty(property)) {
|
|
52
|
+
const message = `Property "${property}" is not in the Schema.org vocabulary.`;
|
|
53
|
+
return [
|
|
54
|
+
{ ...context, severity: 'error', code: 'unknown-property', profile: 'schema.org', message },
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
const findings = termFindings('Property', property, context);
|
|
58
|
+
const known = typesOf(node).filter((type) => getVocabularyType(type));
|
|
59
|
+
if (known.length > 0 && !known.some((type) => isPropertyOfType(property, type))) {
|
|
60
|
+
const message = `Property "${property}" is not defined for ${known.join(', ')}.`;
|
|
61
|
+
findings.push({
|
|
62
|
+
...context,
|
|
63
|
+
severity: 'warning',
|
|
64
|
+
code: 'property-not-in-domain',
|
|
65
|
+
profile: 'schema.org',
|
|
66
|
+
message,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
for (const item of asList(value)) {
|
|
70
|
+
findings.push(...valueFindings(item, { where: context, definitions }));
|
|
71
|
+
}
|
|
72
|
+
return findings;
|
|
73
|
+
}
|
|
74
|
+
function profilesOf(ids) {
|
|
75
|
+
return ids.map((id) => {
|
|
76
|
+
const profile = getProfile(id);
|
|
77
|
+
if (!profile)
|
|
78
|
+
throw new Error(`validateGraph: no reader profile "${id}" is registered.`);
|
|
79
|
+
return profile;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate a JSON-LD graph against the pinned Schema.org vocabulary: every
|
|
84
|
+
* reference resolves within the graph to a node of a type the property
|
|
85
|
+
* accepts, no `@id` is defined twice, every node has a known, current type,
|
|
86
|
+
* every property is known, current and used on a type it belongs to, and
|
|
87
|
+
* every value is in the property's range. Superseded and retired terms are
|
|
88
|
+
* errors; pending terms are information. The rules of each requested reader
|
|
89
|
+
* profile are checked on every top-level node as well (see `profileFindings`).
|
|
90
|
+
*/
|
|
91
|
+
export function validateGraph(graph, options = {}) {
|
|
92
|
+
const readers = profilesOf(options.profiles ?? []);
|
|
93
|
+
const root = { ...graph };
|
|
94
|
+
const nodes = allNodes(root);
|
|
95
|
+
const { definitions, findings } = indexDefinitions(nodes);
|
|
96
|
+
for (const node of nodes) {
|
|
97
|
+
findings.push(...typeFindings(node));
|
|
98
|
+
for (const [property, value] of propertyEntries(node)) {
|
|
99
|
+
findings.push(...propertyFindings(node, property, value, definitions));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Readers' rules are about the entities a page states, not their nested parts
|
|
103
|
+
for (const node of topLevelNodes(root)) {
|
|
104
|
+
for (const profile of readers)
|
|
105
|
+
findings.push(...profileFindings(node, profile));
|
|
106
|
+
}
|
|
107
|
+
return findings;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=validate-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-graph.js","sourceRoot":"","sources":["../../src/validate/validate-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON value checks for Schema.org data types. A data type absent here
|
|
3
|
+
* (CssSelectorType, XPathType, PronounceableText) is text.
|
|
4
|
+
*/
|
|
5
|
+
/** Whether a JSON value is a valid literal of the Schema.org data type */
|
|
6
|
+
export declare function matchesDatatype(datatype: string, value: unknown): boolean;
|
|
7
|
+
//# sourceMappingURL=datatypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datatypes.d.ts","sourceRoot":"","sources":["../../src/vocabulary/datatypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0CH,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON value checks for Schema.org data types. A data type absent here
|
|
3
|
+
* (CssSelectorType, XPathType, PronounceableText) is text.
|
|
4
|
+
*/
|
|
5
|
+
const DATE = /^\d{4}(-\d{2}(-\d{2})?)?$/;
|
|
6
|
+
const TIME = /^\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
|
7
|
+
const DATE_TIME = /^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/;
|
|
8
|
+
const BOOLEAN_TEXT = new Set([
|
|
9
|
+
'true',
|
|
10
|
+
'false',
|
|
11
|
+
'True',
|
|
12
|
+
'False',
|
|
13
|
+
'https://schema.org/True',
|
|
14
|
+
'https://schema.org/False',
|
|
15
|
+
]);
|
|
16
|
+
function isAbsoluteUrl(value) {
|
|
17
|
+
if (!URL.canParse(value))
|
|
18
|
+
return false;
|
|
19
|
+
const { protocol } = new URL(value);
|
|
20
|
+
return protocol === 'http:' || protocol === 'https:';
|
|
21
|
+
}
|
|
22
|
+
function isNumeric(value) {
|
|
23
|
+
if (typeof value === 'number')
|
|
24
|
+
return Number.isFinite(value);
|
|
25
|
+
return typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value));
|
|
26
|
+
}
|
|
27
|
+
function isInteger(value) {
|
|
28
|
+
return isNumeric(value) && Number.isInteger(Number(value));
|
|
29
|
+
}
|
|
30
|
+
const CHECKS = {
|
|
31
|
+
Text: (value) => typeof value === 'string',
|
|
32
|
+
URL: (value) => typeof value === 'string' && isAbsoluteUrl(value),
|
|
33
|
+
Date: (value) => typeof value === 'string' && DATE.test(value),
|
|
34
|
+
DateTime: (value) => typeof value === 'string' && DATE_TIME.test(value),
|
|
35
|
+
Time: (value) => typeof value === 'string' && TIME.test(value),
|
|
36
|
+
Number: isNumeric,
|
|
37
|
+
Float: isNumeric,
|
|
38
|
+
Integer: isInteger,
|
|
39
|
+
Boolean: (value) => typeof value === 'boolean' || (typeof value === 'string' && BOOLEAN_TEXT.has(value)),
|
|
40
|
+
};
|
|
41
|
+
/** Whether a JSON value is a valid literal of the Schema.org data type */
|
|
42
|
+
export function matchesDatatype(datatype, value) {
|
|
43
|
+
const check = CHECKS[datatype] ?? CHECKS['Text'];
|
|
44
|
+
return check?.(value) ?? false;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=datatypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datatypes.js","sourceRoot":"","sources":["../../src/vocabulary/datatypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,IAAI,GAAG,2BAA2B,CAAA;AACxC,MAAM,IAAI,GAAG,qDAAqD,CAAA;AAClE,MAAM,SAAS,GAAG,6EAA6E,CAAA;AAC/F,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,yBAAyB;IACzB,0BAA0B;CAC3B,CAAC,CAAA;AAEF,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACtC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IACnC,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,CAAA;AACtD,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC5D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAC3F,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED,MAAM,MAAM,GAA0D;IACpE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ;IAC1C,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,KAAK,CAAC;IACjE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9D,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;IACvE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9D,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACvF,CAAA;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,KAAc;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;IAChD,OAAO,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { matchesDatatype } from './datatypes.js';
|
|
2
|
+
export { SCHEMAORG_RELEASE } from './schemaorg.generated.js';
|
|
3
|
+
export type { Lifecycle, VocabularyData, VocabularyMember, VocabularyProperty, VocabularyType, } from './types.js';
|
|
4
|
+
export { ancestorsOf, enumerationsOf, getVocabularyProperty, getVocabularyType, isDatatype, isEnumeration, isPropertyOfType, isSubtypeOf, isVocabularyTerm, lifecycleOf, propertiesOf, rangeAcceptsType, termName, } from './vocabulary.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vocabulary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { matchesDatatype } from './datatypes.js';
|
|
2
|
+
export { SCHEMAORG_RELEASE } from './schemaorg.generated.js';
|
|
3
|
+
export { ancestorsOf, enumerationsOf, getVocabularyProperty, getVocabularyType, isDatatype, isEnumeration, isPropertyOfType, isSubtypeOf, isVocabularyTerm, lifecycleOf, propertiesOf, rangeAcceptsType, termName, } from './vocabulary.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vocabulary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAQ5D,OAAO,EACL,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaorg.generated.d.ts","sourceRoot":"","sources":["../../src/vocabulary/schemaorg.generated.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,eAAO,MAAM,iBAAiB,SAAS,CAAA;AAEvC,eAAO,MAAM,UAAU,EAAE,cA29FxB,CAAA"}
|