@bagelink/workspace 1.9.0 → 1.9.2

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.
Files changed (43) hide show
  1. package/README.md +309 -12
  2. package/bin/bgl.ts +153 -16
  3. package/dist/bin/bgl.cjs +898 -22
  4. package/dist/bin/bgl.mjs +894 -19
  5. package/dist/composable.cjs +22 -0
  6. package/dist/composable.d.cts +52 -0
  7. package/dist/composable.d.mts +52 -0
  8. package/dist/composable.d.ts +52 -0
  9. package/dist/composable.mjs +19 -0
  10. package/dist/index.cjs +3 -156
  11. package/dist/index.d.cts +4 -138
  12. package/dist/index.d.mts +4 -138
  13. package/dist/index.d.ts +4 -138
  14. package/dist/index.mjs +2 -139
  15. package/dist/shared/workspace.Bc_dpzhA.mjs +500 -0
  16. package/dist/shared/workspace.BzlV5kcN.d.cts +50 -0
  17. package/dist/shared/workspace.BzlV5kcN.d.mts +50 -0
  18. package/dist/shared/workspace.BzlV5kcN.d.ts +50 -0
  19. package/dist/shared/workspace.DRlDHdPw.cjs +512 -0
  20. package/dist/vite.cjs +131 -0
  21. package/dist/vite.d.cts +98 -0
  22. package/dist/vite.d.mts +98 -0
  23. package/dist/vite.d.ts +98 -0
  24. package/dist/vite.mjs +121 -0
  25. package/env.d.ts +30 -0
  26. package/package.json +20 -2
  27. package/src/build.ts +45 -0
  28. package/src/composable.ts +70 -0
  29. package/src/detect.ts +90 -0
  30. package/src/dev.ts +171 -0
  31. package/src/index.ts +4 -76
  32. package/src/init.ts +72 -14
  33. package/src/lint.ts +91 -3
  34. package/src/netlify.ts +54 -3
  35. package/src/proxy.ts +23 -3
  36. package/src/sdk.ts +211 -0
  37. package/src/types.ts +10 -4
  38. package/src/vite.ts +163 -0
  39. package/src/workspace.ts +132 -26
  40. package/templates/dev-runner.ts +61 -0
  41. package/templates/tsconfig.app.json +23 -0
  42. package/dist/shared/workspace.CCUm_5GG.cjs +0 -746
  43. package/dist/shared/workspace.cX7U2RUq.mjs +0 -730
package/README.md CHANGED
@@ -57,10 +57,15 @@ Create `bgl.config.ts`:
57
57
  import { defineWorkspace } from '@bagelink/workspace'
58
58
  import type { WorkspaceConfig, WorkspaceEnvironment } from '@bagelink/workspace'
59
59
 
