@mintlify/validation 0.1.98 → 0.1.100

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/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import type { ConfigType } from '@mintlify/models';
2
2
  import { MintValidationResults } from './mint-config/common.js';
3
3
  export declare function validateMintConfig(config: ConfigType): MintValidationResults;
4
4
  export * from './openapi/types/endpoint.js';
5
- export { convertOpenAPIV3_1ToEndpoint } from './openapi/convertOpenApi.js';
6
- export { convertSchema } from './openapi/convertSchema.js';
5
+ export { OpenApiToEndpointConverter } from './openapi/OpenApiToEndpointConverter.js';
6
+ export { SchemaConverter } from './openapi/SchemaConverter.js';
7
7
  export { generateExampleFromSchema } from './openapi/generateExampleFromSchema.js';
8
8
  export declare const mintConfigSchema: any;
9
9
  export { sort } from './sort.js';
package/dist/index.js CHANGED
@@ -44,8 +44,8 @@ export function validateMintConfig(config) {
44
44
  return results;
45
45
  }
46
46
  export * from './openapi/types/endpoint.js';
47
- export { convertOpenAPIV3_1ToEndpoint } from './openapi/convertOpenApi.js';
48
- export { convertSchema } from './openapi/convertSchema.js';
47
+ export { OpenApiToEndpointConverter } from './openapi/OpenApiToEndpointConverter.js';
48
+ export { SchemaConverter } from './openapi/SchemaConverter.js';
49
49
  export { generateExampleFromSchema } from './openapi/generateExampleFromSchema.js';
