@cortexkit/antigravity-auth-core 2.2.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/README.md +24 -2
  2. package/dist/abort-forwarding.d.ts +3 -0
  3. package/dist/abort-forwarding.d.ts.map +1 -0
  4. package/dist/abort-forwarding.js +19 -0
  5. package/dist/abort-forwarding.js.map +1 -0
  6. package/dist/account-identity.d.ts +52 -0
  7. package/dist/account-identity.d.ts.map +1 -0
  8. package/dist/account-identity.js +66 -0
  9. package/dist/account-identity.js.map +1 -0
  10. package/dist/account-manager.d.ts +228 -43
  11. package/dist/account-manager.d.ts.map +1 -1
  12. package/dist/account-manager.js +942 -903
  13. package/dist/account-manager.js.map +1 -1
  14. package/dist/account-migration.d.ts +309 -0
  15. package/dist/account-migration.d.ts.map +1 -0
  16. package/dist/account-migration.js +2284 -0
  17. package/dist/account-migration.js.map +1 -0
  18. package/dist/account-repository-codecs.d.ts +82 -0
  19. package/dist/account-repository-codecs.d.ts.map +1 -0
  20. package/dist/account-repository-codecs.js +609 -0
  21. package/dist/account-repository-codecs.js.map +1 -0
  22. package/dist/account-repository-types.d.ts +831 -0
  23. package/dist/account-repository-types.d.ts.map +1 -0
  24. package/dist/account-repository-types.js +137 -0
  25. package/dist/account-repository-types.js.map +1 -0
  26. package/dist/account-repository.d.ts +442 -0
  27. package/dist/account-repository.d.ts.map +1 -0
  28. package/dist/account-repository.js +2253 -0
  29. package/dist/account-repository.js.map +1 -0
  30. package/dist/account-selector.d.ts +470 -0
  31. package/dist/account-selector.d.ts.map +1 -0
  32. package/dist/account-selector.js +1383 -0
  33. package/dist/account-selector.js.map +1 -0
  34. package/dist/account-storage.d.ts.map +1 -1
  35. package/dist/account-storage.js +5 -0
  36. package/dist/account-storage.js.map +1 -1
  37. package/dist/agy-request-metadata.d.ts.map +1 -1
  38. package/dist/agy-request-metadata.js +8 -21
  39. package/dist/agy-request-metadata.js.map +1 -1
  40. package/dist/agy-transport.d.ts.map +1 -1
  41. package/dist/agy-transport.js +21 -35
  42. package/dist/agy-transport.js.map +1 -1
  43. package/dist/antigravity-command-menu.d.ts +171 -0
  44. package/dist/antigravity-command-menu.d.ts.map +1 -0
  45. package/dist/antigravity-command-menu.js +523 -0
  46. package/dist/antigravity-command-menu.js.map +1 -0
  47. package/dist/atomic-write.d.ts +18 -1
  48. package/dist/atomic-write.d.ts.map +1 -1
  49. package/dist/atomic-write.js +15 -3
  50. package/dist/atomic-write.js.map +1 -1
  51. package/dist/common-auth-embedded/NOTICE.txt +21 -0
  52. package/dist/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
  53. package/dist/common-auth-embedded/auth-menu/accounts.js +387 -0
  54. package/dist/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
  55. package/dist/common-auth-embedded/auth-menu/ansi.js +98 -0
  56. package/dist/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
  57. package/dist/common-auth-embedded/auth-menu/confirm.js +21 -0
  58. package/dist/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
  59. package/dist/common-auth-embedded/auth-menu/doctor.js +81 -0
  60. package/dist/common-auth-embedded/auth-menu/index.d.ts +17 -0
  61. package/dist/common-auth-embedded/auth-menu/index.js +12 -0
  62. package/dist/common-auth-embedded/auth-menu/login.d.ts +55 -0
  63. package/dist/common-auth-embedded/auth-menu/login.js +83 -0
  64. package/dist/common-auth-embedded/auth-menu/menu.d.ts +59 -0
  65. package/dist/common-auth-embedded/auth-menu/menu.js +73 -0
  66. package/dist/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
  67. package/dist/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
  68. package/dist/common-auth-embedded/auth-menu/select.d.ts +21 -0
  69. package/dist/common-auth-embedded/auth-menu/select.js +159 -0
  70. package/dist/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
  71. package/dist/common-auth-embedded/auth-menu/terminal.js +19 -0
  72. package/dist/common-auth-embedded/claustrum/consumer.d.ts +102 -0
  73. package/dist/common-auth-embedded/claustrum/consumer.js +298 -0
  74. package/dist/common-auth-embedded/claustrum/custody.d.ts +175 -0
  75. package/dist/common-auth-embedded/claustrum/custody.js +354 -0
  76. package/dist/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
  77. package/dist/common-auth-embedded/claustrum/enrollment.js +759 -0
  78. package/dist/common-auth-embedded/claustrum/errors.d.ts +16 -0
  79. package/dist/common-auth-embedded/claustrum/errors.js +8 -0
  80. package/dist/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
  81. package/dist/common-auth-embedded/claustrum/host-slot.js +72 -0
  82. package/dist/common-auth-embedded/claustrum/index.d.ts +18 -0
  83. package/dist/common-auth-embedded/claustrum/index.js +22 -0
  84. package/dist/common-auth-embedded/claustrum/interlock.d.ts +27 -0
  85. package/dist/common-auth-embedded/claustrum/interlock.js +29 -0
  86. package/dist/common-auth-embedded/claustrum/roster.d.ts +208 -0
  87. package/dist/common-auth-embedded/claustrum/roster.js +536 -0
  88. package/dist/common-auth-embedded/commands/builtins.d.ts +71 -0
  89. package/dist/common-auth-embedded/commands/builtins.js +534 -0
  90. package/dist/common-auth-embedded/commands/index.d.ts +10 -0
  91. package/dist/common-auth-embedded/commands/index.js +5 -0
  92. package/dist/common-auth-embedded/commands/menu.d.ts +61 -0
  93. package/dist/common-auth-embedded/commands/menu.js +300 -0
  94. package/dist/common-auth-embedded/commands/model.d.ts +238 -0
  95. package/dist/common-auth-embedded/commands/model.js +16 -0
  96. package/dist/common-auth-embedded/commands/pi.d.ts +23 -0
  97. package/dist/common-auth-embedded/commands/pi.js +206 -0
  98. package/dist/common-auth-embedded/commands/seam.d.ts +72 -0
  99. package/dist/common-auth-embedded/commands/seam.js +301 -0
  100. package/dist/common-auth-embedded/fs/atomic-write.d.ts +20 -0
  101. package/dist/common-auth-embedded/fs/atomic-write.js +80 -0
  102. package/dist/common-auth-embedded/fs/index.d.ts +7 -0
  103. package/dist/common-auth-embedded/fs/index.js +6 -0
  104. package/dist/common-auth-embedded/fs/lock-constants.d.ts +14 -0
  105. package/dist/common-auth-embedded/fs/lock-constants.js +14 -0
  106. package/dist/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
  107. package/dist/common-auth-embedded/fs/refresh-file-lock.js +501 -0
  108. package/dist/common-auth-embedded/fs/with-lock.d.ts +33 -0
  109. package/dist/common-auth-embedded/fs/with-lock.js +48 -0
  110. package/dist/common-auth-embedded/logger/capture-sink.d.ts +14 -0
  111. package/dist/common-auth-embedded/logger/capture-sink.js +13 -0
  112. package/dist/common-auth-embedded/logger/engine.d.ts +100 -0
  113. package/dist/common-auth-embedded/logger/engine.js +246 -0
  114. package/dist/common-auth-embedded/logger/index.d.ts +6 -0
  115. package/dist/common-auth-embedded/logger/index.js +3 -0
  116. package/dist/common-auth-embedded/logger/redact.d.ts +11 -0
  117. package/dist/common-auth-embedded/logger/redact.js +83 -0
  118. package/dist/common-auth-embedded/pi-slot/index.d.ts +3 -0
  119. package/dist/common-auth-embedded/pi-slot/index.js +2 -0
  120. package/dist/common-auth-embedded/pi-slot/lock.js +212 -0
  121. package/dist/common-auth-embedded/pi-slot/slot.d.ts +49 -0
  122. package/dist/common-auth-embedded/pi-slot/slot.js +383 -0
  123. package/dist/common-auth-embedded/quota/codec.d.ts +11 -0
  124. package/dist/common-auth-embedded/quota/codec.js +12 -0
  125. package/dist/common-auth-embedded/quota/format.d.ts +46 -0
  126. package/dist/common-auth-embedded/quota/format.js +138 -0
  127. package/dist/common-auth-embedded/quota/index.d.ts +10 -0
  128. package/dist/common-auth-embedded/quota/index.js +5 -0
  129. package/dist/common-auth-embedded/quota/map.d.ts +63 -0
  130. package/dist/common-auth-embedded/quota/map.js +105 -0
  131. package/dist/common-auth-embedded/quota/merge.d.ts +48 -0
  132. package/dist/common-auth-embedded/quota/merge.js +162 -0
  133. package/dist/common-auth-embedded/quota/projection.d.ts +64 -0
  134. package/dist/common-auth-embedded/quota/projection.js +134 -0
  135. package/dist/common-auth-embedded/routing/admission.d.ts +93 -0
  136. package/dist/common-auth-embedded/routing/admission.js +142 -0
  137. package/dist/common-auth-embedded/routing/index.d.ts +8 -0
  138. package/dist/common-auth-embedded/routing/index.js +4 -0
  139. package/dist/common-auth-embedded/routing/ordered.d.ts +47 -0
  140. package/dist/common-auth-embedded/routing/ordered.js +58 -0
  141. package/dist/common-auth-embedded/routing/pins.d.ts +22 -0
  142. package/dist/common-auth-embedded/routing/pins.js +34 -0
  143. package/dist/common-auth-embedded/routing/sticky.d.ts +158 -0
  144. package/dist/common-auth-embedded/routing/sticky.js +339 -0
  145. package/dist/common-auth-embedded/source-output.json +1090 -0
  146. package/dist/common-auth-embedded/store/attribution.d.ts +28 -0
  147. package/dist/common-auth-embedded/store/attribution.js +60 -0
  148. package/dist/common-auth-embedded/store/errors.d.ts +55 -0
  149. package/dist/common-auth-embedded/store/errors.js +38 -0
  150. package/dist/common-auth-embedded/store/hooks.d.ts +12 -0
  151. package/dist/common-auth-embedded/store/hooks.js +34 -0
  152. package/dist/common-auth-embedded/store/identity.d.ts +39 -0
  153. package/dist/common-auth-embedded/store/identity.js +79 -0
  154. package/dist/common-auth-embedded/store/index.d.ts +21 -0
  155. package/dist/common-auth-embedded/store/index.js +7 -0
  156. package/dist/common-auth-embedded/store/mutate.d.ts +189 -0
  157. package/dist/common-auth-embedded/store/mutate.js +500 -0
  158. package/dist/common-auth-embedded/store/pool.d.ts +196 -0
  159. package/dist/common-auth-embedded/store/pool.js +120 -0
  160. package/dist/common-auth-embedded/store/provider-state.d.ts +131 -0
  161. package/dist/common-auth-embedded/store/provider-state.js +226 -0
  162. package/dist/common-auth-embedded/store/publication.d.ts +47 -0
  163. package/dist/common-auth-embedded/store/publication.js +304 -0
  164. package/dist/common-auth-embedded/store/pull.d.ts +36 -0
  165. package/dist/common-auth-embedded/store/pull.js +143 -0
  166. package/dist/common-auth-embedded/store/refresh-lock.d.ts +63 -0
  167. package/dist/common-auth-embedded/store/refresh-lock.js +136 -0
  168. package/dist/common-auth-embedded/store/refresh.d.ts +72 -0
  169. package/dist/common-auth-embedded/store/refresh.js +225 -0
  170. package/dist/common-auth-embedded/store/reserved.js +13 -0
  171. package/dist/common-auth-embedded/store/rows.d.ts +313 -0
  172. package/dist/common-auth-embedded/store/rows.js +1258 -0
  173. package/dist/common-auth-embedded/store/runtime.d.ts +36 -0
  174. package/dist/common-auth-embedded/store/runtime.js +68 -0
  175. package/dist/common-auth-embedded/store/schema.d.ts +443 -0
  176. package/dist/common-auth-embedded/store/schema.js +754 -0
  177. package/dist/common-auth-embedded/store/settings.d.ts +63 -0
  178. package/dist/common-auth-embedded/store/settings.js +120 -0
  179. package/dist/common-auth-embedded/store/torn.d.ts +78 -0
  180. package/dist/common-auth-embedded/store/torn.js +294 -0
  181. package/dist/common-auth-embedded/util/any-signal.js +42 -0
  182. package/dist/common-auth-runtime.d.ts +73 -0
  183. package/dist/common-auth-runtime.d.ts.map +1 -0
  184. package/dist/common-auth-runtime.js +65 -0
  185. package/dist/common-auth-runtime.js.map +1 -0
  186. package/dist/credential-redaction.d.ts +13 -0
  187. package/dist/credential-redaction.d.ts.map +1 -0
  188. package/dist/credential-redaction.js +230 -0
  189. package/dist/credential-redaction.js.map +1 -0
  190. package/dist/fetch-timeout.d.ts +4 -2
  191. package/dist/fetch-timeout.d.ts.map +1 -1
  192. package/dist/fetch-timeout.js +121 -14
  193. package/dist/fetch-timeout.js.map +1 -1
  194. package/dist/fingerprint.d.ts +3 -3
  195. package/dist/fingerprint.d.ts.map +1 -1
  196. package/dist/fingerprint.js +4 -4
  197. package/dist/fingerprint.js.map +1 -1
  198. package/dist/index.d.ts +16 -1
  199. package/dist/index.d.ts.map +1 -1
  200. package/dist/index.js +15 -0
  201. package/dist/index.js.map +1 -1
  202. package/dist/model-registry.d.ts +16 -0
  203. package/dist/model-registry.d.ts.map +1 -1
  204. package/dist/model-registry.js +242 -30
  205. package/dist/model-registry.js.map +1 -1
  206. package/dist/quota-manager.d.ts.map +1 -1
  207. package/dist/quota-manager.js +35 -10
  208. package/dist/quota-manager.js.map +1 -1
  209. package/dist/quota-presentation.d.ts +10 -0
  210. package/dist/quota-presentation.d.ts.map +1 -0
  211. package/dist/quota-presentation.js +60 -0
  212. package/dist/quota-presentation.js.map +1 -0
  213. package/dist/quota-types.d.ts +2 -0
  214. package/dist/quota-types.d.ts.map +1 -1
  215. package/dist/rotation.d.ts +8 -0
  216. package/dist/rotation.d.ts.map +1 -1
  217. package/dist/rotation.js +24 -0
  218. package/dist/rotation.js.map +1 -1
  219. package/dist/transform/agy-generation.d.ts +3 -0
  220. package/dist/transform/agy-generation.d.ts.map +1 -0
  221. package/dist/transform/agy-generation.js +28 -0
  222. package/dist/transform/agy-generation.js.map +1 -0
  223. package/dist/transform/claude.d.ts +7 -3
  224. package/dist/transform/claude.d.ts.map +1 -1
  225. package/dist/transform/claude.js +8 -2
  226. package/dist/transform/claude.js.map +1 -1
  227. package/dist/transform/index.d.ts +1 -0
  228. package/dist/transform/index.d.ts.map +1 -1
  229. package/dist/transform/index.js +1 -0
  230. package/dist/transform/index.js.map +1 -1
  231. package/dist/transform/model-resolver.d.ts +2 -1
  232. package/dist/transform/model-resolver.d.ts.map +1 -1
  233. package/dist/transform/model-resolver.js +46 -5
  234. package/dist/transform/model-resolver.js.map +1 -1
  235. package/dist/transform/types.d.ts +1 -1
  236. package/dist/transform/types.d.ts.map +1 -1
  237. package/dist/vault-account-source.d.ts +183 -0
  238. package/dist/vault-account-source.d.ts.map +1 -0
  239. package/dist/vault-account-source.js +296 -0
  240. package/dist/vault-account-source.js.map +1 -0
  241. package/dist/vault-enrollment-authority.d.ts +16 -0
  242. package/dist/vault-enrollment-authority.d.ts.map +1 -0
  243. package/dist/vault-enrollment-authority.js +19 -0
  244. package/dist/vault-enrollment-authority.js.map +1 -0
  245. package/dist/vault-family.d.ts +11 -0
  246. package/dist/vault-family.d.ts.map +1 -0
  247. package/dist/vault-family.js +24 -0
  248. package/dist/vault-family.js.map +1 -0
  249. package/dist/vault-provider-state.d.ts +162 -0
  250. package/dist/vault-provider-state.d.ts.map +1 -0
  251. package/dist/vault-provider-state.js +422 -0
  252. package/dist/vault-provider-state.js.map +1 -0
  253. package/package.json +39 -2
