1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | 'use strict';
|
15 |
|
16 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
17 |
|
18 | function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
19 |
|
20 | const fs = require('fs');
|
21 |
|
22 | const fsPath = require('path');
|
23 |
|
24 | const slash = require('slash');
|
25 |
|
26 | const JSZip = require('jszip');
|
27 |
|
28 | const xregexp = require('xregexp');
|
29 |
|
30 | const languageTagRegex = require('ietf-language-tag-regex');
|
31 |
|
32 | const DefaultArchiveLoader = require('./loaders/defaultarchiveloader');
|
33 |
|
34 | const FileLoader = require('@accordproject/ergo-compiler').FileLoader;
|
35 |
|
36 | const Logger = require('@accordproject/concerto-core').Logger;
|
37 |
|
38 |
|
39 | const IETF_REGEXP = languageTagRegex({
|
40 | exact: false
|
41 | }).toString().slice(1, -2);
|
42 | const SAMPLE_FILE_REGEXP = xregexp('text[/\\\\]sample(_(' + IETF_REGEXP + '))?.md$');
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | class TemplateLoader extends FileLoader {
|
51 | |
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 | static fromArchive(Template, buffer, options) {
|
59 | return _asyncToGenerator(function* () {
|
60 | const method = 'fromArchive';
|
61 | const zip = yield JSZip.loadAsync(buffer);
|
62 |
|
63 |
|
64 | const ctoModelFiles = [];
|
65 | const ctoModelFileNames = [];
|
66 | const sampleTextFiles = {};
|
67 | const readmeContents = yield TemplateLoader.loadZipFileContents(zip, 'README.md');
|
68 | let sampleFiles = yield TemplateLoader.loadZipFilesContents(zip, SAMPLE_FILE_REGEXP);
|
69 | sampleFiles.forEach(
|
70 |
|
71 | function () {
|
72 | var _ref = _asyncToGenerator(function* (sampleFile) {
|
73 | let matches = sampleFile.name.match(SAMPLE_FILE_REGEXP);
|
74 | let locale = 'default';
|
75 |
|
76 | if (matches !== null && matches[2]) {
|
77 | locale = matches[2];
|
78 | }
|
79 |
|
80 | sampleTextFiles[locale] = sampleFile.contents;
|
81 | });
|
82 |
|
83 | return function (_x) {
|
84 | return _ref.apply(this, arguments);
|
85 | };
|
86 | }());
|
87 | const requestContents = yield TemplateLoader.loadZipFileContents(zip, 'request.json', true);
|
88 | const packageJsonObject = yield TemplateLoader.loadZipFileContents(zip, 'package.json', true, true);
|
89 | const templatizedGrammar = yield TemplateLoader.loadZipFileContents(zip, 'text/grammar.tem.md', false, false);
|
90 | Logger.debug(method, 'Looking for model files');
|
91 | let ctoFiles = yield TemplateLoader.loadZipFilesContents(zip, /model[/\\].*\.cto$/);
|
92 | ctoFiles.forEach(
|
93 |
|
94 | function () {
|
95 | var _ref2 = _asyncToGenerator(function* (file) {
|
96 | ctoModelFileNames.push(file.name);
|
97 | ctoModelFiles.push(file.contents);
|
98 | });
|
99 |
|
100 | return function (_x2) {
|
101 | return _ref2.apply(this, arguments);
|
102 | };
|
103 | }());
|
104 |
|
105 | const template = new (Function.prototype.bind.call(Template, null, packageJsonObject, readmeContents, sampleTextFiles, requestContents, options))();
|
106 |
|
107 | Logger.debug(method, 'Adding model files to model manager');
|
108 | template.getModelManager().addModelFiles(ctoModelFiles, ctoModelFileNames, true);
|
109 |
|
110 | Logger.debug(method, 'Setting grammar');
|
111 |
|
112 | if (!templatizedGrammar) {
|
113 | throw new Error('A template must contain a grammar.tem.md file.');
|
114 | } else {
|
115 | template.parserManager.buildGrammar(templatizedGrammar);
|
116 | }
|
117 |
|
118 |
|
119 | if (template.getMetadata().getRuntime() === 'ergo') {
|
120 | template.getLogicManager().addTemplateFile(templatizedGrammar, 'text/grammar.tem.md');
|
121 | Logger.debug(method, 'Adding Ergo files to script manager');
|
122 | const scriptFiles = yield TemplateLoader.loadZipFilesContents(zip, /logic[/\\].*\.ergo$/);
|
123 | scriptFiles.forEach(function (obj) {
|
124 | template.getLogicManager().addLogicFile(obj.contents, obj.name);
|
125 | });
|
126 | } else {
|
127 |
|
128 | Logger.debug(method, 'Adding JS files to script manager');
|
129 | const scriptFiles = yield TemplateLoader.loadZipFilesContents(zip, /logic[/\\].*\.js$/);
|
130 | scriptFiles.forEach(function (obj) {
|
131 | template.getLogicManager().addLogicFile(obj.contents, obj.name);
|
132 | });
|
133 | }
|
134 |
|
135 |
|
136 | template.validate();
|
137 | return template;
|
138 | })();
|
139 | }
|
140 | |
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | static fromUrl(Template, url, options) {
|
150 | return _asyncToGenerator(function* () {
|
151 | const loader = new DefaultArchiveLoader();
|
152 | const buffer = yield loader.load(url, options);
|
153 | return TemplateLoader.fromArchive(Template, buffer, options);
|
154 | })();
|
155 | }
|
156 | |
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 | static fromDirectory(Template, path, options) {
|
169 | return _asyncToGenerator(function* () {
|
170 | if (!options) {
|
171 | options = {};
|
172 | }
|
173 |
|
174 | const method = 'fromDirectory';
|
175 |
|
176 | const readmeContents = yield TemplateLoader.loadFileContents(path, 'README.md');
|
177 |
|
178 | const requestJsonObject = yield TemplateLoader.loadFileContents(path, 'request.json', true);
|
179 |
|
180 | const packageJsonObject = yield TemplateLoader.loadFileContents(path, 'package.json', true, true);
|
181 |
|
182 | Logger.debug(method, 'Looking for sample files');
|
183 | const sampleFiles = yield TemplateLoader.loadFilesContents(path, SAMPLE_FILE_REGEXP);
|
184 | const sampleTextFiles = {};
|
185 | sampleFiles.forEach(file => {
|
186 | const matches = file.name.match(SAMPLE_FILE_REGEXP);
|
187 | let locale = 'default';
|
188 |
|
189 | if (matches !== null && matches[2]) {
|
190 | locale = matches[2];
|
191 | }
|
192 |
|
193 | Logger.debug(method, 'Using sample file locale', locale);
|
194 | sampleTextFiles[locale] = file.contents;
|
195 | });
|
196 |
|
197 | const template = new (Function.prototype.bind.call(Template, null, packageJsonObject, readmeContents, sampleTextFiles, requestJsonObject, options))();
|
198 | const modelFiles = [];
|
199 | const modelFileNames = [];
|
200 | const ctoFiles = yield TemplateLoader.loadFilesContents(path, /model[/\\].*\.cto$/);
|
201 | ctoFiles.forEach(file => {
|
202 | modelFileNames.push(slash(file.name));
|
203 | modelFiles.push(file.contents);
|
204 | });
|
205 | template.getModelManager().addModelFiles(modelFiles, modelFileNames, true);
|
206 |
|
207 | if (!options.skipUpdateExternalModels) {
|
208 | yield template.getModelManager().updateExternalModels();
|
209 | Logger.debug(method, 'Added model files', modelFiles.length);
|
210 | const externalModelFiles = template.getModelManager().getModels();
|
211 | externalModelFiles.forEach(function (file) {
|
212 | fs.writeFileSync(path + '/model/' + file.name, file.content);
|
213 | });
|
214 | }
|
215 |
|
216 |
|
217 | let templatizedGrammar = yield TemplateLoader.loadFileContents(path, 'text/grammar.tem.md', false, false);
|
218 |
|
219 | if (!templatizedGrammar) {
|
220 | throw new Error('A template must either contain a grammar.tem.md file.');
|
221 | } else {
|
222 | template.parserManager.buildGrammar(templatizedGrammar);
|
223 | Logger.debug(method, 'Loaded grammar.tem.md', templatizedGrammar);
|
224 | }
|
225 |
|
226 | Logger.debug(method, 'Loaded grammar.tem.md');
|
227 |
|
228 | if (template.getMetadata().getRuntime() === 'ergo') {
|
229 |
|
230 | template.getLogicManager().addTemplateFile(templatizedGrammar, 'text/grammar.tem.md');
|
231 | const ergoFiles = yield TemplateLoader.loadFilesContents(path, /logic[/\\].*\.ergo$/);
|
232 | ergoFiles.forEach(file => {
|
233 | const resolvedPath = slash(fsPath.resolve(path));
|
234 | const resolvedFilePath = slash(fsPath.resolve(file.name));
|
235 | const truncatedPath = resolvedFilePath.replace(resolvedPath + '/', '');
|
236 | template.getLogicManager().addLogicFile(file.contents, truncatedPath);
|
237 | });
|
238 | } else {
|
239 |
|
240 | const jsFiles = yield TemplateLoader.loadFilesContents(path, /logic[/\\].*\.js$/);
|
241 | jsFiles.forEach(file => {
|
242 | const resolvedPath = slash(fsPath.resolve(path));
|
243 | const resolvedFilePath = slash(fsPath.resolve(file.name));
|
244 | const truncatedPath = resolvedFilePath.replace(resolvedPath + '/', '');
|
245 | template.getLogicManager().addLogicFile(file.contents, truncatedPath);
|
246 | });
|
247 | }
|
248 |
|
249 |
|
250 | template.validate();
|
251 | return template;
|
252 | })();
|
253 | }
|
254 | |
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 | static normalizeText(input) {
|
262 |
|
263 | let text = input.replace(/\r/gm, '');
|
264 | return text;
|
265 | }
|
266 |
|
267 | }
|
268 |
|
269 | module.exports = TemplateLoader; |
\ | No newline at end of file |