@mintlify/common 1.0.1205 → 1.0.1207

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,97 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { getComponentNameFromRef, getPathItemOperations, isFixedHttpMethod, } from '@mintlify/validation';
13
+ export const escapePointer = (segment) => segment.replaceAll('~', '~0').replaceAll('/', '~1');
14
+ export const operationPointer = (method) => isFixedHttpMethod(method)
15
+ ? escapePointer(method)
16
+ : `additionalOperations/${escapePointer(method)}`;
17
+ const REFERENCE_ONLY_KEYS = new Set(['$ref', 'summary', 'description']);
18
+ const isBareLocalRef = (value, section, components) => {
19
+ var _a;
20
+ if (!('$ref' in value) || typeof value.$ref !== 'string')
21
+ return false;
22
+ const name = getComponentNameFromRef(value.$ref, section);
23
+ if (name === undefined || !((_a = components === null || components === void 0 ? void 0 : components[section]) === null || _a === void 0 ? void 0 : _a[name]))
24
+ return false;
25
+ return Object.keys(value).every((key) => REFERENCE_ONLY_KEYS.has(key));
26
+ };
27
+ export const resolvePathItem = (pathItem, components, seen = new Set()) => {
28
+ var _a;
29
+ if (!('$ref' in pathItem) || typeof pathItem.$ref !== 'string')
30
+ return pathItem;
31
+ const { $ref, summary, description } = pathItem, siblings = __rest(pathItem, ["$ref", "summary", "description"]);
32
+ const name = getComponentNameFromRef($ref, 'pathItems');
33
+ const key = `pathItems/${name}`;
34
+ const target = name !== undefined && !seen.has(key) ? (_a = components === null || components === void 0 ? void 0 : components.pathItems) === null || _a === void 0 ? void 0 : _a[name] : undefined;
35
+ const resolvedTarget = target
36
+ ? resolvePathItem(target, components, seen.add(key))
37
+ : {};
38
+ const inline = siblings;
39
+ const additionalOperations = resolvedTarget.additionalOperations || inline.additionalOperations
40
+ ? Object.assign(Object.assign({}, resolvedTarget.additionalOperations), inline.additionalOperations) : undefined;
41
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, resolvedTarget), inline), (additionalOperations ? { additionalOperations } : {})), (summary !== undefined ? { summary } : {})), (description !== undefined ? { description } : {}));
42
+ };
43
+ const resolveCallback = (callback, components, seen) => {
44
+ var _a;
45
+ if (!('$ref' in callback))
46
+ return callback;
47
+ if (typeof callback.$ref !== 'string')
48
+ return undefined;
49
+ const name = getComponentNameFromRef(callback.$ref, 'callbacks');
50
+ const key = `callbacks/${name}`;
51
+ if (name === undefined || seen.has(key))
52
+ return undefined;
53
+ const target = (_a = components === null || components === void 0 ? void 0 : components.callbacks) === null || _a === void 0 ? void 0 : _a[name];
54
+ return target ? resolveCallback(target, components, seen.add(key)) : undefined;
55
+ };
56
+ export const forEachPathItem = (document, visit) => {
57
+ var _a, _b;
58
+ const { components } = document;
59
+ const visitCallback = (location, raw, chain) => {
60
+ if (isBareLocalRef(raw, 'callbacks', components))
61
+ return;
62
+ const seen = new Set(chain);
63
+ const callback = resolveCallback(raw, components, seen);
64
+ for (const [expression, item] of Object.entries(callback !== null && callback !== void 0 ? callback : {})) {
65
+ visitPathItem(`${location}/${escapePointer(expression)}`, item, seen);
66
+ }
67
+ };
68
+ const visitPathItem = (location, raw, chain) => {
69
+ var _a;
70
+ if (isBareLocalRef(raw, 'pathItems', components))
71
+ return;
72
+ const seen = new Set(chain);
73
+ const pathItem = resolvePathItem(raw, components, seen);
74
+ visit(location, pathItem);
75
+ for (const [method, operation] of getPathItemOperations(pathItem)) {
76
+ for (const [name, rawCallback] of Object.entries((_a = operation.callbacks) !== null && _a !== void 0 ? _a : {})) {
77
+ visitCallback(`${location}/${operationPointer(method)}/callbacks/${escapePointer(name)}`, rawCallback, seen);
78
+ }
79
+ }
80
+ };
81
+ for (const [name, item] of Object.entries((_a = components === null || components === void 0 ? void 0 : components.pathItems) !== null && _a !== void 0 ? _a : {})) {
82
+ visitPathItem(`/components/pathItems/${escapePointer(name)}`, item, new Set([`pathItems/${name}`]));
83
+ }
84
+ for (const [name, callback] of Object.entries((_b = components === null || components === void 0 ? void 0 : components.callbacks) !== null && _b !== void 0 ? _b : {})) {
85
+ visitCallback(`/components/callbacks/${escapePointer(name)}`, callback, new Set([`callbacks/${name}`]));
86
+ }
87
+ const roots = [
88
+ ['/paths', document.paths],
89
+ ['/webhooks', document.webhooks],
90
+ ];
91
+ for (const [prefix, entries] of roots) {
92
+ for (const [key, item] of Object.entries(entries !== null && entries !== void 0 ? entries : {})) {
93
+ if (item)
94
+ visitPathItem(`${prefix}/${escapePointer(key)}`, item, new Set());
95
+ }
96
+ }
97
+ };
@@ -1,5 +1,3 @@
1
- import { type OpenAPIV3_2 } from '@mintlify/validation';
1
+ import { type PathItemSources } from './pathItems.js';
2
2
  import type { OpenApiValidateError } from './validate.js';
