@mintlify/prebuild 1.0.1538 → 1.0.1540
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.
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { parseGraphqlSelector, resolveGraphqlOperation, } from '@mintlify/common';
|
|
1
|
+
import { getNamedGraphqlType, parseGraphqlSelector, resolveGraphqlOperation, } from '@mintlify/common';
|
|
2
2
|
import { parseGraphqlSdl } from '@mintlify/scraping';
|
|
3
3
|
import fse from 'fs-extra';
|
|
4
|
+
import kebabCase from 'lodash/kebabCase.js';
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
4
6
|
import { open } from 'node:fs/promises';
|
|
5
7
|
import path from 'node:path';
|
|
8
|
+
import { addWarning } from '../../warnings.js';
|
|
6
9
|
import { getGeneratedRouteKey } from './generatedRouteCollisions.js';
|
|
7
10
|
import { loadRemoteGraphqlSdl, MAX_GRAPHQL_SCHEMA_BYTES } from './loadRemoteGraphqlSdl.js';
|
|
8
11
|
const DEFAULT_OUTPUT_DIR = 'graphql-reference';
|
|
@@ -13,11 +16,71 @@ function graphqlConfig(config) {
|
|
|
13
16
|
? { source: config, directory: DEFAULT_OUTPUT_DIR }
|
|
14
17
|
: { source: config.source, directory: config.directory ?? DEFAULT_OUTPUT_DIR };
|
|
15
18
|
}
|
|
16
|
-
function
|
|
19
|
+
function getPathSegments(names) {
|
|
20
|
+
const firstNames = new Map();
|
|
21
|
+
for (const name of names) {
|
|
22
|
+
const key = name.toLowerCase();
|
|
23
|
+
const current = firstNames.get(key);
|
|
24
|
+
if (current === undefined || name < current)
|
|
25
|
+
firstNames.set(key, name);
|
|
26
|
+
}
|
|
27
|
+
const renamed = names.filter((name) => firstNames.get(name.toLowerCase()) !== name);
|
|
28
|
+
const segmentCounts = new Map();
|
|
29
|
+
for (const name of renamed) {
|
|
30
|
+
const segment = kebabCase(name);
|
|
31
|
+
segmentCounts.set(segment, (segmentCounts.get(segment) ?? 0) + 1);
|
|
32
|
+
}
|
|
33
|
+
return new Map(names.map((name) => {
|
|
34
|
+
const firstName = firstNames.get(name.toLowerCase());
|
|
35
|
+
if (firstName === name)
|
|
36
|
+
return [name, name];
|
|
37
|
+
const kebabName = kebabCase(name);
|
|
38
|
+
const segment = kebabName.includes('-') && segmentCounts.get(kebabName) === 1
|
|
39
|
+
? kebabName
|
|
40
|
+
: `${kebabName ? `${kebabName}-` : ''}${createHash('sha256').update(name).digest('hex').slice(0, 6)}`;
|
|
41
|
+
addWarning({
|
|
42
|
+
type: 'graphql',
|
|
43
|
+
message: `GraphQL name "${name}" shares its URL with "${firstName}", so its page uses "${segment}"`,
|
|
44
|
+
});
|
|
45
|
+
return [name, segment];
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
const typePathCache = new WeakMap();
|
|
49
|
+
const fieldSegmentCache = new WeakMap();
|
|
50
|
+
function getTypePath(reference, name) {
|
|
51
|
+
let typePaths = typePathCache.get(reference);
|
|
52
|
+
if (!typePaths) {
|
|
53
|
+
typePaths = getPathSegments(reference.types.filter((type) => isDocumentedType(reference, type)).map((type) => type.name));
|
|
54
|
+
typePathCache.set(reference, typePaths);
|
|
55
|
+
}
|
|
56
|
+
return typePaths.get(name);
|
|
57
|
+
}
|
|
58
|
+
function getFieldSegment(fields, name) {
|
|
59
|
+
let segments = fieldSegmentCache.get(fields);
|
|
60
|
+
if (!segments) {
|
|
61
|
+
segments = getPathSegments(fields.map((field) => field.name));
|
|
62
|
+
fieldSegmentCache.set(fields, segments);
|
|
63
|
+
}
|
|
64
|
+
return segments.get(name);
|
|
65
|
+
}
|
|
66
|
+
function getOperationPath(reference, rootType, name) {
|
|
67
|
+
let typeName = rootType;
|
|
68
|
+
return path.posix.join(...name.split('.').map((fieldName) => {
|
|
69
|
+
const parent = reference.types.find((type) => type.name === typeName);
|
|
70
|
+
const fields = parent?.kind === 'object' || parent?.kind === 'interface' ? parent.fields : [];
|
|
71
|
+
const field = fields.find((candidate) => candidate.name === fieldName);
|
|
72
|
+
typeName = field ? getNamedGraphqlType(field.type) : undefined;
|
|
73
|
+
return getFieldSegment(fields, fieldName) ?? fieldName;
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
function makePage(reference, source, directory, kind, name, entry) {
|
|
17
77
|
const section = kind === 'query' ? 'queries' : kind === 'mutation' ? 'mutations' : 'types';
|
|
18
78
|
const sectionPath = path.posix.join(directory, section);
|
|
79
|
+
const pagePath = kind === 'type'
|
|
80
|
+
? (getTypePath(reference, name) ?? name)
|
|
81
|
+
: getOperationPath(reference, kind === 'query' ? reference.queryType : reference.mutationType, name);
|
|
19
82
|
return {
|
|
20
|
-
slug: path.posix.join(sectionPath,
|
|
83
|
+
slug: path.posix.join(sectionPath, pagePath),
|
|
21
84
|
directory: path.posix.dirname(sectionPath),
|
|
22
85
|
title: name.slice(name.lastIndexOf('.') + 1),
|
|
23
86
|
...('description' in entry && entry.description ? { description: entry.description } : {}),
|
|
@@ -34,10 +97,22 @@ const DOCUMENTED_TYPE_KINDS = [
|
|
|
34
97
|
'interface',
|
|
35
98
|
'union',
|
|
36
99
|
'enum',
|
|
100
|
+
'scalar',
|
|
37
101
|
];
|
|
102
|
+
function isReferencedType(reference, name) {
|
|
103
|
+
return reference.types.some((type) => ('fields' in type &&
|
|
104
|
+
type.fields.some((field) => getNamedGraphqlType(field.type) === name ||
|
|
105
|
+
('arguments' in field &&
|
|
106
|
+
field.arguments.some((arg) => getNamedGraphqlType(arg.type) === name)))) ||
|
|
107
|
+
('possibleTypes' in type && type.possibleTypes.includes(name)));
|
|
108
|
+
}
|
|
38
109
|
function isDocumentedType(reference, type) {
|
|
39
|
-
|
|
40
|
-
|
|
110
|
+
if (type.name === reference.queryType || type.name === reference.mutationType)
|
|
111
|
+
return false;
|
|
112
|
+
if (type.name === reference.subscriptionType && !isReferencedType(reference, type.name)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
return DOCUMENTED_TYPE_KINDS.includes(type.kind);
|
|
41
116
|
}
|
|
42
117
|
function makeSelectedPage(reference, source, directory, selector) {
|
|
43
118
|
const label = `GraphQL ${selector.kind} ${selector.name}`;
|
|
@@ -46,12 +121,12 @@ function makeSelectedPage(reference, source, directory, selector) {
|
|
|
46
121
|
if (!type || !isDocumentedType(reference, type)) {
|
|
47
122
|
throw new Error(`${label} not found in ${source}`);
|
|
48
123
|
}
|
|
49
|
-
return makePage(source, directory, 'type', selector.name, type);
|
|
124
|
+
return makePage(reference, source, directory, 'type', selector.name, type);
|
|
50
125
|
}
|
|
51
126
|
const resolved = resolveGraphqlOperation(reference, selector);
|
|
52
127
|
if (!resolved)
|
|
53
128
|
throw new Error(`${label} not found in ${source}`);
|
|
54
|
-
return makePage(source, directory, selector.kind, selector.name, resolved.field);
|
|
129
|
+
return makePage(reference, source, directory, selector.kind, selector.name, resolved.field);
|
|
55
130
|
}
|
|
56
131
|
function generatePages(reference, source, directory) {
|
|
57
132
|
const typeByName = new Map(reference.types.map((type) => [type.name, type]));
|
|
@@ -71,16 +146,16 @@ function generatePages(reference, source, directory) {
|
|
|
71
146
|
queries: queryFields
|
|
72
147
|
.slice()
|
|
73
148
|
.sort(byName)
|
|
74
|
-
.map((field) => makePage(source, directory, 'query', field.name, field)),
|
|
149
|
+
.map((field) => makePage(reference, source, directory, 'query', field.name, field)),
|
|
75
150
|
mutations: mutationFields
|
|
76
151
|
.slice()
|
|
77
152
|
.sort(byName)
|
|
78
|
-
.map((field) => makePage(source, directory, 'mutation', field.name, field)),
|
|
153
|
+
.map((field) => makePage(reference, source, directory, 'mutation', field.name, field)),
|
|
79
154
|
types: reference.types
|
|
80
155
|
.filter((type) => isDocumentedType(reference, type))
|
|
81
156
|
.slice()
|
|
82
157
|
.sort(byName)
|
|
83
|
-
.map((type) => makePage(source, directory, 'type', type.name, type)),
|
|
158
|
+
.map((type) => makePage(reference, source, directory, 'type', type.name, type)),
|
|
84
159
|
};
|
|
85
160
|
}
|
|
86
161
|
function mdxStub(page) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type Warning = {
|
|
2
|
-
type: 'missing-file' | 'missing-nav-page' | 'openapi' | 'invalid-import-path' | 'import-resolution-error' | 'default-import-no-default-export' | 'export-collision' | 'undeclared-package' | 'package-import-conflict' | 'parse-error';
|
|
2
|
+
type: 'missing-file' | 'missing-nav-page' | 'openapi' | 'invalid-import-path' | 'import-resolution-error' | 'default-import-no-default-export' | 'export-collision' | 'undeclared-package' | 'package-import-conflict' | 'parse-error' | 'graphql';
|
|
3
3
|
message: string;
|
|
4
4
|
file?: string;
|
|
5
5
|
line?: number;
|