@frontmcp/ui 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/auth/AuthPageWrapper.d.ts +56 -0
  2. package/auth/AuthPageWrapper.d.ts.map +1 -0
  3. package/auth/context.d.ts +23 -0
  4. package/auth/context.d.ts.map +1 -0
  5. package/auth/contract.d.ts +276 -0
  6. package/auth/contract.d.ts.map +1 -0
  7. package/auth/hooks.d.ts +83 -0
  8. package/auth/hooks.d.ts.map +1 -0
  9. package/auth/hydrate.d.ts +50 -0
  10. package/auth/hydrate.d.ts.map +1 -0
  11. package/auth/index.d.ts +23 -0
  12. package/auth/index.d.ts.map +1 -0
  13. package/auth/index.js +421 -0
  14. package/auth/vanilla/auth-flow.d.ts +96 -0
  15. package/auth/vanilla/auth-flow.d.ts.map +1 -0
  16. package/auth/vanilla/index.d.ts +14 -0
  17. package/auth/vanilla/index.d.ts.map +1 -0
  18. package/auth/vanilla/index.js +251 -0
  19. package/bridge/adapters/base-adapter.d.ts +2 -1
  20. package/bridge/adapters/base-adapter.d.ts.map +1 -1
  21. package/bridge/adapters/ext-apps.adapter.d.ts +6 -1
  22. package/bridge/adapters/ext-apps.adapter.d.ts.map +1 -1
  23. package/bridge/adapters/openai.adapter.d.ts +9 -1
  24. package/bridge/adapters/openai.adapter.d.ts.map +1 -1
  25. package/bridge/core/bridge-factory.d.ts +7 -2
  26. package/bridge/core/bridge-factory.d.ts.map +1 -1
  27. package/bridge/index.d.ts +1 -1
  28. package/bridge/index.d.ts.map +1 -1
  29. package/bridge/index.js +38 -0
  30. package/bridge/runtime/iife-generator.d.ts.map +1 -1
  31. package/bridge/types.d.ts +24 -0
  32. package/bridge/types.d.ts.map +1 -1
  33. package/components/Modal/Modal.d.ts +1 -1
  34. package/esm/auth/index.mjs +398 -0
  35. package/esm/auth/vanilla/index.mjs +228 -0
  36. package/esm/bridge/index.mjs +38 -0
  37. package/esm/index.mjs +8 -0
  38. package/esm/package.json +22 -2
  39. package/esm/react/index.mjs +8 -0
  40. package/index.js +8 -0
  41. package/package.json +22 -2
  42. package/react/index.js +8 -0
