mcp-from-openapi 0.0.1 → 2.0.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.
package/src/types.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { JSONSchema7 } from 'json-schema';
1
+ import type { JSONSchema } from 'zod/v4/core';
2
+ /** JSON Schema type from Zod v4 */
3
+ type JsonSchema = JSONSchema.JSONSchema;
2
4
  import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
3
5
  /**
4
6
  * OpenAPI specification version 3.0.x or 3.1.x
@@ -19,7 +21,7 @@ export type ParameterLocation = 'path' | 'query' | 'header' | 'cookie' | 'body';
19
21
  /**
20
22
  * Authentication types supported
21
23
  */
22
- export type AuthType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';
24
+ export type AuthType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect' | 'mutualTLS';
23
25
  export type OperationObject = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject;
24
26
  export type ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;
25
27
  export type RequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject;
@@ -44,11 +46,11 @@ export type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;
44
46
  */
45
47
  export declare function isReferenceObject(obj: any): obj is ReferenceObject;
46
48
  /**
47
- * Convert OpenAPI schema to JSONSchema7
49
+ * Convert OpenAPI schema to JsonSchema
48
50
  * Note: OpenAPI 3.0 uses a subset of JSON Schema Draft 4
49
51
  * OpenAPI 3.1 uses JSON Schema Draft 2020-12
50
52
  */
51
- export declare function toJSONSchema7(schema: SchemaObject | ReferenceObject): JSONSchema7;
53
+ export declare function toJsonSchema(schema: SchemaObject | ReferenceObject): JsonSchema;
52
54
  /**
53
55
  * Main MCP Tool definition generated from OpenAPI
54
56
  */
@@ -65,12 +67,12 @@ export interface McpOpenAPITool {
65
67
  * Combined input schema including all parameters
66
68
  * (path, query, header, cookie, body)
67
69
  */
68
- inputSchema: JSONSchema7;
70
+ inputSchema: JsonSchema;
69
71
  /**
70
72
  * Output schema based on response definitions
71
73
  * Can be a union of multiple status codes
72
74
  */
73
- outputSchema?: JSONSchema7;
75
+ outputSchema?: JsonSchema;
74
76
  /**
75
77
  * Mapping from input schema properties to actual request parameters
76
78
  */
@@ -112,6 +114,11 @@ export interface ParameterMapper {
112
114
  * Custom serialization info
113
115
  */
114
116
  serialization?: SerializationInfo;
117
+ /**
118
+ * Security scheme information (if this is an auth parameter)
119
+ * This allows frameworks to resolve auth from context, env vars, etc.
120
+ */
121
+ security?: SecurityParameterInfo;
115
122
  }
116
123
  /**
117
124
  * Serialization information for complex parameters
@@ -126,6 +133,44 @@ export interface SerializationInfo {
126
133
  */
127
134
  encoding?: Record<string, EncodingObject>;
128
135
  }
136
+ /**
137
+ * Security parameter information for framework-agnostic auth resolution
138
+ */
139
+ export interface SecurityParameterInfo {
140
+ /**
141
+ * Security scheme name from OpenAPI (e.g., "BearerAuth")
142
+ */
143
+ scheme: string;
144
+ /**
145
+ * Security type (apiKey, http, oauth2, openIdConnect)
146
+ */
147
+ type: AuthType;
148
+ /**
149
+ * HTTP authentication scheme (for type: "http")
150
+ * e.g., "bearer", "basic"
151
+ */
152
+ httpScheme?: string;
153
+ /**
154
+ * Bearer token format (e.g., "JWT")
155
+ */
156
+ bearerFormat?: string;
157
+ /**
158
+ * Required OAuth2 scopes
159
+ */
160
+ scopes?: string[];
161
+ /**
162
+ * API key parameter name (for type: "apiKey")
163
+ */
164
+ apiKeyName?: string;
165
+ /**
166
+ * API key location (for type: "apiKey")
167
+ */
168
+ apiKeyIn?: 'query' | 'header' | 'cookie';
169
+ /**
170
+ * Description of the security scheme
171
+ */
172
+ description?: string;
173
+ }
129
174
  /**
130
175
  * Additional metadata about the generated tool
131
176
  */
@@ -191,6 +236,19 @@ export interface SecurityRequirement {
191
236
  * Parameter location (for API key)
192
237
  */
193
238
  in?: 'query' | 'header' | 'cookie';
239
+ /**
240
+ * HTTP authentication scheme (for type: "http")
241
+ * e.g., "bearer", "basic"
242
+ */
243
+ httpScheme?: string;
244
+ /**
245
+ * Bearer token format (e.g., "JWT")
246
+ */
247
+ bearerFormat?: string;
248
+ /**
249
+ * Description of the security scheme
250
+ */
251
+ description?: string;
194
252
  }
195
253
  /**
196
254
  * Server information
@@ -296,6 +354,13 @@ export interface GenerateOptions {
296
354
  * @default false
297
355
  */
298
356
  includeExamples?: boolean;
357
+ /**
358
+ * Whether to include security requirements as input parameters
359
+ * If false, security is only in mapper (frameworks resolve from context/env/etc.)
360
+ * If true, security is added to inputSchema as explicit parameters
361
+ * @default false
362
+ */
363
+ includeSecurityInInput?: boolean;
299
364
  }
300
365
  /**
301
366
  * Naming strategy for resolving parameter conflicts
@@ -369,3 +434,4 @@ export interface ValidationWarning {
369
434
  */
370
435
  code?: string;
371
436
  }
437
+ export {};
package/src/types.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isReferenceObject = isReferenceObject;
4
- exports.toJSONSchema7 = toJSONSchema7;
4
+ exports.toJsonSchema = toJsonSchema;
5
5
  /**
6
6
  * Helper to check if an object is a ReferenceObject
7
7
  */
@@ -9,29 +9,90 @@ function isReferenceObject(obj) {
9
9
  return obj && typeof obj === 'object' && '$ref' in obj;
10
10
  }
11
11
  /**
12
- * Convert OpenAPI schema to JSONSchema7
12
+ * Convert OpenAPI schema to JsonSchema
13
13
  * Note: OpenAPI 3.0 uses a subset of JSON Schema Draft 4
14
14
  * OpenAPI 3.1 uses JSON Schema Draft 2020-12
15
15
  */
16
- function toJSONSchema7(schema) {
16
+ function toJsonSchema(schema) {
17
17
  if (isReferenceObject(schema)) {
18
18
  return { $ref: schema.$ref };
19
19
  }
20
20
  // Handle OpenAPI 3.0 boolean exclusiveMaximum/exclusiveMinimum
21
- const result = { ...schema };
22
- // Convert boolean exclusiveMaximum to number format (JSON Schema Draft 7)
23
- if ('exclusiveMaximum' in schema && typeof schema.exclusiveMaximum === 'boolean') {
24
- if (schema.exclusiveMaximum && 'maximum' in schema) {
25
- result.exclusiveMaximum = schema.maximum;
26
- delete result.maximum;
21
+ // by converting them to JSON Schema Draft 7 numeric format
22
+ const { exclusiveMaximum, exclusiveMinimum, maximum, minimum, ...rest } = schema;
23
+ const result = { ...rest };
24
+ // Handle exclusiveMaximum conversion
25
+ if (typeof exclusiveMaximum === 'boolean') {
26
+ if (exclusiveMaximum && maximum !== undefined) {
27
+ // true + maximum present -> convert to numeric exclusiveMaximum
28
+ result['exclusiveMaximum'] = maximum;
29
+ }
30
+ else if (maximum !== undefined) {
31
+ // false or true without maximum -> keep maximum only
32
+ result['maximum'] = maximum;
33
+ }
34
+ // Boolean exclusiveMaximum is never added (invalid in JSON Schema 7)
35
+ }
36
+ else if (exclusiveMaximum !== undefined) {
37
+ // Already numeric (OpenAPI 3.1) - keep as is
38
+ result['exclusiveMaximum'] = exclusiveMaximum;
39
+ if (maximum !== undefined) {
40
+ result['maximum'] = maximum;
27
41
  }
28
42
  }
29
- // Convert boolean exclusiveMinimum to number format (JSON Schema Draft 7)
30
- if ('exclusiveMinimum' in schema && typeof schema.exclusiveMinimum === 'boolean') {
31
- if (schema.exclusiveMinimum && 'minimum' in schema) {
32
- result.exclusiveMinimum = schema.minimum;
33
- delete result.minimum;
43
+ else if (maximum !== undefined) {
44
+ // No exclusiveMaximum, just maximum
45
+ result['maximum'] = maximum;
46
+ }
47
+ // Handle exclusiveMinimum conversion
48
+ if (typeof exclusiveMinimum === 'boolean') {
49
+ if (exclusiveMinimum && minimum !== undefined) {
50
+ // true + minimum present -> convert to numeric exclusiveMinimum
51
+ result['exclusiveMinimum'] = minimum;
52
+ }
53
+ else if (minimum !== undefined) {
54
+ // false or true without minimum -> keep minimum only
55
+ result['minimum'] = minimum;
34
56
  }
57
+ // Boolean exclusiveMinimum is never added (invalid in JSON Schema 7)
58
+ }
59
+ else if (exclusiveMinimum !== undefined) {
60
+ // Already numeric (OpenAPI 3.1) - keep as is
61
+ result['exclusiveMinimum'] = exclusiveMinimum;
62
+ if (minimum !== undefined) {
63
+ result['minimum'] = minimum;
64
+ }
65
+ }
66
+ else if (minimum !== undefined) {
67
+ // No exclusiveMinimum, just minimum
68
+ result['minimum'] = minimum;
69
+ }
70
+ // Recursively convert nested schemas to ensure all nested schemas are valid JsonSchema
71
+ if (result['properties'] && typeof result['properties'] === 'object') {
72
+ const props = {};
73
+ for (const [key, value] of Object.entries(result['properties'])) {
74
+ props[key] = toJsonSchema(value);
75
+ }
76
+ result['properties'] = props;
77
+ }
78
+ if (result['items']) {
79
+ if (Array.isArray(result['items'])) {
80
+ result['items'] = result['items'].map(toJsonSchema);
81
+ }
82
+ else {
83
+ result['items'] = toJsonSchema(result['items']);
84
+ }
85
+ }
86
+ if (result['additionalProperties'] && typeof result['additionalProperties'] === 'object') {
87
+ result['additionalProperties'] = toJsonSchema(result['additionalProperties']);
88
+ }
89
+ for (const key of ['allOf', 'anyOf', 'oneOf']) {
90
+ if (result[key] && Array.isArray(result[key])) {
91
+ result[key] = result[key].map(toJsonSchema);
92
+ }
93
+ }
94
+ if (result['not']) {
95
+ result['not'] = toJsonSchema(result['not']);
35
96
  }
36
97
  return result;
37
98
  }
package/src/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";;AAoDA,8CAEC;AAOD,sCAyBC;AArCD;;GAEG;AACH,SAAgB,iBAAiB,CAAC,GAAQ;IACxC,OAAO,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,MAAsC;IAClE,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAiB,CAAC;IAC9C,CAAC;IAED,+DAA+D;IAC/D,MAAM,MAAM,GAAgB,EAAE,GAAG,MAAM,EAAS,CAAC;IAEjD,0EAA0E;IAC1E,IAAI,kBAAkB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACjF,IAAI,MAAM,CAAC,gBAAgB,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YACnD,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAiB,CAAC;YACnD,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,IAAI,kBAAkB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACjF,IAAI,MAAM,CAAC,gBAAgB,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YACnD,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAiB,CAAC;YACnD,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { JSONSchema7 } from 'json-schema';\nimport type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * OpenAPI specification version 3.0.x or 3.1.x\n */\nexport type OpenAPIVersion = '3.0.0' | '3.0.1' | '3.0.2' | '3.0.3' | '3.1.0';\n\n/**\n * Unified OpenAPI Document type (supports both 3.0 and 3.1)\n */\nexport type OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document;\n\n/**\n * HTTP methods supported by OpenAPI\n */\nexport type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\n/**\n * Parameter location types\n */\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie' | 'body';\n\n/**\n * Authentication types supported\n */\nexport type AuthType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';\n\n// Re-export OpenAPI types for convenience\nexport type OperationObject = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject;\nexport type ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;\nexport type RequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject;\nexport type ResponseObject = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject;\nexport type ResponsesObject = OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;\nexport type MediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;\nexport type HeaderObject = OpenAPIV3.HeaderObject | OpenAPIV3_1.HeaderObject;\nexport type ExampleObject = OpenAPIV3.ExampleObject | OpenAPIV3_1.ExampleObject;\nexport type PathItemObject = OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject;\nexport type PathsObject = OpenAPIV3.PathsObject | OpenAPIV3_1.PathsObject;\nexport type ServerObject = OpenAPIV3.ServerObject | OpenAPIV3_1.ServerObject;\nexport type SecuritySchemeObject = OpenAPIV3.SecuritySchemeObject | OpenAPIV3_1.SecuritySchemeObject;\nexport type ReferenceObject = OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject;\nexport type TagObject = OpenAPIV3.TagObject | OpenAPIV3_1.TagObject;\nexport type ExternalDocumentationObject = OpenAPIV3.ExternalDocumentationObject | OpenAPIV3_1.ExternalDocumentationObject;\nexport type ServerVariableObject = OpenAPIV3.ServerVariableObject | OpenAPIV3_1.ServerVariableObject;\nexport type EncodingObject = OpenAPIV3.EncodingObject | OpenAPIV3_1.EncodingObject;\nexport type SecurityRequirementObject = OpenAPIV3.SecurityRequirementObject | OpenAPIV3_1.SecurityRequirementObject;\nexport type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;\n\n/**\n * Helper to check if an object is a ReferenceObject\n */\nexport function isReferenceObject(obj: any): obj is ReferenceObject {\n return obj && typeof obj === 'object' && '$ref' in obj;\n}\n\n/**\n * Convert OpenAPI schema to JSONSchema7\n * Note: OpenAPI 3.0 uses a subset of JSON Schema Draft 4\n * OpenAPI 3.1 uses JSON Schema Draft 2020-12\n */\nexport function toJSONSchema7(schema: SchemaObject | ReferenceObject): JSONSchema7 {\n if (isReferenceObject(schema)) {\n return { $ref: schema.$ref } as JSONSchema7;\n }\n\n // Handle OpenAPI 3.0 boolean exclusiveMaximum/exclusiveMinimum\n const result: JSONSchema7 = { ...schema } as any;\n\n // Convert boolean exclusiveMaximum to number format (JSON Schema Draft 7)\n if ('exclusiveMaximum' in schema && typeof schema.exclusiveMaximum === 'boolean') {\n if (schema.exclusiveMaximum && 'maximum' in schema) {\n result.exclusiveMaximum = schema.maximum as number;\n delete result.maximum;\n }\n }\n\n // Convert boolean exclusiveMinimum to number format (JSON Schema Draft 7)\n if ('exclusiveMinimum' in schema && typeof schema.exclusiveMinimum === 'boolean') {\n if (schema.exclusiveMinimum && 'minimum' in schema) {\n result.exclusiveMinimum = schema.minimum as number;\n delete result.minimum;\n }\n }\n\n return result;\n}\n\n/**\n * Main MCP Tool definition generated from OpenAPI\n */\nexport interface McpOpenAPITool {\n /**\n * Unique tool name (from operationId or generated)\n */\n name: string;\n\n /**\n * Tool description (from operation summary/description)\n */\n description: string;\n\n /**\n * Combined input schema including all parameters\n * (path, query, header, cookie, body)\n */\n inputSchema: JSONSchema7;\n\n /**\n * Output schema based on response definitions\n * Can be a union of multiple status codes\n */\n outputSchema?: JSONSchema7;\n\n /**\n * Mapping from input schema properties to actual request parameters\n */\n mapper: ParameterMapper[];\n\n /**\n * Additional metadata about the tool\n */\n metadata: ToolMetadata;\n}\n\n/**\n * Maps input schema properties to their actual request locations\n */\nexport interface ParameterMapper {\n /**\n * Property name in the input schema\n */\n inputKey: string;\n\n /**\n * Where this parameter should be placed in the request\n */\n type: ParameterLocation;\n\n /**\n * Original parameter name (before conflict resolution)\n */\n key: string;\n\n /**\n * Whether this parameter is required\n */\n required?: boolean;\n\n /**\n * Parameter style (for path/query parameters)\n */\n style?: string;\n\n /**\n * Whether to explode arrays/objects\n */\n explode?: boolean;\n\n /**\n * Custom serialization info\n */\n serialization?: SerializationInfo;\n}\n\n/**\n * Serialization information for complex parameters\n */\nexport interface SerializationInfo {\n /**\n * Content type for body parameters\n */\n contentType?: string;\n\n /**\n * Encoding rules\n */\n encoding?: Record<string, EncodingObject>;\n}\n\n/**\n * Additional metadata about the generated tool\n */\nexport interface ToolMetadata {\n /**\n * Original OpenAPI path\n */\n path: string;\n\n /**\n * HTTP method\n */\n method: HTTPMethod;\n\n /**\n * Operation ID from OpenAPI\n */\n operationId?: string;\n\n /**\n * Tags from OpenAPI\n */\n tags?: string[];\n\n /**\n * Whether operation is deprecated\n */\n deprecated?: boolean;\n\n /**\n * Security requirements\n */\n security?: SecurityRequirement[];\n\n /**\n * Server information\n */\n servers?: ServerInfo[];\n\n /**\n * Response status codes included in output schema\n */\n responseStatusCodes?: number[];\n\n /**\n * External documentation\n */\n externalDocs?: ExternalDocumentationObject;\n}\n\n/**\n * Security requirement definition\n */\nexport interface SecurityRequirement {\n /**\n * Security scheme name\n */\n scheme: string;\n\n /**\n * Security type\n */\n type: AuthType;\n\n /**\n * Scopes required (for OAuth2/OpenID Connect)\n */\n scopes?: string[];\n\n /**\n * Parameter name (for API key)\n */\n name?: string;\n\n /**\n * Parameter location (for API key)\n */\n in?: 'query' | 'header' | 'cookie';\n}\n\n/**\n * Server information\n */\nexport interface ServerInfo {\n /**\n * Server URL\n */\n url: string;\n\n /**\n * Server description\n */\n description?: string;\n\n /**\n * Server variables\n */\n variables?: Record<string, ServerVariableObject>;\n}\n\n/**\n * Options for loading OpenAPI specifications\n */\nexport interface LoadOptions {\n /**\n * Whether to dereference $refs in schemas\n * @default true\n */\n dereference?: boolean;\n\n /**\n * Base URL for API requests\n * Overrides servers in OpenAPI spec\n */\n baseUrl?: string;\n\n /**\n * Custom HTTP headers for loading from URL\n */\n headers?: Record<string, string>;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Whether to validate the OpenAPI document\n * @default true\n */\n validate?: boolean;\n\n /**\n * Whether to follow HTTP redirects\n * @default true\n */\n followRedirects?: boolean;\n}\n\n/**\n * Operation object with additional context for filtering\n */\nexport type OperationWithContext = OperationObject & {\n path: string;\n method: string;\n};\n\n/**\n * Options for generating tools\n */\nexport interface GenerateOptions {\n /**\n * Include only these operation IDs\n */\n includeOperations?: string[];\n\n /**\n * Exclude these operation IDs\n */\n excludeOperations?: string[];\n\n /**\n * Custom filter function\n */\n filterFn?: (operation: OperationWithContext) => boolean;\n\n /**\n * Naming strategy for resolving conflicts\n */\n namingStrategy?: NamingStrategy;\n\n /**\n * Preferred response status codes (in order of preference)\n * @default [200, 201, 204, 202, 203, 206]\n */\n preferredStatusCodes?: number[];\n\n /**\n * Whether to include deprecated operations\n * @default false\n */\n includeDeprecated?: boolean;\n\n /**\n * Whether to include all response codes in output schema\n * If false, only preferred status code is used\n * @default true\n */\n includeAllResponses?: boolean;\n\n /**\n * Maximum depth for dereferencing schemas\n * @default 10\n */\n maxSchemaDepth?: number;\n\n /**\n * Whether to include examples in schemas\n * @default false\n */\n includeExamples?: boolean;\n}\n\n/**\n * Naming strategy for resolving parameter conflicts\n */\nexport interface NamingStrategy {\n /**\n * Resolver function for parameter name conflicts\n * @param paramName - Original parameter name\n * @param location - Parameter location\n * @param index - Index of conflicting parameter (0-based)\n * @returns New parameter name\n */\n conflictResolver: (\n paramName: string,\n location: ParameterLocation,\n index: number\n ) => string;\n\n /**\n * Function to generate tool names\n * @param path - OpenAPI path\n * @param method - HTTP method\n * @param operationId - Operation ID if available\n * @returns Tool name\n */\n toolNameGenerator?: (\n path: string,\n method: HTTPMethod,\n operationId?: string\n ) => string;\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /**\n * Whether the document is valid\n */\n valid: boolean;\n\n /**\n * Validation errors\n */\n errors?: ValidationErrorDetail[];\n\n /**\n * Validation warnings\n */\n warnings?: ValidationWarning[];\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationErrorDetail {\n /**\n * Error message\n */\n message: string;\n\n /**\n * Error path (JSON pointer)\n */\n path?: string;\n\n /**\n * Error code\n */\n code?: string;\n}\n\n/**\n * Validation warning\n */\nexport interface ValidationWarning {\n /**\n * Warning message\n */\n message: string;\n\n /**\n * Warning path (JSON pointer)\n */\n path?: string;\n\n /**\n * Warning code\n */\n code?: string;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema } from 'zod/v4/core';\n\n/** JSON Schema type from Zod v4 */\ntype JsonSchema = JSONSchema.JSONSchema;\nimport type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * OpenAPI specification version 3.0.x or 3.1.x\n */\nexport type OpenAPIVersion = '3.0.0' | '3.0.1' | '3.0.2' | '3.0.3' | '3.1.0';\n\n/**\n * Unified OpenAPI Document type (supports both 3.0 and 3.1)\n */\nexport type OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document;\n\n/**\n * HTTP methods supported by OpenAPI\n */\nexport type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\n/**\n * Parameter location types\n */\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie' | 'body';\n\n/**\n * Authentication types supported\n */\nexport type AuthType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect' | 'mutualTLS';\n\n// Re-export OpenAPI types for convenience\nexport type OperationObject = OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject;\nexport type ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject;\nexport type RequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject;\nexport type ResponseObject = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject;\nexport type ResponsesObject = OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;\nexport type MediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject;\nexport type HeaderObject = OpenAPIV3.HeaderObject | OpenAPIV3_1.HeaderObject;\nexport type ExampleObject = OpenAPIV3.ExampleObject | OpenAPIV3_1.ExampleObject;\nexport type PathItemObject = OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject;\nexport type PathsObject = OpenAPIV3.PathsObject | OpenAPIV3_1.PathsObject;\nexport type ServerObject = OpenAPIV3.ServerObject | OpenAPIV3_1.ServerObject;\nexport type SecuritySchemeObject = OpenAPIV3.SecuritySchemeObject | OpenAPIV3_1.SecuritySchemeObject;\nexport type ReferenceObject = OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject;\nexport type TagObject = OpenAPIV3.TagObject | OpenAPIV3_1.TagObject;\nexport type ExternalDocumentationObject =\n | OpenAPIV3.ExternalDocumentationObject\n | OpenAPIV3_1.ExternalDocumentationObject;\nexport type ServerVariableObject = OpenAPIV3.ServerVariableObject | OpenAPIV3_1.ServerVariableObject;\nexport type EncodingObject = OpenAPIV3.EncodingObject | OpenAPIV3_1.EncodingObject;\nexport type SecurityRequirementObject = OpenAPIV3.SecurityRequirementObject | OpenAPIV3_1.SecurityRequirementObject;\nexport type SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject;\n\n/**\n * Helper to check if an object is a ReferenceObject\n */\nexport function isReferenceObject(obj: any): obj is ReferenceObject {\n return obj && typeof obj === 'object' && '$ref' in obj;\n}\n\n/**\n * Convert OpenAPI schema to JsonSchema\n * Note: OpenAPI 3.0 uses a subset of JSON Schema Draft 4\n * OpenAPI 3.1 uses JSON Schema Draft 2020-12\n */\nexport function toJsonSchema(schema: SchemaObject | ReferenceObject): JsonSchema {\n if (isReferenceObject(schema)) {\n return { $ref: schema.$ref } as JsonSchema;\n }\n\n // Handle OpenAPI 3.0 boolean exclusiveMaximum/exclusiveMinimum\n // by converting them to JSON Schema Draft 7 numeric format\n const { exclusiveMaximum, exclusiveMinimum, maximum, minimum, ...rest } = schema;\n\n const result: Record<string, unknown> = { ...rest };\n\n // Handle exclusiveMaximum conversion\n if (typeof exclusiveMaximum === 'boolean') {\n if (exclusiveMaximum && maximum !== undefined) {\n // true + maximum present -> convert to numeric exclusiveMaximum\n result['exclusiveMaximum'] = maximum;\n } else if (maximum !== undefined) {\n // false or true without maximum -> keep maximum only\n result['maximum'] = maximum;\n }\n // Boolean exclusiveMaximum is never added (invalid in JSON Schema 7)\n } else if (exclusiveMaximum !== undefined) {\n // Already numeric (OpenAPI 3.1) - keep as is\n result['exclusiveMaximum'] = exclusiveMaximum;\n if (maximum !== undefined) {\n result['maximum'] = maximum;\n }\n } else if (maximum !== undefined) {\n // No exclusiveMaximum, just maximum\n result['maximum'] = maximum;\n }\n\n // Handle exclusiveMinimum conversion\n if (typeof exclusiveMinimum === 'boolean') {\n if (exclusiveMinimum && minimum !== undefined) {\n // true + minimum present -> convert to numeric exclusiveMinimum\n result['exclusiveMinimum'] = minimum;\n } else if (minimum !== undefined) {\n // false or true without minimum -> keep minimum only\n result['minimum'] = minimum;\n }\n // Boolean exclusiveMinimum is never added (invalid in JSON Schema 7)\n } else if (exclusiveMinimum !== undefined) {\n // Already numeric (OpenAPI 3.1) - keep as is\n result['exclusiveMinimum'] = exclusiveMinimum;\n if (minimum !== undefined) {\n result['minimum'] = minimum;\n }\n } else if (minimum !== undefined) {\n // No exclusiveMinimum, just minimum\n result['minimum'] = minimum;\n }\n\n // Recursively convert nested schemas to ensure all nested schemas are valid JsonSchema\n if (result['properties'] && typeof result['properties'] === 'object') {\n const props: Record<string, JsonSchema> = {};\n for (const [key, value] of Object.entries(result['properties'] as Record<string, SchemaObject | ReferenceObject>)) {\n props[key] = toJsonSchema(value);\n }\n result['properties'] = props;\n }\n\n if (result['items']) {\n if (Array.isArray(result['items'])) {\n result['items'] = (result['items'] as (SchemaObject | ReferenceObject)[]).map(toJsonSchema);\n } else {\n result['items'] = toJsonSchema(result['items'] as SchemaObject | ReferenceObject);\n }\n }\n\n if (result['additionalProperties'] && typeof result['additionalProperties'] === 'object') {\n result['additionalProperties'] = toJsonSchema(result['additionalProperties'] as SchemaObject | ReferenceObject);\n }\n\n for (const key of ['allOf', 'anyOf', 'oneOf'] as const) {\n if (result[key] && Array.isArray(result[key])) {\n result[key] = (result[key] as (SchemaObject | ReferenceObject)[]).map(toJsonSchema);\n }\n }\n\n if (result['not']) {\n result['not'] = toJsonSchema(result['not'] as SchemaObject | ReferenceObject);\n }\n\n return result as JsonSchema;\n}\n\n/**\n * Main MCP Tool definition generated from OpenAPI\n */\nexport interface McpOpenAPITool {\n /**\n * Unique tool name (from operationId or generated)\n */\n name: string;\n\n /**\n * Tool description (from operation summary/description)\n */\n description: string;\n\n /**\n * Combined input schema including all parameters\n * (path, query, header, cookie, body)\n */\n inputSchema: JsonSchema;\n\n /**\n * Output schema based on response definitions\n * Can be a union of multiple status codes\n */\n outputSchema?: JsonSchema;\n\n /**\n * Mapping from input schema properties to actual request parameters\n */\n mapper: ParameterMapper[];\n\n /**\n * Additional metadata about the tool\n */\n metadata: ToolMetadata;\n}\n\n/**\n * Maps input schema properties to their actual request locations\n */\nexport interface ParameterMapper {\n /**\n * Property name in the input schema\n */\n inputKey: string;\n\n /**\n * Where this parameter should be placed in the request\n */\n type: ParameterLocation;\n\n /**\n * Original parameter name (before conflict resolution)\n */\n key: string;\n\n /**\n * Whether this parameter is required\n */\n required?: boolean;\n\n /**\n * Parameter style (for path/query parameters)\n */\n style?: string;\n\n /**\n * Whether to explode arrays/objects\n */\n explode?: boolean;\n\n /**\n * Custom serialization info\n */\n serialization?: SerializationInfo;\n\n /**\n * Security scheme information (if this is an auth parameter)\n * This allows frameworks to resolve auth from context, env vars, etc.\n */\n security?: SecurityParameterInfo;\n}\n\n/**\n * Serialization information for complex parameters\n */\nexport interface SerializationInfo {\n /**\n * Content type for body parameters\n */\n contentType?: string;\n\n /**\n * Encoding rules\n */\n encoding?: Record<string, EncodingObject>;\n}\n\n/**\n * Security parameter information for framework-agnostic auth resolution\n */\nexport interface SecurityParameterInfo {\n /**\n * Security scheme name from OpenAPI (e.g., \"BearerAuth\")\n */\n scheme: string;\n\n /**\n * Security type (apiKey, http, oauth2, openIdConnect)\n */\n type: AuthType;\n\n /**\n * HTTP authentication scheme (for type: \"http\")\n * e.g., \"bearer\", \"basic\"\n */\n httpScheme?: string;\n\n /**\n * Bearer token format (e.g., \"JWT\")\n */\n bearerFormat?: string;\n\n /**\n * Required OAuth2 scopes\n */\n scopes?: string[];\n\n /**\n * API key parameter name (for type: \"apiKey\")\n */\n apiKeyName?: string;\n\n /**\n * API key location (for type: \"apiKey\")\n */\n apiKeyIn?: 'query' | 'header' | 'cookie';\n\n /**\n * Description of the security scheme\n */\n description?: string;\n}\n\n/**\n * Additional metadata about the generated tool\n */\nexport interface ToolMetadata {\n /**\n * Original OpenAPI path\n */\n path: string;\n\n /**\n * HTTP method\n */\n method: HTTPMethod;\n\n /**\n * Operation ID from OpenAPI\n */\n operationId?: string;\n\n /**\n * Tags from OpenAPI\n */\n tags?: string[];\n\n /**\n * Whether operation is deprecated\n */\n deprecated?: boolean;\n\n /**\n * Security requirements\n */\n security?: SecurityRequirement[];\n\n /**\n * Server information\n */\n servers?: ServerInfo[];\n\n /**\n * Response status codes included in output schema\n */\n responseStatusCodes?: number[];\n\n /**\n * External documentation\n */\n externalDocs?: ExternalDocumentationObject;\n}\n\n/**\n * Security requirement definition\n */\nexport interface SecurityRequirement {\n /**\n * Security scheme name\n */\n scheme: string;\n\n /**\n * Security type\n */\n type: AuthType;\n\n /**\n * Scopes required (for OAuth2/OpenID Connect)\n */\n scopes?: string[];\n\n /**\n * Parameter name (for API key)\n */\n name?: string;\n\n /**\n * Parameter location (for API key)\n */\n in?: 'query' | 'header' | 'cookie';\n\n /**\n * HTTP authentication scheme (for type: \"http\")\n * e.g., \"bearer\", \"basic\"\n */\n httpScheme?: string;\n\n /**\n * Bearer token format (e.g., \"JWT\")\n */\n bearerFormat?: string;\n\n /**\n * Description of the security scheme\n */\n description?: string;\n}\n\n/**\n * Server information\n */\nexport interface ServerInfo {\n /**\n * Server URL\n */\n url: string;\n\n /**\n * Server description\n */\n description?: string;\n\n /**\n * Server variables\n */\n variables?: Record<string, ServerVariableObject>;\n}\n\n/**\n * Options for loading OpenAPI specifications\n */\nexport interface LoadOptions {\n /**\n * Whether to dereference $refs in schemas\n * @default true\n */\n dereference?: boolean;\n\n /**\n * Base URL for API requests\n * Overrides servers in OpenAPI spec\n */\n baseUrl?: string;\n\n /**\n * Custom HTTP headers for loading from URL\n */\n headers?: Record<string, string>;\n\n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Whether to validate the OpenAPI document\n * @default true\n */\n validate?: boolean;\n\n /**\n * Whether to follow HTTP redirects\n * @default true\n */\n followRedirects?: boolean;\n}\n\n/**\n * Operation object with additional context for filtering\n */\nexport type OperationWithContext = OperationObject & {\n path: string;\n method: string;\n};\n\n/**\n * Options for generating tools\n */\nexport interface GenerateOptions {\n /**\n * Include only these operation IDs\n */\n includeOperations?: string[];\n\n /**\n * Exclude these operation IDs\n */\n excludeOperations?: string[];\n\n /**\n * Custom filter function\n */\n filterFn?: (operation: OperationWithContext) => boolean;\n\n /**\n * Naming strategy for resolving conflicts\n */\n namingStrategy?: NamingStrategy;\n\n /**\n * Preferred response status codes (in order of preference)\n * @default [200, 201, 204, 202, 203, 206]\n */\n preferredStatusCodes?: number[];\n\n /**\n * Whether to include deprecated operations\n * @default false\n */\n includeDeprecated?: boolean;\n\n /**\n * Whether to include all response codes in output schema\n * If false, only preferred status code is used\n * @default true\n */\n includeAllResponses?: boolean;\n\n /**\n * Maximum depth for dereferencing schemas\n * @default 10\n */\n maxSchemaDepth?: number;\n\n /**\n * Whether to include examples in schemas\n * @default false\n */\n includeExamples?: boolean;\n\n /**\n * Whether to include security requirements as input parameters\n * If false, security is only in mapper (frameworks resolve from context/env/etc.)\n * If true, security is added to inputSchema as explicit parameters\n * @default false\n */\n includeSecurityInInput?: boolean;\n}\n\n/**\n * Naming strategy for resolving parameter conflicts\n */\nexport interface NamingStrategy {\n /**\n * Resolver function for parameter name conflicts\n * @param paramName - Original parameter name\n * @param location - Parameter location\n * @param index - Index of conflicting parameter (0-based)\n * @returns New parameter name\n */\n conflictResolver: (paramName: string, location: ParameterLocation, index: number) => string;\n\n /**\n * Function to generate tool names\n * @param path - OpenAPI path\n * @param method - HTTP method\n * @param operationId - Operation ID if available\n * @returns Tool name\n */\n toolNameGenerator?: (path: string, method: HTTPMethod, operationId?: string) => string;\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /**\n * Whether the document is valid\n */\n valid: boolean;\n\n /**\n * Validation errors\n */\n errors?: ValidationErrorDetail[];\n\n /**\n * Validation warnings\n */\n warnings?: ValidationWarning[];\n}\n\n/**\n * Validation error detail\n */\nexport interface ValidationErrorDetail {\n /**\n * Error message\n */\n message: string;\n\n /**\n * Error path (JSON pointer)\n */\n path?: string;\n\n /**\n * Error code\n */\n code?: string;\n}\n\n/**\n * Validation warning\n */\nexport interface ValidationWarning {\n /**\n * Warning message\n */\n message: string;\n\n /**\n * Warning path (JSON pointer)\n */\n path?: string;\n\n /**\n * Warning code\n */\n code?: string;\n}\n"]}
package/src/validator.js CHANGED
@@ -150,7 +150,9 @@ class Validator {
150
150
  }
151
151
  // Check for path parameters in path string
152
152
  const pathParams = path.match(/\{([^}]+)\}/g)?.map((p) => p.slice(1, -1)) ?? [];
153
- const definedPathParams = new Set(operation.parameters?.filter((p) => p.in === 'path').map((p) => p.name) ?? []);
153
+ const definedPathParams = new Set(operation.parameters
154
+ ?.filter((p) => p.in === 'path')
155
+ .map((p) => p.name) ?? []);
154
156
  for (const param of pathParams) {
155
157
  if (!definedPathParams.has(param)) {
156
158
  errors.push({
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/validator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OpenAPIDocument, ValidationResult, ValidationErrorDetail, ValidationWarning } from './types';\nimport { ValidationError } from './errors';\n\n/**\n * Validates OpenAPI documents\n */\nexport class Validator {\n /**\n * Validate an OpenAPI document\n */\n async validate(document: OpenAPIDocument): Promise<ValidationResult> {\n const errors: ValidationErrorDetail[] = [];\n const warnings: ValidationWarning[] = [];\n\n // Check OpenAPI version\n if (!document.openapi) {\n errors.push({\n message: 'Missing required field: openapi',\n path: '/openapi',\n code: 'MISSING_OPENAPI_VERSION',\n });\n } else if (!this.isValidOpenAPIVersion(document.openapi)) {\n errors.push({\n message: `Unsupported OpenAPI version: ${document.openapi}. Expected 3.0.x or 3.1.x`,\n path: '/openapi',\n code: 'INVALID_OPENAPI_VERSION',\n });\n }\n\n // Check info\n if (!document.info) {\n errors.push({\n message: 'Missing required field: info',\n path: '/info',\n code: 'MISSING_INFO',\n });\n } else {\n if (!document.info.title) {\n errors.push({\n message: 'Missing required field: info.title',\n path: '/info/title',\n code: 'MISSING_TITLE',\n });\n }\n if (!document.info.version) {\n errors.push({\n message: 'Missing required field: info.version',\n path: '/info/version',\n code: 'MISSING_VERSION',\n });\n }\n }\n\n // Check paths\n if (!document.paths || Object.keys(document.paths).length === 0) {\n warnings.push({\n message: 'No paths defined in OpenAPI document',\n path: '/paths',\n code: 'NO_PATHS',\n });\n } else {\n this.validatePaths(document.paths, errors, warnings);\n }\n\n // Check servers\n if (!document.servers || document.servers.length === 0) {\n warnings.push({\n message: 'No servers defined. You may need to provide a baseUrl option.',\n path: '/servers',\n code: 'NO_SERVERS',\n });\n }\n\n // Check security schemes\n if (document.security && !document.components?.securitySchemes) {\n warnings.push({\n message: 'Security requirements defined but no security schemes found',\n path: '/security',\n code: 'NO_SECURITY_SCHEMES',\n });\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n }\n\n /**\n * Check if OpenAPI version is valid\n */\n private isValidOpenAPIVersion(version: string): boolean {\n return /^3\\.[01]\\.\\d+$/.test(version);\n }\n\n /**\n * Validate paths\n */\n private validatePaths(\n paths: Record<string, any>,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[],\n ): void {\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem) continue;\n\n // Check path format\n if (!path.startsWith('/')) {\n errors.push({\n message: `Path must start with '/': ${path}`,\n path: `/paths/${path}`,\n code: 'INVALID_PATH_FORMAT',\n });\n }\n\n // Validate operations\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n let hasOperations = false;\n\n for (const method of methods) {\n const operation = pathItem[method];\n if (operation) {\n hasOperations = true;\n this.validateOperation(operation, path, method, errors, warnings);\n }\n }\n\n if (!hasOperations && !pathItem.$ref) {\n warnings.push({\n message: `Path has no operations: ${path}`,\n path: `/paths/${path}`,\n code: 'NO_OPERATIONS',\n });\n }\n }\n }\n\n /**\n * Validate an operation\n */\n private validateOperation(\n operation: any,\n path: string,\n method: string,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[],\n ): void {\n const basePath = `/paths/${path}/${method}`;\n\n // Check for operationId\n if (!operation.operationId) {\n warnings.push({\n message: `Operation missing operationId: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/operationId`,\n code: 'NO_OPERATION_ID',\n });\n }\n\n // Check for responses\n if (!operation.responses || Object.keys(operation.responses).length === 0) {\n errors.push({\n message: `Operation missing responses: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/responses`,\n code: 'NO_RESPONSES',\n });\n }\n\n // Validate parameters\n if (operation.parameters) {\n this.validateParameters(operation.parameters, path, method, errors, warnings);\n }\n\n // Check for path parameters in path string\n const pathParams = path.match(/\\{([^}]+)\\}/g)?.map((p) => p.slice(1, -1)) ?? [];\n const definedPathParams = new Set(\n operation.parameters?.filter((p: any) => p.in === 'path').map((p: any) => p.name) ?? [],\n );\n\n for (const param of pathParams) {\n if (!definedPathParams.has(param)) {\n errors.push({\n message: `Path parameter '${param}' not defined in parameters: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/parameters`,\n code: 'MISSING_PATH_PARAMETER',\n });\n }\n }\n }\n\n /**\n * Validate parameters\n */\n private validateParameters(\n parameters: any[],\n path: string,\n method: string,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[],\n ): void {\n const basePath = `/paths/${path}/${method}/parameters`;\n\n for (let i = 0; i < parameters.length; i++) {\n const param = parameters[i];\n const paramPath = `${basePath}/${i}`;\n\n if (!param.name) {\n errors.push({\n message: 'Parameter missing name',\n path: `${paramPath}/name`,\n code: 'MISSING_PARAMETER_NAME',\n });\n }\n\n if (!param.in) {\n errors.push({\n message: 'Parameter missing \"in\" field',\n path: `${paramPath}/in`,\n code: 'MISSING_PARAMETER_IN',\n });\n } else if (!['path', 'query', 'header', 'cookie'].includes(param.in)) {\n errors.push({\n message: `Invalid parameter location: ${param.in}`,\n path: `${paramPath}/in`,\n code: 'INVALID_PARAMETER_IN',\n });\n }\n\n if (param.in === 'path' && !param.required) {\n errors.push({\n message: `Path parameter '${param.name}' must be required`,\n path: `${paramPath}/required`,\n code: 'PATH_PARAMETER_NOT_REQUIRED',\n });\n }\n\n if (!param.schema && !param.content) {\n errors.push({\n message: `Parameter '${param.name}' missing schema or content`,\n path: `${paramPath}`,\n code: 'MISSING_PARAMETER_SCHEMA',\n });\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/validator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OpenAPIDocument, ValidationResult, ValidationErrorDetail, ValidationWarning } from './types';\n\n/**\n * Validates OpenAPI documents\n */\nexport class Validator {\n /**\n * Validate an OpenAPI document\n */\n async validate(document: OpenAPIDocument): Promise<ValidationResult> {\n const errors: ValidationErrorDetail[] = [];\n const warnings: ValidationWarning[] = [];\n\n // Check OpenAPI version\n if (!document.openapi) {\n errors.push({\n message: 'Missing required field: openapi',\n path: '/openapi',\n code: 'MISSING_OPENAPI_VERSION',\n });\n } else if (!this.isValidOpenAPIVersion(document.openapi)) {\n errors.push({\n message: `Unsupported OpenAPI version: ${document.openapi}. Expected 3.0.x or 3.1.x`,\n path: '/openapi',\n code: 'INVALID_OPENAPI_VERSION',\n });\n }\n\n // Check info\n if (!document.info) {\n errors.push({\n message: 'Missing required field: info',\n path: '/info',\n code: 'MISSING_INFO',\n });\n } else {\n if (!document.info.title) {\n errors.push({\n message: 'Missing required field: info.title',\n path: '/info/title',\n code: 'MISSING_TITLE',\n });\n }\n if (!document.info.version) {\n errors.push({\n message: 'Missing required field: info.version',\n path: '/info/version',\n code: 'MISSING_VERSION',\n });\n }\n }\n\n // Check paths\n if (!document.paths || Object.keys(document.paths).length === 0) {\n warnings.push({\n message: 'No paths defined in OpenAPI document',\n path: '/paths',\n code: 'NO_PATHS',\n });\n } else {\n this.validatePaths(document.paths, errors, warnings);\n }\n\n // Check servers\n if (!document.servers || document.servers.length === 0) {\n warnings.push({\n message: 'No servers defined. You may need to provide a baseUrl option.',\n path: '/servers',\n code: 'NO_SERVERS',\n });\n }\n\n // Check security schemes\n if (document.security && !document.components?.securitySchemes) {\n warnings.push({\n message: 'Security requirements defined but no security schemes found',\n path: '/security',\n code: 'NO_SECURITY_SCHEMES',\n });\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n }\n\n /**\n * Check if OpenAPI version is valid\n */\n private isValidOpenAPIVersion(version: string): boolean {\n return /^3\\.[01]\\.\\d+$/.test(version);\n }\n\n /**\n * Validate paths\n */\n private validatePaths(\n paths: Record<string, any>,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[]\n ): void {\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem) continue;\n\n // Check path format\n if (!path.startsWith('/')) {\n errors.push({\n message: `Path must start with '/': ${path}`,\n path: `/paths/${path}`,\n code: 'INVALID_PATH_FORMAT',\n });\n }\n\n // Validate operations\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n let hasOperations = false;\n\n for (const method of methods) {\n const operation = pathItem[method];\n if (operation) {\n hasOperations = true;\n this.validateOperation(operation, path, method, errors, warnings);\n }\n }\n\n if (!hasOperations && !pathItem.$ref) {\n warnings.push({\n message: `Path has no operations: ${path}`,\n path: `/paths/${path}`,\n code: 'NO_OPERATIONS',\n });\n }\n }\n }\n\n /**\n * Validate an operation\n */\n private validateOperation(\n operation: any,\n path: string,\n method: string,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[]\n ): void {\n const basePath = `/paths/${path}/${method}`;\n\n // Check for operationId\n if (!operation.operationId) {\n warnings.push({\n message: `Operation missing operationId: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/operationId`,\n code: 'NO_OPERATION_ID',\n });\n }\n\n // Check for responses\n if (!operation.responses || Object.keys(operation.responses).length === 0) {\n errors.push({\n message: `Operation missing responses: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/responses`,\n code: 'NO_RESPONSES',\n });\n }\n\n // Validate parameters\n if (operation.parameters) {\n this.validateParameters(operation.parameters, path, method, errors, warnings);\n }\n\n // Check for path parameters in path string\n const pathParams = path.match(/\\{([^}]+)\\}/g)?.map((p) => p.slice(1, -1)) ?? [];\n const definedPathParams = new Set(\n operation.parameters\n ?.filter((p: any) => p.in === 'path')\n .map((p: any) => p.name) ?? []\n );\n\n for (const param of pathParams) {\n if (!definedPathParams.has(param)) {\n errors.push({\n message: `Path parameter '${param}' not defined in parameters: ${method.toUpperCase()} ${path}`,\n path: `${basePath}/parameters`,\n code: 'MISSING_PATH_PARAMETER',\n });\n }\n }\n }\n\n /**\n * Validate parameters\n */\n private validateParameters(\n parameters: any[],\n path: string,\n method: string,\n errors: ValidationErrorDetail[],\n warnings: ValidationWarning[]\n ): void {\n const basePath = `/paths/${path}/${method}/parameters`;\n\n for (let i = 0; i < parameters.length; i++) {\n const param = parameters[i];\n const paramPath = `${basePath}/${i}`;\n\n if (!param.name) {\n errors.push({\n message: 'Parameter missing name',\n path: `${paramPath}/name`,\n code: 'MISSING_PARAMETER_NAME',\n });\n }\n\n if (!param.in) {\n errors.push({\n message: 'Parameter missing \"in\" field',\n path: `${paramPath}/in`,\n code: 'MISSING_PARAMETER_IN',\n });\n } else if (!['path', 'query', 'header', 'cookie'].includes(param.in)) {\n errors.push({\n message: `Invalid parameter location: ${param.in}`,\n path: `${paramPath}/in`,\n code: 'INVALID_PARAMETER_IN',\n });\n }\n\n if (param.in === 'path' && !param.required) {\n errors.push({\n message: `Path parameter '${param.name}' must be required`,\n path: `${paramPath}/required`,\n code: 'PATH_PARAMETER_NOT_REQUIRED',\n });\n }\n\n if (!param.schema && !param.content) {\n errors.push({\n message: `Parameter '${param.name}' missing schema or content`,\n path: `${paramPath}`,\n code: 'MISSING_PARAMETER_SCHEMA',\n });\n }\n }\n }\n}\n"]}