@foir/sdk 0.4.0 → 0.7.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 (82) hide show
  1. package/CHANGELOG.md +325 -0
  2. package/README.md +63 -0
  3. package/dist/auth/auth.d.ts +140 -0
  4. package/dist/auth/hosted.d.ts +40 -0
  5. package/dist/auth/index.d.ts +15 -0
  6. package/dist/auth/operations.d.ts +123 -0
  7. package/dist/auth/session-client.d.ts +76 -0
  8. package/dist/auth-session.js +137 -0
  9. package/dist/auth.js +238 -26
  10. package/dist/client/platform-client.d.ts +29 -0
  11. package/dist/client.js +290 -32
  12. package/dist/codegen/block-registry.d.ts +4 -8
  13. package/dist/codegen/block-scaffold.d.ts +4 -8
  14. package/dist/codegen/index.d.ts +8 -62
  15. package/dist/codegen/preset.d.ts +60 -0
  16. package/dist/codegen/shared.d.ts +25 -0
  17. package/dist/components/EditorProvider.d.ts +36 -0
  18. package/dist/content/content-renderer.d.ts +47 -0
  19. package/dist/content/index.d.ts +12 -0
  20. package/dist/content/richtext.d.ts +70 -0
  21. package/dist/data/builtins.d.ts +296 -0
  22. package/dist/data/client.d.ts +94 -0
  23. package/dist/data/index.d.ts +54 -0
  24. package/dist/data/manifest.d.ts +161 -0
  25. package/dist/data/schema.d.ts +243 -0
  26. package/dist/data/selection.d.ts +330 -0
  27. package/dist/data/transport.d.ts +107 -0
  28. package/dist/data.js +309 -0
  29. package/dist/graphql/cdn-route.d.ts +42 -0
  30. package/dist/graphql/client.d.ts +30 -0
  31. package/dist/graphql/content-client.d.ts +66 -0
  32. package/dist/graphql/foir-request.d.ts +47 -0
  33. package/dist/hooks/useAutoResize.d.ts +22 -0
  34. package/dist/hooks/useEditor.d.ts +16 -0
  35. package/dist/index.d.ts +10 -394
  36. package/dist/media/BlurhashCanvas.d.ts +10 -0
  37. package/dist/media/ProgressiveMedia.d.ts +56 -0
  38. package/dist/media/index.d.ts +14 -0
  39. package/dist/media/media.d.ts +139 -0
  40. package/dist/media/useProgressiveLoad.d.ts +23 -0
  41. package/dist/media.js +5 -0
  42. package/dist/next/cookieAdapter.d.ts +26 -0
  43. package/dist/next/index.d.ts +15 -0
  44. package/dist/next/middleware.d.ts +49 -0
  45. package/dist/next/session.d.ts +53 -0
  46. package/dist/next.js +230 -26
  47. package/dist/protocol/constants.d.ts +6 -0
  48. package/dist/protocol/messages.d.ts +155 -0
  49. package/dist/protocol/validation.d.ts +8 -0
  50. package/dist/push/index.d.ts +14 -0
  51. package/dist/push/operations.d.ts +22 -0
  52. package/dist/push/web-push.d.ts +39 -0
  53. package/dist/push.js +230 -26
  54. package/dist/react/FoirProvider.d.ts +116 -0
  55. package/dist/react/OAuthButtons.d.ts +20 -0
  56. package/dist/react/SignIn.d.ts +22 -0
  57. package/dist/react/UserButton.d.ts +13 -0
  58. package/dist/react/index.d.ts +19 -0
  59. package/dist/react/localStorageAdapter.d.ts +10 -0
  60. package/dist/react.js +230 -26
  61. package/dist/{realtime.d.ts → realtime/index.d.ts} +35 -16
  62. package/dist/server/callback-client.d.ts +92 -0
  63. package/dist/server/index.d.ts +8 -0
  64. package/dist/server/operation-types.d.ts +134 -0
  65. package/dist/server/require-scoped-token.d.ts +76 -0
  66. package/dist/server/server-client.d.ts +34 -0
  67. package/dist/server/types.d.ts +54 -0
  68. package/dist/server/verify-scoped-token.d.ts +100 -0
  69. package/dist/server/webhook-helpers.d.ts +36 -0
  70. package/dist/transport/foir-http.d.ts +217 -0
  71. package/dist/transport/retry.d.ts +61 -0
  72. package/dist/types/index.d.ts +124 -0
  73. package/package.json +23 -13
  74. package/dist/auth.d.ts +0 -382
  75. package/dist/client.d.ts +0 -83
  76. package/dist/content.d.ts +0 -96
  77. package/dist/media.d.ts +0 -234
  78. package/dist/next.d.ts +0 -178
  79. package/dist/push.d.ts +0 -109
  80. package/dist/react.d.ts +0 -319
  81. package/dist/server.d.ts +0 -534
  82. package/dist/shared-DkWlEd2Z.d.ts +0 -18
