@sap/cds-dk 4.8.0 → 4.9.0
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/CHANGELOG.md +57 -0
- package/bin/activate.js +8 -7
- package/bin/bind.js +12 -12
- package/bin/build/all.js +3 -5
- package/bin/build/index.js +1 -1
- package/bin/cds.js +1 -1
- package/bin/deploy/index.js +7 -1
- package/bin/deploy/to-hana.js +5 -4
- package/bin/deploy/to-sqlite.js +2 -1
- package/bin/extend.js +5 -5
- package/bin/help.js +1 -0
- package/bin/import.js +45 -31
- package/bin/login.js +5 -6
- package/bin/logout.js +2 -2
- package/bin/parse.js +19 -0
- package/lib/bind/bindingUtil.js +47 -50
- package/lib/bind/cfKeyProvider.js +9 -17
- package/lib/bind/userCdsrcJsonStorageProvider.js +1 -0
- package/lib/client/activate.js +3 -2
- package/lib/client/auth_manager.js +1 -0
- package/lib/client/extend.js +6 -6
- package/lib/client/helper/fs_helper.js +8 -8
- package/lib/client/settings_manager.js +12 -9
- package/lib/compile/openapi/csdl2openapi.js +213 -165
- package/lib/compile/openapi/index.js +1 -2
- package/lib/compile/to-xsuaa.js +1 -1
- package/lib/import/index.js +22 -15
- package/lib/import/message.js +3 -1
- package/lib/import/utils/MetadataConverter.js +1 -1
- package/lib/import/v2parser.js +112 -56
- package/lib/import/v4parser.js +152 -99
- package/lib/init/constants.js +6 -2
- package/lib/init/index.js +3 -2
- package/lib/init/template/_merging/existences.js +80 -4
- package/lib/init/template/approuter/files/cds.cdsrc.json +7 -0
- package/lib/init/template/approuter/files/cds.cdsrc.json.hbs +9 -0
- package/lib/init/template/approuter/files/cds.package.json +9 -0
- package/lib/init/template/approuter/files/cds.package.json.hbs +11 -0
- package/lib/init/template/approuter/files/index.html +1 -0
- package/lib/init/template/approuter/files/mta.yaml.hbs +35 -21
- package/lib/init/template/approuter/files/package.json +3 -0
- package/lib/init/template/approuter/files/xs-app.json.hbs +19 -0
- package/lib/init/template/approuter/index.js +47 -18
- package/lib/init/template/auditlog/index.js +5 -5
- package/lib/init/template/hana/files/java/cdsrc.json.hbs +7 -0
- package/lib/init/template/hana/files/java/profile.cdsrc.json.hbs +12 -0
- package/lib/init/template/hana/files/mta.yaml.hbs +10 -17
- package/lib/init/template/hana/files/nodejs/cds.package.json.hbs +9 -0
- package/lib/init/template/hana/files/nodejs/cds.profile.package.json.hbs +14 -0
- package/lib/init/template/hana/files/nodejs/dependencies.package.json +1 -1
- package/lib/init/template/hana/index.js +59 -85
- package/lib/init/template/java/index.js +5 -2
- package/lib/init/template/kibana-logging/files/cds.package.json +7 -0
- package/lib/init/template/kibana-logging/files/cds.profile.package.json.hbs +9 -0
- package/lib/init/template/kibana-logging/files/mta.yaml.hbs +13 -0
- package/lib/init/template/kibana-logging/index.js +64 -0
- package/lib/init/template/mta/files/mta.yaml.hbs +3 -8
- package/lib/init/template/mta/index.js +8 -2
- package/lib/init/template/mtx/files/cds.package.json +0 -12
- package/lib/init/template/mtx/files/cds.package.json.hbs +14 -0
- package/lib/init/template/mtx/files/java/.cdsrc.json +17 -0
- package/lib/init/template/mtx/files/java/package.json +43 -0
- package/lib/init/template/mtx/files/java/server.js +30 -0
- package/lib/init/template/mtx/files/mta.yaml.hbs +6 -6
- package/lib/init/template/mtx/index.js +41 -22
- package/lib/init/template/templateBase.js +4 -1
- package/lib/init/template/xsuaa/files/cds.cdsrc.json +7 -0
- package/lib/init/template/xsuaa/files/cds.cdsrc.json.hbs +9 -0
- package/lib/init/template/xsuaa/files/cds.package.json +1 -1
- package/lib/init/template/xsuaa/files/cds.package.json.hbs +11 -0
- package/lib/init/template/xsuaa/files/mta.yaml.hbs +2 -2
- package/lib/init/template/xsuaa/index.js +43 -27
- package/lib/init/types.d.ts +43 -19
- package/lib/init/util/fsUtil.js +15 -4
- package/lib/init/util/projectReader.js +21 -18
- package/lib/init/util/templateUtil.js +78 -28
- package/lib/util/exec.js +2 -2
- package/lib/watch/livereload-server.js +3 -0
- package/lib/watch/node-watch.js +8 -1
- package/npm-shrinkwrap.json +942 -1259
- package/package.json +3 -3
- package/lib/init/template/approuter/files/xs-app.json +0 -8
- package/lib/init/template/nodejs/files/.vscode/settings.json +0 -7
package/lib/init/util/fsUtil.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
1
2
|
const path = require('path');
|
|
2
3
|
|
|
3
4
|
const {fse, yaml} = require('@sap/cds-foss')
|
|
@@ -5,6 +6,10 @@ const JSONC = require('../../util/jsonc');
|
|
|
5
6
|
|
|
6
7
|
const UTF_8 = 'utf-8';
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* this util implements FsUtil declared in ../types.d.ts
|
|
11
|
+
* the interface FsUtil is also used by @sap/generator-cap-project
|
|
12
|
+
*/
|
|
8
13
|
module.exports = class FsUtil {
|
|
9
14
|
|
|
10
15
|
constructor() {
|
|
@@ -30,10 +35,16 @@ module.exports = class FsUtil {
|
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
async readFile(src) {
|
|
33
|
-
return await
|
|
38
|
+
return await fs.readFile(src, UTF_8);
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
async readJSON(src) {
|
|
41
|
+
async readJSON(src, projectDescriptor) {
|
|
42
|
+
const file = await this.readFile(src);
|
|
43
|
+
if (projectDescriptor) {
|
|
44
|
+
const Mustache = require('mustache');
|
|
45
|
+
const renderedFile = Mustache.render(file, projectDescriptor);
|
|
46
|
+
return JSON.parse(renderedFile);
|
|
47
|
+
}
|
|
37
48
|
return await fse.readJSON(src);
|
|
38
49
|
}
|
|
39
50
|
|
|
@@ -64,7 +75,7 @@ module.exports = class FsUtil {
|
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
async readdir(filePath) {
|
|
67
|
-
return await
|
|
78
|
+
return await fs.readdir(filePath);
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
getTouchedFiles() {
|
|
@@ -76,7 +87,7 @@ module.exports = class FsUtil {
|
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
async stat(filePath) {
|
|
79
|
-
return await
|
|
90
|
+
return await fs.stat(filePath);
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
async hasContent(folderPath) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const { nullLogger } = require('../util/logger')
|
|
3
3
|
const { BuildTaskFactory } = require('@sap/cds/bin/build')
|
|
4
|
+
const { fs } = require('@sap/cds/lib/utils')
|
|
4
5
|
const P_LANGUAGE_JAVA = 'java'
|
|
5
6
|
const P_LANGUAGE_NODEJS = 'nodejs'
|
|
6
7
|
const DEFAULT_P_LANGUAGE = P_LANGUAGE_NODEJS
|
|
@@ -60,12 +61,17 @@ module.exports = class ProjectReader {
|
|
|
60
61
|
|
|
61
62
|
async _getCapDescriptor(env, options) {
|
|
62
63
|
let capDescriptor = {
|
|
64
|
+
for: options && options.for,
|
|
63
65
|
pLanguage: DEFAULT_P_LANGUAGE,
|
|
64
66
|
srv: {},
|
|
65
67
|
db: [],
|
|
66
68
|
requires: [],
|
|
67
69
|
get isMultitenant() {
|
|
68
|
-
return options && options.add.has('mtx') ||
|
|
70
|
+
return options && options.add && options.add.has('mtx') ||
|
|
71
|
+
env.requires.multitenancy ||
|
|
72
|
+
env.requires.db && env.requires.db.multiTenant ||
|
|
73
|
+
this.isJava && fs.existsSync('mtx-sidecar') ||
|
|
74
|
+
false
|
|
69
75
|
},
|
|
70
76
|
get isNodejs() {
|
|
71
77
|
return this.pLanguage === P_LANGUAGE_NODEJS
|
|
@@ -87,6 +93,9 @@ module.exports = class ProjectReader {
|
|
|
87
93
|
},
|
|
88
94
|
get needsSidecar() {
|
|
89
95
|
return (options && options.add.has('hana') || this.db.length > 0) && (this.isJava || !this.isMultitenant)
|
|
96
|
+
},
|
|
97
|
+
get hasApprouter() {
|
|
98
|
+
return !!env.requires.approuter
|
|
90
99
|
}
|
|
91
100
|
}
|
|
92
101
|
|
|
@@ -179,14 +188,6 @@ module.exports = class ProjectReader {
|
|
|
179
188
|
uiDescriptor.appPath = env.folders.app
|
|
180
189
|
}
|
|
181
190
|
|
|
182
|
-
const packageJson = await (async () => { try {
|
|
183
|
-
return await this.fsUtil.readFile(absoluteAppPath+'package.json')
|
|
184
|
-
} catch(error) { /* ignore */ }
|
|
185
|
-
})()
|
|
186
|
-
|
|
187
|
-
if (packageJson && packageJson.dependencies) {
|
|
188
|
-
uiDescriptor.appRouterEnabled = packageJson.dependencies['@sap/approuter'] !== undefined
|
|
189
|
-
}
|
|
190
191
|
return uiDescriptor
|
|
191
192
|
}
|
|
192
193
|
|
|
@@ -316,25 +317,27 @@ module.exports = class ProjectReader {
|
|
|
316
317
|
const hanaResources = new Map()
|
|
317
318
|
const otherResources = new Map()
|
|
318
319
|
|
|
319
|
-
for (
|
|
320
|
+
for (const key of Object.keys(env.requires)) {
|
|
320
321
|
// ignore abstract helper definitions like sql
|
|
321
322
|
if (key === 'sql' || key === 'sqlite' || key === 'hana') continue
|
|
322
|
-
|
|
323
|
+
const { kind } = env.requires[key]
|
|
324
|
+
if (kind === 'hana' || kind === 'hana-mt' || kind === 'hana-cloud') {
|
|
323
325
|
hanaResources.set(key, env.requires[key])
|
|
324
326
|
} else {
|
|
325
327
|
otherResources.set(key, env.requires[key])
|
|
326
328
|
}
|
|
327
329
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
+
|
|
331
|
+
for (const [key, value] of hanaResources) {
|
|
332
|
+
const resource = this._getReqResource(key, value, capDescriptor)
|
|
330
333
|
if (resource) {
|
|
331
334
|
// using production profile
|
|
332
335
|
capDescriptor.requires.push({ resource })
|
|
333
336
|
}
|
|
334
337
|
}
|
|
335
338
|
// add after hana resource dependencies have been handled as multitenant information is required
|
|
336
|
-
for (
|
|
337
|
-
|
|
339
|
+
for (const [key, value] of otherResources) {
|
|
340
|
+
const resource = this._getReqResource(key, value, capDescriptor)
|
|
338
341
|
if (resource) {
|
|
339
342
|
// using production profile
|
|
340
343
|
capDescriptor.requires.push({ resource })
|
|
@@ -391,9 +394,9 @@ module.exports = class ProjectReader {
|
|
|
391
394
|
break
|
|
392
395
|
|
|
393
396
|
case 'xsuaa':
|
|
394
|
-
if (capDescriptor.isMultitenant) {
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
+
// if (capDescriptor.isMultitenant) {
|
|
398
|
+
// resource.name += '-mt'
|
|
399
|
+
// }
|
|
397
400
|
resource.service = reqEntry.kind
|
|
398
401
|
resource.vcap.plan = 'application'
|
|
399
402
|
break
|
|
@@ -32,6 +32,14 @@ module.exports = class TemplateUtil {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
async sortDependencies(packageJSONPath) {
|
|
36
|
+
const json = await this.fsUtil.readJSON(packageJSONPath);
|
|
37
|
+
json.dependencies = Object.fromEntries(
|
|
38
|
+
Object.entries(json.dependencies).sort(([a],[b]) => a>b ? 1 : -1)
|
|
39
|
+
)
|
|
40
|
+
await this.fsUtil.writeJSON(packageJSONPath, json);
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
async _writeTemplateFile(src, destination, templateValues, overwrite = false) {
|
|
36
44
|
const destinationPath = destination.replace(TEMPLATE_EXTENSION_REGEX, '');
|
|
37
45
|
if (overwrite || !(await this.fsUtil.pathExists(destinationPath))) {
|
|
@@ -80,8 +88,8 @@ module.exports = class TemplateUtil {
|
|
|
80
88
|
return target || source;
|
|
81
89
|
}
|
|
82
90
|
|
|
83
|
-
async mergeJSON(targetPath,
|
|
84
|
-
const source = await this.fsUtil.readJSON(
|
|
91
|
+
async mergeJSON(targetPath, from, projectDescriptor, semantics) {
|
|
92
|
+
const source = typeof from === 'string' ? await this.fsUtil.readJSON(from, projectDescriptor) : from
|
|
85
93
|
|
|
86
94
|
if (! await this.fsUtil.pathExists(targetPath)) {
|
|
87
95
|
await this.fsUtil.writeJSON(targetPath, source);
|
|
@@ -97,7 +105,7 @@ module.exports = class TemplateUtil {
|
|
|
97
105
|
await this.fsUtil.writeJSON(targetPath, result)
|
|
98
106
|
} else {
|
|
99
107
|
const target = await this.fsUtil.readJSON(targetPath);
|
|
100
|
-
const sourceFile = await this._processTemplateFile(
|
|
108
|
+
const sourceFile = await this._processTemplateFile(from, projectDescriptor);
|
|
101
109
|
const source = JSON.parse(sourceFile);
|
|
102
110
|
const result = target && source ? this._deepMerge(target, source) : target || source;
|
|
103
111
|
await this.fsUtil.writeJSON(targetPath, result);
|
|
@@ -120,11 +128,16 @@ module.exports = class TemplateUtil {
|
|
|
120
128
|
templateExistenceMap.set(existence.ref, undefined)
|
|
121
129
|
});
|
|
122
130
|
|
|
131
|
+
const { deletions } = semantics
|
|
132
|
+
deletions && deletions.forEach(deletion => {
|
|
133
|
+
existenceMap.set(deletion.existence.ref, undefined)
|
|
134
|
+
})
|
|
135
|
+
|
|
123
136
|
const missingRelationshipsMap = new Map()
|
|
124
137
|
|
|
125
138
|
const relationships = semantics.relationships && semantics.relationships.filter(r => r)
|
|
126
139
|
relationships && relationships.forEach(relationship =>
|
|
127
|
-
missingRelationshipsMap.set(relationship.in, undefined)
|
|
140
|
+
missingRelationshipsMap.set(relationship.in.ref, undefined)
|
|
128
141
|
)
|
|
129
142
|
|
|
130
143
|
let collectionStack = [target.contents]
|
|
@@ -133,22 +146,35 @@ module.exports = class TemplateUtil {
|
|
|
133
146
|
const _getYAMLProperty = (object, keyPath) => keyPath.reduce((p, n) => p && p.get(n), object)
|
|
134
147
|
|
|
135
148
|
const _validateConstraints = (node, dict, index) => {
|
|
136
|
-
existences
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
const _addToMap = existences => existences
|
|
150
|
+
.filter(existence => {
|
|
151
|
+
if (!existence.in) return true
|
|
152
|
+
const neededParent = existence.in && dict.get(existence.in.ref) && dict.get(existence.in.ref).node
|
|
153
|
+
return collectionStack.includes(neededParent)
|
|
154
|
+
})
|
|
155
|
+
.forEach(existence => {
|
|
156
|
+
const json = JSON.parse(String(node));
|
|
157
|
+
const constraintsFulfilled = existence.constraints.every(constraint =>
|
|
158
|
+
constraint.value === _getProperty(json, constraint.comparisonKeyPath)
|
|
159
|
+
)
|
|
160
|
+
if (constraintsFulfilled) {
|
|
161
|
+
const [collection] = collectionStack
|
|
162
|
+
dict.set(existence.ref, { json, node, index, collection })
|
|
163
|
+
}
|
|
142
164
|
})
|
|
165
|
+
_addToMap(existences)
|
|
166
|
+
deletions && _addToMap(deletions.map(deletion => deletion.existence))
|
|
143
167
|
}
|
|
144
168
|
|
|
145
169
|
function _traverseYAMLNode(node, index, actions, templateNode) {
|
|
146
170
|
let shifted = false
|
|
147
171
|
switch (node.type) {
|
|
148
|
-
case 'MAP':
|
|
172
|
+
case 'MAP': {
|
|
149
173
|
actions && actions.visitMap && actions.visitMap(node, index)
|
|
150
|
-
|
|
174
|
+
const [collection] = collectionStack
|
|
175
|
+
if (collection && collection.type === 'SEQ') { collectionStack.unshift(node); shifted = true}
|
|
151
176
|
break;
|
|
177
|
+
}
|
|
152
178
|
case 'SEQ':
|
|
153
179
|
break;
|
|
154
180
|
case 'PAIR':
|
|
@@ -235,15 +261,35 @@ module.exports = class TemplateUtil {
|
|
|
235
261
|
})
|
|
236
262
|
|
|
237
263
|
// 3. Apply overwrites to already found existences
|
|
238
|
-
semantics.overwrites && semantics.overwrites.forEach(({ in:
|
|
239
|
-
const existence = existenceMap.get(ref)
|
|
264
|
+
semantics.overwrites && semantics.overwrites.forEach(({ in: inExistence, keyPath, replacement }) => {
|
|
265
|
+
const existence = existenceMap.get(inExistence.ref)
|
|
240
266
|
if (existence) {
|
|
241
267
|
_getYAMLProperty(existence.node, keyPath.slice(0, keyPath.length - 1))
|
|
242
268
|
.set(keyPath[keyPath.length - 1], replacement)
|
|
243
269
|
}
|
|
244
270
|
})
|
|
245
271
|
|
|
246
|
-
// 4.
|
|
272
|
+
// 4. Delete existences from the project (e.g. separate deployer module when adding mtx)
|
|
273
|
+
semantics.deletions && semantics.deletions.forEach(({ existence: { ref }, relationships }) => {
|
|
274
|
+
const existence = existenceMap.get(ref)
|
|
275
|
+
if (!existence) return
|
|
276
|
+
existence.collection.delete(existence.index)
|
|
277
|
+
|
|
278
|
+
relationships && relationships.forEach(relationship => {
|
|
279
|
+
const parent = target.get(relationship.allWithinKeyPath[0])
|
|
280
|
+
for (const child of parent.items) {
|
|
281
|
+
const c = child.get(relationship.inKeyPath[0])
|
|
282
|
+
const i = c.items.findIndex(node =>
|
|
283
|
+
node.get(relationship.into) === _getProperty(existence.json, relationship.existenceKeyPath)
|
|
284
|
+
)
|
|
285
|
+
if (i > -1) {
|
|
286
|
+
c.delete(i)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
// 5. Create missing existences and pairs
|
|
247
293
|
_traverseYAMLNode(target.contents, null, {
|
|
248
294
|
mergePair: (collection, templateNode) => {
|
|
249
295
|
const childIsArray = false//templateNode.value.type !== 'MAP' && !!templateNode.value.items
|
|
@@ -257,30 +303,34 @@ module.exports = class TemplateUtil {
|
|
|
257
303
|
const [,parent] = collectionStack
|
|
258
304
|
const missingExistences = semantics.existences
|
|
259
305
|
.filter(e => e)
|
|
260
|
-
.filter(existence =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
306
|
+
.filter(existence => {
|
|
307
|
+
const requiredParent = existence.in &&
|
|
308
|
+
existenceMap.get(existence.in.ref) &&
|
|
309
|
+
existenceMap.get(existence.in.ref).node
|
|
310
|
+
return !existence.in || requiredParent === parent
|
|
311
|
+
|
|
312
|
+
})
|
|
313
|
+
.filter(({keyPath}) => parent.get(keyPath[0]) === targetNode)
|
|
314
|
+
.filter(({ref}) => !existenceMap.get(ref))
|
|
265
315
|
missingExistences.forEach(existence => {
|
|
266
|
-
const
|
|
316
|
+
const templateNode = templateExistenceMap.get(existence.ref).node
|
|
317
|
+
const templateExistence = YAML.createNode(templateNode)
|
|
267
318
|
templateExistence.spaceBefore = existence.spaceBefore
|
|
268
319
|
targetNode.add(templateExistence)
|
|
269
|
-
existenceMap.set(existence.ref, templateExistence)
|
|
270
320
|
//this.fsUtil.writeYAML(targetPath, target)
|
|
271
321
|
})
|
|
272
322
|
}
|
|
273
323
|
},
|
|
274
324
|
}, source.contents)
|
|
275
325
|
|
|
276
|
-
//
|
|
326
|
+
// 6. Re-validate the existences in the project
|
|
277
327
|
_traverseYAMLNode(target.contents, null, {
|
|
278
328
|
visitMap: (node, index) => {
|
|
279
329
|
_validateConstraints(node, existenceMap, index)
|
|
280
330
|
}
|
|
281
331
|
})
|
|
282
332
|
|
|
283
|
-
//
|
|
333
|
+
// 7. Create missing relationships
|
|
284
334
|
_traverseYAMLNode(target.contents, null, {
|
|
285
335
|
mergeCollection: (targetNode, templateNode) => {
|
|
286
336
|
if (templateNode.type === 'SEQ') {
|
|
@@ -288,18 +338,18 @@ module.exports = class TemplateUtil {
|
|
|
288
338
|
const relationship = semantics.relationships && semantics.relationships
|
|
289
339
|
.filter(r => r)
|
|
290
340
|
.find(relationship => {
|
|
291
|
-
const existingNode = _getYAMLProperty(existenceMap.get(relationship.in).node, relationship.inKeyPath)
|
|
341
|
+
const existingNode = _getYAMLProperty(existenceMap.get(relationship.in.ref).node, relationship.inKeyPath)
|
|
292
342
|
return targetNode === existingNode
|
|
293
343
|
})
|
|
294
344
|
if (!relationship) return
|
|
295
345
|
|
|
296
346
|
const missingPairs = relationship.existences
|
|
297
|
-
.filter(
|
|
347
|
+
.filter(({ref}) =>
|
|
298
348
|
!targetJSON.some(item =>
|
|
299
|
-
_getProperty(existenceMap.get(
|
|
349
|
+
_getProperty(existenceMap.get(ref).json, relationship.existenceKeyPath) === item[relationship.into]
|
|
300
350
|
)
|
|
301
351
|
)
|
|
302
|
-
.map(
|
|
352
|
+
.map(({ref}) => existenceMap.get(ref).node.get(relationship.into))
|
|
303
353
|
missingPairs.forEach(pair => {
|
|
304
354
|
targetNode.add(YAML.createNode({ [relationship.into]: pair }))
|
|
305
355
|
//await this.fsUtil.writeYAML(targetPath, target)
|
package/lib/util/exec.js
CHANGED
|
@@ -3,7 +3,7 @@ const { spawn, spawnSync } = require('child_process');
|
|
|
3
3
|
const cds = require('@sap/cds/lib');
|
|
4
4
|
const log = cds.log('exec');
|
|
5
5
|
|
|
6
|
-
function* commandIterator(strs,
|
|
6
|
+
function* commandIterator(strs, args) {
|
|
7
7
|
for (let i=0; i<strs.length; i++) {
|
|
8
8
|
const str = strs[i];
|
|
9
9
|
const regex = /((\s+)|(["'])|$)/g;
|
|
@@ -38,7 +38,7 @@ function* commandIterator(strs, ...args) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function processTemplate(strs, args) {
|
|
41
|
+
function processTemplate(strs, ...args) {
|
|
42
42
|
let quote;
|
|
43
43
|
const result = [];
|
|
44
44
|
let index = 0;
|
|
@@ -66,6 +66,9 @@ module.exports = class LiveReload {
|
|
|
66
66
|
this.wsServer.on('close', () => { debug && debug('Socket closed') })
|
|
67
67
|
this.wsServer.on('error', (e) => debug && debug(e))
|
|
68
68
|
}
|
|
69
|
+
const close = () => { this.wsServer.close(); server.close(); debug && debug('Reload server closed') }
|
|
70
|
+
process.once('SIGTERM', close)
|
|
71
|
+
process.once('SIGINT', close)
|
|
69
72
|
})
|
|
70
73
|
}
|
|
71
74
|
|
package/lib/watch/node-watch.js
CHANGED
|
@@ -7,7 +7,14 @@ module.exports = ({ cwd, script, ext, ignore=RegExp(), env={}, delay=200, option
|
|
|
7
7
|
// Phoning home...
|
|
8
8
|
const EventEmitter = require('events')
|
|
9
9
|
const emitter = new EventEmitter
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
const killAndExit = (sig) => {
|
|
12
|
+
DEBUG && DEBUG('Signal:', sig)
|
|
13
|
+
emitter.emit('quit')
|
|
14
|
+
_kill (child, () => process.exit())
|
|
15
|
+
}
|
|
16
|
+
process.on('SIGTERM', killAndExit)
|
|
17
|
+
process.on('SIGINT', killAndExit)
|
|
11
18
|
|
|
12
19
|
// Re-starting child process...
|
|
13
20
|
const { fork } = require('child_process')
|