@joystick.js/node-canary 0.0.0-canary.62 → 0.0.0-canary.63
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/dist/app/index.js
CHANGED
|
@@ -38,6 +38,7 @@ import getTargetDatabaseConnection from "./databases/getTargetDatabaseConnection
|
|
|
38
38
|
import getAPIForDataFunctions from "../ssr/getAPIForDataFunctions.js";
|
|
39
39
|
import getBrowserSafeRequest from "./getBrowserSafeRequest.js";
|
|
40
40
|
import getDataFromComponent from "../ssr/getDataFromComponent.js";
|
|
41
|
+
import getTranslations from "./middleware/getTranslations.js";
|
|
41
42
|
process.setMaxListeners(0);
|
|
42
43
|
class App {
|
|
43
44
|
constructor(options = {}) {
|
|
@@ -166,17 +167,19 @@ class App {
|
|
|
166
167
|
initTests() {
|
|
167
168
|
if (process.env.NODE_ENV === "test") {
|
|
168
169
|
this.express.app.get("/api/_test/bootstrap", async (req, res) => {
|
|
169
|
-
const
|
|
170
|
+
const buildPath = `${process.cwd()}/.joystick/build`;
|
|
171
|
+
const Component = req?.query?.pathToComponent ? await importFile(`${buildPath}/${req?.query?.pathToComponent}`) : null;
|
|
170
172
|
if (Component) {
|
|
171
173
|
const componentInstance = Component();
|
|
172
174
|
const apiForDataFunctions = await getAPIForDataFunctions(req, this?.options?.api);
|
|
173
175
|
const browserSafeRequest = getBrowserSafeRequest(req);
|
|
174
176
|
const data = await getDataFromComponent(componentInstance, apiForDataFunctions, browserSafeRequest);
|
|
177
|
+
const translations = await getTranslations({ build: buildPath, page: req?.query?.pathToComponent }, req);
|
|
175
178
|
return res.status(200).send({
|
|
176
179
|
data: {
|
|
177
180
|
[data?.componentId]: data?.data
|
|
178
181
|
},
|
|
179
|
-
translations
|
|
182
|
+
translations
|
|
180
183
|
});
|
|
181
184
|
}
|
|
182
185
|
res.status(200).send({ data: {}, translations: {} });
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import importFile from "../../lib/importFile.js";
|
|
3
|
+
import { isObject } from "../../validation/lib/typeValidators.js";
|
|
4
|
+
import settings from "../../settings/index.js";
|
|
5
|
+
const getTranslationsFile = async (languageFilePath = "", paths = "") => {
|
|
6
|
+
const languageFile = await importFile(`${paths.build}/i18n/${languageFilePath}`);
|
|
7
|
+
const isValidLanguageFile = languageFile && isObject(languageFile);
|
|
8
|
+
if (isValidLanguageFile) {
|
|
9
|
+
const translationsForPage = languageFile[paths.page];
|
|
10
|
+
return translationsForPage ? translationsForPage : languageFile;
|
|
11
|
+
}
|
|
12
|
+
return {};
|
|
13
|
+
};
|
|
14
|
+
const getLanguagePreferenceRegexes = (userLanguage = "", browserLanguages = []) => {
|
|
15
|
+
let languagePreferences = [];
|
|
16
|
+
if (userLanguage) {
|
|
17
|
+
languagePreferences.push(userLanguage);
|
|
18
|
+
}
|
|
19
|
+
const filteredBrowserLanguages = browserLanguages?.filter((language) => {
|
|
20
|
+
return !language?.includes("*");
|
|
21
|
+
});
|
|
22
|
+
languagePreferences.push(...filteredBrowserLanguages);
|
|
23
|
+
languagePreferences.push(settings?.config?.i18n?.defaultLanguage);
|
|
24
|
+
return languagePreferences?.flatMap((language) => {
|
|
25
|
+
const variants = [language];
|
|
26
|
+
if (language?.length === 2) {
|
|
27
|
+
variants.push(`${language.substring(0, 2)}-`);
|
|
28
|
+
}
|
|
29
|
+
if (language?.length > 2) {
|
|
30
|
+
variants.push(`${language?.split("-")[0]}`);
|
|
31
|
+
variants.push(`${language?.split("-")[0]}-`);
|
|
32
|
+
}
|
|
33
|
+
return variants;
|
|
34
|
+
})?.map((languageString) => {
|
|
35
|
+
const lastCharacter = languageString[languageString.length - 1];
|
|
36
|
+
if (lastCharacter === "-") {
|
|
37
|
+
return new RegExp(`^${languageString}[A-Z]+.js`, "g");
|
|
38
|
+
}
|
|
39
|
+
return new RegExp(`^${languageString}.js`, "g");
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const parseBrowserLanguages = (languages = "") => {
|
|
43
|
+
const rawLanguages = languages.split(",");
|
|
44
|
+
return rawLanguages?.map((rawLanguage) => rawLanguage.split(";")[0]);
|
|
45
|
+
};
|
|
46
|
+
var getTranslations_default = async (paths = {}, req = {}) => {
|
|
47
|
+
const languageFiles = fs.readdirSync(`${paths.build}/i18n`);
|
|
48
|
+
const browserLanguages = parseBrowserLanguages(req?.headers["accept-language"]);
|
|
49
|
+
const languagePreferences = getLanguagePreferenceRegexes(req?.context?.user?.language, browserLanguages);
|
|
50
|
+
let matchingFile = null;
|
|
51
|
+
for (let i = 0; i < languagePreferences.length; i += 1) {
|
|
52
|
+
const languageRegex = languagePreferences[i];
|
|
53
|
+
const match = languageFiles.find((languageFile) => !!languageFile.match(languageRegex));
|
|
54
|
+
if (match) {
|
|
55
|
+
matchingFile = match;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const translationsFile = await getTranslationsFile(matchingFile, paths);
|
|
60
|
+
return translationsFile;
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
getTranslations_default as default
|
|
64
|
+
};
|
|
@@ -11,6 +11,7 @@ import getBuildPath from "../../lib/getBuildPath.js";
|
|
|
11
11
|
import escapeHTML from "../../lib/escapeHTML.js";
|
|
12
12
|
import escapeKeyValuePair from "../../lib/escapeKeyValuePair.js";
|
|
13
13
|
import importFile from "../../lib/importFile.js";
|
|
14
|
+
import getTranslations from "./getTranslations.js";
|
|
14
15
|
const generateHash = (input = "") => {
|
|
15
16
|
return crypto.createHash("sha256").update(input).digest("hex");
|
|
16
17
|
};
|
|
@@ -74,61 +75,6 @@ const getUrl = (request = {}) => {
|
|
|
74
75
|
path: escapeHTML(path)
|
|
75
76
|
};
|
|
76
77
|
};
|
|
77
|
-
const getTranslationsFile = async (languageFilePath = "", paths = "") => {
|
|
78
|
-
const languageFile = await importFile(`${paths.build}/i18n/${languageFilePath}`);
|
|
79
|
-
const isValidLanguageFile = languageFile && isObject(languageFile);
|
|
80
|
-
if (isValidLanguageFile) {
|
|
81
|
-
const translationsForPage = languageFile[paths.page];
|
|
82
|
-
return translationsForPage ? translationsForPage : languageFile;
|
|
83
|
-
}
|
|
84
|
-
return {};
|
|
85
|
-
};
|
|
86
|
-
const getTranslations = async (paths = {}, languagePreferences = []) => {
|
|
87
|
-
const languageFiles = fs.readdirSync(`${paths.build}/i18n`);
|
|
88
|
-
let matchingFile = null;
|
|
89
|
-
for (let i = 0; i < languagePreferences.length; i += 1) {
|
|
90
|
-
const languageRegex = languagePreferences[i];
|
|
91
|
-
const match = languageFiles.find((languageFile) => !!languageFile.match(languageRegex));
|
|
92
|
-
if (match) {
|
|
93
|
-
matchingFile = match;
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const translationsFile = await getTranslationsFile(matchingFile, paths);
|
|
98
|
-
return translationsFile;
|
|
99
|
-
};
|
|
100
|
-
const getLanguagePreferenceRegexes = (userLanguage = "", browserLanguages = []) => {
|
|
101
|
-
let languagePreferences = [];
|
|
102
|
-
if (userLanguage) {
|
|
103
|
-
languagePreferences.push(userLanguage);
|
|
104
|
-
}
|
|
105
|
-
const filteredBrowserLanguages = browserLanguages?.filter((language) => {
|
|
106
|
-
return !language?.includes("*");
|
|
107
|
-
});
|
|
108
|
-
languagePreferences.push(...filteredBrowserLanguages);
|
|
109
|
-
languagePreferences.push(settings?.config?.i18n?.defaultLanguage);
|
|
110
|
-
return languagePreferences?.flatMap((language) => {
|
|
111
|
-
const variants = [language];
|
|
112
|
-
if (language?.length === 2) {
|
|
113
|
-
variants.push(`${language.substring(0, 2)}-`);
|
|
114
|
-
}
|
|
115
|
-
if (language?.length > 2) {
|
|
116
|
-
variants.push(`${language?.split("-")[0]}`);
|
|
117
|
-
variants.push(`${language?.split("-")[0]}-`);
|
|
118
|
-
}
|
|
119
|
-
return variants;
|
|
120
|
-
})?.map((languageString) => {
|
|
121
|
-
const lastCharacter = languageString[languageString.length - 1];
|
|
122
|
-
if (lastCharacter === "-") {
|
|
123
|
-
return new RegExp(`^${languageString}[A-Z]+.js`, "g");
|
|
124
|
-
}
|
|
125
|
-
return new RegExp(`^${languageString}.js`, "g");
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
const parseBrowserLanguages = (languages = "") => {
|
|
129
|
-
const rawLanguages = languages.split(",");
|
|
130
|
-
return rawLanguages?.map((rawLanguage) => rawLanguage.split(";")[0]);
|
|
131
|
-
};
|
|
132
78
|
var render_default = (req, res, next, appInstance = {}) => {
|
|
133
79
|
res.render = async function(path = "", options = {}) {
|
|
134
80
|
const urlFormattedForCache = req?.url?.split("/")?.filter((part) => !!part)?.join("_");
|
|
@@ -170,9 +116,7 @@ var render_default = (req, res, next, appInstance = {}) => {
|
|
|
170
116
|
const Page = pageFile;
|
|
171
117
|
const layoutFile = layoutPath ? await importFile(layoutPath) : null;
|
|
172
118
|
const Layout = layoutFile;
|
|
173
|
-
const
|
|
174
|
-
const languagePreferenceRegexes = getLanguagePreferenceRegexes(req?.context?.user?.language, browserLanguages);
|
|
175
|
-
const translations = await getTranslations({ build: buildPath, page: path }, languagePreferenceRegexes);
|
|
119
|
+
const translations = await getTranslations({ build: buildPath, page: path }, req);
|
|
176
120
|
const url = getUrl(req);
|
|
177
121
|
const props = { ...options?.props || {} };
|
|
178
122
|
if (layoutPath && fs.existsSync(layoutPath)) {
|