@stackwright-pro/openapi 0.0.0-beta-20260417191149

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.
@@ -0,0 +1,981 @@
1
+ import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
2
+ import { z, ZodSchema } from 'zod';
3
+
4
+ /**
5
+ * Supported OpenAPI versions
6
+ */
7
+ type OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document;
8
+ /**
9
+ * An approved API specification.
10
+ * Used by enterprise customers to whitelist specific OpenAPI specs.
11
+ */
12
+ interface ApprovedSpec {
13
+ /** Human-readable name for the spec */
14
+ name: string;
15
+ /** URL or file path to the approved spec */
16
+ url: string;
17
+ /** Expected SHA-256 hash of the spec content */
18
+ sha256: string;
19
+ }
20
+ /**
21
+ * Security configuration for approved specs enforcement.
22
+ * Configured in stackwright.yml under `prebuild.security`.
23
+ */
24
+ interface PrebuildSecurityConfig {
25
+ /** Enable approved-specs enforcement */
26
+ enabled: boolean;
27
+ /** List of approved specifications */
28
+ allowlist: ApprovedSpec[];
29
+ }
30
+ /**
31
+ * Result of validating a spec against the approved list.
32
+ */
33
+ interface ValidationResult {
34
+ /** Whether the spec is approved */
35
+ valid: boolean;
36
+ /** Error code if not valid */
37
+ errorCode?: 'SPEC_NOT_ON_ALLOWLIST' | 'SPEC_MODIFIED' | 'DOWNLOAD_FAILED';
38
+ /** Human-readable error message */
39
+ error?: string;
40
+ /** URL of the spec that was validated */
41
+ specUrl?: string;
42
+ }
43
+ /**
44
+ * Extended site config with prebuild security.
45
+ * Users can add this to stackwright.yml.
46
+ */
47
+ interface SiteConfig {
48
+ /** Prebuild configuration */
49
+ prebuild?: {
50
+ /** Security settings for approved-specs enforcement */
51
+ security?: PrebuildSecurityConfig;
52
+ };
53
+ }
54
+ /**
55
+ * Endpoint filter configuration
56
+ */
57
+ interface EndpointFilter$1 {
58
+ /** Endpoints/patterns to include (default: all) */
59
+ include?: string[];
60
+ /** Endpoints/patterns to exclude */
61
+ exclude?: string[];
62
+ }
63
+ /**
64
+ * Configuration for OpenAPI integration in stackwright.yml
65
+ */
66
+ interface OpenAPIConfig {
67
+ /** Name of this integration */
68
+ name: string;
69
+ /** OpenAPI spec (URL or local file path) */
70
+ spec: string;
71
+ /** Mock server URL for development (e.g., http://localhost:4010) */
72
+ mockUrl?: string;
73
+ /** Authentication configuration */
74
+ auth?: {
75
+ type: 'bearer' | 'apiKey' | 'oauth2';
76
+ token?: string;
77
+ apiKey?: string;
78
+ };
79
+ /** Collections to generate from endpoints */
80
+ collections?: Array<{
81
+ /** API endpoint path */
82
+ endpoint: string;
83
+ /** Field to use as slug/ID */
84
+ slug_field: string;
85
+ /** Optional filters */
86
+ filters?: Record<string, unknown>;
87
+ }>;
88
+ /** Endpoint filter - only generate code for matching endpoints */
89
+ endpoints?: EndpointFilter$1;
90
+ }
91
+ /**
92
+ * Result of OpenAPI compilation
93
+ */
94
+ interface OpenAPICompilationResult {
95
+ /** Generated Zod schemas as code */
96
+ schemas: string;
97
+ /** Generated TypeScript types */
98
+ types: string;
99
+ /** Generated CollectionProvider implementation */
100
+ provider: string;
101
+ /** Generated API client */
102
+ client: string;
103
+ }
104
+
105
+ interface ParseOptions {
106
+ /** Whether to dereference $ref (default: true) */
107
+ dereference?: boolean;
108
+ /** Whether to validate the spec (default: true) */
109
+ validate?: boolean;
110
+ }
111
+ interface ParseResult {
112
+ /** Parsed and normalized OpenAPI document */
113
+ document: OpenAPIDocument;
114
+ /** OpenAPI version (3.0.x or 3.1.x) */
115
+ version: string;
116
+ /** Whether the spec was dereferenced */
117
+ dereferenced: boolean;
118
+ }
119
+ /**
120
+ * OpenAPI spec parser and validator
121
+ *
122
+ * Handles both OpenAPI 3.0 and 3.1 specs.
123
+ * Can parse from URL or local file path.
124
+ */
125
+ declare class OpenAPIParser {
126
+ /**
127
+ * Parse an OpenAPI specification from URL or file path
128
+ *
129
+ * @param specPath - URL or local file path to OpenAPI spec
130
+ * @param options - Parsing options
131
+ * @returns Parsed and validated OpenAPI document
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const parser = new OpenAPIParser();
136
+ * const result = await parser.parse('https://api.example.com/openapi.json');
137
+ * console.log(`Parsed OpenAPI ${result.version}`);
138
+ * ```
139
+ */
140
+ parse(specPath: string, options?: ParseOptions): Promise<ParseResult>;
141
+ /**
142
+ * Detect OpenAPI version from document
143
+ */
144
+ private detectVersion;
145
+ /**
146
+ * Enhance error messages with context
147
+ */
148
+ private enhanceError;
149
+ /**
150
+ * Check if a spec path is a URL
151
+ */
152
+ static isURL(specPath: string): boolean;
153
+ /**
154
+ * Validate that a document is OpenAPI 3.x (not Swagger 2.x)
155
+ */
156
+ static isOpenAPI3(document: unknown): document is OpenAPIDocument;
157
+ }
158
+
159
+ type SchemaObject$1 = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
160
+ /**
161
+ * Resolves schemas from OpenAPI documents
162
+ *
163
+ * Handles extracting and normalizing schemas for code generation.
164
+ */
165
+ declare class SchemaResolver {
166
+ private document;
167
+ constructor(document: OpenAPIV3.Document | OpenAPIV3_1.Document);
168
+ /**
169
+ * Get schema for a specific path and method
170
+ *
171
+ * @param path - API path (e.g., '/equipment')
172
+ * @param method - HTTP method (e.g., 'get')
173
+ * @param responseCode - Response code (default: '200')
174
+ * @returns Schema object or undefined
175
+ */
176
+ getResponseSchema(path: string, method: string, responseCode?: string): SchemaObject$1 | undefined;
177
+ /**
178
+ * Get all schemas defined in components
179
+ */
180
+ getAllSchemas(): Record<string, SchemaObject$1>;
181
+ /**
182
+ * Get a specific component schema by name
183
+ */
184
+ getComponentSchema(name: string): SchemaObject$1 | undefined;
185
+ /**
186
+ * Extract all endpoints from the OpenAPI document
187
+ */
188
+ getAllEndpoints(): Array<{
189
+ path: string;
190
+ method: string;
191
+ operationId?: string;
192
+ summary?: string;
193
+ description?: string;
194
+ }>;
195
+ }
196
+
197
+ type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
198
+ interface ZodGenerationOptions {
199
+ /** Whether to make all fields optional by default */
200
+ optionalByDefault?: boolean;
201
+ /** Custom name for the generated schema */
202
+ schemaName?: string;
203
+ /** If true, emit only the schema + type — no import statements */
204
+ bare?: boolean;
205
+ }
206
+ /**
207
+ * Generates Zod schemas from OpenAPI schema objects
208
+ *
209
+ * This is the CORE of the "mathematically proven code" value proposition.
210
+ * OpenAPI schemas → Zod validation = runtime safety guarantees.
211
+ */
212
+ declare class ZodSchemaGenerator {
213
+ /**
214
+ * Generate a Zod schema from an OpenAPI schema object
215
+ *
216
+ * @param schema - OpenAPI schema object
217
+ * @param options - Generation options
218
+ * @returns Zod schema code as string
219
+ */
220
+ generate(schema: SchemaObject, options?: ZodGenerationOptions): string;
221
+ /**
222
+ * Convert OpenAPI schema to Zod schema code
223
+ */
224
+ private schemaToZod;
225
+ /**
226
+ * Map OpenAPI type to Zod schema
227
+ */
228
+ private schemaTypeToZod;
229
+ /**
230
+ * Handle string schemas with formats and enums
231
+ */
232
+ private stringToZod;
233
+ /**
234
+ * Handle number/integer schemas
235
+ */
236
+ private numberToZod;
237
+ /**
238
+ * Handle array schemas
239
+ */
240
+ private arrayToZod;
241
+ /**
242
+ * Handle object schemas
243
+ */
244
+ private objectToZod;
245
+ /**
246
+ * Handle allOf, anyOf, oneOf composition
247
+ */
248
+ private handleComposition;
249
+ }
250
+
251
+ interface TypeGenerationOptions {
252
+ /** Name for the generated type */
253
+ typeName?: string;
254
+ /** Whether to include JSDoc comments */
255
+ includeJsDoc?: boolean;
256
+ }
257
+ /**
258
+ * Generates TypeScript types from Zod schemas
259
+ *
260
+ * Converts runtime-validatable Zod schemas into compile-time TypeScript types.
261
+ */
262
+ declare class TypeGenerator {
263
+ /**
264
+ * Generate TypeScript type definition from a Zod schema
265
+ *
266
+ * @param zodSchema - Zod schema object
267
+ * @param options - Generation options
268
+ * @returns TypeScript type definition as string
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const schema = z.object({ name: z.string(), age: z.number() });
273
+ * const generator = new TypeGenerator();
274
+ * const typeCode = generator.generate(schema, { typeName: 'User' });
275
+ * // export type User = { name: string; age: number; };
276
+ * ```
277
+ */
278
+ generate(zodSchema: z.ZodTypeAny, options?: TypeGenerationOptions): string;
279
+ /**
280
+ * Generate type from Zod schema code string
281
+ *
282
+ * This is used when we have the schema as code (from ZodSchemaGenerator)
283
+ * rather than as a runtime Zod object.
284
+ *
285
+ * @param zodSchemaCode - Zod schema as TypeScript code string
286
+ * @param typeName - Name for the generated type
287
+ * @returns TypeScript type definition
288
+ */
289
+ generateFromCode(zodSchemaCode: string, typeName: string): string;
290
+ /**
291
+ * Generate multiple types from a map of Zod schemas
292
+ *
293
+ * @param schemas - Map of schema names to Zod schemas
294
+ * @returns Object with type definitions for each schema
295
+ */
296
+ generateMultiple(schemas: Record<string, z.ZodTypeAny>, options?: Omit<TypeGenerationOptions, 'typeName'>): Record<string, string>;
297
+ /**
298
+ * Combine multiple type definitions into a single TypeScript module
299
+ *
300
+ * @param types - Map of type names to type code
301
+ * @param imports - Additional imports to include
302
+ * @returns Complete TypeScript module code
303
+ */
304
+ createModule(types: Record<string, string>, imports?: string[]): string;
305
+ }
306
+
307
+ interface CollectionConfig {
308
+ /** API endpoint path */
309
+ endpoint: string;
310
+ /** Field to use as slug/ID */
311
+ slugField: string;
312
+ /** HTTP method (default: 'get') */
313
+ method?: string;
314
+ /** Collection name (defaults to sanitized endpoint) */
315
+ name?: string;
316
+ }
317
+ interface ProviderGenerationOptions {
318
+ /** Name for the provider class */
319
+ providerName?: string;
320
+ /** Base URL for the API */
321
+ baseUrl?: string;
322
+ /** Auth configuration */
323
+ auth?: {
324
+ type: 'bearer' | 'apiKey';
325
+ headerName?: string;
326
+ };
327
+ /** If true, emit only the class code without import statements */
328
+ bare?: boolean;
329
+ }
330
+ /**
331
+ * Generates CollectionProvider implementations from OpenAPI specs
332
+ *
333
+ * This is the bridge between OpenAPI APIs and Stackwright's content system.
334
+ */
335
+ declare class CollectionProviderGenerator {
336
+ private document;
337
+ constructor(document: OpenAPIDocument);
338
+ /**
339
+ * Generate a CollectionProvider implementation for a specific endpoint
340
+ *
341
+ * @param config - Collection configuration
342
+ * @param options - Generation options
343
+ * @returns TypeScript code for the provider
344
+ */
345
+ generate(config: CollectionConfig, options?: ProviderGenerationOptions): string;
346
+ /**
347
+ * Generate the complete provider code
348
+ */
349
+ private generateProviderCode;
350
+ /**
351
+ * Generate get method implementation
352
+ */
353
+ private generateGetMethod;
354
+ /**
355
+ * Generate auth header code
356
+ */
357
+ private generateAuthHeader;
358
+ /**
359
+ * Get base URL from OpenAPI spec
360
+ */
361
+ private getBaseUrl;
362
+ /**
363
+ * Generate provider class name from config
364
+ */
365
+ private generateProviderName;
366
+ /**
367
+ * Sanitize path to valid identifier
368
+ */
369
+ private sanitizePath;
370
+ /**
371
+ * Capitalize string
372
+ */
373
+ private capitalize;
374
+ /**
375
+ * Guess which field might be a good title
376
+ */
377
+ private guessTitle;
378
+ }
379
+
380
+ /**
381
+ * Mapping of operationId to schema names
382
+ */
383
+ interface SchemaMapping {
384
+ [operationId: string]: {
385
+ /** Schema name for request validation (null if no params) */
386
+ requestSchema: string | null;
387
+ /** Schema name for response validation */
388
+ responseSchema: string;
389
+ };
390
+ }
391
+ /**
392
+ * Options for client generation
393
+ */
394
+ interface ClientGenerationOptions {
395
+ /** Name of the client class */
396
+ className?: string;
397
+ /** Whether to include JSDoc comments (default: true) */
398
+ includeJsDoc?: boolean;
399
+ /** Base URL for the API */
400
+ baseUrl?: string;
401
+ /** Whether to validate responses with Zod (default: true) */
402
+ validateResponses?: boolean;
403
+ /** Use strict validation - throw on parse errors vs safe parse (default: false) */
404
+ strictValidation?: boolean;
405
+ /** Mapping of operationId to schema names for Zod validation */
406
+ schemaMapping?: SchemaMapping;
407
+ }
408
+ /**
409
+ * ClientGenerator
410
+ *
411
+ * Generates fully typed API client functions from OpenAPI operations.
412
+ * Each endpoint becomes a type-safe function with runtime Zod validation.
413
+ *
414
+ * **Refactored to use Zod schemas as single source of truth:**
415
+ * - Types inferred from Zod schemas (no more manual type generation)
416
+ * - Request validation before API calls
417
+ * - Response validation after API calls
418
+ * - Optional strict validation mode
419
+ */
420
+ declare class ClientGenerator {
421
+ private document;
422
+ private resolver;
423
+ private schemaMapping?;
424
+ private requiredSchemas;
425
+ private generatedRequestSchemas;
426
+ constructor(document: OpenAPIDocument, schemaMapping?: SchemaMapping);
427
+ /**
428
+ * Generate typed API client code from OpenAPI document
429
+ */
430
+ generate(options?: ClientGenerationOptions): string;
431
+ /**
432
+ * Generate import statements including Zod and schemas
433
+ */
434
+ private generateImports;
435
+ /**
436
+ * Track which schemas are used for imports
437
+ */
438
+ private addRequiredSchema;
439
+ /**
440
+ * Generate Zod schemas for request parameters
441
+ *
442
+ * This generates schemas like:
443
+ * export const ListEquipmentRequestSchema = z.object({
444
+ * query: z.object({ ... }).optional(),
445
+ * });
446
+ */
447
+ private generateRequestSchemas;
448
+ /**
449
+ * Generate request schema for a single endpoint
450
+ */
451
+ private generateRequestSchemaForEndpoint;
452
+ /**
453
+ * Generate Zod schema for path parameters
454
+ */
455
+ private generatePathParamsSchema;
456
+ /**
457
+ * Generate Zod schema for query parameters
458
+ */
459
+ private generateQueryParamsSchema;
460
+ /**
461
+ * Generate Zod schema for header parameters
462
+ */
463
+ private generateHeaderParamsSchema;
464
+ /**
465
+ * Generate Zod schema for request body
466
+ */
467
+ private generateRequestBodySchema;
468
+ /**
469
+ * Convert parameter schema to Zod schema string
470
+ */
471
+ private parameterSchemaToZod;
472
+ /**
473
+ * Convert OpenAPI schema object to Zod schema string
474
+ *
475
+ * This is a simplified version for parameter schemas.
476
+ * Reuses logic similar to ZodSchemaGenerator but outputs inline.
477
+ */
478
+ private schemaObjectToZod;
479
+ /**
480
+ * Convert string schema to Zod
481
+ */
482
+ private stringSchemaToZod;
483
+ /**
484
+ * Convert number schema to Zod
485
+ */
486
+ private numberSchemaToZod;
487
+ /**
488
+ * Check if header is a common header handled by fetch
489
+ */
490
+ private isCommonHeader;
491
+ /**
492
+ * Extract component name from $ref
493
+ */
494
+ private extractComponentName;
495
+ /**
496
+ * Escape string for use in Zod .describe()
497
+ */
498
+ private escapeString;
499
+ /**
500
+ * Get list of all required schema names
501
+ */
502
+ private getRequiredSchemas;
503
+ /**
504
+ * Generate TypeScript types for request/response
505
+ *
506
+ * If schemaMapping is provided, use z.infer<> to get types from Zod schemas.
507
+ * Otherwise, fall back to legacy manual type generation.
508
+ */
509
+ private generateTypes;
510
+ /**
511
+ * Generate types using Zod inference (NEW)
512
+ */
513
+ /**
514
+ * Generate types using Zod inference (NEW)
515
+ *
516
+ * Request types infer from request schemas (defined in this file).
517
+ * Response types infer from response schemas (imported from ./schemas).
518
+ */
519
+ private generateTypesFromZod;
520
+ /**
521
+ * Generate types using manual conversion (LEGACY - backward compatible)
522
+ */
523
+ private generateTypesLegacy;
524
+ /**
525
+ * Generate request type for an operation (LEGACY)
526
+ */
527
+ private generateRequestTypeLegacy;
528
+ /**
529
+ * Generate response type for an operation (LEGACY)
530
+ */
531
+ private generateResponseTypeLegacy;
532
+ /**
533
+ * Get request body type (LEGACY)
534
+ */
535
+ private getRequestBodyTypeLegacy;
536
+ /**
537
+ * Convert OpenAPI schema to TypeScript type (LEGACY)
538
+ *
539
+ * NOTE: This method is kept for backward compatibility but should be
540
+ * replaced with Zod inference in new code.
541
+ */
542
+ private getTypeFromSchemaLegacy;
543
+ /**
544
+ * Generate error classes for API errors and validation errors
545
+ */
546
+ /**
547
+ * Generate error classes (APIError and ValidationError)
548
+ */
549
+ private generateErrorClasses;
550
+ /**
551
+ * Generate the main client class
552
+ */
553
+ private generateClientClass;
554
+ /**
555
+ * Generate constructor
556
+ */
557
+ private generateConstructor;
558
+ /**
559
+ * Generate a method for an endpoint with Zod validation (NEW)
560
+ */
561
+ /**
562
+ * Generate a method for an endpoint with Zod validation (NEW)
563
+ */
564
+ private generateMethodWithValidation;
565
+ /**
566
+ * Generate a method for an endpoint (LEGACY)
567
+ */
568
+ private generateMethodLegacy;
569
+ /**
570
+ * Generate the request helper method
571
+ */
572
+ private generateRequestHelper;
573
+ /**
574
+ * Get all endpoints from the document
575
+ */
576
+ private getAllEndpoints;
577
+ /**
578
+ * Deduplicate colliding operationIds by appending a path-based suffix.
579
+ *
580
+ * Real-world specs (e.g. SAM.gov) reuse the same operationId across
581
+ * versioned paths. We make each one unique so the generated client
582
+ * has no duplicate method names.
583
+ */
584
+ private deduplicateOperationIds;
585
+ /**
586
+ * Turn an API path into a valid, readable identifier suffix.
587
+ * e.g. '/entity-information/v4/download-entities' -> 'entityInformationV4DownloadEntities'
588
+ */
589
+ private sanitizePath;
590
+ /**
591
+ * Get parameters for an operation
592
+ */
593
+ private getOperationParameters;
594
+ /**
595
+ * Check if operation has request body
596
+ */
597
+ private hasRequestBody;
598
+ /**
599
+ * Check if request body is required
600
+ */
601
+ private isRequestBodyRequired;
602
+ /**
603
+ * Get method name from endpoint
604
+ */
605
+ private getMethodName;
606
+ /**
607
+ * Get type name for operation
608
+ */
609
+ private getOperationTypeName;
610
+ /**
611
+ * Convert to camelCase
612
+ */
613
+ private camelCase;
614
+ /**
615
+ * Convert to PascalCase
616
+ */
617
+ private pascalCase;
618
+ /**
619
+ * Get default base URL from servers
620
+ */
621
+ private getDefaultBaseUrl;
622
+ /**
623
+ * Get API title
624
+ */
625
+ private getAPITitle;
626
+ /**
627
+ * Get API description
628
+ */
629
+ private getAPIDescription;
630
+ }
631
+
632
+ /**
633
+ * OpenAPICollectionProvider
634
+ *
635
+ * Runtime implementation of CollectionProvider for OpenAPI endpoints.
636
+ * This is the runtime component that actually fetches data.
637
+ */
638
+ declare class OpenAPICollectionProvider {
639
+ private baseUrl;
640
+ private auth?;
641
+ constructor(baseUrl: string, auth?: {
642
+ type: string;
643
+ token?: string;
644
+ apiKey?: string;
645
+ } | undefined);
646
+ /**
647
+ * Fetch items from an API endpoint
648
+ */
649
+ fetchItems(endpoint: string): Promise<unknown[]>;
650
+ /**
651
+ * Fetch a single item by slug
652
+ */
653
+ fetchItem(endpoint: string, slug: string): Promise<unknown>;
654
+ }
655
+
656
+ /**
657
+ * Prebuild plugin types
658
+ * TODO: Move to @stackwright/types package when created
659
+ */
660
+ interface PrebuildPluginContext {
661
+ /** Parsed site configuration from stackwright.yml */
662
+ siteConfig: Record<string, any>;
663
+ /** Project root directory */
664
+ projectRoot: string;
665
+ }
666
+ interface PrebuildPlugin {
667
+ /** Plugin name */
668
+ name: string;
669
+ /** Called before build starts */
670
+ beforeBuild?(context: PrebuildPluginContext): Promise<void>;
671
+ /** Called after build completes */
672
+ afterBuild?(context: PrebuildPluginContext): Promise<void>;
673
+ }
674
+ /**
675
+ * Prebuild plugin for OpenAPI integration
676
+ *
677
+ * Reads OpenAPI configuration from stackwright.yml and generates:
678
+ * - Zod validation schemas
679
+ * - TypeScript type definitions
680
+ * - CollectionProvider implementations
681
+ * - Typed API client functions
682
+ *
683
+ * All generated code is written to src/generated/{integrationName}/
684
+ *
685
+ * === Phase 2: Approved-Specs Enforcement ===
686
+ *
687
+ * Enterprise customers can enable security enforcement via stackwright.yml:
688
+ *
689
+ * ```yaml
690
+ * prebuild:
691
+ * security:
692
+ * enabled: true
693
+ * allowlist:
694
+ * - name: logistics-api
695
+ * url: https://api.gov.mil/logistics/v1/openapi.yaml
696
+ * sha256: a1b2c3d4e5f6...
697
+ * ```
698
+ *
699
+ * This ensures only approved API specs can generate code.
700
+ */
701
+ declare class OpenAPIPlugin implements PrebuildPlugin {
702
+ name: string;
703
+ beforeBuild(context: PrebuildPluginContext): Promise<void>;
704
+ /**
705
+ * Print a security rejection error in a formatted box
706
+ */
707
+ private printSecurityRejection;
708
+ private processIntegration;
709
+ private generateSchemas;
710
+ private generateTypes;
711
+ private generateProvider;
712
+ private generateClient;
713
+ private extractComponentName;
714
+ private getOperationTypeName;
715
+ private generateOperationId;
716
+ private getResponseSchemaName;
717
+ private sanitizeName;
718
+ private capitalize;
719
+ }
720
+ /**
721
+ * Factory function to create the plugin instance
722
+ *
723
+ * Usage in user's prebuild script:
724
+ * ```typescript
725
+ * const { createOpenAPIPlugin } = require('@stackwright-pro/openapi/prebuild');
726
+ * runPrebuild({ plugins: [createOpenAPIPlugin()] });
727
+ * ```
728
+ */
729
+ declare function createOpenAPIPlugin(): PrebuildPlugin;
730
+
731
+ /**
732
+ * NOTE: Validates the URL structure and hostname at call time.
733
+ * Does NOT re-validate after DNS resolution (DNS rebinding).
734
+ * This is acceptable for build-time prebuild use.
735
+ * DO NOT reuse this function for runtime server-side request proxying
736
+ * without adding post-resolution IP validation.
737
+ */
738
+ /**
739
+ * Validates that a URL is safe to fetch (SSRF prevention).
740
+ * Exported for use by external consumers and tests.
741
+ *
742
+ * @throws Error if URL targets internal networks or disallowed protocols
743
+ */
744
+ declare function validateUrlSafe(baseUrl: string): URL;
745
+ /**
746
+ * Alias for validateUrlSafe — backward compatibility export
747
+ */
748
+ declare const isUrlSafe: typeof validateUrlSafe;
749
+ /**
750
+ * Configuration for OpenAPI source adapter
751
+ */
752
+ interface OpenAPISourceConfig<T = unknown> {
753
+ /** Base URL of the API */
754
+ baseUrl: string;
755
+ /** API endpoint path */
756
+ endpoint: string;
757
+ /** HTTP method (default: 'get') */
758
+ method?: 'get' | 'post' | 'put' | 'patch' | 'delete';
759
+ /** Optional query parameters */
760
+ params?: Record<string, string | number | boolean>;
761
+ /** Optional request body */
762
+ body?: unknown;
763
+ /** Optional headers */
764
+ headers?: Record<string, string>;
765
+ /** Optional Zod schema for validation */
766
+ schema?: ZodSchema<T>;
767
+ /** Authentication config */
768
+ auth?: {
769
+ type: 'bearer' | 'apiKey';
770
+ token?: string;
771
+ apiKey?: string;
772
+ headerName?: string;
773
+ };
774
+ }
775
+ /**
776
+ * Creates a fetcher function from OpenAPI configuration
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const fetcher = createOpenAPIFetcher({
781
+ * baseUrl: 'https://api.example.com',
782
+ * endpoint: '/equipment',
783
+ * auth: { type: 'bearer', token: process.env.API_TOKEN }
784
+ * });
785
+ *
786
+ * // Use with Pulse
787
+ * <Pulse fetcher={fetcher} interval={5000} />
788
+ * ```
789
+ */
790
+ declare function createOpenAPIFetcher<T = unknown>(config: OpenAPISourceConfig<T>): () => Promise<T>;
791
+
792
+ /**
793
+ * Filters endpoints based on include/exclude patterns.
794
+ *
795
+ * Supports:
796
+ * - Exact match: /equipment
797
+ * - Path prefix (includes subpaths): /equipment matches /equipment and /equipment/123
798
+ * - Path with params: /equipment/{id}
799
+ * - Single wildcard: /admin/* matches /admin/users (not /admin itself)
800
+ * - Double wildcard: /admin/** matches /admin/users and /admin/nested/deep
801
+ * - Root path: / matches all paths
802
+ */
803
+ declare class EndpointFilter {
804
+ private include;
805
+ private exclude;
806
+ constructor(filter?: EndpointFilter$1);
807
+ /**
808
+ * Check if a path should be included in code generation.
809
+ *
810
+ * Logic:
811
+ * 1. If path matches any exclude pattern → excluded
812
+ * 2. If path matches any include pattern → included
813
+ * 3. Otherwise → excluded (default deny)
814
+ */
815
+ matches(path: string): boolean;
816
+ /**
817
+ * Match path against a pattern.
818
+ */
819
+ private matchPattern;
820
+ /**
821
+ * Convert a glob-like pattern to a RegExp.
822
+ *
823
+ * Pattern semantics:
824
+ * - `*` = single path segment (no slashes), minimum 1 character
825
+ * - `**` = multiple path segments (includes slashes), zero or more segments
826
+ * - `{param}` = single path segment parameter
827
+ * - Exact match segments are literal strings
828
+ */
829
+ private globToRegex;
830
+ }
831
+
832
+ /**
833
+ * Validates that OpenAPI specs are on the approved list
834
+ * and haven't been modified since approval.
835
+ *
836
+ * @example
837
+ * ```typescript
838
+ * const config: PrebuildSecurityConfig = {
839
+ * enabled: true,
840
+ * allowlist: [
841
+ * {
842
+ * name: 'Government Logistics API',
843
+ * url: 'https://api.gov.mil/logistics/v1/openapi.yaml',
844
+ * sha256: 'a1b2c3d4e5f6...'
845
+ * }
846
+ * ]
847
+ * };
848
+ *
849
+ * const validator = new ApprovedSpecsValidator(config);
850
+ * const result = await validator.validate('https://api.gov.mil/logistics/v1/openapi.yaml');
851
+ *
852
+ * if (!result.valid) {
853
+ * console.error('Security rejection:', result.error);
854
+ * process.exit(1);
855
+ * }
856
+ * ```
857
+ */
858
+ declare class ApprovedSpecsValidator {
859
+ private allowlist;
860
+ private cache;
861
+ private skipHashVerification;
862
+ private readonly ALLOWED_DIRS;
863
+ private readonly MAX_RESPONSE_SIZE;
864
+ /**
865
+ * Create a new ApprovedSpecsValidator
866
+ *
867
+ * @param config - Security configuration from stackwright.yml
868
+ * @param skipHashVerification - Skip hash check (for testing/development)
869
+ */
870
+ constructor(config: PrebuildSecurityConfig, skipHashVerification?: boolean);
871
+ /**
872
+ * Build list of allowed directories for path traversal prevention.
873
+ * Defaults to cwd, specs subdir, and .stackwright cache dir.
874
+ */
875
+ private buildAllowedDirs;
876
+ /**
877
+ * Validate that a file path is within allowed directories (path traversal prevention).
878
+ * Uses realpathSync to resolve symlinks and prevent symlink traversal attacks.
879
+ *
880
+ * @param filePath - File path to validate
881
+ * @returns true if path is allowed, false otherwise
882
+ */
883
+ private isPathAllowed;
884
+ /**
885
+ * Check if a URL/path is a path traversal attempt.
886
+ * This is checked BEFORE the allowlist to prevent bypassing path security.
887
+ *
888
+ * @param specUrl - URL or path to check
889
+ * @returns true if this is a path traversal attempt
890
+ */
891
+ private isPathTraversalAttempt;
892
+ /**
893
+ * Validate that a hex string is a valid SHA-256 hash (64 hex characters).
894
+ *
895
+ * @param hash - String to validate
896
+ * @returns true if valid SHA-256 hex format
897
+ */
898
+ private isValidHex;
899
+ /**
900
+ * Validate that a redirect URL is safe (SSRF protection).
901
+ * Blocks:
902
+ * - HTTPS → HTTP downgrades
903
+ * - Private IP ranges (10.x.x.x, 172.16-31.x.x, 192.168.x.x, 127.x.x.x)
904
+ * - Localhost and loopback addresses
905
+ * - Cloud metadata endpoints
906
+ * - IPv6 private/link-local addresses
907
+ *
908
+ * @param location - Redirect location URL
909
+ * @param originalProtocol - Protocol of the original request
910
+ * @returns true if redirect is safe, false if it should be blocked
911
+ */
912
+ private isRedirectSafe;
913
+ /**
914
+ * Atomically check if path is allowed and read content if so.
915
+ * Prevents TOCTOU race conditions by combining existence check,
916
+ * symlink resolution, path validation, and file read in a single operation.
917
+ *
918
+ * @param filePath - File path to check and read
919
+ * @returns Object with content if successful, or error message
920
+ */
921
+ private readAllowedFile;
922
+ /**
923
+ * Check if security enforcement is enabled
924
+ */
925
+ isEnabled(): boolean;
926
+ /**
927
+ * Get the allowlist count
928
+ */
929
+ getAllowlistCount(): number;
930
+ /**
931
+ * Validate that a spec is on the approved list and matches expected hash.
932
+ *
933
+ * @param specUrl - URL or file path to the spec to validate
934
+ * @returns ValidationResult indicating if the spec is approved
935
+ */
936
+ validate(specUrl: string): Promise<ValidationResult>;
937
+ /**
938
+ * Validate multiple specs at once (batch validation).
939
+ * Fails fast on first error.
940
+ *
941
+ * @param specUrls - Array of URLs/paths to validate
942
+ * @returns Map of URL to ValidationResult
943
+ */
944
+ validateAll(specUrls: string[]): Promise<Map<string, ValidationResult>>;
945
+ /**
946
+ * Validate all specs and return all results (non-fail-fast).
947
+ *
948
+ * @param specUrls - Array of URLs/paths to validate
949
+ * @returns Map of URL to ValidationResult
950
+ */
951
+ validateAllComplete(specUrls: string[]): Promise<Map<string, ValidationResult>>;
952
+ /**
953
+ * Get content hash from cache or download.
954
+ */
955
+ private getHash;
956
+ /**
957
+ * Download content from URL or file.
958
+ * Includes path traversal and SSRF protection.
959
+ */
960
+ private download;
961
+ /**
962
+ * Check if two URLs match (handles trailing slashes, case sensitivity, etc.).
963
+ * Strips credentials and hash to prevent bypass via @ symbol.
964
+ */
965
+ private urlsMatch;
966
+ /**
967
+ * Format error message for spec not on allowlist
968
+ */
969
+ private formatAllowlistError;
970
+ /**
971
+ * Format error message for hash mismatch
972
+ */
973
+ private formatHashMismatchError;
974
+ /**
975
+ * Clear the download cache.
976
+ * Useful for long-running processes.
977
+ */
978
+ clearCache(): void;
979
+ }
980
+
981
+ export { type ApprovedSpec, ApprovedSpecsValidator, type ClientGenerationOptions, ClientGenerator, type CollectionConfig, CollectionProviderGenerator, EndpointFilter, OpenAPICollectionProvider, type OpenAPICompilationResult, type OpenAPIConfig, type OpenAPIDocument, OpenAPIParser, OpenAPIPlugin, type OpenAPISourceConfig, type ParseOptions, type ParseResult, type PrebuildSecurityConfig, type ProviderGenerationOptions, type SchemaMapping, SchemaResolver, type SiteConfig, type TypeGenerationOptions, TypeGenerator, type ValidationResult, type ZodGenerationOptions, ZodSchemaGenerator, createOpenAPIFetcher, createOpenAPIPlugin, isUrlSafe, validateUrlSafe };