@entropic-bond/localize-react 1.7.6 → 1.7.8
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/lib/entropic-bond-localize-react.cjs +2 -2
- package/lib/entropic-bond-localize-react.cjs.map +1 -1
- package/lib/entropic-bond-localize-react.js +116 -137
- package/lib/entropic-bond-localize-react.js.map +1 -1
- package/lib/entropic-bond-localize-react.umd.cjs +2 -2
- package/lib/entropic-bond-localize-react.umd.cjs.map +1 -1
- package/lib/locale.d.ts +2 -1
- package/lib/localized-component.d.ts +4 -3
- package/package.json +13 -12
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=entropic-bond-localize-react.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("react");var t=class e{constructor(e){this._pendingPromise=void 0,this._table=void 0,this._table=void 0,this._pendingPromise=void 0,this._lang=e.locale||`en`,this._localePath=e.localePath||``}static get instance(){return this._instance||=new e(this._registeredConfig),this._instance}static get currentLocale(){return e._registeredConfig.locale||e.instance._lang}pluralize(t,n=0,r){if(n===1)return t;let i;if(typeof r!=`function`){if(i=r?.[t],i)return i}else i=r?.(t,this._lang);let a=0,o=e._registeredRules[this._lang];for(;!i&&o&&a<o.length;)i=o[a++]?.(t,this._lang);return i??t}static config(e){this._registeredConfig={...this._registeredConfig,...e},this._instance=void 0}async get(e){return this._table||=await this.fetchCache(async()=>{try{return(await fetch(this.getLocaleFilePath())).json()}catch{return(await fetch(this.getLocaleFilePath(`en`))).json()}}),this._table[e]}fetchCache(e){return this._pendingPromise||=new Promise(t=>t(e())),this._pendingPromise}getLocaleFilePath(e){return this._lang.indexOf(`http`)<0?`${this._localePath}/${e||this._lang}.json`:this._lang}static usePluralizerRule(t,n){e._registeredRules[n]||(e._registeredRules[n]=[]),!(e._registeredRules[n].indexOf(t)>=0)&&e._registeredRules[n].unshift(t)}static useRule(t,n){return e.usePluralizerRule(t,n)}static{this.defaultRules={en:[e=>e.slice(-1)===`f`?e.slice(0,-1)+`ves`:e.slice(-1)===`o`?e.slice(0,-1)+`oes`:e.slice(-1)===`x`?e.slice(0,-1)+`xes`:e.slice(-1)===`h`?e.slice(0,-1)+`hes`:e.slice(-1)===`s`?e.slice(0,-1)+`ses`:e.slice(-1)===`y`?e.slice(0,-1)+`ies`:e.slice(-1)===`z`?e.slice(0,-1)+`zes`:e+`s`],es:[e=>e.slice(-1)===`l`?e.slice(0,-1)+`les`:e.slice(-1)===`n`?e.slice(0,-1)+`nes`:e.slice(-1)===`r`?e.slice(0,-1)+`res`:e.slice(-1)===`z`?e.slice(0,-1)+`ces`:e+`s`]}}static{this._instance=void 0}static{this._registeredConfig={}}static{this._registeredRules=e.defaultRules}};function n(e,t=!1){return(n,r=t)=>{if(!n)return`Locale key not found!`;if(!e)return n;let i=n.split(`.`).reduce((e,t)=>{if(!(!e||typeof e!=`object`))return e[t]},e);if(i===void 0&&r)throw Error(`Translation for ${n} not found`);return typeof i==`string`?i:n}}function r(e,t,r=!1){return n(e,r)(t)}var i=class extends e.Component{constructor(e){super(e),this.state={locale:{}},Promise.all([t.instance.get(`Generic`),t.instance.get(this.className())]).then(e=>{let t={...e[0],...e[1]};this.setState({locale:t}),this.onLoadLocale(t)})}onLoadLocale(e){}};function a(e){return function(n){return class extends n{constructor(...n){super(...n),this.loadLocale=Promise.all([t.instance.get(e),t.instance.get(`Generic`)]).then(e=>{let t={...e[0],...e[1]};this.setState({locale:t}),this.onLoadLocale?.(t)})}}}}function o(n){let[r,i]=(0,e.useState)({});return(0,e.useEffect)(()=>{Promise.all([t.instance.get(n),t.instance.get(`Generic`)]).then(e=>i({...e[0],...e[1]}))},[]),r}exports.Locale=t,exports.LocalizedComponent=i,exports.createSafeLocalizerFor=n,exports.localize=a,exports.safeLocalize=r,exports.useLocale=o;
|
|
2
|
+
//# sourceMappingURL=entropic-bond-localize-react.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entropic-bond-localize-react.cjs","sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["interface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise< {} > {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ]\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: {} | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string | symbol ]: string & LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce(( acc: {}, prop: string ) => acc[ prop ], locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn value || keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): {} }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\t\tstate = { locale: {}, ...this['state'] }\n\t\t\t\tloadLocale = Promise.all([\n\t\t\t\t\tLocale.instance.get( className ),\n\t\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t\t]).then( resp => {\n\t\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\t\tthis['setState']({ locale })\n\t\t\t\t\tthis['onLoadLocale'] && this['onLoadLocale']( locale )\n\t\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"names":["_Locale","config","word","amount","pluralizer","plural","i","rules","component","cachedPromise","resolve","locale","rule","Locale","createSafeLocalizerFor","throwOnKeyNotFound","keyPath","throwOnNotFound","value","acc","prop","safeLocalize","LocalizedComponent","Component","props","resp","localize","className","constructor","useLocale","componentName","setLocale","useState","useEffect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"entropic-bond-localize-react.cjs","names":[],"sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["import { LocaleEntries } from './localized-component'\n\ninterface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise<LocaleEntries | undefined> {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ] as LocaleEntries | undefined\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: LocaleEntries | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string ]: string | LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !keyPath ) return 'Locale key not found!'\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce< unknown >( ( acc, prop ) => {\n\t\t\tif ( !acc || typeof acc !== 'object' ) return undefined\n\t\t\treturn ( acc as Record<string, unknown> )[ prop ]\n\t\t}, locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn typeof value === 'string' ? value : keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): Record<string, any> }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\tdeclare state: Record<string, any>\n\t\t\tloadLocale = Promise.all([\n\t\t\t\tLocale.instance.get( className ),\n\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t]).then( resp => {\n\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\tthis.setState({ locale })\n\t\t\t\tthis.onLoadLocale?.( locale )\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"mappings":"0FASA,IAAa,EAAb,MAAa,CAAO,CACnB,YAAqB,EAAuB,sBA0IY,IAAA,eACZ,IAAA,GA1I3C,KAAK,OAAS,IAAA,GACd,KAAK,gBAAkB,IAAA,GACvB,KAAK,MAAQ,EAAO,QAAU,KAC9B,KAAK,YAAc,EAAO,YAAc,EACzC,CAEA,WAAkB,UAAmB,CAIpC,MAHA,CACC,KAAK,YAAY,IAAI,EAAQ,KAAK,iBAAkB,EAE9C,KAAK,SACb,CAEA,WAAW,eAAgB,CAC1B,OAAO,EAAO,kBAAkB,QAAU,EAAO,SAAS,KAC3D,CAUA,UAAW,EAAc,EAAiB,EAAG,EAA6C,CACzF,GAAK,IAAW,EAAI,OAAO,EAE3B,IAAI,EAEJ,GAAK,OAAO,GAAe,WAE1B,IADA,EAAS,IAAc,GAClB,EAAS,OAAO,CAAA,KAGrB,GAAS,IAAc,EAAM,KAAK,KAAM,EAGzC,IAAI,EAAI,EACF,EAAQ,EAAO,iBAAkB,KAAK,OAC5C,KAAQ,CAAC,GAAU,GAAS,EAAI,EAAM,QACrC,EAAS,EAAO,IAAK,GAAI,EAAM,KAAK,KAAM,EAG3C,OAAO,GAAU,CAClB,CAEA,OAAO,OAAQ,EAAuB,CACrC,KAAK,kBAAoB,CACxB,GAAG,KAAK,kBACR,GAAG,CACJ,EACA,KAAK,UAAY,IAAA,EAClB,CAEA,MAAM,IAAK,EAAwD,CAalE,MAZA,CACC,KAAK,SAAS,MAAM,KAAK,WACxB,SAAU,CACT,GAAI,CACH,OAAS,MAAM,MAAO,KAAK,kBAAkB,CAAE,EAAA,CAAI,KAAK,CACzD,MACgB,CACf,OAAS,MAAM,MAAO,KAAK,kBAAkB,IAAI,CAAE,EAAA,CAAI,KAAK,CAC7D,CACD,CACD,EAEM,KAAK,OAAS,EACtB,CAEA,WAAyB,EAA8C,CAItE,MAHA,CACC,KAAK,kBAAkB,IAAI,QAAc,GAAW,EAAS,EAAc,CAAE,CAAE,EAEzE,KAAK,eACb,CAEA,kBAA2B,EAAkB,CAK5C,OAJK,KAAK,MAAM,QAAQ,MAAM,EAAI,EAC1B,GAAI,KAAK,YAAa,GAAI,GAAU,KAAK,MAAO,OAGjD,KAAK,KACb,CAQA,OAAO,kBAAmB,EAAY,EAAiB,CAChD,EAAO,iBAAkB,KAAW,EAAO,iBAAkB,GAAW,CAAC,GAC1E,IAAO,iBAAkB,EAAQ,CAAE,QAAS,CAAK,GAAK,IAC3D,EAAO,iBAAkB,EAAQ,CAAE,QAAS,CAAK,CAClD,CAMA,OAAO,QAAS,EAAY,EAAiB,CAC5C,OAAO,EAAO,kBAAmB,EAAM,CAAO,CAC/C,0BAE8B,CAC7B,GAAI,CACD,GACI,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MAEpD,EAAO,GAEhB,EACA,GAAI,CACD,GACI,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MACtD,EAAK,MAAM,EAAE,IAAM,IAAa,EAAK,MAAO,EAAG,EAAG,EAAI,MAEpD,EAAO,GAEhB,CACD,wBAE+C,IAAA,iCACE,CAAC,+BACe,EAAO,aAKzE,EC1HA,SAAgB,EAAwB,EAAmC,EAAqB,GAAuC,CACtI,OAAS,EAAiB,EAAkB,IAAwB,CACnE,GAAK,CAAC,EAAU,MAAO,wBACvB,GAAK,CAAC,EAAS,OAAO,EACtB,IAAM,EAAQ,EAAQ,MAAM,GAAG,CAAC,CAAC,QAAqB,EAAK,IAAU,CAC/D,MAAC,GAAO,OAAO,GAAQ,UAC5B,OAAS,EAAkC,EAC5C,EAAG,CAAO,EACV,GAAK,IAAU,IAAA,IAAa,EAAkB,MAAM,MAAO,mBAAoB,EAAS,WAAY,EACpG,OAAO,OAAO,GAAU,SAAW,EAAQ,CAC5C,CACD,CAeA,SAAgB,EAAc,EAAmC,EAAiB,EAAqB,GAAgB,CACtH,OAAO,EAAwB,EAAQ,CAAmB,CAAC,CAAE,CAAQ,CACtE,CAeA,IAAsB,EAAtB,cAAgG,EAAA,SAAgB,CAC/G,YAAa,EAAW,CACvB,MAAO,CAAM,EAEb,KAAK,MAAQ,CAAE,OAAQ,CAAC,CAAE,EAE1B,QAAQ,IAAI,CACX,EAAO,SAAS,IAAK,SAAU,EAC/B,EAAO,SAAS,IAAK,KAAK,UAAU,CAAE,CACvC,CAAC,CAAC,CAAC,KAAM,GAAQ,CAChB,IAAM,EAAS,CAAE,GAAG,EAAK,GAAI,GAAG,EAAK,EAAG,EAExC,KAAK,SAAS,CAAE,QAAQ,CAAC,EACzB,KAAK,aAAc,CAAO,CAC3B,CAAC,CACF,CAYA,aAAc,EAAwB,CAAC,CACxC,EAcA,SAAgB,EAAU,EAAoB,CAC7C,OAAO,SAAkE,EAAgB,CACxF,OAAO,cAAc,CAAY,+CAEnB,QAAQ,IAAI,CACxB,EAAO,SAAS,IAAK,CAAU,EAC/B,EAAO,SAAS,IAAK,SAAU,CAChC,CAAC,CAAC,CAAC,KAAM,GAAQ,CAChB,IAAM,EAAS,CAAE,GAAG,EAAK,GAAI,GAAG,EAAK,EAAG,EACxC,KAAK,SAAS,CAAE,QAAO,CAAC,EACxB,KAAK,eAAgB,CAAO,CAC7B,CAAC,EACF,CACD,CACD,CASA,SAAgB,EAAW,EAAwB,CAClD,GAAM,CAAE,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAuB,CAAC,CAAkB,EAW1D,OATA,EAAA,EAAA,UAAA,KAAiB,CAEhB,QAAQ,IAAI,CACX,EAAO,SAAS,IAAK,CAAc,EACnC,EAAO,SAAS,IAAK,SAAU,CAChC,CAAC,CAAC,CAAC,KAAM,GAAQ,EAAU,CAAE,GAAG,EAAK,GAAI,GAAG,EAAK,EAAG,CAAC,CAAC,CAEvD,EAAG,CAAC,CAAC,EAEE,CACR"}
|
|
@@ -1,142 +1,121 @@
|
|
|
1
|
-
import { Component as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Registers a rule to pluralize words
|
|
67
|
-
* @deprecated use usePluralizerRule instead
|
|
68
|
-
*/
|
|
69
|
-
static useRule(e, t) {
|
|
70
|
-
return i.usePluralizerRule(e, t);
|
|
71
|
-
}
|
|
1
|
+
import { Component as e, useEffect as t, useState as n } from "react";
|
|
2
|
+
//#region src/locale.ts
|
|
3
|
+
var r = class e {
|
|
4
|
+
constructor(e) {
|
|
5
|
+
this._pendingPromise = void 0, this._table = void 0, this._table = void 0, this._pendingPromise = void 0, this._lang = e.locale || "en", this._localePath = e.localePath || "";
|
|
6
|
+
}
|
|
7
|
+
static get instance() {
|
|
8
|
+
return this._instance ||= new e(this._registeredConfig), this._instance;
|
|
9
|
+
}
|
|
10
|
+
static get currentLocale() {
|
|
11
|
+
return e._registeredConfig.locale || e.instance._lang;
|
|
12
|
+
}
|
|
13
|
+
pluralize(t, n = 0, r) {
|
|
14
|
+
if (n === 1) return t;
|
|
15
|
+
let i;
|
|
16
|
+
if (typeof r != "function") {
|
|
17
|
+
if (i = r?.[t], i) return i;
|
|
18
|
+
} else i = r?.(t, this._lang);
|
|
19
|
+
let a = 0, o = e._registeredRules[this._lang];
|
|
20
|
+
for (; !i && o && a < o.length;) i = o[a++]?.(t, this._lang);
|
|
21
|
+
return i ?? t;
|
|
22
|
+
}
|
|
23
|
+
static config(e) {
|
|
24
|
+
this._registeredConfig = {
|
|
25
|
+
...this._registeredConfig,
|
|
26
|
+
...e
|
|
27
|
+
}, this._instance = void 0;
|
|
28
|
+
}
|
|
29
|
+
async get(e) {
|
|
30
|
+
return this._table ||= await this.fetchCache(async () => {
|
|
31
|
+
try {
|
|
32
|
+
return (await fetch(this.getLocaleFilePath())).json();
|
|
33
|
+
} catch {
|
|
34
|
+
return (await fetch(this.getLocaleFilePath("en"))).json();
|
|
35
|
+
}
|
|
36
|
+
}), this._table[e];
|
|
37
|
+
}
|
|
38
|
+
fetchCache(e) {
|
|
39
|
+
return this._pendingPromise ||= new Promise((t) => t(e())), this._pendingPromise;
|
|
40
|
+
}
|
|
41
|
+
getLocaleFilePath(e) {
|
|
42
|
+
return this._lang.indexOf("http") < 0 ? `${this._localePath}/${e || this._lang}.json` : this._lang;
|
|
43
|
+
}
|
|
44
|
+
static usePluralizerRule(t, n) {
|
|
45
|
+
e._registeredRules[n] || (e._registeredRules[n] = []), !(e._registeredRules[n].indexOf(t) >= 0) && e._registeredRules[n].unshift(t);
|
|
46
|
+
}
|
|
47
|
+
static useRule(t, n) {
|
|
48
|
+
return e.usePluralizerRule(t, n);
|
|
49
|
+
}
|
|
50
|
+
static {
|
|
51
|
+
this.defaultRules = {
|
|
52
|
+
en: [(e) => e.slice(-1) === "f" ? e.slice(0, -1) + "ves" : e.slice(-1) === "o" ? e.slice(0, -1) + "oes" : e.slice(-1) === "x" ? e.slice(0, -1) + "xes" : e.slice(-1) === "h" ? e.slice(0, -1) + "hes" : e.slice(-1) === "s" ? e.slice(0, -1) + "ses" : e.slice(-1) === "y" ? e.slice(0, -1) + "ies" : e.slice(-1) === "z" ? e.slice(0, -1) + "zes" : e + "s"],
|
|
53
|
+
es: [(e) => e.slice(-1) === "l" ? e.slice(0, -1) + "les" : e.slice(-1) === "n" ? e.slice(0, -1) + "nes" : e.slice(-1) === "r" ? e.slice(0, -1) + "res" : e.slice(-1) === "z" ? e.slice(0, -1) + "ces" : e + "s"]
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
static {
|
|
57
|
+
this._instance = void 0;
|
|
58
|
+
}
|
|
59
|
+
static {
|
|
60
|
+
this._registeredConfig = {};
|
|
61
|
+
}
|
|
62
|
+
static {
|
|
63
|
+
this._registeredRules = e.defaultRules;
|
|
64
|
+
}
|
|
72
65
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const n = t.split(".").reduce((a, c) => a[c], l);
|
|
86
|
-
if (n === void 0 && s) throw Error(`Translation for ${t} not found`);
|
|
87
|
-
return n || t;
|
|
88
|
-
};
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/localized-component.tsx
|
|
68
|
+
function i(e, t = !1) {
|
|
69
|
+
return (n, r = t) => {
|
|
70
|
+
if (!n) return "Locale key not found!";
|
|
71
|
+
if (!e) return n;
|
|
72
|
+
let i = n.split(".").reduce((e, t) => {
|
|
73
|
+
if (!(!e || typeof e != "object")) return e[t];
|
|
74
|
+
}, e);
|
|
75
|
+
if (i === void 0 && r) throw Error(`Translation for ${n} not found`);
|
|
76
|
+
return typeof i == "string" ? i : n;
|
|
77
|
+
};
|
|
89
78
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
79
|
+
function a(e, t, n = !1) {
|
|
80
|
+
return i(e, n)(t);
|
|
92
81
|
}
|
|
93
|
-
class
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.setState({ locale: s }), this.onLoadLocale && this.onLoadLocale(s);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
};
|
|
82
|
+
var o = class extends e {
|
|
83
|
+
constructor(e) {
|
|
84
|
+
super(e), this.state = { locale: {} }, Promise.all([r.instance.get("Generic"), r.instance.get(this.className())]).then((e) => {
|
|
85
|
+
let t = {
|
|
86
|
+
...e[0],
|
|
87
|
+
...e[1]
|
|
88
|
+
};
|
|
89
|
+
this.setState({ locale: t }), this.onLoadLocale(t);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
onLoadLocale(e) {}
|
|
93
|
+
};
|
|
94
|
+
function s(e) {
|
|
95
|
+
return function(t) {
|
|
96
|
+
return class extends t {
|
|
97
|
+
constructor(...t) {
|
|
98
|
+
super(...t), this.loadLocale = Promise.all([r.instance.get(e), r.instance.get("Generic")]).then((e) => {
|
|
99
|
+
let t = {
|
|
100
|
+
...e[0],
|
|
101
|
+
...e[1]
|
|
102
|
+
};
|
|
103
|
+
this.setState({ locale: t }), this.onLoadLocale?.(t);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
};
|
|
124
108
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
109
|
+
function c(e) {
|
|
110
|
+
let [i, a] = n({});
|
|
111
|
+
return t(() => {
|
|
112
|
+
Promise.all([r.instance.get(e), r.instance.get("Generic")]).then((e) => a({
|
|
113
|
+
...e[0],
|
|
114
|
+
...e[1]
|
|
115
|
+
}));
|
|
116
|
+
}, []), i;
|
|
133
117
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
P as localize,
|
|
139
|
-
_ as safeLocalize,
|
|
140
|
-
L as useLocale
|
|
141
|
-
};
|
|
142
|
-
//# sourceMappingURL=entropic-bond-localize-react.js.map
|
|
118
|
+
//#endregion
|
|
119
|
+
export { r as Locale, o as LocalizedComponent, i as createSafeLocalizerFor, s as localize, a as safeLocalize, c as useLocale };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=entropic-bond-localize-react.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entropic-bond-localize-react.js","sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["interface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise< {} > {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ]\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: {} | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string | symbol ]: string & LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce(( acc: {}, prop: string ) => acc[ prop ], locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn value || keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): {} }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\t\tstate = { locale: {}, ...this['state'] }\n\t\t\t\tloadLocale = Promise.all([\n\t\t\t\t\tLocale.instance.get( className ),\n\t\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t\t]).then( resp => {\n\t\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\t\tthis['setState']({ locale })\n\t\t\t\t\tthis['onLoadLocale'] && this['onLoadLocale']( locale )\n\t\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"names":["_Locale","config","word","amount","pluralizer","plural","i","rules","component","cachedPromise","resolve","locale","rule","Locale","createSafeLocalizerFor","throwOnKeyNotFound","keyPath","throwOnNotFound","value","acc","prop","safeLocalize","LocalizedComponent","Component","props","resp","localize","className","constructor","useLocale","componentName","setLocale","useState","useEffect"],"mappings":";AAOO,MAAMA,IAAN,MAAMA,EAAO;AAAA,EACX,YAAaC,GAAuB;AA0I5C,SAAQ,kBAAgD,QACxD,KAAQ,SAAyB,QA1IhC,KAAK,SAAS,QACd,KAAK,kBAAkB,QACvB,KAAK,QAAQA,EAAO,UAAU,MAC9B,KAAK,cAAcA,EAAO,cAAc;AAAA,EACzC;AAAA,EAEA,WAAkB,WAAmB;AACpC,WAAM,KAAK,cACV,KAAK,YAAY,IAAID,EAAQ,KAAK,iBAAkB,IAE9C,KAAK;AAAA,EACb;AAAA,EAEA,WAAW,gBAAgB;AAC1B,WAAOA,EAAO,kBAAkB,UAAUA,EAAO,SAAS;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAAWE,GAAcC,IAAiB,GAAGC,GAA6C;AACzF,QAAKD,MAAW,EAAI,QAAOD;AAE3B,QAAIG;AAEJ,QAAK,OAAOD,KAAe;AAE1B,UADAC,IAASD,IAAcF,CAAK,GACvBG,EAAS,QAAOA;AAAA;AAGrB,MAAAA,IAASD,IAAcF,GAAM,KAAK,KAAM;AAGzC,QAAII,IAAI;AACR,UAAMC,IAAQP,EAAO,iBAAkB,KAAK,KAAM;AAClD,WAAQ,CAACK,KAAUE,KAASD,IAAIC,EAAM;AACrC,MAAAF,IAASE,EAAOD,GAAI,IAAKJ,GAAM,KAAK,KAAM;AAG3C,WAAOG,KAAUH;AAAA,EAClB;AAAA,EAEA,OAAO,OAAQD,GAAuB;AACrC,SAAK,oBAAoB;AAAA,MACxB,GAAG,KAAK;AAAA,MACR,GAAGA;AAAA,IAAA,GAEJ,KAAK,YAAY;AAAA,EAClB;AAAA,EAEA,MAAM,IAAKO,GAAmC;AAC7C,WAAM,KAAK,WACV,KAAK,SAAS,MAAM,KAAK;AAAA,MACxB,YAAU;AACT,YAAI;AACH,kBAAS,MAAM,MAAO,KAAK,kBAAA,CAAoB,GAAI,KAAA;AAAA,QACpD,QACgB;AACf,kBAAS,MAAM,MAAO,KAAK,kBAAkB,IAAI,CAAE,GAAI,KAAA;AAAA,QACxD;AAAA,MACD;AAAA,IAAA,IAGK,KAAK,OAASA,CAAU;AAAA,EAChC;AAAA,EAEQ,WAAiBC,GAA8C;AACtE,WAAM,KAAK,oBACV,KAAK,kBAAkB,IAAI,QAAc,OAAWC,EAASD,EAAA,CAAgB,CAAE,IAEzE,KAAK;AAAA,EACb;AAAA,EAEQ,kBAAmBE,GAAkB;AAC5C,WAAK,KAAK,MAAM,QAAQ,MAAM,IAAI,IAC1B,GAAI,KAAK,WAAY,IAAKA,KAAU,KAAK,KAAM,UAGhD,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,kBAAmBC,GAAYD,GAAiB;AAEtD,IADMX,EAAO,iBAAkBW,CAAO,MAAIX,EAAO,iBAAkBW,CAAO,IAAI,CAAA,IACzE,EAAAX,EAAO,iBAAkBW,CAAO,EAAG,QAASC,CAAK,KAAK,MAC3DZ,EAAO,iBAAkBW,CAAO,EAAG,QAASC,CAAK;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAASA,GAAYD,GAAiB;AAC5C,WAAOX,EAAO,kBAAmBY,GAAMD,CAAO;AAAA,EAC/C;AAmCD;AAjCCX,EAAe,eAAe;AAAA,EAC7B,IAAI;AAAA,IACH,CAAEE,MACIA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QAEpDA,IAAO;AAAA,EACf;AAAA,EAED,IAAI;AAAA,IACH,CAAEA,MACIA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QACtDA,EAAK,MAAM,EAAE,MAAM,MAAaA,EAAK,MAAO,GAAG,EAAG,IAAI,QAEpDA,IAAO;AAAA,EACf;AACD,GAGDF,EAAe,YAAgC,QAC/CA,EAAe,oBAAkC,CAAA,GACjDA,EAAe,mBAAkDA,EAAO;AAxIlE,IAAMa,IAANb;ACqBA,SAASc,EAAwBH,GAAmCI,IAAqB,IAAuC;AACtI,SAAO,CAAEC,GAAiBC,IAAkBF,MAAwB;AACnE,QAAK,CAACJ,EAAS,QAAOK;AACtB,UAAME,IAAQF,EAAQ,MAAM,GAAG,EAAE,OAAO,CAAEG,GAASC,MAAkBD,EAAKC,CAAK,GAAGT,CAAO;AACzF,QAAKO,MAAU,UAAaD,SAAwB,MAAO,mBAAoBD,CAAQ,YAAa;AACpG,WAAOE,KAASF;AAAA,EACjB;AACD;AAeO,SAASK,EAAcV,GAAmCK,GAAiBD,IAAqB,IAAgB;AACtH,SAAOD,EAAwBH,GAAQI,CAAmB,EAAGC,CAAQ;AACtE;AAeO,MAAeM,UAA0EC,EAAgB;AAAA,EAC/G,YAAaC,GAAW;AACvB,UAAOA,CAAM,GAEb,KAAK,QAAQ,EAAE,QAAQ,GAAC,GAExB,QAAQ,IAAI;AAAA,MACXX,EAAO,SAAS,IAAK,SAAU;AAAA,MAC/BA,EAAO,SAAS,IAAK,KAAK,WAAY;AAAA,IAAA,CACtC,EAAE,KAAM,CAAAY,MAAQ;AAChB,YAAMd,IAAS,EAAE,GAAGc,EAAK,CAAC,GAAG,GAAGA,EAAK,CAAC,EAAA;AAEtC,WAAK,SAAS,EAAE,QAAAd,GAAS,GACzB,KAAK,aAAcA,CAAO;AAAA,IAC3B,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,aAAcA,GAAwB;AAAA,EAAC;AACxC;AAcO,SAASe,EAAUC,GAAoB;AAC7C,SAAO,SAAiDC,GAAgB;AACvE,WAAO,cAAcA,EAAY;AAAA,MAA1B,cAAA;AAAA,cAAA,GAAA,SAAA,GACL,KAAA,QAAQ,EAAE,QAAQ,CAAA,GAAI,GAAG,KAAK,MAAO,GACrC,KAAA,aAAa,QAAQ,IAAI;AAAA,UACxBf,EAAO,SAAS,IAAKc,CAAU;AAAA,UAC/Bd,EAAO,SAAS,IAAK,SAAU;AAAA,QAAA,CAC/B,EAAE,KAAM,CAAAY,MAAQ;AAChB,gBAAMd,IAAS,EAAE,GAAGc,EAAK,CAAC,GAAG,GAAGA,EAAK,CAAC,EAAA;AACtC,eAAK,SAAY,EAAE,QAAAd,GAAQ,GAC3B,KAAK,gBAAmB,KAAK,aAAiBA,CAAO;AAAA,QACtD,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ;AACD;AASO,SAASkB,EAAWC,GAAwB;AAClD,QAAM,CAAEnB,GAAQoB,CAAU,IAAIC,EAAS,CAAA,CAAmB;AAE1D,SAAAC,EAAW,MAAM;AAEhB,YAAQ,IAAI;AAAA,MACXpB,EAAO,SAAS,IAAKiB,CAAc;AAAA,MACnCjB,EAAO,SAAS,IAAK,SAAU;AAAA,IAAA,CAC/B,EAAE,KAAM,CAAAY,MAAQM,EAAU,EAAE,GAAGN,EAAK,CAAC,GAAG,GAAGA,EAAK,CAAC,EAAA,CAAG,CAAC;AAAA,EAEvD,GAAG,CAAA,CAAE,GAEEd;AACR;"}
|
|
1
|
+
{"version":3,"file":"entropic-bond-localize-react.js","names":[],"sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["import { LocaleEntries } from './localized-component'\n\ninterface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise<LocaleEntries | undefined> {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ] as LocaleEntries | undefined\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: LocaleEntries | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string ]: string | LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !keyPath ) return 'Locale key not found!'\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce< unknown >( ( acc, prop ) => {\n\t\t\tif ( !acc || typeof acc !== 'object' ) return undefined\n\t\t\treturn ( acc as Record<string, unknown> )[ prop ]\n\t\t}, locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn typeof value === 'string' ? value : keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): Record<string, any> }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\tdeclare state: Record<string, any>\n\t\t\tloadLocale = Promise.all([\n\t\t\t\tLocale.instance.get( className ),\n\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t]).then( resp => {\n\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\tthis.setState({ locale })\n\t\t\t\tthis.onLoadLocale?.( locale )\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"mappings":";;AASA,IAAa,IAAb,MAAa,EAAO;CACnB,YAAqB,GAAuB;EAI3C,uBAsIuD,KAAA,iBACZ,KAAA,GA1I3C,KAAK,SAAS,KAAA,GACd,KAAK,kBAAkB,KAAA,GACvB,KAAK,QAAQ,EAAO,UAAU,MAC9B,KAAK,cAAc,EAAO,cAAc;CACzC;CAEA,WAAkB,WAAmB;EAIpC,OAHA,AACC,KAAK,cAAY,IAAI,EAAQ,KAAK,iBAAkB,GAE9C,KAAK;CACb;CAEA,WAAW,gBAAgB;EAC1B,OAAO,EAAO,kBAAkB,UAAU,EAAO,SAAS;CAC3D;CAUA,UAAW,GAAc,IAAiB,GAAG,GAA6C;EACzF,IAAK,MAAW,GAAI,OAAO;EAE3B,IAAI;EAEJ,IAAK,OAAO,KAAe,YAE1B;OADA,IAAS,IAAc,IAClB,GAAS,OAAO;EAAA,OAGrB,IAAS,IAAc,GAAM,KAAK,KAAM;EAGzC,IAAI,IAAI,GACF,IAAQ,EAAO,iBAAkB,KAAK;EAC5C,OAAQ,CAAC,KAAU,KAAS,IAAI,EAAM,SACrC,IAAS,EAAO,IAAK,GAAI,GAAM,KAAK,KAAM;EAG3C,OAAO,KAAU;CAClB;CAEA,OAAO,OAAQ,GAAuB;EAKrC,AAJA,KAAK,oBAAoB;GACxB,GAAG,KAAK;GACR,GAAG;EACJ,GACA,KAAK,YAAY,KAAA;CAClB;CAEA,MAAM,IAAK,GAAwD;EAalE,OAZA,AACC,KAAK,WAAS,MAAM,KAAK,WACxB,YAAU;GACT,IAAI;IACH,QAAS,MAAM,MAAO,KAAK,kBAAkB,CAAE,EAAA,CAAI,KAAK;GACzD,QACgB;IACf,QAAS,MAAM,MAAO,KAAK,kBAAkB,IAAI,CAAE,EAAA,CAAI,KAAK;GAC7D;EACD,CACD,GAEM,KAAK,OAAS;CACtB;CAEA,WAAyB,GAA8C;EAItE,OAHA,AACC,KAAK,oBAAkB,IAAI,SAAc,MAAW,EAAS,EAAc,CAAE,CAAE,GAEzE,KAAK;CACb;CAEA,kBAA2B,GAAkB;EAK5C,OAJK,KAAK,MAAM,QAAQ,MAAM,IAAI,IAC1B,GAAI,KAAK,YAAa,GAAI,KAAU,KAAK,MAAO,SAGjD,KAAK;CACb;CAQA,OAAO,kBAAmB,GAAY,GAAiB;EACtD,AAAM,EAAO,iBAAkB,OAAW,EAAO,iBAAkB,KAAW,CAAC,IAC1E,IAAO,iBAAkB,EAAQ,CAAE,QAAS,CAAK,KAAK,MAC3D,EAAO,iBAAkB,EAAQ,CAAE,QAAS,CAAK;CAClD;CAMA,OAAO,QAAS,GAAY,GAAiB;EAC5C,OAAO,EAAO,kBAAmB,GAAM,CAAO;CAC/C;;sBAE8B;GAC7B,IAAI,EACD,MACI,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QAEpD,IAAO,GAEhB;GACA,IAAI,EACD,MACI,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QACtD,EAAK,MAAM,EAAE,MAAM,MAAa,EAAK,MAAO,GAAG,EAAG,IAAI,QAEpD,IAAO,GAEhB;EACD;;;mBAE+C,KAAA;;;2BACE,CAAC;;;0BACe,EAAO;;AAKzE;;;AC1HA,SAAgB,EAAwB,GAAmC,IAAqB,IAAuC;CACtI,QAAS,GAAiB,IAAkB,MAAwB;EACnE,IAAK,CAAC,GAAU,OAAO;EACvB,IAAK,CAAC,GAAS,OAAO;EACtB,IAAM,IAAQ,EAAQ,MAAM,GAAG,CAAC,CAAC,QAAqB,GAAK,MAAU;GAC/D,OAAC,KAAO,OAAO,KAAQ,WAC5B,OAAS,EAAkC;EAC5C,GAAG,CAAO;EACV,IAAK,MAAU,KAAA,KAAa,GAAkB,MAAM,MAAO,mBAAoB,EAAS,WAAY;EACpG,OAAO,OAAO,KAAU,WAAW,IAAQ;CAC5C;AACD;AAeA,SAAgB,EAAc,GAAmC,GAAiB,IAAqB,IAAgB;CACtH,OAAO,EAAwB,GAAQ,CAAmB,CAAC,CAAE,CAAQ;AACtE;AAeA,IAAsB,IAAtB,cAAgG,EAAgB;CAC/G,YAAa,GAAW;EAKvB,AAJA,MAAO,CAAM,GAEb,KAAK,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAE1B,QAAQ,IAAI,CACX,EAAO,SAAS,IAAK,SAAU,GAC/B,EAAO,SAAS,IAAK,KAAK,UAAU,CAAE,CACvC,CAAC,CAAC,CAAC,MAAM,MAAQ;GAChB,IAAM,IAAS;IAAE,GAAG,EAAK;IAAI,GAAG,EAAK;GAAG;GAGxC,AADA,KAAK,SAAS,EAAE,UAAQ,CAAC,GACzB,KAAK,aAAc,CAAO;EAC3B,CAAC;CACF;CAYA,aAAc,GAAwB,CAAC;AACxC;AAcA,SAAgB,EAAU,GAAoB;CAC7C,OAAO,SAAkE,GAAgB;EACxF,OAAO,cAAc,EAAY;;mCAEnB,QAAQ,IAAI,CACxB,EAAO,SAAS,IAAK,CAAU,GAC/B,EAAO,SAAS,IAAK,SAAU,CAChC,CAAC,CAAC,CAAC,MAAM,MAAQ;KAChB,IAAM,IAAS;MAAE,GAAG,EAAK;MAAI,GAAG,EAAK;KAAG;KAExC,AADA,KAAK,SAAS,EAAE,UAAO,CAAC,GACxB,KAAK,eAAgB,CAAO;IAC7B,CAAC;;EACF;CACD;AACD;AASA,SAAgB,EAAW,GAAwB;CAClD,IAAM,CAAE,GAAQ,KAAc,EAAS,CAAC,CAAkB;CAW1D,OATA,QAAiB;EAEhB,QAAQ,IAAI,CACX,EAAO,SAAS,IAAK,CAAc,GACnC,EAAO,SAAS,IAAK,SAAU,CAChC,CAAC,CAAC,CAAC,MAAM,MAAQ,EAAU;GAAE,GAAG,EAAK;GAAI,GAAG,EAAK;EAAG,CAAC,CAAC;CAEvD,GAAG,CAAC,CAAC,GAEE;AACR"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
//# sourceMappingURL=entropic-bond-localize-react.umd.cjs.map
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react")):typeof define==`function`&&define.amd?define([`exports`,`react`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e[`entropic-bond-localize-react`]={},e.React))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class e{constructor(e){this._pendingPromise=void 0,this._table=void 0,this._table=void 0,this._pendingPromise=void 0,this._lang=e.locale||`en`,this._localePath=e.localePath||``}static get instance(){return this._instance||=new e(this._registeredConfig),this._instance}static get currentLocale(){return e._registeredConfig.locale||e.instance._lang}pluralize(t,n=0,r){if(n===1)return t;let i;if(typeof r!=`function`){if(i=r?.[t],i)return i}else i=r?.(t,this._lang);let a=0,o=e._registeredRules[this._lang];for(;!i&&o&&a<o.length;)i=o[a++]?.(t,this._lang);return i??t}static config(e){this._registeredConfig={...this._registeredConfig,...e},this._instance=void 0}async get(e){return this._table||=await this.fetchCache(async()=>{try{return(await fetch(this.getLocaleFilePath())).json()}catch{return(await fetch(this.getLocaleFilePath(`en`))).json()}}),this._table[e]}fetchCache(e){return this._pendingPromise||=new Promise(t=>t(e())),this._pendingPromise}getLocaleFilePath(e){return this._lang.indexOf(`http`)<0?`${this._localePath}/${e||this._lang}.json`:this._lang}static usePluralizerRule(t,n){e._registeredRules[n]||(e._registeredRules[n]=[]),!(e._registeredRules[n].indexOf(t)>=0)&&e._registeredRules[n].unshift(t)}static useRule(t,n){return e.usePluralizerRule(t,n)}static{this.defaultRules={en:[e=>e.slice(-1)===`f`?e.slice(0,-1)+`ves`:e.slice(-1)===`o`?e.slice(0,-1)+`oes`:e.slice(-1)===`x`?e.slice(0,-1)+`xes`:e.slice(-1)===`h`?e.slice(0,-1)+`hes`:e.slice(-1)===`s`?e.slice(0,-1)+`ses`:e.slice(-1)===`y`?e.slice(0,-1)+`ies`:e.slice(-1)===`z`?e.slice(0,-1)+`zes`:e+`s`],es:[e=>e.slice(-1)===`l`?e.slice(0,-1)+`les`:e.slice(-1)===`n`?e.slice(0,-1)+`nes`:e.slice(-1)===`r`?e.slice(0,-1)+`res`:e.slice(-1)===`z`?e.slice(0,-1)+`ces`:e+`s`]}}static{this._instance=void 0}static{this._registeredConfig={}}static{this._registeredRules=e.defaultRules}};function r(e,t=!1){return(n,r=t)=>{if(!n)return`Locale key not found!`;if(!e)return n;let i=n.split(`.`).reduce((e,t)=>{if(!(!e||typeof e!=`object`))return e[t]},e);if(i===void 0&&r)throw Error(`Translation for ${n} not found`);return typeof i==`string`?i:n}}function i(e,t,n=!1){return r(e,n)(t)}var a=class extends t.Component{constructor(e){super(e),this.state={locale:{}},Promise.all([n.instance.get(`Generic`),n.instance.get(this.className())]).then(e=>{let t={...e[0],...e[1]};this.setState({locale:t}),this.onLoadLocale(t)})}onLoadLocale(e){}};function o(e){return function(t){return class extends t{constructor(...t){super(...t),this.loadLocale=Promise.all([n.instance.get(e),n.instance.get(`Generic`)]).then(e=>{let t={...e[0],...e[1]};this.setState({locale:t}),this.onLoadLocale?.(t)})}}}}function s(e){let[r,i]=(0,t.useState)({});return(0,t.useEffect)(()=>{Promise.all([n.instance.get(e),n.instance.get(`Generic`)]).then(e=>i({...e[0],...e[1]}))},[]),r}e.Locale=n,e.LocalizedComponent=a,e.createSafeLocalizerFor=r,e.localize=o,e.safeLocalize=i,e.useLocale=s});
|
|
2
|
+
//# sourceMappingURL=entropic-bond-localize-react.umd.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entropic-bond-localize-react.umd.cjs","sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["interface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise< {} > {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ]\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: {} | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string | symbol ]: string & LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce(( acc: {}, prop: string ) => acc[ prop ], locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn value || keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): {} }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\t\tstate = { locale: {}, ...this['state'] }\n\t\t\t\tloadLocale = Promise.all([\n\t\t\t\t\tLocale.instance.get( className ),\n\t\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t\t]).then( resp => {\n\t\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\t\tthis['setState']({ locale })\n\t\t\t\t\tthis['onLoadLocale'] && this['onLoadLocale']( locale )\n\t\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"names":["_Locale","config","word","amount","pluralizer","plural","i","rules","component","cachedPromise","resolve","locale","rule","Locale","createSafeLocalizerFor","throwOnKeyNotFound","keyPath","throwOnNotFound","value","acc","prop","safeLocalize","LocalizedComponent","Component","props","resp","localize","className","constructor","useLocale","componentName","setLocale","useState","useEffect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"entropic-bond-localize-react.umd.cjs","names":[],"sources":["../src/locale.ts","../src/localized-component.tsx"],"sourcesContent":["import { LocaleEntries } from './localized-component'\n\ninterface LocaleConfig {\n\tlocale?: string\n\tlocalePath?: string\n}\n\ntype Rule = ( word: string, locale: string ) => string | undefined\n\nexport class Locale {\n\tprivate constructor( config: LocaleConfig ) {\n\t\tthis._table = undefined\n\t\tthis._pendingPromise = undefined\n\t\tthis._lang = config.locale || 'en'\n\t\tthis._localePath = config.localePath || ''\n\t}\n\n\tpublic static get instance(): Locale {\n\t\tif ( !this._instance ) {\n\t\t\tthis._instance = new Locale( this._registeredConfig )\n\t\t}\n\t\treturn this._instance\n\t}\n\n\tstatic get currentLocale() {\n\t\treturn Locale._registeredConfig.locale || Locale.instance._lang\n\t}\n\n\t/**\n\t * Returns the plural form of a word\n\t * \n\t * @param word to pluralize\n\t * @param amount if the word to pluralize is a number, the amount is used to determine the plural form\n\t * @param pluralizer a map of words to their plural form or a function that returns the plural form\n\t * @returns the plural form of the word\n\t */\n\tpluralize( word: string, amount: number = 0, pluralizer?: Record<string, string> | Rule ) {\n\t\tif ( amount === 1 ) return word\n\n\t\tlet plural: string | undefined\n\n\t\tif ( typeof pluralizer !== 'function' ) {\n\t\t\tplural = pluralizer?.[ word ]\n\t\t\tif ( plural ) return plural\n\t\t}\n\t\telse {\n\t\t\tplural = pluralizer?.( word, this._lang )\n\t\t}\n\n\t\tlet i = 0\n\t\tconst rules = Locale._registeredRules[ this._lang ]\n\t\twhile ( !plural && rules && i < rules.length ) {\n\t\t\tplural = rules[ i++ ]?.( word, this._lang )\n\t\t}\n\n\t\treturn plural ?? word\n\t}\n\n\tstatic config( config: LocaleConfig ) {\n\t\tthis._registeredConfig = {\n\t\t\t...this._registeredConfig,\n\t\t\t...config\n\t\t}\n\t\tthis._instance = undefined\n\t}\n\n\tasync get( component: string ): Promise<LocaleEntries | undefined> {\n\t\tif ( !this._table ) {\n\t\t\tthis._table = await this.fetchCache(\n\t\t\t\tasync ()=>{\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath()\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( error ) {\n\t\t\t\t\t\treturn ( await fetch( this.getLocaleFilePath('en')\t) ).json()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t\treturn this._table![ component ] as LocaleEntries | undefined\n\t}\n\n\tprivate fetchCache< T >( cachedPromise: ()=>Promise< T > ): Promise<T> {\n\t\tif ( !this._pendingPromise ) {\n\t\t\tthis._pendingPromise = new Promise< T >( resolve => resolve( cachedPromise() ) )\n\t\t}\n\t\treturn this._pendingPromise as Promise<T>\n\t}\n\n\tprivate getLocaleFilePath( locale?: string ) {\n\t\tif ( this._lang.indexOf('http') < 0 ) {\n\t\t\treturn `${ this._localePath }/${ locale || this._lang }.json` \n\t\t}\n\n\t\treturn this._lang\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * \n\t * @param rule a function that returns the plural form of a word\n\t * @param locale the locale to use the rule\n\t */\n\tstatic usePluralizerRule( rule: Rule, locale: string ) {\n\t\tif ( !Locale._registeredRules[ locale ] ) Locale._registeredRules[ locale ] = []\n\t\tif ( Locale._registeredRules[ locale ]!.indexOf( rule ) >= 0 ) return\n\t\tLocale._registeredRules[ locale ]!.unshift( rule )\n\t}\n\n\t/**\n\t * Registers a rule to pluralize words\n\t * @deprecated use usePluralizerRule instead\n\t */\n\tstatic useRule( rule: Rule, locale: string ) {\n\t\treturn Locale.usePluralizerRule( rule, locale )\n\t}\n\n\tprivate static defaultRules = {\n\t\ten: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'f' ) return word.slice( 0, -1 ) + 'ves'\n\t\t\t\tif ( word.slice(-1) === 'o' ) return word.slice( 0, -1 ) + 'oes'\n\t\t\t\tif ( word.slice(-1) === 'x' ) return word.slice( 0, -1 ) + 'xes'\n\t\t\t\tif ( word.slice(-1) === 'h' ) return word.slice( 0, -1 ) + 'hes'\n\t\t\t\tif ( word.slice(-1) === 's' ) return word.slice( 0, -1 ) + 'ses'\n\t\t\t\tif ( word.slice(-1) === 'y' ) return word.slice( 0, -1 ) + 'ies'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'zes'\n\t\t\t\t\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t],\n\t\tes: [\n\t\t\t( word: string ) => {\n\t\t\t\tif ( word.slice(-1) === 'l' ) return word.slice( 0, -1 ) + 'les'\n\t\t\t\tif ( word.slice(-1) === 'n' ) return word.slice( 0, -1 ) + 'nes'\n\t\t\t\tif ( word.slice(-1) === 'r' ) return word.slice( 0, -1 ) + 'res'\n\t\t\t\tif ( word.slice(-1) === 'z' ) return word.slice( 0, -1 ) + 'ces'\n\n\t\t\t\treturn word + 's'\n\t\t\t}\n\t\t]\n\t}\n\n\tprivate static _instance: Locale | undefined = undefined\n\tprivate static _registeredConfig: LocaleConfig = {} as LocaleConfig\n\tprivate static _registeredRules: {[ locale: string ]: Rule[] } = Locale.defaultRules\n\tprivate _lang: string\n\tprivate _localePath: string\n\tprivate _pendingPromise: Promise<unknown> | undefined = undefined\n\tprivate _table: LocaleEntries | undefined = undefined\n}\n","import { Component, useEffect, useState } from 'react'\nimport { Locale } from './locale'\n\nexport interface LocaleEntries {\n\t[ key: string ]: string | LocaleEntries\n}\n\nexport interface LocalizedState {\n\tlocale: LocaleEntries\n}\n\n/**\n * Creates a safe localizer function. The function will return the translated \n * value associated to the `keyPath`. If the locale is undefined or the `keyPath` is\n * not found in the locale, the function will return the `keyPath`.\n * @param locale the locale to use\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns a function that will return the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see safeLocalize\n * @sample \n * ```ts\n * const safeLocalizer = createSafeLocalizerFor( locale ) // returns the localizer function\n * safeLocalizer( 'myComponent.myKey' ) // returns the translated value\n * ```\n * @sample const safeLocalizer = createSafeLocalizerFor( locale, true )\n * \n */\nexport function createSafeLocalizerFor( locale: LocaleEntries | undefined, throwOnKeyNotFound = false ): ( keyPath: string ) => string {\n\treturn ( keyPath: string, throwOnNotFound = throwOnKeyNotFound ) => {\n\t\tif ( !keyPath ) return 'Locale key not found!'\n\t\tif ( !locale ) return keyPath\n\t\tconst value = keyPath.split('.').reduce< unknown >( ( acc, prop ) => {\n\t\t\tif ( !acc || typeof acc !== 'object' ) return undefined\n\t\t\treturn ( acc as Record<string, unknown> )[ prop ]\n\t\t}, locale )\n\t\tif ( value === undefined && throwOnNotFound ) throw Error( `Translation for ${ keyPath } not found` )\n\t\treturn typeof value === 'string' ? value : keyPath\n\t}\n}\n\n/**\n * Returns the translated value associated to the keyPath. If the locale is\n * undefined or the keyPath is not found in the locale, the function will return\n * the keyPath.\n * @param locale the locale to use\n * @param keyPath the key path to the value to return\n * @param throwOnKeyNotFound if true, the function will throw an error if the keyPath is not found in the locale\n * @returns the translated value associated to the keyPath\n * @throws Error if the keyPath is not found in the locale and throwOnKeyNotFound is true\n * @see createSafeLocalizerFor\n * @sample safeLocalize( locale, 'myComponent.myKey' )\n * @sample safeLocalize( locale, 'myRootKey', true )\n */\nexport function safeLocalize( locale: LocaleEntries | undefined, keyPath: string, throwOnKeyNotFound = false ): string {\n\treturn createSafeLocalizerFor( locale, throwOnKeyNotFound )( keyPath )\n}\n\nexport type StateWithLocale<S> = S & LocalizedState\n\n/**\n * Derive React components from this class to provide locale capabilities.\n * \n * The locale is a javascript object. The main entries (properties) of object\n * are the names of the components. Every component has its own entry and every\n * subentry is a key-value pair where key is the reference used in the code and\n * the value is the translation to the corresponding idiom.\n * \n * You can use this method or @see localize method to provide localization to your \n * component.\n */\nexport abstract class LocalizedComponent<P={}, S extends LocalizedState=LocalizedState> extends Component<P, S> {\t\n\tconstructor( props: P ) {\n\t\tsuper( props )\n\n\t\tthis.state = { locale: {} } as S\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( 'Generic' ),\n\t\t\tLocale.instance.get( this.className() )\n\t\t]).then( resp => {\n\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\n\t\t\tthis.setState({ locale })\n\t\t\tthis.onLoadLocale( locale )\n\t\t})\n\t}\n\n\t/**\n\t * Derived classes should implement the className method to return a string \n\t * with the class name.\n \t */\n\tabstract className(): string\n\n\t/**\n\t * Override this method to get a notification when the locale has been loaded\n\t * @param locale the loaded locale\n\t */\n\tonLoadLocale( locale: LocaleEntries ) {}\n}\n\n/**\n * Decorator to inject locale capabilities. The decorator will set the component\n * related locale strings in the locale property created on the component state. \n * To have access to the locale state property, you should pass a state interface\n * derived from LocaleState. @see LocalizedComponent\n * \n * You can use this method or @see LocalizedComponent method to provide \n * localization to your component.\n * \n * @param className the class name to retrieve the locale strings for this class.\n * @returns decorator\n */\nexport function localize( className: string ) {\n\treturn function<T extends { new (...args: any[]): Record<string, any> }>(constructor: T) {\n\t\treturn class extends constructor {\n\t\t\tdeclare state: Record<string, any>\n\t\t\tloadLocale = Promise.all([\n\t\t\t\tLocale.instance.get( className ),\n\t\t\t\tLocale.instance.get( 'Generic' )\n\t\t\t]).then( resp => {\n\t\t\t\tconst locale = { ...resp[0], ...resp[1] }\n\t\t\t\tthis.setState({ locale })\n\t\t\t\tthis.onLoadLocale?.( locale )\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Hook to add locale capabilities to React functional components. The hook will \n * return an object with the component related locale strings. \n * \n * @param componentName the component name associated to the locale strings.\n * @returns an object with the localized strings\n */\nexport function useLocale( componentName: string ) {\n\tconst [ locale, setLocale ] = useState({} as LocaleEntries)\n\n\tuseEffect( () => {\n\n\t\tPromise.all([\n\t\t\tLocale.instance.get( componentName ),\n\t\t\tLocale.instance.get( 'Generic' )\n\t\t]).then( resp => setLocale({ ...resp[0], ...resp[1] }))\n\n\t}, [])\n\n\treturn locale\n}\n"],"mappings":"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"}
|
package/lib/locale.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LocaleEntries } from './localized-component';
|
|
1
2
|
interface LocaleConfig {
|
|
2
3
|
locale?: string;
|
|
3
4
|
localePath?: string;
|
|
@@ -17,7 +18,7 @@ export declare class Locale {
|
|
|
17
18
|
*/
|
|
18
19
|
pluralize(word: string, amount?: number, pluralizer?: Record<string, string> | Rule): string;
|
|
19
20
|
static config(config: LocaleConfig): void;
|
|
20
|
-
get(component: string): Promise<
|
|
21
|
+
get(component: string): Promise<LocaleEntries | undefined>;
|
|
21
22
|
private fetchCache;
|
|
22
23
|
private getLocaleFilePath;
|
|
23
24
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
2
|
export interface LocaleEntries {
|
|
3
|
-
[key: string
|
|
3
|
+
[key: string]: string | LocaleEntries;
|
|
4
4
|
}
|
|
5
5
|
export interface LocalizedState {
|
|
6
6
|
locale: LocaleEntries;
|
|
@@ -75,10 +75,11 @@ export declare abstract class LocalizedComponent<P = {}, S extends LocalizedStat
|
|
|
75
75
|
* @returns decorator
|
|
76
76
|
*/
|
|
77
77
|
export declare function localize(className: string): <T extends {
|
|
78
|
-
new (...args: any[]):
|
|
78
|
+
new (...args: any[]): Record<string, any>;
|
|
79
79
|
}>(constructor: T) => {
|
|
80
80
|
new (...args: any[]): {
|
|
81
|
-
|
|
81
|
+
[x: string]: any;
|
|
82
|
+
state: Record<string, any>;
|
|
82
83
|
loadLocale: Promise<void>;
|
|
83
84
|
};
|
|
84
85
|
} & T;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entropic-bond/localize-react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.7.
|
|
4
|
+
"version": "1.7.8",
|
|
5
5
|
"description": "Localize react components",
|
|
6
6
|
"main": "lib/entropic-bond-localize-react.umd.cjs",
|
|
7
7
|
"module": "lib/entropic-bond-localize-react.js",
|
|
@@ -57,19 +57,20 @@
|
|
|
57
57
|
"@testing-library/jest-dom": "^6.9.1",
|
|
58
58
|
"@testing-library/react": "^16.3.2",
|
|
59
59
|
"@testing-library/user-event": "^14.6.1",
|
|
60
|
-
"@types/node": "^
|
|
61
|
-
"@types/react": "^19.2.
|
|
60
|
+
"@types/node": "^26.0.1",
|
|
61
|
+
"@types/react": "^19.2.17",
|
|
62
62
|
"@types/react-dom": "^19.2.3",
|
|
63
|
-
"fetch-mock": "^
|
|
64
|
-
"git-branch-is": "^
|
|
65
|
-
"happy-dom": "^20.
|
|
63
|
+
"fetch-mock": "^12.6.0",
|
|
64
|
+
"git-branch-is": "^5.0.0",
|
|
65
|
+
"happy-dom": "^20.10.6",
|
|
66
66
|
"husky": "^9.1.7",
|
|
67
|
-
"react": "^19.2.
|
|
68
|
-
"react-dom": "^19.2.
|
|
69
|
-
"semantic-release": "^25.0.
|
|
70
|
-
"typescript": "^
|
|
71
|
-
"vite
|
|
72
|
-
"
|
|
67
|
+
"react": "^19.2.7",
|
|
68
|
+
"react-dom": "^19.2.7",
|
|
69
|
+
"semantic-release": "^25.0.5",
|
|
70
|
+
"typescript": "^6.0.3",
|
|
71
|
+
"vite": "^8.1.2",
|
|
72
|
+
"vite-plugin-dts": "^5.0.3",
|
|
73
|
+
"vitest": "^4.1.9"
|
|
73
74
|
},
|
|
74
75
|
"husky": {
|
|
75
76
|
"hooks": {
|