Skip to content

Commit 9f44116

Browse files
wip: serve
1 parent 83a7603 commit 9f44116

File tree

9 files changed

+590
-26
lines changed

9 files changed

+590
-26
lines changed

cli/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@oclif/plugin-plugins": "^5",
1616
"@powersync/cli-core": "workspace:*",
1717
"@powersync/cli-plugin-docker": "workspace:*",
18+
"@powersync/cli-plugin-config-edit": "workspace:*",
1819
"@powersync/cli-schemas": "workspace:*",
1920
"@powersync/management-client": "0.0.1",
2021
"@powersync/management-types": "0.0.1",
@@ -75,7 +76,8 @@
7576
"plugins": [
7677
"@oclif/plugin-help",
7778
"@oclif/plugin-plugins",
78-
"@powersync/cli-plugin-docker"
79+
"@powersync/cli-plugin-docker",
80+
"@powersync/cli-plugin-config-edit"
7981
],
8082
"topicSeparator": " ",
8183
"topics": {

cli/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"references": [
1919
{ "path": "../packages/cli-core" },
2020
{ "path": "../packages/schemas" },
21-
{ "path": "../plugins/docker" }
21+
{ "path": "../plugins/docker" },
22+
{ "path": "../plugins/config-edit" }
2223
],
2324
"ts-node": {
2425
"esm": true

packages/editor/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
},
88
"scripts": {
99
"dev": "vite dev --port 3000",
10-
"build": "vite build",
10+
"build": "vite build && pnpm run copy-editor-dist",
11+
"copy-editor-dist": "node ./scripts/copy-editor-dist.mjs",
1112
"preview": "vite preview",
1213
"test": "vitest run"
1314
},
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { cpSync, existsSync, rmSync } from 'node:fs';
2+
import path from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
5+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
6+
const repoRoot = path.resolve(__dirname, '..', '..', '..');
7+
const sourceDist = path.join(__dirname, '..', '.output');
8+
const targetDist = path.join(repoRoot, 'plugins', 'config-edit', 'editor-dist');
9+
10+
if (!existsSync(sourceDist)) {
11+
console.error(`Editor build not found at ${sourceDist}. Run "pnpm --filter editor build" first.`);
12+
process.exit(1);
13+
}
14+
15+
rmSync(targetDist, { recursive: true, force: true });
16+
cpSync(sourceDist, targetDist, { recursive: true });
17+
console.log(`Copied editor dist to ${targetDist}`);

plugins/config-edit/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
editor-dist

plugins/config-edit/package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@powersync/cli-plugin-config-edit",
3+
"description": "PowerSync CLI plugin to launch the configuration editor",
4+
"version": "0.0.0",
5+
"author": "POWERSYNC",
6+
"type": "module",
7+
"main": "dist/index.js",
8+
"types": "dist/index.d.ts",
9+
"files": [
10+
"dist",
11+
"editor-dist",
12+
"oclif.manifest.json"
13+
],
14+
"scripts": {
15+
"build": "tsc -b",
16+
"clean": "rm -rf dist editor-dist tsconfig.tsbuildinfo",
17+
"lint": "eslint .",
18+
"prepack": "oclif manifest"
19+
},
20+
"dependencies": {
21+
"@oclif/core": "^4",
22+
"@powersync/cli-core": "workspace:*",
23+
"open": "^11",
24+
"vite": "^7"
25+
},
26+
"devDependencies": {
27+
"@types/node": "^24",
28+
"eslint": "^9",
29+
"oclif": "^4",
30+
"typescript": "^5"
31+
},
32+
"engines": {
33+
"node": ">=18.0.0"
34+
},
35+
"oclif": {
36+
"commands": "./dist/commands",
37+
"topicSeparator": " ",
38+
"topics": {
39+
"edit": {
40+
"description": "Open the PowerSync configuration editor"
41+
}
42+
}
43+
}
44+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Flags, ux } from '@oclif/core';
2+
import { SelfHostedInstanceCommand } from '@powersync/cli-core';
3+
import { spawn } from 'node:child_process';
4+
import { createRequire } from 'node:module';
5+
import path from 'node:path';
6+
import { fileURLToPath } from 'node:url';
7+
import open from 'open';
8+
9+
const require = createRequire(import.meta.url);
10+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
11+
12+
export default class EditConfig extends SelfHostedInstanceCommand {
13+
static summary = 'Open the PowerSync configuration editor (Nitro preview).';
14+
static description =
15+
'Sets POWERSYNC_DIRECTORY for the current project and runs the editor Vite preview to edit config files.';
16+
17+
static examples = ['<%= config.bin %> edit config', '<%= config.bin %> edit config --directory ./powersync'];
18+
19+
static flags = {
20+
...SelfHostedInstanceCommand.flags,
21+
host: Flags.string({
22+
description: 'Host to bind the editor preview server.',
23+
required: false,
24+
default: '0.0.0.0'
25+
}),
26+
port: Flags.integer({
27+
description: 'Port for the editor preview server.',
28+
required: false,
29+
default: 3000
30+
})
31+
};
32+
33+
async run(): Promise<void> {
34+
const { flags } = await this.parse(EditConfig);
35+
const projectDir = this.ensureProjectDirExists(flags);
36+
37+
const editorDir = path.resolve(__dirname, '../../..');
38+
const targetDist = path.join(editorDir, 'editor-dist');
39+
40+
const env = {
41+
...process.env,
42+
POWERSYNC_DIRECTORY: projectDir
43+
};
44+
45+
this.log('Launching PowerSync configuration editor...');
46+
this.log(`Project directory: ${projectDir}`);
47+
this.log(`Editor path: ${editorDir}`);
48+
this.log(`Serving built editor from: ${targetDist}`);
49+
50+
const vitePkg = require.resolve('vite/package.json');
51+
const viteBin = path.join(path.dirname(vitePkg), 'bin', 'vite.js');
52+
53+
const child = spawn(
54+
process.execPath,
55+
[viteBin, 'preview', '--host', flags.host, '--port', `${flags.port}`, '--outDir', targetDist],
56+
{
57+
cwd: editorDir,
58+
env,
59+
stdio: 'inherit'
60+
}
61+
);
62+
63+
const urlHost = flags.host === '0.0.0.0' ? 'localhost' : flags.host;
64+
const previewUrl = `http://${urlHost}:${flags.port}`;
65+
66+
child.on('spawn', () => {
67+
this.log(`Opening ${previewUrl} in your browser...`);
68+
void open(previewUrl).catch((err) =>
69+
this.warn(`Could not open browser automatically: ${err instanceof Error ? err.message : String(err)}`)
70+
);
71+
});
72+
73+
child.on('exit', (code) => {
74+
if (code === 0) return;
75+
this.error(ux.colorize('red', `Editor exited with code ${code ?? 'unknown'}`));
76+
});
77+
}
78+
}

plugins/config-edit/tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"module": "Node16",
5+
"outDir": "dist",
6+
"rootDir": "src",
7+
"strict": true,
8+
"target": "es2022",
9+
"moduleResolution": "node16",
10+
"skipLibCheck": true,
11+
"composite": true
12+
},
13+
"include": ["./src/**/*"],
14+
"references": [{ "path": "../../packages/cli-core" }]
15+
}

0 commit comments

Comments
 (0)