i18n-keyless-core 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export type { I18nConfig, Lang, PrimaryLang, Translations, TranslationStore, I18nKeylessRequestBody, I18nKeylessResponse, } from "./types";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,183 @@
1
+ import React from "react";
2
+ export type PrimaryLang = "fr" | "en";
3
+ export type Lang = "fr" | "en" | "nl" | "it" | "de" | "es" | "pl" | "pt" | "ro" | "sv" | "tr" | "ja" | "cn" | "ru" | "ko" | "ar";
4
+ export type Translations = Record<string, string>;
5
+ type GetStorageFunction = (key: string) => string | null | undefined | Promise<string | null | undefined>;
6
+ type SetStorageFunction = (key: string, value: string) => void | Promise<void>;
7
+ type RemoveStorageFunction = (key: string) => void | Promise<void>;
8
+ type ClearStorageFunction = () => void | Promise<void>;
9
+ export interface I18nConfig {
10
+ /**
11
+ * The API key for the i18n-keyless API
12
+ *
13
+ * contact @ambroselli_io on X/Twitter or by mail at arnaud.ambroselli.io@gmail.com for getting one
14
+ */
15
+ API_KEY: string;
16
+ /**
17
+ * Your own API URL for the i18n-keyless API
18
+ *
19
+ * You'll need to implement two routes on your server
20
+ * - GET /translate/:lang
21
+ * - POST /translate -- with a body of { key: string }
22
+ */
23
+ API_URL?: string;
24
+ /**
25
+ * the component should be a React component, such as
26
+ *
27
+ * ```ts
28
+ * export default function MyComponent({ style, className, whatever, children}) {
29
+ * return <Text style={style} className={className} whatever={whatever}>{children}</Text>;
30
+ * }
31
+ * ```
32
+ *
33
+ * Then you can pass MyComponent's props to i18n-keyless' MyI18nText
34
+ *
35
+ * ```ts
36
+ * <MyI18nText style={style} className={className} whatever={whatever}>My text to translate</MyI18nText>
37
+ * ```
38
+ */
39
+ component: React.ComponentType<{
40
+ children: string;
41
+ } & Record<string, unknown>>;
42
+ /**
43
+ * The languages config
44
+ *
45
+ * primary: the language used by the developer
46
+ * supported: the languages supported for the user
47
+ * fallback: if the user's langauge is not supported, the fallback language will be used
48
+ * initWithDefault: the language to use when the app is initialized for the first time
49
+ */
50
+ languages: {
51
+ /**
52
+ * the language used by the developer
53
+ */
54
+ primary: PrimaryLang;
55
+ /**
56
+ * the languages supported for the user.
57
+ * For now we support:
58
+ * fr, nl, it, de, es, pl, pt, ro, sv, tr, ja, cn, ru, ko, ar
59
+ *
60
+ * If you need more, please reach out to @ambroselli_io on X/Twitter or by mail at arnaud.ambroselli.io@gmail.com
61
+ */
62
+ supported: Lang[];
63
+ /**
64
+ * if the user's langauge is not supported, the fallback language will be used
65
+ */
66
+ fallback?: Lang;
67
+ /**
68
+ * the language to use when the app is initialized
69
+ */
70
+ initWithDefault?: Lang;
71
+ };
72
+ /**
73
+ * if true, everytime a primary key is not found
74
+ * there will be a call to POST /translate -- with a body of { key: string }
75
+ * which should handle adding the key to the translations and, if needed,
76
+ * translate the key to all the languages supported by the user
77
+ *
78
+ * Two scenarios
79
+ * 1. Enable it in dev mode only: you'll may add some useless key, but you are 100% sure all the translations are up to date
80
+ * 2. Enable it in prod mode only: you take a risk taht the translations is not available when required for the first user demanding
81
+ * Best take: enable it all the time
82
+ */
83
+ addMissingTranslations: boolean;
84
+ /**
85
+ * called right after the store is initialized, maybe to hide screensplash. or init specific default langauge for dayjs, or whatever
86
+ */
87
+ onInit?: (lang: Lang) => void;
88
+ /**
89
+ * called everytime the language is set, maybe to set also the locale to dayjs or whatever
90
+ */
91
+ onSetLanguage?: (lang: Lang) => void;
92
+ /**
93
+ * if this function exists, it will be called instead of the API call
94
+ * if this function doesn't exist, the default behavior is to call the API
95
+ * therefore you would need either to
96
+ * - use this `handleTranslate` function to handle the translation with your own API
97
+ * - not use this `handleTranslate` function, and use the built in API call with API_KEY filled
98
+ * - not use this `handleTranslate` function nor API_KEY key, and provide your own API_URL
99
+ */
100
+ handleTranslate?: (key: string) => Promise<{
101
+ ok: boolean;
102
+ message: string;
103
+ }>;
104
+ /**
105
+ * if this function exists, it will be called instead of the API call
106
+ * if this function doesn't exist, the default behavior is to call the API, with the API_KEY
107
+ * therefore you need either to
108
+ * - use this `getAllTranslations` function to handle the translation with your own API
109
+ * - not use this `getAllTranslations` function, and use the built in API call with the API_KEY filled
110
+ * - not use this `getAllTranslations` function nor API_KEY key, and provide your own API_URL
111
+ */
112
+ getAllTranslations?: () => Promise<I18nKeylessResponse>;
113
+ /**
114
+ * the storage to use for the translations
115
+ *
116
+ * you can use react-native-mmkv, @react-native-async-storage/async-storage, or window.localStorage, or idb-keyval for IndexedDB, or any storage that has a getItem, setItem, removeItem, or get, set, and remove method
117
+ */
118
+ storage: {
119
+ getItem?: GetStorageFunction;
120
+ get?: GetStorageFunction;
121
+ getString?: GetStorageFunction;
122
+ setItem?: SetStorageFunction;
123
+ set?: SetStorageFunction;
124
+ removeItem?: RemoveStorageFunction;
125
+ remove?: RemoveStorageFunction;
126
+ delete?: RemoveStorageFunction;
127
+ del?: RemoveStorageFunction;
128
+ clear?: ClearStorageFunction;
129
+ clearAll?: ClearStorageFunction;
130
+ } & {
131
+ getString?: GetStorageFunction;
132
+ get?: GetStorageFunction;
133
+ getItem?: GetStorageFunction;
134
+ } & {
135
+ setItem?: SetStorageFunction;
136
+ set?: SetStorageFunction;
137
+ } & {
138
+ removeItem?: RemoveStorageFunction;
139
+ remove?: RemoveStorageFunction;
140
+ delete?: RemoveStorageFunction;
141
+ del?: RemoveStorageFunction;
142
+ } & ({
143
+ clear: ClearStorageFunction;
144
+ clearAll?: never;
145
+ } | {
146
+ clearAll: ClearStorageFunction;
147
+ clear?: never;
148
+ });
149
+ }
150
+ interface TranslationStoreState {
151
+ uniqueId: string | null;
152
+ lastRefresh: string | null;
153
+ translations: Translations;
154
+ currentLanguage: Lang;
155
+ config: I18nConfig | null;
156
+ translating: Record<string, boolean>;
157
+ _hasHydrated: boolean;
158
+ storage: I18nConfig["storage"] | null;
159
+ }
160
+ interface TranslationStoreActions {
161
+ _hydrate: () => Promise<void>;
162
+ getTranslation: (text: string) => string | undefined;
163
+ setTranslations: (translations: Translations) => void;
164
+ translateKey: (key: string) => void;
165
+ setLanguage: (lang: Lang) => void;
166
+ }
167
+ export type TranslationStore = TranslationStoreState & TranslationStoreActions;
168
+ export interface I18nKeylessRequestBody {
169
+ key: string;
170
+ languages: I18nConfig["languages"]["supported"];
171
+ primaryLanguage: I18nConfig["languages"]["primary"];
172
+ }
173
+ export interface I18nKeylessResponse {
174
+ ok: boolean;
175
+ data: {
176
+ translations: Translations;
177
+ uniqueId: string | null;
178
+ lastRefresh: string | null;
179
+ };
180
+ error: string;
181
+ message: string;
182
+ }
183
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "i18n-keyless-core",
3
3
  "private": false,
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -10,7 +10,7 @@
10
10
  "dist"
11
11
  ],
12
12
  "scripts": {
13
- "build:lib": "tsc --project ../../tsconfig.json && npm pack",
13
+ "build:lib": "tsc --project tsconfig.json && npm pack",
14
14
  "prepublishOnly": "npm run build:lib"
15
15
  },
16
16
  "devDependencies": {