@noego/stitch 1.0.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.
Files changed (60) hide show
  1. package/README-schema.md +139 -0
  2. package/bin/stitch.js +156 -0
  3. package/dist/browser/index.d.ts +4 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/cli/StitchCLI.d.ts +12 -0
  6. package/dist/cli/StitchCLI.d.ts.map +1 -0
  7. package/dist/client.cjs +2 -0
  8. package/dist/client.cjs.map +1 -0
  9. package/dist/client.mjs +83 -0
  10. package/dist/client.mjs.map +1 -0
  11. package/dist/core/ConfigParser.d.ts +16 -0
  12. package/dist/core/ConfigParser.d.ts.map +1 -0
  13. package/dist/core/StitchEngine.d.ts +31 -0
  14. package/dist/core/StitchEngine.d.ts.map +1 -0
  15. package/dist/core/Validator.d.ts +18 -0
  16. package/dist/core/Validator.d.ts.map +1 -0
  17. package/dist/core/ViteHelper.d.ts +33 -0
  18. package/dist/core/ViteHelper.d.ts.map +1 -0
  19. package/dist/core/YamlMerger.d.ts +29 -0
  20. package/dist/core/YamlMerger.d.ts.map +1 -0
  21. package/dist/core/YamlMergerBrowser.d.ts +18 -0
  22. package/dist/core/YamlMergerBrowser.d.ts.map +1 -0
  23. package/dist/index.d.ts +15 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/types/StitchTypes.d.ts +38 -0
  26. package/dist/types/StitchTypes.d.ts.map +1 -0
  27. package/dist-ssr/browser/index.d.ts +4 -0
  28. package/dist-ssr/browser/index.d.ts.map +1 -0
  29. package/dist-ssr/cli/StitchCLI.d.ts +12 -0
  30. package/dist-ssr/cli/StitchCLI.d.ts.map +1 -0
  31. package/dist-ssr/core/ConfigParser.d.ts +16 -0
  32. package/dist-ssr/core/ConfigParser.d.ts.map +1 -0
  33. package/dist-ssr/core/StitchEngine.d.ts +31 -0
  34. package/dist-ssr/core/StitchEngine.d.ts.map +1 -0
  35. package/dist-ssr/core/Validator.d.ts +18 -0
  36. package/dist-ssr/core/Validator.d.ts.map +1 -0
  37. package/dist-ssr/core/ViteHelper.d.ts +33 -0
  38. package/dist-ssr/core/ViteHelper.d.ts.map +1 -0
  39. package/dist-ssr/core/YamlMerger.d.ts +29 -0
  40. package/dist-ssr/core/YamlMerger.d.ts.map +1 -0
  41. package/dist-ssr/core/YamlMergerBrowser.d.ts +18 -0
  42. package/dist-ssr/core/YamlMergerBrowser.d.ts.map +1 -0
  43. package/dist-ssr/index.d.ts +15 -0
  44. package/dist-ssr/index.d.ts.map +1 -0
  45. package/dist-ssr/server.cjs +574 -0
  46. package/dist-ssr/server.cjs.map +1 -0
  47. package/dist-ssr/server.d.ts +2 -0
  48. package/dist-ssr/server.js +554 -0
  49. package/dist-ssr/server.js.map +1 -0
  50. package/dist-ssr/types/StitchTypes.d.ts +38 -0
  51. package/dist-ssr/types/StitchTypes.d.ts.map +1 -0
  52. package/docs/advanced_validation.md +188 -0
  53. package/docs/middleware.md +507 -0
  54. package/docs/modules.md +175 -0
  55. package/docs/project.md +856 -0
  56. package/docs/validation.md +77 -0
  57. package/package.json +67 -0
  58. package/readme.md +159 -0
  59. package/schemas/schema.json +360 -0
  60. package/schemas/stitch-schema.json +38 -0
