@websublime/vite-plugin-open-api-server 0.24.0-next.1 → 0.24.0-next.11

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/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Plugin, ViteDevServer } from 'vite';
2
- import { Logger, HandlerFn, AnySeedFn } from '@websublime/vite-plugin-open-api-core';
2
+ import { Logger, SpecInfo, OpenApiServer, WebSocketHub, HandlerFn, AnySeedFn } from '@websublime/vite-plugin-open-api-core';
3
3
  export { HandlerContext, HandlerDefinition, HandlerFn, HandlerReturn, SecurityContext, SeedContext, SeedDefinition, SeedFn, SeedHelper, defineHandlers, defineSeeds } from '@websublime/vite-plugin-open-api-core';
4
+ import { OpenAPIV3_1 } from '@scalar/openapi-types';
5
+ import { Hono } from 'hono';
4
6
  import { App } from 'vue';
5
7
 
6
8
  /**
@@ -19,7 +21,7 @@ import { App } from 'vue';
19
21
  * Used across Tasks 1.2–1.4 for typed error handling.
20
22
  * Matches TECHNICAL-SPECIFICATION-V2.md Appendix B.
21
23
  */
22
- type ValidationErrorCode = 'SPEC_ID_MISSING' | 'SPEC_ID_DUPLICATE' | 'PROXY_PATH_MISSING' | 'PROXY_PATH_TOO_BROAD' | 'PROXY_PATH_DUPLICATE' | 'PROXY_PATH_OVERLAP' | 'SPEC_NOT_FOUND' | 'SPECS_EMPTY';
24
+ type ValidationErrorCode = 'SPEC_ID_MISSING' | 'SPEC_ID_DUPLICATE' | 'PROXY_PATH_MISSING' | 'PROXY_PATH_TOO_BROAD' | 'PROXY_PATH_DUPLICATE' | 'PROXY_PATH_OVERLAP' | 'PROXY_PATH_PREFIX_COLLISION' | 'SPEC_NOT_FOUND' | 'SPECS_EMPTY';
23
25
  /**
24
26
  * Typed validation error for configuration issues.
25
27
  *
@@ -42,6 +44,16 @@ declare class ValidationError extends Error {
42
44
  readonly code: ValidationErrorCode;
43
45
  constructor(code: ValidationErrorCode, message: string);
44
46
  }
47
+ /**
48
+ * How a proxy path was determined.
49
+ *
50
+ * - `'explicit'` — set directly in SpecConfig.proxyPath
51
+ * - `'auto'` — auto-derived from the OpenAPI document's servers[0].url
52
+ *
53
+ * Used by both DeriveProxyPathResult and ResolvedSpecConfig to ensure
54
+ * the two sources of this value stay in sync.
55
+ */
56
+ type ProxyPathSource = 'auto' | 'explicit';
45
57
  /**
46
58
  * Configuration for a single OpenAPI spec instance
47
59
  *
@@ -175,18 +187,18 @@ interface OpenApiServerOptions {
175
187
  */
