@payloadcms/translations 3.0.0-alpha.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.
Files changed (82) hide show
  1. package/README.md +42 -0
  2. package/dist/_generatedFiles_/api/ar.json +85 -0
  3. package/dist/_generatedFiles_/api/az.json +86 -0
  4. package/dist/_generatedFiles_/api/bg.json +85 -0
  5. package/dist/_generatedFiles_/api/cs.json +85 -0
  6. package/dist/_generatedFiles_/api/de.json +85 -0
  7. package/dist/_generatedFiles_/api/en.json +85 -0
  8. package/dist/_generatedFiles_/api/es.json +85 -0
  9. package/dist/_generatedFiles_/api/fa.json +85 -0
  10. package/dist/_generatedFiles_/api/fr.json +85 -0
  11. package/dist/_generatedFiles_/api/hr.json +85 -0
  12. package/dist/_generatedFiles_/api/hu.json +85 -0
  13. package/dist/_generatedFiles_/api/index.d.ts +2552 -0
  14. package/dist/_generatedFiles_/api/index.js +68 -0
  15. package/dist/_generatedFiles_/api/it.json +85 -0
  16. package/dist/_generatedFiles_/api/ja.json +85 -0
  17. package/dist/_generatedFiles_/api/ko.json +84 -0
  18. package/dist/_generatedFiles_/api/my.json +85 -0
  19. package/dist/_generatedFiles_/api/nb.json +85 -0
  20. package/dist/_generatedFiles_/api/nl.json +85 -0
  21. package/dist/_generatedFiles_/api/pl.json +85 -0
  22. package/dist/_generatedFiles_/api/pt.json +85 -0
  23. package/dist/_generatedFiles_/api/ro.json +85 -0
  24. package/dist/_generatedFiles_/api/rs-latin.json +85 -0
  25. package/dist/_generatedFiles_/api/rs.json +85 -0
  26. package/dist/_generatedFiles_/api/ru.json +85 -0
  27. package/dist/_generatedFiles_/api/sv.json +85 -0
  28. package/dist/_generatedFiles_/api/th.json +85 -0
  29. package/dist/_generatedFiles_/api/tr.json +85 -0
  30. package/dist/_generatedFiles_/api/translation-schema.json +403 -0
  31. package/dist/_generatedFiles_/api/ua.json +85 -0
  32. package/dist/_generatedFiles_/api/vi.json +85 -0
  33. package/dist/_generatedFiles_/api/zh-tw.json +85 -0
  34. package/dist/_generatedFiles_/api/zh.json +85 -0
  35. package/dist/_generatedFiles_/client/ar.json +273 -0
  36. package/dist/_generatedFiles_/client/az.json +273 -0
  37. package/dist/_generatedFiles_/client/bg.json +273 -0
  38. package/dist/_generatedFiles_/client/cs.json +273 -0
  39. package/dist/_generatedFiles_/client/de.json +273 -0
  40. package/dist/_generatedFiles_/client/en.json +275 -0
  41. package/dist/_generatedFiles_/client/es.json +273 -0
  42. package/dist/_generatedFiles_/client/fa.json +273 -0
  43. package/dist/_generatedFiles_/client/fr.json +273 -0
  44. package/dist/_generatedFiles_/client/hr.json +273 -0
  45. package/dist/_generatedFiles_/client/hu.json +273 -0
  46. package/dist/_generatedFiles_/client/index.d.ts +8197 -0
  47. package/dist/_generatedFiles_/client/index.js +68 -0
  48. package/dist/_generatedFiles_/client/it.json +273 -0
  49. package/dist/_generatedFiles_/client/ja.json +275 -0
  50. package/dist/_generatedFiles_/client/ko.json +272 -0
  51. package/dist/_generatedFiles_/client/my.json +273 -0
  52. package/dist/_generatedFiles_/client/nb.json +273 -0
  53. package/dist/_generatedFiles_/client/nl.json +273 -0
  54. package/dist/_generatedFiles_/client/pl.json +273 -0
  55. package/dist/_generatedFiles_/client/pt.json +273 -0
  56. package/dist/_generatedFiles_/client/ro.json +273 -0
  57. package/dist/_generatedFiles_/client/rs-latin.json +273 -0
  58. package/dist/_generatedFiles_/client/rs.json +273 -0
  59. package/dist/_generatedFiles_/client/ru.json +273 -0
  60. package/dist/_generatedFiles_/client/sv.json +273 -0
  61. package/dist/_generatedFiles_/client/th.json +273 -0
  62. package/dist/_generatedFiles_/client/tr.json +273 -0
  63. package/dist/_generatedFiles_/client/translation-schema.json +1086 -0
  64. package/dist/_generatedFiles_/client/ua.json +273 -0
  65. package/dist/_generatedFiles_/client/vi.json +273 -0
  66. package/dist/_generatedFiles_/client/zh-tw.json +275 -0
  67. package/dist/_generatedFiles_/client/zh.json +273 -0
  68. package/dist/exports/index.d.ts +3 -0
  69. package/dist/exports/index.js +9 -0
  70. package/dist/types.d.ts +42 -0
  71. package/dist/types.js +2 -0
  72. package/dist/utilities/copyFile.d.ts +1 -0
  73. package/dist/utilities/copyFile.js +15 -0
  74. package/dist/utilities/deepMerge.d.ts +1 -0
  75. package/dist/utilities/deepMerge.js +18 -0
  76. package/dist/utilities/ensureDirExists.d.ts +1 -0
  77. package/dist/utilities/ensureDirExists.js +18 -0
  78. package/dist/utilities/getTranslation.d.ts +3 -0
  79. package/dist/utilities/getTranslation.js +21 -0
  80. package/dist/utilities/init.d.ts +30 -0
  81. package/dist/utilities/init.js +180 -0
  82. package/package.json +37 -0
