@u-krupaveho-kraba/form-schemas 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.
- package/index.js +25 -0
- package/package.json +29 -0
- package/schema/campaign.schema.json +4686 -0
- package/schemas/campaign.js +64 -0
- package/schemas/element.js +88 -0
- package/schemas/elementProperties.js +117 -0
- package/schemas/form.js +33 -0
- package/schemas/formDisplay.js +61 -0
- package/schemas/helpers.js +12 -0
- package/schemas/step.js +15 -0
- package/types/index.d.ts +18 -0
- package/types/schemas/campaign.d.ts +15172 -0
- package/types/schemas/element.d.ts +1503 -0
- package/types/schemas/elementProperties.d.ts +346 -0
- package/types/schemas/form.d.ts +6027 -0
- package/types/schemas/formDisplay.d.ts +278 -0
- package/types/schemas/helpers.d.ts +9 -0
- package/types/schemas/step.d.ts +693 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { FormSchema } from "./form.js";
|
|
3
|
+
export const FormReferenceSchema = z.object({
|
|
4
|
+
ref: z.string(),
|
|
5
|
+
});
|
|
6
|
+
export const CampaignFormDefinitionSchema = z.union([FormSchema, FormReferenceSchema]);
|
|
7
|
+
export const VariantSchema = z.object({
|
|
8
|
+
id: z.string(),
|
|
9
|
+
name: z.string(),
|
|
10
|
+
definition: CampaignFormDefinitionSchema,
|
|
11
|
+
trafficWeight: z.number(),
|
|
12
|
+
});
|
|
13
|
+
export const FrequencyTargetingSchema = z.object({
|
|
14
|
+
minVisitCount: z.optional(z.number()),
|
|
15
|
+
maxDisplays: z.optional(z.number()),
|
|
16
|
+
minHoursBetweenDisplays: z.optional(z.number()),
|
|
17
|
+
});
|
|
18
|
+
export const CampaignTargetingSchema = z.object({
|
|
19
|
+
urlPatterns: z.optional(z.array(z.string())),
|
|
20
|
+
frequency: z.optional(FrequencyTargetingSchema),
|
|
21
|
+
});
|
|
22
|
+
export const CampaignScheduleSchema = z.object({
|
|
23
|
+
startsAt: z.optional(z.string()),
|
|
24
|
+
endsAt: z.optional(z.string()),
|
|
25
|
+
});
|
|
26
|
+
export const ImmediateTriggerSchema = z.object({ type: z.literal("immediate") });
|
|
27
|
+
export const DelayTriggerSchema = z.object({ type: z.literal("delay"), seconds: z.number() });
|
|
28
|
+
export const ScrollDepthTriggerSchema = z.object({
|
|
29
|
+
type: z.literal("scroll_depth"),
|
|
30
|
+
percent: z.number(),
|
|
31
|
+
});
|
|
32
|
+
export const ExitIntentTriggerSchema = z.object({ type: z.literal("exit_intent") });
|
|
33
|
+
export const TriggerConditionSchema = z.discriminatedUnion("type", [
|
|
34
|
+
ImmediateTriggerSchema,
|
|
35
|
+
DelayTriggerSchema,
|
|
36
|
+
ScrollDepthTriggerSchema,
|
|
37
|
+
ExitIntentTriggerSchema,
|
|
38
|
+
]);
|
|
39
|
+
export const CampaignSchema = z.object({
|
|
40
|
+
id: z.string(),
|
|
41
|
+
name: z.string(),
|
|
42
|
+
version: z.literal(1),
|
|
43
|
+
targeting: CampaignTargetingSchema,
|
|
44
|
+
schedule: z.optional(CampaignScheduleSchema),
|
|
45
|
+
trigger: TriggerConditionSchema,
|
|
46
|
+
variants: z.array(VariantSchema),
|
|
47
|
+
});
|
|
48
|
+
// Ticket 113: field names match the real, already-deployed Ecomail publish
|
|
49
|
+
// job's actual index-entry output, not FormReferenceSchema's {ref} shape.
|
|
50
|
+
export const CampaignEntryRefSchema = z.object({
|
|
51
|
+
id: z.string(),
|
|
52
|
+
url: z.string(),
|
|
53
|
+
rules: z.optional(z.unknown()),
|
|
54
|
+
});
|
|
55
|
+
export const CampaignEntrySchema = z.union([CampaignEntryRefSchema, CampaignSchema]);
|
|
56
|
+
// The campaigns.json v1 envelope (ADR 0008) -- see the CampaignsFile doc
|
|
57
|
+
// comment in form-shared/src/types/campaign.ts for how this relates to the
|
|
58
|
+
// shipped index+per-file HTTP delivery split.
|
|
59
|
+
export const CampaignsFileSchema = z.object({
|
|
60
|
+
formatVersion: z.literal(1),
|
|
61
|
+
account: z.string(),
|
|
62
|
+
website: z.string(),
|
|
63
|
+
campaigns: z.array(CampaignSchema),
|
|
64
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { BaseElementPropertiesSchema, ButtonElementPropertiesSchema, CheckboxElementPropertiesSchema, HtmlElementPropertiesSchema, ImageElementPropertiesSchema, RadioElementPropertiesSchema, SelectElementPropertiesSchema, SpacerElementPropertiesSchema, TextElementPropertiesSchema, TextInputElementPropertiesSchema, } from "./elementProperties.js";
|
|
3
|
+
export const ElementTypeSchema = z.enum([
|
|
4
|
+
"text_input",
|
|
5
|
+
"text",
|
|
6
|
+
"block",
|
|
7
|
+
"button",
|
|
8
|
+
"image",
|
|
9
|
+
"column",
|
|
10
|
+
"checkbox",
|
|
11
|
+
"radio",
|
|
12
|
+
"select",
|
|
13
|
+
"html",
|
|
14
|
+
"spacer",
|
|
15
|
+
]);
|
|
16
|
+
// mirrors the Element<T, P> generic helper in form-shared/types/element.ts.
|
|
17
|
+
// Takes a raw shape (not a ZodMiniObject) — matching zod's own `extend()`
|
|
18
|
+
// signature — because spreading a generic ZodMiniObject's `.shape` loses the
|
|
19
|
+
// specific property types under TS's return-type inference; a raw shape
|
|
20
|
+
// generic preserves them.
|
|
21
|
+
function elementSchema(type, propertiesShape) {
|
|
22
|
+
return z.object({
|
|
23
|
+
id: z.string(),
|
|
24
|
+
type: z.literal(type),
|
|
25
|
+
properties: z.object({
|
|
26
|
+
...BaseElementPropertiesSchema.shape,
|
|
27
|
+
...propertiesShape,
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export const ButtonElementSchema = elementSchema("button", ButtonElementPropertiesSchema.shape);
|
|
32
|
+
export const TextElementSchema = elementSchema("text", TextElementPropertiesSchema.shape);
|
|
33
|
+
export const TextInputElementSchema = elementSchema("text_input", TextInputElementPropertiesSchema.shape);
|
|
34
|
+
export const ImageElementSchema = elementSchema("image", ImageElementPropertiesSchema.shape);
|
|
35
|
+
export const CheckboxElementSchema = elementSchema("checkbox", CheckboxElementPropertiesSchema.shape);
|
|
36
|
+
export const RadioElementSchema = elementSchema("radio", RadioElementPropertiesSchema.shape);
|
|
37
|
+
export const SelectElementSchema = elementSchema("select", SelectElementPropertiesSchema.shape);
|
|
38
|
+
export const HtmlElementSchema = elementSchema("html", HtmlElementPropertiesSchema.shape);
|
|
39
|
+
export const SpacerElementSchema = elementSchema("spacer", SpacerElementPropertiesSchema.shape);
|
|
40
|
+
export const BlockColumnElementSchema = z.object({
|
|
41
|
+
id: z.string(),
|
|
42
|
+
type: z.literal("column"),
|
|
43
|
+
get properties() {
|
|
44
|
+
return z.object({
|
|
45
|
+
...BaseElementPropertiesSchema.shape,
|
|
46
|
+
width: z.number(),
|
|
47
|
+
elements: z.array(FormElementSchema),
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const blockLayoutBase = {
|
|
52
|
+
...BaseElementPropertiesSchema.shape,
|
|
53
|
+
};
|
|
54
|
+
export const BlockElementPropertiesSchema = z.discriminatedUnion("block_type", [
|
|
55
|
+
z.object({
|
|
56
|
+
...blockLayoutBase,
|
|
57
|
+
block_type: z.literal("single_column"),
|
|
58
|
+
columns: z.tuple([BlockColumnElementSchema]),
|
|
59
|
+
}),
|
|
60
|
+
z.object({
|
|
61
|
+
...blockLayoutBase,
|
|
62
|
+
block_type: z.literal("double_column"),
|
|
63
|
+
columns: z.tuple([BlockColumnElementSchema, BlockColumnElementSchema]),
|
|
64
|
+
}),
|
|
65
|
+
z.object({
|
|
66
|
+
...blockLayoutBase,
|
|
67
|
+
block_type: z.literal("triple_column"),
|
|
68
|
+
columns: z.tuple([BlockColumnElementSchema, BlockColumnElementSchema, BlockColumnElementSchema]),
|
|
69
|
+
}),
|
|
70
|
+
]);
|
|
71
|
+
export const BlockElementSchema = z.object({
|
|
72
|
+
id: z.string(),
|
|
73
|
+
type: z.literal("block"),
|
|
74
|
+
properties: BlockElementPropertiesSchema,
|
|
75
|
+
});
|
|
76
|
+
export const FormElementSchema = z.discriminatedUnion("type", [
|
|
77
|
+
ButtonElementSchema,
|
|
78
|
+
TextElementSchema,
|
|
79
|
+
TextInputElementSchema,
|
|
80
|
+
ImageElementSchema,
|
|
81
|
+
CheckboxElementSchema,
|
|
82
|
+
RadioElementSchema,
|
|
83
|
+
SelectElementSchema,
|
|
84
|
+
BlockElementSchema,
|
|
85
|
+
BlockColumnElementSchema,
|
|
86
|
+
HtmlElementSchema,
|
|
87
|
+
SpacerElementSchema,
|
|
88
|
+
]);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { DistancePropertySchema, HexSchema } from "./helpers.js";
|
|
3
|
+
import { FormBorderSchema } from "./formDisplay.js";
|
|
4
|
+
export const BaseContainerPropertiesSchema = z.object({
|
|
5
|
+
hideOnMobile: z.boolean(),
|
|
6
|
+
hideOnDesktop: z.boolean(),
|
|
7
|
+
padding: z.optional(DistancePropertySchema),
|
|
8
|
+
border: z.optional(FormBorderSchema),
|
|
9
|
+
backgroundColor: z.optional(z.string()),
|
|
10
|
+
});
|
|
11
|
+
export const BaseElementPropertiesSchema = z.object({
|
|
12
|
+
...BaseContainerPropertiesSchema.shape,
|
|
13
|
+
margin: z.optional(DistancePropertySchema),
|
|
14
|
+
});
|
|
15
|
+
export const LinkTargetSchema = z.object({
|
|
16
|
+
url: z.string(),
|
|
17
|
+
openInNewTab: z.optional(z.boolean()),
|
|
18
|
+
});
|
|
19
|
+
export const ButtonActionSchema = z.discriminatedUnion("type", [
|
|
20
|
+
z.object({ type: z.literal("next_step") }),
|
|
21
|
+
z.object({ type: z.literal("send") }),
|
|
22
|
+
z.object({ type: z.literal("close") }),
|
|
23
|
+
z.object({ type: z.literal("jump_to"), targetStepId: z.string() }),
|
|
24
|
+
z.object({ type: z.literal("redirect"), ...LinkTargetSchema.shape }),
|
|
25
|
+
z.object({ type: z.literal("call"), phoneNumber: z.string() }),
|
|
26
|
+
]);
|
|
27
|
+
export const ButtonWidthSchema = z.union([
|
|
28
|
+
z.literal("full"),
|
|
29
|
+
z.literal("auto"),
|
|
30
|
+
z.object({ unit: z.enum(["px", "%"]), value: z.number() }),
|
|
31
|
+
]);
|
|
32
|
+
export const ButtonAlignSchema = z.enum(["left", "center", "right"]);
|
|
33
|
+
export const ButtonElementPropertiesSchema = z.object({
|
|
34
|
+
text: z.string(),
|
|
35
|
+
action: ButtonActionSchema,
|
|
36
|
+
fontColor: z.optional(z.string()),
|
|
37
|
+
fontFamily: z.optional(z.string()),
|
|
38
|
+
fontSize: z.optional(z.number()),
|
|
39
|
+
fontWeight: z.optional(z.enum(["normal", "bold"])),
|
|
40
|
+
fontStyle: z.optional(z.enum(["normal", "italic"])),
|
|
41
|
+
hover: z.optional(z.object({
|
|
42
|
+
backgroundColor: z.optional(z.string()),
|
|
43
|
+
fontColor: z.optional(z.string()),
|
|
44
|
+
})),
|
|
45
|
+
countAsConversion: z.optional(z.boolean()),
|
|
46
|
+
width: z.optional(ButtonWidthSchema),
|
|
47
|
+
height: z.optional(z.number()),
|
|
48
|
+
align: z.optional(ButtonAlignSchema),
|
|
49
|
+
});
|
|
50
|
+
export const InputTypeSchema = z.enum(["text", "email", "telephone", "number", "date", "url"]);
|
|
51
|
+
export const InputFieldSchema = z.object({
|
|
52
|
+
type: InputTypeSchema,
|
|
53
|
+
name: z.string(),
|
|
54
|
+
label: z.string(),
|
|
55
|
+
});
|
|
56
|
+
export const TextInputElementPropertiesSchema = z.object({
|
|
57
|
+
...InputFieldSchema.shape,
|
|
58
|
+
placeholder: z.string(),
|
|
59
|
+
labelColor: z.optional(HexSchema),
|
|
60
|
+
});
|
|
61
|
+
export const PreferenceOptionSchema = z.object({
|
|
62
|
+
value: z.string(),
|
|
63
|
+
label: z.string(),
|
|
64
|
+
});
|
|
65
|
+
export const PreferenceTypeSchema = z.enum(["checkbox", "hidden", "radio", "select"]);
|
|
66
|
+
export const PreferenceSchema = z.object({
|
|
67
|
+
id: z.union([z.string(), z.number()]),
|
|
68
|
+
name: z.string(),
|
|
69
|
+
options: z.array(PreferenceOptionSchema),
|
|
70
|
+
type: z.optional(PreferenceTypeSchema),
|
|
71
|
+
});
|
|
72
|
+
export const PreferenceElementPropertiesSchema = z.object({
|
|
73
|
+
label: z.string(),
|
|
74
|
+
preference: z.nullable(PreferenceSchema),
|
|
75
|
+
custom_options: z.optional(z.array(PreferenceOptionSchema)),
|
|
76
|
+
required: z.boolean(),
|
|
77
|
+
});
|
|
78
|
+
export const SelectElementPropertiesSchema = z.object({
|
|
79
|
+
...PreferenceElementPropertiesSchema.shape,
|
|
80
|
+
placeholder: z.string(),
|
|
81
|
+
});
|
|
82
|
+
export const CheckboxElementPropertiesSchema = PreferenceElementPropertiesSchema;
|
|
83
|
+
export const RadioElementPropertiesSchema = PreferenceElementPropertiesSchema;
|
|
84
|
+
export const TextElementPropertiesSchema = z.object({
|
|
85
|
+
text: z.string(),
|
|
86
|
+
color: z.string(),
|
|
87
|
+
fontFamily: z.optional(z.string()),
|
|
88
|
+
rotation: z.optional(z.number()),
|
|
89
|
+
textShadow: z.optional(z.object({
|
|
90
|
+
offsetX: z.number(),
|
|
91
|
+
offsetY: z.number(),
|
|
92
|
+
blur: z.number(),
|
|
93
|
+
color: z.string(),
|
|
94
|
+
})),
|
|
95
|
+
});
|
|
96
|
+
export const HtmlElementPropertiesSchema = z.object({
|
|
97
|
+
html: z.string(),
|
|
98
|
+
});
|
|
99
|
+
export const ImageElementPropertiesSchema = z.object({
|
|
100
|
+
src: z.string(),
|
|
101
|
+
link: z.optional(LinkTargetSchema),
|
|
102
|
+
width: z.optional(z.object({ unit: z.enum(["px", "%"]), value: z.number() })),
|
|
103
|
+
align: z.optional(z.enum(["left", "center", "right"])),
|
|
104
|
+
objectFit: z.optional(z.enum(["cover", "contain", "fill"])),
|
|
105
|
+
objectPosition: z.optional(z.string()),
|
|
106
|
+
});
|
|
107
|
+
// pre-authored for the upcoming floating_image element (currently commented
|
|
108
|
+
// out in form-shared's ElementType/FormElementSchema) — not yet a consumer.
|
|
109
|
+
export const FloatingImageElementPropertiesSchema = z.object({
|
|
110
|
+
src: z.string(),
|
|
111
|
+
});
|
|
112
|
+
export const SpacerElementPropertiesSchema = z.object({
|
|
113
|
+
height: z.number(),
|
|
114
|
+
showDivider: z.optional(z.boolean()),
|
|
115
|
+
dividerColor: z.optional(z.string()),
|
|
116
|
+
dividerThickness: z.optional(z.number()),
|
|
117
|
+
});
|
package/schemas/form.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { HexSchema } from "./helpers.js";
|
|
3
|
+
import { StepSchema } from "./step.js";
|
|
4
|
+
import { BasicFormDisplaySchema, MobilePopupFormDisplaySchema, PopupFormDisplaySchema, SliderFormDisplaySchema, } from "./formDisplay.js";
|
|
5
|
+
export const FormTypeSchema = z.enum(["popup", "basic", "slider", "mobile_popup"]);
|
|
6
|
+
export const FormLanguageSchema = z.enum(["cs", "en"]);
|
|
7
|
+
export const FormThemeSchema = z.object({
|
|
8
|
+
corners: z.enum(["none", "sm", "md", "lg"]),
|
|
9
|
+
mainColor: HexSchema,
|
|
10
|
+
secondaryColor: z.tuple([HexSchema, HexSchema, HexSchema, HexSchema]),
|
|
11
|
+
backgroundColor: HexSchema,
|
|
12
|
+
fontFamily: z.string(),
|
|
13
|
+
});
|
|
14
|
+
const formBase = {
|
|
15
|
+
language: FormLanguageSchema,
|
|
16
|
+
steps: z.array(StepSchema),
|
|
17
|
+
theme: FormThemeSchema,
|
|
18
|
+
version: z.literal(1),
|
|
19
|
+
usedFonts: z.array(z.string()),
|
|
20
|
+
};
|
|
21
|
+
export const FormSchema = z.discriminatedUnion("type", [
|
|
22
|
+
z.object({ ...formBase, type: z.literal("basic"), display: BasicFormDisplaySchema }),
|
|
23
|
+
z.object({ ...formBase, type: z.literal("popup"), display: PopupFormDisplaySchema }),
|
|
24
|
+
z.object({ ...formBase, type: z.literal("slider"), display: SliderFormDisplaySchema }),
|
|
25
|
+
z.object({ ...formBase, type: z.literal("mobile_popup"), display: MobilePopupFormDisplaySchema }),
|
|
26
|
+
]);
|
|
27
|
+
// Renamed from FormCampaignSchema (ADR 0016) -- mirrors MountedForm in form-shared.
|
|
28
|
+
export const MountedFormSchema = z.object({
|
|
29
|
+
id: z.string(),
|
|
30
|
+
name: z.string(),
|
|
31
|
+
definition: FormSchema,
|
|
32
|
+
variantId: z.optional(z.string()),
|
|
33
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { DistancePropertySchema, HexSchema } from "./helpers.js";
|
|
3
|
+
export const BorderStyleSchema = z.enum(["none", "solid", "dashed", "dotted"]);
|
|
4
|
+
export const FormBorderSchema = z.object({
|
|
5
|
+
width: z.number(),
|
|
6
|
+
color: HexSchema,
|
|
7
|
+
style: BorderStyleSchema,
|
|
8
|
+
sides: z.optional(z.enum(["all", "top", "right", "bottom", "left"])),
|
|
9
|
+
useTheme: z.optional(z.boolean()),
|
|
10
|
+
});
|
|
11
|
+
export const FormShadowSchema = z.object({
|
|
12
|
+
offsetX: z.number(),
|
|
13
|
+
offsetY: z.number(),
|
|
14
|
+
blur: z.number(),
|
|
15
|
+
spread: z.number(),
|
|
16
|
+
color: z.string(),
|
|
17
|
+
raw: z.optional(z.string()),
|
|
18
|
+
});
|
|
19
|
+
export const TeaserPropertiesSchema = z.object({
|
|
20
|
+
text: z.string(),
|
|
21
|
+
backgroundColor: z.string(),
|
|
22
|
+
textColor: z.string(),
|
|
23
|
+
});
|
|
24
|
+
export const CloseIconPropertiesSchema = z.object({
|
|
25
|
+
color: z.string(),
|
|
26
|
+
size: z.number(),
|
|
27
|
+
padding: DistancePropertySchema,
|
|
28
|
+
position: z.optional(z.object({ top: z.number(), right: z.number() })),
|
|
29
|
+
visibilityDelay: z.optional(z.number()),
|
|
30
|
+
closeOnEscape: z.optional(z.boolean()),
|
|
31
|
+
});
|
|
32
|
+
// mirrors FormPositionId in form-shared/types/form.ts
|
|
33
|
+
export const FormPositionIdSchema = z.literal([1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
|
34
|
+
export const BaseFormDisplaySchema = z.object({
|
|
35
|
+
border: FormBorderSchema,
|
|
36
|
+
shadow: z.optional(FormShadowSchema),
|
|
37
|
+
});
|
|
38
|
+
export const BasicFormDisplaySchema = z.object({
|
|
39
|
+
...BaseFormDisplaySchema.shape,
|
|
40
|
+
maxWidth: z.number(),
|
|
41
|
+
});
|
|
42
|
+
export const PopupFormDisplaySchema = z.object({
|
|
43
|
+
...BaseFormDisplaySchema.shape,
|
|
44
|
+
position: z.object({
|
|
45
|
+
distance: DistancePropertySchema,
|
|
46
|
+
id: FormPositionIdSchema,
|
|
47
|
+
}),
|
|
48
|
+
closeIcon: CloseIconPropertiesSchema,
|
|
49
|
+
teaser: z.optional(TeaserPropertiesSchema),
|
|
50
|
+
});
|
|
51
|
+
export const SliderFormDisplaySchema = z.object({
|
|
52
|
+
...BaseFormDisplaySchema.shape,
|
|
53
|
+
position: z.enum(["bottom-left", "bottom-center", "bottom-right"]),
|
|
54
|
+
closeIcon: CloseIconPropertiesSchema,
|
|
55
|
+
teaser: z.optional(TeaserPropertiesSchema),
|
|
56
|
+
});
|
|
57
|
+
export const MobilePopupFormDisplaySchema = z.object({
|
|
58
|
+
...BaseFormDisplaySchema.shape,
|
|
59
|
+
closeIcon: CloseIconPropertiesSchema,
|
|
60
|
+
teaser: z.optional(TeaserPropertiesSchema),
|
|
61
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
// mirrors HEX = `#${string}` in form-shared/types/helpers.ts
|
|
3
|
+
export const HexSchema = z.templateLiteral(["#", z.string()]);
|
|
4
|
+
// mirrors DistanceProperty in form-shared/types/elementProperties.ts
|
|
5
|
+
// (lives here so formDisplay and elementProperties can both import it without a cycle)
|
|
6
|
+
export const DistancePropertySchema = z.object({
|
|
7
|
+
left: z.number(),
|
|
8
|
+
right: z.number(),
|
|
9
|
+
top: z.number(),
|
|
10
|
+
bottom: z.number(),
|
|
11
|
+
independent: z.boolean(),
|
|
12
|
+
});
|
package/schemas/step.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { FormElementSchema } from "./element.js";
|
|
3
|
+
import { DistancePropertySchema, HexSchema } from "./helpers.js";
|
|
4
|
+
export const StepDisplayPropertiesSchema = z.object({
|
|
5
|
+
padding: DistancePropertySchema,
|
|
6
|
+
backgroundColor: z.optional(HexSchema),
|
|
7
|
+
minHeight: z.optional(z.number()),
|
|
8
|
+
});
|
|
9
|
+
export const StepSchema = z.object({
|
|
10
|
+
type: z.literal("step"),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
elements: z.array(FormElementSchema),
|
|
13
|
+
id: z.string(),
|
|
14
|
+
displayProperties: StepDisplayPropertiesSchema,
|
|
15
|
+
});
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "./schemas/helpers.js";
|
|
2
|
+
export * from "./schemas/formDisplay.js";
|
|
3
|
+
export * from "./schemas/elementProperties.js";
|
|
4
|
+
export * from "./schemas/element.js";
|
|
5
|
+
export * from "./schemas/step.js";
|
|
6
|
+
export * from "./schemas/form.js";
|
|
7
|
+
export * from "./schemas/campaign.js";
|
|
8
|
+
/**
|
|
9
|
+
* Serializes the full form type tree as standard JSON Schema —
|
|
10
|
+
* used to tell an LLM the exact shape of valid form JSON (issue 024).
|
|
11
|
+
*/
|
|
12
|
+
export declare function getFormJsonSchema(): Record<string, unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* Serializes the Campaign contract as standard JSON Schema — the artifact
|
|
15
|
+
* exported to ecomailapp so its PHP publish job can validate against the
|
|
16
|
+
* real schema instead of drifting silently (ticket 115/118, ADR 0017).
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCampaignJsonSchema(): Record<string, unknown>;
|