package/auth/index.js ADDED
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // libs/ui/src/auth/index.ts
21
+ var auth_exports = {};
22
+ __export(auth_exports, {
23
+ AUTH_EXTRA_FIELD: () => AUTH_EXTRA_FIELD,
24
+ AUTH_FLOW_GLOBAL_KEY: () => AUTH_FLOW_GLOBAL_KEY,
25
+ AUTH_WIRE_FIELDS: () => AUTH_WIRE_FIELDS,
26
+ AuthFlowContext: () => AuthFlowContext,
27
+ AuthFlowProvider: () => AuthFlowProvider,
28
+ AuthPageWrapper: () => AuthPageWrapper,
29
+ CONSENT_SUBMITTED_VALUE: () => CONSENT_SUBMITTED_VALUE,
30
+ DEFAULT_AUTH_MOUNT_ID: () => DEFAULT_AUTH_MOUNT_ID,
31
+ DEFAULT_SUBMIT_METHOD: () => DEFAULT_SUBMIT_METHOD,
32
+ WIRE_TRUE: () => WIRE_TRUE,
33
+ getAddedItems: () => getAddedItems,
34
+ getAuthFlow: () => getAuthFlow,
35
+ mountAuthPage: () => mountAuthPage,
36
+ setAuthNavigator: () => setAuthNavigator,
37
+ submitExtra: () => submitExtra,
38
+ submitFinish: () => submitFinish,
39
+ tryGetAuthFlow: () => tryGetAuthFlow,
40
+ useAddedItems: () => useAddedItems,
41
+ useAuthFlow: () => useAuthFlow,
42
+ useExtraField: () => useExtraField
43
+ });
44
+ module.exports = __toCommonJS(auth_exports);
45
+
46
+ // libs/ui/src/auth/contract.ts
47
+ var AUTH_FLOW_GLOBAL_KEY = "__FRONTMCP_AUTH__";
48
+ var DEFAULT_SUBMIT_METHOD = "GET";
49
+ var AUTH_WIRE_FIELDS = {
50
+ /** Pending authorization id. */
51
+ pendingAuthId: "pending_auth_id",
52
+ /** Anti-CSRF token. */
53
+ csrf: "csrf",
54
+ /** Marks a consent-form submission (distinguishes empty-select from first visit). */
55
+ consentSubmitted: "consent_submitted",
56
+ /** Repeated checkbox field carrying selected tool ids on the consent slot. */
57
+ tools: "tools",
58
+ /** Marks a federated submission. */
59
+ federated: "federated",
60
+ /** Repeated checkbox field carrying selected provider ids on the federated slot. */
61
+ providers: "providers",
62
+ /** Marks an incremental authorization. */
63
+ incremental: "incremental",
64
+ /** Target app id for incremental authorization. */
65
+ appId: "app_id",
66
+ /** Generic action discriminator (e.g. consent `authorize`/`skip`, or an extra name). */
67
+ action: "action"
68
+ };
69
+ var CONSENT_SUBMITTED_VALUE = "1";
70
+ var WIRE_TRUE = "true";
71
+ var AUTH_EXTRA_FIELD = AUTH_WIRE_FIELDS.action;
72
+ var DEFAULT_AUTH_MOUNT_ID = "frontmcp-auth-root";
73
+
74
+ // libs/ui/src/auth/vanilla/auth-flow.ts
75
+ function getGlobalCarrier() {
76
+ if (typeof window !== "undefined") {
77
+ return window;
78
+ }
79
+ return globalThis;
80
+ }
81
+ function getAuthFlow() {
82
+ const state = tryGetAuthFlow();
83
+ if (!state) {
84
+ throw new Error(
85
+ `[auth-ui] No injected auth flow state found on window.${AUTH_FLOW_GLOBAL_KEY}. This page must be server-rendered by a FrontMCP @AuthUi slot.`
86
+ );
87
+ }
88
+ return state;
89
+ }
90
+ function tryGetAuthFlow() {
91
+ const carrier = getGlobalCarrier();
92
+ const state = carrier?.[AUTH_FLOW_GLOBAL_KEY];
93
+ if (!state || typeof state !== "object") {
94
+ return void 0;
95
+ }
96
+ return state;
97
+ }
98
+ function getAddedItems(name) {
99
+ const items = tryGetAuthFlow()?.addedItems?.[name];
100
+ return Array.isArray(items) ? items : [];
101
+ }
102
+ function toEntries(input) {
103
+ if (!input) {
104
+ return [];
105
+ }
106
+ if (isFormElement(input)) {
107
+ return formDataToEntries(new FormData(input));
108
+ }
109
+ if (typeof FormData !== "undefined" && input instanceof FormData) {
110
+ return formDataToEntries(input);
111
+ }
112
+ const entries = [];
113
+ for (const [key, value] of Object.entries(input)) {
114
+ if (value === void 0 || value === null) {
115
+ continue;
116
+ }
117
+ if (Array.isArray(value)) {
118
+ for (const v of value) {
119
+ if (v !== void 0 && v !== null) {
120
+ entries.push([key, String(v)]);
121
+ }
122
+ }
123
+ } else {
124
+ entries.push([key, String(value)]);
125
+ }
126
+ }
127
+ return entries;
128
+ }
129
+ function formDataToEntries(fd) {
130
+ const entries = [];
131
+ fd.forEach((value, key) => {
132
+ if (typeof value === "string") {
133
+ entries.push([key, value]);
134
+ }
135
+ });
136
+ return entries;
137
+ }
138
+ function isFormElement(input) {
139
+ return typeof input === "object" && // `nodeName` + a `FormData`-constructible shape is enough; avoids requiring
140
+ // a live `HTMLFormElement` global (jsdom provides one, node does not).
141
+ input.nodeName === "FORM";
142
+ }
143
+ function buildGetUrl(base, entries) {
144
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : void 0;
145
+ const url = origin ? new URL(base, origin) : new URL(base, "http://localhost");
146
+ for (const [key, value] of entries) {
147
+ url.searchParams.append(key, value);
148
+ }
149
+ if (!origin && !/^https?:\/\//i.test(base)) {
150
+ return `${url.pathname}${url.search}`;
151
+ }
152
+ return url.toString();
153
+ }
154
+ function buildUrlEncodedBody(entries) {
155
+ const params = new URLSearchParams();
156
+ for (const [key, value] of entries) {
157
+ params.append(key, value);
158
+ }
159
+ return params.toString();
160
+ }
161
+ function withControlFields(state, entries, markers) {
162
+ const present = new Set(entries.map(([k]) => k));
163
+ const merged = [...entries];
164
+ const ensure = (key, value) => {
165
+ if (value !== void 0 && !present.has(key)) {
166
+ merged.push([key, value]);
167
+ present.add(key);
168
+ }
169
+ };
170
+ ensure(AUTH_WIRE_FIELDS.pendingAuthId, state.pendingAuthId);
171
+ ensure(AUTH_WIRE_FIELDS.csrf, state.csrfToken);
172
+ for (const [key, value] of markers) {
173
+ ensure(key, value);
174
+ }
175
+ return merged;
176
+ }
177
+ function finishMarkers(state) {
178
+ switch (state.slot) {
179
+ case "consent":
180
+ return [[AUTH_WIRE_FIELDS.consentSubmitted, CONSENT_SUBMITTED_VALUE]];
181
+ default:
182
+ return [];
183
+ }
184
+ }
185
+ async function dispatch(method, url, entries) {
186
+ if (typeof fetch !== "function") {
187
+ throw new Error("[auth-ui] global fetch is unavailable in this environment");
188
+ }
189
+ if (method === "GET") {
190
+ return fetch(buildGetUrl(url, entries), {
191
+ method: "GET",
192
+ credentials: "same-origin",
193
+ headers: { Accept: "application/json, text/html" }
194
+ });
195
+ }
196
+ return fetch(url, {
197
+ method: "POST",
198
+ credentials: "same-origin",
199
+ headers: {
200
+ "Content-Type": "application/x-www-form-urlencoded",
201
+ Accept: "application/json, text/html"
202
+ },
203
+ body: buildUrlEncodedBody(entries)
204
+ });
205
+ }
206
+ var defaultNavigator = (url) => {
207
+ if (typeof window !== "undefined" && window.location) {
208
+ window.location.assign(url);
209
+ }
210
+ };
211
+ var currentNavigator = defaultNavigator;
212
+ function setAuthNavigator(navigator) {
213
+ currentNavigator = navigator ?? defaultNavigator;
214
+ }
215
+ async function submitFinish(formOrData, options = {}) {
216
+ const state = options.state ?? getAuthFlow();
217
+ if (!state.submitUrl) {
218
+ throw new Error("[auth-ui] submitFinish called but the injected flow state has no submitUrl");
219
+ }
220
+ const method = state.submitMethod ?? DEFAULT_SUBMIT_METHOD;
221
+ const entries = withControlFields(state, toEntries(formOrData), finishMarkers(state));
222
+ const response = await dispatch(method, state.submitUrl, entries);
223
+ const shouldNavigate = options.navigate ?? (typeof window !== "undefined" && !!window.location);
224
+ if (shouldNavigate && response.redirected && response.url) {
225
+ currentNavigator(response.url);
226
+ }
227
+ return response;
228
+ }
229
+ async function submitExtra(name, data, state) {
230
+ const flow = state ?? getAuthFlow();
231
+ const target = flow.extraUrl ?? flow.submitUrl;
232
+ if (!target) {
233
+ throw new Error("[auth-ui] submitExtra called but the injected flow state has no extraUrl/submitUrl");
234
+ }
235
+ const markers = flow.extraUrl ? [] : [[AUTH_EXTRA_FIELD, name]];
236
+ const entries = withControlFields(flow, toEntries(data), markers);
237
+ const response = await dispatch("POST", target, entries);
238
+ return parseExtraResponse(response);
239
+ }
240
+ async function parseExtraResponse(response) {
241
+ const contentType = response.headers.get("content-type") ?? "";
242
+ if (contentType.includes("application/json")) {
243
+ try {
244
+ const body = await response.json();
245
+ return {
246
+ ok: body.ok ?? response.ok,
247
+ error: typeof body.error === "string" ? body.error : void 0,
248
+ addedItems: body.addedItems && typeof body.addedItems === "object" ? body.addedItems : void 0,
249
+ sideEffects: body.sideEffects && typeof body.sideEffects === "object" ? body.sideEffects : void 0
250
+ };
251
+ } catch {
252
+ }
253
+ }
254
+ if (response.ok) {
255
+ return { ok: true };
256
+ }
257
+ return { ok: false, error: `Request failed with status ${response.status}` };
258
+ }
259
+
260
+ // libs/ui/src/auth/context.tsx
261
+ var import_react = require("react");
262
+ var AuthFlowContext = (0, import_react.createContext)(null);
263
+ function useAuthFlowContext() {
264
+ const ctx = (0, import_react.useContext)(AuthFlowContext);
265
+ if (!ctx) {
266
+ throw new Error("[auth-ui] useAuthFlow* hooks must be used inside <AuthPageWrapper> / <AuthFlowProvider>");
267
+ }
268
+ return ctx;
269
+ }
270
+
271
+ // libs/ui/src/auth/AuthPageWrapper.tsx
272
+ var import_react2 = require("react");
273
+ var import_jsx_runtime = require("react/jsx-runtime");
274
+ function AuthFlowProvider({
275
+ children,
276
+ state: stateOverride
277
+ }) {
278
+ const injected = stateOverride ?? tryGetAuthFlow();
279
+ const [state, setState] = (0, import_react2.useState)(
280
+ injected ?? { slot: "error", error: "No authorization flow state was provided." }
281
+ );
282
+ const value = (0, import_react2.useMemo)(
283
+ () => ({
284
+ state,
285
+ update: (patch) => setState((prev) => ({ ...prev, ...patch }))
286
+ }),
287
+ [state]
288
+ );
289
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthFlowContext.Provider, { value, children });
290
+ }
291
+ function ControlFields({ state }) {
292
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
293
+ state.pendingAuthId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "hidden", name: AUTH_WIRE_FIELDS.pendingAuthId, value: state.pendingAuthId }),
294
+ state.csrfToken !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "hidden", name: AUTH_WIRE_FIELDS.csrf, value: state.csrfToken }),
295
+ state.slot === "consent" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "hidden", name: AUTH_WIRE_FIELDS.consentSubmitted, value: CONSENT_SUBMITTED_VALUE })
296
+ ] });
297
+ }
298
+ function AuthPageWrapper({
299
+ children,
300
+ state: stateOverride,
301
+ renderForm = true,
302
+ className
303
+ }) {
304
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthFlowProvider, { state: stateOverride, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthPageWrapperInner, { renderForm, className, children }) });
305
+ }
306
+ function AuthPageWrapperInner({
307
+ children,
308
+ renderForm,
309
+ className
310
+ }) {
311
+ const ctx = useAuthFlowContextSafe();
312
+ const state = ctx?.state;
313
+ if (!renderForm || !state?.submitUrl) {
314
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: className ?? "frontmcp-auth-page", children });
315
+ }
316
+ const method = (state.submitMethod ?? DEFAULT_SUBMIT_METHOD).toLowerCase();
317
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: className ?? "frontmcp-auth-page", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { action: state.submitUrl, method, children: [
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ControlFields, { state }),
319
+ children
320
+ ] }) });
321
+ }
322
+ function useAuthFlowContextSafe() {
323
+ return (0, import_react2.useContext)(AuthFlowContext);
324
+ }
325
+
326
+ // libs/ui/src/auth/hooks.ts
327
+ var import_react3 = require("react");
328
+ function normalizeFormArg(arg) {
329
+ if (!arg) {
330
+ return void 0;
331
+ }
332
+ const maybeEvent = arg;
333
+ if (typeof maybeEvent.preventDefault === "function" && maybeEvent.currentTarget) {
334
+ maybeEvent.preventDefault();
335
+ return maybeEvent.currentTarget;
336
+ }
337
+ return arg;
338
+ }
339
+ function useAuthFlow() {
340
+ const { state } = useAuthFlowContext();
341
+ const submitFinish2 = (0, import_react3.useCallback)(
342
+ (formOrEvent) => submitFinish(normalizeFormArg(formOrEvent), { state }),
343
+ [state]
344
+ );
345
+ return {
346
+ slot: state.slot,
347
+ pendingAuthId: state.pendingAuthId,
348
+ clientName: state.clientName,
349
+ clientId: state.clientId,
350
+ scopes: state.scopes ?? [],
351
+ redirectUri: state.redirectUri,
352
+ resource: state.resource,
353
+ error: state.error,
354
+ providers: state.providers ?? [],
355
+ tools: state.tools ?? [],
356
+ extras: state.extras ?? {},
357
+ state,
358
+ submitFinish: submitFinish2
359
+ };
360
+ }
361
+ function useAddedItems(name) {
362
+ const { state } = useAuthFlowContext();
363
+ const items = state.addedItems?.[name];
364
+ return Array.isArray(items) ? items : [];
365
+ }
366
+ function useExtraField(name) {
367
+ const { state, update } = useAuthFlowContext();
368
+ const [result, setResult] = (0, import_react3.useState)(void 0);
369
+ const [pending, setPending] = (0, import_react3.useState)(false);
370
+ const onSubmit = (0, import_react3.useCallback)(
371
+ async (formOrEvent) => {
372
+ const data = normalizeFormArg(formOrEvent);
373
+ setPending(true);
374
+ try {
375
+ const res = await submitExtra(name, data, state);
376
+ setResult(res);
377
+ if (res.ok && res.addedItems) {
378
+ update({ addedItems: res.addedItems });
379
+ }
380
+ return res;
381
+ } catch (err) {
382
+ const failure = {
383
+ ok: false,
384
+ error: err instanceof Error ? err.message : "Failed to submit field"
385
+ };
386
+ setResult(failure);
387
+ return failure;
388
+ } finally {
389
+ setPending(false);
390
+ }
391
+ },
392
+ [name, state, update]
393
+ );
394
+ return { onSubmit, result, pending };
395
+ }
396
+
397
+ // libs/ui/src/auth/hydrate.tsx
398
+ var import_client = require("react-dom/client");
399
+ var import_jsx_runtime2 = require("react/jsx-runtime");
400
+ function resolveContainer(container) {
401
+ if (container && typeof container !== "string") {
402
+ return container;
403
+ }
404
+ if (typeof document === "undefined") {
405
+ throw new Error("[auth-ui] mountAuthPage requires a DOM (document is undefined)");
406
+ }
407
+ const selector = container ?? `#${DEFAULT_AUTH_MOUNT_ID}`;
408
+ const el = document.querySelector(selector);
409
+ if (!el) {
410
+ throw new Error(`[auth-ui] mountAuthPage could not find a container matching "${selector}"`);
411
+ }
412
+ return el;
413
+ }
414
+ function mountAuthPage(Component, options = {}) {
415
+ const container = resolveContainer(options.container);
416
+ const root = (0, import_client.createRoot)(container);
417
+ root.render(
418
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthPageWrapper, { state: options.state, renderForm: options.renderForm, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, {}) })
419
+ );
420
+ return root;
421
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * `@frontmcp/ui/auth/vanilla` — framework-free helpers that read the injected
3
+ * {@link AuthFlowState} global and drive the OAuth flow. No React.
4
+ *
5
+ * These are browser-DOM (client-only) primitives the `/auth` React hooks are
6
+ * built on, and are usable directly from a non-React (or no-framework)
7
+ * authorization page. The framework-free CONTRACT they consume is co-located in
8
+ * `@frontmcp/ui/auth` (`./contract`); these helpers touch
9
+ * `window`/`fetch`/`FormData`, so they are browser-only.
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ import { type AuthExtraResult, type AuthFlowState, type AuthFormInput } from '../contract';
14
+ /**
15
+ * Read the server-injected {@link AuthFlowState}.
16
+ *
17
+ * @throws Error when no flow state has been injected (the page was not rendered
18
+ * by a FrontMCP auth slot, or the injection script did not run yet). Callers
19
+ * that want a tolerant read should use {@link tryGetAuthFlow}.
20
+ */
21
+ export declare function getAuthFlow(): AuthFlowState;
22
+ /**
23
+ * Read the server-injected {@link AuthFlowState}, or `undefined` when it is not
24
+ * present. Does not throw — useful for optional/SSR-safe reads.
25
+ */
26
+ export declare function tryGetAuthFlow(): AuthFlowState | undefined;
27
+ /**
28
+ * Return the server-side accumulator for a named multi-step input (e.g. the
29
+ * `envs` a user has added so far). Empty array when the name is absent.
30
+ */
31
+ export declare function getAddedItems<T = unknown>(name: string): T[];
32
+ /**
33
+ * Options for {@link submitFinish}.
34
+ */
35
+ export interface SubmitFinishOptions {
36
+ /**
37
+ * When true (the default in a real browser), a non-redirected/non-JSON HTML
38
+ * response causes a full navigation to `response.url` (the OAuth code
39
+ * redirect). Set false to suppress navigation and inspect the {@link Response}
40
+ * yourself (used by tests and SPA-style pages).
41
+ */
42
+ navigate?: boolean;
43
+ /**
44
+ * Drive the submit from this explicit flow state instead of reading the
45
+ * injected `window.__FRONTMCP_AUTH__`. Used by the React hooks (which already
46
+ * hold the state via context); standalone callers omit it.
47
+ */
48
+ state?: AuthFlowState;
49
+ }
50
+ /**
51
+ * How {@link submitFinish} performs a top-level navigation to the OAuth
52
+ * redirect. Defaults to `window.location.assign`. Exposed so SPA-style pages
53
+ * (and tests) can override it via {@link setAuthNavigator} without fighting a
54
+ * non-configurable `window.location`.
55
+ */
56
+ export type AuthNavigator = (url: string) => void;
57
+ /**
58
+ * Override the navigation function used to follow the OAuth redirect after a
59
+ * successful {@link submitFinish}. Pass no argument to reset to the default
60
+ * (`window.location.assign`).
61
+ */
62
+ export declare function setAuthNavigator(navigator?: AuthNavigator): void;
63
+ /**
64
+ * Finish the authorization flow: submit identity / selection back to the
65
+ * server's callback (`submitUrl`), carrying `pending_auth_id`, `csrf`, and the
66
+ * slot's marker fields (e.g. `consent_submitted=1` for consent).
67
+ *
68
+ * On success the server responds with the OAuth redirect to the client's
69
+ * `redirect_uri`; in a browser this helper follows it via a full navigation
70
+ * unless {@link SubmitFinishOptions.navigate} is false.
71
+ *
72
+ * @param formOrData The developer's form/fields (identity inputs, selected
73
+ * `tools`/`providers` checkboxes, etc.).
74
+ * @param options Submit options. `options.state` lets a caller (e.g. the React
75
+ * hooks) drive the submit from an explicit flow state instead of re-reading the
76
+ * injected global; when omitted the injected `window.__FRONTMCP_AUTH__` is used.
77
+ * @returns The raw {@link Response} (so callers can branch on a re-rendered
78
+ * error page vs. a redirect).
79
+ */
80
+ export declare function submitFinish(formOrData?: AuthFormInput, options?: SubmitFinishOptions): Promise<Response>;
81
+ /**
82
+ * Submit a single validated extra field (a `@AuthExtra(name)` round-trip).
83
+ *
84
+ * Posts the field data plus `pending_auth_id` + `csrf` to `extraUrl` when the
85
+ * server provided one, otherwise to `submitUrl` with an `action=<name>` field
86
+ * so the server can route it. Always uses POST (extras mutate server state —
87
+ * unlike the GET finish round-trip).
88
+ *
89
+ * @param name The extra's name (must match the server's `@AuthExtra(name)`).
90
+ * @param data The field value(s) to validate/add.
91
+ * @param state Optional explicit flow state (the React hooks pass their context
92
+ * state); when omitted the injected `window.__FRONTMCP_AUTH__` is used.
93
+ * @returns A parsed {@link AuthExtraResult} (`{ ok, error?, addedItems? }`).
94
+ */
95
+ export declare function submitExtra(name: string, data?: AuthFormInput, state?: AuthFlowState): Promise<AuthExtraResult>;
96
+ //# sourceMappingURL=auth-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-flow.d.ts","sourceRoot":"","sources":["../../../src/auth/vanilla/auth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AAgBrB;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,aAAa,CAS3C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,aAAa,GAAG,SAAS,CAO1D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,CAG5D;AAwJD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;AAUlD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAEhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAAC,UAAU,CAAC,EAAE,aAAa,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAenH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAarH"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@frontmcp/ui/auth/vanilla` — framework-free (browser-DOM) flow helpers + the
3
+ * contract.
4
+ *
5
+ * Re-exports the contract (the single source of truth lives in
6
+ * `@frontmcp/ui/auth`) so a non-React page can
7
+ * `import { getAuthFlow, type AuthFlowState } from '@frontmcp/ui/auth/vanilla'`
8
+ * from a single entrypoint.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ export * from '../contract';
13
+ export * from './auth-flow';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/vanilla/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}