rspress-plugin-api-extractor 0.8.8 → 0.9.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.
Files changed (53) hide show
  1. package/README.md +11 -11
  2. package/api-extracted-package.js +1 -1
  3. package/build-program.js +3 -3
  4. package/build-stages.js +30 -31
  5. package/config-helpers.js +61 -21
  6. package/errors.js +1 -7
  7. package/frontmatter.js +149 -0
  8. package/index.d.ts +11 -2
  9. package/layers/ConfigServiceLive.js +53 -39
  10. package/layers/TypeRegistryServiceLive.js +11 -6
  11. package/markdown/helpers.js +40 -69
  12. package/markdown/index.js +2 -2
  13. package/markdown/page-generators/class-page.js +40 -42
  14. package/markdown/page-generators/enum-page.js +15 -15
  15. package/markdown/page-generators/function-page.js +18 -20
  16. package/markdown/page-generators/interface-page.js +41 -43
  17. package/markdown/page-generators/namespace-page.js +22 -24
  18. package/markdown/page-generators/type-alias-page.js +14 -16
  19. package/markdown/page-generators/variable-page.js +14 -16
  20. package/markdown/prose-linker.js +22 -0
  21. package/model-loader.js +59 -113
  22. package/package.json +14 -8
  23. package/plugin.js +1 -5
  24. package/runtime/components/EnumMembersTable/index.css +18 -18
  25. package/runtime/components/EnumMembersTable/index.module.js +3 -3
  26. package/runtime/components/ExampleBlock/index.css +2 -2
  27. package/runtime/components/ExampleBlock/index.module.js +2 -2
  28. package/runtime/components/MemberSignature/index.css +6 -6
  29. package/runtime/components/MemberSignature/index.module.js +4 -4
  30. package/runtime/components/ParametersTable/index.css +19 -19
  31. package/runtime/components/ParametersTable/index.module.js +3 -3
  32. package/runtime/components/SignatureBlock/index.css +6 -6
  33. package/runtime/components/SignatureBlock/index.module.js +4 -4
  34. package/runtime/components/SignatureCode/index.css +9 -9
  35. package/runtime/components/SignatureCode/index.module.js +3 -3
  36. package/runtime/components/SignatureToolbar/index.css +18 -18
  37. package/runtime/components/SignatureToolbar/index.module.js +7 -7
  38. package/runtime/components/buttons/index.css +5 -5
  39. package/runtime/components/buttons/index.module.js +2 -2
  40. package/shiki-transformer.js +3 -3
  41. package/sync-node-fs.js +80 -0
  42. package/tsdoc-metadata.json +1 -1
  43. package/twoslash-transformer.js +1 -1
  44. package/content-hash.js +0 -79
  45. package/formatter.js +0 -69
  46. package/layers/SnapshotServiceLive.js +0 -92
  47. package/loader.js +0 -200
  48. package/markdown/cross-linker.js +0 -157
  49. package/migrations/001_create_snapshots.js +0 -25
  50. package/multi-entry-resolver.js +0 -70
  51. package/route-collisions.js +0 -44
  52. package/services/SnapshotService.js +0 -7
  53. package/synthetic-bases.js +0 -74
