view-contracts 0.5.7 → 0.5.9

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 (79) hide show
  1. package/README.md +11 -1
  2. package/cli-contract.yaml +1 -1
  3. package/dist/preview.mjs +185 -185
  4. package/dist/preview.mjs.map +4 -4
  5. package/dist/types/renderers/compose/elementMap.d.ts +10 -0
  6. package/dist/types/renderers/compose/lowering/lowerToCompose.d.ts +22 -0
  7. package/dist/types/renderers/compose/lowering/modifiers.d.ts +36 -0
  8. package/dist/types/renderers/compose/renderComponents.d.ts +9 -0
  9. package/dist/types/renderers/compose/renderRuntime.d.ts +10 -0
  10. package/dist/types/renderers/compose/renderTheme.d.ts +5 -0
  11. package/dist/types/renderers/react/elementMap.d.ts +32 -0
  12. package/dist/types/renderers/react/lowering/foldStyle.d.ts +7 -0
  13. package/dist/types/renderers/react/lowering/lowerToJsx.d.ts +6 -0
  14. package/dist/types/renderers/react/paths.d.ts +1 -0
  15. package/dist/types/renderers/react/renderComponents.d.ts +26 -0
  16. package/dist/types/renderers/react/renderRuntime.d.ts +3 -0
  17. package/dist/types/renderers/react/runtime/style.d.ts +19 -0
  18. package/dist/types/renderers/react/style/foldLiterals.d.ts +3 -0
  19. package/dist/types/renderers/react/syncGeneratedRuntime.d.ts +7 -0
  20. package/dist/types/renderers/registry.d.ts +35 -0
  21. package/dist/types/renderers/swiftui/elementMap.d.ts +10 -0
  22. package/dist/types/renderers/swiftui/lowering/lowerToSwiftUI.d.ts +15 -0
  23. package/dist/types/renderers/swiftui/lowering/modifiers.d.ts +16 -0
  24. package/dist/types/renderers/swiftui/renderComponents.d.ts +9 -0
  25. package/dist/types/renderers/swiftui/renderRuntime.d.ts +10 -0
  26. package/dist/types/renderers/swiftui/renderTheme.d.ts +6 -0
  27. package/dist/types/src/cli.d.ts +2 -0
  28. package/dist/types/src/commands/index.d.ts +2 -0
  29. package/dist/types/src/compiler/compileView.d.ts +27 -0
  30. package/dist/types/src/compiler/jsxToIr.d.ts +33 -0
  31. package/dist/types/src/compiler/viewPartial.d.ts +13 -0
  32. package/dist/types/src/config.d.ts +77 -0
  33. package/dist/types/src/design/buildThemeCss.d.ts +3 -0
  34. package/dist/types/src/design/cssEmitUtils.d.ts +3 -0
  35. package/dist/types/src/design/cssPropertyMap.d.ts +2 -0
  36. package/dist/types/src/design/emitDefaultCss.d.ts +2 -0
  37. package/dist/types/src/design/emitTokenCss.d.ts +4 -0
  38. package/dist/types/src/design/emitVariantCss.d.ts +2 -0
  39. package/dist/types/src/design/index.d.ts +19 -0
  40. package/dist/types/src/design/load.d.ts +1 -0
  41. package/dist/types/src/design/parseTheme.d.ts +2 -0
  42. package/dist/types/src/design/parseTokens.d.ts +2 -0
  43. package/dist/types/src/design/themeElementProperties.d.ts +5 -0
  44. package/dist/types/src/design/types.d.ts +37 -0
  45. package/dist/types/src/design/validate.d.ts +3 -0
  46. package/dist/types/src/design/validateProjectDesign.d.ts +3 -0
  47. package/dist/types/src/design/validateVcNamespace.d.ts +4 -0
  48. package/dist/types/src/design/validateViewVariants.d.ts +3 -0
  49. package/dist/types/src/dsl/index.d.ts +2 -0
  50. package/dist/types/src/dsl/screen.d.ts +17 -0
  51. package/dist/types/src/dsl/types.d.ts +59 -0
  52. package/dist/types/src/extensions/loadExtensions.d.ts +17 -0
  53. package/dist/types/src/extensions/validateExtensionUsage.d.ts +18 -0
  54. package/dist/types/src/generated/cli/contract.d.ts +2 -0
  55. package/dist/types/src/generated/cli/program.d.ts +28 -0
  56. package/dist/types/src/ir/collectViewRefs.d.ts +3 -0
  57. package/dist/types/src/ir/types.d.ts +67 -0
  58. package/dist/types/src/lib/packageRoot.d.ts +2 -0
  59. package/dist/types/src/lib/projectPath.d.ts +2 -0
  60. package/dist/types/src/lib/rendererPaths.d.ts +13 -0
  61. package/dist/types/src/preview/compileScreen.d.ts +15 -0
  62. package/dist/types/src/preview/previewAssets.d.ts +9 -0
  63. package/dist/types/src/preview/previewMock.d.ts +16 -0
  64. package/dist/types/src/preview/previewMockPlugin.d.ts +6 -0
  65. package/dist/types/src/preview/previewServer.d.ts +7 -0
  66. package/dist/types/src/preview/publish.d.ts +5 -0
  67. package/dist/types/src/preview/vitePlugin.d.ts +13 -0
  68. package/dist/types/src/renderer/bridge.d.ts +32 -0
  69. package/dist/types/src/renderer/elementMapValidation.d.ts +6 -0
  70. package/dist/types/src/renderer/style/mergeVisualProps.d.ts +20 -0
  71. package/dist/types/src/renderer/template.d.ts +2 -0
  72. package/dist/types/src/scaffold/standalone.d.ts +2 -0
  73. package/dist/types/src/schema/dsl-catalog.d.ts +56 -0
  74. package/dist/types/src/validate/validateViewProps.d.ts +5 -0
  75. package/dist/view-contracts.bundle.mjs +141 -141
  76. package/dist/view-contracts.bundle.mjs.map +4 -4
  77. package/docs/cli-reference.md +1 -1
  78. package/package.json +19 -6
  79. package/spec/ui-dsl.schema.json +159 -2