3
- type PathItemSources = Partial<Pick<OpenAPIV3_2.Document, 'paths' | 'webhooks' | 'components'>>;
4
3
  export declare const validateQuerystringParameters: (document: PathItemSources) => OpenApiValidateError[];
5
- export {};
@@ -1,22 +1,10 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { getPathItemOperations, isFixedHttpMethod } from '@mintlify/validation';
13
- const escapePointer = (segment) => segment.replaceAll('~', '~0').replaceAll('/', '~1');
14
- const componentName = (ref, section) => { var _a; return (_a = new RegExp(`^#/components/${section}/(.+)$`).exec(ref)) === null || _a === void 0 ? void 0 : _a[1]; };
1
+ import { getComponentNameFromRef, getPathItemOperations, isFixedHttpMethod, } from '@mintlify/validation';
2
+ import { escapePointer, forEachPathItem } from './pathItems.js';
15
3
  const resolveParameter = (parameter, components, seen = new Set()) => {
16
4
  var _a;
17
5
  if (!('$ref' in parameter))
18
6
  return parameter;
19
- const name = componentName(parameter.$ref, 'parameters');
7
+ const name = getComponentNameFromRef(parameter.$ref, 'parameters');
20
8
  if (name === undefined || seen.has(name))
21
9
  return undefined;
22
10
  const resolved = (_a = components === null || components === void 0 ? void 0 : components.parameters) === null || _a === void 0 ? void 0 : _a[name];
@@ -27,37 +15,13 @@ const querystringNames = (parameters, components) => new Set(parameters.flatMap(
27
15
  const resolved = resolveParameter(parameter, components);
28
16
  return (resolved === null || resolved === void 0 ? void 0 : resolved.in) === 'querystring' ? [resolved.name] : [];
29
17
  }));
30
- const resolvePathItem = (pathItem, components, seen = new Set()) => {
31
- var _a;
32
- if (!('$ref' in pathItem) || typeof pathItem.$ref !== 'string')
33
- return pathItem;
34
- const { $ref, summary, description } = pathItem, siblings = __rest(pathItem, ["$ref", "summary", "description"]);
35
- const name = componentName($ref, 'pathItems');
36
- const target = name !== undefined && !seen.has(name) ? (_a = components === null || components === void 0 ? void 0 : components.pathItems) === null || _a === void 0 ? void 0 : _a[name] : undefined;
37
- const resolvedTarget = target && name !== undefined ? resolvePathItem(target, components, seen.add(name)) : {};
38
- return Object.assign(Object.assign(Object.assign({}, resolvedTarget), siblings), { summary, description });
39
- };
40
18
  export const validateQuerystringParameters = (document) => {
41
- var _a, _b, _c, _d, _e, _f, _g, _h;
42
19
  const errors = [];
43
- const pathItems = [
44
- ...Object.entries((_a = document.paths) !== null && _a !== void 0 ? _a : {}).map(([path, item]) => [`/paths/${escapePointer(path)}`, item]),
45
- ...Object.entries((_b = document.webhooks) !== null && _b !== void 0 ? _b : {}).map(([name, item]) => [
46
- `/webhooks/${escapePointer(name)}`,
47
- item,
48
- ]),
49
- ...Object.entries((_d = (_c = document.components) === null || _c === void 0 ? void 0 : _c.pathItems) !== null && _d !== void 0 ? _d : {}).map(([name, item]) => [
50
- `/components/pathItems/${escapePointer(name)}`,
51
- item,
52
- ]),
53
- ];
54
- for (const [location, rawPathItem] of pathItems) {
55
- if (!rawPathItem)
56
- continue;
57
- const pathItem = resolvePathItem(rawPathItem, document.components);
58
- const pathLocations = ((_e = pathItem.parameters) !== null && _e !== void 0 ? _e : []).map((parameter) => parameterLocation(parameter, document.components));
20
+ forEachPathItem(document, (location, pathItem) => {
21
+ var _a, _b, _c, _d;
22
+ const pathLocations = ((_a = pathItem.parameters) !== null && _a !== void 0 ? _a : []).map((parameter) => parameterLocation(parameter, document.components));
59
23
  for (const [method, operation] of getPathItemOperations(pathItem)) {
60
- const operationLocations = ((_f = operation.parameters) !== null && _f !== void 0 ? _f : []).map((parameter) => parameterLocation(parameter, document.components));
24
+ const operationLocations = ((_b = operation.parameters) !== null && _b !== void 0 ? _b : []).map((parameter) => parameterLocation(parameter, document.components));
61
25
  const locations = [...pathLocations, ...operationLocations];
62
26
  const operationPointer = isFixedHttpMethod(method)
63
27
  ? escapePointer(method)
@@ -68,7 +32,7 @@ export const validateQuerystringParameters = (document) => {
68
32
  message: 'in: querystring cannot be combined with in: query parameters on the same operation',
69
33
  });
70
34
  }
71
- const names = querystringNames([...((_g = pathItem.parameters) !== null && _g !== void 0 ? _g : []), ...((_h = operation.parameters) !== null && _h !== void 0 ? _h : [])], document.components);
35
+ const names = querystringNames([...((_c = pathItem.parameters) !== null && _c !== void 0 ? _c : []), ...((_d = operation.parameters) !== null && _d !== void 0 ? _d : [])], document.components);
72
36
  if (names.size > 1) {
73
37
  errors.push({
74
38
  path: `${location}/${operationPointer}/parameters`,
@@ -76,6 +40,6 @@ export const validateQuerystringParameters = (document) => {
76
40
  });
77
41
  }
78
42
  }
79
- }
43
+ });
80
44
  return errors;
