@accordproject/concerto-vocabulary 4.2.0 → 5.0.0-beta.1
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/dist/esm/chunk-3VH3UOGB.mjs +398 -0
- package/dist/esm/chunk-3VH3UOGB.mjs.map +7 -0
- package/dist/esm/chunk-7RW3VXN4.mjs +185 -0
- package/dist/esm/chunk-7RW3VXN4.mjs.map +7 -0
- package/dist/esm/chunk-TA74NV57.mjs +38 -0
- package/dist/esm/chunk-TA74NV57.mjs.map +7 -0
- package/dist/esm/index.mjs +14 -0
- package/dist/esm/index.mjs.map +7 -0
- package/dist/esm/vocabulary.mjs +11 -0
- package/dist/esm/vocabulary.mjs.map +7 -0
- package/dist/esm/vocabularymanager.mjs +13 -0
- package/dist/esm/vocabularymanager.mjs.map +7 -0
- package/dist/esm/yamlparser.mjs +9 -0
- package/dist/esm/yamlparser.mjs.map +7 -0
- package/dist/esm-browser/chunk-2FE6COGH.mjs +2089 -0
- package/dist/esm-browser/chunk-2FE6COGH.mjs.map +7 -0
- package/dist/esm-browser/chunk-CKXQ5OWJ.mjs +187 -0
- package/dist/esm-browser/chunk-CKXQ5OWJ.mjs.map +7 -0
- package/dist/esm-browser/chunk-DSN2E4MW.mjs +6747 -0
- package/dist/esm-browser/chunk-DSN2E4MW.mjs.map +7 -0
- package/dist/esm-browser/chunk-K2X7J5YP.mjs +70 -0
- package/dist/esm-browser/chunk-K2X7J5YP.mjs.map +7 -0
- package/dist/esm-browser/index.mjs +18 -0
- package/dist/esm-browser/index.mjs.map +7 -0
- package/dist/esm-browser/vocabulary.mjs +10 -0
- package/dist/esm-browser/vocabulary.mjs.map +7 -0
- package/dist/esm-browser/vocabularymanager.mjs +12 -0
- package/dist/esm-browser/vocabularymanager.mjs.map +7 -0
- package/dist/esm-browser/yamlparser.mjs +8 -0
- package/dist/esm-browser/yamlparser.mjs.map +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/vocabulary.d.ts +3 -2
- package/dist/vocabulary.js +5 -1
- package/dist/vocabulary.js.map +1 -1
- package/dist/vocabularymanager.d.ts +3 -2
- package/dist/vocabularymanager.js +6 -3
- package/dist/vocabularymanager.js.map +1 -1
- package/package.json +18 -5
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from "module";
|
|
2
|
+
const require = __createRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
vocabulary_default
|
|
5
|
+
} from "./chunk-7RW3VXN4.mjs";
|
|
6
|
+
import {
|
|
7
|
+
parseVocabularyYaml
|
|
8
|
+
} from "./chunk-TA74NV57.mjs";
|
|
9
|
+
|
|
10
|
+
// src/vocabularymanager.ts
|
|
11
|
+
import YAML from "yaml";
|
|
12
|
+
import { MetaModelNamespace } from "@accordproject/concerto-metamodel";
|
|
13
|
+
import { ModelUtil } from "@accordproject/concerto-core";
|
|
14
|
+
var DC_NAMESPACE = "org.accordproject.decoratorcommands@0.4.0";
|
|
15
|
+
function camelCaseToSentence(text) {
|
|
16
|
+
const result = text.replace(/([A-Z]+)/g, " $1").trim();
|
|
17
|
+
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
18
|
+
}
|
|
19
|
+
var VocabularyManager = class _VocabularyManager {
|
|
20
|
+
/**
|
|
21
|
+
* Create the VocabularyManager
|
|
22
|
+
* @param {*} [options] options to configure vocabulary lookup
|
|
23
|
+
* @param {*} [options.missingTermGenerator] A function to call for missing terms. The function
|
|
24
|
+
* should accept namespace, locale, declarationName, propertyName as arguments
|
|
25
|
+
* @constructor
|
|
26
|
+
*/
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.vocabularies = {};
|
|
29
|
+
this.missingTermGenerator = options ? options.missingTermGenerator : null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Computes a term in English based on declaration and property name.
|
|
33
|
+
* @param {string} namespace the namespace
|
|
34
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
35
|
+
* @param {string} declarationName the name of a concept or enum
|
|
36
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
37
|
+
* @returns {string} the term or null if it does not exist
|
|
38
|
+
*/
|
|
39
|
+
static englishMissingTermGenerator(namespace, locale, declarationName, propertyName) {
|
|
40
|
+
if (!declarationName) {
|
|
41
|
+
return camelCaseToSentence(ModelUtil.parseNamespace(namespace).name);
|
|
42
|
+
}
|
|
43
|
+
const firstPart = propertyName ? propertyName.replace("$", "") + " of the" : "";
|
|
44
|
+
return camelCaseToSentence(firstPart + declarationName);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Removes all vocabularies
|
|
48
|
+
*/
|
|
49
|
+
clear() {
|
|
50
|
+
this.vocabularies = {};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Removes a vocabulary from the vocabulary manager
|
|
54
|
+
* @param {string} namespace the namespace for the vocabulary
|
|
55
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
56
|
+
*/
|
|
57
|
+
removeVocabulary(namespace, locale) {
|
|
58
|
+
delete this.vocabularies[`${namespace}/${locale}`];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Adds a vocabulary to the vocabulary manager
|
|
62
|
+
* @param {string} contents the YAML string for the vocabulary
|
|
63
|
+
* @param {*} [options] options to configure vocabulary parsing
|
|
64
|
+
* @param {boolean} [options.enableSafeVocabParsing] When true, ensures vocabulary values are resolved correctly as strings
|
|
65
|
+
* @returns {Vocabulary} the vocabulary the was added
|
|
66
|
+
*/
|
|
67
|
+
addVocabulary(contents, options) {
|
|
68
|
+
if (!contents) {
|
|
69
|
+
throw new Error("Vocabulary contents must be specified");
|
|
70
|
+
}
|
|
71
|
+
const voc = new vocabulary_default(this, options?.enableSafeVocabParsing ? parseVocabularyYaml(contents) : YAML.parse(contents));
|
|
72
|
+
if (this.vocabularies[voc.getIdentifier()]) {
|
|
73
|
+
throw new Error("Vocabulary has already been added.");
|
|
74
|
+
}
|
|
75
|
+
this.vocabularies[voc.getIdentifier()] = voc;
|
|
76
|
+
return voc;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Finds the vocabulary for a requested locale, removing language
|
|
80
|
+
* identifiers from the locale until the locale matches, or if no
|
|
81
|
+
* vocabulary is found, null is returned
|
|
82
|
+
* @param {string} requestedLocale the BCP-47 locale identifier
|
|
83
|
+
* @param {Vocabulary[]} vocabularies the vocabularies to match against
|
|
84
|
+
* @param {*} [options] options to configure vocabulary lookup
|
|
85
|
+
* @param {*} [options.localeMatcher] Pass 'lookup' to find a general vocabulary, if available
|
|
86
|
+
* @returns {Vocabulary} the most specific vocabulary, or null
|
|
87
|
+
*/
|
|
88
|
+
static findVocabulary(requestedLocale, vocabularies, options) {
|
|
89
|
+
let locale = requestedLocale;
|
|
90
|
+
let done = false;
|
|
91
|
+
do {
|
|
92
|
+
const voc = vocabularies.find((v) => v.getLocale() === locale);
|
|
93
|
+
if (voc) {
|
|
94
|
+
return voc;
|
|
95
|
+
}
|
|
96
|
+
if (options?.localeMatcher !== "lookup") {
|
|
97
|
+
done = true;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
const pos = locale.lastIndexOf("-");
|
|
101
|
+
if (pos === -1) {
|
|
102
|
+
done = true;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
locale = locale.substring(0, pos);
|
|
106
|
+
} while (!done);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Gets a vocabulary for a given namespace plus locale
|
|
111
|
+
* @param {string} namespace the namespace for the vocabulary
|
|
112
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
113
|
+
* @param {*} [options] options to configure vocabulary lookup
|
|
114
|
+
* @param {*} [options.localeMatcher] Pass 'lookup' to find a general vocabulary, if available
|
|
115
|
+
* @returns {Vocabulary} the vocabulary or null if no vocabulary exists for the locale
|
|
116
|
+
*/
|
|
117
|
+
getVocabulary(namespace, locale, options) {
|
|
118
|
+
const loc = locale.toLowerCase();
|
|
119
|
+
const voc = this.vocabularies[`${namespace}/${loc}`];
|
|
120
|
+
if (voc) {
|
|
121
|
+
return voc;
|
|
122
|
+
}
|
|
123
|
+
if (options?.localeMatcher === "lookup") {
|
|
124
|
+
const vocs = this.getVocabulariesForNamespace(namespace);
|
|
125
|
+
return _VocabularyManager.findVocabulary(loc, vocs, options);
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Gets all the vocabulary files for a given namespace
|
|
131
|
+
* @param {string} namespace the namespace
|
|
132
|
+
* @returns {Vocabulary[]} the array of vocabularies
|
|
133
|
+
*/
|
|
134
|
+
getVocabulariesForNamespace(namespace) {
|
|
135
|
+
return Object.values(this.vocabularies).filter((v) => v.getNamespace() === namespace);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Gets all the vocabulary files for a given locale
|
|
139
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
140
|
+
* @returns {Vocabulary[]} the array of vocabularies
|
|
141
|
+
*/
|
|
142
|
+
getVocabulariesForLocale(locale) {
|
|
143
|
+
return Object.values(this.vocabularies).filter((v) => v.getLocale() === locale.toLowerCase());
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Resolve the term for a property, looking up terms from a more general vocabulary
|
|
147
|
+
* if required, and resolving properties using an object manager, allowing terms defined
|
|
148
|
+
* on super types to be automatically resolved.
|
|
149
|
+
* @param {ModelManager} modelManager the model manager
|
|
150
|
+
* @param {string} namespace the namespace
|
|
151
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
152
|
+
* @param {string} declarationName the name of a concept or enum
|
|
153
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
154
|
+
* @param {string} [identifier] the identifier of the term (optional)
|
|
155
|
+
* @returns {string|number|boolean|null} the term or null if it does not exist
|
|
156
|
+
*/
|
|
157
|
+
resolveTerm(modelManager, namespace, locale, declarationName, propertyName, identifier) {
|
|
158
|
+
const modelFile = modelManager.getModelFile(namespace);
|
|
159
|
+
const classDecl = modelFile ? modelFile.getType(declarationName) : null;
|
|
160
|
+
const property = propertyName ? classDecl ? classDecl.getProperty(propertyName) : null : null;
|
|
161
|
+
return this.getTerm(property ? property.getNamespace() : namespace, locale, property ? property.getParent().getName() : declarationName, propertyName, identifier);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Resolve the terms for a property, looking up terms from a more general vocabulary
|
|
165
|
+
* if required, and resolving properties using an object manager, allowing terms defined
|
|
166
|
+
* on super types to be automatically resolved.
|
|
167
|
+
* @param {ModelManager} modelManager the model manager
|
|
168
|
+
* @param {string} namespace the namespace
|
|
169
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
170
|
+
* @param {string} declarationName the name of a concept or enum
|
|
171
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
172
|
+
* @param {*} [options] options to configure term resolution
|
|
173
|
+
* @param {boolean} [options.generateMissing=true] whether to synthesize missing terms
|
|
174
|
+
* @returns {*} the terms or null if it does not exist
|
|
175
|
+
*/
|
|
176
|
+
resolveTerms(modelManager, namespace, locale, declarationName, propertyName, options) {
|
|
177
|
+
const modelFile = modelManager.getModelFile(namespace);
|
|
178
|
+
const classDecl = modelFile ? modelFile.getType(declarationName) : null;
|
|
179
|
+
let property;
|
|
180
|
+
if (classDecl && !classDecl.isScalarDeclaration()) {
|
|
181
|
+
if (classDecl.isMapDeclaration()) {
|
|
182
|
+
if (propertyName === "KEY") {
|
|
183
|
+
property = classDecl.getKey();
|
|
184
|
+
} else if (propertyName === "VALUE") {
|
|
185
|
+
property = classDecl.getValue();
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
property = propertyName ? classDecl ? classDecl.getProperty(propertyName) : null : null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return this.getTerms(property ? property.getNamespace() : namespace, locale, property ? property.getParent().getName() : declarationName, propertyName, options);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Gets the term for a concept, enum or property, looking up terms
|
|
195
|
+
* from a more general vocabulary if required
|
|
196
|
+
* @param {string} namespace the namespace
|
|
197
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
198
|
+
* @param {string} declarationName the name of a concept or enum
|
|
199
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
200
|
+
* @param {string} [identifier] the identifier of the term (optional)
|
|
201
|
+
* @returns {string|number|boolean|null} the term or null if it does not exist
|
|
202
|
+
*/
|
|
203
|
+
getTerm(namespace, locale, declarationName, propertyName, identifier) {
|
|
204
|
+
const voc = this.getVocabulary(namespace, locale);
|
|
205
|
+
let term = null;
|
|
206
|
+
if (voc) {
|
|
207
|
+
term = voc.getTerm(declarationName, propertyName, identifier);
|
|
208
|
+
}
|
|
209
|
+
if (term != null) {
|
|
210
|
+
return term;
|
|
211
|
+
} else {
|
|
212
|
+
const dashIndex = locale.lastIndexOf("-");
|
|
213
|
+
if (dashIndex >= 0) {
|
|
214
|
+
return this.getTerm(namespace, locale.substring(0, dashIndex), declarationName, propertyName, identifier);
|
|
215
|
+
} else {
|
|
216
|
+
return this.missingTermGenerator ? this.missingTermGenerator(namespace, locale, declarationName, propertyName) : null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Gets the term for a concept, enum or property, looking up terms
|
|
222
|
+
* from a more general vocabulary if required
|
|
223
|
+
* @param {string} namespace the namespace
|
|
224
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
225
|
+
* @param {string} declarationName the name of a concept or enum
|
|
226
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
227
|
+
* @param {*} [options] options to configure term resolution
|
|
228
|
+
* @param {boolean} [options.generateMissing=true] whether to synthesize missing terms
|
|
229
|
+
* @returns {*} the terms or null if it does not exist
|
|
230
|
+
*/
|
|
231
|
+
getTerms(namespace, locale, declarationName, propertyName, options) {
|
|
232
|
+
const voc = this.getVocabulary(namespace, locale);
|
|
233
|
+
let term = null;
|
|
234
|
+
if (voc) {
|
|
235
|
+
term = voc.getElementTerms(declarationName, propertyName);
|
|
236
|
+
}
|
|
237
|
+
if (term != null) {
|
|
238
|
+
return term;
|
|
239
|
+
} else {
|
|
240
|
+
const dashIndex = locale.lastIndexOf("-");
|
|
241
|
+
if (dashIndex >= 0) {
|
|
242
|
+
return this.getTerms(namespace, locale.substring(0, dashIndex), declarationName, propertyName, options);
|
|
243
|
+
} else {
|
|
244
|
+
if (options?.generateMissing === false) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
let missingKey = propertyName ? propertyName : declarationName;
|
|
248
|
+
missingKey = missingKey ? missingKey : "term";
|
|
249
|
+
return this.missingTermGenerator ? { [missingKey]: this.missingTermGenerator(namespace, locale, declarationName, propertyName) } : null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Creates a DecoractorCommandSet with @Term decorators
|
|
255
|
+
* to decorate all model elements based on the vocabulary for a locale.
|
|
256
|
+
* Pass the return value to the DecoratorManager.decorateModel to apply
|
|
257
|
+
* the decorators to a ModelManager.
|
|
258
|
+
* @param {ModelManager} modelManager - the Model Manager
|
|
259
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
260
|
+
* @returns {*} the decorator command set used to decorate the model.
|
|
261
|
+
*/
|
|
262
|
+
generateDecoratorCommands(modelManager, locale) {
|
|
263
|
+
const commands = [];
|
|
264
|
+
const CLASS_COMMAND = `${DC_NAMESPACE}.Command`;
|
|
265
|
+
const CLASS_TARGET = `${DC_NAMESPACE}.CommandTarget`;
|
|
266
|
+
const CLASS_DECORATOR = `${MetaModelNamespace}.Decorator`;
|
|
267
|
+
const CLASS_DECORATOR_STRING = `${MetaModelNamespace}.DecoratorString`;
|
|
268
|
+
const makeCommand = (target, decoratorName, value) => ({
|
|
269
|
+
"$class": CLASS_COMMAND,
|
|
270
|
+
"type": "UPSERT",
|
|
271
|
+
"target": target,
|
|
272
|
+
"decorator": {
|
|
273
|
+
"$class": CLASS_DECORATOR,
|
|
274
|
+
"name": decoratorName,
|
|
275
|
+
"arguments": [{ "$class": CLASS_DECORATOR_STRING, "value": value }]
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
modelManager.getModelFiles().forEach((model) => {
|
|
279
|
+
const namespace = model.getNamespace();
|
|
280
|
+
const nsTerms = this.getTerms(namespace, locale, "", void 0, { generateMissing: false });
|
|
281
|
+
if (nsTerms) {
|
|
282
|
+
const keys = Object.keys(nsTerms);
|
|
283
|
+
for (let i = 0; i < keys.length; i++) {
|
|
284
|
+
const term = keys[i];
|
|
285
|
+
if (term === "term") {
|
|
286
|
+
commands.push(makeCommand(
|
|
287
|
+
{ "$class": CLASS_TARGET, "namespace": namespace },
|
|
288
|
+
"Term",
|
|
289
|
+
nsTerms[term]
|
|
290
|
+
));
|
|
291
|
+
} else if (term !== "declarations" && term !== "namespace" && term !== "locale") {
|
|
292
|
+
commands.push(makeCommand(
|
|
293
|
+
{ "$class": CLASS_TARGET, "namespace": namespace },
|
|
294
|
+
`Term_${term}`,
|
|
295
|
+
nsTerms[term]
|
|
296
|
+
));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
model.getAllDeclarations().forEach((decl) => {
|
|
301
|
+
const declName = decl.getName();
|
|
302
|
+
const declTerms = this.getTerms(namespace, locale, declName);
|
|
303
|
+
if (declTerms) {
|
|
304
|
+
const keys = Object.keys(declTerms);
|
|
305
|
+
for (let i = 0; i < keys.length; i++) {
|
|
306
|
+
const term = keys[i];
|
|
307
|
+
if (term === declName) {
|
|
308
|
+
commands.push(makeCommand(
|
|
309
|
+
{ "$class": CLASS_TARGET, "namespace": namespace, "declaration": declName },
|
|
310
|
+
"Term",
|
|
311
|
+
declTerms[term]
|
|
312
|
+
));
|
|
313
|
+
} else if (term !== "properties") {
|
|
314
|
+
commands.push(makeCommand(
|
|
315
|
+
{ "$class": CLASS_TARGET, "namespace": namespace, "declaration": declName },
|
|
316
|
+
`Term_${term}`,
|
|
317
|
+
declTerms[term]
|
|
318
|
+
));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
let propertyNames = [];
|
|
323
|
+
if (decl.getProperties) {
|
|
324
|
+
propertyNames = decl.getProperties().map((p) => p.getName());
|
|
325
|
+
} else if (decl.isMapDeclaration?.()) {
|
|
326
|
+
propertyNames = ["KEY", "VALUE"];
|
|
327
|
+
} else {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
for (let p = 0; p < propertyNames.length; p++) {
|
|
331
|
+
const propertyName = propertyNames[p];
|
|
332
|
+
const propertyTerms = this.resolveTerms(modelManager, namespace, locale, declName, propertyName);
|
|
333
|
+
if (propertyTerms) {
|
|
334
|
+
const propertyType = propertyName === "KEY" || propertyName === "VALUE" ? "mapElement" : "property";
|
|
335
|
+
const keys = Object.keys(propertyTerms);
|
|
336
|
+
for (let i = 0; i < keys.length; i++) {
|
|
337
|
+
const term = keys[i];
|
|
338
|
+
commands.push(makeCommand(
|
|
339
|
+
{ "$class": CLASS_TARGET, "namespace": namespace, "declaration": declName, [propertyType]: propertyName },
|
|
340
|
+
term === propertyName ? "Term" : `Term_${term}`,
|
|
341
|
+
propertyTerms[term]
|
|
342
|
+
));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
return {
|
|
349
|
+
"$class": `${DC_NAMESPACE}.DecoratorCommandSet`,
|
|
350
|
+
"name": `terms-${locale}`,
|
|
351
|
+
"version": "1.0.0",
|
|
352
|
+
"commands": commands
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Validates the terms in the vocabulary against the namespaces and declarations
|
|
357
|
+
* within a ModelManager
|
|
358
|
+
* @param {ModelManager} modelManager - the Model Manager
|
|
359
|
+
* @param {string} locale the BCP-47 locale identifier
|
|
360
|
+
* @returns {*} the result of validation
|
|
361
|
+
*/
|
|
362
|
+
validate(modelManager) {
|
|
363
|
+
const missingVocabularies = modelManager.getModelFiles().map((m) => this.getVocabulariesForNamespace(m.getNamespace()).length === 0 ? m.getNamespace() : null).filter((m) => m !== null);
|
|
364
|
+
const additionalVocabularies = Object.values(this.vocabularies).filter((v) => !modelManager.getModelFile(v.getNamespace()));
|
|
365
|
+
const result = {
|
|
366
|
+
missingVocabularies,
|
|
367
|
+
additionalVocabularies,
|
|
368
|
+
vocabularies: {}
|
|
369
|
+
};
|
|
370
|
+
Object.values(this.vocabularies).forEach((voc) => {
|
|
371
|
+
const vocResult = {
|
|
372
|
+
locale: voc.getLocale(),
|
|
373
|
+
namespace: voc.getNamespace(),
|
|
374
|
+
missingTerms: [],
|
|
375
|
+
additionalTerms: []
|
|
376
|
+
};
|
|
377
|
+
const model = modelManager.getModelFile(voc.getNamespace());
|
|
378
|
+
if (model) {
|
|
379
|
+
const errors = voc.validate(model);
|
|
380
|
+
if (errors.missingTerms) {
|
|
381
|
+
vocResult.missingTerms = vocResult.missingTerms.concat(errors.missingTerms);
|
|
382
|
+
}
|
|
383
|
+
if (errors.additionalTerms) {
|
|
384
|
+
vocResult.additionalTerms = vocResult.additionalTerms.concat(errors.additionalTerms);
|
|
385
|
+
}
|
|
386
|
+
result.vocabularies[`${vocResult.namespace}/${vocResult.locale}`] = vocResult;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
var vocabularymanager_default = VocabularyManager;
|
|
393
|
+
|
|
394
|
+
export {
|
|
395
|
+
VocabularyManager,
|
|
396
|
+
vocabularymanager_default
|
|
397
|
+
};
|
|
398
|
+
//# sourceMappingURL=chunk-3VH3UOGB.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/vocabularymanager.ts"],
|
|
4
|
+
"sourcesContent": ["/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport YAML from 'yaml';\nimport { MetaModelNamespace } from '@accordproject/concerto-metamodel';\nimport Vocabulary from './vocabulary';\nimport { ModelUtil, ModelManager } from '@accordproject/concerto-core';\nimport { parseVocabularyYaml } from './yamlparser';\n\nconst DC_NAMESPACE = 'org.accordproject.decoratorcommands@0.4.0';\n\n/**\n * Converts a camel case string to a sentence\n * @param {string} text input\n * @returns {string} modified string\n */\nfunction camelCaseToSentence(text: string): string {\n const result = text.replace(/([A-Z]+)/g, ' $1').trim();\n return result.charAt(0).toUpperCase() + result.slice(1);\n}\n\n/**\n* A vocabulary manager for concerto models. The vocabulary manager\n* stores and provides API access to a set of vocabulary files, where each file\n* is associated with a BCP-47 language tag and a Concerto namespace.\n* @see https://datatracker.ietf.org/doc/html/rfc5646#section-2\n* @class\n* @memberof module:concerto-vocabulary\n*/\nclass VocabularyManager {\n public vocabularies: Record<string, Vocabulary>;\n public missingTermGenerator: any;\n\n /**\n * Create the VocabularyManager\n * @param {*} [options] options to configure vocabulary lookup\n * @param {*} [options.missingTermGenerator] A function to call for missing terms. The function\n * should accept namespace, locale, declarationName, propertyName as arguments\n * @constructor\n */\n constructor(options?: any) {\n this.vocabularies = {}; // key is namespace/locale, value is a Vocabulary object\n this.missingTermGenerator = options ? options.missingTermGenerator : null;\n }\n\n /**\n * Computes a term in English based on declaration and property name.\n * @param {string} namespace the namespace\n * @param {string} locale the BCP-47 locale identifier\n * @param {string} declarationName the name of a concept or enum\n * @param {string} [propertyName] the name of a property (optional)\n * @returns {string} the term or null if it does not exist\n */\n static englishMissingTermGenerator(namespace: string, locale: string, declarationName: string, propertyName?: string): string {\n if(!declarationName){\n return camelCaseToSentence(ModelUtil.parseNamespace(namespace).name);\n }\n const firstPart = propertyName ? propertyName.replace('$', '') + ' of the' : '';\n return camelCaseToSentence(firstPart + declarationName);\n }\n\n /**\n * Removes all vocabularies\n */\n clear() {\n this.vocabularies = {};\n }\n\n /**\n * Removes a vocabulary from the vocabulary manager\n * @param {string} namespace the namespace for the vocabulary\n * @param {string} locale the BCP-47 locale identifier\n */\n removeVocabulary(namespace: string, locale: string) {\n delete this.vocabularies[`${namespace}/${locale}`];\n }\n\n /**\n * Adds a vocabulary to the vocabulary manager\n * @param {string} contents the YAML string for the vocabulary\n * @param {*} [options] options to configure vocabulary parsing\n * @param {boolean} [options.enableSafeVocabParsing] When true, ensures vocabulary values are resolved correctly as strings\n * @returns {Vocabulary} the vocabulary the was added\n */\n addVocabulary(contents: any, options?: any): Vocabulary {\n if (!contents) {\n throw new Error('Vocabulary contents must be specified');\n }\n const voc = new Vocabulary(this, options?.enableSafeVocabParsing ? parseVocabularyYaml(contents) : YAML.parse(contents));\n\n if (this.vocabularies[voc.getIdentifier()]) {\n throw new Error('Vocabulary has already been added.');\n }\n this.vocabularies[voc.getIdentifier()] = voc;\n return voc;\n }\n\n /**\n * Finds the vocabulary for a requested locale, removing language\n * identifiers from the locale until the locale matches, or if no\n * vocabulary is found, null is returned\n * @param {string} requestedLocale the BCP-47 locale identifier\n * @param {Vocabulary[]} vocabularies the vocabularies to match against\n * @param {*} [options] options to configure vocabulary lookup\n * @param {*} [options.localeMatcher] Pass 'lookup' to find a general vocabulary, if available\n * @returns {Vocabulary} the most specific vocabulary, or null\n */\n static findVocabulary(requestedLocale: string, vocabularies: Vocabulary[], options?: any): Vocabulary | null {\n let locale = requestedLocale;\n let done = false;\n do {\n const voc = vocabularies.find(v => v.getLocale() === locale);\n if (voc) {\n return voc;\n }\n\n if (options?.localeMatcher !== 'lookup') {\n done = true;\n break;\n }\n\n const pos = locale.lastIndexOf('-');\n if (pos === -1) {\n done = true;\n break;\n }\n locale = locale.substring(0, pos);\n } while (!done);\n return null;\n }\n\n /**\n * Gets a vocabulary for a given namespace plus locale\n * @param {string} namespace the namespace for the vocabulary\n * @param {string} locale the BCP-47 locale identifier\n * @param {*} [options] options to configure vocabulary lookup\n * @param {*} [options.localeMatcher] Pass 'lookup' to find a general vocabulary, if available\n * @returns {Vocabulary} the vocabulary or null if no vocabulary exists for the locale\n */\n getVocabulary(namespace: string, locale: string, options?: any): Vocabulary | null {\n const loc = locale.toLowerCase();\n const voc = this.vocabularies[`${namespace}/${loc}`];\n if (voc) {\n return voc;\n }\n if (options?.localeMatcher === 'lookup') {\n const vocs = this.getVocabulariesForNamespace(namespace);\n return VocabularyManager.findVocabulary(loc, vocs, options);\n }\n return null;\n }\n\n /**\n * Gets all the vocabulary files for a given namespace\n * @param {string} namespace the namespace\n * @returns {Vocabulary[]} the array of vocabularies\n */\n getVocabulariesForNamespace(namespace: string): Vocabulary[] {\n return Object.values(this.vocabularies).filter(v => v.getNamespace() === namespace);\n }\n\n /**\n * Gets all the vocabulary files for a given locale\n * @param {string} locale the BCP-47 locale identifier\n * @returns {Vocabulary[]} the array of vocabularies\n */\n getVocabulariesForLocale(locale: string): Vocabulary[] {\n return Object.values(this.vocabularies).filter(v => v.getLocale() === locale.toLowerCase());\n }\n\n /**\n * Resolve the term for a property, looking up terms from a more general vocabulary\n * if required, and resolving properties using an object manager, allowing terms defined\n * on super types to be automatically resolved.\n * @param {ModelManager} modelManager the model manager\n * @param {string} namespace the namespace\n * @param {string} locale the BCP-47 locale identifier\n * @param {string} declarationName the name of a concept or enum\n * @param {string} [propertyName] the name of a property (optional)\n * @param {string} [identifier] the identifier of the term (optional)\n * @returns {string|number|boolean|null} the term or null if it does not exist\n */\n resolveTerm(modelManager: ModelManager, namespace: string, locale: string, declarationName: string, propertyName?: string, identifier?: string): string | number | boolean | null {\n const modelFile = modelManager.getModelFile(namespace);\n // @ts-ignore\n const classDecl = modelFile ? (modelFile as any).getType(declarationName) : null;\n const property = propertyName ? classDecl ? classDecl.getProperty(propertyName) : null : null;\n return this.getTerm(property ? property.getNamespace() : namespace, locale, property ? (property.getParent() as any).getName() : declarationName, propertyName, identifier);\n }\n\n /**\n * Resolve the terms for a property, looking up terms from a more general vocabulary\n * if required, and resolving properties using an object manager, allowing terms defined\n * on super types to be automatically resolved.\n * @param {ModelManager} modelManager the model manager\n * @param {string} namespace the namespace\n * @param {string} locale the BCP-47 locale identifier\n * @param {string} declarationName the name of a concept or enum\n * @param {string} [propertyName] the name of a property (optional)\n * @param {*} [options] options to configure term resolution\n * @param {boolean} [options.generateMissing=true] whether to synthesize missing terms\n * @returns {*} the terms or null if it does not exist\n */\n resolveTerms(modelManager: ModelManager, namespace: string, locale: string, declarationName: string, propertyName?: string, options?: any) {\n const modelFile = modelManager.getModelFile(namespace);\n // @ts-ignore\n const classDecl = modelFile ? (modelFile as any).getType(declarationName) : null;\n let property;\n if(classDecl && !classDecl.isScalarDeclaration()) {\n if(classDecl.isMapDeclaration()) {\n if(propertyName === 'KEY') {\n property = classDecl.getKey();\n } else if(propertyName === 'VALUE') {\n property = classDecl.getValue();\n }\n } else {\n property = propertyName ? classDecl ? classDecl.getProperty(propertyName) : null : null;\n }\n }\n return this.getTerms(property ? property.getNamespace() : namespace, locale, property ? (property.getParent() as any).getName() : declarationName, propertyName, options);\n }\n\n /**\n * Gets the term for a concept, enum or property, looking up terms\n * from a more general vocabulary if required\n * @param {string} namespace the namespace\n * @param {string} locale the BCP-47 locale identifier\n * @param {string} declarationName the name of a concept or enum\n * @param {string} [propertyName] the name of a property (optional)\n * @param {string} [identifier] the identifier of the term (optional)\n * @returns {string|number|boolean|null} the term or null if it does not exist\n */\n getTerm(namespace: string, locale: string, declarationName: string, propertyName?: string, identifier?: string): string | number | boolean | null {\n const voc = this.getVocabulary(namespace, locale);\n let term = null;\n if (voc) {\n term = voc.getTerm(declarationName, propertyName, identifier);\n }\n if (term != null) {\n return term;\n }\n else {\n const dashIndex = locale.lastIndexOf('-');\n if (dashIndex >= 0) {\n return this.getTerm(namespace, locale.substring(0, dashIndex), declarationName, propertyName, identifier);\n }\n else {\n return this.missingTermGenerator ? this.missingTermGenerator(namespace, locale, declarationName, propertyName) : null;\n }\n }\n }\n\n /**\n * Gets the term for a concept, enum or property, looking up terms\n * from a more general vocabulary if required\n * @param {string} namespace the namespace\n * @param {string} locale the BCP-47 locale identifier\n * @param {string} declarationName the name of a concept or enum\n * @param {string} [propertyName] the name of a property (optional)\n * @param {*} [options] options to configure term resolution\n * @param {boolean} [options.generateMissing=true] whether to synthesize missing terms\n * @returns {*} the terms or null if it does not exist\n */\n getTerms(namespace: string, locale: string, declarationName: string, propertyName?: string, options?: any): any {\n const voc = this.getVocabulary(namespace, locale);\n let term = null;\n if (voc) {\n term = voc.getElementTerms(declarationName, propertyName);\n }\n if (term != null) {\n return term;\n }\n else {\n const dashIndex = locale.lastIndexOf('-');\n if (dashIndex >= 0) {\n return this.getTerms(namespace, locale.substring(0, dashIndex), declarationName, propertyName, options);\n }\n else {\n if (options?.generateMissing === false) {\n return;\n }\n let missingKey = propertyName ? propertyName : declarationName;\n missingKey = missingKey? missingKey : 'term';\n return this.missingTermGenerator ? { [missingKey]: this.missingTermGenerator(namespace, locale, declarationName, propertyName) } : null;\n }\n }\n }\n\n /**\n * Creates a DecoractorCommandSet with @Term decorators\n * to decorate all model elements based on the vocabulary for a locale.\n * Pass the return value to the DecoratorManager.decorateModel to apply\n * the decorators to a ModelManager.\n * @param {ModelManager} modelManager - the Model Manager\n * @param {string} locale the BCP-47 locale identifier\n * @returns {*} the decorator command set used to decorate the model.\n */\n generateDecoratorCommands(modelManager: ModelManager, locale: string): any {\n const commands: any[] = [];\n\n const CLASS_COMMAND = `${DC_NAMESPACE}.Command`;\n const CLASS_TARGET = `${DC_NAMESPACE}.CommandTarget`;\n const CLASS_DECORATOR = `${MetaModelNamespace}.Decorator`;\n const CLASS_DECORATOR_STRING = `${MetaModelNamespace}.DecoratorString`;\n\n const makeCommand = (target: any, decoratorName: string, value: string) => ({\n '$class': CLASS_COMMAND,\n 'type': 'UPSERT',\n 'target': target,\n 'decorator': {\n '$class': CLASS_DECORATOR,\n 'name': decoratorName,\n 'arguments': [{ '$class': CLASS_DECORATOR_STRING, 'value': value }]\n }\n });\n\n // @ts-ignore\n (modelManager as any).getModelFiles().forEach((model: any) => {\n const namespace = model.getNamespace();\n\n const nsTerms = this.getTerms(namespace, locale, '', undefined, { generateMissing: false });\n if (nsTerms) {\n const keys = Object.keys(nsTerms);\n for (let i = 0; i < keys.length; i++) {\n const term = keys[i];\n if (term === 'term') {\n commands.push(makeCommand(\n { '$class': CLASS_TARGET, 'namespace': namespace },\n 'Term', nsTerms[term]\n ));\n } else if (term !== 'declarations' && term !== 'namespace' && term !== 'locale') {\n commands.push(makeCommand(\n { '$class': CLASS_TARGET, 'namespace': namespace },\n `Term_${term}`, nsTerms[term]\n ));\n }\n }\n }\n\n model.getAllDeclarations().forEach((decl: any) => {\n const declName = decl.getName();\n\n const declTerms = this.getTerms(namespace, locale, declName);\n if (declTerms) {\n const keys = Object.keys(declTerms);\n for (let i = 0; i < keys.length; i++) {\n const term = keys[i];\n if (term === declName) {\n commands.push(makeCommand(\n { '$class': CLASS_TARGET, 'namespace': namespace, 'declaration': declName },\n 'Term', declTerms[term]\n ));\n } else if (term !== 'properties') {\n commands.push(makeCommand(\n { '$class': CLASS_TARGET, 'namespace': namespace, 'declaration': declName },\n `Term_${term}`, declTerms[term]\n ));\n }\n }\n }\n\n let propertyNames: string[] = [];\n if (decl.getProperties) {\n propertyNames = decl.getProperties().map((p: any) => p.getName());\n } else if (decl.isMapDeclaration?.()) {\n propertyNames = ['KEY', 'VALUE'];\n } else {\n return;\n }\n\n for (let p = 0; p < propertyNames.length; p++) {\n const propertyName = propertyNames[p];\n const propertyTerms = this.resolveTerms(modelManager, namespace, locale, declName, propertyName);\n if (propertyTerms) {\n const propertyType = propertyName === 'KEY' || propertyName === 'VALUE' ? 'mapElement' : 'property';\n const keys = Object.keys(propertyTerms);\n for (let i = 0; i < keys.length; i++) {\n const term = keys[i];\n commands.push(makeCommand(\n { '$class': CLASS_TARGET, 'namespace': namespace, 'declaration': declName, [propertyType]: propertyName },\n term === propertyName ? 'Term' : `Term_${term}`, propertyTerms[term]\n ));\n }\n }\n }\n });\n });\n\n return {\n '$class': `${DC_NAMESPACE}.DecoratorCommandSet`,\n 'name': `terms-${locale}`,\n 'version': '1.0.0',\n 'commands': commands\n };\n }\n\n /**\n * Validates the terms in the vocabulary against the namespaces and declarations\n * within a ModelManager\n * @param {ModelManager} modelManager - the Model Manager\n * @param {string} locale the BCP-47 locale identifier\n * @returns {*} the result of validation\n */\n validate(modelManager: ModelManager): any {\n // missing vocabularies\n // @ts-ignore\n const missingVocabularies = (modelManager as any).getModelFiles()\n .map((m: any) => this.getVocabulariesForNamespace(m.getNamespace()).length === 0 ? m.getNamespace() : null)\n .filter((m: any) => m !== null);\n\n // additional vocabularies\n const additionalVocabularies = Object.values(this.vocabularies)\n .filter(v => !modelManager.getModelFile(v.getNamespace()));\n\n const result: any = {\n missingVocabularies,\n additionalVocabularies,\n vocabularies: {}\n };\n\n // validate the models against the vocs\n Object.values(this.vocabularies)\n .forEach(voc => {\n const vocResult: any = {\n locale: voc.getLocale(),\n namespace: voc.getNamespace(),\n missingTerms: [],\n additionalTerms: []\n };\n\n const model = modelManager.getModelFile(voc.getNamespace());\n if (model) {\n const errors = voc.validate(model);\n if (errors.missingTerms) {\n vocResult.missingTerms = vocResult.missingTerms.concat(errors.missingTerms);\n }\n if (errors.additionalTerms) {\n vocResult.additionalTerms = vocResult.additionalTerms.concat(errors.additionalTerms);\n }\n\n result.vocabularies[`${vocResult.namespace}/${vocResult.locale}`] = vocResult;\n }\n });\n return result;\n }\n}\n\nexport { VocabularyManager };\nexport default VocabularyManager;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from "module";
|
|
2
|
+
const require = __createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// src/vocabulary.ts
|
|
5
|
+
var Vocabulary = class _Vocabulary {
|
|
6
|
+
/**
|
|
7
|
+
* Create the Vocabulary
|
|
8
|
+
* @constructor
|
|
9
|
+
* @param {VocabularyManager} vocabularyManager - the manager for this vocabulary
|
|
10
|
+
* @param {object} voc - the JSON representation of the vocabulary
|
|
11
|
+
*/
|
|
12
|
+
constructor(vocabularyManager, voc) {
|
|
13
|
+
if (!vocabularyManager) {
|
|
14
|
+
throw new Error("VocabularyManager must be specified");
|
|
15
|
+
}
|
|
16
|
+
if (!voc) {
|
|
17
|
+
throw new Error("Vocabulary object must be specified");
|
|
18
|
+
}
|
|
19
|
+
if (!voc.declarations) {
|
|
20
|
+
throw new Error("Vocabulary object must have declarations");
|
|
21
|
+
}
|
|
22
|
+
if (!voc.namespace) {
|
|
23
|
+
throw new Error("A vocabulary must specify a namespace");
|
|
24
|
+
}
|
|
25
|
+
if (!voc.locale) {
|
|
26
|
+
throw new Error("A vocabulary must specify a locale");
|
|
27
|
+
}
|
|
28
|
+
_Vocabulary.validateLocale(voc.locale);
|
|
29
|
+
this.vocabularyManager = vocabularyManager;
|
|
30
|
+
this.content = voc;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns the namespace for the vocabulary
|
|
34
|
+
* @returns {string} the namespace for this vocabulary
|
|
35
|
+
*/
|
|
36
|
+
getNamespace() {
|
|
37
|
+
return this.content.namespace;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validates a locale
|
|
41
|
+
* @param {string} locale the locale to validate
|
|
42
|
+
* @throws {Error} if the locale is invalid
|
|
43
|
+
*/
|
|
44
|
+
static validateLocale(locale) {
|
|
45
|
+
new Intl.Locale(locale);
|
|
46
|
+
if (locale !== locale.toLowerCase()) {
|
|
47
|
+
throw new Error("Locale should be lowercase with dashes");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns the locale for the vocabulary
|
|
52
|
+
* @returns {string} the locale for this vocabulary
|
|
53
|
+
*/
|
|
54
|
+
getLocale() {
|
|
55
|
+
return this.content.locale;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the identifier for the vocabulary, composed of the namespace plus the locale
|
|
59
|
+
* @returns {string} the identifier for this vocabulary
|
|
60
|
+
*/
|
|
61
|
+
getIdentifier() {
|
|
62
|
+
return `${this.getNamespace()}/${this.content.locale}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Returns all the declarations for this vocabulary
|
|
66
|
+
* @returns {Array} an array of objects
|
|
67
|
+
*/
|
|
68
|
+
getTerms() {
|
|
69
|
+
return this.content.declarations;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Gets the terms of Namespace
|
|
73
|
+
* @returns {string} the term or null if it does not exist
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
getNamespaceTerms() {
|
|
77
|
+
const namespaceTerms = Object.entries(this.content).filter(([key]) => key !== "namespace" && key !== "locale" && key !== "declarations");
|
|
78
|
+
return namespaceTerms.length > 0 ? Object.fromEntries(namespaceTerms) : null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Gets the term for a concept, enum or property
|
|
82
|
+
* @param {string} declarationName the name of a concept or enum
|
|
83
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
84
|
+
* @param {string} [identifier] the identifier of the term (optional)
|
|
85
|
+
* @returns {string|number|boolean|null} the term or null if it does not exist
|
|
86
|
+
*/
|
|
87
|
+
getTerm(declarationName, propertyName, identifier) {
|
|
88
|
+
if (!declarationName) {
|
|
89
|
+
const namespaceTerms = this.getNamespaceTerms();
|
|
90
|
+
return identifier ? namespaceTerms?.[identifier] : namespaceTerms?.term;
|
|
91
|
+
}
|
|
92
|
+
const decl = this.content.declarations.find((d) => Object.keys(d)[0] === declarationName);
|
|
93
|
+
if (!decl) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
if (!propertyName) {
|
|
97
|
+
return identifier ? decl[identifier] : decl[declarationName];
|
|
98
|
+
} else {
|
|
99
|
+
const property = decl.properties ? decl.properties.find((d) => propertyName in d) : null;
|
|
100
|
+
return property ? identifier ? property[identifier] : property[propertyName] : null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Gets the terms for a concept, enum or property
|
|
105
|
+
* @param {string} declarationName the name of a concept or enum
|
|
106
|
+
* @param {string} [propertyName] the name of a property (optional)
|
|
107
|
+
* @returns {string} the term or null if it does not exist
|
|
108
|
+
*/
|
|
109
|
+
getElementTerms(declarationName, propertyName) {
|
|
110
|
+
if (!declarationName) {
|
|
111
|
+
return this.getNamespaceTerms();
|
|
112
|
+
}
|
|
113
|
+
const decl = this.content.declarations.find((d) => Object.keys(d)[0] === declarationName);
|
|
114
|
+
if (!decl) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
if (!propertyName) {
|
|
118
|
+
return decl;
|
|
119
|
+
} else {
|
|
120
|
+
const property = decl.properties ? decl.properties.find((d) => propertyName in d) : null;
|
|
121
|
+
return property;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validates a vocabulary against a ModelFile, returning errors for
|
|
126
|
+
* missing and additional terms.
|
|
127
|
+
* @param {ModelFile} modelFile the model file for this vocabulary
|
|
128
|
+
* @returns {*} an object with missingTerms and additionalTerms properties
|
|
129
|
+
*/
|
|
130
|
+
validate(modelFile) {
|
|
131
|
+
const getOwnProperties = (declaration) => {
|
|
132
|
+
if (declaration.isMapDeclaration()) {
|
|
133
|
+
return [declaration.getKey(), declaration.getValue()];
|
|
134
|
+
} else {
|
|
135
|
+
return declaration.getOwnProperties?.() ? declaration.getOwnProperties?.() : [];
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const getPropertyName = (property) => {
|
|
139
|
+
if (property.isKey?.()) {
|
|
140
|
+
return "KEY";
|
|
141
|
+
} else if (property.isValue?.()) {
|
|
142
|
+
return "VALUE";
|
|
143
|
+
} else {
|
|
144
|
+
return property.getName();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const checkPropertyExists = (k, p) => {
|
|
148
|
+
const declaration = modelFile.getLocalType(Object.keys(k)[0]);
|
|
149
|
+
const property = Object.keys(p)[0];
|
|
150
|
+
if (declaration.isMapDeclaration()) {
|
|
151
|
+
if (property === "KEY") {
|
|
152
|
+
return true;
|
|
153
|
+
} else if (property === "VALUE") {
|
|
154
|
+
return true;
|
|
155
|
+
} else {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
return declaration.getOwnProperty(Object.keys(p)[0]);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const result = {
|
|
163
|
+
missingTerms: modelFile.getAllDeclarations().flatMap((d) => this.getTerm(d.getName()) ? getOwnProperties(d).flatMap((p) => this.getTerm(d.getName(), getPropertyName(p)) ? null : `${d.getName()}.${getPropertyName(p)}`) : d.getName()).filter((i) => i !== null),
|
|
164
|
+
additionalTerms: this.content.declarations.flatMap((k) => modelFile.getLocalType(Object.keys(k)[0]) ? Array.isArray(k.properties) ? k.properties.flatMap((p) => checkPropertyExists(k, p) ? null : `${Object.keys(k)[0]}.${Object.keys(p)[0]}`) : null : k).filter((i) => i !== null)
|
|
165
|
+
};
|
|
166
|
+
if (!this.content.term) {
|
|
167
|
+
result.missingTerms.push("namespace");
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Converts the object to JSON
|
|
173
|
+
* @returns {*} the contens of this vocabulary
|
|
174
|
+
*/
|
|
175
|
+
toJSON() {
|
|
176
|
+
return this.content;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
var vocabulary_default = Vocabulary;
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
Vocabulary,
|
|
183
|
+
vocabulary_default
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=chunk-7RW3VXN4.mjs.map
|