@devframes/json-render
Advanced tools
| import { z } from "zod"; | ||
| //#region src/prop-schemas.ts | ||
| /** | ||
| * Devframes-authored per-component prop schemas for the base catalog. | ||
| * | ||
| * Upstream `defineCatalog` collapses a multi-component `propsOf` to | ||
| * `Record<string, unknown>`, so it validates component *names* but not | ||
| * per-component *props*. These schemas are the one validation Devframes | ||
| * adds: element props are parsed against the matching schema at both trust | ||
| * boundaries — spec ingress (server) and render time (client). | ||
| * | ||
| * Each schema validates the types of the documented props and tolerates | ||
| * extra keys (upstream directives like `$bindState` resolve to values at | ||
| * render time), so validation catches genuine authoring mistakes without | ||
| * rejecting valid dynamic expressions. | ||
| */ | ||
| const dynamic = z.looseObject({}).and(z.record(z.string(), z.unknown())); | ||
| function scalar(schema) { | ||
| return z.union([schema, dynamic]); | ||
| } | ||
| const str = scalar(z.string()); | ||
| const num = scalar(z.number()); | ||
| const bool = scalar(z.boolean()); | ||
| const StackPropsSchema = z.object({ | ||
| direction: z.enum(["row", "column"]).optional(), | ||
| gap: num.optional(), | ||
| padding: num.optional(), | ||
| align: z.enum([ | ||
| "start", | ||
| "center", | ||
| "end", | ||
| "stretch" | ||
| ]).optional(), | ||
| justify: z.enum([ | ||
| "start", | ||
| "center", | ||
| "end", | ||
| "between", | ||
| "around" | ||
| ]).optional(), | ||
| wrap: bool.optional(), | ||
| flex: scalar(z.union([z.number(), z.string()])).optional() | ||
| }); | ||
| const CardPropsSchema = z.object({ | ||
| title: str.optional(), | ||
| border: bool.optional(), | ||
| collapsible: bool.optional(), | ||
| defaultCollapsed: bool.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const TextPropsSchema = z.object({ | ||
| text: str.optional(), | ||
| variant: z.enum([ | ||
| "heading", | ||
| "subheading", | ||
| "body", | ||
| "caption", | ||
| "code" | ||
| ]).optional(), | ||
| weight: z.enum([ | ||
| "normal", | ||
| "medium", | ||
| "bold" | ||
| ]).optional(), | ||
| color: z.enum([ | ||
| "base", | ||
| "muted", | ||
| "faint", | ||
| "primary", | ||
| "success", | ||
| "warning", | ||
| "danger" | ||
| ]).optional() | ||
| }); | ||
| const BadgePropsSchema = z.object({ | ||
| text: str.optional(), | ||
| variant: z.enum([ | ||
| "default", | ||
| "success", | ||
| "warning", | ||
| "danger", | ||
| "info" | ||
| ]).optional(), | ||
| minWidth: num.optional() | ||
| }); | ||
| const ButtonPropsSchema = z.object({ | ||
| label: str.optional(), | ||
| variant: z.enum([ | ||
| "primary", | ||
| "secondary", | ||
| "ghost", | ||
| "danger" | ||
| ]).optional(), | ||
| icon: str.optional(), | ||
| disabled: bool.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const IconPropsSchema = z.object({ | ||
| name: str.optional(), | ||
| size: num.optional() | ||
| }); | ||
| const DividerPropsSchema = z.object({ label: str.optional() }); | ||
| const TextInputPropsSchema = z.object({ | ||
| value: str.optional(), | ||
| placeholder: str.optional(), | ||
| label: str.optional(), | ||
| disabled: bool.optional(), | ||
| type: z.enum([ | ||
| "text", | ||
| "number", | ||
| "password", | ||
| "email", | ||
| "search" | ||
| ]).optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const SwitchPropsSchema = z.object({ | ||
| value: bool.optional(), | ||
| label: str.optional(), | ||
| disabled: bool.optional() | ||
| }); | ||
| const KeyValueTablePropsSchema = z.object({ | ||
| data: z.union([z.record(z.string(), z.unknown()), dynamic]).optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const DataTablePropsSchema = z.object({ | ||
| columns: scalar(z.array(z.union([z.string(), z.looseObject({ | ||
| key: z.string(), | ||
| label: z.string().optional() | ||
| })]))).optional(), | ||
| rows: scalar(z.array(z.unknown())).optional(), | ||
| height: num.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const CodeBlockPropsSchema = z.object({ | ||
| code: str.optional(), | ||
| language: str.optional(), | ||
| filename: str.optional(), | ||
| height: num.optional() | ||
| }); | ||
| const ProgressPropsSchema = z.object({ | ||
| value: num.optional(), | ||
| max: num.optional(), | ||
| label: str.optional() | ||
| }); | ||
| const TreePropsSchema = z.object({ | ||
| data: z.unknown().optional(), | ||
| defaultExpanded: bool.optional() | ||
| }); | ||
| const TabsPropsSchema = z.object({ | ||
| tabs: scalar(z.array(z.looseObject({ | ||
| value: z.string(), | ||
| label: z.string(), | ||
| icon: z.string().optional(), | ||
| badge: z.string().optional(), | ||
| badgeVariant: z.enum([ | ||
| "default", | ||
| "info", | ||
| "success", | ||
| "warning", | ||
| "danger" | ||
| ]).optional() | ||
| }))).optional(), | ||
| value: str.optional(), | ||
| defaultValue: str.optional(), | ||
| orientation: z.enum(["horizontal", "vertical"]).optional() | ||
| }); | ||
| const LinkPropsSchema = z.object({ | ||
| href: str.optional(), | ||
| label: str.optional(), | ||
| icon: str.optional(), | ||
| external: bool.optional() | ||
| }); | ||
| const SelectPropsSchema = z.object({ | ||
| value: str.optional(), | ||
| options: scalar(z.array(z.union([z.string(), z.looseObject({ | ||
| value: z.string(), | ||
| label: z.string().optional(), | ||
| icon: z.string().optional(), | ||
| description: z.string().optional() | ||
| })]))).optional(), | ||
| placeholder: str.optional(), | ||
| label: str.optional(), | ||
| disabled: bool.optional(), | ||
| searchable: bool.optional() | ||
| }); | ||
| /** | ||
| * Map of base-catalog component name → Zod prop schema. The keys are the | ||
| * canonical component set (catalog v1: the original fourteen plus the | ||
| * additive Tabs/Link/Select). | ||
| */ | ||
| const basePropSchemas = { | ||
| Stack: StackPropsSchema, | ||
| Card: CardPropsSchema, | ||
| Text: TextPropsSchema, | ||
| Badge: BadgePropsSchema, | ||
| Button: ButtonPropsSchema, | ||
| Icon: IconPropsSchema, | ||
| Divider: DividerPropsSchema, | ||
| TextInput: TextInputPropsSchema, | ||
| Switch: SwitchPropsSchema, | ||
| KeyValueTable: KeyValueTablePropsSchema, | ||
| DataTable: DataTablePropsSchema, | ||
| CodeBlock: CodeBlockPropsSchema, | ||
| Progress: ProgressPropsSchema, | ||
| Tree: TreePropsSchema, | ||
| Tabs: TabsPropsSchema, | ||
| Link: LinkPropsSchema, | ||
| Select: SelectPropsSchema | ||
| }; | ||
| /** The ordered list of base-catalog component names (catalog v1). */ | ||
| const baseComponentNames = Object.keys(basePropSchemas); | ||
| //#endregion | ||
| //#region src/view-index.ts | ||
| /** | ||
| * Well-known shared-state key carrying the **view index**: a map of every | ||
| * live JSON-render view registered on a context, keyed by its `stateKey`. | ||
| * | ||
| * A frontend that does not know view ids ahead of time (e.g. the prebuilt | ||
| * standalone SPA in `@devframes/json-render-ui`) subscribes to this one key to | ||
| * discover which views exist, then subscribes to each view's own state. A hub | ||
| * dock, by contrast, is handed a specific {@link JsonRenderViewRef} and needs | ||
| * no index. | ||
| */ | ||
| const JSON_RENDER_INDEX_KEY = "devframe:json-render:index"; | ||
| //#endregion | ||
| export { TextPropsSchema as _, CodeBlockPropsSchema as a, basePropSchemas as b, IconPropsSchema as c, ProgressPropsSchema as d, SelectPropsSchema as f, TextInputPropsSchema as g, TabsPropsSchema as h, CardPropsSchema as i, KeyValueTablePropsSchema as l, SwitchPropsSchema as m, BadgePropsSchema as n, DataTablePropsSchema as o, StackPropsSchema as p, ButtonPropsSchema as r, DividerPropsSchema as s, JSON_RENDER_INDEX_KEY as t, LinkPropsSchema as u, TreePropsSchema as v, baseComponentNames as y }; |
+19
-1
| import { i as JsonRenderViewRef, n as JsonRenderView } from "./types-CC2-FD2H.mjs"; | ||
| import { DockRenderer, DockRendererMountOptions } from "@devframes/hub/client"; | ||
| import { DevframeDockEntryBase } from "@devframes/hub/types"; | ||
@@ -21,2 +22,19 @@ //#region src/hub.d.ts | ||
| /** | ||
| * The mount options a hub viewer hands a json-render dock renderer — the | ||
| * hub's `DockRendererMountOptions` narrowed to the `'json-render'` entry. | ||
| * This protocol package owns the renderer contract so every frontend — | ||
| * `@devframes/json-render-ui`, a community renderer, a host page's own — | ||
| * implements one shared shape instead of re-declaring it. | ||
| */ | ||
| type JsonRenderDockMountOptions = DockRendererMountOptions<DevframeJsonRenderDockEntry>; | ||
| /** | ||
| * The renderer contract for `'json-render'` docks: a hub `DockRenderer` | ||
| * narrowed to {@link DevframeJsonRenderDockEntry}. Implement it to replace | ||
| * the reference frontend — register the implementation locally | ||
| * (`createDevframeClientHost({ renderers })`) or ship it as a prebuilt | ||
| * module registered through the hub's renderer manifest | ||
| * (`initHub({ renderers })`). | ||
| */ | ||
| type JsonRenderDockRenderer = DockRenderer<DevframeJsonRenderDockEntry>; | ||
| /** | ||
| * Build a `json-render` dock entry from a {@link JsonRenderView} and the dock | ||
@@ -28,2 +46,2 @@ * metadata (id, title, icon, …). Projects the view down to its serializable | ||
| //#endregion | ||
| export { DevframeJsonRenderDockEntry, toJsonRenderDockEntry }; | ||
| export { DevframeJsonRenderDockEntry, JsonRenderDockMountOptions, JsonRenderDockRenderer, toJsonRenderDockEntry }; |
+84
-3
@@ -136,5 +136,46 @@ import { Catalog, InferComponentProps, Spec, StateModel, StateStore, UIElement } from "./core.mjs"; | ||
| }, z.core.$strip>; | ||
| declare const TabsPropsSchema: z.ZodObject<{ | ||
| tabs: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{ | ||
| value: z.ZodString; | ||
| label: z.ZodString; | ||
| icon: z.ZodOptional<z.ZodString>; | ||
| badge: z.ZodOptional<z.ZodString>; | ||
| badgeVariant: z.ZodOptional<z.ZodEnum<{ | ||
| success: "success"; | ||
| default: "default"; | ||
| warning: "warning"; | ||
| danger: "danger"; | ||
| info: "info"; | ||
| }>>; | ||
| }, z.core.$loose>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| orientation: z.ZodOptional<z.ZodEnum<{ | ||
| horizontal: "horizontal"; | ||
| vertical: "vertical"; | ||
| }>>; | ||
| }, z.core.$strip>; | ||
| declare const LinkPropsSchema: z.ZodObject<{ | ||
| href: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| external: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| }, z.core.$strip>; | ||
| declare const SelectPropsSchema: z.ZodObject<{ | ||
| value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| options: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{ | ||
| value: z.ZodString; | ||
| label: z.ZodOptional<z.ZodString>; | ||
| icon: z.ZodOptional<z.ZodString>; | ||
| description: z.ZodOptional<z.ZodString>; | ||
| }, z.core.$loose>]>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| placeholder: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| disabled: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| searchable: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| }, z.core.$strip>; | ||
| /** | ||
| * Map of base-catalog component name → Zod prop schema. The keys are the | ||
| * canonical component set (catalog v1). | ||
| * canonical component set (catalog v1: the original fourteen plus the | ||
| * additive Tabs/Link/Select). | ||
| */ | ||
@@ -273,2 +314,42 @@ declare const basePropSchemas: { | ||
| }, z.core.$strip>; | ||
| readonly Tabs: z.ZodObject<{ | ||
| tabs: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{ | ||
| value: z.ZodString; | ||
| label: z.ZodString; | ||
| icon: z.ZodOptional<z.ZodString>; | ||
| badge: z.ZodOptional<z.ZodString>; | ||
| badgeVariant: z.ZodOptional<z.ZodEnum<{ | ||
| success: "success"; | ||
| default: "default"; | ||
| warning: "warning"; | ||
| danger: "danger"; | ||
| info: "info"; | ||
| }>>; | ||
| }, z.core.$loose>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| orientation: z.ZodOptional<z.ZodEnum<{ | ||
| horizontal: "horizontal"; | ||
| vertical: "vertical"; | ||
| }>>; | ||
| }, z.core.$strip>; | ||
| readonly Link: z.ZodObject<{ | ||
| href: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| icon: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| external: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| }, z.core.$strip>; | ||
| readonly Select: z.ZodObject<{ | ||
| value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| options: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{ | ||
| value: z.ZodString; | ||
| label: z.ZodOptional<z.ZodString>; | ||
| icon: z.ZodOptional<z.ZodString>; | ||
| description: z.ZodOptional<z.ZodString>; | ||
| }, z.core.$loose>]>>, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| placeholder: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| disabled: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| searchable: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodIntersection<z.ZodObject<{}, z.core.$loose>, z.ZodRecord<z.ZodString, z.ZodUnknown>>]>>; | ||
| }, z.core.$strip>; | ||
| }; | ||
@@ -308,3 +389,3 @@ /** Canonical base-catalog component name. */ | ||
| /** | ||
| * The Devframes base catalog (catalog v1): the fourteen canonical components | ||
| * The Devframes base catalog (catalog v1): the seventeen canonical components | ||
| * with their Devframes-authored Zod prop schemas and descriptions, and an | ||
@@ -370,2 +451,2 @@ * empty action set (actions are dispatched dynamically via the bridge, they | ||
| //#endregion | ||
| export { BadgePropsSchema, type BaseComponentName, ButtonPropsSchema, CardPropsSchema, type Catalog, CodeBlockPropsSchema, DataTablePropsSchema, type DevframeJsonRenderSpec, DividerPropsSchema, IconPropsSchema, type InferComponentProps, JSON_RENDER_INDEX_KEY, type JsonRenderIndex, type JsonRenderIndexEntry, type JsonRenderView, type JsonRenderViewInlineRef, type JsonRenderViewRef, type JsonRenderViewStateRef, KeyValueTablePropsSchema, ProgressPropsSchema, type Spec, StackPropsSchema, type StateModel, type StateStore, SwitchPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, type UIElement, baseCatalog, baseComponentNames, basePropSchemas, baseSchema }; | ||
| export { BadgePropsSchema, type BaseComponentName, ButtonPropsSchema, CardPropsSchema, type Catalog, CodeBlockPropsSchema, DataTablePropsSchema, type DevframeJsonRenderSpec, DividerPropsSchema, IconPropsSchema, type InferComponentProps, JSON_RENDER_INDEX_KEY, type JsonRenderIndex, type JsonRenderIndexEntry, type JsonRenderView, type JsonRenderViewInlineRef, type JsonRenderViewRef, type JsonRenderViewStateRef, KeyValueTablePropsSchema, LinkPropsSchema, ProgressPropsSchema, SelectPropsSchema, type Spec, StackPropsSchema, type StateModel, type StateStore, SwitchPropsSchema, TabsPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, type UIElement, baseCatalog, baseComponentNames, basePropSchemas, baseSchema }; |
+7
-4
@@ -1,2 +0,2 @@ | ||
| import { _ as basePropSchemas, a as CodeBlockPropsSchema, c as IconPropsSchema, d as StackPropsSchema, f as SwitchPropsSchema, g as baseComponentNames, h as TreePropsSchema, i as CardPropsSchema, l as KeyValueTablePropsSchema, m as TextPropsSchema, n as BadgePropsSchema, o as DataTablePropsSchema, p as TextInputPropsSchema, r as ButtonPropsSchema, s as DividerPropsSchema, t as JSON_RENDER_INDEX_KEY, u as ProgressPropsSchema } from "./view-index-BItK4ftT.mjs"; | ||
| import { _ as TextPropsSchema, a as CodeBlockPropsSchema, b as basePropSchemas, c as IconPropsSchema, d as ProgressPropsSchema, f as SelectPropsSchema, g as TextInputPropsSchema, h as TabsPropsSchema, i as CardPropsSchema, l as KeyValueTablePropsSchema, m as SwitchPropsSchema, n as BadgePropsSchema, o as DataTablePropsSchema, p as StackPropsSchema, r as ButtonPropsSchema, s as DividerPropsSchema, t as JSON_RENDER_INDEX_KEY, u as LinkPropsSchema, v as TreePropsSchema, y as baseComponentNames } from "./view-index-CUg7TaB4.mjs"; | ||
| import { defineCatalog, defineSchema } from "@json-render/core"; | ||
@@ -42,6 +42,9 @@ //#region src/catalog.ts | ||
| Progress: "Determinate progress bar.", | ||
| Tree: "Recursive object/array viewer with expandable nodes." | ||
| Tree: "Recursive object/array viewer with expandable nodes.", | ||
| Tabs: "Tabbed container; each child renders under the positionally-matching tab.", | ||
| Link: "Hyperlink to a safe-scheme URL with an optional icon.", | ||
| Select: "Single-select dropdown bound to a state value, with optional search." | ||
| }; | ||
| /** | ||
| * The Devframes base catalog (catalog v1): the fourteen canonical components | ||
| * The Devframes base catalog (catalog v1): the seventeen canonical components | ||
| * with their Devframes-authored Zod prop schemas and descriptions, and an | ||
@@ -59,2 +62,2 @@ * empty action set (actions are dispatched dynamically via the bridge, they | ||
| //#endregion | ||
| export { BadgePropsSchema, ButtonPropsSchema, CardPropsSchema, CodeBlockPropsSchema, DataTablePropsSchema, DividerPropsSchema, IconPropsSchema, JSON_RENDER_INDEX_KEY, KeyValueTablePropsSchema, ProgressPropsSchema, StackPropsSchema, SwitchPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, baseCatalog, baseComponentNames, basePropSchemas, baseSchema }; | ||
| export { BadgePropsSchema, ButtonPropsSchema, CardPropsSchema, CodeBlockPropsSchema, DataTablePropsSchema, DividerPropsSchema, IconPropsSchema, JSON_RENDER_INDEX_KEY, KeyValueTablePropsSchema, LinkPropsSchema, ProgressPropsSchema, SelectPropsSchema, StackPropsSchema, SwitchPropsSchema, TabsPropsSchema, TextInputPropsSchema, TextPropsSchema, TreePropsSchema, baseCatalog, baseComponentNames, basePropSchemas, baseSchema }; |
| import { n as JsonRenderView, t as DevframeJsonRenderSpec } from "../types-CC2-FD2H.mjs"; | ||
| import { Diagnostic } from "nostics"; | ||
| import { DevframeNodeContext, DevframeScopedNodeContext } from "devframe/types"; | ||
| import { DevframeNodeContext, DevframeScopedNodeContext } from "devframe"; | ||
| //#region src/node/create-view.d.ts | ||
@@ -5,0 +5,0 @@ /** Options for {@link createJsonRenderView}. */ |
@@ -1,2 +0,2 @@ | ||
| import { _ as basePropSchemas, t as JSON_RENDER_INDEX_KEY } from "../view-index-BItK4ftT.mjs"; | ||
| import { b as basePropSchemas, t as JSON_RENDER_INDEX_KEY } from "../view-index-CUg7TaB4.mjs"; | ||
| import { createSharedState } from "devframe/utils/shared-state"; | ||
@@ -3,0 +3,0 @@ import { colors } from "devframe/utils/colors"; |
+7
-7
| { | ||
| "name": "@devframes/json-render", | ||
| "type": "module", | ||
| "version": "0.8.2", | ||
| "description": "Opt-in, framework-neutral JSON-render protocol layer for devframe — spec/catalog types, base catalog, and the node runtime factory.", | ||
| "version": "0.9.0-beta.1", | ||
| "description": "Protocol layer for describing devframe views as JSON that any renderer can display.", | ||
| "author": "Anthony Fu <anthonyfu117@hotmail.com>", | ||
@@ -33,4 +33,4 @@ "license": "MIT", | ||
| "peerDependencies": { | ||
| "@devframes/hub": "0.8.2", | ||
| "devframe": "0.8.2" | ||
| "@devframes/hub": "0.9.0-beta.1", | ||
| "devframe": "0.9.0-beta.1" | ||
| }, | ||
@@ -48,6 +48,6 @@ "peerDependenciesMeta": { | ||
| "devDependencies": { | ||
| "@types/node": "^26.1.2", | ||
| "@types/node": "^26.2.0", | ||
| "tsdown": "^0.22.14", | ||
| "@devframes/hub": "0.8.2", | ||
| "devframe": "0.8.2" | ||
| "@devframes/hub": "0.9.0-beta.1", | ||
| "devframe": "0.9.0-beta.1" | ||
| }, | ||
@@ -54,0 +54,0 @@ "scripts": { |
| import { z } from "zod"; | ||
| //#region src/prop-schemas.ts | ||
| /** | ||
| * Devframes-authored per-component prop schemas for the base catalog. | ||
| * | ||
| * Upstream `defineCatalog` collapses a multi-component `propsOf` to | ||
| * `Record<string, unknown>`, so it validates component *names* but not | ||
| * per-component *props*. These schemas are the one validation Devframes | ||
| * adds: element props are parsed against the matching schema at both trust | ||
| * boundaries — spec ingress (server) and render time (client). | ||
| * | ||
| * Each schema validates the types of the documented props and tolerates | ||
| * extra keys (upstream directives like `$bindState` resolve to values at | ||
| * render time), so validation catches genuine authoring mistakes without | ||
| * rejecting valid dynamic expressions. | ||
| */ | ||
| const dynamic = z.looseObject({}).and(z.record(z.string(), z.unknown())); | ||
| function scalar(schema) { | ||
| return z.union([schema, dynamic]); | ||
| } | ||
| const str = scalar(z.string()); | ||
| const num = scalar(z.number()); | ||
| const bool = scalar(z.boolean()); | ||
| const StackPropsSchema = z.object({ | ||
| direction: z.enum(["row", "column"]).optional(), | ||
| gap: num.optional(), | ||
| padding: num.optional(), | ||
| align: z.enum([ | ||
| "start", | ||
| "center", | ||
| "end", | ||
| "stretch" | ||
| ]).optional(), | ||
| justify: z.enum([ | ||
| "start", | ||
| "center", | ||
| "end", | ||
| "between", | ||
| "around" | ||
| ]).optional(), | ||
| wrap: bool.optional(), | ||
| flex: scalar(z.union([z.number(), z.string()])).optional() | ||
| }); | ||
| const CardPropsSchema = z.object({ | ||
| title: str.optional(), | ||
| border: bool.optional(), | ||
| collapsible: bool.optional(), | ||
| defaultCollapsed: bool.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const TextPropsSchema = z.object({ | ||
| text: str.optional(), | ||
| variant: z.enum([ | ||
| "heading", | ||
| "subheading", | ||
| "body", | ||
| "caption", | ||
| "code" | ||
| ]).optional(), | ||
| weight: z.enum([ | ||
| "normal", | ||
| "medium", | ||
| "bold" | ||
| ]).optional(), | ||
| color: z.enum([ | ||
| "base", | ||
| "muted", | ||
| "faint", | ||
| "primary", | ||
| "success", | ||
| "warning", | ||
| "danger" | ||
| ]).optional() | ||
| }); | ||
| const BadgePropsSchema = z.object({ | ||
| text: str.optional(), | ||
| variant: z.enum([ | ||
| "default", | ||
| "success", | ||
| "warning", | ||
| "danger", | ||
| "info" | ||
| ]).optional(), | ||
| minWidth: num.optional() | ||
| }); | ||
| const ButtonPropsSchema = z.object({ | ||
| label: str.optional(), | ||
| variant: z.enum([ | ||
| "primary", | ||
| "secondary", | ||
| "ghost", | ||
| "danger" | ||
| ]).optional(), | ||
| icon: str.optional(), | ||
| disabled: bool.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const IconPropsSchema = z.object({ | ||
| name: str.optional(), | ||
| size: num.optional() | ||
| }); | ||
| const DividerPropsSchema = z.object({ label: str.optional() }); | ||
| const TextInputPropsSchema = z.object({ | ||
| value: str.optional(), | ||
| placeholder: str.optional(), | ||
| label: str.optional(), | ||
| disabled: bool.optional(), | ||
| type: z.enum([ | ||
| "text", | ||
| "number", | ||
| "password", | ||
| "email", | ||
| "search" | ||
| ]).optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const SwitchPropsSchema = z.object({ | ||
| value: bool.optional(), | ||
| label: str.optional(), | ||
| disabled: bool.optional() | ||
| }); | ||
| const KeyValueTablePropsSchema = z.object({ | ||
| data: z.union([z.record(z.string(), z.unknown()), dynamic]).optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const DataTablePropsSchema = z.object({ | ||
| columns: scalar(z.array(z.union([z.string(), z.looseObject({ | ||
| key: z.string(), | ||
| label: z.string().optional() | ||
| })]))).optional(), | ||
| rows: scalar(z.array(z.unknown())).optional(), | ||
| height: num.optional(), | ||
| loading: bool.optional() | ||
| }); | ||
| const CodeBlockPropsSchema = z.object({ | ||
| code: str.optional(), | ||
| language: str.optional(), | ||
| filename: str.optional(), | ||
| height: num.optional() | ||
| }); | ||
| const ProgressPropsSchema = z.object({ | ||
| value: num.optional(), | ||
| max: num.optional(), | ||
| label: str.optional() | ||
| }); | ||
| const TreePropsSchema = z.object({ | ||
| data: z.unknown().optional(), | ||
| defaultExpanded: bool.optional() | ||
| }); | ||
| /** | ||
| * Map of base-catalog component name → Zod prop schema. The keys are the | ||
| * canonical component set (catalog v1). | ||
| */ | ||
| const basePropSchemas = { | ||
| Stack: StackPropsSchema, | ||
| Card: CardPropsSchema, | ||
| Text: TextPropsSchema, | ||
| Badge: BadgePropsSchema, | ||
| Button: ButtonPropsSchema, | ||
| Icon: IconPropsSchema, | ||
| Divider: DividerPropsSchema, | ||
| TextInput: TextInputPropsSchema, | ||
| Switch: SwitchPropsSchema, | ||
| KeyValueTable: KeyValueTablePropsSchema, | ||
| DataTable: DataTablePropsSchema, | ||
| CodeBlock: CodeBlockPropsSchema, | ||
| Progress: ProgressPropsSchema, | ||
| Tree: TreePropsSchema | ||
| }; | ||
| /** The ordered list of base-catalog component names (catalog v1). */ | ||
| const baseComponentNames = Object.keys(basePropSchemas); | ||
| //#endregion | ||
| //#region src/view-index.ts | ||
| /** | ||
| * Well-known shared-state key carrying the **view index**: a map of every | ||
| * live JSON-render view registered on a context, keyed by its `stateKey`. | ||
| * | ||
| * A frontend that does not know view ids ahead of time (e.g. the prebuilt | ||
| * standalone SPA in `@devframes/json-render-ui`) subscribes to this one key to | ||
| * discover which views exist, then subscribes to each view's own state. A hub | ||
| * dock, by contrast, is handed a specific {@link JsonRenderViewRef} and needs | ||
| * no index. | ||
| */ | ||
| const JSON_RENDER_INDEX_KEY = "devframe:json-render:index"; | ||
| //#endregion | ||
| export { basePropSchemas as _, CodeBlockPropsSchema as a, IconPropsSchema as c, StackPropsSchema as d, SwitchPropsSchema as f, baseComponentNames as g, TreePropsSchema as h, CardPropsSchema as i, KeyValueTablePropsSchema as l, TextPropsSchema as m, BadgePropsSchema as n, DataTablePropsSchema as o, TextInputPropsSchema as p, ButtonPropsSchema as r, DividerPropsSchema as s, JSON_RENDER_INDEX_KEY as t, ProgressPropsSchema as u }; |
56753
17.22%483
10.02%