@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 @@
1
+ export declare const mulberry32: (a: number) => () => number;
@@ -0,0 +1,4 @@
1
+ export const mulberry32 = (a) => () => {
2
+ let t = Math.imul((a = (a + 0x6d2b79f5) | 0) ^ (a >>> 15), 1 | a);
3
+ return ((t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t), (t ^ (t >>> 14)) >>> 0) / Math.pow(2, 32);
4
+ };
@@ -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 validateAdditionalOperations: (document: PathItemSources) => OpenApiValidateError[];
5
- export {};
@@ -1,5 +1,5 @@
1
- import { getPathItemOperations, isAdditionalHttpMethod, isFixedHttpMethod, } from '@mintlify/validation';
2
- const escapePointer = (segment) => segment.replaceAll('~', '~0').replaceAll('/', '~1');
1
+ import { getPathItemOperations, isAdditionalHttpMethod, } from '@mintlify/validation';
2
+ import { escapePointer, operationPointer, } from './pathItems.js';
3
3
  const callbackPathItemsOf = (location, pathItem) => {
4
4
  if (!pathItem || '$ref' in pathItem)
5
5
  return [];
@@ -7,14 +7,11 @@ const callbackPathItemsOf = (location, pathItem) => {
7
7
  const callbacks = operation.callbacks;
8
8
  if (!callbacks)
9
9
  return [];
10
- const operationPointer = isFixedHttpMethod(method)
11
- ? escapePointer(method)
12
- : `additionalOperations/${escapePointer(method)}`;
13
10
  return Object.entries(callbacks).flatMap(([name, callback]) => {
14
11
  if (!callback || '$ref' in callback)
15
12
  return [];
16
13
  return Object.entries(callback).flatMap(([expression, item]) => {
17
- const itemLocation = `${location}/${operationPointer}/callbacks/${escapePointer(name)}/${escapePointer(expression)}`;
14
+ const itemLocation = `${location}/${operationPointer(method)}/callbacks/${escapePointer(name)}/${escapePointer(expression)}`;
18
15
  const entry = [itemLocation, item];
19
16
  return [entry, ...callbackPathItemsOf(itemLocation, item)];
20
17
  });
@@ -0,0 +1,4 @@
1
+ import { type PathItemSources } from './pathItems.js';
2
+ import type { OpenApiValidateError } from './validate.js';
3
+ export declare const resolveDiscriminatorTargetPointer: (target: string) => string | undefined;
4
+ export declare const validateDiscriminatorDefaults: (document: PathItemSources) => OpenApiValidateError[];
@@ -0,0 +1,121 @@
1
+ import { isObject } from '../types/guards.js';
2
+ import { forEachDocumentPosition } from './documentPositions.js';
3
+ import { escapePointer } from './pathItems.js';
4
+ const unescapePointerToken = (token) => token.replace(/~1/g, '/').replace(/~0/g, '~');
5
+ export const resolveDiscriminatorTargetPointer = (target) => {
6
+ if (target.startsWith('#')) {
7
+ try {
8
+ const pointer = decodeURIComponent(target.slice(1));
9
+ return pointer.startsWith('/') ? pointer : undefined;
10
+ }
11
+ catch (_a) {
12
+ return undefined;
13
+ }
14
+ }
15
+ const name = target.startsWith('./') ? target.slice(2) : target;
16
+ return `/components/schemas/${escapePointer(name)}`;
17
+ };
18
+ const ALIAS_KEYS = new Set(['$ref', 'summary', 'description']);
19
+ const componentSchemaName = (pointer) => {
20
+ const match = /^\/components\/schemas\/([^/]+)$/.exec(pointer);
21
+ return (match === null || match === void 0 ? void 0 : match[1]) === undefined ? undefined : unescapePointerToken(match[1]);
22
+ };
23
+ export const validateDiscriminatorDefaults = (document) => {
24
+ const errors = [];
25
+ const componentSchemas = isObject(document.components)
26
+ ? document.components.schemas
27
+ : undefined;
28
+ const schemaExists = (pointer) => {
29
+ const name = pointer === undefined ? undefined : componentSchemaName(pointer);
30
+ return (name !== undefined &&
31
+ isObject(componentSchemas) &&
32
+ Object.prototype.hasOwnProperty.call(componentSchemas, name) &&
33
+ isObject(componentSchemas[name]));
34
+ };
35
+ const canonicalSchemaPointer = (pointer) => {
36
+ const seen = new Set();
37
+ let current = pointer;
38
+ while (!seen.has(current)) {
39
+ seen.add(current);
40
+ const name = componentSchemaName(current);
41
+ const schema = name === undefined || !isObject(componentSchemas) ? undefined : componentSchemas[name];
42
+ if (!isObject(schema) ||
43
+ typeof schema.$ref !== 'string' ||
44
+ !Object.keys(schema).every((key) => ALIAS_KEYS.has(key))) {
45
+ return current;
46
+ }
47
+ const next = resolveDiscriminatorTargetPointer(schema.$ref);
48
+ if (next === undefined || !schemaExists(next))
49
+ return current;
50
+ current = next;
51
+ }
52
+ return current;
53
+ };
54
+ const variantPointers = (schema) => {
55
+ const members = [
56
+ ...(Array.isArray(schema.oneOf) ? schema.oneOf : []),
57
+ ...(Array.isArray(schema.anyOf) ? schema.anyOf : []),
58
+ ];
59
+ if (members.length === 0)
60
+ return undefined;
61
+ return members.flatMap((member) => {
62
+ if (!isObject(member) || typeof member.$ref !== 'string')
63
+ return [];
64
+ const pointer = resolveDiscriminatorTargetPointer(member.$ref);
65
+ return pointer === undefined ? [] : [canonicalSchemaPointer(pointer)];
66
+ });
67
+ };
68
+ const componentSchema = (pointer) => {
69
+ const name = componentSchemaName(pointer);
70
+ const schema = name === undefined || !isObject(componentSchemas) ? undefined : componentSchemas[name];
71
+ return isObject(schema) ? schema : undefined;
72
+ };
73
+ const compositionOf = (schema, seen) => {
74
+ const own = Object.assign(Object.assign(Object.assign({}, ('oneOf' in schema ? { oneOf: schema.oneOf } : {})), ('anyOf' in schema ? { anyOf: schema.anyOf } : {})), ('allOf' in schema ? { allOf: schema.allOf } : {}));
75
+ if (typeof schema.$ref !== 'string')
76
+ return own;
77
+ const pointer = resolveDiscriminatorTargetPointer(schema.$ref);
78
+ const canonical = pointer === undefined ? undefined : canonicalSchemaPointer(pointer);
79
+ if (canonical === undefined || seen.has(canonical))
80
+ return own;
81
+ seen.add(canonical);
82
+ const target = componentSchema(canonical);
83
+ return target === undefined ? own : Object.assign(Object.assign({}, compositionOf(target, seen)), own);
84
+ };
85
+ const reachableVariantPointers = (schema, seen) => {
86
+ const composition = compositionOf(schema, seen);
87
+ const own = variantPointers(composition);
88
+ const nested = (Array.isArray(composition.allOf) ? composition.allOf : []).flatMap((member) => {
89
+ if (!isObject(member))
90
+ return [];
91
+ const inner = reachableVariantPointers(member, seen);
92
+ return inner === undefined ? [] : [inner];
93
+ });
94
+ if (own === undefined && nested.length === 0)
95
+ return undefined;
96
+ return [...(own !== null && own !== void 0 ? own : []), ...nested.flat()];
97
+ };
98
+ forEachDocumentPosition(document, {
99
+ onSchema: (path, schema) => {
100
+ const discriminator = schema.discriminator;
101
+ if (!isObject(discriminator) || typeof discriminator.defaultMapping !== 'string')
102
+ return;
103
+ const target = discriminator.defaultMapping;
104
+ const pointer = resolveDiscriminatorTargetPointer(target);
105
+ const variants = reachableVariantPointers(schema, new Set());
106
+ const exists = schemaExists(pointer);
107
+ const selectable = exists &&
108
+ (variants === undefined ||
109
+ (pointer !== undefined && variants.includes(canonicalSchemaPointer(pointer))));
110
+ if (!selectable) {
111
+ errors.push({
112
+ path: `${path}/discriminator/defaultMapping`,
113
+ message: exists
114
+ ? `defaultMapping ${target} is not one of the schema's oneOf/anyOf variants`
115
+ : `defaultMapping ${target} does not name a schema in mapping or components.schemas`,
116
+ });
117
+ }
118
+ },
119
+ });
120
+ return errors;
121
+ };
@@ -0,0 +1,10 @@
1
+ import { type PathItemSources } from './pathItems.js';
2
+ type Visitor = (path: string, value: Record<string, unknown>) => void;
3
+ export type DocumentVisitors = {
4
+ onMediaType?: Visitor;
5
+ onSchema?: Visitor;
6
+ onParameter?: Visitor;
7
+ onHeaderName?: (path: string, name: string) => void;
8
+ };
9
+ export declare const forEachDocumentPosition: (document: PathItemSources, visitors: DocumentVisitors) => void;
10
+ export {};
@@ -0,0 +1,154 @@
1
+ import { getPathItemOperations } from '@mintlify/validation';
2
+ import { isObject } from '../types/guards.js';
3
+ import { escapePointer, forEachPathItem, operationPointer, } from './pathItems.js';
4
+ const SCHEMA_KEYWORDS = [
5
+ 'additionalProperties',
6
+ 'contains',
7
+ 'contentSchema',
8
+ 'else',
9
+ 'if',
10
+ 'items',
11
+ 'not',
12
+ 'propertyNames',
13
+ 'then',
14
+ 'unevaluatedItems',
15
+ 'unevaluatedProperties',
16
+ ];
17
+ const SCHEMA_MAP_KEYWORDS = [
18
+ '$defs',
19
+ 'dependentSchemas',
20
+ 'patternProperties',
21
+ 'properties',
22
+ ];
23
+ const SCHEMA_LIST_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'];
24
+ const visitSchema = (value, path, walk) => {
25
+ var _a, _b;
26
+ if (!isObject(value) || walk.seen.has(value))
27
+ return;
28
+ walk.seen.add(value);
29
+ (_b = (_a = walk.visitors).onSchema) === null || _b === void 0 ? void 0 : _b.call(_a, path, value);
30
+ for (const keyword of SCHEMA_KEYWORDS) {
31
+ visitSchema(value[keyword], `${path}/${keyword}`, walk);
32
+ }
33
+ for (const keyword of SCHEMA_MAP_KEYWORDS) {
34
+ const entries = value[keyword];
35
+ if (!isObject(entries))
36
+ continue;
37
+ for (const [name, child] of Object.entries(entries)) {
38
+ visitSchema(child, `${path}/${keyword}/${escapePointer(name)}`, walk);
39
+ }
40
+ }
41
+ for (const keyword of SCHEMA_LIST_KEYWORDS) {
42
+ const list = value[keyword];
43
+ if (!Array.isArray(list))
44
+ continue;
45
+ list.forEach((child, index) => visitSchema(child, `${path}/${keyword}/${index}`, walk));
46
+ }
47
+ };
48
+ const visitEncoding = (value, path, walk) => {
49
+ if (!isObject(value) || walk.seen.has(value))
50
+ return;
51
+ walk.seen.add(value);
52
+ visitHeaderMap(value.headers, `${path}/headers`, walk);
53
+ visitEncodings(value, path, walk);
54
+ };
55
+ const visitEncodings = (value, path, walk) => {
56
+ if (isObject(value.encoding)) {
57
+ for (const [name, encoding] of Object.entries(value.encoding)) {
58
+ visitEncoding(encoding, `${path}/encoding/${escapePointer(name)}`, walk);
59
+ }
60
+ }
61
+ if (Array.isArray(value.prefixEncoding)) {
62
+ value.prefixEncoding.forEach((encoding, index) => visitEncoding(encoding, `${path}/prefixEncoding/${index}`, walk));
63
+ }
64
+ visitEncoding(value.itemEncoding, `${path}/itemEncoding`, walk);
65
+ };
66
+ const visitMedia = (value, path, walk) => {
67
+ var _a, _b;
68
+ if (!isObject(value))
69
+ return;
70
+ if (!('$ref' in value))
71
+ (_b = (_a = walk.visitors).onMediaType) === null || _b === void 0 ? void 0 : _b.call(_a, path, value);
72
+ visitSchema(value.schema, `${path}/schema`, walk);
73
+ visitSchema(value.itemSchema, `${path}/itemSchema`, walk);
74
+ visitEncodings(value, path, walk);
75
+ };
76
+ const visitContent = (value, path, walk) => {
77
+ if (!isObject(value))
78
+ return;
79
+ for (const [mediaType, media] of Object.entries(value)) {
80
+ visitMedia(media, `${path}/${escapePointer(mediaType)}`, walk);
81
+ }
82
+ };
83
+ const visitParameterOrHeader = (value, path, walk) => {
84
+ if (!isObject(value) || '$ref' in value)
85
+ return;
86
+ visitSchema(value.schema, `${path}/schema`, walk);
87
+ visitContent(value.content, `${path}/content`, walk);
88
+ };
89
+ const visitParameter = (value, path, walk) => {
90
+ var _a, _b;
91
+ if (!isObject(value) || '$ref' in value)
92
+ return;
93
+ (_b = (_a = walk.visitors).onParameter) === null || _b === void 0 ? void 0 : _b.call(_a, path, value);
94
+ visitParameterOrHeader(value, path, walk);
95
+ };
96
+ const visitComponentMap = (value, path, walk, visit) => {
97
+ if (!isObject(value))
98
+ return;
99
+ for (const [name, entry] of Object.entries(value)) {
100
+ visit(entry, `${path}/${escapePointer(name)}`, walk);
101
+ }
102
+ };
103
+ const visitHeaderMap = (value, path, walk) => {
104
+ var _a, _b;
105
+ if (!isObject(value))
106
+ return;
107
+ for (const [name, header] of Object.entries(value)) {
108
+ const entryPath = `${path}/${escapePointer(name)}`;
109
+ (_b = (_a = walk.visitors).onHeaderName) === null || _b === void 0 ? void 0 : _b.call(_a, entryPath, name);
110
+ visitParameterOrHeader(header, entryPath, walk);
111
+ }
112
+ };
113
+ const visitRequestBody = (value, path, walk) => {
114
+ if (!isObject(value) || '$ref' in value)
115
+ return;
116
+ visitContent(value.content, `${path}/content`, walk);
117
+ };
118
+ const visitResponse = (value, path, walk) => {
119
+ if (!isObject(value) || '$ref' in value)
120
+ return;
121
+ visitHeaderMap(value.headers, `${path}/headers`, walk);
122
+ visitContent(value.content, `${path}/content`, walk);
123
+ };
124
+ export const forEachDocumentPosition = (document, visitors) => {
125
+ var _a, _b, _c, _d, _e;
126
+ const walk = { visitors, seen: new Set() };
127
+ const components = (_a = document.components) !== null && _a !== void 0 ? _a : {};
128
+ for (const [name, schema] of Object.entries((_b = components.schemas) !== null && _b !== void 0 ? _b : {})) {
129
+ visitSchema(schema, `/components/schemas/${escapePointer(name)}`, walk);
130
+ }
131
+ visitComponentMap(components.parameters, '/components/parameters', walk, visitParameter);
132
+ visitComponentMap(components.headers, '/components/headers', walk, visitParameterOrHeader);
133
+ for (const [name, body] of Object.entries((_c = components.requestBodies) !== null && _c !== void 0 ? _c : {})) {
134
+ visitRequestBody(body, `/components/requestBodies/${escapePointer(name)}`, walk);
135
+ }
136
+ for (const [name, response] of Object.entries((_d = components.responses) !== null && _d !== void 0 ? _d : {})) {
137
+ visitResponse(response, `/components/responses/${escapePointer(name)}`, walk);
138
+ }
139
+ for (const [name, media] of Object.entries((_e = components.mediaTypes) !== null && _e !== void 0 ? _e : {})) {
140
+ visitMedia(media, `/components/mediaTypes/${escapePointer(name)}`, walk);
141
+ }
142
+ forEachPathItem(document, (location, pathItem) => {
143
+ var _a, _b, _c;
144
+ ((_a = pathItem.parameters) !== null && _a !== void 0 ? _a : []).forEach((parameter, index) => visitParameter(parameter, `${location}/parameters/${index}`, walk));
145
+ for (const [method, operation] of getPathItemOperations(pathItem)) {
146
+ const operationPath = `${location}/${operationPointer(method)}`;
147
+ ((_b = operation.parameters) !== null && _b !== void 0 ? _b : []).forEach((parameter, index) => visitParameter(parameter, `${operationPath}/parameters/${index}`, walk));
148
+ visitRequestBody(operation.requestBody, `${operationPath}/requestBody`, walk);
149
+ for (const [code, response] of Object.entries((_c = operation.responses) !== null && _c !== void 0 ? _c : {})) {
150
+ visitResponse(response, `${operationPath}/responses/${escapePointer(code)}`, walk);
151
+ }
152
+ }
153
+ });
154
+ };
@@ -0,0 +1,3 @@
1
+ import type { PathItemSources } from './pathItems.js';
2
+ import type { OpenApiValidateError } from './validate.js';
3
+ export declare const validatePositionalEncodings: (document: PathItemSources) => OpenApiValidateError[];
@@ -0,0 +1,59 @@
1
+ import { getComponentNameFromRef } from '@mintlify/validation';
2
+ import { isObject } from '../types/guards.js';
3
+ import { forEachDocumentPosition } from './documentPositions.js';
4
+ const resolveLocalSchema = (schema, componentSchemas, seen = new Set()) => {
5
+ if (!isObject(schema) || typeof schema.$ref !== 'string')
6
+ return schema;
7
+ const name = getComponentNameFromRef(schema.$ref, 'schemas');
8
+ if (name === undefined || seen.has(name))
9
+ return undefined;
10
+ return resolveLocalSchema(componentSchemas[name], componentSchemas, seen.add(name));
11
+ };
12
+ const isArraySchema = (schema, componentSchemas, seen = new Set()) => {
13
+ if (!isObject(schema) || seen.has(schema))
14
+ return false;
15
+ seen.add(schema);
16
+ if (schema.type !== undefined) {
17
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type];
18
+ return types.includes('array') && types.every((type) => type === 'array' || type === 'null');
19
+ }
20
+ if ('items' in schema || 'prefixItems' in schema) {
21
+ return true;
22
+ }
23
+ if (typeof schema.$ref === 'string' &&
24
+ isArraySchema(resolveLocalSchema(schema, componentSchemas), componentSchemas, seen)) {
25
+ return true;
26
+ }
27
+ if (Array.isArray(schema.allOf) &&
28
+ schema.allOf.some((member) => isArraySchema(member, componentSchemas, seen))) {
29
+ return true;
30
+ }
31
+ const alternatives = [
32
+ ...(Array.isArray(schema.oneOf) ? schema.oneOf : []),
33
+ ...(Array.isArray(schema.anyOf) ? schema.anyOf : []),
34
+ ];
35
+ return (alternatives.some((member) => !isNullSchema(resolveLocalSchema(member, componentSchemas))) &&
36
+ alternatives.every((member) => isNullSchema(resolveLocalSchema(member, componentSchemas)) ||
37
+ isArraySchema(member, componentSchemas, new Set(seen))));
38
+ };
39
+ const isNullSchema = (schema) => isObject(schema) &&
40
+ (schema.type === 'null' ||
41
+ (Array.isArray(schema.type) && schema.type.every((type) => type === 'null')));
42
+ export const validatePositionalEncodings = (document) => {
43
+ var _a, _b;
44
+ const errors = [];
45
+ const componentSchemas = (_b = (_a = document.components) === null || _a === void 0 ? void 0 : _a.schemas) !== null && _b !== void 0 ? _b : {};
46
+ forEachDocumentPosition(document, {
47
+ onMediaType: (path, media) => {
48
+ if (('prefixEncoding' in media || 'itemEncoding' in media) &&
49
+ !('itemSchema' in media) &&
50
+ !isArraySchema(media.schema, componentSchemas)) {
51
+ errors.push({
52
+ path,
53
+ message: 'prefixEncoding and itemEncoding require itemSchema or an array schema',
54
+ });
55
+ }
56
+ },
57
+ });
58
+ return errors;
59
+ };
@@ -1,4 +1,4 @@
1
- import { getPathItemOperations } from '@mintlify/validation';
1
+ import { getPathItemOperations, resolvePathItemReference, } from '@mintlify/validation';
2
2
  import jsYaml from 'js-yaml';
3
3
  import { optionallyAddLeadingSlash } from '../fs/optionallySlash.js';
4
4
  import { mergePageGroups } from '../navigation/groupAccess.js';
@@ -73,7 +73,7 @@ function getXMintGroups(pathObject, operationObject) {
73
73
  return groups;
74
74
  }
75
75
  export function generateOpenApiPages(opts) {
76
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
76
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
77
77
  const { spec, specFilePath, outputDirectory } = opts;
78
78
  const outDir = outputDirectory !== null && outputDirectory !== void 0 ? outputDirectory : DEFAULT_OUTPUT_DIR;
79
79
  const openApiFilePathFromRoot = optionallyAddLeadingSlash(specFilePath);
@@ -88,15 +88,15 @@ export function generateOpenApiPages(opts) {
88
88
  {
89
89
  filename: (_a = specFilePath.split('/').pop()) !== null && _a !== void 0 ? _a : 'spec',
90
90
  spec: spec,
91
- originalFileLocation: specFilePath,
91
+ originalFileLocation: openApiFilePathFromRoot,
92
92
  },
93
93
  ];
94
94
  // Process paths
95
- for (const [apiPath, pathItemObject] of Object.entries((_b = spec.paths) !== null && _b !== void 0 ? _b : {})) {
96
- if (!pathItemObject || typeof pathItemObject !== 'object')
95
+ for (const [apiPath, rawPathItem] of Object.entries((_b = spec.paths) !== null && _b !== void 0 ? _b : {})) {
96
+ if (!rawPathItem || typeof rawPathItem !== 'object')
97
97
  continue;
98
98
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
99
- const pathItem = pathItemObject;
99
+ const pathItem = ((_c = resolvePathItemReference(rawPathItem, spec.components)) !== null && _c !== void 0 ? _c : rawPathItem);
100
100
  for (const [method, pathOperation] of getPathItemOperations(pathItem)) {
101
101
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
102
102
  const operation = pathOperation;
@@ -105,10 +105,10 @@ export function generateOpenApiPages(opts) {
105
105
  const xMint = operation['x-mint'];
106
106
  const xMintGroups = getXMintGroups(pathItem, operation);
107
107
  const tagPath = resolveTags(operation.tags);
108
- const tagName = (_c = tagPath.at(-1)) === null || _c === void 0 ? void 0 : _c.name;
109
- const groupName = (_d = tagPath.at(-1)) === null || _d === void 0 ? void 0 : _d.label;
110
- let title = (_e = prepareStringToBeValidFilename(operation.summary)) !== null && _e !== void 0 ? _e : `${method.toLowerCase()}-${prepareStringToBeValidFilename(apiPath)}`;
111
- let folder = (_f = prepareStringToBeValidFilename(tagName)) !== null && _f !== void 0 ? _f : '';
108
+ const tagName = (_d = tagPath.at(-1)) === null || _d === void 0 ? void 0 : _d.name;
109
+ const groupName = (_e = tagPath.at(-1)) === null || _e === void 0 ? void 0 : _e.label;
110
+ let title = (_f = prepareStringToBeValidFilename(operation.summary)) !== null && _f !== void 0 ? _f : `${method.toLowerCase()}-${prepareStringToBeValidFilename(apiPath)}`;
111
+ let folder = (_g = prepareStringToBeValidFilename(tagName)) !== null && _g !== void 0 ? _g : '';
112
112
  let base = posixJoin(outDir, folder, title);
113
113
  if (xMint === null || xMint === void 0 ? void 0 : xMint.href) {
114
114
  const href = xMint.href.startsWith('/') ? xMint.href.slice(1) : xMint.href;
@@ -133,7 +133,7 @@ export function generateOpenApiPages(opts) {
133
133
  if (badge !== undefined && (xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.tag) === undefined) {
134
134
  xMintMetadata = Object.assign(Object.assign({}, xMintMetadata), { tag: badge });
135
135
  }
136
- const page = Object.assign(Object.assign({ title: (_h = (_g = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.title) !== null && _g !== void 0 ? _g : titleTag) !== null && _h !== void 0 ? _h : slugToTitle(filenameWithoutExtension), description: (_j = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.description) !== null && _j !== void 0 ? _j : description, deprecated: (_k = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.deprecated) !== null && _k !== void 0 ? _k : operation.deprecated, openapi: openapiMetaTag, href: posixResolve('/', filenameWithoutExtension), method, path: apiPath, tag: groupName }, (nestedTags ? { tagPath } : {})), { hidden: operation['x-hidden'] === true, xMintMetadata, xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content, version: opts.version });
136
+ const page = Object.assign(Object.assign({ title: (_j = (_h = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.title) !== null && _h !== void 0 ? _h : titleTag) !== null && _j !== void 0 ? _j : slugToTitle(filenameWithoutExtension), description: (_k = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.description) !== null && _k !== void 0 ? _k : description, deprecated: (_l = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.deprecated) !== null && _l !== void 0 ? _l : operation.deprecated, openapi: openapiMetaTag, href: posixResolve('/', filenameWithoutExtension), method, path: apiPath, tag: groupName }, (nestedTags ? { tagPath } : {})), { hidden: operation['x-hidden'] === true, xMintMetadata, xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content, version: opts.version });
137
137
  pages.push(page);
138
138
  }
139
139
  }
@@ -147,7 +147,7 @@ export function generateOpenApiPages(opts) {
147
147
  if (!webhookObject || typeof webhookObject !== 'object')
148
148
  continue;
149
149
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
150
- const pathItem = webhookObject;
150
+ const pathItem = ((_m = resolvePathItemReference(webhookObject, spec.components)) !== null && _m !== void 0 ? _m : webhookObject);
151
151
  for (const [, pathOperation] of getPathItemOperations(pathItem)) {
152
152
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
153
153
  const operation = pathOperation;
@@ -155,10 +155,10 @@ export function generateOpenApiPages(opts) {
155
155
  continue;
156
156
  const xMint = operation['x-mint'];
157
157
  const tagPath = resolveTags(operation.tags);
158
- const tagName = (_l = tagPath.at(-1)) === null || _l === void 0 ? void 0 : _l.name;
159
- const groupName = (_m = tagPath.at(-1)) === null || _m === void 0 ? void 0 : _m.label;
160
- let title = (_o = prepareStringToBeValidFilename(operation.summary)) !== null && _o !== void 0 ? _o : `${prepareStringToBeValidFilename(webhook)}`;
161
- let folder = (_p = prepareStringToBeValidFilename(tagName)) !== null && _p !== void 0 ? _p : '';
158
+ const tagName = (_o = tagPath.at(-1)) === null || _o === void 0 ? void 0 : _o.name;
159
+ const groupName = (_p = tagPath.at(-1)) === null || _p === void 0 ? void 0 : _p.label;
160
+ let title = (_q = prepareStringToBeValidFilename(operation.summary)) !== null && _q !== void 0 ? _q : `${prepareStringToBeValidFilename(webhook)}`;
161
+ let folder = (_r = prepareStringToBeValidFilename(tagName)) !== null && _r !== void 0 ? _r : '';
162
162
  let base = posixJoin(outDir, folder, title);
163
163
  if (xMint === null || xMint === void 0 ? void 0 : xMint.href) {
164
164
  const href = xMint.href.startsWith('/') ? xMint.href.slice(1) : xMint.href;
@@ -175,9 +175,9 @@ export function generateOpenApiPages(opts) {
175
175
  path: webhook,
176
176
  });
177
177
  const badge = resolveBadge(operation.tags);
178
- const xMintMetadata = badge !== undefined && ((_q = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _q === void 0 ? void 0 : _q.tag) === undefined
178
+ const xMintMetadata = badge !== undefined && ((_s = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _s === void 0 ? void 0 : _s.tag) === undefined
179
179
  ? Object.assign(Object.assign({}, xMint === null || xMint === void 0 ? void 0 : xMint.metadata), { tag: badge }) : xMint === null || xMint === void 0 ? void 0 : xMint.metadata;
180
- const page = Object.assign(Object.assign({ title: (_s = (_r = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _r === void 0 ? void 0 : _r.title) !== null && _s !== void 0 ? _s : slugToTitle(filenameWithoutExtension), description: (_u = (_t = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _t === void 0 ? void 0 : _t.description) !== null && _u !== void 0 ? _u : operation.description, deprecated: (_w = (_v = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _v === void 0 ? void 0 : _v.deprecated) !== null && _w !== void 0 ? _w : operation.deprecated, openapi: openapiMetaTag, href: posixResolve('/', filenameWithoutExtension), method: 'webhook', path: webhook, tag: groupName }, (nestedTags ? { tagPath } : {})), { hidden: operation['x-hidden'] === true, isWebhook: true, xMintMetadata, xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content, version: opts.version });
180
+ const page = Object.assign(Object.assign({ title: (_u = (_t = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _t === void 0 ? void 0 : _t.title) !== null && _u !== void 0 ? _u : slugToTitle(filenameWithoutExtension), description: (_w = (_v = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _v === void 0 ? void 0 : _v.description) !== null && _w !== void 0 ? _w : operation.description, deprecated: (_y = (_x = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _x === void 0 ? void 0 : _x.deprecated) !== null && _y !== void 0 ? _y : operation.deprecated, openapi: openapiMetaTag, href: posixResolve('/', filenameWithoutExtension), method: 'webhook', path: webhook, tag: groupName }, (nestedTags ? { tagPath } : {})), { hidden: operation['x-hidden'] === true, isWebhook: true, xMintMetadata, xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content, version: opts.version });
181
181
  pages.push(page);
182
182
  }
183
183
  }
@@ -1,7 +1,8 @@
1
- import { httpMethods, isFixedHttpMethod, parseHttpMethod } from '@mintlify/validation';
1
+ import { httpMethods, isFixedHttpMethod, parseHttpMethod, resolvePathItemReference, } from '@mintlify/validation';
2
2
  import { findOpenApiPath } from './findOpenApiPath.js';
3
3
  import { potentiallyParseOpenApiString } from './parseOpenApiString.js';
4
4
  export const getOpenApiOperationMethodAndEndpoint = (endpointStr, openApiFiles) => {
5
+ var _a;
5
6
  const potentiallyParsedOpenApiString = potentiallyParseOpenApiString(endpointStr);
6
7
  if (potentiallyParsedOpenApiString == undefined) {
7
8
  return undefined;
@@ -15,7 +16,8 @@ export const getOpenApiOperationMethodAndEndpoint = (endpointStr, openApiFiles)
15
16
  const match = findOpenApiPath(openApiFile.paths, endpoint);
16
17
  const filenameMatches = !filename || filename === file.filename || filename === file.originalFileLocation;
17
18
  if (match && filenameMatches) {
18
- path = match.pathItem;
19
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- resolved items keep the PathItemObject shape
20
+ path = ((_a = resolvePathItemReference(match.pathItem, 'components' in openApiFile ? openApiFile.components : undefined)) !== null && _a !== void 0 ? _a : match.pathItem);
19
21
  apiFile = openApiFile;
20
22
  matchedEndpoint = match.pathKey;
21
23
  }
@@ -0,0 +1,3 @@
1
+ import type { PathItemSources } from './pathItems.js';
2
+ import type { OpenApiValidateError } from './validate.js';
3
+ export declare const validateHeaderNames: (document: PathItemSources) => OpenApiValidateError[];
@@ -0,0 +1,25 @@
1
+ import { forEachDocumentPosition } from './documentPositions.js';
2
+ // RFC 9110 field names are tokens: letters, digits and these symbols, nothing else
3
+ const TOKEN_SYMBOLS = new Set("!#$%&'*+-.^_`|~");
4
+ const isTokenChar = (char) => (char >= 'a' && char <= 'z') ||
5
+ (char >= 'A' && char <= 'Z') ||
6
+ (char >= '0' && char <= '9') ||
7
+ TOKEN_SYMBOLS.has(char);
8
+ const isValidHeaderName = (name) => typeof name === 'string' && name.length > 0 && [...name].every(isTokenChar);
9
+ export const validateHeaderNames = (document) => {
10
+ const errors = [];
11
+ const report = (path, name) => errors.push({ path, message: `Header name ${name} is not a valid HTTP field name` });
12
+ forEachDocumentPosition(document, {
13
+ onParameter: (path, parameter) => {
14
+ if (parameter.in === 'header' && typeof parameter.name === 'string') {
15
+ if (!isValidHeaderName(parameter.name))
16
+ report(`${path}/name`, parameter.name);
17
+ }
18
+ },
19
+ onHeaderName: (path, name) => {
20
+ if (!isValidHeaderName(name))
21
+ report(path, name);
22
+ },
23
+ });
24
+ return errors;
25
+ };
@@ -0,0 +1,7 @@
1
+ import { type HttpMethod, type OpenAPIV3_2 } from '@mintlify/validation';
2
+ export type PathItemSources = Partial<Pick<OpenAPIV3_2.Document, 'paths' | 'webhooks' | 'components'>>;
3
+ export type PathItemLike = OpenAPIV3_2.PathItemObject | OpenAPIV3_2.ReferenceObject;
4
+ export declare const escapePointer: (segment: string) => string;
5
+ export declare const operationPointer: (method: HttpMethod) => string;
6
+ export declare const resolvePathItem: (pathItem: PathItemLike, components: OpenAPIV3_2.ComponentsObject | undefined, seen?: Set<string>) => OpenAPIV3_2.PathItemObject;
7
+ export declare const forEachPathItem: (document: PathItemSources, visit: (location: string, pathItem: OpenAPIV3_2.PathItemObject) => void) => void;