@visual-platform/define 0.0.0-stage → 0.1.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.
@@ -0,0 +1,85 @@
1
+ /** Field kinds understood by the editor (blueprint 23, 32) and the runtime (style bindings). */
2
+ export type FieldDef = {
3
+ type: "text" | "textarea";
4
+ label?: string;
5
+ required?: boolean;
6
+ maxLength?: number;
7
+ responsive?: false;
8
+ inline?: boolean;
9
+ } | {
10
+ type: "number";
11
+ label?: string;
12
+ min?: number;
13
+ max?: number;
14
+ responsive?: boolean;
15
+ styleBinding?: string;
16
+ } | {
17
+ type: "boolean";
18
+ label?: string;
19
+ responsive?: boolean;
20
+ styleBinding?: string;
21
+ } | {
22
+ type: "select";
23
+ label?: string;
24
+ options: readonly string[];
25
+ responsive?: boolean;
26
+ styleBinding?: string;
27
+ cssValues?: Record<string, string>;
28
+ } | {
29
+ type: "token";
30
+ label?: string;
31
+ tokenType: "spacing" | "color" | "radius" | "font.size";
32
+ responsive?: boolean;
33
+ styleBinding?: string;
34
+ } | {
35
+ type: "link";
36
+ label?: string;
37
+ required?: boolean;
38
+ } | {
39
+ type: "image";
40
+ label?: string;
41
+ required?: boolean;
42
+ } | {
43
+ type: "icon";
44
+ label?: string;
45
+ required?: boolean;
46
+ } | {
47
+ type: "slot";
48
+ label?: string;
49
+ allow?: readonly string[];
50
+ };
51
+ export type ComponentDefinition<F extends Record<string, FieldDef> = Record<string, FieldDef>> = {
52
+ /** Stable PascalCase type stored in PageDocument nodes. */
53
+ type: string;
54
+ label: string;
55
+ category: string;
56
+ description?: string;
57
+ definitionVersion: number;
58
+ fields: F;
59
+ defaultProps: Partial<Record<NoInfer<keyof F & string>, unknown>>;
60
+ /** Editor canvas hints for customer components (blueprint 31 §6). */
61
+ schematic?: {
62
+ layout?: "banner" | "media-left" | "stack";
63
+ primaryField?: NoInfer<keyof F & string>;
64
+ imageField?: NoInfer<keyof F & string>;
65
+ };
66
+ /** AI usage hint (blueprint 34). */
67
+ ai?: {
68
+ enabled: boolean;
69
+ description: string;
70
+ };
71
+ /** Events this element can emit, bindable to app event names in Studio (ADR-032). */
72
+ events?: Partial<Record<"click" | "change" | "blur" | "enter" | "submit" | "reset" | "toggle", {
73
+ label: string;
74
+ payload?: string;
75
+ }>>;
76
+ };
77
+ export declare function defineComponent<const F extends Record<string, FieldDef>>(def: ComponentDefinition<F>): ComponentDefinition<F>;
78
+ export type StyleBinding = {
79
+ cssVar: string;
80
+ values?: Record<string, string>;
81
+ };
82
+ /** Fields that may carry `$responsive` values and map to CSS custom properties at runtime. */
83
+ export declare function styleBindings(def: ComponentDefinition<Record<string, FieldDef>>): Record<string, StyleBinding>;
84
+ export * from "./schema.js";
85
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3H;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3G;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC/I;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACvI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI;IAC/F,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;IACV,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAClE,qEAAqE;IACrE,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;KAAE,CAAC;IAC7I,oCAAoC;IACpC,EAAE,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,qFAAqF;IACrF,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CACtI,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAG7H;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAE/E,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAQ9G;AACD,cAAc,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ export function defineComponent(def) {
2
+ if (!/^[A-Z][A-Za-z0-9]*$/.test(def.type))
3
+ throw new Error(`component type must be PascalCase: ${def.type}`);
4
+ return def;
5
+ }
6
+ /** Fields that may carry `$responsive` values and map to CSS custom properties at runtime. */
7
+ export function styleBindings(def) {
8
+ const out = {};
9
+ for (const [name, f] of Object.entries(def.fields)) {
10
+ if ("styleBinding" in f && f.styleBinding) {
11
+ out[name] = { cssVar: f.styleBinding, ...("cssValues" in f && f.cssValues ? { values: f.cssValues } : {}) };
12
+ }
13
+ }
14
+ return out;
15
+ }
16
+ export * from "./schema.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6BA,MAAM,UAAU,eAAe,CAA2C,GAA2B;IACnG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7G,OAAO,GAAG,CAAC;AACb,CAAC;AAID,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,GAAkD;IAC9E,MAAM,GAAG,GAAiC,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAyB,EAAE,CAAC;QAC3E,IAAI,cAAc,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9G,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,cAAc,aAAa,CAAC"}
@@ -0,0 +1,160 @@
1
+ import { z } from "zod";
2
+ /** Runtime schema for FieldDef — the server validates every pushed definition (blueprint 23 §4). */
3
+ export declare const FieldDefSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ label: z.ZodOptional<z.ZodString>;
5
+ type: z.ZodEnum<{
6
+ text: "text";
7
+ textarea: "textarea";
8
+ }>;
9
+ required: z.ZodOptional<z.ZodBoolean>;
10
+ maxLength: z.ZodOptional<z.ZodNumber>;
11
+ responsive: z.ZodOptional<z.ZodLiteral<false>>;
12
+ inline: z.ZodOptional<z.ZodBoolean>;
13
+ }, z.core.$strict>, z.ZodObject<{
14
+ label: z.ZodOptional<z.ZodString>;
15
+ type: z.ZodLiteral<"number">;
16
+ min: z.ZodOptional<z.ZodNumber>;
17
+ max: z.ZodOptional<z.ZodNumber>;
18
+ responsive: z.ZodOptional<z.ZodBoolean>;
19
+ styleBinding: z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strict>, z.ZodObject<{
21
+ label: z.ZodOptional<z.ZodString>;
22
+ type: z.ZodLiteral<"boolean">;
23
+ responsive: z.ZodOptional<z.ZodBoolean>;
24
+ styleBinding: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strict>, z.ZodObject<{
26
+ label: z.ZodOptional<z.ZodString>;
27
+ type: z.ZodLiteral<"select">;
28
+ options: z.ZodArray<z.ZodString>;
29
+ responsive: z.ZodOptional<z.ZodBoolean>;
30
+ styleBinding: z.ZodOptional<z.ZodString>;
31
+ cssValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
32
+ }, z.core.$strict>, z.ZodObject<{
33
+ label: z.ZodOptional<z.ZodString>;
34
+ type: z.ZodLiteral<"token">;
35
+ tokenType: z.ZodEnum<{
36
+ color: "color";
37
+ "font.size": "font.size";
38
+ radius: "radius";
39
+ spacing: "spacing";
40
+ }>;
41
+ responsive: z.ZodOptional<z.ZodBoolean>;
42
+ styleBinding: z.ZodOptional<z.ZodString>;
43
+ }, z.core.$strict>, z.ZodObject<{
44
+ label: z.ZodOptional<z.ZodString>;
45
+ type: z.ZodLiteral<"link">;
46
+ required: z.ZodOptional<z.ZodBoolean>;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ label: z.ZodOptional<z.ZodString>;
49
+ type: z.ZodLiteral<"image">;
50
+ required: z.ZodOptional<z.ZodBoolean>;
51
+ }, z.core.$strict>, z.ZodObject<{
52
+ label: z.ZodOptional<z.ZodString>;
53
+ type: z.ZodLiteral<"icon">;
54
+ required: z.ZodOptional<z.ZodBoolean>;
55
+ }, z.core.$strict>, z.ZodObject<{
56
+ label: z.ZodOptional<z.ZodString>;
57
+ type: z.ZodLiteral<"slot">;
58
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
+ }, z.core.$strict>], "type">;
60
+ export declare const ComponentDefinitionSchema: z.ZodObject<{
61
+ type: z.ZodString;
62
+ label: z.ZodString;
63
+ category: z.ZodString;
64
+ description: z.ZodOptional<z.ZodString>;
65
+ definitionVersion: z.ZodNumber;
66
+ fields: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
67
+ label: z.ZodOptional<z.ZodString>;
68
+ type: z.ZodEnum<{
69
+ text: "text";
70
+ textarea: "textarea";
71
+ }>;
72
+ required: z.ZodOptional<z.ZodBoolean>;
73
+ maxLength: z.ZodOptional<z.ZodNumber>;
74
+ responsive: z.ZodOptional<z.ZodLiteral<false>>;
75
+ inline: z.ZodOptional<z.ZodBoolean>;
76
+ }, z.core.$strict>, z.ZodObject<{
77
+ label: z.ZodOptional<z.ZodString>;
78
+ type: z.ZodLiteral<"number">;
79
+ min: z.ZodOptional<z.ZodNumber>;
80
+ max: z.ZodOptional<z.ZodNumber>;
81
+ responsive: z.ZodOptional<z.ZodBoolean>;
82
+ styleBinding: z.ZodOptional<z.ZodString>;
83
+ }, z.core.$strict>, z.ZodObject<{
84
+ label: z.ZodOptional<z.ZodString>;
85
+ type: z.ZodLiteral<"boolean">;
86
+ responsive: z.ZodOptional<z.ZodBoolean>;
87
+ styleBinding: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strict>, z.ZodObject<{
89
+ label: z.ZodOptional<z.ZodString>;
90
+ type: z.ZodLiteral<"select">;
91
+ options: z.ZodArray<z.ZodString>;
92
+ responsive: z.ZodOptional<z.ZodBoolean>;
93
+ styleBinding: z.ZodOptional<z.ZodString>;
94
+ cssValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
95
+ }, z.core.$strict>, z.ZodObject<{
96
+ label: z.ZodOptional<z.ZodString>;
97
+ type: z.ZodLiteral<"token">;
98
+ tokenType: z.ZodEnum<{
99
+ color: "color";
100
+ "font.size": "font.size";
101
+ radius: "radius";
102
+ spacing: "spacing";
103
+ }>;
104
+ responsive: z.ZodOptional<z.ZodBoolean>;
105
+ styleBinding: z.ZodOptional<z.ZodString>;
106
+ }, z.core.$strict>, z.ZodObject<{
107
+ label: z.ZodOptional<z.ZodString>;
108
+ type: z.ZodLiteral<"link">;
109
+ required: z.ZodOptional<z.ZodBoolean>;
110
+ }, z.core.$strict>, z.ZodObject<{
111
+ label: z.ZodOptional<z.ZodString>;
112
+ type: z.ZodLiteral<"image">;
113
+ required: z.ZodOptional<z.ZodBoolean>;
114
+ }, z.core.$strict>, z.ZodObject<{
115
+ label: z.ZodOptional<z.ZodString>;
116
+ type: z.ZodLiteral<"icon">;
117
+ required: z.ZodOptional<z.ZodBoolean>;
118
+ }, z.core.$strict>, z.ZodObject<{
119
+ label: z.ZodOptional<z.ZodString>;
120
+ type: z.ZodLiteral<"slot">;
121
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
122
+ }, z.core.$strict>], "type">>;
123
+ defaultProps: z.ZodRecord<z.ZodString, z.ZodUnknown>;
124
+ schematic: z.ZodOptional<z.ZodObject<{
125
+ layout: z.ZodOptional<z.ZodEnum<{
126
+ banner: "banner";
127
+ "media-left": "media-left";
128
+ stack: "stack";
129
+ }>>;
130
+ primaryField: z.ZodOptional<z.ZodString>;
131
+ imageField: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strict>>;
133
+ ai: z.ZodOptional<z.ZodObject<{
134
+ enabled: z.ZodBoolean;
135
+ description: z.ZodString;
136
+ }, z.core.$strict>>;
137
+ events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
138
+ blur: "blur";
139
+ change: "change";
140
+ click: "click";
141
+ enter: "enter";
142
+ reset: "reset";
143
+ submit: "submit";
144
+ toggle: "toggle";
145
+ }> & z.core.$partial, z.ZodObject<{
146
+ label: z.ZodString;
147
+ payload: z.ZodOptional<z.ZodString>;
148
+ }, z.core.$strict>>>;
149
+ }, z.core.$strict>;
150
+ export type ComponentDefinitionInput = z.infer<typeof ComponentDefinitionSchema>;
151
+ /** Validate a set of definitions together (unique types, no clash with reserved built-ins). */
152
+ export declare function validateDefinitions(defs: unknown[], reservedTypes?: readonly string[]): {
153
+ ok: boolean;
154
+ errors: {
155
+ type?: string | undefined;
156
+ path: string;
157
+ message: string;
158
+ }[];
159
+ };
160
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,oGAAoG;AACpG,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAUzB,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAwBlC,CAAC;AAEL,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAEjF,+FAA+F;AAC/F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,aAAa,GAAE,SAAS,MAAM,EAAO;;;eACjE,MAAM,GAAG,SAAS;cAAQ,MAAM;iBAAW,MAAM;;EAazE"}
package/dist/schema.js ADDED
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ const base = { label: z.string().max(60).optional() };
3
+ const cssVar = z.string().regex(/^--[a-z0-9-]+$/, "styleBinding must be a CSS custom property like --card-gap");
4
+ /** Runtime schema for FieldDef — the server validates every pushed definition (blueprint 23 §4). */
5
+ export const FieldDefSchema = z.discriminatedUnion("type", [
6
+ z.object({ type: z.enum(["text", "textarea"]), ...base, required: z.boolean().optional(), maxLength: z.number().int().positive().optional(), responsive: z.literal(false).optional(), inline: z.boolean().optional() }).strict(),
7
+ z.object({ type: z.literal("number"), ...base, min: z.number().optional(), max: z.number().optional(), responsive: z.boolean().optional(), styleBinding: cssVar.optional() }).strict(),
8
+ z.object({ type: z.literal("boolean"), ...base, responsive: z.boolean().optional(), styleBinding: cssVar.optional() }).strict(),
9
+ z.object({ type: z.literal("select"), ...base, options: z.array(z.string().min(1)).min(1).max(50), responsive: z.boolean().optional(), styleBinding: cssVar.optional(), cssValues: z.record(z.string(), z.string().regex(/^[#a-zA-Z0-9.%()\s,-]+$/)).optional() }).strict(),
10
+ z.object({ type: z.literal("token"), ...base, tokenType: z.enum(["spacing", "color", "radius", "font.size"]), responsive: z.boolean().optional(), styleBinding: cssVar.optional() }).strict(),
11
+ z.object({ type: z.literal("link"), ...base, required: z.boolean().optional() }).strict(),
12
+ z.object({ type: z.literal("image"), ...base, required: z.boolean().optional() }).strict(),
13
+ z.object({ type: z.literal("icon"), ...base, required: z.boolean().optional() }).strict(),
14
+ z.object({ type: z.literal("slot"), ...base, allow: z.array(z.string()).optional() }).strict(),
15
+ ]);
16
+ export const ComponentDefinitionSchema = z
17
+ .object({
18
+ type: z.string().regex(/^[A-Z][A-Za-z0-9]*$/, "type must be PascalCase"),
19
+ label: z.string().min(1).max(60),
20
+ category: z.string().min(1).max(40),
21
+ description: z.string().max(500).optional(),
22
+ definitionVersion: z.number().int().positive(),
23
+ fields: z.record(z.string().regex(/^[a-z][A-Za-z0-9]*$/, "field names are camelCase"), FieldDefSchema).refine((f) => Object.keys(f).length <= 40, "at most 40 fields"),
24
+ defaultProps: z.record(z.string(), z.unknown()),
25
+ schematic: z.object({ layout: z.enum(["banner", "media-left", "stack"]).optional(), primaryField: z.string().optional(), imageField: z.string().optional() }).strict().optional(),
26
+ ai: z.object({ enabled: z.boolean(), description: z.string().max(500) }).strict().optional(),
27
+ events: z.partialRecord(z.enum(["click", "change", "blur", "enter", "submit", "reset", "toggle"]), z.object({ label: z.string().min(1).max(60), payload: z.string().max(200).optional() }).strict()).optional(),
28
+ })
29
+ .strict()
30
+ .superRefine((d, ctx) => {
31
+ for (const k of Object.keys(d.defaultProps))
32
+ if (!(k in d.fields))
33
+ ctx.addIssue({ code: "custom", path: ["defaultProps", k], message: `default for unknown field "${k}"` });
34
+ for (const k of ["primaryField", "imageField"]) {
35
+ const f = d.schematic?.[k];
36
+ if (f && !(f in d.fields))
37
+ ctx.addIssue({ code: "custom", path: ["schematic", k], message: `unknown field "${f}"` });
38
+ }
39
+ for (const [name, f] of Object.entries(d.fields)) {
40
+ if ("styleBinding" in f && f.styleBinding && !("responsive" in f))
41
+ continue;
42
+ if (f.type === "select" && f.cssValues)
43
+ for (const o of Object.keys(f.cssValues))
44
+ if (!f.options.includes(o))
45
+ ctx.addIssue({ code: "custom", path: ["fields", name, "cssValues", o], message: `"${o}" is not an option` });
46
+ }
47
+ });
48
+ /** Validate a set of definitions together (unique types, no clash with reserved built-ins). */
49
+ export function validateDefinitions(defs, reservedTypes = []) {
50
+ const errors = [];
51
+ const seen = new Set();
52
+ defs.forEach((d, i) => {
53
+ const r = ComponentDefinitionSchema.safeParse(d);
54
+ if (!r.success) {
55
+ for (const issue of r.error.issues)
56
+ errors.push({ type: d?.type, path: `[${i}].${issue.path.join(".")}`, message: issue.message });
57
+ return;
58
+ }
59
+ if (seen.has(r.data.type))
60
+ errors.push({ type: r.data.type, path: `[${i}].type`, message: "duplicate type" });
61
+ if (reservedTypes.includes(r.data.type))
62
+ errors.push({ type: r.data.type, path: `[${i}].type`, message: "type is reserved by a built-in component" });
63
+ seen.add(r.data.type);
64
+ });
65
+ return { ok: errors.length === 0, errors };
66
+ }
67
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,35 @@
1
1
  {
2
2
  "name": "@visual-platform/define",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Visual Page Platform — define your own components (fields, slots, events) for the editor.",
5
+ "type": "module",
6
+ "license": "UNLICENSED",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "dependencies": {
21
+ "@visual-platform/contracts": "^0.1.0",
22
+ "zod": "^4.6.7"
23
+ },
24
+ "devDependencies": {
25
+ "@visual-platform/typescript-config": "0.0.0",
26
+ "typescript": "^7.0.2",
27
+ "vitest": "^5.1.0"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.build.json",
31
+ "typecheck": "tsc -p tsconfig.json --noEmit",
32
+ "test": "vitest run --passWithNoTests",
33
+ "clean": "rm -rf dist .turbo"
34
+ }
6
35
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.