@bastani/atomic 0.9.11-alpha.7 → 0.9.11-alpha.8

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 (325) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +3 -5
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/mcp/sampling-handler.ts +1 -5
  6. package/dist/builtin/subagents/package.json +1 -1
  7. package/dist/builtin/web-access/package.json +1 -1
  8. package/dist/builtin/workflows/CHANGELOG.md +1 -0
  9. package/dist/builtin/workflows/README.md +1 -1
  10. package/dist/builtin/workflows/package.json +1 -1
  11. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +1 -24
  12. package/dist/builtin/workflows/src/extension/index.bundle.mjs +31 -28
  13. package/dist/builtin/workflows/src/extension/workflow-model-catalog.ts +26 -0
  14. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +3 -2
  15. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +5 -5
  16. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session-options.ts +3 -3
  17. package/dist/builtin/workflows/src/runs/foreground/stage-runner-session.ts +2 -2
  18. package/dist/cli/list-models.d.ts +2 -2
  19. package/dist/cli/list-models.d.ts.map +1 -1
  20. package/dist/cli/list-models.js +5 -5
  21. package/dist/cli/list-models.js.map +1 -1
  22. package/dist/core/agent-session-accessors.js +1 -1
  23. package/dist/core/agent-session-accessors.js.map +1 -1
  24. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  25. package/dist/core/agent-session-auto-compaction.js +2 -5
  26. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  27. package/dist/core/agent-session-compaction.js +1 -1
  28. package/dist/core/agent-session-compaction.js.map +1 -1
  29. package/dist/core/agent-session-extension-bindings.js +5 -5
  30. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  31. package/dist/core/agent-session-methods.d.ts +4 -4
  32. package/dist/core/agent-session-methods.d.ts.map +1 -1
  33. package/dist/core/agent-session-methods.js.map +1 -1
  34. package/dist/core/agent-session-models.d.ts +1 -1
  35. package/dist/core/agent-session-models.d.ts.map +1 -1
  36. package/dist/core/agent-session-models.js +18 -14
  37. package/dist/core/agent-session-models.js.map +1 -1
  38. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
  39. package/dist/core/agent-session-post-tool-compaction.js +2 -4
  40. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  41. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  42. package/dist/core/agent-session-prompt.js +3 -7
  43. package/dist/core/agent-session-prompt.js.map +1 -1
  44. package/dist/core/agent-session-retry.js +1 -1
  45. package/dist/core/agent-session-retry.js.map +1 -1
  46. package/dist/core/agent-session-runtime-auth.d.ts +3 -3
  47. package/dist/core/agent-session-runtime-auth.d.ts.map +1 -1
  48. package/dist/core/agent-session-runtime-auth.js +4 -14
  49. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  50. package/dist/core/agent-session-runtime.d.ts +1 -1
  51. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  52. package/dist/core/agent-session-runtime.js +3 -3
  53. package/dist/core/agent-session-runtime.js.map +1 -1
  54. package/dist/core/agent-session-services.d.ts +3 -8
  55. package/dist/core/agent-session-services.d.ts.map +1 -1
  56. package/dist/core/agent-session-services.js +16 -23
  57. package/dist/core/agent-session-services.js.map +1 -1
  58. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  59. package/dist/core/agent-session-tool-registry.js +2 -1
  60. package/dist/core/agent-session-tool-registry.js.map +1 -1
  61. package/dist/core/agent-session-types.d.ts +2 -2
  62. package/dist/core/agent-session-types.d.ts.map +1 -1
  63. package/dist/core/agent-session-types.js.map +1 -1
  64. package/dist/core/agent-session.d.ts +2 -2
  65. package/dist/core/agent-session.d.ts.map +1 -1
  66. package/dist/core/agent-session.js +1 -1
  67. package/dist/core/agent-session.js.map +1 -1
  68. package/dist/core/auth-storage-backends.d.ts +1 -0
  69. package/dist/core/auth-storage-backends.d.ts.map +1 -1
  70. package/dist/core/auth-storage-backends.js +18 -4
  71. package/dist/core/auth-storage-backends.js.map +1 -1
  72. package/dist/core/auth-storage.d.ts +12 -139
  73. package/dist/core/auth-storage.d.ts.map +1 -1
  74. package/dist/core/auth-storage.js +68 -374
  75. package/dist/core/auth-storage.js.map +1 -1
  76. package/dist/core/copilot-env-routing.d.ts +36 -0
  77. package/dist/core/copilot-env-routing.d.ts.map +1 -0
  78. package/dist/core/copilot-env-routing.js +94 -0
  79. package/dist/core/copilot-env-routing.js.map +1 -0
  80. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  81. package/dist/core/extensions/loader-virtual-modules.js +10 -2
  82. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  83. package/dist/core/extensions/provider-types.d.ts +0 -40
  84. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  85. package/dist/core/extensions/provider-types.js.map +1 -1
  86. package/dist/core/fallback-models.d.ts +4 -4
  87. package/dist/core/fallback-models.d.ts.map +1 -1
  88. package/dist/core/fallback-models.js +3 -3
  89. package/dist/core/fallback-models.js.map +1 -1
  90. package/dist/core/model-config.d.ts +542 -0
  91. package/dist/core/model-config.d.ts.map +1 -0
  92. package/dist/core/{model-registry-schemas.js → model-config.js} +85 -34
  93. package/dist/core/model-config.js.map +1 -0
  94. package/dist/core/model-registry.d.ts +25 -85
  95. package/dist/core/model-registry.d.ts.map +1 -1
  96. package/dist/core/model-registry.js +65 -388
  97. package/dist/core/model-registry.js.map +1 -1
  98. package/dist/core/model-resolver-cli.d.ts +2 -2
  99. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  100. package/dist/core/model-resolver-cli.js +2 -2
  101. package/dist/core/model-resolver-cli.js.map +1 -1
  102. package/dist/core/model-resolver-initial.d.ts +4 -4
  103. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  104. package/dist/core/model-resolver-initial.js +17 -17
  105. package/dist/core/model-resolver-initial.js.map +1 -1
  106. package/dist/core/model-resolver-scope.d.ts +3 -3
  107. package/dist/core/model-resolver-scope.d.ts.map +1 -1
  108. package/dist/core/model-resolver-scope.js +4 -4
  109. package/dist/core/model-resolver-scope.js.map +1 -1
  110. package/dist/core/model-runtime-auth.d.ts +7 -0
  111. package/dist/core/model-runtime-auth.d.ts.map +1 -0
  112. package/dist/core/model-runtime-auth.js +14 -0
  113. package/dist/core/model-runtime-auth.js.map +1 -0
  114. package/dist/core/model-runtime-providers.d.ts +6 -0
  115. package/dist/core/model-runtime-providers.d.ts.map +1 -0
  116. package/dist/core/model-runtime-providers.js +22 -0
  117. package/dist/core/model-runtime-providers.js.map +1 -0
  118. package/dist/core/model-runtime-restoration.d.ts +6 -0
  119. package/dist/core/model-runtime-restoration.d.ts.map +1 -0
  120. package/dist/core/model-runtime-restoration.js +21 -0
  121. package/dist/core/model-runtime-restoration.js.map +1 -0
  122. package/dist/core/model-runtime-snapshot.d.ts +16 -0
  123. package/dist/core/model-runtime-snapshot.d.ts.map +1 -0
  124. package/dist/core/model-runtime-snapshot.js +52 -0
  125. package/dist/core/model-runtime-snapshot.js.map +1 -0
  126. package/dist/core/model-runtime-streaming.d.ts +17 -0
  127. package/dist/core/model-runtime-streaming.d.ts.map +1 -0
  128. package/dist/core/model-runtime-streaming.js +66 -0
  129. package/dist/core/model-runtime-streaming.js.map +1 -0
  130. package/dist/core/model-runtime-types.d.ts +21 -0
  131. package/dist/core/model-runtime-types.d.ts.map +1 -0
  132. package/dist/core/model-runtime-types.js +2 -0
  133. package/dist/core/model-runtime-types.js.map +1 -0
  134. package/dist/core/model-runtime.d.ts +50 -29
  135. package/dist/core/model-runtime.d.ts.map +1 -1
  136. package/dist/core/model-runtime.js +330 -90
  137. package/dist/core/model-runtime.js.map +1 -1
  138. package/dist/core/models-store.d.ts +2 -10
  139. package/dist/core/models-store.d.ts.map +1 -1
  140. package/dist/core/models-store.js +2 -29
  141. package/dist/core/models-store.js.map +1 -1
  142. package/dist/core/oauth-login.d.ts +24 -0
  143. package/dist/core/oauth-login.d.ts.map +1 -0
  144. package/dist/core/oauth-login.js +87 -0
  145. package/dist/core/oauth-login.js.map +1 -0
  146. package/dist/core/oauth-provider-metadata.d.ts +5 -0
  147. package/dist/core/oauth-provider-metadata.d.ts.map +1 -0
  148. package/dist/core/oauth-provider-metadata.js +19 -0
  149. package/dist/core/oauth-provider-metadata.js.map +1 -0
  150. package/dist/core/provider-composer-internal.d.ts +53 -0
  151. package/dist/core/provider-composer-internal.d.ts.map +1 -0
  152. package/dist/core/provider-composer-internal.js +273 -0
  153. package/dist/core/provider-composer-internal.js.map +1 -0
  154. package/dist/core/provider-composer.d.ts +16 -0
  155. package/dist/core/provider-composer.d.ts.map +1 -0
  156. package/dist/core/provider-composer.js +108 -0
  157. package/dist/core/provider-composer.js.map +1 -0
  158. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  159. package/dist/core/remote-catalog-provider.js +74 -122
  160. package/dist/core/remote-catalog-provider.js.map +1 -1
  161. package/dist/core/resolve-config-value.d.ts +8 -7
  162. package/dist/core/resolve-config-value.d.ts.map +1 -1
  163. package/dist/core/resolve-config-value.js +26 -23
  164. package/dist/core/resolve-config-value.js.map +1 -1
  165. package/dist/core/runtime-credentials.d.ts +16 -0
  166. package/dist/core/runtime-credentials.d.ts.map +1 -0
  167. package/dist/core/runtime-credentials.js +42 -0
  168. package/dist/core/runtime-credentials.js.map +1 -0
  169. package/dist/core/sdk-types.d.ts +1 -7
  170. package/dist/core/sdk-types.d.ts.map +1 -1
  171. package/dist/core/sdk-types.js.map +1 -1
  172. package/dist/core/sdk.d.ts.map +1 -1
  173. package/dist/core/sdk.js +27 -28
  174. package/dist/core/sdk.js.map +1 -1
  175. package/dist/extensions/llama/index.js +1 -1
  176. package/dist/extensions/llama/index.js.map +1 -1
  177. package/dist/extensions/llama/provider.d.ts +2 -4
  178. package/dist/extensions/llama/provider.d.ts.map +1 -1
  179. package/dist/extensions/llama/provider.js +25 -17
  180. package/dist/extensions/llama/provider.js.map +1 -1
  181. package/dist/index.d.ts +2 -3
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +3 -4
  184. package/dist/index.js.map +1 -1
  185. package/dist/main-runtime-api-key.d.ts +6 -0
  186. package/dist/main-runtime-api-key.d.ts.map +1 -0
  187. package/dist/main-runtime-api-key.js +6 -0
  188. package/dist/main-runtime-api-key.js.map +1 -0
  189. package/dist/main-session-options.d.ts +2 -2
  190. package/dist/main-session-options.d.ts.map +1 -1
  191. package/dist/main-session-options.js +3 -3
  192. package/dist/main-session-options.js.map +1 -1
  193. package/dist/main.d.ts.map +1 -1
  194. package/dist/main.js +9 -11
  195. package/dist/main.js.map +1 -1
  196. package/dist/modes/interactive/components/footer.js +1 -1
  197. package/dist/modes/interactive/components/footer.js.map +1 -1
  198. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/login-dialog.js +1 -3
  200. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  201. package/dist/modes/interactive/components/model-selector.d.ts +4 -3
  202. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  203. package/dist/modes/interactive/components/model-selector.js +56 -73
  204. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  205. package/dist/modes/interactive/components/oauth-selector.d.ts +4 -3
  206. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  207. package/dist/modes/interactive/components/oauth-selector.js +15 -24
  208. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  209. package/dist/modes/interactive/interactive-agent-events.js +1 -1
  210. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  211. package/dist/modes/interactive/interactive-auth-login.js +20 -31
  212. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  213. package/dist/modes/interactive/interactive-auth-routing.d.ts +1 -1
  214. package/dist/modes/interactive/interactive-auth-routing.d.ts.map +1 -1
  215. package/dist/modes/interactive/interactive-auth-routing.js +21 -47
  216. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  217. package/dist/modes/interactive/interactive-autocomplete.js +3 -3
  218. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  219. package/dist/modes/interactive/interactive-deferred-startup.js +8 -8
  220. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  221. package/dist/modes/interactive/interactive-extension-runtime.js +2 -1
  222. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  223. package/dist/modes/interactive/interactive-model-catalog-startup.js +2 -2
  224. package/dist/modes/interactive/interactive-model-catalog-startup.js.map +1 -1
  225. package/dist/modes/interactive/interactive-model-routing.js +11 -11
  226. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  227. package/dist/modes/interactive/interactive-render-chat.js +1 -1
  228. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  229. package/dist/modes/interactive/interactive-slash-commands.js +2 -2
  230. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  231. package/dist/modes/interactive/interactive-startup.js +1 -1
  232. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  233. package/dist/modes/interactive-engine/isolated-auth.d.ts +2 -2
  234. package/dist/modes/interactive-engine/isolated-auth.d.ts.map +1 -1
  235. package/dist/modes/interactive-engine/isolated-auth.js +4 -3
  236. package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
  237. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  238. package/dist/modes/interactive-engine/isolated-runtime.js +4 -3
  239. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  240. package/dist/modes/interactive-engine/remote-model-catalog.d.ts +0 -1
  241. package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
  242. package/dist/modes/interactive-engine/remote-model-catalog.js +11 -50
  243. package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
  244. package/dist/modes/rpc/rpc-client-api.d.ts +2 -2
  245. package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
  246. package/dist/modes/rpc/rpc-client-api.js.map +1 -1
  247. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  248. package/dist/modes/rpc/rpc-command-handler.js +26 -19
  249. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  250. package/dist/modes/rpc/rpc-oauth-client.d.ts +1 -1
  251. package/dist/modes/rpc/rpc-oauth-client.d.ts.map +1 -1
  252. package/dist/modes/rpc/rpc-oauth-client.js +1 -1
  253. package/dist/modes/rpc/rpc-oauth-client.js.map +1 -1
  254. package/dist/modes/rpc/rpc-oauth-interaction.d.ts +1 -1
  255. package/dist/modes/rpc/rpc-oauth-interaction.d.ts.map +1 -1
  256. package/dist/modes/rpc/rpc-oauth-interaction.js +1 -1
  257. package/dist/modes/rpc/rpc-oauth-interaction.js.map +1 -1
  258. package/dist/modes/rpc/rpc-provider-auth.d.ts +4 -5
  259. package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
  260. package/dist/modes/rpc/rpc-provider-auth.js +19 -66
  261. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  262. package/dist/modes/rpc/rpc-session-binding.js +1 -1
  263. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  264. package/dist/modes/rpc/rpc-types.d.ts +7 -4
  265. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  266. package/dist/modes/rpc/rpc-types.js.map +1 -1
  267. package/dist/package-manager-cli.d.ts.map +1 -1
  268. package/dist/package-manager-cli.js +5 -7
  269. package/dist/package-manager-cli.js.map +1 -1
  270. package/docs/changelog.mdx +1 -1
  271. package/docs/custom-provider.md +1 -1
  272. package/docs/models.md +4 -6
  273. package/docs/providers.md +13 -0
  274. package/docs/quickstart.md +2 -1
  275. package/docs/sdk.md +32 -49
  276. package/docs/workflows.md +3 -3
  277. package/examples/sdk/02-custom-model.ts +8 -10
  278. package/examples/sdk/09-api-keys-and-oauth.ts +17 -23
  279. package/examples/sdk/12-full-control.ts +9 -11
  280. package/examples/sdk/README.md +17 -21
  281. package/npm-shrinkwrap.json +23 -23
  282. package/package.json +2 -2
  283. package/dist/core/model-registry-auth.d.ts +0 -10
  284. package/dist/core/model-registry-auth.d.ts.map +0 -1
  285. package/dist/core/model-registry-auth.js +0 -98
  286. package/dist/core/model-registry-auth.js.map +0 -1
  287. package/dist/core/model-registry-builtins.d.ts +0 -8
  288. package/dist/core/model-registry-builtins.d.ts.map +0 -1
  289. package/dist/core/model-registry-builtins.js +0 -104
  290. package/dist/core/model-registry-builtins.js.map +0 -1
  291. package/dist/core/model-registry-custom-loader.d.ts +0 -3
  292. package/dist/core/model-registry-custom-loader.d.ts.map +0 -1
  293. package/dist/core/model-registry-custom-loader.js +0 -255
  294. package/dist/core/model-registry-custom-loader.js.map +0 -1
  295. package/dist/core/model-registry-dynamic.d.ts +0 -7
  296. package/dist/core/model-registry-dynamic.d.ts.map +0 -1
  297. package/dist/core/model-registry-dynamic.js +0 -189
  298. package/dist/core/model-registry-dynamic.js.map +0 -1
  299. package/dist/core/model-registry-extension-refresh.d.ts +0 -23
  300. package/dist/core/model-registry-extension-refresh.d.ts.map +0 -1
  301. package/dist/core/model-registry-extension-refresh.js +0 -32
  302. package/dist/core/model-registry-extension-refresh.js.map +0 -1
  303. package/dist/core/model-registry-loader.d.ts +0 -5
  304. package/dist/core/model-registry-loader.d.ts.map +0 -1
  305. package/dist/core/model-registry-loader.js +0 -29
  306. package/dist/core/model-registry-loader.js.map +0 -1
  307. package/dist/core/model-registry-schemas.d.ts +0 -1399
  308. package/dist/core/model-registry-schemas.d.ts.map +0 -1
  309. package/dist/core/model-registry-schemas.js.map +0 -1
  310. package/dist/core/model-registry-types.d.ts +0 -91
  311. package/dist/core/model-registry-types.d.ts.map +0 -1
  312. package/dist/core/model-registry-types.js +0 -2
  313. package/dist/core/model-registry-types.js.map +0 -1
  314. package/dist/core/model-registry-validation.d.ts +0 -7
  315. package/dist/core/model-registry-validation.d.ts.map +0 -1
  316. package/dist/core/model-registry-validation.js +0 -12
  317. package/dist/core/model-registry-validation.js.map +0 -1
  318. package/dist/core/oauth-compat.d.ts +0 -17
  319. package/dist/core/oauth-compat.d.ts.map +0 -1
  320. package/dist/core/oauth-compat.js +0 -2
  321. package/dist/core/oauth-compat.js.map +0 -1
  322. package/dist/core/oauth-provider-bridge.d.ts +0 -63
  323. package/dist/core/oauth-provider-bridge.d.ts.map +0 -1
  324. package/dist/core/oauth-provider-bridge.js +0 -232
  325. package/dist/core/oauth-provider-bridge.js.map +0 -1
