@bagelink/workspace 1.9.0 → 1.10.1
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 +95 -3
- package/bin/bgl.ts +59 -12
- package/dist/bin/bgl.cjs +55 -18
- package/dist/bin/bgl.mjs +51 -14
- package/dist/index.cjs +18 -14
- package/dist/index.d.cts +25 -3
- package/dist/index.d.mts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.mjs +2 -2
- package/dist/shared/{workspace.cX7U2RUq.mjs → workspace.B6LGs4Ed.mjs} +361 -175
- package/dist/shared/{workspace.CCUm_5GG.cjs → workspace.Ndvn7T1u.cjs} +353 -163
- package/package.json +6 -1
- package/src/detect.ts +91 -0
- package/src/index.ts +3 -1
- package/src/sdk.ts +186 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writeFileSync, existsSync, readFileSync, mkdirSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import process from 'node:process';
|
|
3
|
+
import process$1 from 'node:process';
|
|
4
4
|
import prompts from 'prompts';
|
|
5
5
|
|
|
6
6
|
function generateNetlifyRedirect(config) {
|
|
@@ -28,14 +28,14 @@ function writeNetlifyConfig(config, outPath = "./netlify.toml", additionalConfig
|
|
|
28
28
|
console.log(`\u2713 Generated netlify.toml at ${resolvedPath}`);
|
|
29
29
|
}
|
|
30
30
|
function setBuildEnvVars(config) {
|
|
31
|
-
process.env.BGL_PROXY_PATH = config.proxy;
|
|
32
|
-
process.env.BGL_API_HOST = config.host;
|
|
31
|
+
process$1.env.BGL_PROXY_PATH = config.proxy;
|
|
32
|
+
process$1.env.BGL_API_HOST = config.host;
|
|
33
33
|
if (config.openapi_url !== void 0 && config.openapi_url !== "") {
|
|
34
|
-
process.env.BGL_OPENAPI_URL = config.openapi_url;
|
|
34
|
+
process$1.env.BGL_OPENAPI_URL = config.openapi_url;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
async function generateWorkspaceConfig(root = process.cwd(), configFile = "bgl.config.ts") {
|
|
38
|
+
async function generateWorkspaceConfig(root = process$1.cwd(), configFile = "bgl.config.ts") {
|
|
39
39
|
console.log("\n\u{1F527} No bgl.config.ts found. Let's create one!\n");
|
|
40
40
|
const response = await prompts([
|
|
41
41
|
{
|
|
@@ -60,7 +60,7 @@ async function generateWorkspaceConfig(root = process.cwd(), configFile = "bgl.c
|
|
|
60
60
|
]);
|
|
61
61
|
if (!response || !response.projectId) {
|
|
62
62
|
console.log("\n\u274C Config generation cancelled.\n");
|
|
63
|
-
process.exit(1);
|
|
63
|
+
process$1.exit(1);
|
|
64
64
|
}
|
|
65
65
|
const productionHost = response.useCustomHost === true ? response.customHost : `https://${response.projectId}.bagel.to`;
|
|
66
66
|
const configContent = `import { defineWorkspace } from '@bagelink/workspace'
|
|
@@ -128,7 +128,7 @@ export default defineWorkspace(configs)
|
|
|
128
128
|
}
|
|
129
129
|
console.log("\n\u{1F4A1} You can edit these files to customize your configuration.\n");
|
|
130
130
|
}
|
|
131
|
-
function generateWorkspaceConfigSync(projectId, root = process.cwd(), configFile = "bgl.config.ts", customHost) {
|
|
131
|
+
function generateWorkspaceConfigSync(projectId, root = process$1.cwd(), configFile = "bgl.config.ts", customHost) {
|
|
132
132
|
const productionHost = customHost ?? `https://${projectId}.bagel.to`;
|
|
133
133
|
const configContent = `import { defineWorkspace } from '@bagelink/workspace'
|
|
134
134
|
import type { WorkspaceConfig, WorkspaceEnvironment } from '@bagelink/workspace'
|
|
@@ -231,7 +231,313 @@ export default defineConfig(({ mode }) => {
|
|
|
231
231
|
console.log("\u2705 Created vite.config.ts");
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
async function
|
|
234
|
+
async function setupLint(root = process$1.cwd(), isWorkspace = false) {
|
|
235
|
+
console.log("\n\u{1F50D} Setting up linting...\n");
|
|
236
|
+
const response = await prompts([
|
|
237
|
+
{
|
|
238
|
+
type: "multiselect",
|
|
239
|
+
name: "configs",
|
|
240
|
+
message: "Select configurations to set up:",
|
|
241
|
+
choices: [
|
|
242
|
+
{ title: "ESLint", value: "eslint", selected: true },
|
|
243
|
+
{ title: "Prettier", value: "prettier", selected: true },
|
|
244
|
+
{ title: "EditorConfig", value: "editorconfig", selected: true },
|
|
245
|
+
{ title: "Git Hooks", value: "githooks", selected: false }
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
type: "confirm",
|
|
250
|
+
name: "installDeps",
|
|
251
|
+
message: "Install dependencies?",
|
|
252
|
+
initial: true
|
|
253
|
+
}
|
|
254
|
+
]);
|
|
255
|
+
if (!response || !response.configs) {
|
|
256
|
+
console.log("\n\u274C Setup cancelled.\n");
|
|
257
|
+
process$1.exit(1);
|
|
258
|
+
}
|
|
259
|
+
const { configs, installDeps } = response;
|
|
260
|
+
if (configs.includes("eslint")) {
|
|
261
|
+
createEslintConfig(root, isWorkspace);
|
|
262
|
+
}
|
|
263
|
+
if (configs.includes("prettier")) {
|
|
264
|
+
createPrettierConfig(root);
|
|
265
|
+
}
|
|
266
|
+
if (configs.includes("editorconfig")) {
|
|
267
|
+
createEditorConfig(root);
|
|
268
|
+
}
|
|
269
|
+
if (configs.includes("githooks")) {
|
|
270
|
+
createGitHooks(root);
|
|
271
|
+
}
|
|
272
|
+
updatePackageJsonLint(root, configs);
|
|
273
|
+
if (installDeps) {
|
|
274
|
+
console.log("\n\u{1F4E6} Installing dependencies...");
|
|
275
|
+
console.log("Run: bun add -D @bagelink/lint-config eslint prettier typescript");
|
|
276
|
+
}
|
|
277
|
+
console.log("\n\u2705 Linting setup complete!");
|
|
278
|
+
console.log("\nAvailable commands:");
|
|
279
|
+
console.log(" bun run lint - Run linter");
|
|
280
|
+
console.log(" bun run lint:fix - Fix linting issues");
|
|
281
|
+
console.log(" bun run format - Format code with Prettier");
|
|
282
|
+
console.log("");
|
|
283
|
+
}
|
|
284
|
+
function createEslintConfig(root, isWorkspace) {
|
|
285
|
+
const configPath = resolve(root, "eslint.config.js");
|
|
286
|
+
const config = isWorkspace ? `import { defineConfig } from '@bagelink/lint-config/eslint'
|
|
287
|
+
|
|
288
|
+
export default defineConfig({
|
|
289
|
+
// Workspace-level ESLint config
|
|
290
|
+
ignores: ['**/dist/**', '**/node_modules/**', '**/.bun-cache/**'],
|
|
291
|
+
})
|
|
292
|
+
` : `import vue3Config from '@bagelink/lint-config/eslint/vue3'
|
|
293
|
+
|
|
294
|
+
export default vue3Config
|
|
295
|
+
`;
|
|
296
|
+
writeFileSync(configPath, config);
|
|
297
|
+
console.log("\u2705 Created eslint.config.js");
|
|
298
|
+
}
|
|
299
|
+
function createPrettierConfig(root) {
|
|
300
|
+
const configPath = resolve(root, ".prettierrc");
|
|
301
|
+
const config = {
|
|
302
|
+
semi: false,
|
|
303
|
+
singleQuote: true,
|
|
304
|
+
tabWidth: 2,
|
|
305
|
+
useTabs: true,
|
|
306
|
+
trailingComma: "all",
|
|
307
|
+
printWidth: 100,
|
|
308
|
+
arrowParens: "avoid"
|
|
309
|
+
};
|
|
310
|
+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
311
|
+
`);
|
|
312
|
+
console.log("\u2705 Created .prettierrc");
|
|
313
|
+
const ignorePath = resolve(root, ".prettierignore");
|
|
314
|
+
const ignore = `dist
|
|
315
|
+
node_modules
|
|
316
|
+
.bun-cache
|
|
317
|
+
*.min.js
|
|
318
|
+
*.min.css
|
|
319
|
+
`;
|
|
320
|
+
writeFileSync(ignorePath, ignore);
|
|
321
|
+
console.log("\u2705 Created .prettierignore");
|
|
322
|
+
}
|
|
323
|
+
function createEditorConfig(root) {
|
|
324
|
+
const configPath = resolve(root, ".editorconfig");
|
|
325
|
+
const config = `root = true
|
|
326
|
+
|
|
327
|
+
[*]
|
|
328
|
+
charset = utf-8
|
|
329
|
+
indent_style = tab
|
|
330
|
+
indent_size = 2
|
|
331
|
+
end_of_line = lf
|
|
332
|
+
insert_final_newline = true
|
|
333
|
+
trim_trailing_whitespace = true
|
|
334
|
+
|
|
335
|
+
[*.md]
|
|
336
|
+
trim_trailing_whitespace = false
|
|
337
|
+
|
|
338
|
+
[*.{json,yml,yaml}]
|
|
339
|
+
indent_style = space
|
|
340
|
+
indent_size = 2
|
|
341
|
+
`;
|
|
342
|
+
writeFileSync(configPath, config);
|
|
343
|
+
console.log("\u2705 Created .editorconfig");
|
|
344
|
+
}
|
|
345
|
+
function createGitHooks(root) {
|
|
346
|
+
const packageJsonPath = resolve(root, "package.json");
|
|
347
|
+
if (!existsSync(packageJsonPath)) {
|
|
348
|
+
console.warn("\u26A0\uFE0F No package.json found, skipping git hooks");
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const lintStagedConfig = {
|
|
352
|
+
"*.{js,jsx,ts,tsx,vue}": ["eslint --fix"],
|
|
353
|
+
"*.{json,md,yml,yaml}": ["prettier --write"]
|
|
354
|
+
};
|
|
355
|
+
writeFileSync(
|
|
356
|
+
resolve(root, ".lintstagedrc"),
|
|
357
|
+
`${JSON.stringify(lintStagedConfig, null, 2)}
|
|
358
|
+
`
|
|
359
|
+
);
|
|
360
|
+
console.log("\u2705 Created .lintstagedrc");
|
|
361
|
+
console.log("\u2139\uFE0F Add simple-git-hooks and lint-staged to devDependencies");
|
|
362
|
+
console.log(" Then run: npx simple-git-hooks");
|
|
363
|
+
}
|
|
364
|
+
function updatePackageJsonLint(root, configs) {
|
|
365
|
+
const packageJsonPath = resolve(root, "package.json");
|
|
366
|
+
if (!existsSync(packageJsonPath)) {
|
|
367
|
+
console.warn("\u26A0\uFE0F No package.json found");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
try {
|
|
371
|
+
const packageJson = JSON.parse(
|
|
372
|
+
require("fs").readFileSync(packageJsonPath, "utf-8")
|
|
373
|
+
);
|
|
374
|
+
if (!packageJson.scripts) {
|
|
375
|
+
packageJson.scripts = {};
|
|
376
|
+
}
|
|
377
|
+
if (configs.includes("eslint")) {
|
|
378
|
+
if (!packageJson.scripts.lint) {
|
|
379
|
+
packageJson.scripts.lint = "eslint .";
|
|
380
|
+
}
|
|
381
|
+
if (!packageJson.scripts["lint:fix"]) {
|
|
382
|
+
packageJson.scripts["lint:fix"] = "eslint . --fix";
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (configs.includes("prettier")) {
|
|
386
|
+
if (!packageJson.scripts.format) {
|
|
387
|
+
packageJson.scripts.format = "prettier --write .";
|
|
388
|
+
}
|
|
389
|
+
if (!packageJson.scripts["format:check"]) {
|
|
390
|
+
packageJson.scripts["format:check"] = "prettier --check .";
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
writeFileSync(
|
|
394
|
+
packageJsonPath,
|
|
395
|
+
`${JSON.stringify(packageJson, null, 2)}
|
|
396
|
+
`
|
|
397
|
+
);
|
|
398
|
+
console.log("\u2705 Updated package.json with lint scripts");
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error("\u274C Failed to update package.json:", error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
async function generateSDK(root = process$1.cwd(), projectName) {
|
|
405
|
+
console.log("\n\u{1F527} Generating SDK from OpenAPI...\n");
|
|
406
|
+
let config = null;
|
|
407
|
+
let openApiUrl;
|
|
408
|
+
try {
|
|
409
|
+
const configPath = resolve(root, "bgl.config.ts");
|
|
410
|
+
if (existsSync(configPath)) {
|
|
411
|
+
const module = await import(`file://${configPath}`);
|
|
412
|
+
const workspace = module.default;
|
|
413
|
+
if (typeof workspace === "function") {
|
|
414
|
+
config = workspace("development");
|
|
415
|
+
openApiUrl = config.openapi_url;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.warn("\u26A0\uFE0F Could not load bgl.config.ts");
|
|
420
|
+
}
|
|
421
|
+
const response = await prompts([
|
|
422
|
+
{
|
|
423
|
+
type: openApiUrl ? null : "text",
|
|
424
|
+
name: "openApiUrl",
|
|
425
|
+
message: "OpenAPI spec URL:",
|
|
426
|
+
initial: openApiUrl || "http://localhost:8000/openapi.json"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
type: "text",
|
|
430
|
+
name: "outputDir",
|
|
431
|
+
message: "Output directory:",
|
|
432
|
+
initial: "./src/api"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
type: "confirm",
|
|
436
|
+
name: "splitFiles",
|
|
437
|
+
message: "Split into organized files?",
|
|
438
|
+
initial: true
|
|
439
|
+
}
|
|
440
|
+
]);
|
|
441
|
+
if (!response) {
|
|
442
|
+
console.log("\n\u274C SDK generation cancelled.\n");
|
|
443
|
+
process$1.exit(1);
|
|
444
|
+
}
|
|
445
|
+
const finalUrl = openApiUrl || response.openApiUrl;
|
|
446
|
+
const { outputDir, splitFiles } = response;
|
|
447
|
+
console.log(`
|
|
448
|
+
\u{1F4E1} Fetching OpenAPI spec from: ${finalUrl}`);
|
|
449
|
+
console.log(`\u{1F4C1} Output directory: ${outputDir}
|
|
450
|
+
`);
|
|
451
|
+
try {
|
|
452
|
+
const { default: openAPI } = await import('@bagelink/sdk');
|
|
453
|
+
const { types, code } = await openAPI(finalUrl, "/api");
|
|
454
|
+
const outputPath = resolve(root, outputDir);
|
|
455
|
+
if (!existsSync(outputPath)) {
|
|
456
|
+
mkdirSync(outputPath, { recursive: true });
|
|
457
|
+
}
|
|
458
|
+
const typesPath = resolve(outputPath, "types.d.ts");
|
|
459
|
+
writeFileSync(typesPath, types);
|
|
460
|
+
console.log("\u2705 Generated types.d.ts");
|
|
461
|
+
const apiPath = resolve(outputPath, "api.ts");
|
|
462
|
+
writeFileSync(apiPath, code);
|
|
463
|
+
console.log("\u2705 Generated api.ts");
|
|
464
|
+
const indexPath = resolve(outputPath, "index.ts");
|
|
465
|
+
writeFileSync(
|
|
466
|
+
indexPath,
|
|
467
|
+
"export * from './api'\nexport * from './types.d'\n"
|
|
468
|
+
);
|
|
469
|
+
console.log("\u2705 Generated index.ts");
|
|
470
|
+
if (splitFiles) {
|
|
471
|
+
console.log("\n\u{1F500} Splitting into organized files...");
|
|
472
|
+
try {
|
|
473
|
+
const { splitClientCode } = await import('@bagelink/sdk/bin/splitClientGen');
|
|
474
|
+
await splitClientCode({
|
|
475
|
+
bagelinkDir: outputPath,
|
|
476
|
+
useDirectories: true
|
|
477
|
+
});
|
|
478
|
+
const fs = await import('node:fs');
|
|
479
|
+
fs.rmSync(apiPath, { force: true });
|
|
480
|
+
fs.rmSync(typesPath, { force: true });
|
|
481
|
+
fs.rmSync(indexPath, { force: true });
|
|
482
|
+
console.log("\u2705 Files organized into directories");
|
|
483
|
+
} catch (error) {
|
|
484
|
+
console.warn("\u26A0\uFE0F Could not split files, keeping monolithic structure");
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
console.log("\n\u2705 SDK generated successfully!");
|
|
488
|
+
console.log(`
|
|
489
|
+
Import it in your code:`);
|
|
490
|
+
console.log(` import { api } from '${outputDir.replace("./src/", "./")}'`);
|
|
491
|
+
console.log("");
|
|
492
|
+
} catch (error) {
|
|
493
|
+
console.error("\n\u274C Failed to generate SDK:");
|
|
494
|
+
if (error instanceof Error) {
|
|
495
|
+
console.error(error.message);
|
|
496
|
+
} else {
|
|
497
|
+
console.error(error);
|
|
498
|
+
}
|
|
499
|
+
console.log("\nMake sure:");
|
|
500
|
+
console.log(" 1. @bagelink/sdk is installed: bun add -D @bagelink/sdk");
|
|
501
|
+
console.log(" 2. OpenAPI URL is accessible");
|
|
502
|
+
console.log(" 3. API server is running (if using localhost)");
|
|
503
|
+
process$1.exit(1);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
async function generateSDKForWorkspace(root = process$1.cwd()) {
|
|
507
|
+
console.log("\n\u{1F3E2} Generating SDK for workspace projects...\n");
|
|
508
|
+
const fs = await import('node:fs');
|
|
509
|
+
const items = fs.readdirSync(root, { withFileTypes: true });
|
|
510
|
+
const projects = items.filter(
|
|
511
|
+
(item) => item.isDirectory() && item.name !== "node_modules" && item.name !== "shared" && item.name !== ".git" && !item.name.startsWith(".")
|
|
512
|
+
).map((item) => item.name);
|
|
513
|
+
if (projects.length === 0) {
|
|
514
|
+
console.log("No projects found in workspace");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const response = await prompts({
|
|
518
|
+
type: "multiselect",
|
|
519
|
+
name: "selectedProjects",
|
|
520
|
+
message: "Select projects to generate SDK for:",
|
|
521
|
+
choices: projects.map((p) => ({ title: p, value: p, selected: true }))
|
|
522
|
+
});
|
|
523
|
+
if (!response || !response.selectedProjects || response.selectedProjects.length === 0) {
|
|
524
|
+
console.log("\n\u274C No projects selected.\n");
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
for (const project of response.selectedProjects) {
|
|
528
|
+
console.log(`
|
|
529
|
+
\u{1F4E6} Generating SDK for: ${project}`);
|
|
530
|
+
const projectPath = resolve(root, project);
|
|
531
|
+
try {
|
|
532
|
+
await generateSDK(projectPath);
|
|
533
|
+
} catch (error) {
|
|
534
|
+
console.error(`Failed to generate SDK for ${project}:`, error);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
console.log("\n\u2705 All SDKs generated!");
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
async function initWorkspace(root = process$1.cwd()) {
|
|
235
541
|
console.log("\n\u{1F680} Creating Bagel workspace...\n");
|
|
236
542
|
const response = await prompts([
|
|
237
543
|
{
|
|
@@ -261,7 +567,7 @@ async function initWorkspace(root = process.cwd()) {
|
|
|
261
567
|
]);
|
|
262
568
|
if (!response || !response.workspaceName) {
|
|
263
569
|
console.log("\n\u274C Workspace creation cancelled.\n");
|
|
264
|
-
process.exit(1);
|
|
570
|
+
process$1.exit(1);
|
|
265
571
|
}
|
|
266
572
|
const { workspaceName, projectId, createFirstProject, firstProjectName } = response;
|
|
267
573
|
createWorkspaceRoot(root, workspaceName, projectId);
|
|
@@ -284,7 +590,7 @@ function createWorkspaceRoot(root, name, projectId) {
|
|
|
284
590
|
const workspaceDir = resolve(root, name);
|
|
285
591
|
if (existsSync(workspaceDir)) {
|
|
286
592
|
console.error(`\u274C Directory ${name} already exists`);
|
|
287
|
-
process.exit(1);
|
|
593
|
+
process$1.exit(1);
|
|
288
594
|
}
|
|
289
595
|
mkdirSync(workspaceDir, { recursive: true });
|
|
290
596
|
const packageJson = {
|
|
@@ -400,11 +706,11 @@ function createSharedPackage(root) {
|
|
|
400
706
|
);
|
|
401
707
|
console.log("\u2705 Created shared package");
|
|
402
708
|
}
|
|
403
|
-
async function addProject(name, root = process.cwd()) {
|
|
709
|
+
async function addProject(name, root = process$1.cwd()) {
|
|
404
710
|
const projectDir = resolve(root, name);
|
|
405
711
|
if (existsSync(projectDir)) {
|
|
406
712
|
console.error(`\u274C Project ${name} already exists`);
|
|
407
|
-
process.exit(1);
|
|
713
|
+
process$1.exit(1);
|
|
408
714
|
}
|
|
409
715
|
console.log(`
|
|
410
716
|
\u{1F4E6} Creating project: ${name}
|
|
@@ -546,7 +852,7 @@ function updateWorkspaceScripts(root, projectName) {
|
|
|
546
852
|
console.warn("\u26A0\uFE0F Could not update workspace scripts");
|
|
547
853
|
}
|
|
548
854
|
}
|
|
549
|
-
function listProjects(root = process.cwd()) {
|
|
855
|
+
function listProjects(root = process$1.cwd()) {
|
|
550
856
|
try {
|
|
551
857
|
const items = readdirSync(root, { withFileTypes: true });
|
|
552
858
|
return items.filter(
|
|
@@ -557,174 +863,54 @@ function listProjects(root = process.cwd()) {
|
|
|
557
863
|
}
|
|
558
864
|
}
|
|
559
865
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
{
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
{ title: "Prettier", value: "prettier", selected: true },
|
|
570
|
-
{ title: "EditorConfig", value: "editorconfig", selected: true },
|
|
571
|
-
{ title: "Git Hooks", value: "githooks", selected: false }
|
|
572
|
-
]
|
|
573
|
-
},
|
|
574
|
-
{
|
|
575
|
-
type: "confirm",
|
|
576
|
-
name: "installDeps",
|
|
577
|
-
message: "Install dependencies?",
|
|
578
|
-
initial: true
|
|
866
|
+
function isWorkspace(root = process.cwd()) {
|
|
867
|
+
const packageJsonPath = resolve(root, "package.json");
|
|
868
|
+
if (existsSync(packageJsonPath)) {
|
|
869
|
+
try {
|
|
870
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
871
|
+
if (packageJson.workspaces) {
|
|
872
|
+
return true;
|
|
873
|
+
}
|
|
874
|
+
} catch {
|
|
579
875
|
}
|
|
580
|
-
]);
|
|
581
|
-
if (!response || !response.configs) {
|
|
582
|
-
console.log("\n\u274C Setup cancelled.\n");
|
|
583
|
-
process.exit(1);
|
|
584
|
-
}
|
|
585
|
-
const { configs, installDeps } = response;
|
|
586
|
-
if (configs.includes("eslint")) {
|
|
587
|
-
createEslintConfig(root, isWorkspace);
|
|
588
|
-
}
|
|
589
|
-
if (configs.includes("prettier")) {
|
|
590
|
-
createPrettierConfig(root);
|
|
591
876
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
console.log("\n\u{1F4E6} Installing dependencies...");
|
|
601
|
-
console.log("Run: bun add -D @bagelink/lint-config eslint prettier typescript");
|
|
602
|
-
}
|
|
603
|
-
console.log("\n\u2705 Linting setup complete!");
|
|
604
|
-
console.log("\nAvailable commands:");
|
|
605
|
-
console.log(" bun run lint - Run linter");
|
|
606
|
-
console.log(" bun run lint:fix - Fix linting issues");
|
|
607
|
-
console.log(" bun run format - Format code with Prettier");
|
|
608
|
-
console.log("");
|
|
609
|
-
}
|
|
610
|
-
function createEslintConfig(root, isWorkspace) {
|
|
611
|
-
const configPath = resolve(root, "eslint.config.js");
|
|
612
|
-
const config = isWorkspace ? `import { defineConfig } from '@bagelink/lint-config/eslint'
|
|
613
|
-
|
|
614
|
-
export default defineConfig({
|
|
615
|
-
// Workspace-level ESLint config
|
|
616
|
-
ignores: ['**/dist/**', '**/node_modules/**', '**/.bun-cache/**'],
|
|
617
|
-
})
|
|
618
|
-
` : `import vue3Config from '@bagelink/lint-config/eslint/vue3'
|
|
619
|
-
|
|
620
|
-
export default vue3Config
|
|
621
|
-
`;
|
|
622
|
-
writeFileSync(configPath, config);
|
|
623
|
-
console.log("\u2705 Created eslint.config.js");
|
|
624
|
-
}
|
|
625
|
-
function createPrettierConfig(root) {
|
|
626
|
-
const configPath = resolve(root, ".prettierrc");
|
|
627
|
-
const config = {
|
|
628
|
-
semi: false,
|
|
629
|
-
singleQuote: true,
|
|
630
|
-
tabWidth: 2,
|
|
631
|
-
useTabs: true,
|
|
632
|
-
trailingComma: "all",
|
|
633
|
-
printWidth: 100,
|
|
634
|
-
arrowParens: "avoid"
|
|
635
|
-
};
|
|
636
|
-
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
|
|
637
|
-
`);
|
|
638
|
-
console.log("\u2705 Created .prettierrc");
|
|
639
|
-
const ignorePath = resolve(root, ".prettierignore");
|
|
640
|
-
const ignore = `dist
|
|
641
|
-
node_modules
|
|
642
|
-
.bun-cache
|
|
643
|
-
*.min.js
|
|
644
|
-
*.min.css
|
|
645
|
-
`;
|
|
646
|
-
writeFileSync(ignorePath, ignore);
|
|
647
|
-
console.log("\u2705 Created .prettierignore");
|
|
648
|
-
}
|
|
649
|
-
function createEditorConfig(root) {
|
|
650
|
-
const configPath = resolve(root, ".editorconfig");
|
|
651
|
-
const config = `root = true
|
|
652
|
-
|
|
653
|
-
[*]
|
|
654
|
-
charset = utf-8
|
|
655
|
-
indent_style = tab
|
|
656
|
-
indent_size = 2
|
|
657
|
-
end_of_line = lf
|
|
658
|
-
insert_final_newline = true
|
|
659
|
-
trim_trailing_whitespace = true
|
|
660
|
-
|
|
661
|
-
[*.md]
|
|
662
|
-
trim_trailing_whitespace = false
|
|
663
|
-
|
|
664
|
-
[*.{json,yml,yaml}]
|
|
665
|
-
indent_style = space
|
|
666
|
-
indent_size = 2
|
|
667
|
-
`;
|
|
668
|
-
writeFileSync(configPath, config);
|
|
669
|
-
console.log("\u2705 Created .editorconfig");
|
|
670
|
-
}
|
|
671
|
-
function createGitHooks(root) {
|
|
672
|
-
const packageJsonPath = resolve(root, "package.json");
|
|
673
|
-
if (!existsSync(packageJsonPath)) {
|
|
674
|
-
console.warn("\u26A0\uFE0F No package.json found, skipping git hooks");
|
|
675
|
-
return;
|
|
877
|
+
try {
|
|
878
|
+
const items = readdirSync(root, { withFileTypes: true });
|
|
879
|
+
const projectDirs = items.filter(
|
|
880
|
+
(item) => item.isDirectory() && item.name !== "node_modules" && item.name !== "shared" && item.name !== ".git" && !item.name.startsWith(".") && existsSync(resolve(root, item.name, "package.json"))
|
|
881
|
+
);
|
|
882
|
+
return projectDirs.length >= 2;
|
|
883
|
+
} catch {
|
|
884
|
+
return false;
|
|
676
885
|
}
|
|
677
|
-
const lintStagedConfig = {
|
|
678
|
-
"*.{js,jsx,ts,tsx,vue}": ["eslint --fix"],
|
|
679
|
-
"*.{json,md,yml,yaml}": ["prettier --write"]
|
|
680
|
-
};
|
|
681
|
-
writeFileSync(
|
|
682
|
-
resolve(root, ".lintstagedrc"),
|
|
683
|
-
`${JSON.stringify(lintStagedConfig, null, 2)}
|
|
684
|
-
`
|
|
685
|
-
);
|
|
686
|
-
console.log("\u2705 Created .lintstagedrc");
|
|
687
|
-
console.log("\u2139\uFE0F Add simple-git-hooks and lint-staged to devDependencies");
|
|
688
|
-
console.log(" Then run: npx simple-git-hooks");
|
|
689
886
|
}
|
|
690
|
-
function
|
|
691
|
-
const
|
|
692
|
-
if (!
|
|
693
|
-
|
|
694
|
-
|
|
887
|
+
function getWorkspaceInfo(root = process.cwd()) {
|
|
888
|
+
const workspace = isWorkspace(root);
|
|
889
|
+
if (!workspace) {
|
|
890
|
+
return {
|
|
891
|
+
isWorkspace: false,
|
|
892
|
+
projects: [],
|
|
893
|
+
hasShared: false
|
|
894
|
+
};
|
|
695
895
|
}
|
|
696
896
|
try {
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
packageJson.scripts.format = "prettier --write .";
|
|
714
|
-
}
|
|
715
|
-
if (!packageJson.scripts["format:check"]) {
|
|
716
|
-
packageJson.scripts["format:check"] = "prettier --check .";
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
writeFileSync(
|
|
720
|
-
packageJsonPath,
|
|
721
|
-
`${JSON.stringify(packageJson, null, 2)}
|
|
722
|
-
`
|
|
723
|
-
);
|
|
724
|
-
console.log("\u2705 Updated package.json with lint scripts");
|
|
725
|
-
} catch (error) {
|
|
726
|
-
console.error("\u274C Failed to update package.json:", error);
|
|
897
|
+
const items = readdirSync(root, { withFileTypes: true });
|
|
898
|
+
const projects = items.filter(
|
|
899
|
+
(item) => item.isDirectory() && item.name !== "node_modules" && item.name !== "shared" && item.name !== ".git" && !item.name.startsWith(".") && existsSync(resolve(root, item.name, "package.json"))
|
|
900
|
+
).map((item) => item.name);
|
|
901
|
+
const hasShared = existsSync(resolve(root, "shared"));
|
|
902
|
+
return {
|
|
903
|
+
isWorkspace: true,
|
|
904
|
+
projects,
|
|
905
|
+
hasShared
|
|
906
|
+
};
|
|
907
|
+
} catch {
|
|
908
|
+
return {
|
|
909
|
+
isWorkspace: false,
|
|
910
|
+
projects: [],
|
|
911
|
+
hasShared: false
|
|
912
|
+
};
|
|
727
913
|
}
|
|
728
914
|
}
|
|
729
915
|
|
|
730
|
-
export { generateNetlifyConfig as a, generateNetlifyRedirect as b, generateWorkspaceConfigSync as c,
|
|
916
|
+
export { generateNetlifyConfig as a, generateNetlifyRedirect as b, generateWorkspaceConfigSync as c, setupLint as d, generateSDK as e, generateSDKForWorkspace as f, generateWorkspaceConfig as g, addProject as h, initWorkspace as i, getWorkspaceInfo as j, isWorkspace as k, listProjects as l, setBuildEnvVars as s, writeNetlifyConfig as w };
|