@era-laboratories/era-sdk 0.1.0-next.32 → 0.1.0-next.45

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 (200) hide show
  1. package/CHANGELOG.md +339 -0
  2. package/README.md +6 -1
  3. package/dist/auth-D2XawwCn.d.ts +489 -0
  4. package/dist/auth-D2XawwCn.d.ts.map +1 -0
  5. package/dist/casing-_Mn2NyTK.d.ts +24 -0
  6. package/dist/casing-_Mn2NyTK.d.ts.map +1 -0
  7. package/dist/client-Cl72cpdb.js +673 -0
  8. package/dist/client-Cl72cpdb.js.map +1 -0
  9. package/dist/client-Cl_wmzub.d.ts +662 -0
  10. package/dist/client-Cl_wmzub.d.ts.map +1 -0
  11. package/dist/core/auth.d.ts +2 -264
  12. package/dist/core/auth.js +521 -2
  13. package/dist/core/auth.js.map +1 -1
  14. package/dist/core/errors.d.ts +2 -136
  15. package/dist/core/errors.js +360 -2
  16. package/dist/core/errors.js.map +1 -1
  17. package/dist/core/index.d.ts +5 -4
  18. package/dist/core/index.js +5 -8
  19. package/dist/core/streaming.d.ts +2 -139
  20. package/dist/core/streaming.js +365 -2
  21. package/dist/core/streaming.js.map +1 -1
  22. package/dist/devices-BKIkM2KD.d.ts +4640 -0
  23. package/dist/devices-BKIkM2KD.d.ts.map +1 -0
  24. package/dist/errors-Clai0mby.d.ts +448 -0
  25. package/dist/errors-Clai0mby.d.ts.map +1 -0
  26. package/dist/experienceVersions-DtrAFhk4.d.ts +455 -0
  27. package/dist/experienceVersions-DtrAFhk4.d.ts.map +1 -0
  28. package/dist/generated/hub-api/index.d.ts +3 -31091
  29. package/dist/generated/hub-api/index.js +2 -4
  30. package/dist/generated/ingress/index.d.ts +444 -5668
  31. package/dist/generated/ingress/index.d.ts.map +1 -0
  32. package/dist/generated/ingress/index.js +2 -3
  33. package/dist/generated/interstitials/index.d.ts +307 -544
  34. package/dist/generated/interstitials/index.d.ts.map +1 -0
  35. package/dist/generated/interstitials/index.js +2 -3
  36. package/dist/hubPaths-BApRiLjY.js +24 -0
  37. package/dist/hubPaths-BApRiLjY.js.map +1 -0
  38. package/dist/index.d.ts +212 -2298
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +3350 -2041
  41. package/dist/index.js.map +1 -1
  42. package/dist/ingressPaths-Bz91nMzc.js +22 -0
  43. package/dist/ingressPaths-Bz91nMzc.js.map +1 -0
  44. package/dist/interstitials-TWMGqOt4.js +126 -0
  45. package/dist/interstitials-TWMGqOt4.js.map +1 -0
  46. package/dist/modules/chat.d.ts +186 -91
  47. package/dist/modules/chat.d.ts.map +1 -0
  48. package/dist/modules/chat.js +130 -5
  49. package/dist/modules/chat.js.map +1 -1
  50. package/dist/modules/consent.d.ts +298 -39
  51. package/dist/modules/consent.d.ts.map +1 -0
  52. package/dist/modules/consent.js +57 -4
  53. package/dist/modules/consent.js.map +1 -1
  54. package/dist/modules/credits.d.ts +70 -39
  55. package/dist/modules/credits.d.ts.map +1 -0
  56. package/dist/modules/credits.js +28 -6
  57. package/dist/modules/credits.js.map +1 -1
  58. package/dist/modules/devices.d.ts +3 -4
  59. package/dist/modules/devices.js +118 -6
  60. package/dist/modules/devices.js.map +1 -1
  61. package/dist/modules/experienceVersions.d.ts +2 -134
  62. package/dist/modules/experienceVersions.js +175 -4
  63. package/dist/modules/experienceVersions.js.map +1 -1
  64. package/dist/modules/experiences.d.ts +673 -478
  65. package/dist/modules/experiences.d.ts.map +1 -0
  66. package/dist/modules/experiences.js +214 -6
  67. package/dist/modules/experiences.js.map +1 -1
  68. package/dist/modules/interstitials.d.ts +300 -0
  69. package/dist/modules/interstitials.d.ts.map +1 -0
  70. package/dist/modules/interstitials.js +3 -0
  71. package/dist/modules/memory.d.ts +184 -72
  72. package/dist/modules/memory.d.ts.map +1 -0
  73. package/dist/modules/memory.js +90 -6
  74. package/dist/modules/memory.js.map +1 -1
  75. package/dist/modules/oauth.d.ts +207 -28
  76. package/dist/modules/oauth.d.ts.map +1 -0
  77. package/dist/modules/oauth.js +65 -4
  78. package/dist/modules/oauth.js.map +1 -1
  79. package/dist/modules/organizations.d.ts +442 -94
  80. package/dist/modules/organizations.d.ts.map +1 -0
  81. package/dist/modules/organizations.js +152 -6
  82. package/dist/modules/organizations.js.map +1 -1
  83. package/dist/modules/pairableResources.d.ts +86 -0
  84. package/dist/modules/pairableResources.d.ts.map +1 -0
  85. package/dist/modules/pairableResources.js +41 -0
  86. package/dist/modules/pairableResources.js.map +1 -0
  87. package/dist/modules/resources.d.ts +66 -43
  88. package/dist/modules/resources.d.ts.map +1 -0
  89. package/dist/modules/resources.js +32 -6
  90. package/dist/modules/resources.js.map +1 -1
  91. package/dist/modules/sessions.d.ts +289 -96
  92. package/dist/modules/sessions.d.ts.map +1 -0
  93. package/dist/modules/sessions.js +78 -6
  94. package/dist/modules/sessions.js.map +1 -1
  95. package/dist/modules/styling.d.ts +292 -301
  96. package/dist/modules/styling.d.ts.map +1 -0
  97. package/dist/modules/styling.js +98 -5
  98. package/dist/modules/styling.js.map +1 -1
  99. package/dist/modules/tools.d.ts +2 -0
  100. package/dist/modules/tools.js +2 -0
  101. package/dist/modules/tts.d.ts +709 -512
  102. package/dist/modules/tts.d.ts.map +1 -0
  103. package/dist/modules/tts.js +505 -10
  104. package/dist/modules/tts.js.map +1 -1
  105. package/dist/modules/users.d.ts +118 -64
  106. package/dist/modules/users.d.ts.map +1 -0
  107. package/dist/modules/users.js +36 -6
  108. package/dist/modules/users.js.map +1 -1
  109. package/dist/modules/voice.d.ts +3 -926
  110. package/dist/modules/voice.js +3 -11
  111. package/dist/operations-Dvzy-B5G.js +211 -0
  112. package/dist/operations-Dvzy-B5G.js.map +1 -0
  113. package/dist/pathResolver-D-nucJal.js +54 -0
  114. package/dist/pathResolver-D-nucJal.js.map +1 -0
  115. package/dist/sdk.gen-BNWxkq2Z.js +3445 -0
  116. package/dist/sdk.gen-BNWxkq2Z.js.map +1 -0
  117. package/dist/sdk.gen-CAUPzlED.js +934 -0
  118. package/dist/sdk.gen-CAUPzlED.js.map +1 -0
  119. package/dist/sdk.gen-CZu__hlw.js +21537 -0
  120. package/dist/sdk.gen-CZu__hlw.js.map +1 -0
  121. package/dist/sdk.gen-E4swQZW_.d.ts +2450 -0
  122. package/dist/sdk.gen-E4swQZW_.d.ts.map +1 -0
  123. package/dist/streaming-Cex6dlUI.d.ts +241 -0
  124. package/dist/streaming-Cex6dlUI.d.ts.map +1 -0
  125. package/dist/tools-BsKVMAnv.d.ts +1585 -0
  126. package/dist/tools-BsKVMAnv.d.ts.map +1 -0
  127. package/dist/tools-IlJjo2wN.js +3439 -0
  128. package/dist/tools-IlJjo2wN.js.map +1 -0
  129. package/dist/types.gen-1u1-_xHw.d.ts +6142 -0
  130. package/dist/types.gen-1u1-_xHw.d.ts.map +1 -0
  131. package/dist/types.gen-DoQ8Idaw.d.ts +599 -0
  132. package/dist/types.gen-DoQ8Idaw.d.ts.map +1 -0
  133. package/dist/types.gen-lPoAJWsN.d.ts +28298 -0
  134. package/dist/types.gen-lPoAJWsN.d.ts.map +1 -0
  135. package/dist/voice-D8kYRHmM.js +1203 -0
  136. package/dist/voice-D8kYRHmM.js.map +1 -0
  137. package/dist/voice-D99HwDge.d.ts +1101 -0
  138. package/dist/voice-D99HwDge.d.ts.map +1 -0
  139. package/package.json +9 -6
  140. package/dist/chunk-3WWTKEUX.js +0 -56
  141. package/dist/chunk-3WWTKEUX.js.map +0 -1
  142. package/dist/chunk-5A5YCM3V.js +0 -804
  143. package/dist/chunk-5A5YCM3V.js.map +0 -1
  144. package/dist/chunk-5D2T2ZRH.js +0 -380
  145. package/dist/chunk-5D2T2ZRH.js.map +0 -1
  146. package/dist/chunk-5NA2TFPG.js +0 -3
  147. package/dist/chunk-5NA2TFPG.js.map +0 -1
  148. package/dist/chunk-645QZBSJ.js +0 -9
  149. package/dist/chunk-645QZBSJ.js.map +0 -1
  150. package/dist/chunk-6BSO3N5P.js +0 -46
  151. package/dist/chunk-6BSO3N5P.js.map +0 -1
  152. package/dist/chunk-7LKBKCEE.js +0 -64
  153. package/dist/chunk-7LKBKCEE.js.map +0 -1
  154. package/dist/chunk-C5M55XGA.js +0 -80
  155. package/dist/chunk-C5M55XGA.js.map +0 -1
  156. package/dist/chunk-DGR7JL65.js +0 -464
  157. package/dist/chunk-DGR7JL65.js.map +0 -1
  158. package/dist/chunk-ESO3QEAK.js +0 -135
  159. package/dist/chunk-ESO3QEAK.js.map +0 -1
  160. package/dist/chunk-HDUV7OOG.js +0 -937
  161. package/dist/chunk-HDUV7OOG.js.map +0 -1
  162. package/dist/chunk-HSNI6RBW.js +0 -39
  163. package/dist/chunk-HSNI6RBW.js.map +0 -1
  164. package/dist/chunk-HZBK7MHQ.js +0 -1140
  165. package/dist/chunk-HZBK7MHQ.js.map +0 -1
  166. package/dist/chunk-MBVIKC5P.js +0 -9
  167. package/dist/chunk-MBVIKC5P.js.map +0 -1
  168. package/dist/chunk-OJWZE34W.js +0 -2105
  169. package/dist/chunk-OJWZE34W.js.map +0 -1
  170. package/dist/chunk-OQVSZEFE.js +0 -48
  171. package/dist/chunk-OQVSZEFE.js.map +0 -1
  172. package/dist/chunk-QWYPM4MG.js +0 -16790
  173. package/dist/chunk-QWYPM4MG.js.map +0 -1
  174. package/dist/chunk-QXM2MRTI.js +0 -69
  175. package/dist/chunk-QXM2MRTI.js.map +0 -1
  176. package/dist/chunk-RA73ZE4M.js +0 -22
  177. package/dist/chunk-RA73ZE4M.js.map +0 -1
  178. package/dist/chunk-T7ZALSL6.js +0 -27
  179. package/dist/chunk-T7ZALSL6.js.map +0 -1
  180. package/dist/chunk-TE6GQM7G.js +0 -691
  181. package/dist/chunk-TE6GQM7G.js.map +0 -1
  182. package/dist/chunk-TTGM7WVZ.js +0 -237
  183. package/dist/chunk-TTGM7WVZ.js.map +0 -1
  184. package/dist/chunk-TY7R43JL.js +0 -92
  185. package/dist/chunk-TY7R43JL.js.map +0 -1
  186. package/dist/chunk-VK25JW5L.js +0 -18
  187. package/dist/chunk-VK25JW5L.js.map +0 -1
  188. package/dist/chunk-W6XS5SYL.js +0 -143
  189. package/dist/chunk-W6XS5SYL.js.map +0 -1
  190. package/dist/chunk-YLLX4H3M.js +0 -94
  191. package/dist/chunk-YLLX4H3M.js.map +0 -1
  192. package/dist/chunk-YVGD3MU7.js +0 -201
  193. package/dist/chunk-YVGD3MU7.js.map +0 -1
  194. package/dist/client-b0FHDL0O.d.ts +0 -397
  195. package/dist/core/index.js.map +0 -1
  196. package/dist/devices-DDYMQF5y.d.ts +0 -386
  197. package/dist/generated/hub-api/index.js.map +0 -1
  198. package/dist/generated/ingress/index.js.map +0 -1
  199. package/dist/generated/interstitials/index.js.map +0 -1
  200. package/dist/modules/voice.js.map +0 -1