package/dist/content.d.ts DELETED
@@ -1,96 +0,0 @@
1
- import { ReactNode, JSX } from 'react';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
-
4
- /**
5
- * createContentRenderer — the generic content-dispatch primitive.
6
- *
7
- * It does NOT know any concrete block types. Given a registry that maps each
8
- * block `__typename` to a component, it renders a `flexible` field's block
9
- * array: looks each block up by `__typename`, renders unknown types as null,
10
- * keys by the block `_id`, assigns LCP `priority` to the first block that
11
- * actually renders, and threads a consumer-defined `Ctx` to every component.
12
- *
13
- * The "switch" is a typed object lookup. Exhaustiveness is enforced where the
14
- * registry is BUILT — against the exhaustive `BlockRegistry` type the codegen
15
- * plugin (EID-92) generates per project, so omitting a block type is a compile
16
- * error there, not a runtime surprise here. The consumer can supply different
17
- * registries per surface (e.g. web vs email).
18
- */
19
-
20
- /** Minimal shape every block in a `flexible` field carries. */
21
- interface BlockLike {
22
- __typename: string;
23
- _id?: string | null;
24
- }
25
- /** Props a block component receives from the content renderer. */
26
- interface BlockComponentProps<TBlock, TCtx = unknown> {
27
- block: TBlock;
28
- /** Consumer-defined render context (host product, locale, etc.). */
29
- ctx: TCtx;
30
- /** True only for the first block that renders — the LCP candidate. */
31
- priority: boolean;
32
- }
33
- /** A component that renders one block type. */
34
- type BlockComponent<TBlock, TCtx = unknown> = (props: BlockComponentProps<TBlock, TCtx>) => ReactNode;
35
- /**
36
- * A registry mapping `__typename` → block component. In practice this is the
37
- * exhaustive `BlockRegistry` type the codegen plugin emits for the project;
38
- * here it's the structural lower bound the renderer needs.
39
- */
40
- type BlockRegistry<TCtx = unknown> = Record<string, BlockComponent<any, TCtx>>;
41
- interface ContentRendererProps<TCtx> {
42
- blocks: readonly BlockLike[] | null | undefined;
43
- /** Consumer-defined context passed to every block component. */
44
- ctx: TCtx;
45
- }
46
- /**
47
- * Build a `<ContentRenderer>` bound to a block registry. Returns a component
48
- * that takes the `flexible` field's `blocks` array plus a `ctx`.
49
- */
50
- declare function createContentRenderer<TCtx = unknown>(registry: BlockRegistry<TCtx>): (props: ContentRendererProps<TCtx>) => ReactNode;
51
-
52
- /** A resolved typography token from the project's design tokens. */
53
- interface TypographyToken {
54
- /** Token key referenced by a Lexical node's `style`. */
55
- name: string;
56
- /** Rendered HTML element (paragraph / h1–h6 / blockquote). */
57
- tag?: string;
58
- value: {
59
- fontFamily: string[];
60
- fontSize: string | number;
61
- fontWeight: string | number;
62
- lineHeight: string | number;
63
- letterSpacing: string | number;
64
- textTransform?: string;
65
- };
66
- }
67
- /**
68
- * Provide the project's resolved typography tokens to every nested
69
- * `<RichTextRenderer>` so callers don't thread them through each usage. A
70
- * `tokens` prop on the renderer still takes precedence.
71
- */
72
- declare function RichTextTypographyProvider({ tokens, children, }: {
73
- tokens: TypographyToken[];
74
- children: ReactNode;
75
- }): react_jsx_runtime.JSX.Element;
76
- /** Read the injected typography tokens (null when no provider is mounted). */
77
- declare function useRichTextTypography(): TypographyToken[] | null;
78
- interface RichtextValueLike {
79
- html?: string | null;
80
- json?: unknown;
81
- }
82
- interface RichTextRendererProps {
83
- value: RichtextValueLike | null | undefined;
84
- className?: string;
85
- /**
86
- * Resolved typography tokens. Overrides any provided via
87
- * `<RichTextTypographyProvider>`. When neither is set, paragraphs render
88
- * with `fallbackTag` and no inline typography.
89
- */
90
- tokens?: TypographyToken[];
91
- /** Tag used for any paragraph with no token style and no Lexical tag. */
92
- fallbackTag?: keyof JSX.IntrinsicElements;
93
- }
94
- declare function RichTextRenderer({ value, className, tokens, fallbackTag, }: RichTextRendererProps): react_jsx_runtime.JSX.Element | null;
95
-
96
- export { type BlockComponent, type BlockComponentProps, type BlockLike, type BlockRegistry, type ContentRendererProps, RichTextRenderer, type RichTextRendererProps, RichTextTypographyProvider, type TypographyToken, createContentRenderer, useRichTextTypography };
package/dist/media.d.ts DELETED
@@ -1,234 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
-
3
- /**
4
- * Foir media types + adapters.
5
- *
6
- * Framework-agnostic plumbing for rendering Foir image/video fields with
7
- * `<ProgressiveMedia>`: the canonical source shapes, GraphQL-value → source
8
- * adapters (crop normalization, per-format variant sets, HLS URL
9
- * absolutising), and crop-aware dimension maths for CLS-free layout.
10
- *
11
- * HLS manifest URLs are absolutised via the shared `absolutiseFoirMediaUrl`
12
- * from the client transport — not re-implemented here.
13
- */
14
- /** One rendered tier: a URL + its TRUE (crop-aware) dims (for srcset `w` + CLS). */
15
- interface VariantTier {
16
- url: string;
17
- width?: number | null;
18
- height?: number | null;
19
- }
20
- /** Curated tier set in one format (Foir `ImageVariantSet`). */
21
- interface VariantSet {
22
- thumbnail?: VariantTier | null;
23
- small?: VariantTier | null;
24
- medium?: VariantTier | null;
25
- large?: VariantTier | null;
26
- xlarge?: VariantTier | null;
27
- _2xl?: VariantTier | null;
28
- _3xl?: VariantTier | null;
29
- _4xl?: VariantTier | null;
30
- }
31
- /** A `VariantSet` tier name. */
32
- type VariantTierKey = keyof VariantSet;
33
- /**
34
- * Default tier order, smallest→largest, for walking a `VariantSet`
35
- * deterministically when building a `srcset`. Override per `<ProgressiveMedia>`
36
- * via the `variantTiers` prop when a project curates a different tier set.
37
- */
38
- declare const DEFAULT_VARIANT_TIERS: readonly VariantTierKey[];
39
- /** Image source with progressive loading data. */
40
- interface ProgressiveImageSource {
41
- url: string;
42
- alt?: string;
43
- width?: number;
44
- height?: number;
45
- blurhash?: string;
46
- dominantColor?: string;
47
- thumbnailUrl?: string;
48
- /** Per-format tier sets (WebP universal; AVIF preferred via `<picture>`). */
49
- webp?: VariantSet | null;
50
- avif?: VariantSet | null;
51
- /**
52
- * Optional crop rectangle expressed as percentages of the source image
53
- * (`{x, y, width, height}` in 0–100). Foir's image pipeline serves the
54
- * cropped file at the cropped dimensions, so consumers need this to compute
55
- * correct `width`/`height` attrs for CLS-free rendering.
56
- */
57
- crop?: {
58
- x?: number;
59
- y?: number;
60
- width?: number;
61
- height?: number;
62
- };
63
- }
64
- /** Video source with progressive loading data + optional HLS. */
65
- interface ProgressiveVideoSource {
66
- url: string;
67
- width?: number;
68
- height?: number;
69
- blurhash?: string;
70
- dominantColor?: string;
71
- thumbnailUrl?: string;
72
- previewUrl?: string;
73
- hlsUrl?: string;
74
- duration?: number;
75
- }
76
- /**
77
- * Foir GraphQL `ImageValue`-like input — the shape a consumer's codegen
78
- * produces for an image field (intrinsic dims + per-format variant sets +
79
- * crop as opaque JSON). Structurally compatible with the generated type.
80
- */
81
- interface FoirImageInput {
82
- url?: string | null;
83
- alt?: string | null;
84
- width?: number | null;
85
- height?: number | null;
86
- blurhash?: string | null;
87
- dominantColor?: string | null;
88
- webp?: VariantSet | null;
89
- avif?: VariantSet | null;
90
- crop?: {
91
- [key: string]: unknown;
92
- } | null;
93
- }
94
- /** Foir GraphQL `VideoValue`-like input. */
95
- interface FoirVideoInput {
96
- url?: string | null;
97
- width?: number | null;
98
- height?: number | null;
99
- hlsManifestUrl?: string | null;
100
- thumbnailUrl?: string | null;
101
- previewUrl?: string | null;
102
- blurhash?: string | null;
103
- dominantColor?: string | null;
104
- }
105
- /**
106
- * Adapt a Foir image field to the `ProgressiveImageSource` consumed by
107
- * `<ProgressiveMedia>`. Returns `undefined` when the field is empty (the
108
- * caller falls back to a placeholder). Narrows the JSON-typed `crop` to the
109
- * numeric keys; out-of-range values are filtered in `effectiveImageDimensions`.
110
- */
111
- declare function toProgressiveImage(img: FoirImageInput | null | undefined): ProgressiveImageSource | undefined;
112
- /**
113
- * Adapt a Foir video field to the `ProgressiveVideoSource` consumed by
114
- * `<ProgressiveMedia>`. Absolutises the HLS manifest URL (Foir returns it
115
- * relative to its media proxy). Returns `undefined` when the field is empty.
116
- */
117
- declare function toProgressiveVideo(v: FoirVideoInput | null | undefined): ProgressiveVideoSource | undefined;
118
- /**
119
- * Resolve the dimensions of the file Foir's pipeline will actually serve,
120
- * applying any crop percentages to the source's intrinsic size. Returns null
121
- * when the source has no width/height. Drives both the wrapper aspect-ratio
122
- * and the `<img>` `width`/`height` attrs.
123
- */
124
- declare function effectiveImageDimensions(image: {
125
- width?: number | null;
126
- height?: number | null;
127
- crop?: unknown;
128
- } | null | undefined): {
129
- width: number;
130
- height: number;
131
- } | null;
132
- /**
133
- * Compute a CSS `aspect-ratio` string from a Foir image's natural dimensions
134
- * and optional crop. When a usable crop is set the cropped rectangle's aspect
135
- * wins; otherwise the intrinsic width/height; otherwise `null`.
136
- */
137
- declare function cropAspectRatio(image: {
138
- width?: number | null;
139
- height?: number | null;
140
- crop?: unknown;
141
- } | null | undefined): string | null;
142
-
143
- interface ProgressiveMediaProps {
144
- image?: ProgressiveImageSource;
145
- video?: ProgressiveVideoSource;
146
- alt?: string;
147
- className?: string;
148
- /** Fill the parent container instead of using intrinsic aspect ratio. */
149
- fill?: boolean;
150
- /**
151
- * Object-fit for fill mode. Defaults to 'cover'. Has no effect when `fill`
152
- * is false (the image renders at its intrinsic aspect ratio).
153
- */
154
- fit?: 'cover' | 'contain';
155
- /**
156
- * Solid-colour placeholder mode. When neither image nor video is provided,
157
- * render a flat coloured div. `aspectRatio` defaults to 16/10.
158
- */
159
- placeholder?: {
160
- color: string;
161
- aspectRatio?: number;
162
- };
163
- /** Video playback — autoplay on mount. Default true. */
164
- autoplay?: boolean;
165
- /** Video playback — muted. Default true (required for autoplay). */
166
- muted?: boolean;
167
- /** Video playback — loop on end. Default true. */
168
- loop?: boolean;
169
- /**
170
- * When false, skip loading the full media layer (no `<video>`/full `<img>`
171
- * mount, no HLS attach, no full-image preload). The lower layers — colour,
172
- * blurhash, thumbnail — still render. Used by responsive dual-render so the
173
- * CSS-hidden branch doesn't download its full asset. Default true.
174
- */
175
- active?: boolean;
176
- /**
177
- * `sizes` attribute applied to the full `<img>` — tells the browser how
178
- * wide the image renders so it can pick the right `srcset` entry. Default
179
- * `"100vw"`. Has no effect on video sources.
180
- */
181
- sizes?: string;
182
- /**
183
- * When true, treat this media as the page's LCP candidate: thumbnail and
184
- * full `<img>` get `fetchpriority="high"` + `loading="eager"`, and any
185
- * `<video>` mounts immediately. When false (default) below-fold behaviour:
186
- * `loading="lazy"` on `<img>`, and `<video>` is gated by an
187
- * IntersectionObserver so its `src`/HLS only attaches near the viewport.
188
- */
189
- priority?: boolean;
190
- /**
191
- * Tier order, smallest→largest, used to build the `srcset` from a
192
- * `VariantSet`. Defaults to {@link DEFAULT_VARIANT_TIERS}; override when a
193
- * project curates a different tier set.
194
- */
195
- variantTiers?: readonly VariantTierKey[];
196
- }
197
- declare function ProgressiveMedia({ image, video, alt, className, fill, fit, placeholder, autoplay, muted, loop, active, sizes, priority, variantTiers, }: ProgressiveMediaProps): react_jsx_runtime.JSX.Element | null;
198
-
199
- interface BlurhashCanvasProps {
200
- hash: string;
201
- className?: string;
202
- }
203
- /**
204
- * Decodes a BlurHash string to a 32×32 canvas. `blurhash` is an optional peer
205
- * dependency loaded via dynamic import — if it isn't installed the canvas
206
- * stays blank rather than throwing.
207
- */
208
- declare function BlurhashCanvas({ hash, className }: BlurhashCanvasProps): react_jsx_runtime.JSX.Element;
209
-
210
- type LoadStage = 'color' | 'blurhash' | 'thumbnail' | 'full';
211
- interface UseProgressiveLoadOptions {
212
- blurhash?: string;
213
- thumbnailUrl?: string;
214
- fullUrl?: string;
215
- /**
216
- * Optional srcset + sizes — when provided to image sources, the preloader
217
- * matches the variant the visible `<img>` will pick, so the browser dedupes
218
- * the fetch instead of downloading two sizes.
219
- */
220
- fullSrcSet?: string;
221
- fullSizes?: string;
222
- isVideo?: boolean;
223
- }
224
- /**
225
- * State machine for progressive media loading.
226
- * Stages advance forward only: color → blurhash → thumbnail → full.
227
- * Skips stages when data is missing. Never regresses.
228
- */
229
- declare function useProgressiveLoad({ blurhash, thumbnailUrl, fullUrl, fullSrcSet, fullSizes, isVideo, }: UseProgressiveLoadOptions): {
230
- stage: LoadStage;
231
- onFullReady: () => void;
232
- };
233
-
234
- export { BlurhashCanvas, type BlurhashCanvasProps, DEFAULT_VARIANT_TIERS, type FoirImageInput, type FoirVideoInput, type LoadStage, type ProgressiveImageSource, ProgressiveMedia, type ProgressiveMediaProps, type ProgressiveVideoSource, type UseProgressiveLoadOptions, type VariantSet, type VariantTier, type VariantTierKey, cropAspectRatio, effectiveImageDimensions, toProgressiveImage, toProgressiveVideo, useProgressiveLoad };
package/dist/next.d.ts DELETED
@@ -1,178 +0,0 @@
1
- /**
2
- * Foir GraphQL client — a single typed fetch wrapper for SSR/edge loaders.
3
- *
4
- * No GraphQL client (Apollo/urql) required: the Foir public API is a plain
5
- * `POST` with an `x-api-key` header, and the dominant consumers (Hydrogen on
6
- * Oxygen, React Router loaders, TanStack Start on CF Workers) fetch in
7
- * server-only loaders and render — so Apollo's `InMemoryCache`/`useQuery`
8
- * reactivity is dead weight, and a shared cache on a stateless multi-tenant
9
- * edge worker is a cross-tenant hazard. This helper carries only the
10
- * Foir-specific transport concerns (auth header, preview schema channel,
11
- * error shape). Consumers on a GraphQL client (Apollo / urql / react-query /
12
- * graphql-request) use the generated `TypedDocumentNode`s directly with their
13
- * own client and replicate the two Foir-specific headers below — the
14
- * `x-api-key` and, in preview, `X-Foir-Schema-Channel: draft`.
15
- *
16
- * Deduplicates the hand-copied `lib/foir/client.ts` that shipped identically
17
- * across the Foir storefronts.
18
- */
19
-
20
- interface FoirEnv {
21
- PLATFORM_API_URL?: string;
22
- PLATFORM_API_KEY?: string;
23
- PLATFORM_PREVIEW_API_KEY?: string;
24
- FOIR_PREVIEW?: string;
25
- }
26
-
27
- /**
28
- * Foir customer auth — framework-agnostic flows, token lifecycle, and guards.
29
- *
30
- * Session I/O is injected via {@link SessionAdapter} (no Hydrogen/React-Router
31
- * coupling). Pre-login flows authenticate with the project `x-api-key`;
32
- * post-login reads add the customer bearer. The project-specific profile (e.g.
33
- * `isAdmin`) is resolved by a consumer-supplied `resolveUser` — the SDK never
34
- * hardcodes the per-project customer profile shape.
35
- */
36
-
37
- /** The customer identity carried by an auth result. */
38
- interface FoirCustomer {
39
- id: string;
40
- email: string;
41
- }
42
- /**
43
- * Injected session store. Methods may be sync or async so consumers can plug
44
- * in a cookie session (Hydrogen/Remix), a KV store, etc.
45
- */
46
- interface SessionAdapter {
47
- get(key: string): string | null | undefined | Promise<string | null | undefined>;
48
- set(key: string, value: string): void | Promise<void>;
49
- unset(key: string): void | Promise<void>;
50
- }
51
-
52
- /**
53
- * The minimal cookie-store shape this adapter needs. It's satisfied by Next's
54
- * `cookies()` (route handlers / server actions — `await cookies()` on Next 15),
55
- * and by `NextResponse.cookies` in middleware. Kept structural on purpose so the
56
- * SDK doesn't import (or pin a version of) `next/headers`.
57
- */
58
- interface FoirCookieStore {
59
- get(name: string): {
60
- value: string;
61
- } | undefined;
62
- set(name: string, value: string, options?: Record<string, unknown>): void;
63
- delete(name: string): void;
64
- }
65
- interface CookieAdapterOptions {
66
- /** Cookie attributes for writes, merged over the secure defaults. */
67
- cookieOptions?: Record<string, unknown>;
68
- }
69
- declare function foirCookieName(key: string): string;
70
- /**
71
- * A {@link SessionAdapter} backed by an HttpOnly cookie store — the seam for
72
- * server-side (BFF) Foir sessions in Next.js. Pass the cookie store from a route
73
- * handler / server action (`await cookies()`) for reads and writes; a Server
74
- * Component's `cookies()` is read-only, so use it only for reads there.
75
- */
76
- declare function createFoirCookieAdapter(store: FoirCookieStore, opts?: CookieAdapterOptions): SessionAdapter;
77
-
78
- /**
79
- * Server-side session helpers for the Next.js BFF pattern. Each takes the Next
80
- * cookie store (`await cookies()` in a route handler / server action, or the
81
- * read-only `cookies()` in a Server Component for reads).
82
- *
83
- * Note on "verification": the customer access token is opaque to your app and
84
- * validated by the Foir API on use, so `getFoirSession` returns the identity
85
- * stored in the cookies rather than locally verifying a JWT. A rejected/expired
86
- * bearer surfaces when you call the API (and `@foir/sdk/auth`'s `authedRequest`
87
- * transparently refreshes it).
88
- */
89
- /** The signed-in customer from the session cookies, or null. */
90
- declare function getFoirSession(store: FoirCookieStore): Promise<FoirCustomer | null>;
91
- /** The current access token from the session cookies, or null. */
92
- declare function getFoirToken(store: FoirCookieStore): Promise<string | null>;
93
- /** Clear the session cookies (sign out). */
94
- declare function foirSignOut(store: FoirCookieStore, opts?: CookieAdapterOptions): Promise<void>;
95
- interface PasswordArgs {
96
- env: FoirEnv;
97
- store: FoirCookieStore;
98
- email: string;
99
- password: string;
100
- cookieOptions?: CookieAdapterOptions['cookieOptions'];
101
- }
102
- /** Password sign-in in a route handler; persists the session to cookies. */
103
- declare function foirSignInWithPassword({ env, store, email, password, cookieOptions, }: PasswordArgs): Promise<FoirCustomer>;
104
- /** Register a customer in a route handler; persists the session to cookies. */
105
- declare function foirRegisterWithPassword({ env, store, email, password, cookieOptions, }: PasswordArgs): Promise<FoirCustomer>;
106
- /** Complete an OTP sign-in in a route handler; persists the session to cookies. */
107
- declare function foirSignInWithOtp({ env, store, email, otp, cookieOptions, }: {
108
- env: FoirEnv;
109
- store: FoirCookieStore;
110
- email: string;
111
- otp: string;
112
- cookieOptions?: CookieAdapterOptions['cookieOptions'];
113
- }): Promise<FoirCustomer>;
114
- /**
115
- * Complete a provider (OAuth/OIDC) login in your callback route handler:
116
- * exchange the `code` + `state` for tokens and persist them to the session
117
- * cookies. Returns the customer.
118
- */
119
- declare function completeFoirProviderLogin(opts: {
120
- env: FoirEnv;
121
- store: FoirCookieStore;
122
- providerKey: string;
123
- code?: string;
124
- state?: string;
125
- cookieOptions?: CookieAdapterOptions['cookieOptions'];
126
- }): Promise<FoirCustomer>;
127
-
128
- /**
129
- * The slice of `NextRequest` the middleware reads. Typed structurally so the SDK
130
- * doesn't need `next` installed to build — a real `NextRequest` satisfies it, so
131
- * the returned function drops straight into `export const middleware`.
132
- */
133
- interface FoirMiddlewareRequest {
134
- cookies: {
135
- get(name: string): {
136
- value: string;
137
- } | undefined;
138
- };
139
- nextUrl: {
140
- pathname: string;
141
- search: string;
142
- };
143
- url: string;
144
- }
145
- interface FoirMiddlewareConfig {
146
- /** Where to send unauthenticated requests (path or absolute URL). */
147
- signInUrl: string;
148
- /**
149
- * The session cookie whose presence means "signed in". Defaults to the
150
- * access-token cookie the cookie adapter writes (`foir_token`).
151
- */
152
- cookieName?: string;
153
- /**
154
- * Return true for requests that require auth. Omit to protect every request
155
- * the middleware `matcher` passes through.
156
- */
157
- isProtected?(request: FoirMiddlewareRequest): boolean;
158
- /** Query param carrying the original path on the sign-in URL. Default `returnTo`. */
159
- returnParam?: string;
160
- }
161
- /**
162
- * Build a Next.js middleware that redirects unauthenticated requests to your
163
- * sign-in URL. Edge-safe: it checks for the presence of the session cookie only
164
- * — the bearer itself is validated server-side when you call the Foir API — so
165
- * pair it with a real `getFoirSession` check in protected route handlers /
166
- * server components. Returns a standard `Response` (redirect) or `undefined`
167
- * (continue), both of which Next.js middleware accepts.
168
- *
169
- * ```ts
170
- * // middleware.ts
171
- * import { createFoirMiddleware } from '@foir/sdk/next';
172
- * export const middleware = createFoirMiddleware({ signInUrl: '/sign-in' });
173
- * export const config = { matcher: ['/dashboard/:path*'] };
174
- * ```
175
- */
176
- declare function createFoirMiddleware(config: FoirMiddlewareConfig): (request: FoirMiddlewareRequest) => Response | undefined;
177
-
178
- export { type CookieAdapterOptions, type FoirCookieStore, type FoirCustomer, type FoirEnv, type FoirMiddlewareConfig, type FoirMiddlewareRequest, type SessionAdapter, completeFoirProviderLogin, createFoirCookieAdapter, createFoirMiddleware, foirCookieName, foirRegisterWithPassword, foirSignInWithOtp, foirSignInWithPassword, foirSignOut, getFoirSession, getFoirToken };
package/dist/push.d.ts DELETED
@@ -1,109 +0,0 @@
1
- import { TypedDocumentNode } from '@graphql-typed-document-node/core';
2
-
3
- /**
4
- * Foir GraphQL client — a single typed fetch wrapper for SSR/edge loaders.
5
- *
6
- * No GraphQL client (Apollo/urql) required: the Foir public API is a plain
7
- * `POST` with an `x-api-key` header, and the dominant consumers (Hydrogen on
8
- * Oxygen, React Router loaders, TanStack Start on CF Workers) fetch in
9
- * server-only loaders and render — so Apollo's `InMemoryCache`/`useQuery`
10
- * reactivity is dead weight, and a shared cache on a stateless multi-tenant
11
- * edge worker is a cross-tenant hazard. This helper carries only the
12
- * Foir-specific transport concerns (auth header, preview schema channel,
13
- * error shape). Consumers on a GraphQL client (Apollo / urql / react-query /
14
- * graphql-request) use the generated `TypedDocumentNode`s directly with their
15
- * own client and replicate the two Foir-specific headers below — the
16
- * `x-api-key` and, in preview, `X-Foir-Schema-Channel: draft`.
17
- *
18
- * Deduplicates the hand-copied `lib/foir/client.ts` that shipped identically
19
- * across the Foir storefronts.
20
- */
21
-
22
- interface FoirEnv {
23
- PLATFORM_API_URL?: string;
24
- PLATFORM_API_KEY?: string;
25
- PLATFORM_PREVIEW_API_KEY?: string;
26
- FOIR_PREVIEW?: string;
27
- }
28
-
29
- /**
30
- * Foir customer auth — framework-agnostic flows, token lifecycle, and guards.
31
- *
32
- * Session I/O is injected via {@link SessionAdapter} (no Hydrogen/React-Router
33
- * coupling). Pre-login flows authenticate with the project `x-api-key`;
34
- * post-login reads add the customer bearer. The project-specific profile (e.g.
35
- * `isAdmin`) is resolved by a consumer-supplied `resolveUser` — the SDK never
36
- * hardcodes the per-project customer profile shape.
37
- */
38
-
39
- /**
40
- * Injected session store. Methods may be sync or async so consumers can plug
41
- * in a cookie session (Hydrogen/Remix), a KV store, etc.
42
- */
43
- interface SessionAdapter {
44
- get(key: string): string | null | undefined | Promise<string | null | undefined>;
45
- set(key: string, value: string): void | Promise<void>;
46
- unset(key: string): void | Promise<void>;
47
- }
48
-
49
- interface EnableWebPushOptions {
50
- adapter: SessionAdapter;
51
- env: FoirEnv;
52
- /** Path the service worker is served from (must be same-origin). Default `/foir-sw.js`. */
53
- swPath?: string;
54
- /** Service-worker registration scope. Default `/`. */
55
- scope?: string;
56
- /** Optional label stored alongside the device token. */
57
- deviceName?: string;
58
- }
59
- type EnableWebPushResult = {
60
- ok: true;
61
- subscription: PushSubscription;
62
- } | {
63
- ok: false;
64
- reason: 'unsupported' | 'denied' | 'no-config';
65
- };
66
- interface DisableWebPushOptions {
67
- adapter: SessionAdapter;
68
- env: FoirEnv;
69
- /** Scope the service worker was registered with. Default `/`. */
70
- scope?: string;
71
- }
72
- /** True when the current browser supports the Web Push APIs this helper needs. */
73
- declare function isWebPushSupported(): boolean;
74
- /**
75
- * Subscribe the current browser to Foir Web Push and register the subscription
76
- * as a `WEB` device token. Idempotent: reuses an existing subscription when one
77
- * is already present. Returns `{ ok: false }` (never throws) when the browser
78
- * is unsupported or the user declines permission.
79
- */
80
- declare function enableWebPush(opts: EnableWebPushOptions): Promise<EnableWebPushResult>;
81
- /**
82
- * Unsubscribe the current browser from Web Push and deregister the device
83
- * token. Returns `false` when there was no active subscription to remove.
84
- */
85
- declare function disableWebPush(opts: DisableWebPushOptions): Promise<boolean>;
86
-
87
- /** The project's non-secret VAPID public key a browser subscribes with. */
88
- declare const WebPushConfigDocument: TypedDocumentNode<{
89
- webPushConfig: {
90
- vapidPublicKey: string;
91
- } | null;
92
- }, Record<string, never>>;
93
- interface RegisterDeviceTokenInput {
94
- token: string;
95
- platform: 'IOS' | 'ANDROID' | 'WEB';
96
- deviceName?: string;
97
- }
98
- declare const RegisterDeviceTokenDocument: TypedDocumentNode<{
99
- registerDeviceToken: boolean;
100
- }, {
101
- input: RegisterDeviceTokenInput;
102
- }>;
103
- declare const UnregisterDeviceTokenDocument: TypedDocumentNode<{
104
- unregisterDeviceToken: boolean;
105
- }, {
106
- token: string;
107
- }>;
108
-
109
- export { type DisableWebPushOptions, type EnableWebPushOptions, type EnableWebPushResult, RegisterDeviceTokenDocument, type RegisterDeviceTokenInput, UnregisterDeviceTokenDocument, WebPushConfigDocument, disableWebPush, enableWebPush, isWebPushSupported };