176
188
  interface ResolvedSpecConfig {
177
189
  spec: string;
178
- /** Guaranteed to be set after orchestrator resolution */
190
+ /** Empty string until orchestrator resolution; guaranteed non-empty after `createOrchestrator()` */
179
191
  id: string;
180
- /** Guaranteed to be set after orchestrator resolution */
192
+ /** Empty string until orchestrator resolution; guaranteed non-empty after `createOrchestrator()` */
181
193
  proxyPath: string;
182
194
  /**
183
195
  * How proxyPath was determined — used for banner display.
184
196
  *
185
- * Set during static option resolution. The orchestrator (Task 1.7)
186
- * will pass this to the multi-spec banner so it can show
187
- * "(auto-derived)" vs "(explicit)" next to each proxy path.
197
+ * Written back by the orchestrator after document processing.
198
+ * Used by the startup banner to display `(auto-derived)` vs
199
+ * `(explicit)` next to each proxy path.
188
200
  */
189
- proxyPathSource: 'auto' | 'explicit';
201
+ proxyPathSource: ProxyPathSource;
190
202
  handlersDir: string;
191
203
  seedsDir: string;
192
204
  idFields: Record<string, string>;
@@ -208,19 +220,380 @@ interface ResolvedOptions {
208
220
  silent: boolean;
209
221
  logger?: Logger;
210
222
  }
223
+ /**
224
+ * Validate that specs array is non-empty and each entry has a valid spec field.
225
+ *
226
+ * @param specs - Array of spec configurations to validate
227
+ * @throws {ValidationError} SPECS_EMPTY if specs array is missing or empty
228
+ * @throws {ValidationError} SPEC_NOT_FOUND if a spec entry has empty spec field
229
+ */
230
+ declare function validateSpecs(specs: SpecConfig[]): void;
231
+ /**
232
+ * Resolve options with defaults.
233
+ *
234
+ * Note: spec ID and proxyPath resolution requires processing the OpenAPI document
235
+ * first, so they are resolved later in the orchestrator.
236
+ * This function only resolves static defaults.
237
+ *
238
+ * @param options - User-provided options
239
+ * @returns Resolved options with all defaults applied
240
+ */
241
+ declare function resolveOptions(options: OpenApiServerOptions): ResolvedOptions;
211
242
 
212
243
  /**
213
244
  * Vite Plugin Implementation
214
245
  *
215
- * What: Main Vite plugin for OpenAPI mock server
216
- * How: Uses configureServer hook to start mock server and configure proxy
217
- * Why: Integrates OpenAPI mock server seamlessly into Vite dev workflow
246
+ * What: Main Vite plugin for OpenAPI mock server (multi-spec)
247
+ * How: Uses orchestrator to create N spec instances, configures multi-proxy
248
+ * Why: Integrates multiple OpenAPI mock servers seamlessly into Vite dev workflow
218
249
  *
219
250
  * @module plugin
220
251
  */
221
252
 
253
+ /**
254
+ * Create the OpenAPI Server Vite plugin
255
+ *
256
+ * This plugin starts mock servers based on OpenAPI specifications
257
+ * and configures Vite to proxy API requests to them. Supports
258
+ * multiple specs via the orchestrator pattern.
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * // vite.config.ts
263
+ * import { defineConfig } from 'vite';
264
+ * import vue from '@vitejs/plugin-vue';
265
+ * import { openApiServer } from '@websublime/vite-plugin-open-api-server';
266
+ *
267
+ * export default defineConfig({
268
+ * plugins: [
269
+ * vue(),
270
+ * openApiServer({
271
+ * specs: [
272
+ * { spec: './openapi/petstore.yaml', proxyPath: '/api/pets' },
273
+ * { spec: './openapi/inventory.yaml', proxyPath: '/api/inventory' },
274
+ * ],
275
+ * port: 4000,
276
+ * }),
277
+ * ],
278
+ * });
279
+ * ```
280
+ *
281
+ * @param options - Plugin configuration options
282
+ * @returns Vite plugin
283
+ */
222
284
  declare function openApiServer(options: OpenApiServerOptions): Plugin;
223
285
 
286
+ /**
287
+ * Spec ID Derivation
288
+ *
289
+ * What: Functions to derive and validate spec identifiers
290
+ * How: Slugifies explicit IDs or auto-derives from OpenAPI info.title
291
+ * Why: Each spec instance needs a unique, URL-safe identifier for routing,
292
+ * DevTools grouping, logging, and default directory names
293
+ *
294
+ * @module spec-id
295
+ */
296
+
297
+ /**
298
+ * Slugify a string for use as a spec identifier
299
+ *
300
+ * Rules:
301
+ * - Lowercase
302
+ * - Replace spaces and special chars with hyphens
303
+ * - Remove consecutive hyphens
304
+ * - Trim leading/trailing hyphens
305
+ *
306
+ * @example
307
+ * slugify("Swagger Petstore") → "swagger-petstore"
308
+ * slugify("Billing API v2") → "billing-api-v2"
309
+ * slugify("café") → "cafe"
310
+ */
311
+ declare function slugify(input: string): string;
312
+ /**
313
+ * Derive a spec ID from the processed OpenAPI document
314
+ *
315
+ * Priority:
316
+ * 1. Explicit id from config (if non-empty)
317
+ * 2. Slugified info.title from the processed document
318
+ *
319
+ * @param explicitId - ID from SpecConfig.id (may be empty)
320
+ * @param document - Processed OpenAPI document
321
+ * @returns Stable, URL-safe spec identifier
322
+ * @throws {ValidationError} SPEC_ID_MISSING if no ID can be derived (missing title and no explicit id)
323
+ */
324
+ declare function deriveSpecId(explicitId: string, document: OpenAPIV3_1.Document): string;
325
+ /**
326
+ * Validate spec IDs are unique across all specs
327
+ *
328
+ * Collects all duplicated IDs and reports them in a single error.
329
+ *
330
+ * @param ids - Array of resolved spec IDs
331
+ * @throws {ValidationError} SPEC_ID_DUPLICATE if duplicate IDs found
332
+ */
333
+ declare function validateUniqueIds(ids: string[]): void;
334
+
335
+ /**
336
+ * Proxy Path Auto-Detection
337
+ *
338
+ * What: Functions to derive and validate proxy paths for spec instances
339
+ * How: Extracts path from explicit config or auto-derives from servers[0].url
340
+ * Why: Each spec instance needs a unique, non-overlapping proxy path for
341
+ * Vite proxy configuration and request routing
342
+ *
343
+ * @module proxy-path
344
+ */
345
+
346
+ /**
347
+ * Result of proxy path derivation
348
+ *
349
+ * Includes the normalized path and how it was determined,
350
+ * so the startup banner can display "(auto-derived)" vs "(explicit)".
351
+ */
352
+ interface DeriveProxyPathResult {
353
+ /** Normalized proxy path (e.g., "/api/v3") */
354
+ proxyPath: string;
355
+ /** How the path was determined */
356
+ proxyPathSource: ProxyPathSource;
357
+ }
358
+ /**
359
+ * Derive the proxy path from config or OpenAPI document's servers field
360
+ *
361
+ * Priority:
362
+ * 1. Explicit proxyPath from config (if non-empty after trimming)
363
+ * 2. Path portion of servers[0].url
364
+ *
365
+ * Full URLs (e.g., "https://api.example.com/api/v3") have their path
366
+ * extracted via the URL constructor. Relative paths (e.g., "/api/v3")
367
+ * are used directly.
368
+ *
369
+ * @param explicitPath - proxyPath from SpecConfig (may be empty)
370
+ * @param document - Processed OpenAPI document
371
+ * @param specId - Spec ID for error messages
372
+ * @returns Normalized proxy path with source indication
373
+ * @throws {ValidationError} PROXY_PATH_MISSING if path cannot be derived
374
+ * @throws {ValidationError} PROXY_PATH_TOO_BROAD if path resolves to "/" (e.g., "/", ".", "..")
375
+ *
376
+ * @example
377
+ * // Explicit path
378
+ * deriveProxyPath('/api/v3', document, 'petstore')
379
+ * // → { proxyPath: '/api/v3', proxyPathSource: 'explicit' }
380
+ *
381
+ * @example
382
+ * // Auto-derived from servers[0].url = "https://api.example.com/api/v3"
383
+ * deriveProxyPath('', document, 'petstore')
384
+ * // → { proxyPath: '/api/v3', proxyPathSource: 'auto' }
385
+ */
386
+ declare function deriveProxyPath(explicitPath: string, document: OpenAPIV3_1.Document, specId: string): DeriveProxyPathResult;
387
+ /**
388
+ * Normalize and validate a proxy path
389
+ *
390
+ * Rules:
391
+ * - Strip query strings and fragments
392
+ * - Ensure leading slash
393
+ * - Collapse consecutive slashes
394
+ * - Resolve dot segments ("." and ".." per RFC 3986 §5.2.4)
395
+ * - Remove trailing slash
396
+ * - Reject "/" as too broad (would capture all requests, including dot-segments that resolve to "/")
397
+ *
398
+ * @param path - Raw path string to normalize
399
+ * @param specId - Spec ID for error messages
400
+ * @returns Normalized path (e.g., "/api/v3")
401
+ * @throws {ValidationError} PROXY_PATH_TOO_BROAD if path resolves to "/" (e.g., "/", ".", "..")
402
+ *
403
+ * @example
404
+ * normalizeProxyPath('api/v3', 'petstore') → '/api/v3'
405
+ * normalizeProxyPath('/api/v3/', 'petstore') → '/api/v3'
406
+ */
407
+ declare function normalizeProxyPath(path: string, specId: string): string;
408
+ /**
409
+ * Validate proxy paths are unique and non-overlapping
410
+ *
411
+ * Checks for:
412
+ * 1. Duplicate paths — two specs with the same proxyPath
413
+ * 2. Overlapping paths — one path is a prefix of another at a segment boundary
414
+ * (e.g., "/api" and "/api/v1") which would cause routing ambiguity
415
+ * 3. String-prefix collisions — one path is a raw string prefix of another
416
+ * without a segment boundary (e.g., "/api" and "/api2"). Vite's internal
417
+ * proxy matching uses plain `url.startsWith(context)` with no segment
418
+ * awareness, so "/api" would incorrectly capture "/api2/users" requests.
419
+ *
420
+ * @remarks
421
+ * Entries with an empty or falsy `proxyPath` are silently skipped. These
422
+ * represent specs whose proxy path has not yet been resolved (e.g., during
423
+ * early option resolution before the OpenAPI document is processed). Callers
424
+ * should expect unresolved entries to be excluded from uniqueness checks
425
+ * rather than triggering false-positive errors.
426
+ *
427
+ * @param specs - Array of spec entries with id and proxyPath.
428
+ * Entries with empty/falsy proxyPath are skipped (unresolved).
429
+ * @throws {ValidationError} PROXY_PATH_DUPLICATE if duplicate paths found
430
+ * @throws {ValidationError} PROXY_PATH_OVERLAP if overlapping paths found (segment boundary)
431
+ * @throws {ValidationError} PROXY_PATH_PREFIX_COLLISION if one path is a raw string prefix
432
+ * of another without a segment boundary (e.g., "/api" and "/api2")
433
+ *
434
+ * @example
435
+ * // Throws PROXY_PATH_DUPLICATE
436
+ * validateUniqueProxyPaths([
437
+ * { id: 'petstore', proxyPath: '/api/v3' },
438
+ * { id: 'inventory', proxyPath: '/api/v3' },
439
+ * ]);
440
+ *
441
+ * @example
442
+ * // Throws PROXY_PATH_OVERLAP
443
+ * validateUniqueProxyPaths([
444
+ * { id: 'petstore', proxyPath: '/api' },
445
+ * { id: 'inventory', proxyPath: '/api/v1' },
446
+ * ]);
447
+ *
448
+ * @example
449
+ * // Throws PROXY_PATH_PREFIX_COLLISION
450
+ * validateUniqueProxyPaths([
451
+ * { id: 'petstore', proxyPath: '/api' },
452
+ * { id: 'inventory', proxyPath: '/api2' },
453
+ * ]);
454
+ */
455
+ declare function validateUniqueProxyPaths(specs: Array<{
456
+ id: string;
457
+ proxyPath: string;
458
+ }>): void;
459
+
460
+ /**
461
+ * Multi-Spec Orchestrator
462
+ *
463
+ * What: Central orchestrator that creates N spec instances and mounts them on a single Hono app
464
+ * How: Three phases — process specs, validate uniqueness, build main Hono app with dispatch middleware
465
+ * Why: Enables multiple OpenAPI specs to run on a single server with isolated stores and handlers
466
+ *
467
+ * @module orchestrator
468
+ */
469
+
470
+ /**
471
+ * Deterministic color palette for spec identification in DevTools.
472
+ *
473
+ * Colors are assigned by index: spec 0 gets green, spec 1 gets blue, etc.
474
+ * Wraps around for >8 specs.
475
+ */
476
+ declare const SPEC_COLORS: readonly string[];
477
+ /**
478
+ * Resolved spec instance with all runtime data.
479
+ *
480
+ * Created during Phase 1 of orchestration. Each instance owns
481
+ * an isolated core `OpenApiServer` with its own store, registry,
482
+ * handlers, seeds, and timeline.
483
+ */
484
+ interface SpecInstance {
485
+ /** Unique spec identifier (explicit or auto-derived from info.title) */
486
+ id: string;
487
+ /** Spec metadata for DevTools display and WebSocket protocol */
488
+ info: SpecInfo;
489
+ /** Core server instance (isolated Hono app, store, registry, etc.) */
490
+ server: OpenApiServer;
491
+ /** Resolved configuration for this spec */
492
+ config: ResolvedSpecConfig;
493
+ }
494
+ /**
495
+ * Orchestrator result — returned by `createOrchestrator()`.
496
+ *
497
+ * Provides access to the main Hono app (all specs mounted),
498
+ * individual spec instances, aggregated metadata, and lifecycle methods.
499
+ */
500
+ interface OrchestratorResult {
501
+ /**
502
+ * Main Hono app with all specs mounted via X-Spec-Id dispatch.
503
+ *
504
+ * **Note**: Consumers using this property directly must have `hono`
505
+ * as a dependency. The `start()`/`stop()` lifecycle methods do not
506
+ * require direct interaction with this Hono instance.
507
+ */
508
+ app: Hono;
509
+ /** All spec instances (in config order) */
510
+ instances: SpecInstance[];
511
+ /** Spec metadata array for WebSocket `connected` event */
512
+ specsInfo: SpecInfo[];
513
+ /**
514
+ * Shared WebSocket hub for the orchestrator.
515
+ *
516
+ * Created via `createMultiSpecWebSocketHub()` with:
517
+ * - `autoConnect: false` to suppress default connected events
518
+ * - Enhanced `addClient()` that sends specs metadata
519
+ * - Broadcast interception that adds `specId` to all events
520
+ * - Multi-spec command handler for spec-scoped routing
521
+ */
522
+ wsHub: WebSocketHub;
523
+ /** Start the shared HTTP server on the configured port */
524
+ start(): Promise<void>;
525
+ /** Stop the HTTP server and clean up resources */
526
+ stop(): Promise<void>;
527
+ /** Actual bound port after start() resolves (0 before start or after stop) */
528
+ readonly port: number;
529
+ }
530
+ /**
531
+ * Create the multi-spec orchestrator.
532
+ *
533
+ * Flow:
534
+ * 1. **Phase 1 — Process specs**: For each spec config, load handlers/seeds,
535
+ * create a core `OpenApiServer` instance, derive ID and proxy path.
536
+ * 2. **Phase 2 — Validate uniqueness**: Ensure all spec IDs and proxy paths
537
+ * are unique and non-overlapping.
538
+ * 3. **Phase 3 — Build main app**: Create a single Hono app with CORS,
539
+ * DevTools, Internal API, and X-Spec-Id dispatch middleware.
540
+ *
541
+ * **Note**: This function populates the resolved values (id, proxyPath,
542
+ * proxyPathSource, handlersDir, seedsDir) on each `options.specs[i]` object.
543
+ * Since `instances[i].config` is the same object reference, consumers should
544
+ * access resolved values through `instances[i].config` (the authoritative view).
545
+ *
546
+ * @param options - Resolved plugin options (from `resolveOptions()`)
547
+ * @param vite - Vite dev server instance (for ssrLoadModule)
548
+ * @param cwd - Project root directory
549
+ * @returns Orchestrator result with app, instances, and lifecycle methods
550
+ */
551
+ declare function createOrchestrator(options: ResolvedOptions, vite: ViteDevServer, cwd: string): Promise<OrchestratorResult>;
552
+
553
+ /**
554
+ * Multi-Path Proxy Configuration
555
+ *
556
+ * What: Configures Vite proxy for multiple OpenAPI spec instances
557
+ * How: Generates one proxy entry per spec with path rewriting and X-Spec-Id header,
558
+ * plus shared service proxies for DevTools, Internal API, and WebSocket
559
+ * Why: Enables each spec's API requests to be routed through Vite to the shared server
560
+ *
561
+ * @module multi-proxy
562
+ */
563
+
564
+ /**
565
+ * Shared service proxy path prefixes.
566
+ *
567
+ * These constants are the single source of truth for the reserved proxy paths
568
+ * used by the DevTools iframe, internal API, and WebSocket connections.
569
+ * Both `configureMultiProxy()` and the virtual DevTools tab module in
570
+ * `plugin.ts` reference these to prevent divergence.
571
+ */
572
+ declare const DEVTOOLS_PROXY_PATH = "/_devtools";
573
+ declare const API_PROXY_PATH = "/_api";
574
+ declare const WS_PROXY_PATH = "/_ws";
575
+ /**
576
+ * Configure Vite proxy for multiple spec instances and shared services.
577
+ *
578
+ * Generates:
579
+ * 1. **Per-spec proxy entries** — one per spec, with path rewriting (prefix
580
+ * stripping) and an `X-Spec-Id` header so the shared Hono server can
581
+ * route to the correct spec instance.
582
+ * 2. **Shared service proxies** — spec-agnostic entries for `/_devtools`,
583
+ * `/_api`, and `/_ws` that forward to the same server without path
584
+ * rewriting or spec headers.
585
+ *
586
+ * Uses `startsWith`/`slice` for path rewriting instead of the regex approach
587
+ * described in the tech spec (Section 5.7). Literal prefix matching is safer
588
+ * because it correctly handles regex metacharacters in proxy paths (e.g.,
589
+ * `/api.v3` matches literally, not as `/api<any>v3`).
590
+ *
591
+ * @param vite - Vite dev server instance
592
+ * @param instances - Resolved spec instances from the orchestrator
593
+ * @param port - Shared server port
594
+ */
595
+ declare function configureMultiProxy(vite: ViteDevServer, instances: SpecInstance[], port: number): void;
596
+
224
597
  /**
225
598
  * Handler Loading
226
599
  *
@@ -349,14 +722,12 @@ declare function getSeedFiles(seedsDir: string, cwd?: string): Promise<string[]>
349
722
  /**
350
723
  * Hot Reload
351
724
  *
352
- * What: File watcher for hot reloading handlers and seeds
353
- * How: Uses chokidar to watch for file changes
354
- * Why: Enables rapid development iteration without server restart
725
+ * What: File watcher for hot reloading handlers and seeds with per-spec isolation
726
+ * How: Uses chokidar to watch for file changes, one watcher per spec instance
727
+ * Why: Enables rapid development iteration without server restart; per-spec
728
+ * isolation ensures handler/seed changes in one spec don't affect others
355
729
  *
356
730
  * @module hot-reload
357
- *
358
- * TODO: Full implementation in Task 3.3
359
- * This module provides placeholder/basic functionality for Task 3.1
360
731
  */
361
732
 
362
733
  /**
@@ -419,6 +790,14 @@ interface FileWatcher {
419
790
  * @returns Promise resolving to file watcher instance
420
791
  */
421
792
  declare function createFileWatcher(options: FileWatcherOptions): Promise<FileWatcher>;
793
+ /**
794
+ * Debounced function with cancel support
795
+ */
796
+ interface DebouncedFunction<T extends (...args: unknown[]) => unknown> {
797
+ (...args: Parameters<T>): void;
798
+ /** Cancel any pending debounce timer and queued execution */
799
+ cancel(): void;
800
+ }
422
801
  /**
423
802
  * Debounce a function with async execution guard
424
803
  *
@@ -432,9 +811,50 @@ declare function createFileWatcher(options: FileWatcherOptions): Promise<FileWat
432
811
  *
433
812
  * @param fn - Function to debounce (can be sync or async)
434
813
  * @param delay - Debounce delay in milliseconds
435
- * @returns Debounced function
814
+ * @returns Debounced function with cancel() method
436
815
  */
437
- declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
816
+ declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): DebouncedFunction<T>;
817
+ /**
818
+ * Create file watchers for all spec instances
819
+ *
820
+ * Each spec gets independent watchers for its handlers and seeds directories.
821
+ * Changes to one spec's files only trigger reload for that spec instance.
822
+ *
823
+ * @param instances - All spec instances to watch
824
+ * @param vite - Vite dev server (for ssrLoadModule / module invalidation)
825
+ * @param cwd - Project root directory
826
+ * @param options - Resolved plugin options
827
+ * @returns Promise resolving to array of file watchers (one per spec)
828
+ */
829
+ declare function createPerSpecFileWatchers(instances: SpecInstance[], vite: ViteDevServer, cwd: string, options: ResolvedOptions): Promise<FileWatcher[]>;
830
+ /**
831
+ * Reload handlers for a specific spec instance
832
+ *
833
+ * Loads fresh handlers from disk via Vite's ssrLoadModule, updates
834
+ * the spec's server, broadcasts a WebSocket event, and logs the result.
835
+ *
836
+ * @param instance - The spec instance to reload handlers for
837
+ * @param vite - Vite dev server
838
+ * @param cwd - Project root directory
839
+ * @param options - Resolved plugin options
840
+ */
841
+ declare function reloadSpecHandlers(instance: SpecInstance, vite: ViteDevServer, cwd: string, options: ResolvedOptions): Promise<void>;
842
+ /**
843
+ * Reload seeds for a specific spec instance
844
+ *
845
+ * Loads fresh seeds from disk, clears the spec's store, and re-executes
846
+ * seeds. Broadcasts a WebSocket event and logs the result.
847
+ *
848
+ * Note: This operation is not fully atomic — there's a brief window between
849
+ * clearing the store and repopulating it where requests may see empty data.
850
+ * For development tooling, this tradeoff is acceptable.
851
+ *
852
+ * @param instance - The spec instance to reload seeds for
853
+ * @param vite - Vite dev server
854
+ * @param cwd - Project root directory
855
+ * @param options - Resolved plugin options
856
+ */
857
+ declare function reloadSpecSeeds(instance: SpecInstance, vite: ViteDevServer, cwd: string, options: ResolvedOptions): Promise<void>;
438
858
 
