Skip to content

Commit d662cbc

Browse files
authored
fix: extension only qol (#100)
1 parent 2f26dd4 commit d662cbc

6 files changed

Lines changed: 204 additions & 213 deletions

File tree

packages/app/lib/cli/commands/app/dev.ts

Lines changed: 81 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import type { Cli, Worker } from '@youcan/cli-kit';
1+
import type { Worker } from '@youcan/cli-kit';
22
import process from 'node:process';
3-
import { bootAppWorker, bootExtensionWorker, bootTunnelWorker, bootWebWorker } from '@/cli/services/dev/workers';
4-
import { getAppEnvironmentVariables } from '@/cli/services/environment-variables';
5-
import { APP_CONFIG_FILENAME } from '@/constants';
3+
import { bootAppWorker, bootExtensionWorker, bootWebWorker } from '@/cli/services/dev/workers';
64
import { AppCommand } from '@/util/app-command';
75
import { load } from '@/util/app-loader';
8-
import { Env, Filesystem, Http, Path, Services, Session, System, Tasks, UI } from '@youcan/cli-kit';
6+
import { Flags } from '@oclif/core';
7+
import { Env, Http, Services, Session, System, Tasks, UI } from '@youcan/cli-kit';
98

109
interface Context {
1110
cmd: Dev;
@@ -14,7 +13,17 @@ interface Context {
1413

1514
class Dev extends AppCommand {
1615
static description = 'Run the app in dev mode';
16+
17+
static flags = {
18+
'no-tunnel': Flags.boolean({
19+
description: 'Skip cloudflared tunnel and use localhost URL directly',
20+
default: false,
21+
}),
22+
};
23+
1724
private workers: Worker.Interface[] = [];
25+
private hasWebWorker = false;
26+
private useTunnel = false;
1827

1928
constructor(argv: string[], config: any) {
2029
super(argv, config);
@@ -59,93 +68,80 @@ class Dev extends AppCommand {
5968
});
6069
}
6170

62-
private readonly hotKeys = [
63-
{
64-
keyboardKey: 'p',
65-
description: 'preview in your dev store',
66-
handler: async () => this.openAppPreview(),
67-
},
68-
{
69-
keyboardKey: 'q',
70-
description: 'quit',
71-
handler: async () => {
72-
try {
73-
console.log('Shutting down...');
74-
75-
if (this.workers.length > 0) {
76-
await Promise.allSettled(this.workers.map(worker => worker.cleanup()));
77-
}
78-
79-
if (this.controller) {
80-
this.controller.abort();
71+
private get hotKeys() {
72+
return [
73+
{
74+
keyboardKey: 'p',
75+
description: this.hasWebWorker ? 'preview in your dev store' : 'open theme editor',
76+
handler: async () => this.openAppPreview(),
77+
},
78+
{
79+
keyboardKey: 'q',
80+
description: 'quit',
81+
handler: async () => {
82+
try {
83+
console.log('Shutting down...');
84+
85+
if (this.workers.length > 0) {
86+
await Promise.allSettled(this.workers.map(worker => worker.cleanup()));
87+
}
88+
89+
if (this.controller) {
90+
this.controller.abort();
91+
}
92+
this.workers = [];
93+
94+
setTimeout(() => {
95+
process.exit(0);
96+
}, 100);
8197
}
82-
this.workers = [];
83-
84-
setTimeout(() => {
98+
catch (error) {
8599
process.exit(0);
86-
}, 100);
87-
}
88-
catch (error) {
89-
process.exit(0);
90-
}
100+
}
101+
},
91102
},
92-
},
93-
];
103+
];
104+
}
94105

95106
async run(): Promise<any> {
107+
const { flags } = await this.parse(Dev);
96108
this.session = await Session.authenticate(this);
97109
this.app = await load();
98110

99-
const { workers } = await Tasks.run<Context>({ cmd: this, workers: [] }, [
100-
{
101-
title: 'Preparing network options...',
102-
task: async (ctx) => {
103-
ctx.workers.push(await this.prepareNetworkOptions());
111+
this.hasWebWorker = this.app.webs.length > 0;
112+
this.useTunnel = this.hasWebWorker && !flags['no-tunnel'];
113+
114+
const tasks = [];
115+
116+
if (this.hasWebWorker) {
117+
tasks.push({
118+
title: this.useTunnel ? 'Preparing network options...' : 'Preparing network options (localhost)...',
119+
task: async (ctx: Context) => {
120+
ctx.workers.push(...await this.bootWebWorkers());
104121
},
105-
},
122+
});
123+
}
124+
125+
tasks.push(
106126
{
107127
title: 'Syncing app configuration...',
108128
task: async () => { await this.syncAppConfig(); },
109129
},
110130
{
111131
title: 'Preparing dev processes...',
112-
task: async (ctx) => {
132+
task: async (ctx: Context) => {
113133
ctx.workers.push(...await this.prepareDevProcesses());
114134
},
115135
},
116-
]);
136+
);
137+
138+
const { workers } = await Tasks.run<Context>({ cmd: this, workers: [] }, tasks);
117139

118140
UI.renderDevOutput({ hotKeys: this.hotKeys, cmd: this });
119141

120142
this.runWorkers(workers);
121143
}
122144

123-
private async prepareNetworkOptions() {
124-
const port = await System.getPortOrNextOrRandom(3000);
125-
126-
this.app.network_config = {
127-
app_port: port,
128-
app_url: `http://localhost:${port}`,
129-
};
130-
131-
const worker = await bootTunnelWorker(this, this.app, new Services.Cloudflared());
132-
133-
this.app.config = {
134-
...this.app.config,
135-
app_url: worker.getUrl(),
136-
redirect_urls: this.app.config.redirect_urls?.length > 0
137-
? this.app.config.redirect_urls.map(r => new URL(new URL(r).pathname, worker.getUrl()).toString())
138-
: [new URL('/auth/callback', worker.getUrl()).toString()],
139-
};
140-
141-
await Filesystem.writeJsonFile(
142-
Path.join(this.app.root, APP_CONFIG_FILENAME),
143-
this.app.config,
144-
);
145-
146-
return worker;
147-
}
148-
149145
async reloadWorkers() {
150146
this.controller = new AbortController();
151147

@@ -154,13 +150,23 @@ class Dev extends AppCommand {
154150
this.workers = [];
155151
}
156152

157-
const networkConfig = this.app.network_config;
158153
this.app = await load();
159-
this.app.network_config = networkConfig;
154+
155+
const webWorkers = this.hasWebWorker ? await this.bootWebWorkers() : [];
160156

161157
await this.syncAppConfig();
162158

163-
await this.runWorkers(await this.prepareDevProcesses());
159+
const devWorkers = await this.prepareDevProcesses();
160+
161+
await this.runWorkers([...webWorkers, ...devWorkers]);
162+
}
163+
164+
private async bootWebWorkers(): Promise<Worker.Interface[]> {
165+
return Promise.all(
166+
this.app.webs.map(web =>
167+
bootWebWorker(this, this.app, web, this.useTunnel ? new Services.Cloudflared() : undefined),
168+
),
169+
);
164170
}
165171

166172
private async runWorkers(workers: Worker.Interface[]): Promise<void> {
@@ -174,36 +180,17 @@ class Dev extends AppCommand {
174180
bootAppWorker(this, this.app),
175181
];
176182

177-
this.app.webs.forEach(web => promises.unshift(
178-
bootWebWorker(
179-
this,
180-
this.app,
181-
web,
182-
this.buildEnvironmentVariables(),
183-
),
184-
));
185-
186183
this.app.extensions.forEach(ext => promises.unshift(bootExtensionWorker(this, this.app, ext)));
187184

188185
return Promise.all(promises);
189186
}
190187

191-
private buildEnvironmentVariables(): Record<string, string> {
192-
if (!this.app.remote_config) {
193-
throw new Error('remote app config not loaded');
194-
}
195-
if (!this.app.network_config) {
196-
throw new Error('app network config is not set');
188+
private async openAppPreview() {
189+
if (!this.hasWebWorker) {
190+
System.open(`https://${Env.sellerAreaHostname()}/admin/themes`);
191+
return;
197192
}
198193

199-
return {
200-
...getAppEnvironmentVariables(this.app),
201-
APP_URL: this.app.network_config.app_url,
202-
PORT: this.app.network_config.app_port.toString(),
203-
};
204-
}
205-
206-
private async openAppPreview() {
207194
const endpointUrl = `${Env.apiHostname()}/apps/${this.app.config.id}/authorization-url`;
208195
const { url } = await Http.get<{ url: string }>(endpointUrl);
209196

packages/app/lib/cli/services/dev/workers/index.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { AppCommand } from '@/util/app-command';
44
import type { Cli, Services, Worker } from '@youcan/cli-kit';
55
import AppWorker from './app-worker';
66
import ThemeExtensionWorker from './theme-extension-worker';
7-
import TunnelWorker from './tunnel-worker';
87
import WebWorker from './web-worker';
98

109
export interface ExtensionWorkerCtor {
@@ -32,16 +31,8 @@ export async function bootExtensionWorker(command: Cli.Command, app: App, extens
3231
return worker;
3332
}
3433

35-
export async function bootWebWorker(command: Cli.Command, app: App, web: Web, env: Record<string, string>) {
36-
const worker = new WebWorker(command, app, web, env);
37-
38-
await worker.boot();
39-
40-
return worker;
41-
}
42-
43-
export async function bootTunnelWorker(command: AppCommand, app: App, tunnel: Services.Cloudflared) {
44-
const worker = new TunnelWorker(command, app, tunnel);
34+
export async function bootWebWorker(command: AppCommand, app: App, web: Web, tunnelService?: Services.Cloudflared) {
35+
const worker = new WebWorker(command, app, web, tunnelService);
4536

4637
await worker.boot();
4738

packages/app/lib/cli/services/dev/workers/tunnel-worker.ts

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)