@form-engine-ts/react 4.7.0 → 4.8.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 +4 -1
- package/dist/index.cjs +24 -21
- package/dist/index.js +25 -21
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -81,7 +81,10 @@ schema-driven pre-submit confirmation controls in the builder.
|
|
|
81
81
|
|
|
82
82
|
`useTranslationWorkspace` validates added locales against `policy.allowedLocales` and `policy.maxLocales` and returns
|
|
83
83
|
a structured `{ success, error }` result from `addLocale`. Built-in BCP 47, duplicate, and policy checks always run
|
|
84
|
-
before the optional `validateLocale` callback, which receives the locale
|
|
84
|
+
before the optional `validateLocale` callback, which receives the canonical locale and a plain context object containing
|
|
85
|
+
the canonical default locale, current locales, and policy.
|
|
86
|
+
Locale input is normalized to its canonical BCP 47 form before duplicate, policy, custom-validation, and schema updates;
|
|
87
|
+
underscore-separated values such as `EN_us` are accepted as compatibility input.
|
|
85
88
|
Use `isAddLocaleAllowed` to disable locale controls before submission. Removing a locale also clears its
|
|
86
89
|
localized values and metadata; the default locale remains protected.
|
|
87
90
|
|
package/dist/index.cjs
CHANGED
|
@@ -3282,20 +3282,9 @@ function asAsyncAdapter(adapter) {
|
|
|
3282
3282
|
)
|
|
3283
3283
|
};
|
|
3284
3284
|
}
|
|
3285
|
-
function isValidBcp47Locale(locale) {
|
|
3286
|
-
const language = locale.split("-")[0];
|
|
3287
|
-
if (language === void 0 || !/^[a-z]{2,3}$/iu.test(language)) return false;
|
|
3288
|
-
try {
|
|
3289
|
-
Intl.getCanonicalLocales(locale);
|
|
3290
|
-
return true;
|
|
3291
|
-
} catch {
|
|
3292
|
-
return false;
|
|
3293
|
-
}
|
|
3294
|
-
}
|
|
3295
3285
|
var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
3296
|
-
const
|
|
3297
|
-
|
|
3298
|
-
if (!isValidBcp47Locale(locale)) {
|
|
3286
|
+
const canonicalLocale = (0, import_core4.normalizeLocale)(locale);
|
|
3287
|
+
if (canonicalLocale === null) {
|
|
3299
3288
|
return {
|
|
3300
3289
|
valid: false,
|
|
3301
3290
|
error: {
|
|
@@ -3304,21 +3293,23 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
|
3304
3293
|
}
|
|
3305
3294
|
};
|
|
3306
3295
|
}
|
|
3307
|
-
|
|
3296
|
+
const currentLocales = (schema.supportedLocales ?? []).map((candidate) => (0, import_core4.normalizeLocale)(candidate) ?? candidate);
|
|
3297
|
+
const defaultLocale = schema.defaultLocale === void 0 ? "" : (0, import_core4.normalizeLocale)(schema.defaultLocale) ?? schema.defaultLocale;
|
|
3298
|
+
if (canonicalLocale === defaultLocale || currentLocales.includes(canonicalLocale)) {
|
|
3308
3299
|
return {
|
|
3309
3300
|
valid: false,
|
|
3310
3301
|
error: {
|
|
3311
3302
|
type: "locale_already_exists",
|
|
3312
|
-
message: `Locale "${
|
|
3303
|
+
message: `Locale "${canonicalLocale}" is already registered.`
|
|
3313
3304
|
}
|
|
3314
3305
|
};
|
|
3315
3306
|
}
|
|
3316
|
-
if (policy?.allowedLocales !== void 0 && !policy.allowedLocales.
|
|
3307
|
+
if (policy?.allowedLocales !== void 0 && !policy.allowedLocales.some((candidate) => (0, import_core4.normalizeLocale)(candidate) === canonicalLocale)) {
|
|
3317
3308
|
return {
|
|
3318
3309
|
valid: false,
|
|
3319
3310
|
error: {
|
|
3320
3311
|
type: "locale_not_allowed",
|
|
3321
|
-
message: `Locale "${
|
|
3312
|
+
message: `Locale "${canonicalLocale}" is not allowed by policy.`
|
|
3322
3313
|
}
|
|
3323
3314
|
};
|
|
3324
3315
|
}
|
|
@@ -3333,8 +3324,13 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
|
3333
3324
|
};
|
|
3334
3325
|
}
|
|
3335
3326
|
if (customValidator !== void 0) {
|
|
3336
|
-
const
|
|
3337
|
-
|
|
3327
|
+
const context = {
|
|
3328
|
+
locale: canonicalLocale,
|
|
3329
|
+
defaultLocale,
|
|
3330
|
+
currentLocales: Object.freeze([...currentLocales]),
|
|
3331
|
+
...policy === void 0 ? {} : { policy }
|
|
3332
|
+
};
|
|
3333
|
+
const customResult = Reflect.apply(customValidator, void 0, [canonicalLocale, context]);
|
|
3338
3334
|
if (customResult === false) {
|
|
3339
3335
|
return {
|
|
3340
3336
|
valid: false,
|
|
@@ -3487,7 +3483,13 @@ function useTranslationWorkspace({
|
|
|
3487
3483
|
const addLocale = (0, import_react4.useCallback)(
|
|
3488
3484
|
(locale) => {
|
|
3489
3485
|
if (readOnly) return { success: false, error: "Workspace is read-only." };
|
|
3490
|
-
const normalized =
|
|
3486
|
+
const normalized = (0, import_core4.normalizeLocale)(locale);
|
|
3487
|
+
if (normalized === null) {
|
|
3488
|
+
return {
|
|
3489
|
+
success: false,
|
|
3490
|
+
error: workspaceLocaleValidationMessage(validateLocalePipeline(locale, currentSchema, policy, validateLocale))
|
|
3491
|
+
};
|
|
3492
|
+
}
|
|
3491
3493
|
const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale);
|
|
3492
3494
|
if (!validation.valid) return { success: false, error: workspaceLocaleValidationMessage(validation) };
|
|
3493
3495
|
commit({
|
|
@@ -3502,7 +3504,8 @@ function useTranslationWorkspace({
|
|
|
3502
3504
|
const isAddLocaleAllowed = (0, import_react4.useCallback)(
|
|
3503
3505
|
(locale) => {
|
|
3504
3506
|
if (readOnly) return false;
|
|
3505
|
-
const normalized =
|
|
3507
|
+
const normalized = (0, import_core4.normalizeLocale)(locale);
|
|
3508
|
+
if (normalized === null) return false;
|
|
3506
3509
|
return validateLocalePipeline(normalized, currentSchema, policy, validateLocale).valid;
|
|
3507
3510
|
},
|
|
3508
3511
|
[currentSchema, policy, readOnly, validateLocale]
|
package/dist/index.js
CHANGED
|
@@ -3238,6 +3238,7 @@ import {
|
|
|
3238
3238
|
collectSchemaLocales as collectSchemaLocales2,
|
|
3239
3239
|
collectTranslationSlots,
|
|
3240
3240
|
computeSourceTextHash,
|
|
3241
|
+
normalizeLocale,
|
|
3241
3242
|
populateSchemaTranslations as populateSchemaTranslations2,
|
|
3242
3243
|
removeLocaleFromSchema
|
|
3243
3244
|
} from "@form-engine-ts/core";
|
|
@@ -3257,20 +3258,9 @@ function asAsyncAdapter(adapter) {
|
|
|
3257
3258
|
)
|
|
3258
3259
|
};
|
|
3259
3260
|
}
|
|
3260
|
-
function isValidBcp47Locale(locale) {
|
|
3261
|
-
const language = locale.split("-")[0];
|
|
3262
|
-
if (language === void 0 || !/^[a-z]{2,3}$/iu.test(language)) return false;
|
|
3263
|
-
try {
|
|
3264
|
-
Intl.getCanonicalLocales(locale);
|
|
3265
|
-
return true;
|
|
3266
|
-
} catch {
|
|
3267
|
-
return false;
|
|
3268
|
-
}
|
|
3269
|
-
}
|
|
3270
3261
|
var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
3271
|
-
const
|
|
3272
|
-
|
|
3273
|
-
if (!isValidBcp47Locale(locale)) {
|
|
3262
|
+
const canonicalLocale = normalizeLocale(locale);
|
|
3263
|
+
if (canonicalLocale === null) {
|
|
3274
3264
|
return {
|
|
3275
3265
|
valid: false,
|
|
3276
3266
|
error: {
|
|
@@ -3279,21 +3269,23 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
|
3279
3269
|
}
|
|
3280
3270
|
};
|
|
3281
3271
|
}
|
|
3282
|
-
|
|
3272
|
+
const currentLocales = (schema.supportedLocales ?? []).map((candidate) => normalizeLocale(candidate) ?? candidate);
|
|
3273
|
+
const defaultLocale = schema.defaultLocale === void 0 ? "" : normalizeLocale(schema.defaultLocale) ?? schema.defaultLocale;
|
|
3274
|
+
if (canonicalLocale === defaultLocale || currentLocales.includes(canonicalLocale)) {
|
|
3283
3275
|
return {
|
|
3284
3276
|
valid: false,
|
|
3285
3277
|
error: {
|
|
3286
3278
|
type: "locale_already_exists",
|
|
3287
|
-
message: `Locale "${
|
|
3279
|
+
message: `Locale "${canonicalLocale}" is already registered.`
|
|
3288
3280
|
}
|
|
3289
3281
|
};
|
|
3290
3282
|
}
|
|
3291
|
-
if (policy?.allowedLocales !== void 0 && !policy.allowedLocales.
|
|
3283
|
+
if (policy?.allowedLocales !== void 0 && !policy.allowedLocales.some((candidate) => normalizeLocale(candidate) === canonicalLocale)) {
|
|
3292
3284
|
return {
|
|
3293
3285
|
valid: false,
|
|
3294
3286
|
error: {
|
|
3295
3287
|
type: "locale_not_allowed",
|
|
3296
|
-
message: `Locale "${
|
|
3288
|
+
message: `Locale "${canonicalLocale}" is not allowed by policy.`
|
|
3297
3289
|
}
|
|
3298
3290
|
};
|
|
3299
3291
|
}
|
|
@@ -3308,8 +3300,13 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
|
|
|
3308
3300
|
};
|
|
3309
3301
|
}
|
|
3310
3302
|
if (customValidator !== void 0) {
|
|
3311
|
-
const
|
|
3312
|
-
|
|
3303
|
+
const context = {
|
|
3304
|
+
locale: canonicalLocale,
|
|
3305
|
+
defaultLocale,
|
|
3306
|
+
currentLocales: Object.freeze([...currentLocales]),
|
|
3307
|
+
...policy === void 0 ? {} : { policy }
|
|
3308
|
+
};
|
|
3309
|
+
const customResult = Reflect.apply(customValidator, void 0, [canonicalLocale, context]);
|
|
3313
3310
|
if (customResult === false) {
|
|
3314
3311
|
return {
|
|
3315
3312
|
valid: false,
|
|
@@ -3462,7 +3459,13 @@ function useTranslationWorkspace({
|
|
|
3462
3459
|
const addLocale = useCallback3(
|
|
3463
3460
|
(locale) => {
|
|
3464
3461
|
if (readOnly) return { success: false, error: "Workspace is read-only." };
|
|
3465
|
-
const normalized = locale
|
|
3462
|
+
const normalized = normalizeLocale(locale);
|
|
3463
|
+
if (normalized === null) {
|
|
3464
|
+
return {
|
|
3465
|
+
success: false,
|
|
3466
|
+
error: workspaceLocaleValidationMessage(validateLocalePipeline(locale, currentSchema, policy, validateLocale))
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3466
3469
|
const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale);
|
|
3467
3470
|
if (!validation.valid) return { success: false, error: workspaceLocaleValidationMessage(validation) };
|
|
3468
3471
|
commit({
|
|
@@ -3477,7 +3480,8 @@ function useTranslationWorkspace({
|
|
|
3477
3480
|
const isAddLocaleAllowed = useCallback3(
|
|
3478
3481
|
(locale) => {
|
|
3479
3482
|
if (readOnly) return false;
|
|
3480
|
-
const normalized = locale
|
|
3483
|
+
const normalized = normalizeLocale(locale);
|
|
3484
|
+
if (normalized === null) return false;
|
|
3481
3485
|
return validateLocalePipeline(normalized, currentSchema, policy, validateLocale).valid;
|
|
3482
3486
|
},
|
|
3483
3487
|
[currentSchema, policy, readOnly, validateLocale]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@form-engine-ts/react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"typescript"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@form-engine-ts/
|
|
46
|
-
"@form-engine-ts/
|
|
45
|
+
"@form-engine-ts/privacy": "4.8.0",
|
|
46
|
+
"@form-engine-ts/core": "4.8.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": ">=18.2 <20",
|