@pronto-tools-and-more/pronto 3.3.8

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.
Files changed (57) hide show
  1. package/package.json +36 -0
  2. package/src/main.js +3 -0
  3. package/src/parts/App/App.js +54 -0
  4. package/src/parts/Assert/Assert.js +1 -0
  5. package/src/parts/Build/Build.js +24 -0
  6. package/src/parts/Callback/Callback.js +1 -0
  7. package/src/parts/ChangeWatcher/ChangeWatcher.js +51 -0
  8. package/src/parts/Command/Command.js +9 -0
  9. package/src/parts/CommandMap/CommandMap.js +15 -0
  10. package/src/parts/CommitDate/CommitDate.js +15 -0
  11. package/src/parts/CommitHash/CommitHash.js +15 -0
  12. package/src/parts/CommitMessage/CommitMessage.js +14 -0
  13. package/src/parts/CompileSass/CompileSass.js +12 -0
  14. package/src/parts/CompileSassIndividually/CompileSassIndividually.js +22 -0
  15. package/src/parts/Config/Config.js +36 -0
  16. package/src/parts/CreateServer/CreateServer.js +22 -0
  17. package/src/parts/CreateZip/CreateZip.js +8 -0
  18. package/src/parts/DownloadZipFile/DownloadZipFile.js +15 -0
  19. package/src/parts/Exec/Exec.js +2 -0
  20. package/src/parts/Exit/Exit.js +3 -0
  21. package/src/parts/ExtractZip/ExtractZip.js +8 -0
  22. package/src/parts/FileWatcher/FileWatcher.js +11 -0
  23. package/src/parts/FilesPath/FilesPath.js +4 -0
  24. package/src/parts/GetCommandFromCliArgs/GetCommandFromCliArgs.js +15 -0
  25. package/src/parts/GetConfigPath/GetConfigPath.js +6 -0
  26. package/src/parts/GetListContentZipFilesResponse/GetListContentZipFilesResponse.js +13 -0
  27. package/src/parts/GetZipUploadMessage/GetZipUploadMessage.js +7 -0
  28. package/src/parts/HandleFileChange/HandleFileChange.js +12 -0
  29. package/src/parts/HandleIpc/HandleIpc.js +10 -0
  30. package/src/parts/HandleMessage/HandleMessage.js +27 -0
  31. package/src/parts/IpcParent/IpcParent.js +10 -0
  32. package/src/parts/IpcParentModule/IpcParentModule.js +16 -0
  33. package/src/parts/IpcParentType/IpcParentType.js +3 -0
  34. package/src/parts/JsonRpc/JsonRpc.js +1 -0
  35. package/src/parts/LaunchNetworkProcess/LaunchNetworkProcess.js +15 -0
  36. package/src/parts/LaunchSassProcess/LaunchSassProcess.js +13 -0
  37. package/src/parts/ListContentZipFiles/ListContentZipFiles.js +18 -0
  38. package/src/parts/LoadConfig/LoadConfig.js +7 -0
  39. package/src/parts/Login/Login.js +14 -0
  40. package/src/parts/Main/Main.js +8 -0
  41. package/src/parts/NetworkProcess/NetworkProcess.js +26 -0
  42. package/src/parts/NetworkProcessPath/NetworkProcessPath.js +10 -0
  43. package/src/parts/ParseListContentZipFilesResponse/ParseListContentZipFilesResponse.js +11 -0
  44. package/src/parts/Promises/Promises.js +19 -0
  45. package/src/parts/PullCode/PullCode.js +59 -0
  46. package/src/parts/PushCode/PushCode.js +58 -0
  47. package/src/parts/Root/Root.js +6 -0
  48. package/src/parts/SassProcess/SassProcess.js +26 -0
  49. package/src/parts/SassProcessPath/SassProcessPath.js +10 -0
  50. package/src/parts/SendFullUpdates/SendFullUpdates.js +9 -0
  51. package/src/parts/SendSassUpdates/SendSassUpdates.js +50 -0
  52. package/src/parts/SendUpdates/SendUpdates.js +7 -0
  53. package/src/parts/Server/Server.js +10 -0
  54. package/src/parts/UpdateCss/UpdateCss.js +17 -0
  55. package/src/parts/UpdateIndexHtml/UpdateIndexHtml.js +24 -0
  56. package/src/parts/UploadZip/UploadZip.js +21 -0
  57. package/src/parts/VError/VError.js +1 -0
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@pronto-tools-and-more/pronto",
3
+ "version": "3.3.8",
4
+ "description": "",
5
+ "main": "src/main.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "node --unhandled-rejections=warn --experimental-vm-modules ./node_modules/jest/bin/jest.js --detectOpenHandles --forceExit",
9
+ "test:watch": "node --unhandled-rejections=warn --experimental-vm-modules ./node_modules/jest/bin/jest.js --watch",
10
+ "type-check": "tsc"
11
+ },
12
+ "keywords": [],
13
+ "author": "",
14
+ "license": "MIT",
15
+ "dependencies": {
16
+ "@pronto-tools-and-more/file-watcher": "3.3.8",
17
+ "@pronto-tools-and-more/files": "3.3.8",
18
+ "@pronto-tools-and-more/network-process": "3.3.8",
19
+ "@pronto-tools-and-more/sass-compiler": "3.3.8",
20
+ "@lvce-editor/assert": "^1.2.0",
21
+ "@lvce-editor/ipc": "^9.1.0",
22
+ "@lvce-editor/json-rpc": "^1.3.0",
23
+ "@lvce-editor/verror": "^1.3.0",
24
+ "execa": "^9.1.0",
25
+ "express": "^4.19.2"
26
+ },
27
+ "devDependencies": {
28
+ "@types/express": "^4.17.21",
29
+ "@types/node": "^20.12.7",
30
+ "@types/ws": "^8.5.10",
31
+ "jest": "^29.7.0"
32
+ },
33
+ "jest": {
34
+ "injectGlobals": false
35
+ }
36
+ }
package/src/main.js ADDED
@@ -0,0 +1,3 @@
1
+ import * as Main from "./parts/Main/Main.js";
2
+
3
+ Main.main();
@@ -0,0 +1,54 @@
1
+ import express from "express";
2
+ import { existsSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import * as CompileSass from "../CompileSass/CompileSass.js";
6
+ import * as Config from "../Config/Config.js";
7
+ import * as FilesPath from "../FilesPath/FilesPath.js";
8
+ import * as UpdateCss from "../UpdateCss/UpdateCss.js";
9
+ import * as UpdateIndexHtml from "../UpdateIndexHtml/UpdateIndexHtml.js";
10
+
11
+ const handleIndex = (storeFrontPath) => async (req, res) => {
12
+ const indexHtmlPath = join(storeFrontPath, "index.html");
13
+ const indexHtmlContent = await readFile(indexHtmlPath, "utf8");
14
+ const newIndexHtml = UpdateIndexHtml.updateIndexHtml(indexHtmlContent);
15
+ res.end(newIndexHtml);
16
+ };
17
+
18
+ const handleCss = (storeFrontPath) => async (req, res, next) => {
19
+ const pathName = req._parsedUrl.pathname;
20
+ if (!pathName.endsWith(".css")) {
21
+ return next();
22
+ }
23
+ if (pathName === "/assets/custom.css") {
24
+ try {
25
+ const result = await CompileSass.compileSass(Config.rootSassFile);
26
+ res.end(result.css);
27
+ } catch (error) {
28
+ console.warn(error);
29
+ res.end(`css error: ${error}`);
30
+ }
31
+ return;
32
+ }
33
+ const cssPath = join(storeFrontPath, pathName);
34
+ if (!existsSync(cssPath)) {
35
+ return next();
36
+ }
37
+ const cssContent = await readFile(cssPath, "utf8");
38
+ const newCss = UpdateCss.updateCss(cssContent);
39
+ res.end(newCss);
40
+ };
41
+
42
+ export const create = (root) => {
43
+ const app = express();
44
+ const storeFrontPath = join(root, "src", "default", "storefront");
45
+ const defaultPath = join(root, "src", "default");
46
+ const contentPath = join(root, "src", "default", "content");
47
+ app.get("/", handleIndex(storeFrontPath));
48
+ app.use("*", handleCss(storeFrontPath));
49
+ app.use(express.static(FilesPath.filesPath));
50
+ app.use(express.static(storeFrontPath));
51
+ app.use(express.static(defaultPath));
52
+ app.use(express.static(contentPath));
53
+ return app;
54
+ };
@@ -0,0 +1 @@
1
+ export * from "@lvce-editor/assert";
@@ -0,0 +1,24 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import { writeFile } from "fs/promises";
3
+ import * as CompileSass from "../CompileSass/CompileSass.js";
4
+ import * as Config from "../Config/Config.js";
5
+ import * as SassProcess from "../SassProcess/SassProcess.js";
6
+
7
+ const sourceMap = false;
8
+
9
+ export const build = async () => {
10
+ try {
11
+ const result = await CompileSass.compileSass(Config.rootSassFile, {
12
+ updateDynamicResources: false,
13
+ sourceMap,
14
+ });
15
+ const css = result.css + "\n\n/*# sourceMappingURL=custom.css.map */\n";
16
+ await writeFile(Config.rootCssFile, css);
17
+ const rootCssMapFile = Config.rootCssFile + ".map";
18
+ await writeFile(rootCssMapFile, JSON.stringify(result.sourceMap) + "\n");
19
+ } catch (error) {
20
+ throw new VError(error, `Failed to build`);
21
+ } finally {
22
+ SassProcess.dispose();
23
+ }
24
+ };
@@ -0,0 +1 @@
1
+ export { resolve } from "@lvce-editor/json-rpc";
@@ -0,0 +1,51 @@
1
+ import { rm } from "node:fs/promises";
2
+ import * as net from "node:net";
3
+ import * as SendSassUpdates from "../SendSassUpdates/SendSassUpdates.js";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const SOCKET_FILE = "/tmp/pronto.sock";
7
+
8
+ const canHandle = (data) => {
9
+ const dataContent = data.toString();
10
+ try {
11
+ return JSON.parse(dataContent);
12
+ } catch {
13
+ return false;
14
+ }
15
+ };
16
+
17
+ const handleData = async (clients, chunks, data) => {
18
+ chunks.push(data);
19
+ const buffer = Buffer.concat(chunks);
20
+ const parsed = canHandle(buffer);
21
+ if (!parsed) {
22
+ return;
23
+ }
24
+ chunks.length = 0;
25
+ const uri = parsed.params[0];
26
+ const path = fileURLToPath(uri);
27
+ const content = parsed.params[1];
28
+ await SendSassUpdates.sendSassUpdates(clients, path, content);
29
+ };
30
+
31
+ export const create = async (webSocketServer) => {
32
+ try {
33
+ await rm(SOCKET_FILE, { force: true });
34
+
35
+ /**
36
+ *
37
+ * @param {net.Socket} connection
38
+ */
39
+ const handleConnection = (connection) => {
40
+ const chunks = [];
41
+ connection.on("data", (data) => {
42
+ handleData(webSocketServer.clients, chunks, data);
43
+ });
44
+ };
45
+
46
+ const server = net.createServer(handleConnection);
47
+ server.listen(SOCKET_FILE);
48
+ } catch (error) {
49
+ console.warn(`Failed to create change watcher: ${error}`);
50
+ }
51
+ };
@@ -0,0 +1,9 @@
1
+ import * as CommandMap from "../CommandMap/CommandMap.js";
2
+
3
+ export const execute = (method, ...params) => {
4
+ const command = CommandMap.commandMap[method];
5
+ if (!command) {
6
+ throw new Error(`command not found ${method}`);
7
+ }
8
+ return command(...params);
9
+ };
@@ -0,0 +1,15 @@
1
+ import * as Build from "../Build/Build.js";
2
+ import * as Login from "../Login/Login.js";
3
+ import * as PullCode from "../PullCode/PullCode.js";
4
+ import * as PushCode from "../PushCode/PushCode.js";
5
+ import * as Server from "../Server/Server.js";
6
+ import * as UploadZip from "../UploadZip/UploadZip.js";
7
+
8
+ export const commandMap = {
9
+ "Build.build": Build.build,
10
+ "Login.login": Login.login,
11
+ "PullCode.pullCode": PullCode.pullCode,
12
+ "PushCode.pushCode": PushCode.pushCode,
13
+ "Server.start": Server.start,
14
+ "UploadZip.uploadZip": UploadZip.uploadZip,
15
+ };
@@ -0,0 +1,15 @@
1
+ import * as Exec from '../Exec/Exec.js'
2
+ import * as Assert from '../Assert/Assert.js'
3
+
4
+ export const getCommitDate = async (commit) => {
5
+ Assert.string(commit)
6
+ const { stdout } = await Exec.exec('git', ['show', '-s', '--format=%ct', commit])
7
+ const value = parseInt(stdout)
8
+ if (isNaN(value)) {
9
+ throw new Error(`Failed to parse date`)
10
+ }
11
+ const milliseconds = value * 1000
12
+ const date = new Date(milliseconds)
13
+ const isoString = date.toISOString()
14
+ return isoString
15
+ }
@@ -0,0 +1,15 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import * as Exec from "../Exec/Exec.js";
3
+
4
+ export const getCommitHash = async () => {
5
+ try {
6
+ const { stdout } = await Exec.exec("git", [
7
+ "rev-parse",
8
+ "--short=7",
9
+ "HEAD",
10
+ ]);
11
+ return stdout;
12
+ } catch (error) {
13
+ throw new VError(error, "Failed to get commit hash");
14
+ }
15
+ };
@@ -0,0 +1,14 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import * as Exec from "../Exec/Exec.js";
3
+
4
+ export const getCommitMessage = async () => {
5
+ try {
6
+ if (process.env.CI_COMMIT_MESSAGE) {
7
+ return process.env.CI_COMMIT_MESSAGE;
8
+ }
9
+ const { stdout } = await Exec.exec("git", ["log", "-1", "--pretty=%B"]);
10
+ return stdout.trim();
11
+ } catch (error) {
12
+ throw new VError(error, "Failed to get commit message");
13
+ }
14
+ };
@@ -0,0 +1,12 @@
1
+ import * as SassProcess from "../SassProcess/SassProcess.js";
2
+
3
+ export const compileSass = async (
4
+ scssFileName,
5
+ { updateDynamicResources = true, sourceMap = false } = {}
6
+ ) => {
7
+ return SassProcess.invoke("CompileSass.compileSass", {
8
+ absolutePath: scssFileName,
9
+ updateDynamicResources,
10
+ sourceMap,
11
+ });
12
+ };
@@ -0,0 +1,22 @@
1
+ import * as SassProcess from "../SassProcess/SassProcess.js";
2
+
3
+ export const compileSassIndividually = async (
4
+ rootScssFileName,
5
+ {
6
+ updateDynamicResources = true,
7
+ fileName = "",
8
+ needsFull = true,
9
+ content = undefined,
10
+ } = {}
11
+ ) => {
12
+ return SassProcess.invoke(
13
+ "CompileSass.compileSassIndividually",
14
+ rootScssFileName,
15
+ {
16
+ updateDynamicResources,
17
+ fileName,
18
+ needsFull,
19
+ content,
20
+ }
21
+ );
22
+ };
@@ -0,0 +1,36 @@
1
+ import { join } from "path";
2
+ import * as Root from "../Root/Root.js";
3
+
4
+ export const userEmail = process.env.PRONTO_USER_EMAIL;
5
+ export const userPassword = process.env.PRONTO_USER_PASSWORD;
6
+ // TODO use direct backend url
7
+ export const loginUrl = `https://builder.purplemanager.com/api/user/login`;
8
+ export const listResourcesUrl = `https://purplemanager.com/purple-manager-backend/app/listresources`;
9
+ export const appId = `b745c9ad-2d2e-4515-92a0-d0a2baed181e`;
10
+ export const downloadBaseUrl = `https://purplemanager.com/purple-manager-backend/app/downloadappresources`;
11
+ export const uploadBaseUrl = `https://purplemanager.com/purple-manager-backend/app/uploadresources`;
12
+ export const preview = true;
13
+ export const uploadTimeout = 120000;
14
+
15
+ export const rootSassFile = join(
16
+ Root.root,
17
+ "packages",
18
+ "daz",
19
+ "src",
20
+ "default",
21
+ "storefront",
22
+ "assets",
23
+ "scss",
24
+ "__index.scss"
25
+ );
26
+
27
+ export const rootCssFile = join(
28
+ Root.root,
29
+ "packages",
30
+ "daz",
31
+ "src",
32
+ "default",
33
+ "storefront",
34
+ "assets",
35
+ "custom.css"
36
+ );
@@ -0,0 +1,22 @@
1
+ import * as http from "node:http";
2
+ import * as ws from "ws";
3
+ import * as App from "../App/App.js";
4
+ import * as Assert from "../Assert/Assert.js";
5
+ import * as ChangeWatcher from "../ChangeWatcher/ChangeWatcher.js";
6
+ import * as FileWatcher from "../FileWatcher/FileWatcher.js";
7
+ import * as HandleFileChange from "../HandleFileChange/HandleFileChange.js";
8
+
9
+ export const createServer = async (root) => {
10
+ Assert.string(root);
11
+ const app = App.create(root);
12
+ const server = http.createServer(app);
13
+ const webSocketServer = new ws.WebSocketServer({
14
+ server,
15
+ });
16
+ const handleFileChange = (event) => {
17
+ HandleFileChange.handleFileChange(webSocketServer.clients, event, root);
18
+ };
19
+ FileWatcher.create(root, handleFileChange);
20
+ ChangeWatcher.create(webSocketServer);
21
+ return server;
22
+ };
@@ -0,0 +1,8 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ export const createZip = ({ inDir, outFile }) => {
4
+ return NetworkProcess.invoke("Network.createZip", {
5
+ inDir,
6
+ outFile,
7
+ });
8
+ };
@@ -0,0 +1,15 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ export const downloadZipFile = ({
4
+ zipFileId,
5
+ downloadBaseUrl,
6
+ sessionId,
7
+ outFile,
8
+ }) => {
9
+ return NetworkProcess.invoke("Network.downloadZipFile", {
10
+ zipFileId,
11
+ downloadBaseUrl,
12
+ sessionId,
13
+ outFile,
14
+ });
15
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export {execa as exec} from 'execa'
@@ -0,0 +1,3 @@
1
+ export const exit = () => {
2
+ process.exit(0);
3
+ };
@@ -0,0 +1,8 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ export const extractZip = ({ inFile, outDir }) => {
4
+ return NetworkProcess.invoke("Network.extractZip", {
5
+ inFile,
6
+ outDir,
7
+ });
8
+ };
@@ -0,0 +1,11 @@
1
+ import { watch } from "node:fs/promises";
2
+ import * as Assert from "../Assert/Assert.js";
3
+
4
+ export const create = async (root, callback) => {
5
+ Assert.string(root);
6
+ const watcher = watch(root, { recursive: true });
7
+ for await (const event of watcher) {
8
+ callback(event);
9
+ }
10
+ return watcher;
11
+ };
@@ -0,0 +1,4 @@
1
+ import { join } from "node:path";
2
+ import * as Root from "../Root/Root.js";
3
+
4
+ export const filesPath = join(Root.root, "packages", "pronto-files", "files");
@@ -0,0 +1,15 @@
1
+ export const getCommandFromCliArgs = (argv) => {
2
+ if (argv.includes("pull-code") || argv.includes("pull")) {
3
+ return "PullCode.pullCode";
4
+ }
5
+ if (argv.includes("server") || argv.includes("dev")) {
6
+ return "Server.start";
7
+ }
8
+ if (argv.includes("push-code") || argv.includes("push")) {
9
+ return "PushCode.pushCode";
10
+ }
11
+ if (argv.includes("build")) {
12
+ return "Build.build";
13
+ }
14
+ return "";
15
+ };
@@ -0,0 +1,6 @@
1
+ import { join } from "path";
2
+ import * as Root from "../Root/Root.js";
3
+
4
+ export const getConfigPath = () => {
5
+ return join(Root.root, "packages", "daz", "pronto.json");
6
+ };
@@ -0,0 +1,13 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ export const getListContentZipFilesResponse = ({
4
+ listResourcesUrl,
5
+ sessionId,
6
+ appId,
7
+ }) => {
8
+ return NetworkProcess.invoke("Network.getListContentZipFilesResponse", {
9
+ listResourcesUrl,
10
+ sessionId,
11
+ appId,
12
+ });
13
+ };
@@ -0,0 +1,7 @@
1
+ import * as CommitMessage from "../CommitMessage/CommitMessage.js";
2
+
3
+ export const getZipUploadMessage = async () => {
4
+ const commitMessage = await CommitMessage.getCommitMessage();
5
+ const message = `CI ${commitMessage}`;
6
+ return message;
7
+ };
@@ -0,0 +1,12 @@
1
+ import { join } from "node:path";
2
+ import * as SendFullUpdates from "../SendFullUpdates/SendFullUpdates.js";
3
+ import * as SendSassUpdates from "../SendSassUpdates/SendSassUpdates.js";
4
+
5
+ export const handleFileChange = (clients, event, root) => {
6
+ if (event.filename.endsWith(".scss")) {
7
+ const absolutePath = join(root, event.filename);
8
+ SendSassUpdates.sendSassUpdates(clients, absolutePath, undefined);
9
+ } else {
10
+ SendFullUpdates.sendFullUpdates(clients);
11
+ }
12
+ };
@@ -0,0 +1,10 @@
1
+ import * as HandleMessage from "../HandleMessage/HandleMessage.js";
2
+
3
+ export const handleIpc = (ipc) => {
4
+ if ("addEventListener" in ipc) {
5
+ ipc.addEventListener("message", HandleMessage.handleMessage);
6
+ } else if ("on" in ipc) {
7
+ // deprecated
8
+ ipc.on("message", HandleMessage.handleMessage);
9
+ }
10
+ };
@@ -0,0 +1,27 @@
1
+ import * as Callback from "../Callback/Callback.js";
2
+ import * as Command from "../Command/Command.js";
3
+ import * as JsonRpc from "../JsonRpc/JsonRpc.js";
4
+
5
+ const prepare = (error) => {
6
+ return error;
7
+ };
8
+
9
+ const requiresSocket = (method) => {
10
+ return false;
11
+ };
12
+
13
+ const logError = (error, prettyError) => {
14
+ console.error(error);
15
+ };
16
+
17
+ export const handleMessage = (event) => {
18
+ return JsonRpc.handleJsonRpcMessage(
19
+ event.target,
20
+ event.data,
21
+ Command.execute,
22
+ Callback.resolve,
23
+ prepare,
24
+ logError,
25
+ requiresSocket,
26
+ );
27
+ };
@@ -0,0 +1,10 @@
1
+ import * as IpcParentModule from '../IpcParentModule/IpcParentModule.js'
2
+
3
+ export const create = async ({ method, ...options }) => {
4
+ const module = await IpcParentModule.getModule(method)
5
+ // @ts-ignore
6
+ const rawIpc = await module.create(options)
7
+ // @ts-ignore
8
+ const ipc = module.wrap(rawIpc)
9
+ return ipc
10
+ }
@@ -0,0 +1,16 @@
1
+ import {
2
+ IpcParentWithNodeForkedProcess,
3
+ IpcParentWithNodeWorker,
4
+ } from "@lvce-editor/ipc";
5
+ import * as IpcParentType from "../IpcParentType/IpcParentType.js";
6
+
7
+ export const getModule = (method) => {
8
+ switch (method) {
9
+ case IpcParentType.NodeWorker:
10
+ return IpcParentWithNodeWorker;
11
+ case IpcParentType.NodeForkedProcess:
12
+ return IpcParentWithNodeForkedProcess;
13
+ default:
14
+ throw new Error("unexpected ipc type");
15
+ }
16
+ };
@@ -0,0 +1,3 @@
1
+ export const NodeWorker = 1
2
+ export const NodeForkedProcess = 2
3
+ export const ElectronUtilityProcess = 3
@@ -0,0 +1 @@
1
+ export * from '@lvce-editor/json-rpc'
@@ -0,0 +1,15 @@
1
+ import * as HandleIpc from "../HandleIpc/HandleIpc.js";
2
+ import * as IpcParent from "../IpcParent/IpcParent.js";
3
+ import * as IpcParentType from "../IpcParentType/IpcParentType.js";
4
+ import * as NetworkProcessPath from "../NetworkProcessPath/NetworkProcessPath.js";
5
+
6
+ export const launchNetworkProcess = async () => {
7
+ const ipc = await IpcParent.create({
8
+ method: IpcParentType.NodeForkedProcess,
9
+ path: NetworkProcessPath.networkProcessPath,
10
+ });
11
+ HandleIpc.handleIpc(ipc);
12
+ // @ts-ignore
13
+ ipc._rawIpc.unref();
14
+ return ipc;
15
+ };
@@ -0,0 +1,13 @@
1
+ import * as IpcParent from "../IpcParent/IpcParent.js";
2
+ import * as IpcParentType from "../IpcParentType/IpcParentType.js";
3
+ import * as SassProcessPath from "../SassProcessPath/SassProcessPath.js";
4
+ import * as HandleIpc from "../HandleIpc/HandleIpc.js";
5
+
6
+ export const launchSassProcess = async () => {
7
+ const ipc = await IpcParent.create({
8
+ method: IpcParentType.NodeForkedProcess,
9
+ path: SassProcessPath.sassProcessPath,
10
+ });
11
+ HandleIpc.handleIpc(ipc);
12
+ return ipc;
13
+ };
@@ -0,0 +1,18 @@
1
+ import * as GetListContentZipFilesResponse from "../GetListContentZipFilesResponse/GetListContentZipFilesResponse.js";
2
+ import * as ParseListContentZipFilesResponse from "../ParseListContentZipFilesResponse/ParseListContentZipFilesResponse.js";
3
+
4
+ export const listContentZipFiles = async ({
5
+ listResourcesUrl,
6
+ sessionId,
7
+ appId,
8
+ }) => {
9
+ const result =
10
+ await GetListContentZipFilesResponse.getListContentZipFilesResponse({
11
+ listResourcesUrl,
12
+ sessionId,
13
+ appId,
14
+ });
15
+ const zips =
16
+ ParseListContentZipFilesResponse.parseListContentZipFilesResponse(result);
17
+ return zips;
18
+ };
@@ -0,0 +1,7 @@
1
+ import { readFile } from "fs/promises";
2
+
3
+ export const loadConfig = async (configPath) => {
4
+ const content = await readFile(configPath, "utf8");
5
+ const value = JSON.parse(content);
6
+ return value;
7
+ };
@@ -0,0 +1,14 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ /**
4
+ *
5
+ * @param {*} param0
6
+ * @returns {Promise<any>}
7
+ */
8
+ export const login = async ({ loginUrl, userEmail, userPassword }) => {
9
+ return NetworkProcess.invoke("Network.login", {
10
+ loginUrl,
11
+ userEmail,
12
+ userPassword,
13
+ });
14
+ };
@@ -0,0 +1,8 @@
1
+ import * as Command from "../Command/Command.js";
2
+ import * as GetCommandFromCliArgs from "../GetCommandFromCliArgs/GetCommandFromCliArgs.js";
3
+
4
+ export const main = async () => {
5
+ const { argv } = process;
6
+ const command = GetCommandFromCliArgs.getCommandFromCliArgs(argv);
7
+ await Command.execute(command);
8
+ };
@@ -0,0 +1,26 @@
1
+ import * as JsonRpc from "../JsonRpc/JsonRpc.js";
2
+ import * as LaunchNetworkProcess from "../LaunchNetworkProcess/LaunchNetworkProcess.js";
3
+
4
+ const state = {
5
+ /**
6
+ * @type {any}
7
+ */
8
+ ipc: undefined,
9
+ };
10
+
11
+ const getOrCreate = () => {
12
+ if (!state.ipc) {
13
+ state.ipc = LaunchNetworkProcess.launchNetworkProcess();
14
+ }
15
+ return state.ipc;
16
+ };
17
+
18
+ export const invoke = async (method, ...params) => {
19
+ const ipc = await getOrCreate();
20
+ return JsonRpc.invoke(ipc, method, ...params);
21
+ };
22
+
23
+ export const dispose = async () => {
24
+ const ipc = await getOrCreate();
25
+ ipc.dispose();
26
+ };
@@ -0,0 +1,10 @@
1
+ import * as Path from "node:path";
2
+ import * as Root from "../Root/Root.js";
3
+
4
+ export const networkProcessPath = Path.join(
5
+ Root.root,
6
+ "packages",
7
+ "pronto-network-process",
8
+ "src",
9
+ "networkProcessMain.js"
10
+ );
@@ -0,0 +1,11 @@
1
+ export const parseListContentZipFilesResponse = (result) => {
2
+ const zips = result.result;
3
+ if (zips.length === 0) {
4
+ throw new Error("no zips found");
5
+ }
6
+ const first = zips[0];
7
+ return {
8
+ id: first.id,
9
+ name: first.filename,
10
+ };
11
+ };
@@ -0,0 +1,19 @@
1
+ export const withResolvers = () => {
2
+ /**
3
+ * @type {any}
4
+ */
5
+ let _resolve;
6
+ /**
7
+ * @type {any}
8
+ */
9
+ let _reject;
10
+ const promise = new Promise((resolve, reject) => {
11
+ _resolve = resolve;
12
+ _reject = reject;
13
+ });
14
+ return {
15
+ resolve: _resolve,
16
+ reject: _reject,
17
+ promise,
18
+ };
19
+ };
@@ -0,0 +1,59 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import { rename, rm } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import * as Config from "../Config/Config.js";
5
+ import * as DownloadZipFile from "../DownloadZipFile/DownloadZipFile.js";
6
+ import * as ExtractZip from "../ExtractZip/ExtractZip.js";
7
+ import * as GetConfigPath from "../GetConfigPath/GetConfigPath.js";
8
+ import * as ListContentZipFiles from "../ListContentZipFiles/ListContentZipFiles.js";
9
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
10
+ import * as LoadConfig from "../LoadConfig/LoadConfig.js";
11
+ import * as Login from "../Login/Login.js";
12
+ import * as Root from "../Root/Root.js";
13
+
14
+ export const pullCode = async () => {
15
+ try {
16
+ const {
17
+ userEmail,
18
+ userPassword,
19
+ loginUrl,
20
+ appId,
21
+ downloadBaseUrl,
22
+ listResourcesUrl,
23
+ } = Config;
24
+ const outFile = join(Root.root, ".tmp", "update.zip");
25
+ const outDir = join(Root.root, ".tmp", "update");
26
+ const src = join(Root.root, "packages", "daz", "src");
27
+ const oldSrc = join(Root.root, ".tmp", "old-src");
28
+ const configPath = GetConfigPath.getConfigPath();
29
+ const config = await LoadConfig.loadConfig(configPath);
30
+ const sessionInfo = await Login.login({
31
+ loginUrl,
32
+ userEmail,
33
+ userPassword,
34
+ });
35
+ const sessionId = sessionInfo.sessionID;
36
+ const zipFile = await ListContentZipFiles.listContentZipFiles({
37
+ listResourcesUrl,
38
+ sessionId,
39
+ appId,
40
+ });
41
+ await DownloadZipFile.downloadZipFile({
42
+ zipFileId: zipFile.id,
43
+ downloadBaseUrl: downloadBaseUrl,
44
+ sessionId,
45
+ outFile,
46
+ });
47
+ await ExtractZip.extractZip({
48
+ inFile: outFile,
49
+ outDir,
50
+ });
51
+ await rm(oldSrc, { recursive: true, force: true });
52
+ await rename(src, oldSrc);
53
+ await rename(outDir, src);
54
+ } catch (error) {
55
+ throw new VError(error, `Failed to pull code`);
56
+ } finally {
57
+ NetworkProcess.dispose();
58
+ }
59
+ };
@@ -0,0 +1,58 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import { join } from "node:path";
3
+ import * as Config from "../Config/Config.js";
4
+ import * as CreateZip from "../CreateZip/CreateZip.js";
5
+ import * as GetZipUploadMessage from "../GetZipUploadMessage/GetZipUploadMessage.js";
6
+ import * as Login from "../Login/Login.js";
7
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
8
+ import * as Root from "../Root/Root.js";
9
+ import * as UploadZip from "../UploadZip/UploadZip.js";
10
+
11
+ export const pushCode = async () => {
12
+ try {
13
+ const {
14
+ userEmail,
15
+ userPassword,
16
+ loginUrl,
17
+ appId,
18
+ uploadBaseUrl,
19
+ preview,
20
+ uploadTimeout,
21
+ } = Config;
22
+ if (!userEmail) {
23
+ throw new Error(`missing user email`);
24
+ }
25
+ if (!userPassword) {
26
+ throw new Error("missing user password");
27
+ }
28
+ const outFile = join(Root.root, ".tmp", "upload.zip");
29
+ const src = join(Root.root, "packages", "daz", "src");
30
+ const sessionInfo = await Login.login({
31
+ loginUrl,
32
+ userEmail,
33
+ userPassword,
34
+ });
35
+ const sessionId = sessionInfo.sessionID;
36
+ const message = await GetZipUploadMessage.getZipUploadMessage();
37
+
38
+ await CreateZip.createZip({
39
+ inDir: src,
40
+ outFile,
41
+ });
42
+ const response = await UploadZip.uploadZip({
43
+ file: outFile,
44
+ uploadBaseUrl,
45
+ preview,
46
+ appId,
47
+ sessionId,
48
+ uploadTimeout,
49
+ message,
50
+ });
51
+
52
+ console.log({ response });
53
+ } catch (error) {
54
+ throw new VError(error, `Failed to push code`);
55
+ } finally {
56
+ NetworkProcess.dispose();
57
+ }
58
+ };
@@ -0,0 +1,6 @@
1
+ import { dirname } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+
6
+ export const root = `${__dirname}/../../../../..`;
@@ -0,0 +1,26 @@
1
+ import * as LaunchSassProcess from "../LaunchSassProcess/LaunchSassProcess.js";
2
+ import * as JsonRpc from "../JsonRpc/JsonRpc.js";
3
+
4
+ const state = {
5
+ /**
6
+ * @type {any}
7
+ */
8
+ ipc: undefined,
9
+ };
10
+
11
+ const getOrCreate = () => {
12
+ if (!state.ipc) {
13
+ state.ipc = LaunchSassProcess.launchSassProcess();
14
+ }
15
+ return state.ipc;
16
+ };
17
+
18
+ export const invoke = async (method, ...params) => {
19
+ const ipc = await getOrCreate();
20
+ return JsonRpc.invoke(ipc, method, ...params);
21
+ };
22
+
23
+ export const dispose = async () => {
24
+ const ipc = await getOrCreate();
25
+ ipc.dispose();
26
+ };
@@ -0,0 +1,10 @@
1
+ import * as Path from "node:path";
2
+ import * as Root from "../Root/Root.js";
3
+
4
+ export const sassProcessPath = Path.join(
5
+ Root.root,
6
+ "packages",
7
+ "pronto-sass-compiler",
8
+ "src",
9
+ "sassCompilerMain.js"
10
+ );
@@ -0,0 +1,9 @@
1
+ import * as SendUpdates from "../SendUpdates/SendUpdates.js";
2
+
3
+ export const sendFullUpdates = (clients) => {
4
+ SendUpdates.sendUpdates(clients, {
5
+ jsonrpc: "2.0",
6
+ method: "reload",
7
+ params: [],
8
+ });
9
+ };
@@ -0,0 +1,50 @@
1
+ import * as CompileSassIndividually from "../CompileSassIndividually/CompileSassIndividually.js";
2
+ import * as Config from "../Config/Config.js";
3
+ import * as SendUpdates from "../SendUpdates/SendUpdates.js";
4
+
5
+ const incrementalCompileKey = "___incrementalCompile";
6
+
7
+ const clientNeedsFullCompile = (client) => {
8
+ return !client[incrementalCompileKey];
9
+ };
10
+
11
+ const needsFullCompile = (clients) => {
12
+ for (const client of clients) {
13
+ if (clientNeedsFullCompile(client)) {
14
+ return true;
15
+ }
16
+ }
17
+ return false;
18
+ };
19
+
20
+ export const sendSassUpdates = async (clients, fileName, content) => {
21
+ try {
22
+ const needsFull = needsFullCompile(clients);
23
+ const changes = await CompileSassIndividually.compileSassIndividually(
24
+ Config.rootSassFile,
25
+ {
26
+ updateDynamicResources: true,
27
+ fileName,
28
+ needsFull,
29
+ content,
30
+ }
31
+ );
32
+ if (needsFull) {
33
+ for (const client of clients) {
34
+ client[incrementalCompileKey] = true;
35
+ }
36
+ }
37
+ SendUpdates.sendUpdates(clients, {
38
+ jsonrpc: "2.0",
39
+ method: "updateCss",
40
+ params: [changes],
41
+ });
42
+ } catch (error) {
43
+ console.warn(error);
44
+ SendUpdates.sendUpdates(clients, {
45
+ jsonrpc: "2.0",
46
+ method: "updateCssError",
47
+ params: [`${error}`],
48
+ });
49
+ }
50
+ };
@@ -0,0 +1,7 @@
1
+ export const sendUpdates = (clients, message) => {
2
+ const sendClientUpdate = (client) => {
3
+ client.send(JSON.stringify(message));
4
+ };
5
+
6
+ clients.forEach(sendClientUpdate);
7
+ };
@@ -0,0 +1,10 @@
1
+ import * as CreateServer from "../CreateServer/CreateServer.js";
2
+ import * as Promises from "../Promises/Promises.js";
3
+
4
+ export const start = async (root = process.cwd(), port = 3000) => {
5
+ const server = await CreateServer.createServer(root);
6
+ const { resolve, promise } = Promises.withResolvers();
7
+ server.listen(port, resolve);
8
+ await promise;
9
+ console.info(`[server] listening on http://localhost:${port}`);
10
+ };
@@ -0,0 +1,17 @@
1
+ const occurrenceSnippet = "resource://dynamic";
2
+ const replacementSnippet = ``;
3
+
4
+ export const updateCss = (content) => {
5
+ return content.replaceAll(occurrenceSnippet, replacementSnippet);
6
+ };
7
+
8
+ const reverseOccurrenceSnippet = "../../images";
9
+
10
+ const reverseReplacementSnippet = "resource://dynamic/storefront/images";
11
+
12
+ export const reverseUpdateCss = (content) => {
13
+ return content.replaceAll(
14
+ reverseOccurrenceSnippet,
15
+ reverseReplacementSnippet
16
+ );
17
+ };
@@ -0,0 +1,24 @@
1
+ const occurrenceSnippetBody = "</body>";
2
+ const replacementSnippetBody = `
3
+ <script>
4
+ window._editorAppInfo = {
5
+ appId: "b745c9ad-2d2e-4515-92a0-d0a2baed181e",
6
+ baseUrl: "https://purplemanager.com/delivery",
7
+ contentUrl: "https://catalog.purplemanager.com",
8
+ forcePurpleImplUsage: true
9
+ };
10
+ </script>
11
+ <script type="module" src="/assets/preview-inject-bundle.js"></script>
12
+ <script type="module" src="/assets/live-reload.js"></script>
13
+ </body>`;
14
+
15
+ const occurrenceSnippetHead = "</head>";
16
+ const replacementSnippetHead = `
17
+ <link rel="stylesheet" href="/theme.css" />
18
+ </head>`;
19
+
20
+ export const updateIndexHtml = (content) => {
21
+ return content
22
+ .replace(occurrenceSnippetBody, replacementSnippetBody)
23
+ .replace(occurrenceSnippetHead, replacementSnippetHead);
24
+ };
@@ -0,0 +1,21 @@
1
+ import * as NetworkProcess from "../NetworkProcess/NetworkProcess.js";
2
+
3
+ export const uploadZip = ({
4
+ file,
5
+ uploadBaseUrl,
6
+ preview,
7
+ appId,
8
+ sessionId,
9
+ uploadTimeout,
10
+ message,
11
+ }) => {
12
+ return NetworkProcess.invoke("Network.uploadZip", {
13
+ file,
14
+ uploadBaseUrl,
15
+ preview,
16
+ appId,
17
+ sessionId,
18
+ uploadTimeout,
19
+ message,
20
+ });
21
+ };
@@ -0,0 +1 @@
1
+ export * from "@lvce-editor/verror";