@doist/cli-core 0.17.0 → 0.19.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +33 -17
  3. package/dist/auth/errors.d.ts +1 -1
  4. package/dist/auth/errors.d.ts.map +1 -1
  5. package/dist/auth/flow.d.ts.map +1 -1
  6. package/dist/auth/flow.js +7 -8
  7. package/dist/auth/flow.js.map +1 -1
  8. package/dist/auth/index.d.ts +4 -2
  9. package/dist/auth/index.d.ts.map +1 -1
  10. package/dist/auth/index.js +2 -1
  11. package/dist/auth/index.js.map +1 -1
  12. package/dist/auth/keyring/internal.d.ts +50 -0
  13. package/dist/auth/keyring/internal.d.ts.map +1 -0
  14. package/dist/auth/keyring/internal.js +48 -0
  15. package/dist/auth/keyring/internal.js.map +1 -0
  16. package/dist/auth/keyring/migrate.d.ts +19 -17
  17. package/dist/auth/keyring/migrate.d.ts.map +1 -1
  18. package/dist/auth/keyring/migrate.js +111 -49
  19. package/dist/auth/keyring/migrate.js.map +1 -1
  20. package/dist/auth/keyring/record-write.d.ts +13 -1
  21. package/dist/auth/keyring/record-write.d.ts.map +1 -1
  22. package/dist/auth/keyring/record-write.js +18 -0
  23. package/dist/auth/keyring/record-write.js.map +1 -1
  24. package/dist/auth/keyring/token-store.d.ts +7 -1
  25. package/dist/auth/keyring/token-store.d.ts.map +1 -1
  26. package/dist/auth/keyring/token-store.js +63 -34
  27. package/dist/auth/keyring/token-store.js.map +1 -1
  28. package/dist/auth/persist.d.ts +9 -1
  29. package/dist/auth/persist.d.ts.map +1 -1
  30. package/dist/auth/persist.js +20 -0
  31. package/dist/auth/persist.js.map +1 -1
  32. package/dist/auth/providers/pkce.d.ts +1 -1
  33. package/dist/auth/providers/pkce.d.ts.map +1 -1
  34. package/dist/auth/providers/pkce.js +89 -7
  35. package/dist/auth/providers/pkce.js.map +1 -1
  36. package/dist/auth/refresh.d.ts +49 -0
  37. package/dist/auth/refresh.d.ts.map +1 -0
  38. package/dist/auth/refresh.js +184 -0
  39. package/dist/auth/refresh.js.map +1 -0
  40. package/dist/auth/status.d.ts +12 -4
  41. package/dist/auth/status.d.ts.map +1 -1
  42. package/dist/auth/status.js +45 -5
  43. package/dist/auth/status.js.map +1 -1
  44. package/dist/auth/types.d.ts +17 -0
  45. package/dist/auth/types.d.ts.map +1 -1
  46. package/package.json +9 -4
@@ -1,5 +1,12 @@
1
1
  import { CliError, getErrorMessage } from '../../errors.js';
2
2
  import { deriveChallenge, generateVerifier } from '../pkce.js';