@@ -0,0 +1,856 @@
1
+ # Stitch Project Plan: YAML Modularization for Groom Application
2
+
3
+ ## Problem Statement
4
+
5
+ The Groom barber shop application has grown to use large OpenAPI YAML files that are becoming difficult to maintain:
6
+
7
+ - **Backend OpenAPI**: `/Users/shavauhngabay/dev/groom/backend/openapi.yaml` (1,511 lines)
8
+ - **Frontend OpenAPI**: `/Users/shavauhngabay/dev/groom/frontend/openapi.yaml` (466 lines)
9
+
10
+ These monolithic files contain:
11
+ - **Backend**: API endpoint definitions with controllers, middleware, and schemas
12
+ - **Frontend**: Route definitions with Svelte views and layouts for the Forge framework
13
+
14
+ As the application grows, these files will become increasingly unwieldy and difficult to collaborate on.
15
+
16
+ ## Current Architecture Analysis
17
+
18
+ ### Backend (`/groom/backend/`)
19
+ - Uses `@noego/dinner` framework for API routing
20
+ - OpenAPI file defines REST endpoints with custom extensions:
21
+ - `x-controller`: Points to controller classes
22
+ - `x-action`: Specifies controller methods
23
+ - `x-middleware`: Defines middleware chains
24
+ - File structure includes paths, components/schemas, and security definitions
25
+ - Consumed by dinner framework for automatic route generation
26
+
27
+ ### Frontend (`/groom/frontend/`)
28
+ - Uses `@noego/forge` framework for SSR/client-side routing
29
+ - OpenAPI file defines page routes with custom extensions:
30
+ - `x-view`: Specifies Svelte component to render
31
+ - `x-layout`: Defines layout component hierarchy
32
+ - Consumed by forge framework for automatic route generation and component loading
33
+ - Client configured in `client.ts` to load `frontend/openapi.yaml`
34
+ - Server configured in `app.ts` to load same OpenAPI file
35
+
36
+ ## Solution: Stitch YAML Modularization Tool
37
+
38
+ ### Core Concept
39
+ Stitch will allow breaking down large OpenAPI YAML files into smaller, manageable modules that can be combined at build time or runtime.
40
+
41
+ ### Proposed File Structure
42
+
43
+ #### Backend Modularization
44
+ ```
45
+ /groom/backend/
46
+ ├── stitch.yaml # Main stitch configuration
47
+ ├── openapi/
48
+ │ ├── base.yaml # OpenAPI header, info, servers
49
+ │ ├── security.yaml # Security schemes and definitions
50
+ │ ├── components/
51
+ │ │ ├── schemas/
52
+ │ │ │ ├── user.yaml
53
+ │ │ │ ├── business.yaml
54
+ │ │ │ └── booking.yaml
55
+ │ │ └── responses.yaml
56
+ │ └── paths/
57
+ │ ├── users.yaml # All user-related endpoints
58
+ │ ├── businesses.yaml # All business-related endpoints
59
+ │ ├── bookings.yaml # All booking-related endpoints
60
+ │ └── auth.yaml # Authentication endpoints
61
+ ```
62
+
63
+ #### Frontend Modularization
64
+ ```
65
+ /groom/frontend/
66
+ ├── stitch.yaml # Main stitch configuration
67
+ ├── openapi/
68
+ │ ├── base.yaml # OpenAPI header and info
69
+ │ ├── layouts.yaml # Global layout definitions
70
+ │ └── routes/
71
+ │ ├── home.yaml # Home page routes
72
+ │ ├── users.yaml # User-related pages
73
+ │ ├── businesses.yaml # Business-related pages
74
+ │ ├── bookings.yaml # Booking-related pages
75
+ │ └── auth.yaml # Authentication pages
76
+ ```
77
+
78
+ ### Stitch Configuration Format
79
+
80
+ **Simple and Clean**: Stitch uses a minimal configuration format that just lists files to merge.
81
+
82
+ #### Backend `stitch.yaml`
83
+ ```yaml
84
+ stitch:
85
+ - openapi/base.yaml
86
+ - openapi/security.yaml
87
+ - openapi/paths/*.yaml
88
+ - openapi/components/responses.yaml
89
+ - openapi/components/schemas/*.yaml
90
+ ```
91
+
92
+ #### Frontend `stitch.yaml`
93
+ ```yaml
94
+ stitch:
95
+ - openapi/base.yaml
96
+ - openapi/layouts.yaml
97
+ - openapi/routes/*.yaml
98
+ ```
99
+
100
+ **How it works:**
101
+ - Files are merged in order using deep merge
102
+ - Supports glob patterns (e.g., `*.yaml`, `**/*.yaml`)
103
+ - Globs are expanded and sorted alphabetically
104
+ - Later files override earlier files for conflicting keys
105
+ - Arrays and objects are merged intelligently
106
+ - All paths are relative to the stitch.yaml file location
107
+
108
+ ### Implementation Strategy
109
+
110
+ The approach is to build Stitch as a standalone tool first, then update forge and dinner to use Stitch for YAML loading. This ensures Stitch works independently before integration.
111
+
112
+ #### Phase 1: Standalone Stitch Tool (Current Focus)
113
+
114
+ **Goal**: Create a working YAML modularization tool that can be used independently via CLI or programmatic API.
115
+
116
+ ##### Step 1: Core Dependencies & Setup
117
+ ```bash
118
+ # Add required dependencies
119
+ npm install js-yaml @types/js-yaml chokidar @types/chokidar ajv ajv-formats glob @types/glob
120
+ ```
121
+
122
+ Dependencies needed:
123
+ - `js-yaml` - YAML parsing and serialization (same as forge uses)
124
+ - `chokidar` - File watching for watch mode
125
+ - `ajv` + `ajv-formats` - JSON Schema validation for OpenAPI validation
126
+ - `glob` - Glob pattern matching for file expansion
127
+
128
+ ##### Step 2: Core Engine Implementation
129
+
130
+ **File Structure:**
131
+ ```
132
+ src/
133
+ ├── index.ts # Main API exports
134
+ ├── cli/
135
+ │ └── StitchCLI.ts # CLI argument parser (already exists)
136
+ ├── core/
137
+ │ ├── StitchEngine.ts # Main processing engine
138
+ │ ├── ConfigParser.ts # Parse stitch.yaml configuration
139
+ │ ├── YamlMerger.ts # YAML merging logic
140
+ │ └── Validator.ts # OpenAPI validation
141
+ ├── types/
142
+ │ └── StitchTypes.ts # TypeScript interfaces
143
+ └── utils/
144
+ └── FileUtils.ts # File system utilities
145
+ ```
146
+
147
+ **Core Components:**
148
+
149
+ 1. **StitchEngine.ts** - Main orchestrator
150
+ ```typescript
151
+ export class StitchEngine {
152
+ async build(configPath: string, options: BuildOptions): Promise<StitchResult>
153
+ buildSync(configPath: string, options: BuildOptions): StitchResult
154
+ async watch(configPath: string, options: WatchOptions): Promise<void>
155
+ }
156
+
157
+ // Processing flow:
158
+ // 1. Parse stitch.yaml config
159
+ // 2. Expand any glob patterns to actual file paths
160
+ // 3. Load and parse each YAML file in order
161
+ // 4. Deep merge files in order (later files override earlier)
162
+ // 5. Validate merged result if requested
163
+ // 6. Output as YAML/JSON to stdout or file
164
+ ```
165
+
166
+ 2. **ConfigParser.ts** - Parse stitch.yaml files
167
+ ```typescript
168
+ export interface StitchConfig {
169
+ stitch: string[]; // Array of file paths/globs to merge in order
170
+ }
171
+
172
+ export class ConfigParser {
173
+ parseConfig(configPath: string): StitchConfig
174
+ resolveFilePaths(patterns: string[], baseDir: string): string[]
175
+ expandGlobs(patterns: string[], baseDir: string): string[]
176
+ }
177
+ ```
178
+
179
+ 3. **YamlMerger.ts** - Deep YAML merging
180
+ ```typescript
181
+ export class YamlMerger {
182
+ mergeFiles(files: string[]): any
183
+ deepMerge(target: any, source: any): any
184
+
185
+ // Deep merge rules:
186
+ // - Objects: merge properties, source overrides target
187
+ // - Arrays: source replaces target completely
188
+ // - Primitives: source overrides target
189
+ }
190
+ ```
191
+
192
+ 4. **Validator.ts** - OpenAPI schema validation
193
+ ```typescript
194
+ export class Validator {
195
+ validateOpenAPI(yamlContent: any): ValidationResult
196
+ validateYamlSyntax(yamlString: string): ValidationResult
197
+ }
198
+ ```
199
+
200
+ ##### Step 3: CLI Implementation
201
+
202
+ Update `cli.ts` to implement actual functionality:
203
+
204
+ ```typescript
205
+ // cli.ts updates needed
206
+ switch(command.toLowerCase()){
207
+ case "build":
208
+ const inputFile = commands[1] || 'stitch.yaml';
209
+ const engine = new StitchEngine();
210
+ const result = await engine.build(inputFile, {
211
+ output: args.flags.output,
212
+ format: args.flags.format || 'yaml',
213
+ validate: args.flags.validate,
214
+ quiet: args.flags.quiet
215
+ });
216
+
217
+ if (result.success) {
218
+ if (!args.flags.quiet) {
219
+ if (args.flags.output) {
220
+ console.log(`Built successfully to ${args.flags.output}`);
221
+ } else {
222
+ console.log(result.data); // Output to stdout
223
+ }
224
+ }
225
+ } else {
226
+ console.error(result.error);
227
+ process.exit(1);
228
+ }
229
+ break;
230
+
231
+ case "watch":
232
+ const watchFile = commands[1] || 'stitch.yaml';
233
+ const engine = new StitchEngine();
234
+ await engine.watch(watchFile, {
235
+ output: args.flags.output,
236
+ format: args.flags.format || 'yaml',
237
+ validate: args.flags.validate,
238
+ quiet: args.flags.quiet
239
+ });
240
+ break;
241
+ }
242
+ ```
243
+
244
+ ##### Step 4: Programmatic API
245
+
246
+ Export clean API in `src/index.ts`:
247
+
248
+ ```typescript
249
+ export { StitchEngine } from './core/StitchEngine';
250
+ export * from './types/StitchTypes';
251
+
252
+ // Convenience functions
253
+ export const stitch = {
254
+ build: async (options: BuildOptions) => new StitchEngine().build(options.input || 'stitch.yaml', options),
255
+ buildSync: (options: BuildOptions) => new StitchEngine().buildSync(options.input || 'stitch.yaml', options),
256
+ watch: async (options: WatchOptions) => new StitchEngine().watch(options.input || 'stitch.yaml', options),
257
+ };
258
+ ```
259
+
260
+ ##### Step 5: Testing Strategy
261
+
262
+ Create test files to validate functionality:
263
+
264
+ ```
265
+ test/
266
+ ├── fixtures/
267
+ │ ├── simple/
268
+ │ │ ├── stitch.yaml # stitch: [base.yaml, paths.yaml]
269
+ │ │ ├── base.yaml # OpenAPI header, info
270
+ │ │ └── paths.yaml # paths section
271
+ │ └── complex/
272
+ │ ├── stitch.yaml # stitch: [base.yaml, paths/users.yaml, ...]
273
+ │ ├── base.yaml # OpenAPI header, info, servers
274
+ │ ├── paths/
275
+ │ │ ├── users.yaml # paths: { /users: {...} }
276
+ │ │ └── businesses.yaml # paths: { /businesses: {...} }
277
+ │ └── components/
278
+ │ └── schemas.yaml # components: { schemas: {...} }
279
+ └── StitchEngine.test.ts
280
+ ```
281
+
282
+ **Example simple test case:**
283
+
284
+ `test/fixtures/simple/stitch.yaml`:
285
+ ```yaml
286
+ stitch:
287
+ - base.yaml
288
+ - paths.yaml
289
+ ```
290
+
291
+ **Example with globs:**
292
+
293
+ `test/fixtures/complex/stitch.yaml`:
294
+ ```yaml
295
+ stitch:
296
+ - base.yaml
297
+ - paths/*.yaml
298
+ - components/**/*.yaml
299
+ ```
300
+
301
+ `test/fixtures/simple/base.yaml`:
302
+ ```yaml
303
+ openapi: '3.0.3'
304
+ info:
305
+ title: Test API
306
+ version: '1.0.0'
307
+ ```
308
+
309
+ `test/fixtures/simple/paths.yaml`:
310
+ ```yaml
311
+ paths:
312
+ /test:
313
+ get:
314
+ summary: Test endpoint
315
+ responses:
316
+ '200':
317
+ description: OK
318
+ ```
319
+
320
+ **Expected merged result:**
321
+ ```yaml
322
+ openapi: '3.0.3'
323
+ info:
324
+ title: Test API
325
+ version: '1.0.0'
326
+ paths:
327
+ /test:
328
+ get:
329
+ summary: Test endpoint
330
+ responses:
331
+ '200':
332
+ description: OK
333
+ ```
334
+
335
+ #### Phase 2: Integration with Forge/Dinner (Future)
336
+
337
+ Once Stitch is working standalone:
338
+
339
+ 1. **Update forge** to use Stitch for YAML loading
340
+ - Modify `src/parser/openapi.ts` to optionally use Stitch
341
+ - Add fallback to current behavior for backward compatibility
342
+
343
+ 2. **Update dinner** to use Stitch for YAML loading
344
+ - Similar integration approach
345
+
346
+ 3. **Groom Migration**
347
+ - Split existing YAML files using working Stitch tool
348
+ - Update build processes to use Stitch
349
+
350
+ #### Success Criteria for Phase 1
351
+
352
+ 1. ✅ CLI commands work: `stitch build`, `stitch watch`
353
+ 2. ✅ Options work: `--output`, `--format`, `--validate`, `--quiet`
354
+ 3. ✅ Programmatic API works: `stitch.build()`, `stitch.buildSync()`
355
+ 4. ✅ YAML merging preserves OpenAPI structure correctly
356
+ 5. ✅ Watch mode detects file changes and rebuilds
357
+ 6. ✅ Validation catches invalid YAML and OpenAPI issues
358
+ 7. ✅ Error messages are clear and helpful
359
+ 8. ✅ Performance is acceptable (< 1 second for typical builds)
360
+
361
+ ## Phase 1.5: Binary Distribution Setup (Current Task)
362
+
363
+ **Goal**: Package Stitch as a distributable npm package with a global CLI binary.
364
+
365
+ ### Tasks to Complete
366
+
367
+ 1. **Build System Setup**
368
+ - Configure TypeScript compilation for distribution
369
+ - Set up proper build pipeline for binary distribution
370
+ - Ensure all dependencies are properly bundled/referenced
371
+
372
+ 2. **Binary Configuration**
373
+ - Add `bin` field to package.json pointing to compiled CLI
374
+ - Create executable CLI entry point
375
+ - Set proper file permissions and shebang
376
+
377
+ 3. **Package.json Updates**
378
+ - Configure proper exports for both programmatic and CLI usage
379
+ - Set up build scripts for distribution
380
+ - Ensure proper entry points for different use cases
381
+
382
+ 4. **Distribution Testing**
383
+ - Test global installation: `npm install -g .`
384
+ - Verify `stitch` command works globally
385
+ - Test both local and global package usage
386
+ - Ensure programmatic API still works after build
387
+
388
+ ### Implementation Plan
389
+
390
+ #### Step 1: TypeScript Build Configuration
391
+
392
+ **Current Issue**: We're using `tsx` for development, but need compiled JavaScript for distribution.
393
+
394
+ **Solution**:
395
+ - Configure TypeScript to compile to a `bin/` directory
396
+ - Create a standalone CLI entry point that doesn't require tsx
397
+ - Update build scripts to generate distribution-ready files
398
+
399
+ **Updated File Structure:**
400
+ ```
401
+ dist/ # Compiled JavaScript output
402
+ ├── core/
403
+ │ ├── StitchEngine.js
404
+ │ ├── ConfigParser.js
405
+ │ ├── YamlMerger.js
406
+ │ └── Validator.js
407
+ ├── types/
408
+ │ └── StitchTypes.js
409
+ ├── cli/
410
+ │ └── StitchCLI.js
411
+ └── index.js # Main API export
412
+
413
+ bin/
414
+ └── stitch.js # CLI entry point (executable)
415
+
416
+ src/ # Source TypeScript (unchanged)
417
+ cli.ts # Development CLI (stays for dev)
418
+ ```
419
+
420
+ #### Step 2: CLI Entry Point Creation
421
+
422
+ Create `bin/stitch.js` as the executable entry point:
423
+
424
+ ```javascript
425
+ #!/usr/bin/env node
426
+
427
+ // Production CLI entry point - uses compiled JavaScript
428
+ const { StitchEngine } = require('../dist/core/StitchEngine');
429
+ const { StitchCLIFactory } = require('../dist/cli/StitchCLI');
430
+
431
+ // Similar logic to cli.ts but using compiled modules
432
+ // Handle all CLI commands and flags
433
+ ```
434
+
435
+ #### Step 3: Package.json Configuration
436
+
437
+ **Add Binary Configuration:**
438
+ ```json
439
+ {
440
+ "bin": {
441
+ "stitch": "./bin/stitch.js"
442
+ },
443
+ "main": "./dist/index.js",
444
+ "types": "./dist/index.d.ts",
445
+ "files": [
446
+ "dist/**/*",
447
+ "bin/**/*",
448
+ "README.md"
449
+ ]
450
+ }
451
+ ```
452
+
453
+ **Updated Scripts:**
454
+ ```json
455
+ {
456
+ "scripts": {
457
+ "build": "tsc && npm run build:bin",
458
+ "build:bin": "node scripts/create-bin.js",
459
+ "build:client": "vite build --config vite.config.js",
460
+ "build:ssr": "SSR=true vite build --ssr",
461
+ "dev": "tsx cli.ts",
462
+ "test": "jest",
463
+ "prepublishOnly": "npm run build",
464
+ "postinstall": "chmod +x bin/stitch.js"
465
+ }
466
+ }
467
+ ```
468
+
469
+ #### Step 4: TypeScript Configuration Updates
470
+
471
+ **Update tsconfig.json:**
472
+ ```json
473
+ {
474
+ "compilerOptions": {
475
+ "outDir": "dist",
476
+ "declaration": true,
477
+ "declarationMap": true,
478
+ "target": "ES2020",
479
+ "module": "CommonJS",
480
+ "moduleResolution": "node"
481
+ },
482
+ "include": ["src/**/*"],
483
+ "exclude": ["node_modules", "dist", "test", "bin"]
484
+ }
485
+ ```
486
+
487
+ #### Step 5: Distribution Workflow
488
+
489
+ 1. **Development**: Use `npm run dev` (tsx cli.ts)
490
+ 2. **Testing**: Use `npm test` (jest on source files)
491
+ 3. **Building**: Use `npm run build` (compile + create bin)
492
+ 4. **Local Install**: Use `npm install -g .` (test global CLI)
493
+ 5. **Publishing**: Use `npm publish` (with prepublishOnly hook)
494
+
495
+ ### Testing Plan
496
+
497
+ 1. **Build Test**: `npm run build` should create dist/ and bin/
498
+ 2. **Local Install Test**: `npm install -g .` should make `stitch` available
499
+ 3. **CLI Test**: `stitch build test/fixtures/simple/stitch.yaml` should work
500
+ 4. **API Test**: `import { stitch } from 'stitch'` should work
501
+ 5. **Uninstall Test**: `npm uninstall -g stitch` should clean up
502
+
503
+ ### Success Criteria for Phase 1.5
504
+
505
+ 1. ✅ `npm run build` generates distribution files
506
+ 2. ✅ `npm install -g .` installs CLI globally
507
+ 3. ✅ `stitch build [file]` works from any directory
508
+ 4. ✅ Programmatic API works: `require('stitch')` or `import { stitch }`
509
+ 5. ✅ Package is ready for npm publish
510
+ 6. ✅ All original functionality preserved
511
+ 7. ✅ Binary has proper permissions and works cross-platform
512
+ 8. ✅ Clean uninstall with `npm uninstall -g stitch`
513
+
514
+ ## Phase 2: Client-Side / Vite Integration
515
+
516
+ **Goal**: Enable Stitch to work in browser environments with Vite's `?raw` import system.
517
+
518
+ ### Background
519
+
520
+ Currently Stitch reads YAML files from the filesystem using Node.js `fs` module. This works great for:
521
+ - CLI usage (server-side)
522
+ - Node.js programmatic API
523
+
524
+ However, for client-side usage (like in forge framework), we need to support Vite's import system where YAML content is imported at build time using the `?raw` suffix.
525
+
526
+ **Current forge pattern:**
527
+ ```typescript
528
+ // Dynamic YAML import with Vite's raw import
529
+ let open_api_config = (await import(/* @vite-ignore */ config+'?raw')).default;
530
+ open_api_config = yaml.load(open_api_config);
531
+ routes = transform_openapi_config(open_api_config);
532
+ ```
533
+
534
+ ### Proposed Enhancement
535
+
536
+ #### New API: Content-Based Merging
537
+
538
+ Add support for merging YAML content directly (not just file paths):
539
+
540
+ ```typescript
541
+ // New interface for content-based merging
542
+ export interface StitchContentConfig {
543
+ stitch: Array<string | { content: string; name?: string }>;
544
+ }
545
+
546
+ // New methods on YamlMerger
547
+ export class YamlMerger {
548
+ // Existing file-based method
549
+ mergeFiles(filePaths: string[]): any
550
+
551
+ // New content-based method
552
+ mergeContent(contents: Array<{ content: string; name?: string }>): any
553
+
554
+ // Mixed method (files + content)
555
+ merge(items: Array<string | { content: string; name?: string }>): any
556
+ }
557
+ ```
558
+
559
+ #### Usage Examples
560
+
561
+ **Pure content merging (client-side):**
562
+ ```typescript
563
+ import baseYaml from './openapi/base.yaml?raw';
564
+ import pathsYaml from './openapi/paths.yaml?raw';
565
+ import { YamlMerger } from 'stitch';
566
+
567
+ const merger = new YamlMerger();
568
+ const result = merger.mergeContent([
569
+ { content: baseYaml, name: 'base.yaml' },
570
+ { content: pathsYaml, name: 'paths.yaml' }
571
+ ]);
572
+ ```
573
+
574
+ **Mixed file and content merging:**
575
+ ```typescript
576
+ const merger = new YamlMerger();
577
+ const result = merger.merge([
578
+ 'base.yaml', // File path (Node.js)
579
+ { content: importedYaml, name: 'imported.yaml' } // Raw content
580
+ ]);
581
+ ```
582
+
583
+ **Vite integration helper:**
584
+ ```typescript
585
+ // Helper function for Vite environments
586
+ export async function stitchFromViteImports(imports: Record<string, () => Promise<{ default: string }>>) {
587
+ const contents = await Promise.all(
588
+ Object.entries(imports).map(async ([path, importFn]) => ({
589
+ content: (await importFn()).default,
590
+ name: path
591
+ }))
592
+ );
593
+
594
+ const merger = new YamlMerger();
595
+ return merger.mergeContent(contents);
596
+ }
597
+
598
+ // Usage:
599
+ const imports = import.meta.glob('./openapi/*.yaml', { as: 'raw' });
600
+ const merged = await stitchFromViteImports(imports);
601
+ ```
602
+
603
+ #### Implementation Plan
604
+
605
+ 1. **Extend YamlMerger class**
606
+ - Add `mergeContent()` method for content-based merging
607
+ - Add `merge()` method for mixed file/content merging
608
+ - Maintain existing `mergeFiles()` for backward compatibility
609
+
610
+ 2. **Update StitchEngine**
611
+ - Add content-based build methods
612
+ - Support mixed configurations
613
+ - Maintain file-based CLI functionality
614
+
615
+ 3. **Add Vite helpers**
616
+ - Helper functions for common Vite patterns
617
+ - Integration utilities for `import.meta.glob()`
618
+ - Documentation and examples
619
+
620
+ 4. **Browser compatibility**
621
+ - Ensure YamlMerger works in browser environments
622
+ - Remove Node.js-specific dependencies from core merge logic
623
+ - Provide separate builds for Node.js vs browser
624
+
625
+ #### File Structure Changes
626
+
627
+ ```
628
+ src/
629
+ ├── core/
630
+ │ ├── StitchEngine.ts # Node.js + content support
631
+ │ ├── YamlMerger.ts # Universal (Node.js + browser)
632
+ │ └── ViteHelper.ts # NEW: Vite-specific utilities
633
+ ├── browser/
634
+ │ └── index.ts # NEW: Browser-specific exports
635
+ └── node/
636
+ └── index.ts # NEW: Node.js-specific exports
637
+ ```
638
+
639
+ #### Package.json Exports
640
+
641
+ ```json
642
+ {
643
+ "exports": {
644
+ ".": {
645
+ "browser": "./dist/browser/index.js",
646
+ "node": "./dist/node/index.js",
647
+ "default": "./dist/index.js"
648
+ },
649
+ "./vite": "./dist/core/ViteHelper.js"
650
+ }
651
+ }
652
+ ```
653
+
654
+ ### Benefits
655
+
656
+ 1. **Universal Usage**: Same merging logic works in Node.js and browser
657
+ 2. **Vite Integration**: Native support for Vite's import system
658
+ 3. **Performance**: No runtime file system access in browser builds
659
+ 4. **Flexibility**: Mix file-based and content-based merging
660
+ 5. **Backward Compatibility**: Existing CLI and Node.js API unchanged
661
+
662
+ ### Success Criteria for Phase 2
663
+
664
+ 1. ✅ `YamlMerger.mergeContent()` works with raw YAML strings
665
+ 2. ✅ Vite helper functions simplify `import.meta.glob()` usage
666
+ 3. ✅ Browser build works without Node.js dependencies
667
+ 4. ✅ Mixed file + content merging works in Node.js
668
+ 5. ✅ Existing CLI and Node.js functionality preserved
669
+ 6. ✅ forge framework can use Stitch instead of custom merge logic
670
+ 7. ✅ Documentation covers both server and client usage patterns
671
+
672
+ ## Phase 2: Complete ✅
673
+
674
+ **Goal**: Enable Stitch to work in browser environments with Vite's `?raw` import system.
675
+
676
+ ### Implemented Features
677
+
678
+ #### Content-Based Merging API
679
+ - `YamlMerger.mergeContent()` - Merge raw YAML content strings
680
+ - `YamlMerger.merge()` - Mixed file paths and content merging
681
+ - `StitchEngine.buildFromContent()` - Build from content without filesystem
682
+
683
+ #### Vite Integration Helpers
684
+ - `stitchFromViteImports()` - Work with `import.meta.glob()`
685
+ - `stitchFromOrderedViteImports()` - Specific merge order
686
+ - `stitchFromSortedViteImports()` - Alphabetical ordering
687
+ - `stitchFromContent()` - Direct content merging
688
+ - `stitchFromRawContent()` - Simple string array merging
689
+
690
+ #### Browser/Server Separation
691
+ - Browser entry point: `src/browser/index.ts` (no Node.js deps)
692
+ - Server entry point: `src/index.ts` (full functionality)
693
+ - Separate builds via Vite configuration
694
+ - Package.json exports for environment-specific imports
695
+
696
+ #### Usage Examples
697
+
698
+ **Client-side with Vite:**
699
+ ```typescript
700
+ import { stitchFromViteImports } from 'stitch/browser';
701
+
702
+ const imports = import.meta.glob('./openapi/*.yaml', { as: 'raw' });
703
+ const merged = await stitchFromViteImports(imports);
704
+ ```
705
+
706
+ **Direct content merging:**
707
+ ```typescript
708
+ import { stitchFromContent } from 'stitch/browser';
709
+
710
+ const contents = [
711
+ { content: baseYaml, name: 'base.yaml' },
712
+ { content: pathsYaml, name: 'paths.yaml' }
713
+ ];
714
+ const result = stitchFromContent(contents);
715
+ ```
716
+
717
+ **Mixed file + content (Node.js):**
718
+ ```typescript
719
+ import { YamlMerger } from 'stitch';
720
+
721
+ const merger = new YamlMerger();
722
+ const result = merger.merge([
723
+ 'base.yaml', // File path
724
+ { content: importedYaml, name: 'imported.yaml' } // Raw content
725
+ ]);
726
+ ```
727
+
728
+ #### Implementation Order
729
+
730
+ 1. **Dependencies** - Add js-yaml, chokidar, ajv, glob packages
731
+ 2. **Types** - Define TypeScript interfaces (simplified)
732
+ 3. **ConfigParser** - Parse simple stitch.yaml format
733
+ 4. **YamlMerger** - Deep merge implementation
734
+ 5. **Validator** - OpenAPI validation (optional)
735
+ 6. **StitchEngine** - Simple orchestration: parse config → load files → merge → output
736
+ 7. **CLI** - Wire up build/watch commands to engine
737
+ 8. **API** - Export programmatic interface
738
+ 9. **Tests** - Validate with simple merge examples
739
+
740
+ **Core logic is much simpler now:**
741
+ - Parse `stitch.yaml` → get array of files/globs
742
+ - Expand globs to actual file paths (sorted alphabetically)
743
+ - Load each YAML file in order
744
+ - Deep merge them sequentially
745
+ - Output result as YAML or JSON
746
+
747
+ **Glob Examples:**
748
+ - `*.yaml` - All YAML files in current directory
749
+ - `**/*.yaml` - All YAML files recursively
750
+ - `paths/*.yaml` - All YAML files in paths directory
751
+ - `components/**/*.yaml` - All YAML files in components and subdirectories
752
+
753
+ ### Migration Plan
754
+
755
+ #### Step 1: Extract Backend API
756
+ 1. Create backend stitch configuration
757
+ 2. Split `backend/openapi.yaml` into modules:
758
+ - Extract user endpoints to `paths/users.yaml`
759
+ - Extract business endpoints to `paths/businesses.yaml`
760
+ - Extract schemas to component files
761
+ 3. Update build process to generate `openapi.yaml`
762
+ 4. Verify dinner framework still works correctly
763
+
764
+ #### Step 2: Extract Frontend Routes
765
+ 1. Create frontend stitch configuration
766
+ 2. Split `frontend/openapi.yaml` into route modules
767
+ 3. Update build process to generate `openapi.yaml`
768
+ 4. Verify forge framework still works correctly
769
+
770
+ #### Step 3: Team Workflow
771
+ 1. Establish conventions for module organization
772
+ 2. Create documentation for adding new routes/endpoints
773
+ 3. Setup CI validation to ensure merged output is valid
774
+
775
+ ### Benefits
776
+
777
+ 1. **Maintainability**: Smaller, focused files are easier to understand and modify
778
+ 2. **Collaboration**: Reduces merge conflicts when multiple developers work on different features
779
+ 3. **Organization**: Logical grouping of related functionality
780
+ 4. **Reusability**: Common components can be shared across modules
781
+ 5. **Validation**: Individual modules can be validated independently
782
+ 6. **Scalability**: New features can be added as new modules without touching existing files
783
+
784
+ ### Technical Requirements
785
+
786
+ 1. **YAML Processing**: Robust YAML parsing and merging capabilities
787
+ 2. **OpenAPI Validation**: Ensure merged output conforms to OpenAPI 3.0.3 spec
788
+ 3. **File Watching**: Efficient file system monitoring for development
789
+ 4. **Path Resolution**: Proper handling of relative paths and includes
790
+ 5. **Error Handling**: Clear error messages for validation and merge conflicts
791
+ 6. **Performance**: Fast builds for development workflow
792
+
793
+ ### Success Criteria
794
+
795
+ 1. Backend and frontend OpenAPI files successfully split into manageable modules
796
+ 2. Generated combined files are identical to original monolithic files
797
+ 3. Both dinner (backend) and forge (frontend) frameworks work without modification
798
+ 4. Development workflow remains smooth with watch mode
799
+ 5. Build times are acceptable (< 1 second for typical changes)
800
+ 6. Clear error messages help developers fix issues quickly
801
+
802
+ ## Phase 3: VSCode Schema Integration ✅
803
+
804
+ **Goal**: Enable automatic schema validation in VSCode for YAML files.
805
+
806
+ ### Implemented Features
807
+
808
+ #### Install Command
809
+ - `stitch install <schema-file> --target <patterns>` - Install JSON schema for VSCode
810
+ - Automatically creates/updates `.vscode/settings.json`
811
+ - Supports comma-separated file patterns and globs
812
+ - Preserves existing VSCode settings
813
+
814
+ #### CLI Usage
815
+ ```bash
816
+ # Install schema for all YAML files
817
+ stitch install schemas/schema.json --target "*.yaml"
818
+
819
+ # Install schema for specific patterns
820
+ stitch install openapi-schema.json --target "stitch.yaml,openapi/*.yaml"
821
+
822
+ # Custom VSCode settings path
823
+ stitch install schemas/schema.json --target "*.yaml" --vscode custom/.vscode/settings.json
824
+ ```
825
+
826
+ #### Generated VSCode Configuration
827
+ ```json
828
+ {
829
+ "yaml.schemas": {
830
+ "test/fixtures/simple/schema.json": [
831
+ "*.yaml",
832
+ "openapi/*.yaml"
833
+ ]
834
+ }
835
+ }
836
+ ```
837
+
838
+ #### Programmatic API
839
+ ```typescript
840
+ import { StitchEngine } from 'stitch';
841
+
842
+ const engine = new StitchEngine();
843
+ const result = engine.install({
844
+ schemaPath: 'schemas/schema.json',
845
+ targets: ['*.yaml', 'openapi/*.yaml'],
846
+ vscodeSettingsPath: '.vscode/settings.json' // optional
847
+ });
848
+ ```
849
+
850
+ #### Benefits
851
+ - **IDE Integration**: Real-time YAML validation in VSCode
852
+ - **Development Experience**: Catch schema errors as you type
853
+ - **Team Consistency**: Share schema validation across team members
854
+ - **Automated Setup**: No manual VSCode configuration required
855
+
856
+ This modularization will significantly improve the maintainability and scalability of the Groom application's API and route definitions while preserving the existing framework integrations. Stitch is now a complete YAML modularization tool that works seamlessly across CLI, Node.js server environments, browser/Vite environments, and provides IDE integration for enhanced development experience.