@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.
Files changed (107) hide show
  1. package/CHANGELOG.md +1126 -0
  2. package/README.md +94 -0
  3. package/dist/auth/auth.d.ts +243 -0
  4. package/dist/auth/hosted.d.ts +40 -0
  5. package/dist/auth/index.d.ts +21 -0
  6. package/dist/auth/operations.d.ts +144 -0
  7. package/dist/auth/ops.d.ts +99 -0
  8. package/dist/auth/session-client.d.ts +76 -0
  9. package/dist/auth-session.js +137 -0
  10. package/dist/auth.js +973 -92
  11. package/dist/chunk-IGNLWT3H.js +35 -0
  12. package/dist/chunk-OHYVKTGB.js +45 -0
  13. package/dist/chunk-TAL5H6VA.js +39 -0
  14. package/dist/client/platform-client.d.ts +29 -0
  15. package/dist/client.js +275 -37
  16. package/dist/codegen/block-registry.d.ts +13 -23
  17. package/dist/codegen/block-registry.js +3 -31
  18. package/dist/codegen/block-scaffold.d.ts +12 -25
  19. package/dist/codegen/block-scaffold.js +3 -41
  20. package/dist/codegen/index.d.ts +12 -61
  21. package/dist/codegen/index.js +7 -11
  22. package/dist/codegen/item-registry.d.ts +28 -0
  23. package/dist/codegen/item-registry.js +7 -0
  24. package/dist/codegen/item-scaffold.d.ts +29 -0
  25. package/dist/codegen/item-scaffold.js +7 -0
  26. package/dist/codegen/preset.d.ts +67 -0
  27. package/dist/codegen/shared.d.ts +36 -0
  28. package/dist/components/EditorProvider.d.ts +36 -0
  29. package/dist/content/content-renderer.d.ts +113 -0
  30. package/dist/content/index.d.ts +18 -0
  31. package/dist/content/richtext.d.ts +118 -0
  32. package/dist/content.js +227 -80
  33. package/dist/data/builtins.d.ts +506 -0
  34. package/dist/data/client.d.ts +166 -0
  35. package/dist/data/document.d.ts +251 -0
  36. package/dist/data/index.d.ts +73 -0
  37. package/dist/data/manifest.d.ts +424 -0
  38. package/dist/data/schema.d.ts +313 -0
  39. package/dist/data/selection.d.ts +524 -0
  40. package/dist/data/subjects.d.ts +221 -0
  41. package/dist/data/subscription-document.d.ts +75 -0
  42. package/dist/data/subscriptions.d.ts +181 -0
  43. package/dist/data/transport.d.ts +325 -0
  44. package/dist/data/ws-transport.d.ts +197 -0
  45. package/dist/data.js +1683 -0
  46. package/dist/graphql/cdn-route.d.ts +26 -0
  47. package/dist/graphql/client.d.ts +30 -0
  48. package/dist/graphql/content-client.d.ts +66 -0
  49. package/dist/graphql/foir-request.d.ts +47 -0
  50. package/dist/hooks/useAutoResize.d.ts +22 -0
  51. package/dist/hooks/useEditor.d.ts +16 -0
  52. package/dist/index.d.ts +10 -394
  53. package/dist/media/BlurhashCanvas.d.ts +10 -0
  54. package/dist/media/ProgressiveMedia.d.ts +56 -0
  55. package/dist/media/index.d.ts +18 -0
  56. package/dist/media/media.d.ts +139 -0
  57. package/dist/media/screen-capture.d.ts +81 -0
  58. package/dist/media/useProgressiveLoad.d.ts +23 -0
  59. package/dist/media.js +102 -0
  60. package/dist/next/cookieAdapter.d.ts +26 -0
  61. package/dist/next/index.d.ts +15 -0
  62. package/dist/next/middleware.d.ts +49 -0
  63. package/dist/next/session.d.ts +53 -0
  64. package/dist/next.js +763 -78
  65. package/dist/protocol/constants.d.ts +6 -0
  66. package/dist/protocol/messages.d.ts +155 -0
  67. package/dist/protocol/validation.d.ts +8 -0
  68. package/dist/push/index.d.ts +14 -0
  69. package/dist/push/operations.d.ts +22 -0
  70. package/dist/push/web-push.d.ts +39 -0
  71. package/dist/push.js +892 -78
  72. package/dist/react/FoirFeedback.d.ts +62 -0
  73. package/dist/react/FoirProvider.d.ts +116 -0
  74. package/dist/react/OAuthButtons.d.ts +20 -0
  75. package/dist/react/SignIn.d.ts +22 -0
  76. package/dist/react/UserButton.d.ts +13 -0
  77. package/dist/react/feedback-notes.d.ts +101 -0
  78. package/dist/react/index.d.ts +25 -0
  79. package/dist/react/localStorageAdapter.d.ts +10 -0
  80. package/dist/react.js +1373 -91
  81. package/dist/{realtime.d.ts → realtime/index.d.ts} +35 -16
  82. package/dist/realtime.js +1 -1
  83. package/dist/server/callback-client.d.ts +92 -0
  84. package/dist/server/events-client.d.ts +279 -0
  85. package/dist/server/index.d.ts +12 -0
  86. package/dist/server/operation-types.d.ts +134 -0
  87. package/dist/server/require-scoped-token.d.ts +76 -0
  88. package/dist/server/server-client.d.ts +34 -0
  89. package/dist/server/types.d.ts +54 -0
  90. package/dist/server/verify-scoped-token.d.ts +100 -0
  91. package/dist/server/webhook-helpers.d.ts +36 -0
  92. package/dist/server.js +298 -0
  93. package/dist/transport/foir-http.d.ts +234 -0
  94. package/dist/transport/persisted-query.d.ts +68 -0
  95. package/dist/transport/retry.d.ts +61 -0
  96. package/dist/types/index.d.ts +124 -0
  97. package/package.json +35 -13
  98. package/dist/auth.d.ts +0 -382
  99. package/dist/chunk-ADO5FJNM.js +0 -30
  100. package/dist/client.d.ts +0 -135
  101. package/dist/content.d.ts +0 -96
  102. package/dist/media.d.ts +0 -234
  103. package/dist/next.d.ts +0 -178
  104. package/dist/push.d.ts +0 -109
  105. package/dist/react.d.ts +0 -319
  106. package/dist/server.d.ts +0 -534
  107. package/dist/shared-DkWlEd2Z.d.ts +0 -18
