@pronto-tools-and-more/pronto 4.1.1 → 4.3.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/package.json +5 -5
- package/src/parts/App/App.js +48 -5
- package/src/parts/CommandMap/CommandMap.js +3 -1
- package/src/parts/Config/Config.js +14 -0
- package/src/parts/CreateServer/CreateServer.js +13 -2
- package/src/parts/GetAllListContentZipFilesResponse/GetAllListContentZipFilesResponse.js +13 -0
- package/src/parts/GetCommandFromCliArgs/GetCommandFromCliArgs.js +3 -0
- package/src/parts/GetNewMainJsContent/GetNewMainJsContent.js +43 -0
- package/src/parts/GetPdfViewerSnippet/GetPdfViewerSnippet.js +23 -0
- package/src/parts/HandleFileChange/HandleFileChange.js +18 -3
- package/src/parts/HandleMainJs/HandleMainJs.js +32 -0
- package/src/parts/History/History.js +37 -0
- package/src/parts/ParseAllListContentZipFilesResponse/ParseAllListContentZipFilesResponse.js +21 -0
- package/src/parts/Print/Print.js +3 -0
- package/src/parts/ProxyPath/ProxyPath.js +35 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pronto-tools-and-more/pronto",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@pronto-tools-and-more/file-watcher": "4.
|
|
17
|
-
"@pronto-tools-and-more/files": "4.
|
|
18
|
-
"@pronto-tools-and-more/network-process": "4.
|
|
19
|
-
"@pronto-tools-and-more/sass-compiler": "4.
|
|
16
|
+
"@pronto-tools-and-more/file-watcher": "4.3.0",
|
|
17
|
+
"@pronto-tools-and-more/files": "4.3.0",
|
|
18
|
+
"@pronto-tools-and-more/network-process": "4.3.0",
|
|
19
|
+
"@pronto-tools-and-more/sass-compiler": "4.3.0",
|
|
20
20
|
"@lvce-editor/assert": "^1.2.0",
|
|
21
21
|
"@lvce-editor/ipc": "^9.3.0",
|
|
22
22
|
"@lvce-editor/json-rpc": "^1.3.0",
|
package/src/parts/App/App.js
CHANGED
|
@@ -5,8 +5,11 @@ import { join } from "node:path";
|
|
|
5
5
|
import * as CompileSass from "../CompileSass/CompileSass.js";
|
|
6
6
|
import * as Config from "../Config/Config.js";
|
|
7
7
|
import * as FilesPath from "../FilesPath/FilesPath.js";
|
|
8
|
+
import * as HandleMainJs from "../HandleMainJs/HandleMainJs.js";
|
|
8
9
|
import * as UpdateCss from "../UpdateCss/UpdateCss.js";
|
|
10
|
+
import * as HandleResources from "../ProxyPath/ProxyPath.js";
|
|
9
11
|
import * as UpdateIndexHtml from "../UpdateIndexHtml/UpdateIndexHtml.js";
|
|
12
|
+
import * as ProxyPath from "../ProxyPath/ProxyPath.js";
|
|
10
13
|
|
|
11
14
|
const handleIndex =
|
|
12
15
|
(storeFrontPath, appId, baseUrl, contentUrl, platform) =>
|
|
@@ -47,23 +50,63 @@ const handleCss = (storeFrontPath) => async (req, res, next) => {
|
|
|
47
50
|
res.end(newCss);
|
|
48
51
|
};
|
|
49
52
|
|
|
50
|
-
export const create = (
|
|
53
|
+
export const create = ({
|
|
54
|
+
root,
|
|
55
|
+
appId,
|
|
56
|
+
baseUrl,
|
|
57
|
+
contentUrl,
|
|
58
|
+
platform,
|
|
59
|
+
managerBaseUrl,
|
|
60
|
+
kioskBaseUrl,
|
|
61
|
+
catalogApiBaseUrl,
|
|
62
|
+
companyUrl,
|
|
63
|
+
}) => {
|
|
51
64
|
const app = express();
|
|
52
65
|
const storeFrontPath = join(root, "src", "default", "storefront");
|
|
53
66
|
const defaultPath = join(root, "src", "default");
|
|
54
67
|
const contentPath = join(root, "src", "default", "content");
|
|
55
|
-
const appId = Config.appId;
|
|
56
|
-
const baseUrl = Config.baseUrl;
|
|
57
|
-
const contentUrl = Config.contentUrl;
|
|
58
|
-
const platform = Config.platform;
|
|
59
68
|
app.get(
|
|
60
69
|
"/",
|
|
61
70
|
handleIndex(storeFrontPath, appId, baseUrl, contentUrl, platform)
|
|
62
71
|
);
|
|
72
|
+
app.get(
|
|
73
|
+
"/modules/main.js",
|
|
74
|
+
HandleMainJs.handleMainJs({
|
|
75
|
+
storeFrontPath,
|
|
76
|
+
appId,
|
|
77
|
+
catalogApiBaseUrl,
|
|
78
|
+
kioskBaseUrl,
|
|
79
|
+
managerBaseUrl,
|
|
80
|
+
companyUrl,
|
|
81
|
+
})
|
|
82
|
+
);
|
|
63
83
|
app.use("*", handleCss(storeFrontPath));
|
|
64
84
|
app.use(express.static(FilesPath.filesPath));
|
|
65
85
|
app.use(express.static(storeFrontPath));
|
|
66
86
|
app.use(express.static(defaultPath));
|
|
67
87
|
app.use(express.static(contentPath));
|
|
88
|
+
app.use(
|
|
89
|
+
"/resources/web",
|
|
90
|
+
ProxyPath.create({
|
|
91
|
+
prefix: "/resources/web",
|
|
92
|
+
to: Config.managerWebUrl,
|
|
93
|
+
customIf: [
|
|
94
|
+
{
|
|
95
|
+
match: "purpleshared/custom.css",
|
|
96
|
+
file: join(defaultPath, "readmode", "custom.css"),
|
|
97
|
+
postfix: "",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
match: "purpleshared/custom.js",
|
|
101
|
+
file: join(defaultPath, "readmode", "custom.js"),
|
|
102
|
+
postfix: `
|
|
103
|
+
const script = document.createElement('script')
|
|
104
|
+
script.src='/assets/live-reload-readmode.js'
|
|
105
|
+
document.head.append(script)
|
|
106
|
+
`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
})
|
|
110
|
+
);
|
|
68
111
|
return app;
|
|
69
112
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as Build from "../Build/Build.js";
|
|
2
2
|
import * as Help from "../Help/Help.js";
|
|
3
|
+
import * as History from "../History/History.js";
|
|
3
4
|
import * as Login from "../Login/Login.js";
|
|
4
5
|
import * as PullCode from "../PullCode/PullCode.js";
|
|
5
6
|
import * as PushCode from "../PushCode/PushCode.js";
|
|
6
7
|
import * as Server from "../Server/Server.js";
|
|
7
|
-
import * as UploadZip from "../UploadZip/UploadZip.js";
|
|
8
8
|
import * as Upgrade from "../Upgrade/Upgrade.js";
|
|
9
|
+
import * as UploadZip from "../UploadZip/UploadZip.js";
|
|
9
10
|
|
|
10
11
|
export const commandMap = {
|
|
11
12
|
"Build.build": Build.build,
|
|
@@ -16,4 +17,5 @@ export const commandMap = {
|
|
|
16
17
|
"Server.start": Server.start,
|
|
17
18
|
"UploadZip.uploadZip": UploadZip.uploadZip,
|
|
18
19
|
"Upgrade.upgrade": Upgrade.upgrade,
|
|
20
|
+
"History.history": History.history,
|
|
19
21
|
};
|
|
@@ -78,3 +78,17 @@ export const rootCssFile = join(
|
|
|
78
78
|
"src",
|
|
79
79
|
sassPipeline?.output || "not-found.css"
|
|
80
80
|
);
|
|
81
|
+
|
|
82
|
+
export const managerWebUrl =
|
|
83
|
+
config.managerUrl || `https://web.purplemanager.com`;
|
|
84
|
+
|
|
85
|
+
export const kioskBaseUrl =
|
|
86
|
+
config.kioskBaseUrl || "https://kiosk.purplemanager.com";
|
|
87
|
+
|
|
88
|
+
export const managerBaseUrl =
|
|
89
|
+
config.managerBaseUrl || "https://purplemanager.com";
|
|
90
|
+
|
|
91
|
+
export const catalogApiBaseUrl =
|
|
92
|
+
config.catalogApiBaseUrl || "https://catalog.purplemanager.com";
|
|
93
|
+
|
|
94
|
+
export const companyUrl = config.companyUrl || "https://sprylab.com";
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import * as http from "node:http";
|
|
2
|
+
import { join } from "node:path";
|
|
2
3
|
import * as ws from "ws";
|
|
3
4
|
import * as App from "../App/App.js";
|
|
4
5
|
import * as Assert from "../Assert/Assert.js";
|
|
5
6
|
import * as ChangeWatcher from "../ChangeWatcher/ChangeWatcher.js";
|
|
7
|
+
import * as Config from "../Config/Config.js";
|
|
6
8
|
import * as FileWatcher from "../FileWatcher/FileWatcher.js";
|
|
7
9
|
import * as HandleFileChange from "../HandleFileChange/HandleFileChange.js";
|
|
8
|
-
import { join } from "node:path";
|
|
9
10
|
|
|
10
11
|
export const createServer = async (root, errorColor) => {
|
|
11
12
|
Assert.string(root);
|
|
12
|
-
const app = App.create(
|
|
13
|
+
const app = App.create({
|
|
14
|
+
root,
|
|
15
|
+
appId: Config.appId,
|
|
16
|
+
baseUrl: Config.baseUrl,
|
|
17
|
+
contentUrl: Config.contentUrl,
|
|
18
|
+
platform: Config.platform,
|
|
19
|
+
managerBaseUrl: Config.managerBaseUrl,
|
|
20
|
+
kioskBaseUrl: Config.kioskBaseUrl,
|
|
21
|
+
catalogApiBaseUrl: Config.catalogApiBaseUrl,
|
|
22
|
+
companyUrl: Config.companyUrl,
|
|
23
|
+
});
|
|
13
24
|
const server = http.createServer(app);
|
|
14
25
|
const webSocketServer = new ws.WebSocketServer({
|
|
15
26
|
server,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
|
|
2
|
+
|
|
3
|
+
export const getAllListContentZipFilesResponse = ({
|
|
4
|
+
listResourcesUrl,
|
|
5
|
+
sessionId,
|
|
6
|
+
appId,
|
|
7
|
+
}) => {
|
|
8
|
+
return NetworkProcess.invoke("Network.getAllListContentZipFilesResponse", {
|
|
9
|
+
listResourcesUrl,
|
|
10
|
+
sessionId,
|
|
11
|
+
appId,
|
|
12
|
+
});
|
|
13
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// monkeypatch main.js to support pdf viewer
|
|
2
|
+
export const getNewMainJsContent = ({ content, pdfSnippet }) => {
|
|
3
|
+
const needle1 = "loadConfig(){";
|
|
4
|
+
const needle2 = "loadConfig() {";
|
|
5
|
+
const needle4 = "getConfig(){";
|
|
6
|
+
const needle5 = "getConfig() {";
|
|
7
|
+
const needles = [needle1, needle2];
|
|
8
|
+
let index = -1;
|
|
9
|
+
for (const needle of needles) {
|
|
10
|
+
index = content.indexOf(needle);
|
|
11
|
+
if (index !== -1) {
|
|
12
|
+
index += needle.length;
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (index === -1) {
|
|
17
|
+
// no needle found
|
|
18
|
+
return content;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const constructorIndex = content.lastIndexOf("constructor", index);
|
|
22
|
+
if (constructorIndex === -1) {
|
|
23
|
+
return content;
|
|
24
|
+
}
|
|
25
|
+
const configNeedles = [needle4, needle5];
|
|
26
|
+
let configIndex = -1;
|
|
27
|
+
for (const configNeedle of configNeedles) {
|
|
28
|
+
configIndex = content.indexOf(configNeedle, constructorIndex);
|
|
29
|
+
if (configIndex !== -1) {
|
|
30
|
+
configIndex += configNeedle.length;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (configIndex === -1) {
|
|
35
|
+
return content;
|
|
36
|
+
}
|
|
37
|
+
const newContent =
|
|
38
|
+
content.slice(0, configIndex) +
|
|
39
|
+
pdfSnippet +
|
|
40
|
+
"\n" +
|
|
41
|
+
content.slice(configIndex);
|
|
42
|
+
return newContent;
|
|
43
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { join } from "path";
|
|
2
|
+
import * as FilesPath from "../FilesPath/FilesPath.js";
|
|
3
|
+
import { readFile } from "fs/promises";
|
|
4
|
+
|
|
5
|
+
export const getPdfViewerSnippet = async ({
|
|
6
|
+
appId,
|
|
7
|
+
catalogApiBaseUrl,
|
|
8
|
+
kioskBaseUrl,
|
|
9
|
+
managerBaseUrl,
|
|
10
|
+
companyUrl,
|
|
11
|
+
}) => {
|
|
12
|
+
const snippetPath = join(FilesPath.filesPath, "assets", "hack-pdf-viewer.js");
|
|
13
|
+
let snippetContent = await readFile(snippetPath, "utf8");
|
|
14
|
+
snippetContent = snippetContent.replace("%APP_ID%", appId);
|
|
15
|
+
snippetContent = snippetContent.replace(
|
|
16
|
+
"%CATALOG_API_BASE_URL%",
|
|
17
|
+
catalogApiBaseUrl
|
|
18
|
+
);
|
|
19
|
+
snippetContent = snippetContent.replace("%KIOSK_BASE_URL%", kioskBaseUrl);
|
|
20
|
+
snippetContent = snippetContent.replace("%MANAGER_BASE_URL%", managerBaseUrl);
|
|
21
|
+
snippetContent = snippetContent.replace("%COMPANY_URL%", companyUrl);
|
|
22
|
+
return snippetContent;
|
|
23
|
+
};
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import * as SendFullUpdates from "../SendFullUpdates/SendFullUpdates.js";
|
|
3
4
|
import * as SendSassUpdates from "../SendSassUpdates/SendSassUpdates.js";
|
|
5
|
+
import * as SendUpdates from "../SendUpdates/SendUpdates.js";
|
|
4
6
|
|
|
5
|
-
export const handleFileChange = (clients, event, root, errorColor) => {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
export const handleFileChange = async (clients, event, root, errorColor) => {
|
|
8
|
+
const absolutePath = join(root, event.filename);
|
|
9
|
+
if (event.filename === "default/readmode/custom.css") {
|
|
10
|
+
const css = await readFile(absolutePath, "utf8");
|
|
11
|
+
const changes = [
|
|
12
|
+
{
|
|
13
|
+
fileName: event.filename,
|
|
14
|
+
css,
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
SendUpdates.sendUpdates(clients, {
|
|
18
|
+
jsonrpc: "2.0",
|
|
19
|
+
method: "updateCss",
|
|
20
|
+
params: [changes],
|
|
21
|
+
});
|
|
22
|
+
} else if (event.filename.endsWith(".scss")) {
|
|
8
23
|
SendSassUpdates.sendSassUpdates(
|
|
9
24
|
clients,
|
|
10
25
|
absolutePath,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import * as GetNewMainJsContent from "../GetNewMainJsContent/GetNewMainJsContent.js";
|
|
4
|
+
import * as GetPdfViewerSnippet from "../GetPdfViewerSnippet/GetPdfViewerSnippet.js";
|
|
5
|
+
|
|
6
|
+
export const handleMainJs =
|
|
7
|
+
({
|
|
8
|
+
storeFrontPath,
|
|
9
|
+
appId,
|
|
10
|
+
catalogApiBaseUrl,
|
|
11
|
+
kioskBaseUrl,
|
|
12
|
+
managerBaseUrl,
|
|
13
|
+
companyUrl,
|
|
14
|
+
}) =>
|
|
15
|
+
async (req, res) => {
|
|
16
|
+
// TODO use etag
|
|
17
|
+
const mainPath = join(storeFrontPath, "modules", "main.js");
|
|
18
|
+
const content = await readFile(mainPath, "utf8");
|
|
19
|
+
const pdfSnippet = await GetPdfViewerSnippet.getPdfViewerSnippet({
|
|
20
|
+
appId,
|
|
21
|
+
catalogApiBaseUrl,
|
|
22
|
+
kioskBaseUrl,
|
|
23
|
+
managerBaseUrl,
|
|
24
|
+
companyUrl,
|
|
25
|
+
});
|
|
26
|
+
const newContent = GetNewMainJsContent.getNewMainJsContent({
|
|
27
|
+
content,
|
|
28
|
+
pdfSnippet,
|
|
29
|
+
});
|
|
30
|
+
res.setHeader("content-type", "application/javascript");
|
|
31
|
+
res.end(newContent);
|
|
32
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { VError } from "@lvce-editor/verror";
|
|
2
|
+
import * as Config from "../Config/Config.js";
|
|
3
|
+
import * as GetAllListContentZipFilesResponse from "../GetAllListContentZipFilesResponse/GetAllListContentZipFilesResponse.js";
|
|
4
|
+
import * as GetSessionId from "../GetSessionId/GetSessionId.js";
|
|
5
|
+
import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
|
|
6
|
+
import * as ParseAllListContentZipFilesResponse from "../ParseAllListContentZipFilesResponse/ParseAllListContentZipFilesResponse.js";
|
|
7
|
+
import * as Print from "../Print/Print.js";
|
|
8
|
+
|
|
9
|
+
export const history = async () => {
|
|
10
|
+
try {
|
|
11
|
+
const { userEmail, userPassword, loginUrl, appId, listResourcesUrl } =
|
|
12
|
+
Config;
|
|
13
|
+
const sessionId = await GetSessionId.getSessionId({
|
|
14
|
+
loginUrl,
|
|
15
|
+
userEmail,
|
|
16
|
+
userPassword,
|
|
17
|
+
});
|
|
18
|
+
const response =
|
|
19
|
+
await GetAllListContentZipFilesResponse.getAllListContentZipFilesResponse(
|
|
20
|
+
{
|
|
21
|
+
appId,
|
|
22
|
+
listResourcesUrl,
|
|
23
|
+
sessionId,
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
const parsed =
|
|
27
|
+
ParseAllListContentZipFilesResponse.parseAllListContentZipFilesResponse(
|
|
28
|
+
response
|
|
29
|
+
);
|
|
30
|
+
const messageString = JSON.stringify(parsed, null, 2) + "\n";
|
|
31
|
+
Print.print(messageString);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw new VError(error, `Failed to pull code`);
|
|
34
|
+
} finally {
|
|
35
|
+
NetworkProcess.dispose();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { VError } from "@lvce-editor/verror";
|
|
2
|
+
import * as Assert from "../Assert/Assert.js";
|
|
3
|
+
|
|
4
|
+
const parseItem = (item) => {
|
|
5
|
+
const { filename, created } = item;
|
|
6
|
+
return {
|
|
7
|
+
message: filename,
|
|
8
|
+
date: created,
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const parseAllListContentZipFilesResponse = (response) => {
|
|
13
|
+
try {
|
|
14
|
+
Assert.object(response);
|
|
15
|
+
const { result } = response;
|
|
16
|
+
const parsed = result.map(parseItem);
|
|
17
|
+
return parsed;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new VError(error, `Failed to parse response`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { VError } from "@lvce-editor/verror";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
|
|
5
|
+
const getProxyResponse = async (prefix, to, sourceUrl) => {
|
|
6
|
+
try {
|
|
7
|
+
const relativePath = prefix + sourceUrl;
|
|
8
|
+
const baseUrl = to;
|
|
9
|
+
const absolutePath = `${baseUrl}${relativePath}`;
|
|
10
|
+
const response = await fetch(absolutePath);
|
|
11
|
+
if (!response.body) {
|
|
12
|
+
throw new Error("missing response body");
|
|
13
|
+
}
|
|
14
|
+
return response.body;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw new VError(error, `Failed to get proxy response`);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const create = ({ prefix, to, customIf }) => {
|
|
21
|
+
const proxyFn = async (req, res) => {
|
|
22
|
+
for (const item of customIf) {
|
|
23
|
+
if (req.url.includes(item.match)) {
|
|
24
|
+
const absolutePath = item.file;
|
|
25
|
+
const content = await readFile(absolutePath, "utf8");
|
|
26
|
+
const fullContent = content + "\n" + item.postfix;
|
|
27
|
+
res.end(fullContent);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const proxyResponse = await getProxyResponse(prefix, to, req.url);
|
|
32
|
+
await pipeline(proxyResponse, res);
|
|
33
|
+
};
|
|
34
|
+
return proxyFn;
|
|
35
|
+
};
|