@webos-tools/cli 3.1.1 → 3.1.3

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 (53) hide show
  1. package/CHANGELOG.md +173 -157
  2. package/LICENSES/342/200/216/LicenseRef-3rd_party_licenses.txt +1355 -0
  3. package/README.md +21 -19
  4. package/bin/ares-config.js +6 -3
  5. package/bin/ares-device.js +2 -2
  6. package/bin/ares-log.js +6 -2
  7. package/bin/ares-pull.js +1 -1
  8. package/bin/ares-push.js +1 -1
  9. package/bin/ares-setup-device.js +573 -528
  10. package/bin/ares-shell.js +1 -1
  11. package/bin/ares.js +1 -1
  12. package/files/conf/ares.json +5 -5
  13. package/files/conf/novacom-devices.json +18 -1
  14. package/files/conf-base/env/sdk-apollo.json +8 -0
  15. package/files/conf-base/profile/config-apollo.json +29 -0
  16. package/files/conf-base/profile/config-ose.json +1 -1
  17. package/files/conf-base/template-conf/apollo-sdk-templates.json +56 -0
  18. package/files/help/ares-config.help +6 -1
  19. package/files/help/ares-device.help +15 -0
  20. package/files/help/ares-generate.help +27 -1
  21. package/files/help/ares-inspect.help +6 -0
  22. package/files/help/ares-install.help +5 -0
  23. package/files/help/ares-launch.help +5 -0
  24. package/files/help/ares-server.help +5 -0
  25. package/files/help/ares-setup-device.help +40 -0
  26. package/files/help/ares.help +5 -0
  27. package/files/schema/NovacomDevices.schema +2 -1
  28. package/files/templates/apollo-sdk-templates/appinfo/appinfo.json +10 -0
  29. package/files/templates/apollo-sdk-templates/bootplate-web/index.html +88 -0
  30. package/files/templates/apollo-sdk-templates/hosted-webapp/index.html +14 -0
  31. package/files/templates/apollo-sdk-templates/icon/icon.png +0 -0
  32. package/files/templates/apollo-sdk-templates/js-service/helloclient.js +31 -0
  33. package/files/templates/apollo-sdk-templates/js-service/helloworld_webos_service.js +188 -0
  34. package/files/templates/apollo-sdk-templates/native-service/CMakeLists.txt +72 -0
  35. package/files/templates/apollo-sdk-templates/native-service/services.json +11 -0
  36. package/files/templates/apollo-sdk-templates/native-service/src/main.c +144 -0
  37. package/files/templates/apollo-sdk-templates/serviceinfo/package.json +11 -0
  38. package/files/templates/apollo-sdk-templates/serviceinfo/services.json +8 -0
  39. package/lib/base/novacom.js +1 -1
  40. package/lib/base/setup-device.js +338 -335
  41. package/lib/device.js +1 -1
  42. package/lib/generator.js +408 -377
  43. package/lib/package.js +3 -1
  44. package/lib/shell.js +1 -1
  45. package/npm-shrinkwrap.json +9242 -9242
  46. package/package.json +100 -100
  47. package/sbom-info.yaml +1758 -0
  48. package/spec/jsSpecs/ares-config.spec.js +10 -0
  49. package/spec/jsSpecs/ares-generate.spec.js +4 -4
  50. package/spec/jsSpecs/ares-log.spec.js +1 -1
  51. package/spec/test_data/ares-generate.json +18 -1
  52. package/spec/test_data/ares.json +17 -0
  53. package/webos-tools-cli-3.1.3.tgz +0 -0
