@mintlify/common 1.0.1202 → 1.0.1204

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,101 @@
1
+ import { getTagDisplayName } from './getTagDisplayName.js';
2
+ import { isOpenApi32Version } from './validate.js';
3
+ export const isOpenApi32 = (schema) => 'openapi' in schema && isOpenApi32Version(schema.openapi);
4
+ export function validateOpenApiTagTree(tags = []) {
5
+ const errors = [];
6
+ const byName = new Map();
7
+ for (const tag of tags) {
8
+ if (byName.has(tag.name))
9
+ errors.push(`Duplicate OpenAPI tag name: ${tag.name}`);
10
+ byName.set(tag.name, tag);
11
+ }
12
+ for (const tag of tags) {
13
+ if (tag.parent !== undefined && !byName.has(tag.parent)) {
14
+ errors.push(`OpenAPI tag ${tag.name} has unknown parent: ${tag.parent}`);
15
+ }
16
+ }
17
+ const reachesRoot = new Set();
18
+ for (const tag of tags) {
19
+ const seen = new Set();
20
+ let current = tag;
21
+ let circular = false;
22
+ while ((current === null || current === void 0 ? void 0 : current.parent) !== undefined && !reachesRoot.has(current.name)) {
23
+ if (seen.has(current.name)) {
24
+ errors.push(`Circular OpenAPI tag parent reference: ${current.name}`);
25
+ circular = true;
26
+ break;
27
+ }
28
+ seen.add(current.name);
29
+ current = byName.get(current.parent);
30
+ }
31
+ if (!circular)
32
+ seen.forEach((name) => reachesRoot.add(name));
33
+ }
34
+ return errors;
35
+ }
36
+ export function createOpenApiTagResolver(schema) {
37
+ var _a;
38
+ const tags = (_a = schema.tags) !== null && _a !== void 0 ? _a : [];
39
+ const nested = isOpenApi32(schema);
40
+ const byName = new Map(tags.map((tag) => [tag.name, tag]));
41
+ const paths = new Map();
42
+ function resolvePath(name) {
43
+ var _a;
44
+ const cached = paths.get(name);
45
+ if (cached)
46
+ return cached;
47
+ const path = [];
48
+ const ancestors = new Set();
49
+ let current = name;
50
+ while (current !== undefined && !ancestors.has(current)) {
51
+ ancestors.add(current);
52
+ const tag = byName.get(current);
53
+ if ((tag === null || tag === void 0 ? void 0 : tag.kind) === undefined || tag.kind === 'nav' || current === name) {
54
+ path.push({
55
+ name: current,
56
+ label: (_a = tag === null || tag === void 0 ? void 0 : tag['x-group']) !== null && _a !== void 0 ? _a : ((tag === null || tag === void 0 ? void 0 : tag.summary) || current),
57
+ key: current,
58
+ });
59
+ }
60
+ current = (tag === null || tag === void 0 ? void 0 : tag.parent) !== undefined && byName.has(tag.parent) ? tag.parent : undefined;
61
+ }
62
+ path.reverse();
63
+ paths.set(name, path);
64
+ return path;
65
+ }
66
+ const kindOf = (name) => { var _a, _b; return byName.has(name) ? ((_b = (_a = byName.get(name)) === null || _a === void 0 ? void 0 : _a.kind) !== null && _b !== void 0 ? _b : 'none') : 'undeclared'; };
67
+ return (operationTags = []) => {
68
+ var _a, _b, _c;
69
+ const name = nested
70
+ ? ((_b = (_a = operationTags.find((name) => kindOf(name) === 'nav')) !== null && _a !== void 0 ? _a : operationTags.find((name) => kindOf(name) === 'none')) !== null && _b !== void 0 ? _b : operationTags.find((name) => kindOf(name) === 'undeclared'))
71
+ : operationTags[0];
72
+ if (name === undefined || (!nested && !name))
73
+ return [];
74
+ if (!nested)
75
+ return [{ name, label: (_c = getTagDisplayName(name, schema)) !== null && _c !== void 0 ? _c : name }];
76
+ return resolvePath(name);
77
+ };
78
+ }
79
+ export function createOpenApiBadgeResolver(schema) {
80
+ var _a;
81
+ if (!isOpenApi32(schema))
82
+ return () => undefined;
83
+ const badges = new Map();
84
+ for (const tag of ((_a = schema.tags) !== null && _a !== void 0 ? _a : [])) {
85
+ if (tag.kind === 'badge')
86
+ badges.set(tag.name, tag.summary || tag.name);
87
+ }
88
+ return (operationTags = []) => {
89
+ for (const name of operationTags) {
90
+ const label = badges.get(name);
91
+ if (label !== undefined)
92
+ return label;
93
+ }
94
+ return undefined;
95
+ };
96
+ }
97
+ export function findOpenApiNavGroup(nav, tagPath, findGroup) {
98
+ if (tagPath.length === 0)
99
+ return findGroup(nav);
100
+ return tagPath.reduce((pages, tag) => findGroup(pages, tag.label, tag.key), nav);
101
+ }
@@ -7,10 +7,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { getEntrypoint, validate as scalarValidate } from '@mintlify/openapi-parser';
10
+ import { getEntrypoint, normalize, validate as scalarValidate } from '@mintlify/openapi-parser';
11
11
  import { checkForExternalRefs } from '../asyncapi/checkForExternalRefs.js';
