@nzz/q-cli 1.10.3 → 2.0.0-beta.13
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 +22 -313
- package/dist/createCustomCodeItem.js +74 -0
- package/dist/enums.js +7 -0
- package/dist/index.js +50 -0
- package/dist/interfaces.js +1 -0
- package/dist/newCustomCode.js +107 -0
- package/dist/updateItem.js +194 -0
- package/dist/utils.js +88 -0
- package/package.json +29 -36
- package/.nvmrc +0 -1
- package/.travis.yml +0 -17
- package/.vscode/launch.json +0 -36
- package/.vscode/settings.json +0 -5
- package/LICENSE +0 -21
- package/bin/commands/bootstrap.js +0 -68
- package/bin/commands/qItem/configStore.js +0 -144
- package/bin/commands/qItem/copyItem/copyItem.js +0 -103
- package/bin/commands/qItem/copyItem/copySchema.json +0 -37
- package/bin/commands/qItem/createCustomCodeItem/createCustomCodeItem.js +0 -81
- package/bin/commands/qItem/createCustomCodeItem/schema.json +0 -41
- package/bin/commands/qItem/helpers.js +0 -102
- package/bin/commands/qItem/itemService.js +0 -310
- package/bin/commands/qItem/resourcesService.js +0 -148
- package/bin/commands/qItem/schemaService.js +0 -65
- package/bin/commands/qItem/updateItem/updateItem.js +0 -64
- package/bin/commands/server.js +0 -80
- package/bin/q.js +0 -213
- package/dev-server/config/default.js +0 -51
- package/dev-server/public/favicon.ico +0 -0
- package/dev-server/public/style.css +0 -64
- package/dev-server/routes/dev-view.js +0 -52
- package/dev-server/routes/file.js +0 -10
- package/dev-server/routes/rendering-info.js +0 -130
- package/dev-server/routes/routes.js +0 -6
- package/dev-server/routes/tool-default.js +0 -108
- package/dev-server/server-plugins.js +0 -1
- package/dev-server/server.js +0 -18
- package/dev-server/views/index.html +0 -184
- package/skeletons/custom-code-skeleton/.nvmrc +0 -1
- package/skeletons/custom-code-skeleton/.vscode/settings.json +0 -5
- package/skeletons/custom-code-skeleton/README.md +0 -26
- package/skeletons/custom-code-skeleton/index.d.ts +0 -3
- package/skeletons/custom-code-skeleton/package-lock.json +0 -7355
- package/skeletons/custom-code-skeleton/package.json +0 -46
- package/skeletons/custom-code-skeleton/q.config.json +0 -60
- package/skeletons/custom-code-skeleton/rollup.config.js +0 -185
- package/skeletons/custom-code-skeleton/src/App.scss +0 -5
- package/skeletons/custom-code-skeleton/src/App.svelte +0 -7
- package/skeletons/custom-code-skeleton/src/enums.ts +0 -0
- package/skeletons/custom-code-skeleton/src/interfaces.ts +0 -0
- package/skeletons/custom-code-skeleton/src/main-prod.ts +0 -4
- package/skeletons/custom-code-skeleton/src/main.scss +0 -1
- package/skeletons/custom-code-skeleton/src/main.ts +0 -18
- package/skeletons/custom-code-skeleton/tsconfig.json +0 -16
- package/skeletons/et-utils-package-skeleton/.nvmrc +0 -1
- package/skeletons/et-utils-package-skeleton/README.md +0 -12
- package/skeletons/et-utils-package-skeleton/jest.config.ts +0 -17
- package/skeletons/et-utils-package-skeleton/package-lock.json +0 -3969
- package/skeletons/et-utils-package-skeleton/package.json +0 -40
- package/skeletons/et-utils-package-skeleton/scripts/package-fixup.sh +0 -13
- package/skeletons/et-utils-package-skeleton/src/Service.ts +0 -8
- package/skeletons/et-utils-package-skeleton/src/index.ts +0 -4
- package/skeletons/et-utils-package-skeleton/test/Service.spec.ts +0 -10
- package/skeletons/et-utils-package-skeleton/test/tsconfig.json +0 -8
- package/skeletons/et-utils-package-skeleton/tsconfig-base.json +0 -10
- package/skeletons/et-utils-package-skeleton/tsconfig-cjs.json +0 -8
- package/skeletons/et-utils-package-skeleton/tsconfig.json +0 -8
- package/skeletons/server-skeleton/.nvmrc +0 -1
- package/skeletons/server-skeleton/Dockerfile +0 -19
- package/skeletons/server-skeleton/auth/routes.js +0 -85
- package/skeletons/server-skeleton/auth/strategyOptions.js +0 -28
- package/skeletons/server-skeleton/config/base.js +0 -45
- package/skeletons/server-skeleton/config/db.js +0 -6
- package/skeletons/server-skeleton/config/editor.js +0 -105
- package/skeletons/server-skeleton/config/rendering-info.js +0 -70
- package/skeletons/server-skeleton/config/screenshot.js +0 -80
- package/skeletons/server-skeleton/config/targets.js +0 -31
- package/skeletons/server-skeleton/config/tools.js +0 -65
- package/skeletons/server-skeleton/files/favicon.png +0 -0
- package/skeletons/server-skeleton/files/system.js +0 -3612
- package/skeletons/server-skeleton/index.js +0 -106
- package/skeletons/server-skeleton/package-lock.json +0 -1825
- package/skeletons/server-skeleton/package.json +0 -29
- package/skeletons/tool-skeleton/.dockerignore +0 -1
- package/skeletons/tool-skeleton/.nvmrc +0 -1
- package/skeletons/tool-skeleton/.travis.yml +0 -26
- package/skeletons/tool-skeleton/.vscode/settings.json +0 -5
- package/skeletons/tool-skeleton/Dockerfile +0 -19
- package/skeletons/tool-skeleton/LICENSE +0 -20
- package/skeletons/tool-skeleton/README.md +0 -104
- package/skeletons/tool-skeleton/index.js +0 -32
- package/skeletons/tool-skeleton/package-lock.json +0 -10108
- package/skeletons/tool-skeleton/package.json +0 -45
- package/skeletons/tool-skeleton/resources/display-options-schema.json +0 -11
- package/skeletons/tool-skeleton/resources/fixtures/data/basic.json +0 -4
- package/skeletons/tool-skeleton/resources/locales/de/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/locales/en/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/locales/fr/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/schema.json +0 -16
- package/skeletons/tool-skeleton/rollup.config.js +0 -75
- package/skeletons/tool-skeleton/routes/fixtures/data.js +0 -15
- package/skeletons/tool-skeleton/routes/health.js +0 -10
- package/skeletons/tool-skeleton/routes/locales.js +0 -21
- package/skeletons/tool-skeleton/routes/rendering-info/web.js +0 -97
- package/skeletons/tool-skeleton/routes/routes.js +0 -8
- package/skeletons/tool-skeleton/routes/schema.js +0 -19
- package/skeletons/tool-skeleton/routes/script.js +0 -17
- package/skeletons/tool-skeleton/routes/stylesheet.js +0 -17
- package/skeletons/tool-skeleton/sass.config.js +0 -66
- package/skeletons/tool-skeleton/scripts_src/default.js +0 -3
- package/skeletons/tool-skeleton/styles_src/_variables.scss +0 -1
- package/skeletons/tool-skeleton/styles_src/main.scss +0 -2
- package/skeletons/tool-skeleton/test/e2e-tests.js +0 -162
- package/skeletons/tool-skeleton/views/dynamic/YourTool.scss +0 -5
- package/skeletons/tool-skeleton/views/dynamic/YourTool.svelte +0 -19
- package/skeletons/tool-skeleton/views/static/App.scss +0 -5
- package/skeletons/tool-skeleton/views/static/App.svelte +0 -21
- package/skeletons/tool-skeleton/views/static/components/Footer.svelte +0 -31
- package/skeletons/tool-skeleton/views/static/components/Header.svelte +0 -7
- package/skeletons/toolv2-skeleton/.husky/pre-commit +0 -6
- package/skeletons/toolv2-skeleton/.nvmrc +0 -1
- package/skeletons/toolv2-skeleton/.prettierrc.cjs +0 -15
- package/skeletons/toolv2-skeleton/.travis.yml +0 -30
- package/skeletons/toolv2-skeleton/.vscode/settings.json +0 -6
- package/skeletons/toolv2-skeleton/Dockerfile +0 -19
- package/skeletons/toolv2-skeleton/LICENSE +0 -21
- package/skeletons/toolv2-skeleton/README.md +0 -99
- package/skeletons/toolv2-skeleton/dev.js +0 -7
- package/skeletons/toolv2-skeleton/index.js +0 -39
- package/skeletons/toolv2-skeleton/jest.config.ts +0 -39
- package/skeletons/toolv2-skeleton/nodemon.json +0 -4
- package/skeletons/toolv2-skeleton/package-lock.json +0 -21382
- package/skeletons/toolv2-skeleton/package.json +0 -80
- package/skeletons/toolv2-skeleton/resources/display-options-schema.json +0 -11
- package/skeletons/toolv2-skeleton/resources/locales/de/translation.json +0 -8
- package/skeletons/toolv2-skeleton/resources/locales/en/translation.json +0 -10
- package/skeletons/toolv2-skeleton/resources/locales/fr/translation.json +0 -10
- package/skeletons/toolv2-skeleton/resources/schema.json +0 -66
- package/skeletons/toolv2-skeleton/rollup.config.js +0 -48
- package/skeletons/toolv2-skeleton/scripts/postinstall.sh +0 -5
- package/skeletons/toolv2-skeleton/src/.eslintrc.cjs +0 -52
- package/skeletons/toolv2-skeleton/src/components/Main.spec.ts +0 -15
- package/skeletons/toolv2-skeleton/src/components/Main.svelte +0 -32
- package/skeletons/toolv2-skeleton/src/enums.ts +0 -11
- package/skeletons/toolv2-skeleton/src/helpers/fixture-generators.ts +0 -38
- package/skeletons/toolv2-skeleton/src/helpers/toolRuntimeConfig.ts +0 -15
- package/skeletons/toolv2-skeleton/src/interfaces.ts +0 -82
- package/skeletons/toolv2-skeleton/src/modules.d.ts +0 -8
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/exampleDynamicSchema.ts +0 -49
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/index.ts +0 -5
- package/skeletons/toolv2-skeleton/src/routes/health.ts +0 -14
- package/skeletons/toolv2-skeleton/src/routes/locales.ts +0 -31
- package/skeletons/toolv2-skeleton/src/routes/notifications/exampleNotification.ts +0 -46
- package/skeletons/toolv2-skeleton/src/routes/option-availability.ts +0 -27
- package/skeletons/toolv2-skeleton/src/routes/rendering-info/web.ts +0 -150
- package/skeletons/toolv2-skeleton/src/routes/routes.ts +0 -21
- package/skeletons/toolv2-skeleton/src/routes/schema.ts +0 -21
- package/skeletons/toolv2-skeleton/src/routes/stylesheet.ts +0 -31
- package/skeletons/toolv2-skeleton/src/styles/main.scss +0 -6
- package/skeletons/toolv2-skeleton/svelte.config.cjs +0 -6
- package/skeletons/toolv2-skeleton/tasks/compileStyleFiles.cjs +0 -101
- package/skeletons/toolv2-skeleton/tests/e2e-tests.spec.ts +0 -158
- package/skeletons/toolv2-skeleton/tests/helpers.ts +0 -21
- package/skeletons/toolv2-skeleton/tsconfig.json +0 -48
- /package/{bin/commands/qItem/updateItem → dist/assets}/updateSchema.json +0 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import Ajv from 'ajv';
|
11
|
+
import { readFileSync, existsSync, createReadStream } from 'fs';
|
12
|
+
import { resolve } from 'path';
|
13
|
+
import FormData from 'form-data';
|
14
|
+
import fetch from 'node-fetch'; // Use node-fetch instead of native fetch, because native fetch seems to have issues with FormData/uploading files
|
15
|
+
import { getAccessToken, getQServerUrl, logError, logSuccess, updateItem } from './utils.js';
|
16
|
+
import updateSchemaJson from './assets/updateSchema.json' with { type: 'json' };
|
17
|
+
import { Environment } from './enums.js';
|
18
|
+
const envCredentials = {
|
19
|
+
[Environment.LOCAL]: {
|
20
|
+
qServerUrl: '',
|
21
|
+
accessToken: '',
|
22
|
+
},
|
23
|
+
[Environment.TEST]: {
|
24
|
+
qServerUrl: '',
|
25
|
+
accessToken: '',
|
26
|
+
},
|
27
|
+
[Environment.STAGING]: {
|
28
|
+
qServerUrl: '',
|
29
|
+
accessToken: '',
|
30
|
+
},
|
31
|
+
[Environment.PRODUCTION]: {
|
32
|
+
qServerUrl: '',
|
33
|
+
accessToken: '',
|
34
|
+
},
|
35
|
+
};
|
36
|
+
/**
|
37
|
+
* Get the Q server URL and access token from the environment variables or 1Password
|
38
|
+
* @param environment The environment to get the credentials for
|
39
|
+
* @returns The Q server URL and access token
|
40
|
+
*/
|
41
|
+
function getEnvCredentials(environment) {
|
42
|
+
if (envCredentials[environment].qServerUrl === '' || envCredentials[environment].accessToken === '') {
|
43
|
+
envCredentials[environment] = {
|
44
|
+
qServerUrl: getQServerUrl(environment),
|
45
|
+
accessToken: getAccessToken(environment),
|
46
|
+
};
|
47
|
+
}
|
48
|
+
return envCredentials[environment];
|
49
|
+
}
|
50
|
+
function validateConfig(metaSchema, qConfig) {
|
51
|
+
const ajv = new Ajv({ allErrors: true });
|
52
|
+
let isValid = true;
|
53
|
+
let errorsText = '';
|
54
|
+
try {
|
55
|
+
isValid = ajv.validate(metaSchema, qConfig);
|
56
|
+
errorsText = ajv.errorsText();
|
57
|
+
}
|
58
|
+
catch (error) {
|
59
|
+
isValid = false;
|
60
|
+
errorsText = `Error occurred while validating the config file: ${error.message}`;
|
61
|
+
}
|
62
|
+
return {
|
63
|
+
isValid,
|
64
|
+
errorsText,
|
65
|
+
};
|
66
|
+
}
|
67
|
+
function uploadFile(path, qServerUrl, accessToken) {
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
69
|
+
const localFilePath = resolve(path);
|
70
|
+
// Check if the file exists
|
71
|
+
if (!existsSync(localFilePath)) {
|
72
|
+
logError(`File not found: ${localFilePath}`);
|
73
|
+
return undefined;
|
74
|
+
}
|
75
|
+
try {
|
76
|
+
const form = new FormData();
|
77
|
+
// Read the file
|
78
|
+
const fileStream = createReadStream(localFilePath);
|
79
|
+
// Append the file to the form
|
80
|
+
form.append('file', fileStream);
|
81
|
+
// Upload the file to the server
|
82
|
+
const response = yield fetch(`${qServerUrl}/file`, {
|
83
|
+
method: 'POST',
|
84
|
+
body: form,
|
85
|
+
headers: Object.assign(Object.assign({}, form.getHeaders()), { 'user-agent': 'Q Command-line Tool', Authorization: `Bearer ${accessToken}` }),
|
86
|
+
});
|
87
|
+
const data = (yield response.json());
|
88
|
+
if (!data.apiResponseStatus.success) {
|
89
|
+
logError(`Failed to upload file: ${data.apiResponseStatus.msg}`);
|
90
|
+
return undefined;
|
91
|
+
}
|
92
|
+
logSuccess(`Successfully uploaded file: ${localFilePath}`);
|
93
|
+
return data.fileInfo;
|
94
|
+
}
|
95
|
+
catch (error) {
|
96
|
+
logError(`Error uploading file: ${error instanceof Error ? error.message : String(error)}`);
|
97
|
+
}
|
98
|
+
});
|
99
|
+
}
|
100
|
+
/**
|
101
|
+
* Recursively processes a document structure, looking for 'path' properties
|
102
|
+
* and processing them with the processResource function.
|
103
|
+
*
|
104
|
+
* @param item The object or value to process
|
105
|
+
* @param processResource Function to handle path properties
|
106
|
+
* @returns The processed item
|
107
|
+
*/
|
108
|
+
function processPathProperties(item, processResource) {
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
110
|
+
// Base case: if item is null or not an object, return it unchanged
|
111
|
+
if (item === null || typeof item !== 'object') {
|
112
|
+
return item;
|
113
|
+
}
|
114
|
+
// Handle arrays
|
115
|
+
if (Array.isArray(item)) {
|
116
|
+
return yield Promise.all(item.map((element) => __awaiter(this, void 0, void 0, function* () { return yield processPathProperties(element, processResource); })));
|
117
|
+
}
|
118
|
+
// Check if this object has a 'path' property (using Object.prototype.hasOwnProperty.call to avoid prototype pollution)
|
119
|
+
if (Object.prototype.hasOwnProperty.call(item, 'path') && typeof item.path === 'string') {
|
120
|
+
return yield processResource(item.path);
|
121
|
+
}
|
122
|
+
// Process each property recursively
|
123
|
+
const result = Object.assign({}, item);
|
124
|
+
for (const key of Object.keys(item)) {
|
125
|
+
result[key] = yield processPathProperties(item[key], processResource);
|
126
|
+
}
|
127
|
+
return result;
|
128
|
+
});
|
129
|
+
}
|
130
|
+
export default function (command) {
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
132
|
+
const qConfigPath = resolve(command.config);
|
133
|
+
if (!existsSync(qConfigPath)) {
|
134
|
+
logError(`Couldn't find config file: '${qConfigPath}'.\nCreate a config file in the current directory or pass the path to the config file with the option -c <path>`);
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
const qConfig = JSON.parse(readFileSync(qConfigPath, 'utf-8'));
|
138
|
+
const validationResult = validateConfig(updateSchemaJson, qConfig); // Validate the config file against the schema
|
139
|
+
if (!validationResult.isValid) {
|
140
|
+
logError(`A problem occurred while validating the config file: ${validationResult.errorsText}`);
|
141
|
+
process.exit(1);
|
142
|
+
}
|
143
|
+
let qServerUrl;
|
144
|
+
let accessToken;
|
145
|
+
let environmentToUpdate;
|
146
|
+
for (const item of qConfig.items) {
|
147
|
+
for (const environment of item.environments) {
|
148
|
+
// If the environment is specified, use that environment
|
149
|
+
if (command.environment && !environmentToUpdate) {
|
150
|
+
// Skip if the environment is not the one we want to update
|
151
|
+
if (command.environment !== environment.name)
|
152
|
+
continue;
|
153
|
+
environmentToUpdate = command.environment;
|
154
|
+
// Get the credentials for the current environment
|
155
|
+
const credentials = getEnvCredentials(environmentToUpdate);
|
156
|
+
qServerUrl = credentials.qServerUrl;
|
157
|
+
accessToken = credentials.accessToken;
|
158
|
+
console.log(`Updating items on server ${qServerUrl}...`);
|
159
|
+
}
|
160
|
+
else if (!command.environment && environmentToUpdate !== environment.name) {
|
161
|
+
// Otherwise, use the environment from the config
|
162
|
+
environmentToUpdate = environment.name;
|
163
|
+
// Get the credentials for the current environment
|
164
|
+
const credentials = getEnvCredentials(environmentToUpdate);
|
165
|
+
qServerUrl = credentials.qServerUrl;
|
166
|
+
accessToken = credentials.accessToken;
|
167
|
+
console.log(`Updating items on server ${qServerUrl}...`);
|
168
|
+
}
|
169
|
+
else {
|
170
|
+
// If the environment is not specified, skip the environment
|
171
|
+
continue;
|
172
|
+
}
|
173
|
+
console.log(`Updating item ${environment.id} on ${environmentToUpdate} environment...`);
|
174
|
+
let qDoc = structuredClone(item.item);
|
175
|
+
qDoc._id = environment.id;
|
176
|
+
// Process the 'path' properties and upload files
|
177
|
+
qDoc = yield processPathProperties(qDoc, (path) => __awaiter(this, void 0, void 0, function* () {
|
178
|
+
const formattedPath = path.replace('{id}', environment.id);
|
179
|
+
console.log(`Processing resource at path: ${formattedPath}`);
|
180
|
+
return yield uploadFile(formattedPath, qServerUrl, accessToken);
|
181
|
+
}));
|
182
|
+
// Update the item on the Q server
|
183
|
+
const result = yield updateItem(qDoc, qServerUrl, accessToken);
|
184
|
+
if (result.success) {
|
185
|
+
logSuccess(`Successfully updated item with id ${environment.id} on ${environmentToUpdate} environment`);
|
186
|
+
}
|
187
|
+
else {
|
188
|
+
logError(result.msg);
|
189
|
+
process.exit(1);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
}
|
193
|
+
});
|
194
|
+
}
|
package/dist/utils.js
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import { read } from '@1password/op-js';
|
11
|
+
import fetch from 'node-fetch';
|
12
|
+
const colors = {
|
13
|
+
green: '\x1b[32m',
|
14
|
+
reset: '\x1b[0m',
|
15
|
+
red: '\x1b[31m',
|
16
|
+
};
|
17
|
+
export function getAccessToken(env) {
|
18
|
+
return process.env[`Q_${env.toUpperCase()}_ACCESSTOKEN`]
|
19
|
+
? process.env[`Q_${env.toUpperCase()}_ACCESSTOKEN`]
|
20
|
+
: readSecret(`op://Q CLI/qv2-${env.toLowerCase()}/CLI_AUTH_TOKEN`);
|
21
|
+
}
|
22
|
+
export function getQServerUrl(env) {
|
23
|
+
return process.env[`Q_${env.toUpperCase()}_SERVER`]
|
24
|
+
? process.env[`Q_${env.toUpperCase()}_SERVER`]
|
25
|
+
: readSecret(`op://Q CLI/qv2-${env.toLowerCase()}/Q_SERVER_BASE_URL`);
|
26
|
+
}
|
27
|
+
export function logError(message) {
|
28
|
+
console.error(`${colors.red}${message}${colors.reset}`);
|
29
|
+
}
|
30
|
+
export function logSuccess(message) {
|
31
|
+
console.log(`${colors.green}${message}${colors.reset}`);
|
32
|
+
}
|
33
|
+
export function updateItem(qDoc, qServerUrl, accessToken) {
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
35
|
+
const retVal = {
|
36
|
+
id: undefined,
|
37
|
+
msg: '',
|
38
|
+
success: false,
|
39
|
+
};
|
40
|
+
let data;
|
41
|
+
try {
|
42
|
+
const response = yield fetch(`${qServerUrl}/item`, {
|
43
|
+
method: 'POST',
|
44
|
+
body: JSON.stringify(qDoc),
|
45
|
+
headers: {
|
46
|
+
'user-agent': 'Q Command-line Tool',
|
47
|
+
Authorization: `Bearer ${accessToken}`,
|
48
|
+
'Content-Type': 'application/json',
|
49
|
+
},
|
50
|
+
});
|
51
|
+
data = (yield response.json());
|
52
|
+
}
|
53
|
+
catch (error) {
|
54
|
+
if (error instanceof TypeError && error.message.includes('fetch failed')) {
|
55
|
+
retVal.msg =
|
56
|
+
'Network request failed: Unable to connect to the server. Please check your internet connection and server status.';
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
retVal.msg = `Failed to update item: ${error instanceof Error ? error.message : String(error)}`;
|
60
|
+
}
|
61
|
+
return retVal;
|
62
|
+
}
|
63
|
+
if (isAuthError(data)) {
|
64
|
+
retVal.msg = `Authentication error: ${data.error}`;
|
65
|
+
return retVal;
|
66
|
+
}
|
67
|
+
if (!data.success) {
|
68
|
+
retVal.msg = `Error occurred while updating item: ${data.msg}`;
|
69
|
+
return retVal;
|
70
|
+
}
|
71
|
+
retVal.success = true;
|
72
|
+
retVal.id = data.id; // If the item was created, we get the id from the response
|
73
|
+
return retVal;
|
74
|
+
});
|
75
|
+
}
|
76
|
+
// Use type predicate to check response type
|
77
|
+
function isAuthError(data) {
|
78
|
+
return 'error' in data;
|
79
|
+
}
|
80
|
+
function readSecret(reference) {
|
81
|
+
try {
|
82
|
+
return read.parse(reference);
|
83
|
+
}
|
84
|
+
catch (error) {
|
85
|
+
logError(`Error occurred while reading the secret: ${error.message}`);
|
86
|
+
process.exit(1);
|
87
|
+
}
|
88
|
+
}
|
package/package.json
CHANGED
@@ -1,47 +1,40 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nzz/q-cli",
|
3
|
-
"version": "
|
4
|
-
"
|
5
|
-
"
|
6
|
-
"main": "index.
|
7
|
-
"scripts": {
|
8
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
9
|
-
},
|
10
|
-
"repository": {
|
11
|
-
"type": "git",
|
12
|
-
"url": "git+https://github.com/nzzdev/Q-cli.git"
|
13
|
-
},
|
3
|
+
"version": "2.0.0-beta.13",
|
4
|
+
"description": "",
|
5
|
+
"type": "module",
|
6
|
+
"main": "./src/index.ts",
|
14
7
|
"bin": {
|
15
|
-
"Q": "
|
8
|
+
"Q": "./dist/index.js"
|
9
|
+
},
|
10
|
+
"files": [
|
11
|
+
"dist"
|
12
|
+
],
|
13
|
+
"scripts": {
|
14
|
+
"build": "tsc && npm run copy-assets",
|
15
|
+
"copy-assets": "cp -R src/assets dist/",
|
16
|
+
"create-custom-code-item": "tsx ./src/index.ts create-custom-code-item -e local -c ./tests/q.config.json -t 'TEST CUSTOM CODE ITEM'",
|
17
|
+
"update-item": "tsx ./src/index.ts update-item -e local -c ./tests/q.config.json",
|
18
|
+
"new-custom-code": "tsx ./src/index.ts new-custom-code -d my-custom-code-project",
|
19
|
+
"eslint": "TIMING=1 eslint --ext .svelte,.ts --config .eslintrc.cjs .",
|
20
|
+
"lint:all": "run-s -c tscheck lint svelte-check",
|
21
|
+
"tscheck": "tsc --noEmit"
|
16
22
|
},
|
17
23
|
"author": "",
|
18
24
|
"license": "MIT",
|
19
|
-
"bugs": {
|
20
|
-
"url": "https://github.com/nzzdev/Q-cli/issues"
|
21
|
-
},
|
22
|
-
"homepage": "https://github.com/nzzdev/Q-cli#readme",
|
23
25
|
"dependencies": {
|
24
|
-
"@
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"@hapi/wreck": "^17.1.0",
|
30
|
-
"ajv": "^6.12.6",
|
31
|
-
"chalk": "^4.1.1",
|
32
|
-
"commander": "^5.1.0",
|
33
|
-
"configstore": "^5.0.1",
|
34
|
-
"deepmerge": "^4.3.1",
|
35
|
-
"form-data": "^3.0.0",
|
36
|
-
"fs-extra": "^9.0.1",
|
37
|
-
"image-size": "^0.8.3",
|
38
|
-
"joi": "^17.9.1",
|
39
|
-
"node-fetch": "^2.6.9",
|
40
|
-
"nunjucks": "^3.2.2",
|
41
|
-
"promptly": "^3.2.0",
|
42
|
-
"replace-in-file": "^3.4.4"
|
26
|
+
"@1password/op-js": "^0.1.13",
|
27
|
+
"ajv": "^8.17.1",
|
28
|
+
"commander": "^13.1.0",
|
29
|
+
"form-data": "^4.0.2",
|
30
|
+
"node-fetch": "^3.3.2"
|
43
31
|
},
|
44
32
|
"devDependencies": {
|
45
|
-
"@
|
33
|
+
"@repo/types-custom-code": "workspace:^",
|
34
|
+
"@repo/types-db": "workspace:^",
|
35
|
+
"@repo/types-files": "workspace:^",
|
36
|
+
"delivery-server": "workspace:*",
|
37
|
+
"typescript": "^5.2.2",
|
38
|
+
"vitest": "^0.34.6"
|
46
39
|
}
|
47
40
|
}
|
package/.nvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
14
|
package/.travis.yml
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
dist: trusty
|
2
|
-
sudo: true
|
3
|
-
language: node_js
|
4
|
-
node_js:
|
5
|
-
- "14"
|
6
|
-
cache:
|
7
|
-
directories:
|
8
|
-
- node_modules
|
9
|
-
install:
|
10
|
-
- cd ./skeletons/tool-skeleton
|
11
|
-
- npm install
|
12
|
-
script:
|
13
|
-
- npm run build
|
14
|
-
- npm run test
|
15
|
-
notfications:
|
16
|
-
slack:
|
17
|
-
secure: cpd8v7VZ14SE1//jmd6mP+Gndo+htGzleW3E6RdnsEgz1ttAJLvIkx9HxtN2ppwwhQJTv3g4rZUGU2vXyyneRQAMak80tWK8zrhdShg0Yry47M1R24LZsPiwOUCaMLD8O26irSlWgAuwno1LUReiJLnssRDGj0CSW3o+ISp11G9Q338u9PzULhjFnD3lT4pv4u7RAPbTB6MLVjWe7eRxyXATn92HQCtKH5YdVjItbDS/HEZwZOHV+lwrQNu/w/wBqHoEDX4XCJnQdzTdUZdlXmSz/5AS10IlDw05U9P9YEO9toOMWQJunDaslpIhl7kuSkqYrWzb0X+wLVNyLVfA0vf8wQG31WHs5T+Ul2P/O9zm4NzgTCT2khfQaynUpE2Zh9p1asnUSYGN75M+GPYKOkHHdj6KKmZ2APsuggC42vyI7FrsOy0Af9wnaoKxsBfaM/XNxx0hoblRQaQ4RaUaNQ4cF1WwUg6ZOlfewjpFnDLmC+XJS8t6PSlIKgHdTsaJB9wA4xlYPU4JFGMVYGd15tRpGDz9mgQbIkKhAFsFF6PiuemTHSO17Zpij7WKFVZuyAcs6NLZieXNIUwjKrfEzaUV03mPuw2dlxIlzm2TbZrKE97SzNIND2XJ2HTfmIoJ/jL3OKwc3WdE76ypoUl9E5sqg7zRrU+wgZMBM1U4ytY=
|
package/.vscode/launch.json
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
{
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
3
|
-
// Hover to view descriptions of existing attributes.
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
5
|
-
"version": "0.2.0",
|
6
|
-
"configurations": [
|
7
|
-
{
|
8
|
-
"type": "node",
|
9
|
-
"request": "launch",
|
10
|
-
"name": "Debug server command",
|
11
|
-
"program": "${workspaceFolder}/bin/q.js",
|
12
|
-
"args": ["server"]
|
13
|
-
},
|
14
|
-
{
|
15
|
-
"type": "node",
|
16
|
-
"request": "launch",
|
17
|
-
"name": "Debug new-server command",
|
18
|
-
"program": "${workspaceFolder}/bin/q.js",
|
19
|
-
"args": ["new-server", "test-server"]
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"type": "node",
|
23
|
-
"request": "launch",
|
24
|
-
"name": "Debug new-tool command",
|
25
|
-
"program": "${workspaceFolder}/bin/q.js",
|
26
|
-
"args": ["new-tool", "test-tool"]
|
27
|
-
},
|
28
|
-
{
|
29
|
-
"type": "node",
|
30
|
-
"request": "launch",
|
31
|
-
"name": "Debug update-item command",
|
32
|
-
"program": "${workspaceFolder}/bin/q.js",
|
33
|
-
"args": ["update-item"]
|
34
|
-
}
|
35
|
-
]
|
36
|
-
}
|
package/.vscode/settings.json
DELETED
package/LICENSE
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) NZZ Management AG
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
@@ -1,68 +0,0 @@
|
|
1
|
-
const fs = require("fs-extra");
|
2
|
-
const path = require("path");
|
3
|
-
const replaceInFile = require("replace-in-file");
|
4
|
-
const chalk = require("chalk");
|
5
|
-
const errorColor = chalk.red;
|
6
|
-
const successColor = chalk.green;
|
7
|
-
const warningColor = chalk.yellow;
|
8
|
-
|
9
|
-
/**
|
10
|
-
*
|
11
|
-
* @param {string} type - Skeleton type
|
12
|
-
* @param {string} name - Name of the project
|
13
|
-
* @param {string} basedir - Base directory name to be created
|
14
|
-
* @param {Array.<{regex: RegExp, replaceWith: string}>} textReplacements
|
15
|
-
*/
|
16
|
-
module.exports = async function (type, basedir, textReplacements) {
|
17
|
-
if (fs.existsSync(basedir)) {
|
18
|
-
console.error(
|
19
|
-
errorColor(`directory ${basedir} already exists or is not writable`)
|
20
|
-
);
|
21
|
-
process.exit(1);
|
22
|
-
} else {
|
23
|
-
fs.mkdirSync(basedir);
|
24
|
-
}
|
25
|
-
|
26
|
-
try {
|
27
|
-
await fs.copySync(
|
28
|
-
path.join(__dirname, `../../skeletons/${type}-skeleton`),
|
29
|
-
basedir
|
30
|
-
);
|
31
|
-
|
32
|
-
if (textReplacements) {
|
33
|
-
for (const txtRe of textReplacements) {
|
34
|
-
await replaceText(txtRe.regex, txtRe.replaceWith, basedir);
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
console.log(successColor(`Q ${type} is now bootstrapped in ${basedir}`));
|
39
|
-
|
40
|
-
if (type === "tool" || type === "et-utils-package")
|
41
|
-
console.log(
|
42
|
-
warningColor(
|
43
|
-
"Search for 'TODO' inside the new tool/package to get started!"
|
44
|
-
)
|
45
|
-
);
|
46
|
-
} catch (error) {
|
47
|
-
console.error(
|
48
|
-
errorColor(
|
49
|
-
`An unexpected error occurred. Please check the entered information and try again. ${JSON.stringify(
|
50
|
-
error
|
51
|
-
)}`
|
52
|
-
)
|
53
|
-
);
|
54
|
-
}
|
55
|
-
};
|
56
|
-
|
57
|
-
async function replaceText(regex, replaceWith, basedir) {
|
58
|
-
const replaceOptions = {
|
59
|
-
files: `${basedir}/**`, // Replace in all files
|
60
|
-
from: regex,
|
61
|
-
to: replaceWith,
|
62
|
-
glob: {
|
63
|
-
dot: true, // Include file names starting with a dot
|
64
|
-
},
|
65
|
-
};
|
66
|
-
|
67
|
-
return await replaceInFile(replaceOptions);
|
68
|
-
}
|
@@ -1,144 +0,0 @@
|
|
1
|
-
const helpers = require("./helpers.js");
|
2
|
-
const promptly = require("promptly");
|
3
|
-
const Configstore = require("configstore");
|
4
|
-
const package = require("./../../../package.json");
|
5
|
-
const configStore = new Configstore(package.name, {});
|
6
|
-
const chalk = require("chalk");
|
7
|
-
const errorColor = chalk.red;
|
8
|
-
|
9
|
-
async function setAuthenticationConfig(environment, qServer) {
|
10
|
-
const result = await authenticate(environment, qServer);
|
11
|
-
configStore.set(`${environment}.accessToken`, result.accessToken);
|
12
|
-
configStore.set(`${environment}.cookie`, result.cookie);
|
13
|
-
}
|
14
|
-
|
15
|
-
async function setupStore(qConfig, environmentFilter, reset) {
|
16
|
-
if (reset) {
|
17
|
-
configStore.clear();
|
18
|
-
}
|
19
|
-
for (const environment of helpers.getEnvironments(
|
20
|
-
qConfig,
|
21
|
-
environmentFilter
|
22
|
-
)) {
|
23
|
-
await setupConfigFromEnvVars(environment);
|
24
|
-
|
25
|
-
if (!configStore.get(`${environment}.qServer`)) {
|
26
|
-
const qServer = await promptly.prompt(
|
27
|
-
`Enter the Q-Server url for ${environment} environment: `,
|
28
|
-
{
|
29
|
-
validator: (qServer) => {
|
30
|
-
return new URL(qServer).toString();
|
31
|
-
},
|
32
|
-
retry: true,
|
33
|
-
}
|
34
|
-
);
|
35
|
-
configStore.set(`${environment}.qServer`, qServer);
|
36
|
-
}
|
37
|
-
|
38
|
-
const qServer = configStore.get(`${environment}.qServer`);
|
39
|
-
if (!configStore.get(`${environment}.accessToken`)) {
|
40
|
-
await setAuthenticationConfig(environment, qServer);
|
41
|
-
}
|
42
|
-
|
43
|
-
const accessToken = configStore.get(`${environment}.accessToken`);
|
44
|
-
const cookie = configStore.get(`${environment}.cookie`);
|
45
|
-
const isAccessTokenValid = await helpers.checkValidityOfAccessToken(
|
46
|
-
environment,
|
47
|
-
qServer,
|
48
|
-
accessToken,
|
49
|
-
cookie
|
50
|
-
);
|
51
|
-
|
52
|
-
// Get a new access token in case its not valid anymore
|
53
|
-
if (!isAccessTokenValid) {
|
54
|
-
await setAuthenticationConfig(environment, qServer);
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
return configStore;
|
59
|
-
}
|
60
|
-
|
61
|
-
async function setupConfigFromEnvVars(environment) {
|
62
|
-
const environmentPrefix = environment.toUpperCase();
|
63
|
-
|
64
|
-
const qServer = process.env[`Q_${environmentPrefix}_SERVER`];
|
65
|
-
if (qServer) {
|
66
|
-
configStore.set(`${environment}.qServer`, qServer);
|
67
|
-
}
|
68
|
-
const accessToken = process.env[`Q_${environmentPrefix}_ACCESSTOKEN`];
|
69
|
-
const username = process.env[`Q_${environmentPrefix}_USERNAME`];
|
70
|
-
const password = process.env[`Q_${environmentPrefix}_PASSWORD`];
|
71
|
-
if (qServer && accessToken) {
|
72
|
-
configStore.set(`${environment}.accessToken`, accessToken);
|
73
|
-
} else if (qServer && username && password) {
|
74
|
-
const cookie = configStore.get(`${environment}.cookie`);
|
75
|
-
const result = await helpers.getAccessToken(
|
76
|
-
environment,
|
77
|
-
qServer,
|
78
|
-
username,
|
79
|
-
password,
|
80
|
-
cookie
|
81
|
-
);
|
82
|
-
|
83
|
-
if (!result) {
|
84
|
-
console.error(
|
85
|
-
errorColor(
|
86
|
-
`A problem occured while authenticating to the ${environment} environment using environment variables. Please check your credentials and try again.`
|
87
|
-
)
|
88
|
-
);
|
89
|
-
process.exit(1);
|
90
|
-
}
|
91
|
-
|
92
|
-
configStore.set(`${environment}.accessToken`, result.accessToken);
|
93
|
-
configStore.set(`${environment}.cookie`, result.cookie);
|
94
|
-
}
|
95
|
-
}
|
96
|
-
|
97
|
-
async function authenticate(environment, qServer) {
|
98
|
-
let username = configStore.get(`${environment}.username`);
|
99
|
-
if (!username) {
|
100
|
-
username = await promptly.prompt(
|
101
|
-
`Enter your username on ${environment} environment: `,
|
102
|
-
{ validator: (username) => username.trim() }
|
103
|
-
);
|
104
|
-
configStore.set(`${environment}.username`, username);
|
105
|
-
}
|
106
|
-
|
107
|
-
const password = await promptly.password(
|
108
|
-
`Enter your password on ${environment} environment: `,
|
109
|
-
{
|
110
|
-
validator: async (password) => password.trim(),
|
111
|
-
replace: "*",
|
112
|
-
}
|
113
|
-
);
|
114
|
-
|
115
|
-
const cookie = configStore.get(`${environment}.cookie`);
|
116
|
-
let result = await helpers.getAccessToken(
|
117
|
-
environment,
|
118
|
-
qServer,
|
119
|
-
username,
|
120
|
-
password,
|
121
|
-
cookie
|
122
|
-
);
|
123
|
-
|
124
|
-
while (!result) {
|
125
|
-
console.error(
|
126
|
-
errorColor(
|
127
|
-
"A problem occured while authenticating. Please check your credentials and try again."
|
128
|
-
)
|
129
|
-
);
|
130
|
-
|
131
|
-
result = await authenticate(environment, qServer);
|
132
|
-
|
133
|
-
if (result.accessToken) {
|
134
|
-
break;
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
138
|
-
return result;
|
139
|
-
}
|
140
|
-
|
141
|
-
module.exports = {
|
142
|
-
store: configStore,
|
143
|
-
setupStore: setupStore,
|
144
|
-
};
|