3
+ // Upper bound on the refresh-token POST. Kept under the refresh helper's
4
+ // stale-lock threshold so a timed-out grant releases the lock before another
5
+ // invocation would consider it abandoned.
6
+ const REFRESH_TIMEOUT_MS = 10_000;
7
+ function expiresAtFromExpiresIn(expiresIn) {
8
+ return typeof expiresIn === 'number' ? Date.now() + expiresIn * 1000 : undefined;
9
+ }
3
10
  /**
4
11
  * Build an `AuthProvider` for the standard "PKCE S256, public client (no
5
12
  * client_secret)" flow. Covers Outline (user-supplied client_id + base_url)
@@ -23,8 +30,10 @@ export function createPkceProvider(options) {
23
30
  length: options.verifierLength,
24
31
  });
25
32
  const challenge = deriveChallenge(verifier);
26
- const clientId = resolve(options.clientId, input.handshake, input.flags);
27
- const authorizeUrl = resolve(options.authorizeUrl, input.handshake, input.flags);
33
+ const [clientId, authorizeUrl] = await Promise.all([
34
+ resolve(options.clientId, input.handshake, input.flags),
35
+ resolve(options.authorizeUrl, input.handshake, input.flags),
36
+ ]);
28
37
  const url = new URL(authorizeUrl);
29
38
  url.searchParams.set('response_type', 'code');
30
39
  url.searchParams.set('client_id', clientId);
@@ -50,7 +59,7 @@ export function createPkceProvider(options) {
50
59
  // before calling exchange, so a `tokenUrl: ({ flags }) => ...`
51
60
  // resolver sees the same flags it saw during authorize.
52
61
  const flags = input.handshake.flags ?? {};
53
- const tokenUrl = resolve(options.tokenUrl, input.handshake, flags);
62
+ const tokenUrl = await resolve(options.tokenUrl, input.handshake, flags);
54
63
  const body = new URLSearchParams({
55
64
  grant_type: 'authorization_code',
56
65
  code: input.code,
@@ -91,17 +100,90 @@ export function createPkceProvider(options) {
91
100
  return {
92
101
  accessToken: payload.access_token,
93
102
  refreshToken: payload.refresh_token,
94
- expiresAt: typeof payload.expires_in === 'number'
95
- ? Date.now() + payload.expires_in * 1000
96
- : undefined,
103
+ expiresAt: expiresAtFromExpiresIn(payload.expires_in),
97
104
  };
98
105
  },
99
106
  validateToken: options.validate,
107
+ async refreshToken(input) {
108
+ const oauth = await loadOauth4webapi();
109
+ // Mirror `exchangeCode`: a resolver that reads `flags` sees the
110
+ // same view during silent refresh as it did at authorize time.
111
+ const flags = input.handshake.flags ?? {};
112
+ const [tokenUrl, clientId] = await Promise.all([
113
+ resolve(options.tokenUrl, input.handshake, flags),
114
+ resolve(options.clientId, input.handshake, flags),
115
+ ]);
116
+ const as = { issuer: tokenUrl, token_endpoint: tokenUrl };
117
+ const client = { client_id: clientId, token_endpoint_auth_method: 'none' };
118
+ // Bound the network call so a hung token endpoint can't block the
119
+ // CLI indefinitely (and, for refresh consumers, can't hold the
120
+ // refresh lock forever). Route through the consumer's injected
121
+ // fetch when present, so a custom transport (proxy dispatcher,
122
+ // decompression) applies to the refresh grant too — oauth4webapi
123
+ // otherwise captures the global `fetch`.
124
+ const requestOptions = {
125
+ signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
126
+ ...(options.fetchImpl ? { [oauth.customFetch]: options.fetchImpl } : {}),
127
+ };
128
+ try {
129
+ const response = await oauth.refreshTokenGrantRequest(as, client, oauth.None(), input.refreshToken, requestOptions);
130
+ const result = await oauth.processRefreshTokenResponse(as, client, response);
131
+ return {
132
+ accessToken: result.access_token,
133
+ refreshToken: result.refresh_token,
134
+ expiresAt: expiresAtFromExpiresIn(result.expires_in),
135
+ };
136
+ }
137
+ catch (error) {
138
+ // A ResponseBodyError carries the server's OAuth error JSON.
139
+ // `invalid_grant` (any status — some proxies remap 400 → 401)
140
+ // means the refresh token itself was rejected; re-login is the
141
+ // only recovery. Every other code is transient from cli-core's
142
+ // POV — but surface the actual `error`/`error_description` so a
143
+ // misconfigured server (e.g. `invalid_request: Missing
144
+ // client_secret`) is diagnosable rather than hidden behind
145
+ // oauth4webapi's generic "server responded with an error".
146
+ if (error instanceof oauth.ResponseBodyError) {
147
+ const detail = error.error_description
148
+ ? `${error.error} (${error.error_description})`
149
+ : error.error;
150
+ if (error.error === 'invalid_grant') {
151
+ throw new CliError('AUTH_REFRESH_EXPIRED', `Refresh token rejected: ${detail}`, {
152
+ hints: ['Re-run the login command to reauthorize.'],
153
+ });
154
+ }
155
+ throw new CliError('AUTH_REFRESH_TRANSIENT', `Refresh request failed: ${detail}`, {
156
+ hints: ['Try again.'],
157
+ });
158
+ }
159
+ // Network failure, non-JSON body, WWWAuthenticateChallengeError, …
160
+ throw new CliError('AUTH_REFRESH_TRANSIENT', `Refresh request failed: ${getErrorMessage(error)}`, { hints: ['Try again.'] });
161
+ }
162
+ },
100
163
  };
101
164
  }
102
- function resolve(resolver, handshake, flags) {
165
+ async function resolve(resolver, handshake, flags) {
103
166
  return typeof resolver === 'function' ? resolver({ handshake, flags }) : resolver;
104
167
  }
168
+ // Optional peer dep — only refresh consumers install it. The dynamic import
169
+ // (and a missing-peer failure) is memoised so it isn't repeated on every
170
+ // refresh, which sits on the authenticated-call path.
171
+ let oauthModulePromise;
172
+ async function loadOauth4webapi() {
173
+ oauthModulePromise ??= import('oauth4webapi');
174
+ try {
175
+ return await oauthModulePromise;
176
+ }
177
+ catch (error) {
178
+ const code = error?.code;
179
+ if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {
180
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'oauth4webapi is required for refresh-token support.', { hints: ['Run `npm install oauth4webapi` in your CLI.'] });
181
+ }
182
+ // Installed but failed to initialise — surface the real cause rather
183
+ // than a misleading "install it" hint.
184
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', `Failed to load oauth4webapi: ${getErrorMessage(error)}`);
185
+ }
186
+ }
105
187
  async function safeReadText(response) {
106
188
  try {
107
189
  const text = (await response.text()).trim();
@@ -1 +1 @@
1
- {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../../src/auth/providers/pkce.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../../src/auth/providers/pkce.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { AccountRef, AuthAccount, AuthProvider, TokenBundle, TokenStore } from './types.js';
2
+ export type RefreshAccessTokenOptions<TAccount extends AuthAccount> = {
3
+ store: TokenStore<TAccount>;
4
+ provider: AuthProvider<TAccount>;
5
+ ref?: AccountRef;
6
+ /**
7
+ * Refresh proactively when the access token's expiry is within this many
8
+ * ms of now. Default 60_000 (60s). Ignored when `force: true`.
9
+ */
10
+ skewMs?: number;
11
+ /**
12
+ * Reactive path: caller hit a 401 and wants a rotation regardless of
13
+ * expiry. Skips the skew check; still honours all the "unavailable"
14
+ * gates (no refresh token, no provider hook, no `activeBundle`/`setBundle`).
15
+ */
16
+ force?: boolean;
17
+ /**
18
+ * Path to the O_EXCL concurrency lock file. Required — cli-core does not
19
+ * interpret `~` or know where the consumer's config lives. Recommended:
20
+ * `${getConfigPath(serviceName)}.refresh.lock`.
21
+ */
22
+ lockPath: string;
23
+ /**
24
+ * Forwarded to `provider.refreshToken` as its `handshake`, so consumers
25
+ * can pass runtime context the provider's resolvers need (e.g. a
26
+ * `--env`-derived base URL / client id). Defaults to `{}`.
27
+ */
28
+ handshake?: Record<string, unknown>;
29
+ };
30
+ export type RefreshAccessTokenResult<TAccount extends AuthAccount> = {
31
+ rotated: boolean;
32
+ bundle: TokenBundle;
33
+ account: TAccount;
34
+ };
35
+ /**
36
+ * Rotate the access token using the stored refresh token. Proactive when
37
+ * `accessTokenExpiresAt` is within `skewMs` of now; reactive when `force:
38
+ * true`. Uses an `O_EXCL` file lock at `lockPath` so concurrent CLI
39
+ * invocations don't issue parallel refresh-token grants — one POSTs, the
40
+ * others re-read the rotated bundle from the store.
41
+ *
42
+ * Throws `AUTH_REFRESH_UNAVAILABLE` when refresh isn't possible in the
43
+ * current setup: store doesn't implement `activeBundle` + `setBundle`,
44
+ * provider doesn't implement `refreshToken`, no credential, or no refresh
45
+ * token. Server-side rejections surface as `AUTH_REFRESH_EXPIRED` (re-login
46
+ * required) or `AUTH_REFRESH_TRANSIENT` (retryable).
47
+ */
48
+ export declare function refreshAccessToken<TAccount extends AuthAccount>(options: RefreshAccessTokenOptions<TAccount>): Promise<RefreshAccessTokenResult<TAccount>>;
49
+ //# sourceMappingURL=refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/auth/refresh.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEhG,MAAM,MAAM,yBAAyB,CAAC,QAAQ,SAAS,WAAW,IAAI;IAClE,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC3B,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;IAChC,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,wBAAwB,CAAC,QAAQ,SAAS,WAAW,IAAI;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,QAAQ,CAAA;CACpB,CAAA;AAUD;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,SAAS,WAAW,EACjE,OAAO,EAAE,yBAAyB,CAAC,QAAQ,CAAC,GAC7C,OAAO,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CA4F7C"}
@@ -0,0 +1,184 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { open, readFile, stat, unlink } from 'node:fs/promises';
3
+ import { setTimeout as sleep } from 'node:timers/promises';
4
+ import { CliError, getErrorMessage } from '../errors.js';
5
+ import { bundleFromExchange, persistBundle } from './persist.js';
6
+ const DEFAULT_SKEW_MS = 60_000;
7
+ const LOCK_WAIT_TIMEOUT_MS = 2_000;
8
+ const LOCK_POLL_INTERVAL_MS = 50;
9
+ // A lock older than this was almost certainly left by a crashed holder — the
10
+ // refresh POST is bounded by a provider-side timeout well under this — so it's
11
+ // safe to steal rather than block every future refresh forever.
12
+ const LOCK_STALE_MS = 15_000;
13
+ /**
14
+ * Rotate the access token using the stored refresh token. Proactive when
15
+ * `accessTokenExpiresAt` is within `skewMs` of now; reactive when `force:
16
+ * true`. Uses an `O_EXCL` file lock at `lockPath` so concurrent CLI
17
+ * invocations don't issue parallel refresh-token grants — one POSTs, the
18
+ * others re-read the rotated bundle from the store.
19
+ *
20
+ * Throws `AUTH_REFRESH_UNAVAILABLE` when refresh isn't possible in the
21
+ * current setup: store doesn't implement `activeBundle` + `setBundle`,
22
+ * provider doesn't implement `refreshToken`, no credential, or no refresh
23
+ * token. Server-side rejections surface as `AUTH_REFRESH_EXPIRED` (re-login
24
+ * required) or `AUTH_REFRESH_TRANSIENT` (retryable).
25
+ */
26
+ export async function refreshAccessToken(options) {
27
+ const { store, provider, ref, force, lockPath } = options;
28
+ const skewMs = options.skewMs ?? DEFAULT_SKEW_MS;
29
+ const handshake = options.handshake ?? {};
30
+ // Refresh must both read the full bundle and persist the rotated one. A
31
+ // store missing either capability can't participate — fail loudly rather
32
+ // than silently dropping the rotated refresh token via a `set()` fallback.
33
+ if (!store.activeBundle || !store.setBundle) {
34
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'TokenStore must implement activeBundle + setBundle for refresh.', { hints: ['Re-run the login command to reauthorize.'] });
35
+ }
36
+ if (!provider.refreshToken) {
37
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'Auth provider does not implement refreshToken.');
38
+ }
39
+ const activeBundle = store.activeBundle.bind(store);
40
+ const refreshGrant = provider.refreshToken.bind(provider);
41
+ const snapshot = await activeBundle(ref);
42
+ if (!snapshot) {
43
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'No stored credential to refresh.', {
44
+ hints: ['Re-run the login command to reauthorize.'],
45
+ });
46
+ }
47
+ if (!force && !needsRefresh(snapshot.bundle, skewMs)) {
48
+ return { rotated: false, bundle: snapshot.bundle, account: snapshot.account };
49
+ }
50
+ if (!snapshot.bundle.refreshToken) {
51
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'Stored credential has no refresh token.', {
52
+ hints: ['Re-run the login command to reauthorize.'],
53
+ });
54
+ }
55
+ const lockToken = await acquireLock(lockPath);
56
+ if (!lockToken) {
57
+ // Holder didn't release in time. It may have rotated then crashed
58
+ // before unlinking — re-read once and adopt the rotated bundle if so.
59
+ const fresh = await activeBundle(ref);
60
+ if (fresh && hasRotated(snapshot.bundle, fresh.bundle)) {
61
+ return { rotated: true, bundle: fresh.bundle, account: fresh.account };
62
+ }
63
+ throw new CliError('AUTH_REFRESH_TRANSIENT', 'Timed out waiting for a concurrent refresh to complete.', { hints: ['Try again.'] });
64
+ }
65
+ try {
66
+ // Re-read under the lock (covers a clean acquire too): a concurrent
67
+ // holder may have rotated between our snapshot read and acquiring the
68
+ // lock, so adopt their bundle rather than POST a now-stale refresh
69
+ // token. A throw here releases the lock via `finally`.
70
+ const current = await activeBundle(ref);
71
+ if (!current) {
72
+ // A concurrent `logout`/`clear` removed the credential after our
73
+ // first read — do not POST + persist it back into existence.
74
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'Credential was removed during refresh.', {
75
+ hints: ['Re-run the login command to reauthorize.'],
76
+ });
77
+ }
78
+ if (hasRotated(snapshot.bundle, current.bundle)) {
79
+ return { rotated: true, bundle: current.bundle, account: current.account };
80
+ }
81
+ const refreshToken = current.bundle.refreshToken;
82
+ if (!refreshToken) {
83
+ throw new CliError('AUTH_REFRESH_UNAVAILABLE', 'Stored credential has no refresh token.', { hints: ['Re-run the login command to reauthorize.'] });
84
+ }
85
+ const exchange = await refreshGrant({ refreshToken, handshake });
86
+ const account = exchange.account ?? current.account;
87
+ const bundle = bundleFromExchange(exchange, current.bundle);
88
+ await persistBundle({ store, account, bundle });
89
+ return { rotated: true, bundle, account };
90
+ }
91
+ finally {
92
+ await releaseLock(lockPath, lockToken);
93
+ }
94
+ }
95
+ function needsRefresh(bundle, skewMs) {
96
+ // No expiry tracked → can't proactively refresh; defer to reactive 401.
97
+ if (bundle.accessTokenExpiresAt === undefined)
98
+ return false;
99
+ return bundle.accessTokenExpiresAt - Date.now() < skewMs;
100
+ }
101
+ function hasRotated(before, after) {
102
+ return (after.accessToken !== before.accessToken ||
103
+ after.accessTokenExpiresAt !== before.accessTokenExpiresAt ||
104
+ after.refreshToken !== before.refreshToken ||
105
+ after.refreshTokenExpiresAt !== before.refreshTokenExpiresAt);
106
+ }
107
+ /**
108
+ * Acquire the lock, returning a unique ownership token (or `null` on
109
+ * contention timeout). The token is written into the lock file so
110
+ * `releaseLock` only unlinks a lock it still owns — a holder whose stale
111
+ * lock was stolen mid-flight won't delete the new holder's lock.
112
+ */
113
+ async function acquireLock(lockPath) {
114
+ const token = randomUUID();
115
+ if (await tryAcquire(lockPath, token))
116
+ return token;
117
+ const deadline = Date.now() + LOCK_WAIT_TIMEOUT_MS;
118
+ while (Date.now() < deadline) {
119
+ await sleep(LOCK_POLL_INTERVAL_MS);
120
+ if (await tryAcquire(lockPath, token))
121
+ return token;
122
+ }
123
+ return null;
124
+ }
125
+ // Write the lock with O_EXCL. On EEXIST, steal it if it's stale (older than
126
+ // LOCK_STALE_MS — assumes the provider bounds its HTTP, which the built-in
127
+ // PKCE provider does); otherwise report contention.
128
+ async function tryAcquire(lockPath, token) {
129
+ if (await tryWriteLock(lockPath, token))
130
+ return true;
131
+ if (await lockIsStale(lockPath)) {
132
+ await forceUnlink(lockPath);
133
+ return tryWriteLock(lockPath, token);
134
+ }
135
+ return false;
136
+ }
137
+ async function lockIsStale(lockPath) {
138
+ try {
139
+ const { mtimeMs } = await stat(lockPath);
140
+ return Date.now() - mtimeMs > LOCK_STALE_MS;
141
+ }
142
+ catch {
143
+ return false;
144
+ }
145
+ }
146
+ async function tryWriteLock(lockPath, token) {
147
+ let handle;
148
+ try {
149
+ handle = await open(lockPath, 'wx');
150
+ }
151
+ catch (error) {
152
+ const code = error.code;
153
+ if (code === 'EEXIST')
154
+ return false;
155
+ throw new CliError('AUTH_REFRESH_TRANSIENT', `Failed to acquire refresh lock: ${getErrorMessage(error)}`, { hints: ['Try again.'] });
156
+ }
157
+ try {
158
+ await handle.writeFile(token);
159
+ }
160
+ finally {
161
+ await handle.close();
162
+ }
163
+ return true;
164
+ }
165
+ async function releaseLock(lockPath, token) {
166
+ try {
167
+ const owner = (await readFile(lockPath, 'utf8')).trim();
168
+ if (owner === token)
169
+ await unlink(lockPath);
170
+ }
171
+ catch {
172
+ // best-effort: a missing/unreadable lock (manual cleanup, crash, a
173
+ // steal by another holder) must not surface as a refresh failure.
174
+ }
175
+ }
176
+ async function forceUnlink(lockPath) {
177
+ try {
178
+ await unlink(lockPath);
179
+ }
180
+ catch {
181
+ // already gone
182
+ }
183
+ }
184
+ //# sourceMappingURL=refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/auth/refresh.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
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 { AuthAccount, TokenBundle, TokenStore } from './types.js';
4
4
  export type AttachStatusContext<TAccount extends AuthAccount> = {
5
5
  account: TAccount;
6
6
  /** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
@@ -20,6 +20,12 @@ export type AttachStatusCommandOptions<TAccount extends AuthAccount = AuthAccoun
20
20
  fetchLive?(ctx: {
21
21
  account: TAccount;
22
22
  token: string;
23
+ /**
24
+ * Full bundle when the store implements `activeBundle` — lets a
25
+ * consumer render expiry without a second read. Absent when the
26
+ * store only exposes `active()` (no refresh-side metadata available).
27
+ */
28
+ bundle?: TokenBundle;
23
29
  /** `--json` / `--ndjson` flag values, both present (defaulted to `false`). */
24
30
  view: Required<ViewOptions>;
25
31
  flags: Record<string, unknown>;
@@ -49,9 +55,11 @@ export type AttachStatusCommandOptions<TAccount extends AuthAccount = AuthAccoun
49
55
  }): void | Promise<void>;
