@form-engine-ts/core 4.7.0 → 5.0.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 +32 -0
- package/dist/index.cjs +732 -69
- package/dist/index.d.cts +164 -5
- package/dist/index.d.ts +164 -5
- package/dist/index.js +719 -68
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
// src/locale.ts
|
|
2
|
+
var normalizeLocale = (rawLocale) => {
|
|
3
|
+
if (!rawLocale || typeof rawLocale !== "string") return null;
|
|
4
|
+
const trimmed = rawLocale.trim().replace(/_/gu, "-");
|
|
5
|
+
if (trimmed.length === 0) return null;
|
|
6
|
+
try {
|
|
7
|
+
return Intl.getCanonicalLocales(trimmed)[0] ?? null;
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
function canonicalLocaleOrRaw(rawLocale) {
|
|
13
|
+
return normalizeLocale(rawLocale) ?? rawLocale;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
// src/policy.ts
|
|
2
17
|
function collectRecordKeys(value, path, pathsByLocale) {
|
|
3
|
-
for (const
|
|
18
|
+
for (const rawLocale of Object.keys(value ?? {})) {
|
|
19
|
+
const locale = canonicalLocaleOrRaw(rawLocale);
|
|
4
20
|
const paths = pathsByLocale.get(locale) ?? [];
|
|
5
|
-
paths.push(`${path}.${
|
|
21
|
+
paths.push(`${path}.${rawLocale}`);
|
|
6
22
|
pathsByLocale.set(locale, paths);
|
|
7
23
|
}
|
|
8
24
|
}
|
|
@@ -33,13 +49,15 @@ function collectSchemaLocales(schema) {
|
|
|
33
49
|
});
|
|
34
50
|
const translationLocales = new Set(pathsByLocale.keys());
|
|
35
51
|
const allUniqueLocales = /* @__PURE__ */ new Set([
|
|
36
|
-
...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale],
|
|
37
|
-
...schema.supportedLocales ?? [],
|
|
52
|
+
...schema.defaultLocale === void 0 ? [] : [canonicalLocaleOrRaw(schema.defaultLocale)],
|
|
53
|
+
...(schema.supportedLocales ?? []).map(canonicalLocaleOrRaw),
|
|
38
54
|
...translationLocales
|
|
39
55
|
]);
|
|
56
|
+
const defaultLocale = schema.defaultLocale === void 0 ? void 0 : canonicalLocaleOrRaw(schema.defaultLocale);
|
|
57
|
+
const supportedLocales = (schema.supportedLocales ?? []).map(canonicalLocaleOrRaw);
|
|
40
58
|
return {
|
|
41
|
-
...
|
|
42
|
-
supportedLocales
|
|
59
|
+
...defaultLocale === void 0 ? {} : { defaultLocale },
|
|
60
|
+
supportedLocales,
|
|
43
61
|
translationLocales,
|
|
44
62
|
allUniqueLocales,
|
|
45
63
|
translationLocalePaths: pathsByLocale
|
|
@@ -62,7 +80,12 @@ function displayRuleSourceIds(field) {
|
|
|
62
80
|
}
|
|
63
81
|
function registeredEntries(value, registeredLocales) {
|
|
64
82
|
if (value === void 0) return void 0;
|
|
65
|
-
const entries =
|
|
83
|
+
const entries = [];
|
|
84
|
+
for (const [rawLocale, entry] of Object.entries(value)) {
|
|
85
|
+
const locale = normalizeLocale(rawLocale);
|
|
86
|
+
if (locale === null || !registeredLocales.has(locale)) continue;
|
|
87
|
+
entries.push([locale, entry]);
|
|
88
|
+
}
|
|
66
89
|
return entries.length === 0 ? void 0 : Object.fromEntries(entries);
|
|
67
90
|
}
|
|
68
91
|
function sanitizeNodeLocales(node, registeredLocales) {
|
|
@@ -100,6 +123,16 @@ function sanitizePageLocales(page, registeredLocales) {
|
|
|
100
123
|
const translations = registeredEntries(page.translations, registeredLocales);
|
|
101
124
|
return { ...base, ...translations === void 0 ? {} : { translations } };
|
|
102
125
|
}
|
|
126
|
+
function normalizedLocaleList(locales) {
|
|
127
|
+
return [
|
|
128
|
+
...new Set(
|
|
129
|
+
locales.flatMap((locale) => {
|
|
130
|
+
const normalized = normalizeLocale(locale);
|
|
131
|
+
return normalized === null ? [] : [normalized];
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
];
|
|
135
|
+
}
|
|
103
136
|
function sanitizeFieldConstraints(field, policy) {
|
|
104
137
|
const constraint = policy?.fieldConstraints?.[field.type];
|
|
105
138
|
if (constraint === void 0) return field;
|
|
@@ -214,10 +247,9 @@ function validateSchemaStructure(schema) {
|
|
|
214
247
|
}
|
|
215
248
|
function sanitizeSchema(schema, options = {}) {
|
|
216
249
|
const existingQuestionIds = new Set(schema.fields.map((field) => field.id));
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
]);
|
|
250
|
+
const defaultLocale = schema.defaultLocale === void 0 ? null : normalizeLocale(schema.defaultLocale);
|
|
251
|
+
const supportedLocales = schema.supportedLocales === void 0 ? void 0 : normalizedLocaleList(schema.supportedLocales);
|
|
252
|
+
const registeredLocales = /* @__PURE__ */ new Set([...defaultLocale === null ? [] : [defaultLocale], ...supportedLocales ?? []]);
|
|
221
253
|
const cyclic = cyclicQuestionIds(schema.fields);
|
|
222
254
|
const sanitizedFields = schema.fields.map((sourceField) => {
|
|
223
255
|
const field = sanitizeFieldConstraints(sanitizeFieldLocales(sourceField, registeredLocales), options.policy);
|
|
@@ -235,10 +267,17 @@ function sanitizeSchema(schema, options = {}) {
|
|
|
235
267
|
return sanitized;
|
|
236
268
|
});
|
|
237
269
|
const localizedSchema = sanitizeNodeLocales(schema, registeredLocales);
|
|
238
|
-
const {
|
|
270
|
+
const {
|
|
271
|
+
defaultLocale: _defaultLocale,
|
|
272
|
+
supportedLocales: _supportedLocales,
|
|
273
|
+
translations: _translations,
|
|
274
|
+
...schemaWithoutLocaleContent
|
|
275
|
+
} = localizedSchema;
|
|
239
276
|
const translations = registeredEntries(schema.translations, registeredLocales);
|
|
240
277
|
const base = {
|
|
241
278
|
...schemaWithoutLocaleContent,
|
|
279
|
+
...defaultLocale === null ? {} : { defaultLocale },
|
|
280
|
+
...supportedLocales === void 0 ? {} : { supportedLocales },
|
|
242
281
|
...translations === void 0 ? {} : { translations },
|
|
243
282
|
fields: sanitizedFields
|
|
244
283
|
};
|
|
@@ -291,6 +330,12 @@ function isRecord(value) {
|
|
|
291
330
|
function isNonEmptyString(value) {
|
|
292
331
|
return typeof value === "string" && value.trim().length > 0;
|
|
293
332
|
}
|
|
333
|
+
function localeRecordEntry(record, locale) {
|
|
334
|
+
for (const [candidate, value] of Object.entries(record ?? {})) {
|
|
335
|
+
if (canonicalLocaleOrRaw(candidate) === locale) return value;
|
|
336
|
+
}
|
|
337
|
+
return void 0;
|
|
338
|
+
}
|
|
294
339
|
function issue(issues, path, code, message) {
|
|
295
340
|
issues.push({ path, code, message });
|
|
296
341
|
}
|
|
@@ -653,51 +698,55 @@ function collectSchemaText(schema) {
|
|
|
653
698
|
return entries;
|
|
654
699
|
}
|
|
655
700
|
function addRequiredTranslationIssues(schema, locale, issues) {
|
|
656
|
-
if (!(schema.supportedLocales ?? []).
|
|
701
|
+
if (!(schema.supportedLocales ?? []).some((candidate) => canonicalLocaleOrRaw(candidate) === locale)) {
|
|
657
702
|
issue(issues, "supportedLocales", "required_locale_missing", `Required locale ${locale} is missing.`);
|
|
658
703
|
}
|
|
659
|
-
if (
|
|
704
|
+
if (schema.defaultLocale !== void 0 && canonicalLocaleOrRaw(schema.defaultLocale) === locale) return;
|
|
705
|
+
const formTranslation = localeRecordEntry(schema.translations, locale);
|
|
660
706
|
const required = [
|
|
661
|
-
{ path: `translations.${locale}.title`, value:
|
|
707
|
+
{ path: `translations.${locale}.title`, value: formTranslation?.title }
|
|
662
708
|
];
|
|
663
709
|
if (schema.description !== void 0)
|
|
664
|
-
required.push({ path: `translations.${locale}.description`, value:
|
|
710
|
+
required.push({ path: `translations.${locale}.description`, value: formTranslation?.description });
|
|
665
711
|
if (schema.completionMessage !== void 0) {
|
|
666
712
|
required.push({
|
|
667
713
|
path: `translations.${locale}.completionMessage`,
|
|
668
|
-
value:
|
|
714
|
+
value: formTranslation?.completionMessage
|
|
669
715
|
});
|
|
670
716
|
}
|
|
671
717
|
schema.fields.forEach((field, fieldIndex) => {
|
|
718
|
+
const fieldTranslation = localeRecordEntry(field.translations, locale);
|
|
672
719
|
required.push({
|
|
673
720
|
path: `fields[${fieldIndex}].translations.${locale}.title`,
|
|
674
|
-
value:
|
|
721
|
+
value: fieldTranslation?.title
|
|
675
722
|
});
|
|
676
723
|
if (field.description !== void 0) {
|
|
677
724
|
required.push({
|
|
678
725
|
path: `fields[${fieldIndex}].translations.${locale}.description`,
|
|
679
|
-
value:
|
|
726
|
+
value: fieldTranslation?.description
|
|
680
727
|
});
|
|
681
728
|
}
|
|
682
729
|
if (!("options" in field)) return;
|
|
683
730
|
field.options.forEach((option, optionIndex) => {
|
|
731
|
+
const optionTranslation = localeRecordEntry(option.translations, locale);
|
|
684
732
|
required.push({
|
|
685
733
|
path: `fields[${fieldIndex}].options[${optionIndex}].translations.${locale}`,
|
|
686
|
-
value:
|
|
734
|
+
value: optionTranslation
|
|
687
735
|
});
|
|
688
736
|
});
|
|
689
737
|
});
|
|
690
738
|
schema.pages?.forEach((page, pageIndex) => {
|
|
739
|
+
const pageTranslation = localeRecordEntry(page.translations, locale);
|
|
691
740
|
if (page.title !== void 0) {
|
|
692
741
|
required.push({
|
|
693
742
|
path: `pages[${pageIndex}].translations.${locale}.title`,
|
|
694
|
-
value:
|
|
743
|
+
value: pageTranslation?.title
|
|
695
744
|
});
|
|
696
745
|
}
|
|
697
746
|
if (page.description !== void 0) {
|
|
698
747
|
required.push({
|
|
699
748
|
path: `pages[${pageIndex}].translations.${locale}.description`,
|
|
700
|
-
value:
|
|
749
|
+
value: pageTranslation?.description
|
|
701
750
|
});
|
|
702
751
|
}
|
|
703
752
|
});
|
|
@@ -830,8 +879,8 @@ function validatePolicy(schema, policy, issues) {
|
|
|
830
879
|
}
|
|
831
880
|
const collectedLocales = collectSchemaLocales(schema);
|
|
832
881
|
const registeredLocales = /* @__PURE__ */ new Set([
|
|
833
|
-
...
|
|
834
|
-
...
|
|
882
|
+
...collectedLocales.defaultLocale === void 0 ? [] : [collectedLocales.defaultLocale],
|
|
883
|
+
...collectedLocales.supportedLocales
|
|
835
884
|
]);
|
|
836
885
|
for (const locale of collectedLocales.translationLocales) {
|
|
837
886
|
if (registeredLocales.has(locale)) continue;
|
|
@@ -845,23 +894,27 @@ function validatePolicy(schema, policy, issues) {
|
|
|
845
894
|
}
|
|
846
895
|
}
|
|
847
896
|
if (policy.allowedLocales !== void 0) {
|
|
897
|
+
const allowedLocales = new Set(policy.allowedLocales.map(canonicalLocaleOrRaw));
|
|
848
898
|
const pathsByLocale = /* @__PURE__ */ new Map();
|
|
849
|
-
if (
|
|
899
|
+
if (collectedLocales.defaultLocale !== void 0)
|
|
900
|
+
pathsByLocale.set(collectedLocales.defaultLocale, ["defaultLocale"]);
|
|
850
901
|
schema.supportedLocales?.forEach((locale, index) => {
|
|
851
|
-
|
|
902
|
+
const canonical = canonicalLocaleOrRaw(locale);
|
|
903
|
+
pathsByLocale.set(canonical, [...pathsByLocale.get(canonical) ?? [], `supportedLocales[${index}]`]);
|
|
852
904
|
});
|
|
853
905
|
for (const [locale, paths] of collectedLocales.translationLocalePaths) {
|
|
854
906
|
pathsByLocale.set(locale, [...pathsByLocale.get(locale) ?? [], ...paths]);
|
|
855
907
|
}
|
|
856
908
|
for (const [locale, paths] of pathsByLocale) {
|
|
857
|
-
if (!
|
|
909
|
+
if (!allowedLocales.has(locale)) {
|
|
858
910
|
for (const path of paths) {
|
|
859
911
|
issue(issues, path, "disallowed_locale", `Locale ${locale} is not allowed by the form policy.`);
|
|
860
912
|
}
|
|
861
913
|
}
|
|
862
914
|
}
|
|
863
|
-
for (const
|
|
864
|
-
|
|
915
|
+
for (const rawLocale of policy.requiredLocales ?? []) {
|
|
916
|
+
const locale = canonicalLocaleOrRaw(rawLocale);
|
|
917
|
+
if (!allowedLocales.has(locale)) {
|
|
865
918
|
issue(
|
|
866
919
|
issues,
|
|
867
920
|
"policy.requiredLocales",
|
|
@@ -874,7 +927,8 @@ function validatePolicy(schema, policy, issues) {
|
|
|
874
927
|
if (policy.maxLocales !== void 0 && collectedLocales.allUniqueLocales.size > policy.maxLocales) {
|
|
875
928
|
issue(issues, "supportedLocales", "max_locales_exceeded", `At most ${policy.maxLocales} locales are allowed.`);
|
|
876
929
|
}
|
|
877
|
-
for (const locale of policy.requiredLocales ?? [])
|
|
930
|
+
for (const locale of policy.requiredLocales ?? [])
|
|
931
|
+
addRequiredTranslationIssues(schema, canonicalLocaleOrRaw(locale), issues);
|
|
878
932
|
if (policy.maxSchemaBytes !== void 0) {
|
|
879
933
|
try {
|
|
880
934
|
const byteLength = new TextEncoder().encode(JSON.stringify(schema)).byteLength;
|
|
@@ -909,8 +963,12 @@ function validateFormSchema(input, options = {}) {
|
|
|
909
963
|
);
|
|
910
964
|
}
|
|
911
965
|
}
|
|
912
|
-
if (input.defaultLocale !== void 0
|
|
913
|
-
|
|
966
|
+
if (input.defaultLocale !== void 0) {
|
|
967
|
+
if (!isNonEmptyString(input.defaultLocale)) {
|
|
968
|
+
issue(issues, "defaultLocale", "invalid_locale", "Expected a non-empty default locale.");
|
|
969
|
+
} else if (normalizeLocale(input.defaultLocale) === null) {
|
|
970
|
+
issue(issues, "defaultLocale", "invalid_locale", "Expected a valid BCP 47 locale.");
|
|
971
|
+
}
|
|
914
972
|
}
|
|
915
973
|
if (input.supportedLocales !== void 0) {
|
|
916
974
|
if (!Array.isArray(input.supportedLocales) || input.supportedLocales.length === 0) {
|
|
@@ -920,10 +978,15 @@ function validateFormSchema(input, options = {}) {
|
|
|
920
978
|
input.supportedLocales.forEach((locale, index) => {
|
|
921
979
|
if (!isNonEmptyString(locale)) {
|
|
922
980
|
issue(issues, `supportedLocales[${index}]`, "invalid_locale", "Expected a non-empty locale.");
|
|
923
|
-
} else if (locales.has(locale)) {
|
|
924
|
-
issue(issues, `supportedLocales[${index}]`, "duplicate_locale", "Locales must be unique.");
|
|
925
981
|
} else {
|
|
926
|
-
|
|
982
|
+
const normalized = normalizeLocale(locale);
|
|
983
|
+
if (normalized === null) {
|
|
984
|
+
issue(issues, `supportedLocales[${index}]`, "invalid_locale", "Expected a valid BCP 47 locale.");
|
|
985
|
+
} else if (locales.has(normalized)) {
|
|
986
|
+
issue(issues, `supportedLocales[${index}]`, "duplicate_locale", "Locales must be unique.");
|
|
987
|
+
} else {
|
|
988
|
+
locales.add(normalized);
|
|
989
|
+
}
|
|
927
990
|
}
|
|
928
991
|
});
|
|
929
992
|
}
|
|
@@ -1793,7 +1856,408 @@ var DEFAULT_FIELD_TYPE_DEFINITIONS = [
|
|
|
1793
1856
|
}
|
|
1794
1857
|
];
|
|
1795
1858
|
|
|
1859
|
+
// src/i18n/catalogs/en.ts
|
|
1860
|
+
var EN_MESSAGES = Object.freeze({
|
|
1861
|
+
"builder.formTitle": "Form title",
|
|
1862
|
+
"builder.formDescription": "Form description",
|
|
1863
|
+
"builder.completionMessage": "Completion message",
|
|
1864
|
+
"builder.addQuestion": "Add question",
|
|
1865
|
+
"builder.actions.addField": "Add question",
|
|
1866
|
+
"builder.actions.deleteField": "Delete",
|
|
1867
|
+
"builder.actions.moveUp": "Move up",
|
|
1868
|
+
"builder.actions.moveDown": "Move down",
|
|
1869
|
+
"builder.actions.add": "Add",
|
|
1870
|
+
"builder.actions.delete": "Delete",
|
|
1871
|
+
"builder.actions.edit": "Edit",
|
|
1872
|
+
"builder.actions.settings": "Settings",
|
|
1873
|
+
"builder.actions.translate": "Translate",
|
|
1874
|
+
"builder.actions.close": "Close",
|
|
1875
|
+
"builder.actions.dragHandle": "Reorder",
|
|
1876
|
+
"builder.fields.selectType": "Select field type",
|
|
1877
|
+
"builder.fields.typeText": "Text",
|
|
1878
|
+
"builder.fields.typeTextarea": "Textarea",
|
|
1879
|
+
"builder.fields.typeNumber": "Number",
|
|
1880
|
+
"builder.fields.typeRadio": "Radio",
|
|
1881
|
+
"builder.fields.typeCheckbox": "Checkbox",
|
|
1882
|
+
"builder.fields.typeSelect": "Select",
|
|
1883
|
+
"builder.fields.typeRating": "Rating",
|
|
1884
|
+
"builder.fields.typeMultiSelect": "Multi-select",
|
|
1885
|
+
"builder.fieldType.text": "Text",
|
|
1886
|
+
"builder.fieldType.textarea": "Textarea",
|
|
1887
|
+
"builder.fieldType.number": "Number",
|
|
1888
|
+
"builder.fieldType.radio": "Radio",
|
|
1889
|
+
"builder.fieldType.checkbox": "Checkbox",
|
|
1890
|
+
"builder.fieldType.select": "Select",
|
|
1891
|
+
"builder.fieldType.rating": "Rating",
|
|
1892
|
+
"builder.fieldType.multi-select": "Multi-select",
|
|
1893
|
+
"builder.fieldTypeDescription.text": "A single-line text answer",
|
|
1894
|
+
"builder.fieldTypeDescription.textarea": "A long-form text answer",
|
|
1895
|
+
"builder.fieldTypeDescription.number": "A numeric answer",
|
|
1896
|
+
"builder.fieldTypeDescription.radio": "A single-choice answer",
|
|
1897
|
+
"builder.fieldTypeDescription.checkbox": "A yes/no answer",
|
|
1898
|
+
"builder.fieldTypeDescription.select": "A dropdown choice",
|
|
1899
|
+
"builder.fieldTypeDescription.rating": "A rating scale answer",
|
|
1900
|
+
"builder.fieldTypeDescription.multi-select": "Multiple choices",
|
|
1901
|
+
"builder.fieldCategory.text": "Text",
|
|
1902
|
+
"builder.fieldCategory.choice": "Choice",
|
|
1903
|
+
"builder.fieldCategory.number": "Number",
|
|
1904
|
+
"builder.fieldCategory.advanced": "Advanced",
|
|
1905
|
+
"builder.required": "Required",
|
|
1906
|
+
"builder.options": "Options",
|
|
1907
|
+
"builder.localization.title": "Localization",
|
|
1908
|
+
"builder.localization": "Localization",
|
|
1909
|
+
"builder.localization.addLocale": "Add locale",
|
|
1910
|
+
"builder.localization.selectLocaleToAdd": "Select a locale to add",
|
|
1911
|
+
"builder.localization.defaultLocale": "Default locale",
|
|
1912
|
+
"builder.localization.translateAll": "Translate all text",
|
|
1913
|
+
"builder.localization.noLocalesConfigured": "Translations not configured",
|
|
1914
|
+
"builder.localization.localesConfiguredSummary": "{{count}} locales configured",
|
|
1915
|
+
"builder.localization.allLocalesAdded": "All available locales have been added",
|
|
1916
|
+
"builder.localization.maxLocalesReached": "The maximum number of locales ({{max}}) has been reached",
|
|
1917
|
+
"builder.submissionSettings.title": "Submission settings",
|
|
1918
|
+
"builder.submissionSettings.showConfirmation": "Show confirmation before submit",
|
|
1919
|
+
"builder.submissionSettings.renderMode": "Confirmation display mode",
|
|
1920
|
+
"builder.formBuilder": "Form builder",
|
|
1921
|
+
"builder.basicSettings": "Basic settings",
|
|
1922
|
+
"builder.description": "Description",
|
|
1923
|
+
"builder.moveUp": "Move {{title}} up",
|
|
1924
|
+
"builder.moveDown": "Move {{title}} down",
|
|
1925
|
+
"builder.delete": "Delete {{title}}",
|
|
1926
|
+
"builder.deleteAction": "Delete",
|
|
1927
|
+
"builder.questionTitle": "Question title",
|
|
1928
|
+
"builder.questionTitlePlaceholder": "Example: Tell us what we could improve",
|
|
1929
|
+
"builder.newQuestionTitle": "New question",
|
|
1930
|
+
"builder.type": "Type",
|
|
1931
|
+
"builder.minimum": "Minimum",
|
|
1932
|
+
"builder.maximum": "Maximum",
|
|
1933
|
+
"builder.minimumLength": "Minimum length",
|
|
1934
|
+
"builder.maximumLength": "Maximum length",
|
|
1935
|
+
"builder.pattern": "Pattern",
|
|
1936
|
+
"builder.step": "Step",
|
|
1937
|
+
"builder.optionLabel": "Option label {{index}}",
|
|
1938
|
+
"builder.optionLabelPlaceholder": "Example: Very satisfied",
|
|
1939
|
+
"builder.newOptionLabel": "Option {{index}}",
|
|
1940
|
+
"builder.remove": "Remove",
|
|
1941
|
+
"builder.addOption": "Add option",
|
|
1942
|
+
"builder.displayCondition": "Display condition",
|
|
1943
|
+
"builder.alwaysVisible": "Always visible",
|
|
1944
|
+
"builder.conditionOperator": "Condition operator",
|
|
1945
|
+
"builder.conditionValue": "Condition value",
|
|
1946
|
+
"builder.conditionTrue": "true",
|
|
1947
|
+
"builder.conditionFalse": "false",
|
|
1948
|
+
"builder.pages": "Page manager",
|
|
1949
|
+
"builder.enablePages": "Enable multi-step pages",
|
|
1950
|
+
"builder.addPage": "Add page",
|
|
1951
|
+
"builder.newPage": "New page",
|
|
1952
|
+
"builder.pageTitle": "Page title",
|
|
1953
|
+
"builder.pageDescription": "Page description",
|
|
1954
|
+
"builder.pageQuestion": "Question to move to the new page",
|
|
1955
|
+
"builder.questionPage": "Page",
|
|
1956
|
+
"builder.pageCondition": "Page display condition",
|
|
1957
|
+
"builder.unassigned": "Unassigned",
|
|
1958
|
+
"builder.defaultLocale": "Default locale",
|
|
1959
|
+
"builder.supportedLocales": "Supported locales",
|
|
1960
|
+
"builder.addLocale": "Add locale",
|
|
1961
|
+
"builder.editLocale": "Edit locale",
|
|
1962
|
+
"builder.autoTranslate": "Translate all text",
|
|
1963
|
+
"builder.translating": "Translating\u2026",
|
|
1964
|
+
"builder.translationLocale": "Translation locale",
|
|
1965
|
+
"builder.selectLocale": "Select a locale to edit translations.",
|
|
1966
|
+
"builder.selectLocaleToAdd": "Select a locale to add",
|
|
1967
|
+
"builder.translation": "{{locale}} translation",
|
|
1968
|
+
"builder.translatedFormTitle": "Translated form title",
|
|
1969
|
+
"builder.translatedFormDescription": "Translated form description",
|
|
1970
|
+
"builder.translatedCompletionMessage": "Translated completion message",
|
|
1971
|
+
"builder.translatedQuestionTitle": "Translated question title",
|
|
1972
|
+
"builder.translatedDescription": "Translated description",
|
|
1973
|
+
"builder.translationUnavailable": "Provide an async translation adapter to enable automatic translation.",
|
|
1974
|
+
"builder.operator.equals": "equals",
|
|
1975
|
+
"builder.operator.not_equals": "does not equal",
|
|
1976
|
+
"builder.operator.contains": "contains",
|
|
1977
|
+
"builder.operator.not_empty": "is not empty",
|
|
1978
|
+
"builder.showConfirmationBeforeSubmit": "Show confirmation before submit",
|
|
1979
|
+
"builder.confirmationRenderMode": "Confirmation display mode",
|
|
1980
|
+
"renderer.submitButton": "Submit",
|
|
1981
|
+
"renderer.submittingButton": "Submitting...",
|
|
1982
|
+
"renderer.retryButton": "Retry",
|
|
1983
|
+
"renderer.requiredField": "This field is required.",
|
|
1984
|
+
"renderer.alreadySubmittedTitle": "Already Submitted",
|
|
1985
|
+
"renderer.alreadySubmittedMessage": "Already submitted.",
|
|
1986
|
+
"renderer.serverErrorSummary": "Submission failed. Please check your answers and try again.",
|
|
1987
|
+
"renderer.confirmSensitiveDataTitle": "Sensitive data may be included",
|
|
1988
|
+
"renderer.confirmSensitiveDataMessage": "The following answers may contain personal information. Continue submitting?",
|
|
1989
|
+
"renderer.confirmButton": "Proceed",
|
|
1990
|
+
"renderer.cancelButton": "Cancel",
|
|
1991
|
+
"form.submit": "Submit",
|
|
1992
|
+
"form.submitting": "Submitting...",
|
|
1993
|
+
"form.back": "Back",
|
|
1994
|
+
"form.next": "Next",
|
|
1995
|
+
"form.step": "{{current}} / {{total}}",
|
|
1996
|
+
"form.draftRestored": "Draft restored",
|
|
1997
|
+
"form.submissionBlocked": "Submission blocked because personal information was detected.",
|
|
1998
|
+
"form.confirmSensitiveData": "Sensitive data may be included. Please review before submitting.",
|
|
1999
|
+
"form.confirmSubmission": "Proceed",
|
|
2000
|
+
"form.cancelSubmission": "Cancel",
|
|
2001
|
+
"form.yes": "Yes",
|
|
2002
|
+
"form.no": "No",
|
|
2003
|
+
"form.alreadySubmitted": "Already submitted.",
|
|
2004
|
+
"form.submitAnother": "Submit another response",
|
|
2005
|
+
"validation.required": "This field is required.",
|
|
2006
|
+
"validation.invalidOption": "Select a valid option.",
|
|
2007
|
+
"validation.invalidType": "Enter a valid value.",
|
|
2008
|
+
"validation.max": "Value is too large.",
|
|
2009
|
+
"validation.maxLength": "Value is too long.",
|
|
2010
|
+
"validation.maxSelections": "Select fewer options.",
|
|
2011
|
+
"validation.min": "Value is too small.",
|
|
2012
|
+
"validation.minLength": "Value is too short.",
|
|
2013
|
+
"validation.minSelections": "Select more options.",
|
|
2014
|
+
"validation.pattern": "Value has an invalid format.",
|
|
2015
|
+
"validation.sensitiveData": "Sensitive data may be included.",
|
|
2016
|
+
"validation.step": "Enter a value with the correct step.",
|
|
2017
|
+
"validation.unknownField": "This field is not recognized.",
|
|
2018
|
+
"workspace.title": "Translation workspace",
|
|
2019
|
+
"workspace.status.missing": "Missing",
|
|
2020
|
+
"workspace.status.translated": "Translated",
|
|
2021
|
+
"workspace.status.stale": "Source changed",
|
|
2022
|
+
"workspace.status.manual": "Manual",
|
|
2023
|
+
"workspace.status.manualStale": "Manual / source changed",
|
|
2024
|
+
"workspace.errors.localeNotAllowed": "Locale {{locale}} is not allowed.",
|
|
2025
|
+
"workspace.errors.maxLocalesExceeded": "The maximum number of locales ({{max}}) has been reached.",
|
|
2026
|
+
"workspace.errors.readOnly": "This workspace is read-only.",
|
|
2027
|
+
"workspace.errors.adapterNotConfigured": "A translation adapter is not configured.",
|
|
2028
|
+
"workspace.errors.translationFailed": "Translation failed."
|
|
2029
|
+
});
|
|
2030
|
+
|
|
2031
|
+
// src/i18n/catalogs/ja.ts
|
|
2032
|
+
var JA_MESSAGES = Object.freeze({
|
|
2033
|
+
"builder.formTitle": "\u30D5\u30A9\u30FC\u30E0\u306E\u30BF\u30A4\u30C8\u30EB",
|
|
2034
|
+
"builder.formDescription": "\u30D5\u30A9\u30FC\u30E0\u306E\u8AAC\u660E",
|
|
2035
|
+
"builder.completionMessage": "\u9001\u4FE1\u5B8C\u4E86\u30E1\u30C3\u30BB\u30FC\u30B8",
|
|
2036
|
+
"builder.addQuestion": "\u8CEA\u554F\u3092\u8FFD\u52A0",
|
|
2037
|
+
"builder.actions.addField": "\u8CEA\u554F\u3092\u8FFD\u52A0",
|
|
2038
|
+
"builder.actions.deleteField": "\u524A\u9664",
|
|
2039
|
+
"builder.actions.moveUp": "\u4E0A\u3078\u79FB\u52D5",
|
|
2040
|
+
"builder.actions.moveDown": "\u4E0B\u3078\u79FB\u52D5",
|
|
2041
|
+
"builder.actions.add": "\u8FFD\u52A0",
|
|
2042
|
+
"builder.actions.delete": "\u524A\u9664",
|
|
2043
|
+
"builder.actions.edit": "\u7DE8\u96C6",
|
|
2044
|
+
"builder.actions.settings": "\u8A2D\u5B9A",
|
|
2045
|
+
"builder.actions.translate": "\u7FFB\u8A33",
|
|
2046
|
+
"builder.actions.close": "\u9589\u3058\u308B",
|
|
2047
|
+
"builder.actions.dragHandle": "\u4E26\u3079\u66FF\u3048",
|
|
2048
|
+
"builder.fields.selectType": "\u8CEA\u554F\u5F62\u5F0F\u3092\u9078\u629E",
|
|
2049
|
+
"builder.fields.typeText": "\u4E00\u884C\u30C6\u30AD\u30B9\u30C8",
|
|
2050
|
+
"builder.fields.typeTextarea": "\u9577\u6587\u30C6\u30AD\u30B9\u30C8",
|
|
2051
|
+
"builder.fields.typeNumber": "\u6570\u5024",
|
|
2052
|
+
"builder.fields.typeRadio": "\u5358\u4E00\u9078\u629E (\u30E9\u30B8\u30AA\u30DC\u30BF\u30F3)",
|
|
2053
|
+
"builder.fields.typeCheckbox": "\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9",
|
|
2054
|
+
"builder.fields.typeSelect": "\u30C9\u30ED\u30C3\u30D7\u30C0\u30A6\u30F3",
|
|
2055
|
+
"builder.fields.typeRating": "\u8A55\u4FA1\u30B9\u30B1\u30FC\u30EB",
|
|
2056
|
+
"builder.fields.typeMultiSelect": "\u8907\u6570\u9078\u629E",
|
|
2057
|
+
"builder.fieldType.text": "\u4E00\u884C\u30C6\u30AD\u30B9\u30C8",
|
|
2058
|
+
"builder.fieldType.textarea": "\u9577\u6587\u30C6\u30AD\u30B9\u30C8",
|
|
2059
|
+
"builder.fieldType.number": "\u6570\u5024",
|
|
2060
|
+
"builder.fieldType.radio": "\u5358\u4E00\u9078\u629E",
|
|
2061
|
+
"builder.fieldType.checkbox": "\u30C1\u30A7\u30C3\u30AF\u30DC\u30C3\u30AF\u30B9",
|
|
2062
|
+
"builder.fieldType.select": "\u30C9\u30ED\u30C3\u30D7\u30C0\u30A6\u30F3",
|
|
2063
|
+
"builder.fieldType.rating": "\u8A55\u4FA1\u30B9\u30B1\u30FC\u30EB",
|
|
2064
|
+
"builder.fieldType.multi-select": "\u8907\u6570\u9078\u629E",
|
|
2065
|
+
"builder.fieldTypeDescription.text": "\u4E00\u884C\u306E\u56DE\u7B54",
|
|
2066
|
+
"builder.fieldTypeDescription.textarea": "\u9577\u6587\u306E\u56DE\u7B54",
|
|
2067
|
+
"builder.fieldTypeDescription.number": "\u6570\u5024\u306E\u56DE\u7B54",
|
|
2068
|
+
"builder.fieldTypeDescription.radio": "\u5358\u4E00\u9078\u629E\u306E\u56DE\u7B54",
|
|
2069
|
+
"builder.fieldTypeDescription.checkbox": "\u306F\u3044 / \u3044\u3044\u3048\u306E\u56DE\u7B54",
|
|
2070
|
+
"builder.fieldTypeDescription.select": "\u30C9\u30ED\u30C3\u30D7\u30C0\u30A6\u30F3\u5F62\u5F0F\u306E\u56DE\u7B54",
|
|
2071
|
+
"builder.fieldTypeDescription.rating": "\u8A55\u4FA1\u30B9\u30B1\u30FC\u30EB\u306E\u56DE\u7B54",
|
|
2072
|
+
"builder.fieldTypeDescription.multi-select": "\u8907\u6570\u9078\u629E\u306E\u56DE\u7B54",
|
|
2073
|
+
"builder.fieldCategory.text": "\u30C6\u30AD\u30B9\u30C8",
|
|
2074
|
+
"builder.fieldCategory.choice": "\u9078\u629E\u5F0F",
|
|
2075
|
+
"builder.fieldCategory.number": "\u6570\u5024",
|
|
2076
|
+
"builder.fieldCategory.advanced": "\u8A73\u7D30\u8A2D\u5B9A",
|
|
2077
|
+
"builder.required": "\u5FC5\u9808\u9805\u76EE\u306B\u3059\u308B",
|
|
2078
|
+
"builder.options": "\u9078\u629E\u80A2\u4E00\u89A7",
|
|
2079
|
+
"builder.localization.title": "\u591A\u8A00\u8A9E\u8A2D\u5B9A",
|
|
2080
|
+
"builder.localization": "\u591A\u8A00\u8A9E\u8A2D\u5B9A",
|
|
2081
|
+
"builder.localization.addLocale": "\u8A00\u8A9E\u3092\u8FFD\u52A0",
|
|
2082
|
+
"builder.localization.selectLocaleToAdd": "\u8FFD\u52A0\u3059\u308B\u8A00\u8A9E\u3092\u9078\u629E",
|
|
2083
|
+
"builder.localization.defaultLocale": "\u30C7\u30D5\u30A9\u30EB\u30C8\u8A00\u8A9E (\u5143\u8A00\u8A9E)",
|
|
2084
|
+
"builder.localization.translateAll": "\u4E00\u62EC\u81EA\u52D5\u7FFB\u8A33",
|
|
2085
|
+
"builder.localization.noLocalesConfigured": "\u7FFB\u8A33\u8A00\u8A9E\u306F\u307E\u3060\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
|
|
2086
|
+
"builder.localization.localesConfiguredSummary": "{{count}}\u8A00\u8A9E\u306E\u7FFB\u8A33\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002",
|
|
2087
|
+
"builder.localization.allLocalesAdded": "\u3059\u3079\u3066\u306E\u5019\u88DC\u8A00\u8A9E\u304C\u8FFD\u52A0\u6E08\u307F\u3067\u3059",
|
|
2088
|
+
"builder.localization.maxLocalesReached": "\u767B\u9332\u53EF\u80FD\u306A\u6700\u5927\u8A00\u8A9E\u6570 ({{max}}) \u306B\u9054\u3057\u307E\u3057\u305F",
|
|
2089
|
+
"builder.submissionSettings.title": "\u9001\u4FE1\u8A2D\u5B9A",
|
|
2090
|
+
"builder.submissionSettings.showConfirmation": "\u9001\u4FE1\u524D\u306B\u56DE\u7B54\u78BA\u8A8D\u753B\u9762\u3092\u8868\u793A\u3059\u308B",
|
|
2091
|
+
"builder.submissionSettings.renderMode": "\u78BA\u8A8D\u753B\u9762\u306E\u8868\u793A\u5F62\u5F0F",
|
|
2092
|
+
"builder.formBuilder": "\u30D5\u30A9\u30FC\u30E0\u30D3\u30EB\u30C0\u30FC",
|
|
2093
|
+
"builder.basicSettings": "\u57FA\u672C\u8A2D\u5B9A",
|
|
2094
|
+
"builder.description": "\u8AAC\u660E",
|
|
2095
|
+
"builder.moveUp": "{{title}}\u3092\u4E0A\u3078\u79FB\u52D5",
|
|
2096
|
+
"builder.moveDown": "{{title}}\u3092\u4E0B\u3078\u79FB\u52D5",
|
|
2097
|
+
"builder.delete": "{{title}}\u3092\u524A\u9664",
|
|
2098
|
+
"builder.deleteAction": "\u524A\u9664",
|
|
2099
|
+
"builder.questionTitle": "\u8CEA\u554F\u6587",
|
|
2100
|
+
"builder.questionTitlePlaceholder": "\u4F8B: \u6539\u5584\u3067\u304D\u308B\u70B9\u3092\u6559\u3048\u3066\u304F\u3060\u3055\u3044",
|
|
2101
|
+
"builder.newQuestionTitle": "\u65B0\u3057\u3044\u8CEA\u554F",
|
|
2102
|
+
"builder.type": "\u5F62\u5F0F",
|
|
2103
|
+
"builder.minimum": "\u6700\u5C0F\u5024",
|
|
2104
|
+
"builder.maximum": "\u6700\u5927\u5024",
|
|
2105
|
+
"builder.minimumLength": "\u6700\u5C0F\u6587\u5B57\u6570",
|
|
2106
|
+
"builder.maximumLength": "\u6700\u5927\u6587\u5B57\u6570",
|
|
2107
|
+
"builder.pattern": "\u5F62\u5F0F\u30D1\u30BF\u30FC\u30F3",
|
|
2108
|
+
"builder.step": "\u523B\u307F\u5E45",
|
|
2109
|
+
"builder.optionLabel": "\u9078\u629E\u80A2 {{index}}",
|
|
2110
|
+
"builder.optionLabelPlaceholder": "\u4F8B: \u3068\u3066\u3082\u6E80\u8DB3",
|
|
2111
|
+
"builder.newOptionLabel": "\u9078\u629E\u80A2 {{index}}",
|
|
2112
|
+
"builder.remove": "\u524A\u9664",
|
|
2113
|
+
"builder.addOption": "\u9078\u629E\u80A2\u3092\u8FFD\u52A0",
|
|
2114
|
+
"builder.displayCondition": "\u8868\u793A\u6761\u4EF6",
|
|
2115
|
+
"builder.alwaysVisible": "\u5E38\u306B\u8868\u793A",
|
|
2116
|
+
"builder.conditionOperator": "\u6761\u4EF6\u6F14\u7B97\u5B50",
|
|
2117
|
+
"builder.conditionValue": "\u6761\u4EF6\u5024",
|
|
2118
|
+
"builder.conditionTrue": "\u306F\u3044",
|
|
2119
|
+
"builder.conditionFalse": "\u3044\u3044\u3048",
|
|
2120
|
+
"builder.pages": "\u30DA\u30FC\u30B8\u7BA1\u7406",
|
|
2121
|
+
"builder.enablePages": "\u8907\u6570\u30DA\u30FC\u30B8\u3092\u6709\u52B9\u306B\u3059\u308B",
|
|
2122
|
+
"builder.addPage": "\u30DA\u30FC\u30B8\u3092\u8FFD\u52A0",
|
|
2123
|
+
"builder.newPage": "\u65B0\u3057\u3044\u30DA\u30FC\u30B8",
|
|
2124
|
+
"builder.pageTitle": "\u30DA\u30FC\u30B8\u30BF\u30A4\u30C8\u30EB",
|
|
2125
|
+
"builder.pageDescription": "\u30DA\u30FC\u30B8\u306E\u8AAC\u660E",
|
|
2126
|
+
"builder.pageQuestion": "\u65B0\u3057\u3044\u30DA\u30FC\u30B8\u3078\u79FB\u52D5\u3059\u308B\u8CEA\u554F",
|
|
2127
|
+
"builder.questionPage": "\u30DA\u30FC\u30B8",
|
|
2128
|
+
"builder.pageCondition": "\u30DA\u30FC\u30B8\u306E\u8868\u793A\u6761\u4EF6",
|
|
2129
|
+
"builder.unassigned": "\u672A\u5272\u308A\u5F53\u3066",
|
|
2130
|
+
"builder.defaultLocale": "\u30C7\u30D5\u30A9\u30EB\u30C8\u8A00\u8A9E",
|
|
2131
|
+
"builder.supportedLocales": "\u5BFE\u5FDC\u8A00\u8A9E",
|
|
2132
|
+
"builder.addLocale": "\u8A00\u8A9E\u3092\u8FFD\u52A0",
|
|
2133
|
+
"builder.editLocale": "\u8A00\u8A9E\u3092\u7DE8\u96C6",
|
|
2134
|
+
"builder.autoTranslate": "\u3059\u3079\u3066\u7FFB\u8A33",
|
|
2135
|
+
"builder.translating": "\u7FFB\u8A33\u4E2D\u2026",
|
|
2136
|
+
"builder.translationLocale": "\u7FFB\u8A33\u8A00\u8A9E",
|
|
2137
|
+
"builder.selectLocale": "\u7FFB\u8A33\u3092\u7DE8\u96C6\u3059\u308B\u8A00\u8A9E\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2138
|
+
"builder.selectLocaleToAdd": "\u8FFD\u52A0\u3059\u308B\u8A00\u8A9E\u3092\u9078\u629E",
|
|
2139
|
+
"builder.translation": "{{locale}}\u7FFB\u8A33",
|
|
2140
|
+
"builder.translatedFormTitle": "\u7FFB\u8A33\u5F8C\u306E\u30D5\u30A9\u30FC\u30E0\u30BF\u30A4\u30C8\u30EB",
|
|
2141
|
+
"builder.translatedFormDescription": "\u7FFB\u8A33\u5F8C\u306E\u30D5\u30A9\u30FC\u30E0\u8AAC\u660E",
|
|
2142
|
+
"builder.translatedCompletionMessage": "\u7FFB\u8A33\u5F8C\u306E\u9001\u4FE1\u5B8C\u4E86\u30E1\u30C3\u30BB\u30FC\u30B8",
|
|
2143
|
+
"builder.translatedQuestionTitle": "\u7FFB\u8A33\u5F8C\u306E\u8CEA\u554F\u6587",
|
|
2144
|
+
"builder.translatedDescription": "\u7FFB\u8A33\u5F8C\u306E\u8AAC\u660E",
|
|
2145
|
+
"builder.translationUnavailable": "\u81EA\u52D5\u7FFB\u8A33\u306B\u306F\u975E\u540C\u671F\u7FFB\u8A33\u30A2\u30C0\u30D7\u30BF\u30FC\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2146
|
+
"builder.operator.equals": "\u7B49\u3057\u3044",
|
|
2147
|
+
"builder.operator.not_equals": "\u7B49\u3057\u304F\u306A\u3044",
|
|
2148
|
+
"builder.operator.contains": "\u542B\u3080",
|
|
2149
|
+
"builder.operator.not_empty": "\u7A7A\u3067\u306F\u306A\u3044",
|
|
2150
|
+
"builder.showConfirmationBeforeSubmit": "\u9001\u4FE1\u524D\u306B\u78BA\u8A8D\u753B\u9762\u3092\u8868\u793A\u3059\u308B",
|
|
2151
|
+
"builder.confirmationRenderMode": "\u78BA\u8A8D\u753B\u9762\u306E\u8868\u793A\u5F62\u5F0F",
|
|
2152
|
+
"renderer.submitButton": "\u9001\u4FE1\u3059\u308B",
|
|
2153
|
+
"renderer.submittingButton": "\u9001\u4FE1\u4E2D...",
|
|
2154
|
+
"renderer.retryButton": "\u518D\u9001\u4FE1\u3059\u308B",
|
|
2155
|
+
"renderer.requiredField": "\u3053\u306E\u9805\u76EE\u306F\u5FC5\u9808\u3067\u3059\u3002",
|
|
2156
|
+
"renderer.alreadySubmittedTitle": "\u56DE\u7B54\u6E08\u307F\u3067\u3059",
|
|
2157
|
+
"renderer.alreadySubmittedMessage": "\u3053\u306E\u30A2\u30F3\u30B1\u30FC\u30C8\u306B\u306F\u3059\u3067\u306B\u56DE\u7B54\u3057\u3066\u3044\u307E\u3059\u3002",
|
|
2158
|
+
"renderer.serverErrorSummary": "\u9001\u4FE1\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u306E\u4E0A\u3001\u518D\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002",
|
|
2159
|
+
"renderer.confirmSensitiveDataTitle": "\u500B\u4EBA\u60C5\u5831\u304C\u542B\u307E\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059",
|
|
2160
|
+
"renderer.confirmSensitiveDataMessage": "\u4EE5\u4E0B\u306E\u9805\u76EE\u306B\u500B\u4EBA\u60C5\u5831\u3068\u307F\u3089\u308C\u308B\u8A18\u8FF0\u304C\u3042\u308A\u307E\u3059\u3002\u3053\u306E\u307E\u307E\u9001\u4FE1\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B\uFF1F",
|
|
2161
|
+
"renderer.confirmButton": "\u3053\u306E\u307E\u307E\u9001\u4FE1",
|
|
2162
|
+
"renderer.cancelButton": "\u4FEE\u6B63\u3059\u308B",
|
|
2163
|
+
"form.submit": "\u9001\u4FE1\u3059\u308B",
|
|
2164
|
+
"form.submitting": "\u9001\u4FE1\u4E2D...",
|
|
2165
|
+
"form.back": "\u623B\u308B",
|
|
2166
|
+
"form.next": "\u6B21\u3078",
|
|
2167
|
+
"form.step": "{{current}} / {{total}}",
|
|
2168
|
+
"form.draftRestored": "\u4E0B\u66F8\u304D\u3092\u5FA9\u5143\u3057\u307E\u3057\u305F",
|
|
2169
|
+
"form.submissionBlocked": "\u500B\u4EBA\u60C5\u5831\u304C\u691C\u51FA\u3055\u308C\u305F\u305F\u3081\u9001\u4FE1\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
2170
|
+
"form.confirmSensitiveData": "\u500B\u4EBA\u60C5\u5831\u304C\u542B\u307E\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u9001\u4FE1\u524D\u306B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2171
|
+
"form.confirmSubmission": "\u3053\u306E\u307E\u307E\u9001\u4FE1",
|
|
2172
|
+
"form.cancelSubmission": "\u4FEE\u6B63\u3059\u308B",
|
|
2173
|
+
"form.yes": "\u306F\u3044",
|
|
2174
|
+
"form.no": "\u3044\u3044\u3048",
|
|
2175
|
+
"form.alreadySubmitted": "\u56DE\u7B54\u6E08\u307F\u3067\u3059",
|
|
2176
|
+
"form.submitAnother": "\u5225\u306E\u56DE\u7B54\u3092\u9001\u4FE1",
|
|
2177
|
+
"validation.required": "\u3053\u306E\u9805\u76EE\u306F\u5FC5\u9808\u3067\u3059\u3002",
|
|
2178
|
+
"validation.invalidOption": "\u6709\u52B9\u306A\u9078\u629E\u80A2\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2179
|
+
"validation.invalidType": "\u6709\u52B9\u306A\u5024\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2180
|
+
"validation.max": "\u5024\u304C\u5927\u304D\u3059\u304E\u307E\u3059\u3002",
|
|
2181
|
+
"validation.maxLength": "\u5165\u529B\u304C\u9577\u3059\u304E\u307E\u3059\u3002",
|
|
2182
|
+
"validation.maxSelections": "\u9078\u629E\u6570\u3092\u6E1B\u3089\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2183
|
+
"validation.min": "\u5024\u304C\u5C0F\u3055\u3059\u304E\u307E\u3059\u3002",
|
|
2184
|
+
"validation.minLength": "\u5165\u529B\u304C\u77ED\u3059\u304E\u307E\u3059\u3002",
|
|
2185
|
+
"validation.minSelections": "\u3055\u3089\u306B\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2186
|
+
"validation.pattern": "\u5165\u529B\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
2187
|
+
"validation.sensitiveData": "\u500B\u4EBA\u60C5\u5831\u304C\u542B\u307E\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
2188
|
+
"validation.step": "\u6B63\u3057\u3044\u523B\u307F\u5E45\u306E\u5024\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
2189
|
+
"validation.unknownField": "\u3053\u306E\u9805\u76EE\u306F\u8A8D\u8B58\u3055\u308C\u307E\u305B\u3093\u3002",
|
|
2190
|
+
"workspace.title": "\u591A\u8A00\u8A9E\u7FFB\u8A33\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9",
|
|
2191
|
+
"workspace.status.missing": "\u672A\u7FFB\u8A33",
|
|
2192
|
+
"workspace.status.translated": "\u7FFB\u8A33\u6E08\u307F",
|
|
2193
|
+
"workspace.status.stale": "\u539F\u6587\u66F4\u65B0\u3042\u308A",
|
|
2194
|
+
"workspace.status.manual": "\u624B\u52D5\u7DE8\u96C6\u6E08\u307F",
|
|
2195
|
+
"workspace.status.manualStale": "\u624B\u52D5\u7DE8\u96C6\u6E08\u307F (\u539F\u6587\u66F4\u65B0\u3042\u308A)",
|
|
2196
|
+
"workspace.errors.localeNotAllowed": "\u6307\u5B9A\u3055\u308C\u305F\u8A00\u8A9E\u300C{{locale}}\u300D\u306F\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
2197
|
+
"workspace.errors.maxLocalesExceeded": "\u767B\u9332\u53EF\u80FD\u306A\u6700\u5927\u8A00\u8A9E\u6570 ({{max}}) \u306B\u9054\u3057\u307E\u3057\u305F\u3002",
|
|
2198
|
+
"workspace.errors.readOnly": "\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u30E2\u30FC\u30C9\u306E\u305F\u3081\u5909\u66F4\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
2199
|
+
"workspace.errors.adapterNotConfigured": "\u7FFB\u8A33\u30A2\u30C0\u30D7\u30BF\u30FC\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
|
|
2200
|
+
"workspace.errors.translationFailed": "\u7FFB\u8A33\u51E6\u7406\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002"
|
|
2201
|
+
});
|
|
2202
|
+
|
|
2203
|
+
// src/i18n/translator.ts
|
|
2204
|
+
function formatTemplate(template, params = {}) {
|
|
2205
|
+
return template.replace(
|
|
2206
|
+
/\{\{?(\w+)\}\}?/gu,
|
|
2207
|
+
(token, name) => Object.hasOwn(params, name) ? String(params[name]) : token
|
|
2208
|
+
);
|
|
2209
|
+
}
|
|
2210
|
+
function defaultCatalog(locale) {
|
|
2211
|
+
return locale.toLowerCase().startsWith("ja") ? JA_MESSAGES : EN_MESSAGES;
|
|
2212
|
+
}
|
|
2213
|
+
var createFormEngineTranslator = (options = {}) => {
|
|
2214
|
+
const { locale = "ja", fallbackLocale = "en", messages = {}, customCatalogs = {}, fallbackTextResolver } = options;
|
|
2215
|
+
const currentCatalog = { ...defaultCatalog(locale), ...customCatalogs[locale], ...messages };
|
|
2216
|
+
const fallbackCatalog = { ...defaultCatalog(fallbackLocale), ...customCatalogs[fallbackLocale] };
|
|
2217
|
+
return (rawKey, params = {}) => {
|
|
2218
|
+
const key = rawKey;
|
|
2219
|
+
const template = currentCatalog[key] ?? fallbackCatalog[key];
|
|
2220
|
+
if (template !== void 0 && template !== "") return formatTemplate(template, params);
|
|
2221
|
+
if (fallbackTextResolver !== void 0) return fallbackTextResolver(key, locale);
|
|
2222
|
+
return "";
|
|
2223
|
+
};
|
|
2224
|
+
};
|
|
2225
|
+
|
|
1796
2226
|
// src/pagination.ts
|
|
2227
|
+
async function paginateWithFilter(params) {
|
|
2228
|
+
const { pageSize, cursor, maxScanPages = 5, fetchPage, filterPredicate, encodeCursor } = params;
|
|
2229
|
+
normalizeSubmissionPageSize(pageSize);
|
|
2230
|
+
if (!Number.isSafeInteger(maxScanPages) || maxScanPages < 1) {
|
|
2231
|
+
throw new TypeError("maxScanPages must be a positive safe integer.");
|
|
2232
|
+
}
|
|
2233
|
+
const collected = [];
|
|
2234
|
+
let currentRawCursor = cursor;
|
|
2235
|
+
let totalScannedCount = 0;
|
|
2236
|
+
let scanCount = 0;
|
|
2237
|
+
while (collected.length < pageSize && scanCount < maxScanPages) {
|
|
2238
|
+
scanCount += 1;
|
|
2239
|
+
const fetchLimit = pageSize - collected.length + 1;
|
|
2240
|
+
const { rawItems, rawNextCursor } = await fetchPage(currentRawCursor, fetchLimit);
|
|
2241
|
+
totalScannedCount += rawItems.length;
|
|
2242
|
+
for (const item of rawItems) {
|
|
2243
|
+
if (!filterPredicate(item)) continue;
|
|
2244
|
+
collected.push(item);
|
|
2245
|
+
if (collected.length === pageSize) {
|
|
2246
|
+
const lastItem = collected.at(-1);
|
|
2247
|
+
if (lastItem === void 0) break;
|
|
2248
|
+
return {
|
|
2249
|
+
items: collected,
|
|
2250
|
+
hasMore: rawNextCursor !== void 0,
|
|
2251
|
+
...rawNextCursor === void 0 ? {} : { nextCursor: encodeCursor(lastItem) },
|
|
2252
|
+
totalScannedCount
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
if (rawItems.length === 0 || rawNextCursor === void 0) break;
|
|
2257
|
+
currentRawCursor = rawNextCursor;
|
|
2258
|
+
}
|
|
2259
|
+
return { items: collected, hasMore: false, totalScannedCount };
|
|
2260
|
+
}
|
|
1797
2261
|
function asFormResponse2(submission) {
|
|
1798
2262
|
return {
|
|
1799
2263
|
responseId: submission.id,
|
|
@@ -1842,6 +2306,43 @@ async function* iterateSubmissionPages(adapter, formId, queryOptions = {}, optio
|
|
|
1842
2306
|
cursor = nextCursor;
|
|
1843
2307
|
}
|
|
1844
2308
|
}
|
|
2309
|
+
function encodeStorageSubmissionCursor(value) {
|
|
2310
|
+
if (value.kind !== "submission" || value.formId.length === 0 || value.submittedAt.length === 0 || value.id.length === 0) {
|
|
2311
|
+
throw new TypeError("Submission cursor values are invalid.");
|
|
2312
|
+
}
|
|
2313
|
+
return encodeBase64Url(new TextEncoder().encode(JSON.stringify(value)));
|
|
2314
|
+
}
|
|
2315
|
+
function decodeStorageSubmissionCursor(cursor) {
|
|
2316
|
+
const parsed = decodeCursorPayload(cursor, "submission cursor payload is invalid.");
|
|
2317
|
+
if (parsed.kind !== "submission" || typeof parsed.formId !== "string" || parsed.formId.length === 0 || typeof parsed.submittedAt !== "string" || parsed.submittedAt.length === 0 || typeof parsed.id !== "string" || parsed.id.length === 0) {
|
|
2318
|
+
throw new TypeError("submission cursor payload is invalid.");
|
|
2319
|
+
}
|
|
2320
|
+
return {
|
|
2321
|
+
kind: "submission",
|
|
2322
|
+
formId: parsed.formId,
|
|
2323
|
+
submittedAt: parsed.submittedAt,
|
|
2324
|
+
id: parsed.id
|
|
2325
|
+
};
|
|
2326
|
+
}
|
|
2327
|
+
function encodeStorageTextAnswerCursor(value) {
|
|
2328
|
+
if (value.kind !== "text_answer" || value.formId.length === 0 || value.fieldId.length === 0 || value.submittedAt.length === 0 || value.submissionId.length === 0) {
|
|
2329
|
+
throw new TypeError("Text answer cursor values are invalid.");
|
|
2330
|
+
}
|
|
2331
|
+
return encodeBase64Url(new TextEncoder().encode(JSON.stringify(value)));
|
|
2332
|
+
}
|
|
2333
|
+
function decodeStorageTextAnswerCursor(cursor) {
|
|
2334
|
+
const parsed = decodeCursorPayload(cursor, "text answer cursor payload is invalid.");
|
|
2335
|
+
if (parsed.kind !== "text_answer" || typeof parsed.formId !== "string" || parsed.formId.length === 0 || typeof parsed.fieldId !== "string" || parsed.fieldId.length === 0 || typeof parsed.submittedAt !== "string" || parsed.submittedAt.length === 0 || typeof parsed.submissionId !== "string" || parsed.submissionId.length === 0) {
|
|
2336
|
+
throw new TypeError("text answer cursor payload is invalid.");
|
|
2337
|
+
}
|
|
2338
|
+
return {
|
|
2339
|
+
kind: "text_answer",
|
|
2340
|
+
formId: parsed.formId,
|
|
2341
|
+
fieldId: parsed.fieldId,
|
|
2342
|
+
submittedAt: parsed.submittedAt,
|
|
2343
|
+
submissionId: parsed.submissionId
|
|
2344
|
+
};
|
|
2345
|
+
}
|
|
1845
2346
|
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1846
2347
|
function encodeBase64(bytes) {
|
|
1847
2348
|
let result = "";
|
|
@@ -1872,6 +2373,20 @@ function decodeBase64(value) {
|
|
|
1872
2373
|
}
|
|
1873
2374
|
return new Uint8Array(bytes);
|
|
1874
2375
|
}
|
|
2376
|
+
function encodeBase64Url(bytes) {
|
|
2377
|
+
return encodeBase64(bytes).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
2378
|
+
}
|
|
2379
|
+
function decodeCursorPayload(cursor, invalidMessage) {
|
|
2380
|
+
try {
|
|
2381
|
+
const normalized = cursor.replaceAll("-", "+").replaceAll("_", "/").padEnd(Math.ceil(cursor.length / 4) * 4, "=");
|
|
2382
|
+
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(decodeBase64(normalized)));
|
|
2383
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new TypeError(invalidMessage);
|
|
2384
|
+
return parsed;
|
|
2385
|
+
} catch (cause) {
|
|
2386
|
+
if (cause instanceof TypeError && cause.message === invalidMessage) throw cause;
|
|
2387
|
+
throw new TypeError("cursor must be a valid Base64URL JSON token.", { cause });
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
1875
2390
|
function encodeSubmissionCursor(value) {
|
|
1876
2391
|
if (value.submittedAt.length === 0 || value.responseId.length === 0) {
|
|
1877
2392
|
throw new TypeError("Cursor values must not be empty.");
|
|
@@ -2109,6 +2624,28 @@ function validatePageAnswers(schema, pageIndex, values) {
|
|
|
2109
2624
|
}
|
|
2110
2625
|
return issues.length === 0 ? { valid: true, issues: [] } : { valid: false, issues };
|
|
2111
2626
|
}
|
|
2627
|
+
function validateSubmission(schema, submission, options) {
|
|
2628
|
+
const values = submission.values;
|
|
2629
|
+
const answerValidation = validateAnswers(schema, values);
|
|
2630
|
+
const fieldErrors = {};
|
|
2631
|
+
for (const issue2 of answerValidation.issues) {
|
|
2632
|
+
const existing = fieldErrors[issue2.fieldId];
|
|
2633
|
+
fieldErrors[issue2.fieldId] = existing === void 0 ? issue2.messageKey : `${existing}; ${issue2.messageKey}`;
|
|
2634
|
+
}
|
|
2635
|
+
const piiFindings = options?.privacyEngine?.detect(schema, { ...values });
|
|
2636
|
+
if (piiFindings !== void 0) {
|
|
2637
|
+
for (const finding of piiFindings) {
|
|
2638
|
+
const existing = fieldErrors[finding.fieldId];
|
|
2639
|
+
fieldErrors[finding.fieldId] = existing === void 0 ? "validation.sensitiveData" : `${existing}; validation.sensitiveData`;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
return {
|
|
2643
|
+
valid: Object.keys(fieldErrors).length === 0,
|
|
2644
|
+
fieldErrors,
|
|
2645
|
+
formErrors: [],
|
|
2646
|
+
...piiFindings === void 0 ? {} : { piiFindings }
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2112
2649
|
|
|
2113
2650
|
// src/submission.ts
|
|
2114
2651
|
function cloneValues(values) {
|
|
@@ -2116,7 +2653,46 @@ function cloneValues(values) {
|
|
|
2116
2653
|
Object.entries(values).map(([key, value]) => [key, Array.isArray(value) ? Object.freeze([...value]) : value])
|
|
2117
2654
|
);
|
|
2118
2655
|
}
|
|
2119
|
-
function
|
|
2656
|
+
function generatedSubmissionId() {
|
|
2657
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
2658
|
+
}
|
|
2659
|
+
function toFormValues(answers) {
|
|
2660
|
+
const values = {};
|
|
2661
|
+
for (const [key, value] of Object.entries(answers)) {
|
|
2662
|
+
if (isFormValue(value)) values[key] = value;
|
|
2663
|
+
}
|
|
2664
|
+
return values;
|
|
2665
|
+
}
|
|
2666
|
+
function isFormValue(value) {
|
|
2667
|
+
return value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
2668
|
+
}
|
|
2669
|
+
function createSubmission(schemaOrInput, values, options) {
|
|
2670
|
+
if ("answers" in schemaOrInput) {
|
|
2671
|
+
const input = schemaOrInput;
|
|
2672
|
+
const id = input.id ?? generatedSubmissionId();
|
|
2673
|
+
if (input.formId.trim().length === 0) throw new TypeError("formId must not be empty.");
|
|
2674
|
+
if (!Number.isSafeInteger(input.formVersion) || input.formVersion < 1) {
|
|
2675
|
+
throw new TypeError("formVersion must be a positive safe integer.");
|
|
2676
|
+
}
|
|
2677
|
+
const submittedAt = input.submittedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2678
|
+
if (submittedAt.trim().length === 0 || !Number.isFinite(Date.parse(submittedAt))) {
|
|
2679
|
+
throw new TypeError("submittedAt must be a valid date string.");
|
|
2680
|
+
}
|
|
2681
|
+
const answers = Object.freeze({ ...input.answers });
|
|
2682
|
+
return Object.freeze({
|
|
2683
|
+
id,
|
|
2684
|
+
formId: input.formId,
|
|
2685
|
+
formVersion: input.formVersion,
|
|
2686
|
+
locale: "",
|
|
2687
|
+
values: Object.freeze(cloneValues(toFormValues(answers))),
|
|
2688
|
+
answers,
|
|
2689
|
+
metadata: input.metadata,
|
|
2690
|
+
submittedAt,
|
|
2691
|
+
...input.schemaRevision === void 0 ? {} : { schemaRevision: input.schemaRevision }
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2694
|
+
const schema = schemaOrInput;
|
|
2695
|
+
if (values === void 0 || options === void 0) throw new TypeError("values and options are required.");
|
|
2120
2696
|
assertValidFormSchema(schema);
|
|
2121
2697
|
if (options.id.trim().length === 0) throw new TypeError("Submission ID must not be empty.");
|
|
2122
2698
|
if (options.locale.trim().length === 0) throw new TypeError("Submission locale must not be empty.");
|
|
@@ -2136,6 +2712,7 @@ function createSubmission(schema, values, options) {
|
|
|
2136
2712
|
formVersion: schema.version,
|
|
2137
2713
|
locale: options.locale,
|
|
2138
2714
|
values: Object.freeze(cloneValues(visibleValues)),
|
|
2715
|
+
answers: Object.freeze({ ...visibleValues }),
|
|
2139
2716
|
submittedAt: options.submittedAt,
|
|
2140
2717
|
...options.metadata === void 0 ? {} : { metadata: Object.freeze({ ...options.metadata }) },
|
|
2141
2718
|
...options.translationMetadata === void 0 ? {} : { translationMetadata: Object.freeze({ ...options.translationMetadata }) }
|
|
@@ -2192,8 +2769,15 @@ function withTranslationMetadata(node, locale, property, metadata) {
|
|
|
2192
2769
|
}
|
|
2193
2770
|
};
|
|
2194
2771
|
}
|
|
2195
|
-
function
|
|
2196
|
-
const
|
|
2772
|
+
function localeRecordEntry2(record, locale) {
|
|
2773
|
+
const normalizedLocale = normalizeLocale(locale) ?? locale;
|
|
2774
|
+
for (const [candidate, value] of Object.entries(record ?? {})) {
|
|
2775
|
+
if ((normalizeLocale(candidate) ?? candidate) === normalizedLocale) return value;
|
|
2776
|
+
}
|
|
2777
|
+
return void 0;
|
|
2778
|
+
}
|
|
2779
|
+
function createSlot(kind, nodeId, property, locale, sourceText, existingText, nodeMetadata, existingTranslationMetadata, options = {}, parentId) {
|
|
2780
|
+
const path = kind === "form" ? `form.${property}` : kind === "option" ? `fields.${parentId ?? ""}.options.${nodeId}.${property}` : `${kind}s.${nodeId}.${property}`;
|
|
2197
2781
|
const manual = options.isManualTranslation?.(existingTranslationMetadata, { path, locale }) ?? isManualTranslationMetadata(existingTranslationMetadata);
|
|
2198
2782
|
const normalizedMetadata = existingTranslationMetadata === void 0 ? void 0 : options.normalizeMetadata === void 0 ? existingTranslationMetadata : { ...options.normalizeMetadata(existingTranslationMetadata, sourceText) };
|
|
2199
2783
|
const status = getTranslationStatusWithManualOverride(sourceText, existingText, normalizedMetadata, manual);
|
|
@@ -2213,7 +2797,10 @@ function createSlot(kind, nodeId, property, locale, sourceText, existingText, no
|
|
|
2213
2797
|
};
|
|
2214
2798
|
}
|
|
2215
2799
|
function translationSlots(schema, locale, options = {}) {
|
|
2800
|
+
locale = normalizeLocale(locale) ?? locale;
|
|
2216
2801
|
const descriptors = [];
|
|
2802
|
+
const schemaTranslation = localeRecordEntry2(schema.translations, locale);
|
|
2803
|
+
const schemaTranslationMetadata = localeRecordEntry2(schema.translationMetadata, locale);
|
|
2217
2804
|
const addFormSlot = (property, sourceText) => {
|
|
2218
2805
|
const slot = createSlot(
|
|
2219
2806
|
"form",
|
|
@@ -2221,17 +2808,17 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2221
2808
|
property,
|
|
2222
2809
|
locale,
|
|
2223
2810
|
sourceText,
|
|
2224
|
-
|
|
2811
|
+
schemaTranslation?.[property],
|
|
2225
2812
|
schema.metadata,
|
|
2226
|
-
|
|
2813
|
+
schemaTranslationMetadata?.[property],
|
|
2227
2814
|
options
|
|
2228
2815
|
);
|
|
2229
2816
|
descriptors.push({
|
|
2230
2817
|
slot,
|
|
2231
|
-
manual: options.isManualTranslation?.(
|
|
2818
|
+
manual: options.isManualTranslation?.(schemaTranslationMetadata?.[property], {
|
|
2232
2819
|
path: slot.path ?? "",
|
|
2233
2820
|
locale
|
|
2234
|
-
}) ?? isManualTranslationMetadata(
|
|
2821
|
+
}) ?? isManualTranslationMetadata(schemaTranslationMetadata?.[property]),
|
|
2235
2822
|
apply: (current, value, metadata) => withTranslationMetadata(
|
|
2236
2823
|
{ ...current, translations: mergeLocalizedText(current.translations, locale, property, value) },
|
|
2237
2824
|
locale,
|
|
@@ -2244,6 +2831,8 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2244
2831
|
if (schema.description !== void 0) addFormSlot("description", schema.description);
|
|
2245
2832
|
if (schema.completionMessage !== void 0) addFormSlot("completionMessage", schema.completionMessage);
|
|
2246
2833
|
schema.fields.forEach((field, fieldIndex) => {
|
|
2834
|
+
const fieldTranslation = localeRecordEntry2(field.translations, locale);
|
|
2835
|
+
const fieldTranslationMetadata = localeRecordEntry2(field.translationMetadata, locale);
|
|
2247
2836
|
const addFieldSlot = (property, sourceText) => {
|
|
2248
2837
|
const slot = createSlot(
|
|
2249
2838
|
"field",
|
|
@@ -2251,17 +2840,17 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2251
2840
|
property,
|
|
2252
2841
|
locale,
|
|
2253
2842
|
sourceText,
|
|
2254
|
-
|
|
2843
|
+
fieldTranslation?.[property],
|
|
2255
2844
|
field.metadata,
|
|
2256
|
-
|
|
2845
|
+
fieldTranslationMetadata?.[property],
|
|
2257
2846
|
options
|
|
2258
2847
|
);
|
|
2259
2848
|
descriptors.push({
|
|
2260
2849
|
slot,
|
|
2261
|
-
manual: options.isManualTranslation?.(
|
|
2850
|
+
manual: options.isManualTranslation?.(fieldTranslationMetadata?.[property], {
|
|
2262
2851
|
path: slot.path ?? "",
|
|
2263
2852
|
locale
|
|
2264
|
-
}) ?? isManualTranslationMetadata(
|
|
2853
|
+
}) ?? isManualTranslationMetadata(fieldTranslationMetadata?.[property]),
|
|
2265
2854
|
apply: (current, value, metadata) => ({
|
|
2266
2855
|
...current,
|
|
2267
2856
|
fields: current.fields.map(
|
|
@@ -2282,23 +2871,26 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2282
2871
|
if (field.description !== void 0) addFieldSlot("description", field.description);
|
|
2283
2872
|
if ("options" in field) {
|
|
2284
2873
|
field.options.forEach((option, optionIndex) => {
|
|
2874
|
+
const optionTranslation = localeRecordEntry2(option.translations, locale);
|
|
2875
|
+
const optionTranslationMetadata = localeRecordEntry2(option.translationMetadata, locale);
|
|
2285
2876
|
const slot = createSlot(
|
|
2286
2877
|
"option",
|
|
2287
2878
|
option.id,
|
|
2288
2879
|
"label",
|
|
2289
2880
|
locale,
|
|
2290
2881
|
option.label,
|
|
2291
|
-
|
|
2882
|
+
optionTranslation,
|
|
2292
2883
|
option.metadata,
|
|
2293
|
-
|
|
2294
|
-
options
|
|
2884
|
+
optionTranslationMetadata?.label,
|
|
2885
|
+
options,
|
|
2886
|
+
field.id
|
|
2295
2887
|
);
|
|
2296
2888
|
descriptors.push({
|
|
2297
2889
|
slot,
|
|
2298
|
-
manual: options.isManualTranslation?.(
|
|
2890
|
+
manual: options.isManualTranslation?.(optionTranslationMetadata?.label, {
|
|
2299
2891
|
path: slot.path ?? "",
|
|
2300
2892
|
locale
|
|
2301
|
-
}) ?? isManualTranslationMetadata(
|
|
2893
|
+
}) ?? isManualTranslationMetadata(optionTranslationMetadata?.label),
|
|
2302
2894
|
apply: (current, value, metadata) => ({
|
|
2303
2895
|
...current,
|
|
2304
2896
|
fields: current.fields.map((candidate, candidateIndex) => {
|
|
@@ -2324,6 +2916,8 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2324
2916
|
}
|
|
2325
2917
|
});
|
|
2326
2918
|
schema.pages?.forEach((page, pageIndex) => {
|
|
2919
|
+
const pageTranslation = localeRecordEntry2(page.translations, locale);
|
|
2920
|
+
const pageTranslationMetadata = localeRecordEntry2(page.translationMetadata, locale);
|
|
2327
2921
|
const addPageSlot = (property, sourceText) => {
|
|
2328
2922
|
const slot = createSlot(
|
|
2329
2923
|
"page",
|
|
@@ -2331,17 +2925,17 @@ function translationSlots(schema, locale, options = {}) {
|
|
|
2331
2925
|
property,
|
|
2332
2926
|
locale,
|
|
2333
2927
|
sourceText,
|
|
2334
|
-
|
|
2928
|
+
pageTranslation?.[property],
|
|
2335
2929
|
page.metadata,
|
|
2336
|
-
|
|
2930
|
+
pageTranslationMetadata?.[property],
|
|
2337
2931
|
options
|
|
2338
2932
|
);
|
|
2339
2933
|
descriptors.push({
|
|
2340
2934
|
slot,
|
|
2341
|
-
manual: options.isManualTranslation?.(
|
|
2935
|
+
manual: options.isManualTranslation?.(pageTranslationMetadata?.[property], {
|
|
2342
2936
|
path: slot.path ?? "",
|
|
2343
2937
|
locale
|
|
2344
|
-
}) ?? isManualTranslationMetadata(
|
|
2938
|
+
}) ?? isManualTranslationMetadata(pageTranslationMetadata?.[property]),
|
|
2345
2939
|
apply: (current, value, metadata) => ({
|
|
2346
2940
|
...current,
|
|
2347
2941
|
...current.pages === void 0 ? {} : {
|
|
@@ -2429,7 +3023,7 @@ var migrateSchemaTranslationMetadata = (schema, migratorOrOptions) => {
|
|
|
2429
3023
|
(locale, property) => ({
|
|
2430
3024
|
locale,
|
|
2431
3025
|
defaultLocale,
|
|
2432
|
-
path: property
|
|
3026
|
+
path: `form.${property}`,
|
|
2433
3027
|
property,
|
|
2434
3028
|
nodeKind: "form"
|
|
2435
3029
|
}),
|
|
@@ -2528,8 +3122,11 @@ function collectTranslationSlots(schema, locale) {
|
|
|
2528
3122
|
return translationSlots(schema, locale).map((descriptor) => descriptor.slot);
|
|
2529
3123
|
}
|
|
2530
3124
|
function resolveLocalizedSchema(schema, targetLocale) {
|
|
2531
|
-
if (targetLocale === void 0 || targetLocale.length === 0
|
|
2532
|
-
const
|
|
3125
|
+
if (targetLocale === void 0 || targetLocale.length === 0) return schema;
|
|
3126
|
+
const normalizedTargetLocale = normalizeLocale(targetLocale) ?? targetLocale;
|
|
3127
|
+
const defaultLocale = schema.defaultLocale === void 0 ? void 0 : normalizeLocale(schema.defaultLocale);
|
|
3128
|
+
if (normalizedTargetLocale === defaultLocale || targetLocale === schema.defaultLocale) return schema;
|
|
3129
|
+
const formTranslation = localeRecordEntry2(schema.translations, normalizedTargetLocale);
|
|
2533
3130
|
const completionMessage = formTranslation?.completionMessage ?? schema.completionMessage;
|
|
2534
3131
|
return {
|
|
2535
3132
|
...schema,
|
|
@@ -2537,7 +3134,7 @@ function resolveLocalizedSchema(schema, targetLocale) {
|
|
|
2537
3134
|
...(formTranslation?.description ?? schema.description) === void 0 ? {} : { description: formTranslation?.description ?? schema.description },
|
|
2538
3135
|
...completionMessage === void 0 ? {} : { completionMessage },
|
|
2539
3136
|
fields: schema.fields.map((field) => {
|
|
2540
|
-
const translation = field.translations
|
|
3137
|
+
const translation = localeRecordEntry2(field.translations, normalizedTargetLocale);
|
|
2541
3138
|
const localized = {
|
|
2542
3139
|
...field,
|
|
2543
3140
|
title: translation?.title ?? field.title,
|
|
@@ -2548,13 +3145,13 @@ function resolveLocalizedSchema(schema, targetLocale) {
|
|
|
2548
3145
|
...localized,
|
|
2549
3146
|
options: field.options.map((option) => ({
|
|
2550
3147
|
...option,
|
|
2551
|
-
label: option.translations
|
|
3148
|
+
label: localeRecordEntry2(option.translations, normalizedTargetLocale) ?? option.label
|
|
2552
3149
|
}))
|
|
2553
3150
|
};
|
|
2554
3151
|
}),
|
|
2555
3152
|
...schema.pages === void 0 ? {} : {
|
|
2556
3153
|
pages: schema.pages.map((page) => {
|
|
2557
|
-
const translation = page.translations
|
|
3154
|
+
const translation = localeRecordEntry2(page.translations, normalizedTargetLocale);
|
|
2558
3155
|
const title = translation?.title ?? page.title;
|
|
2559
3156
|
const description = translation?.description ?? page.description;
|
|
2560
3157
|
return {
|
|
@@ -2568,8 +3165,13 @@ function resolveLocalizedSchema(schema, targetLocale) {
|
|
|
2568
3165
|
}
|
|
2569
3166
|
async function populateSchemaTranslations(schema, targetLocales, adapter, options = {}) {
|
|
2570
3167
|
assertValidFormSchema(schema);
|
|
2571
|
-
const
|
|
2572
|
-
const
|
|
3168
|
+
const defaultLocale = schema.defaultLocale === void 0 ? void 0 : normalizeLocale(schema.defaultLocale) ?? schema.defaultLocale;
|
|
3169
|
+
const locales = [
|
|
3170
|
+
...new Set(
|
|
3171
|
+
targetLocales.map((locale) => normalizeLocale(locale) ?? locale.trim()).filter((locale) => locale.length > 0 && locale !== defaultLocale)
|
|
3172
|
+
)
|
|
3173
|
+
];
|
|
3174
|
+
const allowedLocales = options.policy?.allowedLocales?.map((locale) => normalizeLocale(locale) ?? locale);
|
|
2573
3175
|
const collectedLocales = collectSchemaLocales(schema);
|
|
2574
3176
|
const disallowedLocale = [...collectedLocales.allUniqueLocales, ...locales].find(
|
|
2575
3177
|
(locale) => allowedLocales !== void 0 && !allowedLocales.includes(locale)
|
|
@@ -2611,7 +3213,7 @@ async function populateSchemaTranslations(schema, targetLocales, adapter, option
|
|
|
2611
3213
|
adapter,
|
|
2612
3214
|
selected.map((descriptor) => descriptor.slot.sourceText),
|
|
2613
3215
|
locale,
|
|
2614
|
-
|
|
3216
|
+
defaultLocale
|
|
2615
3217
|
);
|
|
2616
3218
|
if (translated.length !== selected.length) {
|
|
2617
3219
|
throw new Error(`Translation adapter returned ${translated.length} texts for ${selected.length} inputs.`);
|
|
@@ -2620,7 +3222,7 @@ async function populateSchemaTranslations(schema, targetLocales, adapter, option
|
|
|
2620
3222
|
const translatedText = translated[index];
|
|
2621
3223
|
if (translatedText === void 0) throw new Error("Translation adapter returned an unexpected result.");
|
|
2622
3224
|
const metadata = options.createMetadata?.(descriptor.slot, translatedText) ?? {
|
|
2623
|
-
sourceLocale:
|
|
3225
|
+
sourceLocale: defaultLocale ?? "",
|
|
2624
3226
|
sourceTextHash: computeSourceTextHash(descriptor.slot.sourceText),
|
|
2625
3227
|
translationSource: "automatic",
|
|
2626
3228
|
translatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -2631,8 +3233,8 @@ async function populateSchemaTranslations(schema, targetLocales, adapter, option
|
|
|
2631
3233
|
}
|
|
2632
3234
|
const supportedLocales = [
|
|
2633
3235
|
.../* @__PURE__ */ new Set([
|
|
2634
|
-
...
|
|
2635
|
-
...schema.supportedLocales ?? [],
|
|
3236
|
+
...defaultLocale === void 0 ? [] : [defaultLocale],
|
|
3237
|
+
...(schema.supportedLocales ?? []).map((locale) => normalizeLocale(locale) ?? locale),
|
|
2636
3238
|
...locales
|
|
2637
3239
|
])
|
|
2638
3240
|
];
|
|
@@ -2929,9 +3531,49 @@ function assertVersionMutable(status) {
|
|
|
2929
3531
|
throw new TypeError(`A ${status} form version is immutable.`, { cause: error });
|
|
2930
3532
|
}
|
|
2931
3533
|
}
|
|
3534
|
+
function applyTransitionPlan(plan) {
|
|
3535
|
+
if (plan.schema !== void 0) return plan.schema;
|
|
3536
|
+
if (plan.publishedRecordToSave !== void 0) return plan.publishedRecordToSave.schema;
|
|
3537
|
+
if (plan.draftToCreate !== void 0) return plan.draftToCreate.schema;
|
|
3538
|
+
const archivedSchema = plan.archivedRecordsToSave?.[0]?.schema;
|
|
3539
|
+
if (archivedSchema !== void 0) return archivedSchema;
|
|
3540
|
+
throw new TypeError("A version transition plan must include a target schema.");
|
|
3541
|
+
}
|
|
3542
|
+
async function commitVersionTransition(options) {
|
|
3543
|
+
const { context, beforeTransition, afterTransition, persistAdapter } = options;
|
|
3544
|
+
const { formId, toVersion, expectedRevision, plan } = context;
|
|
3545
|
+
let currentDomainData = context.domainData;
|
|
3546
|
+
try {
|
|
3547
|
+
if (beforeTransition !== void 0) {
|
|
3548
|
+
const hookResult = await beforeTransition(context);
|
|
3549
|
+
if (hookResult !== void 0) currentDomainData = hookResult;
|
|
3550
|
+
}
|
|
3551
|
+
const nextSchema = applyTransitionPlan(plan);
|
|
3552
|
+
const { nextRevision } = await persistAdapter({
|
|
3553
|
+
formId,
|
|
3554
|
+
targetVersion: toVersion,
|
|
3555
|
+
expectedRevision,
|
|
3556
|
+
schema: nextSchema,
|
|
3557
|
+
...currentDomainData === void 0 ? {} : { domainData: currentDomainData }
|
|
3558
|
+
});
|
|
3559
|
+
if (afterTransition !== void 0) {
|
|
3560
|
+
await afterTransition({
|
|
3561
|
+
...context,
|
|
3562
|
+
...currentDomainData === void 0 ? {} : { domainData: currentDomainData },
|
|
3563
|
+
nextRevision
|
|
3564
|
+
});
|
|
3565
|
+
}
|
|
3566
|
+
return { success: true, nextRevision };
|
|
3567
|
+
} catch (cause) {
|
|
3568
|
+
return { success: false, nextRevision: expectedRevision, error: { type: "transition_failed", cause } };
|
|
3569
|
+
}
|
|
3570
|
+
}
|
|
2932
3571
|
export {
|
|
2933
3572
|
DEFAULT_FIELD_TYPE_DEFINITIONS,
|
|
3573
|
+
EN_MESSAGES,
|
|
3574
|
+
JA_MESSAGES,
|
|
2934
3575
|
aggregateResponses,
|
|
3576
|
+
applyTransitionPlan,
|
|
2935
3577
|
assertValidFormSchema,
|
|
2936
3578
|
assertVersionMutable,
|
|
2937
3579
|
calculateChoiceDistribution,
|
|
@@ -2942,16 +3584,22 @@ export {
|
|
|
2942
3584
|
cloneVersionToDraft,
|
|
2943
3585
|
collectSchemaLocales,
|
|
2944
3586
|
collectTranslationSlots,
|
|
3587
|
+
commitVersionTransition,
|
|
2945
3588
|
computeSourceTextHash,
|
|
2946
3589
|
createCloneTransitionPlan,
|
|
2947
3590
|
createDeleteDraftTransitionPlan,
|
|
3591
|
+
createFormEngineTranslator,
|
|
2948
3592
|
createPublishTransitionPlan,
|
|
2949
3593
|
createResponseAccumulator,
|
|
2950
3594
|
createSubmission,
|
|
3595
|
+
decodeStorageSubmissionCursor,
|
|
3596
|
+
decodeStorageTextAnswerCursor,
|
|
2951
3597
|
decodeSubmissionCursor,
|
|
2952
3598
|
decodeTextAnswerCursor,
|
|
2953
3599
|
deleteDraft,
|
|
2954
3600
|
dispatchWebhook,
|
|
3601
|
+
encodeStorageSubmissionCursor,
|
|
3602
|
+
encodeStorageTextAnswerCursor,
|
|
2955
3603
|
encodeSubmissionCursor,
|
|
2956
3604
|
encodeTextAnswerCursor,
|
|
2957
3605
|
escapeCsvCell,
|
|
@@ -2967,7 +3615,9 @@ export {
|
|
|
2967
3615
|
matchesSubmissionFilter,
|
|
2968
3616
|
matchesSubmissionPageFilters,
|
|
2969
3617
|
migrateSchemaTranslationMetadata,
|
|
3618
|
+
normalizeLocale,
|
|
2970
3619
|
normalizeSubmissionPageSize,
|
|
3620
|
+
paginateWithFilter,
|
|
2971
3621
|
pipeResponsesToCsvStream,
|
|
2972
3622
|
populateSchemaTranslations,
|
|
2973
3623
|
publishDraft,
|
|
@@ -2980,5 +3630,6 @@ export {
|
|
|
2980
3630
|
validateAnswers,
|
|
2981
3631
|
validateFormSchema,
|
|
2982
3632
|
validatePageAnswers,
|
|
2983
|
-
validateSchemaStructure
|
|
3633
|
+
validateSchemaStructure,
|
|
3634
|
+
validateSubmission
|
|
2984
3635
|
};
|