60
+ /**
61
+ * Define your workspace environments
62
+ * You can add as many custom environments as needed (e.g., 'staging', 'preview')
63
+ * Use --mode flag to switch: bgl dev --mode <env_name>
64
+ */
60
65
  const configs: Record<WorkspaceEnvironment, WorkspaceConfig> = {
61
66
  localhost: {
62
67
  host: 'http://localhost:8000',
63
- proxy: '/api',
68
+ proxy: '/api', // Optional: remove to skip proxy setup
64
69
  openapi_url: 'http://localhost:8000/openapi.json',
65
70
  },
66
71
  development: {
@@ -72,6 +77,11 @@ const configs: Record<WorkspaceEnvironment, WorkspaceConfig> = {
72
77
  host: 'https://project.bagel.to',
73
78
  proxy: '/api',
74
79
  },
80
+ // Add your own custom environments
81
+ staging: {
82
+ host: 'https://staging.project.bagel.to',
83
+ proxy: '/api',
84
+ },
75
85
  }
76
86
 
77
87
  export default defineWorkspace(configs)
@@ -79,7 +89,66 @@ export default defineWorkspace(configs)
79
89
 
80
90
  ## Usage
81
91
 
82
- ### 1. Configure Vite (`vite.config.ts`)
92
+ ### 1. Add Type Definitions
93
+
94
+ Add to your project's `env.d.ts`:
95
+
96
+ ```typescript
97
+ /// <reference types="@bagelink/workspace/env" />
98
+ ```
99
+
100
+ This provides TypeScript types for injected environment variables.
101
+
102
+ ### 2. Configure Vite (`vite.config.ts`)
103
+
104
+ **Recommended: Use the Vite plugin (keeps your config clean and standard)**
105
+
106
+ ```typescript
107
+ import { defineConfig } from 'vite'
108
+ import vue from '@vitejs/plugin-vue'
109
+ import { bagelink } from '@bagelink/workspace/vite'
110
+ import workspace from './bgl.config'
111
+
112
+ export default defineConfig({
113
+ plugins: [
114
+ vue(),
115
+ bagelink({ workspace }),
116
+ ],
117
+ })
118
+ ```
119
+
120
+ The plugin automatically:
121
+ - Configures proxy based on `bgl.config.ts`
122
+ - Sets up `@` alias pointing to `./src`
123
+ - Sets up `@shared` alias (in monorepos)
124
+ - Keeps your vite.config.ts clean and extensible
125
+
126
+ **Advanced: Custom options**
127
+
128
+ ```typescript
129
+ import { defineConfig } from 'vite'
130
+ import vue from '@vitejs/plugin-vue'
131
+ import { bagelink } from '@bagelink/workspace/vite'
132
+ import { fileURLToPath } from 'node:url'
133
+ import workspace from './bgl.config'
134
+
135
+ export default defineConfig({
136
+ plugins: [
137
+ vue(),
138
+ bagelink({
139
+ workspace,
140
+ config: {
141
+ sharedPath: '../packages/shared',
142
+ additionalAliases: {
143
+ '@utils': fileURLToPath(new URL('./src/utils', import.meta.url))
144
+ }
145
+ }
146
+ }),
147
+ ],
148
+ })
149
+ ```
150
+
151
+ **Legacy: Manual proxy setup**
83
152
 
84
153
  ```typescript
85
154
  import { defineConfig } from 'vite'
@@ -98,19 +167,104 @@ export default defineConfig(({ mode }) => {
98
167
  })
99
168
  ```
100
169
 
101
- ### 2. Add scripts to `package.json`
170
+ ### 3. Use Configuration in Your App
171
+
172
+ **Access config at runtime with `useWorkspace()`:**
173
+
174
+ ```typescript
175
+ import { useWorkspace, getApiUrl } from '@bagelink/workspace'
176
+
177
+ // In your app setup
178
+ const { baseURL, proxy, host, mode } = useWorkspace()
179
+ const auth = createAuth({ baseURL }) // Uses proxy if available, otherwise host
180
+
181
+ // Or get full API URL
182
+ const apiUrl = getApiUrl() // 'https://project.bagel.to/api'
183
+ ```
184
+
185
+ **Vue component example:**
186
+
187
+ ```vue
188
+ <script setup lang="ts">
189
+ import { useWorkspace } from '@bagelink/workspace'
190
+ import { createAuth } from '@bagelink/auth'
191
+
192
+ const { baseURL, proxy, host, mode } = useWorkspace()
193
+ const auth = createAuth({ baseURL }) // Uses proxy if available, otherwise host
194
+
195
+ console.log('API Host:', host)
196
+ console.log('Environment:', mode)
197
+ </script>
198
+ ```
199
+
200
+ **Access raw environment variables:**
201
+
202
+ ```typescript
203
+ // These are injected at build time by the bagelink plugin
204
+ const proxy = import.meta.env.VITE_BGL_PROXY // '/api'
205
+ const host = import.meta.env.VITE_BGL_HOST // 'https://project.bagel.to'
206
+ const openapi = import.meta.env.VITE_BGL_OPENAPI_URL // optional
207
+ ```
208
+
209
+ ### 4. Add scripts to `package.json`
102
210
 
103
211
  ```json
104
212
  {
105
213
  "scripts": {
106
214
  "dev": "vite",
107
215
  "dev:local": "vite --mode localhost",
108
- "build": "vite build"
216
+ "dev:staging": "vite --mode staging",
217
+ "build": "vite build",
218
+ "build:staging": "vite build --mode staging"
109
219
  }
110
220
  }
111
221
  ```
112
222
 
113
- ### 3. Generate Netlify Config
223
+ ### 5. Custom Environments
224
+
225
+ You can define as many custom environments as you need. The environment name is completely flexible:
226
+
227
+ ```typescript
228
+ const configs: Record<WorkspaceEnvironment, WorkspaceConfig> = {
229
+ localhost: {
230
+ host: 'http://localhost:8000',
231
+ proxy: '/api',
232
+ },
233
+ development: {
234
+ host: 'https://dev.project.bagel.to',
235
+ proxy: '/api',
236
+ },
237
+ staging: {
238
+ host: 'https://staging.project.bagel.to',
239
+ proxy: '/api',
240
+ },
241
+ preview: {
242
+ host: 'https://preview.project.bagel.to',
243
+ // No proxy - will use host directly
244
+ },
245
+ production: {
246
+ host: 'https://project.bagel.to',
247
+ proxy: '/api',
248
+ },
249
+ }
250
+ ```
251
+
252
+ Use the `--mode` flag to switch environments:
253
+
254
+ ```bash
255
+ # Development
256
+ bgl dev --mode development
257
+
258
+ # Staging
259
+ bgl dev --mode staging
260
+
261
+ # Production build
262
+ bgl build --mode production
263
+ ```
264
+
265
+ **Note:** The `proxy` field is optional. If omitted, no proxy will be configured for that environment, and `baseURL` from `useWorkspace()` will return the `host` value instead.
266
+
267
+ ### 6. Generate Netlify Config
114
268
 
115
269
  ```typescript
116
270
  import { writeNetlifyConfig } from '@bagelink/workspace'
@@ -304,12 +458,104 @@ bgl lint init
304
458
  - `bun run format` - Format code
305
459
  - `bun run format:check` - Check formatting
306
460
 
307
- **For workspace:**
461
+ **Auto-detects workspace:**
308
462
  ```bash
309
- bgl lint init --workspace
463
+ # In workspace root (auto-detected)
464
+ bgl lint init
465
+ ✓ Detected workspace mode
466
+ # Sets up at workspace root
467
+
468
+ # In single project (auto-detected)
469
+ bgl lint init
470
+ # Sets up in current project
471
+
472
+ # Force modes:
473
+ bgl lint init --workspace # Force workspace mode
474
+ bgl lint init --project # Force single project mode
310
475
  ```
311
476
 
312
- Sets up linting at workspace root level for all projects.
477
+ **Workspace detection:**
478
+ - Checks for `workspaces` field in package.json
479
+ - Checks for multiple project directories
480
+ - Auto-applies best mode
481
+
482
+ ### SDK Generation
483
+
484
+ #### `bgl sdk generate`
485
+
486
+ Generate TypeScript SDK from OpenAPI specification:
487
+
488
+ ```bash
489
+ bgl sdk generate
490
+
491
+ ? OpenAPI spec URL: › http://localhost:8000/openapi.json
492
+ ? Output directory: › ./src/api
493
+ ? Split into organized files? › Yes
494
+
495
+ 📡 Fetching OpenAPI spec from: http://localhost:8000/openapi.json
496
+ 📁 Output directory: ./src/api
497
+
498
+ ✅ Generated types.d.ts
499
+ ✅ Generated api.ts
500
+ ✅ Generated index.ts
501
+ 🔀 Splitting into organized files...
502
+ ✅ Files organized into directories
503
+
504
+ ✅ SDK generated successfully!
505
+
506
+ Import it in your code:
507
+ import { api } from './api'
508
+ ```
509
+
510
+ **Features:**
511
+ - Auto-reads `openapi_url` from `bgl.config.ts`
512
+ - Generates TypeScript types from OpenAPI schema
513
+ - Creates type-safe API client
514
+ - Optional file organization (split by endpoints)
515
+ - Works with both local and remote OpenAPI specs
516
+
517
+ **Auto-detects workspace:**
518
+ ```bash
519
+ # In workspace root (auto-detected)
520
+ bgl sdk generate
521
+ ✓ Detected workspace mode - will generate for multiple projects
522
+
523
+ ? Select projects to generate SDK for:
524
+ ✔ admin
525
+ ✔ customer
526
+ ✔ mobile
527
+
528
+ # In single project (auto-detected)
529
+ bgl sdk generate
530
+ # Generates SDK for current project only
531
+
532
+ # Force modes:
533
+ bgl sdk generate --workspace # Force workspace mode
534
+ bgl sdk generate --project # Force single project mode
535
+ ```
536
+
537
+ **Smart behavior:**
538
+ - Auto-detects workspace structure
539
+ - Prompts for project selection in workspace mode
540
+ - Reads `openapi_url` from each project's `bgl.config.ts`
541
+
542
+ **Generated structure:**
543
+ ```
544
+ src/api/
545
+ ├── index.ts # Main export
546
+ ├── types.d.ts # TypeScript types
547
+ └── api.ts # API client
548
+
549
+ # Or with --split:
550
+ src/api/
551
+ ├── endpoints/
552
+ │ ├── users.ts
553
+ │ ├── auth.ts
554
+ │ └── data.ts
555
+ ├── types/
556
+ │ └── index.ts
557
+ └── index.ts
558
+ ```
313
559
 
314
560
  ### `npx bgl --help`
315
561
 
@@ -317,7 +563,42 @@ Show CLI help.
317
563
 
318
564
  ## API
319
565
 
320
- ### `defineWorkspace(configs)`
566
+ ### Runtime Functions
567
+
568
+ #### `useWorkspace()`
569
+
570
+ Get workspace configuration at runtime. Config is injected as environment variables during build.
571
+
572
+ ```typescript
573
+ import { useWorkspace } from '@bagelink/workspace'
574
+
575
+ const { baseURL, proxy, host, openapiUrl, mode } = useWorkspace()
576
+ ```
577
+
578
+ **Returns:**
579
+ ```typescript
580
+ interface RuntimeWorkspaceConfig {
581
+ baseURL: string // proxy if available, otherwise host
582
+ proxy?: string // '/api' (optional)
583
+ host: string // 'https://project.bagel.to'
584
+ openapiUrl?: string // optional
585
+ mode: string // current environment (e.g., 'localhost', 'development', 'staging')
586
+ }
587
+ ```
588
+
589
+ #### `getApiUrl()`
590
+
591
+ Get the full API URL by combining host and proxy.
592
+
593
+ ```typescript
594
+ import { getApiUrl } from '@bagelink/workspace'
595
+
596
+ const apiUrl = getApiUrl() // 'https://project.bagel.to/api'
597
+ ```
598
+
599
+ ### Configuration Functions
600
+
601
+ #### `defineWorkspace(configs)`
321
602
 
322
603
  Define workspace configuration for all environments.
323
604
 
@@ -356,21 +637,37 @@ const proxy = workspace.createProxy(config)
356
637
  workspace.generateNetlify(config, './netlify.toml')
357
638
  ```
358
639
 
359
- ### `createViteProxy(config)`
640
+ ### Build-Time Functions
641
+
642
+ These are available from `@bagelink/workspace/vite`:
643
+
644
+ #### `createViteProxy(config)`
360
645
 
361
646
  Generate Vite proxy configuration.
362
647
 
363
- ### `writeNetlifyConfig(config, outPath?, additionalConfig?)`
648
+ ```typescript
649
+ import { createViteProxy } from '@bagelink/workspace/vite'
650
+ ```
651
+
652
+ #### `writeNetlifyConfig(config, outPath?, additionalConfig?)`
364
653
 
365
654
  Generate and write netlify.toml file.
366
655
 
367
- ### `setBuildEnvVars(config)`
656
+ ```typescript
657
+ import { writeNetlifyConfig } from '@bagelink/workspace/vite'
658
+ ```
659
+
660
+ #### `setBuildEnvVars(config)`
368
661
 
369
662
  Set environment variables for build process:
370
663
  - `BGL_PROXY_PATH` - Proxy path (e.g., `/api`)
371
664
  - `BGL_API_HOST` - API host URL
372
665
  - `BGL_OPENAPI_URL` - OpenAPI specification URL
373
666
 
667
+ ```typescript
668
+ import { setBuildEnvVars } from '@bagelink/workspace/vite'
669
+ ```
670
+
374
671
  ## License
375
672
 
376
673
  MIT © Bagel Studio
package/bin/bgl.ts CHANGED
@@ -1,23 +1,41 @@
1
1
  #!/usr/bin/env node
2
+ import { resolve } from 'node:path'
2
3
  import process from 'node:process'
4
+ import { runBuild } from '../src/build.js'
5
+ import { isWorkspace } from '../src/detect.js'
6
+ import { runDev } from '../src/dev.js'
3
7
  import { generateWorkspaceConfig } from '../src/init.js'
4
- import { addProject, initWorkspace, listProjects } from '../src/workspace.js'
5
8
  import { setupLint } from '../src/lint.js'
9
+ import { generateSDK, generateSDKForWorkspace } from '../src/sdk.js'
10
+ import { addProject, initWorkspace, listProjects } from '../src/workspace.js'
6
11
 
7
12
  const [,, command, subcommand, ...args] = process.argv
8
13
 
9
14
  async function main() {
10
15
  if (command === 'init') {
11
- const isWorkspace = args.includes('--workspace') || args.includes('-w')
12
- if (isWorkspace) {
16
+ // Check both subcommand and args for --workspace flag
17
+ const createWorkspace
18
+ = subcommand === '--workspace'
19
+ || subcommand === '-w'
20
+ || args.includes('--workspace')
21
+ || args.includes('-w')
22
+
23
+ // Support 'bgl init .' or 'bgl init <path>'
24
+ let targetPath = process.cwd()
25
+ if (subcommand && !subcommand.startsWith('-')) {
26
+ // If subcommand is not a flag, treat it as a path
27
+ targetPath = subcommand === '.' ? process.cwd() : resolve(process.cwd(), subcommand)
28
+ }
29
+
30
+ if (createWorkspace) {
13
31
  await initWorkspace()
14
32
  }
15
33
  else {
16
- await generateWorkspaceConfig()
34
+ await generateWorkspaceConfig(targetPath)
17
35
  }
18
36
  }
19
37
  else if (command === 'add') {
20
- const projectName = args[0]
38
+ const projectName = subcommand // 'bgl add admin' -> subcommand is 'admin'
21
39
  if (!projectName) {
22
40
  console.error('Error: Project name is required')
23
41
  console.log('Usage: bgl add <project-name>')
@@ -32,43 +50,162 @@ async function main() {
32
50
  }
33
51
  else {
34
52
  console.log('\nProjects:')
35
- projects.forEach(p => console.log(` - ${p}`))
53
+ projects.forEach((p) => { console.log(` - ${p}`) })
36
54
  console.log('')
37
55
  }
38
56
  }
39
57
  else if (command === 'lint') {
40
58
  if (subcommand === 'init') {
41
- const isWorkspace = args.includes('--workspace') || args.includes('-w')
42
- await setupLint(process.cwd(), isWorkspace)
59
+ // Auto-detect workspace or allow override
60
+ const forceWorkspace = args.includes('--workspace') || args.includes('-w')
61
+ const forceProject = args.includes('--project') || args.includes('-p')
62
+
63
+ let workspaceMode = isWorkspace(process.cwd())
64
+ if (forceWorkspace) workspaceMode = true
65
+ if (forceProject) workspaceMode = false
66
+
67
+ if (workspaceMode) {
68
+ console.log('✓ Detected workspace mode')
69
+ }
70
+
71
+ await setupLint(process.cwd(), workspaceMode)
43
72
  }
44
73
  else {
45
74
  console.log(`
46
75
  Lint Commands:
47
- bgl lint init Set up linting in current project
48
- bgl lint init --workspace Set up linting for workspace root
76
+ bgl lint init Set up linting (auto-detects workspace)
77
+ bgl lint init --workspace Force workspace mode
78
+ bgl lint init --project Force single project mode
79
+ `)
80
+ process.exit(1)
81
+ }
82
+ }
83
+ else if (command === 'sdk') {
84
+ if (subcommand === 'generate') {
85
+ // Auto-detect workspace or allow override
86
+ const forceWorkspace = args.includes('--workspace') || args.includes('-w')
87
+ const forceProject = args.includes('--project') || args.includes('-p')
88
+
89
+ let workspaceMode = isWorkspace(process.cwd())
90
+ if (forceWorkspace) workspaceMode = true
91
+ if (forceProject) workspaceMode = false
92
+
93
+ if (workspaceMode) {
94
+ console.log('✓ Detected workspace mode - will generate for multiple projects')
95
+ await generateSDKForWorkspace()
96
+ }
97
+ else {
98
+ await generateSDK(process.cwd())
99
+ }
100
+ }
101
+ else {
102
+ console.log(`
103
+ SDK Commands:
104
+ bgl sdk generate Generate SDK (auto-detects workspace)
105
+ bgl sdk generate --workspace Force workspace mode
106
+ bgl sdk generate --project Force single project mode
49
107
  `)
50
108
  process.exit(1)
51
109
  }
52
110
  }
111
+ else if (command === 'dev') {
112
+ const { filter, additionalArgs } = parseFilterArgs(
113
+ undefined,
114
+ subcommand,
115
+ args,
116
+ )
117
+ const exitCode = await runDev(filter, additionalArgs)
118
+ process.exit(exitCode)
119
+ }
120
+ else if (command === 'build') {
121
+ const { filter, additionalArgs } = parseFilterArgs(
122
+ undefined,
123
+ subcommand,
124
+ args,
125
+ )
126
+ const exitCode = await runBuild(filter, additionalArgs)
127
+ process.exit(exitCode)
128
+ }
53
129
  else {
54
130
  console.log(`
55
131
  Bagel Workspace CLI
56
132
 
57
133
  Usage:
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
134
+ bgl init [path] Generate bgl.config.ts for single project
135
+ Examples: bgl init, bgl init ., bgl init ./my-app
136
+ bgl init --workspace Create a new workspace with multiple projects
137
+ bgl add <name> Add a new project to workspace
138
+ bgl list List all projects in workspace
139
+ bgl dev [filter] [...args] Run dev servers with clean output (default: './!shared*')
140
+ Examples:
141
+ bgl dev --mode localhost
142
+ bgl dev --mode staging
143
+ bgl dev admin --mode production
144
+ bgl build [project] [...args] Build project by directory (default: all projects)
145
+ Example: bgl build --mode production
146
+ bgl lint init Set up linting (auto-detects workspace)
147
+ bgl sdk generate Generate SDK (auto-detects workspace)
64
148
 
65
149
  Options:
150
+ --workspace, -w Force workspace mode
151
+ --project, -p Force single project mode
152
+ --mode <env> Set environment (matches bgl.config.ts keys)
66
153
  --help, -h Show this help message
154
+
155
+ Note: Commands auto-detect workspace mode based on directory structure
67
156
  `)
68
157
  process.exit(command === '--help' || command === '-h' ? 0 : 1)
69
158
  }
70
159
  }
71
160
 
161
+ function normalizeFilter(input: string): string {
162
+ // Keep glob patterns as-is, otherwise ensure ./ prefix
163
+ if (input.startsWith('.') || input.includes('*') || input.includes('[')) {
164
+ return input
165
+ }
166
+ return `./${input}`
167
+ }
168
+
169
+ function parseFilterArgs(
170
+ defaultFilter: string | undefined,
171
+ subcommandArg?: string,
172
+ argsList: string[] = [],
173
+ ): { filter?: string, additionalArgs: string[] } {
174
+ const tokens = [subcommandArg, ...argsList].filter(Boolean) as string[]
175
+
176
+ // Flags that take values
177
+ const flagsWithValues = new Set(['--mode', '--host', '--port'])
178
+
179
+ // Find non-flag tokens (excluding flag values)
180
+ const nonFlagIndexes: number[] = []
181
+ for (let i = 0; i < tokens.length; i++) {
182
+ const token = tokens[i]
183
+ if (token.startsWith('-')) {
184
+ // If this flag takes a value, skip the next token
185
+ if (flagsWithValues.has(token)) {
186
+ i++ // Skip next token (the value)
187
+ }
188
+ } else {
189
+ // Not a flag and not a flag value
190
+ const prevToken = i > 0 ? tokens[i - 1] : null
191
+ if (!prevToken || !flagsWithValues.has(prevToken)) {
192
+ nonFlagIndexes.push(i)
193
+ }
194
+ }
195
+ }
196
+
197
+ const filterIndex = nonFlagIndexes.length > 0
198
+ ? nonFlagIndexes[nonFlagIndexes.length - 1]
199
+ : -1
200
+ const filter = filterIndex >= 0
201
+ ? normalizeFilter(tokens[filterIndex])
202
+ : defaultFilter
203
+ const additionalArgs = filterIndex >= 0
204
+ ? tokens.filter((_, index) => index !== filterIndex)
205
+ : tokens
206
+ return { filter, additionalArgs }
207
+ }
208
+
72
209
  main().catch((error: unknown) => {
73
210
  console.error('Error:', error)
74
211
  process.exit(1)