@pulse-editor/cli 0.1.1-beta.2 → 0.1.1-beta.20

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 CHANGED
@@ -12,6 +12,7 @@ import Build from './components/commands/build.js';
12
12
  import Preview from './components/commands/preview.js';
13
13
  import Start from './components/commands/start.js';
14
14
  import Clean from './components/commands/clean.js';
15
+ import Upgrade from './components/commands/upgrade.js';
15
16
  export default function App({ cli }) {
16
17
  const [command, setCommand] = useState(undefined);
17
18
  if (cli.flags.stage) {
@@ -24,5 +25,5 @@ export default function App({ cli }) {
24
25
  const cmd = cli.input[0] ?? 'help';
25
26
  setCommand(cmd);
26
27
  }, [cli.input]);
27
- return (_jsxs(_Fragment, { children: [cli.flags.stage && (_jsx(Text, { color: 'yellow', children: "\u26A0\uFE0F You are in development mode." })), command === 'help' ? (_jsx(Help, { cli: cli })) : command === 'chat' ? (_jsx(Chat, { cli: cli })) : command === 'login' ? (_jsx(Login, { cli: cli })) : command === 'logout' ? (_jsx(Logout, { cli: cli })) : command === 'publish' ? (_jsx(Publish, { cli: cli })) : command === 'create' ? (_jsx(Create, { cli: cli })) : command === 'dev' ? (_jsx(Dev, { cli: cli })) : command === 'build' ? (_jsx(Build, { cli: cli })) : command === 'preview' ? (_jsx(Preview, { cli: cli })) : command === 'start' ? (_jsx(Start, { cli: cli })) : command === 'clean' ? (_jsx(Clean, { cli: cli })) : (command !== undefined && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: 'redBright', children: ["Invalid command: ", command] }), _jsxs(Text, { children: ["Run ", _jsx(Text, { color: 'blueBright', children: "pulse help" }), " to see the list of available commands."] })] })))] }));
28
+ return (_jsxs(_Fragment, { children: [cli.flags.stage && (_jsx(Text, { color: 'yellow', children: "\u26A0\uFE0F You are in development mode." })), command === 'help' ? (_jsx(Help, { cli: cli })) : command === 'chat' ? (_jsx(Chat, { cli: cli })) : command === 'login' ? (_jsx(Login, { cli: cli })) : command === 'logout' ? (_jsx(Logout, { cli: cli })) : command === 'publish' ? (_jsx(Publish, { cli: cli })) : command === 'create' ? (_jsx(Create, { cli: cli })) : command === 'dev' ? (_jsx(Dev, { cli: cli })) : command === 'build' ? (_jsx(Build, { cli: cli })) : command === 'preview' ? (_jsx(Preview, { cli: cli })) : command === 'start' ? (_jsx(Start, { cli: cli })) : command === 'clean' ? (_jsx(Clean, { cli: cli })) : command === 'upgrade' ? (_jsx(Upgrade, { cli: cli })) : (command !== undefined && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: 'redBright', children: ["Invalid command: ", command] }), _jsxs(Text, { children: ["Run ", _jsx(Text, { color: 'blueBright', children: "pulse help" }), " to see the list of available commands."] })] })))] }));
28
29
  }
package/dist/cli.js CHANGED
@@ -15,6 +15,7 @@ ${Object.entries(commandsManual)
15
15
  .join('')}
16
16
  Examples
17
17
  pulse help publish
