@stackwright-pro/openapi 0.1.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.
@@ -0,0 +1,634 @@
1
+ import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Supported OpenAPI versions
6
+ */
7
+ type OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document;
8
+ /**
9
+ * Configuration for OpenAPI integration in stackwright.yml
10
+ */
11
+ interface OpenAPIConfig {
12
+ /** Name of this integration */
13
+ name: string;
14
+ /** OpenAPI spec (URL or local file path) */
15
+ spec: string;
16
+ /** Authentication configuration */
17
+ auth?: {
18
+ type: 'bearer' | 'apiKey' | 'oauth2';
19
+ token?: string;
20
+ apiKey?: string;
21
+ };
22
+ /** Collections to generate from endpoints */
23
+ collections?: Array<{
24
+ /** API endpoint path */
25
+ endpoint: string;
26
+ /** Field to use as slug/ID */
27
+ slug_field: string;
28
+ /** Optional filters */
29
+ filters?: Record<string, unknown>;
30
+ }>;
31
+ }
32
+ /**
33
+ * Result of OpenAPI compilation
34
+ */
35
+ interface OpenAPICompilationResult {
36
+ /** Generated Zod schemas as code */
37
+ schemas: string;
38
+ /** Generated TypeScript types */
39
+ types: string;
40
+ /** Generated CollectionProvider implementation */
41
+ provider: string;
42
+ /** Generated API client */
43
+ client: string;
44
+ }
45
+
46
+ interface ParseOptions {
47
+ /** Whether to dereference $ref (default: true) */
48
+ dereference?: boolean;
49
+ /** Whether to validate the spec (default: true) */
50
+ validate?: boolean;
51
+ }
52
+ interface ParseResult {
53
+ /** Parsed and normalized OpenAPI document */
54
+ document: OpenAPIDocument;
55
+ /** OpenAPI version (3.0.x or 3.1.x) */
56
+ version: string;
57
+ /** Whether the spec was dereferenced */
58
+ dereferenced: boolean;
59
+ }
60
+ /**
61
+ * OpenAPI spec parser and validator
62
+ *
63
+ * Handles both OpenAPI 3.0 and 3.1 specs.
64
+ * Can parse from URL or local file path.
65
+ */
66
+ declare class OpenAPIParser {
67
+ /**
68
+ * Parse an OpenAPI specification from URL or file path
69
+ *
70
+ * @param specPath - URL or local file path to OpenAPI spec
71
+ * @param options - Parsing options
72
+ * @returns Parsed and validated OpenAPI document
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const parser = new OpenAPIParser();
77
+ * const result = await parser.parse('https://api.example.com/openapi.json');
78
+ * console.log(`Parsed OpenAPI ${result.version}`);
79
+ * ```
80
+ */
81
+ parse(specPath: string, options?: ParseOptions): Promise<ParseResult>;
82
+ /**
83
+ * Detect OpenAPI version from document
84
+ */
85
+ private detectVersion;
86
+ /**
87
+ * Enhance error messages with context
88
+ */
89
+ private enhanceError;
90
+ /**
91
+ * Check if a spec path is a URL
92
+ */
93
+ static isURL(specPath: string): boolean;
94
+ /**
95
+ * Validate that a document is OpenAPI 3.x (not Swagger 2.x)
96
+ */
97
+ static isOpenAPI3(document: unknown): document is OpenAPIDocument;
98
+ }
99
+
100
+ type SchemaObject$1 = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
101
+ /**
102
+ * Resolves schemas from OpenAPI documents
103
+ *
104
+ * Handles extracting and normalizing schemas for code generation.
105
+ */
106
+ declare class SchemaResolver {
107
+ private document;
108
+ constructor(document: OpenAPIV3.Document | OpenAPIV3_1.Document);
109
+ /**
110
+ * Get schema for a specific path and method
111
+ *
112
+ * @param path - API path (e.g., '/equipment')
113
+ * @param method - HTTP method (e.g., 'get')
114
+ * @param responseCode - Response code (default: '200')
115
+ * @returns Schema object or undefined
116
+ */
117
+ getResponseSchema(path: string, method: string, responseCode?: string): SchemaObject$1 | undefined;
118
+ /**
119
+ * Get all schemas defined in components
120
+ */
121
+ getAllSchemas(): Record<string, SchemaObject$1>;
122
+ /**
123
+ * Get a specific component schema by name
124
+ */
125
+ getComponentSchema(name: string): SchemaObject$1 | undefined;
126
+ /**
127
+ * Extract all endpoints from the OpenAPI document
128
+ */
129
+ getAllEndpoints(): Array<{
130
+ path: string;
131
+ method: string;
132
+ operationId?: string;
133
+ summary?: string;
134
+ description?: string;
135
+ }>;
136
+ }
137
+
138
+ type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
139
+ interface ZodGenerationOptions {
140
+ /** Whether to make all fields optional by default */
141
+ optionalByDefault?: boolean;
142
+ /** Custom name for the generated schema */
143
+ schemaName?: string;
144
+ }
145
+ /**
146
+ * Generates Zod schemas from OpenAPI schema objects
147
+ *
148
+ * This is the CORE of the "mathematically proven code" value proposition.
149
+ * OpenAPI schemas → Zod validation = runtime safety guarantees.
150
+ */
151
+ declare class ZodSchemaGenerator {
152
+ /**
153
+ * Generate a Zod schema from an OpenAPI schema object
154
+ *
155
+ * @param schema - OpenAPI schema object
156
+ * @param options - Generation options
157
+ * @returns Zod schema code as string
158
+ */
159
+ generate(schema: SchemaObject, options?: ZodGenerationOptions): string;
160
+ /**
161
+ * Convert OpenAPI schema to Zod schema code
162
+ */
163
+ private schemaToZod;
164
+ /**
165
+ * Map OpenAPI type to Zod schema
166
+ */
167
+ private schemaTypeToZod;
168
+ /**
169
+ * Handle string schemas with formats and enums
170
+ */
171
+ private stringToZod;
172
+ /**
173
+ * Handle number/integer schemas
174
+ */
175
+ private numberToZod;
176
+ /**
177
+ * Handle array schemas
178
+ */
179
+ private arrayToZod;
180
+ /**
181
+ * Handle object schemas
182
+ */
183
+ private objectToZod;
184
+ /**
185
+ * Handle allOf, anyOf, oneOf composition
186
+ */
187
+ private handleComposition;
188
+ }
189
+
190
+ interface TypeGenerationOptions {
191
+ /** Name for the generated type */
192
+ typeName?: string;
193
+ /** Whether to include JSDoc comments */
194
+ includeJsDoc?: boolean;
195
+ }
196
+ /**
197
+ * Generates TypeScript types from Zod schemas
198
+ *
199
+ * Converts runtime-validatable Zod schemas into compile-time TypeScript types.
200
+ */
201
+ declare class TypeGenerator {
202
+ /**
203
+ * Generate TypeScript type definition from a Zod schema
204
+ *
205
+ * @param zodSchema - Zod schema object
206
+ * @param options - Generation options
207
+ * @returns TypeScript type definition as string
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * const schema = z.object({ name: z.string(), age: z.number() });
212
+ * const generator = new TypeGenerator();
213
+ * const typeCode = generator.generate(schema, { typeName: 'User' });
214
+ * // export type User = { name: string; age: number; };
215
+ * ```
216
+ */
217
+ generate(zodSchema: z.ZodTypeAny, options?: TypeGenerationOptions): string;
218
+ /**
219
+ * Generate type from Zod schema code string
220
+ *
221
+ * This is used when we have the schema as code (from ZodSchemaGenerator)
222
+ * rather than as a runtime Zod object.
223
+ *
224
+ * @param zodSchemaCode - Zod schema as TypeScript code string
225
+ * @param typeName - Name for the generated type
226
+ * @returns TypeScript type definition
227
+ */
228
+ generateFromCode(zodSchemaCode: string, typeName: string): string;
229
+ /**
230
+ * Generate multiple types from a map of Zod schemas
231
+ *
232
+ * @param schemas - Map of schema names to Zod schemas
233
+ * @returns Object with type definitions for each schema
234
+ */
235
+ generateMultiple(schemas: Record<string, z.ZodTypeAny>, options?: Omit<TypeGenerationOptions, 'typeName'>): Record<string, string>;
236
+ /**
237
+ * Combine multiple type definitions into a single TypeScript module
238
+ *
239
+ * @param types - Map of type names to type code
240
+ * @param imports - Additional imports to include
241
+ * @returns Complete TypeScript module code
242
+ */
243
+ createModule(types: Record<string, string>, imports?: string[]): string;
244
+ }
245
+
246
+ interface CollectionConfig {
247
+ /** API endpoint path */
248
+ endpoint: string;
249
+ /** Field to use as slug/ID */
250
+ slugField: string;
251
+ /** HTTP method (default: 'get') */
252
+ method?: string;
253
+ /** Collection name (defaults to sanitized endpoint) */
254
+ name?: string;
255
+ }
256
+ interface ProviderGenerationOptions {
257
+ /** Name for the provider class */
258
+ providerName?: string;
259
+ /** Base URL for the API */
260
+ baseUrl?: string;
261
+ /** Auth configuration */
262
+ auth?: {
263
+ type: 'bearer' | 'apiKey';
264
+ headerName?: string;
265
+ };
266
+ }
267
+ /**
268
+ * Generates CollectionProvider implementations from OpenAPI specs
269
+ *
270
+ * This is the bridge between OpenAPI APIs and Stackwright's content system.
271
+ */
272
+ declare class CollectionProviderGenerator {
273
+ private document;
274
+ constructor(document: OpenAPIDocument);
275
+ /**
276
+ * Generate a CollectionProvider implementation for a specific endpoint
277
+ *
278
+ * @param config - Collection configuration
279
+ * @param options - Generation options
280
+ * @returns TypeScript code for the provider
281
+ */
282
+ generate(config: CollectionConfig, options?: ProviderGenerationOptions): string;
283
+ /**
284
+ * Generate the complete provider code
285
+ */
286
+ private generateProviderCode;
287
+ /**
288
+ * Generate get method implementation
289
+ */
290
+ private generateGetMethod;
291
+ /**
292
+ * Generate auth header code
293
+ */
294
+ private generateAuthHeader;
295
+ /**
296
+ * Get base URL from OpenAPI spec
297
+ */
298
+ private getBaseUrl;
299
+ /**
300
+ * Generate provider class name from config
301
+ */
302
+ private generateProviderName;
303
+ /**
304
+ * Sanitize path to valid identifier
305
+ */
306
+ private sanitizePath;
307
+ /**
308
+ * Capitalize string
309
+ */
310
+ private capitalize;
311
+ /**
312
+ * Guess which field might be a good title
313
+ */
314
+ private guessTitle;
315
+ }
316
+
317
+ /**
318
+ * Mapping of operationId to schema names
319
+ */
320
+ interface SchemaMapping {
321
+ [operationId: string]: {
322
+ /** Schema name for request validation (null if no params) */
323
+ requestSchema: string | null;
324
+ /** Schema name for response validation */
325
+ responseSchema: string;
326
+ };
327
+ }
328
+ /**
329
+ * Options for client generation
330
+ */
331
+ interface ClientGenerationOptions {
332
+ /** Name of the client class */
333
+ className?: string;
334
+ /** Whether to include JSDoc comments (default: true) */
335
+ includeJsDoc?: boolean;
336
+ /** Base URL for the API */
337
+ baseUrl?: string;
338
+ /** Whether to validate responses with Zod (default: true) */
339
+ validateResponses?: boolean;
340
+ /** Use strict validation - throw on parse errors vs safe parse (default: false) */
341
+ strictValidation?: boolean;
342
+ /** Mapping of operationId to schema names for Zod validation */
343
+ schemaMapping?: SchemaMapping;
344
+ }
345
+ /**
346
+ * ClientGenerator
347
+ *
348
+ * Generates fully typed API client functions from OpenAPI operations.
349
+ * Each endpoint becomes a type-safe function with runtime Zod validation.
350
+ *
351
+ * **Refactored to use Zod schemas as single source of truth:**
352
+ * - Types inferred from Zod schemas (no more manual type generation)
353
+ * - Request validation before API calls
354
+ * - Response validation after API calls
355
+ * - Optional strict validation mode
356
+ */
357
+ declare class ClientGenerator {
358
+ private document;
359
+ private resolver;
360
+ private schemaMapping?;
361
+ private requiredSchemas;
362
+ constructor(document: OpenAPIDocument, schemaMapping?: SchemaMapping);
363
+ /**
364
+ * Generate typed API client code from OpenAPI document
365
+ */
366
+ generate(options?: ClientGenerationOptions): string;
367
+ /**
368
+ * Generate import statements including Zod and schemas
369
+ */
370
+ private generateImports;
371
+ /**
372
+ * Track which schemas are used for imports
373
+ */
374
+ private addRequiredSchema;
375
+ /**
376
+ * Generate Zod schemas for request parameters
377
+ *
378
+ * This generates schemas like:
379
+ * export const ListEquipmentRequestSchema = z.object({
380
+ * query: z.object({ ... }).optional(),
381
+ * });
382
+ */
383
+ private generateRequestSchemas;
384
+ /**
385
+ * Generate request schema for a single endpoint
386
+ */
387
+ private generateRequestSchemaForEndpoint;
388
+ /**
389
+ * Generate Zod schema for path parameters
390
+ */
391
+ private generatePathParamsSchema;
392
+ /**
393
+ * Generate Zod schema for query parameters
394
+ */
395
+ private generateQueryParamsSchema;
396
+ /**
397
+ * Generate Zod schema for header parameters
398
+ */
399
+ private generateHeaderParamsSchema;
400
+ /**
401
+ * Generate Zod schema for request body
402
+ */
403
+ private generateRequestBodySchema;
404
+ /**
405
+ * Convert parameter schema to Zod schema string
406
+ */
407
+ private parameterSchemaToZod;
408
+ /**
409
+ * Convert OpenAPI schema object to Zod schema string
410
+ *
411
+ * This is a simplified version for parameter schemas.
412
+ * Reuses logic similar to ZodSchemaGenerator but outputs inline.
413
+ */
414
+ private schemaObjectToZod;
415
+ /**
416
+ * Convert string schema to Zod
417
+ */
418
+ private stringSchemaToZod;
419
+ /**
420
+ * Convert number schema to Zod
421
+ */
422
+ private numberSchemaToZod;
423
+ /**
424
+ * Check if header is a common header handled by fetch
425
+ */
426
+ private isCommonHeader;
427
+ /**
428
+ * Extract component name from $ref
429
+ */
430
+ private extractComponentName;
431
+ /**
432
+ * Escape string for use in Zod .describe()
433
+ */
434
+ private escapeString;
435
+ /**
436
+ * Get list of all required schema names
437
+ */
438
+ private getRequiredSchemas;
439
+ /**
440
+ * Generate TypeScript types for request/response
441
+ *
442
+ * If schemaMapping is provided, use z.infer<> to get types from Zod schemas.
443
+ * Otherwise, fall back to legacy manual type generation.
444
+ */
445
+ private generateTypes;
446
+ /**
447
+ * Generate types using Zod inference (NEW)
448
+ */
449
+ /**
450
+ * Generate types using Zod inference (NEW)
451
+ *
452
+ * Request types infer from request schemas (defined in this file).
453
+ * Response types infer from response schemas (imported from ./schemas).
454
+ */
455
+ private generateTypesFromZod;
456
+ /**
457
+ * Generate types using manual conversion (LEGACY - backward compatible)
458
+ */
459
+ private generateTypesLegacy;
460
+ /**
461
+ * Generate request type for an operation (LEGACY)
462
+ */
463
+ private generateRequestTypeLegacy;
464
+ /**
465
+ * Generate response type for an operation (LEGACY)
466
+ */
467
+ private generateResponseTypeLegacy;
468
+ /**
469
+ * Get request body type (LEGACY)
470
+ */
471
+ private getRequestBodyTypeLegacy;
472
+ /**
473
+ * Convert OpenAPI schema to TypeScript type (LEGACY)
474
+ *
475
+ * NOTE: This method is kept for backward compatibility but should be
476
+ * replaced with Zod inference in new code.
477
+ */
478
+ private getTypeFromSchemaLegacy;
479
+ /**
480
+ * Generate error classes for API errors and validation errors
481
+ */
482
+ /**
483
+ * Generate error classes (APIError and ValidationError)
484
+ */
485
+ private generateErrorClasses;
486
+ /**
487
+ * Generate the main client class
488
+ */
489
+ private generateClientClass;
490
+ /**
491
+ * Generate constructor
492
+ */
493
+ private generateConstructor;
494
+ /**
495
+ * Generate a method for an endpoint with Zod validation (NEW)
496
+ */
497
+ /**
498
+ * Generate a method for an endpoint with Zod validation (NEW)
499
+ */
500
+ private generateMethodWithValidation;
501
+ /**
502
+ * Generate a method for an endpoint (LEGACY)
503
+ */
504
+ private generateMethodLegacy;
505
+ /**
506
+ * Generate the request helper method
507
+ */
508
+ private generateRequestHelper;
509
+ /**
510
+ * Get all endpoints from the document
511
+ */
512
+ private getAllEndpoints;
513
+ /**
514
+ * Get parameters for an operation
515
+ */
516
+ private getOperationParameters;
517
+ /**
518
+ * Check if operation has request body
519
+ */
520
+ private hasRequestBody;
521
+ /**
522
+ * Check if request body is required
523
+ */
524
+ private isRequestBodyRequired;
525
+ /**
526
+ * Get method name from endpoint
527
+ */
528
+ private getMethodName;
529
+ /**
530
+ * Get type name for operation
531
+ */
532
+ private getOperationTypeName;
533
+ /**
534
+ * Convert to camelCase
535
+ */
536
+ private camelCase;
537
+ /**
538
+ * Convert to PascalCase
539
+ */
540
+ private pascalCase;
541
+ /**
542
+ * Get default base URL from servers
543
+ */
544
+ private getDefaultBaseUrl;
545
+ /**
546
+ * Get API title
547
+ */
548
+ private getAPITitle;
549
+ /**
550
+ * Get API description
551
+ */
552
+ private getAPIDescription;
553
+ }
554
+
555
+ /**
556
+ * OpenAPICollectionProvider
557
+ *
558
+ * Runtime implementation of CollectionProvider for OpenAPI endpoints.
559
+ * This is the runtime component that actually fetches data.
560
+ */
561
+ declare class OpenAPICollectionProvider {
562
+ private baseUrl;
563
+ private auth?;
564
+ constructor(baseUrl: string, auth?: {
565
+ type: string;
566
+ token?: string;
567
+ apiKey?: string;
568
+ } | undefined);
569
+ /**
570
+ * Fetch items from an API endpoint
571
+ */
572
+ fetchItems(endpoint: string): Promise<unknown[]>;
573
+ /**
574
+ * Fetch a single item by slug
575
+ */
576
+ fetchItem(endpoint: string, slug: string): Promise<unknown>;
577
+ }
578
+
579
+ /**
580
+ * Prebuild plugin types
581
+ * TODO: Move to @stackwright/types package when created
582
+ */
583
+ interface PrebuildPluginContext {
584
+ /** Parsed site configuration from stackwright.yml */
585
+ siteConfig: Record<string, any>;
586
+ /** Project root directory */
587
+ projectRoot: string;
588
+ }
589
+ interface PrebuildPlugin {
590
+ /** Plugin name */
591
+ name: string;
592
+ /** Called before build starts */
593
+ beforeBuild?(context: PrebuildPluginContext): Promise<void>;
594
+ /** Called after build completes */
595
+ afterBuild?(context: PrebuildPluginContext): Promise<void>;
596
+ }
597
+ /**
598
+ * Prebuild plugin for OpenAPI integration
599
+ *
600
+ * Reads OpenAPI configuration from stackwright.yml and generates:
601
+ * - Zod validation schemas
602
+ * - TypeScript type definitions
603
+ * - CollectionProvider implementations
604
+ * - Typed API client functions
605
+ *
606
+ * All generated code is written to src/generated/{integrationName}/
607
+ */
608
+ declare class OpenAPIPlugin implements PrebuildPlugin {
609
+ name: string;
610
+ beforeBuild(context: PrebuildPluginContext): Promise<void>;
611
+ private processIntegration;
612
+ private generateSchemas;
613
+ private generateTypes;
614
+ private generateProvider;
615
+ private generateClient;
616
+ private extractComponentName;
617
+ private getOperationTypeName;
618
+ private generateOperationId;
619
+ private getResponseSchemaName;
620
+ private sanitizeName;
621
+ private capitalize;
622
+ }
623
+ /**
624
+ * Factory function to create the plugin instance
625
+ *
626
+ * Usage in user's prebuild script:
627
+ * ```typescript
628
+ * const { createOpenAPIPlugin } = require('@stackwright-pro/openapi/prebuild');
629
+ * runPrebuild({ plugins: [createOpenAPIPlugin()] });
630
+ * ```
631
+ */
632
+ declare function createOpenAPIPlugin(): PrebuildPlugin;
633
+
634
+ export { type ClientGenerationOptions, ClientGenerator, type CollectionConfig, CollectionProviderGenerator, OpenAPICollectionProvider, type OpenAPICompilationResult, type OpenAPIConfig, type OpenAPIDocument, OpenAPIParser, OpenAPIPlugin, type ParseOptions, type ParseResult, type ProviderGenerationOptions, type SchemaMapping, SchemaResolver, type TypeGenerationOptions, TypeGenerator, type ZodGenerationOptions, ZodSchemaGenerator, createOpenAPIPlugin };