50
50
  export const mintConfigSchema = (() => {
51
51
  var _a, _b, _c, _d, _e, _f;
@@ -0,0 +1,6 @@
1
+ export declare abstract class BaseConverter {
2
+ readonly safeParse: boolean;
3
+ protected constructor(safeParse?: boolean);
4
+ protected handleExistingError(error: unknown, path: string[], ...messages: string[]): void;
5
+ protected handleNewError(E: new (path: string[], ...messages: string[]) => Error, path: string[], ...messages: string[]): void;
6
+ }
@@ -0,0 +1,22 @@
1
+ import { generateMessage } from './errors.js';
2
+ export class BaseConverter {
3
+ constructor(safeParse = false) {
4
+ this.safeParse = safeParse;
5
+ }
6
+ handleExistingError(error, path, ...messages) {
7
+ if (this.safeParse) {
8
+ console.error(generateMessage(path, ...messages));
9
+ }
10
+ else {
11
+ throw error;
12
+ }
13
+ }
14
+ handleNewError(E, path, ...messages) {
15
+ if (this.safeParse) {
16
+ console.error(generateMessage(path, ...messages));
17
+ }
18
+ else {
19
+ throw new E(path, ...messages);
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,15 @@
1
+ import { OpenAPIV3_1 } from 'openapi-types';
2
+ import { BaseConverter } from './BaseConverter.js';
3
+ import type { Endpoint, HttpMethod } from './types/endpoint.js';
4
+ export declare class OpenApiToEndpointConverter extends BaseConverter {
5
+ readonly document: OpenAPIV3_1.Document;
6
+ readonly path: string;
7
+ readonly method: HttpMethod;
8
+ readonly safeParse: boolean;
9
+ private constructor();
10
+ private convert;
11
+ private convertContent;
12
+ private convertExamples;
13
+ private convertResponses;
14
+ static convert(spec: OpenAPIV3_1.Document, path: string, method: HttpMethod, safeParse?: boolean): Endpoint | undefined;
15
+ }
@@ -0,0 +1,100 @@
1
+ import { BaseConverter } from './BaseConverter.js';
2
+ import { ParametersConverter } from './ParametersConverter.js';
3
+ import { SchemaConverter } from './SchemaConverter.js';
4
+ import { SecurityConverter } from './SecurityConverter.js';
5
+ import { ServersConverter } from './ServersConverter.js';
6
+ import { InvalidSchemaError } from './errors.js';
7
+ import { generateExampleFromSchema } from './generateExampleFromSchema.js';
8
+ export class OpenApiToEndpointConverter extends BaseConverter {
9
+ constructor(document, path, method, safeParse = false) {
10
+ super(safeParse);
11
+ this.document = document;
12
+ this.path = path;
13
+ this.method = method;
14
+ this.safeParse = safeParse;
15
+ }
16
+ convert() {
17
+ var _a, _b, _c, _d, _e;
18
+ const paths = this.document.paths;
19
+ if (paths === undefined) {
20
+ throw new InvalidSchemaError(['#'], 'paths not defined');
21
+ }
22
+ const pathObject = paths[this.path];
23
+ if (pathObject === undefined) {
24
+ throw new InvalidSchemaError(['#', 'paths'], `path not defined: ${this.path}`);
25
+ }
26
+ const operationObject = pathObject[this.method];
27
+ if (operationObject === undefined) {
28
+ throw new InvalidSchemaError(['#', 'paths', this.path], `operation does not exist: ${this.method}`);
29
+ }
30
+ const securityRequirements = (_a = operationObject.security) !== null && _a !== void 0 ? _a : this.document.security;
31
+ const securitySchemes = (_b = this.document.components) === null || _b === void 0 ? void 0 : _b.securitySchemes;
32
+ const security = SecurityConverter.convert(securityRequirements, securitySchemes, this.safeParse);
33
+ const pathParameters = pathObject.parameters;
34
+ const operationParameters = operationObject.parameters;
35
+ const parameters = ParametersConverter.convert(this.method, pathParameters, operationParameters, ['#', 'paths', this.path], this.safeParse);
36
+ const servers = ServersConverter.convert((_d = (_c = operationObject.servers) !== null && _c !== void 0 ? _c : pathObject.servers) !== null && _d !== void 0 ? _d : this.document.servers);
37
+ const description = (_e = operationObject.description) !== null && _e !== void 0 ? _e : pathObject.description;
38
+ const requestBody = operationObject.requestBody;
39
+ const body = this.convertContent(['#', 'paths', this.path, this.method, 'requestBody', 'content'], requestBody === null || requestBody === void 0 ? void 0 : requestBody.content, requestBody === null || requestBody === void 0 ? void 0 : requestBody.required);
40
+ const deprecated = !!operationObject.deprecated;
41
+ const response = this.convertResponses(['#', 'paths', this.path, this.method, 'responses'], operationObject.responses);
42
+ return {
43
+ description,
44
+ path: this.path,
45
+ method: this.method,
46
+ servers,
47
+ request: {
48
+ security,
49
+ parameters,
50
+ body,
51
+ },
52
+ response,
53
+ deprecated,
54
+ };
55
+ }
56
+ convertContent(debugPath, content, required) {
57
+ if (content === undefined) {
58
+ return {};
59
+ }
60
+ const newEntries = Object.entries(content).map(([contentType, mediaObject]) => {
61
+ const schemaArray = SchemaConverter.convert({
62
+ schema: mediaObject.schema,
63
+ path: [...debugPath, contentType, 'schema'],
64
+ required,
65
+ safeParse: this.safeParse,
66
+ });
67
+ const examples = this.convertExamples(mediaObject.examples, mediaObject.example, schemaArray);
68
+ return [contentType, { schemaArray, examples }];
69
+ });
70
+ return Object.fromEntries(newEntries);
71
+ }
72
+ convertExamples(examples, example, schemaArray) {
73
+ if (examples && Object.values(examples).some(({ value }) => value !== undefined)) {
74
+ return Object.fromEntries(Object.entries(examples)
75
+ .filter(([_, { value }]) => value !== undefined)
76
+ .map(([key, example]) => [
77
+ key,
78
+ {
79
+ summary: example.summary,
80
+ description: example.description,
81
+ value: example.value,
82
+ },
83
+ ]));
84
+ }
85
+ if (example !== undefined) {
86
+ return { example: { value: example } };
87
+ }
88
+ return { example: { value: generateExampleFromSchema(schemaArray[0]) } };
89
+ }
90
+ convertResponses(debugPath, responses) {
91
+ const newEntries = Object.entries(responses).map(([statusCode, response]) => [
92
+ statusCode,
93
+ this.convertContent([...debugPath, statusCode, 'content'], response.content),
94
+ ]);
95
+ return Object.fromEntries(newEntries);
96
+ }
97
+ static convert(spec, path, method, safeParse) {
98
+ return new OpenApiToEndpointConverter(spec, path, method, safeParse).convert();
99
+ }
100
+ }
@@ -0,0 +1,15 @@
1
+ import { OpenAPIV3_1 } from 'openapi-types';
2
+ import { BaseConverter } from './BaseConverter.js';
3
+ import { ParameterSections } from './types/endpoint.js';
4
+ export declare class ParametersConverter extends BaseConverter {
5
+ readonly method: string;
6
+ readonly pathParameters: OpenAPIV3_1.ParameterObject[] | undefined;
7
+ readonly operationParameters: OpenAPIV3_1.ParameterObject[] | undefined;
8
+ readonly path: string[];
9
+ readonly safeParse: boolean;
10
+ private parameterSections;
11
+ private constructor();
12
+ private convert;
13
+ private addParameter;
14
+ static convert(method: string, pathParameters: OpenAPIV3_1.ParameterObject[] | undefined, operationParameters: OpenAPIV3_1.ParameterObject[] | undefined, path: string[], safeParse?: boolean): ParameterSections;
15
+ }
@@ -0,0 +1,50 @@
1
+ import { BaseConverter } from './BaseConverter.js';
2
+ import { SchemaConverter } from './SchemaConverter.js';
3
+ import { InvalidSchemaError } from './errors.js';
4
+ import { copyKeyIfDefined } from './utils.js';
5
+ export class ParametersConverter extends BaseConverter {
6
+ constructor(method, pathParameters, operationParameters, path, safeParse = false) {
7
+ super(safeParse);
8
+ this.method = method;
9
+ this.pathParameters = pathParameters;
10
+ this.operationParameters = operationParameters;
11
+ this.path = path;
12
+ this.safeParse = safeParse;
13
+ this.parameterSections = {
14
+ path: {},
15
+ query: {},
16
+ header: {},
17
+ cookie: {},
18
+ };
19
+ }
20
+ convert() {
21
+ var _a, _b;
22
+ (_a = this.pathParameters) === null || _a === void 0 ? void 0 : _a.forEach((parameterObject, i) => {
23
+ this.addParameter([...this.path, 'parameters', i.toString()], parameterObject);
24
+ });
25
+ (_b = this.operationParameters) === null || _b === void 0 ? void 0 : _b.forEach((parameterObject, i) => {
26
+ this.addParameter([...this.path, this.method, 'parameters', i.toString()], parameterObject);
27
+ });
28
+ return this.parameterSections;
29
+ }
30
+ addParameter(path, parameter) {
31
+ if (!['path', 'header', 'query', 'cookie'].includes(parameter.in)) {
32
+ this.handleNewError(InvalidSchemaError, path, `invalid parameter location: '${parameter.in}'`);
33
+ return;
34
+ }
35
+ const location = parameter.in;
36
+ // parameter.schema may be undefined (if the schema is instead defined in parameter.content), but this is likely super rare
37
+ const parameterSchema = parameter.schema;
38
+ copyKeyIfDefined('description', parameter, parameterSchema);
39
+ copyKeyIfDefined('deprecated', parameter, parameterSchema);
40
+ const newParameter = SchemaConverter.convert({
41
+ schema: parameter.schema,
42
+ path: [...path, 'schema'],
43
+ required: location === 'path' ? true : parameter.required,
44
+ });
45
+ this.parameterSections[location][parameter.name] = { schema: newParameter };
46
+ }
47
+ static convert(method, pathParameters, operationParameters, path, safeParse) {
48
+ return new ParametersConverter(method, pathParameters, operationParameters, path, safeParse).convert();
49
+ }
50
+ }
@@ -0,0 +1,62 @@
1
+ import { OpenAPIV3_1 } from 'openapi-types';
2
+ import { BaseConverter } from './BaseConverter.js';
3
+ import { DataSchemaArray } from './types/endpoint.js';
4
+ export declare class SchemaConverter extends BaseConverter {
5
+ readonly schema: OpenAPIV3_1.SchemaObject | undefined;
6
+ readonly required?: boolean | undefined;
7
+ readonly path: string[];
8
+ readonly location?: "request" | "response" | undefined;
9
+ readonly safeParse: boolean;
10
+ private constructor();
11
+ /**
12
+ * This function converts the `schema` property into a `DataSchemaArray`. Due to
13
+ * the recursive nature of OpenAPI schemas, this conversion happens in two parts:
14
+ *
15
+ * 1. **Reduction**\*: The schema is transformed into its *reduced form*. In this form,
16
+ * the schema and any subschemas are represented by a schema with one property, `oneOf`,
17
+ * whose items are guaranteed NOT to have a `oneOf`, `anyOf`, or `allOf` property.
18
+ *
19
+ * 2. **Conversion**: In this step, we take a schema in its reduced form and convert it
20
+ * into a new data type. This is fairly straightforward, as we just need to convert
21
+ * each element of each `oneOf` schema to a `DataSchema`, and do this for all subschemas.
22
+ *
23
+ * \*We call this step a reduction rather than a conversion because the result is still
24
+ * of the `OpenAPIV3_1.SchemaObject` type.
25
+ *
26
+ * @returns An array of `DataSchema` objects representing all valid schemas
27
+ */
28
+ private convert;
29
+ /**
30
+ * This function should be used to reduce strictly `oneOf` and `anyOf` compositions.
31
+ *
32
+ * @param schemaArray `schema.allOf` or `schema.oneOf`
33
+ * @returns a schema array equivalent to the `schemaArray` argument, but in reduced form
34
+ */
35
+ private reduceOptionsCompositions;
36
+ private reduceCompositionsRecursive;
37
+ private generateTopLevelSchemaArray;
38
+ /**
39
+ * Given two arrays representing schema options, return an array representing schema options that satisfy one element in both arrays.
40
+ *
41
+ * It is helpful to think of each array as a union of all the schemas in the array. This function can then be thought of as taking
42
+ * the intersection of the two union types.
43
+ *
44
+ * Used in the Reduction step.
45
+ *
46
+ * @param a first array of schema options
47
+ * @param b second array of schema options
48
+ * @returns array of schemas that satisfy both arrays
49
+ */
50
+ private multiplySchemaArrays;
51
+ private combineReducedSchemas;
52
+ private combineTopLevelSchemas;
53
+ private convertSchemaRecursive;
54
+ private convertProperties;
55
+ static convert({ schema, required, path, location, safeParse, }: {
56
+ schema: OpenAPIV3_1.SchemaObject | undefined;
57
+ required?: boolean;
58
+ path?: string[];
59
+ location?: 'request' | 'response';
60
+ safeParse?: boolean;
61
+ }): DataSchemaArray;
62
+ }