@@ -1,65 +1,16 @@
1
- import { CodegenConfig } from '@graphql-codegen/cli';
2
- export { B as BlockPluginConfig } from '../shared-DkWlEd2Z.js';
3
-
4
1
  /**
5
- * `@foir/sdk/codegen` — the Foir graphql-codegen preset.
2
+ * `@foir/sdk/codegen` — Foir graphql-codegen preset + item-registry plugin.
6
3
  *
7
- * `foirCodegen()` returns a complete `@graphql-codegen/client-preset` config so
8
- * a consumer's `codegen.ts` is ~3 lines instead of the ~109 every storefront
9
- * hand-copies. It standardizes the Foir conventions (custom scalars,
10
- * `enumValues: 'keep'`, the `X-Foir-Schema-Channel: draft` introspection header)
11
- * AND wires the block-registry plugin so the exhaustive `BlockRegistry` type is
12
- * regenerated alongside the typed documents.
4
+ * Build-time only. `@graphql-codegen/cli` + `@graphql-codegen/client-preset`
5
+ * are optional peer dependencies (the consumer's devDeps). The item-registry
6
+ * and item-scaffold plugins are wired by the preset and also available at
7
+ * `@foir/sdk/codegen/item-registry` / `@foir/sdk/codegen/item-scaffold`.
13
8
  *
14
- * `foirScaffold()` is the separate one-shot that writes the ContentRenderer
15
- * shell (run once; the dev owns the output).
9
+ * The pre-TTS-1391 paths `@foir/sdk/codegen/block-registry` and
10
+ * `/block-scaffold` still resolve, re-exporting those modules unchanged.
16
11
  */
17
-
18
- interface FoirCodegenOptions {
19
- /** Foir public API GraphQL endpoint. */
20
- apiUrl: string;
21
- /**
22
- * Public (`pk_`) API key. Reads the published schema. Used as the fallback
23
- * when no preview key is set.
24
- */
25
- apiKey?: string;
26
- /**
27
- * Preview (`sk_`) key with `drafts:read`. Reads the DRAFT schema channel so
28
- * freshly pushed (un-promoted) model changes are visible to codegen.
29
- * Strongly preferred — a `pk_` key only sees the published schema.
30
- */
31
- previewKey?: string;
32
- /** Output directory for the generated client types. Default `./app/gql/foir/`. */
33
- outputDir?: string;
34
- /** Operation document glob(s). Default `app/graphql/foir/**\/*.graphql`. */
35
- documents?: string | string[];
36
- /** Block union name(s) for the registry. Default `['Block']`. */
37
- blockUnions?: string[];
38
- /** Generated registry file path. Default `<outputDir>block-registry.ts`. */
39
- registryFile?: string;
40
- /** Extra/override custom scalars merged onto the Foir defaults. */
41
- scalars?: Record<string, unknown>;
42
- }
43
- /**
44
- * Build the continuous Foir codegen config: typed documents + the exhaustive
45
- * block registry. Drop it into `codegen.ts` and run `graphql-codegen`.
46
- */
47
- declare function foirCodegen(options: FoirCodegenOptions): CodegenConfig;
48
- interface FoirScaffoldOptions extends FoirCodegenOptions {
49
- /** Output path for the scaffold. Default `<outputDir>ContentRenderer.tsx`. */
50
- scaffoldFile?: string;
51
- /** Render-context type threaded to every block component. Default `unknown`. */
52
- ctxType?: string;
53
- /** Optional ctx-type import line, e.g. `import type { Ctx } from '~/ctx'`. */
54
- ctxImport?: string;
55
- /** Import path for the generated registry type. Default `./block-registry`. */
56
- registryImport?: string;
57
- }
58
- /**
59
- * Build the one-shot scaffold config — writes a ContentRenderer shell with a
60
- * typed stub per block type. Run once (`graphql-codegen --config scaffold.ts`),
61
- * then own and implement the output.
62
- */
63
- declare function foirScaffold(options: FoirScaffoldOptions): CodegenConfig;
64
-
65
- export { type FoirCodegenOptions, type FoirScaffoldOptions, foirCodegen, foirScaffold };
12
+ export { foirCodegen, foirScaffold } from './preset';
13
+ export type { FoirCodegenOptions, FoirScaffoldOptions } from './preset';
14
+ export type { ItemPluginConfig } from './shared';
15
+ /** @deprecated Renamed to `ItemPluginConfig`. */
16
+ export type { BlockPluginConfig } from './shared';
@@ -1,7 +1,3 @@
1
- import {
2
- DEFAULT_UNIONS
3
- } from "../chunk-ADO5FJNM.js";
4
-
5
1
  // src/codegen/preset.ts
