radiant-docs-validator 0.1.0 → 0.1.4
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 +30 -1
- package/dist/index.js +297 -3
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -163,8 +163,37 @@ type Footer = {
|
|
|
163
163
|
socials?: Partial<Record<SocialPlatform, string>>;
|
|
164
164
|
links?: FooterLink[];
|
|
165
165
|
};
|
|
166
|
+
type DocsHrefResolution = {
|
|
167
|
+
kind: "ignored";
|
|
168
|
+
} | {
|
|
169
|
+
kind: "invalid";
|
|
170
|
+
reason: "not-root-absolute" | "generated-route" | "empty-target" | "path-traversal";
|
|
171
|
+
href: string;
|
|
172
|
+
pathname: string;
|
|
173
|
+
suffix: string;
|
|
174
|
+
filePath: string;
|
|
175
|
+
suggestedHref?: string;
|
|
176
|
+
} | {
|
|
177
|
+
kind: "docs-page";
|
|
178
|
+
href: string;
|
|
179
|
+
pathname: string;
|
|
180
|
+
suffix: string;
|
|
181
|
+
filePath: string;
|
|
182
|
+
} | {
|
|
183
|
+
kind: "local-asset";
|
|
184
|
+
href: string;
|
|
185
|
+
pathname: string;
|
|
186
|
+
suffix: string;
|
|
187
|
+
filePath: string;
|
|
188
|
+
extension: string;
|
|
189
|
+
publishable: boolean;
|
|
190
|
+
};
|
|
166
191
|
declare function loadOpenApiSpec(filePathOrUrl: string): Promise<any>;
|
|
167
192
|
declare function getConfig(): Promise<DocsConfig>;
|
|
193
|
+
declare const PUBLISHABLE_STATIC_ASSET_EXTENSIONS: readonly [".avif", ".csv", ".doc", ".docx", ".gif", ".ico", ".jpeg", ".jpg", ".mp3", ".mp4", ".ogg", ".pdf", ".png", ".ppt", ".pptx", ".svg", ".tsv", ".txt", ".wav", ".webm", ".webp", ".xls", ".xlsx", ".zip"];
|
|
194
|
+
declare function isPublishableStaticAssetPath(filePath: string): boolean;
|
|
195
|
+
declare function resolveDocsHref(href: string): DocsHrefResolution;
|
|
196
|
+
declare const resolveDocsPageHref: typeof resolveDocsHref;
|
|
168
197
|
declare function validateMdxContent(): Promise<void>;
|
|
169
198
|
|
|
170
|
-
export { type AssistantButtonConfig, type AssistantButtonSize, type AssistantConfig, type AssistantIcon, type AssistantNavbarButtonConfig, BASE_COLOR_OPTIONS, type BaseColorByMode, type BaseColorOption, type CardButtonTheme, type CardCoverTheme, type CardTheme, type CodeSyntaxThemeConfig, type CodeTheme, DEFAULT_THEME_COLOR_DARK, DEFAULT_THEME_COLOR_LIGHT, type DocsConfig, type DocsTheme, type DocsValidatorOptions, type Footer, type FooterLink, type HiddenPageRoute, type Logo, type LogoVariant, type NavGroup, type NavMenu, type NavMenuItem, type NavOpenApi, type NavOpenApiPage, type NavOpenApiPageRef, type NavPage, type NavTag, type NavbarItem, type NavigationItem, type SocialPlatform, type TagTheme, type ThemeColorByMode, configureDocsValidator, getConfig, loadOpenApiSpec, validateMdxContent };
|
|
199
|
+
export { type AssistantButtonConfig, type AssistantButtonSize, type AssistantConfig, type AssistantIcon, type AssistantNavbarButtonConfig, BASE_COLOR_OPTIONS, type BaseColorByMode, type BaseColorOption, type CardButtonTheme, type CardCoverTheme, type CardTheme, type CodeSyntaxThemeConfig, type CodeTheme, DEFAULT_THEME_COLOR_DARK, DEFAULT_THEME_COLOR_LIGHT, type DocsConfig, type DocsHrefResolution, type DocsTheme, type DocsValidatorOptions, type Footer, type FooterLink, type HiddenPageRoute, type Logo, type LogoVariant, type NavGroup, type NavMenu, type NavMenuItem, type NavOpenApi, type NavOpenApiPage, type NavOpenApiPageRef, type NavPage, type NavTag, type NavbarItem, type NavigationItem, PUBLISHABLE_STATIC_ASSET_EXTENSIONS, type SocialPlatform, type TagTheme, type ThemeColorByMode, configureDocsValidator, getConfig, isPublishableStaticAssetPath, loadOpenApiSpec, resolveDocsHref, resolveDocsPageHref, validateMdxContent };
|
package/dist/index.js
CHANGED
|
@@ -289,6 +289,19 @@ function validateFileExistence(filePath, currentPath) {
|
|
|
289
289
|
);
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
+
function normalizeDocsRootFilePath(value) {
|
|
293
|
+
let normalized = value.replace(/\\/g, "/").trim();
|
|
294
|
+
if (!normalized) return "";
|
|
295
|
+
normalized = normalized.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
296
|
+
const posixNormalized = path.posix.normalize(`/${normalized}`).replace(/^\/+/, "");
|
|
297
|
+
return posixNormalized === "." ? "" : posixNormalized;
|
|
298
|
+
}
|
|
299
|
+
function normalizeDocsFilePath(value) {
|
|
300
|
+
return normalizeDocsRootFilePath(value).replace(/\.(md|mdx)$/i, "");
|
|
301
|
+
}
|
|
302
|
+
function containsPathTraversal(value) {
|
|
303
|
+
return value.replace(/\\/g, "/").split("/").includes("..");
|
|
304
|
+
}
|
|
292
305
|
function normalizeDocsPagePath(value, currentPath, label = "Page path") {
|
|
293
306
|
checkType(value, "string", currentPath, label);
|
|
294
307
|
const trimmedPath = value.trim();
|
|
@@ -1975,6 +1988,273 @@ function validateComponentUsage(content) {
|
|
|
1975
1988
|
);
|
|
1976
1989
|
}
|
|
1977
1990
|
}
|
|
1991
|
+
var EXTERNAL_PROTOCOL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
|
1992
|
+
var DOCS_PAGE_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
|
|
1993
|
+
var DOCS_PAGE_ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".htm", ".html"]);
|
|
1994
|
+
var PUBLISHABLE_STATIC_ASSET_EXTENSIONS = [
|
|
1995
|
+
".avif",
|
|
1996
|
+
".csv",
|
|
1997
|
+
".doc",
|
|
1998
|
+
".docx",
|
|
1999
|
+
".gif",
|
|
2000
|
+
".ico",
|
|
2001
|
+
".jpeg",
|
|
2002
|
+
".jpg",
|
|
2003
|
+
".mp3",
|
|
2004
|
+
".mp4",
|
|
2005
|
+
".ogg",
|
|
2006
|
+
".pdf",
|
|
2007
|
+
".png",
|
|
2008
|
+
".ppt",
|
|
2009
|
+
".pptx",
|
|
2010
|
+
".svg",
|
|
2011
|
+
".tsv",
|
|
2012
|
+
".txt",
|
|
2013
|
+
".wav",
|
|
2014
|
+
".webm",
|
|
2015
|
+
".webp",
|
|
2016
|
+
".xls",
|
|
2017
|
+
".xlsx",
|
|
2018
|
+
".zip"
|
|
2019
|
+
];
|
|
2020
|
+
var PUBLISHABLE_STATIC_ASSET_EXTENSION_SET = new Set(
|
|
2021
|
+
PUBLISHABLE_STATIC_ASSET_EXTENSIONS
|
|
2022
|
+
);
|
|
2023
|
+
function isIgnoredHref(pathname) {
|
|
2024
|
+
if (!pathname) return true;
|
|
2025
|
+
if (pathname.startsWith("#")) return true;
|
|
2026
|
+
if (pathname.startsWith("?")) return true;
|
|
2027
|
+
if (pathname.startsWith("//")) return true;
|
|
2028
|
+
return EXTERNAL_PROTOCOL_REGEX.test(pathname);
|
|
2029
|
+
}
|
|
2030
|
+
function getHrefExtension(pathname) {
|
|
2031
|
+
return path.posix.extname(pathname.replace(/\\/g, "/")).toLowerCase();
|
|
2032
|
+
}
|
|
2033
|
+
function isPublishableStaticAssetPath(filePath) {
|
|
2034
|
+
return PUBLISHABLE_STATIC_ASSET_EXTENSION_SET.has(getHrefExtension(filePath));
|
|
2035
|
+
}
|
|
2036
|
+
function resolveDocsHref(href) {
|
|
2037
|
+
const { pathname, suffix } = splitHrefPathAndSuffix(href);
|
|
2038
|
+
const baseHref = pathname.trim();
|
|
2039
|
+
if (isIgnoredHref(baseHref)) {
|
|
2040
|
+
return { kind: "ignored" };
|
|
2041
|
+
}
|
|
2042
|
+
const normalizedRootFilePath = normalizeDocsRootFilePath(baseHref);
|
|
2043
|
+
const baseResult = {
|
|
2044
|
+
href,
|
|
2045
|
+
pathname: baseHref,
|
|
2046
|
+
suffix,
|
|
2047
|
+
filePath: normalizedRootFilePath
|
|
2048
|
+
};
|
|
2049
|
+
if (containsPathTraversal(baseHref)) {
|
|
2050
|
+
return {
|
|
2051
|
+
kind: "invalid",
|
|
2052
|
+
reason: "path-traversal",
|
|
2053
|
+
...baseResult
|
|
2054
|
+
};
|
|
2055
|
+
}
|
|
2056
|
+
if (!baseHref.startsWith("/")) {
|
|
2057
|
+
return {
|
|
2058
|
+
kind: "invalid",
|
|
2059
|
+
reason: "not-root-absolute",
|
|
2060
|
+
...baseResult,
|
|
2061
|
+
suggestedHref: normalizedRootFilePath ? `/${normalizedRootFilePath}` : void 0
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
if (!normalizedRootFilePath) {
|
|
2065
|
+
return {
|
|
2066
|
+
kind: "invalid",
|
|
2067
|
+
reason: "empty-target",
|
|
2068
|
+
...baseResult
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
const extension = getHrefExtension(baseHref);
|
|
2072
|
+
if (DOCS_PAGE_ROUTE_EXTENSIONS.has(extension)) {
|
|
2073
|
+
return {
|
|
2074
|
+
kind: "invalid",
|
|
2075
|
+
reason: "generated-route",
|
|
2076
|
+
...baseResult
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2079
|
+
if (!extension || DOCS_PAGE_SOURCE_EXTENSIONS.has(extension)) {
|
|
2080
|
+
return {
|
|
2081
|
+
kind: "docs-page",
|
|
2082
|
+
...baseResult,
|
|
2083
|
+
filePath: normalizeDocsFilePath(baseHref)
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
return {
|
|
2087
|
+
kind: "local-asset",
|
|
2088
|
+
...baseResult,
|
|
2089
|
+
extension,
|
|
2090
|
+
publishable: isPublishableStaticAssetPath(normalizedRootFilePath)
|
|
2091
|
+
};
|
|
2092
|
+
}
|
|
2093
|
+
var resolveDocsPageHref = resolveDocsHref;
|
|
2094
|
+
function addRoutableDocsFilePath(routableFilePaths, filePath) {
|
|
2095
|
+
if (typeof filePath !== "string") return;
|
|
2096
|
+
const normalizedFilePath = normalizeDocsFilePath(filePath);
|
|
2097
|
+
if (normalizedFilePath) {
|
|
2098
|
+
routableFilePaths.add(normalizedFilePath);
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
function collectRoutablePageItems(routableFilePaths, items) {
|
|
2102
|
+
if (!Array.isArray(items)) return;
|
|
2103
|
+
for (const item of items) {
|
|
2104
|
+
if (typeof item === "string") {
|
|
2105
|
+
addRoutableDocsFilePath(routableFilePaths, item);
|
|
2106
|
+
continue;
|
|
2107
|
+
}
|
|
2108
|
+
if (!item || typeof item !== "object") continue;
|
|
2109
|
+
if ("page" in item) {
|
|
2110
|
+
addRoutableDocsFilePath(routableFilePaths, item.page);
|
|
2111
|
+
continue;
|
|
2112
|
+
}
|
|
2113
|
+
if ("group" in item) {
|
|
2114
|
+
collectRoutablePageItems(
|
|
2115
|
+
routableFilePaths,
|
|
2116
|
+
item.pages
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
function collectRoutableNavigationPages(routableFilePaths, config) {
|
|
2122
|
+
collectRoutablePageItems(
|
|
2123
|
+
routableFilePaths,
|
|
2124
|
+
config.navigation.pages
|
|
2125
|
+
);
|
|
2126
|
+
for (const item of config.navigation.menu?.items ?? []) {
|
|
2127
|
+
collectRoutablePageItems(
|
|
2128
|
+
routableFilePaths,
|
|
2129
|
+
item.submenu.pages
|
|
2130
|
+
);
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
function buildDocsLinkIndex(config, files) {
|
|
2134
|
+
const allDocsFilePaths = /* @__PURE__ */ new Set();
|
|
2135
|
+
const routableDocsFilePaths = /* @__PURE__ */ new Set();
|
|
2136
|
+
for (const file of files) {
|
|
2137
|
+
const relativePath = path.relative(DOCS_DIR, file);
|
|
2138
|
+
const normalizedFilePath = normalizeDocsFilePath(relativePath);
|
|
2139
|
+
if (normalizedFilePath) {
|
|
2140
|
+
allDocsFilePaths.add(normalizedFilePath);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
collectRoutableNavigationPages(routableDocsFilePaths, config);
|
|
2144
|
+
addRoutableDocsFilePath(routableDocsFilePaths, config.home);
|
|
2145
|
+
for (const route of config.hiddenPageRoutes ?? []) {
|
|
2146
|
+
addRoutableDocsFilePath(routableDocsFilePaths, route.filePath);
|
|
2147
|
+
}
|
|
2148
|
+
return {
|
|
2149
|
+
allDocsFilePaths,
|
|
2150
|
+
routableDocsFilePaths
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
function validateDocsRootAbsoluteHref(args) {
|
|
2154
|
+
const resolvedHref = resolveDocsHref(args.href);
|
|
2155
|
+
if (resolvedHref.kind === "ignored") return;
|
|
2156
|
+
if (resolvedHref.kind === "invalid") {
|
|
2157
|
+
if (resolvedHref.reason === "not-root-absolute") {
|
|
2158
|
+
const suggestion = resolvedHref.suggestedHref ? ` Use "${resolvedHref.suggestedHref}" instead.` : "";
|
|
2159
|
+
throw new Error(
|
|
2160
|
+
`Invalid internal link "${args.href}" in ${args.sourceFile}. Docs page links must be docs-root absolute paths like "/guides/quickstart".${suggestion}`
|
|
2161
|
+
);
|
|
2162
|
+
}
|
|
2163
|
+
if (resolvedHref.reason === "generated-route") {
|
|
2164
|
+
throw new Error(
|
|
2165
|
+
`Invalid internal link "${args.href}" in ${args.sourceFile}. Docs page links must point to MDX source paths from the docs root, not generated HTML routes. Use a path like "/guides/quickstart" or "/guides/quickstart.mdx".`
|
|
2166
|
+
);
|
|
2167
|
+
}
|
|
2168
|
+
if (resolvedHref.reason === "path-traversal") {
|
|
2169
|
+
throw new Error(
|
|
2170
|
+
`Invalid local URL "${args.href}" in ${args.sourceFile}. Local URLs cannot contain ".." path traversal segments.`
|
|
2171
|
+
);
|
|
2172
|
+
}
|
|
2173
|
+
throw new Error(
|
|
2174
|
+
`Invalid internal link "${args.href}" in ${args.sourceFile}. Docs page links must point to a docs page file from the docs root, such as "/guides/quickstart".`
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
if (resolvedHref.kind === "local-asset") {
|
|
2178
|
+
const fullAssetPath = path.join(DOCS_DIR, resolvedHref.filePath);
|
|
2179
|
+
if (!fs.existsSync(fullAssetPath) || !fs.statSync(fullAssetPath).isFile()) {
|
|
2180
|
+
throw new Error(
|
|
2181
|
+
`Invalid local asset "${args.href}" in ${args.sourceFile}. No matching file was found. Expected "${resolvedHref.filePath}" under the docs root.`
|
|
2182
|
+
);
|
|
2183
|
+
}
|
|
2184
|
+
if (!resolvedHref.publishable) {
|
|
2185
|
+
throw new Error(
|
|
2186
|
+
`Invalid local asset "${args.href}" in ${args.sourceFile}. Files with extension "${resolvedHref.extension}" are not published as docs assets.`
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
if (args.expectedTarget === "asset") {
|
|
2192
|
+
throw new Error(
|
|
2193
|
+
`Invalid local asset "${args.href}" in ${args.sourceFile}. Asset references must include a supported file extension.`
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
if (args.linkIndex.routableDocsFilePaths.has(resolvedHref.filePath)) {
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
if (args.linkIndex.allDocsFilePaths.has(resolvedHref.filePath)) {
|
|
2200
|
+
throw new Error(
|
|
2201
|
+
`Invalid internal link "${args.href}" in ${args.sourceFile}. The target file exists ("${resolvedHref.filePath}.mdx"), but it is not a routable docs page. Add it to docs.json navigation, set it as the home page, or link to it from the navbar or footer so it is included in the built site.`
|
|
2202
|
+
);
|
|
2203
|
+
}
|
|
2204
|
+
throw new Error(
|
|
2205
|
+
`Invalid internal link "${args.href}" in ${args.sourceFile}. No matching docs page file was found. Expected "${resolvedHref.filePath}.mdx" under the docs root.`
|
|
2206
|
+
);
|
|
2207
|
+
}
|
|
2208
|
+
function visitMdxTree(node, visitor) {
|
|
2209
|
+
if (!node || typeof node !== "object") return;
|
|
2210
|
+
const typedNode = node;
|
|
2211
|
+
visitor(node);
|
|
2212
|
+
if (!Array.isArray(typedNode.children)) return;
|
|
2213
|
+
for (const child of typedNode.children) {
|
|
2214
|
+
visitMdxTree(child, visitor);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
function createInternalLinkValidationPlugin(args) {
|
|
2218
|
+
return () => (tree) => {
|
|
2219
|
+
visitMdxTree(tree, (node) => {
|
|
2220
|
+
if ((node.type === "link" || node.type === "definition") && typeof node.url === "string") {
|
|
2221
|
+
validateDocsRootAbsoluteHref({
|
|
2222
|
+
href: node.url,
|
|
2223
|
+
sourceFile: args.sourceFile,
|
|
2224
|
+
linkIndex: args.linkIndex,
|
|
2225
|
+
expectedTarget: "link"
|
|
2226
|
+
});
|
|
2227
|
+
}
|
|
2228
|
+
if (node.type === "image" && typeof node.url === "string") {
|
|
2229
|
+
validateDocsRootAbsoluteHref({
|
|
2230
|
+
href: node.url,
|
|
2231
|
+
sourceFile: args.sourceFile,
|
|
2232
|
+
linkIndex: args.linkIndex,
|
|
2233
|
+
expectedTarget: "asset"
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
if (node.type !== "mdxJsxFlowElement" && node.type !== "mdxJsxTextElement") {
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
const element = node;
|
|
2240
|
+
if (!Array.isArray(element.attributes)) return;
|
|
2241
|
+
for (const attribute of element.attributes) {
|
|
2242
|
+
const hrefAttribute = attribute;
|
|
2243
|
+
if (hrefAttribute.type !== "mdxJsxAttribute") continue;
|
|
2244
|
+
if (hrefAttribute.name !== "href" && hrefAttribute.name !== "src") {
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
if (typeof hrefAttribute.value !== "string") continue;
|
|
2248
|
+
validateDocsRootAbsoluteHref({
|
|
2249
|
+
href: hrefAttribute.value,
|
|
2250
|
+
sourceFile: args.sourceFile,
|
|
2251
|
+
linkIndex: args.linkIndex,
|
|
2252
|
+
expectedTarget: hrefAttribute.name === "src" ? "asset" : "link"
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
2255
|
+
});
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
1978
2258
|
function getMdxFiles(dir) {
|
|
1979
2259
|
let results = [];
|
|
1980
2260
|
const list = fs.readdirSync(dir);
|
|
@@ -1983,7 +2263,7 @@ function getMdxFiles(dir) {
|
|
|
1983
2263
|
const stat = fs.statSync(file);
|
|
1984
2264
|
if (stat && stat.isDirectory()) {
|
|
1985
2265
|
results = results.concat(getMdxFiles(file));
|
|
1986
|
-
} else if (
|
|
2266
|
+
} else if (/\.(md|mdx)$/i.test(file)) {
|
|
1987
2267
|
results.push(file);
|
|
1988
2268
|
}
|
|
1989
2269
|
});
|
|
@@ -1991,8 +2271,11 @@ function getMdxFiles(dir) {
|
|
|
1991
2271
|
}
|
|
1992
2272
|
async function validateMdxContent() {
|
|
1993
2273
|
assertConfigured();
|
|
2274
|
+
const config = await getConfig();
|
|
1994
2275
|
const files = getMdxFiles(DOCS_DIR);
|
|
2276
|
+
const linkIndex = buildDocsLinkIndex(config, files);
|
|
1995
2277
|
for (const file of files) {
|
|
2278
|
+
const relativePath = path.relative(DOCS_DIR, file);
|
|
1996
2279
|
try {
|
|
1997
2280
|
const content = fs.readFileSync(file, "utf-8");
|
|
1998
2281
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -2008,9 +2291,16 @@ async function validateMdxContent() {
|
|
|
2008
2291
|
}
|
|
2009
2292
|
}
|
|
2010
2293
|
validateComponentUsage(content);
|
|
2011
|
-
await compile(content, {
|
|
2294
|
+
await compile(content, {
|
|
2295
|
+
jsx: true,
|
|
2296
|
+
remarkPlugins: [
|
|
2297
|
+
createInternalLinkValidationPlugin({
|
|
2298
|
+
sourceFile: relativePath,
|
|
2299
|
+
linkIndex
|
|
2300
|
+
})
|
|
2301
|
+
]
|
|
2302
|
+
});
|
|
2012
2303
|
} catch (e) {
|
|
2013
|
-
const relativePath = path.relative(DOCS_DIR, file);
|
|
2014
2304
|
const location = e.line ? `:${e.line}:${e.column}` : "";
|
|
2015
2305
|
const reason = e.reason || e.message;
|
|
2016
2306
|
throw new Error(
|
|
@@ -2025,11 +2315,15 @@ export {
|
|
|
2025
2315
|
DEFAULT_SHIKI_LIGHT_THEME,
|
|
2026
2316
|
DEFAULT_THEME_COLOR_DARK,
|
|
2027
2317
|
DEFAULT_THEME_COLOR_LIGHT,
|
|
2318
|
+
PUBLISHABLE_STATIC_ASSET_EXTENSIONS,
|
|
2028
2319
|
SHIKI_BUNDLED_THEME_NAMES,
|
|
2029
2320
|
configureDocsValidator,
|
|
2030
2321
|
docsSchema,
|
|
2031
2322
|
getConfig,
|
|
2032
2323
|
isBundledShikiThemeName,
|
|
2324
|
+
isPublishableStaticAssetPath,
|
|
2033
2325
|
loadOpenApiSpec,
|
|
2326
|
+
resolveDocsHref,
|
|
2327
|
+
resolveDocsPageHref,
|
|
2034
2328
|
validateMdxContent
|
|
2035
2329
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "radiant-docs-validator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Shared validation for Radiant documentation repositories",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsup src/index.ts src/frontmatter-schema.ts src/shiki-theme-config.ts --format esm --dts --clean",
|
|
8
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
8
9
|
"prepublishOnly": "npm run build",
|
|
9
10
|
"release": "node scripts/release.js"
|
|
10
11
|
},
|