@nocobase/app-cli-client 0.0.0-stage → 0.1.0-beta.1

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.
Files changed (178) hide show
  1. package/README.md +24 -2
  2. package/dist/brand.d.ts +52 -0
  3. package/dist/brand.d.ts.map +1 -0
  4. package/dist/brand.js +61 -0
  5. package/dist/brand.js.map +1 -0
  6. package/dist/commands.d.ts +9 -0
  7. package/dist/commands.d.ts.map +1 -0
  8. package/dist/commands.js +30 -0
  9. package/dist/commands.js.map +1 -0
  10. package/dist/completion.d.ts +13 -0
  11. package/dist/completion.d.ts.map +1 -0
  12. package/dist/completion.js +157 -0
  13. package/dist/completion.js.map +1 -0
  14. package/dist/config.d.ts +100 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +43 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/docs.d.ts +9 -0
  19. package/dist/docs.d.ts.map +1 -0
  20. package/dist/docs.js +146 -0
  21. package/dist/docs.js.map +1 -0
  22. package/dist/dynamic/execute.d.ts +24 -0
  23. package/dist/dynamic/execute.d.ts.map +1 -0
  24. package/dist/dynamic/execute.js +125 -0
  25. package/dist/dynamic/execute.js.map +1 -0
  26. package/dist/dynamic/files.d.ts +21 -0
  27. package/dist/dynamic/files.d.ts.map +1 -0
  28. package/dist/dynamic/files.js +79 -0
  29. package/dist/dynamic/files.js.map +1 -0
  30. package/dist/dynamic/help.d.ts +6 -0
  31. package/dist/dynamic/help.d.ts.map +1 -0
  32. package/dist/dynamic/help.js +42 -0
  33. package/dist/dynamic/help.js.map +1 -0
  34. package/dist/dynamic/index.d.ts +34 -0
  35. package/dist/dynamic/index.d.ts.map +1 -0
  36. package/dist/dynamic/index.js +197 -0
  37. package/dist/dynamic/index.js.map +1 -0
  38. package/dist/dynamic/manifest.d.ts +21 -0
  39. package/dist/dynamic/manifest.d.ts.map +1 -0
  40. package/dist/dynamic/manifest.js +175 -0
  41. package/dist/dynamic/manifest.js.map +1 -0
  42. package/dist/dynamic/output.d.ts +14 -0
  43. package/dist/dynamic/output.d.ts.map +1 -0
  44. package/dist/dynamic/output.js +103 -0
  45. package/dist/dynamic/output.js.map +1 -0
  46. package/dist/dynamic/parse.d.ts +3 -0
  47. package/dist/dynamic/parse.d.ts.map +1 -0
  48. package/dist/dynamic/parse.js +13 -0
  49. package/dist/dynamic/parse.js.map +1 -0
  50. package/dist/dynamic/rest.d.ts +29 -0
  51. package/dist/dynamic/rest.d.ts.map +1 -0
  52. package/dist/dynamic/rest.js +212 -0
  53. package/dist/dynamic/rest.js.map +1 -0
  54. package/dist/dynamic/session.d.ts +20 -0
  55. package/dist/dynamic/session.d.ts.map +1 -0
  56. package/dist/dynamic/session.js +70 -0
  57. package/dist/dynamic/session.js.map +1 -0
  58. package/dist/dynamic/ticket.d.ts +13 -0
  59. package/dist/dynamic/ticket.d.ts.map +1 -0
  60. package/dist/dynamic/ticket.js +40 -0
  61. package/dist/dynamic/ticket.js.map +1 -0
  62. package/dist/hooks/command-not-found.d.ts +4 -0
  63. package/dist/hooks/command-not-found.d.ts.map +1 -0
  64. package/dist/hooks/command-not-found.js +6 -0
  65. package/dist/hooks/command-not-found.js.map +1 -0
  66. package/dist/index.d.ts +8 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +14 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/install.d.ts +72 -0
  71. package/dist/install.d.ts.map +1 -0
  72. package/dist/install.js +148 -0
  73. package/dist/install.js.map +1 -0
  74. package/dist/lib/command.d.ts +35 -0
  75. package/dist/lib/command.d.ts.map +1 -0
  76. package/dist/lib/command.js +97 -0
  77. package/dist/lib/command.js.map +1 -0
  78. package/dist/lib/credentials.d.ts +110 -0
  79. package/dist/lib/credentials.d.ts.map +1 -0
  80. package/dist/lib/credentials.js +330 -0
  81. package/dist/lib/credentials.js.map +1 -0
  82. package/dist/lib/device.d.ts +48 -0
  83. package/dist/lib/device.d.ts.map +1 -0
  84. package/dist/lib/device.js +189 -0
  85. package/dist/lib/device.js.map +1 -0
  86. package/dist/lib/envelope.d.ts +21 -0
  87. package/dist/lib/envelope.d.ts.map +1 -0
  88. package/dist/lib/envelope.js +87 -0
  89. package/dist/lib/envelope.js.map +1 -0
  90. package/dist/lib/files.d.ts +4 -0
  91. package/dist/lib/files.d.ts.map +1 -0
  92. package/dist/lib/files.js +23 -0
  93. package/dist/lib/files.js.map +1 -0
  94. package/dist/lib/globals.d.ts +25 -0
  95. package/dist/lib/globals.d.ts.map +1 -0
  96. package/dist/lib/globals.js +77 -0
  97. package/dist/lib/globals.js.map +1 -0
  98. package/dist/lib/http.d.ts +45 -0
  99. package/dist/lib/http.d.ts.map +1 -0
  100. package/dist/lib/http.js +141 -0
  101. package/dist/lib/http.js.map +1 -0
  102. package/dist/lib/mime.d.ts +3 -0
  103. package/dist/lib/mime.d.ts.map +1 -0
  104. package/dist/lib/mime.js +38 -0
  105. package/dist/lib/mime.js.map +1 -0
  106. package/dist/lib/secrets/index.d.ts +18 -0
  107. package/dist/lib/secrets/index.d.ts.map +1 -0
  108. package/dist/lib/secrets/index.js +55 -0
  109. package/dist/lib/secrets/index.js.map +1 -0
  110. package/dist/lib/secrets/macos.d.ts +13 -0
  111. package/dist/lib/secrets/macos.d.ts.map +1 -0
  112. package/dist/lib/secrets/macos.js +61 -0
  113. package/dist/lib/secrets/macos.js.map +1 -0
  114. package/dist/lib/secrets/secret-service.d.ts +17 -0
  115. package/dist/lib/secrets/secret-service.d.ts.map +1 -0
  116. package/dist/lib/secrets/secret-service.js +81 -0
  117. package/dist/lib/secrets/secret-service.js.map +1 -0
  118. package/dist/lib/secrets/store.d.ts +28 -0
  119. package/dist/lib/secrets/store.d.ts.map +1 -0
  120. package/dist/lib/secrets/store.js +41 -0
  121. package/dist/lib/secrets/store.js.map +1 -0
  122. package/dist/lib/secrets/windows.d.ts +20 -0
  123. package/dist/lib/secrets/windows.d.ts.map +1 -0
  124. package/dist/lib/secrets/windows.js +155 -0
  125. package/dist/lib/secrets/windows.js.map +1 -0
  126. package/dist/lib/update-hint.d.ts +5 -0
  127. package/dist/lib/update-hint.d.ts.map +1 -0
  128. package/dist/lib/update-hint.js +26 -0
  129. package/dist/lib/update-hint.js.map +1 -0
  130. package/dist/login.d.ts +15 -0
  131. package/dist/login.d.ts.map +1 -0
  132. package/dist/login.js +232 -0
  133. package/dist/login.js.map +1 -0
  134. package/dist/logout.d.ts +13 -0
  135. package/dist/logout.d.ts.map +1 -0
  136. package/dist/logout.js +56 -0
  137. package/dist/logout.js.map +1 -0
  138. package/dist/parse/arguments.d.ts +84 -0
  139. package/dist/parse/arguments.d.ts.map +1 -0
  140. package/dist/parse/arguments.js +460 -0
  141. package/dist/parse/arguments.js.map +1 -0
  142. package/dist/parse/exit.d.ts +7 -0
  143. package/dist/parse/exit.d.ts.map +1 -0
  144. package/dist/parse/exit.js +24 -0
  145. package/dist/parse/exit.js.map +1 -0
  146. package/dist/parse/help.d.ts +22 -0
  147. package/dist/parse/help.d.ts.map +1 -0
  148. package/dist/parse/help.js +151 -0
  149. package/dist/parse/help.js.map +1 -0
  150. package/dist/parse/index.d.ts +5 -0
  151. package/dist/parse/index.d.ts.map +1 -0
  152. package/dist/parse/index.js +7 -0
  153. package/dist/parse/index.js.map +1 -0
  154. package/dist/parse/manifest.d.ts +97 -0
  155. package/dist/parse/manifest.d.ts.map +1 -0
  156. package/dist/parse/manifest.js +4 -0
  157. package/dist/parse/manifest.js.map +1 -0
  158. package/dist/profile.d.ts +4 -0
  159. package/dist/profile.d.ts.map +1 -0
  160. package/dist/profile.js +80 -0
  161. package/dist/profile.js.map +1 -0
  162. package/dist/request.d.ts +25 -0
  163. package/dist/request.d.ts.map +1 -0
  164. package/dist/request.js +35 -0
  165. package/dist/request.js.map +1 -0
  166. package/dist/run.d.ts +17 -0
  167. package/dist/run.d.ts.map +1 -0
  168. package/dist/run.js +88 -0
  169. package/dist/run.js.map +1 -0
  170. package/dist/update.d.ts +45 -0
  171. package/dist/update.d.ts.map +1 -0
  172. package/dist/update.js +177 -0
  173. package/dist/update.js.map +1 -0
  174. package/dist/whoami.d.ts +31 -0
  175. package/dist/whoami.d.ts.map +1 -0
  176. package/dist/whoami.js +118 -0
  177. package/dist/whoami.js.map +1 -0
  178. package/package.json +67 -3