6
2
  var DEFAULT_OUTPUT_DIR = "./app/gql/foir/";
7
3
  var DEFAULT_DOCUMENTS = "app/graphql/foir/**/*.graphql";
@@ -30,8 +26,8 @@ function foirCodegen(options) {
30
26
  const previewKey = options.previewKey ?? options.apiKey;
31
27
  const outputDir = normalizeDir(options.outputDir ?? DEFAULT_OUTPUT_DIR);
32
28
  const documents = options.documents ?? DEFAULT_DOCUMENTS;
33
- const blockUnions = options.blockUnions ?? DEFAULT_UNIONS;
34
- const registryFile = options.registryFile ?? `${outputDir}block-registry.ts`;
29
+ const unions = options.itemUnions ?? options.blockUnions;
30
+ const registryFile = options.registryFile ?? `${outputDir}item-registry.ts`;
35
31
  return {
36
32
  schema: schemaEntry(options.apiUrl, previewKey),
37
33
  documents,
@@ -47,8 +43,8 @@ function foirCodegen(options) {
47
43
  }
48
44
  },
49
45
  [registryFile]: {
50
- plugins: ["@foir/sdk/codegen/block-registry"],
51
- config: { unions: blockUnions }
46
+ plugins: ["@foir/sdk/codegen/item-registry"],
47
+ config: { unions }
52
48
  }
53
49
  }
54
50
  };