@@ -0,0 +1,2 @@
1
+ export { screen, view } from './screen.js';
2
+ export type { ViewAction, ActionHandlers, ScreenContext, ViewContract, ViewPartial, ViewScreenProps, CommonProps, Option, Tone, Align, Justify, ButtonVariant, FieldSize, } from './types.js';
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { FC } from 'react';
3
+ import type { ScreenContext, ViewPartial, ViewScreenProps } from './types.js';
4
+ export type { ViewAction, ActionHandlers, ScreenContext, ViewContract, ViewPartial, ViewScreenProps, CommonProps, Option, Tone, Align, Justify, ButtonVariant, FieldSize, } from './types.js';
5
+ /**
6
+ * Wrap a restricted view-contract TSX definition.
7
+ *
8
+ * - **Preview runtime**: returns a React component (`vm` + `actions` props).
9
+ * - **Compiler**: statically extracts JSX from the render callback → View IR.
10
+ */
11
+ export declare function screen<TViewModel>(render: (ctx: ScreenContext<TViewModel>) => ReactNode): FC<ViewScreenProps<TViewModel>>;
12
+ /**
13
+ * Reusable view-contract sub-component (composable inside screen() or other view()).
14
+ *
15
+ * Compiled by inlining into the parent View IR; preview runtime renders as a normal React FC.
16
+ */
17
+ export declare function view<TProps>(render: (props: TProps) => ReactNode): FC<TProps> & ViewPartial<TProps>;
@@ -0,0 +1,59 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Action descriptor referenced from view contracts (names must match OpenAPI operationId). */
3
+ export interface ViewAction {
4
+ name: string;
5
+ params?: Record<string, unknown>;
6
+ }
7
+ export type ActionHandlers = Record<string, (params?: unknown) => void | Promise<void>>;
8
+ export interface ScreenContext<TViewModel> {
9
+ vm: TViewModel;
10
+ actions: ActionHandlers;
11
+ }
12
+ export interface ViewContract<TViewModel> {
13
+ readonly __viewContract: true;
14
+ readonly render: (ctx: ScreenContext<TViewModel>) => ReactNode;
15
+ }
16
+ export type Tone = 'default' | 'muted' | 'primary' | 'success' | 'warning' | 'danger';
17
+ export type Align = 'start' | 'center' | 'end' | 'stretch';
18
+ export type Justify = 'start' | 'center' | 'end' | 'between' | 'around';
19
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
20
+ export type FieldSize = 'sm' | 'md' | 'lg';
21
+ /**
22
+ * Shared layout/visual props.
23
+ * Dimension props (width, height, gap, padding, …) are numbers in logical units;
24
+ * the web preview maps them to px.
25
+ */
26
+ export interface CommonProps {
27
+ id?: string;
28
+ testId?: string;
29
+ ariaLabel?: string;
30
+ children?: ReactNode;
31
+ hidden?: boolean;
32
+ width?: number;
33
+ minWidth?: number;
34
+ maxWidth?: number;
35
+ height?: number;
36
+ minHeight?: number;
37
+ maxHeight?: number;
38
+ padding?: number;
39
+ margin?: number;
40
+ gap?: number;
41
+ radius?: number;
42
+ border?: boolean;
43
+ shadow?: boolean;
44
+ tone?: Tone;
45
+ }
46
+ export interface Option {
47
+ label: string;
48
+ value: string;
49
+ }
50
+ export interface ViewPartial<TProps> {
51
+ readonly __viewPartial: true;
52
+ readonly render: (props: TProps) => ReactNode;
53
+ }
54
+ export type ViewScreenProps<TViewModel> = {
55
+ vm: TViewModel;
56
+ actions?: ActionHandlers;
57
+ /** Optional theme id — propagated from App element for future multi-theme runtime. */
58
+ theme?: string;
59
+ };
@@ -0,0 +1,17 @@
1
+ export type ExtensionChildren = 'none' | 'any';
2
+ export type ExtensionRenderer = 'react-only' | 'all';
3
+ export type ExtensionPropertyType = 'string' | 'number' | 'boolean' | 'binding' | 'array' | 'object';
4
+ export interface ExtensionPropertyDefinition {
5
+ type: ExtensionPropertyType;
6
+ category: string;
7
+ }
8
+ export interface ExtensionDefinition {
9
+ description: string;
10
+ children: ExtensionChildren;
11
+ renderer: ExtensionRenderer;
12
+ properties: Record<string, ExtensionPropertyDefinition>;
13
+ }
14
+ export interface ExtensionRegistryDocument {
15
+ extensions: Record<string, ExtensionDefinition>;
16
+ }
17
+ export declare function loadExtensions(extensionsPath?: string): Promise<ExtensionRegistryDocument>;
@@ -0,0 +1,18 @@
1
+ import type { IrNode } from '../ir/types.js';
2
+ import type { ExtensionRegistryDocument } from './loadExtensions.js';
3
+ export interface ExtensionUsageValidationResult {
4
+ errors: string[];
5
+ warnings: string[];
6
+ }
7
+ export interface ExtensionUsageValidationOptions {
8
+ /** Binding targets from view-bindings.yaml (e.g. react, swiftui, compose). */
9
+ targets?: string[];
10
+ /** View or partial source path for error messages. */
11
+ source?: string;
12
+ }
13
+ export declare function validateExtensionUsage(node: IrNode, registry: ExtensionRegistryDocument, options?: ExtensionUsageValidationOptions): ExtensionUsageValidationResult;
14
+ /** Validate extension usage for a screen and its reachable partial IR roots. */
15
+ export declare function validateExtensionUsageForView(screen: IrNode, partialRoots: IrNode[], registry: ExtensionRegistryDocument, targets: string[], sources: {
16
+ screen: string;
17
+ partials: string[];
18
+ }): ExtensionUsageValidationResult;
@@ -0,0 +1,2 @@
1
+ export declare const CONTRACT_YAML: string;
2
+ export declare const CONTRACT_JSON_STR: string;
@@ -0,0 +1,28 @@
1
+ import { Command } from "commander";
2
+ export interface CommandHandlers {
3
+ compile: (options: {
4
+ config?: string;
5
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
6
+ renderReact: (options: {
7
+ config?: string;
8
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
9
+ renderBridge: (options: {
10
+ config?: string;
11
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
12
+ build: (options: {
13
+ config?: string;
14
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
15
+ contractsGenerate: (options: {
16
+ config?: string;
17
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
18
+ contractsCheck: (options: {
19
+ config?: string;
20
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
21
+ preview: (options: {
22
+ config?: string;
23
+ port?: string;
24
+ host?: string;
25
+ screen?: string;
26
+ }, parentOpts: Record<string, unknown>) => Promise<void>;
27
+ }
28
+ export declare function createProgram(handlers: CommandHandlers, version: string): Command;
@@ -0,0 +1,3 @@
1
+ import type { IrNode, IrViewRefNode } from './types.js';
2
+ export declare function collectViewRefs(node: IrNode): IrViewRefNode[];
3
+ export declare function viewRefKey(ref: IrViewRefNode): string;
@@ -0,0 +1,67 @@
1
+ /** Language-neutral View Contract intermediate representation. */
2
+ export interface ViewIrDocument {
3
+ version: 1;
4
+ /**
5
+ * Project-root-relative POSIX path of the .view.tsx this document was compiled from.
6
+ * Stamped into generated artifacts, so it must not depend on the working directory
7
+ * the compiler was invoked from.
8
+ */
9
+ source: string;
10
+ viewModel: string;
11
+ exportName: string;
12
+ root: IrNode;
13
+ /** True when this IR document represents a view() partial, not a screen(). */
14
+ isPartial?: boolean;
15
+ /** TypeScript props type for partial exports (e.g. "{ items: KpiCardViewModel[] }"). */
16
+ propsType?: string;
17
+ }
18
+ export type IrNode = IrComponentNode | IrTextNode | IrMapNode | IrFragmentNode | IrBinding | IrViewRefNode;
19
+ export interface IrComponentNode {
20
+ kind: 'component';
21
+ name: string;
22
+ props: Record<string, IrValue>;
23
+ children: IrNode[];
24
+ }
25
+ export interface IrTextNode {
26
+ kind: 'text';
27
+ value: string;
28
+ }
29
+ export interface IrFragmentNode {
30
+ kind: 'fragment';
31
+ children: IrNode[];
32
+ }
33
+ /** Reference to a view() partial — preserved instead of inlining at compile time. */
34
+ export interface IrViewRefNode {
35
+ kind: 'viewRef';
36
+ name: string;
37
+ sourcePath: string;
38
+ props: Record<string, IrValue>;
39
+ }
40
+ export interface IrMapNode {
41
+ kind: 'map';
42
+ source: IrBinding;
43
+ item: string;
44
+ key?: IrBinding;
45
+ body: IrNode;
46
+ }
47
+ export type IrValue = string | number | boolean | null | IrBinding | IrAction | IrLiteral | IrConcat | IrValue[];
48
+ export interface IrBinding {
49
+ kind: 'binding';
50
+ /** Dot path relative to vm or map item scope (e.g. "title", "projects.rows") */
51
+ path: string;
52
+ /** When inside a map callback, names the scope variable (e.g. "item", "row") */
53
+ scope?: string;
54
+ }
55
+ export interface IrAction {
56
+ kind: 'action';
57
+ name: string;
58
+ params?: Record<string, IrValue>;
59
+ }
60
+ export interface IrLiteral {
61
+ kind: 'literal';
62
+ value: unknown;
63
+ }
64
+ export interface IrConcat {
65
+ kind: 'concat';
66
+ parts: (string | IrBinding)[];
67
+ }
@@ -0,0 +1,2 @@
1
+ /** Installed package root (directory containing package.json). */
2
+ export declare function packageRoot(): string;
@@ -0,0 +1,2 @@
1
+ /** Project-relative POSIX path for generated artifacts (no absolute paths). */
2
+ export declare function relativeProjectPath(projectDir: string, absolutePath: string): string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Sole src/ module that may import or reference renderers/.
3
+ * All other src/ code must use loadRendererRegistry() or the path helpers here.
4
+ */
5
+ export type { RenderReactOptions } from '../../renderers/react/renderComponents.js';
6
+ type RendererRegistry = typeof import('../../renderers/registry.js');
7
+ /** Lazy-load the unified renderer registry (renderers/registry.ts). */
8
+ export declare function loadRendererRegistry(): Promise<RendererRegistry>;
9
+ export declare function reactTemplatesDir(customDir?: string): string;
10
+ export declare function reactRuntimeDir(): string;
11
+ export declare function reactStructuralCssPath(): string;
12
+ export declare function reactElementsYamlPath(): string;
13
+ export declare function isReactElementsYamlFile(filePath: string): boolean;
@@ -0,0 +1,15 @@
1
+ export declare const PREVIEW_SCREEN_PREFIX = "view-contracts:screen/";
2
+ export declare const PREVIEW_THEME_ID = "view-contracts:theme.css";
3
+ export declare function previewScreenModuleId(screenName: string): string;
4
+ export declare const PREVIEW_IMPORTS: {
5
+ readonly dispatch: "view-contracts:runtime/dispatch";
6
+ readonly style: "view-contracts:runtime/style";
7
+ readonly types: "view-contracts:runtime/types";
8
+ readonly styleHelpers: "view-contracts:runtime/style-helpers";
9
+ readonly contracts: "view-contracts:contracts";
10
+ readonly extensions: "view-contracts:extensions";
11
+ readonly mock: "view-contracts:preview/mock";
12
+ };
13
+ export declare function previewMockImport(screenName: string): string;
14
+ /** Compile views/*.view.tsx → lowered React source (same pipeline as build, not written to generated/). */
15
+ export declare function compilePreviewScreen(configPath: string, screenName: string): Promise<string>;
@@ -0,0 +1,9 @@
1
+ export interface PreviewAssets {
2
+ themeCss: string;
3
+ bundleJs: string;
4
+ version: number;
5
+ }
6
+ export declare function buildPreviewAssets(configPath: string, screenName: string, version: number): Promise<PreviewAssets & {
7
+ html: string;
8
+ }>;
9
+ export declare function resolvePreviewScreenName(configPath: string, requested?: string): Promise<string>;
@@ -0,0 +1,16 @@
1
+ import type { ViewContractsConfig } from '../config.js';
2
+ export declare const PREVIEW_MOCK_PREFIX = "view-contracts:preview/mock/";
3
+ export declare class PreviewMockError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ export declare function defaultPreviewMocksDir(): string;
7
+ export declare function previewMockModuleId(screenName: string): string;
8
+ export declare function previewMockExportName(screenName: string): string;
9
+ export declare function previewMockFilePath(configPath: string, config: ViewContractsConfig, screenName: string): string;
10
+ export declare function parsePreviewMockDocument(source: unknown, sourceLabel: string): Record<string, unknown>;
11
+ export declare function loadPreviewMockYaml(filePath: string): Promise<Record<string, unknown>>;
12
+ export declare function emitPreviewMockModule(screenName: string, data: Record<string, unknown>): string;
13
+ export declare function buildPreviewMockModule(configPath: string, config: ViewContractsConfig, screenName: string): Promise<string>;
14
+ export declare function isPreviewMockModuleId(id: string): string | null;
15
+ export declare function previewMocksRoot(configPath: string, config: ViewContractsConfig): Promise<string>;
16
+ export declare function pathExists(target: string): Promise<boolean>;
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface PreviewMockPluginOptions {
3
+ configPath: string;
4
+ }
5
+ /** Resolve view-contracts:preview/mock/<Screen> from views/preview/*.mock.yaml */
6
+ export declare function viewContractsPreviewMockPlugin(options: PreviewMockPluginOptions): Plugin;
@@ -0,0 +1,7 @@
1
+ export interface PreviewServerOptions {
2
+ configPath: string;
3
+ port?: number;
4
+ host?: string;
5
+ screen?: string;
6
+ }
7
+ export declare function runPreviewServer(options: PreviewServerOptions): Promise<void>;
@@ -0,0 +1,5 @@
1
+ /** Public npm entry — Vite preview plugins for consumer projects. */
2
+ export { viewContractsPreviewPlugin, previewRuntimeAliases, previewFsAllowPaths, } from './vitePlugin.js';
3
+ export type { ViewContractsPreviewPluginOptions } from './vitePlugin.js';
4
+ export { viewContractsPreviewMockPlugin } from './previewMockPlugin.js';
5
+ export type { PreviewMockPluginOptions } from './previewMockPlugin.js';
@@ -0,0 +1,13 @@
1
+ import type { Plugin } from 'vite';
2
+ export { viewContractsPreviewMockPlugin } from './previewMockPlugin.js';
3
+ export interface ViewContractsPreviewPluginOptions {
4
+ configPath: string;
5
+ }
6
+ export declare function viewContractsPreviewPlugin(options: ViewContractsPreviewPluginOptions): Plugin;
7
+ /** Vite resolve.alias entries for preview dev (uses installed view-contracts package root). */
8
+ export declare function previewRuntimeAliases(projectRootDir: string): Array<{
9
+ find: string | RegExp;
10
+ replacement: string;
11
+ }>;
12
+ /** Paths for vite server.fs.allow — project + installed view-contracts package. */
13
+ export declare function previewFsAllowPaths(viteDir: string, projectRootDir: string): string[];
@@ -0,0 +1,32 @@
1
+ import type { ViewIrDocument } from '../ir/types.js';
2
+ import type { ViewContractsConfig } from '../config.js';
3
+ import { type RenderReactOptions } from '../lib/rendererPaths.js';
4
+ export type { RenderReactOptions };
5
+ export declare function renderReactFromIr(doc: ViewIrDocument, outputPath: string, options: RenderReactOptions): Promise<void>;
6
+ export declare function renderReactPreviewBundle(screen: ViewIrDocument, partials: ViewIrDocument[], options: RenderReactOptions): Promise<string>;
7
+ export declare function partialReactOutputPath(reactDir: string, partial: ViewIrDocument): string;
8
+ export declare function renderReactRuntime(configPath: string, config: ViewContractsConfig): Promise<void>;
9
+ export declare function renderSwiftUIRuntime(configPath: string, config: ViewContractsConfig, bindings: import('../config.js').ViewBindingsFile, design?: {
10
+ theme: import('../design/types.js').ThemeIR;
11
+ tokens: import('../design/types.js').TokenIR;
12
+ }, compiledDocs?: {
13
+ screens: Map<string, ViewIrDocument>;
14
+ partials: ViewIrDocument[];
15
+ }): Promise<void>;
16
+ export declare function renderSwiftComponent(doc: ViewIrDocument, options: {
17
+ theme: import('../design/types.js').ThemeIR;
18
+ tokens: import('../design/types.js').TokenIR;
19
+ allowlistExtra?: string[];
20
+ }): Promise<string>;
21
+ export declare function renderComposeComponent(doc: ViewIrDocument, options: {
22
+ theme: import('../design/types.js').ThemeIR;
23
+ tokens: import('../design/types.js').TokenIR;
24
+ allowlistExtra?: string[];
25
+ }): Promise<string>;
26
+ export declare function renderComposeRuntime(configPath: string, config: ViewContractsConfig, bindings: import('../config.js').ViewBindingsFile, design?: {
27
+ theme: import('../design/types.js').ThemeIR;
28
+ tokens: import('../design/types.js').TokenIR;
29
+ }, compiledDocs?: {
30
+ screens: Map<string, ViewIrDocument>;
31
+ partials: ViewIrDocument[];
32
+ }): Promise<void>;
@@ -0,0 +1,6 @@
1
+ /** Load a YAML file into a typed object (target-agnostic). */
2
+ export declare function loadYamlFile<T>(path: string): Promise<T>;
3
+ /** Ensure element names exist in the DSL vocabulary allowlist. */
4
+ export declare function validateVocabularyElementNames(elementNames: Iterable<string>, allowed: ReadonlySet<string>, sourceLabel: string): void;
5
+ /** Ensure each map entry has required fields (e.g. HTML tag for lowering). */
6
+ export declare function validateMapEntryFields<T extends object>(entries: Record<string, T>, requiredKeys: (keyof T)[], sourceLabel: string): void;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Renderer-agnostic compile-time visual property merge.
3
+ * Precedence: instance > variant > themeDefault (right wins — no modifier accumulation).
4
+ */
5
+ import type { ThemeIR, TokenIR } from '../../design/types.js';
6
+ export type VisualPropSet = Record<string, string | number | boolean>;
7
+ export interface MergeVisualPropsInput {
8
+ elementName: string;
9
+ theme: ThemeIR;
10
+ tokens: TokenIR;
11
+ /** Compile-time literal variant name from View IR, if any. */
12
+ variantLiteral?: string;
13
+ /** Compile-time literal visual props from the View IR node (DSL prop names). */
14
+ instanceLiterals: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * Merge theme default, variant, and instance visual props for one vocabulary element.
18
+ * Later layers override earlier ones for the same property key (override, not accumulate).
19
+ */
20
+ export declare function mergeVisualProps(input: MergeVisualPropsInput): VisualPropSet;
@@ -0,0 +1,2 @@
1
+ /** Render a Handlebars template from a target-specific templates directory. */
2
+ export declare function renderTemplate(templatesDir: string, templateName: string, data: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,2 @@
1
+ import type { ViewBindingsFile } from '../config.js';
2
+ export declare function scaffoldStandaloneApp(configPath: string, bindings: ViewBindingsFile): Promise<void>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * DSL Vocabulary Catalog — Single Source of Truth.
3
+ *
4
+ * All vocabulary metadata lives here. Program code imports directly.
5
+ * The schema generator reads this to produce spec/ui-dsl.schema.json (user-facing).
6
+ */
7
+ export type LoweringMode = "inline-css" | "class-name" | "attribute" | "none";
8
+ export interface PropertyDef {
9
+ readonly type: string | readonly string[];
10
+ readonly category: string;
11
+ readonly lowering: LoweringMode;
12
+ readonly enum?: string;
13
+ readonly description?: string;
14
+ readonly notes?: string;
15
+ }
16
+ export interface ElementDef {
17
+ readonly description: string;
18
+ readonly tier: "core" | "optional" | "extension";
19
+ readonly category: string;
20
+ readonly notes?: string;
21
+ /** Accepted property names — sole authority for property-element binding. */
22
+ readonly properties: readonly string[];
23
+ readonly children: {
24
+ readonly kind: "any" | "none" | "single" | "text" | "list";
25
+ readonly items?: readonly string[];
26
+ };
27
+ }
28
+ export declare const TOKEN_CATALOG: {
29
+ readonly role: readonly ["button", "link", "heading", "list", "listitem", "main", "dialog", "status"];
30
+ readonly widthSize: readonly ["wrap", "fill"];
31
+ readonly heightSize: readonly ["wrap", "fill"];
32
+ readonly align: readonly ["start", "center", "end", "stretch"];
33
+ readonly justify: readonly ["start", "center", "end", "spaceBetween", "spaceAround", "spaceEvenly"];
34
+ readonly contentAlign: readonly ["topStart", "top", "topEnd", "start", "center", "end", "bottomStart", "bottom", "bottomEnd"];
35
+ readonly axis: readonly ["vertical", "horizontal"];
36
+ readonly direction: readonly ["ltr", "rtl", "system"];
37
+ readonly scroll: readonly ["none", "vertical", "horizontal", "both"];
38
+ readonly border: readonly ["none"];
39
+ readonly shadow: readonly ["none", "sm", "md", "lg"];
40
+ readonly textAlign: readonly ["start", "center", "end"];
41
+ readonly lineLimit: readonly ["none"];
42
+ readonly textOverflow: readonly ["clip", "ellipsis"];
43
+ readonly fontWeight: readonly ["regular", "medium", "bold"];
44
+ readonly imageFit: readonly ["contain", "cover", "fill", "none"];
45
+ readonly keyboardType: readonly ["text", "number", "email", "url", "password", "tel"];
46
+ readonly inputType: readonly ["text", "password", "email", "url", "tel"];
47
+ readonly clip: readonly ["none", "bounds", "shape"];
48
+ };
49
+ export declare const PROPERTY_CATALOG: Record<string, PropertyDef>;
50
+ export declare const ELEMENT_CATALOG: Record<string, ElementDef>;
51
+ export declare const ALLOWED_COMPONENTS: Set<string>;
52
+ export declare const LOWERING_STYLE_PROPERTIES: Set<string>;
53
+ export declare const CLASS_NAME_PROPERTIES: Set<string>;
54
+ export declare function elementProps(elementName: string): readonly string[];
55
+ /** Check if an element accepts a property. Element.properties is the sole authority. */
56
+ export declare function propertyAppliesTo(propName: string, elementName: string): boolean;
@@ -0,0 +1,5 @@
1
+ import type { ViewIrDocument } from '../ir/types.js';
2
+ import { type PropertyDef } from '../schema/dsl-catalog.js';
3
+ export declare function validateViewProps(docs: Iterable<ViewIrDocument>, allowlistExtra?: string[]): Promise<void>;
4
+ /** @internal Exported for tests. */
5
+ export declare function isVisualProperty(def: PropertyDef | undefined): boolean;