50
56
  };
51
57
  /**
52
- * Attach `status` as a subcommand of `parent`. Reads `store.active()`, optionally
53
- * confirms via `fetchLive`, then dispatches to `renderText` (human) or
54
- * `renderJson` (machine). Returns the new `Command` so the consumer can chain.
58
+ * Attach `status` as a subcommand of `parent`. Reads the active credential
59
+ * (preferring `store.activeBundle` when `fetchLive` is set, so the token and
60
+ * bundle come from one read), optionally confirms via `fetchLive`, then
61
+ * dispatches to `renderText` (human) or `renderJson` (machine). Returns the
62
+ * new `Command` so the consumer can chain.
55
63
  */
56
64
  export declare function attachStatusCommand<TAccount extends AuthAccount = AuthAccount>(parent: Command, options: AttachStatusCommandOptions<TAccount>): Command;
57
65
  //# sourceMappingURL=status.d.ts.map
@@ -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;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"}
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,EAAc,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAqDlF,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;;;;WAIG;QACH,MAAM,CAAC,EAAE,WAAW,CAAA;QACpB,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;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,WAAW,GAAG,WAAW,EAC1E,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC9C,OAAO,CA4CT"}
@@ -1,10 +1,49 @@
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
+ import { accountNotFoundError, attachUserFlag, extractUserRef, requireSnapshotForRef, } from './user-flag.js';
4
4
  /**
5
- * Attach `status` as a subcommand of `parent`. Reads `store.active()`, optionally
6
- * confirms via `fetchLive`, then dispatches to `renderText` (human) or
7
- * `renderJson` (machine). Returns the new `Command` so the consumer can chain.
5
+ * Resolve the auth snapshot for `status`. When the consumer supplies
6
+ * `fetchLive` (and the store implements `activeBundle`), read the bundle once
7
+ * and derive both the access token and the bundle from it — avoiding a second
8
+ * keyring round-trip on the hot path. Otherwise fall back to the narrow
9
+ * `active()` read. A bundle-read fault (e.g. a refresh-slot error) also falls
10
+ * back to `active()` so it can't break status, which is the user's first port
11
+ * of call when something is wrong. An explicit-ref miss throws
12
+ * `ACCOUNT_NOT_FOUND`, matching `requireSnapshotForRef`.
13
+ */
14
+ async function resolveStatusSnapshot(store, ref, wantsBundle) {
15
+ if (wantsBundle && store.activeBundle) {
16
+ try {
17
+ const snap = await store.activeBundle(ref);
18
+ if (snap) {
19
+ return {
20
+ token: snap.bundle.accessToken,
21
+ account: snap.account,
22
+ bundle: snap.bundle,
23
+ };
24
+ }
25
+ if (ref !== undefined)
26
+ throw accountNotFoundError(ref);
27
+ return null;
28
+ }
29
+ catch (error) {
30
+ // Only a typed read failure falls through to the access-only
31
+ // `active()` read (e.g. a refresh-slot fault that `active()`
32
+ // doesn't hit). Anything else — `ACCOUNT_NOT_FOUND`, or an
33
+ // unexpected store bug — propagates rather than being masked.
34
+ if (!(error instanceof CliError) || error.code !== 'AUTH_STORE_READ_FAILED')
35
+ throw error;
36
+ }
37
+ }
38
+ const snapshot = await requireSnapshotForRef(store, ref);
39
+ return snapshot ? { token: snapshot.token, account: snapshot.account } : null;
40
+ }
41
+ /**
42
+ * Attach `status` as a subcommand of `parent`. Reads the active credential
43
+ * (preferring `store.activeBundle` when `fetchLive` is set, so the token and
44
+ * bundle come from one read), optionally confirms via `fetchLive`, then
45
+ * dispatches to `renderText` (human) or `renderJson` (machine). Returns the
46
+ * new `Command` so the consumer can chain.
8
47
  */
