@foir/sdk 0.5.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.
- package/CHANGELOG.md +325 -0
- package/README.md +63 -0
- package/dist/auth/auth.d.ts +140 -0
- package/dist/auth/hosted.d.ts +40 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/operations.d.ts +123 -0
- package/dist/auth/session-client.d.ts +76 -0
- package/dist/auth-session.js +137 -0
- package/dist/auth.js +238 -26
- package/dist/client/platform-client.d.ts +29 -0
- package/dist/client.js +281 -37
- package/dist/codegen/block-registry.d.ts +4 -8
- package/dist/codegen/block-scaffold.d.ts +4 -8
- package/dist/codegen/index.d.ts +8 -62
- package/dist/codegen/preset.d.ts +60 -0
- package/dist/codegen/shared.d.ts +25 -0
- package/dist/components/EditorProvider.d.ts +36 -0
- package/dist/content/content-renderer.d.ts +47 -0
- package/dist/content/index.d.ts +12 -0
- package/dist/content/richtext.d.ts +70 -0
- package/dist/data/builtins.d.ts +296 -0
- package/dist/data/client.d.ts +94 -0
- package/dist/data/index.d.ts +54 -0
- package/dist/data/manifest.d.ts +161 -0
- package/dist/data/schema.d.ts +243 -0
- package/dist/data/selection.d.ts +330 -0
- package/dist/data/transport.d.ts +107 -0
- package/dist/data.js +309 -0
- package/dist/graphql/cdn-route.d.ts +42 -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 +14 -0
- package/dist/media/media.d.ts +139 -0
- package/dist/media/useProgressiveLoad.d.ts +23 -0
- package/dist/media.js +5 -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 +230 -26
- 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 +230 -26
- 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/index.d.ts +19 -0
- package/dist/react/localStorageAdapter.d.ts +10 -0
- package/dist/react.js +230 -26
- package/dist/{realtime.d.ts → realtime/index.d.ts} +35 -16
- package/dist/server/callback-client.d.ts +92 -0
- package/dist/server/index.d.ts +8 -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/transport/foir-http.d.ts +217 -0
- package/dist/transport/retry.d.ts +61 -0
- package/dist/types/index.d.ts +124 -0
- package/package.json +23 -13
- package/dist/auth.d.ts +0 -382
- 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
package/dist/client.d.ts
DELETED
|
@@ -1,135 +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
|
-
* Returns true when `FOIR_PREVIEW=true` is set in the environment.
|
|
30
|
-
*
|
|
31
|
-
* Preview is selected at the environment level, not per-request: load a
|
|
32
|
-
* preview env file that sets `FOIR_PREVIEW=true` + a `sk_…`
|
|
33
|
-
* `PLATFORM_PREVIEW_API_KEY` with `drafts:read` instead of the default env.
|
|
34
|
-
* The site-wide mode keeps draft semantics consistent — every loader sees
|
|
35
|
-
* the same preview/published view of the world. Intended for non-production
|
|
36
|
-
* surfaces only.
|
|
37
|
-
*/
|
|
38
|
-
declare function isFoirPreview(env: FoirEnv): boolean;
|
|
39
|
-
/** Default Foir CDN origin used to absolutise relative media URLs. */
|
|
40
|
-
declare const FOIR_CDN_BASE = "https://cdn.foir.dev/";
|
|
41
|
-
/**
|
|
42
|
-
* Foir returns `hlsManifestUrl` as a relative path while every other media
|
|
43
|
-
* URL is absolute. Prefix relative paths with the CDN host so the browser
|
|
44
|
-
* doesn't request them from the consumer's own origin. Already-absolute URLs
|
|
45
|
-
* pass through untouched. `cdnBase` is overridable for non-default CDN hosts.
|
|
46
|
-
*/
|
|
47
|
-
declare function absolutiseFoirMediaUrl(url: string | null | undefined, cdnBase?: string): string | undefined;
|
|
48
|
-
interface FoirGraphQLErrorItem {
|
|
49
|
-
message: string;
|
|
50
|
-
path?: Array<string | number>;
|
|
51
|
-
}
|
|
52
|
-
declare class FoirRequestError extends Error {
|
|
53
|
-
/** HTTP status code, when the request failed at the HTTP layer. */
|
|
54
|
-
readonly status?: number;
|
|
55
|
-
/** GraphQL errors, when the request failed with a no-data error envelope. */
|
|
56
|
-
readonly graphQLErrors?: ReadonlyArray<FoirGraphQLErrorItem>;
|
|
57
|
-
readonly cause?: unknown;
|
|
58
|
-
constructor(message: string, options?: {
|
|
59
|
-
cause?: unknown;
|
|
60
|
-
status?: number;
|
|
61
|
-
graphQLErrors?: ReadonlyArray<FoirGraphQLErrorItem>;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Execute a typed GraphQL document against the Foir platform.
|
|
66
|
-
*
|
|
67
|
-
* Throws `FoirRequestError` on HTTP failure or GraphQL errors so the caller
|
|
68
|
-
* can decide whether to rethrow or fall back to local defaults. GraphQL can
|
|
69
|
-
* return partial data alongside errors; when data is present the errors are
|
|
70
|
-
* logged and the data returned (callers handle nulls), and we only throw when
|
|
71
|
-
* there's no data at all.
|
|
72
|
-
*/
|
|
73
|
-
interface FoirRequestOptions {
|
|
74
|
-
/**
|
|
75
|
-
* Customer bearer token. api-public still needs the `x-api-key` to resolve
|
|
76
|
-
* the project; the bearer adds the customer identity for self-scoped reads
|
|
77
|
-
* (e.g. `myProfile`). Used by `@foir/sdk/auth`'s post-login profile fetch.
|
|
78
|
-
*/
|
|
79
|
-
bearerToken?: string;
|
|
80
|
-
}
|
|
81
|
-
declare function foirRequest<TData, TVariables>(env: FoirEnv, document: TypedDocumentNode<TData, TVariables>, variables?: TVariables, options?: FoirRequestOptions): Promise<TData>;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Session-bound content client — forwards the customer bearer on every read
|
|
85
|
-
* when one is available, so auth/segment-targeted variants and customer-scoped
|
|
86
|
-
* records resolve out of the box, with no per-query wiring to forget.
|
|
87
|
-
*
|
|
88
|
-
* Resolution keys off the request's principal (see the platform's two-gate
|
|
89
|
-
* model): the `x-api-key` alone resolves the *anonymous baseline*
|
|
90
|
-
* (`context.authStatus = ""`); adding the customer bearer resolves the request
|
|
91
|
-
* as that customer (`context.authStatus = "authenticated"`, `customer_id` set).
|
|
92
|
-
*
|
|
93
|
-
* Caching: an api-key-only read is identical for every anonymous visitor and is
|
|
94
|
-
* shared-cacheable; a bearer-bearing read resolves per-customer and is not.
|
|
95
|
-
* Because the bearer only exists once a customer signs in, anonymous traffic
|
|
96
|
-
* keeps hitting the shared-cacheable baseline — only signed-in reads become
|
|
97
|
-
* per-customer. Bind this client wherever content is personalized (for most
|
|
98
|
-
* apps, everywhere the customer may be signed in) and use plain `foirRequest`
|
|
99
|
-
* for reads that must stay anonymous regardless of session.
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Supplies the current customer bearer. Sync or async so consumers can read a
|
|
104
|
-
* cookie session (Hydrogen/Remix), a KV store, an in-memory value, etc. Returns
|
|
105
|
-
* the token when signed in, or `null`/`undefined` when signed out.
|
|
106
|
-
*/
|
|
107
|
-
type FoirTokenProvider = () => string | null | undefined | Promise<string | null | undefined>;
|
|
108
|
-
interface FoirContentClientConfig {
|
|
109
|
-
env: FoirEnv;
|
|
110
|
-
/**
|
|
111
|
-
* Resolves the current customer bearer before every request. When it yields a
|
|
112
|
-
* token the token is forwarded, so `authStatus`/segment targeting and
|
|
113
|
-
* customer-scoped records resolve as that customer; when it yields
|
|
114
|
-
* null/undefined the read hits the anonymous baseline. Omit for a client that
|
|
115
|
-
* is always anonymous (equivalent to calling `foirRequest` directly).
|
|
116
|
-
*/
|
|
117
|
-
getToken?: FoirTokenProvider;
|
|
118
|
-
}
|
|
119
|
-
interface FoirContentClient {
|
|
120
|
-
/**
|
|
121
|
-
* Run a typed document, forwarding the bound customer bearer when available.
|
|
122
|
-
* An explicit `options.bearerToken` still wins, so a single call can override
|
|
123
|
-
* the bound token (or force anonymous by passing `undefined` — the bound
|
|
124
|
-
* token only fills in when `options.bearerToken` is not supplied).
|
|
125
|
-
*/
|
|
126
|
-
request<TData, TVariables>(document: TypedDocumentNode<TData, TVariables>, variables?: TVariables, options?: FoirRequestOptions): Promise<TData>;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Create a {@link FoirContentClient} bound to an env + token source. Every
|
|
130
|
-
* `request` forwards the customer bearer when `getToken` yields one, upgrading
|
|
131
|
-
* that read from the anonymous baseline to the signed-in customer.
|
|
132
|
-
*/
|
|
133
|
-
declare function createFoirContentClient(config: FoirContentClientConfig): FoirContentClient;
|
|
134
|
-
|
|
135
|
-
export { FOIR_CDN_BASE, type FoirContentClient, type FoirContentClientConfig, type FoirEnv, FoirRequestError, type FoirRequestOptions, type FoirTokenProvider, absolutiseFoirMediaUrl, createFoirContentClient, foirRequest, isFoirPreview };
|
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 };
|