@venturekit/runtime 0.0.0-dev.20260312012510 → 0.0.0-dev.20260329102450
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/README.md +1 -1
- package/dist/config/env.d.ts +62 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +98 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/secrets.d.ts +67 -0
- package/dist/config/secrets.d.ts.map +1 -0
- package/dist/config/secrets.js +132 -0
- package/dist/config/secrets.js.map +1 -0
- package/dist/handler/adapter.d.ts.map +1 -0
- package/dist/{adapter.js → handler/adapter.js} +5 -44
- package/dist/handler/adapter.js.map +1 -0
- package/dist/{context.d.ts → handler/context.d.ts} +44 -3
- package/dist/handler/context.d.ts.map +1 -0
- package/dist/{context.js → handler/context.js} +9 -9
- package/dist/handler/context.js.map +1 -0
- package/dist/handler/errors.d.ts.map +1 -0
- package/dist/{errors.js → handler/errors.js} +11 -25
- package/dist/handler/errors.js.map +1 -0
- package/dist/{handler.d.ts → handler/handler.d.ts} +36 -3
- package/dist/handler/handler.d.ts.map +1 -0
- package/dist/{handler.js → handler/handler.js} +59 -23
- package/dist/handler/handler.js.map +1 -0
- package/dist/handler/response.d.ts.map +1 -0
- package/dist/{response.js → handler/response.js} +9 -17
- package/dist/handler/response.js.map +1 -0
- package/dist/handler/task-handler.d.ts +192 -0
- package/dist/handler/task-handler.d.ts.map +1 -0
- package/dist/handler/task-handler.js +262 -0
- package/dist/handler/task-handler.js.map +1 -0
- package/dist/index.d.ts +33 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -48
- package/dist/index.js.map +1 -1
- package/dist/{logger.d.ts → logging/logger.d.ts} +1 -1
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/{logger.js → logging/logger.js} +8 -16
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/tracing.d.ts +51 -0
- package/dist/logging/tracing.d.ts.map +1 -0
- package/dist/logging/tracing.js +77 -0
- package/dist/logging/tracing.js.map +1 -0
- package/dist/middleware/middleware.d.ts +120 -0
- package/dist/middleware/middleware.d.ts.map +1 -0
- package/dist/middleware/middleware.js +270 -0
- package/dist/middleware/middleware.js.map +1 -0
- package/dist/middleware/rate-limit-store.d.ts +153 -0
- package/dist/middleware/rate-limit-store.d.ts.map +1 -0
- package/dist/middleware/rate-limit-store.js +182 -0
- package/dist/middleware/rate-limit-store.js.map +1 -0
- package/dist/openapi/openapi.d.ts +147 -0
- package/dist/openapi/openapi.d.ts.map +1 -0
- package/dist/openapi/openapi.js +235 -0
- package/dist/openapi/openapi.js.map +1 -0
- package/dist/openapi.d.ts +10 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +9 -0
- package/dist/openapi.js.map +1 -0
- package/dist/patterns/circuit-breaker.d.ts +78 -0
- package/dist/patterns/circuit-breaker.d.ts.map +1 -0
- package/dist/patterns/circuit-breaker.js +113 -0
- package/dist/patterns/circuit-breaker.js.map +1 -0
- package/dist/patterns/idempotency.d.ts +175 -0
- package/dist/patterns/idempotency.d.ts.map +1 -0
- package/dist/patterns/idempotency.js +305 -0
- package/dist/patterns/idempotency.js.map +1 -0
- package/dist/patterns/invoke.d.ts +279 -0
- package/dist/patterns/invoke.d.ts.map +1 -0
- package/dist/patterns/invoke.js +581 -0
- package/dist/patterns/invoke.js.map +1 -0
- package/dist/patterns/saga.d.ts +391 -0
- package/dist/patterns/saga.d.ts.map +1 -0
- package/dist/patterns/saga.js +556 -0
- package/dist/patterns/saga.js.map +1 -0
- package/dist/patterns.d.ts +17 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +17 -0
- package/dist/patterns.js.map +1 -0
- package/dist/rate-limit.d.ts +16 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +15 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/secrets.d.ts +11 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +10 -0
- package/dist/secrets.js.map +1 -0
- package/dist/testing/test-utils.d.ts +99 -0
- package/dist/testing/test-utils.d.ts.map +1 -0
- package/dist/testing/test-utils.js +153 -0
- package/dist/testing/test-utils.js.map +1 -0
- package/dist/testing.d.ts +10 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +9 -0
- package/dist/testing.js.map +1 -0
- package/dist/ws/ws.d.ts +139 -0
- package/dist/ws/ws.d.ts.map +1 -0
- package/dist/ws/ws.js +294 -0
- package/dist/ws/ws.js.map +1 -0
- package/dist/ws.d.ts +5 -133
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +4 -291
- package/dist/ws.js.map +1 -1
- package/package.json +47 -5
- package/dist/adapter.d.ts.map +0 -1
- package/dist/adapter.js.map +0 -1
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/handler.d.ts.map +0 -1
- package/dist/handler.js.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/middleware.d.ts +0 -47
- package/dist/middleware.d.ts.map +0 -1
- package/dist/middleware.js +0 -147
- package/dist/middleware.js.map +0 -1
- package/dist/response.d.ts.map +0 -1
- package/dist/response.js.map +0 -1
- /package/dist/{adapter.d.ts → handler/adapter.d.ts} +0 -0
- /package/dist/{errors.d.ts → handler/errors.d.ts} +0 -0
- /package/dist/{response.d.ts → handler/response.d.ts} +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VentureKit Rate Limit Stores
|
|
3
|
+
*
|
|
4
|
+
* Pluggable backends for the rateLimitMiddleware.
|
|
5
|
+
*
|
|
6
|
+
* - `createDynamoDBRateLimitStore()` — production-ready, distributed
|
|
7
|
+
* - `createMemoryRateLimitStore()` — for local dev/testing only
|
|
8
|
+
* - `createDefaultRateLimiter()` — zero-config rate limiter with sensible defaults
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Built-in rate limit presets covering common requirements.
|
|
12
|
+
*
|
|
13
|
+
* | Preset | Limit | Window | Use Case |
|
|
14
|
+
* |------------|---------|--------|---------------------------------------|
|
|
15
|
+
* | `relaxed` | 200/min | 60s | Internal APIs, dev environments |
|
|
16
|
+
* | `standard` | 100/min | 60s | Public APIs, most production needs |
|
|
17
|
+
* | `strict` | 20/min | 60s | Auth endpoints, sensitive operations |
|
|
18
|
+
* | `api-key` | 1000/min| 60s | Authenticated API-key consumers |
|
|
19
|
+
*/
|
|
20
|
+
export const RATE_LIMIT_PRESETS = {
|
|
21
|
+
relaxed: { limit: 200, windowMs: 60_000 },
|
|
22
|
+
standard: { limit: 100, windowMs: 60_000 },
|
|
23
|
+
strict: { limit: 20, windowMs: 60_000 },
|
|
24
|
+
'api-key': { limit: 1000, windowMs: 60_000 },
|
|
25
|
+
};
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// In-memory store (dev / testing only)
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Create an in-memory rate limit check function.
|
|
31
|
+
*
|
|
32
|
+
* **WARNING:** This stores counters in the Lambda process memory.
|
|
33
|
+
* It does NOT work correctly with multiple Lambda instances.
|
|
34
|
+
* Use only for local development and testing.
|
|
35
|
+
*
|
|
36
|
+
* For production, use `createDynamoDBRateLimitStore()`.
|
|
37
|
+
*/
|
|
38
|
+
export function createMemoryRateLimitStore(options) {
|
|
39
|
+
const presetConfig = options?.preset ? RATE_LIMIT_PRESETS[options.preset] : undefined;
|
|
40
|
+
const limit = options?.limit ?? presetConfig?.limit ?? 100;
|
|
41
|
+
const windowMs = options?.windowMs ?? presetConfig?.windowMs ?? 60_000;
|
|
42
|
+
const counters = new Map();
|
|
43
|
+
return async (key) => {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
let entry = counters.get(key);
|
|
46
|
+
// Reset expired window
|
|
47
|
+
if (!entry || now >= entry.resetAt) {
|
|
48
|
+
entry = { count: 0, resetAt: now + windowMs };
|
|
49
|
+
counters.set(key, entry);
|
|
50
|
+
}
|
|
51
|
+
entry.count++;
|
|
52
|
+
const allowed = entry.count <= limit;
|
|
53
|
+
const remaining = Math.max(0, limit - entry.count);
|
|
54
|
+
return { allowed, remaining, limit, resetAt: entry.resetAt };
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a DynamoDB-backed rate limit check function.
|
|
59
|
+
*
|
|
60
|
+
* Uses atomic `UpdateItem` with `ADD` to safely increment counters
|
|
61
|
+
* across multiple Lambda instances. Expired entries are automatically
|
|
62
|
+
* cleaned up via DynamoDB TTL.
|
|
63
|
+
*
|
|
64
|
+
* ### DynamoDB Table Schema
|
|
65
|
+
*
|
|
66
|
+
* The table must have:
|
|
67
|
+
* - **Partition key:** `pk` (String) — the rate limit key
|
|
68
|
+
* - **TTL attribute:** `ttl` (Number) — epoch seconds for auto-cleanup
|
|
69
|
+
*
|
|
70
|
+
* You can create this table via infrastructure intents or manually:
|
|
71
|
+
*
|
|
72
|
+
* ```bash
|
|
73
|
+
* aws dynamodb create-table \
|
|
74
|
+
* --table-name venturekit-rate-limits \
|
|
75
|
+
* --attribute-definitions AttributeName=pk,AttributeType=S \
|
|
76
|
+
* --key-schema AttributeName=pk,KeyType=HASH \
|
|
77
|
+
* --billing-mode PAY_PER_REQUEST
|
|
78
|
+
*
|
|
79
|
+
* aws dynamodb update-time-to-live \
|
|
80
|
+
* --table-name venturekit-rate-limits \
|
|
81
|
+
* --time-to-live-specification "Enabled=true, AttributeName=ttl"
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { rateLimitMiddleware } from '@venturekit/runtime';
|
|
87
|
+
* import { createDynamoDBRateLimitStore } from '@venturekit/runtime';
|
|
88
|
+
*
|
|
89
|
+
* const rateLimit = rateLimitMiddleware({
|
|
90
|
+
* check: await createDynamoDBRateLimitStore({ preset: 'standard' }),
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export async function createDynamoDBRateLimitStore(options = {}) {
|
|
95
|
+
const tableName = options.tableName
|
|
96
|
+
|| process.env.VENTURE_RATE_LIMIT_TABLE
|
|
97
|
+
|| 'venturekit-rate-limits';
|
|
98
|
+
const presetConfig = options.preset ? RATE_LIMIT_PRESETS[options.preset] : undefined;
|
|
99
|
+
const limit = options.limit ?? presetConfig?.limit ?? 100;
|
|
100
|
+
const windowMs = options.windowMs ?? presetConfig?.windowMs ?? 60_000;
|
|
101
|
+
const region = options.region || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
|
|
102
|
+
// Lazy-load AWS SDK
|
|
103
|
+
const { DynamoDBClient, UpdateItemCommand } = await import('@aws-sdk/client-dynamodb');
|
|
104
|
+
const client = new DynamoDBClient({ region });
|
|
105
|
+
return async (key) => {
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
const windowStart = Math.floor(now / windowMs) * windowMs;
|
|
108
|
+
const resetAt = windowStart + windowMs;
|
|
109
|
+
const ttl = Math.ceil(resetAt / 1000) + 60; // TTL: window end + 60s buffer
|
|
110
|
+
// Composite key includes the window to auto-rotate
|
|
111
|
+
const pk = `${key}#${windowStart}`;
|
|
112
|
+
try {
|
|
113
|
+
const result = await client.send(new UpdateItemCommand({
|
|
114
|
+
TableName: tableName,
|
|
115
|
+
Key: { pk: { S: pk } },
|
|
116
|
+
UpdateExpression: 'ADD #count :inc SET #ttl = if_not_exists(#ttl, :ttl), #resetAt = if_not_exists(#resetAt, :resetAt)',
|
|
117
|
+
ExpressionAttributeNames: {
|
|
118
|
+
'#count': 'count',
|
|
119
|
+
'#ttl': 'ttl',
|
|
120
|
+
'#resetAt': 'resetAt',
|
|
121
|
+
},
|
|
122
|
+
ExpressionAttributeValues: {
|
|
123
|
+
':inc': { N: '1' },
|
|
124
|
+
':ttl': { N: String(ttl) },
|
|
125
|
+
':resetAt': { N: String(resetAt) },
|
|
126
|
+
},
|
|
127
|
+
ReturnValues: 'ALL_NEW',
|
|
128
|
+
}));
|
|
129
|
+
const count = parseInt(result.Attributes?.count?.N || '1', 10);
|
|
130
|
+
const allowed = count <= limit;
|
|
131
|
+
const remaining = Math.max(0, limit - count);
|
|
132
|
+
return { allowed, remaining, limit, resetAt };
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
// On DynamoDB failure, fail open (allow the request)
|
|
136
|
+
// This prevents rate limiter outages from blocking all traffic
|
|
137
|
+
console.error('[VentureKit] Rate limit DynamoDB error (failing open):', err);
|
|
138
|
+
return { allowed: true, remaining: limit, limit, resetAt: now + windowMs };
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Create a rate limit check function with sensible defaults.
|
|
144
|
+
*
|
|
145
|
+
* - In production (Lambda): uses DynamoDB for distributed rate limiting
|
|
146
|
+
* - In local dev: uses in-memory store
|
|
147
|
+
*
|
|
148
|
+
* This is the recommended way to add rate limiting with minimal configuration.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* import { rateLimitMiddleware } from '@venturekit/runtime';
|
|
153
|
+
* import { createDefaultRateLimiter } from '@venturekit/runtime';
|
|
154
|
+
*
|
|
155
|
+
* // Zero-config — uses 'standard' preset (100 req/min)
|
|
156
|
+
* const rateLimit = rateLimitMiddleware({
|
|
157
|
+
* check: await createDefaultRateLimiter(),
|
|
158
|
+
* });
|
|
159
|
+
*
|
|
160
|
+
* // Strict for auth endpoints
|
|
161
|
+
* const authRateLimit = rateLimitMiddleware({
|
|
162
|
+
* check: await createDefaultRateLimiter({ preset: 'strict' }),
|
|
163
|
+
* });
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
export async function createDefaultRateLimiter(options = {}) {
|
|
167
|
+
const isLocal = !process.env.AWS_LAMBDA_FUNCTION_NAME && !process.env.AWS_EXECUTION_ENV;
|
|
168
|
+
if (isLocal || options.forceMemory) {
|
|
169
|
+
return createMemoryRateLimitStore({
|
|
170
|
+
preset: options.preset,
|
|
171
|
+
limit: options.limit,
|
|
172
|
+
windowMs: options.windowMs,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return createDynamoDBRateLimitStore({
|
|
176
|
+
preset: options.preset,
|
|
177
|
+
limit: options.limit,
|
|
178
|
+
windowMs: options.windowMs,
|
|
179
|
+
tableName: options.tableName,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=rate-limit-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit-store.js","sourceRoot":"","sources":["../../src/middleware/rate-limit-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VentureKit OpenAPI Spec Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates OpenAPI 3.1 specs from route definitions.
|
|
5
|
+
* Works with file-based routing convention:
|
|
6
|
+
* src/routes/<path>/<method>.ts → <METHOD> /<path>
|
|
7
|
+
*
|
|
8
|
+
* Supports Zod-like schema extraction for request/response docs.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* HTTP methods supported by VentureKit
|
|
12
|
+
*/
|
|
13
|
+
export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
14
|
+
/**
|
|
15
|
+
* JSON Schema subset for OpenAPI
|
|
16
|
+
*/
|
|
17
|
+
export interface JsonSchema {
|
|
18
|
+
type?: string;
|
|
19
|
+
properties?: Record<string, JsonSchema>;
|
|
20
|
+
items?: JsonSchema;
|
|
21
|
+
required?: string[];
|
|
22
|
+
description?: string;
|
|
23
|
+
enum?: (string | number)[];
|
|
24
|
+
format?: string;
|
|
25
|
+
example?: unknown;
|
|
26
|
+
nullable?: boolean;
|
|
27
|
+
oneOf?: JsonSchema[];
|
|
28
|
+
anyOf?: JsonSchema[];
|
|
29
|
+
allOf?: JsonSchema[];
|
|
30
|
+
$ref?: string;
|
|
31
|
+
additionalProperties?: boolean | JsonSchema;
|
|
32
|
+
default?: unknown;
|
|
33
|
+
minimum?: number;
|
|
34
|
+
maximum?: number;
|
|
35
|
+
minLength?: number;
|
|
36
|
+
maxLength?: number;
|
|
37
|
+
pattern?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Route definition for OpenAPI generation
|
|
41
|
+
*/
|
|
42
|
+
export interface RouteDefinition {
|
|
43
|
+
/** HTTP method */
|
|
44
|
+
method: HttpMethod;
|
|
45
|
+
/** Path (e.g., "/tasks", "/tasks/{id}") */
|
|
46
|
+
path: string;
|
|
47
|
+
/** Operation summary */
|
|
48
|
+
summary?: string;
|
|
49
|
+
/** Operation description */
|
|
50
|
+
description?: string;
|
|
51
|
+
/** Operation tags */
|
|
52
|
+
tags?: string[];
|
|
53
|
+
/** Required scopes (maps to security) */
|
|
54
|
+
scopes?: string[];
|
|
55
|
+
/** Request body schema */
|
|
56
|
+
requestBody?: JsonSchema;
|
|
57
|
+
/** Query parameter schemas (key → schema; mark required via `queryRequired` array) */
|
|
58
|
+
queryParams?: Record<string, JsonSchema>;
|
|
59
|
+
/** Which query params are required */
|
|
60
|
+
queryRequired?: string[];
|
|
61
|
+
/** Path parameter schemas */
|
|
62
|
+
pathParams?: Record<string, JsonSchema>;
|
|
63
|
+
/** Response schema (for success response) */
|
|
64
|
+
response?: JsonSchema;
|
|
65
|
+
/** Response status code */
|
|
66
|
+
statusCode?: number;
|
|
67
|
+
/** Whether the route is deprecated */
|
|
68
|
+
deprecated?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* OpenAPI info block
|
|
72
|
+
*/
|
|
73
|
+
export interface OpenAPIInfo {
|
|
74
|
+
title: string;
|
|
75
|
+
version: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
contact?: {
|
|
78
|
+
name?: string;
|
|
79
|
+
email?: string;
|
|
80
|
+
url?: string;
|
|
81
|
+
};
|
|
82
|
+
license?: {
|
|
83
|
+
name: string;
|
|
84
|
+
url?: string;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* OpenAPI server block
|
|
89
|
+
*/
|
|
90
|
+
export interface OpenAPIServer {
|
|
91
|
+
url: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* OpenAPI generator options
|
|
96
|
+
*/
|
|
97
|
+
export interface OpenAPIGeneratorOptions {
|
|
98
|
+
info: OpenAPIInfo;
|
|
99
|
+
servers?: OpenAPIServer[];
|
|
100
|
+
/** Security scheme name for authenticated routes */
|
|
101
|
+
securitySchemeName?: string;
|
|
102
|
+
/** Default tags applied to all routes */
|
|
103
|
+
defaultTags?: string[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* OpenAPI 3.1 document (simplified)
|
|
107
|
+
*/
|
|
108
|
+
export interface OpenAPIDocument {
|
|
109
|
+
openapi: string;
|
|
110
|
+
info: OpenAPIInfo;
|
|
111
|
+
servers?: OpenAPIServer[];
|
|
112
|
+
paths: Record<string, Record<string, unknown>>;
|
|
113
|
+
components?: {
|
|
114
|
+
securitySchemes?: Record<string, unknown>;
|
|
115
|
+
schemas?: Record<string, JsonSchema>;
|
|
116
|
+
};
|
|
117
|
+
tags?: Array<{
|
|
118
|
+
name: string;
|
|
119
|
+
description?: string;
|
|
120
|
+
}>;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Generate an OpenAPI 3.1 document from route definitions
|
|
124
|
+
*/
|
|
125
|
+
export declare function generateOpenAPISpec(routes: RouteDefinition[], options: OpenAPIGeneratorOptions): OpenAPIDocument;
|
|
126
|
+
/**
|
|
127
|
+
* Convert file-based route paths to OpenAPI paths.
|
|
128
|
+
*
|
|
129
|
+
* Converts:
|
|
130
|
+
* "tasks" → "/tasks"
|
|
131
|
+
* "tasks/[id]" → "/tasks/{id}"
|
|
132
|
+
* "users/[userId]/posts" → "/users/{userId}/posts"
|
|
133
|
+
*/
|
|
134
|
+
export declare function filePathToOpenAPI(filePath: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* Infer route tag from path (first segment)
|
|
137
|
+
*/
|
|
138
|
+
export declare function inferTag(path: string): string;
|
|
139
|
+
/**
|
|
140
|
+
* Serialize OpenAPI document to JSON
|
|
141
|
+
*/
|
|
142
|
+
export declare function serializeOpenAPI(doc: OpenAPIDocument, pretty?: boolean): string;
|
|
143
|
+
/**
|
|
144
|
+
* Serialize OpenAPI document to YAML-like format (simple, no dependency)
|
|
145
|
+
*/
|
|
146
|
+
export declare function serializeOpenAPIYaml(doc: OpenAPIDocument): string;
|
|
147
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/openapi/openapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VentureKit OpenAPI Spec Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates OpenAPI 3.1 specs from route definitions.
|
|
5
|
+
* Works with file-based routing convention:
|
|
6
|
+
* src/routes/<path>/<method>.ts → <METHOD> /<path>
|
|
7
|
+
*
|
|
8
|
+
* Supports Zod-like schema extraction for request/response docs.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Build a parameter object for OpenAPI
|
|
12
|
+
*/
|
|
13
|
+
function buildParameter(name, location, schema, isRequired) {
|
|
14
|
+
return {
|
|
15
|
+
name,
|
|
16
|
+
in: location,
|
|
17
|
+
required: location === 'path' ? true : isRequired ?? false,
|
|
18
|
+
schema: { type: schema.type ?? 'string', ...(schema.enum ? { enum: schema.enum } : {}), ...(schema.description ? { description: schema.description } : {}) },
|
|
19
|
+
...(schema.description ? { description: schema.description } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Build a request body object for OpenAPI
|
|
24
|
+
*/
|
|
25
|
+
function buildRequestBody(schema) {
|
|
26
|
+
return {
|
|
27
|
+
required: true,
|
|
28
|
+
content: {
|
|
29
|
+
'application/json': {
|
|
30
|
+
schema,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build response objects for OpenAPI
|
|
37
|
+
*/
|
|
38
|
+
function buildResponses(route) {
|
|
39
|
+
const statusCode = route.statusCode ?? (route.method === 'post' ? 201 : route.method === 'delete' ? 204 : 200);
|
|
40
|
+
const responses = {};
|
|
41
|
+
if (statusCode === 204) {
|
|
42
|
+
responses['204'] = { description: 'No Content' };
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const responseObj = {
|
|
46
|
+
description: statusCode === 201 ? 'Created' : 'OK',
|
|
47
|
+
};
|
|
48
|
+
if (route.response) {
|
|
49
|
+
responseObj.content = {
|
|
50
|
+
'application/json': {
|
|
51
|
+
schema: route.response,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
responses[String(statusCode)] = responseObj;
|
|
56
|
+
}
|
|
57
|
+
// Standard error responses
|
|
58
|
+
if (route.scopes && route.scopes.length > 0) {
|
|
59
|
+
responses['401'] = { description: 'Unauthorized' };
|
|
60
|
+
responses['403'] = { description: 'Forbidden' };
|
|
61
|
+
}
|
|
62
|
+
return responses;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate an OpenAPI 3.1 document from route definitions
|
|
66
|
+
*/
|
|
67
|
+
export function generateOpenAPISpec(routes, options) {
|
|
68
|
+
const { info, servers, securitySchemeName = 'bearerAuth', defaultTags, } = options;
|
|
69
|
+
const paths = {};
|
|
70
|
+
const tagSet = new Set();
|
|
71
|
+
let hasAuthRoutes = false;
|
|
72
|
+
for (const route of routes) {
|
|
73
|
+
const openapiPath = route.path;
|
|
74
|
+
if (!paths[openapiPath]) {
|
|
75
|
+
paths[openapiPath] = {};
|
|
76
|
+
}
|
|
77
|
+
// Build parameters
|
|
78
|
+
const parameters = [];
|
|
79
|
+
// Path parameters (always required)
|
|
80
|
+
if (route.pathParams) {
|
|
81
|
+
for (const [name, schema] of Object.entries(route.pathParams)) {
|
|
82
|
+
parameters.push(buildParameter(name, 'path', schema));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Query parameters
|
|
86
|
+
if (route.queryParams) {
|
|
87
|
+
for (const [name, schema] of Object.entries(route.queryParams)) {
|
|
88
|
+
const isRequired = route.queryRequired?.includes(name) ?? false;
|
|
89
|
+
parameters.push(buildParameter(name, 'query', schema, isRequired));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Build operation
|
|
93
|
+
const operation = {};
|
|
94
|
+
if (route.summary)
|
|
95
|
+
operation.summary = route.summary;
|
|
96
|
+
if (route.description)
|
|
97
|
+
operation.description = route.description;
|
|
98
|
+
if (route.deprecated)
|
|
99
|
+
operation.deprecated = true;
|
|
100
|
+
// Tags
|
|
101
|
+
const tags = [...(defaultTags ?? []), ...(route.tags ?? [])];
|
|
102
|
+
if (tags.length > 0) {
|
|
103
|
+
operation.tags = tags;
|
|
104
|
+
for (const tag of tags)
|
|
105
|
+
tagSet.add(tag);
|
|
106
|
+
}
|
|
107
|
+
// Parameters
|
|
108
|
+
if (parameters.length > 0) {
|
|
109
|
+
operation.parameters = parameters;
|
|
110
|
+
}
|
|
111
|
+
// Request body
|
|
112
|
+
if (route.requestBody && ['post', 'put', 'patch'].includes(route.method)) {
|
|
113
|
+
operation.requestBody = buildRequestBody(route.requestBody);
|
|
114
|
+
}
|
|
115
|
+
// Responses
|
|
116
|
+
operation.responses = buildResponses(route);
|
|
117
|
+
// Security
|
|
118
|
+
if (route.scopes && route.scopes.length > 0) {
|
|
119
|
+
hasAuthRoutes = true;
|
|
120
|
+
operation.security = [{ [securitySchemeName]: route.scopes }];
|
|
121
|
+
}
|
|
122
|
+
paths[openapiPath][route.method] = operation;
|
|
123
|
+
}
|
|
124
|
+
// Build document
|
|
125
|
+
const doc = {
|
|
126
|
+
openapi: '3.1.0',
|
|
127
|
+
info,
|
|
128
|
+
paths,
|
|
129
|
+
};
|
|
130
|
+
if (servers && servers.length > 0) {
|
|
131
|
+
doc.servers = servers;
|
|
132
|
+
}
|
|
133
|
+
// Tags
|
|
134
|
+
if (tagSet.size > 0) {
|
|
135
|
+
doc.tags = Array.from(tagSet)
|
|
136
|
+
.sort()
|
|
137
|
+
.map(name => ({ name }));
|
|
138
|
+
}
|
|
139
|
+
// Security schemes
|
|
140
|
+
if (hasAuthRoutes) {
|
|
141
|
+
doc.components = {
|
|
142
|
+
securitySchemes: {
|
|
143
|
+
[securitySchemeName]: {
|
|
144
|
+
type: 'http',
|
|
145
|
+
scheme: 'bearer',
|
|
146
|
+
bearerFormat: 'JWT',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return doc;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Convert file-based route paths to OpenAPI paths.
|
|
155
|
+
*
|
|
156
|
+
* Converts:
|
|
157
|
+
* "tasks" → "/tasks"
|
|
158
|
+
* "tasks/[id]" → "/tasks/{id}"
|
|
159
|
+
* "users/[userId]/posts" → "/users/{userId}/posts"
|
|
160
|
+
*/
|
|
161
|
+
export function filePathToOpenAPI(filePath) {
|
|
162
|
+
let result = filePath
|
|
163
|
+
.replace(/\[([^\]]+)\]/g, '{$1}') // [id] → {id}
|
|
164
|
+
.replace(/\\/g, '/'); // backslash → forward slash
|
|
165
|
+
if (!result.startsWith('/')) {
|
|
166
|
+
result = '/' + result;
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Infer route tag from path (first segment)
|
|
172
|
+
*/
|
|
173
|
+
export function inferTag(path) {
|
|
174
|
+
const segments = path.replace(/^\//, '').split('/');
|
|
175
|
+
return segments[0] || 'default';
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Serialize OpenAPI document to JSON
|
|
179
|
+
*/
|
|
180
|
+
export function serializeOpenAPI(doc, pretty = true) {
|
|
181
|
+
return JSON.stringify(doc, null, pretty ? 2 : undefined);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Serialize OpenAPI document to YAML-like format (simple, no dependency)
|
|
185
|
+
*/
|
|
186
|
+
export function serializeOpenAPIYaml(doc) {
|
|
187
|
+
return toYaml(doc, 0);
|
|
188
|
+
}
|
|
189
|
+
function toYaml(value, indent) {
|
|
190
|
+
const pad = ' '.repeat(indent);
|
|
191
|
+
if (value === null || value === undefined)
|
|
192
|
+
return 'null';
|
|
193
|
+
if (typeof value === 'boolean')
|
|
194
|
+
return String(value);
|
|
195
|
+
if (typeof value === 'number')
|
|
196
|
+
return String(value);
|
|
197
|
+
if (typeof value === 'string') {
|
|
198
|
+
if (value.includes('\n') || value.includes(':') || value.includes('#') || value.includes('"')) {
|
|
199
|
+
return `"${value.replace(/"/g, '\\"')}"`;
|
|
200
|
+
}
|
|
201
|
+
return value;
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
if (value.length === 0)
|
|
205
|
+
return '[]';
|
|
206
|
+
const items = value.map(item => {
|
|
207
|
+
const serialized = toYaml(item, indent + 1);
|
|
208
|
+
if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
|
|
209
|
+
return `${pad}- ${serialized.trimStart()}`;
|
|
210
|
+
}
|
|
211
|
+
return `${pad}- ${serialized}`;
|
|
212
|
+
});
|
|
213
|
+
return '\n' + items.join('\n');
|
|
214
|
+
}
|
|
215
|
+
if (typeof value === 'object') {
|
|
216
|
+
const obj = value;
|
|
217
|
+
const keys = Object.keys(obj);
|
|
218
|
+
if (keys.length === 0)
|
|
219
|
+
return '{}';
|
|
220
|
+
const lines = keys.map(key => {
|
|
221
|
+
const val = obj[key];
|
|
222
|
+
const serialized = toYaml(val, indent + 1);
|
|
223
|
+
if (typeof val === 'object' && val !== null && !Array.isArray(val) && Object.keys(val).length > 0) {
|
|
224
|
+
return `${pad}${key}:\n${serialized}`;
|
|
225
|
+
}
|
|
226
|
+
if (Array.isArray(val) && val.length > 0) {
|
|
227
|
+
return `${pad}${key}:${serialized}`;
|
|
228
|
+
}
|
|
229
|
+
return `${pad}${key}: ${serialized}`;
|
|
230
|
+
});
|
|
231
|
+
return lines.join('\n');
|
|
232
|
+
}
|
|
233
|
+
return String(value);
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/openapi/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+GH;;GAEG;AACH,SAAS,cAAc,CACrB,IAAY,EACZ,QAA0B,EAC1B,MAAkB,EAClB,UAAoB;IAEpB,OAAO;QACL,IAAI;QACJ,EAAE,EAAE,QAAQ;QACZ,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK;QAC1D,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;QAC5J,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,MAAkB;IAC1C,OAAO;QACL,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE;YACP,kBAAkB,EAAE;gBAClB,MAAM;aACP;SACF;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,KAAsB;IAEtB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/G,MAAM,SAAS,GAA4B,EAAE,CAAC;IAE9C,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAA4B;YAC3C,WAAW,EAAE,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;SACnD,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,WAAW,CAAC,OAAO,GAAG;gBACpB,kBAAkB,EAAE;oBAClB,MAAM,EAAE,KAAK,CAAC,QAAQ;iBACvB;aACF,CAAC;QACJ,CAAC;QACD,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,WAAW,CAAC;IAC9C,CAAC;IAED,2BAA2B;IAC3B,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;QACnD,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAyB,EACzB,OAAgC;IAEhC,MAAM,EACJ,IAAI,EACJ,OAAO,EACP,kBAAkB,GAAG,YAAY,EACjC,WAAW,GACZ,GAAG,OAAO,CAAC;IAEZ,MAAM,KAAK,GAA4C,EAAE,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;QAE/B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,mBAAmB;QACnB,MAAM,UAAU,GAA8B,EAAE,CAAC;QAEjD,oCAAoC;QACpC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9D,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC/D,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;gBAChE,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,MAAM,SAAS,GAA4B,EAAE,CAAC;QAE9C,IAAI,KAAK,CAAC,OAAO;YAAE,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACrD,IAAI,KAAK,CAAC,WAAW;YAAE,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACjE,IAAI,KAAK,CAAC,UAAU;YAAE,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;QAElD,OAAO;QACP,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;YACtB,KAAK,MAAM,GAAG,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QAED,aAAa;QACb,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC;QACpC,CAAC;QAED,eAAe;QACf,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACzE,SAAS,CAAC,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9D,CAAC;QAED,YAAY;QACZ,SAAS,CAAC,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAE5C,WAAW;QACX,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,aAAa,GAAG,IAAI,CAAC;YACrB,SAAS,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC/C,CAAC;IAED,iBAAiB;IACjB,MAAM,GAAG,GAAoB;QAC3B,OAAO,EAAE,OAAO;QAChB,IAAI;QACJ,KAAK;KACN,CAAC;IAEF,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,OAAO;IACP,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACpB,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;aAC1B,IAAI,EAAE;aACN,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC;IAED,mBAAmB;IACnB,IAAI,aAAa,EAAE,CAAC;QAClB,GAAG,CAAC,UAAU,GAAG;YACf,eAAe,EAAE;gBACf,CAAC,kBAAkB,CAAC,EAAE;oBACpB,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,QAAQ;oBAChB,YAAY,EAAE,KAAK;iBACpB;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,MAAM,GAAG,QAAQ;SAClB,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAE,cAAc;SAChD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAgB,4BAA4B;IAEnE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAoB,EAAE,SAAkB,IAAI;IAC3E,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAoB;IACvD,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,MAAc;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9F,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;QAC3C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;YAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtE,OAAO,GAAG,GAAG,KAAK,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;YAC7C,CAAC;YACD,OAAO,GAAG,GAAG,KAAK,UAAU,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAA8B,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7H,OAAO,GAAG,GAAG,GAAG,GAAG,MAAM,UAAU,EAAE,CAAC;YACxC,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzC,OAAO,GAAG,GAAG,GAAG,GAAG,IAAI,UAAU,EAAE,CAAC;YACtC,CAAC;YACD,OAAO,GAAG,GAAG,GAAG,GAAG,KAAK,UAAU,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @venturekit/runtime/openapi
|
|
3
|
+
*
|
|
4
|
+
* OpenAPI spec generation from VentureKit route definitions.
|
|
5
|
+
*
|
|
6
|
+
* Import via: `import { generateOpenAPISpec } from '@venturekit/runtime/openapi'`
|
|
7
|
+
*/
|
|
8
|
+
export { generateOpenAPISpec, filePathToOpenAPI, inferTag, serializeOpenAPI, serializeOpenAPIYaml, } from './openapi/openapi.js';
|
|
9
|
+
export type { HttpMethod, JsonSchema, RouteDefinition, OpenAPIInfo, OpenAPIServer, OpenAPIGeneratorOptions, OpenAPIDocument, } from './openapi/openapi.js';
|
|
10
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|
package/dist/openapi.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @venturekit/runtime/openapi
|
|
3
|
+
*
|
|
4
|
+
* OpenAPI spec generation from VentureKit route definitions.
|
|
5
|
+
*
|
|
6
|
+
* Import via: `import { generateOpenAPISpec } from '@venturekit/runtime/openapi'`
|
|
7
|
+
*/
|
|
8
|
+
export { generateOpenAPISpec, filePathToOpenAPI, inferTag, serializeOpenAPI, serializeOpenAPIYaml, } from './openapi/openapi.js';
|
|
9
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC"}
|