@@ -1,156 +1,29 @@
1
1
  /**
2
- * Credential storage for API keys and OAuth tokens.
3
- * Handles loading, saving, and refreshing credentials from auth.json.
4
- *
5
- * Uses file locking to prevent race conditions when multiple pi instances
6
- * try to refresh tokens simultaneously.
2
+ * CredentialStore implementation backed by auth.json.
3
+ * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.
7
4
  */
8
- import { type Credential, type CredentialStore, type ModelAuth, type OAuthCredentials } from "@earendil-works/pi-ai";
5
+ import type { Credential, CredentialInfo, CredentialStore } from "@earendil-works/pi-ai";
9
6
  import { type AuthStorageBackend } from "./auth-storage-backends.ts";
10
- import { type AtomicOAuthLoginCallbacks } from "./oauth-provider-bridge.ts";
11
- export type ApiKeyCredential = {
12
- type: "api_key";
13
- key?: string;
14
- /** Provider-scoped configuration persisted alongside the credential. */
15
- env?: Record<string, string>;
16
- };
17
- export type OAuthCredential = {
18
- type: "oauth";
19
- } & OAuthCredentials;
20
- export type AuthCredential = ApiKeyCredential | OAuthCredential;
21
- export type AuthStorageData = Record<string, AuthCredential>;
22
- export type AuthStatus = {
23
- configured: boolean;
24
- source?: "stored" | "runtime" | "environment" | "fallback" | "models_json_key" | "models_json_command";
25
- label?: string;
26
- };
27
7
  export { FileAuthStorageBackend, InMemoryAuthStorageBackend, type AuthStorageBackend } from "./auth-storage-backends.ts";
