@bagelink/workspace 1.8.0 → 1.9.0

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 CHANGED
@@ -268,6 +268,49 @@ bun run build
268
268
  - Third project: `http://localhost:5175`
269
269
  - etc.
270
270
 
271
+ ### Linting Setup
272
+
273
+ #### `bgl lint init`
274
+
275
+ Set up linting and formatting in your project:
276
+
277
+ ```bash
278
+ bgl lint init
279
+
280
+ ? Select configurations to set up:
281
+ ✔ ESLint
282
+ ✔ Prettier
283
+ ✔ EditorConfig
284
+ ○ Git Hooks
285
+ ? Install dependencies? › Yes
286
+
287
+ ✅ Created eslint.config.js
288
+ ✅ Created .prettierrc
289
+ ✅ Created .prettierignore
290
+ ✅ Created .editorconfig
291
+ ✅ Updated package.json with lint scripts
292
+ ```
293
+
294
+ **Creates:**
295
+ - `eslint.config.js` - ESLint configuration (Vue 3 + TypeScript)
296
+ - `.prettierrc` - Prettier configuration
297
+ - `.prettierignore` - Prettier ignore patterns
298
+ - `.editorconfig` - Editor configuration
299
+ - `.lintstagedrc` - Lint-staged configuration (if git hooks selected)
300
+
301
+ **Adds scripts:**
302
+ - `bun run lint` - Run linter
303
+ - `bun run lint:fix` - Fix linting issues
304
+ - `bun run format` - Format code
305
+ - `bun run format:check` - Check formatting
306
+
307
+ **For workspace:**
308
+ ```bash
309
+ bgl lint init --workspace
310
+ ```
311
+
312
+ Sets up linting at workspace root level for all projects.
313
+
271
314
  ### `npx bgl --help`
272
315
 
273
316
  Show CLI help.
package/bin/bgl.ts CHANGED
@@ -2,8 +2,9 @@
2
2
  import process from 'node:process'
3
3
  import { generateWorkspaceConfig } from '../src/init.js'
4
4
  import { addProject, initWorkspace, listProjects } from '../src/workspace.js'
5
+ import { setupLint } from '../src/lint.js'
5
6
 
6
- const [,, command, ...args] = process.argv
7
+ const [,, command, subcommand, ...args] = process.argv
7
8
 
