@mintlify/common 1.0.1131 → 1.0.1133

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,47 @@
1
+ import { type OverlayDocument } from '@mintlify/validation';
2
+ import type { LoadedOverlay } from './applyOverlay.js';
3
+ /** An overlay file discovered by walking the docs repository. */
4
+ export type DiscoveredOverlay = {
5
+ /** Normalized repo location of the overlay file (no leading slash). */
6
+ location: string;
7
+ document: OverlayDocument;
8
+ /** Normalized spec key from `extends`; undefined means the overlay is never applied. */
9
+ resolvedExtends?: string;
10
+ };
11
+ export type OverlayRegistry = {
12
+ /** Normalized spec source -> ordered overlay refs explicitly configured in docs.json. */
13
+ explicit: Map<string, string[]>;
14
+ /** Auto-discovered overlays (applied only to specs with no explicit list). */
15
+ discovered: DiscoveredOverlay[];
16
+ /** Loads an explicitly referenced overlay by local path or https URL. */
17
+ loadOverlay: (ref: string) => Promise<LoadedOverlay>;
18
+ };
19
+ /** Canonical lookup key: URLs unchanged, paths posix-normalized without a leading slash. */
20
+ export declare function normalizeOverlayKey(reference: string): string;
21
+ /** Resolves an overlay's `extends` against the overlay file's own location. */
22
+ export declare function resolveExtends(overlayLocation: string, extendsValue: string): string;
23
+ export type CreateOverlayRegistryOptions = {
24
+ /** Explicit overlay lists from docs.json, keyed by normalized spec source. */
25
+ explicit?: Map<string, string[]>;
26
+ /** Overlay files discovered in the repository. */
27
+ discovered?: DiscoveredOverlay[];
28
+ /** Reads a local overlay file by normalized repo path. */
29
+ loadLocalDocument?: (normalizedPath: string) => Promise<unknown>;
30
+ /** Allow http:// overlay URLs (CLI --local-schema). */
31
+ localSchema?: boolean;
32
+ /**
33
+ * Overrides fetching and parsing of overlay URLs. Hosted environments substitute an
34
+ * SSRF-safe fetch that blocks private, loopback, and metadata targets across redirects.
35
+ */
36
+ fetchRemoteDocument?: (url: string) => Promise<unknown>;
37
+ };
38
+ /** Validates a parsed value as an Overlay document, JSON-normalizing YAML values. */
39
+ export declare function parseLoadedOverlayDocument(value: unknown, location: string): OverlayDocument;
40
+ export declare function createOverlayRegistry({ explicit, discovered, loadLocalDocument, localSchema, fetchRemoteDocument, }: CreateOverlayRegistryOptions): OverlayRegistry;
41
+ /**
42
+ * Resolves the ordered list of overlays to apply to a spec:
43
+ * - an explicit `overlays` list in docs.json wins (an empty list disables everything)
44
+ * - otherwise auto-discovered overlays whose `extends` resolves to this spec apply, in
45
+ * alphabetical order of the overlay file's location.
46
+ */
47
+ export declare function resolveOverlaysForSpec(registry: OverlayRegistry, specLocation: string): Promise<LoadedOverlay[]>;
@@ -0,0 +1,107 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { parseOverlayDocument } from '@mintlify/validation';
11
+ import { isAbsoluteUrl } from '../../isAbsoluteUrl.js';
12
+ import { fetchYamlDocument } from '../fetchYamlDocument.js';
13
+ import { toJsonValue } from './jsonValue.js';
14
+ /** Canonical lookup key: URLs unchanged, paths posix-normalized without a leading slash. */
15
+ export function normalizeOverlayKey(reference) {
16
+ if (isAbsoluteUrl(reference))
17
+ return reference;
18
+ return normalizePathSegments(reference.split('/'));
19
+ }
20
+ function normalizePathSegments(segments) {
21
+ const resolved = [];
22
+ for (const segment of segments) {
23
+ if (segment === '' || segment === '.')
24
+ continue;
25
+ if (segment === '..') {
26
+ resolved.pop();
27
+ continue;
28
+ }
29
+ resolved.push(segment);
30
+ }
31
+ return resolved.join('/');
32
+ }
33
+ /** Resolves an overlay's `extends` against the overlay file's own location. */
34
+ export function resolveExtends(overlayLocation, extendsValue) {
35
+ if (isAbsoluteUrl(extendsValue))
36
+ return extendsValue;
37
+ if (extendsValue.startsWith('/')) {
38
+ return normalizeOverlayKey(extendsValue);
39
+ }
40
+ const directorySegments = normalizeOverlayKey(overlayLocation).split('/').slice(0, -1);
41
+ return normalizePathSegments([...directorySegments, ...extendsValue.split('/')]);
42
+ }
43
+ /** Validates a parsed value as an Overlay document, JSON-normalizing YAML values. */
44
+ export function parseLoadedOverlayDocument(value, location) {
45
+ const jsonValue = toJsonValue(value, `Overlay document ${location}`);
46
+ return parseOverlayDocument(jsonValue);
47
+ }
48
+ const isAllowedOverlayUrl = (reference, localSchema) => {
49
+ if (reference.startsWith('https:'))
50
+ return true;
51
+ return localSchema === true && reference.startsWith('http:');
52
+ };
53
+ export function createOverlayRegistry({ explicit = new Map(), discovered = [], loadLocalDocument, localSchema, fetchRemoteDocument, }) {
54
+ const cache = new Map();
55
+ const discoveredByLocation = new Map(discovered.map((overlay) => [overlay.location, overlay]));
56
+ const loadOverlay = (ref) => {
57
+ const key = normalizeOverlayKey(ref);
58
+ const cached = cache.get(key);
59
+ if (cached)
60
+ return cached;
61
+ const promise = (() => __awaiter(this, void 0, void 0, function* () {
62
+ if (isAbsoluteUrl(key)) {
63
+ if (!isAllowedOverlayUrl(key, localSchema)) {
64
+ throw new Error(`Overlay URL ${ref} must use https. http:// overlay URLs are only supported with the CLI option --local-schema.`);
65
+ }
66
+ const raw = fetchRemoteDocument
67
+ ? yield fetchRemoteDocument(key)
68
+ : yield fetchYamlDocument(key);
69
+ return { document: parseLoadedOverlayDocument(raw, key), location: key };
70
+ }
71
+ const alreadyDiscovered = discoveredByLocation.get(key);
72
+ if (alreadyDiscovered) {
73
+ return { document: alreadyDiscovered.document, location: alreadyDiscovered.location };
74
+ }
75
+ if (!loadLocalDocument) {
76
+ throw new Error(`Overlay file ${ref} was not found in the repository`);
77
+ }
78
+ const raw = yield loadLocalDocument(key);
79
+ if (raw == undefined) {
80
+ throw new Error(`Overlay file ${ref} was not found in the repository`);
81
+ }
82
+ return { document: parseLoadedOverlayDocument(raw, key), location: key };
83
+ }))();
84
+ cache.set(key, promise);
85
+ return promise;
86
+ };
87
+ return { explicit, discovered, loadOverlay };
88
+ }
89
+ /**
90
+ * Resolves the ordered list of overlays to apply to a spec:
91
+ * - an explicit `overlays` list in docs.json wins (an empty list disables everything)
92
+ * - otherwise auto-discovered overlays whose `extends` resolves to this spec apply, in
93
+ * alphabetical order of the overlay file's location.
94
+ */
95
+ export function resolveOverlaysForSpec(registry, specLocation) {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ const key = normalizeOverlayKey(specLocation);
98
+ const explicitRefs = registry.explicit.get(key);
99
+ if (explicitRefs !== undefined) {
100
+ return Promise.all(explicitRefs.map((ref) => registry.loadOverlay(ref)));
101
+ }
102
+ return registry.discovered
103
+ .filter((overlay) => overlay.resolvedExtends === key)
104
+ .sort((a, b) => (a.location < b.location ? -1 : a.location > b.location ? 1 : 0))
105
+ .map((overlay) => ({ document: overlay.document, location: overlay.location }));
106
+ });
107
+ }