28
- /** Read one persisted provider credential using Atomic's layered config paths. */
29
- export declare function readStoredCredential(providerId: string, authPath?: string | string[]): Credential | undefined;
30
- /**
31
- * Credential storage backed by a JSON file.
32
- */
33
- export declare class AuthStorage {
8
+ export type AuthStorageData = Record<string, Credential>;
9
+ export declare class AuthStorage implements CredentialStore {
34
10
  private data;
35
- private runtimeOverrides;
36
- private fallbackResolver?;
37
- private loadError;
38
- private errors;
39
- private credentialMutationTail;
40
- private credentialVersions;
41
11
  private storage;
42
12
  private constructor();
43
13
  static create(authPath?: string | string[]): AuthStorage;
44
14
  static fromStorage(storage: AuthStorageBackend): AuthStorage;
45
15
  static inMemory(data?: AuthStorageData): AuthStorage;
46
- /**
47
- * Set a runtime API key override (not persisted to disk).
48
- * Used for CLI --api-key flag.
49
- */
50
- setRuntimeApiKey(provider: string, apiKey: string): void;
51
- /** Read a non-persisted request override without resolving stored credentials. */
52
- getRuntimeApiKey(provider: string): string | undefined;
53
- /**
54
- * Remove a runtime API key override.
55
- */
56
- removeRuntimeApiKey(provider: string): void;
57
- /**
58
- * Set a fallback resolver for API keys not found in auth.json or env vars.
59
- * Used for custom provider keys from models.json.
60
- */
61
- setFallbackResolver(resolver: (provider: string) => string | undefined): void;
62
- private recordError;
63
16
  private parseStorageData;
64
17
  /**
65
18
  * Reload credentials from storage.
66
19
  */
67
20
  reload(): void;
68
- /**
69
- * Read the credential snapshot, preferring the backend's lock-free `read()`.
70
- * Falls back to a `withLock`-based read for custom backends that predate
71
- * `read()` so the released `AuthStorageBackend` interface stays compatible.
72
- */
73
- private readSnapshot;
74
- private bumpCredentialVersion;
75
- private persistProviderChange;
76
- /**
77
- * Get credential for a provider.
78
- */
79
- get(provider: string): AuthCredential | undefined;
80
- /**
81
- * Set credential for a provider.
82
- */
83
- set(provider: string, credential: AuthCredential): void;
84
- /**
85
- * Remove credential for a provider.
86
- */
87
- remove(provider: string): void;
88
- /**
89
- * List all providers with credentials.
90
- */
91
- list(): string[];
92
- /**
93
- * Check if credentials exist for a provider in auth.json.
94
- */
95
- has(provider: string): boolean;
96
- /**
97
- * Check if any form of auth is configured for a provider.
98
- * Unlike getApiKey(), this doesn't refresh OAuth tokens.
99
- */
100
- hasAuth(provider: string): boolean;
101
- /**
102
- * Return auth status without exposing credential values or refreshing tokens.
103
- */
104
- getAuthStatus(provider: string): AuthStatus;
105
- /** Return a copy of all persisted credentials. */
106
- getAll(): AuthStorageData;
107
- drainErrors(): Error[];
108
- /**
109
- * Returns the error from the most recent failed credential load, or null when
110
- * the last reload succeeded.
111
- *
112
- * A non-null value means stored credentials could NOT be read — e.g. the auth
113
- * file was temporarily locked by another process (ELOCKED) or contained
114
- * invalid JSON — so an empty/absent credential set is NOT authoritative.
115
- * Callers that would otherwise report "No API key found" should surface this
116
- * load failure instead of treating the provider as unauthenticated
117
- * (issue #1431).
118
- */
119
- getLoadError(): Error | null;
120
- /**
121
- * Login to an OAuth provider.
122
- */
123
- login(providerId: string, callbacks: AtomicOAuthLoginCallbacks): Promise<void>;
124
- /** Logout through the preserved synchronous persistence path. */
125
- logout(provider: string): void;
126
- /** Serialized logout for callers that need persistence completion. */
127
- logoutAsync(provider: string): Promise<void>;
128
- /**
129
- * Refresh OAuth token with backend locking to prevent race conditions.
130
- * Multiple pi instances may try to refresh simultaneously when tokens expire.
131
- */
132
- private refreshOAuthTokenWithLock;
133
- /**
134
- * Get API key for a provider.
135
- * Priority:
136
- * 1. Runtime override (CLI --api-key)
137
- * 2. API key from auth.json
138
- * 3. OAuth token from auth.json (auto-refreshed with locking)
139
- * 4. Environment variable
140
- * 5. Fallback resolver (models.json custom providers)
141
- */
142
- getModelAuth(providerId: string, options?: {
143
- includeFallback?: boolean;
144
- }): Promise<ModelAuth | undefined>;
145
- getApiKey(providerId: string, options?: {
146
- includeFallback?: boolean;
147
- }): Promise<string | undefined>;
148
- /**
149
- * Get all registered OAuth providers
150
- */
151
- getOAuthProviders(): import("./oauth-provider-bridge.ts").OAuthProviderDescriptor[];
152
- private runCredentialMutation;
153
- /** Private async adapter for pi-ai's provider-owned Models runtime. */
154
- asCredentialStore(): CredentialStore;
21
+ read(provider: string): Promise<Credential | undefined>;
22
+ modify(provider: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
23
+ delete(provider: string): Promise<void>;
24
+ /** List credential metadata without resolving configured key values. */
25
+ list(): Promise<readonly CredentialInfo[]>;
155
26
  }
27
+ /** Read one persisted provider credential using Atomic's layered auth.json paths. */
28
+ export declare function readStoredCredential(providerId: string, authPath?: string | string[]): Credential | undefined;
156
29
  //# sourceMappingURL=auth-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-storage.d.ts","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-storage.d.ts","sourceRoot":"","sources":["../../src/core/auth-storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGzF,OAAO,EAAsD,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGzH,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEzH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAGzD,qBAAa,WAAY,YAAW,eAAe;IAClD,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,OAAO,CAAqB;IAEpC,OAAO,eAGN;IAED,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,WAAW,CAKvD;IAED,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAE3D;IAED,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,WAAW,CAIvD;IAED,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,MAAM,IAAI,IAAI,CAeb;IAEK,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAK5D;IAEK,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GACtE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAgBjC;IAEK,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc5C;IAED,wEAAwE;IAClE,IAAI,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAE/C;CAED;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,CAe7G"}
@@ -1,32 +1,15 @@
1
1
  /**
2
- * Credential storage for API keys and OAuth tokens.
3
- * Handles loading, saving, and refreshing credentials from auth.json.
4
- *
5
- * Uses file locking to prevent race conditions when multiple pi instances
6
- * try to refresh tokens simultaneously.
2
+ * CredentialStore implementation backed by auth.json.
3
+ * Provider auth orchestration belongs to ModelRuntime and pi-ai Models.
7
4
  */
8
- import { findEnvKeys, getEnvApiKey } from "@earendil-works/pi-ai/compat";
9
5
  import { join } from "path";
10
6
  import { getAgentConfigPaths, getAgentDir } from "../config.js";
11
7
  import { FileAuthStorageBackend, InMemoryAuthStorageBackend } from "./auth-storage-backends.js";
12
- import { getOAuthProviderDescriptors, loginOAuthProvider, oauthCredentialToAuth, refreshOAuthProvider, } from "./oauth-provider-bridge.js";
13
8
  import { resolveConfigValue } from "./resolve-config-value.js";
14
9
  export { FileAuthStorageBackend, InMemoryAuthStorageBackend } from "./auth-storage-backends.js";
15
- /** Read one persisted provider credential using Atomic's layered config paths. */
16
- export function readStoredCredential(providerId, authPath) {
17
- return AuthStorage.create(authPath).get(providerId);
18
- }
19
- /**
20
- * Credential storage backed by a JSON file.
21
- */
22
10
  export class AuthStorage {
23
11
  constructor(storage) {
24
12
  this.data = {};
25
- this.runtimeOverrides = new Map();
26
- this.loadError = null;
27
- this.errors = [];
28
- this.credentialMutationTail = Promise.resolve();
29
- this.credentialVersions = new Map();
30
13
  this.storage = storage;
31
14
  this.reload();
32
15
  }
@@ -44,34 +27,6 @@ export class AuthStorage {
44
27
  storage.withLock(() => ({ result: undefined, next: JSON.stringify(data, null, 2) }));
45
28
  return AuthStorage.fromStorage(storage);
46
29
  }
47
- /**
48
- * Set a runtime API key override (not persisted to disk).
49
- * Used for CLI --api-key flag.
50
- */
51
- setRuntimeApiKey(provider, apiKey) {
52
- this.runtimeOverrides.set(provider, apiKey);
53
- }
54
- /** Read a non-persisted request override without resolving stored credentials. */
55
- getRuntimeApiKey(provider) {
56
- return this.runtimeOverrides.get(provider);
57
- }
58
- /**
59
- * Remove a runtime API key override.
60
- */
61
- removeRuntimeApiKey(provider) {
62
- this.runtimeOverrides.delete(provider);
63
- }
64
- /**
65
- * Set a fallback resolver for API keys not found in auth.json or env vars.
66
- * Used for custom provider keys from models.json.
67
- */
68
- setFallbackResolver(resolver) {
69
- this.fallbackResolver = resolver;
70
- }
71
- recordError(error) {
72
- const normalizedError = error instanceof Error ? error : new Error(String(error));
73
- this.errors.push(normalizedError);
74
- }
75
30
  parseStorageData(content) {
76
31
  if (!content) {
77
32
  return {};
@@ -83,345 +38,84 @@ export class AuthStorage {
83
38
  */
84
39
  reload() {
85
40
  try {
86
- // Pure read: never take the exclusive write lock. Writers replace
87
- // auth.json atomically, so a lock-free read always sees a complete
88
- // snapshot. This keeps many concurrent sessions from starving each other
89
- // on the lock and misreporting configured providers as unreadable under
90
- // contention (issue #1431).
91
- const content = this.readSnapshot();
41
+ let content;
42
+ if (this.storage.read) {
43
+ content = this.storage.read();
44
+ }
45
+ else {
46
+ this.storage.withLock((current) => {
47
+ content = current;
48
+ return { result: undefined };
49
+ });
50
+ }
92
51
  this.data = this.parseStorageData(content);
93
- this.loadError = null;
94
- }
95
- catch (error) {
96
- this.loadError = error;
97
- this.recordError(error);
98
- }
99
- }
100
- /**
101
- * Read the credential snapshot, preferring the backend's lock-free `read()`.
102
- * Falls back to a `withLock`-based read for custom backends that predate
103
- * `read()` so the released `AuthStorageBackend` interface stays compatible.
104
- */
105
- readSnapshot() {
106
- if (this.storage.read) {
107
- return this.storage.read();
108
52
  }
109
- let content;
110
- this.storage.withLock((current) => {
111
- content = current;
112
- return { result: undefined };
53
+ catch {
54
+ // Preserve the last valid in-memory snapshot.
55
+ }
56
+ }
57
+ async read(provider) {
58
+ const credential = this.data[provider];
59
+ if (credential?.type !== "api_key")
60
+ return credential;
61
+ if (credential.key === undefined)
62
+ return credential;
63
+ return { ...credential, key: resolveConfigValue(credential.key, credential.env) };
64
+ }
65
+ async modify(provider, fn) {
66
+ let persistedData;
67
+ const result = await this.storage.withLockAsync(async (content) => {
68
+ const currentData = this.parseStorageData(content);
69
+ const next = await fn(currentData[provider]);
70
+ if (next === undefined) {
71
+ persistedData = currentData;
72
+ return { result: currentData[provider] };
73
+ }
74
+ const merged = { ...currentData, [provider]: next };
75
+ persistedData = merged;
76
+ return { result: next, next: JSON.stringify(merged, null, 2) };
113
77
  });
114
- return content;
115
- }
116
- bumpCredentialVersion(provider) {
117
- this.credentialVersions.set(provider, (this.credentialVersions.get(provider) ?? 0) + 1);
118
- }
119
- persistProviderChange(provider, credential) {
120
- if (this.loadError) {
121
- this.reload();
122
- if (this.loadError)
123
- throw this.loadError;
124
- }
125
- try {
126
- const persistedData = this.storage.withLock((current) => {
127
- const currentData = this.parseStorageData(current);
128
- const merged = { ...currentData };
129
- if (credential) {
130
- merged[provider] = credential;
131
- }
132
- else {
133
- delete merged[provider];
134
- }
135
- return { result: merged, next: JSON.stringify(merged, null, 2) };
136
- });
78
+ if (persistedData)
137
79
  this.data = persistedData;
138
- this.bumpCredentialVersion(provider);
139
- this.loadError = null;
140
- }
141
- catch (error) {
142
- this.recordError(error);
143
- throw error instanceof Error ? error : new Error(String(error));
144
- }
145
- }
146
- /**
147
- * Get credential for a provider.
148
- */
149
- get(provider) {
150
- return this.data[provider] ?? undefined;
151
- }
152
- /**
153
- * Set credential for a provider.
154
- */
155
- set(provider, credential) {
156
- this.persistProviderChange(provider, credential);
80
+ return result;
157
81
  }
158
- /**
159
- * Remove credential for a provider.
160
- */
161
- remove(provider) {
162
- if (!this.storage.deleteProvider) {
163
- this.persistProviderChange(provider, undefined);
82
+ async delete(provider) {
83
+ if (this.storage.deleteProviderAsync) {
84
+ const content = await this.storage.deleteProviderAsync(provider);
85
+ this.data = this.parseStorageData(content);
164
86
  return;
165
87
  }
166
- try {
167
- this.data = this.parseStorageData(this.storage.deleteProvider(provider));
168
- this.bumpCredentialVersion(provider);
169
- this.loadError = null;
170
- }
171
- catch (error) {
172
- this.recordError(error);
173
- throw error instanceof Error ? error : new Error(String(error));
174
- }
175
- }
176
- /**
177
- * List all providers with credentials.
178
- */
179
- list() {
180
- return Object.keys(this.data);
181
- }
182
- /**
183
- * Check if credentials exist for a provider in auth.json.
184
- */
185
- has(provider) {
186
- return provider in this.data;
187
- }
188
- /**
189
- * Check if any form of auth is configured for a provider.
190
- * Unlike getApiKey(), this doesn't refresh OAuth tokens.
191
- */
192
- hasAuth(provider) {
193
- if (this.runtimeOverrides.has(provider))
194
- return true;
195
- if (this.data[provider])
196
- return true;
197
- if (findEnvKeys(provider)?.[0])
198
- return true;
199
- if (this.fallbackResolver?.(provider))
200
- return true;
201
- return false;
202
- }
203
- /**
204
- * Return auth status without exposing credential values or refreshing tokens.
205
- */
206
- getAuthStatus(provider) {
207
- if (this.data[provider]) {
208
- return { configured: true, source: "stored" };
209
- }
210
- if (this.runtimeOverrides.has(provider)) {
211
- return { configured: false, source: "runtime", label: "--api-key" };
212
- }
213
- const envKeys = findEnvKeys(provider);
214
- if (envKeys?.[0]) {
215
- return { configured: true, source: "environment", label: envKeys[0] };
216
- }
217
- if (this.fallbackResolver?.(provider)) {
218
- return { configured: false, source: "fallback", label: "custom provider config" };
219
- }
220
- return { configured: false };
221
- }
222
- /** Return a copy of all persisted credentials. */
223
- getAll() {
224
- return { ...this.data };
225
- }
226
- drainErrors() {
227
- const drained = [...this.errors];
228
- this.errors = [];
229
- return drained;
230
- }
231
- /**
232
- * Returns the error from the most recent failed credential load, or null when
233
- * the last reload succeeded.
234
- *
235
- * A non-null value means stored credentials could NOT be read — e.g. the auth
236
- * file was temporarily locked by another process (ELOCKED) or contained
237
- * invalid JSON — so an empty/absent credential set is NOT authoritative.
238
- * Callers that would otherwise report "No API key found" should surface this
239
- * load failure instead of treating the provider as unauthenticated
240
- * (issue #1431).
241
- */
242
- getLoadError() {
243
- return this.loadError;
244
- }
245
- /**
246
- * Login to an OAuth provider.
247
- */
248
- async login(providerId, callbacks) {
249
- const credential = await loginOAuthProvider(providerId, callbacks);
250
- await this.asCredentialStore().modify(providerId, async () => credential);
251
- }
252
- /** Logout through the preserved synchronous persistence path. */
253
- logout(provider) {
254
- this.remove(provider);
88
+ let persistedData;
89
+ await this.storage.withLockAsync(async (content) => {
90
+ const currentData = this.parseStorageData(content);
91
+ delete currentData[provider];
92
+ persistedData = currentData;
93
+ return { result: undefined, next: JSON.stringify(currentData, null, 2) };
94
+ });
95
+ if (persistedData)
96
+ this.data = persistedData;
255
97
  }
256
- /** Serialized logout for callers that need persistence completion. */
257
- async logoutAsync(provider) {
258
- await this.asCredentialStore().delete(provider);
98
+ /** List credential metadata without resolving configured key values. */
99
+ async list() {
100
+ return Object.entries(this.data).map(([providerId, credential]) => ({ providerId, type: credential.type }));
259
101
  }
260
- /**
261
- * Refresh OAuth token with backend locking to prevent race conditions.
262
- * Multiple pi instances may try to refresh simultaneously when tokens expire.
263
- */
264
- async refreshOAuthTokenWithLock(providerId) {
265
- return this.runCredentialMutation(async () => {
266
- let synchronizedData;
267
- const credentialVersion = this.credentialVersions.get(providerId) ?? 0;
268
- const result = await this.storage.withLockAsync(async (current) => {
269
- const currentData = this.parseStorageData(current);
270
- synchronizedData = currentData;
271
- const cred = currentData[providerId];
272
- if (cred?.type !== "oauth")
273
- return { result: null };
274
- const oauthCredential = { ...cred, type: "oauth" };
275
- if (Date.now() < cred.expires) {
276
- const auth = await oauthCredentialToAuth(providerId, oauthCredential);
277
- return { result: auth ? { auth, newCredentials: cred } : null };
278
- }
279
- const refreshed = await refreshOAuthProvider(providerId, oauthCredential);
280
- if (!refreshed)
281
- return { result: null };
282
- if ((this.credentialVersions.get(providerId) ?? 0) !== credentialVersion) {
283
- synchronizedData = undefined;
284
- return { result: null };
285
- }
286
- const merged = {
287
- ...currentData,
288
- [providerId]: refreshed.credential,
289
- };
290
- synchronizedData = merged;
291
- return {
292
- result: { auth: refreshed.auth, newCredentials: refreshed.credential },
293
- next: JSON.stringify(merged, null, 2),
294
- };
295
- });
296
- if (synchronizedData)
297
- this.data = synchronizedData;
298
- this.loadError = null;
299
- return result;
102
+ }
103
+ /** Read one persisted provider credential using Atomic's layered auth.json paths. */
104
+ export function readStoredCredential(providerId, authPath) {
105
+ const paths = authPath === undefined
106
+ ? getAgentConfigPaths("auth.json")
107
+ : Array.isArray(authPath) ? authPath : [authPath];
108
+ const storage = new FileAuthStorageBackend(paths[0] ?? join(getAgentDir(), "auth.json"), paths);
109
+ try {
110
+ let credential;
111
+ storage.withLock((content) => {
112
+ credential = content ? JSON.parse(content)[providerId] : undefined;
113
+ return { result: undefined };
300
114
  });
115
+ return credential;
301
116
  }
302
- /**
303
- * Get API key for a provider.
304
- * Priority:
305
- * 1. Runtime override (CLI --api-key)
306
- * 2. API key from auth.json
307
- * 3. OAuth token from auth.json (auto-refreshed with locking)
308
- * 4. Environment variable
309
- * 5. Fallback resolver (models.json custom providers)
310
- */
311
- async getModelAuth(providerId, options) {
312
- const runtimeKey = this.runtimeOverrides.get(providerId);
313
- if (runtimeKey)
314
- return { apiKey: runtimeKey };
315
- const cred = this.data[providerId];
316
- if (cred?.type === "api_key" && cred.key)
317
- return { apiKey: resolveConfigValue(cred.key) };
318
- if (cred?.type === "oauth") {
319
- try {
320
- if (Date.now() >= cred.expires) {
321
- return (await this.refreshOAuthTokenWithLock(providerId))?.auth;
322
- }
323
- return await oauthCredentialToAuth(providerId, { ...cred, type: "oauth" });
324
- }
325
- catch (error) {
326
- this.recordError(error);
327
- this.reload();
328
- const updated = this.data[providerId];
329
- if (updated?.type === "oauth" && Date.now() < updated.expires) {
330
- return oauthCredentialToAuth(providerId, { ...updated, type: "oauth" });
331
- }
332
- return undefined;
333
- }
334
- }
335
- const envKey = getEnvApiKey(providerId);
336
- if (envKey)
337
- return { apiKey: envKey };
338
- if (options?.includeFallback !== false) {
339
- const fallback = this.fallbackResolver?.(providerId);
340
- if (fallback)
341
- return { apiKey: fallback };
342
- }
117
+ catch {
343
118
  return undefined;
344
119
  }
345
- async getApiKey(providerId, options) {
346
- return (await this.getModelAuth(providerId, options))?.apiKey;
347
- }
348
- /**
349
- * Get all registered OAuth providers
350
- */
351
- getOAuthProviders() {
352
- return getOAuthProviderDescriptors();
353
- }
354
- runCredentialMutation(operation) {
355
- const result = this.credentialMutationTail.then(operation, operation);
356
- this.credentialMutationTail = result.then(() => undefined, () => undefined);
357
- return result;
358
- }
359
- /** Private async adapter for pi-ai's provider-owned Models runtime. */
360
- asCredentialStore() {
361
- const runtimeCredential = (providerId) => {
362
- const key = this.runtimeOverrides.get(providerId);
363
- return key === undefined ? undefined : { type: "api_key", key };
364
- };
365
- return {
366
- read: async (providerId) => runtimeCredential(providerId) ?? this.get(providerId),
367
- list: async () => {
368
- const providers = new Set([...this.list(), ...this.runtimeOverrides.keys()]);
369
- return [...providers].map((providerId) => ({
370
- providerId,
371
- type: runtimeCredential(providerId)?.type ?? this.data[providerId].type,
372
- }));
373
- },
374
- modify: (providerId, fn) => this.runCredentialMutation(async () => {
375
- let synchronizedData;
376
- try {
377
- const result = await this.storage.withLockAsync(async (current) => {
378
- const data = this.parseStorageData(current);
379
- const next = await fn(data[providerId]);
380
- if (next === undefined) {
381
- synchronizedData = data;
382
- return { result: data[providerId] };
383
- }
384
- const merged = { ...data, [providerId]: next };
385
- synchronizedData = merged;
386
- return { result: next, next: JSON.stringify(merged, null, 2) };
387
- });
388
- if (synchronizedData) {
389
- this.data = synchronizedData;
390
- this.bumpCredentialVersion(providerId);
391
- }
392
- this.loadError = null;
393
- return result;
394
- }
395
- catch (error) {
396
- this.recordError(error);
397
- throw error;
398
- }
399
- }),
400
- delete: (providerId) => this.runCredentialMutation(async () => {
401
- try {
402
- if (this.storage.deleteProviderAsync) {
403
- this.data = this.parseStorageData(await this.storage.deleteProviderAsync(providerId));
404
- }
405
- else {
406
- let synchronizedData;
407
- await this.storage.withLockAsync(async (current) => {
408
- const data = this.parseStorageData(current);
409
- delete data[providerId];
410
- synchronizedData = data;
411
- return { result: undefined, next: JSON.stringify(data, null, 2) };
412
- });
413
- if (synchronizedData)
414
- this.data = synchronizedData;
415
- }
416
- this.bumpCredentialVersion(providerId);
417
- this.loadError = null;
418
- }
419
- catch (error) {
420
- this.recordError(error);
421
- throw error;
422
- }
423
- }),
424
- };
425
- }
426
120
  }
427
121
  //# sourceMappingURL=auth-storage.js.map