rspress-plugin-api-extractor 0.7.5 → 0.8.0
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/config-utils.js +10 -1
- package/index.d.ts +12 -6
- package/layers/ConfigServiceLive.js +10 -10
- package/package.json +1 -1
- package/plugin.js +6 -5
- package/schemas/config.js +10 -4
package/config-utils.js
CHANGED
|
@@ -15,6 +15,15 @@ function isLoadedModel(result) {
|
|
|
15
15
|
return typeof result === "object" && result !== null && "model" in result;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
+
* Classify the `api` / `apis` options. Callers use `disabled` to skip doc
|
|
19
|
+
* generation without failing the build, and `missing` to fail it.
|
|
20
|
+
*/
|
|
21
|
+
function classifyApiConfig(options) {
|
|
22
|
+
if (options.api != null) return "configured";
|
|
23
|
+
if (options.apis != null && options.apis.length > 0) return "configured";
|
|
24
|
+
return options.api !== void 0 || options.apis !== void 0 ? "disabled" : "missing";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
18
27
|
* Normalize llmsPlugin config to always be an LlmsPlugin object
|
|
19
28
|
*/
|
|
20
29
|
function normalizeLlmsPluginConfig(config) {
|
|
@@ -284,4 +293,4 @@ function validateExternalPackages(externalPackages, packageJson) {
|
|
|
284
293
|
}
|
|
285
294
|
|
|
286
295
|
//#endregion
|
|
287
|
-
export { extractAutoDetectedPackages, extractPeerDependencies, extractTypeUtilities, isLoadedModel, isVersionConfig, mergeLlmsPluginConfig, normalizeLlmsPluginConfig, resolveExternalPackageVersions, resolvePackageVersionConflicts, validateExternalPackages };
|
|
296
|
+
export { classifyApiConfig, extractAutoDetectedPackages, extractPeerDependencies, extractTypeUtilities, isLoadedModel, isVersionConfig, mergeLlmsPluginConfig, normalizeLlmsPluginConfig, resolveExternalPackageVersions, resolvePackageVersionConflicts, validateExternalPackages };
|
package/index.d.ts
CHANGED
|
@@ -398,11 +398,17 @@ type MultiApiConfig = typeof MultiApiConfig.Encoded;
|
|
|
398
398
|
/**
|
|
399
399
|
* Top-level options passed to {@link ApiExtractorPlugin}.
|
|
400
400
|
*
|
|
401
|
+
* @remarks
|
|
402
|
+
* Supplying `api: null`, `apis: null` or `apis: []` opts into an inert plugin:
|
|
403
|
+
* the options are validated but no documentation is generated. This lets a site
|
|
404
|
+
* pre-configure the plugin before any API model exists. Omitting both keys
|
|
405
|
+
* entirely is still a configuration error.
|
|
406
|
+
*
|
|
401
407
|
* @public
|
|
402
408
|
*/
|
|
403
409
|
declare const PluginOptions: Schema.Struct<{
|
|
404
|
-
/** Single-API configuration (mutually exclusive with `apis`). */
|
|
405
|
-
readonly api: Schema.optional<Schema.Struct<{
|
|
410
|
+
/** Single-API configuration (mutually exclusive with `apis`). `null` disables generation. */
|
|
411
|
+
readonly api: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
406
412
|
/** npm package name of the documented package. */
|
|
407
413
|
readonly packageName: Schema.String;
|
|
408
414
|
/** Optional display name shown in the sidebar and page titles. */
|
|
@@ -553,9 +559,9 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
553
559
|
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
554
560
|
/** TypeScript compiler options for Twoslash. */
|
|
555
561
|
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
556
|
-
}
|
|
557
|
-
/** Multi-API portal configuration (mutually exclusive with `api`). */
|
|
558
|
-
readonly apis: Schema.optional<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
562
|
+
}>>>;
|
|
563
|
+
/** Multi-API portal configuration (mutually exclusive with `api`). `null` or `[]` disables generation. */
|
|
564
|
+
readonly apis: Schema.optional<Schema.NullOr<Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
559
565
|
/** npm package name of the documented package. */
|
|
560
566
|
readonly packageName: Schema.String;
|
|
561
567
|
/** Optional display name shown in the sidebar and page titles. */
|
|
@@ -646,7 +652,7 @@ declare const PluginOptions: Schema.Struct<{
|
|
|
646
652
|
readonly tsconfig: Schema.optional<Schema.declare<string | URL | ((...args: Array<unknown>) => unknown), string | URL | ((...args: Array<unknown>) => unknown)>>;
|
|
647
653
|
/** TypeScript compiler options for Twoslash. First API wins, as with `tsconfig`. */
|
|
648
654
|
readonly compilerOptions: Schema.optional<Schema.Unknown>;
|
|
649
|
-
}
|
|
655
|
+
}>>>>>;
|
|
650
656
|
/** Canonical site URL used for Open Graph absolute URLs. */
|
|
651
657
|
readonly siteUrl: Schema.optional<Schema.String>;
|
|
652
658
|
/** Global Open Graph image configuration (overridden per-API). */
|
|
@@ -8,7 +8,7 @@ import { OpenGraphResolver } from "../og-resolver.js";
|
|
|
8
8
|
import { withPhase } from "../observability/spans.js";
|
|
9
9
|
import { resolveTypeScriptConfig } from "../typescript-config.js";
|
|
10
10
|
import { TwoslashManager } from "../twoslash-transformer.js";
|
|
11
|
-
import { extractAutoDetectedPackages, isVersionConfig, mergeLlmsPluginConfig, validateExternalPackages } from "../config-utils.js";
|
|
11
|
+
import { classifyApiConfig, extractAutoDetectedPackages, isVersionConfig, mergeLlmsPluginConfig, validateExternalPackages } from "../config-utils.js";
|
|
12
12
|
import { ApiExtractedPackage } from "../api-extracted-package.js";
|
|
13
13
|
import { CategoryResolver } from "../category-resolver.js";
|
|
14
14
|
import { ConfigValidationError } from "../errors.js";
|
|
@@ -94,21 +94,21 @@ function prependImportsToVfs(vfs, apiPackage, packageName, wantTrace) {
|
|
|
94
94
|
*/
|
|
95
95
|
function validateOptions(options, rspressConfig) {
|
|
96
96
|
return Effect.gen(function* () {
|
|
97
|
-
const
|
|
97
|
+
const api = options.api ?? void 0;
|
|
98
|
+
const apis = options.apis != null && options.apis.length > 0 ? options.apis : void 0;
|
|
98
99
|
const { multiVersion } = rspressConfig;
|
|
99
100
|
if (api && apis) return yield* new ConfigValidationError({
|
|
100
101
|
field: "api/apis",
|
|
101
102
|
reason: "Cannot provide both 'api' and 'apis'. Use 'api' for single-package sites or 'apis' for multi-package portals."
|
|
102
103
|
});
|
|
103
|
-
if (!api && !apis)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (apis) {
|
|
108
|
-
if (apis.length === 0) return yield* new ConfigValidationError({
|
|
109
|
-
field: "apis",
|
|
110
|
-
reason: "'apis' must contain at least one API configuration."
|
|
104
|
+
if (!api && !apis) {
|
|
105
|
+
if (classifyApiConfig(options) === "missing") return yield* new ConfigValidationError({
|
|
106
|
+
field: "api/apis",
|
|
107
|
+
reason: "Must provide either 'api' or 'apis'."
|
|
111
108
|
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (apis) {
|
|
112
112
|
if (multiVersion) return yield* new ConfigValidationError({
|
|
113
113
|
field: "apis",
|
|
114
114
|
reason: "multiVersion is not supported with 'apis' (multi-API mode). Use 'api' (single-API mode) for versioned documentation."
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -12,7 +12,7 @@ import { VfsRegistry } from "./vfs-registry.js";
|
|
|
12
12
|
import { generateApiDocs } from "./build-program.js";
|
|
13
13
|
import { deriveOutputPaths, normalizeBaseRoute, unscopedName } from "./path-derivation.js";
|
|
14
14
|
import { fromDir, fromParentDir } from "./config-helpers.js";
|
|
15
|
-
import { mergeLlmsPluginConfig } from "./config-utils.js";
|
|
15
|
+
import { classifyApiConfig, mergeLlmsPluginConfig } from "./config-utils.js";
|
|
16
16
|
import { DEFAULT_SHIKI_THEMES, setShikiUtilsEventEmitter } from "./markdown/shiki-utils.js";
|
|
17
17
|
import { setModelLoaderEventEmitter } from "./model-loader.js";
|
|
18
18
|
import { resolveObservability } from "./schemas/observability.js";
|
|
@@ -73,6 +73,7 @@ function normalizeThemeConfig(theme) {
|
|
|
73
73
|
*/
|
|
74
74
|
function ApiExtractorPluginImpl(rawOptions) {
|
|
75
75
|
const options = Schema.decodeUnknownSync(PluginOptions)(rawOptions);
|
|
76
|
+
const isInert = classifyApiConfig(options) === "disabled";
|
|
76
77
|
const shikiCrossLinker = new ShikiCrossLinker();
|
|
77
78
|
const envLogLevel = process.env.LOG_LEVEL?.toLowerCase();
|
|
78
79
|
const buildId = `${process.pid}-${performance.now().toString(36)}`;
|
|
@@ -112,7 +113,7 @@ function ApiExtractorPluginImpl(rawOptions) {
|
|
|
112
113
|
name: "rspress-plugin-api-docs",
|
|
113
114
|
async beforeBuild(_config, _isProd) {},
|
|
114
115
|
async afterBuild(_config, isProd) {
|
|
115
|
-
if (isFirstBuild) {
|
|
116
|
+
if (isFirstBuild && !isInert) {
|
|
116
117
|
await effectRuntime.runPromise(logBuildSummary(obs.thresholds.slowCodeBlock));
|
|
117
118
|
if (isProd) await effectRuntime.runPromise(Effect.gen(function* () {
|
|
118
119
|
const packageName = yield* readSitePackageName;
|
|
@@ -183,7 +184,7 @@ function ApiExtractorPluginImpl(rawOptions) {
|
|
|
183
184
|
key: dep.key,
|
|
184
185
|
replacement: dep.replacement
|
|
185
186
|
}));
|
|
186
|
-
try {
|
|
187
|
+
if (!isInert) try {
|
|
187
188
|
const rspressConfigSubset = {
|
|
188
189
|
...rspressMultiVersion != null ? { multiVersion: rspressMultiVersion } : {},
|
|
189
190
|
...rspressLocales.length > 0 ? { locales: rspressLocales.map((lang) => ({ lang })) } : {},
|
|
@@ -253,7 +254,7 @@ function ApiExtractorPluginImpl(rawOptions) {
|
|
|
253
254
|
const updatedConfig = { ..._config };
|
|
254
255
|
if (!updatedConfig.builderConfig) updatedConfig.builderConfig = {};
|
|
255
256
|
if (!updatedConfig.builderConfig.source) updatedConfig.builderConfig.source = {};
|
|
256
|
-
if (rspressLlmsEnabled && resolvedLlmsPlugin.enabled && resolvedLlmsPlugin.scopes) {
|
|
257
|
+
if (!isInert && rspressLlmsEnabled && resolvedLlmsPlugin.enabled && resolvedLlmsPlugin.scopes) {
|
|
257
258
|
if (!updatedConfig.builderConfig.resolve) updatedConfig.builderConfig.resolve = {};
|
|
258
259
|
const pluginDir = path.dirname(fileURLToPath(import.meta.url));
|
|
259
260
|
const customLlmsViewOptions = path.resolve(pluginDir, "runtime/components/ApiLlmsViewOptions/index.js");
|
|
@@ -277,7 +278,7 @@ function ApiExtractorPluginImpl(rawOptions) {
|
|
|
277
278
|
theme: remarkTheme
|
|
278
279
|
}]);
|
|
279
280
|
updatedConfig.markdown.remarkPlugins.push([remarkApiCodeblocks]);
|
|
280
|
-
if (rspressLlmsEnabled && resolvedLlmsPlugin.enabled && resolvedLlmsPlugin.scopes) {
|
|
281
|
+
if (!isInert && rspressLlmsEnabled && resolvedLlmsPlugin.enabled && resolvedLlmsPlugin.scopes) {
|
|
281
282
|
packageRoutes.clear();
|
|
282
283
|
if (options.api) packageRoutes.set(options.api.packageName, normalizeBaseRoute(options.api.baseRoute ?? "/"));
|
|
283
284
|
else if (options.apis) for (const api of options.apis) packageRoutes.set(api.packageName, normalizeBaseRoute(api.baseRoute ?? `/${unscopedName(api.packageName)}`));
|
package/schemas/config.js
CHANGED
|
@@ -287,13 +287,19 @@ const MultiApiConfig = Schema.Struct({
|
|
|
287
287
|
/**
|
|
288
288
|
* Top-level options passed to {@link ApiExtractorPlugin}.
|
|
289
289
|
*
|
|
290
|
+
* @remarks
|
|
291
|
+
* Supplying `api: null`, `apis: null` or `apis: []` opts into an inert plugin:
|
|
292
|
+
* the options are validated but no documentation is generated. This lets a site
|
|
293
|
+
* pre-configure the plugin before any API model exists. Omitting both keys
|
|
294
|
+
* entirely is still a configuration error.
|
|
295
|
+
*
|
|
290
296
|
* @public
|
|
291
297
|
*/
|
|
292
298
|
const PluginOptions = Schema.Struct({
|
|
293
|
-
/** Single-API configuration (mutually exclusive with `apis`). */
|
|
294
|
-
api: Schema.optional(SingleApiConfig),
|
|
295
|
-
/** Multi-API portal configuration (mutually exclusive with `api`). */
|
|
296
|
-
apis: Schema.optional(Schema.mutable(Schema.Array(MultiApiConfig))),
|
|
299
|
+
/** Single-API configuration (mutually exclusive with `apis`). `null` disables generation. */
|
|
300
|
+
api: Schema.optional(Schema.NullOr(SingleApiConfig)),
|
|
301
|
+
/** Multi-API portal configuration (mutually exclusive with `api`). `null` or `[]` disables generation. */
|
|
302
|
+
apis: Schema.optional(Schema.NullOr(Schema.mutable(Schema.Array(MultiApiConfig)))),
|
|
297
303
|
/** Canonical site URL used for Open Graph absolute URLs. */
|
|
298
304
|
siteUrl: Schema.optional(Schema.String),
|
|
299
305
|
/** Global Open Graph image configuration (overridden per-API). */
|