@lightward/mechanic-cli 0.1.12 → 0.1.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 +26 -0
- package/dist/base-command.js +1 -1
- package/dist/commands/globals/delete.d.ts +1 -0
- package/dist/commands/globals/delete.d.ts.map +1 -1
- package/dist/commands/globals/delete.js +4 -1
- package/dist/commands/globals/pull.d.ts +1 -0
- package/dist/commands/globals/pull.d.ts.map +1 -1
- package/dist/commands/globals/pull.js +6 -1
- package/dist/commands/globals/push.d.ts +1 -0
- package/dist/commands/globals/push.d.ts.map +1 -1
- package/dist/commands/globals/push.js +7 -1
- package/dist/commands/globals/set.d.ts +1 -0
- package/dist/commands/globals/set.d.ts.map +1 -1
- package/dist/commands/globals/set.js +6 -1
- package/dist/commands/secrets/delete.d.ts +1 -0
- package/dist/commands/secrets/delete.d.ts.map +1 -1
- package/dist/commands/secrets/delete.js +4 -1
- package/dist/commands/secrets/set.d.ts +1 -0
- package/dist/commands/secrets/set.d.ts.map +1 -1
- package/dist/commands/secrets/set.js +8 -2
- package/dist/commands/version.d.ts +14 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +69 -0
- package/dist/update-check.d.ts +3 -0
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,12 @@ npm install -g @lightward/mechanic-cli
|
|
|
40
40
|
|
|
41
41
|
In interactive terminals, Mechanic occasionally checks npm and prints the update command when a newer CLI is available.
|
|
42
42
|
|
|
43
|
+
To check your installed CLI version against the latest published version:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mechanic version
|
|
47
|
+
```
|
|
48
|
+
|
|
43
49
|
## Quick Start
|
|
44
50
|
|
|
45
51
|
Create an API token in Mechanic:
|
|
@@ -121,6 +127,7 @@ Use JSON output for automation instead of parsing tables or colored text.
|
|
|
121
127
|
```bash
|
|
122
128
|
mechanic init --shop example.myshopify.com [--token <token>] [--api-base-url <url>] [--app-url <url>] [--force]
|
|
123
129
|
mechanic help [command]
|
|
130
|
+
mechanic version [--json]
|
|
124
131
|
mechanic doctor
|
|
125
132
|
mechanic auth login [--token <token>]
|
|
126
133
|
mechanic auth logout
|
|
@@ -489,6 +496,15 @@ new globals but refuses to overwrite existing remote globals whose values differ
|
|
|
489
496
|
use `mechanic globals push --dry-run` to review the plan, then pass `--force`
|
|
490
497
|
when the local file should replace those remote values.
|
|
491
498
|
|
|
499
|
+
For one-off global changes:
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
mechanic globals list
|
|
503
|
+
mechanic globals set warehouse_id --json '"main"'
|
|
504
|
+
mechanic globals set shipping_rules --json '{"regions":["CA","US"]}'
|
|
505
|
+
mechanic globals delete warehouse_id --force
|
|
506
|
+
```
|
|
507
|
+
|
|
492
508
|
Shop secrets are write-only string values. The CLI never creates a secrets file,
|
|
493
509
|
and task pull, preview, and publish never write secret values into task JSON.
|
|
494
510
|
Use `mechanic secrets set <key> --from-stdin` or `--value-env <env>` for
|
|
@@ -497,6 +513,16 @@ trailing newlines. Secret values are not printed after save. Replacing or
|
|
|
497
513
|
deleting a secret can break tasks until they are updated, so existing secret
|
|
498
514
|
values and secret deletes require `--force`.
|
|
499
515
|
|
|
516
|
+
For one-off secret changes:
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
mechanic secrets list
|
|
520
|
+
mechanic secrets set api_token
|
|
521
|
+
printf %s "$API_TOKEN" | mechanic secrets set api_token --from-stdin
|
|
522
|
+
mechanic secrets set api_token --value-env API_TOKEN --force
|
|
523
|
+
mechanic secrets delete api_token --force
|
|
524
|
+
```
|
|
525
|
+
|
|
500
526
|
## Task Sync API
|
|
501
527
|
|
|
502
528
|
This package targets Mechanic's v1 task sync API. The CLI is the recommended
|
package/dist/base-command.js
CHANGED
|
@@ -9,7 +9,7 @@ import { getUpdateNotice, shouldCheckForUpdates } from "./update-check.js";
|
|
|
9
9
|
export class BaseCommand extends Command {
|
|
10
10
|
async finally(error) {
|
|
11
11
|
await super.finally(error);
|
|
12
|
-
if (error || !shouldCheckForUpdates(this.argv)) {
|
|
12
|
+
if (error || this.id === "version" || !shouldCheckForUpdates(this.argv)) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
const notice = await getUpdateNotice();
|
|
@@ -2,6 +2,7 @@ import { BaseCommand } from "../../base-command.js";
|
|
|
2
2
|
export default class GlobalsDelete extends BaseCommand {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
5
6
|
static args: {
|
|
6
7
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAA2C;
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAA2C;IACtE,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAc3B"}
|
|
@@ -5,13 +5,16 @@ import { CliError } from "../../errors.js";
|
|
|
5
5
|
export default class GlobalsDelete extends BaseCommand {
|
|
6
6
|
static summary = "Delete one shop global.";
|
|
7
7
|
static description = "Delete one visible shop-level global.";
|
|
8
|
+
static examples = [
|
|
9
|
+
"$ mechanic globals delete warehouse_id --force",
|
|
10
|
+
];
|
|
8
11
|
static args = {
|
|
9
12
|
key: Args.string({ required: true, description: "Global key, using lower snake-case." }),
|
|
10
13
|
};
|
|
11
14
|
static flags = {
|
|
12
15
|
force: Flags.boolean({
|
|
13
16
|
char: "f",
|
|
14
|
-
description: "
|
|
17
|
+
description: "Confirm deleting this global.",
|
|
15
18
|
}),
|
|
16
19
|
};
|
|
17
20
|
async run() {
|
|
@@ -2,6 +2,7 @@ import { BaseCommand } from "../../base-command.js";
|
|
|
2
2
|
export default class GlobalsPull extends BaseCommand {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
5
6
|
static flags: {
|
|
6
7
|
out: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
8
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/pull.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAAmD;IAC1E,OAAgB,WAAW,SAAiE;
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/pull.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAAmD;IAC1E,OAAgB,WAAW,SAAiE;IAC5F,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;MAQnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA0B3B"}
|
|
@@ -8,9 +8,14 @@ const DEFAULT_GLOBALS_FILE = "mechanic.globals.json";
|
|
|
8
8
|
export default class GlobalsPull extends BaseCommand {
|
|
9
9
|
static summary = "Pull shop globals into mechanic.globals.json.";
|
|
10
10
|
static description = "Pull visible shop-level globals into a repo-safe JSON file.";
|
|
11
|
+
static examples = [
|
|
12
|
+
"$ mechanic globals pull",
|
|
13
|
+
"$ mechanic globals pull --out mechanic.globals.json",
|
|
14
|
+
"$ mechanic globals pull --force",
|
|
15
|
+
];
|
|
11
16
|
static flags = {
|
|
12
17
|
out: Flags.string({
|
|
13
|
-
description: "File path to write.",
|
|
18
|
+
description: "File path to write. Defaults to repo-safe mechanic.globals.json.",
|
|
14
19
|
default: DEFAULT_GLOBALS_FILE,
|
|
15
20
|
}),
|
|
16
21
|
force: Flags.boolean({
|
|
@@ -2,6 +2,7 @@ import { BaseCommand } from "../../base-command.js";
|
|
|
2
2
|
export default class GlobalsPush extends BaseCommand {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
5
6
|
static flags: {
|
|
6
7
|
file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
8
|
"dry-run": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/push.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAgBpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAA8C;IACrE,OAAgB,WAAW,SAAmI;
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/push.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAgBpD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW;IAClD,OAAgB,OAAO,SAA8C;IACrE,OAAgB,WAAW,SAAmI;IAC9J,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,KAAK;;;;MAYnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA6D3B"}
|
|
@@ -15,9 +15,15 @@ function ensurePlainObject(value, source) {
|
|
|
15
15
|
export default class GlobalsPush extends BaseCommand {
|
|
16
16
|
static summary = "Push mechanic.globals.json to this shop.";
|
|
17
17
|
static description = "Push visible shop-level globals from a repo-safe JSON file. This updates listed keys and does not delete missing remote keys.";
|
|
18
|
+
static examples = [
|
|
19
|
+
"$ mechanic globals push --dry-run",
|
|
20
|
+
"$ mechanic globals push",
|
|
21
|
+
"$ mechanic globals push --force",
|
|
22
|
+
"$ mechanic globals push --file mechanic.globals.json --dry-run",
|
|
23
|
+
];
|
|
18
24
|
static flags = {
|
|
19
25
|
file: Flags.string({
|
|
20
|
-
description: "Globals JSON file to read.",
|
|
26
|
+
description: "Globals JSON file to read. Missing remote keys are not deleted.",
|
|
21
27
|
default: DEFAULT_GLOBALS_FILE,
|
|
22
28
|
}),
|
|
23
29
|
"dry-run": Flags.boolean({
|
|
@@ -2,6 +2,7 @@ import { BaseCommand } from "../../base-command.js";
|
|
|
2
2
|
export default class GlobalsSet extends BaseCommand {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
5
6
|
static args: {
|
|
6
7
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAA6C;
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/globals/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAA6C;IACxE,OAAgB,QAAQ,WAItB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAU3B"}
|
|
@@ -5,13 +5,18 @@ import { parseJson } from "../../json.js";
|
|
|
5
5
|
export default class GlobalsSet extends BaseCommand {
|
|
6
6
|
static summary = "Set one shop global.";
|
|
7
7
|
static description = "Set one visible shop-level JSON global.";
|
|
8
|
+
static examples = [
|
|
9
|
+
"$ mechanic globals set warehouse_id --json '\"main\"'",
|
|
10
|
+
"$ mechanic globals set shipping_rules --json '{\"regions\":[\"CA\",\"US\"]}'",
|
|
11
|
+
"$ mechanic globals set reorder_threshold --json 5",
|
|
12
|
+
];
|
|
8
13
|
static args = {
|
|
9
14
|
key: Args.string({ required: true, description: "Global key, using lower snake-case." }),
|
|
10
15
|
};
|
|
11
16
|
static flags = {
|
|
12
17
|
json: Flags.string({
|
|
13
18
|
required: true,
|
|
14
|
-
description: "JSON value
|
|
19
|
+
description: "Any valid JSON value. For strings, include JSON quotes, e.g. --json '\"main\"'.",
|
|
15
20
|
}),
|
|
16
21
|
};
|
|
17
22
|
async run() {
|
|
@@ -2,6 +2,7 @@ import { BaseCommand } from "../../base-command.js";
|
|
|
2
2
|
export default class SecretsDelete extends BaseCommand {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static description: string;
|
|
5
|
+
static examples: string[];
|
|
5
6
|
static args: {
|
|
6
7
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAAqF;
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/delete.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;IACpD,OAAgB,OAAO,SAA6B;IACpD,OAAgB,WAAW,SAAqF;IAChH,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;MAKnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAc3B"}
|
|
@@ -5,13 +5,16 @@ import { CliError } from "../../errors.js";
|
|
|
5
5
|
export default class SecretsDelete extends BaseCommand {
|
|
6
6
|
static summary = "Delete one shop secret.";
|
|
7
7
|
static description = "Delete one write-only shop-level secret. Affected tasks may fail until updated.";
|
|
8
|
+
static examples = [
|
|
9
|
+
"$ mechanic secrets delete api_token --force",
|
|
10
|
+
];
|
|
8
11
|
static args = {
|
|
9
12
|
key: Args.string({ required: true, description: "Secret key, using lower snake-case." }),
|
|
10
13
|
};
|
|
11
14
|
static flags = {
|
|
12
15
|
force: Flags.boolean({
|
|
13
16
|
char: "f",
|
|
14
|
-
description: "
|
|
17
|
+
description: "Confirm deleting this secret.",
|
|
15
18
|
}),
|
|
16
19
|
};
|
|
17
20
|
async run() {
|
|
@@ -7,6 +7,7 @@ export declare function readSecretValueFromEnv(envName: string, env?: NodeJS.Pro
|
|
|
7
7
|
export default class SecretsSet extends BaseCommand {
|
|
8
8
|
static summary: string;
|
|
9
9
|
static description: string;
|
|
10
|
+
static examples: string[];
|
|
10
11
|
static args: {
|
|
11
12
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
13
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,KAAK,WAAW,GAAG,OAAO,KAAK,CAAC;AAEhC,wBAAgB,SAAS,CAAC,KAAK,GAAE,WAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBrE;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,GAAE,WAAmB,GACzB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAYR;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAAwE;
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../src/commands/secrets/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,KAAK,WAAW,GAAG,OAAO,KAAK,CAAC;AAEhC,wBAAgB,SAAS,CAAC,KAAK,GAAE,WAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBrE;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,GAAE,WAAmB,GACzB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAYR;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,OAAgB,OAAO,SAA0B;IACjD,OAAgB,WAAW,SAAwE;IACnG,OAAgB,QAAQ,WAKtB;IAEF,OAAgB,IAAI;;MAElB;IAEF,OAAgB,KAAK;;;;MAanB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBpB,WAAW,CAAC,KAAK,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAsB5F"}
|
|
@@ -40,12 +40,18 @@ export function readSecretValueFromEnv(envName, env = process.env) {
|
|
|
40
40
|
export default class SecretsSet extends BaseCommand {
|
|
41
41
|
static summary = "Set one shop secret.";
|
|
42
42
|
static description = "Set one write-only shop secret. The secret value is never printed.";
|
|
43
|
+
static examples = [
|
|
44
|
+
"$ mechanic secrets set api_token",
|
|
45
|
+
"$ printf %s \"$API_TOKEN\" | mechanic secrets set api_token --from-stdin",
|
|
46
|
+
"$ mechanic secrets set api_token --value-env API_TOKEN",
|
|
47
|
+
"$ mechanic secrets set api_token --value-env API_TOKEN --force",
|
|
48
|
+
];
|
|
43
49
|
static args = {
|
|
44
50
|
key: Args.string({ required: true, description: "Secret key, using lower snake-case." }),
|
|
45
51
|
};
|
|
46
52
|
static flags = {
|
|
47
53
|
"from-stdin": Flags.boolean({
|
|
48
|
-
description: "Read the secret value from stdin.",
|
|
54
|
+
description: "Read the secret value from stdin. Preserves exact input, including trailing newlines.",
|
|
49
55
|
exclusive: ["value-env"],
|
|
50
56
|
}),
|
|
51
57
|
force: Flags.boolean({
|
|
@@ -53,7 +59,7 @@ export default class SecretsSet extends BaseCommand {
|
|
|
53
59
|
description: "Replace the value when this secret key already exists.",
|
|
54
60
|
}),
|
|
55
61
|
"value-env": Flags.string({
|
|
56
|
-
description: "Read the secret value from the named environment variable.",
|
|
62
|
+
description: "Read the secret value from the named environment variable. Empty values are rejected.",
|
|
57
63
|
exclusive: ["from-stdin"],
|
|
58
64
|
}),
|
|
59
65
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
type VersionStatus = "ahead_of_latest" | "unknown" | "update_available" | "up_to_date";
|
|
3
|
+
export default class VersionCommand extends BaseCommand {
|
|
4
|
+
static summary: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: {
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
statusLabel(status: VersionStatus): string;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQjD,KAAK,aAAa,GAAG,iBAAiB,GAAG,SAAS,GAAG,kBAAkB,GAAG,YAAY,CAAC;AAkBvF,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,WAAW;IACrD,OAAgB,OAAO,SAAsD;IAC7E,OAAgB,WAAW,SAAwF;IACnH,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;MAInB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC1B,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;CAY3C"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../base-command.js";
|
|
3
|
+
import { CURRENT_VERSION, PACKAGE_NAME, fetchLatestPackageVersion, isVersionNewer, } from "../update-check.js";
|
|
4
|
+
function statusFor(latestVersion) {
|
|
5
|
+
if (!latestVersion) {
|
|
6
|
+
return "unknown";
|
|
7
|
+
}
|
|
8
|
+
if (isVersionNewer(latestVersion, CURRENT_VERSION)) {
|
|
9
|
+
return "update_available";
|
|
10
|
+
}
|
|
11
|
+
if (isVersionNewer(CURRENT_VERSION, latestVersion)) {
|
|
12
|
+
return "ahead_of_latest";
|
|
13
|
+
}
|
|
14
|
+
return "up_to_date";
|
|
15
|
+
}
|
|
16
|
+
export default class VersionCommand extends BaseCommand {
|
|
17
|
+
static summary = "Show installed and latest Mechanic CLI versions.";
|
|
18
|
+
static description = "Check the installed Mechanic CLI version against the latest published npm version.";
|
|
19
|
+
static examples = [
|
|
20
|
+
"$ mechanic version",
|
|
21
|
+
"$ mechanic version --json",
|
|
22
|
+
];
|
|
23
|
+
static flags = {
|
|
24
|
+
json: Flags.boolean({
|
|
25
|
+
description: "Print version status as JSON for agents or scripts.",
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
async run() {
|
|
29
|
+
const { flags } = await this.parse(VersionCommand);
|
|
30
|
+
const latestVersion = await fetchLatestPackageVersion();
|
|
31
|
+
const status = statusFor(latestVersion);
|
|
32
|
+
if (flags.json) {
|
|
33
|
+
this.outputJson({
|
|
34
|
+
package_name: PACKAGE_NAME,
|
|
35
|
+
installed_version: CURRENT_VERSION,
|
|
36
|
+
latest_version: latestVersion,
|
|
37
|
+
status,
|
|
38
|
+
update_available: status === "update_available",
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.table([
|
|
43
|
+
["Version", "Value"],
|
|
44
|
+
["Installed", CURRENT_VERSION],
|
|
45
|
+
["Latest", latestVersion || "unknown"],
|
|
46
|
+
["Status", this.statusLabel(status)],
|
|
47
|
+
]);
|
|
48
|
+
if (status === "update_available") {
|
|
49
|
+
this.log("");
|
|
50
|
+
this.log(`Update with: ${this.taskName("npm install -g @lightward/mechanic-cli")}`);
|
|
51
|
+
}
|
|
52
|
+
else if (status === "unknown") {
|
|
53
|
+
this.log("");
|
|
54
|
+
this.log(this.muted("Could not check the npm registry. Try again when your network is available."));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
statusLabel(status) {
|
|
58
|
+
switch (status) {
|
|
59
|
+
case "ahead_of_latest":
|
|
60
|
+
return this.color("yellow", "installed version is newer than latest");
|
|
61
|
+
case "unknown":
|
|
62
|
+
return this.color("yellow", "unable to check latest version");
|
|
63
|
+
case "update_available":
|
|
64
|
+
return this.color("yellow", "update available");
|
|
65
|
+
case "up_to_date":
|
|
66
|
+
return this.success("up to date");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
package/dist/update-check.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const PACKAGE_NAME: string;
|
|
2
|
+
export declare const CURRENT_VERSION: string;
|
|
1
3
|
export type UpdateNotice = {
|
|
2
4
|
currentVersion: string;
|
|
3
5
|
latestVersion: string;
|
|
@@ -9,6 +11,7 @@ export type UpdateNoticeOptions = {
|
|
|
9
11
|
now?: Date;
|
|
10
12
|
};
|
|
11
13
|
export declare function isVersionNewer(candidate: string, current: string): boolean;
|
|
14
|
+
export declare function fetchLatestPackageVersion(): Promise<string | null>;
|
|
12
15
|
export declare function getUpdateNotice(options?: UpdateNoticeOptions): Promise<UpdateNotice | null>;
|
|
13
16
|
export declare function shouldCheckForUpdates(argv?: string[], env?: NodeJS.ProcessEnv, isTty?: boolean): boolean;
|
|
14
17
|
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,QAAgD,CAAC;AAC1E,eAAO,MAAM,eAAe,QAAiC,CAAC;AAiB9D,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AAsBF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CA+B1E;AAYD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqBxE;AAUD,wBAAsB,eAAe,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA8CrG;AAED,wBAAgB,qBAAqB,CACnC,IAAI,WAAwB,EAC5B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,KAAK,UAAgC,GACpC,OAAO,CAmBT"}
|
package/dist/update-check.js
CHANGED
|
@@ -2,8 +2,8 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { appConfigPath, readJson, writeJson } from "./fs.js";
|
|
3
3
|
const require = createRequire(import.meta.url);
|
|
4
4
|
const packageJson = require("../package.json");
|
|
5
|
-
const PACKAGE_NAME = packageJson.name || "@lightward/mechanic-cli";
|
|
6
|
-
const CURRENT_VERSION = packageJson.version || "0.0.0";
|
|
5
|
+
export const PACKAGE_NAME = packageJson.name || "@lightward/mechanic-cli";
|
|
6
|
+
export const CURRENT_VERSION = packageJson.version || "0.0.0";
|
|
7
7
|
const NPM_LATEST_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME).replace("%40", "@")}/latest`;
|
|
8
8
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
9
9
|
const NOTIFY_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
@@ -55,7 +55,7 @@ function millisecondsSince(value, now) {
|
|
|
55
55
|
const parsed = Date.parse(value);
|
|
56
56
|
return Number.isFinite(parsed) ? now.getTime() - parsed : Number.POSITIVE_INFINITY;
|
|
57
57
|
}
|
|
58
|
-
async function fetchLatestPackageVersion() {
|
|
58
|
+
export async function fetchLatestPackageVersion() {
|
|
59
59
|
const controller = new AbortController();
|
|
60
60
|
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
61
61
|
try {
|
|
@@ -132,5 +132,7 @@ export function shouldCheckForUpdates(argv = process.argv.slice(2), env = proces
|
|
|
132
132
|
|| env.MECHANIC_UPDATE_CHECK === "0") {
|
|
133
133
|
return false;
|
|
134
134
|
}
|
|
135
|
-
return !argv.some((arg) => arg === "
|
|
135
|
+
return !argv.some((arg) => (arg === "version"
|
|
136
|
+
|| arg === "--json"
|
|
137
|
+
|| arg.startsWith("--json=")));
|
|
136
138
|
}
|