@@ -0,0 +1,489 @@
1
+ //#region src/core/auth.d.ts
2
+ /** PKCE mode — Authorization Code + PKCE against oauth.era.world. */
3
+ interface EraAuthPkce {
4
+ /** Auth mode discriminant — always `'pkce'`. */
5
+ mode: 'pkce';
6
+ /** OAuth client id registered with the Era authorization server. */
7
+ clientId: string;
8
+ /** Redirect URI the authorization code is returned to; must match the registered client. */
9
+ redirectUri: string;
10
+ /** OAuth scopes to request; omit to use the client's default grant. */
11
+ scopes?: string[];
12
+ /**
13
+ * Pluggable token storage. Defaults to in-memory (per session).
14
+ *
15
+ * **Browser callers: do not use browser `localStorage` for refresh tokens.**
16
+ * Any XSS in the host page reads them, and a refresh token is a bearer
17
+ * credential. See {@link TokenStorage} and https://docs.era.world/docs/getting-started/authentication
18
+ * for the matrix (when in-memory is fine, when to wrap a server proxy,
19
+ * when to fall back to IndexedDB + WebCrypto).
20
+ */
21
+ tokenStorage?: TokenStorage;
22
+ }
23
+ /** API-key mode — Bearer era_sk_live_… / era_sk_test_… / era_pk_live_… */
24
+ interface EraAuthApiKey {
25
+ /** Auth mode discriminant — always `'apiKey'`. */
26
+ mode: 'apiKey';
27
+ /** API key (`era_sk_live_…` / `era_sk_test_…` / `era_pk_live_…`) injected as a Bearer token. */
28
+ apiKey: string;
29
+ /**
30
+ * Suppress the one-shot "secret key in a browser" warning emitted when a
31
+ * browser-like environment is detected and the key starts with `era_sk_`.
32
+ *
33
+ * Default: `false`. Set to `true` only when you're sure the apparent
34
+ * browser globals are not actually a public web page — e.g. Electron
35
+ * renderer talking to a Node host that holds the secret, or a Tauri
36
+ * webview where the key is bundled into the native binary. **If a
37
+ * real user could open dev-tools and read `window.fetch.calls[0]`,
38
+ * leave this `false` and switch to a publishable key + server proxy
39
+ * instead.** See https://docs.era.world/docs/getting-started/authentication.
40
+ */
41
+ allowBrowserSecretKey?: boolean;
42
+ }
43
+ /**
44
+ * Auth configuration passed as `auth` to {@link createEraClient}. Discriminated
45
+ * on `mode`: use `'pkce'` ({@link EraAuthPkce}) for first-party apps that sign a
46
+ * user in and hold refreshable OAuth tokens, or `'apiKey'` ({@link EraAuthApiKey})
47
+ * for server-side integrations that authenticate with a static Era API key.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * // Server-side, static key:
52
+ * const era = createEraClient({ auth: { mode: 'apiKey', apiKey: process.env.ERA_KEY! } });
53
+ *
54
+ * // First-party app, signed-in user (tokens seeded via seedTokens):
55
+ * const era = createEraClient({
56
+ * auth: { mode: 'pkce', clientId: 'client_0000000000', redirectUri, tokenStorage },
57
+ * });
58
+ * ```
59
+ */
60
+ type EraAuthConfig = EraAuthPkce | EraAuthApiKey;
61
+ /**
62
+ * Pluggable token storage. Defaults to in-memory (per session).
63
+ *
64
+ * **Security:** do not use browser `localStorage` for refresh tokens. Any
65
+ * XSS in the host page reads them, and a refresh token is a bearer
66
+ * credential — it needs the same protection level as a `Secure; HttpOnly`
67
+ * cookie. `sessionStorage` shares the same XSS surface and only "fixes"
68
+ * persistence; it is not safer.
69
+ *
70
+ * Recommended patterns by runtime:
71
+ *
72
+ * - **Native / server / CLI:** keep the default `MemoryTokenStorage`
73
+ * (per-process). Persisting across restarts is the OS keychain's job —
74
+ * a small adapter can wrap that (Keychain, KWallet, libsecret, …).
75
+ * - **Browser SPAs:** prefer a cookie-backed session via a server-side
76
+ * proxy that exchanges the auth code on the user's behalf. If the SDK
77
+ * must hold tokens client-side, wrap them with WebCrypto and persist
78
+ * in IndexedDB; never `localStorage` / `sessionStorage`.
79
+ *
80
+ * See https://docs.era.world/docs/getting-started/authentication for the full matrix and a reference
81
+ * IndexedDB adapter.
82
+ */
83
+ interface TokenStorage {
84
+ /**
85
+ * Read the value previously written under `key`. Resolve to `null` when the
86
+ * key is absent (never reject for a missing key). The SDK treats `null` as
87
+ * "no session" and, for PKCE, raises a `no_token` {@link EraAuthError}.
88
+ *
89
+ * @param key - Namespaced storage key the SDK owns (e.g. `era-sdk:tokens:<clientId>`).
90
+ * @returns The stored value, or `null` if nothing is stored under `key`.
91
+ */
92
+ get(key: string): Promise<string | null>;
93
+ /**
94
+ * Persist `value` under `key`, overwriting any existing value. The SDK
95
+ * calls this after every successful token refresh, and {@link seedTokens}
96
+ * calls it to prime storage after the initial code exchange.
97
+ *
98
+ * @param key - Namespaced storage key the SDK owns.
99
+ * @param value - Opaque serialized token bundle; treat as a bearer credential and do not log it.
100
+ */
101
+ set(key: string, value: string): Promise<void>;
102
+ /**
103
+ * Remove the value stored under `key`. The SDK calls this on logout
104
+ * ({@link AuthDispatcher.clear}) and when a refresh definitively fails
105
+ * (bad/revoked credential). Deleting an absent key must be a no-op, not a reject.
106
+ *
107
+ * @param key - Namespaced storage key the SDK owns.
108
+ */
109
+ delete(key: string): Promise<void>;
110
+ }
111
+ /**
112
+ * In-memory {@link TokenStorage} — the default when `tokenStorage` is not
113
+ * supplied on a PKCE auth config. Tokens live only for the lifetime of the
114
+ * process (or the browser tab): they are wiped on restart or reload, and are
115
+ * never written to disk or `localStorage`.
116
+ *
117
+ * Fine for Node, servers, CLIs, and tests. In a browser the SDK emits a
118
+ * one-shot console warning when this default is detected, because sign-in
119
+ * won't survive a reload — supply your own {@link TokenStorage} over a store
120
+ * that persists **without** being XSS-readable (do not use `localStorage`).
121
+ * See {@link https://docs.era.world/docs/getting-started/authentication}.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * const storage = new MemoryTokenStorage();
126
+ * await seedTokens(storage, 'client_0000000000', tokens);
127
+ * const era = createEraClient({ auth: { mode: 'pkce', clientId: 'client_0000000000', redirectUri, tokenStorage: storage } });
128
+ * ```
129
+ */
130
+ declare class MemoryTokenStorage implements TokenStorage {
131
+ private readonly store;
132
+ /** {@inheritDoc TokenStorage.get} */
133
+ get(key: string): Promise<string | null>;
134
+ /** {@inheritDoc TokenStorage.set} */
135
+ set(key: string, value: string): Promise<void>;
136
+ /** {@inheritDoc TokenStorage.delete} */
137
+ delete(key: string): Promise<void>;
138
+ }
139
+ /**
140
+ * Machine-readable {@link EraAuthError.code} value. Branch on it (instead of
141
+ * parsing `.message`) to decide how to recover from an auth failure:
142
+ *
143
+ * - `auth_failed` — the token endpoint rejected the request. From a token
144
+ * refresh this is definitive (HTTP 400/401): the credential is bad, re-run
145
+ * the sign-in flow. From {@link exchangeCodeForToken} it is thrown for any
146
+ * HTTP error status — check {@link EraAuthError.transient} (`true` for 5xx,
147
+ * where retrying the exchange may succeed) before discarding the flow.
148
+ * - `refresh_failed` — a token refresh failed transiently (5xx, network error,
149
+ * or a non-credential 4xx) after exhausting retries. Retrying the request
150
+ * later may succeed.
151
+ * - `no_token` — no tokens are stored (initial PKCE sign-in required), no
152
+ * refresh token is available, or the stored tokens were cleared mid-refresh.
153
+ * - `pkce_invalid` — the runtime lacks Web Crypto (`globalThis.crypto.subtle`);
154
+ * PKCE helpers need Node 18+, a modern browser, or an edge runtime.
155
+ * - `invalid_config` — the auth config is malformed: a bad API-key shape, a
156
+ * `state` shorter than 16 chars, or `seedTokens` called without an access token.
157
+ */
158
+ type EraAuthErrorCode = 'auth_failed' | 'refresh_failed' | 'no_token' | 'pkce_invalid' | 'invalid_config';
159
+ /**
160
+ * Constructor payload for {@link EraAuthError}. You normally **catch**
161
+ * `EraAuthError` rather than construct one; this shape is exported so custom
162
+ * `TokenStorage` adapters or auth wrappers can raise SDK-consistent errors.
163
+ */
164
+ interface EraAuthErrorInit {
165
+ /** Machine-readable auth error code driving retry/re-auth decisions. */
166
+ code: EraAuthErrorCode;
167
+ /** Human-readable, body-free error message safe to log. */
168
+ message: string;
169
+ /** true → caller may retry; false → caller must re-auth. */
170
+ transient: boolean;
171
+ /** Underlying error that triggered this one, when available. */
172
+ cause?: unknown;
173
+ /**
174
+ * HTTP status from the token endpoint, when the error came from one
175
+ * (4xx/5xx response). Lets callers branch on the status without
176
+ * regex-parsing `.message`.
177
+ */
178
+ status?: number;
179
+ /**
180
+ * OAuth-level error code parsed from the response body's `error` field
181
+ * (`invalid_grant`, `invalid_client`, `server_error`, `invalid_request`,
182
+ * …). Used by the refresh path to decide whether to purge stored
183
+ * tokens — only `invalid_grant` and `invalid_client` mean the
184
+ * credential itself is bad.
185
+ */
186
+ oauthErrorCode?: string;
187
+ /**
188
+ * Raw response body from the token endpoint. Attached non-enumerably so
189
+ * it never appears in `JSON.stringify(err)` or default `console.error`
190
+ * output — authorization-server error bodies can carry `client_id`,
191
+ * fragments of the supplied `code`, or `refresh_token`, and those must not
192
+ * land in third-party log stores via `error.message`.
193
+ * See {@link EraAuthError.responseBody}.
194
+ */
195
+ responseBody?: string;
196
+ }
197
+ /**
198
+ * Auth-related error. `code` and `transient` drive retry/re-auth decisions.
199
+ *
200
+ * **Security:** `.message` is a fixed status-keyed string (no response body
201
+ * interpolation) so it can be safely logged or shipped to error aggregators
202
+ * like Sentry/Datadog. The raw token-endpoint response body, when one is
203
+ * available, is exposed as the **non-enumerable** {@link EraAuthError.responseBody}
204
+ * field — accessible by name for debugging, invisible to `JSON.stringify`,
205
+ * `Object.keys`, and default `console.error` formatting. Do not log it
206
+ * unfiltered.
207
+ */
208
+ declare class EraAuthError extends Error {
209
+ /**
210
+ * Machine-readable failure category; see {@link EraAuthErrorCode} for the
211
+ * recovery each value calls for.
212
+ */
213
+ readonly code: EraAuthErrorCode;
214
+ /**
215
+ * `true` when retrying later may succeed (network error, 5xx); `false`
216
+ * when the failure is definitive and the user must re-authenticate (or the
217
+ * config must be fixed).
218
+ */
219
+ readonly transient: boolean;
220
+ /**
221
+ * HTTP status from the token endpoint (4xx/5xx). Only token-refresh
222
+ * failures carry it; errors from {@link exchangeCodeForToken} and non-HTTP
223
+ * failures leave it `undefined`.
224
+ */
225
+ readonly status?: number;
226
+ /**
227
+ * OAuth error code parsed from the token-endpoint response body's `error`
228
+ * field (`invalid_grant`, `invalid_client`, `server_error`, …). Only
229
+ * token-refresh failures with a JSON-parseable body populate it; non-JSON
230
+ * bodies, non-HTTP failures, and errors from {@link exchangeCodeForToken}
231
+ * leave it `undefined`.
232
+ */
233
+ readonly oauthErrorCode?: string;
234
+ /**
235
+ * Raw response body from the token endpoint, when available. Defined
236
+ * non-enumerable — accessible by name (`err.responseBody`) but absent
237
+ * from `JSON.stringify(err)` and `Object.keys(err)`. May contain
238
+ * sensitive data (tokens, code fragments, client_id) — do not log
239
+ * unfiltered.
240
+ *
241
+ * `declare` here is intentional: TypeScript with
242
+ * `useDefineForClassFields` would otherwise emit an enumerable
243
+ * `responseBody: undefined` slot on every instance, defeating the
244
+ * non-enumerable invariant. The constructor is the only thing that
245
+ * defines the property — via `Object.defineProperty` when present.
246
+ */
247
+ readonly responseBody?: string;
248
+ /**
249
+ * @param init - Error fields; see {@link EraAuthErrorInit}. `responseBody`,
250
+ * when present, is attached non-enumerably so it stays out of
251
+ * `JSON.stringify` / `console.error` output.
252
+ */
253
+ constructor(init: EraAuthErrorInit);
254
+ }
255
+ /**
256
+ * Token pair returned by the OAuth token endpoint. Produced by
257
+ * {@link exchangeCodeForToken} (initial sign-in) and consumed by
258
+ * {@link seedTokens} to prime a PKCE client's storage. Field names are the
259
+ * raw OAuth 2.0 wire names (RFC 6749 §5.1).
260
+ */
261
+ interface TokenResponse {
262
+ /** OAuth access token (Bearer credential for API calls). */
263
+ access_token: string;
264
+ /** OAuth refresh token; absent when the grant doesn't issue one. */
265
+ refresh_token?: string;
266
+ /** Access-token lifetime in seconds from issuance. */
267
+ expires_in: number;
268
+ /** Token type returned by the issuer (typically `Bearer`). */
269
+ token_type?: string;
270
+ /** Space-delimited scopes actually granted, when echoed back. */
271
+ scope?: string;
272
+ }
273
+ /**
274
+ * Options for {@link buildAuthorizationUrl} — the fields needed to construct
275
+ * the `/oauth2/auth` redirect URL that starts the PKCE sign-in flow.
276
+ */
277
+ interface AuthorizationUrlOpts {
278
+ /** OAuth issuer base URL the `/oauth2/auth` URL is built against. */
279
+ hubUrl: string;
280
+ /** OAuth client id to request authorization for. */
281
+ clientId: string;
282
+ /** Redirect URI the authorization code is returned to. */
283
+ redirectUri: string;
284
+ /** PKCE S256 code challenge (BASE64URL(SHA-256(verifier))). */
285
+ codeChallenge: string;
286
+ /** OAuth CSRF nonce; must be at least 16 chars (use `generateOauthState()`). */
287
+ state: string;
288
+ /** OAuth scopes to request; omit to use the client's default grant. */
289
+ scopes?: string[];
290
+ }
291
+ /**
292
+ * Options for {@link exchangeCodeForToken} — the fields needed to redeem an
293
+ * authorization `code` (plus its PKCE verifier) for a {@link TokenResponse} at
294
+ * the callback step of the PKCE flow.
295
+ */
296
+ interface TokenExchangeOpts {
297
+ /** OAuth issuer base URL the `/oauth2/token` request is POSTed to. */
298
+ hubUrl: string;
299
+ /** OAuth client id the authorization code was issued for. */
300
+ clientId: string;
301
+ /** Authorization code returned to the redirect URI. */
302
+ code: string;
303
+ /** PKCE code verifier matching the challenge sent in the auth request. */
304
+ codeVerifier: string;
305
+ /** Redirect URI that received the code; must match the auth request. */
306
+ redirectUri: string;
307
+ /**
308
+ * Custom `fetch` for the token request. Defaults to the global `fetch`.
309
+ * Supply the same implementation you pass as `EraConfig.fetch` (proxy,
310
+ * egress control, request auditing) so sign-in traffic isn't a hole in
311
+ * that boundary. This helper runs before a client exists, so — unlike the
312
+ * refresh path — it can't pick up `EraConfig.fetch` automatically.
313
+ */
314
+ fetch?: typeof globalThis.fetch;
315
+ }
316
+ /**
317
+ * Returns a 43-char base64url-safe PKCE verifier (32 random bytes).
318
+ * Uses `globalThis.crypto.getRandomValues` (Node 18+, browser, edge runtime).
319
+ * Generate one per sign-in attempt, keep it until the callback, and pass it
320
+ * to {@link exchangeCodeForToken} as `codeVerifier`.
321
+ *
322
+ * @returns A 43-character base64url string.
323
+ * @throws {EraAuthError} `pkce_invalid` when Web Crypto is unavailable
324
+ * (requires Node 18+, a modern browser, or an edge runtime).
325
+ */
326
+ declare function generatePkceVerifier(): string;
327
+ /**
328
+ * Returns a 43-char base64url-safe OAuth `state` value (32 random bytes,
329
+ * mirrors {@link generatePkceVerifier}). `state` is OAuth's CSRF defence:
330
+ * generate one before redirecting to `/oauth2/auth`, persist it next to the
331
+ * PKCE verifier (sessionStorage is acceptable — `state` is not a secret,
332
+ * only an unguessable nonce), and on the callback assert that the `state`
333
+ * query param matches what you stored. A mismatch means the callback was
334
+ * triggered by an attacker-controlled flow; reject without exchanging the
335
+ * code. See https://docs.era.world/docs/getting-started/authentication.
336
+ *
337
+ * @returns A 43-character base64url string.
338
+ * @throws {EraAuthError} `pkce_invalid` when Web Crypto is unavailable
339
+ * (requires Node 18+, a modern browser, or an edge runtime).
340
+ */
341
+ declare function generateOauthState(): string;
342
+ /**
343
+ * Returns BASE64URL(SHA-256(verifier)) — the RFC 7636 S256 code challenge to
344
+ * send in {@link buildAuthorizationUrl}.
345
+ *
346
+ * @param verifier - The PKCE verifier from {@link generatePkceVerifier}.
347
+ * @returns The base64url-encoded SHA-256 challenge.
348
+ * @throws {EraAuthError} `pkce_invalid` when Web Crypto is unavailable
349
+ * (requires Node 18+, a modern browser, or an edge runtime).
350
+ */
351
+ declare function generatePkceChallenge(verifier: string): Promise<string>;
352
+ /**
353
+ * Build the `/oauth2/auth` authorization URL that starts the PKCE sign-in
354
+ * flow. Redirect the user's browser to the returned URL; the authorization
355
+ * code comes back on `redirectUri`, ready for {@link exchangeCodeForToken}.
356
+ * The `code_challenge_method` is always S256 (plain challenges are not
357
+ * supported).
358
+ *
359
+ * @param opts - Client id, redirect URI, S256 code challenge, and CSRF
360
+ * `state`; see {@link AuthorizationUrlOpts}.
361
+ * @returns The absolute `${hubUrl}/oauth2/auth?…` URL to redirect the user to.
362
+ * @throws {EraAuthError} `invalid_config` when `opts.state` is not a string of
363
+ * at least 16 characters — short states defeat OAuth's CSRF protection; mint
364
+ * one with {@link generateOauthState}.
365
+ * @example
366
+ * ```ts
367
+ * const verifier = generatePkceVerifier();
368
+ * const state = generateOauthState();
369
+ * const url = buildAuthorizationUrl({
370
+ * hubUrl: 'https://oauth.era.world',
371
+ * clientId: 'client_0000000000',
372
+ * redirectUri: 'https://example.com/callback',
373
+ * codeChallenge: await generatePkceChallenge(verifier),
374
+ * state,
375
+ * });
376
+ * ```
377
+ */
378
+ declare function buildAuthorizationUrl(opts: AuthorizationUrlOpts): string;
379
+ /**
380
+ * Exchange an authorization code (+ PKCE verifier) for a {@link TokenResponse}.
381
+ * POSTs `grant_type=authorization_code` to `${hubUrl}/oauth2/token`. Call it
382
+ * from your redirect-URI handler, then hand the result to {@link seedTokens}
383
+ * so the client can authenticate.
384
+ *
385
+ * @param opts - Code, verifier, client id, redirect URI, and issuer URL; see
386
+ * {@link TokenExchangeOpts}.
387
+ * @returns The token pair issued by the OAuth server.
388
+ * @throws {EraAuthError} `auth_failed` when the token endpoint responds with
389
+ * any error status. `transient` is `true` for 5xx (retrying the exchange may
390
+ * succeed) and `false` for 4xx (wrong/expired code, verifier mismatch, or bad
391
+ * client). The raw body is exposed only on the non-enumerable `responseBody`,
392
+ * never in `.message`.
393
+ * @example
394
+ * ```ts
395
+ * const tokens = await exchangeCodeForToken({
396
+ * hubUrl: 'https://oauth.era.world',
397
+ * clientId: 'client_0000000000',
398
+ * code: callbackParams.get('code')!,
399
+ * codeVerifier,
400
+ * redirectUri: 'https://example.com/callback',
401
+ * });
402
+ * ```
403
+ */
404
+ declare function exchangeCodeForToken(opts: TokenExchangeOpts): Promise<TokenResponse>;
405
+ /**
406
+ * Auth dispatcher. Returns headers to inject on every request.
407
+ * For PKCE: refreshes proactively near expiry, coalescing concurrent refreshes
408
+ * and retrying transient failures with backoff.
409
+ * For apiKey: static Bearer header, no refresh.
410
+ */
411
+ interface AuthDispatcher {
412
+ /** Which auth mode this dispatcher implements; matches the config's `mode`. */
413
+ readonly mode: 'pkce' | 'apiKey';
414
+ /**
415
+ * Returns auth headers to inject (`Authorization: Bearer …`). In PKCE mode
416
+ * this refreshes first when the access token is near expiry, and throws
417
+ * {@link EraAuthError} when no session exists (`no_token`) or the refresh
418
+ * fails (`auth_failed` / `refresh_failed`). apiKey mode never throws.
419
+ */
420
+ getAuthHeaders(): Promise<Record<string, string>>;
421
+ /** Force a token refresh (PKCE only). No-op for apiKey. */
422
+ refresh(): Promise<void>;
423
+ /** Returns the access token if available, else null. */
424
+ getAccessToken(): Promise<string | null>;
425
+ /** Clear stored tokens (logout). For apiKey, no-op (apiKey is config, not state). */
426
+ clear(): Promise<void>;
427
+ }
428
+ /**
429
+ * Build the {@link AuthDispatcher} for an {@link EraAuthConfig}. `createEraClient`
430
+ * calls this internally; call it directly only when you need the header-injection
431
+ * / refresh machinery outside a full client (e.g. a custom transport).
432
+ *
433
+ * Returns an api-key dispatcher (static Bearer, no refresh) when
434
+ * `config.mode === 'apiKey'`, otherwise a PKCE dispatcher that reads tokens from
435
+ * storage, refreshes proactively near expiry, and coalesces concurrent refreshes.
436
+ *
437
+ * @param config - The auth mode and credentials; see {@link EraAuthConfig}.
438
+ * @param options - Transport overrides. `oauthUrl` is the OAuth issuer host for
439
+ * PKCE refresh (defaults to `https://oauth.era.world`); `fetch` is the fetch
440
+ * implementation used for the refresh call (defaults to `globalThis.fetch`).
441
+ * `hubUrl` is accepted for symmetry but not used by the dispatcher.
442
+ * @returns An {@link AuthDispatcher} matching `config.mode`.
443
+ * @throws {EraAuthError} `invalid_config` when an api-key config carries a key
444
+ * that does not match `era_(sk|pk)_(live|test)_<token>`.
445
+ * @example
446
+ * ```ts
447
+ * const dispatcher = createAuthDispatcher({ mode: 'apiKey', apiKey: 'era_sk_test_0000000000' });
448
+ * const headers = await dispatcher.getAuthHeaders();
449
+ * ```
450
+ */
451
+ declare function createAuthDispatcher(config: EraAuthConfig, options?: {
452
+ hubUrl?: string;
453
+ oauthUrl?: string;
454
+ fetch?: typeof globalThis.fetch;
455
+ }): AuthDispatcher;
456
+ /**
457
+ * Seed a PKCE client's token storage with the result of
458
+ * {@link exchangeCodeForToken}.
459
+ *
460
+ * This is the bridge between the OAuth callback and a working client. After you
461
+ * exchange the `code`, call `seedTokens` with the **same** `tokenStorage` and
462
+ * `clientId` you pass to `createEraClient({ auth: { mode: 'pkce', … } })`. The
463
+ * client then authenticates immediately and refreshes the session on its own.
464
+ *
465
+ * ⚠️ A refresh token is a bearer credential. In browsers, back `tokenStorage`
466
+ * with a store that is NOT XSS-readable — never plain `localStorage`. See
467
+ * https://docs.era.world/docs/getting-started/authentication.
468
+ *
469
+ * @param storage - The same {@link TokenStorage} instance the client will use.
470
+ * @param clientId - The OAuth client id; must match the client's `auth.clientId`
471
+ * (tokens are stored under a key namespaced by it).
472
+ * @param tokens - The {@link TokenResponse} from {@link exchangeCodeForToken}.
473
+ * If `refresh_token` is absent, the session works until the access token
474
+ * expires and cannot be refreshed.
475
+ * @throws {EraAuthError} `invalid_config` if `tokens.access_token` is missing.
476
+ * @example
477
+ * ```ts
478
+ * const tokens = await exchangeCodeForToken({ … });
479
+ * const storage = new MemoryTokenStorage(); // or your adapter
480
+ * await seedTokens(storage, CLIENT_ID, tokens);
481
+ * const era = createEraClient({
482
+ * auth: { mode: 'pkce', clientId: CLIENT_ID, redirectUri, tokenStorage: storage },
483
+ * });
484
+ * ```
485
+ */
486
+ declare function seedTokens(storage: TokenStorage, clientId: string, tokens: TokenResponse): Promise<void>;
487
+ //#endregion
488
+ export { generatePkceChallenge as _, EraAuthError as a, EraAuthPkce as c, TokenResponse as d, TokenStorage as f, generateOauthState as g, exchangeCodeForToken as h, EraAuthConfig as i, MemoryTokenStorage as l, createAuthDispatcher as m, AuthorizationUrlOpts as n, EraAuthErrorCode as o, buildAuthorizationUrl as p, EraAuthApiKey as r, EraAuthErrorInit as s, AuthDispatcher as t, TokenExchangeOpts as u, generatePkceVerifier as v, seedTokens as y };
489
+ //# sourceMappingURL=auth-D2XawwCn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-D2XawwCn.d.ts","names":[],"sources":["../src/core/auth.ts"],"mappings":";;UAeiB;;EAEhB;;EAEA;;EAEA;;EAEA;;;;;;;;;;EAUA,eAAe;;;UAIC;;EAEhB;;EAEA;;;;;;;;;;;;;EAaA;;;;;;;;;;;;;;;;;;;KAoBW,gBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;UA0BzB;;;;;;;;;EAShB,IAAI,cAAc;;;;;;;;;EASlB,IAAI,aAAa,gBAAgB;;;;;;;;EAQjC,OAAO,cAAc;;;;;;;;;;;;;;;;;;;;;cAsBT,8BAA8B;mBACzB;;EAGjB,IAAI,cAAc;;EAKlB,IAAI,aAAa,gBAAgB;;EAMjC,OAAO,cAAc;;;;;;;;;;;;;;;;;;;;;KA2BV;;;;;;UAYK;;EAEhB,MAAM;;EAEN;;EAEA;;EAEA;;;;;;EAMA;;;;;;;;EAQA;;;;;;;;;EASA;;;;;;;;;;;;;cAcY,qBAAqB;;;;;WAKjB,MAAM;;;;;;WAMN;;;;;;WAMA;;;;;;;;WAQA;;;;;;;;;;;;;;WAcQ;;;;;;cAOZ,MAAM;;;;;;;;UAuCF;;EAEhB;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;UAOgB;;EAEhB;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;UAQgB;;EAEhB;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;EAQA,eAAe,WAAW;;;;;;;;;;;;iBAwCX;;;;;;;;;;;;;;;iBAoBA;;;;;;;;;;iBAkBM,sBAAsB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgC/C,sBAAsB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDtB,qBACrB,MAAM,oBACJ,QAAQ;;;;;;;UAqCM;;WAEP;;;;;;;EAOT,kBAAkB,QAAQ;;EAE1B,WAAW;;EAEX,kBAAkB;;EAElB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BM,qBACf,QAAQ,eACR;EACC;EACA;EACA,eAAe,WAAW;IAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkZmB,WACrB,SAAS,cACT,kBACA,QAAQ,gBACN"}
@@ -0,0 +1,24 @@
1
+ //#region src/core/casing.d.ts
2
+ /** `foo_bar_baz` → `fooBarBaz` at the type level. */
3
+ type SnakeToCamel<S extends string> = S extends `${infer Head}_${infer Tail}` ? `${Head}${Capitalize<SnakeToCamel<Tail>>}` : S;
4
+ /**
5
+ * Rename every snake_case key of `T` to camelCase, preserving optionality,
6
+ * readonly-ness, and value types. Homomorphic — applying it to a generated
7
+ * component yields the SDK's camelCase view of the exact same wire shape.
8
+ */
9
+ type CamelizeKeys<T> = { [K in keyof T as K extends string ? SnakeToCamel<K> : K]: T[K]; };
10
+ /**
11
+ * Make the keys `K` of `T` required. Used for generated frame types whose
12
+ * discriminator is `type?: 'x'` (the emitter always stamps it; the schema
13
+ * marks it optional-with-default) — the SDK narrows it to required.
14
+ */
15
+ type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
16
+ /**
17
+ * Pick the keys `K` of `T`, made required and with `null`/`undefined`
18
+ * stripped from their value types. Used where the SDK guarantees presence at
19
+ * runtime (e.g. it throws before constructing the object when absent).
20
+ */
21
+ type PickNonNullable<T, K extends keyof T> = { [P in K]-?: NonNullable<T[P]>; };
22
+ //#endregion
23
+ export { PickNonNullable as n, WithRequired as r, CamelizeKeys as t };
24
+ //# sourceMappingURL=casing-_Mn2NyTK.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"casing-_Mn2NyTK.d.ts","names":[],"sources":["../src/core/casing.ts"],"mappings":";;KAaY,aAAa,oBACxB,mBAAmB,cAAc,YAC3B,OAAO,WAAW,aAAa,WAClC;;;;;;KAOQ,aAAa,QACvB,WAAW,KAAK,mBAAmB,aAAa,KAAK,IAAI,EAAE;;;;;;KAQjD,aAAa,GAAG,gBAAgB,KAAK,IAAI,SAAS,KAAK,GAAG;;;;;;KAO1D,gBAAgB,GAAG,gBAAgB,QAC7C,KAAK,MAAM,YAAY,EAAE"}