@accordproject/concerto-core 1.2.2-20211124164813 → 1.2.2-20211124205408

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Concerto Core
2
2
 
3
- Main library for Concerto model parsing, model manager, JSON instance validation and serialization.
3
+ Main library for Concerto models, model manager, JSON instance validation and serialization.
4
4
 
5
5
  # Installation
6
6
 
package/changelog.txt CHANGED
@@ -24,7 +24,7 @@
24
24
  # Note that the latest public API is documented using JSDocs and is available in api.txt.
25
25
  #
26
26
 
27
- Version 1.2.2 {82c68f1a011449a7783092b0aff0b928} 2021-11-24
27
+ Version 1.2.2 {5b6204cb85376284c240cd69ffb06734} 2021-11-22
28
28
  - Remove custom instanceof and add methods to check runtime type
29
29
  - Remove support for Node 12
30
30
  - Generate Typescript definitions from JSDoc
@@ -14,15 +14,20 @@
14
14
 
15
15
  'use strict';
16
16
 
17
- const parser = require('./parser');
17
+ const { Printer } = require('@accordproject/concerto-cto');
18
18
  const ModelManager = require('../modelmanager');
19
19
  const Factory = require('../factory');
20
20
  const Serializer = require('../serializer');
21
21
 
22
22
  /**
23
- * The metamodel itself, as a CTO string
23
+ * Class to work with the Concerto metamodel
24
24
  */
25
- const metaModelCto = `namespace concerto.metamodel
25
+ class MetaModel {
26
+
27
+ /**
28
+ * The metamodel itself, as a CTO string
29
+ */
30
+ static metaModelCto = `namespace concerto.metamodel
26
31
 