81
45
  };
@@ -0,0 +1,6 @@
1
+ import { type OpenAPIV3_2 } from '@mintlify/validation';
2
+ import { type PathItemSources } from './pathItems.js';
3
+ import type { OpenApiValidateError } from './validate.js';
4
+ type ServerSources = PathItemSources & Partial<Pick<OpenAPIV3_2.Document, 'servers'>>;
5
+ export declare const validateServerUrls: (document: ServerSources) => OpenApiValidateError[];
6
+ export {};
@@ -0,0 +1,50 @@
1
+ import { getPathItemOperations } from '@mintlify/validation';
2
+ import { escapePointer, forEachPathItem, operationPointer, } from './pathItems.js';
3
+ const duplicateVariables = (url) => {
4
+ var _a;
5
+ const seen = new Map();
6
+ for (const match of url.matchAll(/\{([^{}]+)\}/g)) {
7
+ const name = match[1];
8
+ if (name !== undefined)
9
+ seen.set(name, ((_a = seen.get(name)) !== null && _a !== void 0 ? _a : 0) + 1);
10
+ }
11
+ return [...seen.entries()].filter(([, count]) => count > 1).map(([name]) => name);
12
+ };
13
+ export const validateServerUrls = (document) => {
14
+ var _a, _b;
15
+ const errors = [];
16
+ const checkServer = (location, server) => {
17
+ if (!server)
18
+ return;
19
+ for (const name of duplicateVariables(server.url)) {
20
+ errors.push({
21
+ path: `${location}/url`,
22
+ message: `Server variable {${name}} appears more than once in the URL`,
23
+ });
24
+ }
25
+ };
26
+ const checkServers = (location, servers) => servers === null || servers === void 0 ? void 0 : servers.forEach((server, index) => checkServer(`${location}/${index}`, server));
27
+ const checkLinks = (location, links) => {
28
+ for (const [name, link] of Object.entries(links !== null && links !== void 0 ? links : {})) {
29
+ if (!('$ref' in link))
30
+ checkServer(`${location}/${escapePointer(name)}/server`, link.server);
31
+ }
32
+ };
33
+ const checkResponses = (location, responses) => {
34
+ for (const [code, response] of Object.entries(responses !== null && responses !== void 0 ? responses : {})) {
35
+ if (!('$ref' in response))
36
+ checkLinks(`${location}/${escapePointer(code)}/links`, response.links);
37
+ }
38
+ };
39
+ checkServers('/servers', document.servers);
40
+ checkLinks('/components/links', (_a = document.components) === null || _a === void 0 ? void 0 : _a.links);
41
+ checkResponses('/components/responses', (_b = document.components) === null || _b === void 0 ? void 0 : _b.responses);
42
+ forEachPathItem(document, (location, pathItem) => {
43
+ checkServers(`${location}/servers`, pathItem.servers);
44
+ for (const [method, operation] of getPathItemOperations(pathItem)) {
45
+ checkServers(`${location}/${operationPointer(method)}/servers`, operation.servers);
46
+ checkResponses(`${location}/${operationPointer(method)}/responses`, operation.responses);
47
+ }
48
+ });
49
+ return errors;
50
+ };
@@ -8,12 +8,44 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { getEntrypoint, normalize, validate as scalarValidate } from '@mintlify/openapi-parser';
11
+ import { isComponentPathItemReference, resolvePathItemReference } from '@mintlify/validation';
11
12
  import { checkForExternalRefs } from '../asyncapi/checkForExternalRefs.js';
