@digitaldefiance/i18n-lib 3.7.5 → 3.8.1
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/LICENSE +21 -0
- package/README.md +261 -0
- package/package.json +12 -4
- package/src/active-context.ts +4 -0
- package/src/builders/i18n-builder.ts +82 -0
- package/src/builders/{index.d.ts → index.ts} +1 -1
- package/src/component-definition.ts +11 -0
- package/src/component-registration.ts +29 -0
- package/src/component-registry.ts +432 -0
- package/src/context-error-type.ts +7 -0
- package/src/core/component-store.ts +241 -0
- package/src/core/context-manager.ts +113 -0
- package/src/core/enum-registry.ts +106 -0
- package/src/core/i18n-engine.ts +710 -0
- package/src/core/index.ts +16 -0
- package/src/core/language-registry.ts +345 -0
- package/src/core-component-id.ts +5 -0
- package/src/core-i18n.ts +270 -0
- package/src/core-plugin-factory.ts +111 -0
- package/src/core-string-key.ts +59 -0
- package/src/create-translation-adapter.ts +93 -0
- package/src/enum-registry.ts +152 -0
- package/src/errors/base.ts +8 -0
- package/src/errors/context-error.ts +122 -0
- package/src/errors/enhanced-error-base.ts +260 -0
- package/src/errors/handleable.ts +152 -0
- package/src/errors/i18n-error.ts +494 -0
- package/src/errors/index.ts +15 -0
- package/src/errors/simple-typed-error.ts +81 -0
- package/src/errors/{index.d.ts → translatable-exports.ts} +3 -5
- package/src/errors/translatable-generic.ts +245 -0
- package/src/errors/translatable-handleable-generic.ts +222 -0
- package/src/errors/translatable.ts +138 -0
- package/src/errors/typed-handleable.ts +138 -0
- package/src/errors/typed.ts +617 -0
- package/src/gender/{gender-categories.d.ts → gender-categories.ts} +6 -2
- package/src/gender/gender-resolver.ts +40 -0
- package/src/gender/{index.d.ts → index.ts} +0 -1
- package/src/global-active-context.ts +266 -0
- package/src/icu/ast.ts +56 -0
- package/src/icu/compiler.ts +96 -0
- package/src/icu/formatter-registry.ts +36 -0
- package/src/icu/formatters/base-formatter.ts +8 -0
- package/src/icu/formatters/date-formatter.ts +30 -0
- package/src/icu/formatters/number-formatter.ts +32 -0
- package/src/icu/formatters/plural-formatter.ts +12 -0
- package/src/icu/formatters/select-formatter.ts +7 -0
- package/src/icu/formatters/selectordinal-formatter.ts +17 -0
- package/src/icu/formatters/time-formatter.ts +30 -0
- package/src/icu/helpers.ts +34 -0
- package/src/icu/parser.ts +242 -0
- package/src/icu/runtime.ts +37 -0
- package/src/icu/tokenizer.ts +212 -0
- package/src/icu/validator.ts +163 -0
- package/src/{index.d.ts → index.ts} +46 -14
- package/src/interfaces/active-context.interface.ts +41 -0
- package/src/interfaces/component-config.interface.ts +17 -0
- package/src/interfaces/engine-config.interface.ts +22 -0
- package/src/interfaces/global-active-context.ts +39 -0
- package/src/interfaces/handleable-error-options.ts +13 -0
- package/src/interfaces/handleable.ts +20 -0
- package/src/interfaces/i18n-engine.interface.ts +57 -0
- package/src/interfaces/index.ts +13 -0
- package/src/interfaces/language-definition.interface.ts +17 -0
- package/src/interfaces/translation-options.interface.ts +15 -0
- package/src/interfaces/validation-result.interface.ts +24 -0
- package/src/language-codes.ts +40 -0
- package/src/language-definition.ts +13 -0
- package/src/plugin-i18n-engine.ts +707 -0
- package/src/pluralization/{index.d.ts → index.ts} +1 -1
- package/src/pluralization/language-plural-map.ts +186 -0
- package/src/pluralization/{plural-categories.d.ts → plural-categories.ts} +5 -3
- package/src/pluralization/plural-rules.ts +228 -0
- package/src/registry-config.ts +16 -0
- package/src/registry-error-type.ts +19 -0
- package/src/registry-error.ts +100 -0
- package/src/strict-types.ts +35 -0
- package/src/strings/de.ts +75 -0
- package/src/strings/en-GB.ts +74 -0
- package/src/strings/en-US.ts +74 -0
- package/src/strings/es.ts +74 -0
- package/src/strings/fr.ts +75 -0
- package/src/strings/ja.ts +73 -0
- package/src/strings/uk.ts +73 -0
- package/src/strings/zh-CN.ts +72 -0
- package/src/template.ts +72 -0
- package/src/translation-engine.ts +18 -0
- package/src/translation-request.ts +12 -0
- package/src/translation-response.ts +8 -0
- package/src/types/engine.ts +55 -0
- package/src/types/{index.d.ts → index.ts} +1 -1
- package/src/types/{plural-types.d.ts → plural-types.ts} +29 -3
- package/src/types.ts +142 -0
- package/src/utils/currency.ts +141 -0
- package/src/utils/html-escape.ts +55 -0
- package/src/utils/{index.d.ts → index.ts} +0 -1
- package/src/utils/lru-cache.ts +76 -0
- package/src/utils/{plural-helpers.d.ts → plural-helpers.ts} +14 -4
- package/src/utils/{safe-object.js → safe-object.ts} +37 -34
- package/src/utils/string-utils.ts +77 -0
- package/src/utils/timezone.ts +76 -0
- package/src/utils/validation.ts +66 -0
- package/src/utils.ts +215 -0
- package/src/validation/{index.d.ts → index.ts} +0 -1
- package/src/validation/plural-validator.ts +168 -0
- package/src/validation-config.ts +11 -0
- package/src/validation-result.ts +12 -0
- package/src/active-context.d.ts +0 -36
- package/src/active-context.d.ts.map +0 -1
- package/src/active-context.js +0 -3
- package/src/active-context.js.map +0 -1
- package/src/builders/i18n-builder.d.ts +0 -26
- package/src/builders/i18n-builder.d.ts.map +0 -1
- package/src/builders/i18n-builder.js +0 -70
- package/src/builders/i18n-builder.js.map +0 -1
- package/src/builders/index.d.ts.map +0 -1
- package/src/builders/index.js +0 -8
- package/src/builders/index.js.map +0 -1
- package/src/component-definition.d.ts +0 -12
- package/src/component-definition.d.ts.map +0 -1
- package/src/component-definition.js +0 -3
- package/src/component-definition.js.map +0 -1
- package/src/component-registration.d.ts +0 -13
- package/src/component-registration.d.ts.map +0 -1
- package/src/component-registration.js +0 -3
- package/src/component-registration.js.map +0 -1
- package/src/component-registry.d.ts +0 -102
- package/src/component-registry.d.ts.map +0 -1
- package/src/component-registry.js +0 -282
- package/src/component-registry.js.map +0 -1
- package/src/context-error-type.d.ts +0 -8
- package/src/context-error-type.d.ts.map +0 -1
- package/src/context-error-type.js +0 -12
- package/src/context-error-type.js.map +0 -1
- package/src/core/component-store.d.ts +0 -93
- package/src/core/component-store.d.ts.map +0 -1
- package/src/core/component-store.js +0 -198
- package/src/core/component-store.js.map +0 -1
- package/src/core/context-manager.d.ts +0 -72
- package/src/core/context-manager.d.ts.map +0 -1
- package/src/core/context-manager.js +0 -98
- package/src/core/context-manager.js.map +0 -1
- package/src/core/enum-registry.d.ts +0 -48
- package/src/core/enum-registry.d.ts.map +0 -1
- package/src/core/enum-registry.js +0 -85
- package/src/core/enum-registry.js.map +0 -1
- package/src/core/i18n-engine.d.ts +0 -241
- package/src/core/i18n-engine.d.ts.map +0 -1
- package/src/core/i18n-engine.js +0 -568
- package/src/core/i18n-engine.js.map +0 -1
- package/src/core/index.d.ts +0 -9
- package/src/core/index.d.ts.map +0 -1
- package/src/core/index.js +0 -12
- package/src/core/index.js.map +0 -1
- package/src/core/language-registry.d.ts +0 -180
- package/src/core/language-registry.d.ts.map +0 -1
- package/src/core/language-registry.js +0 -295
- package/src/core/language-registry.js.map +0 -1
- package/src/core-i18n.d.ts +0 -91
- package/src/core-i18n.d.ts.map +0 -1
- package/src/core-i18n.js +0 -287
- package/src/core-i18n.js.map +0 -1
- package/src/core-string-key.d.ts +0 -52
- package/src/core-string-key.d.ts.map +0 -1
- package/src/core-string-key.js +0 -61
- package/src/core-string-key.js.map +0 -1
- package/src/create-translation-adapter.d.ts +0 -33
- package/src/create-translation-adapter.d.ts.map +0 -1
- package/src/create-translation-adapter.js +0 -72
- package/src/create-translation-adapter.js.map +0 -1
- package/src/enum-registry.d.ts +0 -65
- package/src/enum-registry.d.ts.map +0 -1
- package/src/enum-registry.js +0 -123
- package/src/enum-registry.js.map +0 -1
- package/src/errors/context-error.d.ts +0 -50
- package/src/errors/context-error.d.ts.map +0 -1
- package/src/errors/context-error.js +0 -75
- package/src/errors/context-error.js.map +0 -1
- package/src/errors/enhanced-error-base.d.ts +0 -125
- package/src/errors/enhanced-error-base.d.ts.map +0 -1
- package/src/errors/enhanced-error-base.js +0 -165
- package/src/errors/enhanced-error-base.js.map +0 -1
- package/src/errors/handleable.d.ts +0 -83
- package/src/errors/handleable.d.ts.map +0 -1
- package/src/errors/handleable.js +0 -136
- package/src/errors/handleable.js.map +0 -1
- package/src/errors/i18n-error.d.ts +0 -211
- package/src/errors/i18n-error.d.ts.map +0 -1
- package/src/errors/i18n-error.js +0 -358
- package/src/errors/i18n-error.js.map +0 -1
- package/src/errors/index.d.ts.map +0 -1
- package/src/errors/index.js +0 -17
- package/src/errors/index.js.map +0 -1
- package/src/errors/simple-typed-error.d.ts +0 -53
- package/src/errors/simple-typed-error.d.ts.map +0 -1
- package/src/errors/simple-typed-error.js +0 -51
- package/src/errors/simple-typed-error.js.map +0 -1
- package/src/errors/translatable-generic.d.ts +0 -84
- package/src/errors/translatable-generic.d.ts.map +0 -1
- package/src/errors/translatable-generic.js +0 -134
- package/src/errors/translatable-generic.js.map +0 -1
- package/src/errors/translatable-handleable-generic.d.ts +0 -116
- package/src/errors/translatable-handleable-generic.d.ts.map +0 -1
- package/src/errors/translatable-handleable-generic.js +0 -121
- package/src/errors/translatable-handleable-generic.js.map +0 -1
- package/src/errors/translatable.d.ts +0 -59
- package/src/errors/translatable.d.ts.map +0 -1
- package/src/errors/translatable.js +0 -80
- package/src/errors/translatable.js.map +0 -1
- package/src/errors/typed-handleable.d.ts +0 -62
- package/src/errors/typed-handleable.d.ts.map +0 -1
- package/src/errors/typed-handleable.js +0 -106
- package/src/errors/typed-handleable.js.map +0 -1
- package/src/errors/typed.d.ts +0 -206
- package/src/errors/typed.d.ts.map +0 -1
- package/src/errors/typed.js +0 -452
- package/src/errors/typed.js.map +0 -1
- package/src/gender/gender-categories.d.ts.map +0 -1
- package/src/gender/gender-categories.js +0 -15
- package/src/gender/gender-categories.js.map +0 -1
- package/src/gender/gender-resolver.d.ts +0 -14
- package/src/gender/gender-resolver.d.ts.map +0 -1
- package/src/gender/gender-resolver.js +0 -35
- package/src/gender/gender-resolver.js.map +0 -1
- package/src/gender/index.d.ts.map +0 -1
- package/src/gender/index.js +0 -6
- package/src/gender/index.js.map +0 -1
- package/src/global-active-context.d.ts +0 -50
- package/src/global-active-context.d.ts.map +0 -1
- package/src/global-active-context.js +0 -185
- package/src/global-active-context.js.map +0 -1
- package/src/icu/ast.d.ts +0 -48
- package/src/icu/ast.d.ts.map +0 -1
- package/src/icu/ast.js +0 -16
- package/src/icu/ast.js.map +0 -1
- package/src/icu/compiler.d.ts +0 -16
- package/src/icu/compiler.d.ts.map +0 -1
- package/src/icu/compiler.js +0 -87
- package/src/icu/compiler.js.map +0 -1
- package/src/icu/formatter-registry.d.ts +0 -10
- package/src/icu/formatter-registry.d.ts.map +0 -1
- package/src/icu/formatter-registry.js +0 -34
- package/src/icu/formatter-registry.js.map +0 -1
- package/src/icu/formatters/base-formatter.d.ts +0 -8
- package/src/icu/formatters/base-formatter.d.ts.map +0 -1
- package/src/icu/formatters/base-formatter.js +0 -3
- package/src/icu/formatters/base-formatter.js.map +0 -1
- package/src/icu/formatters/date-formatter.d.ts +0 -5
- package/src/icu/formatters/date-formatter.d.ts.map +0 -1
- package/src/icu/formatters/date-formatter.js +0 -31
- package/src/icu/formatters/date-formatter.js.map +0 -1
- package/src/icu/formatters/number-formatter.d.ts +0 -5
- package/src/icu/formatters/number-formatter.d.ts.map +0 -1
- package/src/icu/formatters/number-formatter.js +0 -33
- package/src/icu/formatters/number-formatter.js.map +0 -1
- package/src/icu/formatters/plural-formatter.d.ts +0 -5
- package/src/icu/formatters/plural-formatter.d.ts.map +0 -1
- package/src/icu/formatters/plural-formatter.js +0 -15
- package/src/icu/formatters/plural-formatter.js.map +0 -1
- package/src/icu/formatters/select-formatter.d.ts +0 -5
- package/src/icu/formatters/select-formatter.d.ts.map +0 -1
- package/src/icu/formatters/select-formatter.js +0 -10
- package/src/icu/formatters/select-formatter.js.map +0 -1
- package/src/icu/formatters/selectordinal-formatter.d.ts +0 -5
- package/src/icu/formatters/selectordinal-formatter.d.ts.map +0 -1
- package/src/icu/formatters/selectordinal-formatter.js +0 -22
- package/src/icu/formatters/selectordinal-formatter.js.map +0 -1
- package/src/icu/formatters/time-formatter.d.ts +0 -5
- package/src/icu/formatters/time-formatter.d.ts.map +0 -1
- package/src/icu/formatters/time-formatter.js +0 -31
- package/src/icu/formatters/time-formatter.js.map +0 -1
- package/src/icu/helpers.d.ts +0 -9
- package/src/icu/helpers.d.ts.map +0 -1
- package/src/icu/helpers.js +0 -31
- package/src/icu/helpers.js.map +0 -1
- package/src/icu/parser.d.ts +0 -31
- package/src/icu/parser.d.ts.map +0 -1
- package/src/icu/parser.js +0 -203
- package/src/icu/parser.js.map +0 -1
- package/src/icu/runtime.d.ts +0 -10
- package/src/icu/runtime.d.ts.map +0 -1
- package/src/icu/runtime.js +0 -33
- package/src/icu/runtime.js.map +0 -1
- package/src/icu/tokenizer.d.ts +0 -37
- package/src/icu/tokenizer.d.ts.map +0 -1
- package/src/icu/tokenizer.js +0 -187
- package/src/icu/tokenizer.js.map +0 -1
- package/src/icu/validator.d.ts +0 -11
- package/src/icu/validator.d.ts.map +0 -1
- package/src/icu/validator.js +0 -140
- package/src/icu/validator.js.map +0 -1
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -76
- package/src/index.js.map +0 -1
- package/src/interfaces/component-config.interface.d.ts +0 -16
- package/src/interfaces/component-config.interface.d.ts.map +0 -1
- package/src/interfaces/component-config.interface.js +0 -6
- package/src/interfaces/component-config.interface.js.map +0 -1
- package/src/interfaces/engine-config.interface.d.ts +0 -22
- package/src/interfaces/engine-config.interface.d.ts.map +0 -1
- package/src/interfaces/engine-config.interface.js +0 -6
- package/src/interfaces/engine-config.interface.js.map +0 -1
- package/src/interfaces/global-active-context.d.ts +0 -23
- package/src/interfaces/global-active-context.d.ts.map +0 -1
- package/src/interfaces/global-active-context.js +0 -3
- package/src/interfaces/global-active-context.js.map +0 -1
- package/src/interfaces/handleable-error-options.d.ts +0 -14
- package/src/interfaces/handleable-error-options.d.ts.map +0 -1
- package/src/interfaces/handleable-error-options.js +0 -3
- package/src/interfaces/handleable-error-options.js.map +0 -1
- package/src/interfaces/handleable.d.ts +0 -21
- package/src/interfaces/handleable.d.ts.map +0 -1
- package/src/interfaces/handleable.js +0 -3
- package/src/interfaces/handleable.js.map +0 -1
- package/src/interfaces/i18n-engine.interface.d.ts +0 -46
- package/src/interfaces/i18n-engine.interface.d.ts.map +0 -1
- package/src/interfaces/i18n-engine.interface.js +0 -6
- package/src/interfaces/i18n-engine.interface.js.map +0 -1
- package/src/interfaces/index.d.ts +0 -11
- package/src/interfaces/index.d.ts.map +0 -1
- package/src/interfaces/index.js +0 -14
- package/src/interfaces/index.js.map +0 -1
- package/src/interfaces/language-definition.interface.d.ts +0 -17
- package/src/interfaces/language-definition.interface.d.ts.map +0 -1
- package/src/interfaces/language-definition.interface.js +0 -6
- package/src/interfaces/language-definition.interface.js.map +0 -1
- package/src/interfaces/translation-options.interface.d.ts +0 -15
- package/src/interfaces/translation-options.interface.d.ts.map +0 -1
- package/src/interfaces/translation-options.interface.js +0 -6
- package/src/interfaces/translation-options.interface.js.map +0 -1
- package/src/interfaces/validation-result.interface.d.ts +0 -24
- package/src/interfaces/validation-result.interface.d.ts.map +0 -1
- package/src/interfaces/validation-result.interface.js +0 -6
- package/src/interfaces/validation-result.interface.js.map +0 -1
- package/src/language-codes.d.ts +0 -28
- package/src/language-codes.d.ts.map +0 -1
- package/src/language-codes.js +0 -32
- package/src/language-codes.js.map +0 -1
- package/src/language-definition.d.ts +0 -14
- package/src/language-definition.d.ts.map +0 -1
- package/src/language-definition.js +0 -3
- package/src/language-definition.js.map +0 -1
- package/src/plugin-i18n-engine.d.ts +0 -164
- package/src/plugin-i18n-engine.d.ts.map +0 -1
- package/src/plugin-i18n-engine.js +0 -489
- package/src/plugin-i18n-engine.js.map +0 -1
- package/src/pluralization/index.d.ts.map +0 -1
- package/src/pluralization/index.js +0 -10
- package/src/pluralization/index.js.map +0 -1
- package/src/pluralization/language-plural-map.d.ts +0 -29
- package/src/pluralization/language-plural-map.d.ts.map +0 -1
- package/src/pluralization/language-plural-map.js +0 -155
- package/src/pluralization/language-plural-map.js.map +0 -1
- package/src/pluralization/plural-categories.d.ts.map +0 -1
- package/src/pluralization/plural-categories.js +0 -8
- package/src/pluralization/plural-categories.js.map +0 -1
- package/src/pluralization/plural-rules.d.ts +0 -102
- package/src/pluralization/plural-rules.d.ts.map +0 -1
- package/src/pluralization/plural-rules.js +0 -263
- package/src/pluralization/plural-rules.js.map +0 -1
- package/src/registry-config.d.ts +0 -16
- package/src/registry-config.d.ts.map +0 -1
- package/src/registry-config.js +0 -3
- package/src/registry-config.js.map +0 -1
- package/src/registry-error-type.d.ts +0 -20
- package/src/registry-error-type.d.ts.map +0 -1
- package/src/registry-error-type.js +0 -24
- package/src/registry-error-type.js.map +0 -1
- package/src/registry-error.d.ts +0 -19
- package/src/registry-error.d.ts.map +0 -1
- package/src/registry-error.js +0 -49
- package/src/registry-error.js.map +0 -1
- package/src/strict-types.d.ts +0 -19
- package/src/strict-types.d.ts.map +0 -1
- package/src/strict-types.js +0 -18
- package/src/strict-types.js.map +0 -1
- package/src/strings/de.d.ts +0 -3
- package/src/strings/de.d.ts.map +0 -1
- package/src/strings/de.js +0 -57
- package/src/strings/de.js.map +0 -1
- package/src/strings/en-GB.d.ts +0 -3
- package/src/strings/en-GB.d.ts.map +0 -1
- package/src/strings/en-GB.js +0 -57
- package/src/strings/en-GB.js.map +0 -1
- package/src/strings/en-US.d.ts +0 -3
- package/src/strings/en-US.d.ts.map +0 -1
- package/src/strings/en-US.js +0 -57
- package/src/strings/en-US.js.map +0 -1
- package/src/strings/es.d.ts +0 -3
- package/src/strings/es.d.ts.map +0 -1
- package/src/strings/es.js +0 -57
- package/src/strings/es.js.map +0 -1
- package/src/strings/fr.d.ts +0 -3
- package/src/strings/fr.d.ts.map +0 -1
- package/src/strings/fr.js +0 -57
- package/src/strings/fr.js.map +0 -1
- package/src/strings/ja.d.ts +0 -3
- package/src/strings/ja.d.ts.map +0 -1
- package/src/strings/ja.js +0 -57
- package/src/strings/ja.js.map +0 -1
- package/src/strings/uk.d.ts +0 -3
- package/src/strings/uk.d.ts.map +0 -1
- package/src/strings/uk.js +0 -57
- package/src/strings/uk.js.map +0 -1
- package/src/strings/zh-CN.d.ts +0 -3
- package/src/strings/zh-CN.d.ts.map +0 -1
- package/src/strings/zh-CN.js +0 -57
- package/src/strings/zh-CN.js.map +0 -1
- package/src/template.d.ts +0 -13
- package/src/template.d.ts.map +0 -1
- package/src/template.js +0 -40
- package/src/template.js.map +0 -1
- package/src/translation-engine.d.ts +0 -9
- package/src/translation-engine.d.ts.map +0 -1
- package/src/translation-engine.js +0 -3
- package/src/translation-engine.js.map +0 -1
- package/src/translation-request.d.ts +0 -10
- package/src/translation-request.d.ts.map +0 -1
- package/src/translation-request.js +0 -3
- package/src/translation-request.js.map +0 -1
- package/src/translation-response.d.ts +0 -9
- package/src/translation-response.d.ts.map +0 -1
- package/src/translation-response.js +0 -3
- package/src/translation-response.js.map +0 -1
- package/src/types/engine.d.ts +0 -47
- package/src/types/engine.d.ts.map +0 -1
- package/src/types/engine.js +0 -8
- package/src/types/engine.js.map +0 -1
- package/src/types/index.d.ts.map +0 -1
- package/src/types/index.js +0 -9
- package/src/types/index.js.map +0 -1
- package/src/types/plural-types.d.ts.map +0 -1
- package/src/types/plural-types.js +0 -39
- package/src/types/plural-types.js.map +0 -1
- package/src/types.d.ts +0 -96
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -23
- package/src/types.js.map +0 -1
- package/src/utils/currency.d.ts +0 -81
- package/src/utils/currency.d.ts.map +0 -1
- package/src/utils/currency.js +0 -101
- package/src/utils/currency.js.map +0 -1
- package/src/utils/html-escape.d.ts +0 -22
- package/src/utils/html-escape.d.ts.map +0 -1
- package/src/utils/html-escape.js +0 -53
- package/src/utils/html-escape.js.map +0 -1
- package/src/utils/index.d.ts.map +0 -1
- package/src/utils/index.js +0 -12
- package/src/utils/index.js.map +0 -1
- package/src/utils/lru-cache.d.ts +0 -42
- package/src/utils/lru-cache.d.ts.map +0 -1
- package/src/utils/lru-cache.js +0 -73
- package/src/utils/lru-cache.js.map +0 -1
- package/src/utils/plural-helpers.d.ts.map +0 -1
- package/src/utils/plural-helpers.js +0 -35
- package/src/utils/plural-helpers.js.map +0 -1
- package/src/utils/safe-object.d.ts +0 -39
- package/src/utils/safe-object.d.ts.map +0 -1
- package/src/utils/safe-object.js.map +0 -1
- package/src/utils/string-utils.d.ts +0 -28
- package/src/utils/string-utils.d.ts.map +0 -1
- package/src/utils/string-utils.js +0 -63
- package/src/utils/string-utils.js.map +0 -1
- package/src/utils/timezone.d.ts +0 -50
- package/src/utils/timezone.d.ts.map +0 -1
- package/src/utils/timezone.js +0 -74
- package/src/utils/timezone.js.map +0 -1
- package/src/utils/validation.d.ts +0 -40
- package/src/utils/validation.d.ts.map +0 -1
- package/src/utils/validation.js +0 -69
- package/src/utils/validation.js.map +0 -1
- package/src/utils.d.ts +0 -65
- package/src/utils.d.ts.map +0 -1
- package/src/utils.js +0 -129
- package/src/utils.js.map +0 -1
- package/src/validation/index.d.ts.map +0 -1
- package/src/validation/index.js +0 -5
- package/src/validation/index.js.map +0 -1
- package/src/validation/plural-validator.d.ts +0 -46
- package/src/validation/plural-validator.d.ts.map +0 -1
- package/src/validation/plural-validator.js +0 -123
- package/src/validation/plural-validator.js.map +0 -1
- package/src/validation-config.d.ts +0 -12
- package/src/validation-config.d.ts.map +0 -1
- package/src/validation-config.js +0 -3
- package/src/validation-config.js.map +0 -1
- package/src/validation-result.d.ts +0 -13
- package/src/validation-result.d.ts.map +0 -1
- package/src/validation-result.js +0 -3
- package/src/validation-result.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I18n Engine type definitions
|
|
3
|
+
*
|
|
4
|
+
* This file provides type-safe interfaces for i18n engine implementations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generic I18n Engine interface with type-safe string key constraints
|
|
9
|
+
*
|
|
10
|
+
* This interface defines the core methods that any i18n engine implementation
|
|
11
|
+
* should provide, with proper generic constraints for string keys.
|
|
12
|
+
*
|
|
13
|
+
* @template TStringKeys - Union type of valid string keys for translation
|
|
14
|
+
*/
|
|
15
|
+
export interface II18nEngine<TStringKeys extends string = string> {
|
|
16
|
+
/**
|
|
17
|
+
* Translate a string key with optional variables
|
|
18
|
+
* @param key - The translation key
|
|
19
|
+
* @param params - Optional parameters for interpolation
|
|
20
|
+
* @returns The translated string
|
|
21
|
+
*/
|
|
22
|
+
translate(key: TStringKeys, params?: Record<string, unknown>): string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Translate an enum value to a string
|
|
26
|
+
* @template T - The enum type
|
|
27
|
+
* @param enumObj - The enum object
|
|
28
|
+
* @param value - The enum value to translate
|
|
29
|
+
* @param language - Optional language override
|
|
30
|
+
* @returns The translated enum value
|
|
31
|
+
*/
|
|
32
|
+
translateEnum<T extends Record<string, string | number>>(
|
|
33
|
+
enumObj: T,
|
|
34
|
+
value: T[keyof T],
|
|
35
|
+
language?: string,
|
|
36
|
+
): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Set the current language for translations
|
|
40
|
+
* @param language - The language code to set
|
|
41
|
+
*/
|
|
42
|
+
setLanguage(language: string): void;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the current language
|
|
46
|
+
* @returns The current language code
|
|
47
|
+
*/
|
|
48
|
+
getLanguage(): string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Re-export the main II18nEngine interface from interfaces
|
|
53
|
+
* This provides a centralized location for engine type imports
|
|
54
|
+
*/
|
|
55
|
+
export type { II18nEngine as IMainI18nEngine } from '../interfaces/i18n-engine.interface';
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type definitions for pluralization support
|
|
3
3
|
*/
|
|
4
|
+
|
|
4
5
|
import { PluralCategory } from '../pluralization/plural-categories';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* A string value that can be either a simple string or an object with plural forms.
|
|
7
9
|
* When using plural forms, the object should have keys matching PluralCategory values.
|
|
8
10
|
*/
|
|
9
11
|
export type PluralString = string | Partial<Record<PluralCategory, string>>;
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Check if a value is a plural string object (not a simple string).
|
|
12
15
|
* @param value - The value to check
|
|
13
16
|
* @returns True if the value is a plural string object, false if it's a simple string
|
|
14
17
|
*/
|
|
15
|
-
export
|
|
18
|
+
export function isPluralString(value: any): value is Record<PluralCategory, string> {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
/**
|
|
17
23
|
* Get the appropriate plural form from a PluralString based on the category.
|
|
18
24
|
* Falls back to 'other' if the exact category is not found, then to the first available form.
|
|
@@ -20,5 +26,25 @@ export declare function isPluralString(value: any): value is Record<PluralCatego
|
|
|
20
26
|
* @param category - The plural category to retrieve
|
|
21
27
|
* @returns The resolved string, or undefined if no suitable form is found
|
|
22
28
|
*/
|
|
23
|
-
export
|
|
24
|
-
|
|
29
|
+
export function resolvePluralString(
|
|
30
|
+
value: PluralString,
|
|
31
|
+
category: PluralCategory
|
|
32
|
+
): string | undefined {
|
|
33
|
+
if (typeof value === 'string') {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Try exact match first
|
|
38
|
+
if (value[category]) {
|
|
39
|
+
return value[category];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Fallback to 'other'
|
|
43
|
+
if (value.other) {
|
|
44
|
+
return value.other;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Fallback to first available form
|
|
48
|
+
const forms = Object.values(value);
|
|
49
|
+
return forms.length > 0 ? forms[0] : undefined;
|
|
50
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ComponentDefinition } from './component-definition';
|
|
2
|
+
import { LanguageDefinition } from './language-definition';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Standard language context spaces
|
|
6
|
+
*/
|
|
7
|
+
export type LanguageContextSpace = 'admin' | 'user';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default currency code
|
|
11
|
+
*/
|
|
12
|
+
export const DefaultCurrencyCode: string = 'USD';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Default timezone
|
|
16
|
+
*/
|
|
17
|
+
export const DefaultTimezone: string = 'UTC';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default language code
|
|
21
|
+
*/
|
|
22
|
+
export const DefaultLanguageCode: string = 'en-US';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Currency position type
|
|
26
|
+
*/
|
|
27
|
+
export type CurrencyPosition = 'prefix' | 'postfix' | 'infix';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Collection of localized strings for a specific language
|
|
31
|
+
*/
|
|
32
|
+
export type StringsCollection<TStringKey extends string> = Partial<
|
|
33
|
+
Record<TStringKey, string>
|
|
34
|
+
>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Mapping of languages to their respective string collections
|
|
38
|
+
*/
|
|
39
|
+
export type MasterStringsCollection<
|
|
40
|
+
TStringKey extends string,
|
|
41
|
+
TLanguage extends string,
|
|
42
|
+
> = Partial<Record<TLanguage, StringsCollection<TStringKey>>>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Mapping of language codes to their respective languages
|
|
46
|
+
*/
|
|
47
|
+
export type LanguageCodeCollection<TLanguage extends string> = Partial<
|
|
48
|
+
Record<TLanguage, string>
|
|
49
|
+
>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Mapping of enumeration values to their translations in multiple languages
|
|
53
|
+
*/
|
|
54
|
+
export type EnumTranslationMap<
|
|
55
|
+
TEnum extends string | number,
|
|
56
|
+
TLanguage extends string,
|
|
57
|
+
> = Partial<Record<TLanguage, Partial<Record<TEnum, string>>>>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* String collection for a specific language and component
|
|
61
|
+
*/
|
|
62
|
+
export type ComponentStrings<TStringKeys extends string> = {
|
|
63
|
+
[K in TStringKeys]: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Partial string collection (used during registration before validation)
|
|
68
|
+
*/
|
|
69
|
+
export type PartialComponentStrings<TStringKeys extends string> = {
|
|
70
|
+
[K in TStringKeys]?: string;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Language strings for a component across all registered languages
|
|
75
|
+
*/
|
|
76
|
+
export type ComponentLanguageStrings<
|
|
77
|
+
TStringKeys extends string,
|
|
78
|
+
TLanguages extends string,
|
|
79
|
+
> = {
|
|
80
|
+
[L in TLanguages]: ComponentStrings<TStringKeys>;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Partial language strings (used during registration before validation)
|
|
85
|
+
*/
|
|
86
|
+
export type PartialComponentLanguageStrings<
|
|
87
|
+
TStringKeys extends string,
|
|
88
|
+
TLanguages extends string,
|
|
89
|
+
> = {
|
|
90
|
+
[L in TLanguages]?: PartialComponentStrings<TStringKeys>;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generic translation type for any enumeration
|
|
95
|
+
*/
|
|
96
|
+
export type EnumTranslation<T extends string | number> = {
|
|
97
|
+
[K in T]: string;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Generic language translation type for any enumeration
|
|
102
|
+
*/
|
|
103
|
+
export type EnumLanguageTranslation<
|
|
104
|
+
T extends string | number,
|
|
105
|
+
TLanguage extends string = string,
|
|
106
|
+
> = Partial<{
|
|
107
|
+
[L in TLanguage]: EnumTranslation<T>;
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Type utility to extract string keys from a component definition
|
|
112
|
+
*/
|
|
113
|
+
export type ExtractStringKeys<T> = T extends ComponentDefinition<infer K>
|
|
114
|
+
? K
|
|
115
|
+
: never;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Type utility to extract languages from registry
|
|
119
|
+
*/
|
|
120
|
+
export type ExtractLanguages<T> = T extends LanguageDefinition
|
|
121
|
+
? T['id']
|
|
122
|
+
: never;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Utility type to ensure all string keys are provided for all languages
|
|
126
|
+
*/
|
|
127
|
+
export type CompleteComponentStrings<
|
|
128
|
+
TStringKeys extends string,
|
|
129
|
+
TLanguages extends string,
|
|
130
|
+
> = ComponentLanguageStrings<TStringKeys, TLanguages>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Helper function to create typed translations for an enumeration
|
|
134
|
+
*/
|
|
135
|
+
export function createTranslations<
|
|
136
|
+
T extends string | number,
|
|
137
|
+
TLanguage extends string,
|
|
138
|
+
>(
|
|
139
|
+
translations: EnumLanguageTranslation<T, TLanguage>,
|
|
140
|
+
): EnumLanguageTranslation<T, TLanguage> {
|
|
141
|
+
return translations;
|
|
142
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Currency utilities (v2)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { codes, data } from 'currency-codes';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Position of the currency symbol relative to the amount.
|
|
9
|
+
*/
|
|
10
|
+
export type CurrencyPosition = 'prefix' | 'postfix' | 'infix';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for formatting currency values in a specific locale.
|
|
14
|
+
*/
|
|
15
|
+
export interface CurrencyFormat {
|
|
16
|
+
/** The currency symbol (e.g., "$", "€") */
|
|
17
|
+
symbol: string;
|
|
18
|
+
/** Position of the symbol relative to the amount */
|
|
19
|
+
position: CurrencyPosition;
|
|
20
|
+
/** Character used to separate thousands (e.g., ",") */
|
|
21
|
+
groupSeparator: string;
|
|
22
|
+
/** Character used to separate decimal places (e.g., ".") */
|
|
23
|
+
decimalSeparator: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Detailed information about a currency.
|
|
28
|
+
*/
|
|
29
|
+
export interface CurrencyData {
|
|
30
|
+
/** ISO 4217 currency code (e.g., "USD") */
|
|
31
|
+
code: string;
|
|
32
|
+
/** Numeric currency code */
|
|
33
|
+
number: string;
|
|
34
|
+
/** Number of decimal digits */
|
|
35
|
+
digits: number;
|
|
36
|
+
/** Currency name */
|
|
37
|
+
currency: string;
|
|
38
|
+
/** Countries using this currency */
|
|
39
|
+
countries: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Represents a valid ISO 4217 currency code with validation.
|
|
44
|
+
*/
|
|
45
|
+
export class CurrencyCode {
|
|
46
|
+
private _value: string;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new CurrencyCode instance.
|
|
50
|
+
* @param value - The ISO 4217 currency code (defaults to 'USD')
|
|
51
|
+
* @throws {Error} If the currency code is invalid
|
|
52
|
+
*/
|
|
53
|
+
constructor(value: string = 'USD') {
|
|
54
|
+
if (!CurrencyCode.isValid(value)) {
|
|
55
|
+
throw new Error(`Invalid currency code: ${value}`);
|
|
56
|
+
}
|
|
57
|
+
this._value = value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the currency code value.
|
|
62
|
+
* @returns The ISO 4217 currency code
|
|
63
|
+
*/
|
|
64
|
+
get value(): string {
|
|
65
|
+
return this._value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gets the currency code (alias for value).
|
|
70
|
+
* @returns The ISO 4217 currency code
|
|
71
|
+
*/
|
|
72
|
+
get code(): string {
|
|
73
|
+
return this._value;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Checks if a currency code is valid according to ISO 4217.
|
|
78
|
+
* @param code - The currency code to validate
|
|
79
|
+
* @returns True if the code is valid, false otherwise
|
|
80
|
+
*/
|
|
81
|
+
static isValid(code: string): boolean {
|
|
82
|
+
return codes().includes(code);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Gets all valid ISO 4217 currency codes.
|
|
87
|
+
* @returns Array of currency codes
|
|
88
|
+
*/
|
|
89
|
+
static getAll(): string[] {
|
|
90
|
+
return codes();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Gets detailed information for all currencies.
|
|
95
|
+
* @returns Array of currency data objects
|
|
96
|
+
*/
|
|
97
|
+
static getAllData(): CurrencyData[] {
|
|
98
|
+
return data as CurrencyData[];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Gets the currency formatting rules for a specific locale and currency.
|
|
104
|
+
* @param locale - The locale code (e.g., 'en-US', 'fr-FR')
|
|
105
|
+
* @param currencyCode - The ISO 4217 currency code
|
|
106
|
+
* @returns Currency format configuration including symbol, position, and separators
|
|
107
|
+
*/
|
|
108
|
+
export function getCurrencyFormat(
|
|
109
|
+
locale: string,
|
|
110
|
+
currencyCode: string,
|
|
111
|
+
): CurrencyFormat {
|
|
112
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
113
|
+
style: 'currency',
|
|
114
|
+
currency: currencyCode,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const parts = formatter.formatToParts(1234567.89);
|
|
118
|
+
const symbol = parts.find((part) => part.type === 'currency')?.value || '';
|
|
119
|
+
const symbolIndex = parts.findIndex((part) => part.type === 'currency');
|
|
120
|
+
const decimalIndex = parts.findIndex((part) => part.type === 'decimal');
|
|
121
|
+
const integerIndex = parts.findIndex((part) => part.type === 'integer');
|
|
122
|
+
|
|
123
|
+
let position: CurrencyPosition;
|
|
124
|
+
if (decimalIndex === -1) {
|
|
125
|
+
position = symbolIndex < integerIndex ? 'prefix' : 'postfix';
|
|
126
|
+
} else if (symbolIndex < decimalIndex && symbolIndex < integerIndex) {
|
|
127
|
+
position = 'prefix';
|
|
128
|
+
} else if (symbolIndex > decimalIndex) {
|
|
129
|
+
position = 'postfix';
|
|
130
|
+
} else {
|
|
131
|
+
position = 'infix';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
symbol,
|
|
136
|
+
position,
|
|
137
|
+
groupSeparator: parts.find((part) => part.type === 'group')?.value || ',',
|
|
138
|
+
decimalSeparator:
|
|
139
|
+
parts.find((part) => part.type === 'decimal')?.value || '.',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML escaping utilities for XSS prevention
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map of HTML characters to their escaped equivalents.
|
|
7
|
+
*/
|
|
8
|
+
const HTML_ESCAPES: Record<string, string> = {
|
|
9
|
+
'&': '&',
|
|
10
|
+
'<': '<',
|
|
11
|
+
'>': '>',
|
|
12
|
+
'"': '"',
|
|
13
|
+
"'": ''',
|
|
14
|
+
'/': '/',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Regular expression to match characters that need HTML escaping.
|
|
19
|
+
*/
|
|
20
|
+
const HTML_ESCAPE_REGEX = /[&<>"'/]/g;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Escapes HTML special characters to prevent XSS attacks.
|
|
24
|
+
* @param str - The string to escape
|
|
25
|
+
* @returns The escaped string
|
|
26
|
+
*/
|
|
27
|
+
export function escapeHtml(str: string): string {
|
|
28
|
+
return str.replace(HTML_ESCAPE_REGEX, char => HTML_ESCAPES[char]);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Safely converts a value to a string, optionally escaping HTML.
|
|
33
|
+
* Rejects objects to prevent toString exploits.
|
|
34
|
+
* @param value - The value to stringify
|
|
35
|
+
* @param options - Options including whether to escape HTML
|
|
36
|
+
* @param options.escapeHtml - If true, HTML-escapes the result
|
|
37
|
+
* @returns The stringified value
|
|
38
|
+
* @throws {Error} If the value is an object (to prevent exploits)
|
|
39
|
+
*/
|
|
40
|
+
export function safeStringify(value: any, options?: { escapeHtml?: boolean }): string {
|
|
41
|
+
if (value === null || value === undefined) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (typeof value === 'string') {
|
|
46
|
+
return options?.escapeHtml ? escapeHtml(value) : value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
50
|
+
return String(value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Reject objects to prevent toString exploits
|
|
54
|
+
throw new Error('Invalid value type for stringification');
|
|
55
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple LRU Cache implementation for security
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Least Recently Used (LRU) cache implementation.
|
|
7
|
+
* Automatically evicts the oldest entries when the cache reaches maximum size.
|
|
8
|
+
* @template K - The type of cache keys
|
|
9
|
+
* @template V - The type of cached values
|
|
10
|
+
*/
|
|
11
|
+
export class LRUCache<K, V> {
|
|
12
|
+
private cache = new Map<K, V>();
|
|
13
|
+
private readonly maxSize: number;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new LRUCache instance.
|
|
17
|
+
* @param maxSize - Maximum number of entries to store (default: 1000)
|
|
18
|
+
*/
|
|
19
|
+
constructor(maxSize: number = 1000) {
|
|
20
|
+
this.maxSize = maxSize;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves a value from the cache by key.
|
|
25
|
+
* Accessing an item moves it to the end (marks it as most recently used).
|
|
26
|
+
* @param key - The key to look up
|
|
27
|
+
* @returns The cached value, or undefined if not found
|
|
28
|
+
*/
|
|
29
|
+
get(key: K): V | undefined {
|
|
30
|
+
const value = this.cache.get(key);
|
|
31
|
+
if (value !== undefined) {
|
|
32
|
+
// Move to end (most recently used)
|
|
33
|
+
this.cache.delete(key);
|
|
34
|
+
this.cache.set(key, value);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Adds or updates a value in the cache.
|
|
41
|
+
* If the cache is at capacity, the oldest entry is removed.
|
|
42
|
+
* @param key - The key to store
|
|
43
|
+
* @param value - The value to cache
|
|
44
|
+
*/
|
|
45
|
+
set(key: K, value: V): void {
|
|
46
|
+
// Remove if exists to update position
|
|
47
|
+
if (this.cache.has(key)) {
|
|
48
|
+
this.cache.delete(key);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Remove oldest if at capacity
|
|
52
|
+
if (this.cache.size >= this.maxSize) {
|
|
53
|
+
const firstKey = this.cache.keys().next().value;
|
|
54
|
+
if (firstKey !== undefined) {
|
|
55
|
+
this.cache.delete(firstKey);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.cache.set(key, value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Removes all entries from the cache.
|
|
64
|
+
*/
|
|
65
|
+
clear(): void {
|
|
66
|
+
this.cache.clear();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Gets the current number of entries in the cache.
|
|
71
|
+
* @returns The number of cached entries
|
|
72
|
+
*/
|
|
73
|
+
size(): number {
|
|
74
|
+
return this.cache.size;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,26 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Helper functions for creating plural and gender strings
|
|
3
3
|
*/
|
|
4
|
+
|
|
4
5
|
import { PluralCategory } from '../pluralization/plural-categories';
|
|
5
6
|
import { PluralString } from '../types/plural-types';
|
|
6
7
|
import { GenderCategory, GenderedString } from '../gender/gender-categories';
|
|
8
|
+
import { getRequiredPluralForms as getRequiredFormsFromMap } from '../pluralization/language-plural-map';
|
|
9
|
+
|
|
7
10
|
/**
|
|
8
11
|
* Creates a PluralString from a partial record of plural forms.
|
|
9
12
|
* @param forms - Object mapping plural categories to their string forms
|
|
10
13
|
* @returns A PluralString that can be used in translations
|
|
11
14
|
*/
|
|
12
|
-
export
|
|
15
|
+
export function createPluralString(forms: Partial<Record<PluralCategory, string>>): PluralString {
|
|
16
|
+
return forms;
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
/**
|
|
14
20
|
* Creates a GenderedString from a partial record of gender forms.
|
|
15
21
|
* @param forms - Object mapping gender categories to their string forms
|
|
16
22
|
* @returns A GenderedString that can be used in translations
|
|
17
23
|
*/
|
|
18
|
-
export
|
|
24
|
+
export function createGenderedString(forms: Partial<Record<GenderCategory, string>>): GenderedString {
|
|
25
|
+
return forms;
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
/**
|
|
20
29
|
* Gets the required plural forms for a given language.
|
|
21
30
|
* Different languages have different plural rules and require different forms.
|
|
22
31
|
* @param language - The language code
|
|
23
32
|
* @returns Array of plural categories required for the language
|
|
24
33
|
*/
|
|
25
|
-
export
|
|
26
|
-
|
|
34
|
+
export function getRequiredPluralForms(language: string): PluralCategory[] {
|
|
35
|
+
return getRequiredFormsFromMap(language) as PluralCategory[];
|
|
36
|
+
}
|
|
@@ -1,34 +1,31 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Safe object utilities to prevent prototype pollution
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
exports.createSafeObject = createSafeObject;
|
|
7
|
-
exports.isDangerousKey = isDangerousKey;
|
|
8
|
-
exports.safeAssign = safeAssign;
|
|
9
|
-
exports.safeObjectEntries = safeObjectEntries;
|
|
10
|
-
exports.validateObjectKeys = validateObjectKeys;
|
|
4
|
+
|
|
11
5
|
/**
|
|
12
6
|
* List of dangerous keys that should never be set on objects to prevent prototype pollution.
|
|
13
7
|
*/
|
|
14
8
|
const DANGEROUS_KEYS = ['__proto__', 'constructor', 'prototype'];
|
|
9
|
+
|
|
15
10
|
/**
|
|
16
11
|
* Creates a safe object without a prototype chain.
|
|
17
12
|
* This prevents prototype pollution attacks.
|
|
18
13
|
* @template T - The type of values in the object
|
|
19
14
|
* @returns A new object without a prototype
|
|
20
15
|
*/
|
|
21
|
-
function createSafeObject() {
|
|
22
|
-
|
|
16
|
+
export function createSafeObject<T = any>(): Record<string, T> {
|
|
17
|
+
return Object.create(null);
|
|
23
18
|
}
|
|
19
|
+
|
|
24
20
|
/**
|
|
25
21
|
* Checks if a key is in the list of dangerous keys that could enable prototype pollution.
|
|
26
22
|
* @param key - The key to check
|
|
27
23
|
* @returns True if the key is dangerous, false otherwise
|
|
28
24
|
*/
|
|
29
|
-
function isDangerousKey(key) {
|
|
30
|
-
|
|
25
|
+
export function isDangerousKey(key: string): boolean {
|
|
26
|
+
return DANGEROUS_KEYS.includes(key);
|
|
31
27
|
}
|
|
28
|
+
|
|
32
29
|
/**
|
|
33
30
|
* Safely assigns properties from source objects to a target object.
|
|
34
31
|
* Filters out dangerous keys to prevent prototype pollution.
|
|
@@ -37,42 +34,48 @@ function isDangerousKey(key) {
|
|
|
37
34
|
* @param sources - One or more source objects to copy properties from
|
|
38
35
|
* @returns The target object with properties assigned
|
|
39
36
|
*/
|
|
40
|
-
function safeAssign
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
37
|
+
export function safeAssign<T extends Record<string, any>>(
|
|
38
|
+
target: T,
|
|
39
|
+
...sources: Array<Record<string, any> | undefined>
|
|
40
|
+
): T {
|
|
41
|
+
for (const source of sources) {
|
|
42
|
+
if (!source) continue;
|
|
43
|
+
|
|
44
|
+
for (const key of Object.keys(source)) {
|
|
45
|
+
if (!isDangerousKey(key)) {
|
|
46
|
+
// Type-safe property assignment using index signature
|
|
47
|
+
(target as Record<string, any>)[key] = source[key];
|
|
48
|
+
}
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
}
|
|
51
|
+
return target;
|
|
52
52
|
}
|
|
53
|
+
|
|
53
54
|
/**
|
|
54
55
|
* Gets key-value pairs from an object, filtering out dangerous keys.
|
|
55
56
|
* @template T - The type of values in the object
|
|
56
57
|
* @param obj - The object to get entries from
|
|
57
58
|
* @returns Array of [key, value] pairs, excluding dangerous keys
|
|
58
59
|
*/
|
|
59
|
-
function safeObjectEntries(
|
|
60
|
-
|
|
60
|
+
export function safeObjectEntries<T>(
|
|
61
|
+
obj: Record<string, T>,
|
|
62
|
+
): Array<[string, T]> {
|
|
63
|
+
return Object.entries(obj).filter(([key]) => !isDangerousKey(key));
|
|
61
64
|
}
|
|
65
|
+
|
|
62
66
|
/**
|
|
63
67
|
* Validates that an object does not contain dangerous keys.
|
|
64
68
|
* @param obj - The object to validate
|
|
65
69
|
* @throws {Error} If a dangerous key is detected
|
|
66
70
|
*/
|
|
67
|
-
function validateObjectKeys(obj) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
71
|
+
export function validateObjectKeys(obj: Record<string, any>): void {
|
|
72
|
+
if (!obj || typeof obj !== 'object') return;
|
|
73
|
+
|
|
74
|
+
// Check for dangerous keys in Object.keys and getOwnPropertyNames
|
|
75
|
+
const allKeys = [...Object.keys(obj), ...Object.getOwnPropertyNames(obj)];
|
|
76
|
+
for (const key of allKeys) {
|
|
77
|
+
if (DANGEROUS_KEYS.includes(key)) {
|
|
78
|
+
throw new Error(`Dangerous key detected: ${key}`);
|
|
76
79
|
}
|
|
80
|
+
}
|
|
77
81
|
}
|
|
78
|
-
//# sourceMappingURL=safe-object.js.map
|