import { FormLifecycleAdapter } from './lifecycle.js'; import { BuilderTranslationKey } from './i18n/keys.js'; 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; /** Scope used by atomic response limits. Defaults to the form version. */ readonly responseLimitScope?: "form" | "version"; } interface FormRuntimeSettings { readonly formId: string; readonly openAt?: string; readonly closeAt?: string; readonly maxResponses?: number; readonly iconKey?: string; readonly colorToken?: string; readonly metadata?: Readonly>; readonly updatedAt: string; } /** 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 its version or form-wide response limit has capacity. */ 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; getRuntimeSettings?(formId: string): Promise; saveRuntimeSettings?(settings: FormRuntimeSettings): Promise; readonly inspectFormDeletion?: FormLifecycleAdapter["inspectFormDeletion"]; readonly deleteForm?: FormLifecycleAdapter["deleteForm"]; readonly lifecycleCapabilities?: FormLifecycleAdapter["lifecycleCapabilities"]; } interface FormRuntimeSettingsStorageAdapter extends FormStorageAdapter { getRuntimeSettings(formId: string): Promise; saveRuntimeSettings(settings: FormRuntimeSettings): Promise; } 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 its version or form-wide response limit has capacity. */ 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 { canShowPollResults 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 ContentModeIssueCode as G, type ContentModeSettings as H, type ContentModeValidationResult as I, type JsonValue as J, type CustomFormMetadata as K, type FormContentMode as L, type PollAccessContext as M, type PollMetadata as N, type PollRuntimeAdapter as O, type PagedSubmissionStorageAdapter as P, type QuestionType as Q, type QuizEvaluationResult as R, type SensitiveDataFinding as S, type TranslationAdapter as T, type UnifiedSubmissionStorageAdapter as U, type ValidateFormSchemaOptions as V, type QuizFieldMetadata as W, type QuizMetadata as X, type QuizQuestionEvaluation as Y, type QuizQuestionResult as Z, type QuizResult as _, type FormSubmission as a, type LocaleOption as a$, contentMetadataToJson as a0, createInitialSchemaByMode as a1, evaluateQuiz as a2, evaluateQuizLocally as a3, getContentModeDiagnostics as a4, getContentModePolicy as a5, getFormContentMode as a6, readPollMetadata as a7, readQuizFieldMetadata as a8, readQuizMetadata as a9, commitVersionTransition as aA, createCloneTransitionPlan as aB, createDeleteDraftTransitionPlan as aC, createPublishTransitionPlan as aD, deleteDraft as aE, publishDraft as aF, type AnswerValidationResult as aG, type BaseField as aH, type BaseFieldConstraintRule as aI, type CheckboxField as aJ, type CheckboxQuestionAggregate as aK, type ChoiceFieldConstraintRule as aL, type ChoiceOption as aM, type ChoiceQuestionAggregate as aN, type ConditionOperator as aO, type ConditionValue as aP, type CrossTabulationResult as aQ, type DateField as aR, type DisplayRule as aS, type EmailField as aT, type FieldConstraintRule as aU, type FieldDisplayCondition as aV, type FieldType as aW, type FormRuntimeSettingsStorageAdapter as aX, type FormStorageAdapter as aY, type FormSubmissionSettings as aZ, type FormValue as a_, resolveContentModeSettings as aa, validateContentMode as ab, validateContentModeConstraints as ac, type FormSubmissionValidator as ad, type FormSubmissionValidatorResult as ae, type SubmissionSchema as af, type SubmissionValidationResult as ag, validateAnswers as ah, validateFieldValue as ai, validatePageAnswers as aj, validateSubmission as ak, type CloneVersionOptions as al, type CommitVersionTransitionOptions as am, type DeleteDraftOptions as an, type FormVersionState as ao, type FormVersionStatus as ap, type FormVersionTransitionPlan as aq, type PublishDraftOptions as ar, type PublishDraftResult as as, type Result as at, type VersionTransitionContext as au, type VersionTransitionError as av, type VersionTransitionEvent as aw, applyTransitionPlan as ax, assertVersionMutable as ay, cloneVersionToDraft as az, type FormPolicy as b, calculateNumericSummary as b$, type LocalizedText as b0, type MultiSelectField as b1, type NumberField as b2, type NumberQuestionAggregate as b3, type OptionAggregate as b4, type Question as b5, type RadioTextAnswer as b6, type RatingField as b7, type RatingFieldConstraintRule as b8, type SaveSubmissionOptions as b9, type TypedTextAnswerItem as bA, type TypedTextAnswerPage as bB, type UrlField as bC, type ValidationError as bD, type ValidationIssue as bE, type VersionTransitionPlan as bF, type VersionedFormStorageAdapter as bG, assertValidFormSchema as bH, validateFormSchema as bI, type AccumulatorReport as bJ, type AccumulatorResponse as bK, type AccumulatorSkipReason as bL, type ChoiceDistributionEntry as bM, type CsvColumnContext as bN, type CsvColumnDef as bO, type CsvColumnDefinition as bP, type CsvExportOptions as bQ, type MetadataCsvExportOptions as bR, type NodeWritableStream as bS, type NumericSummary as bT, type ResponseAccumulator as bU, type ResponseAccumulatorOptions as bV, type StreamCsvOptions as bW, type TypedStreamCsvOptions as bX, aggregateResponses as bY, calculateChoiceDistribution as bZ, calculateCrossTabulation as b_, type SchemaIssue as ba, type SchemaTranslations as bb, type SchemaValidationResult as bc, type SelectField as bd, type StorageAdapter as be, type StorageCommitError as bf, type StorageSubmissionExportOptions as bg, type SubmissionPage as bh, type SubmissionQueryOptions as bi, type TelField as bj, type TextAnswerItem as bk, type TextAnswerPage as bl, type TextAnswerPageQueryOptions as bm, type TextField as bn, type TextFieldConstraintRule as bo, type TextQuestionAggregate as bp, type TimeField as bq, type TypedExtensibleNode as br, type TypedFieldOption as bs, type TypedFormField as bt, type TypedFormSchema as bu, type TypedFormStorageAdapter as bv, type TypedPagedSubmissionStorageAdapter as bw, type TypedStorageAdapter as bx, type TypedSubmissionPage as by, type TypedSubmissionPageQueryOptions as bz, type FormSchema as c, createResponseAccumulator as c0, escapeCsvCell as c1, exportResponsesToCsv as c2, exportResponsesToCsvStream as c3, pipeResponsesToCsvStream as c4, 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 FormRuntimeSettings as r, type FormSubmissionValidationSource as s, type FormSubmissionWire as t, type StrictFormSubmission as u, type StrictFormSubmissionWire as v, type ContentModeConstraintCode as w, type ContentModeConstraintIssue as x, type ContentModeDiagnostic as y, type ContentModeIssue as z };