12
13
  import { validateAdditionalOperations } from './additionalOperations.js';
14
+ import { validateDiscriminatorDefaults } from './discriminators.js';
15
+ import { validatePositionalEncodings } from './encodings.js';
16
+ import { validateHeaderNames } from './headerNames.js';
13
17
  import { validateQuerystringParameters } from './querystringParameters.js';
18
+ import { validateServerUrls } from './servers.js';
14
19
  import { validateOpenApiTagTree } from './tagHierarchy.js';
15
20
  export const isOpenApi32Version = (version) => typeof version === 'string' && /^3\.2(\.|$)/.test(version);
16
21
  export const getEntrypointSpecification = (document) => { var _a; return Array.isArray(document) ? (_a = getEntrypoint(document)) === null || _a === void 0 ? void 0 : _a.specification : document; };
22
+ const inlineComponentPathItemReferences = (document, specification) => {
23
+ var _a;
24
+ if (typeof specification.openapi !== 'string' || !/^3\.[12](\.|$)/.test(specification.openapi))
25
+ return document;
26
+ const sections = ['paths', 'webhooks'].flatMap((section) => {
27
+ const entries = specification[section];
28
+ if (typeof entries !== 'object' || entries === null)
29
+ return [];
30
+ const referenced = Object.keys(entries).filter((key) => isComponentPathItemReference(entries[key]));
31
+ return referenced.length > 0 ? [{ section, referenced }] : [];
32
+ });
33
+ if (sections.length === 0)
34
+ return document;
35
+ const inlined = structuredClone(specification);
36
+ for (const { section, referenced } of sections) {
37
+ const entries = inlined[section];
38
+ for (const key of referenced) {
39
+ const item = entries[key];
40
+ if (typeof item !== 'object' || item === null)
41
+ continue;
42
+ entries[key] = (_a = resolvePathItemReference(item, inlined.components)) !== null && _a !== void 0 ? _a : item;
43
+ }
44
+ }
45
+ if (!Array.isArray(document))
46
+ return inlined;
47
+ return document.map((entry) => entry.specification === specification ? Object.assign(Object.assign({}, entry), { specification: inlined }) : entry);
48
+ };
17
49
  const validateOpenApi32 = (document, specification) => __awaiter(void 0, void 0, void 0, function* () {
18
50
  const outcome = yield scalarValidate(document);
19
51
  if (!outcome.valid)
@@ -22,6 +54,10 @@ const validateOpenApi32 = (document, specification) => __awaiter(void 0, void 0,
22
54
  ...validateOpenApiTagTree(specification.tags).map((message) => ({ path: '/tags', message })),
23
55
  ...validateAdditionalOperations(specification),
24
56
  ...validateQuerystringParameters(specification),
57
+ ...validateDiscriminatorDefaults(specification),
58
+ ...validatePositionalEncodings(specification),
59
+ ...validateHeaderNames(specification),
60
+ ...validateServerUrls(specification),
25
61
  ];
26
62
  if (structuralErrors.length > 0) {
27
63
  return { valid: false, version: '3.2', errors: structuralErrors };
@@ -47,9 +83,12 @@ export const safeValidate = (document) => __awaiter(void 0, void 0, void 0, func
47
83
  const normalized = normalize(document);
48
84
  const specification = getEntrypointSpecification(normalized);
49
85
  const openApi32Specification = specification && isOpenApi32Version(specification.openapi) ? specification : undefined;
86
+ const inlined = specification
87
+ ? inlineComponentPathItemReferences(normalized, specification)
88
+ : normalized;
50
89
  const result = openApi32Specification
51
- ? yield validateOpenApi32(normalized, openApi32Specification)
52
- : yield scalarValidate(normalized);
90
+ ? yield validateOpenApi32(inlined, openApi32Specification)
91
+ : yield scalarValidate(inlined);
53
92
  const { errors, schema, valid, version } = result;
54
93
  if (version === '2.0')
55
94
  return Object.assign(Object.assign({}, result), { errorMessage: 'OpenAPI versions prior to 3.0 not supported', valid: false });