27
32
  concept Position {
28
33
  o Integer line
@@ -188,6 +193,7 @@ concept ImportType extends Import {
188
193
 
189
194
  concept Model {
190
195
  o String namespace
196
+ o String sourceUri optional
191
197
  o String concertoVersion optional
192
198
  o Import[] imports optional
193
199
  o Declaration[] declarations optional
@@ -198,26 +204,13 @@ concept Models {
198
204
  }
199
205
  `;
200
206
 
201
- /**
202
- * Class to work with the Concerto metamodel
203
- */
204
- class MetaModel {
205
-
206
- /**
207
- * Returns the metamodel CTO
208
- * @returns {string} the metamodel as a CTO string
209
- */
210
- static getMetaModelCto() {
211
- return metaModelCto;
212
- }
213
-
214
207
  /**
215
208
  * Create a metamodel manager (for validation against the metamodel)
216
209
  * @return {*} the metamodel manager
217
210
  */
218
211
  static createMetaModelManager() {
219
212
  const metaModelManager = new ModelManager();
220
- metaModelManager.addModelFile(metaModelCto, 'concerto.metamodel');
213
+ metaModelManager.addModelFile(MetaModel.metaModelCto, 'concerto.metamodel');
221
214
  return metaModelManager;
222
215
  }
223
216
 
@@ -367,11 +360,15 @@ class MetaModel {
367
360
  * Resolve the namespace for names in the metamodel
368
361
  * @param {object} modelManager - the ModelManager
369
362
  * @param {object} metaModel - the MetaModel
363
+ * @param {boolean} [validate] - whether to perform validation
370
364
  * @return {object} the resolved metamodel
371
365
  */
372
- static resolveMetaModel(modelManager, metaModel) {
373
- const result = JSON.parse(JSON.stringify(metaModel));
374
- const nameTable = MetaModel.createNameTable(modelManager, metaModel);
366
+ static resolveMetaModel(modelManager, metaModel, validate = true) {
367
+ // First, validate the JSON metaModel
368
+ const mm = validate ? MetaModel.validateMetaModel(metaModel) : metaModel;
369
+
370
+ const result = JSON.parse(JSON.stringify(mm));
371
+ const nameTable = MetaModel.createNameTable(modelManager, mm);
375
372
  // This adds the fully qualified names to the same object
376
373
  MetaModel.resolveTypeNames(result, nameTable);
377
374
  return result;
@@ -383,7 +380,7 @@ class MetaModel {
383
380
  * @param {boolean} [validate] - whether to perform validation
384
381
  * @return {object} the metamodel for this model
385
382
  */
386
- static modelFileToMetaModel(modelFile, validate) {
383
+ static modelFileToMetaModel(modelFile, validate = true) {
387
384
  // Last, validate the JSON metaModel
388
385
  return validate ? MetaModel.validateMetaModel(modelFile.ast) : modelFile.ast;
389
386
  }
@@ -395,7 +392,7 @@ class MetaModel {
395
392
  * @param {boolean} [validate] - whether to perform validation
396
393
  * @return {object} the metamodel for this model manager
397
394
  */
398
- static modelManagerToMetaModel(modelManager, resolve, validate) {
395
+ static modelManagerToMetaModel(modelManager, resolve, validate = true) {
399
396
  const result = {
400
397
  $class: 'concerto.metamodel.Models',
401
398
  models: [],
@@ -403,293 +400,34 @@ class MetaModel {
403
400
  modelManager.getModelFiles().forEach((modelFile) => {
404
401
  let metaModel = modelFile.ast;
405
402
  if (resolve) {
406
- metaModel = MetaModel.resolveMetaModel(modelManager, metaModel);
403
+ // No need to re-validate when models are obtained from model manager
404
+ metaModel = MetaModel.resolveMetaModel(modelManager, metaModel, false);
407
405
  }
408
406
  result.models.push(metaModel);
409
407
  });
410
408
  return result;
411
409
  }
412
410
 
413
- /**
414
- * Create decorator argument string from a metamodel
415
- * @param {object} mm - the metamodel
416
- * @return {string} the string for the decorator argument
417
- */
418
- static decoratorArgFromMetaModel(mm) {
419
- let result = '';
420
- switch (mm.$class) {
421
- case 'concerto.metamodel.DecoratorTypeReference':
422
- result += `${mm.type.name}${mm.isArray ? '[]' : ''}`;
423
- break;
424
- case 'concerto.metamodel.DecoratorString':
425
- result += `"${mm.value}"`;
426
- break;
427
- default:
428
- result += `${mm.value}`;
429
- break;
430
- }
431
- return result;
432
- }
433
-
434
- /**
435
- * Create decorator string from a metamodel
436
- * @param {object} mm - the metamodel
437
- * @return {string} the string for the decorator
438
- */
439
- static decoratorFromMetaModel(mm) {
440
- let result = '';
441
- result += `@${mm.name}`;
442
- if (mm.arguments) {
443
- result += '(';
444
- result += mm.arguments.map(MetaModel.decoratorArgFromMetaModel).join(',');
445
- result += ')';
446
- }
447
- return result;
448
- }
449
-
450
- /**
451
- * Create decorators string from a metamodel
452
- * @param {object} mm - the metamodel
453
- * @param {string} prefix - indentation
454
- * @return {string} the string for the decorators
455
- */
456
- static decoratorsFromMetaModel(mm, prefix) {
457
- let result = '';
458
- result += mm.map(MetaModel.decoratorFromMetaModel).join(`\n${prefix}`);
459
- result += `\n${prefix}`;
460
- return result;
461
- }
462
-
463
- /**
464
- * Create a property string from a metamodel
465
- * @param {object} mm - the metamodel
466
- * @return {string} the string for that property
467
- */
468
- static propertyFromMetaModel(mm) {
469
- let result = '';
470
- let defaultString = '';
471
- let validatorString = '';
472
-
473
- if (mm.decorators) {
474
- result += MetaModel.decoratorsFromMetaModel(mm.decorators, ' ');
475
- }
476
- if (mm.$class === 'concerto.metamodel.RelationshipProperty') {
477
- result += '-->';
478
- } else {
479
- result += 'o';
480
- }
481
-
482
- switch (mm.$class) {
483
- case 'concerto.metamodel.EnumProperty':
484
- break;
485
- case 'concerto.metamodel.BooleanProperty':
486
- result += ' Boolean';
487
- if (mm.defaultValue === true || mm.defaultValue === false) {
488
- if (mm.defaultValue) {
489
- defaultString += ' default=true';
490
- } else {
491
- defaultString += ' default=false';
492
- }
493
- }
494
- break;
495
- case 'concerto.metamodel.DateTimeProperty':
496
- result += ' DateTime';
497
- break;
498
- case 'concerto.metamodel.DoubleProperty':
499
- result += ' Double';
500
- if (mm.defaultValue) {
501
- const doubleString = mm.defaultValue.toFixed(Math.max(1, (mm.defaultValue.toString().split('.')[1] || []).length));
502
-
503
- defaultString += ` default=${doubleString}`;
504
- }
505
- if (mm.validator) {
506
- const lowerString = mm.validator.lower ? mm.validator.lower : '';
507
- const upperString = mm.validator.upper ? mm.validator.upper : '';
508
- validatorString += ` range=[${lowerString},${upperString}]`;
509
- }
510
- break;
511
- case 'concerto.metamodel.IntegerProperty':
512
- result += ' Integer';
513
- if (mm.defaultValue) {
514
- defaultString += ` default=${mm.defaultValue.toString()}`;
515
- }
516
- if (mm.validator) {
517
- const lowerString = mm.validator.lower ? mm.validator.lower : '';
518
- const upperString = mm.validator.upper ? mm.validator.upper : '';
519
- validatorString += ` range=[${lowerString},${upperString}]`;
520
- }
521
- break;
522
- case 'concerto.metamodel.LongProperty':
523
- result += ' Long';
524
- if (mm.defaultValue) {
525
- defaultString += ` default=${mm.defaultValue.toString()}`;
526
- }
527
- if (mm.validator) {
528
- const lowerString = mm.validator.lower ? mm.validator.lower : '';
529
- const upperString = mm.validator.upper ? mm.validator.upper : '';
530
- validatorString += ` range=[${lowerString},${upperString}]`;
531
- }
532
- break;
533
- case 'concerto.metamodel.StringProperty':
534
- result += ' String';
535
- if (mm.defaultValue) {
536
- defaultString += ` default="${mm.defaultValue}"`;
537
- }
538
- if (mm.validator) {
539
- validatorString += ` regex=/${mm.validator.pattern}/${mm.validator.flags}`;
540
- }
541
- break;
542
- case 'concerto.metamodel.ObjectProperty':
543
- result += ` ${mm.type.name}`;
544
- if (mm.defaultValue) {
545
- defaultString += ` default="${mm.defaultValue}"`;
546
- }
547
- break;
548
- case 'concerto.metamodel.RelationshipProperty':
549
- result += ` ${mm.type.name}`;
550
- break;
551
- }
552
- if (mm.isArray) {
553
- result += '[]';
554
- }
555
- result += ` ${mm.name}`;
556
- if (mm.isOptional) {
557
- result += ' optional';
558
- }
559
- result += defaultString;
560
- result += validatorString;
561
- return result;
562
- }
563
-
564
- /**
565
- * Create a declaration string from a metamodel
566
- * @param {object} mm - the metamodel
567
- * @return {string} the string for that declaration
568
- */
569
- static declFromMetaModel(mm) {
570
- let result = '';
571
- if (mm.decorators) {
572
- result += MetaModel.decoratorsFromMetaModel(mm.decorators, '');
573
- }
574
-
575
- if (mm.isAbstract) {
576
- result += 'abstract ';
577
- }
578
- switch (mm.$class) {
579
- case 'concerto.metamodel.AssetDeclaration':
580
- result += `asset ${mm.name} `;
581
- break;
582
- case 'concerto.metamodel.ConceptDeclaration':
583
- result += `concept ${mm.name} `;
584
- break;
585
- case 'concerto.metamodel.EventDeclaration':
586
- result += `event ${mm.name} `;
587
- break;
588
- case 'concerto.metamodel.ParticipantDeclaration':
589
- result += `participant ${mm.name} `;
590
- break;
591
- case 'concerto.metamodel.TransactionDeclaration':
592
- result += `transaction ${mm.name} `;
593
- break;
594
- case 'concerto.metamodel.EnumDeclaration':
595
- result += `enum ${mm.name} `;
596
- break;
597
- }
598
- if (mm.superType) {
599
- result += `extends ${mm.superType.name} `;
600
- }
601
- // XXX Needs to be fixed to support `identified`
602
- if (mm.identified) {
603
- if (mm.identified.$class === 'concerto.metamodel.IdentifiedBy') {
604
- result += `identified by ${mm.identified.name} `;
605
- } else {
606
- result += 'identified ';
607
- }
608
- }
609
- result += '{';
610
- mm.properties.forEach((property) => {
611
- result += `\n ${MetaModel.propertyFromMetaModel(property)}`;
612
- });
613
- result += '\n}';
614
- return result;
615
- }
616
-
617
- /**
618
- * Create a model string from a metamodel
619
- * @param {object} metaModel - the metamodel
620
- * @param {boolean} [validate] - whether to perform validation
621
- * @return {string} the string for that model
622
- */
623
- static ctoFromMetaModel(metaModel, validate = true) {
624
- // First, validate the JSON metaModel
625
- const mm = validate ? MetaModel.validateMetaModel(metaModel) : metaModel;
626
-
627
- let result = '';
628
- result += `namespace ${mm.namespace}`;
629
- if (mm.imports && mm.imports.length > 0) {
630
- result += '\n';
631
- mm.imports.forEach((imp) => {
632
- let name = '*';
633
- if (imp.$class === 'concerto.metamodel.ImportType') {
634
- name = imp.name;
635
- }
636
- result += `\nimport ${imp.namespace}.${name}`;
637
- if (imp.uri) {
638
- result += ` from ${imp.uri}`;
639
- }
640
- });
641
- }
642
- if (mm.declarations && mm.declarations.length > 0) {
643
- mm.declarations.forEach((decl) => {
644
- result += `\n\n${MetaModel.declFromMetaModel(decl)}`;
645
- });
646
- }
647
- return result;
648
- }
649
-
650
411
  /**
651
412
  * Import metamodel to a model manager
652
413
  * @param {object} metaModel - the metamodel
653
414
  * @param {boolean} [validate] - whether to perform validation
654
415
  * @return {object} the metamodel for this model manager
655
416
  */
656
- static modelManagerFromMetaModel(metaModel, validate) {
417
+ static modelManagerFromMetaModel(metaModel, validate = true) {
657
418
  // First, validate the JSON metaModel
658
419
  const mm = validate ? MetaModel.validateMetaModel(metaModel) : metaModel;
659
420
 
660
421
  const modelManager = new ModelManager();
661
422
 
662
423
  mm.models.forEach((mm) => {
663
- const cto = MetaModel.ctoFromMetaModel(mm, false); // No need to re-validate
424
+ const cto = Printer.toCTO(mm); // No need to re-validate
664
425
  modelManager.addModelFile(cto, null, false);
665
426
  });
666
427
 
667
428
  modelManager.validateModelFiles();
668
429
  return modelManager;
669
430
  }
670
-
671
- /**
672
- * Export metamodel from a model string
673
- * @param {string} model - the string for the model
674
- * @param {boolean} [validate] - whether to perform validation
675
- * @return {object} the metamodel for this model
676
- */
677
- static ctoToMetaModel(model, validate) {
678
- return parser.parse(model);
679
- }
680
-
681
- /**
682
- * Export metamodel from a model string and resolve names
683
- * @param {*} modelManager - the model manager
684
- * @param {string} model - the string for the model
685
- * @param {boolean} [validate] - whether to perform validation
686
- * @return {object} the metamodel for this model
687
- */
688
- static ctoToMetaModelAndResolve(modelManager, model, validate) {
689
- const metaModel = parser.parse(model);
690
- const result = MetaModel.resolveMetaModel(modelManager, metaModel);
691
- return result;
692
- }
693
431
  }
694
432
 
695
433
  module.exports = MetaModel;
@@ -16,7 +16,6 @@
16
16
 
17
17
  const packageJson = require('../../package.json');
18
18
  const semver = require('semver');
19
- const parser = require('./parser');
20
19
  const AssetDeclaration = require('./assetdeclaration');
21
20
  const EnumDeclaration = require('./enumdeclaration');
22
21
  const ConceptDeclaration = require('./conceptdeclaration');
@@ -27,6 +26,7 @@ const IllegalModelException = require('./illegalmodelexception');
27
26
  const ParseException = require('./parseexception');
28
27
  const ModelUtil = require('../modelutil');
29
28
  const Globalize = require('../globalize');
29
+ const { Parser } = require('@accordproject/concerto-cto');
30
30
 
31
31
  /**
32
32
  * Class representing a Model File. A Model File contains a single namespace
@@ -72,8 +72,7 @@ class ModelFile {
72
72
  }
73
73
 
74
74
  try {
75
- this.ast = parser.parse(definitions);
76
- // console.log(`AST ${JSON.stringify(this.ast, null, 2)}`);
75
+ this.ast = Parser.parse(definitions);
77
76
  }
78
77
  catch(err) {
79
78
  if(err.location && err.location.start) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accordproject/concerto-core",
3
- "version": "1.2.2-20211124164813",
3
+ "version": "1.2.2-20211124205408",
4
4
  "description": "Core Implementation for the Concerto Modeling Language",
5
5
  "homepage": "https://github.com/accordproject/concerto",
6
6
  "engines": {
@@ -10,7 +10,6 @@
10
10
  "main": "index.js",
11
11
  "typings": "types/index.d.ts",
12
12
  "scripts": {
13
- "prepare": "peggy ./lib/introspect/parser.pegjs",
14
13
  "pretest": "npm run lint",
15
14
  "lint": "eslint .",
16
15
  "postlint": "npm run licchk",
@@ -59,6 +58,7 @@
59
58
  "yargs": "17.1.0"
60
59
  },
61
60
  "dependencies": {
61
+ "@accordproject/concerto-cto": "1.2.2-20211124205408",
62
62
  "@supercharge/promise-pool": "1.7.0",
63
63
  "axios": "0.23.0",
64
64
  "colors": "1.4.0",
@@ -83,7 +83,6 @@
83
83
  "coverage",
84
84
  "index.d.ts",
85
85
  "./system",
86
- "./introspect/parser.js",
87
86
  "LICENSE",
88
87
  "node_modules",
89
88
  ".nyc-output",
@@ -128,11 +127,7 @@
128
127
  "include": [
129
128
  "lib/**/*.js"
130
129
  ],
131
- "exclude": [
132
- "lib/codegen/parsejs.js",
133
- "lib/codegen/javascriptparser.js",
134
- "lib/introspect/parser.js"
135
- ],
130
+ "exclude": [],
136
131
  "all": true,
137
132
  "check-coverage": true,
138
133
  "statements": 98,
@@ -4,10 +4,9 @@ export = MetaModel;
4
4
  */
5
5
  declare class MetaModel {
6
6
  /**
7
- * Returns the metamodel CTO
8
- * @returns {string} the metamodel as a CTO string
7
+ * The metamodel itself, as a CTO string
9
8
  */
10
- static getMetaModelCto(): string;
9
+ static metaModelCto: string;
11
10
  /**
12
11
  * Create a metamodel manager (for validation against the metamodel)
13
12
  * @return {*} the metamodel manager
@@ -14,6 +14,29 @@ declare class ModelUtil {
14
14
  * @private
15
15
  */
16
16
  private static getShortName;
17
+ /**
18
+ * Returns true if the specified name is a wildcard
19
+ * @param {string} fqn - the source string
20
+ * @return {boolean} true if the specified name is a wildcard
21
+ * @private
22
+ */
23
+ private static isWildcardName;
24
+ /**
25
+ * Returns true if the specified name is a recusive wildcard
26
+ * @param {string} fqn - the source string
27
+ * @return {boolean} true if the specified name is a recusive wildcard
28
+ * @private
29
+ */
30
+ private static isRecursiveWildcardName;
31
+ /**
32
+ * Returns true if a type matches the required fully qualified name. The required
33
+ * name may be a wildcard or recursive wildcard
34
+ * @param {Typed} type - the type to test
35
+ * @param {string} fqn - required fully qualified name
36
+ * @return {boolean} true if the specified type and namespace match
37
+ * @private
38
+ */
39
+ private static isMatchingType;
17
40
  /**
18
41
  * Returns the namespace for a the fully qualified name of a type
19
42
  * @param {string} fqn - the fully qualified identifier of a type
@@ -22,13 +45,6 @@ declare class ModelUtil {
22
45
  * @private
23
46
  */
24
47
  private static getNamespace;
25
- /**
26
- * Return the fully qualified name for an import
27
- * @param {object} imp - the import
28
- * @return {string} - the fully qualified name for that import
29
- * @private
30
- */
31
- private static importFullyQualifiedName;
32
48
  /**
33
49
  * Returns true if the type is a primitive type
34
50
  * @param {string} typeName - the name of the type