@form-engine-ts/core 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -6,10 +6,16 @@ interface DisplayCondition {
6
6
  readonly operator: ConditionOperator;
7
7
  readonly value?: ConditionValue;
8
8
  }
9
+ interface LocalizedText {
10
+ readonly title?: string;
11
+ readonly description?: string;
12
+ }
13
+ type SchemaTranslations = Readonly<Record<string, LocalizedText>>;
9
14
  type ValidationCode = "required" | "invalid_type" | "min_length" | "max_length" | "pattern" | "min" | "max" | "step" | "invalid_option" | "min_selections" | "max_selections" | "unknown_field";
10
15
  interface FieldOption {
11
16
  readonly id: string;
12
17
  readonly label: string;
18
+ readonly translations?: Readonly<Record<string, string>>;
13
19
  }
14
20
  interface BaseField {
15
21
  readonly id: string;
@@ -20,6 +26,7 @@ interface BaseField {
20
26
  readonly required: boolean;
21
27
  readonly messages?: Partial<Record<ValidationCode, string>>;
22
28
  readonly displayCondition?: DisplayCondition;
29
+ readonly translations?: SchemaTranslations;
23
30
  }
24
31
  interface TextField extends BaseField {
25
32
  readonly type: "text" | "textarea";
@@ -54,13 +61,25 @@ interface CheckboxField extends BaseField {
54
61
  readonly type: "checkbox";
55
62
  }
56
63
  type FormField = TextField | NumberField | RatingField | SelectField | MultiSelectField | CheckboxField;
64
+ interface FormPage {
65
+ readonly id: string;
66
+ readonly title?: string;
67
+ readonly description?: string;
68
+ readonly questionIds: readonly string[];
69
+ readonly displayCondition?: DisplayCondition;
70
+ readonly translations?: SchemaTranslations;
71
+ }
57
72
  interface FormSchema {
58
73
  readonly id: string;
59
74
  readonly version: number;
60
75
  readonly title: string;
61
76
  readonly description?: string;
62
77
  readonly submitLabelKey?: string;
78
+ readonly defaultLocale?: string;
79
+ readonly supportedLocales?: readonly string[];
80
+ readonly translations?: SchemaTranslations;
63
81
  readonly fields: readonly FormField[];
82
+ readonly pages?: readonly FormPage[];
64
83
  }
65
84
  type FormValue = string | number | boolean | readonly string[] | undefined;
66
85
  type FormValues = Readonly<Record<string, FormValue>>;
@@ -105,9 +124,13 @@ interface AsyncTranslationAdapter {
105
124
  translateText(text: string, targetLocale: string, sourceLocale?: string): Promise<string>;
106
125
  translateBatch(texts: readonly string[], targetLocale: string, sourceLocale?: string): Promise<readonly string[]>;
107
126
  }
127
+ interface SubmissionQueryOptions {
128
+ readonly since?: string;
129
+ readonly until?: string;
130
+ }
108
131
  interface StorageAdapter {
109
132
  saveSubmission(submission: FormSubmission): Promise<void>;
110
- listSubmissions(formId: string, formVersion?: number): Promise<readonly FormSubmission[]>;
133
+ listSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise<readonly FormSubmission[]>;
111
134
  clearResponses?(formId: string): Promise<void>;
112
135
  clear(): Promise<void>;
113
136
  }
@@ -160,6 +183,14 @@ type Question = FormField;
160
183
  type QuestionType = FieldType;
161
184
  type ChoiceOption = FieldOption;
162
185
  type FormResponse = FormSubmission;
186
+ interface CrossTabulationResult {
187
+ readonly rowQuestionId: string;
188
+ readonly colQuestionId: string;
189
+ readonly matrix: Readonly<Record<string, Readonly<Record<string, number>>>>;
190
+ readonly rowTotals: Readonly<Record<string, number>>;
191
+ readonly colTotals: Readonly<Record<string, number>>;
192
+ readonly grandTotal: number;
193
+ }
163
194
 
164
195
  interface ChoiceDistributionEntry {
165
196
  readonly count: number;
@@ -173,6 +204,7 @@ interface NumericSummary {
173
204
  }
174
205
  declare function calculateChoiceDistribution(responses: readonly FormSubmission[], questionId: string): Record<string, ChoiceDistributionEntry>;
175
206
  declare function calculateNumericSummary(responses: readonly FormSubmission[], questionId: string): NumericSummary;
207
+ declare function calculateCrossTabulation(responses: readonly FormSubmission[], rowQuestionId: string, colQuestionId: string): CrossTabulationResult;
176
208
  declare function aggregateResponses(schema: FormSchema, submissions: readonly FormSubmission[]): FormAnalytics;
177
209
  declare function escapeCsvCell(value: string | number | null | undefined): string;
178
210
  interface CsvExportOptions {
@@ -180,6 +212,27 @@ interface CsvExportOptions {
180
212
  }
181
213
  declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: CsvExportOptions): string;
182
214
 
215
+ type FormEventType = "response.submitted" | "schema.updated";
216
+ interface FormEvent<T = unknown> {
217
+ readonly id: string;
218
+ readonly type: FormEventType;
219
+ readonly formId: string;
220
+ readonly timestamp: string;
221
+ readonly payload: T;
222
+ }
223
+ interface WebhookConfig {
224
+ readonly url: string;
225
+ readonly secret?: string;
226
+ readonly headers?: Readonly<Record<string, string>>;
227
+ readonly timeoutMs?: number;
228
+ }
229
+ interface WebhookDispatchResult {
230
+ readonly success: boolean;
231
+ readonly status?: number;
232
+ readonly error?: string;
233
+ }
234
+ declare function dispatchWebhook<T>(event: FormEvent<T>, config: WebhookConfig, fetchImpl?: typeof fetch): Promise<WebhookDispatchResult>;
235
+
183
236
  type SchemaStructureIssueType = "dangling_condition_reference" | "duplicate_question_id" | "duplicate_choice_id" | "self_condition_reference" | "cyclic_condition_reference";
184
237
  interface SchemaStructureIssue {
185
238
  readonly type: SchemaStructureIssueType;
@@ -200,12 +253,17 @@ interface CreateSubmissionOptions {
200
253
  }
201
254
  declare function createSubmission(schema: FormSchema, values: FormValues, options: CreateSubmissionOptions): FormSubmission;
202
255
 
256
+ declare function resolveLocalizedSchema(schema: FormSchema, targetLocale: string): FormSchema;
257
+ declare function populateSchemaTranslations(schema: FormSchema, targetLocales: readonly string[], adapter: AsyncTranslationAdapter): Promise<FormSchema>;
203
258
  declare function resolveFormTranslation(schema: FormSchema, adapter: AsyncTranslationAdapter, targetLocale: string, sourceLocale?: string): Promise<FormSchema>;
204
259
 
205
260
  declare function validateAnswers(schema: FormSchema, values: FormValues): AnswerValidationResult;
261
+ declare function validatePageAnswers(schema: FormSchema, pageIndex: number, values: FormValues): AnswerValidationResult;
206
262
 
207
263
  declare function isQuestionVisible(question: FormField, currentAnswers: Readonly<Record<string, unknown>>): boolean;
264
+ declare function isDisplayConditionSatisfied(condition: DisplayCondition | undefined, currentAnswers: Readonly<Record<string, unknown>>): boolean;
265
+ declare function calculatePageVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
208
266
  declare function calculateFieldVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
209
267
  declare function selectVisibleAnswers(schema: FormSchema, currentAnswers: FormValues): FormValues;
210
268
 
211
- export { type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CsvExportOptions, type DisplayCondition, type FieldOption, type FieldType, type FormAnalytics, type FormField, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type Question, type QuestionAggregate, type QuestionType, type RatingField, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaValidationResult, type SelectField, type StorageAdapter, type TextField, type TextQuestionAggregate, type TranslationAdapter, type ValidationCode, type ValidationIssue, aggregateResponses, assertValidFormSchema, calculateChoiceDistribution, calculateFieldVisibility, calculateNumericSummary, createSubmission, escapeCsvCell, exportResponsesToCsv, isQuestionVisible, resolveFormTranslation, sanitizeSchema, selectVisibleAnswers, validateAnswers, validateFormSchema, validateSchemaStructure };
269
+ export { type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvExportOptions, type DisplayCondition, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type LocalizedText, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type Question, type QuestionAggregate, type QuestionType, type RatingField, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type ValidationCode, type ValidationIssue, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, createSubmission, dispatchWebhook, escapeCsvCell, exportResponsesToCsv, isDisplayConditionSatisfied, isQuestionVisible, populateSchemaTranslations, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };
package/dist/index.d.ts CHANGED
@@ -6,10 +6,16 @@ interface DisplayCondition {
6
6
  readonly operator: ConditionOperator;
7
7
  readonly value?: ConditionValue;
8
8
  }
9
+ interface LocalizedText {
10
+ readonly title?: string;
11
+ readonly description?: string;
12
+ }
13
+ type SchemaTranslations = Readonly<Record<string, LocalizedText>>;
9
14
  type ValidationCode = "required" | "invalid_type" | "min_length" | "max_length" | "pattern" | "min" | "max" | "step" | "invalid_option" | "min_selections" | "max_selections" | "unknown_field";
10
15
  interface FieldOption {
11
16
  readonly id: string;
12
17
  readonly label: string;
18
+ readonly translations?: Readonly<Record<string, string>>;
13
19
  }
14
20
  interface BaseField {
15
21
  readonly id: string;
@@ -20,6 +26,7 @@ interface BaseField {
20
26
  readonly required: boolean;
21
27
  readonly messages?: Partial<Record<ValidationCode, string>>;
22
28
  readonly displayCondition?: DisplayCondition;
29
+ readonly translations?: SchemaTranslations;
23
30
  }
24
31
  interface TextField extends BaseField {
25
32
  readonly type: "text" | "textarea";
@@ -54,13 +61,25 @@ interface CheckboxField extends BaseField {
54
61
  readonly type: "checkbox";
55
62
  }
56
63
  type FormField = TextField | NumberField | RatingField | SelectField | MultiSelectField | CheckboxField;
64
+ interface FormPage {
65
+ readonly id: string;
66
+ readonly title?: string;
67
+ readonly description?: string;
68
+ readonly questionIds: readonly string[];
69
+ readonly displayCondition?: DisplayCondition;
70
+ readonly translations?: SchemaTranslations;
71
+ }
57
72
  interface FormSchema {
58
73
  readonly id: string;
59
74
  readonly version: number;
60
75
  readonly title: string;
61
76
  readonly description?: string;
62
77
  readonly submitLabelKey?: string;
78
+ readonly defaultLocale?: string;
79
+ readonly supportedLocales?: readonly string[];
80
+ readonly translations?: SchemaTranslations;
63
81
  readonly fields: readonly FormField[];
82
+ readonly pages?: readonly FormPage[];
64
83
  }
65
84
  type FormValue = string | number | boolean | readonly string[] | undefined;
66
85
  type FormValues = Readonly<Record<string, FormValue>>;
@@ -105,9 +124,13 @@ interface AsyncTranslationAdapter {
105
124
  translateText(text: string, targetLocale: string, sourceLocale?: string): Promise<string>;
106
125
  translateBatch(texts: readonly string[], targetLocale: string, sourceLocale?: string): Promise<readonly string[]>;
107
126
  }
127
+ interface SubmissionQueryOptions {
128
+ readonly since?: string;
129
+ readonly until?: string;
130
+ }
108
131
  interface StorageAdapter {
109
132
  saveSubmission(submission: FormSubmission): Promise<void>;
110
- listSubmissions(formId: string, formVersion?: number): Promise<readonly FormSubmission[]>;
133
+ listSubmissions(formId: string, formVersion?: number, options?: SubmissionQueryOptions): Promise<readonly FormSubmission[]>;
111
134
  clearResponses?(formId: string): Promise<void>;
112
135
  clear(): Promise<void>;
113
136
  }
@@ -160,6 +183,14 @@ type Question = FormField;
160
183
  type QuestionType = FieldType;
161
184
  type ChoiceOption = FieldOption;
162
185
  type FormResponse = FormSubmission;
186
+ interface CrossTabulationResult {
187
+ readonly rowQuestionId: string;
188
+ readonly colQuestionId: string;
189
+ readonly matrix: Readonly<Record<string, Readonly<Record<string, number>>>>;
190
+ readonly rowTotals: Readonly<Record<string, number>>;
191
+ readonly colTotals: Readonly<Record<string, number>>;
192
+ readonly grandTotal: number;
193
+ }
163
194
 
164
195
  interface ChoiceDistributionEntry {
165
196
  readonly count: number;
@@ -173,6 +204,7 @@ interface NumericSummary {
173
204
  }
174
205
  declare function calculateChoiceDistribution(responses: readonly FormSubmission[], questionId: string): Record<string, ChoiceDistributionEntry>;
175
206
  declare function calculateNumericSummary(responses: readonly FormSubmission[], questionId: string): NumericSummary;
207
+ declare function calculateCrossTabulation(responses: readonly FormSubmission[], rowQuestionId: string, colQuestionId: string): CrossTabulationResult;
176
208
  declare function aggregateResponses(schema: FormSchema, submissions: readonly FormSubmission[]): FormAnalytics;
177
209
  declare function escapeCsvCell(value: string | number | null | undefined): string;
178
210
  interface CsvExportOptions {
@@ -180,6 +212,27 @@ interface CsvExportOptions {
180
212
  }
181
213
  declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: CsvExportOptions): string;
182
214
 
215
+ type FormEventType = "response.submitted" | "schema.updated";
216
+ interface FormEvent<T = unknown> {
217
+ readonly id: string;
218
+ readonly type: FormEventType;
219
+ readonly formId: string;
220
+ readonly timestamp: string;
221
+ readonly payload: T;
222
+ }
223
+ interface WebhookConfig {
224
+ readonly url: string;
225
+ readonly secret?: string;
226
+ readonly headers?: Readonly<Record<string, string>>;
227
+ readonly timeoutMs?: number;
228
+ }
229
+ interface WebhookDispatchResult {
230
+ readonly success: boolean;
231
+ readonly status?: number;
232
+ readonly error?: string;
233
+ }
234
+ declare function dispatchWebhook<T>(event: FormEvent<T>, config: WebhookConfig, fetchImpl?: typeof fetch): Promise<WebhookDispatchResult>;
235
+
183
236
  type SchemaStructureIssueType = "dangling_condition_reference" | "duplicate_question_id" | "duplicate_choice_id" | "self_condition_reference" | "cyclic_condition_reference";
184
237
  interface SchemaStructureIssue {
185
238
  readonly type: SchemaStructureIssueType;
@@ -200,12 +253,17 @@ interface CreateSubmissionOptions {
200
253
  }
201
254
  declare function createSubmission(schema: FormSchema, values: FormValues, options: CreateSubmissionOptions): FormSubmission;
202
255
 
256
+ declare function resolveLocalizedSchema(schema: FormSchema, targetLocale: string): FormSchema;
257
+ declare function populateSchemaTranslations(schema: FormSchema, targetLocales: readonly string[], adapter: AsyncTranslationAdapter): Promise<FormSchema>;
203
258
  declare function resolveFormTranslation(schema: FormSchema, adapter: AsyncTranslationAdapter, targetLocale: string, sourceLocale?: string): Promise<FormSchema>;
204
259
 
205
260
  declare function validateAnswers(schema: FormSchema, values: FormValues): AnswerValidationResult;
261
+ declare function validatePageAnswers(schema: FormSchema, pageIndex: number, values: FormValues): AnswerValidationResult;
206
262
 
207
263
  declare function isQuestionVisible(question: FormField, currentAnswers: Readonly<Record<string, unknown>>): boolean;
264
+ declare function isDisplayConditionSatisfied(condition: DisplayCondition | undefined, currentAnswers: Readonly<Record<string, unknown>>): boolean;
265
+ declare function calculatePageVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
208
266
  declare function calculateFieldVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
209
267
  declare function selectVisibleAnswers(schema: FormSchema, currentAnswers: FormValues): FormValues;
210
268
 
211
- export { type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CsvExportOptions, type DisplayCondition, type FieldOption, type FieldType, type FormAnalytics, type FormField, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type Question, type QuestionAggregate, type QuestionType, type RatingField, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaValidationResult, type SelectField, type StorageAdapter, type TextField, type TextQuestionAggregate, type TranslationAdapter, type ValidationCode, type ValidationIssue, aggregateResponses, assertValidFormSchema, calculateChoiceDistribution, calculateFieldVisibility, calculateNumericSummary, createSubmission, escapeCsvCell, exportResponsesToCsv, isQuestionVisible, resolveFormTranslation, sanitizeSchema, selectVisibleAnswers, validateAnswers, validateFormSchema, validateSchemaStructure };
269
+ export { type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvExportOptions, type DisplayCondition, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type LocalizedText, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type Question, type QuestionAggregate, type QuestionType, type RatingField, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type ValidationCode, type ValidationIssue, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, createSubmission, dispatchWebhook, escapeCsvCell, exportResponsesToCsv, isDisplayConditionSatisfied, isQuestionVisible, populateSchemaTranslations, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };