mcp-from-openapi 0.0.1

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,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ParameterResolver = void 0;
4
+ const types_1 = require("./types");
5
+ /**
6
+ * Resolves parameters and handles naming conflicts
7
+ */
8
+ class ParameterResolver {
9
+ constructor(namingStrategy) {
10
+ this.namingStrategy = namingStrategy ?? {
11
+ conflictResolver: this.defaultConflictResolver,
12
+ };
13
+ }
14
+ /**
15
+ * Default conflict resolver: prefix with location
16
+ */
17
+ defaultConflictResolver(paramName, location, index) {
18
+ const locationPrefix = {
19
+ path: 'path',
20
+ query: 'query',
21
+ header: 'header',
22
+ cookie: 'cookie',
23
+ body: 'body',
24
+ }[location];
25
+ return `${locationPrefix}${paramName.charAt(0).toUpperCase()}${paramName.slice(1)}`;
26
+ }
27
+ /**
28
+ * Resolve all parameters for an operation
29
+ */
30
+ resolve(operation, pathParameters) {
31
+ const allParameters = [
32
+ ...(pathParameters ?? []),
33
+ ...(operation.parameters ?? []),
34
+ ];
35
+ const requestBody = operation.requestBody;
36
+ // Collect all parameter names and detect conflicts
37
+ const parametersByName = new Map();
38
+ // Process standard parameters
39
+ allParameters.forEach((param) => {
40
+ const info = {
41
+ name: param.name,
42
+ location: param.in,
43
+ required: param.required ?? (param.in === 'path'),
44
+ schema: param.schema ?? { type: 'string' },
45
+ description: param.description,
46
+ style: param.style,
47
+ explode: param.explode,
48
+ allowReserved: param.allowReserved,
49
+ deprecated: param.deprecated,
50
+ };
51
+ if (!parametersByName.has(param.name)) {
52
+ parametersByName.set(param.name, []);
53
+ }
54
+ parametersByName.get(param.name).push(info);
55
+ });
56
+ // Process request body
57
+ if (requestBody?.content) {
58
+ const contentType = this.selectContentType(requestBody.content);
59
+ const mediaType = requestBody.content[contentType];
60
+ if (mediaType?.schema) {
61
+ this.extractBodyParameters(mediaType.schema, parametersByName, requestBody.required ?? false, contentType);
62
+ }
63
+ }
64
+ // Resolve conflicts and build schema + mapper
65
+ const properties = {};
66
+ const required = [];
67
+ const mapper = [];
68
+ for (const [originalName, params] of parametersByName.entries()) {
69
+ if (params.length === 1) {
70
+ // No conflict
71
+ const param = params[0];
72
+ const inputKey = originalName;
73
+ properties[inputKey] = this.buildParameterSchema(param);
74
+ if (param.required) {
75
+ required.push(inputKey);
76
+ }
77
+ mapper.push({
78
+ inputKey,
79
+ type: param.location,
80
+ key: originalName,
81
+ required: param.required,
82
+ style: param.style,
83
+ explode: param.explode,
84
+ serialization: param.serialization,
85
+ });
86
+ }
87
+ else {
88
+ // Conflict - need to resolve
89
+ params.forEach((param, index) => {
90
+ const inputKey = this.namingStrategy.conflictResolver(originalName, param.location, index);
91
+ properties[inputKey] = this.buildParameterSchema(param);
92
+ if (param.required) {
93
+ required.push(inputKey);
94
+ }
95
+ mapper.push({
96
+ inputKey,
97
+ type: param.location,
98
+ key: originalName,
99
+ required: param.required,
100
+ style: param.style,
101
+ explode: param.explode,
102
+ serialization: param.serialization,
103
+ });
104
+ });
105
+ }
106
+ }
107
+ const inputSchema = {
108
+ type: 'object',
109
+ properties,
110
+ ...(required.length > 0 && { required }),
111
+ additionalProperties: false,
112
+ };
113
+ return { inputSchema, mapper };
114
+ }
115
+ /**
116
+ * Extract parameters from request body schema
117
+ */
118
+ extractBodyParameters(schema, parametersByName, required, contentType, prefix = '') {
119
+ if (!schema || typeof schema !== 'object')
120
+ return;
121
+ // Convert to JSONSchema7 for processing
122
+ const jsonSchema = (0, types_1.toJSONSchema7)(schema);
123
+ // Handle object schemas
124
+ if (jsonSchema.type === 'object' && jsonSchema.properties) {
125
+ const requiredFields = new Set(jsonSchema.required ?? []);
126
+ for (const [propName, propSchema] of Object.entries(jsonSchema.properties)) {
127
+ const fullName = prefix ? `${prefix}.${propName}` : propName;
128
+ const isRequired = required && requiredFields.has(propName);
129
+ if (typeof propSchema === 'object' && !('$ref' in propSchema)) {
130
+ const info = {
131
+ name: fullName,
132
+ location: 'body',
133
+ required: isRequired,
134
+ schema: propSchema,
135
+ description: propSchema.description,
136
+ serialization: {
137
+ contentType,
138
+ },
139
+ };
140
+ if (!parametersByName.has(fullName)) {
141
+ parametersByName.set(fullName, []);
142
+ }
143
+ parametersByName.get(fullName).push(info);
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ // For non-object bodies (arrays, primitives), treat as single parameter
149
+ const bodyParamName = prefix || 'body';
150
+ const info = {
151
+ name: bodyParamName,
152
+ location: 'body',
153
+ required,
154
+ schema,
155
+ serialization: {
156
+ contentType,
157
+ },
158
+ };
159
+ if (!parametersByName.has(bodyParamName)) {
160
+ parametersByName.set(bodyParamName, []);
161
+ }
162
+ parametersByName.get(bodyParamName).push(info);
163
+ }
164
+ }
165
+ /**
166
+ * Build JSON Schema for a parameter
167
+ */
168
+ buildParameterSchema(param) {
169
+ const schema = (0, types_1.toJSONSchema7)(param.schema);
170
+ if (param.description) {
171
+ schema.description = param.description;
172
+ }
173
+ if (param.deprecated) {
174
+ schema['deprecated'] = true;
175
+ }
176
+ // Add parameter metadata
177
+ schema['x-parameter-location'] = param.location;
178
+ if (param.style) {
179
+ schema['x-parameter-style'] = param.style;
180
+ }
181
+ if (param.explode !== undefined) {
182
+ schema['x-parameter-explode'] = param.explode;
183
+ }
184
+ return schema;
185
+ }
186
+ /**
187
+ * Select the most appropriate content type
188
+ */
189
+ selectContentType(content) {
190
+ // Preference order
191
+ const preferences = [
192
+ 'application/json',
193
+ 'application/x-www-form-urlencoded',
194
+ 'multipart/form-data',
195
+ 'application/xml',
196
+ 'text/plain',
197
+ ];
198
+ for (const pref of preferences) {
199
+ if (content[pref])
200
+ return pref;
201
+ }
202
+ // Fallback to first available
203
+ const firstKey = Object.keys(content)[0];
204
+ if (!firstKey) {
205
+ throw new Error('No content type available in request body');
206
+ }
207
+ return firstKey;
208
+ }
209
+ }
210
+ exports.ParameterResolver = ParameterResolver;
211
+ //# sourceMappingURL=parameter-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-resolver.js","sourceRoot":"","sources":["../../src/parameter-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7 } from 'json-schema';\nimport type {\n ParameterMapper,\n ParameterObject,\n RequestBodyObject,\n NamingStrategy,\n ParameterLocation,\n SchemaObject,\n ReferenceObject,\n} from './types';\nimport { toJSONSchema7 } from './types';\n\n/**\n * Resolves parameters and handles naming conflicts\n */\nexport class ParameterResolver {\n private namingStrategy: NamingStrategy;\n\n constructor(namingStrategy?: NamingStrategy) {\n this.namingStrategy = namingStrategy ?? {\n conflictResolver: this.defaultConflictResolver,\n };\n }\n\n /**\n * Default conflict resolver: prefix with location\n */\n private defaultConflictResolver(\n paramName: string,\n location: ParameterLocation,\n index: number\n ): string {\n const locationPrefix = {\n path: 'path',\n query: 'query',\n header: 'header',\n cookie: 'cookie',\n body: 'body',\n }[location];\n\n return `${locationPrefix}${paramName.charAt(0).toUpperCase()}${paramName.slice(1)}`;\n }\n\n /**\n * Resolve all parameters for an operation\n */\n resolve(\n operation: any,\n pathParameters?: ParameterObject[]\n ): {\n inputSchema: JSONSchema7;\n mapper: ParameterMapper[];\n } {\n const allParameters: ParameterObject[] = [\n ...(pathParameters ?? []),\n ...(operation.parameters ?? []),\n ];\n\n const requestBody = operation.requestBody as RequestBodyObject | undefined;\n\n // Collect all parameter names and detect conflicts\n const parametersByName = new Map<string, ParameterInfo[]>();\n\n // Process standard parameters\n allParameters.forEach((param) => {\n const info: ParameterInfo = {\n name: param.name,\n location: param.in as ParameterLocation,\n required: param.required ?? (param.in === 'path'),\n schema: param.schema ?? { type: 'string' },\n description: param.description,\n style: param.style,\n explode: param.explode,\n allowReserved: param.allowReserved,\n deprecated: param.deprecated,\n };\n\n if (!parametersByName.has(param.name)) {\n parametersByName.set(param.name, []);\n }\n parametersByName.get(param.name)!.push(info);\n });\n\n // Process request body\n if (requestBody?.content) {\n const contentType = this.selectContentType(requestBody.content);\n const mediaType = requestBody.content[contentType];\n\n if (mediaType?.schema) {\n this.extractBodyParameters(\n mediaType.schema,\n parametersByName,\n requestBody.required ?? false,\n contentType\n );\n }\n }\n\n // Resolve conflicts and build schema + mapper\n const properties: Record<string, JSONSchema7> = {};\n const required: string[] = [];\n const mapper: ParameterMapper[] = [];\n\n for (const [originalName, params] of parametersByName.entries()) {\n if (params.length === 1) {\n // No conflict\n const param = params[0];\n const inputKey = originalName;\n\n properties[inputKey] = this.buildParameterSchema(param);\n if (param.required) {\n required.push(inputKey);\n }\n\n mapper.push({\n inputKey,\n type: param.location,\n key: originalName,\n required: param.required,\n style: param.style,\n explode: param.explode,\n serialization: param.serialization,\n });\n } else {\n // Conflict - need to resolve\n params.forEach((param, index) => {\n const inputKey = this.namingStrategy.conflictResolver(\n originalName,\n param.location,\n index\n );\n\n properties[inputKey] = this.buildParameterSchema(param);\n if (param.required) {\n required.push(inputKey);\n }\n\n mapper.push({\n inputKey,\n type: param.location,\n key: originalName,\n required: param.required,\n style: param.style,\n explode: param.explode,\n serialization: param.serialization,\n });\n });\n }\n }\n\n const inputSchema: JSONSchema7 = {\n type: 'object',\n properties,\n ...(required.length > 0 && { required }),\n additionalProperties: false,\n };\n\n return { inputSchema, mapper };\n }\n\n /**\n * Extract parameters from request body schema\n */\n private extractBodyParameters(\n schema: SchemaObject | ReferenceObject,\n parametersByName: Map<string, ParameterInfo[]>,\n required: boolean,\n contentType: string,\n prefix = ''\n ): void {\n if (!schema || typeof schema !== 'object') return;\n\n // Convert to JSONSchema7 for processing\n const jsonSchema = toJSONSchema7(schema);\n\n // Handle object schemas\n if (jsonSchema.type === 'object' && jsonSchema.properties) {\n const requiredFields = new Set(jsonSchema.required ?? []);\n\n for (const [propName, propSchema] of Object.entries(jsonSchema.properties)) {\n const fullName = prefix ? `${prefix}.${propName}` : propName;\n const isRequired = required && requiredFields.has(propName);\n\n if (typeof propSchema === 'object' && !('$ref' in propSchema)) {\n const info: ParameterInfo = {\n name: fullName,\n location: 'body',\n required: isRequired,\n schema: propSchema as JSONSchema7,\n description: (propSchema as any).description,\n serialization: {\n contentType,\n },\n };\n\n if (!parametersByName.has(fullName)) {\n parametersByName.set(fullName, []);\n }\n parametersByName.get(fullName)!.push(info);\n }\n }\n } else {\n // For non-object bodies (arrays, primitives), treat as single parameter\n const bodyParamName = prefix || 'body';\n const info: ParameterInfo = {\n name: bodyParamName,\n location: 'body',\n required,\n schema,\n serialization: {\n contentType,\n },\n };\n\n if (!parametersByName.has(bodyParamName)) {\n parametersByName.set(bodyParamName, []);\n }\n parametersByName.get(bodyParamName)!.push(info);\n }\n }\n\n /**\n * Build JSON Schema for a parameter\n */\n private buildParameterSchema(param: ParameterInfo): JSONSchema7 {\n const schema: JSONSchema7 = toJSONSchema7(param.schema as any);\n\n if (param.description) {\n schema.description = param.description;\n }\n\n if (param.deprecated) {\n schema['deprecated'] = true;\n }\n\n // Add parameter metadata\n (schema as any)['x-parameter-location'] = param.location;\n if (param.style) {\n (schema as any)['x-parameter-style'] = param.style;\n }\n if (param.explode !== undefined) {\n (schema as any)['x-parameter-explode'] = param.explode;\n }\n\n return schema;\n }\n\n /**\n * Select the most appropriate content type\n */\n private selectContentType(content: Record<string, any>): string {\n // Preference order\n const preferences = [\n 'application/json',\n 'application/x-www-form-urlencoded',\n 'multipart/form-data',\n 'application/xml',\n 'text/plain',\n ];\n\n for (const pref of preferences) {\n if (content[pref]) return pref;\n }\n\n // Fallback to first available\n const firstKey = Object.keys(content)[0];\n if (!firstKey) {\n throw new Error('No content type available in request body');\n }\n return firstKey;\n }\n}\n\n/**\n * Internal parameter info structure\n */\ninterface ParameterInfo {\n name: string;\n location: ParameterLocation;\n required: boolean;\n schema: SchemaObject | ReferenceObject | JSONSchema7;\n description?: string;\n style?: string;\n explode?: boolean;\n allowReserved?: boolean;\n deprecated?: boolean;\n serialization?: {\n contentType?: string;\n encoding?: Record<string, any>;\n };\n}\n"]}
@@ -0,0 +1,30 @@
1
+ import type { JSONSchema7 } from 'json-schema';
2
+ import type { GenerateOptions, ResponsesObject } from './types';
3
+ /**
4
+ * Builds output schemas from OpenAPI response definitions
5
+ */
6
+ export declare class ResponseBuilder {
7
+ private preferredStatusCodes;
8
+ private includeAllResponses;
9
+ constructor(options?: GenerateOptions);
10
+ /**
11
+ * Build output schema from responses
12
+ */
13
+ build(responses?: ResponsesObject): JSONSchema7 | undefined;
14
+ /**
15
+ * Extract schemas from all responses
16
+ */
17
+ private extractResponseSchemas;
18
+ /**
19
+ * Extract schema from a single response
20
+ */
21
+ private extractResponseSchema;
22
+ /**
23
+ * Select the most appropriate content type
24
+ */
25
+ private selectContentType;
26
+ /**
27
+ * Select the preferred schema based on status code preferences
28
+ */
29
+ private selectPreferredSchema;
30
+ }
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseBuilder = void 0;
4
+ const types_1 = require("./types");
5
+ /**
6
+ * Builds output schemas from OpenAPI response definitions
7
+ */
8
+ class ResponseBuilder {
9
+ constructor(options = {}) {
10
+ this.preferredStatusCodes = options.preferredStatusCodes ?? [200, 201, 204, 202, 203, 206];
11
+ this.includeAllResponses = options.includeAllResponses ?? true;
12
+ }
13
+ /**
14
+ * Build output schema from responses
15
+ */
16
+ build(responses) {
17
+ if (!responses || Object.keys(responses).length === 0) {
18
+ return undefined;
19
+ }
20
+ const schemas = this.extractResponseSchemas(responses);
21
+ if (schemas.length === 0) {
22
+ return undefined;
23
+ }
24
+ if (schemas.length === 1) {
25
+ return schemas[0].schema;
26
+ }
27
+ if (this.includeAllResponses) {
28
+ // Return union of all response schemas
29
+ return {
30
+ oneOf: schemas.map((s) => s.schema),
31
+ description: 'Response can be one of multiple status codes',
32
+ };
33
+ }
34
+ else {
35
+ // Return only the preferred status code
36
+ const preferred = this.selectPreferredSchema(schemas);
37
+ return preferred.schema;
38
+ }
39
+ }
40
+ /**
41
+ * Extract schemas from all responses
42
+ */
43
+ extractResponseSchemas(responses) {
44
+ const schemas = [];
45
+ for (const [statusCode, response] of Object.entries(responses)) {
46
+ // Skip if it's a reference object
47
+ if ((0, types_1.isReferenceObject)(response))
48
+ continue;
49
+ // Skip 'default' for now, we'll handle it separately
50
+ if (statusCode === 'default')
51
+ continue;
52
+ const code = parseInt(statusCode, 10);
53
+ if (isNaN(code))
54
+ continue;
55
+ const schema = this.extractResponseSchema(response, code);
56
+ if (schema) {
57
+ schemas.push(schema);
58
+ }
59
+ }
60
+ // Handle default response if no other schemas found
61
+ if (schemas.length === 0 && responses['default']) {
62
+ const defaultResponse = responses['default'];
63
+ if (!(0, types_1.isReferenceObject)(defaultResponse)) {
64
+ const schema = this.extractResponseSchema(defaultResponse, 0);
65
+ if (schema) {
66
+ schemas.push(schema);
67
+ }
68
+ }
69
+ }
70
+ return schemas;
71
+ }
72
+ /**
73
+ * Extract schema from a single response
74
+ */
75
+ extractResponseSchema(response, statusCode) {
76
+ if (!response.content) {
77
+ // Response with no content (e.g., 204 No Content)
78
+ return {
79
+ statusCode,
80
+ schema: {
81
+ type: 'null',
82
+ description: response.description,
83
+ 'x-status-code': statusCode,
84
+ },
85
+ };
86
+ }
87
+ const contentType = this.selectContentType(response.content);
88
+ const mediaType = response.content[contentType];
89
+ if (!mediaType?.schema) {
90
+ return null;
91
+ }
92
+ const schema = {
93
+ ...(0, types_1.toJSONSchema7)(mediaType.schema),
94
+ 'x-status-code': statusCode,
95
+ };
96
+ // Add description if not already present
97
+ if (!schema.description && response.description) {
98
+ schema.description = response.description;
99
+ }
100
+ // Add content type metadata
101
+ schema['x-content-type'] = contentType;
102
+ return { statusCode, schema };
103
+ }
104
+ /**
105
+ * Select the most appropriate content type
106
+ */
107
+ selectContentType(content) {
108
+ // Preference order for responses
109
+ const preferences = [
110
+ 'application/json',
111
+ 'application/hal+json',
112
+ 'application/problem+json',
113
+ 'application/xml',
114
+ 'text/plain',
115
+ 'text/html',
116
+ ];
117
+ for (const pref of preferences) {
118
+ if (content[pref])
119
+ return pref;
120
+ }
121
+ // Fallback to first available
122
+ return Object.keys(content)[0];
123
+ }
124
+ /**
125
+ * Select the preferred schema based on status code preferences
126
+ */
127
+ selectPreferredSchema(schemas) {
128
+ // First, try to find exact match in preferred list
129
+ for (const preferredCode of this.preferredStatusCodes) {
130
+ const found = schemas.find((s) => s.statusCode === preferredCode);
131
+ if (found)
132
+ return found;
133
+ }
134
+ // Next, try to find any 2xx response
135
+ const success = schemas.find((s) => s.statusCode >= 200 && s.statusCode < 300);
136
+ if (success)
137
+ return success;
138
+ // Next, try to find any 3xx response
139
+ const redirect = schemas.find((s) => s.statusCode >= 300 && s.statusCode < 400);
140
+ if (redirect)
141
+ return redirect;
142
+ // Fallback to first available
143
+ return schemas[0];
144
+ }
145
+ }
146
+ exports.ResponseBuilder = ResponseBuilder;
147
+ //# sourceMappingURL=response-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-builder.js","sourceRoot":"","sources":["../../src/response-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7 } from 'json-schema';\nimport type { ResponseObject, GenerateOptions, ResponsesObject } from './types';\nimport { isReferenceObject, toJSONSchema7 } from './types';\n\n/**\n * Builds output schemas from OpenAPI response definitions\n */\nexport class ResponseBuilder {\n private preferredStatusCodes: number[];\n private includeAllResponses: boolean;\n\n constructor(options: GenerateOptions = {}) {\n this.preferredStatusCodes = options.preferredStatusCodes ?? [200, 201, 204, 202, 203, 206];\n this.includeAllResponses = options.includeAllResponses ?? true;\n }\n\n /**\n * Build output schema from responses\n */\n build(responses?: ResponsesObject): JSONSchema7 | undefined {\n if (!responses || Object.keys(responses).length === 0) {\n return undefined;\n }\n\n const schemas = this.extractResponseSchemas(responses);\n\n if (schemas.length === 0) {\n return undefined;\n }\n\n if (schemas.length === 1) {\n return schemas[0].schema;\n }\n\n if (this.includeAllResponses) {\n // Return union of all response schemas\n return {\n oneOf: schemas.map((s) => s.schema),\n description: 'Response can be one of multiple status codes',\n };\n } else {\n // Return only the preferred status code\n const preferred = this.selectPreferredSchema(schemas);\n return preferred.schema;\n }\n }\n\n /**\n * Extract schemas from all responses\n */\n private extractResponseSchemas(responses: ResponsesObject): ResponseSchema[] {\n const schemas: ResponseSchema[] = [];\n\n for (const [statusCode, response] of Object.entries(responses)) {\n // Skip if it's a reference object\n if (isReferenceObject(response)) continue;\n\n // Skip 'default' for now, we'll handle it separately\n if (statusCode === 'default') continue;\n\n const code = parseInt(statusCode, 10);\n if (isNaN(code)) continue;\n\n const schema = this.extractResponseSchema(response, code);\n if (schema) {\n schemas.push(schema);\n }\n }\n\n // Handle default response if no other schemas found\n if (schemas.length === 0 && responses['default']) {\n const defaultResponse = responses['default'];\n if (!isReferenceObject(defaultResponse)) {\n const schema = this.extractResponseSchema(defaultResponse, 0);\n if (schema) {\n schemas.push(schema);\n }\n }\n }\n\n return schemas;\n }\n\n /**\n * Extract schema from a single response\n */\n private extractResponseSchema(response: ResponseObject, statusCode: number): ResponseSchema | null {\n if (!response.content) {\n // Response with no content (e.g., 204 No Content)\n return {\n statusCode,\n schema: {\n type: 'null',\n description: response.description,\n 'x-status-code': statusCode,\n } as JSONSchema7,\n };\n }\n\n const contentType = this.selectContentType(response.content);\n const mediaType = response.content[contentType];\n\n if (!mediaType?.schema) {\n return null;\n }\n\n const schema: JSONSchema7 & { 'x-status-code'?: number } = {\n ...toJSONSchema7(mediaType.schema),\n 'x-status-code': statusCode,\n };\n\n // Add description if not already present\n if (!schema.description && response.description) {\n schema.description = response.description;\n }\n\n // Add content type metadata\n (schema as any)['x-content-type'] = contentType;\n\n return { statusCode, schema };\n }\n\n /**\n * Select the most appropriate content type\n */\n private selectContentType(content: Record<string, any>): string {\n // Preference order for responses\n const preferences = [\n 'application/json',\n 'application/hal+json',\n 'application/problem+json',\n 'application/xml',\n 'text/plain',\n 'text/html',\n ];\n\n for (const pref of preferences) {\n if (content[pref]) return pref;\n }\n\n // Fallback to first available\n return Object.keys(content)[0];\n }\n\n /**\n * Select the preferred schema based on status code preferences\n */\n private selectPreferredSchema(schemas: ResponseSchema[]): ResponseSchema {\n // First, try to find exact match in preferred list\n for (const preferredCode of this.preferredStatusCodes) {\n const found = schemas.find((s) => s.statusCode === preferredCode);\n if (found) return found;\n }\n\n // Next, try to find any 2xx response\n const success = schemas.find((s) => s.statusCode >= 200 && s.statusCode < 300);\n if (success) return success;\n\n // Next, try to find any 3xx response\n const redirect = schemas.find((s) => s.statusCode >= 300 && s.statusCode < 400);\n if (redirect) return redirect;\n\n // Fallback to first available\n return schemas[0];\n }\n}\n\n/**\n * Internal response schema structure\n */\ninterface ResponseSchema {\n statusCode: number;\n schema: JSONSchema7;\n}\n"]}
@@ -0,0 +1,123 @@
1
+ import type { JSONSchema7 } from 'json-schema';
2
+ /**
3
+ * Helper class for building and manipulating JSON schemas
4
+ */
5
+ export declare class SchemaBuilder {
6
+ /**
7
+ * Merge multiple schemas into one
8
+ */
9
+ static merge(schemas: JSONSchema7[]): JSONSchema7;
10
+ /**
11
+ * Create a union schema (oneOf)
12
+ */
13
+ static union(schemas: JSONSchema7[]): JSONSchema7;
14
+ /**
15
+ * Deep clone a schema
16
+ */
17
+ static clone(schema: JSONSchema7): JSONSchema7;
18
+ /**
19
+ * Remove $ref from schema (assumes already dereferenced)
20
+ */
21
+ static removeRefs(schema: JSONSchema7): JSONSchema7;
22
+ private static removeRefsRecursive;
23
+ /**
24
+ * Add description to schema
25
+ */
26
+ static withDescription(schema: JSONSchema7, description: string): JSONSchema7;
27
+ /**
28
+ * Mark schema as required
29
+ */
30
+ static required(schema: JSONSchema7): JSONSchema7;
31
+ /**
32
+ * Mark schema as optional
33
+ */
34
+ static optional(schema: JSONSchema7): JSONSchema7;
35
+ /**
36
+ * Add example to schema
37
+ */
38
+ static withExample(schema: JSONSchema7, example: any): JSONSchema7;
39
+ /**
40
+ * Add default value to schema
41
+ */
42
+ static withDefault(schema: JSONSchema7, defaultValue: any): JSONSchema7;
43
+ /**
44
+ * Add format to schema
45
+ */
46
+ static withFormat(schema: JSONSchema7, format: string): JSONSchema7;
47
+ /**
48
+ * Add pattern to schema
49
+ */
50
+ static withPattern(schema: JSONSchema7, pattern: string): JSONSchema7;
51
+ /**
52
+ * Add enum to schema
53
+ */
54
+ static withEnum(schema: JSONSchema7, values: any[]): JSONSchema7;
55
+ /**
56
+ * Add minimum/maximum constraints
57
+ */
58
+ static withRange(schema: JSONSchema7, min?: number, max?: number, options?: {
59
+ exclusive?: boolean;
60
+ }): JSONSchema7;
61
+ /**
62
+ * Add minLength/maxLength constraints
63
+ */
64
+ static withLength(schema: JSONSchema7, minLength?: number, maxLength?: number): JSONSchema7;
65
+ /**
66
+ * Create object schema
67
+ */
68
+ static object(properties: Record<string, JSONSchema7>, required?: string[]): JSONSchema7;
69
+ /**
70
+ * Create array schema
71
+ */
72
+ static array(items: JSONSchema7, constraints?: {
73
+ minItems?: number;
74
+ maxItems?: number;
75
+ uniqueItems?: boolean;
76
+ }): JSONSchema7;
77
+ /**
78
+ * Create string schema
79
+ */
80
+ static string(constraints?: {
81
+ minLength?: number;
82
+ maxLength?: number;
83
+ pattern?: string;
84
+ format?: string;
85
+ enum?: string[];
86
+ }): JSONSchema7;
87
+ /**
88
+ * Create number schema
89
+ */
90
+ static number(constraints?: {
91
+ minimum?: number;
92
+ maximum?: number;
93
+ exclusiveMinimum?: number;
94
+ exclusiveMaximum?: number;
95
+ multipleOf?: number;
96
+ }): JSONSchema7;
97
+ /**
98
+ * Create integer schema
99
+ */
100
+ static integer(constraints?: {
101
+ minimum?: number;
102
+ maximum?: number;
103
+ exclusiveMinimum?: number;
104
+ exclusiveMaximum?: number;
105
+ multipleOf?: number;
106
+ }): JSONSchema7;
107
+ /**
108
+ * Create boolean schema
109
+ */
110
+ static boolean(): JSONSchema7;
111
+ /**
112
+ * Create null schema
113
+ */
114
+ static null(): JSONSchema7;
115
+ /**
116
+ * Flatten nested oneOf/anyOf/allOf schemas
117
+ */
118
+ static flatten(schema: JSONSchema7, maxDepth?: number): JSONSchema7;
119
+ /**
120
+ * Simplify schema by removing unnecessary fields
121
+ */
122
+ static simplify(schema: JSONSchema7): JSONSchema7;
123
+ }