@pulse-editor/cli 0.1.1-beta.9 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +4 -1
- package/dist/components/commands/build.js +18 -33
- package/dist/components/commands/code.d.ts +5 -0
- package/dist/components/commands/code.js +342 -0
- package/dist/components/commands/create.js +38 -12
- package/dist/components/commands/dev.js +35 -8
- package/dist/components/commands/login.d.ts +2 -2
- package/dist/components/commands/login.js +110 -26
- package/dist/components/commands/preview.js +50 -11
- package/dist/components/commands/publish.js +23 -37
- package/dist/components/commands/{start copy.d.ts → skill.d.ts} +1 -1
- package/dist/components/commands/skill.js +230 -0
- package/dist/components/commands/{preview copy.d.ts → upgrade.d.ts} +1 -1
- package/dist/components/commands/upgrade.js +53 -0
- package/dist/lib/backend/publish-app.d.ts +1 -0
- package/dist/lib/backend/publish-app.js +26 -0
- package/dist/lib/backend-url.d.ts +1 -0
- package/dist/lib/backend-url.js +3 -0
- package/dist/lib/cli-flags.d.ts +22 -0
- package/dist/lib/cli-flags.js +22 -0
- package/dist/lib/manual.js +40 -0
- package/dist/lib/server/express.js +81 -41
- package/dist/lib/server/preview/backend/load-remote.cjs +28 -18
- package/dist/lib/server/utils.js +3 -3
- package/dist/lib/token.js +2 -3
- package/dist/lib/webpack/compile.d.ts +2 -0
- package/dist/lib/webpack/compile.js +30 -0
- package/dist/lib/webpack/configs/mf-client.d.ts +3 -0
- package/dist/lib/webpack/configs/mf-client.js +184 -0
- package/dist/lib/webpack/configs/mf-server.d.ts +2 -0
- package/dist/lib/webpack/configs/mf-server.js +463 -0
- package/dist/lib/webpack/configs/preview.d.ts +3 -0
- package/dist/lib/webpack/configs/preview.js +117 -0
- package/dist/lib/webpack/configs/utils.d.ts +10 -0
- package/dist/lib/webpack/configs/utils.js +172 -0
- package/dist/lib/webpack/dist/pregistered-actions.d.ts +2 -0
- package/dist/lib/webpack/dist/pulse.config.d.ts +7 -0
- package/dist/lib/webpack/dist/src/lib/agents/code-modifier-agent.d.ts +2 -0
- package/dist/lib/webpack/dist/src/lib/agents/vibe-coding-agent.d.ts +3 -0
- package/dist/lib/webpack/dist/src/lib/mcp/utils.d.ts +3 -0
- package/dist/lib/webpack/dist/src/lib/streaming/message-stream-controller.d.ts +10 -0
- package/dist/lib/webpack/dist/src/lib/types.d.ts +58 -0
- package/dist/lib/webpack/dist/src/server-function/generate-code/v1/generate.d.ts +5 -0
- package/dist/lib/webpack/dist/src/server-function/generate-code/v2/generate.d.ts +1 -0
- package/dist/lib/webpack/tsconfig.server.json +19 -0
- package/dist/lib/webpack/webpack-config.d.ts +1 -0
- package/dist/lib/webpack/webpack-config.js +24 -0
- package/dist/lib/webpack/webpack.config.d.ts +2 -0
- package/dist/lib/webpack/webpack.config.js +527 -0
- package/package.json +31 -20
- package/readme.md +7 -1
- package/dist/components/commands/preview copy.js +0 -14
- package/dist/components/commands/start copy.js +0 -14
- package/dist/lib/deps.d.ts +0 -1
- package/dist/lib/deps.js +0 -5
- package/dist/lib/node_module_bin.d.ts +0 -1
- package/dist/lib/node_module_bin.js +0 -7
- package/dist/lib/server/preview/backend/index.d.ts +0 -1
- package/dist/lib/server/preview/backend/index.js +0 -23
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { $ } from 'execa';
|
|
3
|
+
import React, { useEffect, useState } from 'react';
|
|
4
|
+
import { Box, Text } from 'ink';
|
|
5
|
+
import Spinner from 'ink-spinner';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
export default function Upgrade({ cli }) {
|
|
8
|
+
const [isInProjectDir, setIsInProjectDir] = useState(false);
|
|
9
|
+
const [step, setStep] = useState('check-config');
|
|
10
|
+
const [isError, setIsError] = useState(false);
|
|
11
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
async function checkConfig() {
|
|
14
|
+
// Check if the current dir contains pulse.config.ts
|
|
15
|
+
const currentDir = process.cwd();
|
|
16
|
+
const pulseConfigPath = `${currentDir}/pulse.config.ts`;
|
|
17
|
+
if (fs.existsSync(pulseConfigPath)) {
|
|
18
|
+
setIsInProjectDir(true);
|
|
19
|
+
}
|
|
20
|
+
setStep('upgrade');
|
|
21
|
+
}
|
|
22
|
+
checkConfig();
|
|
23
|
+
}, []);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
async function start() {
|
|
26
|
+
try {
|
|
27
|
+
await upgradePackages();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
setIsError(true);
|
|
31
|
+
setErrorMessage(error.message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (isInProjectDir) {
|
|
35
|
+
start();
|
|
36
|
+
}
|
|
37
|
+
}, [isInProjectDir]);
|
|
38
|
+
async function upgradePackages() {
|
|
39
|
+
const tag = cli.flags.beta ? 'beta' : 'latest';
|
|
40
|
+
await $ `npm install react@${React.version} react-dom@${React.version} --save-exact --silent --force`;
|
|
41
|
+
await $ `npm install -D @pulse-editor/cli@${tag} --silent --force`;
|
|
42
|
+
await $ `npm install @pulse-editor/shared-utils@${tag} @pulse-editor/react-api@${tag} --silent --force`;
|
|
43
|
+
// Remove webpack.config.ts if exists
|
|
44
|
+
const webpackConfigPath = `${process.cwd()}/webpack.config.ts`;
|
|
45
|
+
if (fs.existsSync(webpackConfigPath)) {
|
|
46
|
+
fs.unlinkSync(webpackConfigPath);
|
|
47
|
+
}
|
|
48
|
+
// Uninstall @module-federation/node html-webpack-plugin copy-webpack-plugin glob mini-css-extract-plugin webpack webpack-cli webpack-dev-server
|
|
49
|
+
await $ `npm uninstall @module-federation/node html-webpack-plugin copy-webpack-plugin glob mini-css-extract-plugin webpack webpack-cli webpack-dev-server --silent --force`;
|
|
50
|
+
setStep('done');
|
|
51
|
+
}
|
|
52
|
+
return (_jsx(_Fragment, { children: isError ? (_jsxs(Text, { color: 'redBright', children: ["\u274C An error occurred: ", errorMessage || 'Unknown error'] })) : !isInProjectDir ? (_jsx(Text, { color: 'redBright', children: "\u26D4 The current directory does not contain a Pulse Editor project." })) : step === 'check-config' ? (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Checking configuration..." })] })) : step === 'upgrade' ? (_jsx(_Fragment, { children: _jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Upgrading packages..." })] }) })) : (_jsx(Box, { children: _jsx(Text, { color: 'greenBright', children: "\u2705 Upgrade completed successfully." }) })) }));
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function publishApp(isStage: boolean): Promise<Response>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getToken } from '../token.js';
|
|
2
|
+
import { getBackendUrl } from '../backend-url.js';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
export async function publishApp(isStage) {
|
|
5
|
+
// Upload the zip file to the server
|
|
6
|
+
// Read pulse.config.json for visibility
|
|
7
|
+
const config = JSON.parse(fs.readFileSync('./dist/pulse.config.json', 'utf-8'));
|
|
8
|
+
const visibility = config.visibility;
|
|
9
|
+
const formData = new FormData();
|
|
10
|
+
const buffer = fs.readFileSync('./node_modules/@pulse-editor/dist.zip');
|
|
11
|
+
// @ts-ignore Create a Blob from the buffer
|
|
12
|
+
const blob = new Blob([buffer], {
|
|
13
|
+
type: 'application/zip',
|
|
14
|
+
});
|
|
15
|
+
formData.append('file', blob, 'dist.zip');
|
|
16
|
+
formData.append('visibility', visibility);
|
|
17
|
+
// Send the file to the server
|
|
18
|
+
const res = await fetch(`${getBackendUrl(isStage)}/api/app/publish`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
Authorization: `Bearer ${getToken(isStage)}`,
|
|
22
|
+
},
|
|
23
|
+
body: formData,
|
|
24
|
+
});
|
|
25
|
+
return res;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getBackendUrl(stage: boolean): "https://localhost:8080" | "https://pulse-editor.com";
|
package/dist/lib/cli-flags.d.ts
CHANGED
|
@@ -25,5 +25,27 @@ export declare const flags: {
|
|
|
25
25
|
type: "string";
|
|
26
26
|
shortFlag: string;
|
|
27
27
|
};
|
|
28
|
+
beta: {
|
|
29
|
+
type: "boolean";
|
|
30
|
+
};
|
|
31
|
+
build: {
|
|
32
|
+
type: "boolean";
|
|
33
|
+
default: true;
|
|
34
|
+
};
|
|
35
|
+
path: {
|
|
36
|
+
type: "string";
|
|
37
|
+
shortFlag: string;
|
|
38
|
+
};
|
|
39
|
+
displayName: {
|
|
40
|
+
type: "string";
|
|
41
|
+
};
|
|
42
|
+
description: {
|
|
43
|
+
type: "string";
|
|
44
|
+
shortFlag: string;
|
|
45
|
+
};
|
|
46
|
+
continue: {
|
|
47
|
+
type: "boolean";
|
|
48
|
+
default: false;
|
|
49
|
+
};
|
|
28
50
|
};
|
|
29
51
|
export type Flags = typeof flags;
|
package/dist/lib/cli-flags.js
CHANGED
|
@@ -29,4 +29,26 @@ export const flags = defineFlags({
|
|
|
29
29
|
type: 'string',
|
|
30
30
|
shortFlag: 't',
|
|
31
31
|
},
|
|
32
|
+
beta: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
},
|
|
35
|
+
build: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
default: true,
|
|
38
|
+
},
|
|
39
|
+
path: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
shortFlag: 'p',
|
|
42
|
+
},
|
|
43
|
+
displayName: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
},
|
|
46
|
+
description: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
shortFlag: 'd',
|
|
49
|
+
},
|
|
50
|
+
continue: {
|
|
51
|
+
type: 'boolean',
|
|
52
|
+
default: false,
|
|
53
|
+
},
|
|
32
54
|
});
|
package/dist/lib/manual.js
CHANGED
|
@@ -9,6 +9,17 @@ const chat = `\
|
|
|
9
9
|
--interactive, -i
|
|
10
10
|
Start an interactive chat session
|
|
11
11
|
|
|
12
|
+
`;
|
|
13
|
+
const code = `\
|
|
14
|
+
code Generate a new Pulse App from a prompt using AI.
|
|
15
|
+
|
|
16
|
+
Flags:
|
|
17
|
+
--name, -n [app-name]
|
|
18
|
+
Optional app name used for generation.
|
|
19
|
+
--continue, -c
|
|
20
|
+
Continue building on an existing app. Reads the app ID
|
|
21
|
+
and version from the package.json in the current directory.
|
|
22
|
+
|
|
12
23
|
`;
|
|
13
24
|
const login = `\
|
|
14
25
|
login Login to the Pulse Editor Platform.
|
|
@@ -27,6 +38,9 @@ const logout = `\
|
|
|
27
38
|
`;
|
|
28
39
|
const publish = `\
|
|
29
40
|
publish Publish Pulse Editor Extension in current directory to the Pulse Editor Platform.
|
|
41
|
+
Flags:
|
|
42
|
+
--noBuild
|
|
43
|
+
Skip the build step before publishing.
|
|
30
44
|
|
|
31
45
|
`;
|
|
32
46
|
const create = `\
|
|
@@ -41,6 +55,9 @@ const create = `\
|
|
|
41
55
|
--visibility, -v [visibility]
|
|
42
56
|
The visibility of the new project. Options are private,
|
|
43
57
|
public, and unlisted.
|
|
58
|
+
--path, -p [path]
|
|
59
|
+
The path where to create the new project. Defaults to
|
|
60
|
+
the name of the project in the current working directory.
|
|
44
61
|
|
|
45
62
|
`;
|
|
46
63
|
const preview = `\
|
|
@@ -71,10 +88,31 @@ const start = `\
|
|
|
71
88
|
const clean = `\
|
|
72
89
|
clean Clean the dist/ directory.
|
|
73
90
|
|
|
91
|
+
`;
|
|
92
|
+
const upgrade = `\
|
|
93
|
+
upgrade Upgrade Pulse Editor CLI and related packages to the latest version.
|
|
94
|
+
Flags:
|
|
95
|
+
--beta
|
|
96
|
+
Upgrade to the latest beta version.
|
|
97
|
+
|
|
98
|
+
`;
|
|
99
|
+
const skill = `\
|
|
100
|
+
skill Manage skill actions for the current Pulse App.
|
|
101
|
+
|
|
102
|
+
Subcommands:
|
|
103
|
+
create <skill-name> --description "<description>"
|
|
104
|
+
Generate a new skill action using AI and write it to
|
|
105
|
+
src/skill/<skill-name>/action.ts.
|
|
106
|
+
|
|
107
|
+
fix <action-name>
|
|
108
|
+
Fix and apply valid JSDoc comments to an existing skill
|
|
109
|
+
action at src/skill/<action-name>/action.ts using AI.
|
|
110
|
+
|
|
74
111
|
`;
|
|
75
112
|
export const commandsManual = {
|
|
76
113
|
help,
|
|
77
114
|
chat,
|
|
115
|
+
code,
|
|
78
116
|
login,
|
|
79
117
|
logout,
|
|
80
118
|
publish,
|
|
@@ -84,4 +122,6 @@ export const commandsManual = {
|
|
|
84
122
|
build,
|
|
85
123
|
start,
|
|
86
124
|
clean,
|
|
125
|
+
upgrade,
|
|
126
|
+
skill,
|
|
87
127
|
};
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This is a local dev server for "npm run dev" and "npm run preview".
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
5
|
-
import cors from
|
|
6
|
-
import dotenv from
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { networkInterfaces } from
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
4
|
+
import connectLivereload from "connect-livereload";
|
|
5
|
+
import cors from "cors";
|
|
6
|
+
import dotenv from "dotenv";
|
|
7
|
+
import express from "express";
|
|
8
|
+
import livereload from "livereload";
|
|
9
|
+
import { networkInterfaces } from "os";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { pipeline, Readable } from "stream";
|
|
12
|
+
import { pathToFileURL } from "url";
|
|
13
|
+
import { promisify } from "util";
|
|
14
|
+
import { readConfigFile } from "../webpack/configs/utils.js";
|
|
15
15
|
dotenv.config({
|
|
16
16
|
quiet: true,
|
|
17
17
|
});
|
|
18
|
-
const isPreview = process.env?.[
|
|
19
|
-
const isDev = process.env?.[
|
|
20
|
-
const workspaceId = process.env?.[
|
|
18
|
+
const isPreview = process.env?.["PREVIEW"];
|
|
19
|
+
const isDev = process.env?.["NODE_ENV"] === "development";
|
|
20
|
+
const workspaceId = process.env?.["WORKSPACE_ID"];
|
|
21
21
|
const pulseConfig = await readConfigFile();
|
|
22
22
|
if (isDev || isPreview) {
|
|
23
23
|
const livereloadServer = livereload.createServer({
|
|
24
24
|
// @ts-expect-error override server options
|
|
25
|
-
host:
|
|
25
|
+
host: "0.0.0.0",
|
|
26
26
|
});
|
|
27
|
-
livereloadServer.watch(
|
|
28
|
-
livereloadServer.server.once(
|
|
29
|
-
console.log(
|
|
27
|
+
livereloadServer.watch("dist");
|
|
28
|
+
livereloadServer.server.once("connection", () => {
|
|
29
|
+
console.log("✅ LiveReload connected");
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
const app = express();
|
|
@@ -49,51 +49,91 @@ app.use((req, res, next) => {
|
|
|
49
49
|
return next();
|
|
50
50
|
});
|
|
51
51
|
// Serve backend
|
|
52
|
-
app.use(`/${pulseConfig.id}/${pulseConfig.version}/server`, express.static(
|
|
52
|
+
app.use(`/${pulseConfig.id}/${pulseConfig.version}/server`, express.static("dist/server"));
|
|
53
53
|
// Catch backend function calls
|
|
54
54
|
app.all(/^\/server-function\/(.*)/, async (req, res) => {
|
|
55
55
|
const func = req.params[0];
|
|
56
|
-
const url = `${req.protocol}://${req.get(
|
|
56
|
+
const url = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
|
|
57
57
|
// Convert Express req -> Fetch Request
|
|
58
58
|
const request = new Request(url, {
|
|
59
59
|
method: req.method,
|
|
60
60
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
61
|
headers: req.headers,
|
|
62
|
-
body: [
|
|
62
|
+
body: ["GET", "HEAD"].includes(req.method)
|
|
63
63
|
? null
|
|
64
64
|
: JSON.stringify(req.body),
|
|
65
65
|
});
|
|
66
|
-
const dir = path.resolve(
|
|
66
|
+
const dir = path.resolve("node_modules/@pulse-editor/cli/dist/lib/server/preview/backend/load-remote.cjs");
|
|
67
67
|
const fileUrl = pathToFileURL(dir).href;
|
|
68
|
-
const {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (response.body) {
|
|
74
|
-
// Convert WHATWG stream to Node.js stream
|
|
75
|
-
const nodeStream = Readable.fromWeb(response.body);
|
|
76
|
-
// Pipe it directly to Express
|
|
77
|
-
await streamPipeline(nodeStream, res);
|
|
68
|
+
const { loadFunc, loadPrice } = await import(fileUrl);
|
|
69
|
+
const price = await loadPrice(func, pulseConfig.id, "http://localhost:3030", pulseConfig.version);
|
|
70
|
+
if (price) {
|
|
71
|
+
// Make func name and price bold in console
|
|
72
|
+
console.log(`🏃 Running function \x1b[1m${func}\x1b[0m, credits consumed: \x1b[1m${price}\x1b[0m`);
|
|
78
73
|
}
|
|
79
74
|
else {
|
|
80
|
-
|
|
75
|
+
console.log(`🏃 Running function \x1b[1m${func}\x1b[0m.`);
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
const loadedFunc = await loadFunc(func, pulseConfig.id, "http://localhost:3030", pulseConfig.version);
|
|
79
|
+
const response = await loadedFunc(request);
|
|
80
|
+
const streamPipeline = promisify(pipeline);
|
|
81
|
+
if (response) {
|
|
82
|
+
// 1️⃣ Set status code
|
|
83
|
+
res.status(response.status);
|
|
84
|
+
// 2️⃣ Copy headers
|
|
85
|
+
response.headers.forEach((value, key) => {
|
|
86
|
+
res.setHeader(key, value);
|
|
87
|
+
});
|
|
88
|
+
// 3️⃣ Pipe body if present
|
|
89
|
+
if (response.body) {
|
|
90
|
+
const nodeStream = Readable.fromWeb(response.body);
|
|
91
|
+
await streamPipeline(nodeStream, res);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
res.end();
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
});
|
|
83
98
|
if (isPreview) {
|
|
84
99
|
/* Preview mode */
|
|
85
|
-
app.use(express.static(
|
|
86
|
-
|
|
100
|
+
app.use(express.static("dist/client"));
|
|
101
|
+
// Expose skill actions as REST API endpoints in dev and preview modes
|
|
102
|
+
const skillActions = pulseConfig?.actions || [];
|
|
103
|
+
const skillActionNames = skillActions.map((a) => a.name);
|
|
104
|
+
app.post("/skill/:actionName", async (req, res) => {
|
|
105
|
+
const { actionName } = req.params;
|
|
106
|
+
if (skillActionNames.length > 0 && !skillActionNames.includes(actionName)) {
|
|
107
|
+
res
|
|
108
|
+
.status(404)
|
|
109
|
+
.json({ error: `Skill action "${actionName}" not found.` });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const dir = path.resolve("node_modules/@pulse-editor/cli/dist/lib/server/preview/backend/load-remote.cjs");
|
|
113
|
+
const fileUrl = pathToFileURL(dir).href;
|
|
114
|
+
const { loadFunc } = await import(fileUrl);
|
|
115
|
+
try {
|
|
116
|
+
const action = await loadFunc(`skill/${actionName}`, pulseConfig.id, "http://localhost:3030", pulseConfig.version);
|
|
117
|
+
const result = await action(req.body);
|
|
118
|
+
res.json(result);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
122
|
+
console.error(`❌ Error running skill action "${actionName}": ${message}`);
|
|
123
|
+
res.status(500).json({ error: message });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
app.listen(3030, "0.0.0.0");
|
|
87
127
|
}
|
|
88
128
|
else if (isDev) {
|
|
89
129
|
/* Dev mode */
|
|
90
|
-
app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static(
|
|
91
|
-
app.listen(3030,
|
|
130
|
+
app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static("dist"));
|
|
131
|
+
app.listen(3030, "0.0.0.0");
|
|
92
132
|
}
|
|
93
133
|
else {
|
|
94
134
|
/* Production mode */
|
|
95
|
-
app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static(
|
|
96
|
-
app.listen(3030,
|
|
135
|
+
app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static("dist"));
|
|
136
|
+
app.listen(3030, "0.0.0.0", () => {
|
|
97
137
|
console.log(`\
|
|
98
138
|
🎉 Your Pulse extension \x1b[1m${pulseConfig.displayName}\x1b[0m is LIVE!
|
|
99
139
|
|
|
@@ -109,10 +149,10 @@ function getLocalNetworkIP() {
|
|
|
109
149
|
if (!iface)
|
|
110
150
|
continue;
|
|
111
151
|
for (const config of iface) {
|
|
112
|
-
if (config.family ===
|
|
152
|
+
if (config.family === "IPv4" && !config.internal) {
|
|
113
153
|
return config.address; // Returns the first non-internal IPv4 address
|
|
114
154
|
}
|
|
115
155
|
}
|
|
116
156
|
}
|
|
117
|
-
return
|
|
157
|
+
return "localhost"; // Fallback
|
|
118
158
|
}
|
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {createInstance} = require('@module-federation/runtime');
|
|
2
2
|
|
|
3
|
-
async function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
],
|
|
14
|
-
});
|
|
3
|
+
async function importRemoteModule(func, appId, origin, version) {
|
|
4
|
+
const instance = createInstance({
|
|
5
|
+
name: 'server_function_runner',
|
|
6
|
+
remotes: [
|
|
7
|
+
{
|
|
8
|
+
name: appId + '_server',
|
|
9
|
+
entry: `${origin}/${appId}/${version}/server/remoteEntry.js`,
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
});
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const loadedModule = await instance.loadRemote(`${appId}_server/${func}`);
|
|
15
|
+
return loadedModule;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function loadFunc(func, appId, origin, version) {
|
|
19
|
+
// here we assign the return value of the init() function, which can be used to do some more complex
|
|
20
|
+
// things with the module federation runtime
|
|
21
|
+
const module = await importRemoteModule(func, appId, origin, version);
|
|
22
|
+
const loadedFunc = module.default;
|
|
23
|
+
|
|
24
|
+
return loadedFunc;
|
|
25
|
+
}
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
async function loadPrice(func, appId, origin, version) {
|
|
28
|
+
const module = await importRemoteModule(func, appId, origin, version);
|
|
29
|
+
const price = module._CREDIT_PER_CALL;
|
|
30
|
+
return price;
|
|
21
31
|
}
|
|
22
32
|
|
|
23
|
-
module.exports = {
|
|
33
|
+
module.exports = {loadFunc, loadPrice};
|
package/dist/lib/server/utils.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
export async function readConfigFile() {
|
|
3
3
|
// Read pulse.config.json from dist/client
|
|
4
|
-
// Wait until dist/
|
|
4
|
+
// Wait until dist/pulse.config.json exists
|
|
5
5
|
while (true) {
|
|
6
6
|
try {
|
|
7
|
-
await fs.access('dist/
|
|
7
|
+
await fs.access('dist/pulse.config.json');
|
|
8
8
|
break;
|
|
9
9
|
}
|
|
10
10
|
catch (err) {
|
|
@@ -12,6 +12,6 @@ export async function readConfigFile() {
|
|
|
12
12
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
const data = await fs.readFile('dist/
|
|
15
|
+
const data = await fs.readFile('dist/pulse.config.json', 'utf-8');
|
|
16
16
|
return JSON.parse(data);
|
|
17
17
|
}
|
package/dist/lib/token.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
+
import { getBackendUrl } from './backend-url.js';
|
|
4
5
|
export function saveToken(token, devMode) {
|
|
5
6
|
// Save the token to .pulse-editor/config.json in user home directory
|
|
6
7
|
const configDir = path.join(os.homedir(), '.pulse-editor');
|
|
@@ -62,9 +63,7 @@ export function isTokenInEnv(devMode) {
|
|
|
62
63
|
return false;
|
|
63
64
|
}
|
|
64
65
|
export async function checkToken(token, devMode) {
|
|
65
|
-
const res = await fetch(devMode
|
|
66
|
-
? 'https://localhost:8080/api/api-keys/check'
|
|
67
|
-
: 'https://pulse-editor.com/api/api-keys/check', {
|
|
66
|
+
const res = await fetch(`${getBackendUrl(devMode)}/api/api-keys/check`, {
|
|
68
67
|
body: JSON.stringify({ token }),
|
|
69
68
|
headers: {
|
|
70
69
|
'Content-Type': 'application/json',
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import webpack from "webpack";
|
|
2
|
+
import { generateTempTsConfig } from "./configs/utils.js";
|
|
3
|
+
import { createWebpackConfig } from "./webpack-config.js";
|
|
4
|
+
export async function webpackCompile(mode, buildTarget, isWatchMode = false) {
|
|
5
|
+
generateTempTsConfig();
|
|
6
|
+
const configs = await createWebpackConfig(mode === "preview", buildTarget ?? "both", mode === "development"
|
|
7
|
+
? "development"
|
|
8
|
+
: mode === "preview"
|
|
9
|
+
? "development"
|
|
10
|
+
: "production");
|
|
11
|
+
const compiler = webpack(configs);
|
|
12
|
+
if (isWatchMode) {
|
|
13
|
+
compiler.watch({}, (err, stats) => {
|
|
14
|
+
if (err) {
|
|
15
|
+
console.error("❌ Webpack build failed", err);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return compiler;
|
|
20
|
+
}
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
compiler.run((err) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
reject(err);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
resolve();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|