rspress-plugin-api-extractor 0.5.0 → 0.6.1

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/README.md CHANGED
@@ -42,7 +42,7 @@ npx rspress dev
42
42
  # Generates one MDX page per public API item and serves them at http://localhost:3000
43
43
  ```
44
44
 
45
- The plugin reads your `.api.json` model and writes one MDX page per public API item under your docs root, grouped into category folders (classes, interfaces, functions, type aliases, enums, variables and namespaces) with navigation metadata. To produce the model, pair it with [@savvy-web/rslib-builder](https://github.com/savvy-web/rslib-builder), which emits the `.api.json` as part of your TypeScript build.
45
+ The plugin reads your `.api.json` model and writes one MDX page per public API item under your docs root, grouped into category folders (classes, interfaces, functions, type aliases, enums, variables and namespaces) with navigation metadata. To produce the model, pair it with [@savvy-web/bundler](https://github.com/savvy-web/bundler), which emits the `.api.json` as part of your production TypeScript build.
46
46
 
47
47
  ## Features
48
48
 
@@ -2,7 +2,6 @@ import { ApiItemKind, ApiModel, ExcerptTokenKind } from "@microsoft/api-extracto
2
2
  import { VirtualPackage } from "type-registry-effect";
3
3
 
4
4
  //#region src/api-extracted-package.ts
5
- const VirtualPackageClass = VirtualPackage.VirtualPackage;
6
5
  /**
7
6
  * Reconstructs TypeScript declaration files from an API Extractor model.
8
7
  *
@@ -12,10 +11,14 @@ const VirtualPackageClass = VirtualPackage.VirtualPackage;
12
11
  *
13
12
  * Use the factory methods {@link fromApiModel} or {@link fromPackage} to create instances.
14
13
  */
15
- var ApiExtractedPackage = class ApiExtractedPackage extends VirtualPackageClass {
14
+ var ApiExtractedPackage = class ApiExtractedPackage extends VirtualPackage {
16
15
  apiPackage;
17
16
  constructor(apiPackage, packageName, entries) {
18
- super(packageName, "1.0.0", entries);
17
+ super({
18
+ name: packageName,
19
+ version: "1.0.0",
20
+ entries
21
+ });
19
22
  this.apiPackage = apiPackage;
20
23
  }
21
24
  /**
@@ -29,14 +32,23 @@ var ApiExtractedPackage = class ApiExtractedPackage extends VirtualPackageClass
29
32
  * Create an ApiExtractedPackage from an existing ApiPackage instance.
30
33
  */
31
34
  static fromPackage(apiPackage, packageName) {
32
- const tempEntries = /* @__PURE__ */ new Map();
33
- const tempInstance = new ApiExtractedPackage(apiPackage, packageName, tempEntries);
35
+ const scratch = new ApiExtractedPackage(apiPackage, packageName, /* @__PURE__ */ new Map([["index.d.ts", ""]]));
36
+ const entries = /* @__PURE__ */ new Map();
34
37
  for (const ep of apiPackage.entryPoints) {
35
- const entryName = tempInstance.getEntryPointName(ep);
38
+ const entryName = scratch.getEntryPointName(ep);
36
39
  const fileName = entryName ? `${entryName}.d.ts` : "index.d.ts";
37
- tempEntries.set(fileName, tempInstance.generateDeclarations(ep));
40
+ entries.set(fileName, scratch.generateDeclarations(ep));
38
41
  }
39
- return tempInstance;
42
+ return new ApiExtractedPackage(apiPackage, packageName, entries);
43
+ }
44
+ /**
45
+ * Generate the VFS map for this package (`node_modules/<name>/...`).
46
+ *
47
+ * Delegates to the v2 {@link VirtualPackage.toVfs}; kept under the v1 name
48
+ * because the config layer and tests consume it as `generateVfs()`.
49
+ */
50
+ generateVfs() {
51
+ return this.toVfs();
40
52
  }
41
53
  /**
42
54
  * Generate the .d.ts content for a specific entry point.
package/build-program.js CHANGED
@@ -6,8 +6,7 @@ import { withPhase } from "./observability/spans.js";
6
6
  import { TwoslashManager } from "./twoslash-transformer.js";
7
7
  import { VfsRegistry } from "./vfs-registry.js";
8
8
  import path from "node:path";
9
- import { Effect } from "effect";
10
- import { FileSystem } from "@effect/platform";
9
+ import { Effect, FileSystem } from "effect";
11
10
 
12
11
  //#region src/build-program.ts
13
12
  /**
package/build-stages.js CHANGED
@@ -20,8 +20,7 @@ import { assertNoRouteCollisions } from "./route-collisions.js";
20
20
  import { SnapshotService } from "./services/SnapshotService.js";
21
21
  import { BASE_CLASS_ANCHOR, detectSyntheticBases } from "./synthetic-bases.js";
22
22
  import path from "node:path";
23
- import { Effect, Metric, Stream } from "effect";
24
- import { FileSystem } from "@effect/platform";
23
+ import { Effect, FileSystem, Metric, Stream } from "effect";
25
24
  import { ApiItemKind } from "@microsoft/api-extractor-model";
26
25
  import matter from "gray-matter";
27
26
 
@@ -559,11 +558,11 @@ function writeMetadata(input) {
559
558
  const indexDirPath = path.dirname(indexAbsolutePath);
560
559
  yield* fileSystem.makeDirectory(indexDirPath, { recursive: true }).pipe(Effect.orDie);
561
560
  yield* fileSystem.writeFileString(indexAbsolutePath, mainIndex.content).pipe(Effect.orDie);
562
- yield* Metric.increment(BuildMetrics.filesTotal);
563
- yield* Metric.increment(BuildMetrics.filesNew);
561
+ yield* Metric.update(BuildMetrics.filesTotal, 1);
562
+ yield* Metric.update(BuildMetrics.filesNew, 1);
564
563
  } else {
565
- yield* Metric.increment(BuildMetrics.filesTotal);
566
- yield* Metric.increment(BuildMetrics.filesUnchanged);
564
+ yield* Metric.update(BuildMetrics.filesTotal, 1);
565
+ yield* Metric.update(BuildMetrics.filesUnchanged, 1);
567
566
  }
568
567
  generatedFiles.add("index.mdx");
569
568
  const categoryMetaEntriesMap = /* @__PURE__ */ new Map();
@@ -765,7 +764,7 @@ function buildPipelineForApi(input) {
765
764
  ...input.packageName != null ? { packageName: input.packageName } : {},
766
765
  ...input.apiName != null ? { apiName: input.apiName } : {}
767
766
  };
768
- return Stream.fromIterable(input.workItems).pipe(Stream.mapEffect((workItem) => generateSinglePage(workItem, generateCtx), { concurrency: input.pageConcurrency }), Stream.filter((result) => result !== null), Stream.mapEffect((result) => writeSingleFile(result, writeCtx), { concurrency: input.pageConcurrency }), Stream.runFold([], (acc, result) => [...acc, result]));
767
+ return Stream.fromIterable(input.workItems).pipe(Stream.mapEffect((workItem) => generateSinglePage(workItem, generateCtx), { concurrency: input.pageConcurrency }), Stream.filter((result) => result !== null), Stream.mapEffect((result) => writeSingleFile(result, writeCtx), { concurrency: input.pageConcurrency }), Stream.runFold(() => [], (acc, result) => [...acc, result]));
769
768
  }
770
769
 
771
770
  //#endregion
package/config-helpers.js CHANGED
@@ -52,17 +52,14 @@ function resolveBaseRoute(baseRoute, info) {
52
52
  function fromDir(dir, overrides = {}) {
53
53
  const { baseRoute, cwd, ...rest } = overrides;
54
54
  const info = discoverDir(path.resolve(cwd ?? process.cwd(), dir));
55
- const discovered = {
55
+ const tsconfigPath = path.join(info.dir, "tsconfig.json");
56
+ return {
56
57
  packageName: info.packageName,
57
58
  name: info.packageName,
58
59
  model: info.modelPath,
59
- packageJson: path.join(info.dir, "package.json")
60
- };
61
- if (baseRoute !== void 0) discovered.baseRoute = resolveBaseRoute(baseRoute, info);
62
- const tsconfigPath = path.join(info.dir, "tsconfig.json");
63
- if (fs.existsSync(tsconfigPath)) discovered.tsconfig = tsconfigPath;
64
- return {
65
- ...discovered,
60
+ packageJson: path.join(info.dir, "package.json"),
61
+ ...baseRoute !== void 0 ? { baseRoute: resolveBaseRoute(baseRoute, info) } : {},
62
+ ...fs.existsSync(tsconfigPath) ? { tsconfig: tsconfigPath } : {},
66
63
  ...rest
67
64
  };
68
65
  }
package/config-utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import { SemVer } from "semver-effect";
2
+ import { SemVer } from "@effected/semver";
3
3
 
4
4
  //#region src/config-utils.ts
5
5
  /**
@@ -146,7 +146,7 @@ function extractAutoDetectedPackages(packageJson, options = {}) {
146
146
  }
147
147
  /**
148
148
  * Deduplicate external packages by name, resolving to the highest version when conflicts exist.
149
- * Uses semver-effect to pick the highest version from duplicates.
149
+ * Uses @effected/semver to pick the highest version from duplicates.
150
150
  *
151
151
  * @param packages - Array of external package specs (may contain duplicates)
152
152
  * @returns Deduplicated array with highest versions
@@ -211,7 +211,7 @@ function resolveExternalPackageVersions(packages, resolve) {
211
211
  return Effect.forEach(packages, (pkg) => resolve(pkg).pipe(Effect.map((version) => ({
212
212
  name: pkg.name,
213
213
  version
214
- })), Effect.catchAll(() => Effect.succeed(null))), { concurrency: 5 }).pipe(Effect.map((results) => results.filter((spec) => spec !== null)));
214
+ })), Effect.catch(() => Effect.succeed(null))), { concurrency: 5 }).pipe(Effect.map((results) => results.filter((spec) => spec !== null)));
215
215
  }
216
216
  /**
217
217
  * Strip range prefixes from a version string to get a clean semver.
@@ -220,7 +220,7 @@ function stripRangePrefix(version) {
220
220
  return version.replace(/^[~^>=<]+\s*/, "");
221
221
  }
222
222
  /**
223
- * Find the highest version from a list of version specifiers using semver-effect.
223
+ * Find the highest version from a list of version specifiers using @effected/semver.
224
224
  * Handles version ranges and exact versions.
225
225
  *
226
226
  * @param versions - Array of version strings (can be ranges or exact versions)