18
+
18
19
  `, {
19
20
  importMeta: import.meta,
20
21
  flags: flags,
@@ -3,6 +3,7 @@ import { useEffect } from 'react';
3
3
  import { execa } from 'execa';
4
4
  import fs from 'fs';
5
5
  import { cleanDist } from '../../lib/execa-utils/clean.js';
6
+ import { webpackCompile } from '../../lib/webpack/compile.js';
6
7
  export default function Build({ cli }) {
7
8
  useEffect(() => {
8
9
  async function buildProd() {
@@ -23,6 +24,19 @@ export default function Build({ cli }) {
23
24
  });
24
25
  }
25
26
  }
27
+ // Create node_modules/.pulse/server directory
28
+ if (!fs.existsSync('node_modules/.pulse/server')) {
29
+ if (process.platform === 'win32') {
30
+ await execa('mkdir node_modules\\.pulse\\server', {
31
+ shell: true,
32
+ });
33
+ }
34
+ else {
35
+ await execa('mkdir -p node_modules/.pulse/server', {
36
+ shell: true,
37
+ });
38
+ }
39
+ }
26
40
  if (process.platform === 'win32') {
27
41
  await execa('xcopy /E /I node_modules\\@pulse-editor\\cli\\dist\\lib\\server node_modules\\.pulse\\server', {
28
42
  shell: true,
@@ -35,40 +49,11 @@ export default function Build({ cli }) {
35
49
  }
36
50
  }
37
51
  await cleanDist();
38
- if (buildTarget === undefined) {
39
- // Start building
40
- await execa('npx webpack --mode production', {
41
- stdio: 'inherit',
42
- shell: true,
43
- env: {
44
- NODE_OPTIONS: '--import=tsx',
45
- },
46
- });
47
- }
48
- else if (buildTarget === 'client') {
49
- // Start building client only
50
- await execa('npx webpack --mode production', {
51
- stdio: 'inherit',
52
- shell: true,
53
- env: {
54
- NODE_OPTIONS: '--import=tsx',
55
- BUILD_TARGET: 'client',
56
- },
57
- });
58
- }
59
- else if (buildTarget === 'server') {
60
- // Start building server only
61
- await execa('npx webpack --mode production', {
62
- stdio: 'inherit',
63
- shell: true,
64
- env: {
65
- NODE_OPTIONS: '--import=tsx',
66
- BUILD_TARGET: 'server',
67
- },
68
- });
52
+ try {
53
+ await webpackCompile('production', buildTarget);
69
54
  }
70
- else {
71
- console.error(`❌ Unknown build target: ${buildTarget}`);
55
+ catch (err) {
56
+ console.error('❌ Webpack build failed', err);
72
57
  }
73
58
  }
74
59
  buildProd();
@@ -1,10 +1,10 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Text } from 'ink';
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
2
  import { useEffect } from 'react';
4
3
  import { execa } from 'execa';
5
4
  import fs from 'fs';
6
5
  import { getDepsBinPath } from '../../lib/execa-utils/deps.js';
7
6
  import { cleanDist } from '../../lib/execa-utils/clean.js';
7
+ import { webpackCompile } from '../../lib/webpack/compile.js';
8
8
  export default function Dev({ cli }) {
9
9
  useEffect(() => {
10
10
  async function startDevServer() {
@@ -22,6 +22,19 @@ export default function Dev({ cli }) {
22
22
  });
23
23
  }
24
24
  }
25
+ // Create node_modules/.pulse/server directory
26
+ if (!fs.existsSync('node_modules/.pulse/server')) {
27
+ if (process.platform === 'win32') {
28
+ await execa('mkdir node_modules\\.pulse\\server', {
29
+ shell: true,
30
+ });
31
+ }
32
+ else {
33
+ await execa('mkdir -p node_modules/.pulse/server', {
34
+ shell: true,
35
+ });
36
+ }
37
+ }
25
38
  if (process.platform === 'win32') {
26
39
  await execa('xcopy /E /I node_modules\\@pulse-editor\\cli\\dist\\lib\\server node_modules\\.pulse\\server', {
27
40
  shell: true,
@@ -34,7 +47,14 @@ export default function Dev({ cli }) {
34
47
  }
35
48
  // Start dev server
36
49
  await cleanDist();
37
- await execa(`${getDepsBinPath('concurrently')} --prefix none "webpack --mode development --watch" "tsx watch --clear-screen=false node_modules/@pulse-editor/cli/dist/lib/server/express.js"`, {
50
+ // Start webpack in dev watch mode and watch for changes
51
+ const compiler = await webpackCompile('development', undefined, true);
52
+ // Start server with tsx
53
+ await execa(getDepsBinPath('tsx'), [
54
+ 'watch',
55
+ '--clear-screen=false',
56
+ 'node_modules/@pulse-editor/cli/dist/lib/server/express.js',
57
+ ], {
38
58
  stdio: 'inherit',
39
59
  shell: true,
40
60
  env: {
@@ -42,8 +62,20 @@ export default function Dev({ cli }) {
42
62
  NODE_ENV: 'development',
43
63
  },
44
64
  });
65
+ // Handle process exit to close webpack compiler
66
+ process.on('SIGINT', () => {
67
+ if (compiler && typeof compiler.close === 'function') {
68
+ compiler.close(() => {
69
+ process.exit();
70
+ });
71
+ }
72
+ else {
73
+ process.exit();
74
+ }
75
+ });
45
76
  }
77
+ console.log('🚀 Starting development server...');
46
78
  startDevServer();
47
79
  }, []);
48
- return (_jsx(_Fragment, { children: _jsx(Text, { children: "Starting dev server..." }) }));
80
+ return _jsx(_Fragment, {});
49
81
  }
@@ -4,5 +4,6 @@ import { commandsManual } from '../../lib/manual.js';
4
4
  import Header from '../header.js';
5
5
  export default function Help({ cli }) {
6
6
  const subCommand = cli.input[1];
7
- return (_jsx(_Fragment, { children: subCommand ? (_jsx(Text, { children: commandsManual[subCommand] })) : (_jsxs(_Fragment, { children: [_jsx(Header, {}), _jsx(Text, { children: cli.help })] })) }));
7
+ return (_jsx(_Fragment, { children: subCommand ? (_jsx(Text, { children: commandsManual[subCommand]?.trimEnd() ??
8
+ `No help found for command: ${subCommand}` })) : (_jsxs(_Fragment, { children: [_jsx(Header, {}), _jsx(Text, { children: cli.help })] })) }));
8
9
  }
@@ -1,10 +1,10 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Text } from 'ink';
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
2
  import { useEffect } from 'react';
4
3
  import { execa } from 'execa';
5
4
  import fs from 'fs';
6
5
  import { getDepsBinPath } from '../../lib/execa-utils/deps.js';
7
6
  import { cleanDist } from '../../lib/execa-utils/clean.js';
7
+ import { webpackCompile } from '../../lib/webpack/compile.js';
8
8
  export default function Preview({ cli }) {
9
9
  useEffect(() => {
10
10
  async function startPreviewServer() {
@@ -22,9 +22,19 @@ export default function Preview({ cli }) {
22
22
  });
23
23
  }
24
24
  }
25
- await execa('mkdir "node_modules/.pulse/server"', {
26
- shell: true,
27
- });
25
+ // Create node_modules/.pulse/server directory
26
+ if (!fs.existsSync('node_modules/.pulse/server')) {
27
+ if (process.platform === 'win32') {
28
+ await execa('mkdir node_modules\\.pulse\\server', {
29
+ shell: true,
30
+ });
31
+ }
32
+ else {
33
+ await execa('mkdir -p node_modules/.pulse/server', {
34
+ shell: true,
35
+ });
36
+ }
37
+ }
28
38
  if (process.platform === 'win32') {
29
39
  await execa('xcopy /E /I node_modules\\@pulse-editor\\cli\\dist\\lib\\server node_modules\\.pulse\\server', {
30
40
  shell: true,
@@ -37,7 +47,29 @@ export default function Preview({ cli }) {
37
47
  }
38
48
  // Start preview server
39
49
  await cleanDist();
40
- await execa(`${getDepsBinPath('concurrently')} --prefix none "npx webpack --mode development --watch" "tsx watch --clear-screen=false node_modules/@pulse-editor/cli/dist/lib/server/express.js"`, {
50
+ // await execa(
51
+ // getDepsBinPath('concurrently'),
52
+ // [
53
+ // '--prefix',
54
+ // 'none',
55
+ // '"npx webpack --mode development --watch"',
56
+ // '"tsx watch --clear-screen=false node_modules/@pulse-editor/cli/dist/lib/server/express.js"',
57
+ // ],
58
+ // {
59
+ // stdio: 'inherit',
60
+ // shell: true,
61
+ // env: {
62
+ // NODE_OPTIONS: '--import=tsx',
63
+ // PREVIEW: 'true',
64
+ // },
65
+ // },
66
+ // );
67
+ const compiler = await webpackCompile('preview', undefined, true);
68
+ await execa(getDepsBinPath('tsx'), [
69
+ 'watch',
70
+ '--clear-screen=false',
71
+ 'node_modules/@pulse-editor/cli/dist/lib/server/express.js',
72
+ ], {
41
73
  stdio: 'inherit',
42
74
  shell: true,
43
75
  env: {
@@ -45,8 +77,20 @@ export default function Preview({ cli }) {
45
77
  PREVIEW: 'true',
46
78
  },
47
79
  });
80
+ // Handle process exit to close webpack compiler
81
+ process.on('SIGINT', () => {
82
+ if (compiler && typeof compiler.close === 'function') {
83
+ compiler.close(() => {
84
+ process.exit();
85
+ });
86
+ }
87
+ else {
88
+ process.exit();
89
+ }
90
+ });
48
91
  }
92
+ console.log('🚀 Starting preview server...');
49
93
  startPreviewServer();
50
94
  }, []);
51
- return (_jsx(_Fragment, { children: _jsx(Text, { children: "Starting preview server..." }) }));
95
+ return _jsx(_Fragment, {});
52
96
  }
@@ -5,12 +5,15 @@ import { checkToken, getToken } from '../../lib/token.js';
5
5
  import Spinner from 'ink-spinner';
6
6
  import fs from 'fs';
7
7
  import { $ } from 'execa';
8
+ import { publishApp } from '../../lib/backend/publish-app.js';
8
9
  export default function Publish({ cli }) {
9
10
  const [isInProjectDir, setIsInProjectDir] = useState(false);
10
11
  const [isCheckingAuth, setIsCheckingAuth] = useState(true);
11
12
  const [isAuthenticated, setIsAuthenticated] = useState(false);
12
13
  const [isBuilding, setIsBuilding] = useState(false);
13
14
  const [isBuildingError, setIsBuildingError] = useState(false);
15
+ const [isZipping, setIsZipping] = useState(false);
16
+ const [isZippingError, setIsZippingError] = useState(false);
14
17
  const [isPublishing, setIsPublishing] = useState(false);
15
18
  const [isPublishingError, setIsPublishingError] = useState(false);
16
19
  const [isPublished, setIsPublished] = useState(false);
@@ -45,56 +48,39 @@ export default function Publish({ cli }) {
45
48
  // Build the extension
46
49
  useEffect(() => {
47
50
  async function buildExtension() {
48
- setIsBuilding(true);
49
- try {
50
- await $ `npm run build`;
51
- }
52
- catch (error) {
53
- setIsBuildingError(true);
54
- setIsBuilding(false);
55
- setFailureMessage('Build failed. Please run `npm run build` to see the error.');
56
- return;
51
+ if (cli.flags.build) {
52
+ setIsBuilding(true);
53
+ try {
54
+ await $ `npm run build`;
55
+ }
56
+ catch (error) {
57
+ setIsBuildingError(true);
58
+ setFailureMessage('Build failed. Please run `npm run build` to see the error.');
59
+ return;
60
+ }
61
+ finally {
62
+ setIsBuilding(false);
63
+ }
57
64
  }
65
+ setIsZipping(true);
58
66
  // Zip the dist folder
59
67
  try {
60
68
  await $({ cwd: 'dist' }) `zip -r ../node_modules/@pulse-editor/dist.zip *`;
61
69
  }
62
70
  catch (error) {
63
- setIsBuildingError(true);
64
- setIsBuilding(false);
71
+ setIsZippingError(true);
65
72
  setFailureMessage('Failed to zip the build output.');
66
73
  return;
67
74
  }
68
75
  finally {
69
- setIsBuilding(false);
76
+ setIsZipping(false);
70
77
  }
71
78
  await publishExtension();
72
79
  }
73
80
  async function publishExtension() {
74
81
  setIsPublishing(true);
75
- // Read pulse.config.json for visibility
76
- const config = JSON.parse(fs.readFileSync('./dist/client/pulse.config.json', 'utf-8'));
77
- const visibility = config.visibility;
78
- // Upload the zip file to the server
79
82
  try {
80
- const formData = new FormData();
81
- const buffer = fs.readFileSync('./node_modules/@pulse-editor/dist.zip');
82
- // @ts-ignore Create a Blob from the buffer
83
- const blob = new Blob([buffer], {
84
- type: 'application/zip',
85
- });
86
- formData.append('file', blob, 'dist.zip');
87
- formData.append('visibility', visibility);
88
- // Send the file to the server
89
- const res = await fetch(cli.flags.stage
90
- ? 'https://localhost:8080/api/app/publish'
91
- : 'https://pulse-editor.com/api/app/publish', {
92
- method: 'POST',
93
- headers: {
94
- Authorization: `Bearer ${getToken(cli.flags.stage)}`,
95
- },
96
- body: formData,
97
- });
83
+ const res = await publishApp(cli.flags.stage);
98
84
  if (res.status === 200) {
99
85
  setIsPublished(true);
100
86
  }
@@ -122,5 +108,5 @@ export default function Publish({ cli }) {
122
108
  buildExtension();
123
109
  }
124
110
  }, [isAuthenticated]);
125
- return (_jsx(_Fragment, { children: !isInProjectDir ? (_jsx(Text, { color: 'redBright', children: "\u26D4 The current directory does not contain a Pulse Editor project." })) : isCheckingAuth ? (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Checking authentication..." })] })) : isAuthenticated ? (_jsxs(_Fragment, { children: [isBuilding && (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Building..." })] })), isBuildingError && (_jsx(Text, { color: 'redBright', children: "\u274C Error building the extension. Please run `npm run build` to see the error." })), isPublishing && (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Publishing..." })] })), isPublishingError && (_jsxs(_Fragment, { children: [_jsx(Text, { color: 'redBright', children: "\u274C Failed to publish extension." }), failureMessage && (_jsxs(Text, { color: 'redBright', children: ["Error: ", failureMessage] }))] })), isPublished && (_jsx(Text, { color: 'greenBright', children: "\u2705 Extension published successfully." }))] })) : (_jsxs(Text, { children: ["You are not authenticated or your access token is invalid. Publishing to Extension Marketplace is in Beta access. Please visit", _jsx(Text, { color: 'blueBright', children: " https://pulse-editor.com/beta " }), "to apply for Beta access."] })) }));
111
+ return (_jsx(_Fragment, { children: !isInProjectDir ? (_jsx(Text, { color: 'redBright', children: "\u26D4 The current directory does not contain a Pulse Editor project." })) : isCheckingAuth ? (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Checking authentication..." })] })) : !isAuthenticated ? (_jsxs(Text, { children: ["You are not authenticated or your access token is invalid. Publishing to Extension Marketplace is in Beta access. Please visit", _jsx(Text, { color: 'blueBright', children: " https://pulse-editor.com/beta " }), "to apply for Beta access."] })) : (_jsxs(_Fragment, { children: [isBuilding && (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Building..." })] })), isBuildingError && (_jsx(Text, { color: 'redBright', children: "\u274C Error building the extension. Please run `npm run build` to see the error." })), isZipping && (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Compressing build..." })] })), isZippingError && (_jsx(Text, { color: 'redBright', children: "\u274C Error zipping the build output." })), isPublishing && (_jsxs(Box, { children: [_jsx(Spinner, { type: "dots" }), _jsx(Text, { children: " Publishing..." })] })), isPublishingError && (_jsxs(_Fragment, { children: [_jsx(Text, { color: 'redBright', children: "\u274C Failed to publish extension." }), failureMessage && (_jsxs(Text, { color: 'redBright', children: ["Error: ", failureMessage] }))] })), isPublished && (_jsx(Text, { color: 'greenBright', children: "\u2705 Extension published successfully." }))] })) }));
126
112
  }
@@ -1,5 +1,5 @@
1
1
  import { Result } from 'meow';
2
2
  import { Flags } from '../../lib/cli-flags.js';
3
- export default function Preview({ cli }: {
3
+ export default function Upgrade({ cli }: {
4
4
  cli: Result<Flags>;
5
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -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,27 @@
1
+ import { getToken } from '../token.js';
2
+ import fs from 'fs';
3
+ export async function publishApp(isStage) {
4
+ // Upload the zip file to the server
5
+ // Read pulse.config.json for visibility
6
+ const config = JSON.parse(fs.readFileSync('./dist/client/pulse.config.json', 'utf-8'));
7
+ const visibility = config.visibility;
8
+ const formData = new FormData();
9
+ const buffer = fs.readFileSync('./node_modules/@pulse-editor/dist.zip');
10
+ // @ts-ignore Create a Blob from the buffer
11
+ const blob = new Blob([buffer], {
12
+ type: 'application/zip',
13
+ });
14
+ formData.append('file', blob, 'dist.zip');
15
+ formData.append('visibility', visibility);
16
+ // Send the file to the server
17
+ const res = await fetch(isStage
18
+ ? 'https://localhost:8080/api/app/publish'
19
+ : 'https://pulse-editor.com/api/app/publish', {
20
+ method: 'POST',
21
+ headers: {
22
+ Authorization: `Bearer ${getToken(isStage)}`,
23
+ },
24
+ body: formData,
25
+ });
26
+ return res;
27
+ }
@@ -25,5 +25,12 @@ 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
+ };
28
35
  };
29
36
  export type Flags = typeof flags;
@@ -29,4 +29,11 @@ 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
+ },
32
39
  });
@@ -5,5 +5,5 @@ export async function cleanDist() {
5
5
  await execa(`${getDepsBinPath('rimraf')} dist`, {
6
6
  shell: true,
7
7
  });
8
- console.log('✅ Cleaned dist directory.');
8
+ console.log('✅ Cleaned dist directory.');
9
9
  }
@@ -1,5 +1,14 @@
1
+ import fs from 'fs';
1
2
  // Get deps bin at node_modules/@pulse-editor/cli/node_modules
2
3
  export function getDepsBinPath(name) {
3
4
  const workingDir = process.cwd();
4
- return `${workingDir}/node_modules/@pulse-editor/cli/node_modules/.bin/${process.platform === 'win32' ? `${name}.cmd` : name}`;
5
+ // Check if the package is installed in the node_modules, if yes, just return "npx <name>"
6
+ if (fs.existsSync(`${workingDir}/node_modules/${name}`)) {
7
+ return `npx ${name}`;
8
+ }
9
+ // Check if the package exists in node_modules/@pulse-editor/cli/node_modules
10
+ else if (fs.existsSync(`${workingDir}/node_modules/@pulse-editor/cli/node_modules/${name}`)) {
11
+ return `${workingDir}/node_modules/@pulse-editor/cli/node_modules/.bin/${process.platform === 'win32' ? `${name}.cmd` : name}`;
12
+ }
13
+ throw new Error(`Dependency ${name} not found.`);
5
14
  }
@@ -1,5 +1,6 @@
1
1
  const help = `\
