@foir/sdk 0.5.0 → 0.8.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 +1126 -0
- package/README.md +94 -0
- package/dist/auth/auth.d.ts +243 -0
- package/dist/auth/hosted.d.ts +40 -0
- package/dist/auth/index.d.ts +21 -0
- package/dist/auth/operations.d.ts +144 -0
- package/dist/auth/ops.d.ts +99 -0
- package/dist/auth/session-client.d.ts +76 -0
- package/dist/auth-session.js +137 -0
- package/dist/auth.js +973 -92
- package/dist/chunk-IGNLWT3H.js +35 -0
- package/dist/chunk-OHYVKTGB.js +45 -0
- package/dist/chunk-TAL5H6VA.js +39 -0
- package/dist/client/platform-client.d.ts +29 -0
- package/dist/client.js +275 -37
- package/dist/codegen/block-registry.d.ts +13 -23
- package/dist/codegen/block-registry.js +3 -31
- package/dist/codegen/block-scaffold.d.ts +12 -25
- package/dist/codegen/block-scaffold.js +3 -41
- package/dist/codegen/index.d.ts +12 -61
- package/dist/codegen/index.js +7 -11
- package/dist/codegen/item-registry.d.ts +28 -0
- package/dist/codegen/item-registry.js +7 -0
- package/dist/codegen/item-scaffold.d.ts +29 -0
- package/dist/codegen/item-scaffold.js +7 -0
- package/dist/codegen/preset.d.ts +67 -0
- package/dist/codegen/shared.d.ts +36 -0
- package/dist/components/EditorProvider.d.ts +36 -0
- package/dist/content/content-renderer.d.ts +113 -0
- package/dist/content/index.d.ts +18 -0
- package/dist/content/richtext.d.ts +118 -0
- package/dist/content.js +227 -80
- package/dist/data/builtins.d.ts +506 -0
- package/dist/data/client.d.ts +166 -0
- package/dist/data/document.d.ts +251 -0
- package/dist/data/index.d.ts +73 -0
- package/dist/data/manifest.d.ts +424 -0
- package/dist/data/schema.d.ts +313 -0
- package/dist/data/selection.d.ts +524 -0
- package/dist/data/subjects.d.ts +221 -0
- package/dist/data/subscription-document.d.ts +75 -0
- package/dist/data/subscriptions.d.ts +181 -0
- package/dist/data/transport.d.ts +325 -0
- package/dist/data/ws-transport.d.ts +197 -0
- package/dist/data.js +1683 -0
- package/dist/graphql/cdn-route.d.ts +26 -0
- package/dist/graphql/client.d.ts +30 -0
- package/dist/graphql/content-client.d.ts +66 -0
- package/dist/graphql/foir-request.d.ts +47 -0
- package/dist/hooks/useAutoResize.d.ts +22 -0
- package/dist/hooks/useEditor.d.ts +16 -0
- package/dist/index.d.ts +10 -394
- package/dist/media/BlurhashCanvas.d.ts +10 -0
- package/dist/media/ProgressiveMedia.d.ts +56 -0
- package/dist/media/index.d.ts +18 -0
- package/dist/media/media.d.ts +139 -0
- package/dist/media/screen-capture.d.ts +81 -0
- package/dist/media/useProgressiveLoad.d.ts +23 -0
- package/dist/media.js +102 -0
- package/dist/next/cookieAdapter.d.ts +26 -0
- package/dist/next/index.d.ts +15 -0
- package/dist/next/middleware.d.ts +49 -0
- package/dist/next/session.d.ts +53 -0
- package/dist/next.js +763 -78
- package/dist/protocol/constants.d.ts +6 -0
- package/dist/protocol/messages.d.ts +155 -0
- package/dist/protocol/validation.d.ts +8 -0
- package/dist/push/index.d.ts +14 -0
- package/dist/push/operations.d.ts +22 -0
- package/dist/push/web-push.d.ts +39 -0
- package/dist/push.js +892 -78
- package/dist/react/FoirFeedback.d.ts +62 -0
- package/dist/react/FoirProvider.d.ts +116 -0
- package/dist/react/OAuthButtons.d.ts +20 -0
- package/dist/react/SignIn.d.ts +22 -0
- package/dist/react/UserButton.d.ts +13 -0
- package/dist/react/feedback-notes.d.ts +101 -0
- package/dist/react/index.d.ts +25 -0
- package/dist/react/localStorageAdapter.d.ts +10 -0
- package/dist/react.js +1373 -91
- package/dist/{realtime.d.ts → realtime/index.d.ts} +35 -16
- package/dist/realtime.js +1 -1
- package/dist/server/callback-client.d.ts +92 -0
- package/dist/server/events-client.d.ts +279 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/operation-types.d.ts +134 -0
- package/dist/server/require-scoped-token.d.ts +76 -0
- package/dist/server/server-client.d.ts +34 -0
- package/dist/server/types.d.ts +54 -0
- package/dist/server/verify-scoped-token.d.ts +100 -0
- package/dist/server/webhook-helpers.d.ts +36 -0
- package/dist/server.js +298 -0
- package/dist/transport/foir-http.d.ts +234 -0
- package/dist/transport/persisted-query.d.ts +68 -0
- package/dist/transport/retry.d.ts +61 -0
- package/dist/types/index.d.ts +124 -0
- package/package.json +35 -13
- package/dist/auth.d.ts +0 -382
- package/dist/chunk-ADO5FJNM.js +0 -30
- package/dist/client.d.ts +0 -135
- package/dist/content.d.ts +0 -96
- package/dist/media.d.ts +0 -234
- package/dist/next.d.ts +0 -178
- package/dist/push.d.ts +0 -109
- package/dist/react.d.ts +0 -319
- package/dist/server.d.ts +0 -534
- package/dist/shared-DkWlEd2Z.d.ts +0 -18
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FoirCustomerNote, FoirSubject, FoirSubjectRegistry } from '../data';
|
|
2
|
+
import { type FoirFeedbackClient } from './feedback-notes';
|
|
3
|
+
export type { FoirFeedbackClient } from './feedback-notes';
|
|
4
|
+
export interface FoirFeedbackProps {
|
|
5
|
+
/**
|
|
6
|
+
* The data client the page reads through — the one you passed the subject
|
|
7
|
+
* registry to. Its `notes` namespace is what a submission goes to, and its
|
|
8
|
+
* `files` namespace is what a screenshot is uploaded through.
|
|
9
|
+
*/
|
|
10
|
+
client: FoirFeedbackClient;
|
|
11
|
+
/**
|
|
12
|
+
* The registry from `createFoirSubjectRegistry()`, the same object you passed
|
|
13
|
+
* to `createFoirClient({ subjects })`.
|
|
14
|
+
*
|
|
15
|
+
* Passed rather than discovered, because the registry is deliberately an
|
|
16
|
+
* object the host owns and not a flag the client turns on — see the registry's
|
|
17
|
+
* own header for why a list of what a page fetched is not the SDK's to hand
|
|
18
|
+
* out. Omit it and the widget has no subject unless you pass one.
|
|
19
|
+
*/
|
|
20
|
+
subjects?: FoirSubjectRegistry;
|
|
21
|
+
/**
|
|
22
|
+
* Pin what the feedback is about, overriding the registry.
|
|
23
|
+
*
|
|
24
|
+
* `null` states there is nothing to comment on, which is a different claim
|
|
25
|
+
* from omitting the prop and worth being able to make: a checkout step or a
|
|
26
|
+
* dashboard renders no record and should say so rather than inherit whatever
|
|
27
|
+
* the previous page fetched.
|
|
28
|
+
*/
|
|
29
|
+
subject?: FoirSubject | null;
|
|
30
|
+
/**
|
|
31
|
+
* What to call the subject on screen, overriding the label the registry
|
|
32
|
+
* resolved. Omit both and the widget shows no name at all.
|
|
33
|
+
*/
|
|
34
|
+
label?: string;
|
|
35
|
+
/** The disclosure button's text. Default `Feedback`. */
|
|
36
|
+
triggerLabel?: string;
|
|
37
|
+
/** The panel's heading. Default `Send feedback`. */
|
|
38
|
+
title?: string;
|
|
39
|
+
/** The composer's placeholder. Default `What would you like to tell us?`. */
|
|
40
|
+
placeholder?: string;
|
|
41
|
+
/** Start with the panel open. Default false. */
|
|
42
|
+
defaultOpen?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Called when the visitor has to sign in first. Given a handler, the widget
|
|
45
|
+
* renders a button that calls it; given none, it says so and stops.
|
|
46
|
+
*/
|
|
47
|
+
onSignIn?: () => void;
|
|
48
|
+
/** Called with the note once it is written. */
|
|
49
|
+
onSubmitted?: (note: FoirCustomerNote) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Called with anything that failed. The widget also logs it — this is for
|
|
52
|
+
* routing it into your own error reporting, not for making it visible.
|
|
53
|
+
*/
|
|
54
|
+
onError?: (error: unknown) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Style it yourself. Passing a class turns OFF the built-in inline styles
|
|
57
|
+
* entirely, so the `data-foir-feedback-*` attributes below are yours to target
|
|
58
|
+
* without fighting anything.
|
|
59
|
+
*/
|
|
60
|
+
className?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function FoirFeedback({ client, subjects, subject, label, triggerLabel, title, placeholder, defaultOpen, onSignIn, onSubmitted, onError, className, }: FoirFeedbackProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { AuthProviderPublic, FoirCustomer, FoirSessionConfig, SessionAdapter } from '../auth';
|
|
3
|
+
import type { ProviderCallbackInput, ProviderLoginInput } from '../auth';
|
|
4
|
+
import type { FoirEnv } from '../graphql/foir-request';
|
|
5
|
+
/** Where the session hydration stands. */
|
|
6
|
+
export type FoirStatus = 'loading' | 'authenticated' | 'unauthenticated';
|
|
7
|
+
/** The full context value. Read it through the hooks below, not directly. */
|
|
8
|
+
export interface FoirContextValue {
|
|
9
|
+
status: FoirStatus;
|
|
10
|
+
customer: FoirCustomer | null;
|
|
11
|
+
/** The API config; exposed so advanced consumers can call `@foir/sdk/auth` directly. */
|
|
12
|
+
env: FoirEnv;
|
|
13
|
+
/** The session store backing this provider. */
|
|
14
|
+
adapter: SessionAdapter;
|
|
15
|
+
signIn(vars: {
|
|
16
|
+
email: string;
|
|
17
|
+
password: string;
|
|
18
|
+
}): Promise<FoirCustomer>;
|
|
19
|
+
register(vars: {
|
|
20
|
+
email: string;
|
|
21
|
+
password: string;
|
|
22
|
+
}): Promise<FoirCustomer>;
|
|
23
|
+
requestOtp(email: string): Promise<boolean>;
|
|
24
|
+
signInWithOtp(vars: {
|
|
25
|
+
email: string;
|
|
26
|
+
otp: string;
|
|
27
|
+
}): Promise<FoirCustomer>;
|
|
28
|
+
/** Start a provider (OAuth/OIDC) login. Redirect providers navigate away. */
|
|
29
|
+
signInWithProvider(providerKey: string, opts?: Omit<ProviderLoginInput, 'providerKey'>): Promise<void>;
|
|
30
|
+
/** Complete a provider login from your callback route (code + state). */
|
|
31
|
+
completeProviderLogin(input: Omit<ProviderCallbackInput, 'providerKey'> & {
|
|
32
|
+
providerKey: string;
|
|
33
|
+
}): Promise<FoirCustomer>;
|
|
34
|
+
signOut(): Promise<void>;
|
|
35
|
+
/** Rotate the access token; returns false (and signs out) if it can't. */
|
|
36
|
+
refresh(): Promise<boolean>;
|
|
37
|
+
/** The current access token, or null when signed out. */
|
|
38
|
+
getToken(): Promise<string | null>;
|
|
39
|
+
/** The project's configured auth providers (for OAuth buttons). */
|
|
40
|
+
getProviders(): Promise<AuthProviderPublic[]>;
|
|
41
|
+
/**
|
|
42
|
+
* In `hostedSession` mode, where to send the browser to sign in — sign-in is a
|
|
43
|
+
* redirect to your Foir login domain, not an in-page form. Null in token mode,
|
|
44
|
+
* where you call {@link FoirContextValue.signIn} instead.
|
|
45
|
+
*/
|
|
46
|
+
hostedSignInUrl: ((returnTo?: string) => string) | null;
|
|
47
|
+
}
|
|
48
|
+
export interface FoirProviderProps {
|
|
49
|
+
/** API config: `{ PLATFORM_API_URL, PLATFORM_API_KEY }` (a publishable `pk_` key). */
|
|
50
|
+
env: FoirEnv;
|
|
51
|
+
/** Session store for token mode. Defaults to a browser localStorage adapter. */
|
|
52
|
+
adapter?: SessionAdapter;
|
|
53
|
+
/**
|
|
54
|
+
* Opt into Foir-hosted first-party sessions: the durable credential is an
|
|
55
|
+
* HttpOnly cookie on your own domain and the access token lives only in
|
|
56
|
+
* memory, so nothing authentication-related is reachable from JS. This is the
|
|
57
|
+
* secure default for a backend-less SPA, and it REPLACES `adapter` — pass one
|
|
58
|
+
* or the other, not both.
|
|
59
|
+
*
|
|
60
|
+
* Requires a verified custom login domain sharing a registrable domain with
|
|
61
|
+
* your app (`app.acme.com` + `login.acme.com`). Sign-in becomes a redirect to
|
|
62
|
+
* {@link FoirContextValue.hostedSignInUrl}; the password/OTP/provider actions
|
|
63
|
+
* do not apply and will throw.
|
|
64
|
+
*/
|
|
65
|
+
hostedSession?: Omit<FoirSessionConfig, 'onSignOut'>;
|
|
66
|
+
children: ReactNode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Provides Foir customer auth to a React tree. Hydrates the session on mount,
|
|
70
|
+
* then exposes the current customer and sign-in/out actions through
|
|
71
|
+
* {@link useFoirSession}, {@link useFoirUser}, and {@link useFoirAuth}.
|
|
72
|
+
*
|
|
73
|
+
* Two session models:
|
|
74
|
+
*
|
|
75
|
+
* default tokens in a `SessionAdapter` (localStorage unless you pass
|
|
76
|
+
* your own). Simple, but a refresh token sits in JS.
|
|
77
|
+
* `hostedSession` Foir-hosted first-party cookie; the bearer never leaves
|
|
78
|
+
* memory. Needs a custom login domain. Prefer this.
|
|
79
|
+
*/
|
|
80
|
+
export declare function FoirProvider({ env, adapter, hostedSession, children, }: FoirProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
81
|
+
/** The current session state. */
|
|
82
|
+
export interface FoirSession {
|
|
83
|
+
status: FoirStatus;
|
|
84
|
+
customer: FoirCustomer | null;
|
|
85
|
+
isLoading: boolean;
|
|
86
|
+
isAuthenticated: boolean;
|
|
87
|
+
}
|
|
88
|
+
/** Read the current session status and customer. */
|
|
89
|
+
export declare function useFoirSession(): FoirSession;
|
|
90
|
+
/** The signed-in customer (`{ id, email }`), or null. */
|
|
91
|
+
export declare function useFoirUser(): FoirCustomer | null;
|
|
92
|
+
/** The sign-in / sign-out actions. */
|
|
93
|
+
export declare function useFoirAuth(): {
|
|
94
|
+
signIn: (vars: {
|
|
95
|
+
email: string;
|
|
96
|
+
password: string;
|
|
97
|
+
}) => Promise<FoirCustomer>;
|
|
98
|
+
register: (vars: {
|
|
99
|
+
email: string;
|
|
100
|
+
password: string;
|
|
101
|
+
}) => Promise<FoirCustomer>;
|
|
102
|
+
requestOtp: (email: string) => Promise<boolean>;
|
|
103
|
+
signInWithOtp: (vars: {
|
|
104
|
+
email: string;
|
|
105
|
+
otp: string;
|
|
106
|
+
}) => Promise<FoirCustomer>;
|
|
107
|
+
signInWithProvider: (providerKey: string, opts?: Omit<ProviderLoginInput, "providerKey">) => Promise<void>;
|
|
108
|
+
completeProviderLogin: (input: Omit<ProviderCallbackInput, "providerKey"> & {
|
|
109
|
+
providerKey: string;
|
|
110
|
+
}) => Promise<FoirCustomer>;
|
|
111
|
+
signOut: () => Promise<void>;
|
|
112
|
+
refresh: () => Promise<boolean>;
|
|
113
|
+
getToken: () => Promise<string | null>;
|
|
114
|
+
getProviders: () => Promise<AuthProviderPublic[]>;
|
|
115
|
+
hostedSignInUrl: ((returnTo?: string) => string) | null;
|
|
116
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { AuthProviderPublic } from '../auth';
|
|
3
|
+
export interface OAuthButtonsProps {
|
|
4
|
+
/** Passed to the provider login (where the callback returns the user). */
|
|
5
|
+
returnTo?: string;
|
|
6
|
+
/** Override the provider's default redirect URI (must be allow-listed). */
|
|
7
|
+
redirectUri?: string;
|
|
8
|
+
/** Filter which providers render (defaults to every redirect-capable one). */
|
|
9
|
+
filter?(provider: AuthProviderPublic): boolean;
|
|
10
|
+
/** Render your own button. Receives the provider and a click handler. */
|
|
11
|
+
children?(provider: AuthProviderPublic, signIn: () => void): ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
onError?(error: unknown): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Renders a sign-in button per configured OAuth/OIDC/SAML provider. Clicking a
|
|
17
|
+
* button starts the provider login and (for redirect flows) navigates away.
|
|
18
|
+
* Pass a `children` render prop to fully control the button markup.
|
|
19
|
+
*/
|
|
20
|
+
export declare function OAuthButtons({ returnTo, redirectUri, filter, children, className, onError, }: OAuthButtonsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FoirCustomer } from '../auth';
|
|
2
|
+
export interface SignInProps {
|
|
3
|
+
/** `password` (default) or `otp` (email one-time code). Ignored when `hostedUrl` is set. */
|
|
4
|
+
method?: 'password' | 'otp';
|
|
5
|
+
/** Render a single button that redirects to a hosted login page instead of an embedded form. */
|
|
6
|
+
hostedUrl?: string;
|
|
7
|
+
/** Show OAuth provider buttons below the form. Default true. */
|
|
8
|
+
oauth?: boolean;
|
|
9
|
+
/** Navigate here after a successful sign-in. */
|
|
10
|
+
afterSignInUrl?: string;
|
|
11
|
+
/** Called with the customer on a successful sign-in (before any redirect). */
|
|
12
|
+
onSignIn?(customer: FoirCustomer): void;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A drop-in customer sign-in. Renders an email/password (or OTP) form and,
|
|
17
|
+
* unless disabled, OAuth provider buttons. Set `hostedUrl` to instead render a
|
|
18
|
+
* button that redirects to a hosted login page. All state is handled through
|
|
19
|
+
* {@link FoirProvider}; on success it calls `onSignIn` and optionally navigates
|
|
20
|
+
* to `afterSignInUrl`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function SignIn({ method, hostedUrl, oauth, afterSignInUrl, onSignIn, className, }: SignInProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UserButtonProps {
|
|
2
|
+
/** Called after a successful sign-out. */
|
|
3
|
+
afterSignOut?(): void;
|
|
4
|
+
/** Navigate here after sign-out. */
|
|
5
|
+
afterSignOutUrl?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A minimal signed-in affordance: the customer's email plus a sign-out button.
|
|
10
|
+
* Renders nothing when signed out. Style it via `className` (the default is an
|
|
11
|
+
* unopinionated inline layout).
|
|
12
|
+
*/
|
|
13
|
+
export declare function UserButton({ afterSignOut, afterSignOutUrl, className }: UserButtonProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The non-visual half of `<FoirFeedback>`: reading the notes surface, uploading
|
|
3
|
+
* an attachment, and telling one refusal from another.
|
|
4
|
+
*
|
|
5
|
+
* Separate from the component because none of it is React. A namespace op
|
|
6
|
+
* answers `unknown` — the manifest publishes root field NAMES and no result
|
|
7
|
+
* shape (see `data/selection.ts`) — so every response here has to be read rather
|
|
8
|
+
* than cast, and reading is the part worth testing on its own.
|
|
9
|
+
*/
|
|
10
|
+
import type { FoirCustomerNote, FoirNoteConfig, FoirSubject } from '../data';
|
|
11
|
+
import type { FoirScreenCapture } from '../media/screen-capture';
|
|
12
|
+
/**
|
|
13
|
+
* The client the widget needs, and no more of it.
|
|
14
|
+
*
|
|
15
|
+
* Structural rather than `FoirClient<S>`, for two reasons. `FoirClient` is
|
|
16
|
+
* generic in the caller's generated schema, so naming it here would force the
|
|
17
|
+
* component's props to be generic in a parameter nothing else reads. And what
|
|
18
|
+
* the widget actually depends on is three root fields — narrowing to them means
|
|
19
|
+
* a client whose key cannot reach `files` still satisfies this type, which is
|
|
20
|
+
* the honest shape: a project with screenshots off never uploads anything.
|
|
21
|
+
*
|
|
22
|
+
* The signatures are the ones `foir types` emits for every namespace op —
|
|
23
|
+
* `Record<string, unknown>` in, `unknown` out — so a real generated client
|
|
24
|
+
* assigns to this without a cast. `react/__tests__/feedback.test-d.ts` pins that.
|
|
25
|
+
*/
|
|
26
|
+
export interface FoirFeedbackClient {
|
|
27
|
+
readonly ns: {
|
|
28
|
+
readonly notes: {
|
|
29
|
+
noteConfig(args?: Record<string, unknown>): Promise<unknown>;
|
|
30
|
+
createMyNote(args?: Record<string, unknown>): Promise<unknown>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Absent on a credential without the files scopes, which is why it is
|
|
34
|
+
* optional. Screenshot capture is the only thing that reaches it.
|
|
35
|
+
*/
|
|
36
|
+
readonly files?: {
|
|
37
|
+
createFileUpload(args?: Record<string, unknown>): Promise<unknown>;
|
|
38
|
+
confirmFileUpload(args?: Record<string, unknown>): Promise<unknown>;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Why a call to the notes surface was refused, when the refusal is one the
|
|
44
|
+
* widget can name.
|
|
45
|
+
*
|
|
46
|
+
* The distinction earns its place because the three have different audiences.
|
|
47
|
+
* `signIn` is the visitor's to fix. `scope` is the OPERATOR's — a role that does
|
|
48
|
+
* not grant `notes:write` produces `missing required scope: notes:write`, which
|
|
49
|
+
* reads like a bad API key and is not one; the key is fine and the customer's
|
|
50
|
+
* role is short a capability. `other` is everything the widget will not pretend
|
|
51
|
+
* to understand.
|
|
52
|
+
*/
|
|
53
|
+
export type FoirFeedbackFault = {
|
|
54
|
+
kind: 'signIn';
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'scope';
|
|
57
|
+
scope: string;
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'other';
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Read the refusal, if it is one of the two the widget can act on.
|
|
63
|
+
*
|
|
64
|
+
* Matched on the platform's own sentences rather than on an error code, because
|
|
65
|
+
* these two arrive as plain GraphQL errors with no `extensions.code` to read.
|
|
66
|
+
* Both the wrapper's message and every individual GraphQL error are scanned: the
|
|
67
|
+
* transport joins them into one string on the way out, but a partial-error
|
|
68
|
+
* envelope keeps them apart, and only one of the two forms is guaranteed.
|
|
69
|
+
*/
|
|
70
|
+
export declare function classifyNotesFault(err: unknown): FoirFeedbackFault;
|
|
71
|
+
/**
|
|
72
|
+
* `noteConfig`, read.
|
|
73
|
+
*
|
|
74
|
+
* Throws on a shape it does not recognise rather than defaulting
|
|
75
|
+
* `screenshotsEnabled` to false. Defaulting would be the quiet version of a
|
|
76
|
+
* project's setting being ignored: the offer would disappear from every surface
|
|
77
|
+
* at once and the only symptom would be a missing button.
|
|
78
|
+
*/
|
|
79
|
+
export declare function readNoteConfig(client: FoirFeedbackClient): Promise<FoirNoteConfig>;
|
|
80
|
+
/** What one submission carries. */
|
|
81
|
+
export interface FoirFeedbackSubmission {
|
|
82
|
+
/**
|
|
83
|
+
* What the note is about. Always a RECORD subject: the registry only ever
|
|
84
|
+
* names records, and a host pinning one names a record too.
|
|
85
|
+
*/
|
|
86
|
+
subject: FoirSubject;
|
|
87
|
+
body: string;
|
|
88
|
+
/** The still the visitor chose to attach, or null. */
|
|
89
|
+
screenshot: FoirScreenCapture | null;
|
|
90
|
+
/** Injectable for the presigned PUT. Defaults to `globalThis.fetch`. */
|
|
91
|
+
fetch?: typeof globalThis.fetch;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Upload the attachment (if there is one), then write the note.
|
|
95
|
+
*
|
|
96
|
+
* In that order, and with the upload failing the whole submission rather than
|
|
97
|
+
* being skipped. A note that arrived without the picture the visitor attached is
|
|
98
|
+
* worse than one that did not arrive: they have no way to tell, and the thing
|
|
99
|
+
* they wrote ("as you can see in the screenshot") stops making sense.
|
|
100
|
+
*/
|
|
101
|
+
export declare function submitFeedbackNote(client: FoirFeedbackClient, submission: FoirFeedbackSubmission): Promise<FoirCustomerNote>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@foir/sdk/react` — drop-in React components for Foir customers.
|
|
3
|
+
*
|
|
4
|
+
* Wrap your app in `<FoirProvider>`, then read the session with
|
|
5
|
+
* `useFoirSession` / `useFoirUser` and drive it with `useFoirAuth` — or drop in
|
|
6
|
+
* the `<SignIn>`, `<OAuthButtons>`, and `<UserButton>` components. Built entirely
|
|
7
|
+
* on `@foir/sdk/auth`; `react` is the only peer dependency.
|
|
8
|
+
*
|
|
9
|
+
* `<FoirFeedback>` is the annotation half: a feedback widget that anchors to the
|
|
10
|
+
* RECORD the page was rendered from rather than to its URL. It takes the data
|
|
11
|
+
* client from `@foir/sdk/data` and the subject registry you built for it.
|
|
12
|
+
*/
|
|
13
|
+
export { FoirProvider, useFoirSession, useFoirUser, useFoirAuth, } from './FoirProvider';
|
|
14
|
+
export type { FoirProviderProps, FoirContextValue, FoirSession, FoirStatus, } from './FoirProvider';
|
|
15
|
+
export { SignIn } from './SignIn';
|
|
16
|
+
export type { SignInProps } from './SignIn';
|
|
17
|
+
export { OAuthButtons } from './OAuthButtons';
|
|
18
|
+
export type { OAuthButtonsProps } from './OAuthButtons';
|
|
19
|
+
export { UserButton } from './UserButton';
|
|
20
|
+
export type { UserButtonProps } from './UserButton';
|
|
21
|
+
export { FoirFeedback } from './FoirFeedback';
|
|
22
|
+
export type { FoirFeedbackProps, FoirFeedbackClient } from './FoirFeedback';
|
|
23
|
+
export { createLocalStorageAdapter } from './localStorageAdapter';
|
|
24
|
+
export type { FoirCustomer, SessionAdapter, AuthProviderPublic } from '../auth';
|
|
25
|
+
export type { FoirEnv } from '../graphql/foir-request';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SessionAdapter } from '../auth';
|
|
2
|
+
/**
|
|
3
|
+
* A {@link SessionAdapter} backed by the browser's `localStorage`.
|
|
4
|
+
*
|
|
5
|
+
* SSR-safe: with no `window` (server render) reads return `null` and writes are
|
|
6
|
+
* no-ops, so {@link FoirProvider} starts in `loading` and hydrates the real
|
|
7
|
+
* session on the client after mount. This is the default adapter when you don't
|
|
8
|
+
* pass one to `FoirProvider`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createLocalStorageAdapter(): SessionAdapter;
|