@accordproject/concerto-util 1.2.2-20211130213656
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/LICENSE +11 -0
- package/README.md +13 -0
- package/changelog.txt +109 -0
- package/index.js +40 -0
- package/lib/filedownloader.js +135 -0
- package/lib/loaders/compositefileloader.js +95 -0
- package/lib/loaders/defaultfileloader.js +45 -0
- package/lib/loaders/githubfileloader.js +58 -0
- package/lib/loaders/httpfileloader.js +73 -0
- package/lib/logger.js +250 -0
- package/lib/typedstack.js +88 -0
- package/lib/writer.js +116 -0
- package/package.json +119 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
2
|
+
you may not use this file except in compliance with the License.
|
|
3
|
+
You may obtain a copy of the License at
|
|
4
|
+
|
|
5
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software
|
|
8
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
9
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
10
|
+
See the License for the specific language governing permissions and
|
|
11
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Concerto Core
|
|
2
|
+
|
|
3
|
+
Main library for Concerto models, model manager, JSON instance validation and serialization.
|
|
4
|
+
|
|
5
|
+
# Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @accordproject/concerto-core --save
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## License <a name="license"></a>
|
|
12
|
+
Accord Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file. Accord Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/.
|
|
13
|
+
|
package/changelog.txt
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
#
|
|
14
|
+
# This is the changelog for Hyperledger Concerto. It lists all significant changes to
|
|
15
|
+
# functionality and public API.
|
|
16
|
+
#
|
|
17
|
+
# The most recent entry in the changelog should be at the top of this file
|
|
18
|
+
# and must follow the format: Version <number> {public api digest} <date>. The version
|
|
19
|
+
# number must match that specified in package.json. The public api digest is computed
|
|
20
|
+
# and validated using ./scripts/api-changelog.sh
|
|
21
|
+
#
|
|
22
|
+
# Any changes to the public API must have an associated changelog entry.
|
|
23
|
+
#
|
|
24
|
+
# Note that the latest public API is documented using JSDocs and is available in api.txt.
|
|
25
|
+
#
|
|
26
|
+
|
|
27
|
+
Version 1.2.2 {a17601f3c2c7e81f521c8779093b03fa} 2021-11-24
|
|
28
|
+
- Remove custom instanceof and add methods to check runtime type
|
|
29
|
+
- Remove support for Node 12
|
|
30
|
+
- Generate Typescript definitions from JSDoc
|
|
31
|
+
- Parser directly constructs metamodel instance
|
|
32
|
+
- Convert MetaModel to a class for Typescript + Webpack compatability
|
|
33
|
+
- Update Acorn to latest and refactor the JavaScript parser so we can use static class members
|
|
34
|
+
|
|
35
|
+
Version 1.2.2 {b19318bb094e5da7bdff192cf9a3b4f2} 2021-08-12
|
|
36
|
+
- Fixes to metamodel, including terminology changes
|
|
37
|
+
- Ability to roundtrip model manager to metamodel
|
|
38
|
+
- Expose name resolution to MetaModel API
|
|
39
|
+
|
|
40
|
+
Version 1.1.2 {2c9512d9d90bde289b47942937d252ca} 2021-08-12
|
|
41
|
+
- Add Factory.newId for creating new unique IDs
|
|
42
|
+
|
|
43
|
+
Version 1.1.0 {16fb2d5684ec917532a19428c74f1ebf} 2021-07-13
|
|
44
|
+
- Add support for Concerto metamodel with import/export to CTO
|
|
45
|
+
|
|
46
|
+
Version 1.0.3 {1fe469fe1a79af5d5a4f5ec7dee6b7d4} 2021-06-25
|
|
47
|
+
- Aligns JSDoc and the TypeScript interface
|
|
48
|
+
|
|
49
|
+
Version 1.0.0-alpha.8 {08b0c809336354e7d1b17a2e44fca8b0} 2021-04-22
|
|
50
|
+
- Add datetimeutil & Consolidate UTC offset support
|
|
51
|
+
- Delete Concerto.instanceOf replace by ModelManager.derivesFrom
|
|
52
|
+
|
|
53
|
+
Version 1.0.0-alpha.7 {aec0f0d4e25be4dab03d6b94be60767b} 2021-04-17
|
|
54
|
+
- Remove unused systemtime options in modelfile API
|
|
55
|
+
- Fixes to the validation option targeting the ergo ES6 runtime
|
|
56
|
+
|
|
57
|
+
Version 1.0.0-alpha.5 {446997953e3ac90783ff9d492a8e7fdc} 2021-04-08
|
|
58
|
+
- Support Concerto version pragma at the beginning of model files
|
|
59
|
+
- Remove allowEmptyId option in factory API
|
|
60
|
+
|
|
61
|
+
Version 1.0.0-alpha.4 {3b7ebc06a536a5e81624225c7b0079ee} 2021-04-08
|
|
62
|
+
- Allow optional UTC offset for validating DateTime values
|
|
63
|
+
|
|
64
|
+
Version 1.0.0-alpha.3 {7b8763c243f937d84579350aef348c3c} 2020-12-25
|
|
65
|
+
- Concepts may now be identified
|
|
66
|
+
- assets/participants have a system identifier created ($identifier) automatically
|
|
67
|
+
- /transaction/events have a system timestamp created ($timestamp) automatically
|
|
68
|
+
- Can no longer redefine the identifier declared by a super type
|
|
69
|
+
- 'concerto' namespace is now reserved and cannot be used by user code
|
|
70
|
+
- All types extend concerto.Concept
|
|
71
|
+
- Removed System Models APIs
|
|
72
|
+
- Remove notion of system table
|
|
73
|
+
- Remove user ability to change system model
|
|
74
|
+
- Update JsDoc for ModelManager.addModelFiles
|
|
75
|
+
- Add Logger API
|
|
76
|
+
- Add instanceof alternatives to Factory and Serializer
|
|
77
|
+
- Add new Concerto API (experimental)
|
|
78
|
+
|
|
79
|
+
Version 0.82.9 {c96bafdd4a2bb7402f6b520a0cefe537} 2020-09-09
|
|
80
|
+
- Add option parameters to ModelLoader
|
|
81
|
+
|
|
82
|
+
Version 0.82.6 {03fa6481ffdf0e58cb110c6f24009d18} 2020-02-26
|
|
83
|
+
- Update JsDoc for ModelManager.addModelFiles
|
|
84
|
+
|
|
85
|
+
Version 0.82.1 {dee013e99a3c2d6acc4eddfb00aad2a2} 2019-10-22
|
|
86
|
+
- Make several constructors public
|
|
87
|
+
- Add model loader utility class
|
|
88
|
+
|
|
89
|
+
Version 0.80.3 {6f5a9ab45943cb76732c14b11f47d044} 2019-08-24
|
|
90
|
+
- Add Ergo option to serializer
|
|
91
|
+
|
|
92
|
+
Version 0.80.1 {297c88d29ce911ec6efc0f28ceeeb660} 2019-08-24
|
|
93
|
+
- Adds getModels and writeModelsToFileSystem functions to ModelManager
|
|
94
|
+
- Fixes API generation for hasSymbol function
|
|
95
|
+
|
|
96
|
+
Version 0.71.7 {2b5649f2b8f13d52241959f613cbfdd7} 2019-07-29
|
|
97
|
+
- Add static hasInstance as alternative instanceof implementation for AssetDeclaration, ClassDeclaration, EnumDeclaration, ConceptDeclaration, EnumValueDeclaration, Field, ModelFile, ModelManager, RelationshipDeclaration, TransactionDeclaration
|
|
98
|
+
|
|
99
|
+
Version 0.70.5 {db48b7eb8404d9206e9bc8efb3de0009} 2019-06-23
|
|
100
|
+
- Update exception triggered when creating EventDeclaration class
|
|
101
|
+
|
|
102
|
+
Version 0.31.0 {82c0c10648bd10fb79b84db3fcda1776} 2018-10-03
|
|
103
|
+
- Remove built-in system model file
|
|
104
|
+
|
|
105
|
+
Version 0.30.1 {fd4b813bc0bda4042db3c4657893593f} 2018-10-03
|
|
106
|
+
- Remove Wallet
|
|
107
|
+
|
|
108
|
+
Version 0.30.0 {785896a0c4c91e70dcbbfcc5bab33938} 2018-10-02
|
|
109
|
+
- Refactor to make model manager its own module
|
package/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Concerto module. Concerto is a framework for defining domain
|
|
19
|
+
* specific models.
|
|
20
|
+
*
|
|
21
|
+
* @module concerto-util
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Transitive closure downloader
|
|
25
|
+
module.exports.FileDownloader = require('./lib/filedownloader');
|
|
26
|
+
|
|
27
|
+
// File Loaders
|
|
28
|
+
module.exports.CompositeFileLoader = require('./lib/loaders/compositefileloader');
|
|
29
|
+
module.exports.DefaultFileLoader = require('./lib/loaders/defaultfileloader');
|
|
30
|
+
module.exports.GitHubFileLoader = require('./lib/loaders/githubfileloader');
|
|
31
|
+
module.exports.HTTPFileLoader = require('./lib/loaders/httpfileloader');
|
|
32
|
+
|
|
33
|
+
// Writers
|
|
34
|
+
module.exports.Writer = require('./lib/writer');
|
|
35
|
+
|
|
36
|
+
// Logger
|
|
37
|
+
module.exports.Logger = require('./lib/logger');
|
|
38
|
+
|
|
39
|
+
// TypedStack
|
|
40
|
+
module.exports.TypedStack = require('./lib/typedstack');
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const debug = require('debug')('concerto:FileDownloader');
|
|
18
|
+
const PromisePool = require('@supercharge/promise-pool');
|
|
19
|
+
|
|
20
|
+
const flatten = arr => [].concat(...arr);
|
|
21
|
+
const filterUndefined = arr => arr.filter(Boolean);
|
|
22
|
+
|
|
23
|
+
const handleJobError = async (error, job) => {
|
|
24
|
+
const badHttpResponse = error.response && error.response.status && error.response.status !== 200;
|
|
25
|
+
const dnsFailure = error.code && error.code === 'ENOTFOUND';
|
|
26
|
+
if(badHttpResponse || dnsFailure){
|
|
27
|
+
const err = new Error(`Unable to download external model dependency '${job.url}'`);
|
|
28
|
+
err.code = 'MISSING_DEPENDENCY';
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
throw new Error('Failed to load model file. Job: ' + job.url + ' Details: ' + error);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Downloads the transitive closure of a set of model files.
|
|
36
|
+
* @class
|
|
37
|
+
* @memberof module:concerto-core
|
|
38
|
+
*/
|
|
39
|
+
class FileDownloader {
|
|
40
|
+
/**
|
|
41
|
+
* Create a FileDownloader and bind to a FileLoader.
|
|
42
|
+
* @param {fileLoader} fileLoader - the loader to use to download model files
|
|
43
|
+
* @param {*} getExternalImports - a function taking a file and returning new files
|
|
44
|
+
* @param {Number} concurrency - the number of model files to download concurrently
|
|
45
|
+
*/
|
|
46
|
+
constructor(fileLoader, getExternalImports, concurrency = 10) {
|
|
47
|
+
this.fileLoader = fileLoader;
|
|
48
|
+
this.concurrency = concurrency;
|
|
49
|
+
this.getExternalImports = getExternalImports;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Download all external dependencies for an array of model files
|
|
54
|
+
* @param {File[]} files - the model files
|
|
55
|
+
* @param {Object} [options] - Options object passed to FileLoaders
|
|
56
|
+
* @return {Promise} a promise that resolves to Files[] for the external model files
|
|
57
|
+
*/
|
|
58
|
+
downloadExternalDependencies(files, options) {
|
|
59
|
+
const method = 'downloadExternalDependencies';
|
|
60
|
+
debug(method);
|
|
61
|
+
|
|
62
|
+
const downloadedUris = new Set();
|
|
63
|
+
|
|
64
|
+
if (!options) {
|
|
65
|
+
options = {};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const jobs = flatten(files.map(file => {
|
|
69
|
+
const externalImports = this.getExternalImports(file);
|
|
70
|
+
return Object.keys(externalImports).map(importDeclaration => ({
|
|
71
|
+
downloadedUris: downloadedUris,
|
|
72
|
+
url: externalImports[importDeclaration],
|
|
73
|
+
options: options
|
|
74
|
+
}));
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
return PromisePool
|
|
78
|
+
.withConcurrency(this.concurrency)
|
|
79
|
+
.for(jobs)
|
|
80
|
+
.handleError(handleJobError)
|
|
81
|
+
.process(x => this.runJob(x, this.fileLoader))
|
|
82
|
+
.then(({ results }) => filterUndefined(flatten(results)));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Execute a Job
|
|
87
|
+
* @param {Object} job - the job to execute
|
|
88
|
+
* @param {Object} fileLoader - the loader to use to download model files.
|
|
89
|
+
* @return {Promise} a promise to the job results
|
|
90
|
+
*/
|
|
91
|
+
runJob(job, fileLoader) {
|
|
92
|
+
const downloadedUris = job.downloadedUris;
|
|
93
|
+
const options = job.options;
|
|
94
|
+
const url = job.url;
|
|
95
|
+
|
|
96
|
+
// cache the URI, so we don't download it again
|
|
97
|
+
downloadedUris.add(url);
|
|
98
|
+
|
|
99
|
+
debug('runJob', 'Loading', url);
|
|
100
|
+
return fileLoader.load(url, options).
|
|
101
|
+
then(async file => {
|
|
102
|
+
debug('runJob', 'Loaded', url, );
|
|
103
|
+
|
|
104
|
+
// get the external imports
|
|
105
|
+
const externalImports = this.getExternalImports(file);
|
|
106
|
+
const importedUris = Array.from(
|
|
107
|
+
new Set(
|
|
108
|
+
Object.keys(externalImports)
|
|
109
|
+
.map((importDeclaration) => externalImports[importDeclaration])
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
debug('runJob', 'importedUris', importedUris);
|
|
113
|
+
|
|
114
|
+
const externalImportsFiles = await PromisePool
|
|
115
|
+
.withConcurrency(this.concurrency)
|
|
116
|
+
.for(importedUris)
|
|
117
|
+
.handleError(handleJobError)
|
|
118
|
+
.process(uri => {
|
|
119
|
+
if (!downloadedUris.has(uri)) {
|
|
120
|
+
// recurse and add a new job for the referenced URI
|
|
121
|
+
return this.runJob({
|
|
122
|
+
options: options,
|
|
123
|
+
url: uri,
|
|
124
|
+
downloadedUris: downloadedUris
|
|
125
|
+
}, fileLoader);
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
.then(({ results }) => filterUndefined(flatten(results)));
|
|
129
|
+
|
|
130
|
+
return externalImportsFiles.concat([file]);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = FileDownloader;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* <p>
|
|
19
|
+
* Manages a set of model file loaders, delegating to the first model file
|
|
20
|
+
* loader that accepts a URL.
|
|
21
|
+
* </p>
|
|
22
|
+
* @private
|
|
23
|
+
* @class
|
|
24
|
+
* @memberof module:concerto-util
|
|
25
|
+
*/
|
|
26
|
+
class CompositeFileLoader {
|
|
27
|
+
/**
|
|
28
|
+
* Create the CompositeFileLoader. Used to delegate to a set of FileLoaders.
|
|
29
|
+
*/
|
|
30
|
+
constructor() {
|
|
31
|
+
this.fileLoaders = [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Adds a FileLoader implemenetation to the FileLoader
|
|
36
|
+
* @param {FileLoader} fileLoader - The script to add to the ScriptManager
|
|
37
|
+
*/
|
|
38
|
+
addFileLoader(fileLoader) {
|
|
39
|
+
this.fileLoaders.push(fileLoader);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get the array of FileLoader instances
|
|
44
|
+
* @return {FileLoaders[]} The FileLoader registered
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
getFileLoaders() {
|
|
48
|
+
return this.fileLoaders;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Remove all registered FileLoaders
|
|
53
|
+
*/
|
|
54
|
+
clearFileLoaders() {
|
|
55
|
+
this.fileLoaders = [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if this ModelLoader can process the URL
|
|
60
|
+
* @param {string} url - the URL
|
|
61
|
+
* @return {boolean} true if this ModelLoader accepts the URL
|
|
62
|
+
* @abstract
|
|
63
|
+
*/
|
|
64
|
+
accepts(url) {
|
|
65
|
+
for (let n = 0; n < this.fileLoaders.length; n++) {
|
|
66
|
+
const ml = this.fileLoaders[n];
|
|
67
|
+
|
|
68
|
+
if (ml.accepts(url)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Load a File from a URL and return it
|
|
78
|
+
* @param {string} url - the url to get
|
|
79
|
+
* @param {object} options - additional options
|
|
80
|
+
* @return {Promise} a promise to the File
|
|
81
|
+
*/
|
|
82
|
+
load(url, options) {
|
|
83
|
+
for (let n = 0; n < this.fileLoaders.length; n++) {
|
|
84
|
+
const ml = this.fileLoaders[n];
|
|
85
|
+
|
|
86
|
+
if (ml.accepts(url)) {
|
|
87
|
+
return ml.load(url, options);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
throw new Error('Failed to find a model file loader that can handle: ' + url);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = CompositeFileLoader;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const CompositeFileLoader = require('./compositefileloader');
|
|
18
|
+
const HTTPFileLoader = require('./httpfileloader');
|
|
19
|
+
const GitHubFileLoader = require('./githubfileloader');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* <p>
|
|
23
|
+
* A default CompositeFileLoader implementation which supports
|
|
24
|
+
* github://, http:// and https:// URLs.
|
|
25
|
+
* </p>
|
|
26
|
+
* @private
|
|
27
|
+
* @class
|
|
28
|
+
* @see See {@link CompositeFileLoader}
|
|
29
|
+
* @memberof module:concerto-util
|
|
30
|
+
*/
|
|
31
|
+
class DefaultFileLoader extends CompositeFileLoader {
|
|
32
|
+
/**
|
|
33
|
+
* Create the DefaultFileLoader.
|
|
34
|
+
* @param {*} processFile - a function to apply to the content of the file
|
|
35
|
+
*/
|
|
36
|
+
constructor(processFile) {
|
|
37
|
+
super();
|
|
38
|
+
const http = new HTTPFileLoader(processFile);
|
|
39
|
+
const github = new GitHubFileLoader(processFile);
|
|
40
|
+
this.addFileLoader(github);
|
|
41
|
+
this.addFileLoader(http);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = DefaultFileLoader;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const HTTPFileLoader = require('./httpfileloader');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Loads Files from an external source, such as a URL.
|
|
21
|
+
*
|
|
22
|
+
* @class
|
|
23
|
+
* @private
|
|
24
|
+
* @memberof module:concerto-util
|
|
25
|
+
*/
|
|
26
|
+
class GitHubFileLoader extends HTTPFileLoader {
|
|
27
|
+
/**
|
|
28
|
+
* Create the GitHubFileLoader.
|
|
29
|
+
* @param {*} processFile - a function to apply to the content of the file
|
|
30
|
+
*/
|
|
31
|
+
constructor(processFile) {
|
|
32
|
+
super(processFile);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if this ModelLoader can process the URL
|
|
37
|
+
* @param {string} url - the URL
|
|
38
|
+
* @return {boolean} true if this ModelLoader accepts the URL
|
|
39
|
+
* @abstract
|
|
40
|
+
*/
|
|
41
|
+
accepts(url) {
|
|
42
|
+
return url.startsWith('github://');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Load a File from a URL and return it
|
|
47
|
+
* @param {string} url - the url to get
|
|
48
|
+
* @param {object} options - additional options
|
|
49
|
+
* @return {Promise} a promise to the File
|
|
50
|
+
*/
|
|
51
|
+
load(url, options) {
|
|
52
|
+
const rewrittenUrl = 'https://raw.githubusercontent.com/' + url.substring(9);
|
|
53
|
+
const result = super.load(rewrittenUrl, options);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = GitHubFileLoader;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const axios = require('axios');
|
|
18
|
+
const url = require('url');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Loads Files from an HTTP(S) URL using the axios library.
|
|
22
|
+
* @class
|
|
23
|
+
* @private
|
|
24
|
+
* @memberof module:concerto-util
|
|
25
|
+
*/
|
|
26
|
+
class HTTPFileLoader {
|
|
27
|
+
/**
|
|
28
|
+
* Create the HTTPFileLoader.
|
|
29
|
+
* @param {*} processFile - a function to apply to the content of the file
|
|
30
|
+
*/
|
|
31
|
+
constructor(processFile) {
|
|
32
|
+
this.processFile = processFile;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if this ModelLoader can process the URL
|
|
37
|
+
* @param {string} url - the URL
|
|
38
|
+
* @return {boolean} true if this ModelLoader accepts the URL
|
|
39
|
+
* @abstract
|
|
40
|
+
*/
|
|
41
|
+
accepts(url) {
|
|
42
|
+
return url.startsWith('http://') || url.startsWith('https://');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Load a File from a URL and return it
|
|
47
|
+
* @param {string} requestUrl - the url to get
|
|
48
|
+
* @param {object} options - additional options
|
|
49
|
+
* @return {Promise} a promise to the File
|
|
50
|
+
*/
|
|
51
|
+
load(requestUrl, options) {
|
|
52
|
+
|
|
53
|
+
if(!options) {
|
|
54
|
+
options = {};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const request = JSON.parse(JSON.stringify(options));
|
|
58
|
+
request.url = requestUrl;
|
|
59
|
+
request.method = 'get';
|
|
60
|
+
request.responseType = 'text';
|
|
61
|
+
|
|
62
|
+
return axios(request)
|
|
63
|
+
.then((response) => {
|
|
64
|
+
let parsedUrl = url.parse(requestUrl);
|
|
65
|
+
// external Files have a name that starts with '@'
|
|
66
|
+
// (so that they are identified as external when an archive is read back in)
|
|
67
|
+
const name = '@' + (parsedUrl.host + parsedUrl.pathname).replace(/\//g, '.');
|
|
68
|
+
return this.processFile(name, response.data);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = HTTPFileLoader;
|
package/lib/logger.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/* eslint-disable no-console */
|
|
18
|
+
/* eslint-disable no-use-before-define */
|
|
19
|
+
|
|
20
|
+
const colors = require('colors/safe');
|
|
21
|
+
const jsonColorize = require('json-colorizer');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default levels for the npm configuration.
|
|
25
|
+
* @type {Object}
|
|
26
|
+
*/
|
|
27
|
+
const levels = {
|
|
28
|
+
error: 0,
|
|
29
|
+
warn: 1,
|
|
30
|
+
info: 2,
|
|
31
|
+
http: 3,
|
|
32
|
+
verbose: 4,
|
|
33
|
+
debug: 5,
|
|
34
|
+
silly: 6
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Default levels for the npm configuration.
|
|
39
|
+
* @type {Object}
|
|
40
|
+
*/
|
|
41
|
+
const colorMap = {
|
|
42
|
+
error: 'red',
|
|
43
|
+
warn: 'yellow',
|
|
44
|
+
info: 'green',
|
|
45
|
+
verbose: 'cyan',
|
|
46
|
+
debug: 'blue',
|
|
47
|
+
silly: 'magenta'
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const timestamp = () => (new Date()).toLocaleTimeString();
|
|
51
|
+
const colorize = level => colors[colorMap[level]](level.toUpperCase());
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Helper function to test if a string is a stringified version of a JSON object
|
|
55
|
+
* @param {string} str - the input string to test
|
|
56
|
+
* @returns {boolean} - true iff the string can be parsed as JSON
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
const isJson = (str) => {
|
|
60
|
+
try {
|
|
61
|
+
return (JSON.parse(str) && !!str);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Helper function to color and format JSON objects
|
|
69
|
+
* @param {any} obj - the input obj to prettify
|
|
70
|
+
* @returns {any} - the prettified object
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
const prettifyJson = (obj) => {
|
|
74
|
+
if(typeof obj === 'object' || isJson(obj)) {
|
|
75
|
+
return jsonColorize(obj, { pretty: true, colors });
|
|
76
|
+
}
|
|
77
|
+
return obj;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The default transport for logging at multiple levels to the console
|
|
82
|
+
* @param {string} level - the required log level. e.g. error, warn, info, debug, etc.
|
|
83
|
+
* @param {any} obj - the input obj to prettify
|
|
84
|
+
* @returns {void} -
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
const defaultTransportShim = (level, ...args) => {
|
|
88
|
+
let mutatedLevel = level;
|
|
89
|
+
let data = args;
|
|
90
|
+
let first = data.shift();
|
|
91
|
+
|
|
92
|
+
// Flatten log object
|
|
93
|
+
if(first && typeof first === 'object' && first.level && first.message){
|
|
94
|
+
const padding = first.padding && first.padding[first.level];
|
|
95
|
+
if (first.level === 'error' && first.stack) {
|
|
96
|
+
mutatedLevel = 'error';
|
|
97
|
+
first = `${first.message}\n${first.stack}`;
|
|
98
|
+
} else if (Object.keys(levels).includes(first.level)) {
|
|
99
|
+
mutatedLevel = first.level;
|
|
100
|
+
first = first.message;
|
|
101
|
+
}
|
|
102
|
+
first = padding ? `${padding} ${first}` : first;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
data.unshift(first);
|
|
106
|
+
|
|
107
|
+
const stream = ['error', 'warn'].includes(mutatedLevel) ? console.error : console.log;
|
|
108
|
+
|
|
109
|
+
stream(
|
|
110
|
+
`${timestamp()} - ${colorize(mutatedLevel)}:`,
|
|
111
|
+
...data
|
|
112
|
+
.map(obj => obj instanceof Error ? `${obj.message}\n${obj.stack}`: obj)
|
|
113
|
+
.map(prettifyJson)
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
const defaultTransport = {};
|
|
117
|
+
Object.keys(levels).forEach(level => {
|
|
118
|
+
defaultTransport[level] = (...args) => defaultTransportShim(level, ...args);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A utility class with static function that print to the console
|
|
123
|
+
* @private
|
|
124
|
+
*/
|
|
125
|
+
class Logger {
|
|
126
|
+
/**
|
|
127
|
+
* A reusable function for logging at multiple levels
|
|
128
|
+
* @param {string} level - the required log level. e.g. error, warn, info, debug, etc.
|
|
129
|
+
* @param {any} obj - the input obj to prettify
|
|
130
|
+
* @returns {void} -
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
static dispatch(level, ...args) {
|
|
134
|
+
if (levels[level] > levels[this.level]){
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
this.transports.forEach(t => {
|
|
139
|
+
if(t[level]){
|
|
140
|
+
t[level](...args);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Add a custom transport for logging
|
|
147
|
+
* @param {Object} transport - The transport object should have function for the usual logging operations e.g. error, warn, info, debug, etc.
|
|
148
|
+
* @returns {void} -
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
static add(transport) {
|
|
152
|
+
this.transports.push(transport);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Write an error statement to the console.
|
|
157
|
+
*
|
|
158
|
+
* Prints to `stderr` with newline.
|
|
159
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
160
|
+
* @param {any} args -
|
|
161
|
+
* @returns {void} -
|
|
162
|
+
* @private
|
|
163
|
+
*/
|
|
164
|
+
static error(...args){ return this.dispatch('error', ...args); }
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Write a warning statement to the console.
|
|
168
|
+
*
|
|
169
|
+
* Prints to `stderr` with newline.
|
|
170
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
171
|
+
* @param {any} args -
|
|
172
|
+
* @returns {void} -
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
static warn(...args){ return this.dispatch('warn', ...args); }
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Write an info statement to the console.
|
|
179
|
+
*
|
|
180
|
+
* Prints to `stdout` with newline.
|
|
181
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
182
|
+
* @param {any} args -
|
|
183
|
+
* @returns {void} -
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
static info(...args){ return this.dispatch('info', ...args); }
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Write an info statement to the console. Alias for `logger.log`
|
|
190
|
+
*
|
|
191
|
+
* Prints to `stdout` with newline.
|
|
192
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
193
|
+
* @param {any} args -
|
|
194
|
+
* @returns {void} -
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
static log(...args){ return this.info(...args); }
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Write an http statement to the console.
|
|
201
|
+
*
|
|
202
|
+
* Prints to `stdout` with newline.
|
|
203
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
204
|
+
* @param {any} args -
|
|
205
|
+
* @returns {void} -
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
static http(...args){ return this.dispatch('http', ...args); }
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Write a verbose log statement to the console.
|
|
212
|
+
*
|
|
213
|
+
* Prints to `stdout` with newline.
|
|
214
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
215
|
+
* @param {any} args -
|
|
216
|
+
* @returns {void} -
|
|
217
|
+
* @private
|
|
218
|
+
*/
|
|
219
|
+
static verbose(...args){ return this.dispatch('verbose', ...args); }
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Write a debug statement to the console.
|
|
223
|
+
*
|
|
224
|
+
* Prints to `stdout` with newline.
|
|
225
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
226
|
+
* @param {any} args -
|
|
227
|
+
* @returns {void} -
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
static debug(...args){ return this.dispatch('debug', ...args); }
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Write a silly level statement to the console.
|
|
234
|
+
*
|
|
235
|
+
* Prints to `stdout` with newline.
|
|
236
|
+
* @param {any|object} data - if this is an object with properties `level` and `message` it will be flattened first
|
|
237
|
+
* @param {any} args -
|
|
238
|
+
* @returns {void} -
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
static silly(...args){ return this.dispatch('silly', ...args); }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Set the default logging level
|
|
245
|
+
Logger.level = 'info';
|
|
246
|
+
|
|
247
|
+
// A list of user-provided logging tranports
|
|
248
|
+
Logger.transports = [ defaultTransport ];
|
|
249
|
+
|
|
250
|
+
module.exports = Logger;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Tracks a stack of typed instances. The type information is used to detect
|
|
19
|
+
* overflow / underflow bugs by the caller. It also performs basic sanity
|
|
20
|
+
* checking on push/pop to make detecting bugs easier.
|
|
21
|
+
* @class
|
|
22
|
+
* @memberof module:concerto-core
|
|
23
|
+
*/
|
|
24
|
+
class TypedStack {
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create the Stack with the resource at the head.
|
|
28
|
+
* @param {Object} resource - the resource to be put at the head of the stack
|
|
29
|
+
*/
|
|
30
|
+
constructor(resource) {
|
|
31
|
+
this.stack = [];
|
|
32
|
+
this.push(resource);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Push a new object.
|
|
37
|
+
* @param {Object} obj - the object being visited
|
|
38
|
+
* @param {Object} expectedType - the expected type of the object being pushed
|
|
39
|
+
*/
|
|
40
|
+
push(obj, expectedType) {
|
|
41
|
+
if(expectedType && !(obj instanceof expectedType)) {
|
|
42
|
+
throw new Error('Did not find expected type ' + expectedType.constructor.name + ' as argument to push. Found: ' + obj.toString());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.stack.push(obj);
|
|
46
|
+
//console.log('Push depth is: ' + this.stack.length + ', contents: ' + this.stack.toString() );
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Push a new object.
|
|
51
|
+
* @param {Object} expectedType - the type that should be the result of pop
|
|
52
|
+
* @return {Object} the result of pop
|
|
53
|
+
*/
|
|
54
|
+
pop(expectedType) {
|
|
55
|
+
this.peek(expectedType);
|
|
56
|
+
return this.stack.pop();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Peek the top of the stack
|
|
61
|
+
* @param {Object} expectedType - the type that should be the result of pop
|
|
62
|
+
* @return {Object} the result of peek
|
|
63
|
+
*/
|
|
64
|
+
peek(expectedType) {
|
|
65
|
+
|
|
66
|
+
//console.log( 'pop ' );
|
|
67
|
+
|
|
68
|
+
if(this.stack.length < 1) {
|
|
69
|
+
throw new Error('Stack is empty!');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const result = this.stack[this.stack.length-1];
|
|
73
|
+
if(expectedType && !(result instanceof expectedType)) {
|
|
74
|
+
throw new Error('Did not find expected type ' + expectedType + ' on head of stack. Found: ' + result);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Clears the stack
|
|
82
|
+
*/
|
|
83
|
+
clear() {
|
|
84
|
+
this.stack = [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = TypedStack;
|
package/lib/writer.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Writer buffers text to be written in memory. It handles simple
|
|
19
|
+
* indentation and tracks the number of lines written.
|
|
20
|
+
* @private
|
|
21
|
+
* @class
|
|
22
|
+
* @memberof module:concerto-util
|
|
23
|
+
*/
|
|
24
|
+
class Writer {
|
|
25
|
+
/**
|
|
26
|
+
* Create a Writer.
|
|
27
|
+
*/
|
|
28
|
+
constructor() {
|
|
29
|
+
this.beforeBuffer = '';
|
|
30
|
+
this.buffer = '';
|
|
31
|
+
this.linesWritten = 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Writes text to the start of the buffer
|
|
36
|
+
* @param {int} tabs - the number of tabs to use
|
|
37
|
+
* @param {string} text - the text to write
|
|
38
|
+
*/
|
|
39
|
+
writeBeforeLine(tabs, text) {
|
|
40
|
+
for(let n=0; n < tabs; n++) {
|
|
41
|
+
this.beforeBuffer += ' ';
|
|
42
|
+
}
|
|
43
|
+
this.beforeBuffer += text;
|
|
44
|
+
this.beforeBuffer += '\n';
|
|
45
|
+
this.linesWritten++;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Append text to the buffer
|
|
50
|
+
* @param {int} tabs - the number of tabs to use
|
|
51
|
+
* @param {string} text - the text to write
|
|
52
|
+
*/
|
|
53
|
+
writeLine(tabs, text) {
|
|
54
|
+
for(let n=0; n < tabs; n++) {
|
|
55
|
+
this.write(' ');
|
|
56
|
+
}
|
|
57
|
+
this.write(text);
|
|
58
|
+
this.write('\n');
|
|
59
|
+
this.linesWritten++;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns the number of lines that have been written to the buffer.
|
|
64
|
+
* @return {int} the number of lines written to the buffer.
|
|
65
|
+
*/
|
|
66
|
+
getLineCount() {
|
|
67
|
+
return this.linesWritten;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Append text to the buffer, prepending tabs
|
|
73
|
+
* @param {int} tabs - the number of tabs to use
|
|
74
|
+
* @param {string} text - the text to write
|
|
75
|
+
*/
|
|
76
|
+
writeIndented(tabs,text) {
|
|
77
|
+
for(let n=0; n < tabs; n++) {
|
|
78
|
+
this.write(' ');
|
|
79
|
+
}
|
|
80
|
+
this.write(text);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Append text to the buffer (no automatic newline). The
|
|
85
|
+
* text may contain newline, and these will increment the linesWritten
|
|
86
|
+
* counter.
|
|
87
|
+
* @param {string} msg - the text to write
|
|
88
|
+
*/
|
|
89
|
+
write(msg) {
|
|
90
|
+
if(typeof msg !== 'string' ) {
|
|
91
|
+
throw new Error('Can only append strings. Argument ' + msg + ' has type ' + typeof msg);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.buffer += msg;
|
|
95
|
+
this.linesWritten += msg.split(/\r\n|\r|\n/).length;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the text that has been buffered in this Writer.
|
|
100
|
+
* @return {string} the buffered text.
|
|
101
|
+
*/
|
|
102
|
+
getBuffer() {
|
|
103
|
+
return this.beforeBuffer + this.buffer;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Empties the underyling buffer and resets the line count.
|
|
108
|
+
*/
|
|
109
|
+
clearBuffer() {
|
|
110
|
+
this.beforeBuffer = '';
|
|
111
|
+
this.buffer = '';
|
|
112
|
+
this.linesWritten = 0;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = Writer;
|
package/package.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@accordproject/concerto-util",
|
|
3
|
+
"version": "1.2.2-20211130213656",
|
|
4
|
+
"description": "Utilities for Concerto Modeling Language",
|
|
5
|
+
"homepage": "https://github.com/accordproject/concerto",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=12",
|
|
8
|
+
"npm": ">=6"
|
|
9
|
+
},
|
|
10
|
+
"main": "index.js",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"pretest": "npm run lint",
|
|
13
|
+
"lint": "eslint .",
|
|
14
|
+
"postlint": "npm run licchk",
|
|
15
|
+
"licchk": "license-check-and-add",
|
|
16
|
+
"postlicchk": "npm run doc",
|
|
17
|
+
"doc": "jsdoc --pedantic --recurse -c jsdoc.json",
|
|
18
|
+
"test": "nyc mocha --recursive -t 10000",
|
|
19
|
+
"test:watch": "nyc mocha --watch --recursive -t 10000",
|
|
20
|
+
"mocha": "mocha --recursive -t 10000",
|
|
21
|
+
"nyc": "nyc mocha --recursive -t 10000"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/accordproject/concerto.git",
|
|
26
|
+
"directory": "packages/concerto-util"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"blockchain",
|
|
30
|
+
"hyperledger",
|
|
31
|
+
"solutions"
|
|
32
|
+
],
|
|
33
|
+
"author": "accordproject.org",
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"chai": "4.3.4",
|
|
37
|
+
"chai-as-promised": "7.1.1",
|
|
38
|
+
"chai-things": "0.2.0",
|
|
39
|
+
"eslint": "8.2.0",
|
|
40
|
+
"jsdoc": "^3.6.7",
|
|
41
|
+
"license-check-and-add": "2.3.6",
|
|
42
|
+
"mocha": "8.3.2",
|
|
43
|
+
"moxios": "0.4.0",
|
|
44
|
+
"nyc": "15.1.0",
|
|
45
|
+
"sinon": "10.0.0",
|
|
46
|
+
"sinon-chai": "3.6.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@supercharge/promise-pool": "1.7.0",
|
|
50
|
+
"axios": "0.23.0",
|
|
51
|
+
"colors": "1.4.0",
|
|
52
|
+
"debug": "4.3.1",
|
|
53
|
+
"json-colorizer": "2.2.2"
|
|
54
|
+
},
|
|
55
|
+
"browserslist": "> 0.25%, not dead",
|
|
56
|
+
"license-check-and-add-config": {
|
|
57
|
+
"folder": "./lib",
|
|
58
|
+
"license": "HEADER",
|
|
59
|
+
"exact_paths_method": "EXCLUDE",
|
|
60
|
+
"exact_paths": [
|
|
61
|
+
"api.txt",
|
|
62
|
+
"composer-logs",
|
|
63
|
+
"coverage",
|
|
64
|
+
"./parser.js",
|
|
65
|
+
"LICENSE",
|
|
66
|
+
"node_modules",
|
|
67
|
+
".nyc-output",
|
|
68
|
+
"out",
|
|
69
|
+
".tern-project"
|
|
70
|
+
],
|
|
71
|
+
"file_type_method": "EXCLUDE",
|
|
72
|
+
"file_types": [
|
|
73
|
+
".yml",
|
|
74
|
+
".yaml",
|
|
75
|
+
".zip",
|
|
76
|
+
".tgz"
|
|
77
|
+
],
|
|
78
|
+
"insert_license": false,
|
|
79
|
+
"license_formats": {
|
|
80
|
+
"js|njk|pegjs|cto|acl|qry": {
|
|
81
|
+
"prepend": "/*",
|
|
82
|
+
"append": " */",
|
|
83
|
+
"eachLine": {
|
|
84
|
+
"prepend": " * "
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"npmrc|editorconfig|txt": {
|
|
88
|
+
"eachLine": {
|
|
89
|
+
"prepend": "# "
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"md": {
|
|
93
|
+
"file": "HEADER.md"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"nyc": {
|
|
98
|
+
"produce-source-map": "true",
|
|
99
|
+
"sourceMap": "inline",
|
|
100
|
+
"reporter": [
|
|
101
|
+
"lcov",
|
|
102
|
+
"text-summary",
|
|
103
|
+
"html",
|
|
104
|
+
"json"
|
|
105
|
+
],
|
|
106
|
+
"include": [
|
|
107
|
+
"lib/**/*.js"
|
|
108
|
+
],
|
|
109
|
+
"exclude": [
|
|
110
|
+
"lib/parser.js"
|
|
111
|
+
],
|
|
112
|
+
"all": true,
|
|
113
|
+
"check-coverage": true,
|
|
114
|
+
"statements": 99,
|
|
115
|
+
"branches": 93,
|
|
116
|
+
"functions": 98,
|
|
117
|
+
"lines": 99
|
|
118
|
+
}
|
|
119
|
+
}
|