@doist/cli-core 0.12.0 → 0.14.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 +12 -0
- package/README.md +44 -15
- package/dist/auth/errors.d.ts +1 -1
- package/dist/auth/errors.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/keyring/index.d.ts +3 -0
- package/dist/auth/keyring/index.d.ts.map +1 -0
- package/dist/auth/keyring/index.js +2 -0
- package/dist/auth/keyring/index.js.map +1 -0
- package/dist/auth/keyring/secure-store.d.ts +39 -0
- package/dist/auth/keyring/secure-store.d.ts.map +1 -0
- package/dist/auth/keyring/secure-store.js +71 -0
- package/dist/auth/keyring/secure-store.js.map +1 -0
- package/dist/auth/logout.d.ts +9 -2
- package/dist/auth/logout.d.ts.map +1 -1
- package/dist/auth/logout.js +22 -11
- package/dist/auth/logout.js.map +1 -1
- package/dist/auth/types.d.ts +9 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [0.14.0](https://github.com/Doist/cli-core/compare/v0.13.0...v0.14.0) (2026-05-16)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **auth:** tolerate AUTH_STORE_READ_FAILED in logout --user ([#26](https://github.com/Doist/cli-core/issues/26)) ([23652bc](https://github.com/Doist/cli-core/commit/23652bcb436fda917bc10aba99918ce1503786b6))
|
|
6
|
+
|
|
7
|
+
## [0.13.0](https://github.com/Doist/cli-core/compare/v0.12.0...v0.13.0) (2026-05-16)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **auth:** add createSecureStore keyring primitive (1/4) ([#25](https://github.com/Doist/cli-core/issues/25)) ([30bcbd7](https://github.com/Doist/cli-core/commit/30bcbd7e49aede98d0777424169324af03f56eaf))
|
|
12
|
+
|
|
1
13
|
## [0.12.0](https://github.com/Doist/cli-core/compare/v0.11.0...v0.12.0) (2026-05-14)
|
|
2
14
|
|
|
3
15
|
### 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` / `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`)
|
|
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`, `stripUserFlag`, `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`, `createSecureStore`, PKCE helpers, `AuthProvider` / `TokenStore` / `AccountRef` / `SecureStore` 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`) and a thin cross-platform OS-keyring wrapper (`createSecureStore`) backed by `@napi-rs/keyring`. `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), `open` (browser launch), and `@napi-rs/keyring` (when using `createSecureStore`) are optional peer/optional 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
|
|
|
@@ -213,7 +213,7 @@ attachTokenViewCommand<Account>(auth, {
|
|
|
213
213
|
})
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
`attachLogoutCommand` snapshots `store.active()`
|
|
216
|
+
`attachLogoutCommand` snapshots `store.active(ref)` when either `--user <ref>` is supplied or one of the consumer hooks (`revokeToken` / `onCleared`) needs the prior account, calls `store.clear(ref)`, awaits `revokeToken({ token, account, ref, view, flags })` for best-effort server-side revocation, emits `✓ Logged out` (human) or `{ "ok": true }` (`--json`, silent under `--ndjson`), and finally fires `onCleared({ account, ref, view, flags })`. `ref` is the parsed `--user` argument (or `undefined`) so consumers can distinguish "nothing was stored" (`account: null`, `ref: undefined`) from "cleared an unreadable record by ref" (`account: null`, `ref: "me"`). `revokeToken` failures are always swallowed; the pre-flight snapshot's error contract is covered in the `--user <ref>` section below. The exported `AttachLogoutRevokeContext<TAccount>` is the ctx type for typing standalone revoke implementations.
|
|
217
217
|
|
|
218
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.
|
|
219
219
|
|
|
@@ -288,6 +288,33 @@ export const tokenStore: TokenStore<Account> = {
|
|
|
288
288
|
|
|
289
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
290
|
|
|
291
|
+
#### Keyring primitive (`createSecureStore`)
|
|
292
|
+
|
|
293
|
+
When the OS credential manager is the right place for your token, `createSecureStore` is a thin cross-platform wrapper around `@napi-rs/keyring`. It exposes a three-method handle (`getSecret` / `setSecret` / `deleteSecret`) for one slot identified by `serviceName` + `account`:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import { createSecureStore, SecureStoreUnavailableError } from '@doist/cli-core/auth'
|
|
297
|
+
|
|
298
|
+
const slot = createSecureStore({ serviceName: 'todoist-cli', account: 'api-token' })
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
await slot.setSecret(token)
|
|
302
|
+
} catch (error) {
|
|
303
|
+
if (error instanceof SecureStoreUnavailableError) {
|
|
304
|
+
// Keyring unreachable (WSL without D-Bus, missing native binary on an
|
|
305
|
+
// exotic arch, Keychain locked, …). Fall back to wherever your CLI
|
|
306
|
+
// stores fallback state — config file with a clear plaintext warning,
|
|
307
|
+
// an env-var prompt, etc.
|
|
308
|
+
} else {
|
|
309
|
+
throw error
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Every failure mode — `@napi-rs/keyring` failing to load on an arch without a prebuilt binary, libsecret not running on a headless Linux box, the Keychain prompting and the user denying — is normalised into `SecureStoreUnavailableError`. The `@napi-rs/keyring` module is dynamic-imported so a missing native binary doesn't crash module load before the error can surface.
|
|
315
|
+
|
|
316
|
+
`@napi-rs/keyring` is declared in cli-core's own `optionalDependencies`, so npm pulls it in transitively when you install `@doist/cli-core` — your consumer CLI does not need to add it explicitly. The library ships pre-built native binaries for Windows (Credential Manager), macOS (Keychain), and Linux glibc + musl (libsecret / Secret Service).
|
|
317
|
+
|
|
291
318
|
#### `--user <ref>` and multi-user wiring
|
|
292
319
|
|
|
293
320
|
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.
|
|
@@ -311,6 +338,8 @@ Account-selection resolvers (env > `--user` > default > single-only > error), `a
|
|
|
311
338
|
|
|
312
339
|
`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.
|
|
313
340
|
|
|
341
|
+
A `TokenStore` MAY throw `CliError('AUTH_STORE_READ_FAILED', …)` from `active(ref)` when a matching record exists but the token itself can't be read (e.g. an OS keyring backing the store is offline). `attachLogoutCommand` catches this specific code on the explicit-ref path and proceeds with `clear(ref)` — local logout doesn't need the token, and the `revokeToken` hook is skipped because there's no token to send. Every other error from `active(ref)` (notably `ACCOUNT_NOT_FOUND` from a genuine ref miss, plus any consumer-thrown code) still propagates so a real miss isn't masked. Without `--user`, the logout pre-flight swallows any snapshot read failure so the local clear always runs. `attachStatusCommand` and `attachTokenViewCommand` propagate `AUTH_STORE_READ_FAILED` since they have no way to render or print without the token.
|
|
342
|
+
|
|
314
343
|
#### Custom `AuthProvider` (non-PKCE flows)
|
|
315
344
|
|
|
316
345
|
Implement `AuthProvider` directly for Dynamic Client Registration, device code, magic-link, etc. The four hooks fire in this order during `runOAuthFlow`:
|
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' | 'NO_ACCOUNT_SELECTED' | 'ACCOUNT_NOT_FOUND';
|
|
6
|
+
export type AuthErrorCode = 'AUTH_OAUTH_FAILED' | 'AUTH_CALLBACK_TIMEOUT' | 'AUTH_PORT_BIND_FAILED' | 'AUTH_TOKEN_EXCHANGE_FAILED' | 'AUTH_STORE_WRITE_FAILED' | 'AUTH_STORE_READ_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,GAChB,qBAAqB,GACrB,mBAAmB,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,wBAAwB,GACxB,mBAAmB,GACnB,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,CAAA"}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -14,4 +14,6 @@ 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
16
|
export type { AccountRef, AuthAccount, AuthorizeInput, AuthorizeResult, AuthProvider, ExchangeInput, ExchangeResult, PrepareInput, PrepareResult, TokenStore, ValidateInput, } from './types.js';
|
|
17
|
+
export { SecureStoreUnavailableError, createSecureStore } from './keyring/index.js';
|
|
18
|
+
export type { CreateSecureStoreOptions, SecureStore } from './keyring/index.js';
|
|
17
19
|
//# 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,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"}
|
|
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;AACnB,OAAO,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACnF,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/auth/index.js
CHANGED
|
@@ -5,4 +5,5 @@ export { attachStatusCommand } from './status.js';
|
|
|
5
5
|
export { attachTokenViewCommand } from './token-view.js';
|
|
6
6
|
export { DEFAULT_VERIFIER_ALPHABET, deriveChallenge, generateState, generateVerifier, } from './pkce.js';
|
|
7
7
|
export { createPkceProvider } from './providers/pkce.js';
|
|
8
|
+
export { SecureStoreUnavailableError, createSecureStore } from './keyring/index.js';
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
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;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"}
|
|
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;AAexD,OAAO,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAClF,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/keyring/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown when the OS credential manager cannot be reached — missing native
|
|
3
|
+
* binary for the current architecture, libsecret/D-Bus unavailable
|
|
4
|
+
* (common in WSL / headless Linux / containers / CI), Keychain locked, or
|
|
5
|
+
* any other error returned by the underlying keyring backend.
|
|
6
|
+
*
|
|
7
|
+
* The original throwable is preserved on `cause` so platform-specific
|
|
8
|
+
* diagnostics (stack, native error code) aren't lost — callers that want
|
|
9
|
+
* to degrade to a plaintext fallback should catch this specific class
|
|
10
|
+
* rather than swallowing every `Error`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class SecureStoreUnavailableError extends Error {
|
|
13
|
+
constructor(message?: string, options?: {
|
|
14
|
+
cause?: unknown;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export type SecureStore = {
|
|
18
|
+
getSecret(): Promise<string | null>;
|
|
19
|
+
setSecret(secret: string): Promise<void>;
|
|
20
|
+
deleteSecret(): Promise<boolean>;
|
|
21
|
+
};
|
|
22
|
+
export type CreateSecureStoreOptions = {
|
|
23
|
+
/** Stable per-application identifier (Keychain "service", Credential Manager "target prefix", libsecret "service"). */
|
|
24
|
+
serviceName: string;
|
|
25
|
+
/** Per-credential identifier within the service. For multi-account CLIs, typically `user-${id}`. */
|
|
26
|
+
account: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Thin wrapper around `@napi-rs/keyring` that normalizes every failure mode
|
|
30
|
+
* into `SecureStoreUnavailableError`. `serviceName` + `account` together
|
|
31
|
+
* identify one credential slot in the OS keyring.
|
|
32
|
+
*
|
|
33
|
+
* The dynamic import + `AsyncEntry` construction is memoised per-store so
|
|
34
|
+
* repeated reads/writes share one entry and a missing native binary
|
|
35
|
+
* fast-fails on subsequent calls instead of retrying the import every time
|
|
36
|
+
* (the rejected promise replays its rejection on each `await`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSecureStore(options: CreateSecureStoreOptions): SecureStore;
|
|
39
|
+
//# sourceMappingURL=secure-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/secure-store.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBAE9C,OAAO,SAA6C,EACpD,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKpC;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACnC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACnC,uHAAuH;IACvH,WAAW,EAAE,MAAM,CAAA;IACnB,oGAAoG;IACpG,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAID;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAoChF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { getErrorMessage } from '../../errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when the OS credential manager cannot be reached — missing native
|
|
4
|
+
* binary for the current architecture, libsecret/D-Bus unavailable
|
|
5
|
+
* (common in WSL / headless Linux / containers / CI), Keychain locked, or
|
|
6
|
+
* any other error returned by the underlying keyring backend.
|
|
7
|
+
*
|
|
8
|
+
* The original throwable is preserved on `cause` so platform-specific
|
|
9
|
+
* diagnostics (stack, native error code) aren't lost — callers that want
|
|
10
|
+
* to degrade to a plaintext fallback should catch this specific class
|
|
11
|
+
* rather than swallowing every `Error`.
|
|
12
|
+
*/
|
|
13
|
+
export class SecureStoreUnavailableError extends Error {
|
|
14
|
+
constructor(message = 'System credential storage is unavailable', options) {
|
|
15
|
+
super(message, options);
|
|
16
|
+
this.name = 'SecureStoreUnavailableError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Thin wrapper around `@napi-rs/keyring` that normalizes every failure mode
|
|
21
|
+
* into `SecureStoreUnavailableError`. `serviceName` + `account` together
|
|
22
|
+
* identify one credential slot in the OS keyring.
|
|
23
|
+
*
|
|
24
|
+
* The dynamic import + `AsyncEntry` construction is memoised per-store so
|
|
25
|
+
* repeated reads/writes share one entry and a missing native binary
|
|
26
|
+
* fast-fails on subsequent calls instead of retrying the import every time
|
|
27
|
+
* (the rejected promise replays its rejection on each `await`).
|
|
28
|
+
*/
|
|
29
|
+
export function createSecureStore(options) {
|
|
30
|
+
const { serviceName, account } = options;
|
|
31
|
+
let entryPromise;
|
|
32
|
+
async function withEntry(fn) {
|
|
33
|
+
if (!entryPromise) {
|
|
34
|
+
// Dynamic import: `@napi-rs/keyring` is an optional dependency.
|
|
35
|
+
// On unsupported architectures the native binary is absent and
|
|
36
|
+
// a static import would crash module load before we can surface
|
|
37
|
+
// `SecureStoreUnavailableError`.
|
|
38
|
+
entryPromise = (async () => {
|
|
39
|
+
const { AsyncEntry } = await import('@napi-rs/keyring');
|
|
40
|
+
return new AsyncEntry(serviceName, account);
|
|
41
|
+
})();
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const entry = await entryPromise;
|
|
45
|
+
return await fn(entry);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw toUnavailableError(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
async getSecret() {
|
|
53
|
+
return withEntry(async (entry) => (await entry.getPassword()) ?? null);
|
|
54
|
+
},
|
|
55
|
+
async setSecret(secret) {
|
|
56
|
+
return withEntry(async (entry) => {
|
|
57
|
+
await entry.setPassword(secret);
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
async deleteSecret() {
|
|
61
|
+
return withEntry((entry) => entry.deleteCredential());
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function toUnavailableError(error) {
|
|
66
|
+
if (error instanceof SecureStoreUnavailableError) {
|
|
67
|
+
return error;
|
|
68
|
+
}
|
|
69
|
+
return new SecureStoreUnavailableError(getErrorMessage(error), { cause: error });
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=secure-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../../../src/auth/keyring/secure-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAClD,YACI,OAAO,GAAG,0CAA0C,EACpD,OAA6B;QAE7B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAA;IAC7C,CAAC;CACJ;AAiBD;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAiC;IAC/D,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;IACxC,IAAI,YAA6C,CAAA;IAEjD,KAAK,UAAU,SAAS,CAAI,EAAqC;QAC7D,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,gEAAgE;YAChE,+DAA+D;YAC/D,gEAAgE;YAChE,iCAAiC;YACjC,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;gBACvB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;gBACvD,OAAO,IAAI,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;YAC/C,CAAC,CAAC,EAAE,CAAA;QACR,CAAC;QACD,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAA;YAChC,OAAO,MAAM,EAAE,CAAC,KAAK,CAAC,CAAA;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,CAAC,SAAS;YACX,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,CAAA;QAC1E,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,MAAM;YAClB,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBAC7B,MAAM,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC,CAAC,CAAA;QACN,CAAC;QACD,KAAK,CAAC,YAAY;YACd,OAAO,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAA;QACzD,CAAC;KACJ,CAAA;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACtC,IAAI,KAAK,YAAY,2BAA2B,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,IAAI,2BAA2B,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;AACpF,CAAC"}
|
package/dist/auth/logout.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
2
|
import type { ViewOptions } from '../options.js';
|
|
3
|
-
import type { AuthAccount, TokenStore } from './types.js';
|
|
3
|
+
import type { AccountRef, AuthAccount, TokenStore } from './types.js';
|
|
4
4
|
export type AttachLogoutContext<TAccount extends AuthAccount> = {
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* The account that was active immediately before `clear()` ran, or
|
|
7
|
+
* `null` if nothing was stored. Also `null` on the `AUTH_STORE_READ_FAILED`
|
|
8
|
+
* recovery path (matching record existed but the token wasn't readable);
|
|
9
|
+
* `ref` is still populated in that case so consumers can distinguish.
|
|
10
|
+
*/
|
|
6
11
|
account: TAccount | null;
|
|
12
|
+
/** The `--user <ref>` value, or `undefined` when not supplied. Always present so consumers can tell "no stored account" from "cleared an unreadable account by ref". */
|
|
13
|
+
ref: AccountRef | undefined;
|
|
7
14
|
/** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
|
|
8
15
|
view: Required<ViewOptions>;
|
|
9
16
|
/** Consumer-attached options. The registrar flags (`--json`, `--ndjson`, `--user`) are stripped. */
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/auth/logout.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,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGrE,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAC5D;;;;;OAKG;IACH,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAA;IACxB,wKAAwK;IACxK,GAAG,EAAE,UAAU,GAAG,SAAS,CAAA;IAC3B,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,CA+DT"}
|
package/dist/auth/logout.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CliError } from '../errors.js';
|
|
1
2
|
import { formatJson } from '../json.js';
|
|
2
3
|
import { attachUserFlag, extractUserRef, requireSnapshotForRef } from './user-flag.js';
|
|
3
4
|
/**
|
|
@@ -20,21 +21,30 @@ export function attachLogoutCommand(parent, options) {
|
|
|
20
21
|
ndjson: Boolean(ndjson),
|
|
21
22
|
};
|
|
22
23
|
const ref = extractUserRef(cmd);
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// `logout --user mistake` would print
|
|
24
|
+
// Snapshot only when something downstream needs it:
|
|
25
|
+
// - an explicit `--user <ref>` must surface a typed miss before
|
|
26
|
+
// `clear()` runs (otherwise `logout --user mistake` would print
|
|
27
|
+
// `✓ Logged out` after a no-op clear);
|
|
28
|
+
// - either consumer hook is supplied and wants the prior account.
|
|
29
|
+
// `requireSnapshotForRef` handles both `ref === undefined` (returns
|
|
30
|
+
// the snapshot directly) and the explicit-ref path (throws
|
|
31
|
+
// `ACCOUNT_NOT_FOUND` on a null snapshot), so one call covers both.
|
|
26
32
|
const needsSnapshot = ref !== undefined || Boolean(options.revokeToken || options.onCleared);
|
|
27
33
|
let snapshot = null;
|
|
28
34
|
if (needsSnapshot) {
|
|
29
|
-
|
|
35
|
+
try {
|
|
30
36
|
snapshot = await requireSnapshotForRef(options.store, ref);
|
|
31
37
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
catch (error) {
|
|
39
|
+
// Without an explicit ref, any snapshot read failure must
|
|
40
|
+
// not block local clear (we just lose the hooks' account
|
|
41
|
+
// context). With an explicit ref, `AUTH_STORE_READ_FAILED`
|
|
42
|
+
// is the only recoverable case — clear can still run
|
|
43
|
+
// without the token. Everything else (notably
|
|
44
|
+
// `ACCOUNT_NOT_FOUND` from a genuine ref miss) propagates.
|
|
45
|
+
if (ref !== undefined &&
|
|
46
|
+
!(error instanceof CliError && error.code === 'AUTH_STORE_READ_FAILED')) {
|
|
47
|
+
throw error;
|
|
38
48
|
}
|
|
39
49
|
}
|
|
40
50
|
}
|
|
@@ -45,6 +55,7 @@ export function attachLogoutCommand(parent, options) {
|
|
|
45
55
|
await options.revokeToken({
|
|
46
56
|
token: snapshot.token,
|
|
47
57
|
account: snapshot.account,
|
|
58
|
+
ref,
|
|
48
59
|
view,
|
|
49
60
|
flags,
|
|
50
61
|
});
|
|
@@ -59,7 +70,7 @@ export function attachLogoutCommand(parent, options) {
|
|
|
59
70
|
else if (!view.ndjson) {
|
|
60
71
|
console.log('✓ Logged out');
|
|
61
72
|
}
|
|
62
|
-
await options.onCleared?.({ account, view, flags });
|
|
73
|
+
await options.onCleared?.({ account, ref, view, flags });
|
|
63
74
|
});
|
|
64
75
|
}
|
|
65
76
|
//# sourceMappingURL=logout.js.map
|
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;AAGvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/auth/logout.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/types.d.ts
CHANGED
|
@@ -71,7 +71,15 @@ export type AccountRef = string;
|
|
|
71
71
|
* the README example).
|
|
72
72
|
*/
|
|
73
73
|
export type TokenStore<TAccount extends AuthAccount = AuthAccount> = {
|
|
74
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Active snapshot, or `null` when nothing matches (the attachers translate
|
|
76
|
+
* a ref miss into `ACCOUNT_NOT_FOUND`). A store MAY throw
|
|
77
|
+
* `CliError('AUTH_STORE_READ_FAILED', …)` when a matching record exists
|
|
78
|
+
* but the token itself can't be read (e.g. an OS keyring backing the
|
|
79
|
+
* store is offline) — `attachLogoutCommand` catches that code on the
|
|
80
|
+
* explicit-ref path and proceeds with `clear(ref)`; `attachStatusCommand`
|
|
81
|
+
* and `attachTokenViewCommand` propagate it.
|
|
82
|
+
*/
|
|
75
83
|
active(ref?: AccountRef): Promise<{
|
|
76
84
|
token: string;
|
|
77
85
|
account: TAccount;
|
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,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAA;AAE/B;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,IAAI;IACjE
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Shared core utilities for Doist CLI projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -83,6 +83,9 @@
|
|
|
83
83
|
"chalk": "5.6.2",
|
|
84
84
|
"yocto-spinner": "1.2.0"
|
|
85
85
|
},
|
|
86
|
+
"optionalDependencies": {
|
|
87
|
+
"@napi-rs/keyring": "1.3.0"
|
|
88
|
+
},
|
|
86
89
|
"peerDependencies": {
|
|
87
90
|
"commander": ">=14",
|
|
88
91
|
"marked": ">=18",
|