@adinsure-ops/ops-cli 5.4.2 → 5.5.0-rc1
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 +140 -2
- package/bin/run.js +2 -6
- package/lib/command.base.d.ts +7 -1
- package/lib/command.base.jira.d.ts +23 -5
- package/lib/command.base.jira.js +47 -12
- package/lib/command.base.js +37 -8
- package/lib/command.download.d.ts +11 -0
- package/lib/command.download.js +27 -0
- package/lib/commands/config/get.d.ts +1 -1
- package/lib/commands/config/list.js +1 -1
- package/lib/commands/config/set.d.ts +2 -2
- package/lib/commands/config/set.js +2 -2
- package/lib/commands/config/unset.d.ts +1 -1
- package/lib/commands/docker/update-image-version.d.ts +31 -3
- package/lib/commands/docker/update-image-version.js +112 -6
- package/lib/commands/doctor.d.ts +1 -1
- package/lib/commands/download/client.d.ts +7 -20
- package/lib/commands/download/client.js +12 -47
- package/lib/commands/download/identity-server.d.ts +7 -20
- package/lib/commands/download/identity-server.js +12 -47
- package/lib/commands/download/jmeter.d.ts +3 -3
- package/lib/commands/download/jmeter.js +9 -11
- package/lib/commands/download/keycloak-scim.d.ts +4 -4
- package/lib/commands/download/keycloak-scim.js +9 -11
- package/lib/commands/download/platform.d.ts +7 -20
- package/lib/commands/download/platform.js +12 -47
- package/lib/commands/download/scheduler.d.ts +7 -20
- package/lib/commands/download/scheduler.js +12 -47
- package/lib/commands/download/server.d.ts +7 -20
- package/lib/commands/download/server.js +12 -47
- package/lib/commands/download/signalr.d.ts +7 -20
- package/lib/commands/download/signalr.js +12 -47
- package/lib/commands/download/studio.d.ts +12 -24
- package/lib/commands/download/studio.js +14 -48
- package/lib/commands/gitlab/get-tag-pipeline.d.ts +7 -7
- package/lib/commands/gitlab/get-tag-pipeline.js +5 -5
- package/lib/commands/gitlab/next-nightly-tag.d.ts +7 -7
- package/lib/commands/gitlab/next-nightly-tag.js +6 -6
- package/lib/commands/jira/issue.d.ts +4 -4
- package/lib/commands/jira/issue.js +2 -2
- package/lib/commands/jira/labels.d.ts +8 -9
- package/lib/commands/jira/labels.js +11 -10
- package/lib/commands/log/add.d.ts +10 -5
- package/lib/commands/log/add.js +42 -13
- package/lib/commands/log/generate.d.ts +6 -6
- package/lib/commands/log/generate.js +16 -8
- package/lib/commands/log/validate.js +2 -2
- package/lib/commands/login.d.ts +25 -5
- package/lib/commands/login.js +162 -40
- package/lib/commands/login.ru.d.ts +2 -2
- package/lib/commands/login.ru.js +1 -1
- package/lib/commands/npm/check-publish.d.ts +4 -4
- package/lib/commands/npm/check-publish.js +1 -1
- package/lib/commands/npm/dependency-update.d.ts +17 -4
- package/lib/commands/npm/dependency-update.js +64 -41
- package/lib/commands/npm/publish.d.ts +5 -5
- package/lib/commands/npm/publish.js +2 -2
- package/lib/commands/nuget/dependency-update.d.ts +3 -3
- package/lib/commands/prepare-content.d.ts +3 -3
- package/lib/commands/prepare-content.js +24 -41
- package/lib/commands/sql.d.ts +17 -17
- package/lib/commands/sql.js +23 -27
- package/lib/commands/translate.d.ts +8 -8
- package/lib/commands/translate.js +10 -8
- package/lib/commands/version.d.ts +10 -10
- package/lib/commands/version.js +6 -7
- package/lib/lib/command.d.ts +5 -3
- package/lib/lib/command.js +44 -44
- package/lib/lib/config.js +1 -1
- package/lib/lib/gitlab.d.ts +3 -1
- package/lib/lib/gitlab.js +13 -7
- package/lib/lib/http.d.ts +37 -0
- package/lib/lib/http.js +278 -0
- package/lib/lib/npm.d.ts +7 -4
- package/lib/lib/npm.js +15 -6
- package/lib/lib/npmrc.js +3 -3
- package/lib/lib/yarnrc.js +3 -3
- package/lib/security/cache.js +1 -1
- package/lib/security/context.d.ts +10 -8
- package/lib/security/context.js +49 -64
- package/oclif.manifest.json +533 -532
- package/package.json +71 -62
package/README.md
CHANGED
|
@@ -8,21 +8,156 @@ Operations CLI for supporting AdInsure development processes.
|
|
|
8
8
|
|
|
9
9
|
`npm install -g @adinsure-ops/ops-cli`
|
|
10
10
|
|
|
11
|
+
## HTTP proxy support
|
|
12
|
+
|
|
13
|
+
HTTP requests use Node.js fetch with an undici proxy dispatcher.
|
|
14
|
+
Set `HTTP_PROXY` and `HTTPS_PROXY` for your proxy, and `NO_PROXY` for hosts that
|
|
15
|
+
must be reached directly. Lowercase equivalents take precedence; `ALL_PROXY`
|
|
16
|
+
is used when the protocol-specific proxy variable is not set. No
|
|
17
|
+
`NODE_USE_ENV_PROXY` flag is needed, including on Node.js 22.13.0.
|
|
18
|
+
`HTTP_PROXY` applies only to HTTP, and `HTTPS_PROXY` only to HTTPS. `NO_PROXY`
|
|
19
|
+
retains the existing matching rules: bare hosts match exactly; leading dots or
|
|
20
|
+
wildcards match suffixes. HTTP requests use proxy forwarding; HTTPS uses CONNECT
|
|
21
|
+
with certificate validation. Proxy credentials may use an empty password.
|
|
22
|
+
|
|
23
|
+
Redirects to another origin drop authentication headers, including GitLab's
|
|
24
|
+
`PRIVATE-TOKEN`, and a 307/308 redirect that would resend a request body to
|
|
25
|
+
another origin is refused. Same-origin redirects retain credentials. Debug output includes
|
|
26
|
+
the HTTP method and URL path, without headers, bodies or query strings.
|
|
27
|
+
|
|
11
28
|
## CLI development
|
|
12
29
|
|
|
13
|
-
For
|
|
30
|
+
For live-service verification of the built package, see the [native fetch manual test guide](docs/testing/manual-testing.md).
|
|
31
|
+
|
|
32
|
+
For development you will need **[Node.js](https://nodejs.org/en/)** (22.13.0+ on Node 22, or Node 24+) and **[Yarn](https://yarnpkg.com/en/)** installed.
|
|
14
33
|
|
|
15
34
|
We recommend **[Visual Studio Code](https://code.visualstudio.com/)** IDE.
|
|
16
35
|
|
|
36
|
+
Run `yarn test` for the main suite and `yarn test-unit` for the unit suite.
|
|
37
|
+
`yarn test-with-coverage` runs the main suite with the detailed reporter and writes
|
|
38
|
+
HTML, LCOV and Cobertura coverage reports to `coverage/`. Coverage uses c8 so that
|
|
39
|
+
the TypeScript modules loaded through `ts-node/esm` are included.
|
|
40
|
+
|
|
41
|
+
Mocha 12 currently uses `@types/mocha` 10.0.10, the latest published type definitions;
|
|
42
|
+
there is no matching version 12 of the types package.
|
|
43
|
+
|
|
17
44
|
To quick start development:
|
|
18
45
|
|
|
19
46
|
- Clone this repository (`git clone https://git.adacta-fintech.com/ops/ops-cli.git`)
|
|
20
47
|
- Open in VS Code
|
|
21
48
|
- Run `yarn install`
|
|
49
|
+
- Run `yarn build` to compile the CLI
|
|
22
50
|
- For easier debugging, run `yarn link`
|
|
23
51
|
|
|
24
52
|
You can run and debug commands directly from terminal by running `ops [command]` (if you `yarn link`-ed the package) or execute `.\bin\run [command]` (if you didn't link, e.g. `.\bin\run.cmd sql schema` for non-Windows environments and `.\bin\dev.cmd sql schema` for Windows environments). For debugging, you can follow oclif's documentation on how to turn on debug mode for a single command **[here](https://oclif.io/docs/debugging/)**.
|
|
25
53
|
|
|
54
|
+
The compiler uses TypeScript 6 with NodeNext module resolution and full library type checking. Use `.js` extensions for relative imports in TypeScript source files. Run `yarn build`, `yarn eslint`, `yarn test`, and `yarn pack` to validate changes; the tests continue to use ts-node 10.
|
|
55
|
+
|
|
56
|
+
TypeScript compatibility requires the scoped `**/path-scurry/lru-cache` resolution to 11.5.3. The 10.x cache declarations implement `Map` with incompatible iterator types and lack the new ESNext `Map` methods. Keep this resolution until the dependency chain provides compatible declarations; do not disable library checking.
|
|
57
|
+
|
|
58
|
+
## Dependency management and SBOM (LJADIRD-66109)
|
|
59
|
+
|
|
60
|
+
### SBOM and Dependency-Track
|
|
61
|
+
|
|
62
|
+
The `sca:dbUp` job in [.build/.gitlab-ci-sca.yml](.build/.gitlab-ci-sca.yml) generates a
|
|
63
|
+
CycloneDX SBOM with `dependency-track-cli` ([sbom.conf.yml](sbom.conf.yml)) and uploads it to
|
|
64
|
+
the Dependency-Track project `ops-cli`. It runs on version tags, protected branches and the
|
|
65
|
+
`SCA` pipeline schedule.
|
|
66
|
+
|
|
67
|
+
The SBOM contains production dependencies only. The job installs with
|
|
68
|
+
`yarn install --frozen-lockfile --production --ignore-scripts`, so devDependencies (build,
|
|
69
|
+
test and lint tooling) are not in `node_modules` and are not reported. To reproduce locally:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
yarn install --frozen-lockfile --production --ignore-scripts
|
|
73
|
+
npx @cyclonedx/cyclonedx-npm --ignore-npm-errors --output-file ops-cli-BOM.json package.json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Record the outcome of every reviewed finding in Dependency-Track (analysis state and comment),
|
|
77
|
+
for example *False positive* for withdrawn advisories or *Not affected* when the vulnerable code
|
|
78
|
+
path is not used.
|
|
79
|
+
|
|
80
|
+
### Renovate
|
|
81
|
+
|
|
82
|
+
[renovate.json](renovate.json) defines the update policy. It is prepared but not yet run by any
|
|
83
|
+
Renovate instance.
|
|
84
|
+
|
|
85
|
+
- Patch and minor updates are grouped into one merge request per week (Monday morning).
|
|
86
|
+
- Major updates are opened as separate merge requests.
|
|
87
|
+
- Production `dependencies` stay pinned to exact versions; devDependencies keep caret ranges,
|
|
88
|
+
which are only raised when the new version is outside the range.
|
|
89
|
+
- `yarn.lock` is refreshed weekly (lock file maintenance), which also updates transitive dependencies.
|
|
90
|
+
- Security updates are opened immediately.
|
|
91
|
+
- Node.js and `@types/node` majors, images from `adinsure.azurecr.io`, the `docs/` and
|
|
92
|
+
`.docs-engine/` packages and the `test/` fixtures are excluded.
|
|
93
|
+
- To preview the merge requests without GitLab access, run
|
|
94
|
+
`LOG_LEVEL=debug npx renovate --platform=local` in the repository root (read-only).
|
|
95
|
+
|
|
96
|
+
## Dependency maintenance (LJADIRD-66108)
|
|
97
|
+
|
|
98
|
+
The upgrade retains TypeScript 6.0.3, typescript-eslint 8.72.1, Mocha 12.0.3,
|
|
99
|
+
c8 12 and full library type checking. The chosen versions are:
|
|
100
|
+
|
|
101
|
+
| Package | Version |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| `@oclif/core` | 5.1.11 |
|
|
104
|
+
| `@oclif/plugin-help` | 7.0.6 |
|
|
105
|
+
| `@oclif/plugin-not-found` | 4.0.7 |
|
|
106
|
+
| `@oclif/plugin-warn-if-update-available` | 4.0.5 |
|
|
107
|
+
| `@oclif/test` | 5.0.3 |
|
|
108
|
+
| `oclif` | 6.0.15 |
|
|
109
|
+
| `minimatch` | 11.0.4 |
|
|
110
|
+
| `rimraf` | 6.1.4 |
|
|
111
|
+
| `replace-in-file` | 9.0.0 |
|
|
112
|
+
| `eslint` / `@eslint/js` | 10.14.0 / 10.0.1 |
|
|
113
|
+
| `inquirer` | 14.2.5 |
|
|
114
|
+
| `@azure/msal-node` | 7.2.0 |
|
|
115
|
+
|
|
116
|
+
Node 22.13.0 replaces the previous 22.12.0 minimum: both Inquirer 14 and
|
|
117
|
+
[ESLint 10](https://eslint.org/docs/latest/use/migrate-to-10.0.0) require it.
|
|
118
|
+
Node 23 is excluded by the shared engine range. CI tests Node 22 and 24.
|
|
119
|
+
This runtime requirement should be released as a major version; versioning and
|
|
120
|
+
publication remain handled by the existing release-tag pipeline.
|
|
121
|
+
|
|
122
|
+
Tests use `runCommand()` and `captureOutput()` following the
|
|
123
|
+
[oclif test migration guide](https://github.com/oclif/test/blob/main/MIGRATION.md).
|
|
124
|
+
The Mocha ESM root workaround is no longer needed. All 357 original main tests
|
|
125
|
+
and 2 unit tests are retained. Additional regressions cover changelog confirmation
|
|
126
|
+
(including cancellation and redirected output), replacement-file updates, and MSAL
|
|
127
|
+
token acquisition and cache compatibility (367 main tests total). Prepare-content
|
|
128
|
+
tests also exercise paths containing spaces. Mocha allows 20 seconds for source-mode
|
|
129
|
+
command discovery on CI. `yarn test-with-coverage` still verifies executed TypeScript
|
|
130
|
+
source lines. The command list, arguments, flags and top-level help are unchanged
|
|
131
|
+
against the pre-upgrade master baseline (5215289). Top-level help also matches
|
|
132
|
+
published 5.4.2 after normalizing the version. Two flag-description differences
|
|
133
|
+
from that release (`log:add --force`, `npm:dependency-update --exclude`) already
|
|
134
|
+
exist on master; this upgrade adds none.
|
|
135
|
+
|
|
136
|
+
Inquirer uses its typed prompt API and modern `select` prompt in place of `list`;
|
|
137
|
+
its bundled declarations replace `@types/inquirer`. Changelog generation uses
|
|
138
|
+
Inquirer confirmation because oclif removed `ux.confirm`. The MSAL upgrade keeps
|
|
139
|
+
the existing manually hosted authorization-code flow, which is unaffected by the
|
|
140
|
+
[built-in loopback changes in v7](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/v7-migration.md).
|
|
141
|
+
|
|
142
|
+
The Debian packaging job now runs for relevant merge requests as well as tags.
|
|
143
|
+
After installation, `node test/smoke-package.mjs` checks help, version handling,
|
|
144
|
+
a command's help from every topic, isolated config operations and a cached update
|
|
145
|
+
warning without contacting external services. It also loads every CLI command
|
|
146
|
+
implementation with the installed package's dependencies and bundled Node runtime;
|
|
147
|
+
help alone only exercises manifest metadata. `ops version` is the release
|
|
148
|
+
command and still requires a type; `ops --version` prints the CLI version.
|
|
149
|
+
|
|
150
|
+
Validation on 2026-11-05 passed build, lint, all 367 main tests, both unit tests,
|
|
151
|
+
and coverage integrity on Node 22.13.0 and 24.22.0, plus manifest generation on Node 24. Debian
|
|
152
|
+
packages built for amd64 and arm64; installed-package smoke checks passed on
|
|
153
|
+
arm64 and in the repository's amd64 Docker image as its non-root user. Real
|
|
154
|
+
terminal input, selection and confirmation prompts were also checked.
|
|
155
|
+
|
|
156
|
+
This is a maintenance upgrade, not a claim that the dependency tree is free of
|
|
157
|
+
security findings. The direct minimatch dependency is upgraded; transitive glob
|
|
158
|
+
and minimatch versions remain controlled by their upstream packages. Do not force
|
|
159
|
+
incompatible transitive major versions to suppress audit findings.
|
|
160
|
+
|
|
26
161
|
## Upgrade guilde
|
|
27
162
|
|
|
28
163
|
### Upgrade to version 5.1.0
|
|
@@ -781,9 +916,12 @@ can start with or without the `/` character but using makes the syntax more read
|
|
|
781
916
|
|
|
782
917
|
Example:
|
|
783
918
|
{js:/transformations/templateRenderer.js}
|
|
919
|
+
{js:/transformations/templateRenderer.mjs}
|
|
784
920
|
```
|
|
785
921
|
|
|
786
|
-
JavaScript transformation is supported only for files, not directories.
|
|
922
|
+
JavaScript transformation is supported only for files, not directories. Transformation modules can use
|
|
923
|
+
`.js` or `.mjs` extensions. Async transformations finish before removal operations run; failures cause
|
|
924
|
+
the command to exit with an error.
|
|
787
925
|
|
|
788
926
|
Transformation module path should be relative to `.opsprepare` file but can start with `/` character
|
|
789
927
|
for better readability. It can export multiple functions though only one can be used in single
|
package/bin/run.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import oclif from '@oclif/core';
|
|
2
|
+
import { execute } from '@oclif/core';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
oclif.run(process.argv.slice(2), import.meta.url)
|
|
7
|
-
.then(oclif.flush)
|
|
8
|
-
.catch(oclif.Errors.handle);
|
|
4
|
+
await execute({ dir: import.meta.url });
|
package/lib/command.base.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Command, Config } from '@oclif/core';
|
|
2
|
+
import HttpClient from './lib/http.js';
|
|
2
3
|
import SecurityContext from './security/context.js';
|
|
3
4
|
export default abstract class CommandBase<T extends typeof Command> extends Command {
|
|
4
5
|
protected readonly security: SecurityContext;
|
|
6
|
+
protected readonly http: HttpClient;
|
|
5
7
|
private readonly childProcess;
|
|
6
8
|
private readonly _yarnVersionRegex;
|
|
7
9
|
constructor(argv: string[], config: Config);
|
|
@@ -22,5 +24,9 @@ export default abstract class CommandBase<T extends typeof Command> extends Comm
|
|
|
22
24
|
* @returns {string[]} An array of files inside the directory with the specified filter
|
|
23
25
|
*/
|
|
24
26
|
getFilesRecursive(dir: string, baseRelativePath: string, filter: RegExp): Promise<string[]>;
|
|
25
|
-
|
|
27
|
+
protected catch(error: Error & {
|
|
28
|
+
exitCode?: number;
|
|
29
|
+
}): Promise<unknown>;
|
|
30
|
+
protected finally(error: Error | undefined): Promise<void>;
|
|
31
|
+
run(): Promise<unknown>;
|
|
26
32
|
}
|
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import JiraApi from 'jira-client';
|
|
2
1
|
import CommandBase from './command.base.js';
|
|
2
|
+
export interface JiraConnection {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
headers: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
interface JiraIssue {
|
|
7
|
+
fields: {
|
|
8
|
+
labels: string[];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export type JiraLabelOperation = {
|
|
12
|
+
add: string;
|
|
13
|
+
} | {
|
|
14
|
+
remove: string;
|
|
15
|
+
};
|
|
3
16
|
export default abstract class CommandBaseJira extends CommandBase<typeof CommandBaseJira> {
|
|
4
17
|
static flags: {
|
|
5
|
-
username: import("@oclif/core/
|
|
6
|
-
password: import("@oclif/core/
|
|
7
|
-
hostname: import("@oclif/core/
|
|
18
|
+
username: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
password: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
hostname: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
21
|
};
|
|
9
|
-
jiraInit(urlString: string, username: string, password: string):
|
|
22
|
+
protected jiraInit(urlString: string, username: string, password: string): JiraConnection;
|
|
23
|
+
protected getJiraIssue(jira: JiraConnection, issue: string): Promise<JiraIssue>;
|
|
24
|
+
protected updateJiraLabels(jira: JiraConnection, issue: string, labels: JiraLabelOperation[]): Promise<unknown>;
|
|
25
|
+
private jiraResponse;
|
|
26
|
+
private jiraErrorMessage;
|
|
10
27
|
}
|
|
28
|
+
export {};
|
package/lib/command.base.jira.js
CHANGED
|
@@ -1,23 +1,58 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
|
-
import JiraApi from 'jira-client';
|
|
4
|
-
import url from 'url';
|
|
5
3
|
import CommandBase from './command.base.js';
|
|
4
|
+
import { HttpError } from './lib/http.js';
|
|
6
5
|
class CommandBaseJira extends CommandBase {
|
|
7
6
|
jiraInit(urlString, username, password) {
|
|
7
|
+
const jiraUrl = new URL(urlString);
|
|
8
|
+
return {
|
|
9
|
+
// Preserve the existing hostname flag's treatment of ports and context paths.
|
|
10
|
+
baseUrl: `${jiraUrl.protocol}//${jiraUrl.hostname}/rest/api/2`,
|
|
11
|
+
headers: Object.assign({ Accept: 'application/json' }, (username && password ? { Authorization: `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}` } : {})),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
getJiraIssue(jira, issue) {
|
|
15
|
+
return this.jiraResponse(this.http.getJson(`${jira.baseUrl}/issue/${encodeURIComponent(issue)}`, {
|
|
16
|
+
headers: jira.headers,
|
|
17
|
+
params: { expand: '', fields: '*all', properties: '*all', fieldsByKeys: false },
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
updateJiraLabels(jira, issue, labels) {
|
|
21
|
+
return this.jiraResponse(this.http.putJson(`${jira.baseUrl}/issue/${encodeURIComponent(issue)}`, {
|
|
22
|
+
update: { labels },
|
|
23
|
+
}, { headers: jira.headers }));
|
|
24
|
+
}
|
|
25
|
+
jiraResponse(request) {
|
|
8
26
|
return __awaiter(this, void 0, void 0, function* () {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
27
|
+
try {
|
|
28
|
+
const { data } = yield request;
|
|
29
|
+
if (data && typeof data === 'object' && 'errorMessages' in data &&
|
|
30
|
+
Array.isArray(data.errorMessages) && data.errorMessages.length > 0) {
|
|
31
|
+
// jira-client serialized its application Error to an empty JSON object.
|
|
32
|
+
throw new Error('{}');
|
|
33
|
+
}
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof HttpError) {
|
|
38
|
+
// Oclif prints the name as well as the message. Keep the plain "Error:"
|
|
39
|
+
// prefix without losing the shared HttpError instance/status/data.
|
|
40
|
+
error.name = 'Error';
|
|
41
|
+
error.message = this.jiraErrorMessage(error);
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
19
45
|
});
|
|
20
46
|
}
|
|
47
|
+
jiraErrorMessage(error) {
|
|
48
|
+
if (error.status === 401) {
|
|
49
|
+
return 'Jira authentication failed (HTTP 401). Check the Jira username and password.';
|
|
50
|
+
}
|
|
51
|
+
// Keep Jira's JSON error details; never print HTML or other raw error pages.
|
|
52
|
+
if (error.data !== null && typeof error.data === 'object')
|
|
53
|
+
return JSON.stringify(error.data);
|
|
54
|
+
return `Jira request failed (HTTP ${error.status}).`;
|
|
55
|
+
}
|
|
21
56
|
}
|
|
22
57
|
CommandBaseJira.flags = {
|
|
23
58
|
username: Flags.string({
|
package/lib/command.base.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { Command, ux } from '@oclif/core';
|
|
3
|
-
import axios from 'axios';
|
|
4
3
|
import chalk from 'chalk';
|
|
5
4
|
import fs from 'fs-extra';
|
|
6
|
-
import path from 'path';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import HttpClient from './lib/http.js';
|
|
7
7
|
import SecurityContext from './security/context.js';
|
|
8
8
|
import ChildProcessCommand from './lib/command.js';
|
|
9
9
|
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
|
@@ -12,7 +12,8 @@ export default class CommandBase extends Command {
|
|
|
12
12
|
super(argv, config);
|
|
13
13
|
this.childProcess = new ChildProcessCommand();
|
|
14
14
|
this._yarnVersionRegex = /^\d+\.\d+\.\d+/;
|
|
15
|
-
this.
|
|
15
|
+
this.http = new HttpClient(message => this.debug(message));
|
|
16
|
+
this.security = new SecurityContext(this.config.configDir, this.http);
|
|
16
17
|
}
|
|
17
18
|
getGitRoot(startDir) {
|
|
18
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -102,13 +103,41 @@ export default class CommandBase extends Command {
|
|
|
102
103
|
return files;
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
catch(error) {
|
|
107
|
+
const _super = Object.create(null, {
|
|
108
|
+
catch: { get: () => super.catch }
|
|
109
|
+
});
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
// Inquirer rejects with ExitPromptError when the user presses Ctrl+C at a prompt.
|
|
112
|
+
if ((error === null || error === void 0 ? void 0 : error.name) === 'ExitPromptError') {
|
|
113
|
+
if (ux.action.running) {
|
|
114
|
+
ux.action.stop('aborted');
|
|
115
|
+
}
|
|
116
|
+
this.exit(130);
|
|
117
|
+
}
|
|
118
|
+
return _super.catch.call(this, error);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
finally(error) {
|
|
122
|
+
const _super = Object.create(null, {
|
|
123
|
+
finally: { get: () => super.finally }
|
|
124
|
+
});
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
try {
|
|
127
|
+
yield this.http.close();
|
|
128
|
+
}
|
|
129
|
+
catch (_a) {
|
|
130
|
+
// Releasing idle connections must never replace the command's own result or error.
|
|
131
|
+
this.debug('HTTP client close failed');
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
yield _super.finally.call(this, error);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
106
138
|
run() {
|
|
107
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
-
|
|
109
|
-
this.debug(`${chalk.bgCyan('DEBUG: ')} Request that was sent with your command:\n${JSON.stringify(req, null, 2)}`);
|
|
110
|
-
return req;
|
|
111
|
-
});
|
|
140
|
+
return undefined;
|
|
112
141
|
});
|
|
113
142
|
}
|
|
114
143
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import CommandBase from './command.base.js';
|
|
3
|
+
import { HttpResponse } from './lib/http.js';
|
|
4
|
+
export default abstract class DownloadCommand<T extends typeof Command> extends CommandBase<T> {
|
|
5
|
+
protected abstract readonly azureUrl: string;
|
|
6
|
+
protected abstract readonly packageName: string;
|
|
7
|
+
protected readonly extension: string;
|
|
8
|
+
private readonly gitlabUrl;
|
|
9
|
+
downloadFileFromAzure(version: string): Promise<HttpResponse<Buffer>>;
|
|
10
|
+
downloadFileFromGitLabRu(version: string): Promise<HttpResponse<Buffer>>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import CommandBase from './command.base.js';
|
|
3
|
+
export default class DownloadCommand extends CommandBase {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.extension = 'zip';
|
|
7
|
+
this.gitlabUrl = 'https://gitlabru.adacta-fintech.ru/api/v4/projects/2/packages/generic';
|
|
8
|
+
}
|
|
9
|
+
downloadFileFromAzure(version) {
|
|
10
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
11
|
+
return this.http.getBuffer(`${this.azureUrl}/${this.packageName}-${version}.${this.extension}`, {
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: 'Bearer ' + (yield this.security.getToken()),
|
|
14
|
+
'Content-Type': 'application/octet-stream',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
downloadFileFromGitLabRu(version) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const fileName = `${this.packageName}-${version}.${this.extension}`;
|
|
22
|
+
return this.http.getBuffer(`${this.gitlabUrl}/${this.packageName}/${version}/${fileName}`, {
|
|
23
|
+
headers: { 'PRIVATE-TOKEN': this.security.getTokenRu() },
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -5,7 +5,7 @@ export default class ConfigGet extends CommandBase<typeof ConfigGet> {
|
|
|
5
5
|
static usage: string;
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static args: {
|
|
8
|
-
type: import("@oclif/core/
|
|
8
|
+
type: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
9
9
|
};
|
|
10
10
|
run(): Promise<void>;
|
|
11
11
|
}
|
|
@@ -12,7 +12,7 @@ class ConfigList extends CommandBase {
|
|
|
12
12
|
const configPath = this.security.getConfigPath();
|
|
13
13
|
const config = new OpsConfig(configPath);
|
|
14
14
|
const allConfig = config.list();
|
|
15
|
-
this.log(chalk.green(
|
|
15
|
+
this.log(chalk.green('config.json:'));
|
|
16
16
|
this.log(JSON.stringify(allConfig, null, 2));
|
|
17
17
|
});
|
|
18
18
|
}
|
|
@@ -5,8 +5,8 @@ export default class ConfigSet extends CommandBase<typeof ConfigSet> {
|
|
|
5
5
|
static usage: 'config:set <type> <value>';
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static args: {
|
|
8
|
-
type: import("@oclif/core/
|
|
9
|
-
value: import("@oclif/core/
|
|
8
|
+
type: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
9
|
+
value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
10
10
|
};
|
|
11
11
|
run(): Promise<void>;
|
|
12
12
|
}
|
|
@@ -2,8 +2,8 @@ import { __awaiter } from "tslib";
|
|
|
2
2
|
import { Args } from '@oclif/core';
|
|
3
3
|
import CommandBase from '../../command.base.js';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import path from 'path';
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
7
|
import OpsConfig from '../../lib/config.js';
|
|
8
8
|
class ConfigSet extends CommandBase {
|
|
9
9
|
run() {
|
|
@@ -5,7 +5,7 @@ export default class ConfigUnset extends CommandBase<typeof ConfigUnset> {
|
|
|
5
5
|
static usage: string;
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static args: {
|
|
8
|
-
type: import("@oclif/core/
|
|
8
|
+
type: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
9
9
|
};
|
|
10
10
|
run(): Promise<void>;
|
|
11
11
|
}
|
|
@@ -4,11 +4,39 @@ export default class DockerUpdateImageVersion extends CommandBase<typeof DockerU
|
|
|
4
4
|
static usage: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static args: {
|
|
7
|
-
version: import("@oclif/core/
|
|
7
|
+
version: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
8
|
};
|
|
9
9
|
static flags: {
|
|
10
|
-
services: import("@oclif/core/
|
|
11
|
-
'file-path': import("@oclif/core/
|
|
10
|
+
services: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'file-path': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
12
|
};
|
|
13
13
|
run(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Update the image tag of a single service. Aliases, alias keys and merge keys are resolved as YAML resolves them,
|
|
16
|
+
* and only the selected service changes, also when its image or mapping is shared with other nodes.
|
|
17
|
+
*/
|
|
18
|
+
private updateImage;
|
|
19
|
+
/**
|
|
20
|
+
* Get the value of a key in a map as a node that belongs only to this map, so it can be changed without changing
|
|
21
|
+
* other nodes. An aliased or inherited value is replaced with a copy, and aliases of an anchored value get a copy.
|
|
22
|
+
*/
|
|
23
|
+
private ownValue;
|
|
24
|
+
/**
|
|
25
|
+
* Find the pair of a key in a map. Keys may be aliases, and keys that are not in the map itself
|
|
26
|
+
* are looked up in its merge keys (<<), in the order YAML 1.1 merges them.
|
|
27
|
+
*/
|
|
28
|
+
private findPair;
|
|
29
|
+
private keyValue;
|
|
30
|
+
private isMergeKey;
|
|
31
|
+
private resolveAlias;
|
|
32
|
+
/**
|
|
33
|
+
* Copy a node without its anchors, so the copy does not redefine them. Aliases in the node are replaced
|
|
34
|
+
* with copies of the nodes they resolve to where they are now, because they may resolve to another node
|
|
35
|
+
* where the copy is placed (an anchor can be redefined in between).
|
|
36
|
+
*/
|
|
37
|
+
private copy;
|
|
38
|
+
/**
|
|
39
|
+
* Replace every alias of an anchored node with a copy of it, so changing the node does not change its aliases
|
|
40
|
+
*/
|
|
41
|
+
private detachAliases;
|
|
14
42
|
}
|