@@ -1,44 +0,0 @@
1
- //#region src/route-collisions.ts
2
- /**
3
- * Group candidates by their final route (`${folder}/${baseName}`) and return the
4
- * groups with more than one distinct item. The route key is the lowercased path
5
- * the file is written to, so detection matches generation (and what a
6
- * case-insensitive filesystem would merge). Companion pairs (same name, different
7
- * folders) land under different keys and are never collisions.
8
- *
9
- * Output is deterministic: collisions ordered by route, items within a collision
10
- * ordered by canonicalReference.
11
- */
12
- function detectRouteCollisions(candidates) {
13
- const byKey = /* @__PURE__ */ new Map();
14
- for (const candidate of candidates) {
15
- const key = `${candidate.folder}/${candidate.baseName}`;
16
- const group = byKey.get(key) ?? [];
17
- group.push(candidate);
18
- byKey.set(key, group);
19
- }
20
- const collisions = [];
21
- for (const [route, group] of byKey) if (group.length > 1) {
22
- const items = [...group].sort((a, b) => a.canonicalRef < b.canonicalRef ? -1 : a.canonicalRef > b.canonicalRef ? 1 : 0);
23
- collisions.push({
24
- route,
25
- items
26
- });
27
- }
28
- collisions.sort((a, b) => a.route < b.route ? -1 : a.route > b.route ? 1 : 0);
29
- return collisions;
30
- }
31
- /** Build an actionable build-time error message for one or more route collisions. */
32
- function formatRouteCollisionError(collisions, baseRoute) {
33
- const lines = [];
34
- for (const collision of collisions) {
35
- lines.push(`Route collision: ${collision.items.length} API items resolve to the same documentation path "${baseRoute}/${collision.route}":`);
36
- for (const item of collision.items) lines.push(` - ${item.displayName} (${item.kind}) [${item.canonicalRef}]`);
37
- }
38
- lines.push("");
39
- lines.push("Item names must be unique per category folder. Paths are lowercased, so names differing only in case collide. Rename one of the items, or configure categories so they map to different folders.");
40
- return `[rspress-plugin-api-extractor] ${lines.join("\n")}`;
41
- }
42
-
43
- //#endregion
44
- export { detectRouteCollisions, formatRouteCollisionError };
@@ -1,7 +0,0 @@
1
- import { Context } from "effect";
2
-
3
- //#region src/services/SnapshotService.ts
4
- var SnapshotService = class extends Context.Service()("rspress-plugin-api-extractor/SnapshotService") {};
5
-
6
- //#endregion
7
- export { SnapshotService };
@@ -1,74 +0,0 @@
1
- import { ApiExportedMixin, ApiItemKind, ExcerptTokenKind } from "@microsoft/api-extractor-model";
2
-
3
- //#region src/synthetic-bases.ts
4
- /**
5
- * Anchor id of the inline "Base Class" section rendered on the owner class
6
- * page. Must match the slug RSPress derives from the `## Base Class` heading
7
- * emitted by ClassPageGenerator.
8
- */
9
- const BASE_CLASS_ANCHOR = "base-class";
10
- const EMPTY_DETECTION = {
11
- bases: /* @__PURE__ */ new Map(),
12
- baseByOwner: /* @__PURE__ */ new Map()
13
- };
14
- /**
15
- * Strip the trailing meaning (`:class`, `:var`, `:function(1)`, ...) from a
16
- * canonical reference string so the reference token in an extends clause
17
- * (`example!~Person_base`) matches the declaration's canonical reference
18
- * (`example!~Person_base:var`).
19
- */
20
- function stripMeaning(canonicalRef) {
21
- return canonicalRef.replace(/:[a-z]+(\(\d+\))?$/i, "");
22
- }
23
- /** True when the item carries ApiExportedMixin and is NOT exported from its entry point. */
24
- function isUnexported(item) {
25
- return ApiExportedMixin.isBaseClassOf(item) && !item.isExported;
26
- }
27
- /**
28
- * Detect synthetic base declarations among top-level API items.
29
- *
30
- * An item qualifies when it is unexported (hoisted into the model only because
31
- * something references it) AND at least one class's extends clause references
32
- * its canonical symbol. Unexported items with no class referencing them
33
- * (genuine forgotten exports) are left alone, as are extends references whose
34
- * target is absent from the model.
35
- */
36
- function detectSyntheticBases(items) {
37
- const unexportedByRef = /* @__PURE__ */ new Map();
38
- for (const item of items) {
39
- if (!isUnexported(item)) continue;
40
- const ref = item.canonicalReference?.toString();
41
- if (ref) unexportedByRef.set(stripMeaning(ref), item);
42
- }
43
- if (unexportedByRef.size === 0) return EMPTY_DETECTION;
44
- const owners = /* @__PURE__ */ new Map();
45
- const baseByOwner = /* @__PURE__ */ new Map();
46
- for (const item of items) {
47
- if (item.kind !== ApiItemKind.Class) continue;
48
- const apiClass = item;
49
- const extendsType = apiClass.extendsType;
50
- if (!extendsType) continue;
51
- for (const token of extendsType.excerpt.spannedTokens) {
52
- if (token.kind !== ExcerptTokenKind.Reference || !token.canonicalReference) continue;
53
- const base = unexportedByRef.get(stripMeaning(token.canonicalReference.toString()));
54
- if (!base || base === item || baseByOwner.has(item)) continue;
55
- baseByOwner.set(item, base);
56
- const ownerList = owners.get(base);
57
- if (ownerList) ownerList.push(apiClass);
58
- else owners.set(base, [apiClass]);
59
- }
60
- }
61
- if (owners.size === 0) return EMPTY_DETECTION;
62
- const bases = /* @__PURE__ */ new Map();
63
- for (const [baseItem, ownerClasses] of owners) bases.set(baseItem, {
64
- baseItem,
65
- ownerClasses
66
- });
67
- return {
68
- bases,
69
- baseByOwner
70
- };
71
- }
72
-
73
- //#endregion
74
- export { BASE_CLASS_ANCHOR, detectSyntheticBases };