@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.
- package/README.md +42 -0
- package/dist/_generatedFiles_/api/ar.json +85 -0
- package/dist/_generatedFiles_/api/az.json +86 -0
- package/dist/_generatedFiles_/api/bg.json +85 -0
- package/dist/_generatedFiles_/api/cs.json +85 -0
- package/dist/_generatedFiles_/api/de.json +85 -0
- package/dist/_generatedFiles_/api/en.json +85 -0
- package/dist/_generatedFiles_/api/es.json +85 -0
- package/dist/_generatedFiles_/api/fa.json +85 -0
- package/dist/_generatedFiles_/api/fr.json +85 -0
- package/dist/_generatedFiles_/api/hr.json +85 -0
- package/dist/_generatedFiles_/api/hu.json +85 -0
- package/dist/_generatedFiles_/api/index.d.ts +2552 -0
- package/dist/_generatedFiles_/api/index.js +68 -0
- package/dist/_generatedFiles_/api/it.json +85 -0
- package/dist/_generatedFiles_/api/ja.json +85 -0
- package/dist/_generatedFiles_/api/ko.json +84 -0
- package/dist/_generatedFiles_/api/my.json +85 -0
- package/dist/_generatedFiles_/api/nb.json +85 -0
- package/dist/_generatedFiles_/api/nl.json +85 -0
- package/dist/_generatedFiles_/api/pl.json +85 -0
- package/dist/_generatedFiles_/api/pt.json +85 -0
- package/dist/_generatedFiles_/api/ro.json +85 -0
- package/dist/_generatedFiles_/api/rs-latin.json +85 -0
- package/dist/_generatedFiles_/api/rs.json +85 -0
- package/dist/_generatedFiles_/api/ru.json +85 -0
- package/dist/_generatedFiles_/api/sv.json +85 -0
- package/dist/_generatedFiles_/api/th.json +85 -0
- package/dist/_generatedFiles_/api/tr.json +85 -0
- package/dist/_generatedFiles_/api/translation-schema.json +403 -0
- package/dist/_generatedFiles_/api/ua.json +85 -0
- package/dist/_generatedFiles_/api/vi.json +85 -0
- package/dist/_generatedFiles_/api/zh-tw.json +85 -0
- package/dist/_generatedFiles_/api/zh.json +85 -0
- package/dist/_generatedFiles_/client/ar.json +273 -0
- package/dist/_generatedFiles_/client/az.json +273 -0
- package/dist/_generatedFiles_/client/bg.json +273 -0
- package/dist/_generatedFiles_/client/cs.json +273 -0
- package/dist/_generatedFiles_/client/de.json +273 -0
- package/dist/_generatedFiles_/client/en.json +275 -0
- package/dist/_generatedFiles_/client/es.json +273 -0
- package/dist/_generatedFiles_/client/fa.json +273 -0
- package/dist/_generatedFiles_/client/fr.json +273 -0
- package/dist/_generatedFiles_/client/hr.json +273 -0
- package/dist/_generatedFiles_/client/hu.json +273 -0
- package/dist/_generatedFiles_/client/index.d.ts +8197 -0
- package/dist/_generatedFiles_/client/index.js +68 -0
- package/dist/_generatedFiles_/client/it.json +273 -0
- package/dist/_generatedFiles_/client/ja.json +275 -0
- package/dist/_generatedFiles_/client/ko.json +272 -0
- package/dist/_generatedFiles_/client/my.json +273 -0
- package/dist/_generatedFiles_/client/nb.json +273 -0
- package/dist/_generatedFiles_/client/nl.json +273 -0
- package/dist/_generatedFiles_/client/pl.json +273 -0
- package/dist/_generatedFiles_/client/pt.json +273 -0
- package/dist/_generatedFiles_/client/ro.json +273 -0
- package/dist/_generatedFiles_/client/rs-latin.json +273 -0
- package/dist/_generatedFiles_/client/rs.json +273 -0
- package/dist/_generatedFiles_/client/ru.json +273 -0
- package/dist/_generatedFiles_/client/sv.json +273 -0
- package/dist/_generatedFiles_/client/th.json +273 -0
- package/dist/_generatedFiles_/client/tr.json +273 -0
- package/dist/_generatedFiles_/client/translation-schema.json +1086 -0
- package/dist/_generatedFiles_/client/ua.json +273 -0
- package/dist/_generatedFiles_/client/vi.json +273 -0
- package/dist/_generatedFiles_/client/zh-tw.json +275 -0
- package/dist/_generatedFiles_/client/zh.json +273 -0
- package/dist/exports/index.d.ts +3 -0
- package/dist/exports/index.js +9 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +2 -0
- package/dist/utilities/copyFile.d.ts +1 -0
- package/dist/utilities/copyFile.js +15 -0
- package/dist/utilities/deepMerge.d.ts +1 -0
- package/dist/utilities/deepMerge.js +18 -0
- package/dist/utilities/ensureDirExists.d.ts +1 -0
- package/dist/utilities/ensureDirExists.js +18 -0
- package/dist/utilities/getTranslation.d.ts +3 -0
- package/dist/utilities/getTranslation.js +21 -0
- package/dist/utilities/init.d.ts +30 -0
- package/dist/utilities/init.js +180 -0
- 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,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
|
+
}
|