package/dist/login.js ADDED
@@ -0,0 +1,232 @@
1
+ import { createInterface } from 'node:readline/promises';
2
+ import { Flags } from '@oclif/core';
3
+ import { EXIT_CODES } from '@nocobase/agent-protocol';
4
+ import { authRouteOf, manifestPathOf } from "./config.js";
5
+ import { CliManifestSchema } from "./dynamic/manifest.js";
6
+ import { loadDynamic } from "./dynamic/index.js";
7
+ import { serverPath } from "./dynamic/session.js";
8
+ import { AppCommand, UsageError } from "./lib/command.js";
9
+ import { credentialHeaders, DEFAULT_PROFILE, envValue, listProfiles, normalizeServer, saveUserConfig, userClient, } from "./lib/credentials.js";
10
+ import { cliUserAgent, openBrowser, pollDeviceAuthorization, startDeviceAuthorization, } from "./lib/device.js";
11
+ import { CliCommandError } from "./lib/envelope.js";
12
+ import { globalFlags } from "./lib/globals.js";
13
+ import { AppApiError } from "./lib/http.js";
14
+ import { askUpdateHint, printUpdateHint } from "./lib/update-hint.js";
15
+ import { describeStorage } from "./lib/secrets/index.js";
16
+ async function readStdin() {
17
+ const chunks = [];
18
+ for await (const chunk of process.stdin)
19
+ chunks.push(chunk);
20
+ return Buffer.concat(chunks).toString('utf8').trim();
21
+ }
22
+ /** A user code in two halves, `WDJB-MJHT`, as device sign-in pages show it; the server ignores the hyphen. */
23
+ function displayUserCode(code) {
24
+ return code.length === 8 ? `${code.slice(0, 4)}-${code.slice(4)}` : code;
25
+ }
26
+ const interactive = () => Boolean(process.stdin.isTTY) && Boolean(process.stderr.isTTY);
27
+ async function ask(question) {
28
+ const lines = createInterface({
29
+ input: process.stdin,
30
+ output: process.stderr,
31
+ });
32
+ try {
33
+ return (await lines.question(question)).trim();
34
+ }
35
+ finally {
36
+ lines.close();
37
+ }
38
+ }
39
+ /** `<bin> login`: signs in through the browser, or stores an API key given on standard input. */
40
+ export function loginCommand(app) {
41
+ const example = app.exampleServer ?? 'https://app.example.com';
42
+ const envServer = app.envPrefix === undefined ? undefined : `${app.envPrefix}_SERVER`;
43
+ return class Login extends AppCommand {
44
+ static summary = `Sign in to a ${app.displayName} server.`;
45
+ static description = `Opens ${app.displayName} in the browser, where you approve the code it shows; the CLI then holds a session of ` +
46
+ `its own, renewed while you use it, which it keeps in the system keychain (the macOS Keychain, the Secret ` +
47
+ `Service on Linux or the Windows Credential Manager; where there is none, ~/${app.stateDir}/config.json, 0600, ` +
48
+ `with a warning). Without a browser, open the address it prints anywhere you are signed in. For CI, create an ` +
49
+ `API key in the application and pass it on standard input with --api-key-stdin` +
50
+ (app.envPrefix === undefined
51
+ ? '.'
52
+ : `, or skip signing in: set ${app.envPrefix}_SERVER and ${app.envPrefix}_API_KEY.`) +
53
+ ` Each server you sign in to is a profile (--profile <name>, "${DEFAULT_PROFILE}" at first).`;
54
+ static examples = [
55
+ `<%= config.bin %> login --server ${example}`,
56
+ `<%= config.bin %> login --server ${example} --profile staging`,
57
+ `<%= config.bin %> login --server ${example} --api-key-stdin < key.txt`,
58
+ ];
59
+ static flags = {
60
+ server: Flags.string({
61
+ description: `The ${app.displayName} server URL; the profile's own when it has one${envServer ? `, or ${envServer}` : ''}.`,
62
+ }),
63
+ 'api-key-stdin': Flags.boolean({
64
+ description: 'Read an API key from standard input instead of signing in through the browser.',
65
+ }),
66
+ token: Flags.string({
67
+ description: 'An API key (prefer --api-key-stdin, which keeps it out of the shell history).',
68
+ exclusive: ['api-key-stdin'],
69
+ }),
70
+ browser: Flags.boolean({
71
+ description: 'Open the browser to approve the sign-in; --no-browser prints the address instead.',
72
+ allowNo: true,
73
+ default: true,
74
+ }),
75
+ 'skip-verify': Flags.boolean({
76
+ description: 'Store an API key without checking it against the server.',
77
+ }),
78
+ };
79
+ async serverOf(given) {
80
+ const profile = globalFlags().profile;
81
+ const known = (await listProfiles({ paths: this.paths, config: app, profile })).find((entry) => entry.current);
82
+ const server = given ??
83
+ envValue(app, process.env, 'SERVER') ??
84
+ (known && (profile === undefined || known.name === profile)
85
+ ? known.server
86
+ : undefined) ??
87
+ (interactive()
88
+ ? await ask(`${app.displayName} server URL (such as ${example}): `)
89
+ : undefined);
90
+ if (!server)
91
+ throw new CliCommandError('MISSING_ARGUMENT', `Which ${app.displayName} server? Pass --server.`, {
92
+ exit: EXIT_CODES.validation,
93
+ suggestions: [
94
+ {
95
+ message: `Sign in with \`${app.bin} login --server ${example}\`.`,
96
+ },
97
+ ],
98
+ });
99
+ try {
100
+ return normalizeServer(server);
101
+ }
102
+ catch {
103
+ throw new UsageError(`Not a server URL: ${server}`);
104
+ }
105
+ }
106
+ async run() {
107
+ const { flags } = await this.parse(Login);
108
+ const server = await this.serverOf(flags.server);
109
+ const profile = globalFlags().profile;
110
+ const byKey = flags['api-key-stdin'] === true || flags.token !== undefined;
111
+ if (!byKey && app.auth === undefined)
112
+ throw new UsageError(`${app.displayName} offers no browser sign-in here: pass an API key with --api-key-stdin.`);
113
+ let key;
114
+ let identity;
115
+ if (byKey) {
116
+ key = flags['api-key-stdin'] ? await readStdin() : (flags.token ?? '');
117
+ if (key === '')
118
+ throw new UsageError('Pass the API key on standard input with --api-key-stdin.');
119
+ if (!flags['skip-verify'])
120
+ identity = await this.verify(server, { key, kind: 'apiKey' });
121
+ }
122
+ else {
123
+ key = (await this.device(server, !flags.browser)).token;
124
+ identity = await this.verify(server, { key, kind: 'session' });
125
+ }
126
+ const kind = byKey ? 'apiKey' : 'session';
127
+ const saved = await saveUserConfig(server, key, {
128
+ paths: this.paths,
129
+ config: app,
130
+ profile,
131
+ kind,
132
+ });
133
+ if (saved.warning !== undefined)
134
+ this.warn(saved.warning);
135
+ const hint = askUpdateHint({
136
+ server,
137
+ headers: credentialHeaders({ key, kind }),
138
+ });
139
+ // Fetches the commands now, so completion and `docs` have them before the first command runs.
140
+ await loadDynamic().catch(() => undefined);
141
+ const where = describeStorage(saved.storage, this.paths.userConfig);
142
+ this.log(`Signed in to ${server}${identity ? ` as ${identity.displayName}` : ''} (profile ${saved.profile})` +
143
+ `; the ${byKey ? 'key' : 'session'} is in ${where}.`);
144
+ const result = {
145
+ server,
146
+ profile: saved.profile,
147
+ storage: saved.storage,
148
+ method: byKey ? 'api-key' : 'browser',
149
+ ...(identity ?? {}),
150
+ };
151
+ await printUpdateHint(hint);
152
+ return result;
153
+ }
154
+ /** Checks a credential against the manifest; only an authentication failure is fatal. */
155
+ async verify(server, credential) {
156
+ try {
157
+ const { identity } = await userClient({
158
+ server,
159
+ ...credential,
160
+ }).get(manifestPathOf(app), CliManifestSchema);
161
+ return identity;
162
+ }
163
+ catch (error) {
164
+ if (!(error instanceof AppApiError) ||
165
+ error.status === 401 ||
166
+ error.status === 403 ||
167
+ error.status === 0)
168
+ throw error;
169
+ this.warn(`Could not confirm the ${credential.kind === 'session' ? 'session' : 'key'} (${error.reason}); stored it anyway.`);
170
+ return undefined;
171
+ }
172
+ }
173
+ async device(server, noBrowser) {
174
+ const auth = app.auth;
175
+ // Kept with the session the server creates, so the person can tell this machine's sign-in from others.
176
+ const options = { userAgent: cliUserAgent(app) };
177
+ let started;
178
+ try {
179
+ started = await startDeviceAuthorization(server, auth, options);
180
+ }
181
+ catch (error) {
182
+ if (error instanceof AppApiError &&
183
+ (error.status === 404 || error.reason === 'INVALID_CLIENT'))
184
+ throw new CliCommandError('BROWSER_SIGN_IN_UNAVAILABLE', error.status === 404
185
+ ? `${server} offers no browser sign-in (${serverPath(server, authRouteOf(auth, '/device/code'))} answered 404).`
186
+ : `${server} does not accept ${app.bin} for browser sign-in (invalid_client).`, {
187
+ exit: EXIT_CODES.notFound,
188
+ suggestions: [
189
+ {
190
+ message: `Create an API key in ${app.displayName} and pass it: \`${app.bin} login --server ${server} --api-key-stdin < key.txt\`.`,
191
+ },
192
+ ],
193
+ });
194
+ throw error;
195
+ }
196
+ // The code and the address go to stderr, so `--json` keeps stdout to its one document.
197
+ const say = (line) => process.stderr.write(`${line}\n`);
198
+ say(`Your one-time code: ${displayUserCode(started.userCode)}`);
199
+ const opened = !noBrowser &&
200
+ interactive() &&
201
+ openBrowser(started.verificationUriComplete);
202
+ if (opened)
203
+ say(`Opened the sign-in page in your browser; check the code there and approve. If it did not open, visit ${started.verificationUriComplete}`);
204
+ else
205
+ say(`On any device where you are signed in, open ${started.verificationUri} and enter the code, or open ${started.verificationUriComplete}`);
206
+ say(`Waiting (the code expires in ${Math.round(started.expiresIn / 60)} minutes)…`);
207
+ try {
208
+ return await pollDeviceAuthorization(server, auth, started, options);
209
+ }
210
+ catch (error) {
211
+ if (error instanceof AppApiError && error.reason === 'ACCESS_DENIED')
212
+ throw new CliCommandError('ACCESS_DENIED', 'The sign-in was declined in the browser; nothing was stored.', { exit: EXIT_CODES.auth });
213
+ if (error instanceof AppApiError &&
214
+ (error.reason === 'EXPIRED_TOKEN' || error.reason === 'INVALID_GRANT'))
215
+ throw new CliCommandError('EXPIRED_TOKEN', 'The code expired before it was approved; nothing was stored.', {
216
+ exit: EXIT_CODES.auth,
217
+ suggestions: [
218
+ {
219
+ message: 'Sign in again.',
220
+ run: {
221
+ command: app.bin,
222
+ args: ['login', '--server', server],
223
+ },
224
+ },
225
+ ],
226
+ });
227
+ throw error;
228
+ }
229
+ }
230
+ };
231
+ }
232
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Command } from '@oclif/core';
2
+ import { type AppCliConfig } from './config.ts';
3
+ /** What `logout` answers. */
4
+ export interface LogoutResult {
5
+ readonly profile: string;
6
+ readonly server: string;
7
+ /** Whether the server signed the session out; false for an API key, or when the server could not be reached. */
8
+ readonly revoked: boolean;
9
+ readonly dryRun?: boolean;
10
+ }
11
+ /** `<bin> logout`: forgets a profile's credential here and, for a session a browser sign-in gave, signs it out there. */
12
+ export declare function logoutCommand(app: AppCliConfig): Command.Class;
13
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../src/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAY7D,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gHAAgH;IAChH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,yHAAyH;AACzH,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAmE9D"}
package/dist/logout.js ADDED
@@ -0,0 +1,56 @@
1
+ import { authRouteOf } from "./config.js";
2
+ import { serverPath } from "./dynamic/session.js";
3
+ import { AppCommand, UsageError } from "./lib/command.js";
4
+ import { envValue, readUserConfig, removeProfile, userClient, } from "./lib/credentials.js";
5
+ import { globalFlags } from "./lib/globals.js";
6
+ import { AppApiError } from "./lib/http.js";
7
+ /** `<bin> logout`: forgets a profile's credential here and, for a session a browser sign-in gave, signs it out there. */
8
+ export function logoutCommand(app) {
9
+ return class Logout extends AppCommand {
10
+ static summary = 'Sign out: forget the credential here and end the session on the server.';
11
+ static description = 'Removes the profile (the current one, or --profile) and its credential from the keychain or config.json. The ' +
12
+ `session \`${app.bin} login\` received in the browser is signed out on the server too; an API key passed with ` +
13
+ '--api-key-stdin stays valid there, to be revoked where it was created.';
14
+ static supportsDryRun = true;
15
+ static examples = [
16
+ '<%= config.bin %> logout',
17
+ '<%= config.bin %> logout --profile staging --dry-run',
18
+ ];
19
+ async run() {
20
+ await this.parse(Logout);
21
+ if (envValue(app, process.env, 'API_KEY') !== undefined)
22
+ throw new UsageError(`${app.envPrefix}_API_KEY is set: the CLI acts with it, not with a profile. Unset it to sign out.`);
23
+ const user = await readUserConfig({
24
+ paths: this.paths,
25
+ config: app,
26
+ profile: globalFlags().profile,
27
+ }).catch(() => undefined);
28
+ const profile = user?.profile ?? globalFlags().profile;
29
+ if (user === undefined || profile === undefined)
30
+ throw new UsageError(`Not signed in${profile ? ` as profile ${profile}` : ''}; nothing to sign out of.`);
31
+ const session = user.kind === 'session';
32
+ if (this.dryRun) {
33
+ this.log(`Would forget profile ${profile} (${user.server})${session ? ' and sign its session out on the server' : ''}.`);
34
+ return { profile, server: user.server, revoked: false, dryRun: true };
35
+ }
36
+ let revoked = false;
37
+ if (session)
38
+ try {
39
+ await userClient(user).request('POST', serverPath(user.server, authRouteOf(app.auth, '/sign-out')), {});
40
+ revoked = true;
41
+ }
42
+ catch (error) {
43
+ // 401 or 403: the session is no longer valid there anyway.
44
+ if (!(error instanceof AppApiError) ||
45
+ (error.status !== 401 && error.status !== 403))
46
+ this.warn(`Could not sign the session out on ${user.server} (${error instanceof Error ? error.message : String(error)}); forgot it here.`);
47
+ }
48
+ else
49
+ this.warn(`The API key stays valid on ${user.server}: revoke it where it was created.`);
50
+ await removeProfile(profile, { paths: this.paths, config: app });
51
+ this.log(`Signed out of ${user.server} (profile ${profile})${revoked ? '; the session is ended' : ''}.`);
52
+ return { profile, server: user.server, revoked };
53
+ }
54
+ };
55
+ }
56
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../src/logout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { type ExitCode } from '@nocobase/agent-protocol';
2
+ import type { CommandSuggestion } from '@nocobase/cli-envelope';
3
+ import type { CliCommand, CliEnvDefault, CliParameter } from './manifest.ts';
4
+ /** A line the command cannot take, with what the cli-envelope says of it. */
5
+ export declare class CliParseError extends Error {
6
+ readonly code: string;
7
+ readonly exit: ExitCode;
8
+ readonly suggestions: readonly CommandSuggestion[];
9
+ readonly details: unknown;
10
+ constructor(code: string, message: string, options?: {
11
+ readonly exit?: ExitCode;
12
+ readonly suggestions?: readonly CommandSuggestion[];
13
+ readonly details?: unknown;
14
+ });
15
+ }
16
+ /** A file to send, as the environment found it. */
17
+ export interface CliFileRef {
18
+ /** Its base name, or for a changed file its path inside the directory. */
19
+ readonly name: string;
20
+ readonly size: number;
21
+ }
22
+ /** Where a line's files, environment and answers come from. */
23
+ export interface CliParseIo<F extends CliFileRef = CliFileRef> {
24
+ /** A text file's content; undefined when it cannot be read. */
25
+ readText(path: string): Promise<string | undefined>;
26
+ /** An environment variable; undefined when it is not set. */
27
+ env(name: string): string | undefined;
28
+ /** A file to send; undefined when it is not a file. Absent where there are no files to send: such flags are refused. */
29
+ file?(path: string): Promise<F | undefined>;
30
+ /** The changed files of a directory (`changed`); `flag` names them in errors. */
31
+ changed?(spec: NonNullable<CliParameter['changed']>, flag: string): Promise<readonly F[]>;
32
+ /** Asks for a missing value; present only where someone can answer. */
33
+ ask?(parameter: CliParameter): Promise<string>;
34
+ }
35
+ export interface CliParseOptions<F extends CliFileRef = CliFileRef> {
36
+ /** The CLI's command name, for messages. */
37
+ readonly bin: string;
38
+ readonly io: CliParseIo<F>;
39
+ /** `--yes` was given before the command. */
40
+ readonly yes?: boolean;
41
+ /** `--dry-run` was given: the command's own `dry-run` flag is set, and a command without one is refused. */
42
+ readonly dryRun?: boolean;
43
+ }
44
+ /** What a line asks of a command. */
45
+ export interface CliCall<F extends CliFileRef = CliFileRef> {
46
+ /** The value of each parameter given; a binary body field holds its files. */
47
+ readonly values: ReadonlyMap<CliParameter, unknown>;
48
+ /** The body's file, read: an object whose fields the flags override. */
49
+ readonly bodyFile?: Readonly<Record<string, unknown>>;
50
+ /** The files of each upload parameter. */
51
+ readonly uploads: ReadonlyMap<CliParameter, readonly F[]>;
52
+ /** The file streamed to the ticket the request answers. */
53
+ readonly ticket?: F;
54
+ /** Changed files sent with the request, by the field they fill. */
55
+ readonly changed?: {
56
+ readonly field: string;
57
+ readonly files: readonly F[];
58
+ };
59
+ /** `--out`, as typed. */
60
+ readonly out?: string;
61
+ readonly yes: boolean;
62
+ readonly json: boolean;
63
+ readonly help: boolean;
64
+ }
65
+ /** A command's words, such as `issue comment add`. */
66
+ export declare function commandWords(command: Pick<CliCommand, 'id'>): string;
67
+ /** The parameters a person types without a flag, in order. */
68
+ export declare function positionalOf(command: CliCommand): CliParameter[];
69
+ /** How a parameter is named on the line: `<issue>` or `--title`. */
70
+ export declare function parameterLabel(parameter: CliParameter): string;
71
+ /** Whether running the command sends a file of the caller's, or saves one. */
72
+ export declare function needsLocalFiles(command: CliCommand): boolean;
73
+ /** Whether a file name fits `accept` (extensions such as `.log`; media types are left to the server). */
74
+ export declare function accepts(accept: readonly string[], file: string): boolean;
75
+ /**
76
+ * The first of `sources` the environment has: a variable that is set and not empty, or the field of the JSON file a
77
+ * variable names. Undefined when none is; an unreadable file or a missing field falls through to the next source.
78
+ */
79
+ export declare function envDefaultOf(sources: readonly CliEnvDefault[], io: Pick<CliParseIo, 'env' | 'readText'>): Promise<string | undefined>;
80
+ /** What a line without its required arguments is told, and how to see them all. */
81
+ export declare function missingArguments(bin: string, command: CliCommand, missing: readonly CliParameter[]): CliParseError;
82
+ /** Reads the rest of the line, after the command's words, against the command's parameters. */
83
+ export declare function parseCommandLine<F extends CliFileRef>(command: CliCommand, rest: readonly string[], options: CliParseOptions<F>): Promise<CliCall<F>>;
84
+ //# sourceMappingURL=arguments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arguments.d.ts","sourceRoot":"","sources":["../../src/parse/arguments.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7E,6EAA6E;AAC7E,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBAGxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;QACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;KACvB;CAST;AAED,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,+DAA+D;AAC/D,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC3D,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD,6DAA6D;IAC7D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,wHAAwH;IACxH,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC5C,iFAAiF;IACjF,OAAO,CAAC,CACN,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzB,uEAAuE;IACvE,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAChE,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,4GAA4G;IAC5G,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,qCAAqC;AACrC,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IACxD,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACpD,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;IAC1D,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;KAC9B,CAAC;IACF,yBAAyB;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAKD,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM,CAEpE;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY,EAAE,CAIhE;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM,CAI9D;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAS5D;AAED,yGAAyG;AACzG,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMxE;AAaD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,SAAS,aAAa,EAAE,EACjC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,UAAU,CAAC,GACvC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqB7B;AA6DD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,aAAa,CAwBf;AAED,+FAA+F;AAC/F,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,UAAU,EACzD,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAuTrB"}