@verisure-italy/funnel-types
v1.8.0
Published
Types for Funnel service
Readme
@verisure-italy/funnel-types
Domain contracts for funnels, funnel paths, and survey payloads, with discriminated unions used heavily for routing conditions and question variants.
Installation
pnpm add @verisure-italy/funnel-typesMain Exports
funnelTypes,questionTypes, androutingConditionsfunnelTypeSchema,questionTypeSchema,routingConditionSchemafunnelSchemafunnelPathSchemasurveySchema- supporting schemas for contexts, flows, routing targets, and survey metadata
What This Package Gives You
- a complete authoring model for funnel definitions
- typed question variants with safe narrowing
- survey payloads aligned with funnel metadata
- route-condition modeling for flow transitions
Schema Inventory
| Schema | Type alias | Kind | Purpose |
| --- | --- | --- | --- |
| funnelTypeSchema | FunnelType | enum | Funnel-type catalog |
| questionTypeSchema | QuestionType | enum | Question-type catalog |
| routingConditionSchema | RoutingCondition | enum | Supported routing conditions |
| funnelContextSchema | FunnelContext | object schema | Context definition |
| funnelFlowQuestionSchema | FunnelFlowQuestion | object schema | Flow-question link |
| funnelFlowSchema | FunnelFlow | object schema | Flow definition |
| funnelRoutingTargetSchema | FunnelRoutingTarget | object schema | Routing target |
| funnelRoutingSchema | FunnelRouting | object schema | Routing rule |
| funnelQuestionSchema | FunnelQuestion | discriminated union | Question variants |
| funnelSchema | Funnel | object schema | Full funnel definition |
| funnelPathSchema | FunnelPath | object schema | Path configuration |
| surveyMetaSchema | SurveyMeta | object schema | Survey request metadata |
| surveySchema | Survey | object schema | Persisted survey |
Enum Reference
| Schema | Values |
| --- | --- |
| funnelTypeSchema | home, business |
| questionTypeSchema | choices, zip_code, zip_code_auto, phone, phone_number, text |
| routingConditionSchema | exact, contains, starts_with, ends_with, out_of_area, match_all |
Schema Reference
funnelContextSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| code | string | Yes | Non-empty |
| title | string | Yes | Non-empty |
funnelFlowQuestionSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| context | string | Yes | Context code |
| question | string | Yes | Question code |
funnelFlowSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| code | string | Yes | Flow code |
| default | boolean | No (default) | Defaults to false |
| questions | FunnelFlowQuestion[] | Yes | At least one entry |
funnelRoutingTargetSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| flow | string | Yes | Target flow |
| question | string | Yes | Target question |
funnelRoutingSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| condition | union | Yes | Routing condition |
| from | FunnelRoutingTarget | Yes | Source target |
| to | FunnelRoutingTarget | Yes | Destination target |
condition variants
| Variant | Fields |
| --- | --- |
| exact, contains, starts_with, ends_with | value: string required |
| match_all | value: null |
| out_of_area | value: boolean, defaults to true |
funnelQuestionSchema
Common base fields:
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| code | string | Yes | Must match ^[a-z0-9-]+$ |
| script | string | Yes | Non-empty |
| description | string \| null | No | Optional |
| progress | number | Yes | Integer from 1 to 100 |
| type | QuestionType | Yes | Variant discriminator |
Variant-specific fields:
| Variant | Additional fields |
| --- | --- |
| choices | options.responses[] with unique value fields |
| phone, phone_number | options.onlyMobile: boolean |
| zip_code, zip_code_auto | options.isTipsEnabled: boolean (defaults to false if omitted) |
| text | options optional empty object |
Answer tips
Funnel.tips is a list of { question, answer, text }, all strings. Legacy payloads default to an empty list. funnelTipSchema, funnelTipsSchema and FunnelTip are exported.
Matching uses the question code and exact saved answer, not its label. Duplicate pairs and missing question/choice references are rejected. Text has no editorial validation and is rendered as plain text by the frontend. This feature is independent of Risk Rank (options.isTipsEnabled) and of behavior/theme.
funnelSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| id | string | Yes | UUID |
| contexts | FunnelContext[] | Yes | At least one |
| flows | FunnelFlow[] | Yes | At least one |
| questions | FunnelQuestion[] | Yes | At least one |
| routing | FunnelRouting[] | Yes | Can be empty |
| slug | string | Yes | Must match ^[a-z0-9-]+$ |
| title | string | Yes | Non-empty |
| type | FunnelType | Yes | Funnel type |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
funnelPathSchema
Navigation and visual styling are independent. funnelBehaviors,
funnelBehaviorSchema, FunnelBehavior describe default | scroll;
funnelThemes, funnelThemeSchema, FunnelTheme describe
default | old-style | dark.
Use funnelPathCreateSchema / FunnelPathCreate for creation and
funnelPathUpdateSchema / FunnelPathUpdate for partial updates. Do not use
funnelPathSchema.partial() for updates: Zod 4 retains nested defaults and
could overwrite an omitted behavior. The update schema preserves omission.
legacyFunnelPathSchema is a read-only compatibility entry point for persisted
theme=scroll records: it maps to behavior=scroll, theme=default unless a
behavior is already explicit. New writes reject scroll as a theme.
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| id | string | Yes | UUID |
| autoPopUpOffer | boolean | No (default) | Defaults to false |
| behavior | FunnelBehavior | No (default) | Defaults to default; independent of theme |
| theme | FunnelTheme | No (default) | Defaults to default; visual styling only |
| enableRetargeting | boolean | No (default) | Defaults to false |
| fallbackSourceId | string | Yes | UUID |
| funnelIds | string[] | Yes | At least one UUID |
| path | string | Yes | Must match ^[a-z0-9-]+$ |
| titleDesktop | string \| null | No | Optional |
| subTitleDesktop | string \| null | No | Optional |
| titleIntroduction | string \| null | No | Optional |
| subTitleIntroduction | string \| null | No | Optional |
| titleMobile | string \| null | No | Optional |
| subTitleMobile | string \| null | No | Optional |
| titleHeader | string \| null | No | Optional |
| titleSubHeader | string \| null | No | Optional |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
surveyMetaSchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| queryString | string \| null | Yes (nullable) | Original query string |
| ip | string | Yes | Non-empty |
| referrer | string \| null | Yes (nullable) | Referrer value |
| clientId | string \| null | Yes (nullable) | Client id |
| fingerprint | string | Yes | Non-empty |
| creativity | string | Yes | UUID |
| userAgent | string \| null | Yes (nullable) | Raw user-agent |
surveySchema
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| id | string | Yes | UUID |
| alisId | string \| null | No | Optional external id |
| alisSentAt | number \| null | No | Optional timestamp |
| couponCode | string \| null | Yes (nullable) | Coupon applied to the survey |
| funnel | string | Yes | Funnel UUID |
| funnelInfo.slug | string | Yes | Funnel slug |
| funnelInfo.title | string | Yes | Funnel title |
| funnelInfo.type | FunnelType | Yes | Funnel type |
| funnelPath.id | string | Yes | Path UUID |
| funnelPath.path | string | Yes | Path slug |
| meta | SurveyMeta | Yes | Survey metadata |
| origin | string | Yes | Non-empty |
| sourceId | string | Yes | UUID |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
Example
import { funnelQuestionSchema } from '@verisure-italy/funnel-types'
const question = funnelQuestionSchema.parse({
code: 'contact-phone',
script: 'What is your phone number?',
progress: 50,
type: 'phone',
options: {
onlyMobile: true,
},
})Stable release
1.8.0 promotes the stage-tested behavior/theme separation and answer-tip contracts to the npm latest tag. Consumers should pin 1.8.0. The dev tag remains on 1.8.0-dev.0; no unrelated SDK packages are released.
