@nzz/q-cli 1.6.1 → 1.7.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/README.md +75 -20
- package/bin/commands/qItem/configStore.js +142 -0
- package/bin/commands/qItem/copyItem/copyItem.js +103 -0
- package/bin/commands/qItem/copyItem/copySchema.json +37 -0
- package/bin/commands/qItem/helpers.js +102 -0
- package/bin/commands/qItem/itemService.js +302 -0
- package/bin/commands/{updateItem/resourcesHelpers.js → qItem/resourcesService.js} +0 -102
- package/bin/commands/qItem/schemaService.js +64 -0
- package/bin/commands/{updateItem → qItem/updateItem}/updateItem.js +10 -5
- package/bin/commands/{updateItem/schema.json → qItem/updateItem/updateSchema.json} +0 -0
- package/bin/q.js +19 -1
- package/package.json +1 -1
- package/bin/commands/updateItem/helpers.js +0 -440
@@ -1,440 +0,0 @@
|
|
1
|
-
const fetch = require("node-fetch");
|
2
|
-
const deepmerge = require("deepmerge");
|
3
|
-
const Ajv = require("ajv");
|
4
|
-
// Remove additional properties which are not defined by the json schema
|
5
|
-
// See https://ajv.js.org/options.html#removeadditional for details
|
6
|
-
const ajv = new Ajv({ schemaId: "auto", removeAdditional: true });
|
7
|
-
ajv.addMetaSchema(require("ajv/lib/refs/json-schema-draft-04.json"));
|
8
|
-
const promptly = require("promptly");
|
9
|
-
const chalk = require("chalk");
|
10
|
-
const errorColor = chalk.red;
|
11
|
-
const Configstore = require("configstore");
|
12
|
-
const package = require("../../../package.json");
|
13
|
-
const config = new Configstore(package.name, {});
|
14
|
-
const resourcesHelpers = require("./resourcesHelpers.js");
|
15
|
-
|
16
|
-
async function updateItem(item, environment, config, qConfigPath) {
|
17
|
-
const qServer = config.get(`${environment.name}.qServer`);
|
18
|
-
const accessToken = config.get(`${environment.name}.accessToken`);
|
19
|
-
const cookie = config.get(`${environment.name}.cookie`);
|
20
|
-
const existingItem = await getItem(qServer, environment, accessToken, cookie);
|
21
|
-
const updatedItem = await getUpdatedItem(
|
22
|
-
qServer,
|
23
|
-
accessToken,
|
24
|
-
cookie,
|
25
|
-
existingItem,
|
26
|
-
item,
|
27
|
-
environment,
|
28
|
-
qConfigPath
|
29
|
-
);
|
30
|
-
return await saveItem(qServer, environment, accessToken, cookie, updatedItem);
|
31
|
-
}
|
32
|
-
|
33
|
-
async function getItem(qServer, environment, accessToken, cookie) {
|
34
|
-
try {
|
35
|
-
const response = await fetch(`${qServer}item/${environment.id}`, {
|
36
|
-
headers: {
|
37
|
-
"user-agent": "Q Command-line Tool",
|
38
|
-
Authorization: `Bearer ${accessToken}`,
|
39
|
-
Cookie: cookie ? cookie : "",
|
40
|
-
},
|
41
|
-
});
|
42
|
-
if (response.ok) {
|
43
|
-
return await response.json();
|
44
|
-
} else {
|
45
|
-
throw new Error(
|
46
|
-
`A problem occured while getting item with id ${environment.id} on ${environment.name} environment. Please make sure that the id is correct, you have an internet connection and try again.`
|
47
|
-
);
|
48
|
-
}
|
49
|
-
} catch (error) {
|
50
|
-
console.error(errorColor(error.message));
|
51
|
-
process.exit(1);
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
async function getUpdatedItem(
|
56
|
-
qServer,
|
57
|
-
accessToken,
|
58
|
-
cookie,
|
59
|
-
existingItem,
|
60
|
-
item,
|
61
|
-
environment,
|
62
|
-
qConfigPath
|
63
|
-
) {
|
64
|
-
try {
|
65
|
-
const toolSchema = await resourcesHelpers.getToolSchema(
|
66
|
-
qServer,
|
67
|
-
existingItem.tool
|
68
|
-
);
|
69
|
-
// Removes additional properties not defined in the schema on the top level object of the item
|
70
|
-
toolSchema.additionalProperties = false;
|
71
|
-
// If options object is available additional properties not defined in the schema are removed
|
72
|
-
if (toolSchema.properties && toolSchema.properties.options) {
|
73
|
-
toolSchema.properties.options.additionalProperties = false;
|
74
|
-
}
|
75
|
-
const defaultItem = resourcesHelpers.getDefaultItem(toolSchema);
|
76
|
-
item = JSON.parse(JSON.stringify(item));
|
77
|
-
item = await resourcesHelpers.handleResources(
|
78
|
-
qServer,
|
79
|
-
accessToken,
|
80
|
-
cookie,
|
81
|
-
item,
|
82
|
-
defaultItem,
|
83
|
-
qConfigPath,
|
84
|
-
environment
|
85
|
-
);
|
86
|
-
|
87
|
-
// Merge options:
|
88
|
-
// File of files property will be updated (if file exists on destination)
|
89
|
-
// If it doesn't exist it is appended to the files array
|
90
|
-
// All other properties are overwritten from source config
|
91
|
-
const options = {
|
92
|
-
arrayMerge: (destArr, srcArr) => srcArr,
|
93
|
-
customMerge: (key) => {
|
94
|
-
if (key === "files") {
|
95
|
-
return (destArr, srcArr) => {
|
96
|
-
if (destArr.length <= 0) {
|
97
|
-
return srcArr;
|
98
|
-
}
|
99
|
-
|
100
|
-
srcArr.forEach((fileObj) => {
|
101
|
-
let destIndex = destArr.findIndex(
|
102
|
-
(destFileObj) =>
|
103
|
-
destFileObj.file.originalName === fileObj.file.originalName
|
104
|
-
);
|
105
|
-
|
106
|
-
if (destIndex !== -1) {
|
107
|
-
destArr[destIndex] = fileObj;
|
108
|
-
} else {
|
109
|
-
destArr.push(fileObj);
|
110
|
-
}
|
111
|
-
});
|
112
|
-
return destArr;
|
113
|
-
};
|
114
|
-
}
|
115
|
-
},
|
116
|
-
};
|
117
|
-
|
118
|
-
// merges existing item with the item defined in q.config.json
|
119
|
-
const updatedItem = deepmerge(existingItem, item, options);
|
120
|
-
// normalizes the item which removes additional properties not defined in the schema
|
121
|
-
// and validates the item against the schema
|
122
|
-
const normalizedItem = getNormalizedItem(
|
123
|
-
toolSchema,
|
124
|
-
updatedItem,
|
125
|
-
environment
|
126
|
-
);
|
127
|
-
// the normalized item is merged with the existing item. This is done because properties such as _id and _rev
|
128
|
-
// defined in the existing item are removed during normalization, because they are not defined in the schema
|
129
|
-
return deepmerge(existingItem, normalizedItem, options);
|
130
|
-
} catch (error) {
|
131
|
-
console.error(errorColor(error.message));
|
132
|
-
process.exit(1);
|
133
|
-
}
|
134
|
-
}
|
135
|
-
|
136
|
-
async function saveItem(
|
137
|
-
qServer,
|
138
|
-
environment,
|
139
|
-
accessToken,
|
140
|
-
cookie,
|
141
|
-
updatedItem
|
142
|
-
) {
|
143
|
-
try {
|
144
|
-
delete updatedItem.updatedDate;
|
145
|
-
const response = await fetch(`${qServer}item`, {
|
146
|
-
method: "PUT",
|
147
|
-
body: JSON.stringify(updatedItem),
|
148
|
-
headers: {
|
149
|
-
"user-agent": "Q Command-line Tool",
|
150
|
-
Authorization: `Bearer ${accessToken}`,
|
151
|
-
"Content-Type": "application/json",
|
152
|
-
Cookie: cookie ? cookie : "",
|
153
|
-
},
|
154
|
-
});
|
155
|
-
if (response.ok) {
|
156
|
-
return await response.json();
|
157
|
-
} else {
|
158
|
-
throw new Error(
|
159
|
-
`A problem occured while saving item with id ${environment.id} on ${environment.name} environment. Please check your connection and try again.`
|
160
|
-
);
|
161
|
-
}
|
162
|
-
} catch (error) {
|
163
|
-
console.error(errorColor(error.message));
|
164
|
-
process.exit(1);
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
function getItems(qConfig, environmentFilter) {
|
169
|
-
const items = qConfig.items
|
170
|
-
.filter((item) => {
|
171
|
-
if (environmentFilter) {
|
172
|
-
return item.environments.some(
|
173
|
-
(environment) => environment.name === environmentFilter
|
174
|
-
);
|
175
|
-
}
|
176
|
-
|
177
|
-
return true;
|
178
|
-
})
|
179
|
-
.map((item) => {
|
180
|
-
if (environmentFilter) {
|
181
|
-
item.environments = item.environments.filter(
|
182
|
-
(environment) => environment.name === environmentFilter
|
183
|
-
);
|
184
|
-
}
|
185
|
-
|
186
|
-
return item;
|
187
|
-
});
|
188
|
-
|
189
|
-
return items;
|
190
|
-
}
|
191
|
-
|
192
|
-
function validateConfig(config) {
|
193
|
-
const isValid = ajv.validate(require("./schema.json"), config);
|
194
|
-
return {
|
195
|
-
isValid: isValid,
|
196
|
-
errorsText: ajv.errorsText(),
|
197
|
-
};
|
198
|
-
}
|
199
|
-
|
200
|
-
function getNormalizedItem(schema, item, environment) {
|
201
|
-
const isValid = ajv.validate(schema, item);
|
202
|
-
if (!isValid) {
|
203
|
-
throw new Error(
|
204
|
-
`A problem occured while validating item with id ${environment.id} on ${
|
205
|
-
environment.name
|
206
|
-
} environment: ${ajv.errorsText()}`
|
207
|
-
);
|
208
|
-
}
|
209
|
-
|
210
|
-
return item;
|
211
|
-
}
|
212
|
-
|
213
|
-
function getEnvironments(qConfig, environmentFilter) {
|
214
|
-
try {
|
215
|
-
const environments = new Set();
|
216
|
-
for (const item of qConfig.items) {
|
217
|
-
for (const environment of item.environments) {
|
218
|
-
if (environmentFilter) {
|
219
|
-
if (environmentFilter === environment.name) {
|
220
|
-
environments.add(environment.name);
|
221
|
-
}
|
222
|
-
} else {
|
223
|
-
environments.add(environment.name);
|
224
|
-
}
|
225
|
-
}
|
226
|
-
}
|
227
|
-
|
228
|
-
if (environments.size > 0) {
|
229
|
-
return Array.from(environments);
|
230
|
-
} else {
|
231
|
-
throw new Error(
|
232
|
-
`No items with environment ${environmentFilter} found. Please check your configuration and try again.`
|
233
|
-
);
|
234
|
-
}
|
235
|
-
} catch (error) {
|
236
|
-
console.error(errorColor(error.message));
|
237
|
-
process.exit(1);
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
|
-
async function setAuthenticationConfig(environment, qServer) {
|
242
|
-
const result = await authenticate(environment, qServer);
|
243
|
-
config.set(`${environment}.accessToken`, result.accessToken);
|
244
|
-
config.set(`${environment}.cookie`, result.cookie);
|
245
|
-
}
|
246
|
-
|
247
|
-
async function setupConfig(qConfig, environmentFilter, reset) {
|
248
|
-
if (reset) {
|
249
|
-
config.clear();
|
250
|
-
}
|
251
|
-
for (const environment of getEnvironments(qConfig, environmentFilter)) {
|
252
|
-
await setupConfigFromEnvVars(environment);
|
253
|
-
|
254
|
-
if (!config.get(`${environment}.qServer`)) {
|
255
|
-
const qServer = await promptly.prompt(
|
256
|
-
`Enter the Q-Server url for ${environment} environment: `,
|
257
|
-
{
|
258
|
-
validator: (qServer) => {
|
259
|
-
return new URL(qServer).toString();
|
260
|
-
},
|
261
|
-
retry: true,
|
262
|
-
}
|
263
|
-
);
|
264
|
-
config.set(`${environment}.qServer`, qServer);
|
265
|
-
}
|
266
|
-
|
267
|
-
const qServer = config.get(`${environment}.qServer`);
|
268
|
-
if (!config.get(`${environment}.accessToken`)) {
|
269
|
-
await setAuthenticationConfig(environment, qServer);
|
270
|
-
}
|
271
|
-
|
272
|
-
const accessToken = config.get(`${environment}.accessToken`);
|
273
|
-
const cookie = config.get(`${environment}.cookie`);
|
274
|
-
const isAccessTokenValid = await checkValidityOfAccessToken(
|
275
|
-
environment,
|
276
|
-
qServer,
|
277
|
-
accessToken,
|
278
|
-
cookie
|
279
|
-
);
|
280
|
-
|
281
|
-
// Get a new access token in case its not valid anymore
|
282
|
-
if (!isAccessTokenValid) {
|
283
|
-
await setAuthenticationConfig(environment, qServer);
|
284
|
-
}
|
285
|
-
}
|
286
|
-
|
287
|
-
return config;
|
288
|
-
}
|
289
|
-
|
290
|
-
async function setupConfigFromEnvVars(environment) {
|
291
|
-
const environmentPrefix = environment.toUpperCase();
|
292
|
-
|
293
|
-
const qServer = process.env[`Q_${environmentPrefix}_SERVER`];
|
294
|
-
if (qServer) {
|
295
|
-
config.set(`${environment}.qServer`, qServer);
|
296
|
-
}
|
297
|
-
const accessToken = process.env[`Q_${environmentPrefix}_ACCESSTOKEN`];
|
298
|
-
const username = process.env[`Q_${environmentPrefix}_USERNAME`];
|
299
|
-
const password = process.env[`Q_${environmentPrefix}_PASSWORD`];
|
300
|
-
if (qServer && accessToken) {
|
301
|
-
config.set(`${environment}.accessToken`, accessToken);
|
302
|
-
} else if (qServer && username && password) {
|
303
|
-
const cookie = config.get(`${environment}.cookie`);
|
304
|
-
const result = await getAccessToken(
|
305
|
-
environment,
|
306
|
-
qServer,
|
307
|
-
username,
|
308
|
-
password,
|
309
|
-
cookie
|
310
|
-
);
|
311
|
-
|
312
|
-
if (!result) {
|
313
|
-
console.error(
|
314
|
-
errorColor(
|
315
|
-
`A problem occured while authenticating to the ${environment} environment using environment variables. Please check your credentials and try again.`
|
316
|
-
)
|
317
|
-
);
|
318
|
-
process.exit(1);
|
319
|
-
}
|
320
|
-
|
321
|
-
config.set(`${environment}.accessToken`, result.accessToken);
|
322
|
-
config.set(`${environment}.cookie`, result.cookie);
|
323
|
-
}
|
324
|
-
}
|
325
|
-
|
326
|
-
async function authenticate(environment, qServer) {
|
327
|
-
let username = config.get(`${environment}.username`);
|
328
|
-
if (!username) {
|
329
|
-
username = await promptly.prompt(
|
330
|
-
`Enter your username on ${environment} environment: `,
|
331
|
-
{ validator: (username) => username.trim() }
|
332
|
-
);
|
333
|
-
config.set(`${environment}.username`, username);
|
334
|
-
}
|
335
|
-
|
336
|
-
const password = await promptly.password(
|
337
|
-
`Enter your password on ${environment} environment: `,
|
338
|
-
{
|
339
|
-
validator: async (password) => password.trim(),
|
340
|
-
replace: "*",
|
341
|
-
}
|
342
|
-
);
|
343
|
-
|
344
|
-
const cookie = config.get(`${environment}.cookie`);
|
345
|
-
let result = await getAccessToken(
|
346
|
-
environment,
|
347
|
-
qServer,
|
348
|
-
username,
|
349
|
-
password,
|
350
|
-
cookie
|
351
|
-
);
|
352
|
-
|
353
|
-
while (!result) {
|
354
|
-
console.error(
|
355
|
-
errorColor(
|
356
|
-
"A problem occured while authenticating. Please check your credentials and try again."
|
357
|
-
)
|
358
|
-
);
|
359
|
-
|
360
|
-
result = await authenticate(environment, qServer);
|
361
|
-
|
362
|
-
if (result.accessToken) {
|
363
|
-
break;
|
364
|
-
}
|
365
|
-
}
|
366
|
-
|
367
|
-
return result;
|
368
|
-
}
|
369
|
-
|
370
|
-
async function getAccessToken(
|
371
|
-
environment,
|
372
|
-
qServer,
|
373
|
-
username,
|
374
|
-
password,
|
375
|
-
cookie
|
376
|
-
) {
|
377
|
-
try {
|
378
|
-
const response = await fetch(`${qServer}authenticate`, {
|
379
|
-
method: "POST",
|
380
|
-
headers: {
|
381
|
-
"user-agent": "Q Command-line Tool",
|
382
|
-
origin: qServer,
|
383
|
-
Cookie: cookie ? cookie : "",
|
384
|
-
},
|
385
|
-
body: JSON.stringify({
|
386
|
-
username: username,
|
387
|
-
password: password,
|
388
|
-
}),
|
389
|
-
});
|
390
|
-
|
391
|
-
if (response.ok) {
|
392
|
-
const body = await response.json();
|
393
|
-
return {
|
394
|
-
accessToken: body.access_token,
|
395
|
-
cookie: response.headers.get("set-cookie"),
|
396
|
-
};
|
397
|
-
}
|
398
|
-
|
399
|
-
return false;
|
400
|
-
} catch (error) {
|
401
|
-
console.error(
|
402
|
-
errorColor(
|
403
|
-
`A problem occured while authenticating on ${environment} environment. Please check your connection and try again.`
|
404
|
-
)
|
405
|
-
);
|
406
|
-
process.exit(1);
|
407
|
-
}
|
408
|
-
}
|
409
|
-
|
410
|
-
async function checkValidityOfAccessToken(
|
411
|
-
environment,
|
412
|
-
qServer,
|
413
|
-
accessToken,
|
414
|
-
cookie
|
415
|
-
) {
|
416
|
-
try {
|
417
|
-
const response = await fetch(`${qServer}user`, {
|
418
|
-
headers: {
|
419
|
-
"user-agent": "Q Command-line Tool",
|
420
|
-
Authorization: `Bearer ${accessToken}`,
|
421
|
-
Cookie: cookie ? cookie : "",
|
422
|
-
},
|
423
|
-
});
|
424
|
-
return response.ok;
|
425
|
-
} catch (error) {
|
426
|
-
console.error(
|
427
|
-
errorColor(
|
428
|
-
`A problem occured while checking the validity of your access token on ${environment} environment. Please check your connection and try again.`
|
429
|
-
)
|
430
|
-
);
|
431
|
-
process.exit(1);
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
module.exports = {
|
436
|
-
updateItem: updateItem,
|
437
|
-
setupConfig: setupConfig,
|
438
|
-
getItems: getItems,
|
439
|
-
validateConfig: validateConfig,
|
440
|
-
};
|