import { FormLifecycleAdapter } from './lifecycle.cjs'; import { BuilderTranslationKey } from './i18n/keys.cjs'; type FormContentMode = "survey" | "poll" | "quiz"; interface PollMetadata { readonly resultVisibility: "after_submit" | "always" | "closed_only" | "private"; readonly strictOneVotePerUser?: boolean; } interface QuizFieldMetadata { readonly correctOptionId: string; readonly explanation?: string; readonly points?: number; } interface QuizMetadata { readonly showExplanation: "after_submit" | "immediate"; readonly passingScore?: number; } interface CustomFormMetadata { readonly mode: FormContentMode; readonly poll?: PollMetadata; readonly quiz?: QuizMetadata; readonly [key: string]: unknown; } type ContentModeConstraintCode = "CONTENT_MODE_CONSTRAINT" | "POLL_SINGLE_FIELD_REQUIRED" | "POLL_INVALID_FIELD_TYPE" | "POLL_MIN_OPTIONS_REQUIRED" | "RADIO_TEXT_INPUT_SURVEY_ONLY" | "QUIZ_CORRECT_OPTION_MISSING" | "QUIZ_INVALID_CORRECT_OPTION"; interface ContentModeConstraintIssue extends SchemaIssue { readonly code: ContentModeConstraintCode; } interface ContentModeValidationResult { readonly valid: boolean; readonly issues: readonly ContentModeConstraintIssue[]; } declare function getFormContentMode(metadata: unknown): FormContentMode; declare function readPollMetadata(metadata: unknown): PollMetadata; declare function readQuizMetadata(metadata: unknown): QuizMetadata; declare function readQuizFieldMetadata(metadata: unknown): QuizFieldMetadata; interface ContentModeSettings { readonly minFields?: number; readonly maxFields?: number; readonly allowedFieldTypes?: FormPolicy["allowedFieldTypes"]; readonly minOptionsPerField?: number; readonly maxOptionsPerField?: number; readonly evaluateQuiz?: (schema: FormSchema, answers: FormValues) => QuizEvaluationResult; } declare function resolveContentModeSettings(mode: FormContentMode, policy?: FormPolicy): ContentModeSettings; declare function validateContentModeConstraints(schema: FormSchema, policy?: FormPolicy): ContentModeValidationResult; /** Explicit JSON boundary: rejects non-JSON values instead of silently dropping them. */ declare function contentMetadataToJson(value: unknown): Readonly>; declare function createInitialSchemaByMode(mode: FormContentMode, options: { readonly title: string; readonly locale: string; readonly id?: string; }): FormSchema; declare function getContentModePolicy(mode: FormContentMode, policy?: FormPolicy): FormPolicy; interface ContentModeIssue { readonly path: string; readonly message: string; } type ContentModeIssueCode = "field_count" | "options_maximum" | "quiz_evaluator_missing" | "poll_field_count" | "quiz_field_count" | "unsupported_field_type" | "options_minimum" | "radio_text_input" | "correct_option_missing" | "points_type" | "explanation_type" | "points_range" | "poll_result_visibility" | "poll_strict_one_vote" | "quiz_explanation_timing" | "quiz_passing_score"; interface ContentModeDiagnostic extends ContentModeIssue { readonly code: ContentModeIssueCode; } /** Opt-in validation, separate from the backwards-compatible base schema validator. */ declare function getContentModeDiagnostics(schema: FormSchema, policy?: FormPolicy): readonly ContentModeDiagnostic[]; /** Opt-in validation, separate from the backwards-compatible base schema validator. */ declare function validateContentMode(schema: FormSchema, policy?: FormPolicy): readonly ContentModeIssue[]; interface QuizQuestionResult { readonly fieldId: string; readonly title: string; readonly correct: boolean; readonly correctOption: string; readonly explanation?: string; readonly points: number; readonly earned: number; } interface QuizResult { readonly questions: readonly QuizQuestionResult[]; readonly score: number; readonly total: number; readonly passed?: boolean; } interface QuizQuestionEvaluation { readonly questionId: string; readonly isCorrect: boolean; readonly correctOptionId?: string; readonly selectedOptionId?: string; readonly explanation?: string; readonly scoreEarned: number; readonly maxScore: number; } interface QuizEvaluationResult { readonly totalScore: number; readonly maxPossibleScore: number; readonly isPassed?: boolean; readonly questions: readonly QuizQuestionEvaluation[]; readonly reward?: { readonly type: "coupon" | "badge" | "text"; readonly code?: string; readonly message?: string; }; } declare function evaluateQuizLocally(schema: FormSchema, answers: FormValues, policy?: FormPolicy): QuizEvaluationResult; declare function evaluateQuiz(schema: FormSchema, answers: FormValues, policy?: FormPolicy): QuizResult; interface PollAccessContext { readonly submitted: boolean; readonly closed: boolean; readonly canViewResults: boolean; } declare function canShowPollResults(metadata: PollMetadata, context: PollAccessContext): boolean; /** Implementations must enforce identity and authorization at the persistence boundary. */ interface PollRuntimeAdapter { readonly loadResults: (schema: FormSchema, signal: AbortSignal) => Promise; readonly canVote: (schema: FormSchema) => Promise; } interface SensitiveDataFinding { readonly fieldId: string; readonly type: string; readonly start?: number; readonly end?: number; readonly matchedText?: string; readonly maskedText?: string; } interface PrivacyEngine { detect(schema: FormSchema, values: Record): readonly SensitiveDataFinding[]; } interface SubmissionValidationResult { readonly valid: boolean; readonly fieldErrors: Readonly>; readonly formErrors: readonly string[]; readonly piiFindings?: readonly SensitiveDataFinding[]; } /** A Zod-compatible schema accepted by storage and RPC integrations. */ interface SubmissionSchema { readonly safeParse: (value: unknown) => { readonly success: true; readonly data: TOutput; } | { readonly success: false; readonly error: unknown; }; } type FormSubmissionValidatorResult = undefined | boolean | SubmissionValidationResult; /** Application-owned submission validation callback. */ type FormSubmissionValidator = (submission: FormSubmission) => unknown | Promise; type FormSubmissionValidationSource = FormSchema | SubmissionSchema | FormSubmissionValidator; /** Validates one non-empty field value with the same rules used by form submission validation. */ declare function validateFieldValue(field: FormField, value: FormValue): boolean; declare function validateAnswers(schema: FormSchema, values: FormValues): AnswerValidationResult; declare function validatePageAnswers(schema: FormSchema, pageIndex: number, values: FormValues): AnswerValidationResult; declare function validateSubmission(schema: FormSchema, submission: FormSubmission, options?: { readonly privacyEngine?: PrivacyEngine; }): SubmissionValidationResult; type Result = { readonly success: true; readonly value: T; } | { readonly success: false; readonly error: E; }; type FormVersionStatus = "draft" | "published" | "archived"; interface FormVersionRecord extends ExtensibleNode { readonly formId: string; readonly version: number; readonly status: FormVersionStatus; readonly schema: FormSchema; readonly revision: number; readonly createdFromVersion?: number; readonly createdAt: string; readonly publishedAt?: string; readonly archivedAt?: string; } interface FormVersionState { readonly formId: string; readonly draftVersion?: number; readonly publishedVersion?: number; readonly nextVersion: number; readonly revision: number; } interface VersionTransitionEvent { readonly type: "draft.created" | "draft.deleted" | "version.published" | "version.archived"; readonly formId: string; readonly fromRevision: number; readonly toRevision: number; readonly affectedVersions: readonly number[]; readonly occurredAt: string; } type VersionTransitionError = { readonly type: "draft_already_exists"; readonly currentDraftVersion: number; } | { readonly type: "draft_not_found"; } | { readonly type: "missing_published_record"; readonly expectedVersion: number; } | { readonly type: "form_id_mismatch"; } | { readonly type: "invalid_published_status"; } | { readonly type: "unexpected_published_record"; } | { readonly type: "revision_conflict"; readonly expectedRevision: number; readonly actualRevision: number; } | { readonly type: "invalid_source_version"; readonly requestedVersion: number; readonly publishedVersion?: number; } | { readonly type: "version_immutable"; readonly status: FormVersionStatus; } | { readonly type: "max_version_exceeded"; readonly max: number; } | { readonly type: "validation_failed"; readonly issues: readonly SchemaIssue[]; } | { readonly type: "transition_failed"; readonly cause: unknown; }; interface VersionTransitionContext { readonly formId: string; readonly fromVersion: number; readonly toVersion: number; readonly expectedRevision: number; readonly plan: FormVersionTransitionPlan; readonly domainData?: TDomain; } type FormVersionTransitionPlan = VersionTransitionPlan; interface CommitVersionTransitionOptions { readonly context: VersionTransitionContext; readonly beforeTransition?: (context: VersionTransitionContext) => Promise | TDomain | void; readonly afterTransition?: (context: VersionTransitionContext & { readonly nextRevision: number; }) => Promise | void; readonly persistAdapter: (params: { readonly formId: string; readonly targetVersion: number; readonly expectedRevision: number; readonly schema: FormSchema; readonly domainData?: TDomain; }) => Promise<{ readonly nextRevision: number; }>; } interface CloneVersionOptions { readonly maxVersions?: number; readonly expectedRevision?: number; readonly clonedAt?: string; readonly metadata?: Readonly>; /** Additional known published versions that may be used as a clone source. */ readonly allowedSourceVersions?: readonly number[]; } interface PublishDraftOptions { readonly expectedRevision?: number; readonly currentPublishedRecord?: FormVersionRecord; readonly validate?: (schema: FormSchema) => boolean | Promise | readonly SchemaIssue[] | Promise; readonly publishedAt?: string; /** @deprecated Use publishedAt. */ readonly timestamp?: string; } interface DeleteDraftOptions { readonly expectedRevision?: number; readonly deletedAt?: string; } interface PublishDraftResult { readonly nextState: FormVersionState; readonly publishedRecord: FormVersionRecord; readonly archivedRecords: readonly FormVersionRecord[]; /** @deprecated Read archivedRecords instead. */ readonly archivedVersion?: number; } declare function cloneVersionToDraft(state: FormVersionState, sourceSchema: FormSchema, options?: CloneVersionOptions): Result<{ readonly nextState: FormVersionState; readonly draftSchema: FormSchema; }, VersionTransitionError>; declare function createCloneTransitionPlan(state: FormVersionState, sourceRecord: FormVersionRecord, options?: CloneVersionOptions): Result<{ readonly nextState: FormVersionState; readonly plan: VersionTransitionPlan; }, VersionTransitionError>; declare function publishDraft(state: FormVersionState, draftSchema: FormSchema, options?: PublishDraftOptions): Promise>; declare function createPublishTransitionPlan(state: FormVersionState, draftRecord: FormVersionRecord, options?: PublishDraftOptions): Promise>; declare function deleteDraft(state: FormVersionState, options?: DeleteDraftOptions): Result<{ readonly nextState: FormVersionState; }, VersionTransitionError>; declare function createDeleteDraftTransitionPlan(state: FormVersionState, draftRecord: FormVersionRecord, options?: DeleteDraftOptions): Result<{ readonly nextState: FormVersionState; readonly plan: VersionTransitionPlan; }, VersionTransitionError>; declare function assertVersionMutable(status: FormVersionStatus): void; declare function applyTransitionPlan(plan: FormVersionTransitionPlan): FormSchema; declare function commitVersionTransition(options: CommitVersionTransitionOptions): Promise<{ readonly success: boolean; readonly nextRevision: number; readonly error?: VersionTransitionError; }>; type FieldType = "text" | "textarea" | "number" | "rating" | "date" | "time" | "email" | "tel" | "url" | "select" | "multi-select" | "checkbox" | "radio"; type QuestionType = FieldType; interface BaseFieldConstraintRule { readonly defaultRequired?: boolean; readonly fixedRequired?: boolean; } interface RatingFieldConstraintRule extends BaseFieldConstraintRule { readonly defaultMin?: number; readonly defaultMax?: number; readonly fixedMin?: number; readonly fixedMax?: number; readonly allowedMinRange?: readonly [number, number]; readonly allowedMaxRange?: readonly [number, number]; } interface TextFieldConstraintRule extends BaseFieldConstraintRule { readonly defaultMaxLength?: number; readonly maxMaxLength?: number; } interface ChoiceFieldConstraintRule extends BaseFieldConstraintRule { readonly minOptions?: number; readonly maxOptions?: number; } type FieldConstraintRule = RatingFieldConstraintRule | TextFieldConstraintRule | ChoiceFieldConstraintRule | BaseFieldConstraintRule; interface FormPolicy { readonly contentMode?: ContentModeSettings; readonly allowedFieldTypes?: readonly FieldType[]; readonly maxFields?: number; readonly maxOptionsPerField?: number; readonly requiredLocales?: readonly string[]; readonly allowedLocales?: readonly string[]; readonly maxLocales?: number; readonly maxTextLength?: number; readonly maxSchemaBytes?: number; /** Per-question-type defaults and immutable or bounded field constraints. */ readonly fieldConstraints?: Partial>; } type ConditionOperator = "equals" | "not_equals" | "contains" | "not_contains" | "is_empty" | "is_not_empty" | "greater_than" | "less_than" /** @deprecated Use is_not_empty instead. */ | "not_empty"; type ConditionValue = string | number | boolean; type JsonValue = string | number | boolean | null | readonly JsonValue[] | { readonly [key: string]: JsonValue; }; interface BaseSubmissionMetadata { readonly [key: string]: JsonValue | undefined; } /** A contract or tenant-managed locale and its translation capabilities. */ interface LocaleOption { /** Canonical BCP 47 locale tag. */ readonly locale: string; /** Human-readable locale name. */ readonly label: string; /** Whether automatic translation is allowed for this locale. Defaults to true. */ readonly translatable?: boolean; /** Whether the locale may be removed from the form. Defaults to true. */ readonly removable?: boolean; readonly metadata?: Readonly>; } /** Arbitrary, JSON-serializable data preserved by every form-engine operation. */ interface ExtensibleNode { readonly metadata?: Readonly>; /** Locale -> translated property -> metadata created for that translation. */ readonly translationMetadata?: Readonly>>>>>; } interface DisplayCondition { readonly questionId: string; readonly operator: ConditionOperator; readonly value?: ConditionValue; } interface FieldDisplayCondition { readonly fieldId: string; readonly operator: ConditionOperator; readonly value?: unknown; } interface DisplayConditionGroup { readonly logic: "all" | "any"; readonly conditions: readonly (FieldDisplayCondition | DisplayConditionGroup)[]; } interface DisplayRule { readonly action: "show" | "hide"; readonly condition: DisplayConditionGroup; } interface LocalizedText { readonly title?: string; readonly description?: string; readonly completionMessage?: string; readonly closedMessage?: string; readonly notYetOpenMessage?: string; } type SchemaTranslations = Readonly>; type ValidationCode = "required" | "invalid_type" | "min_length" | "max_length" | "pattern" | "min" | "max" | "step" | "invalid_option" | "min_selections" | "max_selections" | "invalid_format" | "unknown_field"; interface FieldOption extends ExtensibleNode { readonly id: string; readonly label: string; readonly textInput?: boolean; readonly pinned?: boolean; readonly translations?: Readonly>; } interface BaseField extends ExtensibleNode { readonly id: string; readonly type: FieldType; readonly title: string; readonly description?: string; readonly translationKey?: string; readonly required: boolean; readonly messages?: Partial>; readonly displayCondition?: DisplayCondition; readonly displayRule?: DisplayRule; readonly translations?: SchemaTranslations; } interface TextField extends BaseField { readonly type: "text" | "textarea"; readonly placeholderKey?: string; readonly minLength?: number; readonly maxLength?: number; readonly pattern?: string; } interface DateField extends BaseField { readonly type: "date"; readonly placeholderKey?: string; readonly minDate?: string; readonly maxDate?: string; } interface TimeField extends BaseField { readonly type: "time"; readonly placeholderKey?: string; readonly minTime?: string; readonly maxTime?: string; } interface EmailField extends BaseField { readonly type: "email"; readonly placeholderKey?: string; } interface TelField extends BaseField { readonly type: "tel"; readonly placeholderKey?: string; } interface UrlField extends BaseField { readonly type: "url"; readonly placeholderKey?: string; } interface NumberField extends BaseField { readonly type: "number"; readonly placeholderKey?: string; readonly min?: number; readonly max?: number; readonly step?: number; } interface RatingField extends BaseField { readonly type: "rating"; readonly min?: number; readonly max?: number; } interface SelectField extends BaseField { readonly type: "select" | "radio"; readonly options: readonly FieldOption[]; readonly shuffleOptions?: boolean; } interface MultiSelectField extends BaseField { readonly type: "multi-select"; readonly options: readonly FieldOption[]; readonly shuffleOptions?: boolean; readonly minSelections?: number; readonly maxSelections?: number; } interface CheckboxField extends BaseField { readonly type: "checkbox"; } type FormField = TextField | DateField | TimeField | EmailField | TelField | UrlField | NumberField | RatingField | SelectField | MultiSelectField | CheckboxField; interface FormPage extends ExtensibleNode { readonly id: string; readonly title?: string; readonly description?: string; readonly questionIds: readonly string[]; readonly displayCondition?: DisplayCondition; readonly translations?: SchemaTranslations; } interface FormSchema extends ExtensibleNode { readonly id: string; readonly version: number; readonly title: string; readonly description?: string; readonly completionMessage?: string; readonly submitLabelKey?: string; readonly defaultLocale?: string; readonly supportedLocales?: readonly string[]; readonly translations?: SchemaTranslations; readonly fields: readonly FormField[]; readonly pages?: readonly FormPage[]; readonly submissionSettings?: FormSubmissionSettings; } /** Metadata-typed schema view that keeps the legacy FormSchema contract unchanged. */ type TypedExtensibleNode> = Readonly>, TTranslationMetadata extends Readonly> = Readonly>> = Omit & { readonly metadata?: TMetadata; readonly translationMetadata?: Readonly>>>; }; type TypedFieldOption> = Readonly>, TTranslationMetadata extends Readonly> = Readonly>> = Omit & TypedExtensibleNode; type TypedFormFieldVariant>, TTranslationMetadata extends Readonly>> = Omit & TypedExtensibleNode & (TField extends { readonly options: readonly FieldOption[]; } ? { readonly options: readonly TypedFieldOption[]; } : object); type TypedFormField> = Readonly>, TTranslationMetadata extends Readonly> = Readonly>> = FormField extends infer TField ? TField extends FormField ? TypedFormFieldVariant : never : never; type TypedFormSchema> = Readonly>, TTranslationMetadata extends Readonly> = Readonly>> = Omit & TypedExtensibleNode & { readonly fields: readonly TypedFormField[]; }; interface FormSubmissionSettings extends ExtensibleNode { readonly showConfirmationBeforeSubmit?: boolean; readonly confirmationRenderMode?: "dialog" | "inline" | "replace"; readonly confirmButtonLabel?: string; readonly cancelButtonLabel?: string; readonly openAt?: string; readonly closeAt?: string; readonly maxResponses?: number; readonly closedMessage?: string; readonly notYetOpenMessage?: string; readonly honeypotFieldId?: string; } interface RadioTextAnswer { readonly optionId: string; readonly text: string; } type FormValue = string | number | boolean | readonly string[] | RadioTextAnswer | undefined; type FormValues = Readonly>; interface SchemaIssue { readonly path: string; readonly code: string; readonly message: string; /** Compatibility discriminator for structured policy issues. */ readonly type?: string; /** Present for policy issues that identify a field property and its expected value. */ readonly fieldId?: string; readonly property?: string; readonly expected?: boolean | number | readonly [number, number]; readonly cycle?: readonly string[]; } type SchemaValidationResult = { readonly valid: true; readonly value: FormSchema; readonly issues: readonly []; } | { readonly valid: false; readonly issues: readonly SchemaIssue[]; }; interface ValidationIssue { readonly fieldId: string; readonly code: ValidationCode; readonly messageKey: string; readonly params: Readonly>; } type ValidationError = ValidationIssue; type AnswerValidationResult = { readonly valid: true; readonly issues: readonly []; } | { readonly valid: false; readonly issues: readonly ValidationIssue[]; }; interface FormSubmissionBase extends Pick { readonly id: string; readonly formId: string; readonly formVersion: number; readonly locale?: string; readonly values: FormValues; readonly submittedAt: string; readonly schemaRevision?: number; } type FormSubmission = FormSubmissionBase & ([TMeta] extends [undefined] ? { readonly metadata?: BaseSubmissionMetadata; } : { readonly metadata: TMeta; }); type SubmissionSaveResult = { readonly status: "created"; readonly submission: FormSubmission; readonly payloadHash: string; } | { readonly status: "duplicate"; readonly submission: FormSubmission; readonly payloadHash: string; } | { readonly status: "conflict"; readonly submissionId: string; readonly payloadHash: string; readonly existingPayloadHash: string; }; interface SaveSubmissionOptions { /** Return a typed duplicate/conflict result instead of propagating a duplicate-key error. */ readonly idempotent?: boolean; /** Re-fetch and validate the stored FormSchema before persisting. */ readonly validateAgainstSchema?: boolean; /** Validate with an explicitly supplied FormSchema, Zod-compatible schema, or callback. */ readonly validation?: FormSubmissionValidationSource; /** Alias for `validation` for adapters that expose a validator-oriented API. */ readonly validator?: FormSubmissionValidationSource; /** Explicit schema alias for adapters that expose schema-oriented options. */ readonly schema?: FormSubmissionValidationSource; } /** A submission whose persisted or transport representation always includes a locale. */ interface StrictFormSubmission extends Omit { readonly values: Readonly>; readonly locale: string; readonly metadata: TMeta; } /** Clean network and persistence representation of a form submission. */ interface FormSubmissionWire { readonly id: string; readonly formId: string; readonly formVersion: number; readonly values: Readonly>; readonly locale?: string; readonly metadata: TMeta; readonly submittedAt: string; readonly schemaRevision?: number; } /** Strict wire representation used by integrations that require a locale. */ interface StrictFormSubmissionWire extends Omit, "locale"> { readonly locale: string; } interface CreateSubmissionInput { readonly id?: string; readonly idFormat?: "uuid" | "ulid" | "custom"; readonly formId: string; readonly formVersion: number; readonly answers: Record; readonly metadata: TMeta; readonly submittedAt?: string; readonly schemaRevision?: number; } interface TranslationAdapter { /** Return null or undefined when the key cannot be resolved by the adapter. */ translate(key: string, locale: string, params?: Readonly>): string | undefined | null; } interface AsyncTranslationAdapter { translateText(text: string, targetLocale: string, sourceLocale?: string, signal?: AbortSignal): Promise; translateBatch(texts: readonly string[], targetLocale: string, sourceLocale?: string, signal?: AbortSignal): Promise; } interface SubmissionQueryOptions { readonly since?: string; readonly until?: string; } interface StorageAdapter { saveSubmission(submission: FormSubmission): Promise; /** Atomically saves a submission only while the form version remains below its response limit. */ saveSubmissionWithinLimit?(submission: FormSubmission, maxResponses: number, options?: SaveSubmissionOptions): Promise; countSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise; listSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise; clearResponses?(formId: string): Promise; clear(): Promise; } interface FormStorageAdapter extends StorageAdapter { saveSchema(schema: FormSchema): Promise; getSchema(formId: string, formVersion: number): Promise; listSchemas(): Promise; deleteSchema(formId: string, formVersion: number): Promise; deleteSubmission(submissionId: string): Promise; readonly inspectFormDeletion?: FormLifecycleAdapter["inspectFormDeletion"]; readonly deleteForm?: FormLifecycleAdapter["deleteForm"]; readonly lifecycleCapabilities?: FormLifecycleAdapter["lifecycleCapabilities"]; } interface SubmissionPageQueryOptions { readonly version?: number; readonly cursor?: string; readonly pageSize?: number; readonly since?: string; readonly until?: string; readonly locale?: string; readonly filter?: SubmissionFilter | ((submission: FormSubmission) => boolean); /** @deprecated Prefer the generic filter AST. */ readonly metadataFilters?: Readonly>; } interface TextAnswerPageQueryOptions extends SubmissionPageQueryOptions { readonly fieldIds?: readonly string[]; } type SubmissionFilter = { readonly op: "eq"; readonly path: string; readonly value: JsonValue; } | { readonly op: "in"; readonly path: string; readonly values: readonly JsonValue[]; } | { readonly op: "range"; readonly path: string; readonly from?: JsonValue; readonly to?: JsonValue; } | { readonly op: "exists"; readonly path: string; readonly value: boolean; } | { readonly op: "and"; readonly filters: readonly SubmissionFilter[]; } | { readonly op: "or"; readonly filters: readonly SubmissionFilter[]; }; interface SubmissionPage { readonly items: readonly FormSubmission[]; readonly nextCursor?: string; readonly hasMore: boolean; } interface PagedSubmissionStorageAdapter extends FormStorageAdapter { listSubmissionPage(formId: string, options?: SubmissionPageQueryOptions): Promise; listTextAnswerPage?(formId: string, fieldIdOrOptions?: string | TextAnswerPageQueryOptions, options?: TextAnswerPageQueryOptions): Promise; } /** Metadata-typed submission contract for application-owned storage adapters. */ interface TypedStorageAdapter { saveSubmission(submission: FormSubmission): Promise; countSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise; listSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise[]>; clearResponses?(formId: string): Promise; clear(): Promise; } /** Metadata-typed form storage contract. */ interface TypedFormStorageAdapter extends TypedStorageAdapter { saveSchema(schema: FormSchema): Promise; getSchema(formId: string, formVersion: number): Promise; listSchemas(): Promise; deleteSchema(formId: string, formVersion: number): Promise; deleteSubmission(submissionId: string): Promise; } /** Metadata-typed query options for paged storage. */ interface TypedSubmissionPageQueryOptions { readonly version?: number; readonly cursor?: string; readonly pageSize?: number; readonly since?: string; readonly until?: string; /** @deprecated Use `since`. */ readonly fromSubmittedAt?: string; /** @deprecated Use `until`. */ readonly toSubmittedAt?: string; readonly locale?: string; readonly filter?: SubmissionFilter | ((submission: FormSubmission) => boolean); readonly metadataFilters?: Readonly>; } /** Metadata-typed page returned by application-owned paged storage. */ interface TypedSubmissionPage { readonly items: readonly FormSubmission[]; readonly nextCursor?: string; readonly hasMore: boolean; } /** Metadata-typed paged form storage contract. */ interface TypedPagedSubmissionStorageAdapter extends TypedFormStorageAdapter { listSubmissionPage(formId: string, options?: TypedSubmissionPageQueryOptions): Promise>; } /** * Common submission-only contract for storage adapters that support typed saves and cursor paging. * MongoDB and Azure Table implementations expose this same surface so callers do not need an * adapter-specific branch. */ interface UnifiedSubmissionStorageAdapter { saveSubmission(submission: FormSubmission, options?: SaveSubmissionOptions): Promise>; /** Atomically saves a submission only while the form version remains below its response limit. */ saveSubmissionWithinLimit(submission: FormSubmission, maxResponses: number, options?: SaveSubmissionOptions): Promise | { readonly status: "limit_reached"; }>; listSubmissionPage(formId: string, options?: TypedSubmissionPageQueryOptions): Promise>; listTextAnswerPage(formId: string, fieldIdOrOptions?: string | TextAnswerPageQueryOptions, options?: TextAnswerPageQueryOptions): Promise>; countSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise; aggregateResponses(schema: FormSchema, options?: TypedSubmissionPageQueryOptions): Promise; exportResponsesToCsv(schema: FormSchema, options?: StorageSubmissionExportOptions): Promise; validateSubmission(submission: FormSubmission, source?: FormSubmissionValidationSource): Promise; } interface StorageSubmissionExportOptions extends Omit, "customColumns" | "includeMetadataFields"> { readonly query?: TypedSubmissionPageQueryOptions; readonly customColumns?: TMeta extends BaseSubmissionMetadata ? MetadataCsvExportOptions["customColumns"] : MetadataCsvExportOptions["customColumns"]; readonly includeMetadataFields?: TMeta extends BaseSubmissionMetadata ? MetadataCsvExportOptions["includeMetadataFields"] : MetadataCsvExportOptions["includeMetadataFields"]; } interface TextAnswerItem { readonly responseId: string; readonly formId: string; readonly formVersion: number; readonly fieldId: string; readonly text: string; readonly locale?: string; readonly submittedAt: string; readonly metadata?: Readonly>; } interface TextAnswerPage { readonly items: readonly TextAnswerItem[]; readonly nextCursor?: string; readonly hasMore: boolean; } /** Text-answer page retaining the metadata type of the source submission. */ interface TypedTextAnswerItem extends Omit { readonly metadata?: [TMeta] extends [undefined] ? Readonly> : TMeta; } interface TypedTextAnswerPage { readonly items: readonly TypedTextAnswerItem[]; readonly nextCursor?: string; readonly hasMore: boolean; } interface VersionTransitionPlan { readonly formId: string; readonly expectedRevision: number; readonly nextRevision: number; readonly draftToCreate?: FormVersionRecord; readonly draftToDeleteVersion?: number; readonly publishedRecordToSave?: FormVersionRecord; readonly archivedRecordsToSave?: readonly FormVersionRecord[]; readonly events: readonly VersionTransitionEvent[]; /** The complete next state value used by persistent adapters. */ readonly nextVersion?: number; /** Optional target schema for adapters that do not use a version record. */ readonly schema?: FormSchema; readonly timestamp: string; } type StorageCommitError = { readonly type: "revision_conflict"; readonly expectedRevision: number; readonly actualRevision?: number; } | { readonly type: "draft_already_exists"; readonly currentDraftVersion: number; } | { readonly type: "transaction_unsupported"; } | { readonly type: "invalid_transition"; readonly message: string; } | { readonly type: "storage_error"; readonly cause: unknown; }; interface VersionedFormStorageAdapter extends FormStorageAdapter { getVersionState(formId: string): Promise; getVersionRecord(formId: string, version: number): Promise; listVersionRecords(formId: string): Promise; commitVersionTransition(plan: VersionTransitionPlan): Promise>; } interface BaseQuestionAggregate { readonly fieldId: string; readonly answeredCount: number; readonly unansweredCount: number; } interface TextQuestionAggregate extends BaseQuestionAggregate { readonly kind: "text" | "textarea" | "date" | "time" | "email" | "tel" | "url"; } interface NumberQuestionAggregate extends BaseQuestionAggregate { readonly kind: "number" | "rating"; readonly minimum: number | null; readonly maximum: number | null; readonly average: number | null; readonly total: number; } interface OptionAggregate { readonly id: string; readonly count: number; readonly percentageOfSubmissions: number; } interface ChoiceQuestionAggregate extends BaseQuestionAggregate { readonly kind: "select" | "radio" | "multi-select"; readonly options: readonly OptionAggregate[]; } interface CheckboxQuestionAggregate extends BaseQuestionAggregate { readonly kind: "checkbox"; readonly trueCount: number; readonly falseCount: number; readonly truePercentageOfSubmissions: number; readonly falsePercentageOfSubmissions: number; } type QuestionAggregate = TextQuestionAggregate | NumberQuestionAggregate | ChoiceQuestionAggregate | CheckboxQuestionAggregate; interface FormAnalytics { readonly formId: string; readonly formVersion: number; readonly submissionCount: number; readonly questions: readonly QuestionAggregate[]; } type Question = FormField; type ChoiceOption = FieldOption; interface FieldTypeDefinition { readonly type: QuestionType; readonly labelKey: BuilderTranslationKey; readonly defaultLabel: string; readonly category: "text" | "choice" | "number" | "advanced"; readonly hasOptions: boolean; } interface FormResponse extends ExtensibleNode { readonly responseId: string; readonly formId: string; readonly formVersion?: number; readonly sourceLocale?: string; readonly answers: Readonly>; readonly submittedAt: string; } interface CrossTabulationResult { readonly rowQuestionId: string; readonly colQuestionId: string; readonly matrix: Readonly>>>; readonly rowTotals: Readonly>; readonly colTotals: Readonly>; readonly grandTotal: number; } interface ValidateFormSchemaOptions { readonly policy?: FormPolicy; } declare function validateFormSchema(input: unknown, options?: ValidateFormSchemaOptions): SchemaValidationResult; declare function assertValidFormSchema(input: unknown, options?: ValidateFormSchemaOptions): asserts input is FormSchema; interface ChoiceDistributionEntry { readonly count: number; readonly percentage: number; } interface NumericSummary { readonly average: number | null; readonly min: number | null; readonly max: number | null; readonly total: number; } declare function calculateChoiceDistribution(responses: readonly FormSubmission[], questionId: string): Record; declare function calculateNumericSummary(responses: readonly FormSubmission[], questionId: string): NumericSummary; declare function calculateCrossTabulation(responses: readonly FormSubmission[], rowQuestionId: string, colQuestionId: string): CrossTabulationResult; declare function aggregateResponses(schema: FormSchema, submissions: readonly FormSubmission[], options?: ValidateFormSchemaOptions): FormAnalytics; type AccumulatorResponse = FormSubmission | FormResponse; type AccumulatorSkipReason = "form_id_mismatch" | "version_mismatch" | "invalid_structure"; interface AccumulatorReport { readonly processedCount: number; readonly skippedCount: number; readonly skipReasons: readonly { readonly responseId: string; readonly reason: AccumulatorSkipReason; }[]; } interface ResponseAccumulator { add(submission: AccumulatorResponse): { readonly success: boolean; readonly skipped?: boolean; readonly error?: string; }; addMany(submissions: Iterable): AccumulatorReport; merge(other: ResponseAccumulator): ResponseAccumulator; finalize(): FormAnalytics; getReport(): AccumulatorReport; } interface ResponseAccumulatorOptions { readonly mode?: "strict" | "lenient"; readonly policy?: FormPolicy; } declare function createResponseAccumulator(schema: FormSchema, options?: ResponseAccumulatorOptions): ResponseAccumulator; declare function escapeCsvCell(value: string | number | boolean | null | undefined, neutralizeFormulas?: boolean): string; interface CsvColumnDefinition { readonly key: string; readonly header: string; readonly getValue: (submission: FormSubmission, schema: FormSchema) => string | number | boolean | null | undefined; } interface CsvExportOptions { readonly policy?: FormPolicy; readonly withBom?: boolean; readonly neutralizeFormulas?: boolean; /** Alias for withBom used by the public export contract. */ readonly useBom?: boolean; /** Alias for neutralizeFormulas used by the public export contract. */ readonly preventFormulaInjection?: boolean; readonly customColumns?: readonly CsvColumnDefinition[]; readonly includePiiStatus?: boolean; readonly includeLocale?: boolean; } interface MetadataCsvExportOptions extends CsvExportOptions { readonly includeMetadataFields?: readonly Extract[]; } interface CsvColumnDef { readonly header: string; readonly getValue: (context: CsvColumnContext) => string | number | boolean | null | undefined | Promise; } interface CsvColumnContext extends FormResponse { readonly submission: FormResponse; readonly formVersion: number; readonly schema: FormSchema; } interface StreamCsvOptions extends CsvExportOptions { readonly columns?: readonly CsvColumnDef[]; readonly includeDefaultColumns?: boolean; } interface TypedStreamCsvOptions extends Omit { readonly includeMetadataFields?: readonly Extract[]; } type CsvStream = ReadableStream & AsyncIterable; declare function exportResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable, options?: StreamCsvOptions): AsyncIterable; declare function exportResponsesToCsvStream(schema: FormSchema, submissions: Iterable> | AsyncIterable>, options?: TypedStreamCsvOptions): CsvStream; declare function exportResponsesToCsvStream(schema: FormSchema, submissions: Iterable | AsyncIterable, options?: StreamCsvOptions): CsvStream; interface NodeWritableStream { write(chunk: Uint8Array): boolean; once(event: "drain", listener: () => void): unknown; once(event: "error", listener: (error: Error) => void): unknown; removeListener(event: "drain", listener: () => void): unknown; removeListener(event: "error", listener: (error: Error) => void): unknown; end(callback: () => void): unknown; } declare function pipeResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable, writable: WritableStream | NodeWritableStream, options?: StreamCsvOptions): Promise; declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: CsvExportOptions): string; declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: MetadataCsvExportOptions): string; export { contentMetadataToJson as $, type AsyncTranslationAdapter as A, type BaseSubmissionMetadata as B, type CreateSubmissionInput as C, type DisplayConditionGroup as D, type ExtensibleNode as E, type FormAnalytics as F, type ContentModeSettings as G, type ContentModeValidationResult as H, type CustomFormMetadata as I, type JsonValue as J, type FormContentMode as K, type PollAccessContext as L, type PollMetadata as M, type PollRuntimeAdapter as N, type QuizEvaluationResult as O, type PagedSubmissionStorageAdapter as P, type QuestionType as Q, type QuizFieldMetadata as R, type SensitiveDataFinding as S, type TranslationAdapter as T, type UnifiedSubmissionStorageAdapter as U, type ValidateFormSchemaOptions as V, type QuizMetadata as W, type QuizQuestionEvaluation as X, type QuizQuestionResult as Y, type QuizResult as Z, canShowPollResults as _, type FormSubmission as a, type MultiSelectField as a$, createInitialSchemaByMode as a0, evaluateQuiz as a1, evaluateQuizLocally as a2, getContentModeDiagnostics as a3, getContentModePolicy as a4, getFormContentMode as a5, readPollMetadata as a6, readQuizFieldMetadata as a7, readQuizMetadata as a8, resolveContentModeSettings as a9, createCloneTransitionPlan as aA, createDeleteDraftTransitionPlan as aB, createPublishTransitionPlan as aC, deleteDraft as aD, publishDraft as aE, type AnswerValidationResult as aF, type BaseField as aG, type BaseFieldConstraintRule as aH, type CheckboxField as aI, type CheckboxQuestionAggregate as aJ, type ChoiceFieldConstraintRule as aK, type ChoiceOption as aL, type ChoiceQuestionAggregate as aM, type ConditionOperator as aN, type ConditionValue as aO, type CrossTabulationResult as aP, type DateField as aQ, type DisplayRule as aR, type EmailField as aS, type FieldConstraintRule as aT, type FieldDisplayCondition as aU, type FieldType as aV, type FormStorageAdapter as aW, type FormSubmissionSettings as aX, type FormValue as aY, type LocaleOption as aZ, type LocalizedText as a_, validateContentMode as aa, validateContentModeConstraints as ab, type FormSubmissionValidator as ac, type FormSubmissionValidatorResult as ad, type SubmissionSchema as ae, type SubmissionValidationResult as af, validateAnswers as ag, validateFieldValue as ah, validatePageAnswers as ai, validateSubmission as aj, type CloneVersionOptions as ak, type CommitVersionTransitionOptions as al, type DeleteDraftOptions as am, type FormVersionState as an, type FormVersionStatus as ao, type FormVersionTransitionPlan as ap, type PublishDraftOptions as aq, type PublishDraftResult as ar, type Result as as, type VersionTransitionContext as at, type VersionTransitionError as au, type VersionTransitionEvent as av, applyTransitionPlan as aw, assertVersionMutable as ax, cloneVersionToDraft as ay, commitVersionTransition as az, type FormPolicy as b, escapeCsvCell as b$, type NumberField as b0, type NumberQuestionAggregate as b1, type OptionAggregate as b2, type Question as b3, type RadioTextAnswer as b4, type RatingField as b5, type RatingFieldConstraintRule as b6, type SaveSubmissionOptions as b7, type SchemaIssue as b8, type SchemaTranslations as b9, type UrlField as bA, type ValidationError as bB, type ValidationIssue as bC, type VersionTransitionPlan as bD, type VersionedFormStorageAdapter as bE, assertValidFormSchema as bF, validateFormSchema as bG, type AccumulatorReport as bH, type AccumulatorResponse as bI, type AccumulatorSkipReason as bJ, type ChoiceDistributionEntry as bK, type CsvColumnContext as bL, type CsvColumnDef as bM, type CsvColumnDefinition as bN, type CsvExportOptions as bO, type MetadataCsvExportOptions as bP, type NodeWritableStream as bQ, type NumericSummary as bR, type ResponseAccumulator as bS, type ResponseAccumulatorOptions as bT, type StreamCsvOptions as bU, type TypedStreamCsvOptions as bV, aggregateResponses as bW, calculateChoiceDistribution as bX, calculateCrossTabulation as bY, calculateNumericSummary as bZ, createResponseAccumulator as b_, type SchemaValidationResult as ba, type SelectField as bb, type StorageAdapter as bc, type StorageCommitError as bd, type StorageSubmissionExportOptions as be, type SubmissionPage as bf, type SubmissionQueryOptions as bg, type TelField as bh, type TextAnswerItem as bi, type TextAnswerPage as bj, type TextAnswerPageQueryOptions as bk, type TextField as bl, type TextFieldConstraintRule as bm, type TextQuestionAggregate as bn, type TimeField as bo, type TypedExtensibleNode as bp, type TypedFieldOption as bq, type TypedFormField as br, type TypedFormSchema as bs, type TypedFormStorageAdapter as bt, type TypedPagedSubmissionStorageAdapter as bu, type TypedStorageAdapter as bv, type TypedSubmissionPage as bw, type TypedSubmissionPageQueryOptions as bx, type TypedTextAnswerItem as by, type TypedTextAnswerPage as bz, type FormSchema as c, exportResponsesToCsv as c0, exportResponsesToCsvStream as c1, pipeResponsesToCsvStream as c2, type FormField as d, type FieldTypeDefinition as e, type FieldOption as f, type FormPage as g, type SubmissionPageQueryOptions as h, type FormResponse as i, type SubmissionFilter as j, type QuestionAggregate as k, type FormVersionRecord as l, type ValidationCode as m, type DisplayCondition as n, type FormValues as o, type SubmissionSaveResult as p, type PrivacyEngine as q, type FormSubmissionValidationSource as r, type FormSubmissionWire as s, type StrictFormSubmission as t, type StrictFormSubmissionWire as u, type ContentModeConstraintCode as v, type ContentModeConstraintIssue as w, type ContentModeDiagnostic as x, type ContentModeIssue as y, type ContentModeIssueCode as z };