@@ -57,15 +53,15 @@ function foirScaffold(options) {
57
53
  const previewKey = options.previewKey ?? options.apiKey;
58
54
  const outputDir = normalizeDir(options.outputDir ?? DEFAULT_OUTPUT_DIR);
59
55
  const scaffoldFile = options.scaffoldFile ?? `${outputDir}ContentRenderer.tsx`;
60
- const blockUnions = options.blockUnions ?? DEFAULT_UNIONS;
56
+ const unions = options.itemUnions ?? options.blockUnions;
61
57
  return {
62
58
  schema: schemaEntry(options.apiUrl, previewKey),
63
59
  ignoreNoDocuments: true,
64
60
  generates: {
65
61
  [scaffoldFile]: {
66
- plugins: ["@foir/sdk/codegen/block-scaffold"],
62
+ plugins: ["@foir/sdk/codegen/item-scaffold"],
67
63
  config: {
68
- unions: blockUnions,
64
+ unions,
69
65
  ctxType: options.ctxType,
70
66
  ctxImport: options.ctxImport,
71
67
  registryImport: options.registryImport
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@foir/sdk/codegen/item-registry` — a graphql-codegen plugin.
3
+ *
4
+ * Introspects the project's public schema, collects every member of the
5
+ * flexible union(s), and emits an EXHAUSTIVE `ItemRegistry` type — one key per
6
+ * item `__typename`, each typed `ItemComponent<ThatItem, Ctx>`. Because the
7
+ * type requires every key, a project that adds an inline model (→ a new item
8
+ * `__typename`) breaks the consumer's build until the new component is wired:
9
+ * exhaustiveness by construction, replacing the hand-synced switch a storefront
10
+ * would otherwise carry.
11
+ *
12
+ * Wired automatically by `foirCodegen()`. The generated file imports the item
13
+ * types from the codegen output (`./graphql`) and `ItemComponent` from
14
+ * `@foir/sdk/content`, so it pairs directly with `createContentRenderer`.
15
+ *
16
+ * Reachable at the pre-TTS-1391 path `@foir/sdk/codegen/block-registry` too,
17
+ * which re-exports this module unchanged.
18
+ */
19
+ import type { GraphQLSchema } from 'graphql';
20
+ import { type ItemPluginConfig } from './shared';
21
+ export interface ItemRegistryConfig extends ItemPluginConfig {
22
+ /** Name of the generated registry type. Default `ItemRegistry`. */
23
+ registryName?: string;
24
+ }
25
+ /** @deprecated Renamed to {@link ItemRegistryConfig}. */
26
+ export type BlockRegistryConfig = ItemRegistryConfig;
27
+ /** graphql-codegen plugin entrypoint. */
28
+ export declare const plugin: (schema: GraphQLSchema, _documents: unknown, config?: ItemRegistryConfig) => string;
@@ -0,0 +1,7 @@
1
+ import {
2
+ plugin
3
+ } from "../chunk-IGNLWT3H.js";
4
+ import "../chunk-TAL5H6VA.js";
5
+ export {
6
+ plugin
7
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `@foir/sdk/codegen/item-scaffold` — a one-shot graphql-codegen plugin.
3
+ *
4
+ * Emits a ContentRenderer shell: a stub component per item `__typename`, an
5
+ * `itemRegistry` of the (exhaustive) `ItemRegistry` type, and a
6
+ * `createContentRenderer` wiring. Unlike the item-registry plugin (which
7
+ * regenerates every run), this is a STARTING POINT the dev then owns — run it
8
+ * once via `foirScaffold()`, then implement each stub. It compiles out of the
9
+ * box (each stub is a typed no-op) so the build stays green while you fill them
10
+ * in. Adding a new item type later surfaces as a compile error on
11
+ * `itemRegistry` (via the regenerated `ItemRegistry` type), not here.
12
+ *
13
+ * Reachable at the pre-TTS-1391 path `@foir/sdk/codegen/block-scaffold` too,
14
+ * which re-exports this module unchanged.
15
+ */
16
+ import type { GraphQLSchema } from 'graphql';
17
+ import { type ItemPluginConfig } from './shared';
18
+ export interface ItemScaffoldConfig extends ItemPluginConfig {
19
+ /** Import path for the generated registry type. Default `./item-registry`. */
20
+ registryImport?: string;
21
+ /** Render-context type name threaded to every component. Default `unknown`. */
22
+ ctxType?: string;
23
+ /** Optional import line for the ctx type, e.g. `import type { Ctx } from '~/ctx'`. */
24
+ ctxImport?: string;
25
+ }
26
+ /** @deprecated Renamed to {@link ItemScaffoldConfig}. */
27
+ export type BlockScaffoldConfig = ItemScaffoldConfig;
28
+ /** graphql-codegen plugin entrypoint. */
29
+ export declare const plugin: (schema: GraphQLSchema, _documents: unknown, config?: ItemScaffoldConfig) => string;
@@ -0,0 +1,7 @@
1
+ import {
2
+ plugin
3
+ } from "../chunk-OHYVKTGB.js";
4
+ import "../chunk-TAL5H6VA.js";
5
+ export {
6
+ plugin
7
+ };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * `@foir/sdk/codegen` — the Foir graphql-codegen preset.
3
+ *
4
+ * `foirCodegen()` returns a complete `@graphql-codegen/client-preset` config so
5
+ * a consumer's `codegen.ts` is ~3 lines instead of the ~109 every storefront
6
+ * hand-copies. It standardizes the Foir conventions (custom scalars,
7
+ * `enumValues: 'keep'`, the `X-Foir-Schema-Channel: draft` introspection header)
8
+ * AND wires the item-registry plugin so the exhaustive `ItemRegistry` type is
9
+ * regenerated alongside the typed documents.
10
+ *
11
+ * `foirScaffold()` is the separate one-shot that writes the ContentRenderer
12
+ * shell (run once; the dev owns the output).
13
+ */
14
+ import type { CodegenConfig } from '@graphql-codegen/cli';
15
+ export interface FoirCodegenOptions {
16
+ /** Foir public API GraphQL endpoint. */
17
+ apiUrl: string;
18
+ /**
19
+ * Public (`pk_`) API key. Reads the published schema. Used as the fallback
20
+ * when no preview key is set.
21
+ */
22
+ apiKey?: string;
23
+ /**
24
+ * Preview (`sk_`) key with `drafts:read`. Reads the DRAFT schema channel so
25
+ * freshly pushed (un-promoted) model changes are visible to codegen.
26
+ * Strongly preferred — a `pk_` key only sees the published schema.
27
+ */
28
+ previewKey?: string;
29
+ /** Output directory for the generated client types. Default `./app/gql/foir/`. */
30
+ outputDir?: string;
31
+ /** Operation document glob(s). Default `app/graphql/foir/**\/*.graphql`. */
32
+ documents?: string | string[];
33
+ /**
34
+ * Entries union name(s) for the registry. When unset, every prose
35
+ * entries union in the schema (the unions carrying `Passage`) is
36
+ * discovered at introspection time. Set explicitly to narrow the
37
+ * registry to specific fields' unions.
38
+ */
39
+ itemUnions?: string[];
40
+ /** @deprecated Renamed to `itemUnions`. Honoured when `itemUnions` is unset. */
41
+ blockUnions?: string[];
42
+ /** Generated registry file path. Default `<outputDir>item-registry.ts`. */
43
+ registryFile?: string;
44
+ /** Extra/override custom scalars merged onto the Foir defaults. */
45
+ scalars?: Record<string, unknown>;
46
+ }
47
+ /**
48
+ * Build the continuous Foir codegen config: typed documents + the exhaustive
49
+ * item registry. Drop it into `codegen.ts` and run `graphql-codegen`.
50
+ */
51
+ export declare function foirCodegen(options: FoirCodegenOptions): CodegenConfig;
52
+ export interface FoirScaffoldOptions extends FoirCodegenOptions {
53
+ /** Output path for the scaffold. Default `<outputDir>ContentRenderer.tsx`. */
54
+ scaffoldFile?: string;
55
+ /** Render-context type threaded to every item component. Default `unknown`. */
56
+ ctxType?: string;
57
+ /** Optional ctx-type import line, e.g. `import type { Ctx } from '~/ctx'`. */
58
+ ctxImport?: string;
59
+ /** Import path for the generated registry type. Default `./item-registry`. */
60
+ registryImport?: string;
61
+ }
62
+ /**
63
+ * Build the one-shot scaffold config — writes a ContentRenderer shell with a
64
+ * typed stub per item type. Run once (`graphql-codegen --config scaffold.ts`),
65
+ * then own and implement the output.
66
+ */
67
+ export declare function foirScaffold(options: FoirScaffoldOptions): CodegenConfig;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared introspection helpers for the Foir codegen plugins.
3
+ */
4
+ import { type GraphQLSchema } from 'graphql';
5
+ export interface ItemPluginConfig {
6
+ /**
7
+ * Union type name(s) to collect item members from. When unset, the
8
+ * plugins DISCOVER the project's prose entries unions: every union whose
9
+ * member set includes `Passage` (each prose field's entries union is
10
+ * named by its materialised member set, so there is no single fixed
11
+ * name to configure). Set explicitly to narrow the registry to specific
12
+ * fields' unions.
13
+ */
14
+ unions?: string[];
15
+ /** Import path for the codegen-generated types. Default `./graphql`. */
16
+ graphqlImport?: string;
17
+ /** Import path for the SDK content primitives. Default `@foir/sdk/content`. */
18
+ sdkImport?: string;
19
+ }
20
+ /** @deprecated Renamed to {@link ItemPluginConfig}. */
21
+ export type BlockPluginConfig = ItemPluginConfig;
22
+ export declare const DEFAULT_GRAPHQL_IMPORT = "./graphql";
23
+ export declare const DEFAULT_SDK_IMPORT = "@foir/sdk/content";
24
+ /**
25
+ * Collect the deduped, sorted set of object-type member names across the
26
+ * named union(s) — or, when no names are given, across every prose entries
27
+ * union in the schema (the unions whose members include `Passage`).
28
+ * `Passage` itself is excluded: the content renderer owns passage
29
+ * rendering, so no registry component exists for it.
30
+ *
31
+ * Throws when nothing resolves — that almost always means a misconfigured
32
+ * union name, or a schema with no prose fields that place models.
33
+ */
34
+ export declare function collectItemMembers(schema: GraphQLSchema, unionNames?: string[]): string[];
35
+ /** @deprecated Renamed to {@link collectItemMembers}. */
36
+ export declare const collectBlockMembers: typeof collectItemMembers;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * EditorProvider - React context provider for Foir editor iframes.
3
+ *
4
+ * Wraps your editor root to handle postMessage lifecycle, theme sync,
5
+ * and provide the platform client via context.
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ import type { EditorInit, EditorContextValue, LocaleContext } from '../types';
9
+ export declare const EditorContext: import("react").Context<EditorContextValue | null>;
10
+ export interface EditorProviderProps {
11
+ children: ReactNode;
12
+ /**
13
+ * Parent window origin for postMessage validation.
14
+ * Must be an explicit origin (e.g., 'https://admin.example.com').
15
+ * Falls back to VITE_PARENT_ORIGIN or NEXT_PUBLIC_PARENT_ORIGIN env var.
16
+ */
17
+ parentOrigin?: string;
18
+ /**
19
+ * Platform API URL for GraphQL requests.
20
+ * Falls back to VITE_API_URL or NEXT_PUBLIC_API_URL env var.
21
+ */
22
+ apiUrl?: string;
23
+ onInit?: (init: EditorInit) => void;
24
+ onValuesChanged?: (values: Record<string, unknown>) => void;
25
+ onVariantChanged?: (variantKey: string, values: Record<string, unknown>) => void;
26
+ onSaveResult?: (success: boolean, error?: string, versionId?: string) => void;
27
+ onPublishResult?: (success: boolean, error?: string) => void;
28
+ onThemeChanged?: (theme: 'light' | 'dark') => void;
29
+ onSelectionChanged?: (keys: string[], fields: Array<{
30
+ key: string;
31
+ label: string;
32
+ type: string;
33
+ }>) => void;
34
+ onLocaleChanged?: (locale: LocaleContext) => void;
35
+ }
36
+ export declare function EditorProvider({ children, parentOrigin: parentOriginProp, apiUrl: apiUrlProp, onInit, onValuesChanged, onVariantChanged, onSaveResult, onPublishResult, onThemeChanged, onSelectionChanged, onLocaleChanged, }: EditorProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * createContentRenderer — the generic content-dispatch primitive.
3
+ *
4
+ * It does NOT know any concrete item types. Given a registry that maps each
5
+ * entry `__typename` to a component, it renders a prose flow's entries (or a
6
+ * plain item array): looks each entry up by `__typename`, renders unknown
7
+ * types as null, keys by the entry `_key`/`_id` where one is present, assigns
8
+ * LCP `priority` to the first entry that actually renders, and threads a
9
+ * consumer-defined `Ctx` to every component.
10
+ *
11
+ * Passage entries — the flow's text — are not registry-dispatched: a run of
12
+ * consecutive passages renders as ONE unit through `options.passageRun` (or
13
+ * the SDK's `PassageList` with provider tokens when none is supplied), so
14
+ * prose reads as a single body with shared list structure.
15
+ *
16
+ * The "switch" is a typed object lookup. Exhaustiveness is enforced where the
17
+ * registry is BUILT — against the exhaustive `ItemRegistry` type the codegen
18
+ * plugin (EID-92) generates per project, so omitting an item type is a compile
19
+ * error there, not a runtime surprise here. The consumer can supply different
20
+ * registries per surface (e.g. web vs email).
21
+ *
22
+ * # On the word
23
+ *
24
+ * A prose field holds ENTRIES. A modeller may name the field `blocks`,
25
+ * `sections`, `modules` or anything else, and this renderer must not care:
26
+ * dispatch is on `__typename` and never on a field name. The `Block*` spellings
27
+ * below are deprecated aliases kept so existing consumers compile — see
28
+ * TTS-1391.
29
+ */
30
+ import { type ReactNode } from 'react';
31
+ import { type PassageLike } from './richtext';
32
+ /** Minimal shape every entry in a prose flow carries. */
33
+ export interface ItemLike {
34
+ __typename: string;
35
+ _id?: string | null;
36
+ _key?: string | null;
37
+ }
38
+ /** Props an item component receives from the content renderer. */
39
+ export interface ItemComponentProps<TItem, TCtx = unknown> {
40
+ item: TItem;
41
+ /**
42
+ * The same value as `item`.
43
+ *
44
+ * @deprecated Use `item`. Kept so components scaffolded before TTS-1391
45
+ * keep compiling; it is passed on every render and will be removed in a
46
+ * future major.
47
+ */
48
+ block: TItem;
49
+ /** Consumer-defined render context (host product, locale, etc.). */
50
+ ctx: TCtx;
51
+ /** True only for the first item that renders — the LCP candidate. */
52
+ priority: boolean;
53
+ }
54
+ /** A component that renders one item type. */
55
+ export type ItemComponent<TItem, TCtx = unknown> = (props: ItemComponentProps<TItem, TCtx>) => ReactNode;
56
+ /**
57
+ * A registry mapping `__typename` → item component. In practice this is the
58
+ * exhaustive `ItemRegistry` type the codegen plugin emits for the project;
59
+ * here it's the structural lower bound the renderer needs.
60
+ */
61
+ export type ItemRegistry<TCtx = unknown> = Record<string, ItemComponent<any, TCtx>>;
62
+ /** A prose flow's projection wrapper: the field value carrying `entries`. */
63
+ export interface EntriesLike {
64
+ entries?: readonly (ItemLike | null | undefined)[] | null;
65
+ }
66
+ /**
67
+ * The prose field's entries — the projection wrapper (`{ entries }`), or a
68
+ * plain array — plus the context threaded to every component.
69
+ *
70
+ * `items` is canonical. `blocks` is the pre-TTS-1391 spelling and still
71
+ * accepted; passing both is a type error rather than a silent precedence rule,
72
+ * because a caller who set both cannot be told which one this honoured.
73
+ */
74
+ export type ContentRendererProps<TCtx> = {
75
+ /** Consumer-defined context passed to every item component. */
76
+ ctx: TCtx;
77
+ } & ({
78
+ items: readonly (ItemLike | null | undefined)[] | EntriesLike | null | undefined;
79
+ blocks?: never;
80
+ } | {
81
+ /** @deprecated Use `items`. */
82
+ blocks: readonly (ItemLike | null | undefined)[] | EntriesLike | null | undefined;
83
+ items?: never;
84
+ });
85
+ /** Props the passage-run component receives. */
86
+ export interface PassageRunProps<TCtx = unknown> {
87
+ /** The consecutive passage entries of this run, in document order. */
88
+ passages: PassageLike[];
89
+ /** Consumer-defined render context. */
90
+ ctx: TCtx;
91
+ /** True only when the run is the flow's first rendered unit. */
92
+ priority: boolean;
93
+ }
94
+ export interface ContentRendererOptions<TCtx = unknown> {
95
+ /**
96
+ * Renders a run of consecutive passage entries. Defaults to the SDK's
97
+ * `PassageList` (typography tokens via `RichTextTypographyProvider`).
98
+ */
99
+ passageRun?: (props: PassageRunProps<TCtx>) => ReactNode;
100
+ }
101
+ /**
102
+ * Build a `<ContentRenderer>` bound to an item registry. Returns a component
103
+ * that takes the prose field's value (or a plain entry array) plus a `ctx`.
104
+ */
105
+ export declare function createContentRenderer<TCtx = unknown>(registry: ItemRegistry<TCtx>, options?: ContentRendererOptions<TCtx>): (props: ContentRendererProps<TCtx>) => ReactNode;
106
+ /** @deprecated Renamed to {@link ItemLike}. */
107
+ export type BlockLike = ItemLike;
108
+ /** @deprecated Renamed to {@link ItemComponentProps}. */
109
+ export type BlockComponentProps<TBlock, TCtx = unknown> = ItemComponentProps<TBlock, TCtx>;
110
+ /** @deprecated Renamed to {@link ItemComponent}. */
111
+ export type BlockComponent<TBlock, TCtx = unknown> = ItemComponent<TBlock, TCtx>;
112
+ /** @deprecated Renamed to {@link ItemRegistry}. */
113
+ export type BlockRegistry<TCtx = unknown> = ItemRegistry<TCtx>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `@foir/sdk/content` — generic content-rendering primitives.
3
+ *
4
+ * Ships ONLY the framework-agnostic primitives: the entry-dispatch renderer
5
+ * and a prose renderer (passages with spans, marks and markDefs) with
6
+ * injected typography tokens. Concrete item components, host/Shopify
7
+ * context, and layout systems stay app-side. `react` is a peer dependency.
8
+ */
9
+ export { createContentRenderer } from './content-renderer';
10
+ export type { ItemLike, EntriesLike, ItemComponent, ItemComponentProps, ItemRegistry, ContentRendererProps, ContentRendererOptions, PassageRunProps, } from './content-renderer';
11
+ /**
12
+ * Pre-TTS-1391 spellings. `Block` was one project's name for a flexible field,
13
+ * never a platform concept; these are kept so existing consumers compile and
14
+ * will be removed in a future major.
15
+ */
16
+ export type { BlockLike, BlockComponent, BlockComponentProps, BlockRegistry, } from './content-renderer';
17
+ export { RichTextRenderer, RichTextTypographyProvider, useRichTextTypography, PassageList, passagesOf, isPassageEntry, safeHref, } from './richtext';
18
+ export type { RichTextRendererProps, PassageListProps, TypographyToken, ProseValueLike, PassageLike, ProseSpanLike, } from './richtext';
@@ -0,0 +1,118 @@
1
+ /**
2
+ * RichTextRenderer — render a Foir prose value (a flow of passages) with
3
+ * per-passage typography tokens applied as inline styles.
4
+ *
5
+ * The design-token dependency is INJECTED, not imported from an app: pass the
6
+ * resolved `typography` token array as a prop, or provide it once via
7
+ * `<RichTextTypographyProvider>`. With no tokens the structure still renders
8
+ * (fallback tag, no inline typography), and a value without a typed `entries`
9
+ * projection falls back to its stored flow (`json`) and then its `html`
10
+ * projection. No `@foir`-app imports.
11
+ *
12
+ * Passage semantics:
13
+ * - `kind` (paragraph / h1–h6 / quote / code) picks the HTML element.
14
+ * - `token` names a typography token; its resolved CSS is inlined and the
15
+ * token's `tag` wins over the kind's element when both are present.
16
+ * - `align` maps to text-align on the rendered element.
17
+ * - `list` + `level` flatten list membership onto the passage; consecutive
18
+ * list passages regroup into <ul>/<ol> with nesting rebuilt from `level`.
19
+ * - Span marks are the eight decorations (bold, italic, underline,
20
+ * strikethrough, code, subscript, superscript, highlight) or the `_key`
21
+ * of a markDef on the same passage (links, scheme-checked through
22
+ * `safeHref`).
23
+ * - A soft line break is `"\n"` inside a span's text.
24
+ */
25
+ import { type ReactNode, type JSX } from 'react';
26
+ /**
27
+ * safeHref allow-lists link schemes so stored prose can't smuggle a
28
+ * `javascript:` (or `data:`/`vbscript:`) URL that executes on click (EID-207).
29
+ * Relative URLs, anchors, and the http(s)/mailto/tel schemes pass; anything
30
+ * else collapses to '#'. Editors are not fully trusted, so this runs on the
31
+ * structured render path, not only the html fallback.
32
+ */
33
+ export declare function safeHref(url: string | undefined): string;
34
+ /** A resolved typography token from the project's design tokens. */
35
+ export interface TypographyToken {
36
+ /** Token key referenced by a passage's `token`. */
37
+ name: string;
38
+ /** Rendered HTML element (paragraph / h1–h6 / blockquote). */
39
+ tag?: string;
40
+ value: {
41
+ fontFamily: string[];
42
+ fontSize: string | number;
43
+ fontWeight: string | number;
44
+ lineHeight: string | number;
45
+ letterSpacing: string | number;
46
+ textTransform?: string;
47
+ };
48
+ }
49
+ /**
50
+ * Provide the project's resolved typography tokens to every nested
51
+ * `<RichTextRenderer>` / `<PassageList>` so callers don't thread them through
52
+ * each usage. A `tokens` prop on the renderer still takes precedence.
53
+ */
54
+ export declare function RichTextTypographyProvider({ tokens, children, }: {
55
+ tokens: TypographyToken[];
56
+ children: ReactNode;
57
+ }): import("react/jsx-runtime").JSX.Element;
58
+ /** Read the injected typography tokens (null when no provider is mounted). */
59
+ export declare function useRichTextTypography(): TypographyToken[] | null;
60
+ export interface ProseSpanLike {
61
+ text?: string | null;
62
+ marks?: ReadonlyArray<string | null> | null;
63
+ }
64
+ export interface PassageLike {
65
+ __typename?: string;
66
+ _type?: string;
67
+ _key?: string | null;
68
+ kind?: string | null;
69
+ token?: string | null;
70
+ align?: string | null;
71
+ list?: string | null;
72
+ level?: number | null;
73
+ language?: string | null;
74
+ markDefs?: unknown;
75
+ spans?: ReadonlyArray<ProseSpanLike | null> | null;
76
+ }
77
+ export interface ProseValueLike {
78
+ html?: string | null;
79
+ json?: unknown;
80
+ entries?: ReadonlyArray<PassageLike | null> | null;
81
+ }
82
+ /** True for a passage entry from either the typed projection
83
+ * (`__typename: "Passage"`) or the stored flow (`_type: "passage"`). */
84
+ export declare function isPassageEntry(entry: unknown): entry is PassageLike;
85
+ /**
86
+ * Extract the renderable passages from a prose value. Prefers the typed
87
+ * `entries` projection; falls back to walking the stored flow (`json`).
88
+ * Embed entries are skipped — a prose *value* position renders text; embeds
89
+ * in list positions render through the consumer's content renderer instead.
90
+ */
91
+ export declare function passagesOf(value: ProseValueLike | null | undefined): PassageLike[];
92
+ export interface RichTextRendererProps {
93
+ value: ProseValueLike | null | undefined;
94
+ className?: string;
95
+ /**
96
+ * Resolved typography tokens. Overrides any provided via
97
+ * `<RichTextTypographyProvider>`. When neither is set, paragraphs render
98
+ * with `fallbackTag` and no inline typography.
99
+ */
100
+ tokens?: TypographyToken[];
101
+ /** Tag used for a paragraph passage with no token tag. */
102
+ fallbackTag?: keyof JSX.IntrinsicElements;
103
+ }
104
+ export declare function RichTextRenderer({ value, className, tokens, fallbackTag, }: RichTextRendererProps): import("react/jsx-runtime").JSX.Element | null;
105
+ export interface PassageListProps {
106
+ passages: ReadonlyArray<PassageLike>;
107
+ /** Resolved typography tokens; falls back to the provider's. */
108
+ tokens?: TypographyToken[];
109
+ /** Tag used for a paragraph passage with no token tag. */
110
+ fallbackTag?: keyof JSX.IntrinsicElements;
111
+ }
112
+ /**
113
+ * Render a run of passages: consecutive list passages regroup into (nested)
114
+ * <ul>/<ol>, everything else renders as its own element. Used by
115
+ * `RichTextRenderer` for prose field values and by `createContentRenderer`
116
+ * for passage runs inside a flow's entries.
117
+ */
118
+ export declare function PassageList({ passages, tokens, fallbackTag, }: PassageListProps): import("react/jsx-runtime").JSX.Element;