@bagelink/workspace 1.10.6 → 1.10.9
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/README.md +214 -9
- package/bin/bgl.ts +95 -4
- package/dist/bin/bgl.cjs +856 -16
- package/dist/bin/bgl.mjs +847 -8
- package/dist/composable.cjs +22 -0
- package/dist/composable.d.cts +52 -0
- package/dist/composable.d.mts +52 -0
- package/dist/composable.d.ts +52 -0
- package/dist/composable.mjs +19 -0
- package/dist/index.cjs +3 -160
- package/dist/index.d.cts +4 -160
- package/dist/index.d.mts +4 -160
- package/dist/index.d.ts +4 -160
- package/dist/index.mjs +2 -139
- package/dist/shared/workspace.Bc_dpzhA.mjs +500 -0
- package/dist/shared/workspace.BzlV5kcN.d.cts +50 -0
- package/dist/shared/workspace.BzlV5kcN.d.mts +50 -0
- package/dist/shared/workspace.BzlV5kcN.d.ts +50 -0
- package/dist/shared/workspace.DRlDHdPw.cjs +512 -0
- package/dist/vite.cjs +135 -0
- package/dist/vite.d.cts +98 -0
- package/dist/vite.d.mts +98 -0
- package/dist/vite.d.ts +98 -0
- package/dist/vite.mjs +125 -0
- package/env.d.ts +30 -0
- package/package.json +24 -3
- package/src/build.ts +45 -0
- package/src/composable.ts +70 -0
- package/src/dev.ts +171 -0
- package/src/index.ts +4 -78
- package/src/init.ts +72 -14
- package/src/lint.ts +90 -2
- package/src/netlify.ts +54 -3
- package/src/proxy.ts +23 -3
- package/src/sdk.ts +80 -44
- package/src/types.ts +10 -4
- package/src/vite.ts +166 -0
- package/src/workspace.ts +125 -18
- package/templates/dev-runner.ts +61 -0
- package/templates/tsconfig.app.json +23 -0
- package/dist/shared/workspace.DQ-r7Tja.cjs +0 -925
- package/dist/shared/workspace.Dq4_YhqE.mjs +0 -905
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const node_fs = require('node:fs');
|
|
4
|
+
const node_path = require('node:path');
|
|
5
|
+
const process = require('node:process');
|
|
6
|
+
const prompts = require('prompts');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
9
|
+
|
|
10
|
+
const process__default = /*#__PURE__*/_interopDefaultCompat(process);
|
|
11
|
+
const prompts__default = /*#__PURE__*/_interopDefaultCompat(prompts);
|
|
12
|
+
|
|
13
|
+
async function initWorkspace(root = process__default.cwd()) {
|
|
14
|
+
console.log("\n\u{1F680} Creating Bagel workspace...\n");
|
|
15
|
+
const response = await prompts__default([
|
|
16
|
+
{
|
|
17
|
+
type: "text",
|
|
18
|
+
name: "workspaceName",
|
|
19
|
+
message: "Workspace name:",
|
|
20
|
+
initial: "my-workspace"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: "text",
|
|
24
|
+
name: "projectId",
|
|
25
|
+
message: "Bagel project ID:",
|
|
26
|
+
initial: "my-project"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: "confirm",
|
|
30
|
+
name: "createFirstProject",
|
|
31
|
+
message: "Create first project?",
|
|
32
|
+
initial: true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: (prev) => prev ? "text" : null,
|
|
36
|
+
name: "firstProjectName",
|
|
37
|
+
message: "First project name:",
|
|
38
|
+
initial: "web"
|
|
39
|
+
}
|
|
40
|
+
]);
|
|
41
|
+
if (!response || !response.workspaceName) {
|
|
42
|
+
console.log("\n\u274C Workspace creation cancelled.\n");
|
|
43
|
+
process__default.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const { workspaceName, projectId, createFirstProject, firstProjectName } = response;
|
|
46
|
+
const workspaceDir = node_path.resolve(root, workspaceName);
|
|
47
|
+
createWorkspaceRoot(root, workspaceName, projectId);
|
|
48
|
+
createSharedPackage(workspaceDir);
|
|
49
|
+
if (createFirstProject && firstProjectName) {
|
|
50
|
+
await addProject(firstProjectName, workspaceDir);
|
|
51
|
+
}
|
|
52
|
+
console.log("\n\u2705 Workspace created successfully!");
|
|
53
|
+
console.log("\nNext steps:");
|
|
54
|
+
console.log(` cd ${workspaceName}`);
|
|
55
|
+
console.log(" bun install");
|
|
56
|
+
if (createFirstProject) {
|
|
57
|
+
console.log(` bun run dev:${firstProjectName}`);
|
|
58
|
+
} else {
|
|
59
|
+
console.log(" bgl add <project-name> # Add a project");
|
|
60
|
+
}
|
|
61
|
+
console.log("");
|
|
62
|
+
}
|
|
63
|
+
function createWorkspaceRoot(root, name, projectId) {
|
|
64
|
+
const workspaceDir = node_path.resolve(root, name);
|
|
65
|
+
if (node_fs.existsSync(workspaceDir)) {
|
|
66
|
+
console.error(`\u274C Directory ${name} already exists`);
|
|
67
|
+
process__default.exit(1);
|
|
68
|
+
}
|
|
69
|
+
node_fs.mkdirSync(workspaceDir, { recursive: true });
|
|
70
|
+
const packageJson = {
|
|
71
|
+
name,
|
|
72
|
+
private: true,
|
|
73
|
+
workspaces: ["*", "!node_modules"],
|
|
74
|
+
scripts: {
|
|
75
|
+
"dev": "bgl dev",
|
|
76
|
+
"dev:local": "bgl dev --mode localhost",
|
|
77
|
+
"dev:verbose": "bun run --filter './!shared*' dev",
|
|
78
|
+
"build": "bgl build",
|
|
79
|
+
"typecheck": "tsc --noEmit",
|
|
80
|
+
"lint": "eslint . --cache",
|
|
81
|
+
"lint:fix": "eslint . --cache --fix"
|
|
82
|
+
},
|
|
83
|
+
dependencies: {
|
|
84
|
+
"@bagelink/auth": "latest",
|
|
85
|
+
"@bagelink/sdk": "latest",
|
|
86
|
+
"@bagelink/vue": "latest",
|
|
87
|
+
"pinia": "latest",
|
|
88
|
+
"vue": "latest",
|
|
89
|
+
"vue-router": "latest"
|
|
90
|
+
},
|
|
91
|
+
devDependencies: {
|
|
92
|
+
"@bagelink/lint-config": "latest",
|
|
93
|
+
"@bagelink/workspace": "latest",
|
|
94
|
+
"@vitejs/plugin-vue": "latest",
|
|
95
|
+
"eslint": "latest",
|
|
96
|
+
"typescript": "^5.0.0",
|
|
97
|
+
"vite": "latest"
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
node_fs.writeFileSync(
|
|
101
|
+
node_path.resolve(workspaceDir, "package.json"),
|
|
102
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
103
|
+
`
|
|
104
|
+
);
|
|
105
|
+
const bglConfig = `import { defineWorkspace } from '@bagelink/workspace'
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Define your workspace environments
|
|
109
|
+
* You can add as many custom environments as needed (e.g., 'staging', 'preview')
|
|
110
|
+
* Use --mode flag to switch: bgl dev --mode <env_name>
|
|
111
|
+
*/
|
|
112
|
+
export default defineWorkspace({
|
|
113
|
+
localhost: {
|
|
114
|
+
host: 'http://localhost:8000',
|
|
115
|
+
proxy: '/api', // Optional: remove to skip proxy setup
|
|
116
|
+
openapi_url: 'http://localhost:8000/openapi.json',
|
|
117
|
+
},
|
|
118
|
+
development: {
|
|
119
|
+
host: 'https://${projectId}.bagel.to',
|
|
120
|
+
proxy: '/api',
|
|
121
|
+
openapi_url: 'https://${projectId}.bagel.to/openapi.json',
|
|
122
|
+
},
|
|
123
|
+
production: {
|
|
124
|
+
host: 'https://${projectId}.bagel.to',
|
|
125
|
+
proxy: '/api',
|
|
126
|
+
openapi_url: 'https://${projectId}.bagel.to/openapi.json',
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
`;
|
|
130
|
+
node_fs.writeFileSync(node_path.resolve(workspaceDir, "bgl.config.ts"), bglConfig);
|
|
131
|
+
const tsConfig = {
|
|
132
|
+
compilerOptions: {
|
|
133
|
+
target: "ES2020",
|
|
134
|
+
useDefineForClassFields: true,
|
|
135
|
+
module: "ESNext",
|
|
136
|
+
lib: ["ES2020", "DOM", "DOM.Iterable"],
|
|
137
|
+
skipLibCheck: true,
|
|
138
|
+
moduleResolution: "bundler",
|
|
139
|
+
allowImportingTsExtensions: true,
|
|
140
|
+
resolveJsonModule: true,
|
|
141
|
+
isolatedModules: true,
|
|
142
|
+
noEmit: true,
|
|
143
|
+
jsx: "preserve",
|
|
144
|
+
strict: true,
|
|
145
|
+
noUnusedLocals: true,
|
|
146
|
+
noUnusedParameters: true,
|
|
147
|
+
noFallthroughCasesInSwitch: true,
|
|
148
|
+
baseUrl: ".",
|
|
149
|
+
paths: {
|
|
150
|
+
"shared/*": ["./shared/*"]
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
node_fs.writeFileSync(
|
|
155
|
+
node_path.resolve(workspaceDir, "tsconfig.json"),
|
|
156
|
+
`${JSON.stringify(tsConfig, null, 2)}
|
|
157
|
+
`
|
|
158
|
+
);
|
|
159
|
+
const gitignore = `node_modules
|
|
160
|
+
dist
|
|
161
|
+
.DS_Store
|
|
162
|
+
*.local
|
|
163
|
+
.env.local
|
|
164
|
+
.vite
|
|
165
|
+
`;
|
|
166
|
+
node_fs.writeFileSync(node_path.resolve(workspaceDir, ".gitignore"), gitignore);
|
|
167
|
+
const scriptsDir = node_path.resolve(workspaceDir, "scripts");
|
|
168
|
+
node_fs.mkdirSync(scriptsDir, { recursive: true });
|
|
169
|
+
const devRunnerContent = `#!/usr/bin/env bun
|
|
170
|
+
import { spawn } from 'bun'
|
|
171
|
+
import { readdir } from 'fs/promises'
|
|
172
|
+
import { resolve } from 'path'
|
|
173
|
+
|
|
174
|
+
const projectsRoot = process.cwd()
|
|
175
|
+
const projects = (await readdir(projectsRoot, { withFileTypes: true }))
|
|
176
|
+
.filter(
|
|
177
|
+
item =>
|
|
178
|
+
item.isDirectory()
|
|
179
|
+
&& item.name !== 'node_modules'
|
|
180
|
+
&& item.name !== 'shared'
|
|
181
|
+
&& item.name !== 'scripts'
|
|
182
|
+
&& item.name !== '.git'
|
|
183
|
+
&& !item.name.startsWith('.'),
|
|
184
|
+
)
|
|
185
|
+
.map(item => item.name)
|
|
186
|
+
|
|
187
|
+
console.log(\`\\n\u{1F680} Starting \${projects.length} project\${projects.length > 1 ? 's' : ''}...\\n\`)
|
|
188
|
+
|
|
189
|
+
const urlPattern = /Local:\\s+(http:\\/\\/localhost:\\d+)/
|
|
190
|
+
|
|
191
|
+
projects.forEach((project) => {
|
|
192
|
+
const proc = spawn({
|
|
193
|
+
cmd: ['bun', 'run', 'dev'],
|
|
194
|
+
cwd: resolve(projectsRoot, project),
|
|
195
|
+
stdout: 'pipe',
|
|
196
|
+
stderr: 'pipe',
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const decoder = new TextDecoder()
|
|
200
|
+
|
|
201
|
+
proc.stdout.pipeTo(
|
|
202
|
+
new WritableStream({
|
|
203
|
+
write(chunk) {
|
|
204
|
+
const text = decoder.decode(chunk)
|
|
205
|
+
const match = text.match(urlPattern)
|
|
206
|
+
if (match) {
|
|
207
|
+
console.log(\` \u2713 \${project.padEnd(15)} \u2192 \${match[1]}\`)
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
}),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
proc.stderr.pipeTo(
|
|
214
|
+
new WritableStream({
|
|
215
|
+
write(chunk) {
|
|
216
|
+
const text = decoder.decode(chunk)
|
|
217
|
+
if (text.includes('error') || text.includes('Error')) {
|
|
218
|
+
console.error(\` \u2717 \${project}: \${text.trim()}\`)
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
}),
|
|
222
|
+
)
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
console.log('\\n\u{1F4A1} Press Ctrl+C to stop all servers\\n')
|
|
226
|
+
|
|
227
|
+
process.on('SIGINT', () => {
|
|
228
|
+
console.log('\\n\\n\u{1F44B} Stopping all servers...\\n')
|
|
229
|
+
process.exit()
|
|
230
|
+
})
|
|
231
|
+
`;
|
|
232
|
+
node_fs.writeFileSync(node_path.resolve(scriptsDir, "dev.ts"), devRunnerContent);
|
|
233
|
+
console.log(`\u2705 Created workspace: ${name}`);
|
|
234
|
+
}
|
|
235
|
+
function createSharedPackage(root) {
|
|
236
|
+
const sharedDir = node_path.resolve(root, "shared");
|
|
237
|
+
node_fs.mkdirSync(sharedDir, { recursive: true });
|
|
238
|
+
const packageJson = {
|
|
239
|
+
name: "shared",
|
|
240
|
+
version: "1.0.0",
|
|
241
|
+
type: "module",
|
|
242
|
+
exports: {
|
|
243
|
+
".": "./index.ts",
|
|
244
|
+
"./utils": "./utils/index.ts",
|
|
245
|
+
"./types": "./types/index.ts"
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
node_fs.writeFileSync(
|
|
249
|
+
node_path.resolve(sharedDir, "package.json"),
|
|
250
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
251
|
+
`
|
|
252
|
+
);
|
|
253
|
+
node_fs.writeFileSync(
|
|
254
|
+
node_path.resolve(sharedDir, "index.ts"),
|
|
255
|
+
"// Shared utilities and exports\nexport * from './utils'\n"
|
|
256
|
+
);
|
|
257
|
+
node_fs.mkdirSync(node_path.resolve(sharedDir, "utils"), { recursive: true });
|
|
258
|
+
node_fs.writeFileSync(
|
|
259
|
+
node_path.resolve(sharedDir, "utils", "index.ts"),
|
|
260
|
+
"// Shared utility functions\nexport function formatDate(date: Date): string {\n return date.toISOString()\n}\n"
|
|
261
|
+
);
|
|
262
|
+
node_fs.mkdirSync(node_path.resolve(sharedDir, "types"), { recursive: true });
|
|
263
|
+
node_fs.writeFileSync(
|
|
264
|
+
node_path.resolve(sharedDir, "types", "index.ts"),
|
|
265
|
+
"// Shared types\nexport interface User {\n id: string\n name: string\n}\n"
|
|
266
|
+
);
|
|
267
|
+
console.log("\u2705 Created shared package");
|
|
268
|
+
}
|
|
269
|
+
async function addProject(name, root = process__default.cwd()) {
|
|
270
|
+
const projectDir = node_path.resolve(root, name);
|
|
271
|
+
if (node_fs.existsSync(projectDir)) {
|
|
272
|
+
console.error(`\u274C Project ${name} already exists`);
|
|
273
|
+
process__default.exit(1);
|
|
274
|
+
}
|
|
275
|
+
console.log(`
|
|
276
|
+
\u{1F4E6} Creating project: ${name}
|
|
277
|
+
`);
|
|
278
|
+
node_fs.mkdirSync(projectDir, { recursive: true });
|
|
279
|
+
const isWorkspace = node_fs.existsSync(node_path.resolve(root, "bgl.config.ts"));
|
|
280
|
+
const packageJson = {
|
|
281
|
+
name,
|
|
282
|
+
type: "module",
|
|
283
|
+
scripts: {
|
|
284
|
+
dev: "vite",
|
|
285
|
+
build: "vite build",
|
|
286
|
+
preview: "vite preview"
|
|
287
|
+
},
|
|
288
|
+
dependencies: {},
|
|
289
|
+
devDependencies: {
|
|
290
|
+
"@vitejs/plugin-vue": "latest",
|
|
291
|
+
"vite": "latest",
|
|
292
|
+
"vue": "latest"
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
if (isWorkspace) {
|
|
296
|
+
packageJson.dependencies.shared = "workspace:*";
|
|
297
|
+
}
|
|
298
|
+
node_fs.writeFileSync(
|
|
299
|
+
node_path.resolve(projectDir, "package.json"),
|
|
300
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
301
|
+
`
|
|
302
|
+
);
|
|
303
|
+
const bglConfigContent = isWorkspace ? `import { defineWorkspace } from '@bagelink/workspace'
|
|
304
|
+
import rootWorkspace from '../bgl.config'
|
|
305
|
+
|
|
306
|
+
export default defineWorkspace({
|
|
307
|
+
localhost: rootWorkspace('localhost'),
|
|
308
|
+
development: rootWorkspace('development'),
|
|
309
|
+
production: rootWorkspace('production'),
|
|
310
|
+
})
|
|
311
|
+
` : `import { defineWorkspace } from '@bagelink/workspace'
|
|
312
|
+
|
|
313
|
+
export default defineWorkspace({
|
|
314
|
+
localhost: {
|
|
315
|
+
host: 'http://localhost:8000',
|
|
316
|
+
proxy: '/api',
|
|
317
|
+
},
|
|
318
|
+
development: {
|
|
319
|
+
host: 'https://my-project.bagel.to',
|
|
320
|
+
proxy: '/api',
|
|
321
|
+
},
|
|
322
|
+
production: {
|
|
323
|
+
host: 'https://my-project.bagel.to',
|
|
324
|
+
proxy: '/api',
|
|
325
|
+
},
|
|
326
|
+
})
|
|
327
|
+
`;
|
|
328
|
+
node_fs.writeFileSync(node_path.resolve(projectDir, "bgl.config.ts"), bglConfigContent);
|
|
329
|
+
const viteConfig = `import { defineConfig } from 'vite'
|
|
330
|
+
import vue from '@vitejs/plugin-vue'
|
|
331
|
+
import { bagelink } from '@bagelink/workspace/vite'
|
|
332
|
+
import workspace from './bgl.config'
|
|
333
|
+
|
|
334
|
+
export default defineConfig({
|
|
335
|
+
plugins: [
|
|
336
|
+
vue(),
|
|
337
|
+
bagelink({ workspace }),
|
|
338
|
+
],
|
|
339
|
+
})
|
|
340
|
+
`;
|
|
341
|
+
node_fs.writeFileSync(node_path.resolve(projectDir, "vite.config.ts"), viteConfig);
|
|
342
|
+
const srcDir = node_path.resolve(projectDir, "src");
|
|
343
|
+
node_fs.mkdirSync(srcDir, { recursive: true });
|
|
344
|
+
const indexHtml = `<!DOCTYPE html>
|
|
345
|
+
<html lang="en">
|
|
346
|
+
<head>
|
|
347
|
+
<meta charset="UTF-8">
|
|
348
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
349
|
+
<title>${name}</title>
|
|
350
|
+
</head>
|
|
351
|
+
<body>
|
|
352
|
+
<div id="app"></div>
|
|
353
|
+
<script type="module" src="/src/main.ts"><\/script>
|
|
354
|
+
</body>
|
|
355
|
+
</html>
|
|
356
|
+
`;
|
|
357
|
+
node_fs.writeFileSync(node_path.resolve(projectDir, "index.html"), indexHtml);
|
|
358
|
+
const mainTs = `import { createApp } from 'vue'
|
|
359
|
+
import { BagelVue } from '@bagelink/vue'
|
|
360
|
+
import App from './App.vue'
|
|
361
|
+
|
|
362
|
+
createApp(App)
|
|
363
|
+
.use(BagelVue)
|
|
364
|
+
.mount('#app')
|
|
365
|
+
`;
|
|
366
|
+
node_fs.writeFileSync(node_path.resolve(srcDir, "main.ts"), mainTs);
|
|
367
|
+
const appVue = `<script setup lang="ts">
|
|
368
|
+
import { ref } from 'vue'
|
|
369
|
+
${isWorkspace ? "import { formatDate } from 'shared/utils'\n" : ""}
|
|
370
|
+
const count = ref(0)
|
|
371
|
+
<\/script>
|
|
372
|
+
|
|
373
|
+
<template>
|
|
374
|
+
<div>
|
|
375
|
+
<h1>${name}</h1>
|
|
376
|
+
<button @click="count++">Count: {{ count }}</button>
|
|
377
|
+
${isWorkspace ? "<p>{{ formatDate(new Date()) }}</p>" : ""}
|
|
378
|
+
</div>
|
|
379
|
+
</template>
|
|
380
|
+
`;
|
|
381
|
+
node_fs.writeFileSync(node_path.resolve(srcDir, "App.vue"), appVue);
|
|
382
|
+
console.log(`\u2705 Created project: ${name}`);
|
|
383
|
+
if (isWorkspace) {
|
|
384
|
+
updateWorkspaceScripts(root, name);
|
|
385
|
+
}
|
|
386
|
+
console.log("\nNext steps:");
|
|
387
|
+
console.log(` cd ${name}`);
|
|
388
|
+
console.log(" bun install");
|
|
389
|
+
console.log(" bun run dev");
|
|
390
|
+
console.log("");
|
|
391
|
+
}
|
|
392
|
+
function updateWorkspaceScripts(root, projectName) {
|
|
393
|
+
const packageJsonPath = node_path.resolve(root, "package.json");
|
|
394
|
+
if (!node_fs.existsSync(packageJsonPath)) return;
|
|
395
|
+
try {
|
|
396
|
+
const packageJson = JSON.parse(
|
|
397
|
+
node_fs.readFileSync(packageJsonPath, "utf-8")
|
|
398
|
+
);
|
|
399
|
+
if (!packageJson.scripts) {
|
|
400
|
+
packageJson.scripts = {};
|
|
401
|
+
}
|
|
402
|
+
packageJson.scripts[`dev:${projectName}`] = `bun --filter ${projectName} dev`;
|
|
403
|
+
packageJson.scripts[`build:${projectName}`] = `bun --filter ${projectName} build`;
|
|
404
|
+
node_fs.writeFileSync(
|
|
405
|
+
packageJsonPath,
|
|
406
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
407
|
+
`
|
|
408
|
+
);
|
|
409
|
+
console.log(`\u2705 Added scripts: dev:${projectName}, build:${projectName}`);
|
|
410
|
+
} catch (error) {
|
|
411
|
+
console.warn("\u26A0\uFE0F Could not update workspace scripts");
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function listProjects(root = process__default.cwd()) {
|
|
415
|
+
try {
|
|
416
|
+
const items = node_fs.readdirSync(root, { withFileTypes: true });
|
|
417
|
+
return items.filter(
|
|
418
|
+
(item) => item.isDirectory() && item.name !== "node_modules" && item.name !== "shared" && item.name !== "scripts" && item.name !== ".git" && !item.name.startsWith(".")
|
|
419
|
+
).filter((item) => {
|
|
420
|
+
const packageJsonPath = node_path.resolve(root, item.name, "package.json");
|
|
421
|
+
if (!node_fs.existsSync(packageJsonPath)) return false;
|
|
422
|
+
try {
|
|
423
|
+
const packageJson = JSON.parse(node_fs.readFileSync(packageJsonPath, "utf-8"));
|
|
424
|
+
return packageJson.scripts?.dev !== void 0;
|
|
425
|
+
} catch {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}).map((item) => item.name).sort();
|
|
429
|
+
} catch {
|
|
430
|
+
return [];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function generateNetlifyRedirect(config) {
|
|
435
|
+
const redirect = `# API Proxy Configuration
|
|
436
|
+
# Environment variables are set in Netlify UI or netlify.toml [build.environment] section
|
|
437
|
+
|
|
438
|
+
[[redirects]]
|
|
439
|
+
from = "${config.proxy}/*"
|
|
440
|
+
to = "${config.host}/:splat"
|
|
441
|
+
status = 200
|
|
442
|
+
force = true
|
|
443
|
+
headers = {X-From = "Netlify"}
|
|
444
|
+
`;
|
|
445
|
+
return redirect;
|
|
446
|
+
}
|
|
447
|
+
function generateNetlifyConfigTemplate() {
|
|
448
|
+
return `# Standard Netlify configuration for Bagelink projects
|
|
449
|
+
# Uses environment variables for proxy configuration
|
|
450
|
+
|
|
451
|
+
[build.environment]
|
|
452
|
+
# Set these in Netlify UI or override here
|
|
453
|
+
# BGL_PROXY_PATH = "/api"
|
|
454
|
+
# BGL_API_HOST = "https://your-project.bagel.to"
|
|
455
|
+
|
|
456
|
+
[[redirects]]
|
|
457
|
+
# Proxy API requests to backend
|
|
458
|
+
# Uses BGL_PROXY_PATH and BGL_API_HOST from environment
|
|
459
|
+
from = "/api/*"
|
|
460
|
+
to = "https://your-project.bagel.to/:splat"
|
|
461
|
+
status = 200
|
|
462
|
+
force = true
|
|
463
|
+
headers = {X-From = "Netlify"}
|
|
464
|
+
|
|
465
|
+
# Example: Multiple API backends
|
|
466
|
+
# [[redirects]]
|
|
467
|
+
# from = "/api/v2/*"
|
|
468
|
+
# to = "https://api-v2.example.com/:splat"
|
|
469
|
+
# status = 200
|
|
470
|
+
# force = true
|
|
471
|
+
`;
|
|
472
|
+
}
|
|
473
|
+
function generateNetlifyConfig(config, additionalConfig, useTemplate = false) {
|
|
474
|
+
if (useTemplate) {
|
|
475
|
+
return generateNetlifyConfigTemplate();
|
|
476
|
+
}
|
|
477
|
+
const redirect = generateNetlifyRedirect(config);
|
|
478
|
+
if (additionalConfig !== void 0 && additionalConfig !== "") {
|
|
479
|
+
return `${redirect}
|
|
480
|
+
${additionalConfig}`;
|
|
481
|
+
}
|
|
482
|
+
return redirect;
|
|
483
|
+
}
|
|
484
|
+
function writeNetlifyConfig(config, outPath = "./netlify.toml", additionalConfig, useTemplate = false) {
|
|
485
|
+
const content = generateNetlifyConfig(config, additionalConfig, useTemplate);
|
|
486
|
+
const resolvedPath = node_path.resolve(outPath);
|
|
487
|
+
node_fs.writeFileSync(resolvedPath, content, "utf-8");
|
|
488
|
+
console.log(`\u2713 Generated netlify.toml at ${resolvedPath}`);
|
|
489
|
+
if (!useTemplate) {
|
|
490
|
+
console.log("\n\u{1F4A1} Tip: For environment-based config, set these in Netlify UI:");
|
|
491
|
+
console.log(` BGL_PROXY_PATH = "${config.proxy}"`);
|
|
492
|
+
console.log(` BGL_API_HOST = "${config.host}"`);
|
|
493
|
+
if (config.openapi_url) {
|
|
494
|
+
console.log(` BGL_OPENAPI_URL = "${config.openapi_url}"`);
|
|
495
|
+
}
|
|
496
|
+
console.log("");
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function setBuildEnvVars(config) {
|
|
500
|
+
process__default.env.BGL_PROXY_PATH = config.proxy;
|
|
501
|
+
process__default.env.BGL_API_HOST = config.host;
|
|
502
|
+
if (config.openapi_url !== void 0 && config.openapi_url !== "") {
|
|
503
|
+
process__default.env.BGL_OPENAPI_URL = config.openapi_url;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
exports.addProject = addProject;
|
|
508
|
+
exports.generateNetlifyConfig = generateNetlifyConfig;
|
|
509
|
+
exports.initWorkspace = initWorkspace;
|
|
510
|
+
exports.listProjects = listProjects;
|
|
511
|
+
exports.setBuildEnvVars = setBuildEnvVars;
|
|
512
|
+
exports.writeNetlifyConfig = writeNetlifyConfig;
|
package/dist/vite.cjs
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const node_path = require('node:path');
|
|
4
|
+
const process = require('node:process');
|
|
5
|
+
const node_url = require('node:url');
|
|
6
|
+
const netlify = require('./shared/workspace.DRlDHdPw.cjs');
|
|
7
|
+
require('node:fs');
|
|
8
|
+
require('prompts');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
11
|
+
|
|
12
|
+
const process__default = /*#__PURE__*/_interopDefaultCompat(process);
|
|
13
|
+
|
|
14
|
+
function createViteProxy(config) {
|
|
15
|
+
const proxy = {};
|
|
16
|
+
if (config.proxy && config.host) {
|
|
17
|
+
proxy[config.proxy] = {
|
|
18
|
+
target: config.host,
|
|
19
|
+
changeOrigin: true,
|
|
20
|
+
rewrite: (path) => path.replace(new RegExp(`^${config.proxy}`), ""),
|
|
21
|
+
secure: false,
|
|
22
|
+
ws: true,
|
|
23
|
+
followRedirects: true,
|
|
24
|
+
autoRewrite: true,
|
|
25
|
+
protocolRewrite: "http",
|
|
26
|
+
configure: (proxy2, _options) => {
|
|
27
|
+
proxy2.on("proxyReq", (proxyReq, req, _res) => {
|
|
28
|
+
if (req.headers.origin) {
|
|
29
|
+
proxyReq.setHeader("origin", config.host);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
proxy2.on("error", (err, _req, _res) => {
|
|
33
|
+
console.log("proxy error", err);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (config.host) {
|
|
39
|
+
proxy["/files"] = {
|
|
40
|
+
target: config.host,
|
|
41
|
+
changeOrigin: true,
|
|
42
|
+
secure: false,
|
|
43
|
+
ws: true,
|
|
44
|
+
followRedirects: true
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return proxy;
|
|
48
|
+
}
|
|
49
|
+
function createCustomProxy(paths, target, options = {}) {
|
|
50
|
+
const proxy = {};
|
|
51
|
+
for (const path of paths) {
|
|
52
|
+
proxy[path] = {
|
|
53
|
+
target,
|
|
54
|
+
changeOrigin: options.changeOrigin ?? true,
|
|
55
|
+
secure: options.secure ?? false,
|
|
56
|
+
ws: options.ws ?? true,
|
|
57
|
+
...options.rewrite === true && {
|
|
58
|
+
rewrite: (p) => p.replace(new RegExp(`^${path}`), "")
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return proxy;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function bagelink(options) {
|
|
66
|
+
const { workspace, config = {} } = options;
|
|
67
|
+
let workspaceConfig;
|
|
68
|
+
return {
|
|
69
|
+
name: "vite-plugin-bagelink",
|
|
70
|
+
enforce: "pre",
|
|
71
|
+
configResolved(resolved) {
|
|
72
|
+
workspaceConfig = workspace(resolved.mode);
|
|
73
|
+
},
|
|
74
|
+
config(userConfig, { mode }) {
|
|
75
|
+
workspaceConfig = workspace(mode);
|
|
76
|
+
const alias = {};
|
|
77
|
+
if (config.includeSharedAlias !== false) {
|
|
78
|
+
const sharedPath = config.sharedPath ?? "../shared";
|
|
79
|
+
alias["@shared"] = node_url.fileURLToPath(new URL(sharedPath, `file://${process__default.cwd()}/`));
|
|
80
|
+
}
|
|
81
|
+
alias["@"] = node_url.fileURLToPath(new URL("./src", `file://${process__default.cwd()}/`));
|
|
82
|
+
if (config.additionalAliases) {
|
|
83
|
+
Object.assign(alias, config.additionalAliases);
|
|
84
|
+
}
|
|
85
|
+
let port;
|
|
86
|
+
try {
|
|
87
|
+
const currentDir = process__default.cwd();
|
|
88
|
+
const projectName = node_path.basename(currentDir);
|
|
89
|
+
const parentDir = node_url.fileURLToPath(new URL("..", `file://${currentDir}/`));
|
|
90
|
+
const allProjects = netlify.listProjects(parentDir);
|
|
91
|
+
const projectIndex = allProjects.indexOf(projectName);
|
|
92
|
+
if (projectIndex !== -1) {
|
|
93
|
+
port = 5173 + projectIndex;
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
const server = {
|
|
98
|
+
...config.configureProxy !== false && {
|
|
99
|
+
proxy: createViteProxy(workspaceConfig)
|
|
100
|
+
},
|
|
101
|
+
...port !== void 0 && {
|
|
102
|
+
port,
|
|
103
|
+
strictPort: false
|
|
104
|
+
// use next available port if preferred is taken
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const define = {
|
|
108
|
+
...workspaceConfig.proxy && {
|
|
109
|
+
"import.meta.env.VITE_BGL_PROXY": JSON.stringify(workspaceConfig.proxy)
|
|
110
|
+
},
|
|
111
|
+
"import.meta.env.VITE_BGL_HOST": JSON.stringify(workspaceConfig.host),
|
|
112
|
+
...workspaceConfig.openapi_url && {
|
|
113
|
+
"import.meta.env.VITE_BGL_OPENAPI_URL": JSON.stringify(workspaceConfig.openapi_url)
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
resolve: {
|
|
118
|
+
alias
|
|
119
|
+
},
|
|
120
|
+
define,
|
|
121
|
+
server,
|
|
122
|
+
optimizeDeps: {
|
|
123
|
+
exclude: ["@bagelink/workspace"]
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
exports.generateNetlifyConfig = netlify.generateNetlifyConfig;
|
|
131
|
+
exports.setBuildEnvVars = netlify.setBuildEnvVars;
|
|
132
|
+
exports.writeNetlifyConfig = netlify.writeNetlifyConfig;
|
|
133
|
+
exports.bagelink = bagelink;
|
|
134
|
+
exports.createCustomProxy = createCustomProxy;
|
|
135
|
+
exports.createViteProxy = createViteProxy;
|