@bagelink/workspace 1.8.26 → 1.8.28
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/bin/bgl.cjs +28 -429
- package/dist/bin/bgl.mjs +24 -425
- package/dist/shared/workspace.CuE882NE.cjs +495 -0
- package/dist/shared/workspace.ThBu2HJO.mjs +483 -0
- package/dist/vite.cjs +25 -6
- package/dist/vite.mjs +26 -6
- package/package.json +1 -1
- package/src/dev.ts +30 -21
- package/src/vite.ts +28 -6
- package/src/workspace.ts +2 -1
- package/dist/shared/workspace.Dx9_TIij.cjs +0 -86
- package/dist/shared/workspace.Twuo1PFw.mjs +0 -78
package/dist/bin/bgl.mjs
CHANGED
|
@@ -2,413 +2,9 @@
|
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import process from 'node:process';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
|
-
import {
|
|
5
|
+
import { l as listProjects, w as writeNetlifyConfig, i as initWorkspace, a as addProject } from '../shared/workspace.ThBu2HJO.mjs';
|
|
6
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
|
|
6
7
|
import prompts from 'prompts';
|
|
7
|
-
import { w as writeNetlifyConfig } from '../shared/workspace.Twuo1PFw.mjs';
|
|
8
|
-
|
|
9
|
-
async function initWorkspace(root = process.cwd()) {
|
|
10
|
-
console.log("\n\u{1F680} Creating Bagel workspace...\n");
|
|
11
|
-
const response = await prompts([
|
|
12
|
-
{
|
|
13
|
-
type: "text",
|
|
14
|
-
name: "workspaceName",
|
|
15
|
-
message: "Workspace name:",
|
|
16
|
-
initial: "my-workspace"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
type: "text",
|
|
20
|
-
name: "projectId",
|
|
21
|
-
message: "Bagel project ID:",
|
|
22
|
-
initial: "my-project"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
type: "confirm",
|
|
26
|
-
name: "createFirstProject",
|
|
27
|
-
message: "Create first project?",
|
|
28
|
-
initial: true
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: (prev) => prev ? "text" : null,
|
|
32
|
-
name: "firstProjectName",
|
|
33
|
-
message: "First project name:",
|
|
34
|
-
initial: "web"
|
|
35
|
-
}
|
|
36
|
-
]);
|
|
37
|
-
if (!response || !response.workspaceName) {
|
|
38
|
-
console.log("\n\u274C Workspace creation cancelled.\n");
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
const { workspaceName, projectId, createFirstProject, firstProjectName } = response;
|
|
42
|
-
const workspaceDir = resolve(root, workspaceName);
|
|
43
|
-
createWorkspaceRoot(root, workspaceName, projectId);
|
|
44
|
-
createSharedPackage(workspaceDir);
|
|
45
|
-
if (createFirstProject && firstProjectName) {
|
|
46
|
-
await addProject(firstProjectName, workspaceDir);
|
|
47
|
-
}
|
|
48
|
-
console.log("\n\u2705 Workspace created successfully!");
|
|
49
|
-
console.log("\nNext steps:");
|
|
50
|
-
console.log(` cd ${workspaceName}`);
|
|
51
|
-
console.log(" bun install");
|
|
52
|
-
if (createFirstProject) {
|
|
53
|
-
console.log(` bun run dev:${firstProjectName}`);
|
|
54
|
-
} else {
|
|
55
|
-
console.log(" bgl add <project-name> # Add a project");
|
|
56
|
-
}
|
|
57
|
-
console.log("");
|
|
58
|
-
}
|
|
59
|
-
function createWorkspaceRoot(root, name, projectId) {
|
|
60
|
-
const workspaceDir = resolve(root, name);
|
|
61
|
-
if (existsSync(workspaceDir)) {
|
|
62
|
-
console.error(`\u274C Directory ${name} already exists`);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
mkdirSync(workspaceDir, { recursive: true });
|
|
66
|
-
const packageJson = {
|
|
67
|
-
name,
|
|
68
|
-
private: true,
|
|
69
|
-
workspaces: ["*", "!node_modules"],
|
|
70
|
-
scripts: {
|
|
71
|
-
"dev": "bgl dev",
|
|
72
|
-
"dev:local": "bgl dev --mode localhost",
|
|
73
|
-
"dev:verbose": "bun run --filter './!shared*' dev",
|
|
74
|
-
"build": "bgl build",
|
|
75
|
-
"typecheck": "tsc --noEmit",
|
|
76
|
-
"lint": "eslint . --cache",
|
|
77
|
-
"lint:fix": "eslint . --cache --fix"
|
|
78
|
-
},
|
|
79
|
-
dependencies: {
|
|
80
|
-
"@bagelink/auth": "latest",
|
|
81
|
-
"@bagelink/sdk": "latest",
|
|
82
|
-
"@bagelink/vue": "latest",
|
|
83
|
-
"pinia": "latest",
|
|
84
|
-
"vue": "latest",
|
|
85
|
-
"vue-router": "latest"
|
|
86
|
-
},
|
|
87
|
-
devDependencies: {
|
|
88
|
-
"@bagelink/lint-config": "latest",
|
|
89
|
-
"@bagelink/workspace": "latest",
|
|
90
|
-
"@vitejs/plugin-vue": "latest",
|
|
91
|
-
"eslint": "latest",
|
|
92
|
-
"typescript": "^5.0.0",
|
|
93
|
-
"vite": "latest"
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
writeFileSync(
|
|
97
|
-
resolve(workspaceDir, "package.json"),
|
|
98
|
-
`${JSON.stringify(packageJson, null, 2)}
|
|
99
|
-
`
|
|
100
|
-
);
|
|
101
|
-
const bglConfig = `import { defineWorkspace } from '@bagelink/workspace'
|
|
102
|
-
|
|
103
|
-
export default defineWorkspace({
|
|
104
|
-
localhost: {
|
|
105
|
-
host: 'http://localhost:8000',
|
|
106
|
-
proxy: '/api',
|
|
107
|
-
openapi_url: 'http://localhost:8000/openapi.json',
|
|
108
|
-
},
|
|
109
|
-
development: {
|
|
110
|
-
host: 'https://${projectId}.bagel.to',
|
|
111
|
-
proxy: '/api',
|
|
112
|
-
openapi_url: 'https://${projectId}.bagel.to/openapi.json',
|
|
113
|
-
},
|
|
114
|
-
production: {
|
|
115
|
-
host: 'https://${projectId}.bagel.to',
|
|
116
|
-
proxy: '/api',
|
|
117
|
-
openapi_url: 'https://${projectId}.bagel.to/openapi.json',
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
`;
|
|
121
|
-
writeFileSync(resolve(workspaceDir, "bgl.config.ts"), bglConfig);
|
|
122
|
-
const tsConfig = {
|
|
123
|
-
compilerOptions: {
|
|
124
|
-
target: "ES2020",
|
|
125
|
-
useDefineForClassFields: true,
|
|
126
|
-
module: "ESNext",
|
|
127
|
-
lib: ["ES2020", "DOM", "DOM.Iterable"],
|
|
128
|
-
skipLibCheck: true,
|
|
129
|
-
moduleResolution: "bundler",
|
|
130
|
-
allowImportingTsExtensions: true,
|
|
131
|
-
resolveJsonModule: true,
|
|
132
|
-
isolatedModules: true,
|
|
133
|
-
noEmit: true,
|
|
134
|
-
jsx: "preserve",
|
|
135
|
-
strict: true,
|
|
136
|
-
noUnusedLocals: true,
|
|
137
|
-
noUnusedParameters: true,
|
|
138
|
-
noFallthroughCasesInSwitch: true,
|
|
139
|
-
baseUrl: ".",
|
|
140
|
-
paths: {
|
|
141
|
-
"shared/*": ["./shared/*"]
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
writeFileSync(
|
|
146
|
-
resolve(workspaceDir, "tsconfig.json"),
|
|
147
|
-
`${JSON.stringify(tsConfig, null, 2)}
|
|
148
|
-
`
|
|
149
|
-
);
|
|
150
|
-
const gitignore = `node_modules
|
|
151
|
-
dist
|
|
152
|
-
.DS_Store
|
|
153
|
-
*.local
|
|
154
|
-
.env.local
|
|
155
|
-
.vite
|
|
156
|
-
`;
|
|
157
|
-
writeFileSync(resolve(workspaceDir, ".gitignore"), gitignore);
|
|
158
|
-
const scriptsDir = resolve(workspaceDir, "scripts");
|
|
159
|
-
mkdirSync(scriptsDir, { recursive: true });
|
|
160
|
-
const devRunnerContent = `#!/usr/bin/env bun
|
|
161
|
-
import { spawn } from 'bun'
|
|
162
|
-
import { readdir } from 'fs/promises'
|
|
163
|
-
import { resolve } from 'path'
|
|
164
|
-
|
|
165
|
-
const projectsRoot = process.cwd()
|
|
166
|
-
const projects = (await readdir(projectsRoot, { withFileTypes: true }))
|
|
167
|
-
.filter(
|
|
168
|
-
item =>
|
|
169
|
-
item.isDirectory()
|
|
170
|
-
&& item.name !== 'node_modules'
|
|
171
|
-
&& item.name !== 'shared'
|
|
172
|
-
&& item.name !== 'scripts'
|
|
173
|
-
&& item.name !== '.git'
|
|
174
|
-
&& !item.name.startsWith('.'),
|
|
175
|
-
)
|
|
176
|
-
.map(item => item.name)
|
|
177
|
-
|
|
178
|
-
console.log(\`\\n\u{1F680} Starting \${projects.length} project\${projects.length > 1 ? 's' : ''}...\\n\`)
|
|
179
|
-
|
|
180
|
-
const urlPattern = /Local:\\s+(http:\\/\\/localhost:\\d+)/
|
|
181
|
-
|
|
182
|
-
projects.forEach((project) => {
|
|
183
|
-
const proc = spawn({
|
|
184
|
-
cmd: ['bun', 'run', 'dev'],
|
|
185
|
-
cwd: resolve(projectsRoot, project),
|
|
186
|
-
stdout: 'pipe',
|
|
187
|
-
stderr: 'pipe',
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
const decoder = new TextDecoder()
|
|
191
|
-
|
|
192
|
-
proc.stdout.pipeTo(
|
|
193
|
-
new WritableStream({
|
|
194
|
-
write(chunk) {
|
|
195
|
-
const text = decoder.decode(chunk)
|
|
196
|
-
const match = text.match(urlPattern)
|
|
197
|
-
if (match) {
|
|
198
|
-
console.log(\` \u2713 \${project.padEnd(15)} \u2192 \${match[1]}\`)
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
}),
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
proc.stderr.pipeTo(
|
|
205
|
-
new WritableStream({
|
|
206
|
-
write(chunk) {
|
|
207
|
-
const text = decoder.decode(chunk)
|
|
208
|
-
if (text.includes('error') || text.includes('Error')) {
|
|
209
|
-
console.error(\` \u2717 \${project}: \${text.trim()}\`)
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
}),
|
|
213
|
-
)
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
console.log('\\n\u{1F4A1} Press Ctrl+C to stop all servers\\n')
|
|
217
|
-
|
|
218
|
-
process.on('SIGINT', () => {
|
|
219
|
-
console.log('\\n\\n\u{1F44B} Stopping all servers...\\n')
|
|
220
|
-
process.exit()
|
|
221
|
-
})
|
|
222
|
-
`;
|
|
223
|
-
writeFileSync(resolve(scriptsDir, "dev.ts"), devRunnerContent);
|
|
224
|
-
console.log(`\u2705 Created workspace: ${name}`);
|
|
225
|
-
}
|
|
226
|
-
function createSharedPackage(root) {
|
|
227
|
-
const sharedDir = resolve(root, "shared");
|
|
228
|
-
mkdirSync(sharedDir, { recursive: true });
|
|
229
|
-
const packageJson = {
|
|
230
|
-
name: "shared",
|
|
231
|
-
version: "1.0.0",
|
|
232
|
-
type: "module",
|
|
233
|
-
exports: {
|
|
234
|
-
".": "./index.ts",
|
|
235
|
-
"./utils": "./utils/index.ts",
|
|
236
|
-
"./types": "./types/index.ts"
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
writeFileSync(
|
|
240
|
-
resolve(sharedDir, "package.json"),
|
|
241
|
-
`${JSON.stringify(packageJson, null, 2)}
|
|
242
|
-
`
|
|
243
|
-
);
|
|
244
|
-
writeFileSync(
|
|
245
|
-
resolve(sharedDir, "index.ts"),
|
|
246
|
-
"// Shared utilities and exports\nexport * from './utils'\n"
|
|
247
|
-
);
|
|
248
|
-
mkdirSync(resolve(sharedDir, "utils"), { recursive: true });
|
|
249
|
-
writeFileSync(
|
|
250
|
-
resolve(sharedDir, "utils", "index.ts"),
|
|
251
|
-
"// Shared utility functions\nexport function formatDate(date: Date): string {\n return date.toISOString()\n}\n"
|
|
252
|
-
);
|
|
253
|
-
mkdirSync(resolve(sharedDir, "types"), { recursive: true });
|
|
254
|
-
writeFileSync(
|
|
255
|
-
resolve(sharedDir, "types", "index.ts"),
|
|
256
|
-
"// Shared types\nexport interface User {\n id: string\n name: string\n}\n"
|
|
257
|
-
);
|
|
258
|
-
console.log("\u2705 Created shared package");
|
|
259
|
-
}
|
|
260
|
-
async function addProject(name, root = process.cwd()) {
|
|
261
|
-
const projectDir = resolve(root, name);
|
|
262
|
-
if (existsSync(projectDir)) {
|
|
263
|
-
console.error(`\u274C Project ${name} already exists`);
|
|
264
|
-
process.exit(1);
|
|
265
|
-
}
|
|
266
|
-
console.log(`
|
|
267
|
-
\u{1F4E6} Creating project: ${name}
|
|
268
|
-
`);
|
|
269
|
-
mkdirSync(projectDir, { recursive: true });
|
|
270
|
-
const isWorkspace = existsSync(resolve(root, "bgl.config.ts"));
|
|
271
|
-
const packageJson = {
|
|
272
|
-
name,
|
|
273
|
-
type: "module",
|
|
274
|
-
scripts: {
|
|
275
|
-
dev: "vite",
|
|
276
|
-
build: "vite build",
|
|
277
|
-
preview: "vite preview"
|
|
278
|
-
},
|
|
279
|
-
dependencies: {},
|
|
280
|
-
devDependencies: {
|
|
281
|
-
"@vitejs/plugin-vue": "latest",
|
|
282
|
-
"vite": "latest",
|
|
283
|
-
"vue": "latest"
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
if (isWorkspace) {
|
|
287
|
-
packageJson.dependencies.shared = "workspace:*";
|
|
288
|
-
}
|
|
289
|
-
writeFileSync(
|
|
290
|
-
resolve(projectDir, "package.json"),
|
|
291
|
-
`${JSON.stringify(packageJson, null, 2)}
|
|
292
|
-
`
|
|
293
|
-
);
|
|
294
|
-
const bglConfigContent = isWorkspace ? `import { defineWorkspace } from '@bagelink/workspace'
|
|
295
|
-
import rootWorkspace from '../bgl.config'
|
|
296
|
-
|
|
297
|
-
export default defineWorkspace({
|
|
298
|
-
localhost: rootWorkspace('localhost'),
|
|
299
|
-
development: rootWorkspace('development'),
|
|
300
|
-
production: rootWorkspace('production'),
|
|
301
|
-
})
|
|
302
|
-
` : `import { defineWorkspace } from '@bagelink/workspace'
|
|
303
|
-
|
|
304
|
-
export default defineWorkspace({
|
|
305
|
-
localhost: {
|
|
306
|
-
host: 'http://localhost:8000',
|
|
307
|
-
proxy: '/api',
|
|
308
|
-
},
|
|
309
|
-
development: {
|
|
310
|
-
host: 'https://my-project.bagel.to',
|
|
311
|
-
proxy: '/api',
|
|
312
|
-
},
|
|
313
|
-
production: {
|
|
314
|
-
host: 'https://my-project.bagel.to',
|
|
315
|
-
proxy: '/api',
|
|
316
|
-
},
|
|
317
|
-
})
|
|
318
|
-
`;
|
|
319
|
-
writeFileSync(resolve(projectDir, "bgl.config.ts"), bglConfigContent);
|
|
320
|
-
const viteConfig = `import { defineConfig } from 'vite'
|
|
321
|
-
import vue from '@vitejs/plugin-vue'
|
|
322
|
-
import { bagelink } from '@bagelink/workspace/vite'
|
|
323
|
-
import workspace from './bgl.config'
|
|
324
|
-
|
|
325
|
-
export default defineConfig({
|
|
326
|
-
plugins: [
|
|
327
|
-
vue(),
|
|
328
|
-
bagelink({ workspace }),
|
|
329
|
-
],
|
|
330
|
-
})
|
|
331
|
-
`;
|
|
332
|
-
writeFileSync(resolve(projectDir, "vite.config.ts"), viteConfig);
|
|
333
|
-
const srcDir = resolve(projectDir, "src");
|
|
334
|
-
mkdirSync(srcDir, { recursive: true });
|
|
335
|
-
const indexHtml = `<!DOCTYPE html>
|
|
336
|
-
<html lang="en">
|
|
337
|
-
<head>
|
|
338
|
-
<meta charset="UTF-8">
|
|
339
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
340
|
-
<title>${name}</title>
|
|
341
|
-
</head>
|
|
342
|
-
<body>
|
|
343
|
-
<div id="app"></div>
|
|
344
|
-
<script type="module" src="/src/main.ts"><\/script>
|
|
345
|
-
</body>
|
|
346
|
-
</html>
|
|
347
|
-
`;
|
|
348
|
-
writeFileSync(resolve(projectDir, "index.html"), indexHtml);
|
|
349
|
-
const mainTs = `import { createApp } from 'vue'
|
|
350
|
-
import App from './App.vue'
|
|
351
|
-
|
|
352
|
-
createApp(App).mount('#app')
|
|
353
|
-
`;
|
|
354
|
-
writeFileSync(resolve(srcDir, "main.ts"), mainTs);
|
|
355
|
-
const appVue = `<script setup lang="ts">
|
|
356
|
-
import { ref } from 'vue'
|
|
357
|
-
${isWorkspace ? "import { formatDate } from 'shared/utils'\n" : ""}
|
|
358
|
-
const count = ref(0)
|
|
359
|
-
<\/script>
|
|
360
|
-
|
|
361
|
-
<template>
|
|
362
|
-
<div>
|
|
363
|
-
<h1>${name}</h1>
|
|
364
|
-
<button @click="count++">Count: {{ count }}</button>
|
|
365
|
-
${isWorkspace ? "<p>{{ formatDate(new Date()) }}</p>" : ""}
|
|
366
|
-
</div>
|
|
367
|
-
</template>
|
|
368
|
-
`;
|
|
369
|
-
writeFileSync(resolve(srcDir, "App.vue"), appVue);
|
|
370
|
-
console.log(`\u2705 Created project: ${name}`);
|
|
371
|
-
if (isWorkspace) {
|
|
372
|
-
updateWorkspaceScripts(root, name);
|
|
373
|
-
}
|
|
374
|
-
console.log("\nNext steps:");
|
|
375
|
-
console.log(` cd ${name}`);
|
|
376
|
-
console.log(" bun install");
|
|
377
|
-
console.log(" bun run dev");
|
|
378
|
-
console.log("");
|
|
379
|
-
}
|
|
380
|
-
function updateWorkspaceScripts(root, projectName) {
|
|
381
|
-
const packageJsonPath = resolve(root, "package.json");
|
|
382
|
-
if (!existsSync(packageJsonPath)) return;
|
|
383
|
-
try {
|
|
384
|
-
const packageJson = JSON.parse(
|
|
385
|
-
readFileSync(packageJsonPath, "utf-8")
|
|
386
|
-
);
|
|
387
|
-
if (!packageJson.scripts) {
|
|
388
|
-
packageJson.scripts = {};
|
|
389
|
-
}
|
|
390
|
-
packageJson.scripts[`dev:${projectName}`] = `bun --filter ${projectName} dev`;
|
|
391
|
-
packageJson.scripts[`build:${projectName}`] = `bun --filter ${projectName} build`;
|
|
392
|
-
writeFileSync(
|
|
393
|
-
packageJsonPath,
|
|
394
|
-
`${JSON.stringify(packageJson, null, 2)}
|
|
395
|
-
`
|
|
396
|
-
);
|
|
397
|
-
console.log(`\u2705 Added scripts: dev:${projectName}, build:${projectName}`);
|
|
398
|
-
} catch (error) {
|
|
399
|
-
console.warn("\u26A0\uFE0F Could not update workspace scripts");
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
function listProjects(root = process.cwd()) {
|
|
403
|
-
try {
|
|
404
|
-
const items = readdirSync(root, { withFileTypes: true });
|
|
405
|
-
return items.filter(
|
|
406
|
-
(item) => item.isDirectory() && item.name !== "node_modules" && item.name !== "shared" && item.name !== "scripts" && item.name !== ".git" && !item.name.startsWith(".")
|
|
407
|
-
).map((item) => item.name);
|
|
408
|
-
} catch {
|
|
409
|
-
return [];
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
8
|
|
|
413
9
|
async function runBuild(filter, additionalArgs = []) {
|
|
414
10
|
const argsStr = additionalArgs.length > 0 ? ` -- ${additionalArgs.join(" ")}` : "";
|
|
@@ -464,7 +60,9 @@ function isWorkspace(root = process.cwd()) {
|
|
|
464
60
|
}
|
|
465
61
|
|
|
466
62
|
const servers = /* @__PURE__ */ new Map();
|
|
63
|
+
const projectToPort = /* @__PURE__ */ new Map();
|
|
467
64
|
const seenLines = /* @__PURE__ */ new Set();
|
|
65
|
+
const START_PORT = 5173;
|
|
468
66
|
const colors = {
|
|
469
67
|
reset: "\x1B[0m",
|
|
470
68
|
cyan: "\x1B[36m",
|
|
@@ -479,12 +77,13 @@ function clearAndPrintServers() {
|
|
|
479
77
|
}
|
|
480
78
|
console.log(`${colors.cyan}\u{1F680} Development Servers${colors.reset}
|
|
481
79
|
`);
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
80
|
+
const sortedServers = Array.from(servers.entries()).sort((a, b) => a[1].order - b[1].order);
|
|
81
|
+
for (const [name, info] of sortedServers) {
|
|
82
|
+
const url = `http://localhost:${info.assignedPort}`;
|
|
83
|
+
if (info.status === "ready") {
|
|
485
84
|
console.log(`${colors.green}\u25CF${colors.reset} ${colors.cyan}${name}${colors.reset} ${colors.dim}\u2192${colors.reset} ${url}`);
|
|
486
85
|
} else {
|
|
487
|
-
console.log(`${colors.yellow}\u25CB${colors.reset} ${colors.dim}${name} (starting...)${colors.reset}`);
|
|
86
|
+
console.log(`${colors.yellow}\u25CB${colors.reset} ${colors.dim}${name} (starting...)${colors.reset} ${colors.dim}${url}${colors.reset}`);
|
|
488
87
|
}
|
|
489
88
|
}
|
|
490
89
|
console.log("");
|
|
@@ -493,10 +92,20 @@ async function runDev(filter, additionalArgs = []) {
|
|
|
493
92
|
const argsStr = additionalArgs.length > 0 ? ` -- ${additionalArgs.join(" ")}` : "";
|
|
494
93
|
const resolvedFilters = resolveFilters(filter);
|
|
495
94
|
if (!resolvedFilters || resolvedFilters.length === 0) return 1;
|
|
95
|
+
const projectNames = resolvedFilters.map((f) => f.replace("./", "")).sort();
|
|
96
|
+
projectNames.forEach((name, index) => {
|
|
97
|
+
const assignedPort = START_PORT + index;
|
|
98
|
+
servers.set(name, {
|
|
99
|
+
name,
|
|
100
|
+
assignedPort,
|
|
101
|
+
status: "starting",
|
|
102
|
+
order: index
|
|
103
|
+
});
|
|
104
|
+
projectToPort.set(name, assignedPort);
|
|
105
|
+
});
|
|
106
|
+
clearAndPrintServers();
|
|
496
107
|
const filterArgs = resolvedFilters.map((f) => `--filter '${f}'`).join(" ");
|
|
497
|
-
|
|
498
|
-
console.log(`${colors.dim}Starting dev servers: ${projectNames}${argsStr}${colors.reset}
|
|
499
|
-
`);
|
|
108
|
+
projectNames.join(", ");
|
|
500
109
|
const command = `bun run ${filterArgs} dev${argsStr}`;
|
|
501
110
|
const proc = spawn(command, {
|
|
502
111
|
cwd: process.cwd(),
|
|
@@ -509,15 +118,6 @@ async function runDev(filter, additionalArgs = []) {
|
|
|
509
118
|
if (!line.trim()) return;
|
|
510
119
|
if (seenLines.has(line)) return;
|
|
511
120
|
seenLines.add(line);
|
|
512
|
-
const projectMatch = line.match(/^(\w+)\s+dev:/);
|
|
513
|
-
if (projectMatch) {
|
|
514
|
-
const name = projectMatch[1];
|
|
515
|
-
if (!servers.has(name)) {
|
|
516
|
-
console.log(`${colors.dim}[DEBUG] Detected project: ${name}${colors.reset}`);
|
|
517
|
-
servers.set(name, { name, status: "starting" });
|
|
518
|
-
clearAndPrintServers();
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
121
|
const portMatch = line.match(/Local:\s+http:\/\/localhost:(\d+)/);
|
|
522
122
|
if (portMatch) {
|
|
523
123
|
const port = Number.parseInt(portMatch[1], 10);
|
|
@@ -525,9 +125,8 @@ async function runDev(filter, additionalArgs = []) {
|
|
|
525
125
|
if (projectInLine) {
|
|
526
126
|
const name = projectInLine[1];
|
|
527
127
|
const info = servers.get(name);
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
info.port = port;
|
|
128
|
+
if (info && info.assignedPort === port && !info.actualPort) {
|
|
129
|
+
info.actualPort = port;
|
|
531
130
|
info.status = "ready";
|
|
532
131
|
clearAndPrintServers();
|
|
533
132
|
}
|