@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.
Files changed (40) hide show
  1. package/dist/esm/chunk-3VH3UOGB.mjs +398 -0
  2. package/dist/esm/chunk-3VH3UOGB.mjs.map +7 -0
  3. package/dist/esm/chunk-7RW3VXN4.mjs +185 -0
  4. package/dist/esm/chunk-7RW3VXN4.mjs.map +7 -0
  5. package/dist/esm/chunk-TA74NV57.mjs +38 -0
  6. package/dist/esm/chunk-TA74NV57.mjs.map +7 -0
  7. package/dist/esm/index.mjs +14 -0
  8. package/dist/esm/index.mjs.map +7 -0
  9. package/dist/esm/vocabulary.mjs +11 -0
  10. package/dist/esm/vocabulary.mjs.map +7 -0
  11. package/dist/esm/vocabularymanager.mjs +13 -0
  12. package/dist/esm/vocabularymanager.mjs.map +7 -0
  13. package/dist/esm/yamlparser.mjs +9 -0
  14. package/dist/esm/yamlparser.mjs.map +7 -0
  15. package/dist/esm-browser/chunk-2FE6COGH.mjs +2089 -0
  16. package/dist/esm-browser/chunk-2FE6COGH.mjs.map +7 -0
  17. package/dist/esm-browser/chunk-CKXQ5OWJ.mjs +187 -0
  18. package/dist/esm-browser/chunk-CKXQ5OWJ.mjs.map +7 -0
  19. package/dist/esm-browser/chunk-DSN2E4MW.mjs +6747 -0
  20. package/dist/esm-browser/chunk-DSN2E4MW.mjs.map +7 -0
  21. package/dist/esm-browser/chunk-K2X7J5YP.mjs +70 -0
  22. package/dist/esm-browser/chunk-K2X7J5YP.mjs.map +7 -0
  23. package/dist/esm-browser/index.mjs +18 -0
  24. package/dist/esm-browser/index.mjs.map +7 -0
  25. package/dist/esm-browser/vocabulary.mjs +10 -0
  26. package/dist/esm-browser/vocabulary.mjs.map +7 -0
  27. package/dist/esm-browser/vocabularymanager.mjs +12 -0
  28. package/dist/esm-browser/vocabularymanager.mjs.map +7 -0
  29. package/dist/esm-browser/yamlparser.mjs +8 -0
  30. package/dist/esm-browser/yamlparser.mjs.map +7 -0
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +7 -4
  33. package/dist/index.js.map +1 -1
  34. package/dist/vocabulary.d.ts +3 -2
  35. package/dist/vocabulary.js +5 -1
  36. package/dist/vocabulary.js.map +1 -1
  37. package/dist/vocabularymanager.d.ts +3 -2
  38. package/dist/vocabularymanager.js +6 -3
  39. package/dist/vocabularymanager.js.map +1 -1
  40. 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