@joystick.js/node-canary 0.0.0-canary.31 → 0.0.0-canary.310
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/_package.json +2 -2
- package/dist/action/class.js +21 -0
- package/dist/api/get.js +15 -13
- package/dist/api/set.js +15 -13
- package/dist/app/accounts/createMetadataTableColumns.js +12 -0
- package/dist/app/accounts/deleteUser.js +7 -0
- package/dist/app/accounts/generateSession.js +2 -4
- package/dist/app/accounts/getBrowserSafeUser.js +5 -2
- package/dist/app/accounts/hasLoginTokenExpired.js +1 -2
- package/dist/app/accounts/index.js +2 -0
- package/dist/app/accounts/login.js +6 -0
- package/dist/app/accounts/recoverPassword.js +3 -0
- package/dist/app/accounts/resetPassword.js +6 -0
- package/dist/app/accounts/signup.js +50 -7
- package/dist/app/accounts/verifyEmail.js +3 -0
- package/dist/app/cluster.js +26 -0
- package/dist/app/databases/generate_sql_from_object.js +45 -0
- package/dist/app/databases/mongodb/buildConnectionString.js +1 -1
- package/dist/app/databases/mongodb/createAccountsIndexes.js +18 -0
- package/dist/app/databases/mongodb/createSessionsIndexes.js +10 -0
- package/dist/app/databases/mongodb/index.js +1 -1
- package/dist/app/databases/mongodb/queries/accounts.js +8 -1
- package/dist/app/databases/mongodb/queries/queues.js +40 -26
- package/dist/app/databases/mongodb/queries/sessions.js +26 -0
- package/dist/app/databases/postgresql/createSessionsIndexes.js +10 -0
- package/dist/app/databases/postgresql/createSessionsTables.js +14 -0
- package/dist/app/databases/postgresql/handleCleanupQueues.js +35 -0
- package/dist/app/databases/postgresql/index.js +66 -4
- package/dist/app/databases/postgresql/queries/accounts.js +5 -2
- package/dist/app/databases/postgresql/queries/queues.js +69 -36
- package/dist/app/databases/postgresql/queries/sessions.js +43 -0
- package/dist/app/databases/queryMap.js +6 -2
- package/dist/app/databases/stringToSnakeCase.js +6 -0
- package/dist/app/getBrowserSafeRequest.js +3 -2
- package/dist/app/index.js +222 -75
- package/dist/app/initExpress.js +1 -1
- package/dist/app/middleware/csp.js +2 -2
- package/dist/app/middleware/getTranslations.js +64 -0
- package/dist/app/middleware/get_insecure_landing_page_html.js +71 -0
- package/dist/app/middleware/hmr/client.js +13 -9
- package/dist/app/middleware/index.js +6 -5
- package/dist/app/middleware/insecure.js +3 -4
- package/dist/app/middleware/render.js +11 -68
- package/dist/app/middleware/session.js +12 -11
- package/dist/app/queues/index.js +64 -28
- package/dist/app/registerGetters.js +5 -6
- package/dist/app/registerSetters.js +5 -6
- package/dist/app/runGetter.js +17 -5
- package/dist/app/runSessionQuery.js +15 -0
- package/dist/app/runSetter.js +17 -5
- package/dist/app/sanitizeAPIResponse.js +1 -1
- package/dist/app/validateSession.js +8 -3
- package/dist/app/validateUploaderOptions.js +3 -3
- package/dist/app/validateUploads.js +12 -1
- package/dist/email/send.js +7 -1
- package/dist/email/templates/reset-password.js +0 -1
- package/dist/fixture/index.js +40 -0
- package/dist/index.js +19 -0
- package/dist/lib/escapeKeyValuePair.js +13 -0
- package/dist/lib/formatAPIError.js +0 -1
- package/dist/lib/getBuildPath.js +1 -1
- package/dist/lib/getSSLCertificates.js +3 -3
- package/dist/lib/importFile.js +7 -0
- package/dist/lib/isValidJSONString.js +1 -1
- package/dist/lib/log.js +0 -3
- package/dist/lib/objectToSQLKeysString.js +1 -1
- package/dist/lib/objectToSQLValuesString.js +1 -1
- package/dist/lib/serializeQueryParameters.js +1 -1
- package/dist/lib/timestamps.js +47 -0
- package/dist/lib/wait.js +8 -0
- package/dist/push/logs/index.js +10 -3
- package/dist/settings/load.js +3 -5
- package/dist/ssr/compileCSS.js +4 -4
- package/dist/ssr/findComponentInTree.js +1 -1
- package/dist/ssr/getAPIForDataFunctions.js +35 -0
- package/dist/ssr/getDataFromComponent.js +15 -0
- package/dist/ssr/index.js +19 -45
- package/dist/ssr/replaceWhenTags.js +2 -3
- package/dist/ssr/setHeadTagsInHTML.js +3 -3
- package/dist/test/index.js +9 -0
- package/dist/test/trackFunctionCall.js +17 -0
- package/dist/validation/inputWithSchema/index.js +3 -3
- package/dist/validation/schema/index.js +5 -5
- package/dist/websockets/index.js +4 -0
- package/getSanitizedContext.js +43 -0
- package/package.json +2 -1
- package/dist/app/accounts/roles/index.test.js +0 -123
- package/dist/app/index.test.js +0 -575
- package/dist/app/middleware/sanitizeRequestParameters.js +0 -21
- package/dist/email/send.test.js +0 -37
- package/dist/validation/index.test.js +0 -463
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import log from "../lib/log";
|
|
2
|
+
import trackFunctionCall from "../test/trackFunctionCall.js";
|
|
2
3
|
const handleCheckUpload = ({
|
|
3
4
|
uploaderName,
|
|
4
5
|
maxSizeInMegabytes,
|
|
@@ -49,6 +50,16 @@ const formatUploads = ({
|
|
|
49
50
|
try {
|
|
50
51
|
return Promise.all(uploads.map(async (upload) => {
|
|
51
52
|
const fileExtension = upload?.mimeType?.split("/").pop();
|
|
53
|
+
const fileNameIsFunction = typeof uploaderOptions?.fileName === "function";
|
|
54
|
+
if (fileNameIsFunction) {
|
|
55
|
+
trackFunctionCall(`node.uploaders.${uploaderName}.fileName`, [{
|
|
56
|
+
input,
|
|
57
|
+
fileName: upload?.originalname,
|
|
58
|
+
fileSize: upload?.size,
|
|
59
|
+
fileExtension,
|
|
60
|
+
mimeType: upload?.mimetype
|
|
61
|
+
}]);
|
|
62
|
+
}
|
|
52
63
|
return {
|
|
53
64
|
uploaderName,
|
|
54
65
|
providers: uploaderOptions?.providers,
|
|
@@ -56,7 +67,7 @@ const formatUploads = ({
|
|
|
56
67
|
s3: uploaderOptions?.s3,
|
|
57
68
|
maxSizeInMegabytes: typeof uploaderOptions?.maxSizeInMegabytes === "function" ? await uploaderOptions?.maxSizeInMegabytes({ input, upload }) : uploaderOptions?.maxSizeInMegabytes,
|
|
58
69
|
mimeTypes: uploaderOptions?.mimeTypes,
|
|
59
|
-
fileName:
|
|
70
|
+
fileName: fileNameIsFunction ? uploaderOptions.fileName({ input, fileName: upload?.originalname, fileSize: upload?.size, fileExtension, mimeType: upload?.mimetype }) : upload?.originalname,
|
|
60
71
|
originalFileName: upload?.originalname,
|
|
61
72
|
fileSize: upload?.size,
|
|
62
73
|
mimeType: upload?.mimetype,
|
package/dist/email/send.js
CHANGED
|
@@ -7,7 +7,13 @@ import settings from "../settings";
|
|
|
7
7
|
import validateSMTPSettings from "./validateSMTPSettings";
|
|
8
8
|
import render from "./render";
|
|
9
9
|
import getBuildPath from "../lib/getBuildPath";
|
|
10
|
-
|
|
10
|
+
import trackFunctionCall from "../test/trackFunctionCall.js";
|
|
11
|
+
var send_default = async (args) => {
|
|
12
|
+
const { template: templateName, props, base: baseName, ...restOfOptions } = args;
|
|
13
|
+
if (process.env.NODE_ENV === "test") {
|
|
14
|
+
trackFunctionCall("node.email.send", [args]);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
11
17
|
const validSMTPSettings = validateSMTPSettings(settings?.config?.email?.smtp);
|
|
12
18
|
if (!validSMTPSettings) {
|
|
13
19
|
console.warn(chalk.redBright("Cannot send email, invalid SMTP settings."));
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import ui from "@joystick.js/ui";
|
|
2
2
|
const ResetPassword = ui.component({
|
|
3
|
-
id: process.env.NODE_ENV === "test" ? "testComponent1234" : null,
|
|
4
3
|
render: ({ props }) => {
|
|
5
4
|
return `
|
|
6
5
|
<p>A password reset was requested for this email address (${props.emailAddress}). If you requested this reset, click the link below to reset your password:</p>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class Fixture {
|
|
2
|
+
constructor(options = {}) {
|
|
3
|
+
this.options = options;
|
|
4
|
+
this.quantity = options?.quantity;
|
|
5
|
+
this.run = this.run.bind(this);
|
|
6
|
+
return this.run;
|
|
7
|
+
}
|
|
8
|
+
async run(input = {}) {
|
|
9
|
+
this.input = input;
|
|
10
|
+
const skip = typeof this?.options?.skip === "function" ? await this.options.skip(this, input) : false;
|
|
11
|
+
let dataToCreate = [];
|
|
12
|
+
if (!skip) {
|
|
13
|
+
dataToCreate = await this.generateDataToCreate(input);
|
|
14
|
+
if (typeof this?.options?.onCreate === "function") {
|
|
15
|
+
await this.options.onCreate(this, dataToCreate, (onAfterCreateEachInput = {}) => {
|
|
16
|
+
return this?.options?.onAfterCreateEach(this, onAfterCreateEachInput, input);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (typeof this?.options?.onAfterCreateAll === "function") {
|
|
21
|
+
this.options.onAfterCreateAll(this, dataToCreate, input);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async generateDataToCreate(input = {}) {
|
|
25
|
+
const data = [];
|
|
26
|
+
for (let i = 0; i < this?.quantity; i += 1) {
|
|
27
|
+
if (typeof this?.options?.template === "function") {
|
|
28
|
+
const dataToCreate = await this.options?.template(this, i, input);
|
|
29
|
+
data.push(dataToCreate);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
var fixture_default = (options = {}) => {
|
|
36
|
+
return new Fixture(options);
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
fixture_default as default
|
|
40
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -4,22 +4,29 @@ import { dirname } from "path";
|
|
|
4
4
|
import sanitizeHTML from "sanitize-html";
|
|
5
5
|
import _accounts from "./app/accounts";
|
|
6
6
|
import _action from "./action/index.js";
|
|
7
|
+
import _fixture from "./fixture/index.js";
|
|
8
|
+
import _test from "./test/index.js";
|
|
7
9
|
import _websockets from "./websockets";
|
|
8
10
|
import api from "./api/index.js";
|
|
9
11
|
import app from "./app/index.js";
|
|
10
12
|
import generateId from "./lib/generateId.js";
|
|
13
|
+
import _generate_sql_from_object from "./app/databases/generate_sql_from_object";
|
|
11
14
|
import getOrigin from "./api/getOrigin";
|
|
12
15
|
import loadSettings from "./settings/load";
|
|
13
16
|
import pushLogs from "./push/logs/index.js";
|
|
14
17
|
import nodeUrlPolyfills from "./lib/nodeUrlPolyfills.js";
|
|
15
18
|
import sendEmail from "./email/send";
|
|
19
|
+
const { readFile } = fs.promises;
|
|
16
20
|
if (process.env.NODE_ENV !== "development" && process.env.IS_PUSH_DEPLOYED) {
|
|
17
21
|
pushLogs();
|
|
18
22
|
}
|
|
23
|
+
const generate_sql_from_object = _generate_sql_from_object;
|
|
19
24
|
const accounts = _accounts;
|
|
20
25
|
const action = _action;
|
|
26
|
+
const fixture = _fixture;
|
|
21
27
|
const get = api.get;
|
|
22
28
|
const set = api.set;
|
|
29
|
+
const test = _test;
|
|
23
30
|
const email = {
|
|
24
31
|
send: sendEmail
|
|
25
32
|
};
|
|
@@ -36,6 +43,11 @@ const __dirname = nodeUrlPolyfills.__dirname;
|
|
|
36
43
|
const id = generateId;
|
|
37
44
|
const origin = getOrigin();
|
|
38
45
|
const settings = loadSettings();
|
|
46
|
+
const push = {
|
|
47
|
+
continent: fs.existsSync("/root/push/continent.txt") ? (await readFile("/root/push/continent.txt", "utf-8"))?.replace("\n", "") : null,
|
|
48
|
+
instance_token: fs.existsSync("/root/push/instance_token.txt") ? (await readFile("/root/push/instance_token.txt", "utf-8"))?.replace("\n", "") : null,
|
|
49
|
+
current_version: fs.existsSync("/root/push/versions/current") ? (await readFile("/root/push/versions/current", "utf-8"))?.replace("\n", "") : null
|
|
50
|
+
};
|
|
39
51
|
global.joystick = {
|
|
40
52
|
id: generateId,
|
|
41
53
|
emitters: {},
|
|
@@ -51,9 +63,12 @@ var src_default = {
|
|
|
51
63
|
action,
|
|
52
64
|
app,
|
|
53
65
|
email,
|
|
66
|
+
fixture,
|
|
67
|
+
generate_sql_from_object,
|
|
54
68
|
get,
|
|
55
69
|
id,
|
|
56
70
|
origin,
|
|
71
|
+
push,
|
|
57
72
|
sanitize,
|
|
58
73
|
set,
|
|
59
74
|
settings,
|
|
@@ -67,10 +82,14 @@ export {
|
|
|
67
82
|
action,
|
|
68
83
|
src_default as default,
|
|
69
84
|
email,
|
|
85
|
+
fixture,
|
|
86
|
+
generate_sql_from_object,
|
|
70
87
|
get,
|
|
71
88
|
id,
|
|
72
89
|
origin,
|
|
90
|
+
push,
|
|
73
91
|
sanitize,
|
|
74
92
|
set,
|
|
93
|
+
test,
|
|
75
94
|
websockets
|
|
76
95
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import escapeHTML from "./escapeHTML.js";
|
|
2
|
+
var escapeKeyValuePair_default = (target = {}) => {
|
|
3
|
+
const parameters = Object.entries(target || {});
|
|
4
|
+
for (let i = 0; i < parameters?.length; i += 1) {
|
|
5
|
+
const [key, value] = parameters[i];
|
|
6
|
+
delete target[key];
|
|
7
|
+
target[escapeHTML(key)] = escapeHTML(value);
|
|
8
|
+
}
|
|
9
|
+
return target;
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
escapeKeyValuePair_default as default
|
|
13
|
+
};
|
package/dist/lib/getBuildPath.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
var getBuildPath_default = () => {
|
|
3
|
-
if (process.env.NODE_ENV
|
|
3
|
+
if (["development", "test"].includes(process.env.NODE_ENV) || fs.existsSync(".joystick/build")) {
|
|
4
4
|
return ".joystick/build/";
|
|
5
5
|
}
|
|
6
6
|
return "";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
var getSSLCertificates_default = (ssl = null) => {
|
|
3
|
-
const pushCertificatePath = "/
|
|
4
|
-
const pushKeyPath = "/
|
|
3
|
+
const pushCertificatePath = "/root/push/certs/cert.pem";
|
|
4
|
+
const pushKeyPath = "/root/push/certs/key.pem";
|
|
5
5
|
const certPath = process.env.IS_PUSH_DEPLOYED ? pushCertificatePath : ssl?.cert || null;
|
|
6
6
|
const keyPath = process.env.IS_PUSH_DEPLOYED ? pushKeyPath : ssl?.key || null;
|
|
7
7
|
const certExists = fs.existsSync(certPath);
|
|
8
8
|
const keyExists = fs.existsSync(keyPath);
|
|
9
|
-
if (process.env.NODE_ENV
|
|
9
|
+
if (["development", "test"].includes(process.env.NODE_ENV) || !certExists || !keyExists) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
return {
|
package/dist/lib/log.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isObject } from "../validation/lib/typeValidators";
|
|
2
2
|
import camelPascalToSnake from "./camelPascalToSnake";
|
|
3
3
|
const objectToSQLKeys = (objectToConvert = {}, target = []) => {
|
|
4
|
-
const keyValuePairs = Object.entries(objectToConvert);
|
|
4
|
+
const keyValuePairs = Object.entries(objectToConvert || {});
|
|
5
5
|
keyValuePairs.forEach(([key, value]) => {
|
|
6
6
|
if (isObject(value)) {
|
|
7
7
|
target.push(camelPascalToSnake(key));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isObject } from "../validation/lib/typeValidators";
|
|
2
2
|
const objectToSQLValues = (objectToConvert = {}, target = []) => {
|
|
3
|
-
const keyValuePairs = Object.entries(objectToConvert);
|
|
3
|
+
const keyValuePairs = Object.entries(objectToConvert || {});
|
|
4
4
|
keyValuePairs.forEach(([_key, value]) => {
|
|
5
5
|
if (isObject(value)) {
|
|
6
6
|
objectToSQLValues(value, target);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
var timestamps_default = {
|
|
2
|
+
get_current_time: (options2 = {}) => {
|
|
3
|
+
const timestamp = new Date().toISOString();
|
|
4
|
+
return options2?.mongodb_ttl ? new Date(timestamp) : timestamp;
|
|
5
|
+
},
|
|
6
|
+
get_future_time: (unit = "", quantity = 0, options2 = {}) => {
|
|
7
|
+
const date = new Date();
|
|
8
|
+
switch (unit) {
|
|
9
|
+
case "seconds":
|
|
10
|
+
date.setSeconds(date.getSeconds() + quantity);
|
|
11
|
+
return options2?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
12
|
+
case "minutes":
|
|
13
|
+
date.setMinutes(date.getMinutes() + quantity);
|
|
14
|
+
return options2?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
15
|
+
case "hours":
|
|
16
|
+
date.setHours(date.getHours() + quantity);
|
|
17
|
+
return options2?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
18
|
+
case "days":
|
|
19
|
+
date.setHours(date.getHours() + quantity * 24);
|
|
20
|
+
return options2?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
21
|
+
default:
|
|
22
|
+
return options2?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
get_past_time: (unit = "", quantity = 0) => {
|
|
26
|
+
const date = new Date();
|
|
27
|
+
switch (unit) {
|
|
28
|
+
case "seconds":
|
|
29
|
+
date.setSeconds(date.getSeconds() - quantity);
|
|
30
|
+
return options?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
31
|
+
case "minutes":
|
|
32
|
+
date.setMinutes(date.getMinutes() - quantity);
|
|
33
|
+
return options?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
34
|
+
case "hours":
|
|
35
|
+
date.setHours(date.getHours() - quantity);
|
|
36
|
+
return options?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
37
|
+
case "days":
|
|
38
|
+
date.setHours(date.getHours() - quantity * 24);
|
|
39
|
+
return options?.mongodb_ttl ? new Date(date.toISOString()) : date.toISOString();
|
|
40
|
+
default:
|
|
41
|
+
return options?.mongodb_ttl ? new Date(new Date().toISOString()) : new Date().toISOString();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
timestamps_default as default
|
|
47
|
+
};
|
package/dist/lib/wait.js
ADDED
package/dist/push/logs/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import dayjs from "dayjs";
|
|
2
2
|
import TuskDB from "@tuskdb/node";
|
|
3
|
+
import timestamps from "../../lib/timestamps";
|
|
3
4
|
const captureLog = (callback = null) => {
|
|
4
5
|
process.stdout.write = (data) => {
|
|
5
6
|
if (callback) {
|
|
@@ -13,7 +14,12 @@ const captureLog = (callback = null) => {
|
|
|
13
14
|
};
|
|
14
15
|
process.on("uncaughtException", (error) => {
|
|
15
16
|
if (callback) {
|
|
16
|
-
callback("uncaughtException", error);
|
|
17
|
+
callback("uncaughtException", error?.message || "Uncaught Exception");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
process.on("unhandledRejection", (error) => {
|
|
21
|
+
if (callback) {
|
|
22
|
+
callback("unhandledRejection", error?.message || "Unhandled Rejection");
|
|
17
23
|
}
|
|
18
24
|
});
|
|
19
25
|
};
|
|
@@ -21,6 +27,7 @@ const writeLogsToDisk = () => {
|
|
|
21
27
|
const db = new TuskDB({
|
|
22
28
|
file: {
|
|
23
29
|
development: "logs.json",
|
|
30
|
+
staging: "/root/logs.json",
|
|
24
31
|
production: "/root/logs.json"
|
|
25
32
|
}[process.env.NODE_ENV || "development"],
|
|
26
33
|
collections: {
|
|
@@ -32,14 +39,14 @@ const writeLogsToDisk = () => {
|
|
|
32
39
|
case "stdout":
|
|
33
40
|
return db.collection("logs").insertOne({
|
|
34
41
|
error: false,
|
|
35
|
-
timestamp:
|
|
42
|
+
timestamp: timestamps.get_current_time(),
|
|
36
43
|
data
|
|
37
44
|
});
|
|
38
45
|
case "stderr":
|
|
39
46
|
case "uncaughtException":
|
|
40
47
|
return db.collection("logs").insertOne({
|
|
41
48
|
error: true,
|
|
42
|
-
timestamp:
|
|
49
|
+
timestamp: timestamps.get_current_time(),
|
|
43
50
|
data
|
|
44
51
|
});
|
|
45
52
|
default:
|
package/dist/settings/load.js
CHANGED
package/dist/ssr/compileCSS.js
CHANGED
|
@@ -30,7 +30,7 @@ var compileCSS_default = (css = "", componentInstance = {}) => {
|
|
|
30
30
|
`;
|
|
31
31
|
}
|
|
32
32
|
if (hasMinRules && hasMinWidthRules) {
|
|
33
|
-
const minWidthRules = Object.entries(css?.min?.width);
|
|
33
|
+
const minWidthRules = Object.entries(css?.min?.width || {});
|
|
34
34
|
for (let i = 0; i < minWidthRules.length; i += 1) {
|
|
35
35
|
const [minWidth, minWidthRule] = minWidthRules[i];
|
|
36
36
|
compiledCSS += `
|
|
@@ -41,7 +41,7 @@ var compileCSS_default = (css = "", componentInstance = {}) => {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
if (hasMinRules && hasMinHeightRules) {
|
|
44
|
-
const minHeightRules = Object.entries(css?.min?.height);
|
|
44
|
+
const minHeightRules = Object.entries(css?.min?.height || {});
|
|
45
45
|
for (let i = 0; i < minHeightRules.length; i += 1) {
|
|
46
46
|
const [minHeight, minHeightRule] = minHeightRules[i];
|
|
47
47
|
compiledCSS += `
|
|
@@ -52,7 +52,7 @@ var compileCSS_default = (css = "", componentInstance = {}) => {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
if (hasMaxRules && hasMaxWidthRules) {
|
|
55
|
-
const maxWidthRules = Object.entries(css?.max?.width);
|
|
55
|
+
const maxWidthRules = Object.entries(css?.max?.width || {});
|
|
56
56
|
for (let i = 0; i < maxWidthRules.length; i += 1) {
|
|
57
57
|
const [maxWidth, maxWidthRule] = maxWidthRules[i];
|
|
58
58
|
compiledCSS += `
|
|
@@ -63,7 +63,7 @@ var compileCSS_default = (css = "", componentInstance = {}) => {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
if (hasMaxRules && hasMaxHeightRules) {
|
|
66
|
-
const maxHeightRules = Object.entries(css?.max?.height);
|
|
66
|
+
const maxHeightRules = Object.entries(css?.max?.height || {});
|
|
67
67
|
for (let i = 0; i < maxHeightRules.length; i += 1) {
|
|
68
68
|
const [maxHeight, maxHeightRule] = maxHeightRules[i];
|
|
69
69
|
compiledCSS += `
|
|
@@ -4,7 +4,7 @@ const isObject = (value) => {
|
|
|
4
4
|
const findComponentInTree = (tree = {}, componentId = "", callback = {}) => {
|
|
5
5
|
const isTree = tree && tree.id;
|
|
6
6
|
if (isObject(tree) && isTree) {
|
|
7
|
-
const entries = Object.entries(tree);
|
|
7
|
+
const entries = Object.entries(tree || {});
|
|
8
8
|
for (let i = 0; i < entries.length; i += 1) {
|
|
9
9
|
const [treeKey, treeValue] = entries[i];
|
|
10
10
|
if (treeKey === "id" && treeValue === componentId) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import get from "../api/get";
|
|
2
|
+
import set from "../api/set";
|
|
3
|
+
var getAPIForDataFunctions_default = (req = {}, api = {}) => {
|
|
4
|
+
try {
|
|
5
|
+
return {
|
|
6
|
+
get: (getterName = "", getterOptions = {}) => {
|
|
7
|
+
return get({
|
|
8
|
+
getterName,
|
|
9
|
+
getterOptions: api?.getters[getterName] || {},
|
|
10
|
+
skip: getterOptions?.skip,
|
|
11
|
+
input: getterOptions?.input,
|
|
12
|
+
output: getterOptions?.output,
|
|
13
|
+
context: req?.context,
|
|
14
|
+
APIOptions: api?.options
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
set: (setterName = "", setterOptions = {}) => {
|
|
18
|
+
return set({
|
|
19
|
+
setterName,
|
|
20
|
+
setterOptions: api?.setters[setterName] || {},
|
|
21
|
+
skip: setterOptions?.skip,
|
|
22
|
+
input: setterOptions?.input,
|
|
23
|
+
output: setterOptions?.output,
|
|
24
|
+
context: req?.context,
|
|
25
|
+
APIOptions: api?.options
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
} catch (exception) {
|
|
30
|
+
throw new Error(`[ssr.getAPIForDataFunctions] ${exception.message}`);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
export {
|
|
34
|
+
getAPIForDataFunctions_default as default
|
|
35
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var getDataFromComponent_default = async (componentInstance = {}, api = {}, browserSafeUser = {}, browserSafeRequest = {}) => {
|
|
2
|
+
try {
|
|
3
|
+
componentInstance.user = browserSafeUser;
|
|
4
|
+
const data = await componentInstance.handleFetchData(api, browserSafeRequest, {}, componentInstance);
|
|
5
|
+
return {
|
|
6
|
+
componentId: componentInstance?.id,
|
|
7
|
+
data
|
|
8
|
+
};
|
|
9
|
+
} catch (exception) {
|
|
10
|
+
throw new Error(`[ssr.getDataFromComponent] ${exception.message}`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
export {
|
|
14
|
+
getDataFromComponent_default as default
|
|
15
|
+
};
|
package/dist/ssr/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
-
import { __package } from "../index.js";
|
|
2
|
+
import joystick, { __package } from "../index.js";
|
|
3
3
|
import get from "../api/get";
|
|
4
4
|
import set from "../api/set";
|
|
5
5
|
import getBrowserSafeRequest from "../app/getBrowserSafeRequest";
|
|
@@ -8,6 +8,9 @@ import getCSSFromTree from "./getCSSFromTree";
|
|
|
8
8
|
import replaceWhenTags from "./replaceWhenTags";
|
|
9
9
|
import setHeadTagsInHTML from "./setHeadTagsInHTML";
|
|
10
10
|
import { parseHTML } from "linkedom";
|
|
11
|
+
import getDataFromComponent from "./getDataFromComponent.js";
|
|
12
|
+
import getAPIForDataFunctions from "./getAPIForDataFunctions.js";
|
|
13
|
+
import getBrowserSafeUser from "../app/accounts/getBrowserSafeUser.js";
|
|
11
14
|
const injectCSSIntoHTML = (html, baseCSS = "", css = "") => {
|
|
12
15
|
try {
|
|
13
16
|
return html.replace("${css}", css).replace("${globalCSS}", `<style>${baseCSS || ""}</style>`).replace("${componentCSS}", css);
|
|
@@ -21,6 +24,7 @@ const handleHTMLReplacementsForApp = ({
|
|
|
21
24
|
componentInstance = {},
|
|
22
25
|
dataFromComponent,
|
|
23
26
|
dataForClient = {},
|
|
27
|
+
browserSafeUser = {},
|
|
24
28
|
browserSafeRequest = {},
|
|
25
29
|
props = {},
|
|
26
30
|
translations = {},
|
|
@@ -44,9 +48,10 @@ const handleHTMLReplacementsForApp = ({
|
|
|
44
48
|
window.__joystick_ssr__ = true;
|
|
45
49
|
${process.env.NODE_ENV === "development" ? `window.__joystick_hmr_port__ = ${parseInt(process.env.PORT, 10) + 1};` : ""}
|
|
46
50
|
window.__joystick_data__ = ${JSON.stringify({
|
|
47
|
-
[componentInstance.id]: dataFromComponent?.data
|
|
51
|
+
[componentInstance.id]: dataFromComponent?.data,
|
|
48
52
|
...dataForClient || {}
|
|
49
53
|
})};
|
|
54
|
+
window.__joystick_user__ = ${JSON.stringify(browserSafeUser)};
|
|
50
55
|
window.__joystick_req__ = ${JSON.stringify(browserSafeRequest)};
|
|
51
56
|
window.__joystick_ssr_props__ = ${JSON.stringify(props)};
|
|
52
57
|
window.__joystick_i18n__ = ${JSON.stringify(translations)};
|
|
@@ -90,6 +95,7 @@ const getHTMLWithTargetReplacements = ({
|
|
|
90
95
|
baseHTML = "",
|
|
91
96
|
dataFromComponent = {},
|
|
92
97
|
dataForClient = {},
|
|
98
|
+
browserSafeUser = {},
|
|
93
99
|
browserSafeRequest = {},
|
|
94
100
|
props = {},
|
|
95
101
|
translations = {},
|
|
@@ -112,6 +118,7 @@ const getHTMLWithTargetReplacements = ({
|
|
|
112
118
|
componentHTML,
|
|
113
119
|
dataFromComponent,
|
|
114
120
|
dataForClient,
|
|
121
|
+
browserSafeUser,
|
|
115
122
|
browserSafeRequest,
|
|
116
123
|
props,
|
|
117
124
|
translations,
|
|
@@ -146,6 +153,7 @@ const processHTML = ({
|
|
|
146
153
|
isEmailRender = false,
|
|
147
154
|
emailSubject = "",
|
|
148
155
|
emailPreheader = "",
|
|
156
|
+
browserSafeUser = {},
|
|
149
157
|
browserSafeRequest = {},
|
|
150
158
|
props = {},
|
|
151
159
|
translations = {},
|
|
@@ -169,6 +177,7 @@ const processHTML = ({
|
|
|
169
177
|
dataFromComponent,
|
|
170
178
|
dataFromTree,
|
|
171
179
|
dataForClient,
|
|
180
|
+
browserSafeUser,
|
|
172
181
|
browserSafeRequest,
|
|
173
182
|
props,
|
|
174
183
|
translations,
|
|
@@ -200,7 +209,7 @@ const getBaseCSS = (baseHTMLName = "") => {
|
|
|
200
209
|
};
|
|
201
210
|
const addAttributesToDOM = (dom = {}, attributes = {}) => {
|
|
202
211
|
try {
|
|
203
|
-
const attributeKeys = Object.keys(attributes);
|
|
212
|
+
const attributeKeys = Object.keys(attributes || {});
|
|
204
213
|
const attributeKeysWithoutClassList = attributeKeys?.filter((key) => key !== "class");
|
|
205
214
|
if (Array.isArray(attributes?.class?.list)) {
|
|
206
215
|
if (attributes?.class?.method === "replace") {
|
|
@@ -290,17 +299,6 @@ const buildTreeForComponent = (componentInstance = {}, ssrTree = {}, translation
|
|
|
290
299
|
throw new Error(`[ssr.buildTreeForComponent] ${exception.message}`);
|
|
291
300
|
}
|
|
292
301
|
};
|
|
293
|
-
const getDataFromComponent = async (componentInstance = {}, api = {}, browserSafeRequest = {}) => {
|
|
294
|
-
try {
|
|
295
|
-
const data = await componentInstance.handleFetchData(api, browserSafeRequest, {}, componentInstance);
|
|
296
|
-
return {
|
|
297
|
-
componentId: componentInstance?.id,
|
|
298
|
-
data
|
|
299
|
-
};
|
|
300
|
-
} catch (exception) {
|
|
301
|
-
throw new Error(`[ssr.getDataFromComponent] ${exception.message}`);
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
302
|
const getTreeForSSR = (componentInstance = {}) => {
|
|
305
303
|
try {
|
|
306
304
|
return {
|
|
@@ -321,34 +319,6 @@ const getComponentInstance = (Component, options = {}) => {
|
|
|
321
319
|
throw new Error(`[ssr.getComponentInstance] ${exception.message}`);
|
|
322
320
|
}
|
|
323
321
|
};
|
|
324
|
-
const getAPIForDataFunctions = (req = {}, api = {}) => {
|
|
325
|
-
try {
|
|
326
|
-
return {
|
|
327
|
-
get: (getterName = "", getterOptions = {}) => {
|
|
328
|
-
return get({
|
|
329
|
-
getterName,
|
|
330
|
-
getterOptions: api?.getters[getterName] || {},
|
|
331
|
-
input: getterOptions?.input,
|
|
332
|
-
output: getterOptions?.output,
|
|
333
|
-
context: req?.context,
|
|
334
|
-
APIOptions: api?.options
|
|
335
|
-
});
|
|
336
|
-
},
|
|
337
|
-
set: (setterName = "", setterOptions = {}) => {
|
|
338
|
-
return set({
|
|
339
|
-
setterName,
|
|
340
|
-
setterOptions: api?.setters[setterName] || {},
|
|
341
|
-
input: setterOptions?.input,
|
|
342
|
-
output: setterOptions?.output,
|
|
343
|
-
context: req?.context,
|
|
344
|
-
APIOptions: api?.options
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
} catch (exception) {
|
|
349
|
-
throw new Error(`[ssr.getAPIForDataFunctions] ${exception.message}`);
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
322
|
const validateOptions = (options) => {
|
|
353
323
|
try {
|
|
354
324
|
if (!options)
|
|
@@ -363,6 +333,7 @@ const ssr = async (options, { resolve, reject }) => {
|
|
|
363
333
|
try {
|
|
364
334
|
validateOptions(options);
|
|
365
335
|
const apiForDataFunctions = getAPIForDataFunctions(options.req, options?.api);
|
|
336
|
+
const browserSafeUser = getBrowserSafeUser(options?.req?.context?.user);
|
|
366
337
|
const browserSafeRequest = options?.email ? {} : getBrowserSafeRequest({ ...options?.req || {} });
|
|
367
338
|
const componentInstance = getComponentInstance(options.componentFunction, {
|
|
368
339
|
props: options?.props || {},
|
|
@@ -371,13 +342,14 @@ const ssr = async (options, { resolve, reject }) => {
|
|
|
371
342
|
api: apiForDataFunctions,
|
|
372
343
|
req: browserSafeRequest
|
|
373
344
|
});
|
|
345
|
+
componentInstance.user = browserSafeUser;
|
|
374
346
|
const ssrTree = getTreeForSSR(componentInstance);
|
|
375
347
|
const ssrTreeForCSS = getTreeForSSR(componentInstance);
|
|
376
|
-
const dataFromComponent = await getDataFromComponent(componentInstance, apiForDataFunctions, browserSafeRequest).then((data) => data).catch((error) => {
|
|
348
|
+
const dataFromComponent = await getDataFromComponent(componentInstance, apiForDataFunctions, browserSafeUser, browserSafeRequest).then((data) => data).catch((error) => {
|
|
377
349
|
return [{ error }];
|
|
378
350
|
});
|
|
379
|
-
buildTreeForComponent(componentInstance, ssrTree);
|
|
380
|
-
buildTreeForComponent(componentInstance, ssrTreeForCSS);
|
|
351
|
+
buildTreeForComponent(componentInstance, ssrTree, options?.translations);
|
|
352
|
+
buildTreeForComponent(componentInstance, ssrTreeForCSS, options?.translations);
|
|
381
353
|
const dataFromTree = await getDataFromTree(ssrTree).then((data) => data).catch((error) => {
|
|
382
354
|
return [{ error }];
|
|
383
355
|
});
|
|
@@ -397,6 +369,7 @@ const ssr = async (options, { resolve, reject }) => {
|
|
|
397
369
|
isEmailRender: options?.email,
|
|
398
370
|
emailSubject: options?.emailSubject,
|
|
399
371
|
emailPreheader: options?.emailPreheader,
|
|
372
|
+
browserSafeUser,
|
|
400
373
|
browserSafeRequest,
|
|
401
374
|
props: options?.props,
|
|
402
375
|
translations: options?.translations,
|
|
@@ -417,6 +390,7 @@ const ssr = async (options, { resolve, reject }) => {
|
|
|
417
390
|
isEmailRender: options?.email,
|
|
418
391
|
emailSubject: options?.emailSubject,
|
|
419
392
|
emailPreheader: options?.emailPreheader,
|
|
393
|
+
browserSafeUser,
|
|
420
394
|
browserSafeRequest,
|
|
421
395
|
props: options?.props,
|
|
422
396
|
translations: options?.translations,
|