@sap/cds-dk 7.9.3 → 7.9.5
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/bin/watch.js +1 -1
- package/lib/bind/bindingResolver.js +3 -5
- package/lib/bind/index.js +4 -7
- package/lib/build/provider/hana/template/.hdiconfig-all +3 -0
- package/lib/build/provider/hana/template/.hdiconfig-cloud +3 -0
- package/lib/deploy/to-hana/hana.js +1 -1
- package/lib/init/constants.js +1 -1
- package/lib/init/index.js +2 -0
- package/lib/init/template/hana/files/src/.hdiconfig +3 -0
- package/lib/util/cf.js +66 -54
- package/npm-shrinkwrap.json +20 -17
- package/package.json +1 -1
package/bin/watch.js
CHANGED
|
@@ -65,7 +65,7 @@ const t = module.exports.codes = {
|
|
|
65
65
|
}
|
|
66
66
|
const extDefaults = 'cds,csn,csv,ts,mjs,cjs,js,json,properties,edmx,xml,env'
|
|
67
67
|
const ignore = RegExp(
|
|
68
|
-
`(node_modules|_out|@types|@cds-models)\\${sep}` +
|
|
68
|
+
`(.git|node_modules|_out|@types|@cds-models)\\${sep}` +
|
|
69
69
|
`|app(\\${sep}.+)?\\${sep}(` +
|
|
70
70
|
`(webapp|dist|target)\\${sep}|` +
|
|
71
71
|
`tsconfig\\.json$|` +
|
|
@@ -26,10 +26,8 @@ class BindingResolver {
|
|
|
26
26
|
|
|
27
27
|
const resolvedBindings = {}
|
|
28
28
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
// await Promise.all(Object.keys(bindings).map(async name => {
|
|
32
|
-
for (const name of Object.keys(bindings)) {
|
|
29
|
+
// run in parallel
|
|
30
|
+
await Promise.all(Object.keys(bindings).map(async name => {
|
|
33
31
|
const binding = bindings[name]
|
|
34
32
|
const cacheKey = JSON.stringify(binding)
|
|
35
33
|
let resolvedBinding
|
|
@@ -40,7 +38,7 @@ class BindingResolver {
|
|
|
40
38
|
resolvedBinding = cache[cacheKey]
|
|
41
39
|
}
|
|
42
40
|
resolvedBindings[name] = resolvedBinding
|
|
43
|
-
}
|
|
41
|
+
}));
|
|
44
42
|
return Object.keys(resolvedBindings).length > 0 ? resolvedBindings : undefined
|
|
45
43
|
}
|
|
46
44
|
|
package/lib/bind/index.js
CHANGED
|
@@ -32,12 +32,9 @@ async function bind(options) {
|
|
|
32
32
|
const onText = { 'cf': 'Cloud Foundry', 'k8s': 'Kubernetes' }[on];
|
|
33
33
|
if (!options['to-app-services']) logger.log(`Retrieving data from ${bold(onText)}...`);
|
|
34
34
|
|
|
35
|
+
// run in parallel
|
|
35
36
|
const targets = options.to.split(/,/g);
|
|
36
|
-
|
|
37
|
-
// see https://github.com/cloudfoundry/cli/issues/2232
|
|
38
|
-
// resolvedServices = await Promise.all(targets.map(async target => {
|
|
39
|
-
const resolvedServices = [];
|
|
40
|
-
for (const target of targets) {
|
|
37
|
+
const resolvedServices = await Promise.all(targets.map(async target => {
|
|
41
38
|
let binding;
|
|
42
39
|
if (on === 'k8s') {
|
|
43
40
|
binding = { type: on, name: target };
|
|
@@ -51,8 +48,8 @@ async function bind(options) {
|
|
|
51
48
|
resolvedService._target = target;
|
|
52
49
|
delete resolvedService.credentials;
|
|
53
50
|
resolvedService.binding.resolved = false;
|
|
54
|
-
|
|
55
|
-
}
|
|
51
|
+
return resolvedService;
|
|
52
|
+
}));
|
|
56
53
|
|
|
57
54
|
if (options.kind) {
|
|
58
55
|
resolvedServices.forEach(service => service.kind = options.kind);
|
package/lib/init/constants.js
CHANGED
package/lib/init/index.js
CHANGED
|
@@ -245,6 +245,8 @@ module.exports = class CDSGenerator {
|
|
|
245
245
|
templates.set(plugin, template)
|
|
246
246
|
const dependencies = await template.requires()
|
|
247
247
|
dependencies?.forEach(d => plugins.add(d))
|
|
248
|
+
} else {
|
|
249
|
+
throw 'cannot run plugin \'' + plugin + '\'' + (DEBUG ? 'Does not satisfy the canRun() function:\n ' + template.canRun : '')
|
|
248
250
|
}
|
|
249
251
|
}
|
|
250
252
|
}
|
package/lib/util/cf.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
// eslint-disable-next-line no-console
|
|
2
|
-
|
|
3
1
|
const cp = require('child_process');
|
|
4
2
|
const fsp = require('fs').promises;
|
|
5
3
|
const os = require('os');
|
|
6
4
|
const path = require('path');
|
|
7
5
|
const util = require('util');
|
|
8
6
|
|
|
7
|
+
const axios = require('axios');
|
|
8
|
+
|
|
9
9
|
const IS_WIN = os.platform() === 'win32';
|
|
10
10
|
const execAsync = util.promisify(cp.exec);
|
|
11
11
|
|
|
12
12
|
const cds = require('../cds')
|
|
13
13
|
|
|
14
|
-
const LOG = cds.log ? cds.log('
|
|
15
|
-
const DEBUG = cds.debug('
|
|
14
|
+
const LOG = cds.log ? cds.log('cli') : console;
|
|
15
|
+
const DEBUG = cds.debug('cli');
|
|
16
16
|
|
|
17
17
|
const { bold, warn } = require('./term');
|
|
18
18
|
|
|
@@ -27,6 +27,7 @@ const OPERATION_STATE_FAILED = 'failed';
|
|
|
27
27
|
const OPERATION_STATE_SUCCEEDED = 'succeeded';
|
|
28
28
|
|
|
29
29
|
const CF_CLIENT_MINIMUM_VERSION = 8;
|
|
30
|
+
const ENCODED_COMMA = encodeURIComponent(',');
|
|
30
31
|
|
|
31
32
|
module.exports = new class CfUtil {
|
|
32
33
|
spaceInfo;
|
|
@@ -56,47 +57,46 @@ module.exports = new class CfUtil {
|
|
|
56
57
|
err.stderr = err.stderr?.trim();
|
|
57
58
|
throw err;
|
|
58
59
|
} finally {
|
|
59
|
-
// eslint-disable-next-line no-console
|
|
60
60
|
DEBUG && console.timeEnd(cmdLine);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
async cfRequest(urlPath, queryObj, bodyObj) {
|
|
65
|
-
|
|
66
|
-
const entries = Object.entries(queryObj);
|
|
67
|
-
const queryStr = entries.map(([key, value]) => {
|
|
68
|
-
if (Array.isArray(value)) {
|
|
69
|
-
value = value.join(',');
|
|
70
|
-
}
|
|
71
|
-
// commas cause problems in cf curl when not double encoded
|
|
72
|
-
// value = value.replace(/,/g, encodeURIComponent(','));
|
|
73
|
-
return `${key}=${encodeURIComponent(value)}`;
|
|
74
|
-
}).join('&');
|
|
65
|
+
const url = this.spaceInfo.apiEndpoint + urlPath;
|
|
75
66
|
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
const options = {
|
|
68
|
+
headers: { 'Authorization': this.spaceInfo.token }
|
|
69
|
+
};
|
|
78
70
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const result = await this.cfRun(...args);
|
|
87
|
-
let response = {};
|
|
88
|
-
if (result.stdout) {
|
|
89
|
-
response = JSON.parse(result.stdout);
|
|
90
|
-
} else if (result.stderr) {
|
|
91
|
-
response = { errors: [{ title: result.stderr }] };
|
|
71
|
+
if (queryObj && Object.keys(queryObj).length > 0) {
|
|
72
|
+
const params = {};
|
|
73
|
+
for (const [k, v] of Object.entries(queryObj)) {
|
|
74
|
+
// cf rest API does not accept comma in query parameters
|
|
75
|
+
params[k] = v.replaceAll(',', ENCODED_COMMA);
|
|
76
|
+
}
|
|
77
|
+
options.params = params;
|
|
92
78
|
}
|
|
93
79
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
80
|
+
try {
|
|
81
|
+
let response;
|
|
82
|
+
if (bodyObj) {
|
|
83
|
+
response = (await axios.post(url, bodyObj, options));
|
|
84
|
+
} else {
|
|
85
|
+
response = (await axios.get(url, options));
|
|
86
|
+
}
|
|
87
|
+
if (DEBUG) {
|
|
88
|
+
options.headers.Authorization = 'bearer <token>';
|
|
89
|
+
LOG.debug(`POST ${url}\n${JSON.stringify(options, null, 4)}\n${JSON.stringify(response.data, null, 4)}`);
|
|
90
|
+
}
|
|
91
|
+
return response.data;
|
|
92
|
+
} catch (err) {
|
|
93
|
+
if (err instanceof axios.AxiosError) {
|
|
94
|
+
if (err.response?.data?.errors[0]) {
|
|
95
|
+
throw JSON.stringify(err.response.data.errors[0], null, 4);
|
|
96
|
+
}
|
|
97
|
+
throw err.message;
|
|
98
|
+
}
|
|
97
99
|
}
|
|
98
|
-
|
|
99
|
-
return response;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
_extract(string, pattern, errorMsg) {
|
|
@@ -104,7 +104,7 @@ module.exports = new class CfUtil {
|
|
|
104
104
|
if (match?.[1]) {
|
|
105
105
|
return match[1];
|
|
106
106
|
}
|
|
107
|
-
throw
|
|
107
|
+
throw errorMsg;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
async _getCfTargetFromConfigFile() {
|
|
@@ -147,8 +147,10 @@ module.exports = new class CfUtil {
|
|
|
147
147
|
|
|
148
148
|
async getCfTarget() {
|
|
149
149
|
await this._checkCliVersion();
|
|
150
|
-
await this._getCfAuthorization();
|
|
151
|
-
|
|
150
|
+
const token = await this._getCfAuthorization();
|
|
151
|
+
const target = await this._getCfTargetFromConfigFile() || await this._getCfTargetFromCli();
|
|
152
|
+
target.token = token;
|
|
153
|
+
return target;
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
async _checkCliVersion() {
|
|
@@ -167,22 +169,26 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
167
169
|
LOG.debug('getting space info');
|
|
168
170
|
|
|
169
171
|
const target = await this.getCfTarget();
|
|
170
|
-
|
|
172
|
+
this.spaceInfo = target;
|
|
171
173
|
const { org, space } = target;
|
|
172
|
-
const orgs = await this.cfRequest(
|
|
174
|
+
const orgs = await this.cfRequest('/v3/organizations', { names: org });
|
|
173
175
|
if (!orgs?.resources?.length) {
|
|
174
|
-
throw
|
|
176
|
+
throw `CF org ${bold(org)} not found!`;
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
const orgGuid = orgs.resources[0].guid;
|
|
178
|
-
const spaces = await this.cfRequest(
|
|
180
|
+
const spaces = await this.cfRequest('/v3/spaces', { names: space, organization_guids: orgGuid });
|
|
179
181
|
if (!spaces?.resources?.length) {
|
|
180
|
-
throw
|
|
182
|
+
throw `CF space ${bold(space)} not found in org ${bold(org)}!`;
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
const spaceGuid = spaces.resources[0].guid;
|
|
184
186
|
|
|
185
|
-
this.spaceInfo =
|
|
187
|
+
this.spaceInfo = {
|
|
188
|
+
...target,
|
|
189
|
+
orgGuid,
|
|
190
|
+
spaceGuid
|
|
191
|
+
}
|
|
186
192
|
}
|
|
187
193
|
|
|
188
194
|
return this.spaceInfo;
|
|
@@ -228,7 +234,10 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
228
234
|
return serviceInstance;
|
|
229
235
|
|
|
230
236
|
case OPERATION_STATE_FAILED:
|
|
231
|
-
|
|
237
|
+
if (!DEBUG && serviceInstance?.last_operation?.description) {
|
|
238
|
+
throw serviceInstance.last_operation.description;
|
|
239
|
+
}
|
|
240
|
+
throw `The returned service reported state '${OPERATION_STATE_FAILED}'.\n${JSON.stringify(serviceInstance, null, 4)}`;
|
|
232
241
|
|
|
233
242
|
default:
|
|
234
243
|
console.error(`Unsupported server response state '${serviceInstance?.last_operation?.state}'. Waiting for next response.`);
|
|
@@ -236,7 +245,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
236
245
|
}
|
|
237
246
|
}
|
|
238
247
|
|
|
239
|
-
throw
|
|
248
|
+
throw `Timeout occurred while getting service ${bold(serviceName)}`;
|
|
240
249
|
}
|
|
241
250
|
|
|
242
251
|
|
|
@@ -260,7 +269,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
260
269
|
});
|
|
261
270
|
|
|
262
271
|
if (!servicePlan?.resources?.length) {
|
|
263
|
-
throw
|
|
272
|
+
throw `No service plans found for ${planName} in service offering ${serviceOfferingName}.`;
|
|
264
273
|
}
|
|
265
274
|
|
|
266
275
|
const body = {
|
|
@@ -287,7 +296,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
287
296
|
|
|
288
297
|
const postResult = await this.cfRequest('/v3/service_instances', undefined, body);
|
|
289
298
|
if (postResult?.errors) {
|
|
290
|
-
throw
|
|
299
|
+
throw postResult.errors[0].detail;
|
|
291
300
|
}
|
|
292
301
|
|
|
293
302
|
const newService = await this.getService(serviceName, false);
|
|
@@ -295,7 +304,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
295
304
|
return newService;
|
|
296
305
|
}
|
|
297
306
|
|
|
298
|
-
throw
|
|
307
|
+
throw `Could not create service ${bold(serviceName)}`;
|
|
299
308
|
}
|
|
300
309
|
|
|
301
310
|
async _getServiceKey(serviceInstance, serviceKeyName, showMessage = true) {
|
|
@@ -322,7 +331,10 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
322
331
|
}
|
|
323
332
|
|
|
324
333
|
case OPERATION_STATE_FAILED:
|
|
325
|
-
|
|
334
|
+
if (!DEBUG && binding?.last_operation?.description) {
|
|
335
|
+
throw binding.last_operation.description;
|
|
336
|
+
}
|
|
337
|
+
throw `The returned binding reported state '${OPERATION_STATE_FAILED}'.\n${JSON.stringify(binding, null, 4)}`;
|
|
326
338
|
|
|
327
339
|
default:
|
|
328
340
|
console.error(`Unsupported server response state '${binding?.last_operation?.state}'. Waiting for next response.`);
|
|
@@ -330,7 +342,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
330
342
|
}
|
|
331
343
|
}
|
|
332
344
|
|
|
333
|
-
throw
|
|
345
|
+
throw `Timeout occurred while getting service key ${bold(serviceKeyName)}`;
|
|
334
346
|
}
|
|
335
347
|
|
|
336
348
|
async getOrCreateServiceKey(serviceInstance, serviceKeyName, parameters, { silent = false, create = true } = {}) {
|
|
@@ -357,7 +369,7 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
357
369
|
|
|
358
370
|
const postResult = await this.cfRequest('/v3/service_credential_bindings', undefined, body);
|
|
359
371
|
if (postResult?.errors) {
|
|
360
|
-
throw
|
|
372
|
+
throw postResult.errors[0].detail;
|
|
361
373
|
}
|
|
362
374
|
|
|
363
375
|
const newServiceKey = await this._getServiceKey(serviceInstance, serviceKeyName, false);
|
|
@@ -365,6 +377,6 @@ Deployment will stop in the near future for Cloud Foundry client versions < ${CF
|
|
|
365
377
|
return newServiceKey;
|
|
366
378
|
}
|
|
367
379
|
|
|
368
|
-
throw
|
|
380
|
+
throw `Could not create service key ${bold(serviceKeyName)}`;
|
|
369
381
|
}
|
|
370
|
-
}
|
|
382
|
+
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds-dk",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@sap/cds-dk",
|
|
9
|
-
"version": "7.9.
|
|
9
|
+
"version": "7.9.5",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@sap/cds": "^7",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"node_modules/@eslint-community/regexpp": {
|
|
56
|
-
"version": "4.
|
|
56
|
+
"version": "4.11.0",
|
|
57
57
|
"license": "MIT",
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
}
|
|
209
209
|
},
|
|
210
210
|
"node_modules/@sap/cds": {
|
|
211
|
-
"version": "7.9.
|
|
211
|
+
"version": "7.9.3",
|
|
212
212
|
"license": "SEE LICENSE IN LICENSE",
|
|
213
213
|
"dependencies": {
|
|
214
214
|
"@cap-js/cds-types": "<1",
|
|
@@ -240,15 +240,15 @@
|
|
|
240
240
|
}
|
|
241
241
|
},
|
|
242
242
|
"node_modules/@sap/cds-fiori": {
|
|
243
|
-
"version": "1.2.
|
|
243
|
+
"version": "1.2.7",
|
|
244
244
|
"license": "SEE LICENSE IN LICENSE",
|
|
245
245
|
"peerDependencies": {
|
|
246
|
-
"@sap/cds": ">=7.
|
|
246
|
+
"@sap/cds": ">=7.6",
|
|
247
247
|
"express": ">=4"
|
|
248
248
|
}
|
|
249
249
|
},
|
|
250
250
|
"node_modules/@sap/cds-foss": {
|
|
251
|
-
"version": "5.0.
|
|
251
|
+
"version": "5.0.1",
|
|
252
252
|
"license": "See LICENSE in LICENSE",
|
|
253
253
|
"dependencies": {
|
|
254
254
|
"big.js": "^6.1.1",
|
|
@@ -261,7 +261,7 @@
|
|
|
261
261
|
}
|
|
262
262
|
},
|
|
263
263
|
"node_modules/@sap/cds-mtxs": {
|
|
264
|
-
"version": "1.18.
|
|
264
|
+
"version": "1.18.2",
|
|
265
265
|
"license": "SEE LICENSE IN LICENSE",
|
|
266
266
|
"dependencies": {
|
|
267
267
|
"@sap/hdi-deploy": "^4",
|
|
@@ -273,10 +273,10 @@
|
|
|
273
273
|
}
|
|
274
274
|
},
|
|
275
275
|
"node_modules/@sap/eslint-plugin-cds": {
|
|
276
|
-
"version": "3.0.
|
|
276
|
+
"version": "3.0.4",
|
|
277
277
|
"license": "See LICENSE file",
|
|
278
278
|
"dependencies": {
|
|
279
|
-
"@sap/cds": ">=
|
|
279
|
+
"@sap/cds": ">=7",
|
|
280
280
|
"semver": "^7.3.4"
|
|
281
281
|
},
|
|
282
282
|
"engines": {
|
|
@@ -396,7 +396,7 @@
|
|
|
396
396
|
}
|
|
397
397
|
},
|
|
398
398
|
"node_modules/acorn": {
|
|
399
|
-
"version": "8.
|
|
399
|
+
"version": "8.12.1",
|
|
400
400
|
"license": "MIT",
|
|
401
401
|
"bin": {
|
|
402
402
|
"acorn": "bin/acorn"
|
|
@@ -1175,7 +1175,7 @@
|
|
|
1175
1175
|
}
|
|
1176
1176
|
},
|
|
1177
1177
|
"node_modules/esquery": {
|
|
1178
|
-
"version": "1.
|
|
1178
|
+
"version": "1.6.0",
|
|
1179
1179
|
"license": "BSD-3-Clause",
|
|
1180
1180
|
"dependencies": {
|
|
1181
1181
|
"estraverse": "^5.1.0"
|
|
@@ -2214,7 +2214,7 @@
|
|
|
2214
2214
|
"license": "MIT"
|
|
2215
2215
|
},
|
|
2216
2216
|
"node_modules/node-abi": {
|
|
2217
|
-
"version": "3.
|
|
2217
|
+
"version": "3.65.0",
|
|
2218
2218
|
"license": "MIT",
|
|
2219
2219
|
"optional": true,
|
|
2220
2220
|
"dependencies": {
|
|
@@ -2301,8 +2301,11 @@
|
|
|
2301
2301
|
}
|
|
2302
2302
|
},
|
|
2303
2303
|
"node_modules/object-inspect": {
|
|
2304
|
-
"version": "1.13.
|
|
2304
|
+
"version": "1.13.2",
|
|
2305
2305
|
"license": "MIT",
|
|
2306
|
+
"engines": {
|
|
2307
|
+
"node": ">= 0.4"
|
|
2308
|
+
},
|
|
2306
2309
|
"funding": {
|
|
2307
2310
|
"url": "https://github.com/sponsors/ljharb"
|
|
2308
2311
|
}
|
|
@@ -3136,7 +3139,7 @@
|
|
|
3136
3139
|
}
|
|
3137
3140
|
},
|
|
3138
3141
|
"node_modules/uglify-js": {
|
|
3139
|
-
"version": "3.
|
|
3142
|
+
"version": "3.18.0",
|
|
3140
3143
|
"license": "BSD-2-Clause",
|
|
3141
3144
|
"optional": true,
|
|
3142
3145
|
"bin": {
|
|
@@ -3244,7 +3247,7 @@
|
|
|
3244
3247
|
"license": "ISC"
|
|
3245
3248
|
},
|
|
3246
3249
|
"node_modules/ws": {
|
|
3247
|
-
"version": "8.
|
|
3250
|
+
"version": "8.18.0",
|
|
3248
3251
|
"license": "MIT",
|
|
3249
3252
|
"engines": {
|
|
3250
3253
|
"node": ">=10.0.0"
|
|
@@ -3280,7 +3283,7 @@
|
|
|
3280
3283
|
}
|
|
3281
3284
|
},
|
|
3282
3285
|
"node_modules/yaml": {
|
|
3283
|
-
"version": "2.4.
|
|
3286
|
+
"version": "2.4.5",
|
|
3284
3287
|
"license": "ISC",
|
|
3285
3288
|
"bin": {
|
|
3286
3289
|
"yaml": "bin.mjs"
|