@keboola/api-client-react 27.0.0 → 31.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,337 @@
1
+ # @keboola/api-client-react
2
+
3
+ ## 31.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies:
8
+ - @keboola/api-client@31.0.0
9
+
10
+ ## 30.0.0
11
+
12
+ ### Patch Changes
13
+
14
+ - The published tarball now carries a `CHANGELOG.md`, so a consumer can read what changed in a release — breaking changes included — without leaving their `node_modules`.
15
+
16
+ It could not simply be added to `files`. This repo is private, so every reference `@changesets/changelog-github` emits is a dead link for anyone reading from npm: PR links, commit SHAs, author handles, and the Linear and cross-repo links that changeset prose carries. Across the publishable packages that came to 490 PR links, 863 commit links, 490 author credits and 102 dependency-bump blocks.
17
+
18
+ The published file is generated, not maintained. `scripts/public-changelog.mjs` removes those links ahead of the publish and leaves the prose. An identifier the author typed themselves stays as text — `UT-4009`, `connection#8040` — because it is part of the sentence and, without its URL, resolves to nothing outside Keboola. The repo-side `CHANGELOG.md` keeps every link, because that is how a release gets traced internally. It is rewritten only for the moment the tarballs are packed, then restored — which the release also depends on: `changesets/action` reads each changelog back off disk _after_ the publish command returns, to build that version's GitHub Release body, so without the restore the internal releases would carry the public text. A reference the rules do not cover fails the publish rather than shipping.
19
+
20
+ One incidental fix: a hex colour written as `#222529` in changeset prose had been autolinked into a link to issue 222529. Unwrapping restores the colour, so the published notes read as the author wrote them.
21
+
22
+ - Updated dependencies:
23
+ - @keboola/api-client@30.0.0
24
+
25
+ ## 29.0.0
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies:
30
+ - @keboola/api-client@29.0.0
31
+
32
+ ## 28.0.0
33
+
34
+ ### Patch Changes
35
+
36
+ - Build with tsdown instead of tsup. Fixes declaration bundling against the new `@keboola/api-client` output: tsup's dts pass inlined `@keboola/api-client/*` subpath types and leaked unresolvable relative chunk imports into `dist/index.d.ts` (attw red in all four modes); with tsdown, peer dependencies stay external in declarations — subpaths included.
37
+
38
+ - Updated dependencies:
39
+ - @keboola/api-client@28.0.0
40
+
41
+ ## 27.0.0
42
+
43
+ ### Minor Changes
44
+
45
+ - `LegacyAuthProvider` gained an `errorFallback` slot, the counterpart of the one its bearer twin `AuthProvider` already had.
46
+
47
+ It previously asked only `session.isStorageReady()`, so an errored storage build was indistinguishable from a pending one and kept rendering `fallback` — a consumer whose SAPI token had expired showed a loading state forever. It now reads the build state from `debug()`/`subscribe`, renders `errorFallback` on failure (defaulting to `fallback`, so the old behaviour stands when it is omitted) and logs the failure, which nothing else did.
48
+
49
+ ### Patch Changes
50
+
51
+ - Updated dependencies:
52
+ - @keboola/api-client@27.0.0
53
+
54
+ ## 26.0.0
55
+
56
+ ### Patch Changes
57
+
58
+ - These packages now ship their `AGENTS.md` usage contract to npm, so external
59
+ consumers (and their AI agents) can read it at
60
+ `node_modules/@keboola/<name>/AGENTS.md`, version-pinned to the release they
61
+ actually installed.
62
+
63
+ Previously only `@keboola/design` published its `AGENTS.md`; every other package
64
+ omitted it from `files`, so instructions that point agents at that path — such as
65
+ `apps/boilerplate/AGENTS.md` — silently resolved to nothing outside the monorepo.
66
+ No code or type changes.
67
+
68
+ - Updated dependencies:
69
+ - @keboola/api-client@26.0.0
70
+
71
+ ## 25.0.0
72
+
73
+ ### Patch Changes
74
+
75
+ - Updated dependencies:
76
+ - @keboola/api-client@25.0.0
77
+
78
+ ## 24.0.0
79
+
80
+ ### Patch Changes
81
+
82
+ - Updated dependencies:
83
+ - @keboola/api-client@24.0.0
84
+
85
+ ## 23.0.0
86
+
87
+ ### Patch Changes
88
+
89
+ - Updated dependencies:
90
+ - @keboola/api-client@23.0.0
91
+
92
+ ## 22.0.0
93
+
94
+ ### Patch Changes
95
+
96
+ - Updated dependencies:
97
+ - @keboola/api-client@22.0.0
98
+
99
+ ## 21.0.0
100
+
101
+ ### Major Changes
102
+
103
+ - Reshape the SDK lifecycle around two authentication flows behind one product surface.
104
+ - **Breaking:** the entry points are now `createKeboola()` (bearer / OAuth) and `createLegacyKeboola()` (legacy SAPI + management token). Each returns `{ api, session }` — `api` is the flow-agnostic product surface (`auth`, `management`, `storage`, `queue`, `context`, `sdk`, …); `session` is the flow-specific lifecycle (bearer: `authenticate(credential)` → `setProject(id)`; legacy: `authenticateStorage(sapiToken)` / `authenticateManagement(manageToken)`). The old `createApiClient()` / `init()` lifecycle and the `ApiClient` type are removed.
105
+ - **Breaking:** per-service factories take an `auth` strategy instead of a bare token — `createStorageClient({ baseUrl, auth: { type: 'sapi-token', token } })`, `createManagementClient({ baseUrl, auth: { type: 'management-token', token } })` (bearer: `{ type: 'bearer', token }`). `createManagementClient` keeps `withAuthMiddleware` (default `true`; pass `false` for a raw validity-check client).
106
+ - `@keboola/api-client-react` exposes three providers: `ApiClientProvider` (propagates `api` to `useApiClient()`), `LegacyAuthProvider` (drives the legacy session to ready and gates on a fallback), and `AuthProvider` (bearer; finished with the login flow in a follow-up). `useApiClient` / `useProject` / `useStack` return the `api` surface.
107
+ - **Breaking:** the token-less public clients `assets` / `status` are not part of the keboola client — import `createAssetsClient` / `createStatusClient` from `@keboola/api-client/assets` and `@keboola/api-client/status`. `metastore` is a stack-discovered service, exposed as `api.metastore`.
108
+ - `KeboolaError` / `isKeboolaError` are exported from the package root and are the errors the client actually throws (lifecycle gating: `NotReady`, `Unconfigured`, `NoManagementToken`, …).
109
+
110
+ Migration: `const api = createApiClient(); await api.init(opts)` → `const { api, session } = createLegacyKeboola(opts); await session.authenticateStorageAsync(token)` (or `createKeboola` for the bearer flow). Per-service: `createStorageClient({ baseUrl, token })` → `createStorageClient({ baseUrl, auth: { type: 'sapi-token', token } })`.
111
+
112
+ - Give `AuthProvider` one slot per session state, and make the interactive mode's login slot mandatory.
113
+ - **Breaking:** the single `fallback` prop is replaced by three, so a genuine failure is no longer indistinguishable from "not signed in yet": `loadingFallback` (restoring / bootstrapping), `anonymousFallback` (no session — render the sign-in UI), and `errorFallback` (the storage build failed). `children` still render only once the session is scoped and storage is ready.
114
+ - **Breaking:** props are a discriminated union over the two bootstrap modes. Programmatic (`credential` + `projectId`) requires `baseUrl`, since a credential is bound to the stack that issued it. Interactive takes neither credential nor `baseUrl` — the stack comes from the restored session or from the login UI — and **requires** `anonymousFallback`, so omitting the login UI is a compile error instead of a permanently blank screen.
115
+ - `children` may now be a function receiving the scoped `{ projectId, baseUrl }`, so consumers don't re-narrow session state to read the project they landed on.
116
+ - The loading state is seeded from `session.hasPersistedValue()`: with nothing persisted there is nothing to wait for, so the login UI paints on the first render instead of flashing a loader for an empty, network-free restore.
117
+
118
+ ### Minor Changes
119
+
120
+ - Finish the bearer (programmatic) auth flow. `AuthProvider` is now the bearer twin of `LegacyAuthProvider`: it takes `baseUrl` / `credential` / `projectId` (plus optional `onAccessTokenChange` and `fallback`), drives the session to ready on mount, mirrors the rotating access token out via `onAccessTokenChange`, and gates its children behind readiness.
121
+
122
+ - Rework the bearer (OAuth) auth internals for a cleaner separation of concerns. Token handling now lives in a `TokenCredential`-style provider — `getAccessToken({ forceRefresh })` always returns a usable access token, refreshing (deduped) on near-expiry or when forced — consumed by a thin auth middleware that stamps the live token on every request and replays once on a 401. The bearer session config is a discriminated-union state machine (`anonymous` / `authenticated` / `scoped`) that owns its own credential model and the fire-once session-expiry latch: `session.authenticate` now takes a `TokenSet` (`accessToken`, `refreshToken`, `expiresIn`) rather than the full login credential, and `SessionSnapshot.config` is that state union. Also adds a `dedupe` (single-flight) util.
123
+
124
+ ### Patch Changes
125
+
126
+ - Updated dependencies:
127
+ - @keboola/api-client@21.0.0
128
+
129
+ ## 20.0.0
130
+
131
+ ### Patch Changes
132
+
133
+ - Updated dependencies:
134
+ - @keboola/api-client@20.0.0
135
+
136
+ ## 19.0.0
137
+
138
+ ### Patch Changes
139
+
140
+ - Updated dependencies:
141
+ - @keboola/api-client@19.0.0
142
+
143
+ ## 18.0.0
144
+
145
+ ### Major Changes
146
+
147
+ - Discover the metastore service from stack info instead of taking a `metastoreBaseUrl` option.
148
+ - **Breaking:** `metastoreBaseUrl` is removed from `ApiClientOptions`. `createApiClient`/`init()` no longer accept it, and `ApiClientProvider` no longer accepts the `metastoreBaseUrl` prop.
149
+ - `metastore` is now a stack-discovered service client (like `queue`, `vault`, …): its base URL comes from `getStackInfo` service discovery, exposed on the client as `api.metastore` and consumed by the tag SDK. On stacks that don't advertise a metastore service, the client resolves to a lazy no-op that throws only when a metastore method is actually called.
150
+
151
+ Migration: drop `metastoreBaseUrl` from every `createApiClient`/`init()`/`ApiClientProvider` call — the URL is resolved automatically from the stack.
152
+
153
+ ### Patch Changes
154
+
155
+ - Updated dependencies:
156
+ - @keboola/api-client@18.0.0
157
+
158
+ ## 17.0.0
159
+
160
+ ### Patch Changes
161
+
162
+ - Updated dependencies:
163
+ - @keboola/api-client@17.0.0
164
+
165
+ ## 16.0.0
166
+
167
+ ### Major Changes
168
+
169
+ - Remove `createDevApiClient` (and, in `@keboola/api-client-react`, `DevApiClientProvider` / `useDevApiClient`).
170
+
171
+ `createDevApiClient` was a stateless pass-through — `{ verify: { storageApiToken, managementApiToken } }` with no lifecycle, no base-URL registry, no `init()`. It doesn't fit the client model; it's just two host-parameterized verify calls. The React dev-provider layer existed only to carry that object through context.
172
+
173
+ Verify a candidate token with the real per-service clients directly (host-parameterized per call, no provider):
174
+ - storage: `createStorageClient({ baseUrl: host, token }).tokens.verify()`
175
+ - management: `createManagementClient({ baseUrl: host, token, withAuthMiddleware: false }).verifyToken()`
176
+
177
+ ### Patch Changes
178
+
179
+ - Updated dependencies:
180
+ - @keboola/api-client@16.0.0
181
+
182
+ ## 15.0.0
183
+
184
+ ### Patch Changes
185
+
186
+ - Updated dependencies:
187
+ - @keboola/api-client@15.0.0
188
+
189
+ ## 14.0.0
190
+
191
+ ### Patch Changes
192
+
193
+ - Updated dependencies:
194
+ - @keboola/api-client@14.0.0
195
+
196
+ ## 13.0.0
197
+
198
+ ### Patch Changes
199
+
200
+ - Updated dependencies:
201
+ - @keboola/api-client@13.0.0
202
+
203
+ ## 12.0.0
204
+
205
+ ### Patch Changes
206
+
207
+ - Updated dependencies:
208
+ - @keboola/api-client@12.0.0
209
+
210
+ ## 11.0.0
211
+
212
+ ### Patch Changes
213
+
214
+ - Updated dependencies:
215
+ - @keboola/api-client@11.0.0
216
+
217
+ ## 10.0.0
218
+
219
+ ### Patch Changes
220
+
221
+ - Updated dependencies:
222
+ - @keboola/api-client@10.0.0
223
+
224
+ ## 9.0.0
225
+
226
+ ### Patch Changes
227
+
228
+ - Updated dependencies:
229
+ - @keboola/api-client@9.0.0
230
+
231
+ ## 8.0.2
232
+
233
+ ### Patch Changes
234
+
235
+ - docs: document the sanctioned non-component data-access pattern (loaders / module-scope services) — use a per-service client or a bootstrap `createApiClient` instance, not the `useApiClient` hook
236
+
237
+ - Updated dependencies:
238
+ - @keboola/api-client@8.0.2
239
+
240
+ ## 8.0.0
241
+
242
+ ### Patch Changes
243
+
244
+ - Updated dependencies:
245
+ - @keboola/api-client@8.0.0
246
+
247
+ ## 7.0.0
248
+
249
+ ### Patch Changes
250
+
251
+ - Updated dependencies:
252
+ - @keboola/api-client@7.0.0
253
+
254
+ ## 6.0.0
255
+
256
+ ### Patch Changes
257
+
258
+ - Updated dependencies:
259
+ - @keboola/api-client@6.0.0
260
+
261
+ ## 5.0.0
262
+
263
+ ### Patch Changes
264
+
265
+ - Updated dependencies:
266
+ - @keboola/api-client@5.0.0
267
+
268
+ ## 4.0.0
269
+
270
+ ### Patch Changes
271
+
272
+ - Updated dependencies:
273
+ - @keboola/api-client@4.0.0
274
+
275
+ ## 3.0.0
276
+
277
+ ### Patch Changes
278
+
279
+ - Updated dependencies:
280
+ - @keboola/api-client@3.0.0
281
+
282
+ ## 2.0.0
283
+
284
+ ### Patch Changes
285
+
286
+ - Re-publish to scrub `workspace:^` from the npm tarball manifests.
287
+
288
+ `@keboola/design@1.2.0` shipped with literal `workspace:^` strings in
289
+ `dependencies` (`codemirror-lang-sfsql`, `codemirror-lang-sql`,
290
+ `tailwind-config`), making `npm install @keboola/design` fail with
291
+ `EUNSUPPORTEDPROTOCOL` — npm has no way to resolve the yarn-only
292
+ workspace protocol against a public registry.
293
+ `@keboola/api-client-react@1.0.1` shipped with the same
294
+ leak in `peerDependencies` (`@keboola/api-client`) — less fatal
295
+ because peerDeps are warnings, not errors, but still wrong.
296
+
297
+ Root cause was the publish workflow invoking plain `npm publish`
298
+ (which doesn't understand `workspace:^`) instead of
299
+ `yarn npm publish` (which rewrites it just-in-time). This changeset
300
+ rides alongside the workflow script fix, so the next release cycle
301
+ republishes both packages cleanly through the corrected path.
302
+
303
+ The other recently-bumped packages (`api-client`, `brand-registry`,
304
+ `brand-audit`, `codemirror-lang-*`, `agent-precheck`,
305
+ `oxlint-config`) don't need patches — they happen to have no
306
+ `@keboola/*` runtime or peer deps, so the bug couldn't bite them.
307
+
308
+ - Updated dependencies:
309
+ - @keboola/api-client@2.0.0
310
+
311
+ ## 1.0.1
312
+
313
+ ### Patch Changes
314
+
315
+ - Re-publish to fix unresolved `workspace:^` protocol references in the npm tarball manifests.
316
+
317
+ The initial bootstrap publishes (2026-05-18 for `@keboola/api-client` and `@keboola/api-client-react`, later for the rest) were run manually with `npm publish` from a maintainer machine. Bare `npm publish` doesn't understand yarn's `workspace:` protocol, so the published `package.json` files shipped with literal `workspace:^` strings in `dependencies`, `peerDependencies`, and `devDependencies`.
318
+
319
+ The blocker is `@keboola/api-client-react@1.0.0`'s `peerDependencies` declaring `@keboola/api-client: workspace:^`. Running `npm install @keboola/api-client-react` from outside the monorepo fails with `EUNSUPPORTEDPROTOCOL` because npm can't resolve the `workspace:` protocol. The same string also appears in `@keboola/api-client`, `@keboola/brand-registry`, and `@keboola/oxlint-config` `devDependencies` — npm ignores those for transitive installs, but they're still wrong in the published manifests and worth cleaning up in the same release.
320
+
321
+ This patch bump triggers a regular changesets-driven release. When `changeset publish` runs in CI, it rewrites `workspace:*` references to the actual resolved version ranges before calling `npm publish`, restoring a consumable npm surface for every package.
322
+
323
+ `@keboola/codemirror-lang-sql` has the same issue but is already covered by an existing pending changeset (`codemirror-lang-sql-publish.md`, minor bump for initial publish setup); the next release will fix it through that bump.
324
+
325
+ No source code or runtime behavior changes. The local `workspace:^` references in source `package.json` files stay (they're correct for monorepo workspace deps; the rewrite happens only at publish time).
326
+
327
+ - Updated dependencies:
328
+ - @keboola/api-client@1.0.1
329
+
330
+ ## 1.0.0
331
+
332
+ ### Patch Changes
333
+
334
+ - Initial publish setup for `@keboola/api-client-react` — React provider + hooks (`useApiClient`, `useProject`, `useStack`, `useDevApiClient`) for the Keboola SDK. Ships dual ESM/CJS bundles via `tsup` with React 18/19 as peer dependencies. Linked with `@keboola/api-client` so both packages release together.
335
+
336
+ - Updated dependencies:
337
+ - @keboola/api-client@1.0.0
package/dist/index.cjs CHANGED
@@ -1,139 +1,161 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var jsxRuntime = require('react/jsx-runtime');
5
-
6
- // src/context.ts
7
- var MISSING_API_CLIENT_ERROR = "useApiClient must be used within <ApiClientProvider />";
8
- var MISSING_PROJECT_ERROR = "useProject must be used within <ApiClientProvider />";
9
- var MISSING_STACK_ERROR = "useStack must be used within <ApiClientProvider />";
10
- var MISSING_AUTH_ERROR = "useAuth must be used within <AuthProvider />";
11
- var MISSING_LEGACY_AUTH_ERROR = "useLegacyAuth must be used within <LegacyAuthProvider />";
12
- var ApiContext = react.createContext(null);
13
- var ApiProvider = ApiContext;
14
- var AuthContext = react.createContext(null);
15
- var AuthContextProvider = AuthContext;
16
- var LegacyAuthContext = react.createContext(null);
17
- var LegacyAuthContextProvider = LegacyAuthContext;
18
- var useApiClient = () => {
19
- const api = react.use(ApiContext);
20
- if (api === null) throw new Error(MISSING_API_CLIENT_ERROR);
21
- return api;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let react = require("react");
3
+ let react_jsx_runtime = require("react/jsx-runtime");
4
+ //#region src/context.ts
5
+ const MISSING_API_CLIENT_ERROR = "useApiClient must be used within <ApiClientProvider />";
6
+ const MISSING_PROJECT_ERROR = "useProject must be used within <ApiClientProvider />";
7
+ const MISSING_STACK_ERROR = "useStack must be used within <ApiClientProvider />";
8
+ const MISSING_AUTH_ERROR = "useAuth must be used within <AuthProvider />";
9
+ const MISSING_LEGACY_AUTH_ERROR = "useLegacyAuth must be used within <LegacyAuthProvider />";
10
+ const ApiContext = (0, react.createContext)(null);
11
+ const ApiProvider = ApiContext;
12
+ const AuthContext = (0, react.createContext)(null);
13
+ const AuthContextProvider = AuthContext;
14
+ const LegacyAuthContext = (0, react.createContext)(null);
15
+ const LegacyAuthContextProvider = LegacyAuthContext;
16
+ const useApiClient = () => {
17
+ const api = (0, react.use)(ApiContext);
18
+ if (api === null) throw new Error(MISSING_API_CLIENT_ERROR);
19
+ return api;
22
20
  };
23
- var useProject = () => {
24
- const api = react.use(ApiContext);
25
- if (api === null) throw new Error(MISSING_PROJECT_ERROR);
26
- return api.context.project;
21
+ const useProject = () => {
22
+ const api = (0, react.use)(ApiContext);
23
+ if (api === null) throw new Error(MISSING_PROJECT_ERROR);
24
+ return api.context.project;
27
25
  };
28
- var useStack = () => {
29
- const api = react.use(ApiContext);
30
- if (api === null) throw new Error(MISSING_STACK_ERROR);
31
- return api.context.stack;
26
+ const useStack = () => {
27
+ const api = (0, react.use)(ApiContext);
28
+ if (api === null) throw new Error(MISSING_STACK_ERROR);
29
+ return api.context.stack;
32
30
  };
33
- var useAuth = () => {
34
- const session = react.use(AuthContext);
35
- if (session === null) throw new Error(MISSING_AUTH_ERROR);
36
- return session;
31
+ /** The bearer (OAuth) lifecycle session. Throws outside `<AuthProvider />`. */
32
+ const useAuth = () => {
33
+ const session = (0, react.use)(AuthContext);
34
+ if (session === null) throw new Error(MISSING_AUTH_ERROR);
35
+ return session;
37
36
  };
38
- var useLegacyAuth = () => {
39
- const session = react.use(LegacyAuthContext);
40
- if (session === null) throw new Error(MISSING_LEGACY_AUTH_ERROR);
41
- return session;
37
+ /** The legacy (SAPI) lifecycle session. Throws outside `<LegacyAuthProvider />`. */
38
+ const useLegacyAuth = () => {
39
+ const session = (0, react.use)(LegacyAuthContext);
40
+ if (session === null) throw new Error(MISSING_LEGACY_AUTH_ERROR);
41
+ return session;
42
42
  };
43
- var ApiClientProvider = ({ api, children }) => /* @__PURE__ */ jsxRuntime.jsx(ApiProvider, { value: api, children });
44
- var AuthProvider = ({
45
- session,
46
- baseUrl,
47
- credential,
48
- projectId,
49
- onAccessTokenChange,
50
- loadingFallback = null,
51
- errorFallback = null,
52
- anonymousFallback = null,
53
- children
54
- }) => {
55
- const [snapshot, setSnapshot] = react.useState(() => session.debug());
56
- const [isRestoring, setIsRestoring] = react.useState(() => session.hasPersistedValue());
57
- const [restoreStatus, setRestoreStatus] = react.useState(null);
58
- const restoreStartedRef = react.useRef(false);
59
- react.useEffect(() => session.subscribe(setSnapshot), [session]);
60
- react.useEffect(() => {
61
- if (baseUrl === void 0) return;
62
- if (snapshot.config.baseUrl !== null) return;
63
- session.setBaseUrl(baseUrl);
64
- }, [session, baseUrl, snapshot.config.baseUrl]);
65
- react.useEffect(() => {
66
- if (restoreStartedRef.current) return;
67
- restoreStartedRef.current = true;
68
- session.restore().then((result) => setRestoreStatus(result.status)).catch((error) => {
69
- console.error("Keboola bearer session restore failed", error);
70
- setRestoreStatus("empty");
71
- }).finally(() => setIsRestoring(false));
72
- }, [session]);
73
- react.useEffect(() => {
74
- if (restoreStatus === null || restoreStatus === "restored") return;
75
- if (credential === void 0) return;
76
- if (snapshot.config.status !== "anonymous") return;
77
- session.authenticate(credential);
78
- }, [session, restoreStatus, credential, snapshot.config.status]);
79
- react.useEffect(() => {
80
- if (restoreStatus === null || restoreStatus === "restored") return;
81
- if (projectId === void 0) return;
82
- if (snapshot.config.status !== "authenticated") return;
83
- session.setProject(projectId);
84
- }, [session, restoreStatus, projectId, snapshot.config.status]);
85
- const accessToken = snapshot.config.status === "anonymous" ? void 0 : snapshot.config.credential.accessToken;
86
- react.useEffect(() => {
87
- if (accessToken !== void 0) onAccessTokenChange?.(accessToken);
88
- }, [accessToken, onAccessTokenChange]);
89
- const isProgrammatic = credential !== void 0 && projectId !== void 0;
90
- const content = (() => {
91
- if (snapshot.storage === "ready") {
92
- if (typeof children !== "function") return children;
93
- if (snapshot.config.status !== "scoped") return null;
94
- const { projectId: scopedProjectId, baseUrl: scopedBaseUrl } = snapshot.config;
95
- return children({ projectId: scopedProjectId, baseUrl: scopedBaseUrl });
96
- }
97
- if (snapshot.storage === "errored") return errorFallback;
98
- if (isRestoring || snapshot.storage === "pending" || isProgrammatic) return loadingFallback;
99
- return anonymousFallback;
100
- })();
101
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContextProvider, { value: session, children: content });
43
+ //#endregion
44
+ //#region src/ApiClientProvider.tsx
45
+ /**
46
+ * Provides the product API to `useApiClient()`. A pure pass-through: the auth lifecycle (driving
47
+ * to ready, gating on a fallback) belongs to `AuthProvider` / `LegacyAuthProvider`, which mount
48
+ * this provider once their session is ready.
49
+ */
50
+ const ApiClientProvider = ({ api, children }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiProvider, {
51
+ value: api,
52
+ children
53
+ });
54
+ //#endregion
55
+ //#region src/AuthProvider.tsx
56
+ const AuthProvider = ({ session, baseUrl, credential, projectId, onAccessTokenChange, loadingFallback = null, errorFallback = null, anonymousFallback = null, children }) => {
57
+ const [snapshot, setSnapshot] = (0, react.useState)(() => session.debug());
58
+ const [isRestoring, setIsRestoring] = (0, react.useState)(() => session.hasPersistedValue());
59
+ const [restoreStatus, setRestoreStatus] = (0, react.useState)(null);
60
+ const restoreStartedRef = (0, react.useRef)(false);
61
+ (0, react.useEffect)(() => session.subscribe(setSnapshot), [session]);
62
+ (0, react.useEffect)(() => {
63
+ if (baseUrl === void 0) return;
64
+ if (snapshot.config.baseUrl !== null) return;
65
+ session.setBaseUrl(baseUrl);
66
+ }, [
67
+ session,
68
+ baseUrl,
69
+ snapshot.config.baseUrl
70
+ ]);
71
+ (0, react.useEffect)(() => {
72
+ if (restoreStartedRef.current) return;
73
+ restoreStartedRef.current = true;
74
+ session.restore().then((result) => setRestoreStatus(result.status)).catch((error) => {
75
+ console.error("Keboola bearer session restore failed", error);
76
+ setRestoreStatus("empty");
77
+ }).finally(() => setIsRestoring(false));
78
+ }, [session]);
79
+ (0, react.useEffect)(() => {
80
+ if (restoreStatus === null || restoreStatus === "restored") return;
81
+ if (credential === void 0) return;
82
+ if (snapshot.config.status !== "anonymous") return;
83
+ session.authenticate(credential);
84
+ }, [
85
+ session,
86
+ restoreStatus,
87
+ credential,
88
+ snapshot.config.status
89
+ ]);
90
+ (0, react.useEffect)(() => {
91
+ if (restoreStatus === null || restoreStatus === "restored") return;
92
+ if (projectId === void 0) return;
93
+ if (snapshot.config.status !== "authenticated") return;
94
+ session.setProject(projectId);
95
+ }, [
96
+ session,
97
+ restoreStatus,
98
+ projectId,
99
+ snapshot.config.status
100
+ ]);
101
+ const accessToken = snapshot.config.status === "anonymous" ? void 0 : snapshot.config.credential.accessToken;
102
+ (0, react.useEffect)(() => {
103
+ if (accessToken !== void 0) onAccessTokenChange?.(accessToken);
104
+ }, [accessToken, onAccessTokenChange]);
105
+ const isProgrammatic = credential !== void 0 && projectId !== void 0;
106
+ const content = (() => {
107
+ if (snapshot.storage === "ready") {
108
+ if (typeof children !== "function") return children;
109
+ if (snapshot.config.status !== "scoped") return null;
110
+ const { projectId: scopedProjectId, baseUrl: scopedBaseUrl } = snapshot.config;
111
+ return children({
112
+ projectId: scopedProjectId,
113
+ baseUrl: scopedBaseUrl
114
+ });
115
+ }
116
+ if (snapshot.storage === "errored") return errorFallback;
117
+ if (isRestoring || snapshot.storage === "pending" || isProgrammatic) return loadingFallback;
118
+ return anonymousFallback;
119
+ })();
120
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthContextProvider, {
121
+ value: session,
122
+ children: content
123
+ });
102
124
  };
103
- var LegacyAuthProvider = ({
104
- session,
105
- baseUrl,
106
- storageToken,
107
- managementToken,
108
- fallback = null,
109
- errorFallback = fallback,
110
- children
111
- }) => {
112
- const [storageState, setStorageState] = react.useState(() => session.debug().storage);
113
- const startedRef = react.useRef(false);
114
- react.useEffect(() => {
115
- const unsubscribe = session.subscribe((snapshot) => setStorageState(snapshot.storage));
116
- if (!startedRef.current) {
117
- startedRef.current = true;
118
- session.setBaseUrl(baseUrl);
119
- if (managementToken) session.authenticateManagement(managementToken);
120
- void session.authenticateStorageAsync(storageToken).catch((error) => console.error("Keboola session bootstrap failed", error));
121
- }
122
- return unsubscribe;
123
- }, []);
124
- react.useEffect(() => {
125
- if (storageState === "errored") {
126
- console.error("Keboola session bootstrap failed: the storage build errored.");
127
- }
128
- }, [storageState]);
129
- const content = (() => {
130
- if (storageState === "ready") return children;
131
- if (storageState === "errored") return errorFallback;
132
- return fallback;
133
- })();
134
- return /* @__PURE__ */ jsxRuntime.jsx(LegacyAuthContextProvider, { value: session, children: content });
125
+ //#endregion
126
+ //#region src/LegacyAuthProvider.tsx
127
+ /**
128
+ * Owns the legacy (SAPI) lifecycle: on mount it configures the stack and drives the session to
129
+ * ready, rendering `fallback` until the storage build resolves. The backend-injected SAPI token is
130
+ * known up front, so this drives itself (unlike the interactive bearer `AuthProvider`). Exposes the
131
+ * session via `useLegacyAuth()` and gates `children` behind readiness.
132
+ */
133
+ const LegacyAuthProvider = ({ session, baseUrl, storageToken, managementToken, fallback = null, errorFallback = fallback, children }) => {
134
+ const [storageState, setStorageState] = (0, react.useState)(() => session.debug().storage);
135
+ const startedRef = (0, react.useRef)(false);
136
+ (0, react.useEffect)(() => {
137
+ const unsubscribe = session.subscribe((snapshot) => setStorageState(snapshot.storage));
138
+ if (!startedRef.current) {
139
+ startedRef.current = true;
140
+ session.setBaseUrl(baseUrl);
141
+ if (managementToken) session.authenticateManagement(managementToken);
142
+ session.authenticateStorageAsync(storageToken).catch((error) => console.error("Keboola session bootstrap failed", error));
143
+ }
144
+ return unsubscribe;
145
+ }, []);
146
+ (0, react.useEffect)(() => {
147
+ if (storageState === "errored") console.error("Keboola session bootstrap failed: the storage build errored.");
148
+ }, [storageState]);
149
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LegacyAuthContextProvider, {
150
+ value: session,
151
+ children: (() => {
152
+ if (storageState === "ready") return children;
153
+ if (storageState === "errored") return errorFallback;
154
+ return fallback;
155
+ })()
156
+ });
135
157
  };
136
-
158
+ //#endregion
137
159
  exports.ApiClientProvider = ApiClientProvider;
138
160
  exports.AuthProvider = AuthProvider;
139
161
  exports.LegacyAuthProvider = LegacyAuthProvider;
@@ -142,5 +164,5 @@ exports.useAuth = useAuth;
142
164
  exports.useLegacyAuth = useLegacyAuth;
143
165
  exports.useProject = useProject;
144
166
  exports.useStack = useStack;
145
- //# sourceMappingURL=index.cjs.map
167
+
146
168
  //# sourceMappingURL=index.cjs.map