@@ -0,0 +1,18 @@
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
+ exports.ensureDirectoryExists = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ function ensureDirectoryExists(directory) {
9
+ try {
10
+ if (!fs_1.default.existsSync(directory)) {
11
+ fs_1.default.mkdirSync(directory, { recursive: true });
12
+ }
13
+ }
14
+ catch (error) {
15
+ console.error(`Error creating directory '${directory}': ${error.message}`);
16
+ }
17
+ }
18
+ exports.ensureDirectoryExists = ensureDirectoryExists;
@@ -0,0 +1,3 @@
1
+ import type { JSX } from 'react';
2
+ import { I18n } from '../types';
3
+ export declare const getTranslation: (label: JSX.Element | Record<string, string> | string, i18n: Pick<I18n, 'fallbackLanguage' | 'language'>) => string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTranslation = void 0;
4
+ const getTranslation = (label, i18n) => {
5
+ if (typeof label === 'object') {
6
+ if (label[i18n.language]) {
7
+ return label[i18n.language];
8
+ }
9
+ let fallbacks = [];
10
+ if (typeof i18n.fallbackLanguage === 'string') {
11
+ fallbacks = [i18n.fallbackLanguage];
12
+ }
13
+ else if (Array.isArray(i18n.fallbackLanguage)) {
14
+ fallbacks = i18n.fallbackLanguage;
15
+ }
16
+ const fallbackLang = fallbacks.find((language) => label[language]);
17
+ return fallbackLang && label[fallbackLang] ? fallbackLang : label[Object.keys(label)[0]];
18
+ }
19
+ return label;
20
+ };
21
+ exports.getTranslation = getTranslation;
@@ -0,0 +1,30 @@
1
+ import { Translations, InitI18n } from '../types';
2
+ /**
3
+ * @function getTranslationString
4
+ *
5
+ * Gets a translation string from a translations object
6
+ *
7
+ * @returns string
8
+ */
9
+ export declare const getTranslationString: ({ count, key, translations, }: {
10
+ count?: number;
11
+ key: string;
12
+ translations: Translations[0];
13
+ }) => string;
14
+ /**
15
+ * @function t
16
+ *
17
+ * Merges config defined translations with translations passed in as an argument
18
+ * returns a function that can be used to translate a string
19
+ *
20
+ * @returns string
21
+ */
22
+ type TFunctionConstructor = ({ key, translations, vars, }: {
23
+ key: string;
24
+ translations?: Translations[0];
25
+ vars?: Record<string, any>;
26
+ }) => string;
27
+ export declare const t: TFunctionConstructor;
28
+ export declare function matchLanguage(header: string): string | undefined;
29
+ export declare const initI18n: InitI18n;
30
+ export {};
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initI18n = exports.matchLanguage = exports.t = exports.getTranslationString = void 0;
4
+ const deepMerge_1 = require("./deepMerge");
5
+ /**
6
+ * @function getTranslationString
7
+ *
8
+ * Gets a translation string from a translations object
9
+ *
10
+ * @returns string
11
+ */
12
+ const getTranslationString = ({ count, key, translations, }) => {
13
+ const keys = key.split(':');
14
+ let keySuffix = '';
15
+ const translation = keys.reduce((acc, key, index) => {
16
+ if (typeof acc === 'string')
17
+ return acc;
18
+ if (typeof count === 'number') {
19
+ if (count === 0 && `${key}_zero` in acc) {
20
+ keySuffix = '_zero';
21
+ }
22
+ else if (count === 1 && `${key}_one` in acc) {
23
+ keySuffix = '_one';
24
+ }
25
+ else if (count === 2 && `${key}_two` in acc) {
26
+ keySuffix = '_two';
27
+ }
28
+ else if (count > 5 && `${key}_many` in acc) {
29
+ keySuffix = '_many';
30
+ }
31
+ else if (count > 2 && count <= 5 && `${key}_few` in acc) {
32
+ keySuffix = '_few';
33
+ }
34
+ else if (`${key}_other` in acc) {
35
+ keySuffix = '_other';
36
+ }
37
+ }
38
+ let keyToUse = key;
39
+ if (index === keys.length - 1 && keySuffix) {
40
+ keyToUse = `${key}${keySuffix}`;
41
+ }
42
+ if (acc && keyToUse in acc) {
43
+ return acc[keyToUse];
44
+ }
45
+ return undefined;
46
+ }, translations);
47
+ if (!translation) {
48
+ console.log('key not found: ', key);
49
+ }
50
+ return translation || key;
51
+ };
52
+ exports.getTranslationString = getTranslationString;
53
+ /**
54
+ * @function replaceVars
55
+ *
56
+ * Replaces variables in a translation string with values from an object
57
+ *
58
+ * @returns string
59
+ */
60
+ const replaceVars = ({ translationString, vars, }) => {
61
+ const parts = translationString.split(/({{.*?}})/);
62
+ return parts
63
+ .map((part) => {
64
+ if (part.startsWith('{{') && part.endsWith('}}')) {
65
+ const placeholder = part.substring(2, part.length - 2).trim();
66
+ return vars[placeholder] || part;
67
+ }
68
+ else {
69
+ return part;
70
+ }
71
+ })
72
+ .join('');
73
+ };
74
+ const t = ({ key, translations, vars }) => {
75
+ let translationString = (0, exports.getTranslationString)({
76
+ count: typeof vars?.count === 'number' ? vars.count : undefined,
77
+ key,
78
+ translations,
79
+ });
80
+ if (vars) {
81
+ translationString = replaceVars({
82
+ translationString,
83
+ vars,
84
+ });
85
+ }
86
+ if (!translationString) {
87
+ translationString = key;
88
+ }
89
+ return translationString;
90
+ };
91
+ exports.t = t;
92
+ function parseAcceptLanguage(header) {
93
+ return header
94
+ .split(',')
95
+ .map((lang) => {
96
+ const [language, quality] = lang.trim().split(';q=');
97
+ return {
98
+ language,
99
+ quality: quality ? parseFloat(quality) : 1,
100
+ };
101
+ })
102
+ .sort((a, b) => b.quality - a.quality); // Sort by quality, highest to lowest
103
+ }
104
+ const acceptedLanguages = [
105
+ 'ar',
106
+ 'az',
107
+ 'bg',
108
+ 'cs',
109
+ 'de',
110
+ 'en',
111
+ 'es',
112
+ 'fa',
113
+ 'fr',
114
+ 'hr',
115
+ 'hu',
116
+ 'it',
117
+ 'ja',
118
+ 'ko',
119
+ 'my',
120
+ 'nb',
121
+ 'nl',
122
+ 'pl',
123
+ 'pt',
124
+ 'ro',
125
+ 'rs',
126
+ 'rsLatin',
127
+ 'ru',
128
+ 'sv',
129
+ 'th',
130
+ 'tr',
131
+ 'ua',
132
+ 'vi',
133
+ 'zh',
134
+ 'zhTw',
135
+ ];
136
+ function matchLanguage(header) {
137
+ const parsedHeader = parseAcceptLanguage(header);
138
+ for (const { language } of parsedHeader) {
139
+ for (const acceptedLanguage of acceptedLanguages) {
140
+ if (language.startsWith(acceptedLanguage)) {
141
+ return acceptedLanguage;
142
+ }
143
+ }
144
+ }
145
+ return undefined;
146
+ }
147
+ exports.matchLanguage = matchLanguage;
148
+ const initTFunction = (args) => (key, vars) => {
149
+ const { config, language, translations } = args;
150
+ const mergedLanguages = (0, deepMerge_1.deepMerge)(config?.translations ?? {}, translations);
151
+ const languagePreference = matchLanguage(language);
152
+ return (0, exports.t)({
153
+ key,
154
+ translations: mergedLanguages[languagePreference],
155
+ vars,
156
+ });
157
+ };
158
+ function memoize(fn, keys) {
159
+ const cacheMap = new Map();
160
+ return function (args) {
161
+ const cacheKey = keys.reduce((acc, key) => acc + args[key], '');
162
+ if (!cacheMap.has(cacheKey)) {
163
+ const result = fn(args);
164
+ cacheMap.set(cacheKey, result);
165
+ }
166
+ return cacheMap.get(cacheKey);
167
+ };
168
+ }
169
+ exports.initI18n = memoize((({ config, language = 'en', translations, context }) => {
170
+ const i18n = {
171
+ fallbackLanguage: config.fallbackLanguage,
172
+ language: language || config.fallbackLanguage,
173
+ t: initTFunction({
174
+ config,
175
+ language: language || config.fallbackLanguage,
176
+ translations,
177
+ }),
178
+ };
179
+ return i18n;
180
+ }), ['language', 'context']);
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@payloadcms/translations",
3
+ "version": "3.0.0-alpha.0",
4
+ "main": "./dist/exports/index.ts",
5
+ "types": "./dist/types.d.ts",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/exports/index.js",
12
+ "require": "./dist/exports/index.js"
13
+ },
14
+ "./api": {
15
+ "import": "./dist/_generatedFiles_/api/index.js",
16
+ "require": "./dist/_generatedFiles_/api/index.js"
17
+ },
18
+ "./client": {
19
+ "import": "./dist/_generatedFiles_/client/index.js",
20
+ "require": "./dist/_generatedFiles_/client/index.js"
21
+ }
22
+ },
23
+ "devDependencies": {
24
+ "@swc/core": "^1.3.102",
25
+ "@types/react": "^18",
26
+ "typescript": "5.2.2",
27
+ "@payloadcms/eslint-config": "1.1.1"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "scripts": {
33
+ "writeFiles": "npx ts-node ./writeTranslationFiles.ts",
34
+ "build": "pnpm writeFiles && tsc",
35
+ "clean": "rimraf {dist,*.tsbuildinfo}"
36
+ }
37
+ }