keycloakify 7.14.3 → 7.15.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 +8 -0
- package/bin/keycloakify/generateTheme/generateMessageProperties.d.ts +8 -0
- package/bin/keycloakify/generateTheme/generateMessageProperties.js +271 -0
- package/bin/keycloakify/generateTheme/generateMessageProperties.js.map +1 -0
- package/bin/keycloakify/generateTheme/generateTheme.js +11 -0
- package/bin/keycloakify/generateTheme/generateTheme.js.map +1 -1
- package/package.json +12 -2
- package/src/bin/keycloakify/generateTheme/generateMessageProperties.ts +179 -0
- package/src/bin/keycloakify/generateTheme/generateTheme.ts +14 -0
package/README.md
CHANGED
@@ -121,6 +121,14 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
121
121
|
|
122
122
|
# Changelog highlights
|
123
123
|
|
124
|
+
## 7.15
|
125
|
+
|
126
|
+
- The i18n messages you defines in your theme are now also maid available to Keycloak.
|
127
|
+
In practice this mean that you can now customize the `kcContext.message.summary` that
|
128
|
+
display a general alert and the values returned by `kcContext.messagesPerField.get()` that
|
129
|
+
are used to display specific error on some field of the form.
|
130
|
+
[See video](https://youtu.be/D6tZcemReTI)
|
131
|
+
|
124
132
|
## 7.14
|
125
133
|
|
126
134
|
- Deprecate the `extraPages` build option. Keycloakify is now able to analyze your code to detect extra pages.
|
@@ -0,0 +1,271 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __read = (this && this.__read) || function (o, n) {
|
26
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
27
|
+
if (!m) return o;
|
28
|
+
var i = m.call(o), r, ar = [], e;
|
29
|
+
try {
|
30
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
31
|
+
}
|
32
|
+
catch (error) { e = { error: error }; }
|
33
|
+
finally {
|
34
|
+
try {
|
35
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
36
|
+
}
|
37
|
+
finally { if (e) throw e.error; }
|
38
|
+
}
|
39
|
+
return ar;
|
40
|
+
};
|
41
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
42
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
43
|
+
if (ar || !(i in from)) {
|
44
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
45
|
+
ar[i] = from[i];
|
46
|
+
}
|
47
|
+
}
|
48
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
49
|
+
};
|
50
|
+
var __values = (this && this.__values) || function(o) {
|
51
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
52
|
+
if (m) return m.call(o);
|
53
|
+
if (o && typeof o.length === "number") return {
|
54
|
+
next: function () {
|
55
|
+
if (o && i >= o.length) o = void 0;
|
56
|
+
return { value: o && o[i++], done: !o };
|
57
|
+
}
|
58
|
+
};
|
59
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
60
|
+
};
|
61
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
62
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
63
|
+
};
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
65
|
+
exports.generateMessageProperties = void 0;
|
66
|
+
var crawl_1 = require("../../tools/crawl");
|
67
|
+
var path_1 = require("path");
|
68
|
+
var fs_1 = require("fs");
|
69
|
+
var symToStr_1 = require("tsafe/symToStr");
|
70
|
+
var removeDuplicates_1 = require("evt/tools/reducers/removeDuplicates");
|
71
|
+
var recast = __importStar(require("recast"));
|
72
|
+
var babelParser = __importStar(require("@babel/parser"));
|
73
|
+
var generator_1 = __importDefault(require("@babel/generator"));
|
74
|
+
var babelTypes = __importStar(require("@babel/types"));
|
75
|
+
function generateMessageProperties(params) {
|
76
|
+
var _a, e_1, _b, e_2, _c, e_3, _d, e_4, _e;
|
77
|
+
var themeSrcDirPath = params.themeSrcDirPath, themeType = params.themeType;
|
78
|
+
var files = (0, crawl_1.crawl)({
|
79
|
+
"dirPath": (0, path_1.join)(themeSrcDirPath, themeType),
|
80
|
+
"returnedPathsType": "absolute"
|
81
|
+
});
|
82
|
+
files = files.filter(function (file) {
|
83
|
+
var regex = /\.(js|ts|tsx)$/;
|
84
|
+
return regex.test(file);
|
85
|
+
});
|
86
|
+
files = files.sort(function (a, b) {
|
87
|
+
var regex = /\.i18n\.(ts|js|tsx)$/;
|
88
|
+
var aIsI18nFile = regex.test(a);
|
89
|
+
var bIsI18nFile = regex.test(b);
|
90
|
+
return aIsI18nFile === bIsI18nFile ? 0 : aIsI18nFile ? -1 : 1;
|
91
|
+
});
|
92
|
+
files = files.sort(function (a, b) { return a.length - b.length; });
|
93
|
+
files = files.filter(function (file) { return (0, fs_1.readFileSync)(file).toString("utf8").includes("createUseI18n"); });
|
94
|
+
if (files.length === 0) {
|
95
|
+
return [];
|
96
|
+
}
|
97
|
+
var extraMessages = files
|
98
|
+
.map(function (file) {
|
99
|
+
var root = recast.parse((0, fs_1.readFileSync)(file).toString("utf8"), {
|
100
|
+
"parser": {
|
101
|
+
"parse": function (code) { return babelParser.parse(code, { "sourceType": "module", "plugins": ["typescript"] }); },
|
102
|
+
"generator": generator_1.default,
|
103
|
+
"types": babelTypes
|
104
|
+
}
|
105
|
+
});
|
106
|
+
var codes = [];
|
107
|
+
recast.visit(root, {
|
108
|
+
"visitCallExpression": function (path) {
|
109
|
+
if (path.node.callee.type === "Identifier" && path.node.callee.name === "createUseI18n") {
|
110
|
+
codes.push((0, generator_1.default)(path.node.arguments[0]).code);
|
111
|
+
}
|
112
|
+
this.traverse(path);
|
113
|
+
}
|
114
|
+
});
|
115
|
+
return codes;
|
116
|
+
})
|
117
|
+
.flat()
|
118
|
+
.map(function (code) {
|
119
|
+
var extraMessages = {};
|
120
|
+
try {
|
121
|
+
eval("".concat((0, symToStr_1.symToStr)({ extraMessages: extraMessages }), " = ").concat(code));
|
122
|
+
}
|
123
|
+
catch (_a) {
|
124
|
+
console.warn([
|
125
|
+
"WARNING: Make sure that the first argument of createUseI18n can be evaluated in a javascript",
|
126
|
+
"runtime where only the node globals are available.",
|
127
|
+
"This is important because we need to put your i18n messages in messages_*.properties files",
|
128
|
+
"or they won't be available server side.",
|
129
|
+
"\n",
|
130
|
+
"The following code could not be evaluated:",
|
131
|
+
"\n",
|
132
|
+
code
|
133
|
+
].join(" "));
|
134
|
+
}
|
135
|
+
return extraMessages;
|
136
|
+
});
|
137
|
+
var languageTags = (_a = extraMessages
|
138
|
+
.map(function (extraMessage) { return Object.keys(extraMessage); })
|
139
|
+
.flat())
|
140
|
+
.reduce.apply(_a, __spreadArray([], __read((0, removeDuplicates_1.removeDuplicates)()), false));
|
141
|
+
var keyValueMapByLanguageTag = {};
|
142
|
+
try {
|
143
|
+
for (var languageTags_1 = __values(languageTags), languageTags_1_1 = languageTags_1.next(); !languageTags_1_1.done; languageTags_1_1 = languageTags_1.next()) {
|
144
|
+
var languageTag = languageTags_1_1.value;
|
145
|
+
var keyValueMap = {};
|
146
|
+
try {
|
147
|
+
for (var extraMessages_1 = (e_2 = void 0, __values(extraMessages)), extraMessages_1_1 = extraMessages_1.next(); !extraMessages_1_1.done; extraMessages_1_1 = extraMessages_1.next()) {
|
148
|
+
var extraMessage = extraMessages_1_1.value;
|
149
|
+
var keyValueMap_i = extraMessage[languageTag];
|
150
|
+
if (keyValueMap_i === undefined) {
|
151
|
+
continue;
|
152
|
+
}
|
153
|
+
try {
|
154
|
+
for (var _f = (e_3 = void 0, __values(Object.entries(keyValueMap_i))), _g = _f.next(); !_g.done; _g = _f.next()) {
|
155
|
+
var _h = __read(_g.value, 2), key = _h[0], value = _h[1];
|
156
|
+
if (keyValueMap[key] !== undefined) {
|
157
|
+
console.warn([
|
158
|
+
"WARNING: The following key is defined multiple times:",
|
159
|
+
"\n",
|
160
|
+
key,
|
161
|
+
"\n",
|
162
|
+
"The following value will be ignored:",
|
163
|
+
"\n",
|
164
|
+
value,
|
165
|
+
"\n",
|
166
|
+
"The following value was already defined:",
|
167
|
+
"\n",
|
168
|
+
keyValueMap[key]
|
169
|
+
].join(" "));
|
170
|
+
continue;
|
171
|
+
}
|
172
|
+
keyValueMap[key] = value;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
176
|
+
finally {
|
177
|
+
try {
|
178
|
+
if (_g && !_g.done && (_d = _f.return)) _d.call(_f);
|
179
|
+
}
|
180
|
+
finally { if (e_3) throw e_3.error; }
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
185
|
+
finally {
|
186
|
+
try {
|
187
|
+
if (extraMessages_1_1 && !extraMessages_1_1.done && (_c = extraMessages_1.return)) _c.call(extraMessages_1);
|
188
|
+
}
|
189
|
+
finally { if (e_2) throw e_2.error; }
|
190
|
+
}
|
191
|
+
keyValueMapByLanguageTag[languageTag] = keyValueMap;
|
192
|
+
}
|
193
|
+
}
|
194
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
195
|
+
finally {
|
196
|
+
try {
|
197
|
+
if (languageTags_1_1 && !languageTags_1_1.done && (_b = languageTags_1.return)) _b.call(languageTags_1);
|
198
|
+
}
|
199
|
+
finally { if (e_1) throw e_1.error; }
|
200
|
+
}
|
201
|
+
var out = [];
|
202
|
+
try {
|
203
|
+
for (var _j = __values(Object.entries(keyValueMapByLanguageTag)), _k = _j.next(); !_k.done; _k = _j.next()) {
|
204
|
+
var _l = __read(_k.value, 2), languageTag = _l[0], keyValueMap = _l[1];
|
205
|
+
var propertiesFileSource = Object.entries(keyValueMap)
|
206
|
+
.map(function (_a) {
|
207
|
+
var _b = __read(_a, 2), key = _b[0], value = _b[1];
|
208
|
+
return "".concat(key, "=").concat(escapeString(value));
|
209
|
+
})
|
210
|
+
.join("\n");
|
211
|
+
out.push({
|
212
|
+
languageTag: languageTag,
|
213
|
+
"propertiesFileSource": ["# This file was generated by keycloakify", "", "parent=base", "", propertiesFileSource, ""].join("\n")
|
214
|
+
});
|
215
|
+
}
|
216
|
+
}
|
217
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
218
|
+
finally {
|
219
|
+
try {
|
220
|
+
if (_k && !_k.done && (_e = _j.return)) _e.call(_j);
|
221
|
+
}
|
222
|
+
finally { if (e_4) throw e_4.error; }
|
223
|
+
}
|
224
|
+
return out;
|
225
|
+
}
|
226
|
+
exports.generateMessageProperties = generateMessageProperties;
|
227
|
+
// Convert a JavaScript string to UTF-16 encoding
|
228
|
+
function toUTF16(codePoint) {
|
229
|
+
if (codePoint <= 0xffff) {
|
230
|
+
// BMP character
|
231
|
+
return "\\u" + codePoint.toString(16).padStart(4, "0");
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
// Non-BMP character
|
235
|
+
codePoint -= 0x10000;
|
236
|
+
var highSurrogate = (codePoint >> 10) + 0xd800;
|
237
|
+
var lowSurrogate = (codePoint % 0x400) + 0xdc00;
|
238
|
+
return "\\u" + highSurrogate.toString(16).padStart(4, "0") + "\\u" + lowSurrogate.toString(16).padStart(4, "0");
|
239
|
+
}
|
240
|
+
}
|
241
|
+
// Escapes special characters and converts unicode to UTF-16 encoding
|
242
|
+
function escapeString(str) {
|
243
|
+
var e_5, _a;
|
244
|
+
var escapedStr = "";
|
245
|
+
try {
|
246
|
+
for (var _b = __values(__spreadArray([], __read(str), false)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
247
|
+
var char = _c.value;
|
248
|
+
var codePoint = char.codePointAt(0);
|
249
|
+
if (!codePoint)
|
250
|
+
continue;
|
251
|
+
if (char === "'") {
|
252
|
+
escapedStr += "''"; // double single quotes
|
253
|
+
}
|
254
|
+
else if (codePoint > 0x7f) {
|
255
|
+
escapedStr += toUTF16(codePoint); // non-ascii characters
|
256
|
+
}
|
257
|
+
else {
|
258
|
+
escapedStr += char;
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
262
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
263
|
+
finally {
|
264
|
+
try {
|
265
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
266
|
+
}
|
267
|
+
finally { if (e_5) throw e_5.error; }
|
268
|
+
}
|
269
|
+
return escapedStr;
|
270
|
+
}
|
271
|
+
//# sourceMappingURL=generateMessageProperties.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generateMessageProperties.js","sourceRoot":"","sources":["../../../src/bin/keycloakify/generateTheme/generateMessageProperties.ts"],"names":[],"mappings":"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"}
|
@@ -119,6 +119,7 @@ var assert_1 = require("tsafe/assert");
|
|
119
119
|
var downloadKeycloakStaticResources_1 = require("./downloadKeycloakStaticResources");
|
120
120
|
var readFieldNameUsage_1 = require("./readFieldNameUsage");
|
121
121
|
var readExtraPageNames_1 = require("./readExtraPageNames");
|
122
|
+
var generateMessageProperties_1 = require("./generateMessageProperties");
|
122
123
|
(0, assert_1.assert)();
|
123
124
|
function generateTheme(params) {
|
124
125
|
var _a;
|
@@ -219,6 +220,16 @@ function generateTheme(params) {
|
|
219
220
|
fs.mkdirSync(themeDirPath, { "recursive": true });
|
220
221
|
fs.writeFileSync((0, path_1.join)(themeDirPath, pageId), Buffer.from(ftlCode, "utf8"));
|
221
222
|
});
|
223
|
+
(0, generateMessageProperties_1.generateMessageProperties)({
|
224
|
+
themeSrcDirPath: themeSrcDirPath,
|
225
|
+
themeType: themeType
|
226
|
+
}).forEach(function (_a) {
|
227
|
+
var languageTag = _a.languageTag, propertiesFileSource = _a.propertiesFileSource;
|
228
|
+
var messagesDirPath = (0, path_1.join)(themeDirPath, "messages");
|
229
|
+
fs.mkdirSync((0, path_1.join)(themeDirPath, "messages"), { "recursive": true });
|
230
|
+
var propertiesFilePath = (0, path_1.join)(messagesDirPath, "messages_".concat(languageTag, ".properties"));
|
231
|
+
fs.writeFileSync(propertiesFilePath, Buffer.from(propertiesFileSource, "utf8"));
|
232
|
+
});
|
222
233
|
keycloakDirInPublicDir = (0, path_1.join)(reactAppBuildDirPath, "..", "public", mockTestingResourcesPath_1.basenameOfKeycloakDirInPublicDir);
|
223
234
|
if (fs.existsSync(keycloakDirInPublicDir)) {
|
224
235
|
return [3 /*break*/, 2];
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"generateTheme.js","sourceRoot":"","sources":["../../../src/bin/keycloakify/generateTheme/generateTheme.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAAkE;AAClE,qCAAyB;AACzB,6BAAwC;AACxC,kGAAiG;AACjG,gFAA+E;AAC/E,8CAAiI;AACjI,2EAAkF;AAClF,iDAAgD;AAEhD,uCAAsC;AACtC,qFAAoF;AACpF,2DAA0D;AAC1D,2DAA2D;
|
1
|
+
{"version":3,"file":"generateTheme.js","sourceRoot":"","sources":["../../../src/bin/keycloakify/generateTheme/generateTheme.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "keycloakify",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.15.0",
|
4
4
|
"description": "Create Keycloak themes using React",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -82,6 +82,7 @@
|
|
82
82
|
"src/bin/keycloakify/generateJavaStackFiles.ts",
|
83
83
|
"src/bin/keycloakify/generateStartKeycloakTestingContainer.ts",
|
84
84
|
"src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts",
|
85
|
+
"src/bin/keycloakify/generateTheme/generateMessageProperties.ts",
|
85
86
|
"src/bin/keycloakify/generateTheme/generateTheme.ts",
|
86
87
|
"src/bin/keycloakify/generateTheme/index.ts",
|
87
88
|
"src/bin/keycloakify/generateTheme/readExtraPageNames.ts",
|
@@ -360,6 +361,9 @@
|
|
360
361
|
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts",
|
361
362
|
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js",
|
362
363
|
"bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map",
|
364
|
+
"bin/keycloakify/generateTheme/generateMessageProperties.d.ts",
|
365
|
+
"bin/keycloakify/generateTheme/generateMessageProperties.js",
|
366
|
+
"bin/keycloakify/generateTheme/generateMessageProperties.js.map",
|
363
367
|
"bin/keycloakify/generateTheme/generateTheme.d.ts",
|
364
368
|
"bin/keycloakify/generateTheme/generateTheme.js",
|
365
369
|
"bin/keycloakify/generateTheme/generateTheme.js.map",
|
@@ -717,6 +721,7 @@
|
|
717
721
|
"src/bin/keycloakify/generateJavaStackFiles.ts",
|
718
722
|
"src/bin/keycloakify/generateStartKeycloakTestingContainer.ts",
|
719
723
|
"src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts",
|
724
|
+
"src/bin/keycloakify/generateTheme/generateMessageProperties.ts",
|
720
725
|
"src/bin/keycloakify/generateTheme/generateTheme.ts",
|
721
726
|
"src/bin/keycloakify/generateTheme/index.ts",
|
722
727
|
"src/bin/keycloakify/generateTheme/readExtraPageNames.ts",
|
@@ -907,12 +912,14 @@
|
|
907
912
|
"@storybook/manager-webpack5": "^6.5.13",
|
908
913
|
"@storybook/react": "^6.5.13",
|
909
914
|
"@storybook/testing-library": "^0.0.13",
|
915
|
+
"@types/babel__generator": "^7.6.4",
|
910
916
|
"@types/make-fetch-happen": "^10.0.1",
|
911
917
|
"@types/minimist": "^1.2.2",
|
912
918
|
"@types/node": "^18.15.3",
|
913
919
|
"@types/react": "^18.0.35",
|
914
920
|
"@types/react-dom": "^18.0.11",
|
915
921
|
"@types/yauzl": "^2.10.0",
|
922
|
+
"@types/yazl": "^2.4.2",
|
916
923
|
"concurrently": "^8.0.1",
|
917
924
|
"copyfiles": "^2.4.1",
|
918
925
|
"eslint-plugin-storybook": "^0.6.7",
|
@@ -934,8 +941,10 @@
|
|
934
941
|
"zod-to-json-schema": "^3.20.4"
|
935
942
|
},
|
936
943
|
"dependencies": {
|
944
|
+
"@babel/generator": "^7.22.9",
|
945
|
+
"@babel/parser": "^7.22.7",
|
946
|
+
"@babel/types": "^7.22.5",
|
937
947
|
"@octokit/rest": "^18.12.0",
|
938
|
-
"@types/yazl": "^2.4.2",
|
939
948
|
"cheerio": "^1.0.0-rc.5",
|
940
949
|
"cli-select": "^1.1.2",
|
941
950
|
"evt": "^2.4.18",
|
@@ -944,6 +953,7 @@
|
|
944
953
|
"minimist": "^1.2.6",
|
945
954
|
"path-browserify": "^1.0.1",
|
946
955
|
"react-markdown": "^5.0.3",
|
956
|
+
"recast": "^0.23.3",
|
947
957
|
"rfc4648": "^1.5.2",
|
948
958
|
"tsafe": "^1.6.0",
|
949
959
|
"yauzl": "^2.10.0",
|
@@ -0,0 +1,179 @@
|
|
1
|
+
import type { ThemeType } from "../generateFtl";
|
2
|
+
import { crawl } from "../../tools/crawl";
|
3
|
+
import { join as pathJoin } from "path";
|
4
|
+
import { readFileSync } from "fs";
|
5
|
+
import { symToStr } from "tsafe/symToStr";
|
6
|
+
import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
7
|
+
import * as recast from "recast";
|
8
|
+
import * as babelParser from "@babel/parser";
|
9
|
+
import babelGenerate from "@babel/generator";
|
10
|
+
import * as babelTypes from "@babel/types";
|
11
|
+
|
12
|
+
export function generateMessageProperties(params: {
|
13
|
+
themeSrcDirPath: string;
|
14
|
+
themeType: ThemeType;
|
15
|
+
}): { languageTag: string; propertiesFileSource: string }[] {
|
16
|
+
const { themeSrcDirPath, themeType } = params;
|
17
|
+
|
18
|
+
let files = crawl({
|
19
|
+
"dirPath": pathJoin(themeSrcDirPath, themeType),
|
20
|
+
"returnedPathsType": "absolute"
|
21
|
+
});
|
22
|
+
|
23
|
+
files = files.filter(file => {
|
24
|
+
const regex = /\.(js|ts|tsx)$/;
|
25
|
+
return regex.test(file);
|
26
|
+
});
|
27
|
+
|
28
|
+
files = files.sort((a, b) => {
|
29
|
+
const regex = /\.i18n\.(ts|js|tsx)$/;
|
30
|
+
const aIsI18nFile = regex.test(a);
|
31
|
+
const bIsI18nFile = regex.test(b);
|
32
|
+
return aIsI18nFile === bIsI18nFile ? 0 : aIsI18nFile ? -1 : 1;
|
33
|
+
});
|
34
|
+
|
35
|
+
files = files.sort((a, b) => a.length - b.length);
|
36
|
+
|
37
|
+
files = files.filter(file => readFileSync(file).toString("utf8").includes("createUseI18n"));
|
38
|
+
|
39
|
+
if (files.length === 0) {
|
40
|
+
return [];
|
41
|
+
}
|
42
|
+
|
43
|
+
const extraMessages = files
|
44
|
+
.map(file => {
|
45
|
+
const root = recast.parse(readFileSync(file).toString("utf8"), {
|
46
|
+
"parser": {
|
47
|
+
"parse": (code: string) => babelParser.parse(code, { "sourceType": "module", "plugins": ["typescript"] }),
|
48
|
+
"generator": babelGenerate,
|
49
|
+
"types": babelTypes
|
50
|
+
}
|
51
|
+
});
|
52
|
+
|
53
|
+
const codes: string[] = [];
|
54
|
+
|
55
|
+
recast.visit(root, {
|
56
|
+
"visitCallExpression": function (path) {
|
57
|
+
if (path.node.callee.type === "Identifier" && path.node.callee.name === "createUseI18n") {
|
58
|
+
codes.push(babelGenerate(path.node.arguments[0] as any).code);
|
59
|
+
}
|
60
|
+
this.traverse(path);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
|
64
|
+
return codes;
|
65
|
+
})
|
66
|
+
.flat()
|
67
|
+
.map(code => {
|
68
|
+
let extraMessages: { [languageTag: string]: Record<string, string> } = {};
|
69
|
+
|
70
|
+
try {
|
71
|
+
eval(`${symToStr({ extraMessages })} = ${code}`);
|
72
|
+
} catch {
|
73
|
+
console.warn(
|
74
|
+
[
|
75
|
+
"WARNING: Make sure that the first argument of createUseI18n can be evaluated in a javascript",
|
76
|
+
"runtime where only the node globals are available.",
|
77
|
+
"This is important because we need to put your i18n messages in messages_*.properties files",
|
78
|
+
"or they won't be available server side.",
|
79
|
+
"\n",
|
80
|
+
"The following code could not be evaluated:",
|
81
|
+
"\n",
|
82
|
+
code
|
83
|
+
].join(" ")
|
84
|
+
);
|
85
|
+
}
|
86
|
+
|
87
|
+
return extraMessages;
|
88
|
+
});
|
89
|
+
|
90
|
+
const languageTags = extraMessages
|
91
|
+
.map(extraMessage => Object.keys(extraMessage))
|
92
|
+
.flat()
|
93
|
+
.reduce(...removeDuplicates<string>());
|
94
|
+
|
95
|
+
const keyValueMapByLanguageTag: Record<string, Record<string, string>> = {};
|
96
|
+
|
97
|
+
for (const languageTag of languageTags) {
|
98
|
+
const keyValueMap: Record<string, string> = {};
|
99
|
+
|
100
|
+
for (const extraMessage of extraMessages) {
|
101
|
+
const keyValueMap_i = extraMessage[languageTag];
|
102
|
+
|
103
|
+
if (keyValueMap_i === undefined) {
|
104
|
+
continue;
|
105
|
+
}
|
106
|
+
|
107
|
+
for (const [key, value] of Object.entries(keyValueMap_i)) {
|
108
|
+
if (keyValueMap[key] !== undefined) {
|
109
|
+
console.warn(
|
110
|
+
[
|
111
|
+
"WARNING: The following key is defined multiple times:",
|
112
|
+
"\n",
|
113
|
+
key,
|
114
|
+
"\n",
|
115
|
+
"The following value will be ignored:",
|
116
|
+
"\n",
|
117
|
+
value,
|
118
|
+
"\n",
|
119
|
+
"The following value was already defined:",
|
120
|
+
"\n",
|
121
|
+
keyValueMap[key]
|
122
|
+
].join(" ")
|
123
|
+
);
|
124
|
+
continue;
|
125
|
+
}
|
126
|
+
|
127
|
+
keyValueMap[key] = value;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
keyValueMapByLanguageTag[languageTag] = keyValueMap;
|
132
|
+
}
|
133
|
+
|
134
|
+
const out: { languageTag: string; propertiesFileSource: string }[] = [];
|
135
|
+
|
136
|
+
for (const [languageTag, keyValueMap] of Object.entries(keyValueMapByLanguageTag)) {
|
137
|
+
const propertiesFileSource = Object.entries(keyValueMap)
|
138
|
+
.map(([key, value]) => `${key}=${escapeString(value)}`)
|
139
|
+
.join("\n");
|
140
|
+
|
141
|
+
out.push({
|
142
|
+
languageTag,
|
143
|
+
"propertiesFileSource": ["# This file was generated by keycloakify", "", "parent=base", "", propertiesFileSource, ""].join("\n")
|
144
|
+
});
|
145
|
+
}
|
146
|
+
|
147
|
+
return out;
|
148
|
+
}
|
149
|
+
|
150
|
+
// Convert a JavaScript string to UTF-16 encoding
|
151
|
+
function toUTF16(codePoint: number): string {
|
152
|
+
if (codePoint <= 0xffff) {
|
153
|
+
// BMP character
|
154
|
+
return "\\u" + codePoint.toString(16).padStart(4, "0");
|
155
|
+
} else {
|
156
|
+
// Non-BMP character
|
157
|
+
codePoint -= 0x10000;
|
158
|
+
let highSurrogate = (codePoint >> 10) + 0xd800;
|
159
|
+
let lowSurrogate = (codePoint % 0x400) + 0xdc00;
|
160
|
+
return "\\u" + highSurrogate.toString(16).padStart(4, "0") + "\\u" + lowSurrogate.toString(16).padStart(4, "0");
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
// Escapes special characters and converts unicode to UTF-16 encoding
|
165
|
+
function escapeString(str: string): string {
|
166
|
+
let escapedStr = "";
|
167
|
+
for (const char of [...str]) {
|
168
|
+
const codePoint = char.codePointAt(0);
|
169
|
+
if (!codePoint) continue;
|
170
|
+
if (char === "'") {
|
171
|
+
escapedStr += "''"; // double single quotes
|
172
|
+
} else if (codePoint > 0x7f) {
|
173
|
+
escapedStr += toUTF16(codePoint); // non-ascii characters
|
174
|
+
} else {
|
175
|
+
escapedStr += char;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
return escapedStr;
|
179
|
+
}
|
@@ -11,6 +11,7 @@ import { assert } from "tsafe/assert";
|
|
11
11
|
import { downloadKeycloakStaticResources } from "./downloadKeycloakStaticResources";
|
12
12
|
import { readFieldNameUsage } from "./readFieldNameUsage";
|
13
13
|
import { readExtraPagesNames } from "./readExtraPageNames";
|
14
|
+
import { generateMessageProperties } from "./generateMessageProperties";
|
14
15
|
|
15
16
|
export type BuildOptionsLike = BuildOptionsLike.Standalone | BuildOptionsLike.ExternalAssets;
|
16
17
|
|
@@ -173,6 +174,19 @@ export async function generateTheme(params: {
|
|
173
174
|
fs.writeFileSync(pathJoin(themeDirPath, pageId), Buffer.from(ftlCode, "utf8"));
|
174
175
|
});
|
175
176
|
|
177
|
+
generateMessageProperties({
|
178
|
+
themeSrcDirPath,
|
179
|
+
themeType
|
180
|
+
}).forEach(({ languageTag, propertiesFileSource }) => {
|
181
|
+
const messagesDirPath = pathJoin(themeDirPath, "messages");
|
182
|
+
|
183
|
+
fs.mkdirSync(pathJoin(themeDirPath, "messages"), { "recursive": true });
|
184
|
+
|
185
|
+
const propertiesFilePath = pathJoin(messagesDirPath, `messages_${languageTag}.properties`);
|
186
|
+
|
187
|
+
fs.writeFileSync(propertiesFilePath, Buffer.from(propertiesFileSource, "utf8"));
|
188
|
+
});
|
189
|
+
|
176
190
|
//TODO: Remove this block we left it for now only for backward compatibility
|
177
191
|
// we now have a separate script for this
|
178
192
|
copy_keycloak_resources_to_public: {
|