2
2
  help [command] Show help for a command.
3
+
3
4
  `;
4
5
  const chat = `\
5
6
  chat [message] (WIP) Chat with the Pulse Editor AI assistant.
@@ -22,9 +23,14 @@ const login = `\
22
23
  `;
23
24
  const logout = `\
24
25
  logout Logout from the Pulse Editor Platform.
26
+
25
27
  `;
26
28
  const publish = `\
27
29
  publish Publish Pulse Editor Extension in current directory to the Pulse Editor Platform.
30
+ Flags:
31
+ --noBuild
32
+ Skip the build step before publishing.
33
+
28
34
  `;
29
35
  const create = `\
30
36
  create Create a new Pulse App using the starter template.
@@ -38,6 +44,43 @@ const create = `\
38
44
  --visibility, -v [visibility]
39
45
  The visibility of the new project. Options are private,
40
46
  public, and unlisted.
47
+
48
+ `;
49
+ const preview = `\
50
+ preview Build the Pulse App in development mode and
51
+ start a preview server accessible via browser
52
+ with live reloading.
53
+
54
+ `;
55
+ const dev = `\
56
+ dev Build the Pulse App in development mode and
57
+ start a local development server for Pulse Editor
58
+ to load the app from, with live reloading.
59
+
60
+ `;
61
+ const build = `\
62
+ build Build the Pulse App for production deployment.
63
+ Flags:
64
+ --target, -t [target]
65
+ The build target. Options are 'client', 'server', or
66
+ unspecified (both client and server).
67
+
68
+ `;
69
+ const start = `\
70
+ start Build the Pulse App in production mode and
71
+ start a local server for Pulse Editor to load the app from.
72
+
73
+ `;
74
+ const clean = `\
75
+ clean Clean the dist/ directory.
76
+
77
+ `;
78
+ const upgrade = `\
79
+ upgrade Upgrade Pulse Editor CLI and related packages to the latest version.
80
+ Flags:
81
+ --beta
82
+ Upgrade to the latest beta version.
83
+
41
84
  `;
42
85
  export const commandsManual = {
43
86
  help,
@@ -46,4 +89,10 @@ export const commandsManual = {
46
89
  logout,
47
90
  publish,
48
91
  create,
92
+ preview,
93
+ dev,
94
+ build,
95
+ start,
96
+ clean,
97
+ upgrade,
49
98
  };
@@ -16,7 +16,7 @@ dotenv.config({
16
16
  quiet: true,
17
17
  });
18
18
  const isPreview = process.env?.['PREVIEW'];
19
- const isDev = process.env?.['NODE_ENV'];
19
+ const isDev = process.env?.['NODE_ENV'] === 'development';
20
20
  const workspaceId = process.env?.['WORKSPACE_ID'];
21
21
  const pulseConfig = await readConfigFile();
22
22
  if (isDev || isPreview) {
@@ -94,12 +94,12 @@ else {
94
94
  /* Production mode */
95
95
  app.use(`/${pulseConfig.id}/${pulseConfig.version}`, express.static('dist'));
96
96
  app.listen(3030, '0.0.0.0', () => {
97
- console.log(`\
98
- 🎉 Your Pulse extension \x1b[1m${pulseConfig.displayName}\x1b[0m is LIVE!
99
-
100
- ⚡️ Local: http://localhost:3030/${pulseConfig.id}/${pulseConfig.version}/
101
- ⚡️ Network: http://${getLocalNetworkIP()}:3030/${pulseConfig.id}/${pulseConfig.version}/
102
-
97
+ console.log(`\
98
+ 🎉 Your Pulse extension \x1b[1m${pulseConfig.displayName}\x1b[0m is LIVE!
99
+
100
+ ⚡️ Local: http://localhost:3030/${pulseConfig.id}/${pulseConfig.version}/
101
+ ⚡️ Network: http://${getLocalNetworkIP()}:3030/${pulseConfig.id}/${pulseConfig.version}/
102
+
103
103
  ✨ Try it out in the Pulse Editor and let the magic happen! 🚀`);
104
104
  });
105
105
  }