agentfootprint 9.111.0 → 9.112.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.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * ontology/skosJsonLd — the JSON-LD spellings a SKOS document uses, resolved
3
+ * to IRIs with no inference.
4
+ *
5
+ * Pattern: pure functions over an already-parsed JSON-LD document; a
6
+ * zero-import leaf under `fromSkos.ts`.
7
+ * Role: Map (reader side). A key is resolved by the document's own
8
+ * `@context` when it has one — a term mapping, a prefix, `@vocab` —
9
+ * else by the fixed table of the vocabularies SKOS documents lean on
10
+ * (`skos:`, `dcterms:`, `owl:`, `schema:`, `footprint:`). A full IRI
11
+ * is itself. A bare key no context maps is NOT a SKOS property: it
12
+ * is left unresolved, never guessed from its spelling.
13
+ * Emits: N/A.
14
+ *
15
+ * Out of scope, by the owner's ruling (2026-09-18): a Turtle parser (the
16
+ * input is an OBJECT), remote `@context` fetching (a context given by URL is
17
+ * not resolved), OWL.
18
+ */
19
+ /** The SKOS core namespace. */
20
+ export declare const SKOS_NS = "http://www.w3.org/2004/02/skos/core#";
21
+ /** The OWL namespace — read for `owl:versionInfo` only; OWL itself is out of scope. */
22
+ export declare const OWL_NS = "http://www.w3.org/2002/07/owl#";
23
+ /** Our own namespace for what SKOS cannot say: units, sources, tools, coverage, other relations. */
24
+ export declare const FOOTPRINT_NS = "https://footprintjs.dev/ns/ontology#";
25
+ /** The prefixes the reader knows without a context — the fixed table. */
26
+ export declare const KNOWN_PREFIXES: Readonly<Record<string, string>>;
27
+ /** The IRIs the reader looks at, by name. */
28
+ export declare const SKOS: Readonly<{
29
+ readonly Concept: "http://www.w3.org/2004/02/skos/core#Concept";
30
+ readonly ConceptScheme: "http://www.w3.org/2004/02/skos/core#ConceptScheme";
31
+ readonly prefLabel: "http://www.w3.org/2004/02/skos/core#prefLabel";
32
+ readonly altLabel: "http://www.w3.org/2004/02/skos/core#altLabel";
33
+ readonly hiddenLabel: "http://www.w3.org/2004/02/skos/core#hiddenLabel";
34
+ readonly definition: "http://www.w3.org/2004/02/skos/core#definition";
35
+ readonly scopeNote: "http://www.w3.org/2004/02/skos/core#scopeNote";
36
+ readonly broader: "http://www.w3.org/2004/02/skos/core#broader";
37
+ readonly narrower: "http://www.w3.org/2004/02/skos/core#narrower";
38
+ readonly related: "http://www.w3.org/2004/02/skos/core#related";
39
+ readonly inScheme: "http://www.w3.org/2004/02/skos/core#inScheme";
40
+ readonly topConceptOf: "http://www.w3.org/2004/02/skos/core#topConceptOf";
41
+ readonly hasTopConcept: "http://www.w3.org/2004/02/skos/core#hasTopConcept";
42
+ }>;
43
+ /** Where a scheme's version may be written, in the order the reader looks. */
44
+ export declare const VERSION_IRIS: readonly string[];
45
+ /** The `footprint:` properties `toSkos` writes and `readSkos` reads back. */
46
+ export declare const FOOTPRINT: Readonly<{
47
+ readonly unit: "https://footprintjs.dev/ns/ontology#unit";
48
+ readonly edge: "https://footprintjs.dev/ns/ontology#edge";
49
+ readonly to: "https://footprintjs.dev/ns/ontology#to";
50
+ readonly relation: "https://footprintjs.dev/ns/ontology#relation";
51
+ readonly meaning: "https://footprintjs.dev/ns/ontology#meaning";
52
+ }>;
53
+ export type JsonLdNode = Readonly<Record<string, unknown>>;
54
+ /** A resolved `@context`: term → IRI, prefix → IRI, an optional `@vocab` and default `@language`. */
55
+ export interface SkosContext {
56
+ readonly terms: ReadonlyMap<string, string>;
57
+ readonly prefixes: ReadonlyMap<string, string>;
58
+ readonly vocab?: string;
59
+ readonly language?: string;
60
+ }
61
+ export declare function isRecord(value: unknown): value is JsonLdNode;
62
+ /**
63
+ * Read a `@context` (an object, an array of objects, or a URL — the last
64
+ * is not fetched). A term whose value is a string or `{ "@id": … }` maps
65
+ * to that IRI; a term whose value ends in `#` or `/` is also a prefix.
66
+ */
67
+ export declare function readContext(context: unknown): SkosContext;
68
+ /**
69
+ * Resolve a key or a `@type` / `@id` value to an IRI: a keyword stays a
70
+ * keyword; a term the context maps; `prefix:local`; a full IRI; a bare
71
+ * name under `@vocab`. Anything else stays as written (a bare literal),
72
+ * which no SKOS IRI ever equals — so it is ignored, not misread.
73
+ */
74
+ export declare function expandIri(value: string, context: SkosContext): string;
75
+ /** A node's properties keyed by expanded IRI (keywords keep their `@` names). */
76
+ export declare function expandNode(node: JsonLdNode, context: SkosContext): ReadonlyMap<string, unknown>;
77
+ /** Every value under a property as a flat list (`@list`, arrays and singles alike). */
78
+ export declare function valuesOf(node: ReadonlyMap<string, unknown>, iri: string): readonly unknown[];
79
+ /** The `@type` IRIs of a node. */
80
+ export declare function typesOf(node: ReadonlyMap<string, unknown>, context: SkosContext): readonly string[];
81
+ /** A language-tagged or plain literal. */
82
+ export interface Literal {
83
+ readonly value: string;
84
+ readonly language?: string;
85
+ }
86
+ /** The literals under a property: plain strings, numbers and `{ "@value", "@language"? }` objects. */
87
+ export declare function literalsOf(node: ReadonlyMap<string, unknown>, iri: string, context: SkosContext): readonly Literal[];
88
+ /** The IRIs a property points at: strings (resolved) and `{ "@id": … }` objects. */
89
+ export declare function irisOf(node: ReadonlyMap<string, unknown>, iri: string, context: SkosContext): readonly string[];
90
+ /**
91
+ * The literal in the asked language: a label TAGGED with it wins; a label
92
+ * with no tag at all serves any language (it is not tagged as another);
93
+ * a label tagged with a different language is never taken. Tags compare
94
+ * case-insensitively and exactly (`en` is not `en-US`).
95
+ */
96
+ export declare function inLanguage(literals: readonly Literal[], language: string): readonly string[];
97
+ /**
98
+ * A concept id from its IRI: the last `/` or `#` segment, percent-decoded,
99
+ * lower-cased, `-` and spaces to `_`. Empty when the IRI ends in a delimiter.
100
+ */
101
+ export declare function idFromIri(iri: string): string;
@@ -0,0 +1,219 @@
1
+ /**
2
+ * ontology/skosJsonLd — the JSON-LD spellings a SKOS document uses, resolved
3
+ * to IRIs with no inference.
4
+ *
5
+ * Pattern: pure functions over an already-parsed JSON-LD document; a
6
+ * zero-import leaf under `fromSkos.ts`.
7
+ * Role: Map (reader side). A key is resolved by the document's own
8
+ * `@context` when it has one — a term mapping, a prefix, `@vocab` —
9
+ * else by the fixed table of the vocabularies SKOS documents lean on
10
+ * (`skos:`, `dcterms:`, `owl:`, `schema:`, `footprint:`). A full IRI
11
+ * is itself. A bare key no context maps is NOT a SKOS property: it
12
+ * is left unresolved, never guessed from its spelling.
13
+ * Emits: N/A.
14
+ *
15
+ * Out of scope, by the owner's ruling (2026-09-18): a Turtle parser (the
16
+ * input is an OBJECT), remote `@context` fetching (a context given by URL is
17
+ * not resolved), OWL.
18
+ */
19
+ /** The SKOS core namespace. */
20
+ export const SKOS_NS = 'http://www.w3.org/2004/02/skos/core#';
21
+ /** The OWL namespace — read for `owl:versionInfo` only; OWL itself is out of scope. */
22
+ export const OWL_NS = 'http://www.w3.org/2002/07/owl#';
23
+ /** Our own namespace for what SKOS cannot say: units, sources, tools, coverage, other relations. */
24
+ export const FOOTPRINT_NS = 'https://footprintjs.dev/ns/ontology#';
25
+ /** The prefixes the reader knows without a context — the fixed table. */
26
+ export const KNOWN_PREFIXES = Object.freeze({
27
+ skos: SKOS_NS,
28
+ dcterms: 'http://purl.org/dc/terms/',
29
+ dct: 'http://purl.org/dc/terms/',
30
+ owl: OWL_NS,
31
+ rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
32
+ rdfs: 'http://www.w3.org/2000/01/rdf-schema#',
33
+ xsd: 'http://www.w3.org/2001/XMLSchema#',
34
+ schema: 'https://schema.org/',
35
+ footprint: FOOTPRINT_NS,
36
+ });
37
+ /** The IRIs the reader looks at, by name. */
38
+ export const SKOS = Object.freeze({
39
+ Concept: `${SKOS_NS}Concept`,
40
+ ConceptScheme: `${SKOS_NS}ConceptScheme`,
41
+ prefLabel: `${SKOS_NS}prefLabel`,
42
+ altLabel: `${SKOS_NS}altLabel`,
43
+ hiddenLabel: `${SKOS_NS}hiddenLabel`,
44
+ definition: `${SKOS_NS}definition`,
45
+ scopeNote: `${SKOS_NS}scopeNote`,
46
+ broader: `${SKOS_NS}broader`,
47
+ narrower: `${SKOS_NS}narrower`,
48
+ related: `${SKOS_NS}related`,
49
+ inScheme: `${SKOS_NS}inScheme`,
50
+ topConceptOf: `${SKOS_NS}topConceptOf`,
51
+ hasTopConcept: `${SKOS_NS}hasTopConcept`,
52
+ });
53
+ /** Where a scheme's version may be written, in the order the reader looks. */
54
+ export const VERSION_IRIS = Object.freeze([
55
+ 'http://purl.org/dc/terms/modified',
56
+ `${OWL_NS}versionInfo`,
57
+ 'https://schema.org/version',
58
+ 'http://schema.org/version',
59
+ ]);
60
+ /** The `footprint:` properties `toSkos` writes and `readSkos` reads back. */
61
+ export const FOOTPRINT = Object.freeze({
62
+ unit: `${FOOTPRINT_NS}unit`,
63
+ edge: `${FOOTPRINT_NS}edge`,
64
+ to: `${FOOTPRINT_NS}to`,
65
+ relation: `${FOOTPRINT_NS}relation`,
66
+ meaning: `${FOOTPRINT_NS}meaning`,
67
+ });
68
+ export function isRecord(value) {
69
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
70
+ }
71
+ function isAbsoluteIri(value) {
72
+ return /^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(value) || value.startsWith('urn:');
73
+ }
74
+ /**
75
+ * Read a `@context` (an object, an array of objects, or a URL — the last
76
+ * is not fetched). A term whose value is a string or `{ "@id": … }` maps
77
+ * to that IRI; a term whose value ends in `#` or `/` is also a prefix.
78
+ */
79
+ export function readContext(context) {
80
+ const terms = new Map();
81
+ const prefixes = new Map(Object.entries(KNOWN_PREFIXES));
82
+ let vocab;
83
+ let language;
84
+ const parts = Array.isArray(context) ? context : [context];
85
+ for (const part of parts) {
86
+ if (!isRecord(part))
87
+ continue;
88
+ for (const [key, raw] of Object.entries(part)) {
89
+ if (key === '@vocab' && typeof raw === 'string')
90
+ vocab = raw;
91
+ else if (key === '@language' && typeof raw === 'string')
92
+ language = raw;
93
+ else if (key.startsWith('@'))
94
+ continue;
95
+ else {
96
+ const iri = typeof raw === 'string' ? raw : isRecord(raw) ? raw['@id'] : undefined;
97
+ if (typeof iri !== 'string')
98
+ continue;
99
+ const expanded = expandCompact(iri, prefixes) ?? iri;
100
+ terms.set(key, expanded);
101
+ if (expanded.endsWith('#') || expanded.endsWith('/'))
102
+ prefixes.set(key, expanded);
103
+ }
104
+ }
105
+ }
106
+ return { terms, prefixes, ...(vocab && { vocab }), ...(language && { language }) };
107
+ }
108
+ /** `prefix:local` → IRI when the prefix is known; else undefined. */
109
+ function expandCompact(value, prefixes) {
110
+ const colon = value.indexOf(':');
111
+ if (colon <= 0 || isAbsoluteIri(value))
112
+ return undefined;
113
+ const base = prefixes.get(value.slice(0, colon));
114
+ return base === undefined ? undefined : base + value.slice(colon + 1);
115
+ }
116
+ /**
117
+ * Resolve a key or a `@type` / `@id` value to an IRI: a keyword stays a
118
+ * keyword; a term the context maps; `prefix:local`; a full IRI; a bare
119
+ * name under `@vocab`. Anything else stays as written (a bare literal),
120
+ * which no SKOS IRI ever equals — so it is ignored, not misread.
121
+ */
122
+ export function expandIri(value, context) {
123
+ if (value.startsWith('@'))
124
+ return value;
125
+ const term = context.terms.get(value);
126
+ if (term !== undefined)
127
+ return term;
128
+ const compact = expandCompact(value, context.prefixes);
129
+ if (compact !== undefined)
130
+ return compact;
131
+ if (isAbsoluteIri(value))
132
+ return value;
133
+ if (context.vocab !== undefined && !value.includes(':'))
134
+ return context.vocab + value;
135
+ return value;
136
+ }
137
+ /** A node's properties keyed by expanded IRI (keywords keep their `@` names). */
138
+ export function expandNode(node, context) {
139
+ const out = new Map();
140
+ for (const [key, value] of Object.entries(node))
141
+ out.set(expandIri(key, context), value);
142
+ return out;
143
+ }
144
+ /** Every value under a property as a flat list (`@list`, arrays and singles alike). */
145
+ export function valuesOf(node, iri) {
146
+ const raw = node.get(iri);
147
+ if (raw === undefined || raw === null)
148
+ return [];
149
+ if (Array.isArray(raw))
150
+ return raw;
151
+ if (isRecord(raw) && Array.isArray(raw['@list']))
152
+ return raw['@list'];
153
+ return [raw];
154
+ }
155
+ /** The `@type` IRIs of a node. */
156
+ export function typesOf(node, context) {
157
+ return valuesOf(node, '@type')
158
+ .filter((t) => typeof t === 'string')
159
+ .map((t) => expandIri(t, context));
160
+ }
161
+ /** The literals under a property: plain strings, numbers and `{ "@value", "@language"? }` objects. */
162
+ export function literalsOf(node, iri, context) {
163
+ const out = [];
164
+ for (const raw of valuesOf(node, iri)) {
165
+ if (typeof raw === 'string' || typeof raw === 'number') {
166
+ out.push({ value: String(raw), ...(context.language && { language: context.language }) });
167
+ }
168
+ else if (isRecord(raw) &&
169
+ (typeof raw['@value'] === 'string' || typeof raw['@value'] === 'number')) {
170
+ const language = typeof raw['@language'] === 'string' ? raw['@language'] : context.language;
171
+ out.push({ value: String(raw['@value']), ...(language && { language }) });
172
+ }
173
+ }
174
+ return out;
175
+ }
176
+ /** The IRIs a property points at: strings (resolved) and `{ "@id": … }` objects. */
177
+ export function irisOf(node, iri, context) {
178
+ const out = [];
179
+ for (const raw of valuesOf(node, iri)) {
180
+ if (typeof raw === 'string')
181
+ out.push(expandIri(raw, context));
182
+ else if (isRecord(raw) && typeof raw['@id'] === 'string')
183
+ out.push(expandIri(raw['@id'], context));
184
+ }
185
+ return out;
186
+ }
187
+ /**
188
+ * The literal in the asked language: a label TAGGED with it wins; a label
189
+ * with no tag at all serves any language (it is not tagged as another);
190
+ * a label tagged with a different language is never taken. Tags compare
191
+ * case-insensitively and exactly (`en` is not `en-US`).
192
+ */
193
+ export function inLanguage(literals, language) {
194
+ const wanted = language.toLowerCase();
195
+ const tagged = literals.filter((l) => l.language?.toLowerCase() === wanted);
196
+ const untagged = literals.filter((l) => l.language === undefined);
197
+ return [...tagged, ...untagged].map((l) => l.value);
198
+ }
199
+ /**
200
+ * A concept id from its IRI: the last `/` or `#` segment, percent-decoded,
201
+ * lower-cased, `-` and spaces to `_`. Empty when the IRI ends in a delimiter.
202
+ */
203
+ export function idFromIri(iri) {
204
+ const stripped = iri.replace(/[?].*$/, '');
205
+ const last = Math.max(stripped.lastIndexOf('/'), stripped.lastIndexOf('#'));
206
+ const segment = last < 0 ? stripped : stripped.slice(last + 1);
207
+ let decoded = segment;
208
+ try {
209
+ decoded = decodeURIComponent(segment);
210
+ }
211
+ catch {
212
+ // Not percent-encoded: the segment is used as written.
213
+ }
214
+ return decoded
215
+ .trim()
216
+ .toLowerCase()
217
+ .replace(/[-\s]+/g, '_');
218
+ }
219
+ //# sourceMappingURL=skosJsonLd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skosJsonLd.js","sourceRoot":"","sources":["../../../src/ontology/skosJsonLd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ontology/toSkos — the reverse walk: our map written as a SKOS concept
3
+ * scheme in JSON-LD, with what SKOS cannot say in a `footprint:` namespace
4
+ * declared in the `@context`, so nothing of ours is lost.
5
+ *
6
+ * Pattern: one pure function over an `OntologySpec`; the twin of
7
+ * `fromSkos.ts · readSkos`, pinned as a round trip
8
+ * (`readSkos(toSkos(spec))` ≡ the spec's terms and edges).
9
+ * Role: Map. A term becomes a `skos:Concept` (prefLabel = id, definition
10
+ * = meaning, altLabel = aliases, `footprint:unit`); `is-a` becomes
11
+ * `skos:broader`, `related` becomes `skos:related`, every other
12
+ * relation — and any edge carrying a `meaning` — becomes a
13
+ * `footprint:edge`; a source becomes a `footprint:Source` node and
14
+ * a holding a `footprint:heldBy` entry (source, via, coverage).
15
+ * The scheme node carries the version as `owl:versionInfo`.
16
+ * Emits: N/A.
17
+ *
18
+ * NOT serving: the model is still served `serve.ts · ontologyPiece`; this
19
+ * is an export for a host that keeps its taxonomy in SKOS (the owner's
20
+ * ruling: serving in SKOS vocabulary waits for the bench).
21
+ */
22
+ import type { OntologySpec } from './types.js';
23
+ /** The base every IRI `toSkos` mints hangs off: `<base><id>` for the scheme, `<base><id>#<term>` for a concept. */
24
+ export declare const SKOS_IRI_BASE = "https://footprintjs.dev/ontology/";
25
+ export interface ToSkosOptions {
26
+ /** The `@language` every label and definition is tagged with (default `'en'`). */
27
+ readonly language?: string;
28
+ }
29
+ /** A JSON-LD document: `@context` + `@graph`. */
30
+ export interface SkosDocument {
31
+ readonly '@context': Readonly<Record<string, string>>;
32
+ readonly '@graph': readonly Readonly<Record<string, unknown>>[];
33
+ }
34
+ /** Write the map as a SKOS concept scheme in JSON-LD. Pure: same spec, same document. */
35
+ export declare function toSkos(spec: OntologySpec, options?: ToSkosOptions): SkosDocument;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * ontology/toSkos — the reverse walk: our map written as a SKOS concept
3
+ * scheme in JSON-LD, with what SKOS cannot say in a `footprint:` namespace
4
+ * declared in the `@context`, so nothing of ours is lost.
5
+ *
6
+ * Pattern: one pure function over an `OntologySpec`; the twin of
7
+ * `fromSkos.ts · readSkos`, pinned as a round trip
8
+ * (`readSkos(toSkos(spec))` ≡ the spec's terms and edges).
9
+ * Role: Map. A term becomes a `skos:Concept` (prefLabel = id, definition
10
+ * = meaning, altLabel = aliases, `footprint:unit`); `is-a` becomes
11
+ * `skos:broader`, `related` becomes `skos:related`, every other
12
+ * relation — and any edge carrying a `meaning` — becomes a
13
+ * `footprint:edge`; a source becomes a `footprint:Source` node and
14
+ * a holding a `footprint:heldBy` entry (source, via, coverage).
15
+ * The scheme node carries the version as `owl:versionInfo`.
16
+ * Emits: N/A.
17
+ *
18
+ * NOT serving: the model is still served `serve.ts · ontologyPiece`; this
19
+ * is an export for a host that keeps its taxonomy in SKOS (the owner's
20
+ * ruling: serving in SKOS vocabulary waits for the bench).
21
+ */
22
+ import { FOOTPRINT_NS, OWL_NS, SKOS_NS } from './skosJsonLd.js';
23
+ /** The base every IRI `toSkos` mints hangs off: `<base><id>` for the scheme, `<base><id>#<term>` for a concept. */
24
+ export const SKOS_IRI_BASE = 'https://footprintjs.dev/ontology/';
25
+ const CONTEXT = Object.freeze({
26
+ skos: SKOS_NS,
27
+ owl: OWL_NS,
28
+ footprint: FOOTPRINT_NS,
29
+ });
30
+ /** Write the map as a SKOS concept scheme in JSON-LD. Pure: same spec, same document. */
31
+ export function toSkos(spec, options = {}) {
32
+ const language = options.language ?? 'en';
33
+ const schemeIri = `${SKOS_IRI_BASE}${spec.id}`;
34
+ const conceptIri = (id) => `${schemeIri}#${id}`;
35
+ const sourceIri = (id) => `${schemeIri}/sources/${id}`;
36
+ const edges = spec.edges ?? [];
37
+ const nodeIds = Object.keys(spec.nodes).sort();
38
+ const literal = (value) => ({
39
+ '@value': value,
40
+ '@language': language,
41
+ });
42
+ const concepts = nodeIds.map((id) => {
43
+ const node = spec.nodes[id];
44
+ const outgoing = edges.filter((e) => e.from === id);
45
+ const broader = outgoing
46
+ .filter((e) => e.relation === 'is-a')
47
+ .map((e) => ({ '@id': conceptIri(e.to) }));
48
+ const related = outgoing
49
+ .filter((e) => e.relation === 'related')
50
+ .map((e) => ({ '@id': conceptIri(e.to) }));
51
+ const declared = outgoing.filter(needsFootprintEdge).map((e) => ({
52
+ 'footprint:to': { '@id': conceptIri(e.to) },
53
+ 'footprint:relation': e.relation,
54
+ ...(e.meaning !== undefined && { 'footprint:meaning': e.meaning }),
55
+ }));
56
+ const heldBy = (node.sources ?? []).map((held) => ({
57
+ 'footprint:source': { '@id': sourceIri(held.source) },
58
+ ...(held.via !== undefined && { 'footprint:via': [...held.via] }),
59
+ ...(held.coverage !== undefined && { 'footprint:coverage': held.coverage }),
60
+ }));
61
+ return {
62
+ '@id': conceptIri(id),
63
+ '@type': 'skos:Concept',
64
+ 'skos:inScheme': { '@id': schemeIri },
65
+ 'skos:prefLabel': literal(id),
66
+ 'skos:definition': literal(node.meaning),
67
+ ...(node.aliases !== undefined &&
68
+ node.aliases.length > 0 && { 'skos:altLabel': node.aliases.map(literal) }),
69
+ ...(broader.length > 0 && { 'skos:broader': broader }),
70
+ ...(related.length > 0 && { 'skos:related': related }),
71
+ ...(node.unit !== undefined && { 'footprint:unit': node.unit }),
72
+ ...(declared.length > 0 && { 'footprint:edge': declared }),
73
+ ...(heldBy.length > 0 && { 'footprint:heldBy': heldBy }),
74
+ };
75
+ });
76
+ const sources = Object.keys(spec.sources)
77
+ .sort()
78
+ .map((id) => {
79
+ const source = spec.sources[id];
80
+ return {
81
+ '@id': sourceIri(id),
82
+ '@type': 'footprint:Source',
83
+ 'footprint:meaning': source.meaning,
84
+ ...(source.coverage !== undefined && { 'footprint:coverage': source.coverage }),
85
+ ...(source.configured !== undefined && { 'footprint:configured': source.configured }),
86
+ ...(source.aliases !== undefined &&
87
+ source.aliases.length > 0 && { 'footprint:aliases': [...source.aliases] }),
88
+ };
89
+ });
90
+ const topConcepts = nodeIds
91
+ .filter((id) => !edges.some((e) => e.from === id && e.relation === 'is-a'))
92
+ .map((id) => ({ '@id': conceptIri(id) }));
93
+ const scheme = {
94
+ '@id': schemeIri,
95
+ '@type': 'skos:ConceptScheme',
96
+ 'owl:versionInfo': spec.version,
97
+ ...(topConcepts.length > 0 && { 'skos:hasTopConcept': topConcepts }),
98
+ };
99
+ return { '@context': CONTEXT, '@graph': [scheme, ...concepts, ...sources] };
100
+ }
101
+ /** An edge SKOS cannot carry whole: another relation, or an `is-a`/`related` with a meaning. */
102
+ function needsFootprintEdge(edge) {
103
+ return (edge.relation !== 'is-a' && edge.relation !== 'related') || edge.meaning !== undefined;
104
+ }
105
+ //# sourceMappingURL=toSkos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toSkos.js","sourceRoot":"","sources":["../../../src/ontology/toSkos.ts"],"names":[],"mappings":"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"}