@@ -0,0 +1,36 @@
1
+ import { type PoolOperation, PoolOperationError } from './errors.js';
2
+ import { type ReadResult, type StoreContext } from './mutate.js';
3
+ import type { PoolLockOptions, PoolLockSpec } from './refresh-lock.js';
4
+ import { type PoolRow } from './schema.js';
5
+ /** Where a pull was fired from; `load` fires at most once per process per row. */
6
+ export type PullReason = 'load' | 'add' | 'replace' | 'admission';
7
+ /** What every operation module shares. */
8
+ export interface StoreRuntime {
9
+ ctx: StoreContext;
10
+ providerLock: PoolLockSpec;
11
+ rowLockOptions: Partial<PoolLockOptions>;
12
+ firePull(id: string, reason: PullReason): void;
13
+ }
14
+ /**
15
+ * The row lock's (name, path): keyed by the row's recorded wire identity when
16
+ * known, else its local id, beside the state file. The key is prefixed and
17
+ * URL-encoded so it can never name a store lock or leave the directory.
18
+ */
19
+ export declare function rowLockSpec(rt: StoreRuntime, row: Pick<PoolRow, 'id' | 'identity'>): PoolLockSpec;
20
+ /** An unlocked read that must find a ready pool holding the row. */
21
+ export declare function readRow(rt: StoreRuntime, operation: PoolOperation, id: string): Promise<{
22
+ result: Extract<ReadResult, {
23
+ status: 'ready';
24
+ }>;
25
+ row: PoolRow;
26
+ }>;
27
+ export declare function unknownRow(operation: PoolOperation, id: string): PoolOperationError;
28
+ /**
29
+ * Refuses a row the store was told to distrust: opened with
30
+ * `requireCredentialStamps`, a row whose credential stamp is not bound loads
31
+ * `unbound` (see `PoolRow.unbound`). Called on every locked read of the row
32
+ * an operation acts on, before it calls a provider or writes, so a credential
33
+ * another writer swapped in while the operation waited is refused too.
34
+ */
35
+ export declare function requireBound(operation: PoolOperation, row: PoolRow): void;
36
+ export declare function refusal(operation: PoolOperation, id: string, kind: PoolOperationError['kind'], message: string, retryable?: boolean): PoolOperationError;
@@ -0,0 +1,68 @@
1
+ import { PoolOperationError } from './errors.js';
2
+ import { notReadyError, readPool, } from './mutate.js';
3
+ import { assertNotReserved } from './reserved.js';
4
+ import { CREDENTIAL_STAMP_KEY, entryIn, isRecord, rowLockKey, } from './schema.js';
5
+ /**
6
+ * The row lock's (name, path): keyed by the row's recorded wire identity when
7
+ * known, else its local id, beside the state file. The key is prefixed and
8
+ * URL-encoded so it can never name a store lock or leave the directory.
9
+ */
10
+ export function rowLockSpec(rt, row) {
11
+ return {
12
+ ...rt.rowLockOptions,
13
+ name: `row-${encodeURIComponent(rowLockKey(row))}`,
14
+ path: rt.ctx.statePath,
15
+ };
16
+ }
17
+ /** An unlocked read that must find a ready pool holding the row. */
18
+ export async function readRow(rt, operation, id) {
19
+ const result = await readPool(rt.ctx);
20
+ if (result.status !== 'ready')
21
+ throw notReadyError(result, operation, id);
22
+ const row = result.rows.find((candidate) => candidate.id === id);
23
+ const entry = entryIn(result.config, id);
24
+ const accounts = result.state.accounts;
25
+ const account = isRecord(accounts) && Object.hasOwn(accounts, id) ? accounts[id] : undefined;
26
+ const stamp = isRecord(account) ? account[CREDENTIAL_STAMP_KEY] : undefined;
27
+ if (row &&
28
+ !['enable', 'disable'].includes(operation) &&
29
+ entry &&
30
+ Object.hasOwn(entry, 'staged'))
31
+ assertNotReserved(operation, id, entry.staged);
32
+ if (!row && isRecord(stamp) && Object.hasOwn(stamp, 'staged'))
33
+ assertNotReserved(operation, id, stamp.staged);
34
+ if (!row)
35
+ throw unknownRow(operation, id);
36
+ return { result, row };
37
+ }
38
+ export function unknownRow(operation, id) {
39
+ return new PoolOperationError({
40
+ operation,
41
+ rowId: id,
42
+ phase: operation === 'pull' ? 'pull' : 'before-first-write',
43
+ retryable: false,
44
+ kind: 'unknown-row',
45
+ message: `no row ${id} in the pool`,
46
+ });
47
+ }
48
+ /**
49
+ * Refuses a row the store was told to distrust: opened with
50
+ * `requireCredentialStamps`, a row whose credential stamp is not bound loads
51
+ * `unbound` (see `PoolRow.unbound`). Called on every locked read of the row
52
+ * an operation acts on, before it calls a provider or writes, so a credential
53
+ * another writer swapped in while the operation waited is refused too.
54
+ */
55
+ export function requireBound(operation, row) {
56
+ if (row.unbound)
57
+ throw refusal(operation, row.id, 'unbound-credential', `row ${row.id}'s credential is not the one this store stamped for it (stamp ${row.stamp}); replace it with fresh material`);
58
+ }
59
+ export function refusal(operation, id, kind, message, retryable = false) {
60
+ return new PoolOperationError({
61
+ operation,
62
+ rowId: id,
63
+ phase: operation === 'pull' ? 'pull' : 'before-first-write',
64
+ retryable,
65
+ kind,
66
+ message,
67
+ });
68
+ }
@@ -0,0 +1,443 @@
1
+ /** Top-level key of the config file that holds everything the pool adds. */
2
+ export declare const POOL_KEY = "commonAuthPool";
3
+ /** The pool schema this library reads and writes. */
4
+ export declare const POOL_SCHEMA_VERSION = 1;
5
+ /** Property of `commonAuthPool` holding the per-row entries, keyed by local id. */
6
+ export declare const POOL_ROWS_KEY = "rows";
7
+ /**
8
+ * Property of `commonAuthPool` (since 0.8.0) holding, per id, the highest
9
+ * credential epoch a row with that id held when the store last dropped it
10
+ * from the pool. A row added later under the same id starts past it (see
11
+ * `nextAddEpochIn`), so an attribution taken for the dropped row never
12
+ * matches the new one. Older readers ignore it, and older writers keep it
13
+ * as they keep every pool key they do not know.
14
+ */
15
+ export declare const POOL_RETIRED_EPOCHS_KEY = "retiredEpochs";
16
+ /** The `version` older readers of the same files expect at the top level. */
17
+ export declare const LEGACY_STORE_VERSION = 1;
18
+ /**
19
+ * How far ahead of the clock a stored `lastRefreshedAt` may sit and still be
20
+ * trusted. Older readers of the state file apply the same bound, and a stamp
21
+ * strictly above it counts as absent when they compare two copies of a token.
22
+ */
23
+ export declare const REFRESH_STAMP_TOLERANCE_MS: number;
24
+ export type OAuthCredential = {
25
+ type: 'oauth';
26
+ access?: string;
27
+ refresh: string;
28
+ expires?: number;
29
+ };
30
+ export type ApiKeyCredential = {
31
+ type: 'api';
32
+ apiKey: string;
33
+ baseURL: string;
34
+ authHeader?: 'authorization-bearer' | 'x-api-key';
35
+ };
36
+ export type PoolCredential = OAuthCredential | ApiKeyCredential;
37
+ /**
38
+ * What `rotate` takes. Rotation refreshes the secret of the endpoint a row
39
+ * already has, so an API key may leave out `baseURL` (and `authHeader`) to
40
+ * keep the row's; one it gives must equal the row's.
41
+ */
42
+ export type RotateCredential = OAuthCredential | (Omit<ApiKeyCredential, 'baseURL'> & {
43
+ baseURL?: string;
44
+ });
45
+ /** A credential as stored: an OAuth credential also carries its refresh stamp. */
46
+ export type StoredCredential = (OAuthCredential & {
47
+ lastRefreshedAt?: number;
48
+ }) | ApiKeyCredential;
49
+ /** Quota codec supplied by `/quota`: the store never interprets the map itself. */
50
+ export interface QuotaCodec {
51
+ validate(value: unknown): boolean;
52
+ merge(stored: unknown | undefined, observation: unknown): unknown;
53
+ }
54
+ /**
55
+ * What `ProviderStateCodec.onReplace` is told about a replacement: the row id,
56
+ * the credential epoch the new credential starts, `previousIdentity` (the
57
+ * identity the locked row recorded before the replace), `identity` (the
58
+ * identity the replace records), and the provider state the caller handed to
59
+ * `replace`, if any. Each identity is absent when none was recorded.
60
+ */
61
+ export interface ProviderStateReplacement {
62
+ id: string;
63
+ credentialEpoch: number;
64
+ previousIdentity?: string;
65
+ identity?: string;
66
+ incoming?: unknown;
67
+ }
68
+ /**
69
+ * Codec for the provider state a plugin keeps beside each row's credential
70
+ * (a project id, a device fingerprint, eligibility times: whatever belongs to
71
+ * that credential). The store never interprets the value: it stores it as
72
+ * JSON, asks `validate` before every write and on every load, and calls the
73
+ * hooks below where two values meet. Every hook is synchronous and runs
74
+ * under the store locks.
75
+ */
76
+ export interface ProviderStateCodec {
77
+ validate(value: unknown): boolean;
78
+ /**
79
+ * The part of a (valid) value that belongs to the credential: what is true
80
+ * of the account the credential signs in to, such as a project id or a
81
+ * device fingerprint, as opposed to what the plugin merely tracks about
82
+ * its use, such as a cooldown or a cursor. The credential stamp covers the
83
+ * digest of exactly this projection, so a foreign edit of it hides the
84
+ * value, while the rest may change through `updateProviderState` without
85
+ * the stamp being rewritten. It must be a pure function of the value that
86
+ * returns JSON with a deterministic key order. Without it the whole value
87
+ * is credential-bound.
88
+ */
89
+ credentialBound?(value: unknown): unknown;
90
+ /**
91
+ * Combines the value on disk with one a write brings (`add` of a secret the
92
+ * pool already holds, `rotate`, or a refresh whose provider returned a
93
+ * state). Called only when the row has a value on disk; without it the
94
+ * incoming value replaces the stored one. Its result is validated.
95
+ */
96
+ merge?(onDisk: unknown, incoming: unknown): unknown;
97
+ /**
98
+ * The provider state of a row once `replace` gives it a new credential
99
+ * epoch. `previous` is the old credential's value (undefined when the row
100
+ * shows none). Returning undefined clears it. Without this hook a replace
101
+ * keeps the value handed to `replace` and otherwise clears the state.
102
+ */
103
+ onReplace?(previous: unknown | undefined, replacement: ProviderStateReplacement): unknown | undefined;
104
+ }
105
+ /**
106
+ * Why a row shows no provider state although the state file holds one for it.
107
+ *
108
+ * `uncovered`: the value's credential-bound part (see
109
+ * `ProviderStateCodec.credentialBound`) is not the one this store last
110
+ * wrote beside the row's credential at its credential epoch and recorded
111
+ * identity. Another writer edited it, or
112
+ * wrote the credential beside it without knowing about it (an older version
113
+ * of this library, which drops the coverage, or a writer that does not know
114
+ * the pool at all), or it belongs to an earlier credential of the row.
115
+ * `invalid`: the value is covered but the codec rejects it, or the store was
116
+ * opened without a provider-state codec.
117
+ */
118
+ export type ProviderStateDrop = 'uncovered' | 'invalid';
119
+ /**
120
+ * What the stamp beside a row's credential proves (see `CredentialStamp`).
121
+ *
122
+ * `none`: the row holds no credential, so there is nothing to stamp.
123
+ * `bound`: the stamp was written with this credential (its digest matches),
124
+ * names the row's credential epoch (1 for a row without a per-row entry),
125
+ * the identity it records (or its recording none) and any endpoint it
126
+ * records are the row's, and its dispatch digest matches everything a
127
+ * request would send (the OAuth access and refresh tokens and expiry; the API
128
+ * key with its `baseURL` and `authHeader`).
129
+ * `missing`: the credential carries no stamp (written by a writer that does
130
+ * not know about stamps, or one that dropped it).
131
+ * `malformed`: the stamp is not one this store writes (wrong shape, or an
132
+ * epoch outside the positive safe integers).
133
+ * `mismatched`: the stamp was written for another credential, epoch,
134
+ * identity, endpoint, or token to send than the row now holds.
135
+ * `legacy`: a well-formed stamp written with this credential's secret but
136
+ * with no dispatch digest (written by 0.4.3 or earlier), so it proves
137
+ * neither the token sent nor the account or endpoint it goes to.
138
+ */
139
+ export type CredentialStampStatus = 'none' | 'bound' | 'missing' | 'malformed' | 'mismatched' | 'legacy';
140
+ /** One row of the pool as loaded. */
141
+ export interface PoolRow {
142
+ id: string;
143
+ type: 'oauth' | 'api';
144
+ label?: string;
145
+ enabled: boolean;
146
+ addedAt?: number;
147
+ /** Recorded wire identity (the roster row's `accountId`), when known. */
148
+ identity?: string;
149
+ /** Undefined when the state file holds no usable credential for the row. */
150
+ credential?: StoredCredential;
151
+ /** Stable hash of the credential's secret material; never persisted. */
152
+ fingerprint?: string;
153
+ /** Undefined when the row has no per-row entry yet. */
154
+ credentialEpoch?: number;
155
+ needsFirstReading: boolean;
156
+ disabledReason?: string;
157
+ /** Store-owned reservation; only `publishRoster` releases it for ordinary use. */
158
+ staged?: {
159
+ reservation: string;
160
+ };
161
+ /** The opaque quota map, as validated by the codec. */
162
+ quota?: unknown;
163
+ /**
164
+ * The opaque provider state kept beside the credential, as validated by
165
+ * the provider-state codec. Absent when the row has none, or when the one
166
+ * on disk is not shown (see `providerStateDropped`).
167
+ */
168
+ providerState?: unknown;
169
+ /**
170
+ * Set when the state file holds a provider state for the row that is not
171
+ * shown, and why. The value stays on disk untouched until a write on the
172
+ * row sets or clears it; the row itself stays usable.
173
+ */
174
+ providerStateDropped?: ProviderStateDrop;
175
+ hasEntry: boolean;
176
+ /** A row that may be refreshed, pulled for, or admitted. */
177
+ candidate: boolean;
178
+ /** Set when the roster row or the per-row entry failed validation. */
179
+ invalid?: 'roster' | 'entry';
180
+ /**
181
+ * Set when a replace stopped between its two writes: the state file holds
182
+ * the new credential, stamped with the epoch and the identity or endpoint
183
+ * it belongs to, and the config still holds the replaced row. Also set when
184
+ * a write that gives a row its first identity (`recordIdentity`, or a
185
+ * `rotate` or refresh that learns one) stopped after stamping the identity
186
+ * and before recording it in the config, and when an attributed `disable`
187
+ * or `enable` that changed the provider state stopped after its state
188
+ * write and before flipping the row in the config. The row is shown as the
189
+ * write leaves it once completed, is never a candidate, and the next store
190
+ * write on it writes the config to match.
191
+ */
192
+ torn?: true;
193
+ /**
194
+ * Whether the credential is the one the store last stamped for this row
195
+ * (see `CredentialStampStatus`). Every row the store loads carries it; a
196
+ * torn row reports the stamp of the row as it is shown completed. It is
197
+ * optional only so that rows built by hand (test fixtures) still type.
198
+ */
199
+ stamp?: CredentialStampStatus;
200
+ /**
201
+ * Set only when the store was opened with `requireCredentialStamps` and
202
+ * the row's `stamp` is not `bound`: the row is never a candidate, and
203
+ * `refresh`, quota pulls, `recordQuota`, `recordIdentity`, `rotate` and a
204
+ * re-`add` onto it refuse with `unbound-credential`. Only `replace` (or a
205
+ * new row) makes it usable again.
206
+ */
207
+ unbound?: true;
208
+ }
209
+ /**
210
+ * Key, inside a state-file account entry, of the stamp naming what the
211
+ * credential beside it belongs to. Older readers ignore it.
212
+ */
213
+ export declare const CREDENTIAL_STAMP_KEY = "commonAuthPool";
214
+ /**
215
+ * What the config holds for a credential when its stamp is written: the
216
+ * identity it belongs to (absent: none is known yet) and, for an API key, its
217
+ * endpoint. For a replace it is the config the replace is about to write.
218
+ */
219
+ export interface CredentialBinding {
220
+ identity?: string;
221
+ baseURL?: string;
222
+ authHeader?: 'authorization-bearer' | 'x-api-key';
223
+ }
224
+ /**
225
+ * Written beside every credential the store puts in the state file. It names
226
+ * the credential epoch the credential belongs to and a digest of its secret,
227
+ * so a stamp left beside a credential another writer put there afterwards is
228
+ * recognisable and ignored.
229
+ *
230
+ * `digest` covers only the refresh token or API key: it names the credential
231
+ * lineage, and torn-replace detection matches it, including against stamps
232
+ * older versions wrote, so it keeps that exact definition. `dispatch` covers
233
+ * everything a request sends (see `dispatchDigest`), so a token or endpoint
234
+ * changed beside an unchanged lineage secret is caught; stamps written by
235
+ * 0.4.3 or earlier lack it.
236
+ *
237
+ * `binding` is the config the credential was written beside (see
238
+ * `CredentialBinding`); every write since 0.4.4 records it, earlier versions
239
+ * only on replace. `replace` marks a stamp written by a replace, which is
240
+ * what lets a reader complete a replace that stopped after writing the
241
+ * credential: a stamp from any other write is never completed as torn.
242
+ *
243
+ * `providerState` is the digest of the credential-bound part of the provider
244
+ * state beside the credential (see `providerStateDigest`); it is absent when
245
+ * the row has none, so the stamp of a row without provider state is exactly
246
+ * what 0.5.0 wrote. It is apart from `digest` and `dispatch`, which keep
247
+ * their meaning: the credential's stamp status never depends on it.
248
+ */
249
+ export interface CredentialStamp {
250
+ credentialEpoch: number;
251
+ digest: string;
252
+ dispatch?: string;
253
+ binding?: CredentialBinding;
254
+ replace?: true;
255
+ providerState?: string;
256
+ staged?: StagedStamp;
257
+ }
258
+ /** Original staged-add metadata, persisted with the credential before config exists. */
259
+ export interface StagedStamp {
260
+ reservation: string;
261
+ label?: string;
262
+ disabledReason: string;
263
+ providerState?: string;
264
+ }
265
+ /** Canonical JSON: recursively sorted object keys, preserved array order. */
266
+ export declare function canonicalJson(value: unknown): string;
267
+ export declare function canonicalDigest(value: unknown): string;
268
+ export declare function parseReservation(raw: unknown): {
269
+ reservation: string;
270
+ } | undefined;
271
+ /**
272
+ * Key, inside a state-file account entry, of the provider state kept beside
273
+ * the credential. Older readers ignore it.
274
+ */
275
+ export declare const PROVIDER_STATE_KEY = "commonAuthProviderState";
276
+ export type ConfigClassification = {
277
+ status: 'ready';
278
+ exists: boolean;
279
+ config: Record<string, unknown>;
280
+ } | {
281
+ status: 'pending-migration';
282
+ config: Record<string, unknown>;
283
+ } | {
284
+ status: 'error';
285
+ reason: string;
286
+ };
287
+ export type StateClassification = {
288
+ status: 'ready';
289
+ exists: boolean;
290
+ state: Record<string, unknown>;
291
+ } | {
292
+ status: 'error';
293
+ reason: string;
294
+ };
295
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
296
+ /**
297
+ * Ids are stored exactly as given. Older readers trim ids, so an id with
298
+ * surrounding whitespace would be renamed by them; such ids, empty ids and
299
+ * prototype keys are refused instead of being rewritten.
300
+ */
301
+ export declare function idProblem(id: unknown): string | undefined;
302
+ /** Same URL rule the older readers apply to an API-key row's `baseURL`. */
303
+ export declare function isValidBaseURL(value: unknown): boolean;
304
+ export declare function fingerprintOf(credential: PoolCredential | StoredCredential): string;
305
+ /**
306
+ * The digest a credential stamp carries. It is kept apart from the
307
+ * fingerprint (a different input prefix) so the persisted value is never the
308
+ * dedupe key.
309
+ */
310
+ export declare function credentialDigest(credential: PoolCredential | StoredCredential): string;
311
+ /**
312
+ * The digest of everything a request made with the credential sends or is
313
+ * served by: the OAuth access token, refresh token and expiry (the expiry
314
+ * decides whether the access token is used or refreshed first), or the API
315
+ * key with the `baseURL` and header it is sent to. Its input prefix differs
316
+ * from both the fingerprint's and `credentialDigest`'s, so it never equals
317
+ * either. The parts are JSON-encoded as a list, so no two credentials share
318
+ * an input. An access token or expiry the state file cannot hold as loaded
319
+ * (not a string, not a finite number) counts as absent, which is how
320
+ * `buildRawRows` loads it back.
321
+ */
322
+ export declare function dispatchDigest(credential: PoolCredential | StoredCredential): string;
323
+ /**
324
+ * The stamp for a credential written into a row at `credentialEpoch`, beside
325
+ * the config `binding` describes. `replace` is set only by a replace.
326
+ */
327
+ export declare function stampFor(credential: PoolCredential | StoredCredential, credentialEpoch: number, binding: CredentialBinding, options?: {
328
+ replace?: boolean;
329
+ providerState?: string;
330
+ }): CredentialStamp;
331
+ /**
332
+ * The digest a stamp carries for a provider state: of its credential-bound
333
+ * part (`ProviderStateCodec.credentialBound`, the whole value without it), as
334
+ * it serializes. The store only ever stores values that survive a JSON round
335
+ * trip unchanged, so the digest of a value read back from disk equals the one
336
+ * computed when it was written. Its input prefix differs from every other
337
+ * digest the store writes.
338
+ */
339
+ export declare function providerStateDigest(codec: Pick<ProviderStateCodec, 'credentialBound'> | undefined, value: unknown): string;
340
+ /**
341
+ * The provider-state digest of the stamp in a state-file account entry, when
342
+ * that stamp binds it to this row: written with this credential (its lineage
343
+ * digest matches), at this credential epoch, naming this recorded identity.
344
+ * Whether the value beside it still has that digest is checked apart, by
345
+ * `providerStateFields`; this alone is what a write that keeps the value
346
+ * carries into the stamp it writes, so a value no stamp of this store bound
347
+ * to the row stays unbound rather than being vouched for, and one edited
348
+ * after it was bound stays detectably edited.
349
+ */
350
+ export declare function boundProviderStateDigest(account: unknown, credential: PoolCredential | StoredCredential | undefined, credentialEpoch: number | undefined, identity: string | undefined): string | undefined;
351
+ /**
352
+ * A credential epoch is a positive safe integer. Above `MAX_SAFE_INTEGER`,
353
+ * adding one may give back the same number, so a replace would not move the
354
+ * epoch and nothing could tell the old credential's work from the new one's.
355
+ */
356
+ export declare function isCredentialEpoch(value: unknown): value is number;
357
+ /** A well-formed stamp, or undefined for anything else (which is ignored). */
358
+ export declare function parseStamp(raw: unknown): CredentialStamp | undefined;
359
+ /** A parsed file, or the reason it could not be parsed. */
360
+ export type FileRead = {
361
+ exists: false;
362
+ } | {
363
+ exists: true;
364
+ value: unknown;
365
+ } | {
366
+ exists: true;
367
+ parseError: unknown;
368
+ };
369
+ export declare function classifyConfig(read: FileRead): ConfigClassification;
370
+ export declare function classifyState(read: FileRead): StateClassification;
371
+ export declare function rosterOf(config: Record<string, unknown>): unknown[];
372
+ export declare function entriesOf(config: Record<string, unknown>): Record<string, unknown>;
373
+ /** The first roster row with this id (the one the pool loads). */
374
+ export declare function rosterRowIn(config: Record<string, unknown>, id: string): Record<string, unknown> | undefined;
375
+ /** The per-row entries of a config, created (empty) when absent. */
376
+ export declare function ensureEntries(config: Record<string, unknown>): Record<string, unknown>;
377
+ export declare function entryIn(config: Record<string, unknown>, id: string): Record<string, unknown> | undefined;
378
+ /** Sets an entry as an own property, so an id such as `toString` is safe. */
379
+ export declare function setEntryIn(config: Record<string, unknown>, id: string, entry: Record<string, unknown>): void;
380
+ /**
381
+ * The credential epoch recorded for a dropped id (see
382
+ * `POOL_RETIRED_EPOCHS_KEY`), or undefined when none is. A value that is not
383
+ * a credential epoch counts as none.
384
+ */
385
+ export declare function retiredEpochIn(config: Record<string, unknown>, id: string): number | undefined;
386
+ /**
387
+ * The credential epoch `add` gives a new row with this id: one past the
388
+ * highest epoch the id is known to have held, which is the epoch recorded
389
+ * when the store dropped it, or the epoch of an entry left behind by a writer
390
+ * that removed only its roster row; 1 for an id the pool never held.
391
+ *
392
+ * An attribution names a row by id and credential epoch (and identity), and
393
+ * an id is chosen by the plugin, so it is often the same one again (`main`).
394
+ * Were a re-added row to start at epoch 1 again, an attribution taken for the
395
+ * removed row's credential would match the new credential exactly, in this
396
+ * process or any other. Starting past every earlier epoch makes such an
397
+ * attribution fail as it does after a `replace`. The result may lie past the
398
+ * safe integers (an id whose last row was at `Number.MAX_SAFE_INTEGER`);
399
+ * `add` refuses such an id.
400
+ */
401
+ export declare function nextAddEpochIn(config: Record<string, unknown>, id: string): number;
402
+ /**
403
+ * Records, in a config being written, the epochs of the ids it drops: for
404
+ * each, the epoch its entry claims (1 for a row without one, the epoch such a
405
+ * row is at), kept only when above what is already recorded, so the record
406
+ * for an id never goes down. Valid recorded values of other ids are kept; a
407
+ * record that is not an object, or a value in it that is not an epoch, says
408
+ * nothing and is replaced. An entry whose epoch cannot be read records 1.
409
+ */
410
+ export declare function retireEpochsIn(config: Record<string, unknown>, dropped: Iterable<string>): void;
411
+ /**
412
+ * Builds the rows of a ready pool from the files exactly as they are, without
413
+ * looking at credential stamps (see `loadRows` for the rows every reader
414
+ * gets). A roster row the older readers would reject, a duplicate id, or a
415
+ * malformed per-row entry makes that one row invalid (never a candidate) and
416
+ * blocks nothing else.
417
+ */
418
+ export declare function buildRawRows(config: Record<string, unknown>, state: Record<string, unknown>, codec: QuotaCodec, providerCodec?: ProviderStateCodec): PoolRow[];
419
+ /** The row-lock key: recorded wire identity when known, else the local id. */
420
+ export declare function rowLockKey(row: Pick<PoolRow, 'id' | 'identity'>): string;
421
+ /**
422
+ * The refresh stamp a write persists: the clock, raised to one past a prior
423
+ * stamp that is still trusted, so a stale copy of the previous token can never
424
+ * compare newer than the rotation. A prior stamp beyond the trust bound says
425
+ * nothing and is ignored.
426
+ */
427
+ export declare function rotationStamp(prior: number | undefined, now: number): number;
428
+ /** True when a rotation stamped now would itself be past the trust bound. */
429
+ export declare function rotationStampUntrusted(prior: number | undefined, now: number): boolean;
430
+ /** The legacy-shaped roster row for a new row. */
431
+ export declare function rosterRowFor(input: {
432
+ id: string;
433
+ credential: PoolCredential;
434
+ identity?: string;
435
+ label?: string;
436
+ addedAt: number;
437
+ }): Record<string, unknown>;
438
+ /** The state-file fields a credential occupies, in the older readers' names. */
439
+ export declare function stateFieldsFor(credential: PoolCredential, lastRefreshedAt: number | undefined): Record<string, unknown>;
440
+ export declare function storedCredential(credential: PoolCredential, lastRefreshedAt: number | undefined): StoredCredential;
441
+ export declare function credentialProblem(credential: unknown, options?: {
442
+ baseURLOptional?: boolean;
443
+ }): string | undefined;