@mintlify/validation 0.1.890 → 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.
Files changed (45) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +2 -0
  3. package/dist/openapi/componentRefs.d.ts +2 -0
  4. package/dist/openapi/componentRefs.js +19 -0
  5. package/dist/openapi/pathItemReferences.d.ts +6 -0
  6. package/dist/openapi/pathItemReferences.js +58 -0
  7. package/dist/openapi/utils.d.ts +1 -0
  8. package/dist/openapi/utils.js +1 -0
  9. package/dist/openapi/v2/buildRefUuidMap.js +2 -1
  10. package/dist/openapi/v2/contextualHash.d.ts +1 -0
  11. package/dist/openapi/v2/contextualHash.js +5 -0
  12. package/dist/openapi/v2/mapCallback.d.ts +4 -2
  13. package/dist/openapi/v2/mapCallback.js +44 -14
  14. package/dist/openapi/v2/mapCallbackComponents.js +2 -1
  15. package/dist/openapi/v2/mapExample.js +3 -8
  16. package/dist/openapi/v2/mapHeader.d.ts +1 -1
  17. package/dist/openapi/v2/mapHeader.js +4 -2
  18. package/dist/openapi/v2/mapMedia.js +32 -10
  19. package/dist/openapi/v2/mapMediaTypeComponents.d.ts +8 -0
  20. package/dist/openapi/v2/mapMediaTypeComponents.js +22 -0
  21. package/dist/openapi/v2/mapOperation.d.ts +4 -2
  22. package/dist/openapi/v2/mapOperation.js +20 -4
  23. package/dist/openapi/v2/mapParameter.d.ts +1 -1
  24. package/dist/openapi/v2/mapParameter.js +4 -4
  25. package/dist/openapi/v2/mapPath.d.ts +4 -2
  26. package/dist/openapi/v2/mapPath.js +22 -8
  27. package/dist/openapi/v2/mapPathComponents.js +10 -1
  28. package/dist/openapi/v2/mapPaths.js +16 -3
  29. package/dist/openapi/v2/mapRequestBody.d.ts +1 -1
  30. package/dist/openapi/v2/mapRequestBody.js +4 -4
  31. package/dist/openapi/v2/mapResponse.d.ts +1 -1
  32. package/dist/openapi/v2/mapResponse.js +4 -2
  33. package/dist/openapi/v2/mapSchemaComponents.js +4 -1
  34. package/dist/openapi/v2/mapSecurityRequirement.d.ts +1 -0
  35. package/dist/openapi/v2/mapSecurityRequirement.js +15 -6
  36. package/dist/openapi/v2/mapWebhooks.js +8 -2
  37. package/dist/openapi/v2/openApiToSchemaGraph.js +2 -0
  38. package/dist/openapi/v2/ownCopy.d.ts +1 -0
  39. package/dist/openapi/v2/ownCopy.js +11 -0
  40. package/dist/openapi/v2/replaceSchemaRefs.d.ts +7 -1
  41. package/dist/openapi/v2/replaceSchemaRefs.js +118 -12
  42. package/dist/openapi/v2/schemaGraphToOpenApi.js +51 -5
  43. package/dist/openapi/v2/types/index.d.ts +26 -8
  44. package/dist/tsconfig.build.tsbuildinfo +1 -1
  45. 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,2 @@
1
+ export declare const getComponentNameFromRef: (ref: string, section: string) => string | undefined;
2
+ export declare const getSecuritySchemeNameFromFragment: (key: string) => string | undefined;
@@ -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
+ };
@@ -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.
@@ -1,4 +1,5 @@
1
1
  import lcm from 'lcm';
2
+ export const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
2
3
  export const structuredDataContentTypes = [
3
4
  'multipart/form-data',
4
5
  'application/json',
@@ -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', // TODO: add support for 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
- }) => void;
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
- export const mapCallback = ({ callback, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
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 objectHash = hash(callback);
7
- // map uuid and hash to uuidObjectHashMap
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 (objectHash in hashedNodeMap) {
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- callback = objectHash;
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[objectHash] = callback;
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, pathItem]) => {
44
+ Object.entries(callback).forEach(([expression, rawPathItem]) => {
45
+ var _a;
30
46
  const pathUuid = uuidv4();
31
- mapPath({
32
- pathItem: pathItem,
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
- // if ref, replace with uuid
13
- if ('$ref' in example && example.$ref) {
14
- const refId = example.$ref;
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
- export const mapHeader = ({ header, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
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(header);
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 content && content.schema && typeof content.schema === 'object') {
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: content.schema, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
39
+ mapSchema({ schema: media.itemSchema, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
18
40
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- content.schema = uuid;
41
+ media.itemSchema = uuid;
20
42
  }
21
43
  // if examples in media, create ExampleOrRef node
22
- if ('examples' in content && content.examples && typeof content.examples === 'object') {
23
- Object.entries(content.examples).forEach(([exampleName, example]) => {
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 (content.examples) {
48
+ if (media.examples) {
27
49
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- content.examples[exampleName] = uuid;
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] = content;
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
- }) => void;
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
- export const mapOperation = ({ operation, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, method, isWebhook, }) => {
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 objectHash = hash(Object.assign(Object.assign({}, operation), { method, type }));
12
- uuidObjectHashMap[uuid] = objectHash;
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({ callback, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid });
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
- export const mapParameter = ({ parameter, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, }) => {
7
- const objectHash = hash(parameter);
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
- }) => void;
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
- const objectHash = hash(pathItem);
9
- uuidObjectHashMap[uuid] = objectHash;
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 refId = pathItem.$ref;
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
- if (!('$ref' in pathItem)) {
53
+ {
47
54
  const additionalOperationUuids = {};
48
- for (const [method, operation] of getPathItemOperations(pathItem)) {
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({ pathItem, refUuidMap, uuidObjectHashMap, hashedNodeMap, uuid, path: name });
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
  };