@mintlify/validation 0.1.889 → 0.1.891
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 +2 -0
- package/dist/index.js +2 -0
- package/dist/openapi/componentRefs.d.ts +2 -0
- package/dist/openapi/componentRefs.js +19 -0
- package/dist/openapi/pathItemReferences.d.ts +6 -0
- package/dist/openapi/pathItemReferences.js +58 -0
- package/dist/openapi/utils.d.ts +1 -0
- package/dist/openapi/utils.js +1 -0
- package/dist/openapi/v2/buildRefUuidMap.js +2 -1
- package/dist/openapi/v2/contextualHash.d.ts +1 -0
- package/dist/openapi/v2/contextualHash.js +5 -0
- package/dist/openapi/v2/mapCallback.d.ts +4 -2
- package/dist/openapi/v2/mapCallback.js +44 -14
- package/dist/openapi/v2/mapCallbackComponents.js +2 -1
- package/dist/openapi/v2/mapExample.js +3 -8
- package/dist/openapi/v2/mapHeader.d.ts +1 -1
- package/dist/openapi/v2/mapHeader.js +4 -2
- package/dist/openapi/v2/mapMedia.js +32 -10
- package/dist/openapi/v2/mapMediaTypeComponents.d.ts +8 -0
- package/dist/openapi/v2/mapMediaTypeComponents.js +22 -0
- package/dist/openapi/v2/mapOperation.d.ts +4 -2
- package/dist/openapi/v2/mapOperation.js +20 -4
- package/dist/openapi/v2/mapParameter.d.ts +1 -1
- package/dist/openapi/v2/mapParameter.js +4 -4
- package/dist/openapi/v2/mapPath.d.ts +4 -2
- package/dist/openapi/v2/mapPath.js +22 -8
- package/dist/openapi/v2/mapPathComponents.js +10 -1
- package/dist/openapi/v2/mapPaths.js +16 -3
- package/dist/openapi/v2/mapRequestBody.d.ts +1 -1
- package/dist/openapi/v2/mapRequestBody.js +4 -4
- package/dist/openapi/v2/mapResponse.d.ts +1 -1
- package/dist/openapi/v2/mapResponse.js +4 -2
- package/dist/openapi/v2/mapSchemaComponents.js +4 -1
- package/dist/openapi/v2/mapSecurityRequirement.d.ts +1 -0
- package/dist/openapi/v2/mapSecurityRequirement.js +15 -6
- package/dist/openapi/v2/mapWebhooks.js +8 -2
- package/dist/openapi/v2/openApiToSchemaGraph.js +2 -0
- package/dist/openapi/v2/ownCopy.d.ts +1 -0
- package/dist/openapi/v2/ownCopy.js +11 -0
- package/dist/openapi/v2/replaceSchemaRefs.d.ts +7 -1
- package/dist/openapi/v2/replaceSchemaRefs.js +118 -12
- package/dist/openapi/v2/schemaGraphToOpenApi.js +51 -5
- package/dist/openapi/v2/types/index.d.ts +26 -8
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { DocsConfig, docsConfigSchema } from './mint-config/schemas/v2/index.js'
|
|
|
2
2
|
export * from './openapi/types/endpoint.js';
|
|
3
3
|
export * as OpenAPIV3_2 from './openapi/types/openapi-v3_2.js';
|
|
4
4
|
export * from './openapi/OpenApiToEndpointConverter.js';
|
|
5
|
+
export { getComponentNameFromRef, getSecuritySchemeNameFromFragment, } from './openapi/componentRefs.js';
|
|
6
|
+
export { isComponentPathItemReference, resolvePathItemReference, } from './openapi/pathItemReferences.js';
|
|
5
7
|
export { stripComponents } from './openapi/stripComponents.js';
|
|
6
8
|
export { SchemaConverter } from './openapi/SchemaConverter.js';
|
|
7
9
|
export { getFileLikeStringEncoding, getSchemaContentEncoding, getSchemaContentMediaType, } from './openapi/utils.js';
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,8 @@ import { searchableSchema } from './mint-config/schemas/v2/properties/reusable/s
|
|
|
22
22
|
export * from './openapi/types/endpoint.js';
|
|
23
23
|
export * as OpenAPIV3_2 from './openapi/types/openapi-v3_2.js';
|
|
24
24
|
export * from './openapi/OpenApiToEndpointConverter.js';
|
|
25
|
+
export { getComponentNameFromRef, getSecuritySchemeNameFromFragment, } from './openapi/componentRefs.js';
|
|
26
|
+
export { isComponentPathItemReference, resolvePathItemReference, } from './openapi/pathItemReferences.js';
|
|
25
27
|
export { stripComponents } from './openapi/stripComponents.js';
|
|
26
28
|
export { SchemaConverter } from './openapi/SchemaConverter.js';
|
|
27
29
|
export { getFileLikeStringEncoding, getSchemaContentEncoding, getSchemaContentMediaType, } from './openapi/utils.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const getComponentNameFromRef = (ref, section) => {
|
|
2
|
+
if (!ref.startsWith('#'))
|
|
3
|
+
return undefined;
|
|
4
|
+
let pointer;
|
|
5
|
+
try {
|
|
6
|
+
pointer = decodeURIComponent(ref.slice(1));
|
|
7
|
+
}
|
|
8
|
+
catch (_a) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const prefix = `/components/${section}/`;
|
|
12
|
+
if (!pointer.startsWith(prefix))
|
|
13
|
+
return undefined;
|
|
14
|
+
const token = pointer.slice(prefix.length);
|
|
15
|
+
if (token.length === 0 || token.includes('/'))
|
|
16
|
+
return undefined;
|
|
17
|
+
return token.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
18
|
+
};
|
|
19
|
+
export const getSecuritySchemeNameFromFragment = (key) => getComponentNameFromRef(key, 'securitySchemes');
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type PathItemRecord = Record<string, unknown>;
|
|
2
|
+
export declare const resolvePathItemReference: (pathItem: object, components: unknown, seen?: Set<string>) => PathItemRecord | undefined;
|
|
3
|
+
export declare const getComponentPathItemName: (pathItem: unknown) => string | undefined;
|
|
4
|
+
export declare const isComponentPathItemReference: (pathItem: unknown) => boolean;
|
|
5
|
+
export declare const activePathItemsOf: (pathItem: unknown) => ReadonlySet<string>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
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 } from './componentRefs.js';
|
|
13
|
+
import { isObject } from './utils.js';
|
|
14
|
+
const getComponentPathItem = (components, name) => {
|
|
15
|
+
if (!isObject(components))
|
|
16
|
+
return undefined;
|
|
17
|
+
const section = components.pathItems;
|
|
18
|
+
if (!isObject(section))
|
|
19
|
+
return undefined;
|
|
20
|
+
const target = section[name];
|
|
21
|
+
return isObject(target) ? target : undefined;
|
|
22
|
+
};
|
|
23
|
+
export const resolvePathItemReference = (pathItem, components, seen = new Set()) => {
|
|
24
|
+
var _a;
|
|
25
|
+
if (!isObject(pathItem))
|
|
26
|
+
return undefined;
|
|
27
|
+
const ref = pathItem.$ref;
|
|
28
|
+
if (typeof ref !== 'string')
|
|
29
|
+
return pathItem;
|
|
30
|
+
const name = getComponentNameFromRef(ref, 'pathItems');
|
|
31
|
+
if (name === undefined || seen.has(name))
|
|
32
|
+
return undefined;
|
|
33
|
+
const target = getComponentPathItem(components, name);
|
|
34
|
+
if (target === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
seen.add(name);
|
|
37
|
+
const { $ref: _unresolved } = target, targetFields = __rest(target, ["$ref"]);
|
|
38
|
+
const resolvedTarget = (_a = resolvePathItemReference(target, components, seen)) !== null && _a !== void 0 ? _a : targetFields;
|
|
39
|
+
const merged = structuredClone(resolvedTarget);
|
|
40
|
+
for (const [key, value] of Object.entries(pathItem)) {
|
|
41
|
+
if (key === '$ref' || value === undefined)
|
|
42
|
+
continue;
|
|
43
|
+
if (key === 'additionalOperations' && isObject(value) && isObject(merged[key])) {
|
|
44
|
+
merged[key] = Object.assign(Object.assign({}, merged[key]), value);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
merged[key] = value;
|
|
48
|
+
}
|
|
49
|
+
return merged;
|
|
50
|
+
};
|
|
51
|
+
export const getComponentPathItemName = (pathItem) => isObject(pathItem) && typeof pathItem.$ref === 'string'
|
|
52
|
+
? getComponentNameFromRef(pathItem.$ref, 'pathItems')
|
|
53
|
+
: undefined;
|
|
54
|
+
export const isComponentPathItemReference = (pathItem) => getComponentPathItemName(pathItem) !== undefined;
|
|
55
|
+
export const activePathItemsOf = (pathItem) => {
|
|
56
|
+
const name = getComponentPathItemName(pathItem);
|
|
57
|
+
return name === undefined ? new Set() : new Set([name]);
|
|
58
|
+
};
|
package/dist/openapi/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
2
|
import { DataSchema } from './types/endpoint.js';
|
|
3
3
|
import { ComponentsSection, Schema3_1, SimpleSchema, SimpleSchemaWithSubschemas } from './types/schema.js';
|
|
4
|
+
export declare const isObject: (value: unknown) => value is Record<string, unknown>;
|
|
4
5
|
export declare const structuredDataContentTypes: string[];
|
|
5
6
|
/**
|
|
6
7
|
* Returns the FileSchema contentEncoding when a string schema represents a file upload.
|
package/dist/openapi/utils.js
CHANGED
|
@@ -12,9 +12,10 @@ export const buildRefUuidMap = (spec) => {
|
|
|
12
12
|
'requestBodies',
|
|
13
13
|
'headers',
|
|
14
14
|
'securitySchemes',
|
|
15
|
+
'mediaTypes',
|
|
15
16
|
'links', // TODO: add support for links
|
|
16
17
|
'callbacks', // TODO: add support for callbacks
|
|
17
|
-
'pathItems',
|
|
18
|
+
'pathItems',
|
|
18
19
|
];
|
|
19
20
|
const components = spec.components;
|
|
20
21
|
componentsObjectKeys.forEach((key) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const contextualHash: (structuralHash: string, suppressedPathItems: ReadonlySet<string>, activePathItems: ReadonlySet<string>) => string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import hash from 'object-hash';
|
|
2
|
+
export const contextualHash = (structuralHash, suppressedPathItems, activePathItems) => {
|
|
3
|
+
const inherited = [...suppressedPathItems].filter((name) => activePathItems.has(name)).sort();
|
|
4
|
+
return inherited.length === 0 ? structuralHash : hash({ structuralHash, inherited });
|
|
5
|
+
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { RefUuidMap, UUIDObjectHashMap, HashedNodeMap, UUID, CallbackOrRef } from './types/index.js';
|
|
2
|
-
export declare const mapCallback: ({ callback, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }: {
|
|
2
|
+
export declare const mapCallback: ({ callback: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, components, activePathItems, }: {
|
|
3
3
|
callback: CallbackOrRef;
|
|
4
4
|
refUuidMap: RefUuidMap;
|
|
5
5
|
uuidObjectHashMap: UUIDObjectHashMap;
|
|
6
6
|
hashedNodeMap: HashedNodeMap;
|
|
7
7
|
uuid: UUID;
|
|
8
|
-
|
|
8
|
+
components?: unknown;
|
|
9
|
+
activePathItems?: ReadonlySet<string>;
|
|
10
|
+
}) => ReadonlySet<string>;
|
|
@@ -1,44 +1,74 @@
|
|
|
1
1
|
import hash from 'object-hash';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { getComponentNameFromRef } from '../componentRefs.js';
|
|
4
|
+
import { getComponentPathItemName, resolvePathItemReference } from '../pathItemReferences.js';
|
|
5
|
+
import { contextualHash } from './contextualHash.js';
|
|
3
6
|
import { mapPath } from './mapPath.js';
|
|
4
|
-
|
|
7
|
+
import { ownCopy } from './ownCopy.js';
|
|
8
|
+
const referencesComponentPathItems = (value, seen = new WeakSet()) => {
|
|
9
|
+
if (typeof value !== 'object' || value === null || seen.has(value))
|
|
10
|
+
return false;
|
|
11
|
+
seen.add(value);
|
|
12
|
+
if (Array.isArray(value))
|
|
13
|
+
return value.some((item) => referencesComponentPathItems(item, seen));
|
|
14
|
+
return Object.entries(value).some(([key, child]) => (key === '$ref' &&
|
|
15
|
+
typeof child === 'string' &&
|
|
16
|
+
getComponentNameFromRef(child, 'pathItems') !== undefined) ||
|
|
17
|
+
referencesComponentPathItems(child, seen));
|
|
18
|
+
};
|
|
19
|
+
export const mapCallback = ({ callback: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, components, activePathItems = new Set(), }) => {
|
|
5
20
|
// hash the raw object
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
uuidObjectHashMap[uuid] = objectHash;
|
|
21
|
+
const structuralHash = hash(input);
|
|
22
|
+
const suppressedPathItems = new Set();
|
|
9
23
|
// if we've seen this exact object before, skip processing
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return;
|
|
24
|
+
if (!referencesComponentPathItems(input) && structuralHash in hashedNodeMap) {
|
|
25
|
+
uuidObjectHashMap[uuid] = structuralHash;
|
|
26
|
+
return suppressedPathItems;
|
|
14
27
|
}
|
|
28
|
+
const callback = ownCopy(input, []);
|
|
15
29
|
// if ref, replace with uuid
|
|
16
30
|
if ('$ref' in callback && callback.$ref) {
|
|
31
|
+
uuidObjectHashMap[uuid] = structuralHash;
|
|
17
32
|
const refId = callback.$ref;
|
|
18
33
|
const refUuid = refUuidMap[refId];
|
|
19
34
|
if (refUuid && uuidObjectHashMap[refUuid]) {
|
|
20
35
|
uuidObjectHashMap[uuid] = uuidObjectHashMap[refUuid];
|
|
21
|
-
return;
|
|
36
|
+
return suppressedPathItems;
|
|
22
37
|
}
|
|
23
38
|
const resolvedRefUuid = refUuid || uuidv4();
|
|
24
39
|
callback.$ref = resolvedRefUuid;
|
|
25
|
-
hashedNodeMap[
|
|
26
|
-
return;
|
|
40
|
+
hashedNodeMap[structuralHash] = callback;
|
|
41
|
+
return suppressedPathItems;
|
|
27
42
|
}
|
|
28
43
|
// for path item in callback, create Path node
|
|
29
|
-
Object.entries(callback).forEach(([expression,
|
|
44
|
+
Object.entries(callback).forEach(([expression, rawPathItem]) => {
|
|
45
|
+
var _a;
|
|
30
46
|
const pathUuid = uuidv4();
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
const componentName = getComponentPathItemName(rawPathItem);
|
|
48
|
+
const isCyclic = componentName !== undefined && activePathItems.has(componentName);
|
|
49
|
+
if (isCyclic)
|
|
50
|
+
suppressedPathItems.add(componentName);
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- resolved items keep the PathObjectOrRef shape
|
|
52
|
+
const pathItem = structuredClone((_a = (isCyclic ? undefined : resolvePathItemReference(rawPathItem, components))) !== null && _a !== void 0 ? _a : rawPathItem);
|
|
53
|
+
const suppressedBelow = mapPath({
|
|
54
|
+
pathItem,
|
|
33
55
|
refUuidMap,
|
|
34
56
|
uuidObjectHashMap,
|
|
35
57
|
hashedNodeMap,
|
|
36
58
|
uuid: pathUuid,
|
|
37
59
|
path: expression,
|
|
60
|
+
components,
|
|
61
|
+
activePathItems: componentName === undefined || isCyclic
|
|
62
|
+
? activePathItems
|
|
63
|
+
: new Set([...activePathItems, componentName]),
|
|
38
64
|
});
|
|
65
|
+
suppressedBelow.forEach((name) => suppressedPathItems.add(name));
|
|
39
66
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
67
|
callback[expression] = pathUuid;
|
|
41
68
|
});
|
|
42
69
|
// add to hashedNodeMap
|
|
70
|
+
const objectHash = contextualHash(structuralHash, suppressedPathItems, activePathItems);
|
|
71
|
+
uuidObjectHashMap[uuid] = objectHash;
|
|
43
72
|
hashedNodeMap[objectHash] = callback;
|
|
73
|
+
return suppressedPathItems;
|
|
44
74
|
};
|
|
@@ -9,11 +9,12 @@ export const mapCallbackComponents = ({ spec, refUuidMap, uuidObjectHashMap, has
|
|
|
9
9
|
const refId = `#/components/callbacks/${callbackName}`;
|
|
10
10
|
const uuid = refUuidMap[refId] || uuidv4();
|
|
11
11
|
mapCallback({
|
|
12
|
-
callback,
|
|
12
|
+
callback: structuredClone(callback),
|
|
13
13
|
refUuidMap,
|
|
14
14
|
uuidObjectHashMap,
|
|
15
15
|
hashedNodeMap,
|
|
16
16
|
uuid,
|
|
17
|
+
components: spec.components,
|
|
17
18
|
});
|
|
18
19
|
});
|
|
19
20
|
};
|
|
@@ -9,12 +9,7 @@ export const mapExample = ({ example, refUuidMap, uuidObjectHashMap, hashedNodeM
|
|
|
9
9
|
example = objectHash;
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const refUuid = refUuidMap[refId] || uuidv4();
|
|
16
|
-
example.$ref = refUuid;
|
|
17
|
-
}
|
|
18
|
-
// add to hashedNodeMap
|
|
19
|
-
hashedNodeMap[objectHash] = example;
|
|
12
|
+
hashedNodeMap[objectHash] =
|
|
13
|
+
'$ref' in example && example.$ref
|
|
14
|
+
? Object.assign(Object.assign({}, example), { $ref: refUuidMap[example.$ref] || uuidv4() }) : example;
|
|
20
15
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HashedNodeMap, HeaderOrRefObject, RefUuidMap, UUIDObjectHashMap, UUID } from './types/index.js';
|
|
2
|
-
export declare const mapHeader: ({ header, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }: {
|
|
2
|
+
export declare const mapHeader: ({ header: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }: {
|
|
3
3
|
header: HeaderOrRefObject;
|
|
4
4
|
refUuidMap: RefUuidMap;
|
|
5
5
|
uuidObjectHashMap: UUIDObjectHashMap;
|
|
@@ -3,11 +3,13 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
3
3
|
import { mapExample } from './mapExample.js';
|
|
4
4
|
import { mapMedia } from './mapMedia.js';
|
|
5
5
|
import { mapSchema } from './mapSchema.js';
|
|
6
|
-
|
|
6
|
+
import { ownCopy } from './ownCopy.js';
|
|
7
|
+
export const mapHeader = ({ header: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
|
|
7
8
|
// hash the raw object
|
|
8
|
-
const objectHash = hash(
|
|
9
|
+
const objectHash = hash(input);
|
|
9
10
|
// map uuid and hash to uuidObjectHashMap
|
|
10
11
|
uuidObjectHashMap[uuid] = objectHash;
|
|
12
|
+
const header = ownCopy(input, ['examples', 'content', 'schema']);
|
|
11
13
|
// if ref, replace with uuid
|
|
12
14
|
if ('$ref' in header && header.$ref) {
|
|
13
15
|
const refId = header.$ref;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import hash from 'object-hash';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { getComponentNameFromRef } from '../componentRefs.js';
|
|
3
4
|
import { mapExample } from './mapExample.js';
|
|
4
5
|
import { mapSchema } from './mapSchema.js';
|
|
5
6
|
export const mapMedia = ({ content, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
|
|
@@ -7,30 +8,51 @@ export const mapMedia = ({ content, refUuidMap, uuidObjectHashMap, hashedNodeMap
|
|
|
7
8
|
uuidObjectHashMap[uuid] = objectHash;
|
|
8
9
|
// if we've seen this exact object before, skip processing
|
|
9
10
|
if (objectHash in hashedNodeMap) {
|
|
10
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
-
content = objectHash;
|
|
12
11
|
return;
|
|
13
12
|
}
|
|
13
|
+
if ('$ref' in content && typeof content.$ref === 'string') {
|
|
14
|
+
const name = getComponentNameFromRef(content.$ref, 'mediaTypes');
|
|
15
|
+
const refId = name === undefined ? content.$ref : `#/components/mediaTypes/${name}`;
|
|
16
|
+
const mediaRef = Object.assign(Object.assign({}, content), { $ref: refUuidMap[refId] || uuidv4() });
|
|
17
|
+
hashedNodeMap[objectHash] = mediaRef;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const ownReference = (node) => typeof node === 'object' && node !== null && '$ref' in node ? Object.assign({}, node) : node;
|
|
21
|
+
const media = Object.assign(Object.assign({}, content), ('examples' in content && content.examples
|
|
22
|
+
? {
|
|
23
|
+
examples: Object.fromEntries(Object.entries(content.examples).map(([name, example]) => [name, ownReference(example)])),
|
|
24
|
+
}
|
|
25
|
+
: {}));
|
|
26
|
+
if ('schema' in media)
|
|
27
|
+
media.schema = ownReference(media.schema);
|
|
28
|
+
if ('itemSchema' in media)
|
|
29
|
+
media.itemSchema = ownReference(media.itemSchema);
|
|
14
30
|
// if schema in media, create SchemaOrRef node
|
|
15
|
-
if ('schema' in
|
|
31
|
+
if ('schema' in media && media.schema && typeof media.schema === 'object') {
|
|
32
|
+
const uuid = uuidv4();
|
|
33
|
+
mapSchema({ schema: media.schema, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
+
media.schema = uuid;
|
|
36
|
+
}
|
|
37
|
+
if ('itemSchema' in media && media.itemSchema && typeof media.itemSchema === 'object') {
|
|
16
38
|
const uuid = uuidv4();
|
|
17
|
-
mapSchema({ schema:
|
|
39
|
+
mapSchema({ schema: media.itemSchema, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
|
|
18
40
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
-
|
|
41
|
+
media.itemSchema = uuid;
|
|
20
42
|
}
|
|
21
43
|
// if examples in media, create ExampleOrRef node
|
|
22
|
-
if ('examples' in
|
|
23
|
-
Object.entries(
|
|
44
|
+
if ('examples' in media && media.examples && typeof media.examples === 'object') {
|
|
45
|
+
Object.entries(media.examples).forEach(([exampleName, example]) => {
|
|
24
46
|
const uuid = uuidv4();
|
|
25
47
|
mapExample({ example, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
|
|
26
|
-
if (
|
|
48
|
+
if (media.examples) {
|
|
27
49
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
-
|
|
50
|
+
media.examples[exampleName] = uuid;
|
|
29
51
|
}
|
|
30
52
|
});
|
|
31
53
|
}
|
|
32
54
|
// if encoding in media, create Encoding node
|
|
33
55
|
// TODO: add support for encoding
|
|
34
56
|
// add to hashedNodeMap
|
|
35
|
-
hashedNodeMap[objectHash] =
|
|
57
|
+
hashedNodeMap[objectHash] = media;
|
|
36
58
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
2
|
+
import { HashedNodeMap, RefUuidMap, UUIDObjectHashMap } from './types/index.js';
|
|
3
|
+
export declare const mapMediaTypeComponents: ({ spec, refUuidMap, uuidObjectHashMap, hashedNodeMap, }: {
|
|
4
|
+
spec: OpenAPIV3.Document | OpenAPIV3_1.Document;
|
|
5
|
+
refUuidMap: RefUuidMap;
|
|
6
|
+
uuidObjectHashMap: UUIDObjectHashMap;
|
|
7
|
+
hashedNodeMap: HashedNodeMap;
|
|
8
|
+
}) => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { mapMedia } from './mapMedia.js';
|
|
3
|
+
export const mapMediaTypeComponents = ({ spec, refUuidMap, uuidObjectHashMap, hashedNodeMap, }) => {
|
|
4
|
+
const components = spec.components
|
|
5
|
+
? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- 3.2 field on a 3.1-typed document
|
|
6
|
+
spec.components
|
|
7
|
+
: undefined;
|
|
8
|
+
const mediaTypeComponents = components === null || components === void 0 ? void 0 : components.mediaTypes;
|
|
9
|
+
if (!mediaTypeComponents)
|
|
10
|
+
return;
|
|
11
|
+
Object.entries(mediaTypeComponents).forEach(([name, content]) => {
|
|
12
|
+
const refId = `#/components/mediaTypes/${name}`;
|
|
13
|
+
const uuid = refUuidMap[refId] || uuidv4();
|
|
14
|
+
mapMedia({
|
|
15
|
+
content: structuredClone(content),
|
|
16
|
+
refUuidMap,
|
|
17
|
+
uuidObjectHashMap,
|
|
18
|
+
hashedNodeMap,
|
|
19
|
+
uuid,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HttpMethod } from '../types/endpoint.js';
|
|
2
2
|
import { OperationObject, RefUuidMap, UUIDObjectHashMap, HashedNodeMap, UUID } from './types/index.js';
|
|
3
|
-
export declare const mapOperation: ({ operation, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, method, isWebhook, }: {
|
|
3
|
+
export declare const mapOperation: ({ operation: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, method, isWebhook, components, activePathItems, }: {
|
|
4
4
|
operation: OperationObject;
|
|
5
5
|
refUuidMap: RefUuidMap;
|
|
6
6
|
uuidObjectHashMap: UUIDObjectHashMap;
|
|
@@ -8,4 +8,6 @@ export declare const mapOperation: ({ operation, refUuidMap, uuidObjectHashMap,
|
|
|
8
8
|
uuid: UUID;
|
|
9
9
|
method: HttpMethod;
|
|
10
10
|
isWebhook?: boolean;
|
|
11
|
-
|
|
11
|
+
components?: unknown;
|
|
12
|
+
activePathItems?: ReadonlySet<string>;
|
|
13
|
+
}) => ReadonlySet<string>;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import hash from 'object-hash';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { contextualHash } from './contextualHash.js';
|
|
3
4
|
import { mapCallback } from './mapCallback.js';
|
|
4
5
|
import { mapParameter } from './mapParameter.js';
|
|
5
6
|
import { mapRequestBody } from './mapRequestBody.js';
|
|
6
7
|
import { mapResponse } from './mapResponse.js';
|
|
7
8
|
import { mapSecurityRequirement } from './mapSecurityRequirement.js';
|
|
8
|
-
|
|
9
|
+
import { ownCopy } from './ownCopy.js';
|
|
10
|
+
export const mapOperation = ({ operation: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, method, isWebhook, components, activePathItems = new Set(), }) => {
|
|
9
11
|
var _a;
|
|
12
|
+
const operation = ownCopy(input, ['responses', 'callbacks']);
|
|
10
13
|
const type = isWebhook ? 'webhook' : 'path';
|
|
11
|
-
const
|
|
12
|
-
uuidObjectHashMap[uuid] =
|
|
14
|
+
const structuralHash = hash(Object.assign(Object.assign({}, operation), { method, type }));
|
|
15
|
+
uuidObjectHashMap[uuid] = structuralHash;
|
|
16
|
+
const suppressedPathItems = new Set();
|
|
13
17
|
// parameters
|
|
14
18
|
if ('parameters' in operation) {
|
|
15
19
|
const parameterUuids = [];
|
|
@@ -49,7 +53,16 @@ export const mapOperation = ({ operation, refUuidMap, uuidObjectHashMap, hashedN
|
|
|
49
53
|
if ('callbacks' in operation && operation.callbacks) {
|
|
50
54
|
Object.entries(operation.callbacks).forEach(([callbackName, callback]) => {
|
|
51
55
|
const uuid = uuidv4();
|
|
52
|
-
mapCallback({
|
|
56
|
+
const suppressedBelow = mapCallback({
|
|
57
|
+
callback,
|
|
58
|
+
refUuidMap,
|
|
59
|
+
uuidObjectHashMap,
|
|
60
|
+
hashedNodeMap,
|
|
61
|
+
uuid,
|
|
62
|
+
components,
|
|
63
|
+
activePathItems,
|
|
64
|
+
});
|
|
65
|
+
suppressedBelow.forEach((name) => suppressedPathItems.add(name));
|
|
53
66
|
if (operation.callbacks) {
|
|
54
67
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
68
|
operation.callbacks[callbackName] = uuid;
|
|
@@ -83,5 +96,8 @@ export const mapOperation = ({ operation, refUuidMap, uuidObjectHashMap, hashedN
|
|
|
83
96
|
operation.method = method;
|
|
84
97
|
operation.type = type;
|
|
85
98
|
// add to hashedNodeMap
|
|
99
|
+
const objectHash = contextualHash(structuralHash, suppressedPathItems, activePathItems);
|
|
100
|
+
uuidObjectHashMap[uuid] = objectHash;
|
|
86
101
|
hashedNodeMap[objectHash] = operation;
|
|
102
|
+
return suppressedPathItems;
|
|
87
103
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HashedNodeMap, ParameterOrRefObject, RefUuidMap, UUID, UUIDObjectHashMap } from './types/index.js';
|
|
2
|
-
export declare const mapParameter: ({ parameter, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }: {
|
|
2
|
+
export declare const mapParameter: ({ parameter: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }: {
|
|
3
3
|
parameter: ParameterOrRefObject;
|
|
4
4
|
refUuidMap: RefUuidMap;
|
|
5
5
|
uuidObjectHashMap: UUIDObjectHashMap;
|
|
@@ -3,15 +3,15 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
3
3
|
import { mapExample } from './mapExample.js';
|
|
4
4
|
import { mapMedia } from './mapMedia.js';
|
|
5
5
|
import { mapSchema } from './mapSchema.js';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { ownCopy } from './ownCopy.js';
|
|
7
|
+
export const mapParameter = ({ parameter: input, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
|
|
8
|
+
const objectHash = hash(input);
|
|
8
9
|
uuidObjectHashMap[uuid] = objectHash;
|
|
9
10
|
// if we've seen this exact object before, skip processing
|
|
10
11
|
if (objectHash in hashedNodeMap) {
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
-
parameter = objectHash;
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
14
|
+
const parameter = ownCopy(input, ['examples', 'content', 'schema']);
|
|
15
15
|
// if ref, replace with uuid
|
|
16
16
|
if ('$ref' in parameter && parameter.$ref) {
|
|
17
17
|
const refId = parameter.$ref;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefUuidMap, UUIDObjectHashMap, HashedNodeMap, UUID, PathObjectOrRef } from './types/index.js';
|
|
2
|
-
export declare const mapPath: ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, path, isWebhook, }: {
|
|
2
|
+
export declare const mapPath: ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, path, isWebhook, components, activePathItems, }: {
|
|
3
3
|
pathItem: PathObjectOrRef;
|
|
4
4
|
refUuidMap: RefUuidMap;
|
|
5
5
|
uuidObjectHashMap: UUIDObjectHashMap;
|
|
@@ -7,4 +7,6 @@ export declare const mapPath: ({ pathItem, refUuidMap, uuidObjectHashMap, hashed
|
|
|
7
7
|
uuid: UUID;
|
|
8
8
|
path: string;
|
|
9
9
|
isWebhook?: boolean;
|
|
10
|
-
|
|
10
|
+
components?: unknown;
|
|
11
|
+
activePathItems?: ReadonlySet<string>;
|
|
12
|
+
}) => ReadonlySet<string>;
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import hash from 'object-hash';
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { getComponentPathItemName } from '../pathItemReferences.js';
|
|
3
4
|
import { getPathItemOperations, isFixedHttpMethod } from '../types/endpoint.js';
|
|
5
|
+
import { contextualHash } from './contextualHash.js';
|
|
4
6
|
import { mapOperation } from './mapOperation.js';
|
|
5
7
|
import { mapParameter } from './mapParameter.js';
|
|
6
|
-
export const mapPath = ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, path, isWebhook, }) => {
|
|
8
|
+
export const mapPath = ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, path, isWebhook, components, activePathItems = new Set(), }) => {
|
|
7
9
|
var _a;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
pathItem.path = path;
|
|
11
|
+
if (isWebhook)
|
|
12
|
+
pathItem.isWebhook = true;
|
|
13
|
+
const structuralHash = hash(pathItem);
|
|
14
|
+
uuidObjectHashMap[uuid] = structuralHash;
|
|
15
|
+
const suppressedPathItems = new Set();
|
|
10
16
|
if ('$ref' in pathItem && pathItem.$ref) {
|
|
11
|
-
const
|
|
17
|
+
const name = getComponentPathItemName(pathItem);
|
|
18
|
+
const refId = name === undefined ? pathItem.$ref : `#/components/pathItems/${name}`;
|
|
12
19
|
const refUuid = refUuidMap[refId] || uuidv4();
|
|
13
20
|
pathItem.$ref = refUuid;
|
|
14
21
|
}
|
|
@@ -43,11 +50,13 @@ export const mapPath = ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap
|
|
|
43
50
|
pathItem.servers = serverUuids;
|
|
44
51
|
}
|
|
45
52
|
// process operations per http method
|
|
46
|
-
|
|
53
|
+
{
|
|
47
54
|
const additionalOperationUuids = {};
|
|
48
|
-
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- sibling operations share the PathObject shape
|
|
56
|
+
const operations = getPathItemOperations(pathItem);
|
|
57
|
+
for (const [method, operation] of operations) {
|
|
49
58
|
const operationUuid = uuidv4();
|
|
50
|
-
mapOperation({
|
|
59
|
+
const suppressedBelow = mapOperation({
|
|
51
60
|
operation,
|
|
52
61
|
refUuidMap,
|
|
53
62
|
uuidObjectHashMap,
|
|
@@ -55,7 +64,10 @@ export const mapPath = ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap
|
|
|
55
64
|
uuid: operationUuid,
|
|
56
65
|
method,
|
|
57
66
|
isWebhook,
|
|
67
|
+
components,
|
|
68
|
+
activePathItems,
|
|
58
69
|
});
|
|
70
|
+
suppressedBelow.forEach((name) => suppressedPathItems.add(name));
|
|
59
71
|
if (isFixedHttpMethod(method)) {
|
|
60
72
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
73
|
pathItem[method] = operationUuid;
|
|
@@ -70,7 +82,9 @@ export const mapPath = ({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap
|
|
|
70
82
|
pathItem.additionalOperations = additionalOperationUuids;
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
|
-
pathItem.path = path;
|
|
74
85
|
// store path object
|
|
86
|
+
const objectHash = contextualHash(structuralHash, suppressedPathItems, activePathItems);
|
|
87
|
+
uuidObjectHashMap[uuid] = objectHash;
|
|
75
88
|
hashedNodeMap[objectHash] = pathItem;
|
|
89
|
+
return suppressedPathItems;
|
|
76
90
|
};
|
|
@@ -9,6 +9,15 @@ export const mapPathComponents = ({ spec, refUuidMap, uuidObjectHashMap, hashedN
|
|
|
9
9
|
Object.entries(pathComponents).forEach(([name, pathItem]) => {
|
|
10
10
|
const refId = `#/components/pathItems/${name}`;
|
|
11
11
|
const uuid = refUuidMap[refId] || uuidv4();
|
|
12
|
-
mapPath({
|
|
12
|
+
mapPath({
|
|
13
|
+
pathItem: structuredClone(pathItem),
|
|
14
|
+
refUuidMap,
|
|
15
|
+
uuidObjectHashMap,
|
|
16
|
+
hashedNodeMap,
|
|
17
|
+
uuid,
|
|
18
|
+
path: name,
|
|
19
|
+
components: spec.components,
|
|
20
|
+
activePathItems: new Set([name]),
|
|
21
|
+
});
|
|
13
22
|
});
|
|
14
23
|
};
|