@form-engine-ts/core 2.5.0 → 2.6.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/README.md +14 -4
- package/dist/index.cjs +228 -25
- package/dist/index.d.cts +135 -66
- package/dist/index.d.ts +135 -66
- package/dist/index.js +225 -25
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
+
type Result<T, E> = {
|
|
2
|
+
readonly success: true;
|
|
3
|
+
readonly value: T;
|
|
4
|
+
} | {
|
|
5
|
+
readonly success: false;
|
|
6
|
+
readonly error: E;
|
|
7
|
+
};
|
|
8
|
+
type FormVersionStatus = "draft" | "published" | "archived";
|
|
9
|
+
interface FormVersionRecord extends ExtensibleNode {
|
|
10
|
+
readonly formId: string;
|
|
11
|
+
readonly version: number;
|
|
12
|
+
readonly status: FormVersionStatus;
|
|
13
|
+
readonly schema: FormSchema;
|
|
14
|
+
readonly revision: number;
|
|
15
|
+
readonly createdFromVersion?: number;
|
|
16
|
+
readonly createdAt: string;
|
|
17
|
+
readonly publishedAt?: string;
|
|
18
|
+
readonly archivedAt?: string;
|
|
19
|
+
}
|
|
20
|
+
interface FormVersionState {
|
|
21
|
+
readonly formId: string;
|
|
22
|
+
readonly draftVersion?: number;
|
|
23
|
+
readonly publishedVersion?: number;
|
|
24
|
+
readonly nextVersion: number;
|
|
25
|
+
readonly revision: number;
|
|
26
|
+
}
|
|
27
|
+
type VersionTransitionError = {
|
|
28
|
+
readonly type: "draft_already_exists";
|
|
29
|
+
readonly currentDraftVersion: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly type: "draft_not_found";
|
|
32
|
+
} | {
|
|
33
|
+
readonly type: "revision_conflict";
|
|
34
|
+
readonly expectedRevision: number;
|
|
35
|
+
readonly actualRevision: number;
|
|
36
|
+
} | {
|
|
37
|
+
readonly type: "invalid_source_version";
|
|
38
|
+
readonly requestedVersion: number;
|
|
39
|
+
readonly publishedVersion?: number;
|
|
40
|
+
} | {
|
|
41
|
+
readonly type: "version_immutable";
|
|
42
|
+
readonly status: FormVersionStatus;
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: "max_version_exceeded";
|
|
45
|
+
readonly max: number;
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "validation_failed";
|
|
48
|
+
readonly issues: readonly SchemaIssue[];
|
|
49
|
+
};
|
|
50
|
+
interface CloneVersionOptions {
|
|
51
|
+
readonly maxVersions?: number;
|
|
52
|
+
readonly expectedRevision?: number;
|
|
53
|
+
/** Additional known published versions that may be used as a clone source. */
|
|
54
|
+
readonly allowedSourceVersions?: readonly number[];
|
|
55
|
+
}
|
|
56
|
+
interface PublishDraftOptions {
|
|
57
|
+
readonly expectedRevision?: number;
|
|
58
|
+
readonly currentPublishedRecord?: FormVersionRecord;
|
|
59
|
+
readonly validate?: (schema: FormSchema) => boolean | Promise<boolean> | readonly SchemaIssue[] | Promise<readonly SchemaIssue[]>;
|
|
60
|
+
readonly publishedAt?: string;
|
|
61
|
+
/** @deprecated Use publishedAt. */
|
|
62
|
+
readonly timestamp?: string;
|
|
63
|
+
}
|
|
64
|
+
interface DeleteDraftOptions {
|
|
65
|
+
readonly expectedRevision?: number;
|
|
66
|
+
}
|
|
67
|
+
interface PublishDraftResult {
|
|
68
|
+
readonly nextState: FormVersionState;
|
|
69
|
+
readonly publishedRecord: FormVersionRecord;
|
|
70
|
+
readonly archivedRecords: readonly FormVersionRecord[];
|
|
71
|
+
/** @deprecated Read archivedRecords instead. */
|
|
72
|
+
readonly archivedVersion?: number;
|
|
73
|
+
}
|
|
74
|
+
declare function cloneVersionToDraft(state: FormVersionState, sourceSchema: FormSchema, options?: CloneVersionOptions): Result<{
|
|
75
|
+
readonly nextState: FormVersionState;
|
|
76
|
+
readonly draftSchema: FormSchema;
|
|
77
|
+
}, VersionTransitionError>;
|
|
78
|
+
declare function publishDraft(state: FormVersionState, draftSchema: FormSchema, options?: PublishDraftOptions): Promise<Result<PublishDraftResult, VersionTransitionError>>;
|
|
79
|
+
declare function createPublishTransitionPlan(state: FormVersionState, draftRecord: FormVersionRecord, options?: PublishDraftOptions): Promise<Result<{
|
|
80
|
+
readonly nextState: FormVersionState;
|
|
81
|
+
readonly plan: VersionTransitionPlan;
|
|
82
|
+
}, VersionTransitionError>>;
|
|
83
|
+
declare function deleteDraft(state: FormVersionState, options?: DeleteDraftOptions): Result<{
|
|
84
|
+
readonly nextState: FormVersionState;
|
|
85
|
+
}, VersionTransitionError>;
|
|
86
|
+
declare function assertVersionMutable(status: FormVersionStatus): void;
|
|
87
|
+
|
|
1
88
|
type FieldType = "text" | "textarea" | "number" | "rating" | "select" | "multi-select" | "checkbox" | "radio";
|
|
2
89
|
interface FormPolicy {
|
|
3
90
|
readonly allowedFieldTypes?: readonly FieldType[];
|
|
@@ -170,6 +257,8 @@ interface SubmissionPageQueryOptions {
|
|
|
170
257
|
readonly since?: string;
|
|
171
258
|
readonly until?: string;
|
|
172
259
|
readonly locale?: string;
|
|
260
|
+
readonly filter?: (submission: FormSubmission) => boolean;
|
|
261
|
+
readonly metadataFilters?: Readonly<Record<string, JsonValue>>;
|
|
173
262
|
}
|
|
174
263
|
interface SubmissionPage {
|
|
175
264
|
readonly items: readonly FormSubmission[];
|
|
@@ -179,6 +268,22 @@ interface SubmissionPage {
|
|
|
179
268
|
interface PagedSubmissionStorageAdapter extends FormStorageAdapter {
|
|
180
269
|
listSubmissionPage(formId: string, options?: SubmissionPageQueryOptions): Promise<SubmissionPage>;
|
|
181
270
|
}
|
|
271
|
+
interface VersionTransitionPlan {
|
|
272
|
+
readonly formId: string;
|
|
273
|
+
readonly expectedRevision: number;
|
|
274
|
+
readonly nextRevision: number;
|
|
275
|
+
readonly draftToCreate?: FormVersionRecord;
|
|
276
|
+
readonly draftToDeleteVersion?: number;
|
|
277
|
+
readonly publishedRecordToSave?: FormVersionRecord;
|
|
278
|
+
readonly archivedRecordsToSave?: readonly FormVersionRecord[];
|
|
279
|
+
readonly timestamp: string;
|
|
280
|
+
}
|
|
281
|
+
interface VersionedFormStorageAdapter extends FormStorageAdapter {
|
|
282
|
+
commitVersionTransition(plan: VersionTransitionPlan): Promise<{
|
|
283
|
+
readonly success: boolean;
|
|
284
|
+
readonly error?: string;
|
|
285
|
+
}>;
|
|
286
|
+
}
|
|
182
287
|
interface BaseQuestionAggregate {
|
|
183
288
|
readonly fieldId: string;
|
|
184
289
|
readonly answeredCount: number;
|
|
@@ -223,6 +328,7 @@ type ChoiceOption = FieldOption;
|
|
|
223
328
|
interface FormResponse extends ExtensibleNode {
|
|
224
329
|
readonly responseId: string;
|
|
225
330
|
readonly formId: string;
|
|
331
|
+
readonly formVersion?: number;
|
|
226
332
|
readonly sourceLocale?: string;
|
|
227
333
|
readonly answers: Readonly<Record<string, unknown>>;
|
|
228
334
|
readonly submittedAt: string;
|
|
@@ -251,14 +357,25 @@ declare function calculateNumericSummary(responses: readonly FormSubmission[], q
|
|
|
251
357
|
declare function calculateCrossTabulation(responses: readonly FormSubmission[], rowQuestionId: string, colQuestionId: string): CrossTabulationResult;
|
|
252
358
|
declare function aggregateResponses(schema: FormSchema, submissions: readonly FormSubmission[]): FormAnalytics;
|
|
253
359
|
type AccumulatorResponse = FormSubmission | FormResponse;
|
|
360
|
+
type AccumulatorSkipReason = "form_id_mismatch" | "version_mismatch" | "invalid_structure";
|
|
361
|
+
interface AccumulatorReport {
|
|
362
|
+
readonly processedCount: number;
|
|
363
|
+
readonly skippedCount: number;
|
|
364
|
+
readonly skipReasons: readonly {
|
|
365
|
+
readonly responseId: string;
|
|
366
|
+
readonly reason: AccumulatorSkipReason;
|
|
367
|
+
}[];
|
|
368
|
+
}
|
|
254
369
|
interface ResponseAccumulator {
|
|
255
370
|
add(submission: AccumulatorResponse): {
|
|
256
371
|
readonly success: boolean;
|
|
372
|
+
readonly skipped?: boolean;
|
|
257
373
|
readonly error?: string;
|
|
258
374
|
};
|
|
259
|
-
addMany(submissions: Iterable<AccumulatorResponse>):
|
|
375
|
+
addMany(submissions: Iterable<AccumulatorResponse>): AccumulatorReport;
|
|
260
376
|
merge(other: ResponseAccumulator): ResponseAccumulator;
|
|
261
377
|
finalize(): FormAnalytics;
|
|
378
|
+
getReport(): AccumulatorReport;
|
|
262
379
|
}
|
|
263
380
|
interface ResponseAccumulatorOptions {
|
|
264
381
|
readonly mode?: "strict" | "lenient";
|
|
@@ -271,13 +388,27 @@ interface CsvExportOptions {
|
|
|
271
388
|
}
|
|
272
389
|
interface CsvColumnDef {
|
|
273
390
|
readonly header: string;
|
|
274
|
-
readonly getValue: (
|
|
391
|
+
readonly getValue: (context: CsvColumnContext) => string | number | boolean | null | undefined | Promise<string | number | boolean | null | undefined>;
|
|
392
|
+
}
|
|
393
|
+
interface CsvColumnContext extends FormResponse {
|
|
394
|
+
readonly submission: FormResponse;
|
|
395
|
+
readonly formVersion: number;
|
|
396
|
+
readonly schema: FormSchema;
|
|
275
397
|
}
|
|
276
398
|
interface StreamCsvOptions extends CsvExportOptions {
|
|
277
399
|
readonly columns?: readonly CsvColumnDef[];
|
|
278
400
|
readonly includeDefaultColumns?: boolean;
|
|
279
401
|
}
|
|
280
402
|
declare function exportResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable<AccumulatorResponse>, options?: StreamCsvOptions): AsyncIterable<string>;
|
|
403
|
+
interface NodeWritableStream {
|
|
404
|
+
write(chunk: Uint8Array): boolean;
|
|
405
|
+
once(event: "drain", listener: () => void): unknown;
|
|
406
|
+
once(event: "error", listener: (error: Error) => void): unknown;
|
|
407
|
+
removeListener(event: "drain", listener: () => void): unknown;
|
|
408
|
+
removeListener(event: "error", listener: (error: Error) => void): unknown;
|
|
409
|
+
end(callback: () => void): unknown;
|
|
410
|
+
}
|
|
411
|
+
declare function pipeResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable<AccumulatorResponse>, writable: WritableStream<Uint8Array> | NodeWritableStream, options?: StreamCsvOptions): Promise<void>;
|
|
281
412
|
declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: CsvExportOptions): string;
|
|
282
413
|
|
|
283
414
|
type FormEventType = "response.submitted" | "schema.updated";
|
|
@@ -314,6 +445,7 @@ interface SubmissionCursorValue {
|
|
|
314
445
|
declare function encodeSubmissionCursor(value: SubmissionCursorValue): string;
|
|
315
446
|
declare function decodeSubmissionCursor(cursor: string): SubmissionCursorValue;
|
|
316
447
|
declare function normalizeSubmissionPageSize(pageSize: number | undefined, fallback?: number): number;
|
|
448
|
+
declare function matchesSubmissionPageFilters(submission: FormSubmission, options: Pick<SubmissionPageQueryOptions, "filter" | "metadataFilters">): boolean;
|
|
317
449
|
|
|
318
450
|
interface CollectedLocales {
|
|
319
451
|
readonly defaultLocale?: string;
|
|
@@ -382,73 +514,10 @@ declare function resolveFormTranslation(schema: FormSchema, adapter: AsyncTransl
|
|
|
382
514
|
declare function validateAnswers(schema: FormSchema, values: FormValues): AnswerValidationResult;
|
|
383
515
|
declare function validatePageAnswers(schema: FormSchema, pageIndex: number, values: FormValues): AnswerValidationResult;
|
|
384
516
|
|
|
385
|
-
type Result<T, E> = {
|
|
386
|
-
readonly success: true;
|
|
387
|
-
readonly value: T;
|
|
388
|
-
} | {
|
|
389
|
-
readonly success: false;
|
|
390
|
-
readonly error: E;
|
|
391
|
-
};
|
|
392
|
-
type FormVersionStatus = "draft" | "published" | "archived";
|
|
393
|
-
interface FormVersionRecord {
|
|
394
|
-
readonly formId: string;
|
|
395
|
-
readonly version: number;
|
|
396
|
-
readonly status: FormVersionStatus;
|
|
397
|
-
readonly schema: FormSchema;
|
|
398
|
-
readonly createdAt: string;
|
|
399
|
-
readonly publishedAt?: string;
|
|
400
|
-
readonly archivedAt?: string;
|
|
401
|
-
}
|
|
402
|
-
interface FormVersionState {
|
|
403
|
-
readonly formId: string;
|
|
404
|
-
readonly draftVersion?: number;
|
|
405
|
-
readonly publishedVersion?: number;
|
|
406
|
-
readonly nextVersion: number;
|
|
407
|
-
readonly revision: number;
|
|
408
|
-
}
|
|
409
|
-
type VersionTransitionError = {
|
|
410
|
-
readonly type: "draft_already_exists";
|
|
411
|
-
readonly currentDraftVersion: number;
|
|
412
|
-
} | {
|
|
413
|
-
readonly type: "draft_not_found";
|
|
414
|
-
} | {
|
|
415
|
-
readonly type: "revision_conflict";
|
|
416
|
-
readonly expectedRevision: number;
|
|
417
|
-
readonly actualRevision: number;
|
|
418
|
-
} | {
|
|
419
|
-
readonly type: "version_immutable";
|
|
420
|
-
readonly status: FormVersionStatus;
|
|
421
|
-
} | {
|
|
422
|
-
readonly type: "max_version_exceeded";
|
|
423
|
-
readonly max: number;
|
|
424
|
-
};
|
|
425
|
-
interface CloneVersionOptions {
|
|
426
|
-
readonly maxVersions?: number;
|
|
427
|
-
}
|
|
428
|
-
interface PublishDraftOptions {
|
|
429
|
-
readonly expectedRevision?: number;
|
|
430
|
-
readonly validate?: (schema: FormSchema) => boolean;
|
|
431
|
-
/** Supplies deterministic record timestamps while keeping the transition pure. */
|
|
432
|
-
readonly timestamp?: string;
|
|
433
|
-
}
|
|
434
|
-
declare function cloneVersionToDraft(state: FormVersionState, sourceSchema: FormSchema, options?: CloneVersionOptions): Result<{
|
|
435
|
-
readonly nextState: FormVersionState;
|
|
436
|
-
readonly draftSchema: FormSchema;
|
|
437
|
-
}, VersionTransitionError>;
|
|
438
|
-
declare function publishDraft(state: FormVersionState, draftSchema: FormSchema, options?: PublishDraftOptions): Result<{
|
|
439
|
-
readonly nextState: FormVersionState;
|
|
440
|
-
readonly publishedRecord: FormVersionRecord;
|
|
441
|
-
readonly archivedVersion?: number;
|
|
442
|
-
}, VersionTransitionError>;
|
|
443
|
-
declare function deleteDraft(state: FormVersionState): Result<{
|
|
444
|
-
readonly nextState: FormVersionState;
|
|
445
|
-
}, VersionTransitionError>;
|
|
446
|
-
declare function assertVersionMutable(status: FormVersionStatus): void;
|
|
447
|
-
|
|
448
517
|
declare function isQuestionVisible(question: FormField, currentAnswers: Readonly<Record<string, unknown>>): boolean;
|
|
449
518
|
declare function isDisplayConditionSatisfied(condition: DisplayCondition | undefined, currentAnswers: Readonly<Record<string, unknown>>): boolean;
|
|
450
519
|
declare function calculatePageVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
|
|
451
520
|
declare function calculateFieldVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
|
|
452
521
|
declare function selectVisibleAnswers(schema: FormSchema, currentAnswers: FormValues): FormValues;
|
|
453
522
|
|
|
454
|
-
export { type AccumulatorResponse, type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type CloneVersionOptions, type CollectedLocales, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvColumnDef, type CsvExportOptions, type DisplayCondition, type ExtensibleNode, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormPolicy, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type FormVersionRecord, type FormVersionState, type FormVersionStatus, type JsonValue, type LocalizedText, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type PagedSubmissionStorageAdapter, type PopulateTranslationOptions, type PublishDraftOptions, type Question, type QuestionAggregate, type QuestionType, type RatingField, type ResponseAccumulator, type ResponseAccumulatorOptions, type Result, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type StreamCsvOptions, type SubmissionCursorValue, type SubmissionPage, type SubmissionPageQueryOptions, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type TranslationReport, type TranslationSlot, type ValidateFormSchemaOptions, type ValidationCode, type ValidationError, type ValidationIssue, type VersionTransitionError, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, assertVersionMutable, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, cloneVersionToDraft, collectSchemaLocales, createResponseAccumulator, createSubmission, decodeSubmissionCursor, deleteDraft, dispatchWebhook, encodeSubmissionCursor, escapeCsvCell, exportResponsesToCsv, exportResponsesToCsvStream, isDisplayConditionSatisfied, isQuestionVisible, normalizeSubmissionPageSize, populateSchemaTranslations, publishDraft, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, transformFieldType, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };
|
|
523
|
+
export { type AccumulatorReport, type AccumulatorResponse, type AccumulatorSkipReason, type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type CloneVersionOptions, type CollectedLocales, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvColumnContext, type CsvColumnDef, type CsvExportOptions, type DeleteDraftOptions, type DisplayCondition, type ExtensibleNode, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormPolicy, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type FormVersionRecord, type FormVersionState, type FormVersionStatus, type JsonValue, type LocalizedText, type MultiSelectField, type NodeWritableStream, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type PagedSubmissionStorageAdapter, type PopulateTranslationOptions, type PublishDraftOptions, type PublishDraftResult, type Question, type QuestionAggregate, type QuestionType, type RatingField, type ResponseAccumulator, type ResponseAccumulatorOptions, type Result, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type StreamCsvOptions, type SubmissionCursorValue, type SubmissionPage, type SubmissionPageQueryOptions, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type TranslationReport, type TranslationSlot, type ValidateFormSchemaOptions, type ValidationCode, type ValidationError, type ValidationIssue, type VersionTransitionError, type VersionTransitionPlan, type VersionedFormStorageAdapter, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, assertVersionMutable, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, cloneVersionToDraft, collectSchemaLocales, createPublishTransitionPlan, createResponseAccumulator, createSubmission, decodeSubmissionCursor, deleteDraft, dispatchWebhook, encodeSubmissionCursor, escapeCsvCell, exportResponsesToCsv, exportResponsesToCsvStream, isDisplayConditionSatisfied, isQuestionVisible, matchesSubmissionPageFilters, normalizeSubmissionPageSize, pipeResponsesToCsvStream, populateSchemaTranslations, publishDraft, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, transformFieldType, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
+
type Result<T, E> = {
|
|
2
|
+
readonly success: true;
|
|
3
|
+
readonly value: T;
|
|
4
|
+
} | {
|
|
5
|
+
readonly success: false;
|
|
6
|
+
readonly error: E;
|
|
7
|
+
};
|
|
8
|
+
type FormVersionStatus = "draft" | "published" | "archived";
|
|
9
|
+
interface FormVersionRecord extends ExtensibleNode {
|
|
10
|
+
readonly formId: string;
|
|
11
|
+
readonly version: number;
|
|
12
|
+
readonly status: FormVersionStatus;
|
|
13
|
+
readonly schema: FormSchema;
|
|
14
|
+
readonly revision: number;
|
|
15
|
+
readonly createdFromVersion?: number;
|
|
16
|
+
readonly createdAt: string;
|
|
17
|
+
readonly publishedAt?: string;
|
|
18
|
+
readonly archivedAt?: string;
|
|
19
|
+
}
|
|
20
|
+
interface FormVersionState {
|
|
21
|
+
readonly formId: string;
|
|
22
|
+
readonly draftVersion?: number;
|
|
23
|
+
readonly publishedVersion?: number;
|
|
24
|
+
readonly nextVersion: number;
|
|
25
|
+
readonly revision: number;
|
|
26
|
+
}
|
|
27
|
+
type VersionTransitionError = {
|
|
28
|
+
readonly type: "draft_already_exists";
|
|
29
|
+
readonly currentDraftVersion: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly type: "draft_not_found";
|
|
32
|
+
} | {
|
|
33
|
+
readonly type: "revision_conflict";
|
|
34
|
+
readonly expectedRevision: number;
|
|
35
|
+
readonly actualRevision: number;
|
|
36
|
+
} | {
|
|
37
|
+
readonly type: "invalid_source_version";
|
|
38
|
+
readonly requestedVersion: number;
|
|
39
|
+
readonly publishedVersion?: number;
|
|
40
|
+
} | {
|
|
41
|
+
readonly type: "version_immutable";
|
|
42
|
+
readonly status: FormVersionStatus;
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: "max_version_exceeded";
|
|
45
|
+
readonly max: number;
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "validation_failed";
|
|
48
|
+
readonly issues: readonly SchemaIssue[];
|
|
49
|
+
};
|
|
50
|
+
interface CloneVersionOptions {
|
|
51
|
+
readonly maxVersions?: number;
|
|
52
|
+
readonly expectedRevision?: number;
|
|
53
|
+
/** Additional known published versions that may be used as a clone source. */
|
|
54
|
+
readonly allowedSourceVersions?: readonly number[];
|
|
55
|
+
}
|
|
56
|
+
interface PublishDraftOptions {
|
|
57
|
+
readonly expectedRevision?: number;
|
|
58
|
+
readonly currentPublishedRecord?: FormVersionRecord;
|
|
59
|
+
readonly validate?: (schema: FormSchema) => boolean | Promise<boolean> | readonly SchemaIssue[] | Promise<readonly SchemaIssue[]>;
|
|
60
|
+
readonly publishedAt?: string;
|
|
61
|
+
/** @deprecated Use publishedAt. */
|
|
62
|
+
readonly timestamp?: string;
|
|
63
|
+
}
|
|
64
|
+
interface DeleteDraftOptions {
|
|
65
|
+
readonly expectedRevision?: number;
|
|
66
|
+
}
|
|
67
|
+
interface PublishDraftResult {
|
|
68
|
+
readonly nextState: FormVersionState;
|
|
69
|
+
readonly publishedRecord: FormVersionRecord;
|
|
70
|
+
readonly archivedRecords: readonly FormVersionRecord[];
|
|
71
|
+
/** @deprecated Read archivedRecords instead. */
|
|
72
|
+
readonly archivedVersion?: number;
|
|
73
|
+
}
|
|
74
|
+
declare function cloneVersionToDraft(state: FormVersionState, sourceSchema: FormSchema, options?: CloneVersionOptions): Result<{
|
|
75
|
+
readonly nextState: FormVersionState;
|
|
76
|
+
readonly draftSchema: FormSchema;
|
|
77
|
+
}, VersionTransitionError>;
|
|
78
|
+
declare function publishDraft(state: FormVersionState, draftSchema: FormSchema, options?: PublishDraftOptions): Promise<Result<PublishDraftResult, VersionTransitionError>>;
|
|
79
|
+
declare function createPublishTransitionPlan(state: FormVersionState, draftRecord: FormVersionRecord, options?: PublishDraftOptions): Promise<Result<{
|
|
80
|
+
readonly nextState: FormVersionState;
|
|
81
|
+
readonly plan: VersionTransitionPlan;
|
|
82
|
+
}, VersionTransitionError>>;
|
|
83
|
+
declare function deleteDraft(state: FormVersionState, options?: DeleteDraftOptions): Result<{
|
|
84
|
+
readonly nextState: FormVersionState;
|
|
85
|
+
}, VersionTransitionError>;
|
|
86
|
+
declare function assertVersionMutable(status: FormVersionStatus): void;
|
|
87
|
+
|
|
1
88
|
type FieldType = "text" | "textarea" | "number" | "rating" | "select" | "multi-select" | "checkbox" | "radio";
|
|
2
89
|
interface FormPolicy {
|
|
3
90
|
readonly allowedFieldTypes?: readonly FieldType[];
|
|
@@ -170,6 +257,8 @@ interface SubmissionPageQueryOptions {
|
|
|
170
257
|
readonly since?: string;
|
|
171
258
|
readonly until?: string;
|
|
172
259
|
readonly locale?: string;
|
|
260
|
+
readonly filter?: (submission: FormSubmission) => boolean;
|
|
261
|
+
readonly metadataFilters?: Readonly<Record<string, JsonValue>>;
|
|
173
262
|
}
|
|
174
263
|
interface SubmissionPage {
|
|
175
264
|
readonly items: readonly FormSubmission[];
|
|
@@ -179,6 +268,22 @@ interface SubmissionPage {
|
|
|
179
268
|
interface PagedSubmissionStorageAdapter extends FormStorageAdapter {
|
|
180
269
|
listSubmissionPage(formId: string, options?: SubmissionPageQueryOptions): Promise<SubmissionPage>;
|
|
181
270
|
}
|
|
271
|
+
interface VersionTransitionPlan {
|
|
272
|
+
readonly formId: string;
|
|
273
|
+
readonly expectedRevision: number;
|
|
274
|
+
readonly nextRevision: number;
|
|
275
|
+
readonly draftToCreate?: FormVersionRecord;
|
|
276
|
+
readonly draftToDeleteVersion?: number;
|
|
277
|
+
readonly publishedRecordToSave?: FormVersionRecord;
|
|
278
|
+
readonly archivedRecordsToSave?: readonly FormVersionRecord[];
|
|
279
|
+
readonly timestamp: string;
|
|
280
|
+
}
|
|
281
|
+
interface VersionedFormStorageAdapter extends FormStorageAdapter {
|
|
282
|
+
commitVersionTransition(plan: VersionTransitionPlan): Promise<{
|
|
283
|
+
readonly success: boolean;
|
|
284
|
+
readonly error?: string;
|
|
285
|
+
}>;
|
|
286
|
+
}
|
|
182
287
|
interface BaseQuestionAggregate {
|
|
183
288
|
readonly fieldId: string;
|
|
184
289
|
readonly answeredCount: number;
|
|
@@ -223,6 +328,7 @@ type ChoiceOption = FieldOption;
|
|
|
223
328
|
interface FormResponse extends ExtensibleNode {
|
|
224
329
|
readonly responseId: string;
|
|
225
330
|
readonly formId: string;
|
|
331
|
+
readonly formVersion?: number;
|
|
226
332
|
readonly sourceLocale?: string;
|
|
227
333
|
readonly answers: Readonly<Record<string, unknown>>;
|
|
228
334
|
readonly submittedAt: string;
|
|
@@ -251,14 +357,25 @@ declare function calculateNumericSummary(responses: readonly FormSubmission[], q
|
|
|
251
357
|
declare function calculateCrossTabulation(responses: readonly FormSubmission[], rowQuestionId: string, colQuestionId: string): CrossTabulationResult;
|
|
252
358
|
declare function aggregateResponses(schema: FormSchema, submissions: readonly FormSubmission[]): FormAnalytics;
|
|
253
359
|
type AccumulatorResponse = FormSubmission | FormResponse;
|
|
360
|
+
type AccumulatorSkipReason = "form_id_mismatch" | "version_mismatch" | "invalid_structure";
|
|
361
|
+
interface AccumulatorReport {
|
|
362
|
+
readonly processedCount: number;
|
|
363
|
+
readonly skippedCount: number;
|
|
364
|
+
readonly skipReasons: readonly {
|
|
365
|
+
readonly responseId: string;
|
|
366
|
+
readonly reason: AccumulatorSkipReason;
|
|
367
|
+
}[];
|
|
368
|
+
}
|
|
254
369
|
interface ResponseAccumulator {
|
|
255
370
|
add(submission: AccumulatorResponse): {
|
|
256
371
|
readonly success: boolean;
|
|
372
|
+
readonly skipped?: boolean;
|
|
257
373
|
readonly error?: string;
|
|
258
374
|
};
|
|
259
|
-
addMany(submissions: Iterable<AccumulatorResponse>):
|
|
375
|
+
addMany(submissions: Iterable<AccumulatorResponse>): AccumulatorReport;
|
|
260
376
|
merge(other: ResponseAccumulator): ResponseAccumulator;
|
|
261
377
|
finalize(): FormAnalytics;
|
|
378
|
+
getReport(): AccumulatorReport;
|
|
262
379
|
}
|
|
263
380
|
interface ResponseAccumulatorOptions {
|
|
264
381
|
readonly mode?: "strict" | "lenient";
|
|
@@ -271,13 +388,27 @@ interface CsvExportOptions {
|
|
|
271
388
|
}
|
|
272
389
|
interface CsvColumnDef {
|
|
273
390
|
readonly header: string;
|
|
274
|
-
readonly getValue: (
|
|
391
|
+
readonly getValue: (context: CsvColumnContext) => string | number | boolean | null | undefined | Promise<string | number | boolean | null | undefined>;
|
|
392
|
+
}
|
|
393
|
+
interface CsvColumnContext extends FormResponse {
|
|
394
|
+
readonly submission: FormResponse;
|
|
395
|
+
readonly formVersion: number;
|
|
396
|
+
readonly schema: FormSchema;
|
|
275
397
|
}
|
|
276
398
|
interface StreamCsvOptions extends CsvExportOptions {
|
|
277
399
|
readonly columns?: readonly CsvColumnDef[];
|
|
278
400
|
readonly includeDefaultColumns?: boolean;
|
|
279
401
|
}
|
|
280
402
|
declare function exportResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable<AccumulatorResponse>, options?: StreamCsvOptions): AsyncIterable<string>;
|
|
403
|
+
interface NodeWritableStream {
|
|
404
|
+
write(chunk: Uint8Array): boolean;
|
|
405
|
+
once(event: "drain", listener: () => void): unknown;
|
|
406
|
+
once(event: "error", listener: (error: Error) => void): unknown;
|
|
407
|
+
removeListener(event: "drain", listener: () => void): unknown;
|
|
408
|
+
removeListener(event: "error", listener: (error: Error) => void): unknown;
|
|
409
|
+
end(callback: () => void): unknown;
|
|
410
|
+
}
|
|
411
|
+
declare function pipeResponsesToCsvStream(schema: FormSchema, submissions: AsyncIterable<AccumulatorResponse>, writable: WritableStream<Uint8Array> | NodeWritableStream, options?: StreamCsvOptions): Promise<void>;
|
|
281
412
|
declare function exportResponsesToCsv(schema: FormSchema, responses: readonly FormSubmission[], options?: CsvExportOptions): string;
|
|
282
413
|
|
|
283
414
|
type FormEventType = "response.submitted" | "schema.updated";
|
|
@@ -314,6 +445,7 @@ interface SubmissionCursorValue {
|
|
|
314
445
|
declare function encodeSubmissionCursor(value: SubmissionCursorValue): string;
|
|
315
446
|
declare function decodeSubmissionCursor(cursor: string): SubmissionCursorValue;
|
|
316
447
|
declare function normalizeSubmissionPageSize(pageSize: number | undefined, fallback?: number): number;
|
|
448
|
+
declare function matchesSubmissionPageFilters(submission: FormSubmission, options: Pick<SubmissionPageQueryOptions, "filter" | "metadataFilters">): boolean;
|
|
317
449
|
|
|
318
450
|
interface CollectedLocales {
|
|
319
451
|
readonly defaultLocale?: string;
|
|
@@ -382,73 +514,10 @@ declare function resolveFormTranslation(schema: FormSchema, adapter: AsyncTransl
|
|
|
382
514
|
declare function validateAnswers(schema: FormSchema, values: FormValues): AnswerValidationResult;
|
|
383
515
|
declare function validatePageAnswers(schema: FormSchema, pageIndex: number, values: FormValues): AnswerValidationResult;
|
|
384
516
|
|
|
385
|
-
type Result<T, E> = {
|
|
386
|
-
readonly success: true;
|
|
387
|
-
readonly value: T;
|
|
388
|
-
} | {
|
|
389
|
-
readonly success: false;
|
|
390
|
-
readonly error: E;
|
|
391
|
-
};
|
|
392
|
-
type FormVersionStatus = "draft" | "published" | "archived";
|
|
393
|
-
interface FormVersionRecord {
|
|
394
|
-
readonly formId: string;
|
|
395
|
-
readonly version: number;
|
|
396
|
-
readonly status: FormVersionStatus;
|
|
397
|
-
readonly schema: FormSchema;
|
|
398
|
-
readonly createdAt: string;
|
|
399
|
-
readonly publishedAt?: string;
|
|
400
|
-
readonly archivedAt?: string;
|
|
401
|
-
}
|
|
402
|
-
interface FormVersionState {
|
|
403
|
-
readonly formId: string;
|
|
404
|
-
readonly draftVersion?: number;
|
|
405
|
-
readonly publishedVersion?: number;
|
|
406
|
-
readonly nextVersion: number;
|
|
407
|
-
readonly revision: number;
|
|
408
|
-
}
|
|
409
|
-
type VersionTransitionError = {
|
|
410
|
-
readonly type: "draft_already_exists";
|
|
411
|
-
readonly currentDraftVersion: number;
|
|
412
|
-
} | {
|
|
413
|
-
readonly type: "draft_not_found";
|
|
414
|
-
} | {
|
|
415
|
-
readonly type: "revision_conflict";
|
|
416
|
-
readonly expectedRevision: number;
|
|
417
|
-
readonly actualRevision: number;
|
|
418
|
-
} | {
|
|
419
|
-
readonly type: "version_immutable";
|
|
420
|
-
readonly status: FormVersionStatus;
|
|
421
|
-
} | {
|
|
422
|
-
readonly type: "max_version_exceeded";
|
|
423
|
-
readonly max: number;
|
|
424
|
-
};
|
|
425
|
-
interface CloneVersionOptions {
|
|
426
|
-
readonly maxVersions?: number;
|
|
427
|
-
}
|
|
428
|
-
interface PublishDraftOptions {
|
|
429
|
-
readonly expectedRevision?: number;
|
|
430
|
-
readonly validate?: (schema: FormSchema) => boolean;
|
|
431
|
-
/** Supplies deterministic record timestamps while keeping the transition pure. */
|
|
432
|
-
readonly timestamp?: string;
|
|
433
|
-
}
|
|
434
|
-
declare function cloneVersionToDraft(state: FormVersionState, sourceSchema: FormSchema, options?: CloneVersionOptions): Result<{
|
|
435
|
-
readonly nextState: FormVersionState;
|
|
436
|
-
readonly draftSchema: FormSchema;
|
|
437
|
-
}, VersionTransitionError>;
|
|
438
|
-
declare function publishDraft(state: FormVersionState, draftSchema: FormSchema, options?: PublishDraftOptions): Result<{
|
|
439
|
-
readonly nextState: FormVersionState;
|
|
440
|
-
readonly publishedRecord: FormVersionRecord;
|
|
441
|
-
readonly archivedVersion?: number;
|
|
442
|
-
}, VersionTransitionError>;
|
|
443
|
-
declare function deleteDraft(state: FormVersionState): Result<{
|
|
444
|
-
readonly nextState: FormVersionState;
|
|
445
|
-
}, VersionTransitionError>;
|
|
446
|
-
declare function assertVersionMutable(status: FormVersionStatus): void;
|
|
447
|
-
|
|
448
517
|
declare function isQuestionVisible(question: FormField, currentAnswers: Readonly<Record<string, unknown>>): boolean;
|
|
449
518
|
declare function isDisplayConditionSatisfied(condition: DisplayCondition | undefined, currentAnswers: Readonly<Record<string, unknown>>): boolean;
|
|
450
519
|
declare function calculatePageVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
|
|
451
520
|
declare function calculateFieldVisibility(schema: FormSchema, currentAnswers: Readonly<Record<string, unknown>>): Readonly<Record<string, boolean>>;
|
|
452
521
|
declare function selectVisibleAnswers(schema: FormSchema, currentAnswers: FormValues): FormValues;
|
|
453
522
|
|
|
454
|
-
export { type AccumulatorResponse, type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type CloneVersionOptions, type CollectedLocales, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvColumnDef, type CsvExportOptions, type DisplayCondition, type ExtensibleNode, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormPolicy, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type FormVersionRecord, type FormVersionState, type FormVersionStatus, type JsonValue, type LocalizedText, type MultiSelectField, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type PagedSubmissionStorageAdapter, type PopulateTranslationOptions, type PublishDraftOptions, type Question, type QuestionAggregate, type QuestionType, type RatingField, type ResponseAccumulator, type ResponseAccumulatorOptions, type Result, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type StreamCsvOptions, type SubmissionCursorValue, type SubmissionPage, type SubmissionPageQueryOptions, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type TranslationReport, type TranslationSlot, type ValidateFormSchemaOptions, type ValidationCode, type ValidationError, type ValidationIssue, type VersionTransitionError, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, assertVersionMutable, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, cloneVersionToDraft, collectSchemaLocales, createResponseAccumulator, createSubmission, decodeSubmissionCursor, deleteDraft, dispatchWebhook, encodeSubmissionCursor, escapeCsvCell, exportResponsesToCsv, exportResponsesToCsvStream, isDisplayConditionSatisfied, isQuestionVisible, normalizeSubmissionPageSize, populateSchemaTranslations, publishDraft, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, transformFieldType, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };
|
|
523
|
+
export { type AccumulatorReport, type AccumulatorResponse, type AccumulatorSkipReason, type AnswerValidationResult, type AsyncTranslationAdapter, type BaseField, type CheckboxField, type CheckboxQuestionAggregate, type ChoiceDistributionEntry, type ChoiceOption, type ChoiceQuestionAggregate, type CloneVersionOptions, type CollectedLocales, type ConditionOperator, type ConditionValue, type CreateSubmissionOptions, type CrossTabulationResult, type CsvColumnContext, type CsvColumnDef, type CsvExportOptions, type DeleteDraftOptions, type DisplayCondition, type ExtensibleNode, type FieldOption, type FieldType, type FormAnalytics, type FormEvent, type FormEventType, type FormField, type FormPage, type FormPolicy, type FormResponse, type FormSchema, type FormStorageAdapter, type FormSubmission, type FormValue, type FormValues, type FormVersionRecord, type FormVersionState, type FormVersionStatus, type JsonValue, type LocalizedText, type MultiSelectField, type NodeWritableStream, type NumberField, type NumberQuestionAggregate, type NumericSummary, type OptionAggregate, type PagedSubmissionStorageAdapter, type PopulateTranslationOptions, type PublishDraftOptions, type PublishDraftResult, type Question, type QuestionAggregate, type QuestionType, type RatingField, type ResponseAccumulator, type ResponseAccumulatorOptions, type Result, type SchemaIssue, type SchemaStructureIssue, type SchemaStructureIssueType, type SchemaTranslations, type SchemaValidationResult, type SelectField, type StorageAdapter, type StreamCsvOptions, type SubmissionCursorValue, type SubmissionPage, type SubmissionPageQueryOptions, type SubmissionQueryOptions, type TextField, type TextQuestionAggregate, type TranslationAdapter, type TranslationReport, type TranslationSlot, type ValidateFormSchemaOptions, type ValidationCode, type ValidationError, type ValidationIssue, type VersionTransitionError, type VersionTransitionPlan, type VersionedFormStorageAdapter, type WebhookConfig, type WebhookDispatchResult, aggregateResponses, assertValidFormSchema, assertVersionMutable, calculateChoiceDistribution, calculateCrossTabulation, calculateFieldVisibility, calculateNumericSummary, calculatePageVisibility, cloneVersionToDraft, collectSchemaLocales, createPublishTransitionPlan, createResponseAccumulator, createSubmission, decodeSubmissionCursor, deleteDraft, dispatchWebhook, encodeSubmissionCursor, escapeCsvCell, exportResponsesToCsv, exportResponsesToCsvStream, isDisplayConditionSatisfied, isQuestionVisible, matchesSubmissionPageFilters, normalizeSubmissionPageSize, pipeResponsesToCsvStream, populateSchemaTranslations, publishDraft, resolveFormTranslation, resolveLocalizedSchema, sanitizeSchema, selectVisibleAnswers, transformFieldType, validateAnswers, validateFormSchema, validatePageAnswers, validateSchemaStructure };
|