@doist/cli-core 0.10.0 → 0.12.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 +16 -0
- package/README.md +89 -34
- package/dist/auth/errors.d.ts +1 -1
- package/dist/auth/errors.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -2
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/logout.d.ts +22 -10
- package/dist/auth/logout.d.ts.map +1 -1
- package/dist/auth/logout.js +43 -11
- package/dist/auth/logout.js.map +1 -1
- package/dist/auth/status.d.ts +4 -5
- package/dist/auth/status.d.ts.map +1 -1
- package/dist/auth/status.js +9 -11
- package/dist/auth/status.js.map +1 -1
- package/dist/auth/token-view.d.ts.map +1 -1
- package/dist/auth/token-view.js +6 -4
- package/dist/auth/token-view.js.map +1 -1
- package/dist/auth/types.d.ts +17 -10
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/user-flag.d.ts +15 -0
- package/dist/auth/user-flag.d.ts.map +1 -0
- package/dist/auth/user-flag.js +26 -0
- package/dist/auth/user-flag.js.map +1 -0
- package/dist/global-args.d.ts +25 -11
- package/dist/global-args.d.ts.map +1 -1
- package/dist/global-args.js +73 -11
- package/dist/global-args.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [0.12.0](https://github.com/Doist/cli-core/compare/v0.11.0...v0.12.0) (2026-05-14)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **auth:** multi-user TokenStore contract ([#23](https://github.com/Doist/cli-core/issues/23)) ([f83310a](https://github.com/Doist/cli-core/commit/f83310a3dec62636884dab6bea2aed3c89aab502))
|
|
6
|
+
|
|
7
|
+
## [0.11.0](https://github.com/Doist/cli-core/compare/v0.10.0...v0.11.0) (2026-05-12)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **auth:** add revokeToken hook to attachLogoutCommand ([#21](https://github.com/Doist/cli-core/issues/21)) ([c7febdd](https://github.com/Doist/cli-core/commit/c7febdd85bbd766496df36d7c9b94eba0265d40e))
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **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))
|
|
16
|
+
|
|
1
17
|
## [0.10.0](https://github.com/Doist/cli-core/compare/v0.9.0...v0.10.0) (2026-05-12)
|
|
2
18
|
|
|
3
19
|
### 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 (
|
|
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` / `AccountRef` 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 (single-user store implements `list` / `setDefault` trivially against the one account). `logout` / `status` / `token` always attach `--user <ref>` and thread the parsed ref to `store.active(ref)` (and `store.clear(ref)` on `logout`). `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`, `stripUserFlag`, `createGlobalArgsStore`, `createAccessibleGate`, `createSpinnerGate`, `getProgressJsonlPath`, `isProgressJsonlEnabled` | Parse well-known global flags (`--json`, `--ndjson`, `--quiet`, `--verbose`, `--accessible`, `--no-spinner`, `--progress-jsonl`, `--user <ref>`) and derive predicates from them. `stripUserFlag` removes `--user` tokens from argv so the cleaned array can be forwarded to Commander when the flag has no root-program attachment. |
|
|
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('--
|
|
220
|
+
Both attachers strip the standard `--json` / `--ndjson` / `--user` 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('--full')` 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
|
|
|
@@ -230,33 +236,80 @@ Under `--json` / `--ndjson`, the authorize-URL fallback (printed when `open` is
|
|
|
230
236
|
|
|
231
237
|
#### Implementing `TokenStore`
|
|
232
238
|
|
|
233
|
-
|
|
239
|
+
`TokenStore` is uniformly multi-user-shaped — single-user CLIs implement `list` / `setDefault` trivially against their one stored account. There is no separate single-user contract.
|
|
234
240
|
|
|
235
241
|
```ts
|
|
236
|
-
import { getConfigPath, readConfig, updateConfig, writeConfig } from '@doist/cli-core'
|
|
237
|
-
import type { TokenStore } from '@doist/cli-core/auth'
|
|
242
|
+
import { CliError, getConfigPath, readConfig, updateConfig, writeConfig } from '@doist/cli-core'
|
|
243
|
+
import type { AccountRef, TokenStore } from '@doist/cli-core/auth'
|
|
238
244
|
|
|
239
245
|
type Account = { id: string; label?: string; email: string }
|
|
240
246
|
type StoredAuth = { account: Account; token: string }
|
|
241
247
|
|
|
242
|
-
const configPath = getConfigPath('
|
|
248
|
+
const configPath = getConfigPath('outline-cli')
|
|
243
249
|
|
|
250
|
+
function matches(account: Account, ref: AccountRef): boolean {
|
|
251
|
+
return account.id === ref || account.label === ref
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Single-user impl. Honour `ref` on every method — returning null on a miss
|
|
255
|
+
// is what lets the attachers translate `<cmd> --user wrong` into a typed
|
|
256
|
+
// `ACCOUNT_NOT_FOUND` error instead of a misleading success or
|
|
257
|
+
// `NOT_AUTHENTICATED`.
|
|
244
258
|
export const tokenStore: TokenStore<Account> = {
|
|
245
|
-
async active() {
|
|
259
|
+
async active(ref?: AccountRef) {
|
|
246
260
|
const config = await readConfig<{ auth?: StoredAuth }>(configPath)
|
|
247
|
-
|
|
261
|
+
if (!config.auth) return null
|
|
262
|
+
if (ref !== undefined && !matches(config.auth.account, ref)) return null
|
|
263
|
+
return { account: config.auth.account, token: config.auth.token }
|
|
248
264
|
},
|
|
249
265
|
async set(account, token) {
|
|
250
266
|
await updateConfig<{ auth: StoredAuth }>(configPath, { auth: { account, token } })
|
|
251
267
|
},
|
|
252
|
-
async clear() {
|
|
253
|
-
const
|
|
268
|
+
async clear(ref?: AccountRef) {
|
|
269
|
+
const config = await readConfig<{ auth?: StoredAuth }>(configPath)
|
|
270
|
+
if (!config.auth) return
|
|
271
|
+
if (ref !== undefined && !matches(config.auth.account, ref)) return
|
|
272
|
+
const { auth: _drop, ...rest } = config
|
|
254
273
|
await writeConfig(configPath, rest)
|
|
255
274
|
},
|
|
275
|
+
async list() {
|
|
276
|
+
const snapshot = await this.active()
|
|
277
|
+
return snapshot ? [{ account: snapshot.account, isDefault: true }] : []
|
|
278
|
+
},
|
|
279
|
+
async setDefault(ref: AccountRef) {
|
|
280
|
+
const snapshot = await this.active()
|
|
281
|
+
if (!snapshot || !matches(snapshot.account, ref)) {
|
|
282
|
+
throw new CliError('ACCOUNT_NOT_FOUND', `No stored account matches "${ref}".`)
|
|
283
|
+
}
|
|
284
|
+
// Single-user store — already the default.
|
|
285
|
+
},
|
|
256
286
|
}
|
|
257
287
|
```
|
|
258
288
|
|
|
259
|
-
For OS
|
|
289
|
+
For multi-account storage (OS keychain, per-user config slots, …), implement the same five methods against your backend and honour `ref` on `active` / `clear` / `setDefault`. `AccountRef` is an opaque `string` — cli-core does not constrain matching semantics (id-exact, email-case-insensitive, label, …). The store impl owns that.
|
|
290
|
+
|
|
291
|
+
#### `--user <ref>` and multi-user wiring
|
|
292
|
+
|
|
293
|
+
The three account-touching attachers (`attachLogoutCommand` / `attachStatusCommand` / `attachTokenViewCommand`) always attach `--user <ref>` on their subcommand. `attachLogoutCommand` threads the parsed ref to both `store.active(ref)` and `store.clear(ref)`; `attachStatusCommand` and `attachTokenViewCommand` only call `store.active(ref)`. When `--user` is supplied but `store.active(ref)` returns `null`, each attacher throws `CliError('ACCOUNT_NOT_FOUND', …)` so the user sees a typed miss rather than `NOT_AUTHENTICATED` or a silent `✓ Logged out`. Single-user stores returning `null` for a non-matching ref is the supported way to feed this guard.
|
|
294
|
+
|
|
295
|
+
For pre-subcommand `--user` (`<cli> --user alice some-cmd`) that should apply to non-auth commands too, parse it globally and strip from argv before handing to Commander:
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
import { parseGlobalArgs, stripUserFlag } from '@doist/cli-core'
|
|
299
|
+
|
|
300
|
+
const args = parseGlobalArgs(process.argv.slice(2))
|
|
301
|
+
console.log(args.user) // 'alice' | undefined
|
|
302
|
+
|
|
303
|
+
await program.parseAsync([
|
|
304
|
+
process.argv[0],
|
|
305
|
+
process.argv[1],
|
|
306
|
+
...stripUserFlag(process.argv.slice(2)),
|
|
307
|
+
])
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Account-selection resolvers (env > `--user` > default > single-only > error), `account list`, and `account use` subcommands stay per-CLI for now — cli-core ships only the contract until at least one consumer has shipped these end-to-end.
|
|
311
|
+
|
|
312
|
+
`ACCOUNT_NOT_FOUND` is thrown by the account-touching attachers when `--user <ref>` was supplied but `store.active(ref)` returned `null`. `NO_ACCOUNT_SELECTED` is reserved for consumer-thrown resolver failures (multiple accounts stored, no default, no `--user`); cli-core does not throw it itself.
|
|
260
313
|
|
|
261
314
|
#### Custom `AuthProvider` (non-PKCE flows)
|
|
262
315
|
|
|
@@ -299,15 +352,17 @@ The `handshake` is shared mutable state across hooks. `runOAuthFlow` folds the r
|
|
|
299
352
|
|
|
300
353
|
Every failure in this subpath surfaces as a `CliError`:
|
|
301
354
|
|
|
302
|
-
| Code | Cause
|
|
303
|
-
| ---------------------------- |
|
|
304
|
-
| `AUTH_OAUTH_FAILED` | Provider returned `?error=...`, the flow was aborted via `signal`, or the callback server stopped before completion.
|
|
305
|
-
| `AUTH_CALLBACK_TIMEOUT` | No valid callback within `timeoutMs` (default 3 minutes).
|
|
306
|
-
| `AUTH_PORT_BIND_FAILED` | Could not bind any port in `[preferredPort, preferredPort + portFallbackCount]`, or `--callback-port` was out of range.
|
|
307
|
-
| `AUTH_TOKEN_EXCHANGE_FAILED` | Token endpoint network error, non-2xx response, non-JSON body, or missing `access_token`.
|
|
308
|
-
| `AUTH_STORE_WRITE_FAILED` | `TokenStore.set` threw a non-`CliError`. (`CliError`s thrown from `set` propagate unchanged.)
|
|
309
|
-
| `NOT_AUTHENTICATED` | `status` / `token` ran with an empty `TokenStore` (and no `onNotAuthenticated` callback for `status`). Default message: `'Not signed in.'`.
|
|
310
|
-
| `TOKEN_FROM_ENV` | `attachTokenViewCommand` refused to print: `envVarName` was set and the env var is populated.
|
|
355
|
+
| Code | Cause |
|
|
356
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
357
|
+
| `AUTH_OAUTH_FAILED` | Provider returned `?error=...`, the flow was aborted via `signal`, or the callback server stopped before completion. |
|
|
358
|
+
| `AUTH_CALLBACK_TIMEOUT` | No valid callback within `timeoutMs` (default 3 minutes). |
|
|
359
|
+
| `AUTH_PORT_BIND_FAILED` | Could not bind any port in `[preferredPort, preferredPort + portFallbackCount]`, or `--callback-port` was out of range. |
|
|
360
|
+
| `AUTH_TOKEN_EXCHANGE_FAILED` | Token endpoint network error, non-2xx response, non-JSON body, or missing `access_token`. |
|
|
361
|
+
| `AUTH_STORE_WRITE_FAILED` | `TokenStore.set` threw a non-`CliError`. (`CliError`s thrown from `set` propagate unchanged.) |
|
|
362
|
+
| `NOT_AUTHENTICATED` | `status` / `token` ran with an empty `TokenStore` (and no `onNotAuthenticated` callback for `status`). Default message: `'Not signed in.'`. |
|
|
363
|
+
| `TOKEN_FROM_ENV` | `attachTokenViewCommand` refused to print: `envVarName` was set and the env var is populated. |
|
|
364
|
+
| `NO_ACCOUNT_SELECTED` | Reserved for consumer-thrown resolver failures when multiple accounts are stored without a default and no `--user` was supplied. |
|
|
365
|
+
| `ACCOUNT_NOT_FOUND` | `logout` / `status` / `token` were invoked with `--user <ref>` but `store.active(ref)` returned `null`. Also reserved for consumer resolvers when a ref doesn't match any stored account. |
|
|
311
366
|
|
|
312
367
|
The consumer's top-level error handler formats and exits.
|
|
313
368
|
|
package/dist/auth/errors.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* aggregator in `../errors.ts` so consumers don't have to redeclare them in
|
|
4
4
|
* their own `TCode` union when catching.
|
|
5
5
|
*/
|
|
6
|
-
export type AuthErrorCode = 'AUTH_OAUTH_FAILED' | 'AUTH_CALLBACK_TIMEOUT' | 'AUTH_PORT_BIND_FAILED' | 'AUTH_TOKEN_EXCHANGE_FAILED' | 'AUTH_STORE_WRITE_FAILED' | 'NOT_AUTHENTICATED' | 'TOKEN_FROM_ENV';
|
|
6
|
+
export type AuthErrorCode = 'AUTH_OAUTH_FAILED' | 'AUTH_CALLBACK_TIMEOUT' | 'AUTH_PORT_BIND_FAILED' | 'AUTH_TOKEN_EXCHANGE_FAILED' | 'AUTH_STORE_WRITE_FAILED' | 'NOT_AUTHENTICATED' | 'TOKEN_FROM_ENV' | 'NO_ACCOUNT_SELECTED' | 'ACCOUNT_NOT_FOUND';
|
|
7
7
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACnB,mBAAmB,GACnB,uBAAuB,GACvB,uBAAuB,GACvB,4BAA4B,GAC5B,yBAAyB,GACzB,mBAAmB,GACnB,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACnB,mBAAmB,GACnB,uBAAuB,GACvB,uBAAuB,GACvB,4BAA4B,GAC5B,yBAAyB,GACzB,mBAAmB,GACnB,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,CAAA"}
|
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';
|
|
@@ -13,5 +13,5 @@ export { DEFAULT_VERIFIER_ALPHABET, deriveChallenge, generateState, generateVeri
|
|
|
13
13
|
export type { GenerateVerifierOptions } from './pkce.js';
|
|
14
14
|
export { createPkceProvider } from './providers/pkce.js';
|
|
15
15
|
export type { PkceLazyString, PkceProviderOptions } from './providers/pkce.js';
|
|
16
|
-
export type { AuthAccount, AuthorizeInput, AuthorizeResult, AuthProvider, ExchangeInput, ExchangeResult, PrepareInput, PrepareResult, TokenStore, ValidateInput, } from './types.js';
|
|
16
|
+
export type { AccountRef, AuthAccount, AuthorizeInput, AuthorizeResult, AuthProvider, ExchangeInput, ExchangeResult, PrepareInput, PrepareResult, TokenStore, ValidateInput, } from './types.js';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
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,UAAU,EACV,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
|
@@ -4,30 +4,42 @@ import type { AuthAccount, TokenStore } from './types.js';
|
|
|
4
4
|
export type AttachLogoutContext<TAccount extends AuthAccount> = {
|
|
5
5
|
/** The account that was active immediately before `clear()` ran, or `null` if nothing was stored. */
|
|
6
6
|
account: TAccount | null;
|
|
7
|
+
/** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
|
|
7
8
|
view: Required<ViewOptions>;
|
|
8
|
-
/**
|
|
9
|
-
* Stripped per-CLI flags — the parsed options object with the standard
|
|
10
|
-
* registrar flags (`--json`, `--ndjson`) removed. Any consumer-attached
|
|
11
|
-
* `.option(...)` lands here (e.g. `--user <ref>` from a multi-user CLI).
|
|
12
|
-
*/
|
|
9
|
+
/** Consumer-attached options. The registrar flags (`--json`, `--ndjson`, `--user`) are stripped. */
|
|
13
10
|
flags: Record<string, unknown>;
|
|
14
11
|
};
|
|
12
|
+
export type AttachLogoutRevokeContext<TAccount extends AuthAccount> = Omit<AttachLogoutContext<TAccount>, 'account'> & {
|
|
13
|
+
/** Live token from the snapshot — pass to the server-side revocation endpoint. */
|
|
14
|
+
token: string;
|
|
15
|
+
/** Non-null because the hook is skipped when nothing was stored. */
|
|
16
|
+
account: TAccount;
|
|
17
|
+
};
|
|
15
18
|
export type AttachLogoutCommandOptions<TAccount extends AuthAccount = AuthAccount> = {
|
|
16
19
|
store: TokenStore<TAccount>;
|
|
17
20
|
/** Override the subcommand description. */
|
|
18
21
|
description?: string;
|
|
19
22
|
/**
|
|
20
|
-
* Fires after `store.clear()` resolves
|
|
23
|
+
* Fires after `store.clear()` resolves, when a prior session was stored.
|
|
24
|
+
* Use to call a server-side token-revocation endpoint. The hook is awaited,
|
|
25
|
+
* but errors are swallowed so local logout always succeeds even when the
|
|
26
|
+
* server is unreachable. Skipped when no session was stored or when
|
|
27
|
+
* `store.active()` itself fails.
|
|
28
|
+
*/
|
|
29
|
+
revokeToken?(ctx: AttachLogoutRevokeContext<TAccount>): void | Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Fires after `revokeToken` settles. Use to surface keyring-fallback
|
|
21
32
|
* warnings or other CLI-specific follow-ups. Consumers in machine-output
|
|
22
33
|
* mode should route any extra prose to stderr to keep stdout parseable.
|
|
23
34
|
*/
|
|
24
35
|
onCleared?(ctx: AttachLogoutContext<TAccount>): void | Promise<void>;
|
|
25
36
|
};
|
|
26
37
|
/**
|
|
27
|
-
* Attach `logout` as a subcommand of `parent`. Snapshots the active
|
|
28
|
-
* calls `store.clear()`,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
38
|
+
* Attach `logout` as a subcommand of `parent`. Snapshots the active session
|
|
39
|
+
* (only when a hook needs it), calls `store.clear()`, optionally awaits
|
|
40
|
+
* `revokeToken` for best-effort server-side revocation, emits the success
|
|
41
|
+
* line gated on `--json` / `--ndjson`, then invokes `onCleared` for
|
|
42
|
+
* follow-ups. Returns the new `Command` so the consumer can chain.
|
|
31
43
|
*/
|
|
32
44
|
export declare function attachLogoutCommand<TAccount extends AuthAccount = AuthAccount>(parent: Command, options: AttachLogoutCommandOptions<TAccount>): Command;
|
|
33
45
|
//# 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;
|
|
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;AAGzD,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAC5D,qGAAqG;IACrG,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAA;IACxB,8EAA8E;IAC9E,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC3B,oGAAoG;IACpG,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,CAkDT"}
|
package/dist/auth/logout.js
CHANGED
|
@@ -1,26 +1,58 @@
|
|
|
1
1
|
import { formatJson } from '../json.js';
|
|
2
|
+
import { attachUserFlag, extractUserRef, requireSnapshotForRef } from './user-flag.js';
|
|
2
3
|
/**
|
|
3
|
-
* Attach `logout` as a subcommand of `parent`. Snapshots the active
|
|
4
|
-
* calls `store.clear()`,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Attach `logout` as a subcommand of `parent`. Snapshots the active session
|
|
5
|
+
* (only when a hook needs it), calls `store.clear()`, optionally awaits
|
|
6
|
+
* `revokeToken` for best-effort server-side revocation, emits the success
|
|
7
|
+
* line gated on `--json` / `--ndjson`, then invokes `onCleared` for
|
|
8
|
+
* follow-ups. Returns the new `Command` so the consumer can chain.
|
|
7
9
|
*/
|
|
8
10
|
export function attachLogoutCommand(parent, options) {
|
|
9
|
-
|
|
11
|
+
const command = parent
|
|
10
12
|
.command('logout')
|
|
11
13
|
.description(options.description ?? 'Remove the saved authentication token')
|
|
12
14
|
.option('--json', 'Emit machine-readable JSON output')
|
|
13
|
-
.option('--ndjson', 'Emit machine-readable NDJSON output')
|
|
14
|
-
|
|
15
|
-
const { json, ndjson, ...flags } = cmd;
|
|
15
|
+
.option('--ndjson', 'Emit machine-readable NDJSON output');
|
|
16
|
+
return attachUserFlag(command).action(async (cmd) => {
|
|
17
|
+
const { json, ndjson, user: _user, ...flags } = cmd;
|
|
16
18
|
const view = {
|
|
17
19
|
json: Boolean(json),
|
|
18
20
|
ndjson: Boolean(ndjson),
|
|
19
21
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
const ref = extractUserRef(cmd);
|
|
23
|
+
// Explicit ref must surface a typed miss before `clear()` runs —
|
|
24
|
+
// `clear(ref)` is contractually a no-op on miss, so otherwise
|
|
25
|
+
// `logout --user mistake` would print `✓ Logged out`.
|
|
26
|
+
const needsSnapshot = ref !== undefined || Boolean(options.revokeToken || options.onCleared);
|
|
27
|
+
let snapshot = null;
|
|
28
|
+
if (needsSnapshot) {
|
|
29
|
+
if (ref !== undefined) {
|
|
30
|
+
snapshot = await requireSnapshotForRef(options.store, ref);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
try {
|
|
34
|
+
snapshot = await options.store.active(ref);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Snapshot lookup failures must not block local clear.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
22
41
|
const account = snapshot?.account ?? null;
|
|
23
|
-
await options.store.clear();
|
|
42
|
+
await options.store.clear(ref);
|
|
43
|
+
if (options.revokeToken && snapshot) {
|
|
44
|
+
try {
|
|
45
|
+
await options.revokeToken({
|
|
46
|
+
token: snapshot.token,
|
|
47
|
+
account: snapshot.account,
|
|
48
|
+
view,
|
|
49
|
+
flags,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Best-effort: server revoke failures must not surface to the user.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
24
56
|
if (view.json) {
|
|
25
57
|
console.log(formatJson({ ok: true }));
|
|
26
58
|
}
|
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;AAGvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAyCtF;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAC/B,MAAe,EACf,OAA6C;IAE7C,MAAM,OAAO,GAAG,MAAM;SACjB,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,CAAA;IAC9D,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAA4B,EAAE,EAAE;QACzE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,CAAA;QACnD,MAAM,IAAI,GAA0B;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;SAC1B,CAAA;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QAC/B,iEAAiE;QACjE,8DAA8D;QAC9D,sDAAsD;QACtD,MAAM,aAAa,GAAG,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;QAC5F,IAAI,QAAQ,GAAgD,IAAI,CAAA;QAChE,IAAI,aAAa,EAAE,CAAC;YAChB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACpB,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;YAC9D,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC;oBACD,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAC9C,CAAC;gBAAC,MAAM,CAAC;oBACL,uDAAuD;gBAC3D,CAAC;YACL,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAA;QACzC,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,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;AACN,CAAC"}
|
package/dist/auth/status.d.ts
CHANGED
|
@@ -3,12 +3,9 @@ import type { ViewOptions } from '../options.js';
|
|
|
3
3
|
import type { AuthAccount, TokenStore } from './types.js';
|
|
4
4
|
export type AttachStatusContext<TAccount extends AuthAccount> = {
|
|
5
5
|
account: TAccount;
|
|
6
|
+
/** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
|
|
6
7
|
view: Required<ViewOptions>;
|
|
7
|
-
/**
|
|
8
|
-
* Stripped per-CLI flags — the parsed options object with the standard
|
|
9
|
-
* registrar flags (`--json`, `--ndjson`) removed. Any consumer-attached
|
|
10
|
-
* `.option(...)` lands here (e.g. `--full`, `--user <ref>`).
|
|
11
|
-
*/
|
|
8
|
+
/** Consumer-attached options (e.g. `--full`). The registrar flags (`--json`, `--ndjson`, `--user`) are stripped. */
|
|
12
9
|
flags: Record<string, unknown>;
|
|
13
10
|
};
|
|
14
11
|
export type AttachStatusCommandOptions<TAccount extends AuthAccount = AuthAccount> = {
|
|
@@ -23,6 +20,7 @@ export type AttachStatusCommandOptions<TAccount extends AuthAccount = AuthAccoun
|
|
|
23
20
|
fetchLive?(ctx: {
|
|
24
21
|
account: TAccount;
|
|
25
22
|
token: string;
|
|
23
|
+
/** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
|
|
26
24
|
view: Required<ViewOptions>;
|
|
27
25
|
flags: Record<string, unknown>;
|
|
28
26
|
}): Promise<TAccount>;
|
|
@@ -45,6 +43,7 @@ export type AttachStatusCommandOptions<TAccount extends AuthAccount = AuthAccoun
|
|
|
45
43
|
* `CliError('NOT_AUTHENTICATED', …)`.
|
|
46
44
|
*/
|
|
47
45
|
onNotAuthenticated?(ctx: {
|
|
46
|
+
/** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
|
|
48
47
|
view: Required<ViewOptions>;
|
|
49
48
|
flags: Record<string, unknown>;
|
|
50
49
|
}): void | Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/auth/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/auth/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGzD,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAC5D,OAAO,EAAE,QAAQ,CAAA;IACjB,8EAA8E;IAC9E,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC3B,oHAAoH;IACpH,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,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE;QACZ,OAAO,EAAE,QAAQ,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;QACb,8EAA8E;QAC9E,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;QAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACjC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACrB;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;IAC1E;;;;OAIG;IACH,UAAU,CAAC,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAA;IAChF;;;OAGG;IACH,kBAAkB,CAAC,CAAC,GAAG,EAAE;QACrB,8EAA8E;QAC9E,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;QAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACjC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B,CAAA;AAED;;;;GAIG;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/status.js
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
import { CliError } from '../errors.js';
|
|
2
2
|
import { formatJson, formatNdjson } from '../json.js';
|
|
3
|
+
import { attachUserFlag, extractUserRef, requireSnapshotForRef } from './user-flag.js';
|
|
3
4
|
/**
|
|
4
5
|
* Attach `status` as a subcommand of `parent`. Reads `store.active()`, optionally
|
|
5
6
|
* confirms via `fetchLive`, then dispatches to `renderText` (human) or
|
|
6
7
|
* `renderJson` (machine). Returns the new `Command` so the consumer can chain.
|
|
7
8
|
*/
|
|
8
9
|
export function attachStatusCommand(parent, options) {
|
|
9
|
-
|
|
10
|
+
const command = parent
|
|
10
11
|
.command('status')
|
|
11
12
|
.description(options.description ?? 'Show the current authentication status')
|
|
12
13
|
.option('--json', 'Emit machine-readable JSON output')
|
|
13
|
-
.option('--ndjson', 'Emit machine-readable NDJSON output')
|
|
14
|
-
|
|
15
|
-
const { json, ndjson, ...flags } = cmd;
|
|
14
|
+
.option('--ndjson', 'Emit machine-readable NDJSON output');
|
|
15
|
+
return attachUserFlag(command).action(async (cmd) => {
|
|
16
|
+
const { json, ndjson, user: _user, ...flags } = cmd;
|
|
16
17
|
const view = {
|
|
17
18
|
json: Boolean(json),
|
|
18
19
|
ndjson: Boolean(ndjson),
|
|
19
20
|
};
|
|
20
|
-
const
|
|
21
|
+
const ref = extractUserRef(cmd);
|
|
22
|
+
const snapshot = await requireSnapshotForRef(options.store, ref);
|
|
21
23
|
if (!snapshot) {
|
|
22
24
|
if (options.onNotAuthenticated) {
|
|
23
25
|
await options.onNotAuthenticated({ view, flags });
|
|
@@ -34,16 +36,12 @@ export function attachStatusCommand(parent, options) {
|
|
|
34
36
|
})
|
|
35
37
|
: snapshot.account;
|
|
36
38
|
if (view.json) {
|
|
37
|
-
const payload = options.renderJson
|
|
38
|
-
? options.renderJson({ account, flags })
|
|
39
|
-
: account;
|
|
39
|
+
const payload = options.renderJson ? options.renderJson({ account, flags }) : account;
|
|
40
40
|
console.log(formatJson(payload));
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
if (view.ndjson) {
|
|
44
|
-
const payload = options.renderJson
|
|
45
|
-
? options.renderJson({ account, flags })
|
|
46
|
-
: account;
|
|
44
|
+
const payload = options.renderJson ? options.renderJson({ account, flags }) : account;
|
|
47
45
|
console.log(formatNdjson([payload]));
|
|
48
46
|
return;
|
|
49
47
|
}
|
package/dist/auth/status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/auth/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/auth/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGrD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAgDtF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAC/B,MAAe,EACf,OAA6C;IAE7C,MAAM,OAAO,GAAG,MAAM;SACjB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,wCAAwC,CAAC;SAC5E,MAAM,CAAC,QAAQ,EAAE,mCAAmC,CAAC;SACrD,MAAM,CAAC,UAAU,EAAE,qCAAqC,CAAC,CAAA;IAC9D,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAA4B,EAAE,EAAE;QACzE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,CAAA;QACnD,MAAM,IAAI,GAA0B;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC;SAC1B,CAAA;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QAC/B,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBAC7B,MAAM,OAAO,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;gBACjD,OAAM;YACV,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS;YAC7B,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC;gBACpB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,IAAI;gBACJ,KAAK;aACR,CAAC;YACJ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAA;QACtB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YACrF,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;YAChC,OAAM;QACV,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YACrF,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YACpC,OAAM;QACV,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QACzD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACtD,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-view.d.ts","sourceRoot":"","sources":["../../src/auth/token-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"token-view.d.ts","sourceRoot":"","sources":["../../src/auth/token-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGzD,MAAM,MAAM,6BAA6B,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACpF,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC3B,qGAAqG;IACrG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,EAC7E,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,6BAA6B,CAAC,QAAQ,CAAC,GACjD,OAAO,CAyBT"}
|
package/dist/auth/token-view.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CliError } from '../errors.js';
|
|
2
2
|
import { isStdoutTTY } from '../terminal.js';
|
|
3
|
+
import { attachUserFlag, extractUserRef, requireSnapshotForRef } from './user-flag.js';
|
|
3
4
|
/**
|
|
4
5
|
* Attach a "print the saved token" subcommand to `parent`. Writes the bare
|
|
5
6
|
* token to stdout with no envelope so the output is pipe-safe (e.g. `eval $(td
|
|
@@ -8,10 +9,10 @@ import { isStdoutTTY } from '../terminal.js';
|
|
|
8
9
|
* when no token is stored. Returns the new `Command` for chaining.
|
|
9
10
|
*/
|
|
10
11
|
export function attachTokenViewCommand(parent, options) {
|
|
11
|
-
|
|
12
|
+
const command = parent
|
|
12
13
|
.command(options.name ?? 'token')
|
|
13
|
-
.description(options.description ?? 'Print the saved authentication token')
|
|
14
|
-
|
|
14
|
+
.description(options.description ?? 'Print the saved authentication token');
|
|
15
|
+
return attachUserFlag(command).action(async (cmd) => {
|
|
15
16
|
if (options.envVarName && process.env[options.envVarName]) {
|
|
16
17
|
throw new CliError('TOKEN_FROM_ENV', `Refusing to print: token is being read from $${options.envVarName}, not the saved store.`, {
|
|
17
18
|
hints: [
|
|
@@ -20,7 +21,8 @@ export function attachTokenViewCommand(parent, options) {
|
|
|
20
21
|
],
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
|
-
const
|
|
24
|
+
const ref = extractUserRef(cmd);
|
|
25
|
+
const snapshot = await requireSnapshotForRef(options.store, ref);
|
|
24
26
|
if (!snapshot) {
|
|
25
27
|
throw new CliError('NOT_AUTHENTICATED', 'Not signed in.');
|
|
26
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-view.js","sourceRoot":"","sources":["../../src/auth/token-view.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"token-view.js","sourceRoot":"","sources":["../../src/auth/token-view.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAgBtF;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAClC,MAAe,EACf,OAAgD;IAEhD,MAAM,OAAO,GAAG,MAAM;SACjB,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC;SAChC,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,sCAAsC,CAAC,CAAA;IAC/E,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,GAA4B,EAAE,EAAE;QACzE,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,QAAQ,CACd,gBAAgB,EAChB,gDAAgD,OAAO,CAAC,UAAU,wBAAwB,EAC1F;gBACI,KAAK,EAAE;oBACH,SAAS,OAAO,CAAC,UAAU,4BAA4B;oBACvD,6GAA6G;iBAChH;aACJ,CACJ,CAAA;QACL,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QAC/B,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAA;QAC7D,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACpC,IAAI,WAAW,EAAE;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;AACN,CAAC"}
|
package/dist/auth/types.d.ts
CHANGED
|
@@ -63,22 +63,29 @@ export type AuthProvider<TAccount extends AuthAccount = AuthAccount> = {
|
|
|
63
63
|
/** Skipped when `exchangeCode` already returned an `account`. */
|
|
64
64
|
validateToken(input: ValidateInput): Promise<TAccount>;
|
|
65
65
|
};
|
|
66
|
+
/** Opaque account selector. Stores own the matching rule (id, email, label, …). */
|
|
67
|
+
export type AccountRef = string;
|
|
66
68
|
/**
|
|
67
|
-
* Persistent token + account storage.
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* interface that an inline ~30-line config-file version covers the
|
|
71
|
-
* single-user case.
|
|
69
|
+
* Persistent token + account storage. Uniformly multi-user-shaped — single-user
|
|
70
|
+
* stores implement `list` / `setDefault` against their one stored account (see
|
|
71
|
+
* the README example).
|
|
72
72
|
*/
|
|
73
73
|
export type TokenStore<TAccount extends AuthAccount = AuthAccount> = {
|
|
74
|
-
/**
|
|
75
|
-
active(): Promise<{
|
|
74
|
+
/** Active snapshot, or `null` when nothing matches (the attachers translate a ref miss into `ACCOUNT_NOT_FOUND`). */
|
|
75
|
+
active(ref?: AccountRef): Promise<{
|
|
76
76
|
token: string;
|
|
77
77
|
account: TAccount;
|
|
78
78
|
} | null>;
|
|
79
|
-
/** Persist `token` for `account`, replacing any previous entry. Throw `CliError`
|
|
79
|
+
/** Persist `token` for `account`, replacing any previous entry. Throw `CliError` for typed failures; other thrown values become `AUTH_STORE_WRITE_FAILED`. */
|
|
80
80
|
set(account: TAccount, token: string): Promise<void>;
|
|
81
|
-
/** Remove
|
|
82
|
-
clear(): Promise<void>;
|
|
81
|
+
/** Remove a stored credential. No-op when `ref` doesn't match. */
|
|
82
|
+
clear(ref?: AccountRef): Promise<void>;
|
|
83
|
+
/** Every stored account with a default marker. */
|
|
84
|
+
list(): Promise<ReadonlyArray<{
|
|
85
|
+
account: TAccount;
|
|
86
|
+
isDefault: boolean;
|
|
87
|
+
}>>;
|
|
88
|
+
/** Mark `ref` as the new default. Throw `CliError('ACCOUNT_NOT_FOUND', …)` on miss. */
|
|
89
|
+
setDefault(ref: AccountRef): Promise<void>;
|
|
83
90
|
};
|
|
84
91
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/auth/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,MAAM,WAAW,GAAG;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACrE,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yFAAyF;IACzF,OAAO,CAAC,EAAE,QAAQ,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACnE,8EAA8E;IAC9E,OAAO,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IACrD,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC1D,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;IACrE,iEAAiE;IACjE,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CACzD,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { AccountRef, AuthAccount, TokenStore } from './types.js';
|
|
3
|
+
export declare function attachUserFlag(command: Command): Command;
|
|
4
|
+
/** `cmd.user` as an `AccountRef`, or `undefined` when absent. */
|
|
5
|
+
export declare function extractUserRef(cmd: Record<string, unknown>): AccountRef | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Read `store.active(ref)` and throw `ACCOUNT_NOT_FOUND` if the explicit
|
|
8
|
+
* `ref` doesn't match. With `ref === undefined` returns the snapshot
|
|
9
|
+
* (possibly `null`) unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export declare function requireSnapshotForRef<TAccount extends AuthAccount>(store: TokenStore<TAccount>, ref: AccountRef | undefined): Promise<{
|
|
12
|
+
token: string;
|
|
13
|
+
account: TAccount;
|
|
14
|
+
} | null>;
|
|
15
|
+
//# sourceMappingURL=user-flag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-flag.d.ts","sourceRoot":"","sources":["../../src/auth/user-flag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AASrE,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAExD;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,GAAG,SAAS,CAEnF;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,SAAS,WAAW,EACpE,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,EAC3B,GAAG,EAAE,UAAU,GAAG,SAAS,GAC5B,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAAC,CAMtD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CliError } from '../errors.js';
|
|
2
|
+
// Shared `--user <ref>` wiring + snapshot-or-throw helper so the three auth
|
|
3
|
+
// attachers can't drift on flag wording or miss semantics. Internal — not
|
|
4
|
+
// re-exported.
|
|
5
|
+
const USER_FLAG = '--user <ref>';
|
|
6
|
+
const USER_FLAG_DESCRIPTION = 'Target a specific stored account';
|
|
7
|
+
export function attachUserFlag(command) {
|
|
8
|
+
return command.option(USER_FLAG, USER_FLAG_DESCRIPTION);
|
|
9
|
+
}
|
|
10
|
+
/** `cmd.user` as an `AccountRef`, or `undefined` when absent. */
|
|
11
|
+
export function extractUserRef(cmd) {
|
|
12
|
+
return typeof cmd.user === 'string' ? cmd.user : undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read `store.active(ref)` and throw `ACCOUNT_NOT_FOUND` if the explicit
|
|
16
|
+
* `ref` doesn't match. With `ref === undefined` returns the snapshot
|
|
17
|
+
* (possibly `null`) unchanged.
|
|
18
|
+
*/
|
|
19
|
+
export async function requireSnapshotForRef(store, ref) {
|
|
20
|
+
const snapshot = await store.active(ref);
|
|
21
|
+
if (ref !== undefined && snapshot === null) {
|
|
22
|
+
throw new CliError('ACCOUNT_NOT_FOUND', `No stored account matches "${ref}".`);
|
|
23
|
+
}
|
|
24
|
+
return snapshot;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=user-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-flag.js","sourceRoot":"","sources":["../../src/auth/user-flag.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGvC,4EAA4E;AAC5E,0EAA0E;AAC1E,eAAe;AAEf,MAAM,SAAS,GAAG,cAAc,CAAA;AAChC,MAAM,qBAAqB,GAAG,kCAAkC,CAAA;AAEhE,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC3C,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAA;AAC3D,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,cAAc,CAAC,GAA4B;IACvD,OAAO,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACvC,KAA2B,EAC3B,GAA2B;IAE3B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,GAAG,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACzC,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,8BAA8B,GAAG,IAAI,CAAC,CAAA;IAClF,CAAC;IACD,OAAO,QAAQ,CAAA;AACnB,CAAC"}
|
package/dist/global-args.d.ts
CHANGED
|
@@ -20,25 +20,39 @@ export type GlobalArgs = Required<Pick<ViewOptions, 'json' | 'ndjson'>> & {
|
|
|
20
20
|
noSpinner: boolean;
|
|
21
21
|
/** false = absent, true = present without path, string = path. */
|
|
22
22
|
progressJsonl: string | true | false;
|
|
23
|
+
/** Account selector from `--user <ref>` / `--user=<ref>`; `undefined` when absent or valueless. */
|
|
24
|
+
user?: string;
|
|
23
25
|
};
|
|
24
26
|
/**
|
|
25
27
|
* Parse well-known global flags from `argv`. Pure — pass an explicit array
|
|
26
28
|
* for testing, or omit to read `process.argv.slice(2)`.
|
|
27
29
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* matching
|
|
31
|
-
*
|
|
32
|
-
* The trade-off is intentional — callers run this before Commander has
|
|
33
|
-
* parsed argv, so we can't yet distinguish positionals from option values.
|
|
30
|
+
* Runs before Commander so it can't distinguish positionals from option
|
|
31
|
+
* values: a positional that looks like a global short flag
|
|
32
|
+
* (`td comment add 123 -q`) flips the matching state. Use the `--`
|
|
33
|
+
* terminator to stop the parser before a positional that needs protecting.
|
|
34
34
|
*
|
|
35
|
-
* `--progress-jsonl` accepts only the bare form
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
35
|
+
* `--progress-jsonl` accepts only the bare form and the `=path` form; the
|
|
36
|
+
* space-separated form would silently consume the next positional (e.g.
|
|
37
|
+
* `td task add --progress-jsonl "Buy milk"` would treat `Buy milk` as a
|
|
38
|
+
* file path). `--user` accepts both forms but never consumes a following
|
|
39
|
+
* flag — pair with `stripUserFlag` before forwarding argv to Commander.
|
|
40
40
|
*/
|
|
41
41
|
export declare function parseGlobalArgs(argv?: string[]): GlobalArgs;
|
|
42
|
+
/**
|
|
43
|
+
* Strip pre-subcommand `--user` tokens so a Commander program with no root
|
|
44
|
+
* `--user` option doesn't trip on the flag. Stops at the first non-flag
|
|
45
|
+
* token (including `--` and the empty string) so subcommand-level `--user`
|
|
46
|
+
* — attached by the auth attachers — still reaches Commander.
|
|
47
|
+
*
|
|
48
|
+
* Assumes `--user` is the only space-separated root option. CLIs that
|
|
49
|
+
* attach other root options taking values (e.g. `--profile <name>`) must
|
|
50
|
+
* either strip those first or attach `--user` on the root program directly
|
|
51
|
+
* — this helper only knows about `--user`.
|
|
52
|
+
*
|
|
53
|
+
* Pure; does not mutate `argv`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function stripUserFlag(argv: string[]): string[];
|
|
42
56
|
export type GlobalArgsStore<T extends GlobalArgs = GlobalArgs> = {
|
|
43
57
|
get(): T;
|
|
44
58
|
/** Clear the cached parse result. Call from test teardown. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-args.d.ts","sourceRoot":"","sources":["../src/global-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,GAAG;IACtE,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"global-args.d.ts","sourceRoot":"","sources":["../src/global-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,GAAG;IACtE,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC1B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAA;IACpC,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAiCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAuD3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAoBtD;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI;IAC7D,GAAG,IAAI,CAAC,CAAA;IACR,8DAA8D;IAC9D,KAAK,IAAI,IAAI,CAAA;CAChB,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAAC,UAAU,CAAC,CAAA;AACpE,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AAkB/F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED,MAAM,MAAM,qBAAqB,GAAG;IAChC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,UAAU,CAAA;CAC5B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,OAAO,CAE/E;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC7B,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,UAAU,CAAA;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,OAAO,CAAA;CAChC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,OAAO,CAgBzE"}
|
package/dist/global-args.js
CHANGED
|
@@ -17,22 +17,41 @@ const SHORT_FLAGS = {
|
|
|
17
17
|
q: 'quiet',
|
|
18
18
|
v: 'verbose',
|
|
19
19
|
};
|
|
20
|
+
/** Whether `token` is a usable value for a space-separated long option (not absent, not `--`, not another flag). */
|
|
21
|
+
function isFlagValue(token) {
|
|
22
|
+
return token !== undefined && token !== '--' && !token.startsWith('-');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* If `argv[i]` is a `--user` token, return how to consume it; otherwise `null`.
|
|
26
|
+
* `consumed` is the number of argv slots the token occupies (2 for the
|
|
27
|
+
* space form, 1 for `--user=val` / valueless).
|
|
28
|
+
*/
|
|
29
|
+
function readUserFlagAt(argv, i) {
|
|
30
|
+
const arg = argv[i];
|
|
31
|
+
if (arg === '--user') {
|
|
32
|
+
const next = argv[i + 1];
|
|
33
|
+
return isFlagValue(next) ? { value: next, consumed: 2 } : { value: undefined, consumed: 1 };
|
|
34
|
+
}
|
|
35
|
+
if (arg.startsWith('--user=')) {
|
|
36
|
+
const value = arg.slice('--user='.length);
|
|
37
|
+
return { value: value !== '' ? value : undefined, consumed: 1 };
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
20
41
|
/**
|
|
21
42
|
* Parse well-known global flags from `argv`. Pure — pass an explicit array
|
|
22
43
|
* for testing, or omit to read `process.argv.slice(2)`.
|
|
23
44
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* matching
|
|
27
|
-
*
|
|
28
|
-
* The trade-off is intentional — callers run this before Commander has
|
|
29
|
-
* parsed argv, so we can't yet distinguish positionals from option values.
|
|
45
|
+
* Runs before Commander so it can't distinguish positionals from option
|
|
46
|
+
* values: a positional that looks like a global short flag
|
|
47
|
+
* (`td comment add 123 -q`) flips the matching state. Use the `--`
|
|
48
|
+
* terminator to stop the parser before a positional that needs protecting.
|
|
30
49
|
*
|
|
31
|
-
* `--progress-jsonl` accepts only the bare form
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
50
|
+
* `--progress-jsonl` accepts only the bare form and the `=path` form; the
|
|
51
|
+
* space-separated form would silently consume the next positional (e.g.
|
|
52
|
+
* `td task add --progress-jsonl "Buy milk"` would treat `Buy milk` as a
|
|
53
|
+
* file path). `--user` accepts both forms but never consumes a following
|
|
54
|
+
* flag — pair with `stripUserFlag` before forwarding argv to Commander.
|
|
36
55
|
*/
|
|
37
56
|
export function parseGlobalArgs(argv) {
|
|
38
57
|
const args = argv ?? process.argv.slice(2);
|
|
@@ -73,6 +92,14 @@ export function parseGlobalArgs(argv) {
|
|
|
73
92
|
else if (arg.startsWith('--progress-jsonl=')) {
|
|
74
93
|
result.progressJsonl = arg.slice('--progress-jsonl='.length);
|
|
75
94
|
}
|
|
95
|
+
else if (arg === '--user' || arg.startsWith('--user=')) {
|
|
96
|
+
const consumed = readUserFlagAt(args, i);
|
|
97
|
+
if (consumed) {
|
|
98
|
+
if (consumed.value !== undefined)
|
|
99
|
+
result.user = consumed.value;
|
|
100
|
+
i += consumed.consumed - 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
76
103
|
else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') {
|
|
77
104
|
// Short-flag group: -v, -vq, -vvv, etc. Unknown shorts are
|
|
78
105
|
// silently ignored — they belong to Commander or subcommands.
|
|
@@ -89,6 +116,41 @@ export function parseGlobalArgs(argv) {
|
|
|
89
116
|
}
|
|
90
117
|
return result;
|
|
91
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Strip pre-subcommand `--user` tokens so a Commander program with no root
|
|
121
|
+
* `--user` option doesn't trip on the flag. Stops at the first non-flag
|
|
122
|
+
* token (including `--` and the empty string) so subcommand-level `--user`
|
|
123
|
+
* — attached by the auth attachers — still reaches Commander.
|
|
124
|
+
*
|
|
125
|
+
* Assumes `--user` is the only space-separated root option. CLIs that
|
|
126
|
+
* attach other root options taking values (e.g. `--profile <name>`) must
|
|
127
|
+
* either strip those first or attach `--user` on the root program directly
|
|
128
|
+
* — this helper only knows about `--user`.
|
|
129
|
+
*
|
|
130
|
+
* Pure; does not mutate `argv`.
|
|
131
|
+
*/
|
|
132
|
+
export function stripUserFlag(argv) {
|
|
133
|
+
const result = [];
|
|
134
|
+
let i = 0;
|
|
135
|
+
while (i < argv.length) {
|
|
136
|
+
const arg = argv[i];
|
|
137
|
+
if (arg === '--' || isFlagValue(arg)) {
|
|
138
|
+
// First non-flag token (positional, `--`, or empty string) ends
|
|
139
|
+
// the scan; copy the rest verbatim for Commander.
|
|
140
|
+
for (let j = i; j < argv.length; j++)
|
|
141
|
+
result.push(argv[j]);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
const consumed = readUserFlagAt(argv, i);
|
|
145
|
+
if (consumed) {
|
|
146
|
+
i += consumed.consumed;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
result.push(arg);
|
|
150
|
+
i += 1;
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
92
154
|
export function createGlobalArgsStore(parse) {
|
|
93
155
|
// Overloads ensure callers passing a custom `T` must supply a matching
|
|
94
156
|
// parser; the implementation default only kicks in for the no-arg
|
package/dist/global-args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-args.js","sourceRoot":"","sources":["../src/global-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"global-args.js","sourceRoot":"","sources":["../src/global-args.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type { ConfigErrorCode, CoreConfig, ReadConfigStrictResult, UpdateChannel
|
|
|
3
3
|
export { printEmpty } from './empty.js';
|
|
4
4
|
export { CliError, getErrorMessage } from './errors.js';
|
|
5
5
|
export type { CliErrorCode, CliErrorOptions, ErrorType } from './errors.js';
|
|
6
|
-
export { createAccessibleGate, createGlobalArgsStore, createSpinnerGate, getProgressJsonlPath, isProgressJsonlEnabled, parseGlobalArgs, } from './global-args.js';
|
|
6
|
+
export { createAccessibleGate, createGlobalArgsStore, createSpinnerGate, getProgressJsonlPath, isProgressJsonlEnabled, parseGlobalArgs, stripUserFlag, } from './global-args.js';
|
|
7
7
|
export type { AccessibleGateOptions, GlobalArgs, GlobalArgsStore, SpinnerGateOptions, } from './global-args.js';
|
|
8
8
|
export { formatJson, formatNdjson } from './json.js';
|
|
9
9
|
export { emitView } from './options.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,WAAW,GACd,MAAM,aAAa,CAAA;AACpB,YAAY,EACR,eAAe,EACf,UAAU,EACV,sBAAsB,EACtB,aAAa,EACb,kBAAkB,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EACH,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,WAAW,GACd,MAAM,aAAa,CAAA;AACpB,YAAY,EACR,eAAe,EACf,UAAU,EACV,sBAAsB,EACtB,aAAa,EACb,kBAAkB,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EACH,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,aAAa,GAChB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACR,qBAAqB,EACrB,UAAU,EACV,eAAe,EACf,kBAAkB,GACrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,YAAY,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,cAAc,GACjB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { BROKEN_CONFIG_STATE_TO_CODE, getConfigPath, readConfig, readConfigOrThrow, readConfigStrict, updateConfig, updateConfigOrThrow, writeConfig, } from './config.js';
|
|
2
2
|
export { printEmpty } from './empty.js';
|
|
3
3
|
export { CliError, getErrorMessage } from './errors.js';
|
|
4
|
-
export { createAccessibleGate, createGlobalArgsStore, createSpinnerGate, getProgressJsonlPath, isProgressJsonlEnabled, parseGlobalArgs, } from './global-args.js';
|
|
4
|
+
export { createAccessibleGate, createGlobalArgsStore, createSpinnerGate, getProgressJsonlPath, isProgressJsonlEnabled, parseGlobalArgs, stripUserFlag, } from './global-args.js';
|
|
5
5
|
export { formatJson, formatNdjson } from './json.js';
|
|
6
6
|
export { emitView } from './options.js';
|
|
7
7
|
export { createSpinner } from './spinner.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,WAAW,GACd,MAAM,aAAa,CAAA;AAQpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EACH,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,WAAW,GACd,MAAM,aAAa,CAAA;AAQpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EACH,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,aAAa,GAChB,MAAM,kBAAkB,CAAA;AAOzB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQ5C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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.2",
|
|
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",
|