@pronto-tools-and-more/network-process 3.3.9

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 ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@pronto-tools-and-more/network-process",
3
+ "version": "3.3.9",
4
+ "description": "",
5
+ "main": "src/networkProcessMain.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
+ "@lvce-editor/assert": "^1.2.0",
17
+ "@lvce-editor/ipc": "^9.1.0",
18
+ "@lvce-editor/json-rpc": "^1.3.0",
19
+ "@lvce-editor/verror": "^1.3.0",
20
+ "archiver": "^7.0.1",
21
+ "extract-zip": "^2.0.1",
22
+ "ky": "^1.2.4"
23
+ },
24
+ "devDependencies": {
25
+ "@types/archiver": "^6.0.2",
26
+ "@types/node": "^20.12.7",
27
+ "jest": "^29.7.0"
28
+ },
29
+ "jest": {
30
+ "injectGlobals": false
31
+ }
32
+ }
@@ -0,0 +1,3 @@
1
+ import * as Main from "./parts/Main/Main.js";
2
+
3
+ Main.main();
@@ -0,0 +1 @@
1
+ export * from "@lvce-editor/assert";
@@ -0,0 +1 @@
1
+ export { resolve } from "@lvce-editor/json-rpc";
@@ -0,0 +1,9 @@
1
+ import * as CommandState from "../CommandState/CommandState.js";
2
+
3
+ export const execute = (command, ...args) => {
4
+ const fn = CommandState.getCommand(command);
5
+ if (!fn) {
6
+ throw new Error(`Command not found ${command}`);
7
+ }
8
+ return fn(...args);
9
+ };
@@ -0,0 +1,16 @@
1
+ import * as CreateZip from "../CreateZip/CreateZip.js";
2
+ import * as DownloadZipFile from "../DownloadZipFile/DownloadZipFile.js";
3
+ import * as ExtractZip from "../ExtractZip/ExtractZip.js";
4
+ import * as GetListContentZipFilesResponse from "../GetListContentZipFilesResponse/GetListContentZipFilesResponse.js";
5
+ import * as Login from "../Login/Login.js";
6
+ import * as UploadZip from "../UploadZip/UploadZip.js";
7
+
8
+ export const commandMap = {
9
+ "Network.uploadZip": UploadZip.uploadZip,
10
+ "Network.createZip": CreateZip.createZip,
11
+ "Network.downloadZipFile": DownloadZipFile.downloadZipFile,
12
+ "Network.extractZip": ExtractZip.extractZip,
13
+ "Network.getListContentZipFilesResponse":
14
+ GetListContentZipFilesResponse.getListContentZipFilesResponse,
15
+ "Network.login": Login.login,
16
+ };
@@ -0,0 +1,17 @@
1
+ export const state = {
2
+ commands: Object.create(null),
3
+ };
4
+
5
+ export const registerCommand = (key, fn) => {
6
+ state.commands[key] = fn;
7
+ };
8
+
9
+ export const registerCommands = (commandMap) => {
10
+ for (const [key, value] of Object.entries(commandMap)) {
11
+ registerCommand(key, value);
12
+ }
13
+ };
14
+
15
+ export const getCommand = (key) => {
16
+ return state.commands[key];
17
+ };
@@ -0,0 +1,25 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import archiver from "archiver";
3
+ import { createWriteStream } from "node:fs";
4
+ import { mkdir } from "node:fs/promises";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { dirname } from "path";
7
+ import * as Assert from "../Assert/Assert.js";
8
+
9
+ export const createZip = async ({ inDir, outFile }) => {
10
+ try {
11
+ Assert.string(inDir);
12
+ Assert.string(outFile);
13
+ const archive = archiver("zip", {
14
+ zlib: { level: 9 }, // Sets the compression level.
15
+ });
16
+ await mkdir(dirname(outFile), { recursive: true });
17
+ const outStream = createWriteStream(outFile);
18
+ const promise = pipeline(archive, outStream);
19
+ archive.directory(inDir, false);
20
+ await archive.finalize();
21
+ await promise;
22
+ } catch (error) {
23
+ throw new VError(error, `Failed to create zip`);
24
+ }
25
+ };
@@ -0,0 +1,36 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import ky from "ky";
3
+ import { createWriteStream } from "node:fs";
4
+ import { mkdir } from "node:fs/promises";
5
+ import { dirname } from "node:path";
6
+ import { pipeline } from "node:stream/promises";
7
+ import * as Assert from "../Assert/Assert.js";
8
+
9
+ export const downloadZipFile = async ({
10
+ zipFileId,
11
+ downloadBaseUrl,
12
+ sessionId,
13
+ outFile,
14
+ }) => {
15
+ try {
16
+ Assert.string(zipFileId);
17
+ Assert.string(downloadBaseUrl);
18
+ Assert.string(sessionId);
19
+ Assert.string(outFile);
20
+ const response = await ky(downloadBaseUrl, {
21
+ searchParams: {
22
+ appResourcesId: zipFileId,
23
+ sessionID: sessionId,
24
+ },
25
+ });
26
+ if (!response.body) {
27
+ throw new Error("missing body");
28
+ }
29
+ await mkdir(dirname(outFile), { recursive: true });
30
+ const outStream = createWriteStream(outFile);
31
+ await pipeline(response.body, outStream);
32
+ return response;
33
+ } catch (error) {
34
+ throw new VError(error, `Failed to download zip file`);
35
+ }
36
+ };
@@ -0,0 +1,13 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import * as Assert from "../Assert/Assert.js";
3
+ import extract from "extract-zip";
4
+
5
+ export const extractZip = async ({ inFile, outDir }) => {
6
+ try {
7
+ Assert.string(inFile);
8
+ Assert.string(outDir);
9
+ await extract(inFile, { dir: outDir });
10
+ } catch (error) {
11
+ throw new VError(error, `Failed to extract zip`);
12
+ }
13
+ };
@@ -0,0 +1,9 @@
1
+ import * as Assert from "../Assert/Assert.js";
2
+
3
+ export const getFormData = async (blob, fileName) => {
4
+ Assert.object(blob);
5
+ Assert.string(fileName);
6
+ const body = new FormData();
7
+ body.set("file", blob, fileName);
8
+ return body;
9
+ };
@@ -0,0 +1,78 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import ky from "ky";
3
+ import * as Assert from "../Assert/Assert.js";
4
+ import * as GetXr from "../GetXr/GetXr.js";
5
+
6
+ const getBodyJson = () => {
7
+ return {
8
+ pageNumber: 0,
9
+ pageSize: 1,
10
+ sortBy: "created",
11
+ sortDirection: "asc",
12
+ filters: [],
13
+ t: "cri",
14
+ };
15
+ };
16
+
17
+ const getHeaders = () => {
18
+ const xr = GetXr.getXr();
19
+ return {
20
+ accept: "*/*",
21
+ "accept-language": "en,en-US;q=0.9",
22
+ "content-type": "application/json",
23
+ priority: "u=1, i",
24
+ "sec-ch-ua":
25
+ '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
26
+ "sec-ch-ua-mobile": "?0",
27
+ "sec-ch-ua-platform": '"Linux"',
28
+ "sec-fetch-dest": "empty",
29
+ "sec-fetch-mode": "cors",
30
+ "sec-fetch-site": "same-origin",
31
+ xr,
32
+ // TODO
33
+ cookie: "",
34
+ Referer: "https://purplemanager.com/",
35
+ "Referrer-Policy": "strict-origin-when-cross-origin",
36
+ };
37
+ };
38
+
39
+ export const getListContentZipFilesResponse = async ({
40
+ listResourcesUrl,
41
+ sessionId,
42
+ appId,
43
+ }) => {
44
+ try {
45
+ Assert.string(listResourcesUrl);
46
+ const body = getBodyJson();
47
+ const headers = getHeaders();
48
+ const response = await ky(listResourcesUrl, {
49
+ json: body,
50
+ method: "post",
51
+ headers,
52
+ searchParams: {
53
+ appId,
54
+ sessionID: sessionId,
55
+ xr: headers.xr,
56
+ },
57
+ });
58
+ const result = await response.json();
59
+ return result;
60
+ } catch (error) {
61
+ // @ts-ignore
62
+ if (error && error.name === "HTTPError") {
63
+ // @ts-ignore
64
+ const serverMessage = await error.response.text();
65
+ if (serverMessage === "INTERNAL_ERROR") {
66
+ throw new Error(
67
+ "Failed to list content zip files: internal error. Hint: Check invalid credentials too many requests"
68
+ );
69
+ }
70
+ if (serverMessage) {
71
+ throw new Error(
72
+ `Failed to list content zip files: Server ${serverMessage}`
73
+ );
74
+ }
75
+ }
76
+ throw new VError(error, `Failed to list content zip files`);
77
+ }
78
+ };
@@ -0,0 +1,4 @@
1
+ export const getXr = () => {
2
+ const xr = Math.random().toFixed(8).toString();
3
+ return xr;
4
+ };
@@ -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,15 @@
1
+ import * as IpcChildModule from "../IpcChildModule/IpcChildModule.js";
2
+
3
+ export const listen = async ({ method, ...params }) => {
4
+ const module = await IpcChildModule.getModule(method);
5
+ // @ts-ignore
6
+ const rawIpc = await module.listen(params);
7
+ // @ts-ignore
8
+ if (module.signal) {
9
+ // @ts-ignore
10
+ module.signal(rawIpc);
11
+ }
12
+ // @ts-ignore
13
+ const ipc = module.wrap(rawIpc);
14
+ return ipc;
15
+ };
@@ -0,0 +1,25 @@
1
+ import {
2
+ IpcChildWithElectronMessagePort,
3
+ IpcChildWithElectronUtilityProcess,
4
+ IpcChildWithNodeForkedProcess,
5
+ IpcChildWithNodeWorker,
6
+ IpcChildWithWebSocket,
7
+ } from "@lvce-editor/ipc";
8
+ import * as IpcChildType from "../IpcChildType/IpcChildType.js";
9
+
10
+ export const getModule = (method) => {
11
+ switch (method) {
12
+ case IpcChildType.NodeForkedProcess:
13
+ return IpcChildWithNodeForkedProcess;
14
+ case IpcChildType.NodeWorker:
15
+ return IpcChildWithNodeWorker;
16
+ case IpcChildType.ElectronUtilityProcess:
17
+ return IpcChildWithElectronUtilityProcess;
18
+ case IpcChildType.ElectronMessagePort:
19
+ return IpcChildWithElectronMessagePort;
20
+ case IpcChildType.WebSocket:
21
+ return IpcChildWithWebSocket;
22
+ default:
23
+ throw new Error("unexpected ipc type");
24
+ }
25
+ };
@@ -0,0 +1,20 @@
1
+ export const NodeWorker = 1;
2
+ export const NodeForkedProcess = 2;
3
+ export const ElectronUtilityProcess = 3;
4
+ export const ElectronMessagePort = 4;
5
+ export const NodeMessagePort = 5;
6
+ export const WebSocket = 6;
7
+
8
+ export const Auto = () => {
9
+ const { argv } = process;
10
+ if (argv.includes("--ipc-type=node-worker")) {
11
+ return NodeWorker;
12
+ }
13
+ if (argv.includes("--ipc-type=node-forked-process")) {
14
+ return NodeForkedProcess;
15
+ }
16
+ if (argv.includes("--ipc-type=electron-utility-process")) {
17
+ return ElectronUtilityProcess;
18
+ }
19
+ throw new Error(`[shared-process] unknown ipc type`);
20
+ };
@@ -0,0 +1 @@
1
+ export * from "@lvce-editor/json-rpc";
@@ -0,0 +1,8 @@
1
+ import * as HandleIpc from "../HandleIpc/HandleIpc.js";
2
+ import * as IpcChild from "../IpcChild/IpcChild.js";
3
+ import * as IpcChildType from "../IpcChildType/IpcChildType.js";
4
+
5
+ export const listen = async () => {
6
+ const ipc = await IpcChild.listen({ method: IpcChildType.Auto() });
7
+ HandleIpc.handleIpc(ipc);
8
+ };
@@ -0,0 +1,52 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import ky from "ky";
3
+ import * as Assert from "../Assert/Assert.js";
4
+ import * as GetXr from "../GetXr/GetXr.js";
5
+
6
+ const getBodyJson = (userEmail, userPassword) => {
7
+ Assert.string(userEmail);
8
+ Assert.string(userPassword);
9
+ return {
10
+ email: userEmail,
11
+ password: userPassword,
12
+ permanent: true,
13
+ };
14
+ };
15
+
16
+ const getHeaders = () => {
17
+ const xr = GetXr.getXr();
18
+ return {
19
+ accept: "*/*",
20
+ "content-type": "application/json",
21
+ xr,
22
+ };
23
+ };
24
+
25
+ /**
26
+ *
27
+ * @param {*} param0
28
+ * @returns {Promise<any>}
29
+ */
30
+ export const login = async ({ loginUrl, userEmail, userPassword }) => {
31
+ try {
32
+ Assert.string(loginUrl);
33
+ const body = getBodyJson(userEmail, userPassword);
34
+ const headers = getHeaders();
35
+ const response = await ky(loginUrl, {
36
+ json: body,
37
+ method: "post",
38
+ headers,
39
+ });
40
+ return response.json();
41
+ } catch (error) {
42
+ // @ts-ignore
43
+ if (error && error.name === "HTTPError") {
44
+ // @ts-ignore
45
+ const serverMessage = await error.response.text();
46
+ if (serverMessage === "INTERNAL_ERROR") {
47
+ throw new Error("Failed to login: Internal error. Hint: Check headers");
48
+ }
49
+ }
50
+ throw new VError(error, `Failed to login`);
51
+ }
52
+ };
@@ -0,0 +1,8 @@
1
+ import * as CommandMap from "../CommandMap/CommandMap.js";
2
+ import * as CommandState from "../CommandState/CommandState.js";
3
+ import * as Listen from "../Listen/Listen.js";
4
+
5
+ export const main = async () => {
6
+ CommandState.registerCommands(CommandMap.commandMap);
7
+ await Listen.listen();
8
+ };
@@ -0,0 +1,66 @@
1
+ import { VError } from "@lvce-editor/verror";
2
+ import { openAsBlob } from "fs";
3
+ import ky from "ky";
4
+ import * as Assert from "../Assert/Assert.js";
5
+ import * as GetFormData from "../GetFormData/GetFormData.js";
6
+ import * as GetXr from "../GetXr/GetXr.js";
7
+
8
+ const getHeaders = () => {
9
+ const xr = GetXr.getXr();
10
+ return {
11
+ xr,
12
+ };
13
+ };
14
+
15
+ export const uploadZip = async ({
16
+ file,
17
+ uploadBaseUrl,
18
+ preview,
19
+ appId,
20
+ sessionId,
21
+ uploadTimeout,
22
+ message,
23
+ }) => {
24
+ try {
25
+ Assert.string(file);
26
+ Assert.string(uploadBaseUrl);
27
+ Assert.boolean(preview);
28
+ Assert.number(uploadTimeout);
29
+ Assert.string(message);
30
+ Assert.string(sessionId);
31
+ Assert.string(appId);
32
+
33
+ const blob = await openAsBlob(file, {
34
+ type: "application/zip",
35
+ });
36
+ const formData = await GetFormData.getFormData(blob, `${message}.zip`);
37
+ const headers = getHeaders();
38
+ const response = await ky.post(uploadBaseUrl, {
39
+ headers,
40
+ body: formData,
41
+ searchParams: {
42
+ preview,
43
+ appId,
44
+ sessionID: sessionId,
45
+ xr: headers.xr,
46
+ },
47
+ timeout: uploadTimeout,
48
+ });
49
+ return response.text();
50
+ } catch (error) {
51
+ // @ts-ignore
52
+ if (error && error.name === "HTTPError") {
53
+ // @ts-ignore
54
+ const serverMessage = await error.response.text();
55
+ if (serverMessage === "INTERNAL_ERROR") {
56
+ throw new Error(
57
+ "Failed to list upload zip file: internal error. Hint: Check headers"
58
+ );
59
+ }
60
+ if (serverMessage) {
61
+ throw new Error(`Failed to upload zip file: Server ${serverMessage}`);
62
+ }
63
+ }
64
+ throw new VError(error, `Failed to upload zip`);
65
+ }
66
+ };