@nimpl/i18n 1.2.0 → 2.0.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const I18nContext_1 = require("./lib/I18nContext");
8
8
  const I18nTransmitter_1 = __importDefault(require("./I18nTransmitter"));
9
- const getDictionary_1 = __importDefault(require("./lib/getDictionary"));
10
- const I18nProvider = async ({ children, lang, clientTerms = [] }) => {
11
- const dictionary = await (0, getDictionary_1.default)(lang);
12
- return (react_1.default.createElement(I18nContext_1.I18nContext.Provider, { value: { lang, dictionary } },
9
+ const I18nProvider = ({ children, lang, clientTerms = [] }) => {
10
+ return (react_1.default.createElement(I18nContext_1.I18nContext.Provider, { value: { lang } },
13
11
  react_1.default.createElement(I18nTransmitter_1.default, { terms: clientTerms, cleanThread: true }, children)));
14
12
  };
15
13
  exports.default = I18nProvider;
@@ -5,10 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const object_path_1 = __importDefault(require("object-path"));
8
- const get_server_context_1 = __importDefault(require("next-impl-getters/get-server-context"));
8
+ const get_server_context_1 = __importDefault(require("@nimpl/getters/get-server-context"));
9
9
  const I18nContext_1 = require("./lib/I18nContext");
10
10
  const ClientI18nProvider_1 = __importDefault(require("./lib/ClientI18nProvider"));
11
11
  const formatServerTranslate_1 = __importDefault(require("./lib/formatServerTranslate"));
12
+ const getDictionary_1 = __importDefault(require("./lib/getDictionary"));
12
13
  const formatServerTranslates = (result, targetKey, translates, opts = {}) => {
13
14
  if (!translates)
14
15
  return;
@@ -27,7 +28,8 @@ const I18nTransmitter = async ({ terms, children, cleanThread }) => {
27
28
  if (!context) {
28
29
  throw new Error("Please, Init I18nProvider - https://github.com/vordgi/nimpl-i18n#server-components");
29
30
  }
30
- const { dictionary, lang } = context;
31
+ const { lang } = context;
32
+ const dictionary = await (0, getDictionary_1.default)(lang);
31
33
  const result = {};
32
34
  terms.forEach((term) => {
33
35
  if (Array.isArray(term)) {
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const Translation_1 = __importDefault(require("./lib/Translation"));
8
8
  const getTranslation_1 = __importDefault(require("./getTranslation"));
9
- const ServerTranslation = ({ term, components, query, removeUnusedQueries }) => {
10
- const { t } = (0, getTranslation_1.default)();
9
+ const ServerTranslation = async ({ term, components, query, removeUnusedQueries, }) => {
10
+ const { t } = await (0, getTranslation_1.default)();
11
11
  const text = t(term, { query, removeUnusedQueries });
12
12
  return react_1.default.createElement(Translation_1.default, { term: term, text: text, components: components });
13
13
  };
@@ -15,10 +15,10 @@ const getConfig = async () => {
15
15
  const config = await dynamicImport((0, url_1.pathToFileURL)(CONFIG_PATH).href);
16
16
  const { load, languages } = config.default;
17
17
  if (!load) {
18
- throw new Error(`Can't find loaderProvider - https://github.com/vordgi/nimpl-i18n#configuration`);
18
+ throw new Error(`Can't find load method in configuration file - https://github.com/vordgi/nimpl-i18n#configuration`);
19
19
  }
20
20
  if (!languages) {
21
- throw new Error(`Can't find loaderProvider - https://github.com/vordgi/nimpl-i18n#configuration`);
21
+ throw new Error(`Can't find languages list in configuration file - https://github.com/vordgi/nimpl-i18n#configuration`);
22
22
  }
23
23
  return config.default;
24
24
  }
@@ -4,15 +4,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const object_path_1 = __importDefault(require("object-path"));
7
- const get_server_context_1 = __importDefault(require("next-impl-getters/get-server-context"));
7
+ const get_server_context_1 = __importDefault(require("@nimpl/getters/get-server-context"));
8
8
  const I18nContext_1 = require("./lib/I18nContext");
9
9
  const formatServerTranslate_1 = __importDefault(require("./lib/formatServerTranslate"));
10
- const getTranslation = (namespace) => {
10
+ const getDictionary_1 = __importDefault(require("./lib/getDictionary"));
11
+ const getTranslation = async (namespace) => {
11
12
  const context = (0, get_server_context_1.default)(I18nContext_1.I18nContext);
12
13
  if (!context) {
13
14
  throw new Error("Please, Init I18nProvider - https://nimpl.tech/i18n/usage#i18nprovider");
14
15
  }
15
- const { dictionary, lang } = context;
16
+ const dictionary = await (0, getDictionary_1.default)(context.lang);
17
+ const { lang } = context;
16
18
  const namespaceDictionary = namespace ? object_path_1.default.get(dictionary, namespace) : dictionary;
17
19
  const t = (term, opts) => {
18
20
  let termDictionary = namespaceDictionary;
@@ -4,5 +4,5 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.I18nContext = void 0;
7
- const create_server_context_1 = __importDefault(require("next-impl-getters/create-server-context"));
7
+ const create_server_context_1 = __importDefault(require("@nimpl/getters/create-server-context"));
8
8
  exports.I18nContext = (0, create_server_context_1.default)(null);
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const getConfig_1 = __importDefault(require("../configuration/getConfig"));
3
7
  const getDictionary = async (lang) => {
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- const origFetch = globalThis._nextOriginalFetch || fetch;
6
- const dataResp = await origFetch(`http://localhost:${process.env.I18N_CACHE_PORT}/?secret=${process.env.I18N_CACHE_SECRET}&lang=${lang}`, { cache: "no-cache" });
7
- const data = await dataResp.json();
8
+ const config = await (0, getConfig_1.default)();
9
+ if (!lang || !config.languages.includes(lang)) {
10
+ throw new Error(`Can\' load data for language "${lang}", valid languages are: ${config.languages.join(", ")}`);
11
+ }
12
+ const { data } = await config.load(lang);
8
13
  return data;
9
14
  };
10
15
  exports.default = getDictionary;
@@ -3,5 +3,5 @@ type GetTranslationReturnType = {
3
3
  t: (term: string, opts?: I18nOptions) => string;
4
4
  lang: string;
5
5
  };
6
- declare const getTranslation: (namespace?: string) => GetTranslationReturnType;
6
+ declare const getTranslation: (namespace?: string) => Promise<GetTranslationReturnType>;
7
7
  export default getTranslation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimpl/i18n",
3
- "version": "1.2.0",
3
+ "version": "2.0.0-canary.0",
4
4
  "description": "i18n library for working with translations in server and client components",
5
5
  "exports": {
6
6
  "./ClientTranslation": {
@@ -71,7 +71,7 @@
71
71
  },
72
72
  "dependencies": {
73
73
  "html-entities": "2.4.0",
74
- "next-impl-getters": "0.3.1",
74
+ "@nimpl/getters": "1.3.4",
75
75
  "object-path": "0.11.8"
76
76
  }
77
77
  }
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CacheHandler = void 0;
4
- class CacheHandler {
5
- cache;
6
- constructor() {
7
- this.cache = new Map();
8
- }
9
- async get(key) {
10
- return this.cache.get(key);
11
- }
12
- async set(key, data) {
13
- this.cache.set(key, data);
14
- }
15
- async has(key) {
16
- return this.cache.has(key);
17
- }
18
- }
19
- exports.CacheHandler = CacheHandler;
@@ -1,108 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const isPromise_1 = require("../helpers/isPromise");
4
- const CacheHandler_1 = require("./CacheHandler");
5
- class DataLoader {
6
- cache = {};
7
- loadTranslates;
8
- revalidate;
9
- cacheHandler = new CacheHandler_1.CacheHandler();
10
- checkIsActual;
11
- retryAttempts;
12
- languages;
13
- constructor(opts) {
14
- this.loadTranslates = opts.load;
15
- this.revalidate = opts.revalidate;
16
- this.checkIsActual = opts.checkIsActual;
17
- this.retryAttempts = opts.retryAttempts || 3;
18
- this.languages = opts.languages || [];
19
- }
20
- async prolongCache(lang) {
21
- const prevMeta = this.cache[lang];
22
- if (prevMeta && !(0, isPromise_1.isPromise)(prevMeta)) {
23
- prevMeta.lastUpdated = Date.now();
24
- }
25
- }
26
- async actualizeData(lang, lastLoadMeta) {
27
- const isOutdatedCache = !lastLoadMeta ||
28
- (this.revalidate !== undefined &&
29
- this.revalidate !== false &&
30
- lastLoadMeta.lastUpdated + 1000 * this.revalidate < Date.now());
31
- if (isOutdatedCache) {
32
- this.cache[lang] = new Promise(async (resolve) => {
33
- if (this.checkIsActual) {
34
- const isActual = await this.callWithRetries(() => this.checkIsActual(lang, lastLoadMeta));
35
- if (isActual) {
36
- this.prolongCache(lang);
37
- resolve(undefined);
38
- }
39
- }
40
- const fullData = await this.callWithRetries(() => this.loadTranslates(lang));
41
- if (!fullData?.data) {
42
- throw new Error(`No data key in load response for lang: ${lang}`);
43
- }
44
- this.cacheHandler.set(lang, fullData.data);
45
- this.cache[lang] = {
46
- ...fullData.meta,
47
- lastUpdated: Date.now(),
48
- isRevalidated: false,
49
- };
50
- resolve(fullData.data);
51
- });
52
- const data = await this.cache[lang];
53
- return data;
54
- }
55
- }
56
- async load(lang) {
57
- if (!this.languages.includes(lang)) {
58
- console.error(`Unknown language: ${lang}`);
59
- return {};
60
- }
61
- const cache = this.cache;
62
- try {
63
- const lastLoadResult = cache[lang];
64
- /** We are still loading */
65
- if ((0, isPromise_1.isPromise)(lastLoadResult)) {
66
- const data = await cache[lang];
67
- return data;
68
- }
69
- /** Cache doesn't exist or it's outdated */
70
- const actualData = await this.actualizeData(lang, lastLoadResult);
71
- if (actualData)
72
- return actualData;
73
- }
74
- catch (e) {
75
- console.error(`Can\'t load actual data for lang ${lang}: `, e);
76
- }
77
- const isCacheExist = await this.cacheHandler.has(lang);
78
- if (isCacheExist) {
79
- return this.cacheHandler.get(lang);
80
- }
81
- throw new Error("Can't load data or read from cache");
82
- }
83
- async revalidateTag(lang) {
84
- const prevMeta = this.cache[lang];
85
- if (prevMeta && !(0, isPromise_1.isPromise)(prevMeta)) {
86
- prevMeta.isRevalidated = true;
87
- await this.load(lang);
88
- }
89
- }
90
- async callWithRetries(cb) {
91
- let attempts = 0;
92
- const call = async () => {
93
- try {
94
- attempts += 1;
95
- return await cb();
96
- }
97
- catch {
98
- if (attempts === this.retryAttempts) {
99
- throw new Error("Can't load data");
100
- }
101
- console.warn("Can't load data, trying again...");
102
- call();
103
- }
104
- };
105
- return call();
106
- }
107
- }
108
- exports.default = DataLoader;
@@ -1,51 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const crypto_1 = __importDefault(require("crypto"));
7
- const getConfig_1 = __importDefault(require("./getConfig"));
8
- const http_1 = __importDefault(require("http"));
9
- const DataLoader_1 = __importDefault(require("./DataLoader"));
10
- async function createCacheServer(port) {
11
- const serverSecret = crypto_1.default.randomBytes(32).toString("hex");
12
- const config = await (0, getConfig_1.default)();
13
- const dataLoader = new DataLoader_1.default(config);
14
- const server = http_1.default.createServer(async (req, res) => {
15
- try {
16
- const url = new URL(req.url || "/", "http://n");
17
- const secret = url.searchParams.get("secret");
18
- const lang = url.searchParams.get("lang");
19
- const type = url.searchParams.get("type");
20
- if (type === "dev" && process.env.NODE_ENV === "development") {
21
- return res.end(JSON.stringify({ secret: serverSecret }));
22
- }
23
- if (secret !== serverSecret || !lang) {
24
- return res.end();
25
- }
26
- const data = await dataLoader.load(lang);
27
- res.end(JSON.stringify(data));
28
- }
29
- catch (e) {
30
- console.log("error on data loading", e);
31
- }
32
- });
33
- await new Promise((resolve) => {
34
- server.listen(+port, "localhost", () => {
35
- resolve(1);
36
- });
37
- });
38
- process.on("SIGINT", () => {
39
- server.close();
40
- });
41
- process.on("SIGQUIT", () => {
42
- server.close();
43
- });
44
- process.on("SIGTERM", () => {
45
- server.close();
46
- });
47
- return {
48
- secret: serverSecret,
49
- };
50
- }
51
- exports.default = createCacheServer;
package/dist/withI18n.js DELETED
@@ -1,32 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const createCacheServer_1 = __importDefault(require("./configuration/createCacheServer"));
7
- const PORT = "24";
8
- let cacheSecret = process.env.I18N_CACHE_SECRET;
9
- const withI18n = async () => {
10
- if (!cacheSecret) {
11
- try {
12
- const devResp = await fetch(`http://localhost:${PORT}/?type=dev`);
13
- const data = await devResp.json();
14
- if (data) {
15
- cacheSecret = data.secret;
16
- }
17
- }
18
- catch {
19
- //
20
- }
21
- }
22
- if (!cacheSecret) {
23
- const { secret } = await (0, createCacheServer_1.default)(PORT);
24
- cacheSecret = secret;
25
- }
26
- process.env.I18N_CACHE_PORT = PORT;
27
- if (cacheSecret)
28
- process.env.I18N_CACHE_SECRET = cacheSecret;
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
- return (nextConfig) => nextConfig;
31
- };
32
- exports.default = withI18n;
package/withI18n.d.ts DELETED
@@ -1,2 +0,0 @@
1
- declare const withI18n: () => Promise<(nextConfig: any) => any>;
2
- export default withI18n;