@choiceopen/automation-plugin-cli 0.1.3 → 0.2.2
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 +227 -23
- package/dist/commands/auth/index.d.ts +11 -0
- package/dist/commands/auth/index.js +15 -0
- package/dist/commands/auth/login.d.ts +16 -0
- package/dist/commands/auth/login.js +117 -0
- package/dist/commands/auth/status.d.ts +11 -0
- package/dist/commands/auth/status.js +61 -0
- package/dist/commands/plugin/checksum.d.ts +13 -0
- package/dist/commands/plugin/checksum.js +22 -0
- package/dist/commands/plugin/index.d.ts +11 -0
- package/dist/commands/plugin/index.js +16 -0
- package/dist/commands/plugin/init.d.ts +31 -0
- package/dist/commands/plugin/init.js +289 -0
- package/dist/commands/plugin/pack.d.ts +13 -0
- package/dist/commands/plugin/pack.js +22 -0
- package/dist/commands/plugin/permission.d.ts +13 -0
- package/dist/commands/plugin/permission.js +22 -0
- package/dist/commands/plugin/refresh-key.d.ts +9 -0
- package/dist/commands/plugin/refresh-key.js +103 -0
- package/dist/commands/plugin/run.d.ts +13 -0
- package/dist/commands/plugin/run.js +22 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/config.d.ts +15 -0
- package/dist/utils/config.js +65 -0
- package/dist/utils/generator.d.ts +20 -0
- package/dist/utils/generator.js +68 -0
- package/dist/utils/theme.d.ts +13 -0
- package/dist/utils/theme.js +13 -0
- package/dist/utils/views.d.ts +2 -0
- package/dist/utils/views.js +8 -0
- package/oclif.manifest.json +452 -2
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
atomemo-plugin-cli
|
|
2
2
|
=================
|
|
3
3
|
|
|
4
|
-
A command-line utility for building and publishing Choiceform
|
|
4
|
+
A command-line utility for building and publishing Choiceform Atomemo Plugin.
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
[](https://oclif.io)
|
|
@@ -17,29 +17,83 @@ A command-line utility for building and publishing Choiceform Automation Plugin.
|
|
|
17
17
|
<!-- usage -->
|
|
18
18
|
```sh-session
|
|
19
19
|
$ npm install -g @choiceopen/automation-plugin-cli
|
|
20
|
-
$
|
|
20
|
+
$ atomemo COMMAND
|
|
21
21
|
running command...
|
|
22
|
-
$
|
|
23
|
-
@choiceopen/automation-plugin-cli/0.
|
|
24
|
-
$
|
|
22
|
+
$ atomemo (--version)
|
|
23
|
+
@choiceopen/automation-plugin-cli/0.2.2 darwin-arm64 node-v24.13.0
|
|
24
|
+
$ atomemo --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
|
-
$
|
|
26
|
+
$ atomemo COMMAND
|
|
27
27
|
...
|
|
28
28
|
```
|
|
29
29
|
<!-- usagestop -->
|
|
30
30
|
# Commands
|
|
31
31
|
<!-- commands -->
|
|
32
|
-
* [`
|
|
33
|
-
* [`
|
|
34
|
-
* [`
|
|
32
|
+
* [`atomemo auth login`](#atomemo-auth-login)
|
|
33
|
+
* [`atomemo auth status`](#atomemo-auth-status)
|
|
34
|
+
* [`atomemo autocomplete [SHELL]`](#atomemo-autocomplete-shell)
|
|
35
|
+
* [`atomemo help [COMMAND]`](#atomemo-help-command)
|
|
36
|
+
* [`atomemo plugin checksum [FILE]`](#atomemo-plugin-checksum-file)
|
|
37
|
+
* [`atomemo plugin init`](#atomemo-plugin-init)
|
|
38
|
+
* [`atomemo plugin pack [FILE]`](#atomemo-plugin-pack-file)
|
|
39
|
+
* [`atomemo plugin permission [FILE]`](#atomemo-plugin-permission-file)
|
|
40
|
+
* [`atomemo plugin refresh-key`](#atomemo-plugin-refresh-key)
|
|
41
|
+
* [`atomemo plugin run [FILE]`](#atomemo-plugin-run-file)
|
|
42
|
+
* [`atomemo version`](#atomemo-version)
|
|
35
43
|
|
|
36
|
-
## `
|
|
44
|
+
## `atomemo auth login`
|
|
45
|
+
|
|
46
|
+
Uses device authorization flow to login with your Choiceform account by following these steps:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
USAGE
|
|
50
|
+
$ atomemo auth login
|
|
51
|
+
|
|
52
|
+
DESCRIPTION
|
|
53
|
+
Uses device authorization flow to login with your Choiceform account by following these steps:
|
|
54
|
+
|
|
55
|
+
1. Request a validation code automatically
|
|
56
|
+
2. Show the validation code and a verification URL to the user
|
|
57
|
+
3. Open the verification URL in the user's browser and paste the verification code
|
|
58
|
+
4. Submit the validation code to complete the device authorization flow
|
|
59
|
+
|
|
60
|
+
EXAMPLES
|
|
61
|
+
Login by using device authorization flow
|
|
62
|
+
|
|
63
|
+
$ atomemo auth login
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
_See code: [src/commands/auth/login.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/auth/login.ts)_
|
|
67
|
+
|
|
68
|
+
## `atomemo auth status`
|
|
69
|
+
|
|
70
|
+
Display the current authentication status.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
USAGE
|
|
74
|
+
$ atomemo auth status
|
|
75
|
+
|
|
76
|
+
DESCRIPTION
|
|
77
|
+
Display the current authentication status.
|
|
78
|
+
|
|
79
|
+
Shows user information and session details if authenticated,
|
|
80
|
+
or prompts to login if not yet authenticated.
|
|
81
|
+
|
|
82
|
+
EXAMPLES
|
|
83
|
+
Check current authentication status
|
|
84
|
+
|
|
85
|
+
$ atomemo auth status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
_See code: [src/commands/auth/status.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/auth/status.ts)_
|
|
89
|
+
|
|
90
|
+
## `atomemo autocomplete [SHELL]`
|
|
37
91
|
|
|
38
92
|
Display autocomplete installation instructions.
|
|
39
93
|
|
|
40
94
|
```
|
|
41
95
|
USAGE
|
|
42
|
-
$
|
|
96
|
+
$ atomemo autocomplete [SHELL] [-r]
|
|
43
97
|
|
|
44
98
|
ARGUMENTS
|
|
45
99
|
[SHELL] (zsh|bash|powershell) Shell type
|
|
@@ -51,26 +105,26 @@ DESCRIPTION
|
|
|
51
105
|
Display autocomplete installation instructions.
|
|
52
106
|
|
|
53
107
|
EXAMPLES
|
|
54
|
-
$
|
|
108
|
+
$ atomemo autocomplete
|
|
55
109
|
|
|
56
|
-
$
|
|
110
|
+
$ atomemo autocomplete bash
|
|
57
111
|
|
|
58
|
-
$
|
|
112
|
+
$ atomemo autocomplete zsh
|
|
59
113
|
|
|
60
|
-
$
|
|
114
|
+
$ atomemo autocomplete powershell
|
|
61
115
|
|
|
62
|
-
$
|
|
116
|
+
$ atomemo autocomplete --refresh-cache
|
|
63
117
|
```
|
|
64
118
|
|
|
65
119
|
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v3.2.39/src/commands/autocomplete/index.ts)_
|
|
66
120
|
|
|
67
|
-
## `
|
|
121
|
+
## `atomemo help [COMMAND]`
|
|
68
122
|
|
|
69
|
-
Display help for
|
|
123
|
+
Display help for atomemo.
|
|
70
124
|
|
|
71
125
|
```
|
|
72
126
|
USAGE
|
|
73
|
-
$
|
|
127
|
+
$ atomemo help [COMMAND...] [-n]
|
|
74
128
|
|
|
75
129
|
ARGUMENTS
|
|
76
130
|
[COMMAND...] Command to show help for.
|
|
@@ -79,16 +133,166 @@ FLAGS
|
|
|
79
133
|
-n, --nested-commands Include all nested commands in the output.
|
|
80
134
|
|
|
81
135
|
DESCRIPTION
|
|
82
|
-
Display help for
|
|
136
|
+
Display help for atomemo.
|
|
83
137
|
```
|
|
84
138
|
|
|
85
139
|
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.36/src/commands/help.ts)_
|
|
86
140
|
|
|
87
|
-
## `
|
|
141
|
+
## `atomemo plugin checksum [FILE]`
|
|
142
|
+
|
|
143
|
+
describe the command here
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
USAGE
|
|
147
|
+
$ atomemo plugin checksum [FILE] [-f] [-n <value>]
|
|
148
|
+
|
|
149
|
+
ARGUMENTS
|
|
150
|
+
[FILE] file to read
|
|
151
|
+
|
|
152
|
+
FLAGS
|
|
153
|
+
-f, --force
|
|
154
|
+
-n, --name=<value> name to print
|
|
155
|
+
|
|
156
|
+
DESCRIPTION
|
|
157
|
+
describe the command here
|
|
158
|
+
|
|
159
|
+
EXAMPLES
|
|
160
|
+
$ atomemo plugin checksum
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
_See code: [src/commands/plugin/checksum.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/checksum.ts)_
|
|
164
|
+
|
|
165
|
+
## `atomemo plugin init`
|
|
166
|
+
|
|
167
|
+
Initialize a new plugin with step-by-step interactive instructions.
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
USAGE
|
|
171
|
+
$ atomemo plugin init [-i] [-n my-awesome-plugin] [-d Descriptive text...]
|
|
172
|
+
[-a John Doe] [-e john.doe@example.com] [-u <value>] [--locales en_US|zh_Hans|ja_JP...] [-l
|
|
173
|
+
elixir|python|typescript] [-t extension|llm|tool|trigger]
|
|
174
|
+
|
|
175
|
+
FLAGS
|
|
176
|
+
-a, --author=John Doe Author name
|
|
177
|
+
-d, --description=Descriptive text... Short description
|
|
178
|
+
-e, --email=john.doe@example.com Author email address
|
|
179
|
+
-i, --[no-]interactive Use interactive mode (by default)
|
|
180
|
+
-l, --language=<option> Programming language to use for plugin development
|
|
181
|
+
<options: elixir|python|typescript>
|
|
182
|
+
-n, --name=my-awesome-plugin Plugin name
|
|
183
|
+
-t, --type=<option> Plugin type
|
|
184
|
+
<options: extension|llm|tool|trigger>
|
|
185
|
+
-u, --url=<value> Repository URL
|
|
186
|
+
--locales=<option>... Provide READMEs in which languages
|
|
187
|
+
<options: en_US|zh_Hans|ja_JP>
|
|
188
|
+
|
|
189
|
+
DESCRIPTION
|
|
190
|
+
Initialize a new plugin with step-by-step interactive instructions.
|
|
191
|
+
|
|
192
|
+
Providing required flags skips interactive flow and completes initialization in one go.
|
|
193
|
+
|
|
194
|
+
EXAMPLES
|
|
195
|
+
Start with interactive initialization:
|
|
196
|
+
|
|
197
|
+
$ atomemo plugin init
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
_See code: [src/commands/plugin/init.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/init.ts)_
|
|
201
|
+
|
|
202
|
+
## `atomemo plugin pack [FILE]`
|
|
203
|
+
|
|
204
|
+
describe the command here
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
USAGE
|
|
208
|
+
$ atomemo plugin pack [FILE] [-f] [-n <value>]
|
|
209
|
+
|
|
210
|
+
ARGUMENTS
|
|
211
|
+
[FILE] file to read
|
|
212
|
+
|
|
213
|
+
FLAGS
|
|
214
|
+
-f, --force
|
|
215
|
+
-n, --name=<value> name to print
|
|
216
|
+
|
|
217
|
+
DESCRIPTION
|
|
218
|
+
describe the command here
|
|
219
|
+
|
|
220
|
+
EXAMPLES
|
|
221
|
+
$ atomemo plugin pack
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
_See code: [src/commands/plugin/pack.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/pack.ts)_
|
|
225
|
+
|
|
226
|
+
## `atomemo plugin permission [FILE]`
|
|
227
|
+
|
|
228
|
+
describe the command here
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
USAGE
|
|
232
|
+
$ atomemo plugin permission [FILE] [-f] [-n <value>]
|
|
233
|
+
|
|
234
|
+
ARGUMENTS
|
|
235
|
+
[FILE] file to read
|
|
236
|
+
|
|
237
|
+
FLAGS
|
|
238
|
+
-f, --force
|
|
239
|
+
-n, --name=<value> name to print
|
|
240
|
+
|
|
241
|
+
DESCRIPTION
|
|
242
|
+
describe the command here
|
|
243
|
+
|
|
244
|
+
EXAMPLES
|
|
245
|
+
$ atomemo plugin permission
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
_See code: [src/commands/plugin/permission.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/permission.ts)_
|
|
249
|
+
|
|
250
|
+
## `atomemo plugin refresh-key`
|
|
251
|
+
|
|
252
|
+
Refresh or create API Key for plugin debugging in development stage.
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
USAGE
|
|
256
|
+
$ atomemo plugin refresh-key
|
|
257
|
+
|
|
258
|
+
DESCRIPTION
|
|
259
|
+
Refresh or create API Key for plugin debugging in development stage.
|
|
260
|
+
|
|
261
|
+
EXAMPLES
|
|
262
|
+
$ atomemo plugin refresh-key
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
_See code: [src/commands/plugin/refresh-key.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/refresh-key.ts)_
|
|
266
|
+
|
|
267
|
+
## `atomemo plugin run [FILE]`
|
|
268
|
+
|
|
269
|
+
describe the command here
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
USAGE
|
|
273
|
+
$ atomemo plugin run [FILE] [-f] [-n <value>]
|
|
274
|
+
|
|
275
|
+
ARGUMENTS
|
|
276
|
+
[FILE] file to read
|
|
277
|
+
|
|
278
|
+
FLAGS
|
|
279
|
+
-f, --force
|
|
280
|
+
-n, --name=<value> name to print
|
|
281
|
+
|
|
282
|
+
DESCRIPTION
|
|
283
|
+
describe the command here
|
|
284
|
+
|
|
285
|
+
EXAMPLES
|
|
286
|
+
$ atomemo plugin run
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
_See code: [src/commands/plugin/run.ts](https://github.com/choice-open/automation-plugin-cli/blob/v0.2.2/src/commands/plugin/run.ts)_
|
|
290
|
+
|
|
291
|
+
## `atomemo version`
|
|
88
292
|
|
|
89
293
|
```
|
|
90
294
|
USAGE
|
|
91
|
-
$
|
|
295
|
+
$ atomemo version [--json] [--verbose]
|
|
92
296
|
|
|
93
297
|
FLAGS
|
|
94
298
|
--verbose Show additional information about the CLI.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class Auth extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: {
|
|
6
|
+
command: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}[];
|
|
9
|
+
static hidden: boolean;
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class Auth extends Command {
|
|
3
|
+
static description = "Manages your plugin via subcommands";
|
|
4
|
+
static enableJsonFlag = true;
|
|
5
|
+
static examples = [
|
|
6
|
+
{
|
|
7
|
+
command: "<%= config.bin %> help <%= command.id %> [COMMAND]",
|
|
8
|
+
description: "Check help for each individual sub-command",
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
static hidden = true;
|
|
12
|
+
async run() {
|
|
13
|
+
await this.config.runCommand("help", ["auth"]);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class AuthLogin extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: {
|
|
5
|
+
command: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}[];
|
|
8
|
+
static flags: {};
|
|
9
|
+
private pollingInterval;
|
|
10
|
+
private client_id;
|
|
11
|
+
private grant_type;
|
|
12
|
+
private endpoint;
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
private requestDeviceCode;
|
|
15
|
+
private pollForToken;
|
|
16
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import confirm from "@inquirer/confirm";
|
|
2
|
+
import { Command } from "@oclif/core";
|
|
3
|
+
import { colorize } from "@oclif/core/ux";
|
|
4
|
+
import { assert } from "es-toolkit";
|
|
5
|
+
import open from "open";
|
|
6
|
+
import { dedent } from "ts-dedent";
|
|
7
|
+
import yoctoSpinner from "yocto-spinner";
|
|
8
|
+
import * as configStore from "../../utils/config.js";
|
|
9
|
+
export default class AuthLogin extends Command {
|
|
10
|
+
static description = dedent `
|
|
11
|
+
Uses device authorization flow to login with your Choiceform account by following these steps:
|
|
12
|
+
|
|
13
|
+
1. Request a validation code automatically
|
|
14
|
+
2. Show the validation code and a verification URL to the user
|
|
15
|
+
3. Open the verification URL in the user's browser and paste the verification code
|
|
16
|
+
4. Submit the validation code to complete the device authorization flow
|
|
17
|
+
`;
|
|
18
|
+
static examples = [
|
|
19
|
+
{
|
|
20
|
+
command: "<%= config.bin %> <%= command.id %>",
|
|
21
|
+
description: "Login by using device authorization flow",
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
static flags = {};
|
|
25
|
+
pollingInterval = 5;
|
|
26
|
+
client_id = "atomemo_plugin_cli";
|
|
27
|
+
grant_type = "urn:ietf:params:oauth:grant-type:device_code";
|
|
28
|
+
async run() {
|
|
29
|
+
await this.parse(AuthLogin);
|
|
30
|
+
const config = await configStore.load();
|
|
31
|
+
assert(config.auth?.endpoint, "Auth endpoint is required");
|
|
32
|
+
this.endpoint = config.auth.endpoint;
|
|
33
|
+
const payload = await this.requestDeviceCode(this.endpoint);
|
|
34
|
+
this.log(colorize("yellowBright", "Starting device authorization flow...\n"));
|
|
35
|
+
this.log(colorize("bold", colorize("gray", "Verification URL : ")), payload.verification_uri);
|
|
36
|
+
this.log(colorize("bold", colorize("gray", "Verification Code: ")), `${payload.user_code}\n`);
|
|
37
|
+
const autoOpen = await confirm({
|
|
38
|
+
message: dedent `
|
|
39
|
+
Do you want to open the verification URL in your browser automatically?
|
|
40
|
+
If not, you can manually open the URL and paste the code.
|
|
41
|
+
`,
|
|
42
|
+
});
|
|
43
|
+
if (autoOpen) {
|
|
44
|
+
await open(payload.verification_uri_complete);
|
|
45
|
+
}
|
|
46
|
+
const spinner = yoctoSpinner({ text: "Polling for token..." }).start();
|
|
47
|
+
const result = (await this.pollForToken(payload.device_code, spinner));
|
|
48
|
+
await configStore.update({ auth: { access_token: result.access_token } });
|
|
49
|
+
const session = await fetch(`${this.endpoint}/v1/auth/get-session`, {
|
|
50
|
+
headers: {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
"User-Agent": "Choiceform (Atomemo Plugin CLI)",
|
|
53
|
+
Authorization: `Bearer ${result.access_token}`,
|
|
54
|
+
},
|
|
55
|
+
}).then((response) => response.json());
|
|
56
|
+
this.log(colorize("greenBright", dedent `
|
|
57
|
+
Welcome back, ${session.user.name} <${session.user.email}>!
|
|
58
|
+
To create a new plugin, you can use the following command:
|
|
59
|
+
\`${colorize("bold", colorize("yellowBright", "atomemo plugin init"))}\`
|
|
60
|
+
`));
|
|
61
|
+
}
|
|
62
|
+
async requestDeviceCode(endpoint) {
|
|
63
|
+
const response = await fetch(`${endpoint}/v1/auth/device/code`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
"User-Agent": "Choiceform (Atomemo Plugin CLI)",
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({ client_id: this.client_id }),
|
|
70
|
+
});
|
|
71
|
+
return (await response.json());
|
|
72
|
+
}
|
|
73
|
+
async pollForToken(device_code, spinner) {
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
const poll = async () => {
|
|
76
|
+
const response = await fetch(`${this.endpoint}/v1/auth/device/token`, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
"User-Agent": "Choiceform (Atomemo Plugin CLI)",
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify({
|
|
83
|
+
grant_type: this.grant_type,
|
|
84
|
+
client_id: this.client_id,
|
|
85
|
+
device_code,
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
const payload = (await response.json());
|
|
89
|
+
if (payload.error) {
|
|
90
|
+
switch (payload.error) {
|
|
91
|
+
case "authorization_pending":
|
|
92
|
+
setTimeout(poll, this.pollingInterval * 1000);
|
|
93
|
+
break;
|
|
94
|
+
case "slow_down":
|
|
95
|
+
this.pollingInterval += 5;
|
|
96
|
+
setTimeout(poll, this.pollingInterval * 1000);
|
|
97
|
+
break;
|
|
98
|
+
case "access_denied":
|
|
99
|
+
spinner.error("Access was denied by the user");
|
|
100
|
+
return process.exit(0);
|
|
101
|
+
case "expired_token":
|
|
102
|
+
spinner.error("The device code has expired. Please try again.");
|
|
103
|
+
return process.exit(0);
|
|
104
|
+
default:
|
|
105
|
+
spinner.error(`Error: ${payload.error_description}`);
|
|
106
|
+
return process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
spinner.success("Token acquired successfully\n");
|
|
111
|
+
resolve(payload);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
setTimeout(poll, this.pollingInterval * 1000);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class AuthStatus extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: {
|
|
5
|
+
command: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}[];
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
private fetchSession;
|
|
10
|
+
private formatDate;
|
|
11
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import { colorize } from "@oclif/core/ux";
|
|
3
|
+
import { assert } from "es-toolkit";
|
|
4
|
+
import { dedent } from "ts-dedent";
|
|
5
|
+
import * as configStore from "../../utils/config.js";
|
|
6
|
+
export default class AuthStatus extends Command {
|
|
7
|
+
static description = dedent `
|
|
8
|
+
Display the current authentication status.
|
|
9
|
+
|
|
10
|
+
Shows user information and session details if authenticated,
|
|
11
|
+
or prompts to login if not yet authenticated.
|
|
12
|
+
`;
|
|
13
|
+
static examples = [
|
|
14
|
+
{
|
|
15
|
+
command: "<%= config.bin %> <%= command.id %>",
|
|
16
|
+
description: "Check current authentication status",
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
async run() {
|
|
20
|
+
await this.parse(AuthStatus);
|
|
21
|
+
const config = await configStore.load();
|
|
22
|
+
if (!config.auth?.access_token) {
|
|
23
|
+
this.log(colorize("yellow", "Your device has not been authenticated yet. Please execute `atomemo auth login`."));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
assert(config.auth?.endpoint, "Auth endpoint is required");
|
|
27
|
+
try {
|
|
28
|
+
const session = await this.fetchSession(config.auth.endpoint, config.auth.access_token);
|
|
29
|
+
this.log(colorize("greenBright", "✓ Authenticated\n"));
|
|
30
|
+
this.log(colorize("bold", colorize("gray", "Name : ")), session.user.name);
|
|
31
|
+
this.log(colorize("bold", colorize("gray", "Email : ")), session.user.email);
|
|
32
|
+
this.log(colorize("bold", colorize("gray", "Updated : ")), this.formatDate(session.session.updatedAt));
|
|
33
|
+
this.log(colorize("bold", colorize("gray", "Expires : ")), this.formatDate(session.session.expiresAt));
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
37
|
+
this.log(colorize("red", `✗ Failed to fetch session: ${message}`));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async fetchSession(endpoint, accessToken) {
|
|
42
|
+
const response = await fetch(`${endpoint}/v1/auth/get-session`, {
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
"User-Agent": "Choiceform (Atomemo Plugin CLI)",
|
|
46
|
+
Authorization: `Bearer ${accessToken}`,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
if (response.status === 401) {
|
|
51
|
+
throw new Error("Access token is invalid or expired, please login again");
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
54
|
+
}
|
|
55
|
+
return (await response.json());
|
|
56
|
+
}
|
|
57
|
+
formatDate(isoDate) {
|
|
58
|
+
const date = new Date(isoDate);
|
|
59
|
+
return date.toLocaleString();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class PluginChecksum extends Command {
|
|
3
|
+
static args: {
|
|
4
|
+
file: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Args, Command, Flags } from "@oclif/core";
|
|
2
|
+
export default class PluginChecksum extends Command {
|
|
3
|
+
static args = {
|
|
4
|
+
file: Args.string({ description: "file to read" }),
|
|
5
|
+
};
|
|
6
|
+
static description = "describe the command here";
|
|
7
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
8
|
+
static flags = {
|
|
9
|
+
// flag with no value (-f, --force)
|
|
10
|
+
force: Flags.boolean({ char: "f" }),
|
|
11
|
+
// flag with a value (-n, --name=VALUE)
|
|
12
|
+
name: Flags.string({ char: "n", description: "name to print" }),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
const { args, flags } = await this.parse(PluginChecksum);
|
|
16
|
+
const name = flags.name ?? "world";
|
|
17
|
+
this.log(`hello ${name} from /Users/nightire/Code/github.com/choice-open/automation-plugin-cli/src/commands/plugin/checksum.ts`);
|
|
18
|
+
if (args.file && flags.force) {
|
|
19
|
+
this.log(`you input --force and --file: ${args.file}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class Plugin extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: {
|
|
6
|
+
command: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}[];
|
|
9
|
+
static hidden: boolean;
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class Plugin extends Command {
|
|
3
|
+
static description = "Manages your plugin via subcommands";
|
|
4
|
+
static enableJsonFlag = true;
|
|
5
|
+
static examples = [
|
|
6
|
+
{
|
|
7
|
+
command: "<%= config.bin %> help <%= command.id %> [COMMAND]",
|
|
8
|
+
description: "Check help for each individual sub-command",
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
static hidden = true;
|
|
12
|
+
async run() {
|
|
13
|
+
await this.parse(Plugin);
|
|
14
|
+
await this.config.runCommand("help", ["plugin"]);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class PluginInit extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: {
|
|
5
|
+
command: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}[];
|
|
8
|
+
static flags: {
|
|
9
|
+
interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
description: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
author: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
email: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
url: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
locales: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
language: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
private nameIsValid;
|
|
21
|
+
private reconcileInteractiveFlag;
|
|
22
|
+
private runInteractiveMode;
|
|
23
|
+
private collectName;
|
|
24
|
+
private collectDescription;
|
|
25
|
+
private collectAuthor;
|
|
26
|
+
private collectEmail;
|
|
27
|
+
private collectURL;
|
|
28
|
+
private collectLocales;
|
|
29
|
+
private collectLanguage;
|
|
30
|
+
private collectType;
|
|
31
|
+
}
|