12
+ import { validateAdditionalOperations } from './additionalOperations.js';
13
+ import { validateQuerystringParameters } from './querystringParameters.js';
14
+ import { validateOpenApiTagTree } from './tagHierarchy.js';
12
15
  export const isOpenApi32Version = (version) => typeof version === 'string' && /^3\.2(\.|$)/.test(version);
13
16
  export const getEntrypointSpecification = (document) => { var _a; return Array.isArray(document) ? (_a = getEntrypoint(document)) === null || _a === void 0 ? void 0 : _a.specification : document; };
17
+ const validateOpenApi32 = (document, specification) => __awaiter(void 0, void 0, void 0, function* () {
18
+ const outcome = yield scalarValidate(document);
19
+ if (!outcome.valid)
20
+ return Object.assign(Object.assign({}, outcome), { version: '3.2' });
21
+ const structuralErrors = [
22
+ ...validateOpenApiTagTree(specification.tags).map((message) => ({ path: '/tags', message })),
23
+ ...validateAdditionalOperations(specification),
24
+ ...validateQuerystringParameters(specification),
25
+ ];
26
+ if (structuralErrors.length > 0) {
27
+ return { valid: false, version: '3.2', errors: structuralErrors };
28
+ }
29
+ return Object.assign(Object.assign({}, outcome), { version: '3.2' });
30
+ });
14
31
  export const validate = (document) => __awaiter(void 0, void 0, void 0, function* () {
15
32
  const result = yield safeValidate(document);
16
33
  if ('errorMessage' in result) {
@@ -27,7 +44,12 @@ export const safeValidate = (document) => __awaiter(void 0, void 0, void 0, func
27
44
  const errorMessage = error instanceof Error ? error.message : String(error);
28
45
  return { errors: [{ message: errorMessage }], valid: false, errorMessage };
29
46
  }
30
- const result = yield scalarValidate(document);
47
+ const normalized = normalize(document);
48
+ const specification = getEntrypointSpecification(normalized);
49
+ const openApi32Specification = specification && isOpenApi32Version(specification.openapi) ? specification : undefined;
50
+ const result = openApi32Specification
51
+ ? yield validateOpenApi32(normalized, openApi32Specification)
52
+ : yield scalarValidate(normalized);
31
53
  const { errors, schema, valid, version } = result;
32
54
  if (version === '2.0')
33
55
  return Object.assign(Object.assign({}, result), { errorMessage: 'OpenAPI versions prior to 3.0 not supported', valid: false });