9
48
  export function attachStatusCommand(parent, options) {
10
49
  const command = parent
@@ -19,7 +58,7 @@ export function attachStatusCommand(parent, options) {
19
58
  ndjson: Boolean(ndjson),
20
59
  };
21
60
  const ref = extractUserRef(cmd);
22
- const snapshot = await requireSnapshotForRef(options.store, ref);
61
+ const snapshot = await resolveStatusSnapshot(options.store, ref, Boolean(options.fetchLive));
23
62
  if (!snapshot) {
24
63
  if (options.onNotAuthenticated) {
25
64
  await options.onNotAuthenticated({ view, flags });
@@ -31,6 +70,7 @@ export function attachStatusCommand(parent, options) {
31
70
  ? await options.fetchLive({
32
71
  account: snapshot.account,
33
72
  token: snapshot.token,
73
+ ...(snapshot.bundle ? { bundle: snapshot.bundle } : {}),
34
74
  view,
35
75
  flags,
36
76
  })
@@ -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;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
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/auth/status.ts"],"names":[],"mappings":"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"}
@@ -79,6 +79,11 @@ export type TokenBundle = {
79
79
  accessTokenExpiresAt?: number;
80
80
  refreshTokenExpiresAt?: number;
81
81
  };
82
+ /** Read-side snapshot returned by `activeBundle`. Mirrors `setBundle`'s write side. */
83
+ export type ActiveBundleSnapshot<TAccount extends AuthAccount = AuthAccount> = {
84
+ account: TAccount;
85
+ bundle: TokenBundle;
86
+ };
82
87
  /** Opaque account selector. Stores own the matching rule (id, email, label, …). */
83
88
  export type AccountRef = string;
84
89
  /**
@@ -112,6 +117,18 @@ export type TokenStore<TAccount extends AuthAccount = AuthAccount> = {
112
117
  setBundle?(account: TAccount, bundle: TokenBundle, options?: {
113
118
  promoteDefault?: boolean;
114
119
  }): Promise<void>;
120
+ /**
121
+ * Full-bundle read for refresh-capable consumers. Returns the matching
122
+ * account + bundle, or `null` on miss. Optional on the contract — the
123
+ * silent-refresh helper throws `AUTH_REFRESH_UNAVAILABLE` when a custom
124
+ * store doesn't implement it. `KeyringTokenStore` overrides this as
125
+ * required so cli-core helpers can call it without a non-null assertion.
126
+ *
127
+ * Stores MAY throw `CliError('AUTH_STORE_READ_FAILED', …)` on the same
128
+ * conditions as `active()` (e.g. keyring offline while a matching
129
+ * record exists).
130
+ */
131
+ activeBundle?(ref?: AccountRef): Promise<ActiveBundleSnapshot<TAccount> | null>;
115
132
  /** Remove a stored credential. No-op when `ref` doesn't match. */
116
133
  clear(ref?: AccountRef): Promise<void>;
117
134
  /** Every stored account with a default marker. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
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.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "Shared core utilities for Doist CLI projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -66,15 +66,16 @@
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.7.0",
69
+ "@types/node": "25.8.0",
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
+ "oauth4webapi": "3.8.6",
75
76
  "open": "11.0.0",
76
- "oxfmt": "0.49.0",
77
- "oxlint": "1.64.0",
77
+ "oxfmt": "0.50.0",
78
+ "oxlint": "1.65.0",
78
79
  "semantic-release": "25.0.3",
79
80
  "typescript": "6.0.3",
80
81
  "vitest": "4.1.6"
@@ -90,6 +91,7 @@
90
91
  "commander": ">=14",
91
92
  "marked": ">=18",
92
93
  "marked-terminal-renderer": ">=2",
94
+ "oauth4webapi": ">=3",
93
95
  "open": ">=10",
94
96
  "vitest": ">=4.1"
95
97
  },
@@ -103,6 +105,9 @@
103
105
  "marked-terminal-renderer": {
104
106
  "optional": true
105
107
  },
108
+ "oauth4webapi": {
109
+ "optional": true
110
+ },
106
111
  "open": {
107
112
  "optional": true
108
113
  },