glossarist 0.4.48 → 0.4.50
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/package.json +1 -1
- package/src/concept-collection.ts +7 -1
- package/src/concept-parser.ts +7 -1
- package/src/concept-reader.ts +4 -3
- package/src/concept-serializer.ts +12 -1
- package/src/concept-writer.ts +5 -1
- package/src/diff/collection-diff.ts +49 -1
- package/src/diff/concept-diff.ts +152 -1
- package/src/diff/diff-patch.ts +17 -1
- package/src/diff/diff-renderer.ts +56 -1
- package/src/gcr-reader.ts +26 -1
- package/src/gcr-writer.ts +3 -1
- package/src/managed-concept-collection.ts +36 -1
- package/src/rdf/agents-emitter.ts +8 -5
- package/src/rdf/bibliography-emitter.ts +2 -3
- package/src/rdf/curie.ts +1 -1
- package/src/rdf/document-writer.ts +1 -2
- package/src/rdf/gloss-concept.ts +3 -3
- package/src/rdf/gloss-designation.ts +2 -3
- package/src/rdf/gloss-non-verbal-rep.ts +11 -1
- package/src/rdf/sections-builder.ts +13 -1
- package/src/rdf/shacl.ts +2 -1
- package/src/rdf/write-turtle-sync.ts +13 -1
- package/src/reference-resolver.ts +31 -1
- package/src/render-classification.ts +10 -1
- package/src/v1-reader.ts +3 -1
- package/src/validators/asset-index.ts +6 -1
- package/src/validators/concept-validator.ts +2 -1
- package/src/validators/gcr-validator.ts +2 -1
- package/src/validators/v3-rules.ts +5 -1
package/package.json
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck — TEMPORARY during TS migration. TODO(Phase 2e): remove and type fully.
|
|
2
1
|
import { naturalSort } from './sort.js';
|
|
3
2
|
|
|
4
3
|
const _items = Symbol('items');
|
|
@@ -87,17 +86,21 @@ export class ConceptCollection {
|
|
|
87
86
|
if (Array.isArray(sectionId)) {
|
|
88
87
|
const targetSet = new Set(sectionId);
|
|
89
88
|
return new ConceptCollection(this[_items].filter(c => {
|
|
89
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
90
90
|
const ids = options.register
|
|
91
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
91
92
|
? options.register.conceptSectionIds(c)
|
|
92
93
|
: _flatConceptSectionIds(c);
|
|
93
94
|
return ids.some(id => targetSet.has(id));
|
|
94
95
|
}));
|
|
95
96
|
}
|
|
97
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
96
98
|
if (!options.register) {
|
|
97
99
|
throw new Error('bySection(sectionId) requires { register } to expand the concept section closures');
|
|
98
100
|
}
|
|
99
101
|
const target = sectionId;
|
|
100
102
|
return new ConceptCollection(this[_items].filter(c => {
|
|
103
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
101
104
|
const ids = options.register.conceptSectionIds(c);
|
|
102
105
|
return ids.includes(target);
|
|
103
106
|
}));
|
|
@@ -112,6 +115,7 @@ export class ConceptCollection {
|
|
|
112
115
|
sorted() {
|
|
113
116
|
const copy = [...this[_items]];
|
|
114
117
|
copy.sort((a, b) => naturalSort(a.id, b.id));
|
|
118
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
115
119
|
return new ConceptCollection(copy);
|
|
116
120
|
}
|
|
117
121
|
|
|
@@ -155,9 +159,11 @@ function _flatConceptSectionIds(concept) {
|
|
|
155
159
|
if (!Array.isArray(source)) continue;
|
|
156
160
|
for (const entry of source) {
|
|
157
161
|
if (typeof entry === 'string') {
|
|
162
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
158
163
|
out.push(entry);
|
|
159
164
|
} else if (entry && typeof entry === 'object') {
|
|
160
165
|
const id = entry.id ?? entry.sectionId ?? entry.ref?.id;
|
|
166
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
161
167
|
if (id) out.push(String(id));
|
|
162
168
|
}
|
|
163
169
|
}
|
package/src/concept-parser.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck — TEMPORARY during TS migration. TODO(Phase 2e): remove and type fully.
|
|
2
1
|
import * as yaml from 'js-yaml';
|
|
3
2
|
import { Concept } from './models/concept.js';
|
|
4
3
|
import { RelatedConcept } from './models/related-concept.js';
|
|
@@ -22,10 +21,14 @@ const STRUCTURAL_KEYS = new Set([
|
|
|
22
21
|
function _registryStructuralKeys() {
|
|
23
22
|
const out = [];
|
|
24
23
|
for (const cls of HyperedgeRegistry.allClasses()) {
|
|
24
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
25
25
|
out.push(cls.wireKey);
|
|
26
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
26
27
|
out.push(_camelCase(cls.wireKey));
|
|
27
28
|
for (const k of cls.v1WireKeys ?? []) {
|
|
29
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
28
30
|
out.push(k);
|
|
31
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
29
32
|
out.push(_camelCase(k));
|
|
30
33
|
}
|
|
31
34
|
}
|
|
@@ -62,6 +65,7 @@ export class ConceptParser {
|
|
|
62
65
|
// behavior (yaml.org core schema).
|
|
63
66
|
docs = yaml.loadAll(raw, { schema: yaml.CORE_SCHEMA ?? yaml.JSON_SCHEMA });
|
|
64
67
|
} catch (err) {
|
|
68
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
65
69
|
throw new YamlParseError(label, err);
|
|
66
70
|
}
|
|
67
71
|
|
|
@@ -179,6 +183,7 @@ function _resolveHyperedgeData(container) {
|
|
|
179
183
|
if (Array.isArray(arr)) {
|
|
180
184
|
for (const r of arr) {
|
|
181
185
|
const tagged = _addTypeIfMissing(r, cls.typeTag);
|
|
186
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
182
187
|
if (tagged != null) out.push(tagged);
|
|
183
188
|
}
|
|
184
189
|
}
|
|
@@ -192,6 +197,7 @@ function _resolveHyperedgeData(container) {
|
|
|
192
197
|
for (const h of v1Arr) {
|
|
193
198
|
const hash = h?.toJSON && typeof h.toJSON === 'function' ? h.toJSON() : h;
|
|
194
199
|
const migrated = migrateHyperedgeToRelation(hash);
|
|
200
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
195
201
|
if (migrated) out.push({ ...migrated, type: cls.typeTag });
|
|
196
202
|
}
|
|
197
203
|
}
|
package/src/concept-reader.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Concept } from './models/concept.js';
|
|
2
|
+
import type { RegisterJson } from './models/register.js';
|
|
2
3
|
import fs from 'fs';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import * as yaml from 'js-yaml';
|
|
@@ -38,7 +39,7 @@ export function readConcepts(dir) {
|
|
|
38
39
|
.filter(f => f.endsWith('.yaml') && f !== 'register.yaml')
|
|
39
40
|
.sort(naturalSort);
|
|
40
41
|
|
|
41
|
-
const concepts = [];
|
|
42
|
+
const concepts: Concept[] = [];
|
|
42
43
|
for (const file of files) {
|
|
43
44
|
const raw = fs.readFileSync(path.join(dir, file), 'utf8');
|
|
44
45
|
const concept = conceptParser.parse(raw, file);
|
|
@@ -150,5 +151,5 @@ export function readRegister(dir) {
|
|
|
150
151
|
const p = path.join(dir, 'register.yaml');
|
|
151
152
|
if (!fs.existsSync(p)) return null;
|
|
152
153
|
const raw = yaml.load(fs.readFileSync(p, 'utf8'));
|
|
153
|
-
return Register.fromJSON(raw);
|
|
154
|
+
return Register.fromJSON(raw as RegisterJson);
|
|
154
155
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck — TEMPORARY during TS migration. TODO(Phase 2e): remove and type fully.
|
|
2
1
|
import * as yaml from 'js-yaml';
|
|
3
2
|
import { PartitiveHyperedge } from './models/partitive-hyperedge.js';
|
|
4
3
|
import { GenericHyperedge } from './models/generic-hyperedge.js';
|
|
@@ -21,10 +20,13 @@ function _emitTypedRelations(concept) {
|
|
|
21
20
|
export class ConceptSerializer {
|
|
22
21
|
toCanonicalYaml(concept) {
|
|
23
22
|
const doc = { termid: concept.id };
|
|
23
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
24
24
|
if (concept.term) doc.term = concept.term;
|
|
25
25
|
|
|
26
26
|
const { partitive, generic } = _emitTypedRelations(concept);
|
|
27
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
27
28
|
if (partitive.length > 0) doc.partitive_relations = partitive;
|
|
29
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
28
30
|
if (generic.length > 0) doc.generic_relations = generic;
|
|
29
31
|
|
|
30
32
|
for (const lang of concept.languages) {
|
|
@@ -51,6 +53,7 @@ export class ConceptSerializer {
|
|
|
51
53
|
localizedConcepts[lang] = lcId;
|
|
52
54
|
|
|
53
55
|
const lcObj = lc.toJSON();
|
|
56
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
54
57
|
langDocs.push({ data: lcObj, id: lcId });
|
|
55
58
|
}
|
|
56
59
|
|
|
@@ -60,22 +63,30 @@ export class ConceptSerializer {
|
|
|
60
63
|
};
|
|
61
64
|
|
|
62
65
|
if (concept.domains.length > 0) {
|
|
66
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
63
67
|
mainDoc.data.domains = concept.domains.map(d => d.toJSON());
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
if (concept.relatedConcepts.length > 0) {
|
|
71
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
67
72
|
mainDoc.related = concept.relatedConcepts.map(rc => rc.toJSON());
|
|
68
73
|
}
|
|
69
74
|
const { partitive, generic } = _emitTypedRelations(concept);
|
|
75
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
70
76
|
if (partitive.length > 0) mainDoc.partitive_relations = partitive;
|
|
77
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
71
78
|
if (generic.length > 0) mainDoc.generic_relations = generic;
|
|
72
79
|
if (concept.sources.length > 0) {
|
|
80
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
73
81
|
mainDoc.sources = concept.sources.map(s => s.toJSON());
|
|
74
82
|
}
|
|
75
83
|
if (concept.dates.length > 0) {
|
|
84
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
76
85
|
mainDoc.dates = concept.dates.map(d => d.toJSON());
|
|
77
86
|
}
|
|
87
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
78
88
|
if (concept.status) mainDoc.status = concept.status;
|
|
89
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
79
90
|
if (concept.schemaVersion) mainDoc.schema_version = concept.schemaVersion;
|
|
80
91
|
|
|
81
92
|
const parts = [
|
package/src/concept-writer.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck — TEMPORARY during TS migration. TODO(Phase 2e): remove and type fully.
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import { conceptSerializer } from './concept-serializer.js';
|
|
@@ -19,7 +18,9 @@ export function writeConcept(dir, concept, format = 'auto') {
|
|
|
19
18
|
const y = format === 'canonical'
|
|
20
19
|
? conceptSerializer.toCanonicalYaml(concept)
|
|
21
20
|
: format === 'managed'
|
|
21
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
22
22
|
? conceptSerializer.toManagedYaml(concept)
|
|
23
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
23
24
|
: conceptSerializer.toYaml(concept);
|
|
24
25
|
|
|
25
26
|
fs.writeFileSync(path.join(dir, `${concept.id}.yaml`), y, 'utf8');
|
|
@@ -30,12 +31,15 @@ export function writeConcepts(dir, concepts, options = {}) {
|
|
|
30
31
|
fs.mkdirSync(dir, { recursive: true });
|
|
31
32
|
|
|
32
33
|
for (const concept of concepts) {
|
|
34
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
33
35
|
writeConcept(dir, concept, options.format);
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
36
39
|
if (options.register) {
|
|
37
40
|
fs.writeFileSync(
|
|
38
41
|
path.join(dir, 'register.yaml'),
|
|
42
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
39
43
|
conceptSerializer.toRegisterYaml(options.register),
|
|
40
44
|
'utf8',
|
|
41
45
|
);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck — TEMPORARY during TS migration. TODO(Phase 2e): remove and type fully.
|
|
2
1
|
import { GlossaristModel } from '../models/base.js';
|
|
3
2
|
import { Added, Removed, Matched, deserializeChange } from './change.js';
|
|
4
3
|
import { ConceptDiff, DiffStats, diffConcepts } from './concept-diff.js';
|
|
@@ -7,83 +6,121 @@ import { averageSimilarity } from './similarity.js';
|
|
|
7
6
|
export class ConceptCollectionDiff extends GlossaristModel {
|
|
8
7
|
constructor(data: Record<string, unknown> = {}) {
|
|
9
8
|
super();
|
|
9
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
10
10
|
this.oldCount = data.oldCount ?? data.old_count ?? 0;
|
|
11
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
11
12
|
this.newCount = data.newCount ?? data.new_count ?? 0;
|
|
12
13
|
|
|
14
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
13
15
|
this._matched = wrapIdList(data.matched, Matched);
|
|
16
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
14
17
|
this._added = wrapIdList(data.added, Added);
|
|
18
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
15
19
|
this._removed = wrapIdList(data.removed, Removed);
|
|
16
20
|
|
|
21
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
17
22
|
this._conceptDiffs = {};
|
|
18
23
|
const raw = data.conceptDiffs ?? data.concept_diffs ?? {};
|
|
19
24
|
for (const [id, diff] of Object.entries(raw)) {
|
|
25
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
20
26
|
this._conceptDiffs[id] = diff instanceof ConceptDiff
|
|
21
27
|
? diff
|
|
22
28
|
: ConceptDiff.fromJSON(diff);
|
|
23
29
|
}
|
|
30
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
24
31
|
this._statsCache = undefined;
|
|
32
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
25
33
|
this._similarityCache = undefined;
|
|
26
34
|
}
|
|
27
35
|
|
|
36
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
28
37
|
get matched() { return this._matched; }
|
|
38
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
29
39
|
get added() { return this._added; }
|
|
40
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
30
41
|
get removed() { return this._removed; }
|
|
42
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
31
43
|
get conceptDiffs() { return this._conceptDiffs; }
|
|
32
44
|
|
|
33
45
|
get changedIds() {
|
|
46
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
34
47
|
return Object.keys(this._conceptDiffs);
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
get hasChanges() {
|
|
51
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
38
52
|
return this._added.length > 0
|
|
53
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
39
54
|
|| this._removed.length > 0
|
|
55
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
40
56
|
|| Object.values(this._conceptDiffs).some(d => d.hasChanges);
|
|
41
57
|
}
|
|
42
58
|
|
|
43
59
|
conceptDiff(id) {
|
|
60
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
44
61
|
return this._conceptDiffs[id] ?? null;
|
|
45
62
|
}
|
|
46
63
|
|
|
47
64
|
get stats() {
|
|
65
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
48
66
|
if (this._statsCache === undefined) {
|
|
67
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
49
68
|
let added = this._added.length;
|
|
69
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
50
70
|
let removed = this._removed.length;
|
|
51
71
|
let changed = 0;
|
|
72
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
52
73
|
for (const diff of Object.values(this._conceptDiffs)) {
|
|
74
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
53
75
|
const s = diff.stats;
|
|
54
76
|
added += s.added;
|
|
55
77
|
removed += s.removed;
|
|
56
78
|
changed += s.changed;
|
|
57
79
|
}
|
|
80
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
58
81
|
this._statsCache = new DiffStats({ added, removed, changed });
|
|
59
82
|
}
|
|
83
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
60
84
|
return this._statsCache;
|
|
61
85
|
}
|
|
62
86
|
|
|
63
87
|
get similarity() {
|
|
88
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
64
89
|
if (this._similarityCache === undefined) {
|
|
90
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
65
91
|
if (this._matched.length === 0) {
|
|
92
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
66
93
|
this._similarityCache = 0;
|
|
67
94
|
} else {
|
|
95
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
68
96
|
const values = this._matched.map(entry => {
|
|
69
97
|
const id = entry.value;
|
|
98
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
70
99
|
const diff = this._conceptDiffs[id];
|
|
71
100
|
return diff ? diff.similarity : 1.0;
|
|
72
101
|
});
|
|
102
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
73
103
|
this._similarityCache = averageSimilarity(values);
|
|
74
104
|
}
|
|
75
105
|
}
|
|
106
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
76
107
|
return this._similarityCache;
|
|
77
108
|
}
|
|
78
109
|
|
|
79
110
|
*walk() {
|
|
111
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
80
112
|
for (let i = 0; i < this._added.length; i++) {
|
|
113
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
81
114
|
yield { path: `added[${i}]`, change: this._added[i] };
|
|
82
115
|
}
|
|
116
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
83
117
|
for (let i = 0; i < this._removed.length; i++) {
|
|
118
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
84
119
|
yield { path: `removed[${i}]`, change: this._removed[i] };
|
|
85
120
|
}
|
|
121
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
86
122
|
for (const [id, diff] of Object.entries(this._conceptDiffs)) {
|
|
123
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
87
124
|
for (const entry of diff.walk()) {
|
|
88
125
|
yield { path: `concepts.${id}.${entry.path}`, change: entry.change, conceptId: id, language: entry.language };
|
|
89
126
|
}
|
|
@@ -92,14 +129,21 @@ export class ConceptCollectionDiff extends GlossaristModel {
|
|
|
92
129
|
|
|
93
130
|
toJSON() {
|
|
94
131
|
const obj = {
|
|
132
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
95
133
|
old_count: this.oldCount,
|
|
134
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
96
135
|
new_count: this.newCount,
|
|
136
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
97
137
|
matched: this._matched.map(c => c.toJSON()),
|
|
138
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
98
139
|
added: this._added.map(c => c.toJSON()),
|
|
140
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
99
141
|
removed: this._removed.map(c => c.toJSON()),
|
|
100
142
|
concept_diffs: {},
|
|
101
143
|
};
|
|
144
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
102
145
|
for (const [id, diff] of Object.entries(this._conceptDiffs)) {
|
|
146
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
103
147
|
obj.concept_diffs[id] = diff.toJSON();
|
|
104
148
|
}
|
|
105
149
|
return obj;
|
|
@@ -111,6 +155,7 @@ export class ConceptCollectionDiff extends GlossaristModel {
|
|
|
111
155
|
}
|
|
112
156
|
|
|
113
157
|
export function diffConceptCollections(oldCollection, newCollection, options = {}) {
|
|
158
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
114
159
|
const language = options.language ?? 'eng';
|
|
115
160
|
|
|
116
161
|
const oldConcepts = extractConcepts(oldCollection);
|
|
@@ -131,12 +176,15 @@ export function diffConceptCollections(oldCollection, newCollection, options = {
|
|
|
131
176
|
const oldConcept = oldMap.get(id);
|
|
132
177
|
const newConcept = newMap.get(id);
|
|
133
178
|
|
|
179
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
134
180
|
if (options.skipUnchanged && conceptsEqual(oldConcept, newConcept)) {
|
|
135
181
|
continue;
|
|
136
182
|
}
|
|
137
183
|
|
|
138
184
|
const diff = diffConcepts(oldConcept, newConcept, language);
|
|
185
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
139
186
|
if (diff.hasChanges || !options.skipUnchanged) {
|
|
187
|
+
// @ts-expect-error TODO(Phase 2e): type this fully
|
|
140
188
|
conceptDiffs[id] = diff;
|
|
141
189
|
}
|
|
142
190
|
}
|