8
9
  async function main() {
9
10
  if (command === 'init') {
@@ -35,18 +36,34 @@ async function main() {
35
36
  console.log('')
36
37
  }
37
38
  }
39
+ else if (command === 'lint') {
40
+ if (subcommand === 'init') {
41
+ const isWorkspace = args.includes('--workspace') || args.includes('-w')
42
+ await setupLint(process.cwd(), isWorkspace)
43
+ }
44
+ else {
45
+ console.log(`
46
+ Lint Commands:
47
+ bgl lint init Set up linting in current project
48
+ bgl lint init --workspace Set up linting for workspace root
49
+ `)
50
+ process.exit(1)
51
+ }
52
+ }
38
53
  else {
39
54
  console.log(`
40
55
  Bagel Workspace CLI
41
56
 
42
57
  Usage:
43
- bgl init Generate bgl.config.ts for single project
44
- bgl init --workspace Create a new workspace with multiple projects
45
- bgl add <name> Add a new project to workspace
46
- bgl list List all projects in workspace
58
+ bgl init Generate bgl.config.ts for single project
59
+ bgl init --workspace Create a new workspace with multiple projects
60
+ bgl add <name> Add a new project to workspace
61
+ bgl list List all projects in workspace
62
+ bgl lint init Set up linting in current project
63
+ bgl lint init --workspace Set up linting for workspace root
47
64
 
48
65
  Options:
49
- --help, -h Show this help message
66
+ --help, -h Show this help message
50
67
  `)
51
68
  process.exit(command === '--help' || command === '-h' ? 0 : 1)
52
69
  }
package/dist/bin/bgl.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  const process = require('node:process');
5
- const workspace = require('../shared/workspace.Bwsdwbt-.cjs');
5
+ const lint = require('../shared/workspace.CCUm_5GG.cjs');
6
6
  require('node:fs');
7
7
  require('node:path');
8
8
  require('prompts');
@@ -11,14 +11,14 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
11
11
 
12
12
  const process__default = /*#__PURE__*/_interopDefaultCompat(process);
13
13
 
14
- const [, , command, ...args] = process__default.argv;
14
+ const [, , command, subcommand, ...args] = process__default.argv;
15
15
  async function main() {
16
16
  if (command === "init") {
17
17
  const isWorkspace = args.includes("--workspace") || args.includes("-w");
18
18
  if (isWorkspace) {
19
- await workspace.initWorkspace();
19
+ await lint.initWorkspace();
20
20
  } else {
21
- await workspace.generateWorkspaceConfig();
21
+ await lint.generateWorkspaceConfig();
22
22
  }
23
23
  } else if (command === "add") {
24
24
  const projectName = args[0];
@@ -27,9 +27,9 @@ async function main() {
27
27
  console.log("Usage: bgl add <project-name>");
28
28
  process__default.exit(1);
29
29
  }
30
- await workspace.addProject(projectName);
30
+ await lint.addProject(projectName);
31
31
  } else if (command === "list") {
32
- const projects = workspace.listProjects();
32
+ const projects = lint.listProjects();
33
33
  if (projects.length === 0) {
34
34
  console.log("No projects found");
35
35
  } else {
@@ -37,18 +37,32 @@ async function main() {
37
37
  projects.forEach((p) => console.log(` - ${p}`));
38
38
  console.log("");
39
39
  }
40
+ } else if (command === "lint") {
41
+ if (subcommand === "init") {
42
+ const isWorkspace = args.includes("--workspace") || args.includes("-w");
43
+ await lint.setupLint(process__default.cwd(), isWorkspace);
44
+ } else {
45
+ console.log(`
46
+ Lint Commands:
47
+ bgl lint init Set up linting in current project
48
+ bgl lint init --workspace Set up linting for workspace root
49
+ `);
50
+ process__default.exit(1);
51
+ }
40
52
  } else {
41
53
  console.log(`
42
54
  Bagel Workspace CLI
43
55
 
44
56
  Usage:
45
- bgl init Generate bgl.config.ts for single project
46
- bgl init --workspace Create a new workspace with multiple projects
47
- bgl add <name> Add a new project to workspace
48
- bgl list List all projects in workspace
57
+ bgl init Generate bgl.config.ts for single project
58
+ bgl init --workspace Create a new workspace with multiple projects
59
+ bgl add <name> Add a new project to workspace
60
+ bgl list List all projects in workspace
61
+ bgl lint init Set up linting in current project
62
+ bgl lint init --workspace Set up linting for workspace root
49
63
 
50
64
  Options:
51
- --help, -h Show this help message
65
+ --help, -h Show this help message
52
66
  `);
53
67
  process__default.exit(command === "--help" || command === "-h" ? 0 : 1);
54
68
  }
package/dist/bin/bgl.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import process from 'node:process';
3
- import { i as initWorkspace, g as generateWorkspaceConfig, d as addProject, l as listProjects } from '../shared/workspace.Dq-27S1f.mjs';
3
+ import { i as initWorkspace, g as generateWorkspaceConfig, d as addProject, l as listProjects, e as setupLint } from '../shared/workspace.cX7U2RUq.mjs';
4
4
  import 'node:fs';
5
5
  import 'node:path';
6
6
  import 'prompts';
7
7
 
8
- const [, , command, ...args] = process.argv;
8
+ const [, , command, subcommand, ...args] = process.argv;
9
9
  async function main() {
10
10
  if (command === "init") {
11
11
  const isWorkspace = args.includes("--workspace") || args.includes("-w");
@@ -31,18 +31,32 @@ async function main() {
31
31
  projects.forEach((p) => console.log(` - ${p}`));
32
32
  console.log("");
33
33
  }
34
+ } else if (command === "lint") {
35
+ if (subcommand === "init") {
36
+ const isWorkspace = args.includes("--workspace") || args.includes("-w");
37
+ await setupLint(process.cwd(), isWorkspace);
38
+ } else {
39
+ console.log(`
40
+ Lint Commands:
41
+ bgl lint init Set up linting in current project
42
+ bgl lint init --workspace Set up linting for workspace root
43
+ `);
44
+ process.exit(1);
45
+ }
34
46
  } else {
35
47
  console.log(`
36
48
  Bagel Workspace CLI
37
49
 
38
50
  Usage:
39
- bgl init Generate bgl.config.ts for single project
40
- bgl init --workspace Create a new workspace with multiple projects
41
- bgl add <name> Add a new project to workspace
42
- bgl list List all projects in workspace
51
+ bgl init Generate bgl.config.ts for single project
52
+ bgl init --workspace Create a new workspace with multiple projects
53
+ bgl add <name> Add a new project to workspace
54
+ bgl list List all projects in workspace
55
+ bgl lint init Set up linting in current project
56
+ bgl lint init --workspace Set up linting for workspace root
43
57
 
44
58
  Options:
45
- --help, -h Show this help message
59
+ --help, -h Show this help message
46
60
  `);
47
61
  process.exit(command === "--help" || command === "-h" ? 0 : 1);
48
62
  }
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  const node_fs = require('node:fs');
4
4
  const node_path = require('node:path');
5
5
  const process = require('node:process');
6
- const workspace = require('./shared/workspace.Bwsdwbt-.cjs');
6
+ const lint = require('./shared/workspace.CCUm_5GG.cjs');
7
7
  require('prompts');
8
8
 
9
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -32,7 +32,7 @@ async function resolveConfig(mode = "development", options = {}) {
32
32
  currentDir = parentDir;
33
33
  }
34
34
  if (options.interactive !== false) {
35
- await workspace.generateWorkspaceConfig(root, configFile);
35
+ await lint.generateWorkspaceConfig(root, configFile);
36
36
  const newConfig = await loadConfig(localConfigPath, mode);
37
37
  if (newConfig) {
38
38
  return newConfig;
@@ -131,13 +131,13 @@ function createWorkspace(options = {}) {
131
131
  * Generate Netlify configuration file
132
132
  */
133
133
  generateNetlify(config, outPath = "./netlify.toml", additionalConfig) {
134
- workspace.writeNetlifyConfig(config, outPath, additionalConfig);
134
+ lint.writeNetlifyConfig(config, outPath, additionalConfig);
135
135
  },
136
136
  /**
137
137
  * Set build environment variables
138
138
  */
139
139
  setBuildEnv(config) {
140
- workspace.setBuildEnvVars(config);
140
+ lint.setBuildEnvVars(config);
141
141
  },
142
142
  /**
143
143
  * Clear cached configuration
@@ -148,15 +148,16 @@ function createWorkspace(options = {}) {
148
148
  };
149
149
  }
150
150
 
151
- exports.addProject = workspace.addProject;
152
- exports.generateNetlifyConfig = workspace.generateNetlifyConfig;
153
- exports.generateNetlifyRedirect = workspace.generateNetlifyRedirect;
154
- exports.generateWorkspaceConfig = workspace.generateWorkspaceConfig;
155
- exports.generateWorkspaceConfigSync = workspace.generateWorkspaceConfigSync;
156
- exports.initWorkspace = workspace.initWorkspace;
157
- exports.listProjects = workspace.listProjects;
158
- exports.setBuildEnvVars = workspace.setBuildEnvVars;
159
- exports.writeNetlifyConfig = workspace.writeNetlifyConfig;
151
+ exports.addProject = lint.addProject;
152
+ exports.generateNetlifyConfig = lint.generateNetlifyConfig;
153
+ exports.generateNetlifyRedirect = lint.generateNetlifyRedirect;
154
+ exports.generateWorkspaceConfig = lint.generateWorkspaceConfig;
155
+ exports.generateWorkspaceConfigSync = lint.generateWorkspaceConfigSync;
156
+ exports.initWorkspace = lint.initWorkspace;
157
+ exports.listProjects = lint.listProjects;
158
+ exports.setBuildEnvVars = lint.setBuildEnvVars;
159
+ exports.setupLint = lint.setupLint;
160
+ exports.writeNetlifyConfig = lint.writeNetlifyConfig;
160
161
  exports.createCustomProxy = createCustomProxy;
161
162
  exports.createViteProxy = createViteProxy;
162
163
  exports.createWorkspace = createWorkspace;
package/dist/index.d.cts CHANGED
@@ -104,6 +104,11 @@ declare function addProject(name: string, root?: string): Promise<void>;
104
104
  */
105
105
  declare function listProjects(root?: string): string[];
106
106
 
107
+ /**
108
+ * Set up linting in a project
109
+ */
110
+ declare function setupLint(root?: string, isWorkspace?: boolean): Promise<void>;
111
+
107
112
  /**
108
113
  * Define workspace configuration
109
114
  * Simple helper to get config from a config map
@@ -136,5 +141,5 @@ declare function createWorkspace(options?: WorkspaceOptions): {
136
141
  clearCache(): void;
137
142
  };
138
143
 
139
- export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, writeNetlifyConfig };
144
+ export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, setupLint, writeNetlifyConfig };
140
145
  export type { ProxyConfig, WorkspaceConfig, WorkspaceEnvironment, WorkspaceOptions };
package/dist/index.d.mts CHANGED
@@ -104,6 +104,11 @@ declare function addProject(name: string, root?: string): Promise<void>;
104
104
  */
105
105
  declare function listProjects(root?: string): string[];
106
106
 
107
+ /**
108
+ * Set up linting in a project
109
+ */
110
+ declare function setupLint(root?: string, isWorkspace?: boolean): Promise<void>;
111
+
107
112
  /**
108
113
  * Define workspace configuration
109
114
  * Simple helper to get config from a config map
@@ -136,5 +141,5 @@ declare function createWorkspace(options?: WorkspaceOptions): {
136
141
  clearCache(): void;
137
142
  };
138
143
 
139
- export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, writeNetlifyConfig };
144
+ export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, setupLint, writeNetlifyConfig };
140
145
  export type { ProxyConfig, WorkspaceConfig, WorkspaceEnvironment, WorkspaceOptions };
package/dist/index.d.ts CHANGED
@@ -104,6 +104,11 @@ declare function addProject(name: string, root?: string): Promise<void>;
104
104
  */
105
105
  declare function listProjects(root?: string): string[];
106
106
 
107
+ /**
108
+ * Set up linting in a project
109
+ */
110
+ declare function setupLint(root?: string, isWorkspace?: boolean): Promise<void>;
111
+
107
112
  /**
108
113
  * Define workspace configuration
109
114
  * Simple helper to get config from a config map
@@ -136,5 +141,5 @@ declare function createWorkspace(options?: WorkspaceOptions): {
136
141
  clearCache(): void;
137
142
  };
138
143
 
139
- export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, writeNetlifyConfig };
144
+ export { addProject, createCustomProxy, createViteProxy, createWorkspace, defineWorkspace, generateNetlifyConfig, generateNetlifyRedirect, generateWorkspaceConfig, generateWorkspaceConfigSync, initWorkspace, listProjects, mergeConfigs, resolveConfig, setBuildEnvVars, setupLint, writeNetlifyConfig };
140
145
  export type { ProxyConfig, WorkspaceConfig, WorkspaceEnvironment, WorkspaceOptions };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { resolve, join } from 'node:path';
3
3
  import process from 'node:process';
4
- import { g as generateWorkspaceConfig, s as setBuildEnvVars, w as writeNetlifyConfig } from './shared/workspace.Dq-27S1f.mjs';
5
- export { d as addProject, a as generateNetlifyConfig, b as generateNetlifyRedirect, c as generateWorkspaceConfigSync, i as initWorkspace, l as listProjects } from './shared/workspace.Dq-27S1f.mjs';
4
+ import { g as generateWorkspaceConfig, s as setBuildEnvVars, w as writeNetlifyConfig } from './shared/workspace.cX7U2RUq.mjs';
5
+ export { d as addProject, a as generateNetlifyConfig, b as generateNetlifyRedirect, c as generateWorkspaceConfigSync, i as initWorkspace, l as listProjects, e as setupLint } from './shared/workspace.cX7U2RUq.mjs';
6
6
  import 'prompts';
7
7
 
8
8
  async function resolveConfig(mode = "development", options = {}) {
@@ -564,6 +564,176 @@ function listProjects(root = process__default.cwd()) {
564
564
  }
565
565
  }
566
566
 
567
+ async function setupLint(root = process__default.cwd(), isWorkspace = false) {
568
+ console.log("\n\u{1F50D} Setting up linting...\n");
569
+ const response = await prompts__default([
570
+ {
571
+ type: "multiselect",
572
+ name: "configs",
573
+ message: "Select configurations to set up:",
574
+ choices: [
575
+ { title: "ESLint", value: "eslint", selected: true },
576
+ { title: "Prettier", value: "prettier", selected: true },
577
+ { title: "EditorConfig", value: "editorconfig", selected: true },
578
+ { title: "Git Hooks", value: "githooks", selected: false }
579
+ ]
580
+ },
581
+ {
582
+ type: "confirm",
583
+ name: "installDeps",
584
+ message: "Install dependencies?",
585
+ initial: true
586
+ }
587
+ ]);
588
+ if (!response || !response.configs) {
589
+ console.log("\n\u274C Setup cancelled.\n");
590
+ process__default.exit(1);
591
+ }
592
+ const { configs, installDeps } = response;
593
+ if (configs.includes("eslint")) {
594
+ createEslintConfig(root, isWorkspace);
595
+ }
596
+ if (configs.includes("prettier")) {
597
+ createPrettierConfig(root);
598
+ }
599
+ if (configs.includes("editorconfig")) {
600
+ createEditorConfig(root);
601
+ }
602
+ if (configs.includes("githooks")) {
603
+ createGitHooks(root);
604
+ }
605
+ updatePackageJsonLint(root, configs);
606
+ if (installDeps) {
607
+ console.log("\n\u{1F4E6} Installing dependencies...");
608
+ console.log("Run: bun add -D @bagelink/lint-config eslint prettier typescript");
609
+ }
610
+ console.log("\n\u2705 Linting setup complete!");
611
+ console.log("\nAvailable commands:");
612
+ console.log(" bun run lint - Run linter");
613
+ console.log(" bun run lint:fix - Fix linting issues");
614
+ console.log(" bun run format - Format code with Prettier");
615
+ console.log("");
616
+ }
617
+ function createEslintConfig(root, isWorkspace) {
618
+ const configPath = node_path.resolve(root, "eslint.config.js");
619
+ const config = isWorkspace ? `import { defineConfig } from '@bagelink/lint-config/eslint'
620
+
621
+ export default defineConfig({
622
+ // Workspace-level ESLint config
623
+ ignores: ['**/dist/**', '**/node_modules/**', '**/.bun-cache/**'],
624
+ })
625
+ ` : `import vue3Config from '@bagelink/lint-config/eslint/vue3'
626
+
627
+ export default vue3Config
628
+ `;
629
+ node_fs.writeFileSync(configPath, config);
630
+ console.log("\u2705 Created eslint.config.js");
631
+ }
632
+ function createPrettierConfig(root) {
633
+ const configPath = node_path.resolve(root, ".prettierrc");
634
+ const config = {
635
+ semi: false,
636
+ singleQuote: true,
637
+ tabWidth: 2,
638
+ useTabs: true,
639
+ trailingComma: "all",
640
+ printWidth: 100,
641
+ arrowParens: "avoid"
642
+ };
643
+ node_fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}
644
+ `);
645
+ console.log("\u2705 Created .prettierrc");
646
+ const ignorePath = node_path.resolve(root, ".prettierignore");
647
+ const ignore = `dist
648
+ node_modules
649
+ .bun-cache
650
+ *.min.js
651
+ *.min.css
652
+ `;
653
+ node_fs.writeFileSync(ignorePath, ignore);
654
+ console.log("\u2705 Created .prettierignore");
655
+ }
656
+ function createEditorConfig(root) {
657
+ const configPath = node_path.resolve(root, ".editorconfig");
658
+ const config = `root = true
659
+
660
+ [*]
661
+ charset = utf-8
662
+ indent_style = tab
663
+ indent_size = 2
664
+ end_of_line = lf
665
+ insert_final_newline = true
666
+ trim_trailing_whitespace = true
667
+
668
+ [*.md]
669
+ trim_trailing_whitespace = false
670
+
671
+ [*.{json,yml,yaml}]
672
+ indent_style = space
673
+ indent_size = 2
674
+ `;
675
+ node_fs.writeFileSync(configPath, config);
676
+ console.log("\u2705 Created .editorconfig");
677
+ }
678
+ function createGitHooks(root) {
679
+ const packageJsonPath = node_path.resolve(root, "package.json");
680
+ if (!node_fs.existsSync(packageJsonPath)) {
681
+ console.warn("\u26A0\uFE0F No package.json found, skipping git hooks");
682
+ return;
683
+ }
684
+ const lintStagedConfig = {
685
+ "*.{js,jsx,ts,tsx,vue}": ["eslint --fix"],
686
+ "*.{json,md,yml,yaml}": ["prettier --write"]
687
+ };
688
+ node_fs.writeFileSync(
689
+ node_path.resolve(root, ".lintstagedrc"),
690
+ `${JSON.stringify(lintStagedConfig, null, 2)}
691
+ `
692
+ );
693
+ console.log("\u2705 Created .lintstagedrc");
694
+ console.log("\u2139\uFE0F Add simple-git-hooks and lint-staged to devDependencies");
695
+ console.log(" Then run: npx simple-git-hooks");
696
+ }
697
+ function updatePackageJsonLint(root, configs) {
698
+ const packageJsonPath = node_path.resolve(root, "package.json");
699
+ if (!node_fs.existsSync(packageJsonPath)) {
700
+ console.warn("\u26A0\uFE0F No package.json found");
701
+ return;
702
+ }
703
+ try {
704
+ const packageJson = JSON.parse(
705
+ require("fs").readFileSync(packageJsonPath, "utf-8")
706
+ );
707
+ if (!packageJson.scripts) {
708
+ packageJson.scripts = {};
709
+ }
710
+ if (configs.includes("eslint")) {
711
+ if (!packageJson.scripts.lint) {
712
+ packageJson.scripts.lint = "eslint .";
713
+ }
714
+ if (!packageJson.scripts["lint:fix"]) {
715
+ packageJson.scripts["lint:fix"] = "eslint . --fix";
716
+ }
717
+ }
718
+ if (configs.includes("prettier")) {
719
+ if (!packageJson.scripts.format) {
720
+ packageJson.scripts.format = "prettier --write .";
721
+ }
722
+ if (!packageJson.scripts["format:check"]) {
723
+ packageJson.scripts["format:check"] = "prettier --check .";
724
+ }
725
+ }
726
+ node_fs.writeFileSync(
727
+ packageJsonPath,
728
+ `${JSON.stringify(packageJson, null, 2)}
729
+ `
730
+ );
731
+ console.log("\u2705 Updated package.json with lint scripts");
732
+ } catch (error) {
733
+ console.error("\u274C Failed to update package.json:", error);
734
+ }
735
+ }
736
+
567
737
  exports.addProject = addProject;
568
738
  exports.generateNetlifyConfig = generateNetlifyConfig;
569
739
  exports.generateNetlifyRedirect = generateNetlifyRedirect;
@@ -572,4 +742,5 @@ exports.generateWorkspaceConfigSync = generateWorkspaceConfigSync;
572
742
  exports.initWorkspace = initWorkspace;
573
743
  exports.listProjects = listProjects;
574
744
  exports.setBuildEnvVars = setBuildEnvVars;
745
+ exports.setupLint = setupLint;
575
746
  exports.writeNetlifyConfig = writeNetlifyConfig;
@@ -557,4 +557,174 @@ function listProjects(root = process.cwd()) {
557
557
  }
558
558
  }
559
559
 
560
- export { generateNetlifyConfig as a, generateNetlifyRedirect as b, generateWorkspaceConfigSync as c, addProject as d, generateWorkspaceConfig as g, initWorkspace as i, listProjects as l, setBuildEnvVars as s, writeNetlifyConfig as w };
560
+ async function setupLint(root = process.cwd(), isWorkspace = false) {
561
+ console.log("\n\u{1F50D} Setting up linting...\n");
562
+ const response = await prompts([
563
+ {
564
+ type: "multiselect",
565
+ name: "configs",
566
+ message: "Select configurations to set up:",
567
+ choices: [
568
+ { title: "ESLint", value: "eslint", selected: true },
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
579
+ }
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
+ }
592
+ if (configs.includes("editorconfig")) {
593
+ createEditorConfig(root);
594
+ }
595
+ if (configs.includes("githooks")) {
596
+ createGitHooks(root);
597
+ }
598
+ updatePackageJsonLint(root, configs);
599
+ if (installDeps) {
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;
676
+ }
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
+ }
690
+ function updatePackageJsonLint(root, configs) {
691
+ const packageJsonPath = resolve(root, "package.json");
692
+ if (!existsSync(packageJsonPath)) {
693
+ console.warn("\u26A0\uFE0F No package.json found");
694
+ return;
695
+ }
696
+ try {
697
+ const packageJson = JSON.parse(
698
+ require("fs").readFileSync(packageJsonPath, "utf-8")
699
+ );
700
+ if (!packageJson.scripts) {
701
+ packageJson.scripts = {};
702
+ }
703
+ if (configs.includes("eslint")) {
704
+ if (!packageJson.scripts.lint) {
705
+ packageJson.scripts.lint = "eslint .";
706
+ }
707
+ if (!packageJson.scripts["lint:fix"]) {
708
+ packageJson.scripts["lint:fix"] = "eslint . --fix";
709
+ }
710
+ }
711
+ if (configs.includes("prettier")) {
712
+ if (!packageJson.scripts.format) {
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);
727
+ }
728
+ }
729
+
730
+ export { generateNetlifyConfig as a, generateNetlifyRedirect as b, generateWorkspaceConfigSync as c, addProject as d, setupLint as e, generateWorkspaceConfig as g, initWorkspace as i, listProjects as l, setBuildEnvVars as s, writeNetlifyConfig as w };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/workspace",
3
3
  "type": "module",
4
- "version": "1.8.0",
4
+ "version": "1.9.0",
5
5
  "description": "Monorepo workspace tooling for Bagel projects with proxy and config management",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -52,6 +52,14 @@
52
52
  "dependencies": {
53
53
  "prompts": "^2.4.2"
54
54
  },
55
+ "peerDependencies": {
56
+ "vite": ">=5.0.0"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "@bagelink/lint-config": {
60
+ "optional": true
61
+ }
62
+ },
55
63
  "devDependencies": {
56
64
  "@types/node": "^24.0.0",
57
65
  "@types/prompts": "^2.4.9",
@@ -59,9 +67,6 @@
59
67
  "typescript": "^5.8.3",
60
68
  "unbuild": "^3.5.0"
61
69
  },
62
- "peerDependencies": {
63
- "vite": ">=5.0.0"
64
- },
65
70
  "scripts": {
66
71
  "dev": "unbuild --stub",
67
72
  "build": "unbuild",
package/src/index.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  }
36
36
 
37
37
  export { addProject, initWorkspace, listProjects } from './workspace'
38
+ export { setupLint } from './lint'
38
39
 
39
40
  /**
40
41
  * Define workspace configuration
package/src/lint.ts ADDED
@@ -0,0 +1,235 @@
1
+ import { existsSync, writeFileSync } from 'node:fs'
2
+ import { resolve } from 'node:path'
3
+ import process from 'node:process'
4
+ import prompts from 'prompts'
5
+
6
+ /**
7
+ * Set up linting in a project
8
+ */
9
+ export async function setupLint(
10
+ root: string = process.cwd(),
11
+ isWorkspace: boolean = false,
12
+ ): Promise<void> {
13
+ console.log('\n🔍 Setting up linting...\n')
14
+
15
+ const response = await prompts([
16
+ {
17
+ type: 'multiselect',
18
+ name: 'configs',
19
+ message: 'Select configurations to set up:',
20
+ choices: [
21
+ { title: 'ESLint', value: 'eslint', selected: true },
22
+ { title: 'Prettier', value: 'prettier', selected: true },
23
+ { title: 'EditorConfig', value: 'editorconfig', selected: true },
24
+ { title: 'Git Hooks', value: 'githooks', selected: false },
25
+ ],
26
+ },
27
+ {
28
+ type: 'confirm',
29
+ name: 'installDeps',
30
+ message: 'Install dependencies?',
31
+ initial: true,
32
+ },
33
+ ])
34
+
35
+ if (!response || !response.configs) {
36
+ console.log('\n❌ Setup cancelled.\n')
37
+ process.exit(1)
38
+ }
39
+
40
+ const { configs, installDeps } = response
41
+
42
+ // Create config files
43
+ if (configs.includes('eslint')) {
44
+ createEslintConfig(root, isWorkspace)
45
+ }
46
+
47
+ if (configs.includes('prettier')) {
48
+ createPrettierConfig(root)
49
+ }
50
+
51
+ if (configs.includes('editorconfig')) {
52
+ createEditorConfig(root)
53
+ }
54
+
55
+ if (configs.includes('githooks')) {
56
+ createGitHooks(root)
57
+ }
58
+
59
+ // Update package.json
60
+ updatePackageJsonLint(root, configs)
61
+
62
+ if (installDeps) {
63
+ console.log('\n📦 Installing dependencies...')
64
+ console.log('Run: bun add -D @bagelink/lint-config eslint prettier typescript')
65
+ }
66
+
67
+ console.log('\n✅ Linting setup complete!')
68
+ console.log('\nAvailable commands:')
69
+ console.log(' bun run lint - Run linter')
70
+ console.log(' bun run lint:fix - Fix linting issues')
71
+ console.log(' bun run format - Format code with Prettier')
72
+ console.log('')
73
+ }
74
+
75
+ /**
76
+ * Create ESLint config
77
+ */
78
+ function createEslintConfig(root: string, isWorkspace: boolean): void {
79
+ const configPath = resolve(root, 'eslint.config.js')
80
+
81
+ const config = isWorkspace
82
+ ? `import { defineConfig } from '@bagelink/lint-config/eslint'
83
+
84
+ export default defineConfig({
85
+ // Workspace-level ESLint config
86
+ ignores: ['**/dist/**', '**/node_modules/**', '**/.bun-cache/**'],
87
+ })
88
+ `
89
+ : `import vue3Config from '@bagelink/lint-config/eslint/vue3'
90
+
91
+ export default vue3Config
92
+ `
93
+
94
+ writeFileSync(configPath, config)
95
+ console.log('✅ Created eslint.config.js')
96
+ }
97
+
98
+ /**
99
+ * Create Prettier config
100
+ */
101
+ function createPrettierConfig(root: string): void {
102
+ const configPath = resolve(root, '.prettierrc')
103
+
104
+ const config = {
105
+ semi: false,
106
+ singleQuote: true,
107
+ tabWidth: 2,
108
+ useTabs: true,
109
+ trailingComma: 'all',
110
+ printWidth: 100,
111
+ arrowParens: 'avoid',
112
+ }
113
+
114
+ writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`)
115
+ console.log('✅ Created .prettierrc')
116
+
117
+ // .prettierignore
118
+ const ignorePath = resolve(root, '.prettierignore')
119
+ const ignore = `dist
120
+ node_modules
121
+ .bun-cache
122
+ *.min.js
123
+ *.min.css
124
+ `
125
+
126
+ writeFileSync(ignorePath, ignore)
127
+ console.log('✅ Created .prettierignore')
128
+ }
129
+
130
+ /**
131
+ * Create EditorConfig
132
+ */
133
+ function createEditorConfig(root: string): void {
134
+ const configPath = resolve(root, '.editorconfig')
135
+
136
+ const config = `root = true
137
+
138
+ [*]
139
+ charset = utf-8
140
+ indent_style = tab
141
+ indent_size = 2
142
+ end_of_line = lf
143
+ insert_final_newline = true
144
+ trim_trailing_whitespace = true
145
+
146
+ [*.md]
147
+ trim_trailing_whitespace = false
148
+
149
+ [*.{json,yml,yaml}]
150
+ indent_style = space
151
+ indent_size = 2
152
+ `
153
+
154
+ writeFileSync(configPath, config)
155
+ console.log('✅ Created .editorconfig')
156
+ }
157
+
158
+ /**
159
+ * Create Git Hooks
160
+ */
161
+ function createGitHooks(root: string): void {
162
+ const packageJsonPath = resolve(root, 'package.json')
163
+
164
+ if (!existsSync(packageJsonPath)) {
165
+ console.warn('⚠️ No package.json found, skipping git hooks')
166
+ return
167
+ }
168
+
169
+ // .lintstagedrc
170
+ const lintStagedConfig = {
171
+ '*.{js,jsx,ts,tsx,vue}': ['eslint --fix'],
172
+ '*.{json,md,yml,yaml}': ['prettier --write'],
173
+ }
174
+
175
+ writeFileSync(
176
+ resolve(root, '.lintstagedrc'),
177
+ `${JSON.stringify(lintStagedConfig, null, 2)}\n`,
178
+ )
179
+
180
+ console.log('✅ Created .lintstagedrc')
181
+ console.log('ℹ️ Add simple-git-hooks and lint-staged to devDependencies')
182
+ console.log(' Then run: npx simple-git-hooks')
183
+ }
184
+
185
+ /**
186
+ * Update package.json with lint scripts
187
+ */
188
+ function updatePackageJsonLint(root: string, configs: string[]): void {
189
+ const packageJsonPath = resolve(root, 'package.json')
190
+
191
+ if (!existsSync(packageJsonPath)) {
192
+ console.warn('⚠️ No package.json found')
193
+ return
194
+ }
195
+
196
+ try {
197
+ const packageJson = JSON.parse(
198
+ require('fs').readFileSync(packageJsonPath, 'utf-8'),
199
+ )
200
+
201
+ if (!packageJson.scripts) {
202
+ packageJson.scripts = {}
203
+ }
204
+
205
+ // Add lint scripts
206
+ if (configs.includes('eslint')) {
207
+ if (!packageJson.scripts.lint) {
208
+ packageJson.scripts.lint = 'eslint .'
209
+ }
210
+ if (!packageJson.scripts['lint:fix']) {
211
+ packageJson.scripts['lint:fix'] = 'eslint . --fix'
212
+ }
213
+ }
214
+
215
+ // Add format scripts
216
+ if (configs.includes('prettier')) {
217
+ if (!packageJson.scripts.format) {
218
+ packageJson.scripts.format = 'prettier --write .'
219
+ }
220
+ if (!packageJson.scripts['format:check']) {
221
+ packageJson.scripts['format:check'] = 'prettier --check .'
222
+ }
223
+ }
224
+
225
+ writeFileSync(
226
+ packageJsonPath,
227
+ `${JSON.stringify(packageJson, null, 2)}\n`,
228
+ )
229
+
230
+ console.log('✅ Updated package.json with lint scripts')
231
+ }
232
+ catch (error) {
233
+ console.error('❌ Failed to update package.json:', error)
234
+ }
235
+ }