439
859
  /**
440
860
  * Vue DevTools Integration
@@ -452,7 +872,7 @@ declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, dela
452
872
  interface RegisterDevToolsOptions {
453
873
  /**
454
874
  * The port where the OpenAPI server is running
455
- * @default 3000
875
+ * @default 4000
456
876
  */
457
877
  port?: number;
458
878
  /**
@@ -494,7 +914,7 @@ interface RegisterDevToolsOptions {
494
914
  *
495
915
  * // Register OpenAPI Server DevTools
496
916
  * if (import.meta.env.DEV) {
497
- * await registerDevTools(app, { port: 3000 });
917
+ * await registerDevTools(app);
498
918
  * }
499
919
  *
500
920
  * app.mount('#app');
@@ -510,11 +930,11 @@ declare function registerDevTools(app: App, options?: RegisterDevToolsOptions):
510
930
  * When running in a browser, protocol and host are automatically derived from
511
931
  * window.location if not explicitly provided.
512
932
  *
513
- * @param port - Server port (default: 3000)
933
+ * @param port - Server port (default: 4000, matching OpenApiServerOptions.port)
514
934
  * @param host - Server host (default: 'localhost' or window.location.hostname)
515
935
  * @param protocol - Protocol to use (default: 'http' or window.location.protocol)
516
936
  * @returns DevTools SPA URL
517
937
  */