package/lib/generator.js CHANGED
@@ -1,377 +1,408 @@
1
- #!/usr/bin/env node
2
-
3
- /*
4
- * Copyright (c) 2020-2024 LG Electronics Inc.
5
- *
6
- * SPDX-License-Identifier: Apache-2.0
7
- */
8
-
9
- const promise = require('bluebird'),
10
- Table = require('easy-table'),
11
- fs = promise.promisifyAll(require('fs-extra')),
12
- log = require('npmlog'),
13
- path = require('path'),
14
- errHndl = require('./base/error-handler'),
15
- copyToDirAsync = require('./util/copy').copyToDirAsync,
16
- readJsonSync = require('./util/json').readJsonSync,
17
- merge = require('./util/merge');
18
-
19
- const templatePath = path.join(__dirname, '/../files/conf/', 'template.json');
20
- let templates;
21
-
22
- log.heading = 'generator';
23
- log.level = 'warn';
24
-
25
- function Generator() {
26
- if (templatePath) {
27
- const cliPath = path.join(__dirname, '..');
28
- let contents = fs.readFileSync(templatePath);
29
- contents = contents.toString().replace(/\$cli-root/gi, cliPath).replace(/\\/g,'/');
30
- templates = JSON.parse(contents);
31
- } else {
32
- templates = null;
33
- }
34
- }
35
-
36
- Generator.prototype.showTemplates = function(listType, next) {
37
- const templateList = this.getTmpl(),
38
- table = new Table(),
39
- _displayType = {
40
- "webapp": "Web App",
41
- "nativeapp": "Native App",
42
- "webappinfo": "Web App Info",
43
- "nativeappinfo": "Native App Info",
44
- "jsservice": "JS Service",
45
- "nativeservice": "Native Service",
46
- "jsserviceinfo": "JS Service Info",
47
- "nativeserviceinfo": "Native Service Info",
48
- "icon": "Icon",
49
- "library": "Library",
50
- "packageinfo": "Package Info",
51
- "qmlapp": "QML App",
52
- "qmlappinfo": "QML App Info"
53
- };
54
-
55
- for (const name in templateList) {
56
- if (templateList[name].hide === true || !templateList[name].type) {
57
- continue;
58
- }
59
- const isDefault = (templateList[name].default) ? "(default) " : "",
60
- type = _displayType[templateList[name].type] || templateList[name].type;
61
-
62
- if (listType && ["true", "false", true, false].indexOf(listType) === -1) {
63
- if (templateList[name].type &&
64
- (templateList[name].type.match(new RegExp(listType+"$","gi")) === null)) {
65
- continue;
66
- }
67
- }
68
- table.cell('ID', name);
69
- table.cell('Project Type', type);
70
- table.cell('Description', isDefault + templateList[name].description);
71
- table.newRow();
72
- }
73
- return next(null, {msg: table.toString()});
74
- };
75
-
76
- Generator.prototype.generate = function(options, next) {
77
- // For API
78
- if (!options.tmplName) {
79
- return next(errHndl.getErrMsg("EMPTY_VALUE", "TEMPLATE"));
80
- }
81
- if (!options.out) {
82
- return next(errHndl.getErrMsg("EMPTY_VALUE", "APP_DIR"));
83
- }
84
-
85
- const tmplName = options.tmplName,
86
- pkginfo = options.pkginfo || {},
87
- svcinfo = options.svcinfo || {},
88
- svcName = options.svcName,
89
- out = options.out,
90
- dest = path.resolve(out),
91
- existDir = this.existOutDir(dest),
92
- templateList = this.getTmpl(),
93
- template = templateList[tmplName];
94
- let appinfo = options.appinfo || {};
95
-
96
- // For API
97
- if (!template) {
98
- return next(errHndl.getErrMsg("INVALID_VALUE", "TEMPLATE", options.tmplName));
99
- }
100
- if (!options.overwrite && existDir) {
101
- return next(errHndl.getErrMsg("NOT_OVERWRITE_DIR", dest));
102
- }
103
-
104
- if (template.metadata && template.metadata.data && typeof template.metadata.data === 'object') {
105
- appinfo = merge(appinfo, template.metadata.data);
106
- }
107
-
108
- promise.resolve()
109
- .then(function() {
110
- // If props is not exist, this input from query-mode
111
- // If props is exist, this input from props
112
- // Check argv.query, argv["no-query"], options.props and conditional statement.
113
- if (template.type.match(/(app$|appinfo$)/)) {
114
- parsePropArgs(options.props, appinfo);
115
- } else if (template.type.match(/(service$|serviceinfo$)/)) {
116
- parsePropArgs(options.props, svcinfo);
117
- } else if (template.type.match(/(package$|packageinfo$)/)) {
118
- parsePropArgs(options.props, pkginfo);
119
- }
120
- })
121
- .then(function() {
122
- if (svcName) {
123
- svcinfo.id = svcName;
124
- svcinfo.services = [{
125
- "name": svcName
126
- }];
127
- } else if (!svcName && svcinfo && !!svcinfo.id) {
128
- svcinfo.services = [{
129
- "name": svcinfo.id
130
- }];
131
- }
132
- });
133
-
134
- return promise.resolve()
135
- .then(function() {
136
- log.info("generator#generate()", "template name:" + tmplName);
137
- next(null, {msg: "Generating " + tmplName + " in " + dest});
138
-
139
- let srcs;
140
- if (tmplName.match(/(^hosted)/)) {
141
- srcs = [].concat(template.path);
142
- return promise.all(srcs.map(function(src) {
143
- return copyToDirAsync(src, dest);
144
- })).then(function() {
145
- let metaTmpl;
146
- let url;
147
- if (template.metadata && template.metadata.id) {
148
- metaTmpl = templateList[template.metadata.id];
149
- }
150
- if (metaTmpl) {
151
- if (appinfo.url) {
152
- url = appinfo.url;
153
- delete appinfo.url;
154
- const urlTmpl = {"path":path.join(srcs[0],'index.html')};
155
- _writeURLdata(urlTmpl, url);
156
- }
157
- return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
158
- } else {
159
- return;
160
- }
161
- });
162
- } else if (tmplName.match(/(^qmlapp$)/)) {
163
- srcs = [].concat(template.path);
164
- return promise.all(srcs.map(function(src) {
165
- return copyToDirAsync(src, dest);
166
- })).then(function() {
167
- let metaTmpl;
168
- if (template.metadata && template.metadata.id) {
169
- metaTmpl = templateList[template.metadata.id];
170
- }
171
- if (metaTmpl) {
172
- if (appinfo.id) {
173
- const qmlTmpl = {"path":path.join(srcs[0],'main.qml')};
174
- _writeAppIDdata(qmlTmpl, appinfo.id);
175
- }
176
- return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
177
- } else {
178
- return;
179
- }
180
- });
181
- } else if (template.type.match(/info$/)) {
182
- return _writeMetadata(template, appinfo, svcinfo, pkginfo);
183
- } else {
184
- srcs = [].concat(template.path);
185
- return promise.all(srcs.map(function(src) {
186
- log.info("generator#generate()", "template src:" + src);
187
- return copyToDirAsync(src, dest);
188
- })).then(function() {
189
- let metaTmpl;
190
- if (template.metadata && template.metadata.id) {
191
- metaTmpl = templateList[template.metadata.id];
192
- }
193
- if (metaTmpl) {
194
- return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
195
- } else {
196
- return;
197
- }
198
- });
199
- }
200
- })
201
- .then(function() {
202
- const deps = templateList[tmplName].deps || [];
203
- return promise.all(deps.map(function(dep) {
204
- if (!templateList[dep]) {
205
- log.warn("generator#generate()", "Invalid template id:" + dep);
206
- return;
207
- } else if (!templateList[dep].path) {
208
- log.warn("generator#generate()", "Invalid template path:" + dep);
209
- return;
210
- }
211
- return copyToDirAsync(templateList[dep].path, dest);
212
- }));
213
- })
214
- .then(function() {
215
- log.info("generator#generate()", "done");
216
- return next(null, {
217
- msg: "Success"
218
- });
219
- })
220
- .catch(function(err) {
221
- log.silly("generator#generate()", "err:", err);
222
- throw err;
223
- });
224
-
225
- function _writeAppIDdata(qmlTmpl, appId) {
226
- const filePaths = [].concat(qmlTmpl.path);
227
- return promise.all(filePaths.map(function(file) {
228
- return fs.lstatAsync(file)
229
- .then(function(stats) {
230
- if (!stats.isFile()) {
231
- throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
232
- }
233
- // eslint-disable-next-line no-useless-escape
234
- const exp = /appId\s*:\s*[\'\"][\w.]*[\'\"]/g;
235
- const destFile = path.join(dest, path.basename(file));
236
- let qmlFile = fs.readFileSync(file, 'utf8');
237
- qmlFile = qmlFile.replace(exp, "appId: \"" + appId + "\"");
238
-
239
- fs.writeFileSync(destFile, qmlFile, {encoding: 'utf8'});
240
- });
241
- }))
242
- .then(function() {
243
- log.info("generator#generate()#_writeAppIDdata()", "done");
244
- return;
245
- })
246
- .catch(function(err) {
247
- log.silly("generator#generate()#_writeAppIDdata()", "err:", err);
248
- throw err;
249
- });
250
- }
251
-
252
- function _writeURLdata(urlTmpl, url) {
253
- const filePaths = [].concat(urlTmpl.path);
254
- return promise.all(filePaths.map(function(file) {
255
- return fs.lstatAsync(file)
256
- .then(function(stats) {
257
- if (!stats.isFile()) {
258
- throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
259
- }
260
- let html = fs.readFileSync(file, 'utf8');
261
- // eslint-disable-next-line no-useless-escape
262
- const exp = new RegExp("(?:[\'\"])([\:/.A-z?<_&\s=>0-9;-]+\')");
263
- // eslint-disable-next-line no-useless-escape
264
- html = html.replace(exp, "\'" + url + "\'");
265
- const destFile = path.join(dest, path.basename(file));
266
-
267
- fs.writeFileSync(destFile, html, {encoding: 'utf8'});
268
- });
269
- }))
270
- .then(function() {
271
- log.info("generator#generate()#_writeURLdata()", "done");
272
- return;
273
- })
274
- .catch(function(err) {
275
- log.silly("generator#generate()#_writeURLdata()", "err:", err);
276
- throw err;
277
- });
278
- }
279
-
280
- function _writeMetadata(metaTmpl, _appinfo, _svcinfo, _pkginfo) {
281
- const metaPaths = [].concat(metaTmpl.path),
282
- appInfo = _appinfo || {},
283
- svcInfo = _svcinfo || {},
284
- pkgInfo = _pkginfo || {};
285
-
286
- return promise.all(metaPaths.map(function(file) {
287
- return fs.lstatAsync(file)
288
- .then(function(stats) {
289
- if (!stats.isFile()) {
290
- throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
291
- }
292
- const fileName = path.basename(file);
293
- let info = readJsonSync(file);
294
-
295
- if (fileName === 'appinfo.json') {
296
- info = merge(info, appInfo);
297
- } else if (fileName === "services.json") {
298
- info = merge(info, svcInfo);
299
- } else if (fileName === "package.json" &&
300
- (metaTmpl.type === "jsserviceinfo" || metaTmpl.type === "nativeserviceinfo")) {
301
- info.name = svcInfo.id || info.name;
302
- } else if (fileName === "packageinfo.json") {
303
- info = merge(info, pkgInfo);
304
- }
305
- return info;
306
- })
307
- .then(function(info) {
308
- const destFile = path.join(dest, path.basename(file));
309
- return fs.mkdirsAsync(dest)
310
- .then(function() {
311
- return fs.writeFileSync(destFile, JSON.stringify(info, null, 2), {
312
- encoding: 'utf8'
313
- });
314
- });
315
- });
316
- }))
317
- .then(function() {
318
- log.info("generator#generate()#_writeMetadata()", "done");
319
- return;
320
- })
321
- .catch(function(err) {
322
- log.silly("generator#generate()#_writeMetadata()", "err:", err);
323
- throw err;
324
- });
325
- }
326
- };
327
-
328
- Generator.prototype.getTmpl = function() {
329
- return templates;
330
- };
331
-
332
- Generator.prototype.existOutDir = function(outDir) {
333
- log.verbose("generator#existOutDir()", outDir);
334
- try {
335
- const files = fs.readdirSync(outDir);
336
- if (files.length > 0)
337
- return true;
338
- } catch (err) {
339
- if (err && err.code === 'ENOTDIR') {
340
- throw errHndl.getErrMsg("NOT_DIRTYPE_PATH", outDir);
341
- }
342
- if (err && err.code === 'ENOENT') {
343
- log.verbose("generator#generate()", "The directory does not exist.");
344
- return false;
345
- }
346
- throw err;
347
- }
348
- };
349
-
350
- // Internal functions
351
- function parsePropArgs(property, targetInfo) {
352
- const props = property || [],
353
- info = targetInfo || {};
354
- if (props.length === 1 && props[0].indexOf('{') !== -1 && props[0].indexOf('}') !== -1 &&
355
- ((props[0].split("'").length - 1) % 2) === 0)
356
- {
357
- // eslint-disable-next-line no-useless-escape
358
- props[0] = props[0].replace(/\'/g,'"');
359
- }
360
- props.forEach(function(prop) {
361
- try {
362
- const data = JSON.parse(prop);
363
- for (const k in data) {
364
- info[k] = data[k];
365
- }
366
- } catch (err) {
367
- const tokens = prop.split('=');
368
- if (tokens.length === 2) {
369
- info[tokens[0]] = tokens[1];
370
- } else {
371
- log.warn('Ignoring invalid arguments:', prop);
372
- }
373
- }
374
- });
375
- }
376
-
377
- module.exports = Generator;
1
+ #!/usr/bin/env node
2
+
3
+ /*
4
+ * Copyright (c) 2020-2024 LG Electronics Inc.
5
+ *
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ const promise = require('bluebird'),
10
+ Table = require('easy-table'),
11
+ fs = promise.promisifyAll(require('fs-extra')),
12
+ log = require('npmlog'),
13
+ path = require('path'),
14
+ errHndl = require('./base/error-handler'),
15
+ copyToDirAsync = require('./util/copy').copyToDirAsync,
16
+ readJsonSync = require('./util/json').readJsonSync,
17
+ merge = require('./util/merge');
18
+
19
+ const templatePath = path.join(__dirname, '/../files/conf/', 'template.json');
20
+ let templates;
21
+
22
+ log.heading = 'generator';
23
+ log.level = 'warn';
24
+
25
+ function Generator() {
26
+ if (templatePath) {
27
+ const cliPath = path.join(__dirname, '..');
28
+ let contents = fs.readFileSync(templatePath);
29
+ contents = contents.toString().replace(/\$cli-root/gi, cliPath).replace(/\\/g,'/');
30
+ templates = JSON.parse(contents);
31
+ } else {
32
+ templates = null;
33
+ }
34
+ }
35
+
36
+ Generator.prototype.showTemplates = function(listType, next) {
37
+ const templateList = this.getTmpl(),
38
+ table = new Table(),
39
+ _displayType = {
40
+ "webapp": "Web App",
41
+ "nativeapp": "Native App",
42
+ "webappinfo": "Web App Info",
43
+ "nativeappinfo": "Native App Info",
44
+ "jsservice": "JS Service",
45
+ "nativeservice": "Native Service",
46
+ "jsserviceinfo": "JS Service Info",
47
+ "nativeserviceinfo": "Native Service Info",
48
+ "icon": "Icon",
49
+ "library": "Library",
50
+ "packageinfo": "Package Info",
51
+ "qmlapp": "QML App",
52
+ "qmlappinfo": "QML App Info"
53
+ };
54
+
55
+ for (const name in templateList) {
56
+ if (templateList[name].hide === true || !templateList[name].type) {
57
+ continue;
58
+ }
59
+ const isDefault = (templateList[name].default) ? "(default) " : "",
60
+ type = _displayType[templateList[name].type] || templateList[name].type;
61
+
62
+ if (listType && ["true", "false", true, false].indexOf(listType) === -1) {
63
+ if (templateList[name].type &&
64
+ (templateList[name].type.match(new RegExp(listType+"$","gi")) === null)) {
65
+ continue;
66
+ }
67
+ }
68
+ table.cell('ID', name);
69
+ table.cell('Project Type', type);
70
+ table.cell('Description', isDefault + templateList[name].description);
71
+ table.newRow();
72
+ }
73
+ return next(null, {msg: table.toString()});
74
+ };
75
+
76
+ Generator.prototype.generate = function(options, next) {
77
+ // For API
78
+ if (!options.tmplName) {
79
+ return next(errHndl.getErrMsg("EMPTY_VALUE", "TEMPLATE"));
80
+ }
81
+ if (!options.out) {
82
+ return next(errHndl.getErrMsg("EMPTY_VALUE", "APP_DIR"));
83
+ }
84
+
85
+ const tmplName = options.tmplName,
86
+ pkginfo = options.pkginfo || {},
87
+ svcinfo = options.svcinfo || {},
88
+ svcName = options.svcName,
89
+ out = options.out,
90
+ dest = path.resolve(out),
91
+ existDir = this.existOutDir(dest),
92
+ templateList = this.getTmpl(),
93
+ template = templateList[tmplName];
94
+ let appinfo = options.appinfo || {};
95
+
96
+ // For API
97
+ if (!template) {
98
+ return next(errHndl.getErrMsg("INVALID_VALUE", "TEMPLATE", options.tmplName));
99
+ }
100
+ if (!options.overwrite && existDir) {
101
+ return next(errHndl.getErrMsg("NOT_OVERWRITE_DIR", dest));
102
+ }
103
+
104
+ if (template.metadata && template.metadata.data && typeof template.metadata.data === 'object') {
105
+ appinfo = merge(appinfo, template.metadata.data);
106
+ }
107
+
108
+ promise.resolve()
109
+ .then(function() {
110
+ // If props is not exist, this input from query-mode
111
+ // If props is exist, this input from props
112
+ // Check argv.query, argv["no-query"], options.props and conditional statement.
113
+ if (template.type.match(/(app$|appinfo$)/)) {
114
+ parsePropArgs(options.props, appinfo);
115
+ } else if (template.type.match(/(service$|serviceinfo$)/)) {
116
+ parsePropArgs(options.props, svcinfo);
117
+ } else if (template.type.match(/(package$|packageinfo$)/)) {
118
+ parsePropArgs(options.props, pkginfo);
119
+ }
120
+ })
121
+ .then(function() {
122
+ if (svcName) {
123
+ svcinfo.id = svcName;
124
+ svcinfo.services = [{
125
+ "name": svcName
126
+ }];
127
+ } else if (!svcName && svcinfo && !!svcinfo.id) {
128
+ svcinfo.services = [{
129
+ "name": svcinfo.id
130
+ }];
131
+ }
132
+ });
133
+
134
+ return promise.resolve()
135
+ .then(function() {
136
+ log.info("generator#generate()", "template name:" + tmplName);
137
+ next(null, {msg: "Generating " + tmplName + " in " + dest});
138
+
139
+ let srcs;
140
+ if (tmplName.match(/(^hosted)/)) {
141
+ srcs = [].concat(template.path);
142
+ return promise.all(srcs.map(function(src) {
143
+ return copyToDirAsync(src, dest);
144
+ })).then(function() {
145
+ let metaTmpl;
146
+ let url;
147
+ if (template.metadata && template.metadata.id) {
148
+ metaTmpl = templateList[template.metadata.id];
149
+ }
150
+ if (metaTmpl) {
151
+ if (appinfo.url) {
152
+ url = appinfo.url;
153
+ delete appinfo.url;
154
+ const urlTmpl = {"path":path.join(srcs[0],'index.html')};
155
+ _writeURLdata(urlTmpl, url);
156
+ }
157
+ return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
158
+ } else {
159
+ return;
160
+ }
161
+ });
162
+ } else if (tmplName.match(/(^qmlapp$)/)) {
163
+ srcs = [].concat(template.path);
164
+ return promise.all(srcs.map(function(src) {
165
+ return copyToDirAsync(src, dest);
166
+ })).then(function() {
167
+ let metaTmpl;
168
+ if (template.metadata && template.metadata.id) {
169
+ metaTmpl = templateList[template.metadata.id];
170
+ }
171
+ if (metaTmpl) {
172
+ if (appinfo.id) {
173
+ const qmlTmpl = {"path":path.join(srcs[0],'main.qml')};
174
+ _writeAppIDdata(qmlTmpl, appinfo.id);
175
+ }
176
+ return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
177
+ } else {
178
+ return;
179
+ }
180
+ });
181
+ } else if (tmplName.match(/(^native_service$)/)) {
182
+ srcs = [].concat(template.path);
183
+ return promise.all(srcs.map(function(src) {
184
+ return copyToDirAsync(src, dest);
185
+ })).then(function() {
186
+ if(svcinfo.id){
187
+ const serviceId = svcinfo.id;
188
+ const appId = _appIdFromServiceId(serviceId);
189
+
190
+ //Replace app id and service id
191
+ const mainFilePath = path.join(dest,'src','main.c');
192
+ let mainFile = fs.readFileSync(mainFilePath, 'utf8');
193
+ mainFile = mainFile.replace(/SERVICE_ID/g, serviceId).replace(/APP_ID/g, appId);
194
+ fs.writeFileSync(mainFilePath, mainFile, {encoding: 'utf8'});
195
+
196
+ //Replace the default service id
197
+ const serviceInfoFile = path.join(dest,"services.json");
198
+ const serviceInfo = readJsonSync(serviceInfoFile)
199
+ serviceInfo.id = serviceId;
200
+ if(serviceInfo.services && Array.isArray(serviceInfo.services)){
201
+ serviceInfo.services[0]['name'] = serviceId;
202
+ }
203
+ fs.writeFileSync(serviceInfoFile, JSON.stringify(serviceInfo, null, 2));
204
+ }
205
+ });
206
+ } else if (template.type.match(/info$/)) {
207
+ return _writeMetadata(template, appinfo, svcinfo, pkginfo);
208
+ } else {
209
+ srcs = [].concat(template.path);
210
+ return promise.all(srcs.map(function(src) {
211
+ log.info("generator#generate()", "template src:" + src);
212
+ return copyToDirAsync(src, dest);
213
+ })).then(function() {
214
+ let metaTmpl;
215
+ if (template.metadata && template.metadata.id) {
216
+ metaTmpl = templateList[template.metadata.id];
217
+ }
218
+ if (metaTmpl) {
219
+ return _writeMetadata(metaTmpl, appinfo, svcinfo, pkginfo);
220
+ } else {
221
+ return;
222
+ }
223
+ });
224
+ }
225
+ })
226
+ .then(function() {
227
+ const deps = templateList[tmplName].deps || [];
228
+ return promise.all(deps.map(function(dep) {
229
+ if (!templateList[dep]) {
230
+ log.warn("generator#generate()", "Invalid template id:" + dep);
231
+ return;
232
+ } else if (!templateList[dep].path) {
233
+ log.warn("generator#generate()", "Invalid template path:" + dep);
234
+ return;
235
+ }
236
+ return copyToDirAsync(templateList[dep].path, dest);
237
+ }));
238
+ })
239
+ .then(function() {
240
+ log.info("generator#generate()", "done");
241
+ return next(null, {
242
+ msg: "Success"
243
+ });
244
+ })
245
+ .catch(function(err) {
246
+ log.silly("generator#generate()", "err:", err);
247
+ throw err;
248
+ });
249
+
250
+ function _writeAppIDdata(qmlTmpl, appId) {
251
+ const filePaths = [].concat(qmlTmpl.path);
252
+ return promise.all(filePaths.map(function(file) {
253
+ return fs.lstatAsync(file)
254
+ .then(function(stats) {
255
+ if (!stats.isFile()) {
256
+ throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
257
+ }
258
+ // eslint-disable-next-line no-useless-escape
259
+ const exp = /appId\s*:\s*[\'\"][\w.]*[\'\"]/g;
260
+ const destFile = path.join(dest, path.basename(file));
261
+ let qmlFile = fs.readFileSync(file, 'utf8');
262
+ qmlFile = qmlFile.replace(exp, "appId: \"" + appId + "\"");
263
+
264
+ fs.writeFileSync(destFile, qmlFile, {encoding: 'utf8'});
265
+ });
266
+ }))
267
+ .then(function() {
268
+ log.info("generator#generate()#_writeAppIDdata()", "done");
269
+ return;
270
+ })
271
+ .catch(function(err) {
272
+ log.silly("generator#generate()#_writeAppIDdata()", "err:", err);
273
+ throw err;
274
+ });
275
+ }
276
+
277
+ function _writeURLdata(urlTmpl, url) {
278
+ const filePaths = [].concat(urlTmpl.path);
279
+ return promise.all(filePaths.map(function(file) {
280
+ return fs.lstatAsync(file)
281
+ .then(function(stats) {
282
+ if (!stats.isFile()) {
283
+ throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
284
+ }
285
+ let html = fs.readFileSync(file, 'utf8');
286
+ // eslint-disable-next-line no-useless-escape
287
+ const exp = new RegExp("(?:[\'\"])([\:/.A-z?<_&\s=>0-9;-]+\')");
288
+ // eslint-disable-next-line no-useless-escape
289
+ html = html.replace(exp, "\'" + url + "\'");
290
+ const destFile = path.join(dest, path.basename(file));
291
+
292
+ fs.writeFileSync(destFile, html, {encoding: 'utf8'});
293
+ });
294
+ }))
295
+ .then(function() {
296
+ log.info("generator#generate()#_writeURLdata()", "done");
297
+ return;
298
+ })
299
+ .catch(function(err) {
300
+ log.silly("generator#generate()#_writeURLdata()", "err:", err);
301
+ throw err;
302
+ });
303
+ }
304
+
305
+ function _appIdFromServiceId(serviceId){
306
+ const svcIdInArray = serviceId.split(".");
307
+ if(svcIdInArray.length === 1) return serviceId;
308
+ return svcIdInArray.slice(0,svcIdInArray.length -1).join(".");
309
+ }
310
+
311
+ function _writeMetadata(metaTmpl, _appinfo, _svcinfo, _pkginfo) {
312
+ const metaPaths = [].concat(metaTmpl.path),
313
+ appInfo = _appinfo || {},
314
+ svcInfo = _svcinfo || {},
315
+ pkgInfo = _pkginfo || {};
316
+
317
+ return promise.all(metaPaths.map(function(file) {
318
+ return fs.lstatAsync(file)
319
+ .then(function(stats) {
320
+ if (!stats.isFile()) {
321
+ throw errHndl.getErrMsg("INVALID_PATH", "meta template", file);
322
+ }
323
+ const fileName = path.basename(file);
324
+ let info = readJsonSync(file);
325
+
326
+ if (fileName === 'appinfo.json') {
327
+ info = merge(info, appInfo);
328
+ } else if (fileName === "services.json") {
329
+ info = merge(info, svcInfo);
330
+ } else if (fileName === "package.json" &&
331
+ (metaTmpl.type === "jsserviceinfo" || metaTmpl.type === "nativeserviceinfo")) {
332
+ info.name = svcInfo.id || info.name;
333
+ } else if (fileName === "packageinfo.json") {
334
+ info = merge(info, pkgInfo);
335
+ }
336
+ return info;
337
+ })
338
+ .then(function(info) {
339
+ const destFile = path.join(dest, path.basename(file));
340
+ return fs.mkdirsAsync(dest)
341
+ .then(function() {
342
+ return fs.writeFileSync(destFile, JSON.stringify(info, null, 2), {
343
+ encoding: 'utf8'
344
+ });
345
+ });
346
+ });
347
+ }))
348
+ .then(function() {
349
+ log.info("generator#generate()#_writeMetadata()", "done");
350
+ return;
351
+ })
352
+ .catch(function(err) {
353
+ log.silly("generator#generate()#_writeMetadata()", "err:", err);
354
+ throw err;
355
+ });
356
+ }
357
+ };
358
+
359
+ Generator.prototype.getTmpl = function() {
360
+ return templates;
361
+ };
362
+
363
+ Generator.prototype.existOutDir = function(outDir) {
364
+ log.verbose("generator#existOutDir()", outDir);
365
+ try {
366
+ const files = fs.readdirSync(outDir);
367
+ if (files.length > 0)
368
+ return true;
369
+ } catch (err) {
370
+ if (err && err.code === 'ENOTDIR') {
371
+ throw errHndl.getErrMsg("NOT_DIRTYPE_PATH", outDir);
372
+ }
373
+ if (err && err.code === 'ENOENT') {
374
+ log.verbose("generator#generate()", "The directory does not exist.");
375
+ return false;
376
+ }
377
+ throw err;
378
+ }
379
+ };
380
+
381
+ // Internal functions
382
+ function parsePropArgs(property, targetInfo) {
383
+ const props = property || [],
384
+ info = targetInfo || {};
385
+ if (props.length === 1 && props[0].indexOf('{') !== -1 && props[0].indexOf('}') !== -1 &&
386
+ ((props[0].split("'").length - 1) % 2) === 0)
387
+ {
388
+ // eslint-disable-next-line no-useless-escape
389
+ props[0] = props[0].replace(/\'/g,'"');
390
+ }
391
+ props.forEach(function(prop) {
392
+ try {
393
+ const data = JSON.parse(prop);
394
+ for (const k in data) {
395
+ info[k] = data[k];
396
+ }
397
+ } catch (err) {
398
+ const tokens = prop.split('=');
399
+ if (tokens.length === 2) {
400
+ info[tokens[0]] = tokens[1];
401
+ } else {
402
+ log.warn('Ignoring invalid arguments:', prop);
403
+ }
404
+ }
405
+ });
406
+ }
407
+
408
+ module.exports = Generator;