rspress-plugin-api-extractor 0.18.12 → 0.19.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/package.json +3 -3
- package/services/OgService.js +28 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rspress-plugin-api-extractor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "RSPress plugin for generating API documentation from TypeScript API Extractor models",
|
|
6
6
|
"keywords": [
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"@effect/platform-node": "^4.0.2",
|
|
41
41
|
"@effected/github": "^0.15.1",
|
|
42
42
|
"@effected/glob": "^0.10.0",
|
|
43
|
+
"@effected/images": "^0.1.0",
|
|
43
44
|
"@effected/jsonc": "^0.15.1",
|
|
44
45
|
"@effected/markdown": "^0.15.1",
|
|
45
46
|
"@effected/memfs": "^0.14.0",
|
|
@@ -55,7 +56,7 @@
|
|
|
55
56
|
"@effected/yaml": "^0.19.1",
|
|
56
57
|
"@microsoft/api-extractor-model": "7.33.12",
|
|
57
58
|
"@shikijs/twoslash": "^4.5.0",
|
|
58
|
-
"@tsdoctor/bundle": "0.
|
|
59
|
+
"@tsdoctor/bundle": "0.6.0",
|
|
59
60
|
"@tsdoctor/manifest": "0.2.5",
|
|
60
61
|
"@tsdoctor/model": "0.8.6",
|
|
61
62
|
"@tsdoctor/pages": "0.3.7",
|
|
@@ -67,7 +68,6 @@
|
|
|
67
68
|
"clsx": "^2.1.1",
|
|
68
69
|
"effect": "^4.0.2",
|
|
69
70
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
70
|
-
"image-size": "^2.0.4",
|
|
71
71
|
"mdast-util-to-hast": "^13.2.1",
|
|
72
72
|
"open": "^11.0.0",
|
|
73
73
|
"prettier": "^3.9.9",
|
package/services/OgService.js
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import { PluginEvent } from "../observability/events.js";
|
|
2
2
|
import { emit } from "../observability/EventBus.js";
|
|
3
3
|
import { Context, Data, Effect, FileSystem, Layer, Option, Path } from "effect";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { resolveUrl } from "@tsdoctor/seo";
|
|
5
|
+
import { ImageFacts } from "@effected/images";
|
|
6
6
|
|
|
7
7
|
//#region src/services/OgService.ts
|
|
8
|
+
/**
|
|
9
|
+
* Resolving an API's configured Open Graph image into page metadata.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Replaces the `OpenGraphResolver` class, which did synchronous `node:fs` from
|
|
13
|
+
* inside `Effect.promise`, carried its own sync-island event emitter, and
|
|
14
|
+
* returned `undefined` for all three of its failure modes — indistinguishable
|
|
15
|
+
* from "no image was configured".
|
|
16
|
+
*
|
|
17
|
+
* This is also where phase 4's SEO work lands, which is why the contract is
|
|
18
|
+
* wider than today's single caller needs: it names its failures instead of
|
|
19
|
+
* erasing them.
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
8
23
|
const OgImageErrorBase = Data.TaggedError("OgImageError");
|
|
9
24
|
/**
|
|
10
25
|
* A configured OG image that could not be resolved.
|
|
11
26
|
*
|
|
12
27
|
* @remarks
|
|
13
|
-
* `cause` carries the original failure (an `
|
|
14
|
-
* filesystem error) rather than a stringified copy of it.
|
|
28
|
+
* `cause` carries the original failure (an `@effected/images`
|
|
29
|
+
* `ImageParseError`, a filesystem error) rather than a stringified copy of it.
|
|
15
30
|
*/
|
|
16
31
|
var OgImageError = class extends OgImageErrorBase {
|
|
17
32
|
get message() {
|
|
@@ -38,8 +53,10 @@ var OgService = class OgService extends Context.Service()("rspress-plugin-api-ex
|
|
|
38
53
|
* phase 4 starts GENERATING images, which are expensive and content-addressed,
|
|
39
54
|
* the XDG cache is the right home for them.
|
|
40
55
|
*
|
|
41
|
-
* `
|
|
42
|
-
* path and therefore required real `node:fs`.
|
|
56
|
+
* `ImageFacts.fromBytes` over the read bytes replaces `imageSizeFromFile`,
|
|
57
|
+
* which took a path and therefore required real `node:fs`. It reads PNG,
|
|
58
|
+
* JPEG, GIF, WebP and AVIF; anything else (SVG included) is an unreadable
|
|
59
|
+
* image, which warns and drops the dimensions.
|
|
43
60
|
*
|
|
44
61
|
* `Effect.suspend(() => make())` rather than a bare `make`: a static
|
|
45
62
|
* initializer runs while the module body is still evaluating, so naming a
|
|
@@ -85,7 +102,7 @@ const make = () => Effect.gen(function* () {
|
|
|
85
102
|
const readImageFacts = (filePath) => Effect.gen(function* () {
|
|
86
103
|
const memoed = factsByPath.get(filePath);
|
|
87
104
|
if (memoed !== void 0) return memoed;
|
|
88
|
-
const result = yield* Effect.result(fileSystem.readFile(filePath).pipe(Effect.flatMap(
|
|
105
|
+
const result = yield* Effect.result(fileSystem.readFile(filePath).pipe(Effect.flatMap(ImageFacts.fromBytes)));
|
|
89
106
|
if (result._tag === "Failure") {
|
|
90
107
|
const error = new OgImageError({
|
|
91
108
|
code: "unreadable-image",
|
|
@@ -103,12 +120,11 @@ const make = () => Effect.gen(function* () {
|
|
|
103
120
|
factsByPath.set(filePath, null);
|
|
104
121
|
return null;
|
|
105
122
|
}
|
|
106
|
-
const
|
|
107
|
-
const mimeType = imageMimeType(size.type);
|
|
123
|
+
const { width, height, mimeType } = result.success;
|
|
108
124
|
const facts = {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
125
|
+
width,
|
|
126
|
+
height,
|
|
127
|
+
type: mimeType
|
|
112
128
|
};
|
|
113
129
|
factsByPath.set(filePath, facts);
|
|
114
130
|
return facts;
|