518
938
  declare function getDevToolsUrl(port?: number, host?: string, protocol?: 'http' | 'https'): string;
519
939
 
520
- export { type FileWatcher, type FileWatcherOptions, type LoadHandlersResult, type LoadSeedsResult, type OpenApiServerOptions, type RegisterDevToolsOptions, type ResolvedOptions, type ResolvedSpecConfig, type SpecConfig, ValidationError, type ValidationErrorCode, createFileWatcher, debounce, getDevToolsUrl, getHandlerFiles, getSeedFiles, loadHandlers, loadSeeds, openApiServer, registerDevTools };
940
+ export { API_PROXY_PATH, DEVTOOLS_PROXY_PATH, type DebouncedFunction, type DeriveProxyPathResult, type FileWatcher, type FileWatcherOptions, type LoadHandlersResult, type LoadSeedsResult, type OpenApiServerOptions, type OrchestratorResult, type ProxyPathSource, type RegisterDevToolsOptions, type ResolvedOptions, type ResolvedSpecConfig, SPEC_COLORS, type SpecConfig, type SpecInstance, ValidationError, type ValidationErrorCode, WS_PROXY_PATH, configureMultiProxy, createFileWatcher, createOrchestrator, createPerSpecFileWatchers, debounce, deriveProxyPath, deriveSpecId, getDevToolsUrl, getHandlerFiles, getSeedFiles, loadHandlers, loadSeeds, normalizeProxyPath, openApiServer, registerDevTools, reloadSpecHandlers, reloadSpecSeeds, resolveOptions, slugify, validateSpecs, validateUniqueIds, validateUniqueProxyPaths };