@doist/cli-core 0.10.0 → 0.11.0
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/CHANGELOG.md +10 -0
- package/README.md +22 -16
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/logout.d.ts +20 -5
- package/dist/auth/logout.d.ts.map +1 -1
- package/dist/auth/logout.js +28 -5
- package/dist/auth/logout.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [0.11.0](https://github.com/Doist/cli-core/compare/v0.10.0...v0.11.0) (2026-05-12)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **auth:** add revokeToken hook to attachLogoutCommand ([#21](https://github.com/Doist/cli-core/issues/21)) ([c7febdd](https://github.com/Doist/cli-core/commit/c7febdd85bbd766496df36d7c9b94eba0265d40e))
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* **deps:** update dependency yocto-spinner to v1.2.0 ([#20](https://github.com/Doist/cli-core/issues/20)) ([a15c2ed](https://github.com/Doist/cli-core/commit/a15c2edc8dc84e929ddb8fd19d836083528b10d7))
|
|
10
|
+
|
|
1
11
|
## [0.10.0](https://github.com/Doist/cli-core/compare/v0.9.0...v0.10.0) (2026-05-12)
|
|
2
12
|
|
|
3
13
|
### Features
|
package/README.md
CHANGED
|
@@ -12,20 +12,20 @@ npm install @doist/cli-core
|
|
|
12
12
|
|
|
13
13
|
## What's in it
|
|
14
14
|
|
|
15
|
-
| Module | Key exports
|
|
16
|
-
| -------------------- |
|
|
17
|
-
| `auth` (subpath) | `attachLoginCommand`, `attachLogoutCommand`, `attachStatusCommand`, `attachTokenViewCommand`, `runOAuthFlow`, `createPkceProvider`, PKCE helpers, `AuthProvider` / `TokenStore` types | OAuth runtime plus the Commander attachers for `<cli> [auth] login` / `logout` / `status` / `token`. Ships the standard public-client PKCE flow (`createPkceProvider`); `AuthProvider` and `TokenStore` are the escape hatches for DCR, OS-keychain, multi-account, etc. — consumers implement `TokenStore` directly (a single-user config-file version is ~30 LoC). `commander` (when using the attachers) and `open` (browser launch) are optional peer-deps. |
|
|
18
|
-
| `commands` (subpath) | `registerChangelogCommand`, `registerUpdateCommand` (+ semver helpers)
|
|
19
|
-
| `config` | `getConfigPath`, `readConfig`, `readConfigStrict`, `writeConfig`, `updateConfig`, `CoreConfig`, `UpdateChannel`
|
|
20
|
-
| `empty` | `printEmpty`
|
|
21
|
-
| `errors` | `CliError`
|
|
22
|
-
| `global-args` | `parseGlobalArgs`, `createGlobalArgsStore`, `createAccessibleGate`, `createSpinnerGate`, `getProgressJsonlPath`, `isProgressJsonlEnabled`
|
|
23
|
-
| `json` | `formatJson`, `formatNdjson`
|
|
24
|
-
| `markdown` (subpath) | `preloadMarkdown`, `renderMarkdown`, `TerminalRendererOptions`
|
|
25
|
-
| `options` | `ViewOptions`
|
|
26
|
-
| `spinner` | `createSpinner`
|
|
27
|
-
| `terminal` | `isCI`, `isStderrTTY`, `isStdinTTY`, `isStdoutTTY`
|
|
28
|
-
| `testing` (subpath) | `describeEmptyMachineOutput`
|
|
15
|
+
| Module | Key exports | Purpose |
|
|
16
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `auth` (subpath) | `attachLoginCommand`, `attachLogoutCommand`, `attachStatusCommand`, `attachTokenViewCommand`, `runOAuthFlow`, `createPkceProvider`, PKCE helpers, `AuthProvider` / `TokenStore` types, `AttachLogoutRevokeContext` | OAuth runtime plus the Commander attachers for `<cli> [auth] login` / `logout` / `status` / `token`. `attachLogoutCommand` accepts an optional `revokeToken` hook for best-effort server-side token revocation. Ships the standard public-client PKCE flow (`createPkceProvider`); `AuthProvider` and `TokenStore` are the escape hatches for DCR, OS-keychain, multi-account, etc. — consumers implement `TokenStore` directly (a single-user config-file version is ~30 LoC). `commander` (when using the attachers) and `open` (browser launch) are optional peer-deps. |
|
|
18
|
+
| `commands` (subpath) | `registerChangelogCommand`, `registerUpdateCommand` (+ semver helpers) | Commander wiring for cli-core's standard commands (e.g. `<cli> changelog`, `<cli> update`, `<cli> update switch`). **Requires** `commander` as an optional peer-dep. |
|
|
19
|
+
| `config` | `getConfigPath`, `readConfig`, `readConfigStrict`, `writeConfig`, `updateConfig`, `CoreConfig`, `UpdateChannel` | Read / write a per-CLI JSON config file with typed error codes; `CoreConfig` is the shape of fields cli-core itself owns (extend it for per-CLI fields). |
|
|
20
|
+
| `empty` | `printEmpty` | Print an empty-state message gated on `--json` / `--ndjson` so machine consumers never see human strings on stdout. |
|
|
21
|
+
| `errors` | `CliError` | Typed CLI error class with `code` and exit-code mapping. |
|
|
22
|
+
| `global-args` | `parseGlobalArgs`, `createGlobalArgsStore`, `createAccessibleGate`, `createSpinnerGate`, `getProgressJsonlPath`, `isProgressJsonlEnabled` | Parse well-known global flags (`--json`, `--ndjson`, `--quiet`, `--verbose`, `--accessible`, `--no-spinner`, `--progress-jsonl`) and derive predicates from them. |
|
|
23
|
+
| `json` | `formatJson`, `formatNdjson` | Stable JSON / newline-delimited JSON formatting for stdout. |
|
|
24
|
+
| `markdown` (subpath) | `preloadMarkdown`, `renderMarkdown`, `TerminalRendererOptions` | Lazy-init terminal markdown renderer. **Requires** `marked` and `marked-terminal-renderer` as peer-deps — install only if your CLI uses this subpath. |
|
|
25
|
+
| `options` | `ViewOptions` | Type contract for `{ json?, ndjson? }` per-command options that machine-output gates derive from. |
|
|
26
|
+
| `spinner` | `createSpinner` | Loading spinner factory wrapping `yocto-spinner` with disable gates. |
|
|
27
|
+
| `terminal` | `isCI`, `isStderrTTY`, `isStdinTTY`, `isStdoutTTY` | TTY / CI detection helpers. |
|
|
28
|
+
| `testing` (subpath) | `describeEmptyMachineOutput` | Vitest helpers reusable by consuming CLIs (e.g. parametrised empty-state suite covering `--json` / `--ndjson` / human modes). |
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
@@ -182,6 +182,12 @@ import {
|
|
|
182
182
|
|
|
183
183
|
attachLogoutCommand<Account>(auth, {
|
|
184
184
|
store,
|
|
185
|
+
revokeToken: async ({ token }) => {
|
|
186
|
+
// Optional pre-clear server-side revocation. Errors are swallowed so
|
|
187
|
+
// local logout always succeeds — surface diagnostics via your own
|
|
188
|
+
// logging if you need them.
|
|
189
|
+
await api.revokeToken(token)
|
|
190
|
+
},
|
|
185
191
|
onCleared: ({ account, view }) => {
|
|
186
192
|
// Optional follow-up — surface keyring-fallback warnings, etc.
|
|
187
193
|
// Route extra prose to stderr in machine-output mode.
|
|
@@ -207,11 +213,11 @@ attachTokenViewCommand<Account>(auth, {
|
|
|
207
213
|
})
|
|
208
214
|
```
|
|
209
215
|
|
|
210
|
-
`attachLogoutCommand` snapshots `store.active()` (only when `onCleared` is supplied — skipped otherwise to avoid keyring / file I/O), calls `store.clear()`, then emits `✓ Logged out` (human) or `{ "ok": true }` (`--json`, silent under `--ndjson`)
|
|
216
|
+
`attachLogoutCommand` snapshots `store.active()` (only when `revokeToken` or `onCleared` is supplied — skipped otherwise to avoid keyring / file I/O), calls `store.clear()`, then awaits `revokeToken({ token, account, view, flags })` for best-effort server-side revocation, emits `✓ Logged out` (human) or `{ "ok": true }` (`--json`, silent under `--ndjson`), and finally fires `onCleared({ account, view, flags })`. Local clear runs first so logout always succeeds locally even if the snapshot read fails or the server is unreachable; both `store.active()` and `revokeToken` errors are swallowed (`revokeToken` is also skipped when no session was stored). The exported `AttachLogoutRevokeContext<TAccount>` is the ctx type for typing standalone revoke implementations.
|
|
211
217
|
|
|
212
218
|
`attachStatusCommand` reads `store.active()`, optionally runs `fetchLive` (consumer translates 401 → `CliError('NO_TOKEN', …)`), then dispatches to `renderJson` (`--json` / `--ndjson` via `formatJson` / `formatNdjson`, defaults to the account itself, **only invoked in machine-output mode**) or `renderText` (human mode, string or array of lines). When the store is empty it throws `CliError('NOT_AUTHENTICATED', 'Not signed in.')` unless `onNotAuthenticated` is supplied.
|
|
213
219
|
|
|
214
|
-
Both attachers strip the standard `--json` / `--ndjson` registrar flags from the parsed options and pass the remainder to their callbacks as `flags` — same escape hatch `attachLoginCommand` uses, so a consumer can chain e.g. `.option('--user <ref>')` and read it in `onCleared` / `renderText` / `fetchLive` / `renderJson` / `onNotAuthenticated`.
|
|
220
|
+
Both attachers strip the standard `--json` / `--ndjson` registrar flags from the parsed options and pass the remainder to their callbacks as `flags` — same escape hatch `attachLoginCommand` uses, so a consumer can chain e.g. `.option('--user <ref>')` and read it in `revokeToken` / `onCleared` / `renderText` / `fetchLive` / `renderJson` / `onNotAuthenticated`.
|
|
215
221
|
|
|
216
222
|
`attachTokenViewCommand` writes the bare stored token to stdout (no envelope, pipe-safe) and appends a trailing newline only when stdout is a TTY. When `envVarName` is set and the env var is populated, it throws `CliError('TOKEN_FROM_ENV', …)` to avoid disclosing a token the CLI did not manage. Defaults to subcommand name `token`; pass `name: 'view'` to nest under an existing `token` group.
|
|
217
223
|
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { RunOAuthFlowOptions, RunOAuthFlowResult } from './flow.js';
|
|
|
4
4
|
export { attachLoginCommand } from './login.js';
|
|
5
5
|
export type { AttachLoginCommandOptions, AttachLoginContext } from './login.js';
|
|
6
6
|
export { attachLogoutCommand } from './logout.js';
|
|
7
|
-
export type { AttachLogoutCommandOptions, AttachLogoutContext } from './logout.js';
|
|
7
|
+
export type { AttachLogoutCommandOptions, AttachLogoutContext, AttachLogoutRevokeContext, } from './logout.js';
|
|
8
8
|
export { attachStatusCommand } from './status.js';
|
|
9
9
|
export type { AttachStatusCommandOptions, AttachStatusContext } from './status.js';
|
|
10
10
|
export { attachTokenViewCommand } from './token-view.js';
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,YAAY,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,YAAY,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EACR,0BAA0B,EAC1B,mBAAmB,EACnB,yBAAyB,GAC5B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,YAAY,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EACH,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,gBAAgB,GACnB,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9E,YAAY,EACR,WAAW,EACX,cAAc,EACd,eAAe,EACf,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,GAChB,MAAM,YAAY,CAAA"}
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAMjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAExD,OAAO,EACH,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,gBAAgB,GACnB,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/auth/logout.d.ts
CHANGED
|
@@ -12,22 +12,37 @@ export type AttachLogoutContext<TAccount extends AuthAccount> = {
|
|
|
12
12
|
*/
|
|
13
13
|
flags: Record<string, unknown>;
|
|
14
14
|
};
|
|
15
|
+
export type AttachLogoutRevokeContext<TAccount extends AuthAccount> = Omit<AttachLogoutContext<TAccount>, 'account'> & {
|
|
16
|
+
/** Live token from the snapshot — pass to the server-side revocation endpoint. */
|
|
17
|
+
token: string;
|
|
18
|
+
/** Non-null because the hook is skipped when nothing was stored. */
|
|
19
|
+
account: TAccount;
|
|
20
|
+
};
|
|
15
21
|
export type AttachLogoutCommandOptions<TAccount extends AuthAccount = AuthAccount> = {
|
|
16
22
|
store: TokenStore<TAccount>;
|
|
17
23
|
/** Override the subcommand description. */
|
|
18
24
|
description?: string;
|
|
19
25
|
/**
|
|
20
|
-
* Fires after `store.clear()` resolves
|
|
26
|
+
* Fires after `store.clear()` resolves, when a prior session was stored.
|
|
27
|
+
* Use to call a server-side token-revocation endpoint. The hook is awaited,
|
|
28
|
+
* but errors are swallowed so local logout always succeeds even when the
|
|
29
|
+
* server is unreachable. Skipped when no session was stored or when
|
|
30
|
+
* `store.active()` itself fails.
|
|
31
|
+
*/
|
|
32
|
+
revokeToken?(ctx: AttachLogoutRevokeContext<TAccount>): void | Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Fires after `revokeToken` settles. Use to surface keyring-fallback
|
|
21
35
|
* warnings or other CLI-specific follow-ups. Consumers in machine-output
|
|
22
36
|
* mode should route any extra prose to stderr to keep stdout parseable.
|
|
23
37
|
*/
|
|
24
38
|
onCleared?(ctx: AttachLogoutContext<TAccount>): void | Promise<void>;
|
|
25
39
|
};
|
|
26
40
|
/**
|
|
27
|
-
* Attach `logout` as a subcommand of `parent`. Snapshots the active
|
|
28
|
-
* calls `store.clear()`,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
41
|
+
* Attach `logout` as a subcommand of `parent`. Snapshots the active session
|
|
42
|
+
* (only when a hook needs it), calls `store.clear()`, optionally awaits
|
|
43
|
+
* `revokeToken` for best-effort server-side revocation, emits the success
|
|
44
|
+
* line gated on `--json` / `--ndjson`, then invokes `onCleared` for
|
|
45
|
+
* follow-ups. Returns the new `Command` so the consumer can chain.
|
|
31
46
|
*/
|
|
32
47
|
export declare function attachLogoutCommand<TAccount extends AuthAccount = AuthAccount>(parent: Command, options: AttachLogoutCommandOptions<TAccount>): Command;
|
|
33
48
|
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEzD,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAC5D,qGAAqG;IACrG,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAA;IACxB,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC3B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACjF,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvE,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/auth/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEzD,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAC5D,qGAAqG;IACrG,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAA;IACxB,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC3B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,yBAAyB,CAAC,QAAQ,SAAS,WAAW,IAAI,IAAI,CACtE,mBAAmB,CAAC,QAAQ,CAAC,EAC7B,SAAS,CACZ,GAAG;IACA,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,OAAO,EAAE,QAAQ,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACjF,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,GAAG,EAAE,yBAAyB,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5E;;;;OAIG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvE,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,EAC1E,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC9C,OAAO,CA2CT"}
|
package/dist/auth/logout.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { formatJson } from '../json.js';
|
|
2
2
|
/**
|
|
3
|
-
* Attach `logout` as a subcommand of `parent`. Snapshots the active
|
|
4
|
-
* calls `store.clear()`,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Attach `logout` as a subcommand of `parent`. Snapshots the active session
|
|
4
|
+
* (only when a hook needs it), calls `store.clear()`, optionally awaits
|
|
5
|
+
* `revokeToken` for best-effort server-side revocation, emits the success
|
|
6
|
+
* line gated on `--json` / `--ndjson`, then invokes `onCleared` for
|
|
7
|
+
* follow-ups. Returns the new `Command` so the consumer can chain.
|
|
7
8
|
*/
|
|
8
9
|
export function attachLogoutCommand(parent, options) {
|
|
9
10
|
return parent
|
|
@@ -18,9 +19,31 @@ export function attachLogoutCommand(parent, options) {
|
|
|
18
19
|
ndjson: Boolean(ndjson),
|
|
19
20
|
};
|
|
20
21
|
// Skip the keyring/file read when no callback consumes the snapshot.
|
|
21
|
-
const
|
|
22
|
+
const needsSnapshot = Boolean(options.revokeToken || options.onCleared);
|
|
23
|
+
let snapshot = null;
|
|
24
|
+
if (needsSnapshot) {
|
|
25
|
+
try {
|
|
26
|
+
snapshot = await options.store.active();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Snapshot lookup failures must not block local clear.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
22
32
|
const account = snapshot?.account ?? null;
|
|
23
33
|
await options.store.clear();
|
|
34
|
+
if (options.revokeToken && snapshot) {
|
|
35
|
+
try {
|
|
36
|
+
await options.revokeToken({
|
|
37
|
+
token: snapshot.token,
|
|
38
|
+
account: snapshot.account,
|
|
39
|
+
view,
|
|
40
|
+
flags,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Best-effort: server revoke failures must not surface to the user.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
24
47
|
if (view.json) {
|
|
25
48
|
console.log(formatJson({ ok: true }));
|
|
26
49
|
}
|
package/dist/auth/logout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/auth/logout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/auth/logout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AA8CvC;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAC/B,MAAe,EACf,OAA6C;IAE7C,OAAO,MAAM;SACR,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,uCAAuC,CAAC;SAC3E,MAAM,CAAC,QAAQ,EAAE,mCAAmC,CAAC;SACrD,MAAM,CAAC,UAAU,EAAE,qCAAqC,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,GAA4B,EAAE,EAAE;QAC3C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,CAAA;QACtC,MAAM,IAAI,GAA0B;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;SAC1B,CAAA;QACD,qEAAqE;QACrE,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;QACvE,IAAI,QAAQ,GAAgD,IAAI,CAAA;QAChE,IAAI,aAAa,EAAE,CAAC;YAChB,IAAI,CAAC;gBACD,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;YAC3C,CAAC;YAAC,MAAM,CAAC;gBACL,uDAAuD;YAC3D,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAA;QACzC,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,OAAO,CAAC,WAAW,IAAI,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC;gBACD,MAAM,OAAO,CAAC,WAAW,CAAC;oBACtB,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,IAAI;oBACJ,KAAK;iBACR,CAAC,CAAA;YACN,CAAC;YAAC,MAAM,CAAC;gBACL,oEAAoE;YACxE,CAAC;QACL,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACzC,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAC/B,CAAC;QACD,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;AACV,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Shared core utilities for Doist CLI projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -66,22 +66,22 @@
|
|
|
66
66
|
"@semantic-release/changelog": "6.0.3",
|
|
67
67
|
"@semantic-release/exec": "7.1.0",
|
|
68
68
|
"@semantic-release/git": "10.0.1",
|
|
69
|
-
"@types/node": "25.6.
|
|
69
|
+
"@types/node": "25.6.1",
|
|
70
70
|
"commander": "14.0.3",
|
|
71
71
|
"conventional-changelog-conventionalcommits": "9.3.1",
|
|
72
72
|
"lefthook": "2.1.6",
|
|
73
73
|
"marked": "18.0.3",
|
|
74
74
|
"marked-terminal-renderer": "2.2.0",
|
|
75
75
|
"open": "11.0.0",
|
|
76
|
-
"oxfmt": "0.
|
|
77
|
-
"oxlint": "1.
|
|
76
|
+
"oxfmt": "0.48.0",
|
|
77
|
+
"oxlint": "1.63.0",
|
|
78
78
|
"semantic-release": "25.0.3",
|
|
79
79
|
"typescript": "6.0.3",
|
|
80
80
|
"vitest": "4.1.5"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"chalk": "5.6.2",
|
|
84
|
-
"yocto-spinner": "1.
|
|
84
|
+
"yocto-spinner": "1.2.0"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"commander": ">=14",
|