@tsdoctor/seo 0.1.2 → 0.2.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/OpenGraph.js +18 -14
- package/README.md +1 -1
- package/Seo.js +2 -0
- package/index.d.ts +34 -30
- package/index.js +2 -2
- package/package.json +5 -5
package/OpenGraph.js
CHANGED
|
@@ -8,9 +8,9 @@ import { Schema } from "effect";
|
|
|
8
8
|
* page-metadata assembly and the two tag emitters.
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
* The schemas and {@link createPageMetadata}
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* The schemas and {@link createPageMetadata} moved here verbatim from the
|
|
12
|
+
* RSPress adapter (`schemas/opengraph.ts` and `og-resolver.ts`).
|
|
13
|
+
* {@link openGraphTags} is the tag-emission logic that was
|
|
14
14
|
* inlined in the adapter's `generateFrontmatter`, lifted unchanged — same tag
|
|
15
15
|
* order, same conditional emission of each optional image sub-tag — so that a
|
|
16
16
|
* second adapter can reach the vocabulary rather than reimplement it.
|
|
@@ -52,6 +52,10 @@ const OpenGraphMetadata = Schema.Struct({
|
|
|
52
52
|
siteUrl: Schema.String,
|
|
53
53
|
/** Page route path (e.g. `/api/classes/myclass`). */
|
|
54
54
|
pageRoute: Schema.String,
|
|
55
|
+
/** Page title for the `og:title` and `twitter:title` tags. */
|
|
56
|
+
title: Schema.String,
|
|
57
|
+
/** Site name for the `og:site_name` tag, when the site declares one. */
|
|
58
|
+
siteName: Schema.optional(Schema.String),
|
|
55
59
|
/** Page description for the `og:description` tag. */
|
|
56
60
|
description: Schema.String,
|
|
57
61
|
/** ISO 8601 date string for `article:published_time`. */
|
|
@@ -68,14 +72,6 @@ const OpenGraphMetadata = Schema.Struct({
|
|
|
68
72
|
ogType: Schema.String
|
|
69
73
|
});
|
|
70
74
|
/**
|
|
71
|
-
* Descriptive alt text for a package's (or one API's) OG image.
|
|
72
|
-
*
|
|
73
|
-
* @public
|
|
74
|
-
*/
|
|
75
|
-
function ogAltText(packageName, apiName) {
|
|
76
|
-
return apiName ? `${apiName} - ${packageName} API Documentation` : `${packageName} API Documentation`;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
75
|
* Assemble the complete Open Graph metadata for one documentation page.
|
|
80
76
|
*
|
|
81
77
|
* @public
|
|
@@ -84,6 +80,8 @@ function createPageMetadata(options) {
|
|
|
84
80
|
return {
|
|
85
81
|
siteUrl: options.siteUrl,
|
|
86
82
|
pageRoute: options.pageRoute,
|
|
83
|
+
title: options.title,
|
|
84
|
+
...options.siteName != null ? { siteName: options.siteName } : {},
|
|
87
85
|
description: options.description,
|
|
88
86
|
publishedTime: options.publishedTime,
|
|
89
87
|
modifiedTime: options.modifiedTime,
|
|
@@ -111,8 +109,10 @@ function openGraphTags(metadata) {
|
|
|
111
109
|
const tags = [
|
|
112
110
|
meta("og:url", canonicalUrl(metadata.siteUrl, metadata.pageRoute)),
|
|
113
111
|
meta("og:type", metadata.ogType),
|
|
114
|
-
meta("og:
|
|
112
|
+
meta("og:title", metadata.title)
|
|
115
113
|
];
|
|
114
|
+
if (metadata.siteName !== void 0 && metadata.siteName !== "") tags.push(meta("og:site_name", metadata.siteName));
|
|
115
|
+
tags.push(meta("og:description", metadata.description));
|
|
116
116
|
const image = metadata.ogImage;
|
|
117
117
|
if (image) {
|
|
118
118
|
tags.push(meta("og:image", image.url));
|
|
@@ -143,7 +143,11 @@ function openGraphTags(metadata) {
|
|
|
143
143
|
* @public
|
|
144
144
|
*/
|
|
145
145
|
function twitterTags(metadata, site) {
|
|
146
|
-
const tags = [
|
|
146
|
+
const tags = [
|
|
147
|
+
metaNamed("twitter:card", metadata.ogImage ? "summary_large_image" : "summary"),
|
|
148
|
+
metaNamed("twitter:title", metadata.title),
|
|
149
|
+
metaNamed("twitter:description", metadata.description)
|
|
150
|
+
];
|
|
147
151
|
if (site != null && site !== "") tags.push(metaNamed("twitter:site", site));
|
|
148
152
|
if (metadata.ogImage) {
|
|
149
153
|
tags.push(metaNamed("twitter:image", metadata.ogImage.url));
|
|
@@ -153,4 +157,4 @@ function twitterTags(metadata, site) {
|
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
//#endregion
|
|
156
|
-
export { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, createPageMetadata,
|
|
160
|
+
export { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, createPageMetadata, openGraphTags, twitterTags };
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Framework-neutral `<head>` metadata for static TypeScript API documentation: sch
|
|
|
16
16
|
- **`headTags(input: SeoPageInput)`** — every `<head>` tag for one page, in a fixed order so a diff over generated pages stays readable.
|
|
17
17
|
- **`HeadTag`, `meta`, `metaNamed`, `link`, `jsonLd`, `escapeScriptBody`** — the neutral tag vocabulary. `escapeScriptBody` is idempotent, so a body already escaped by an upstream serializer survives a second pass unchanged.
|
|
18
18
|
- **`deriveSiteUrl`, `canonicalUrl`, `resolveUrl`, `imageMimeType`** — URL derivation. With no configured origin the prefix is `""`, so URLs stay root-relative and the tags are still emitted rather than dropped.
|
|
19
|
-
- **`OpenGraphImageConfig`, `OpenGraphImageMetadata`, `OpenGraphMetadata`, `createPageMetadata`, `openGraphTags`, `twitterTags
|
|
19
|
+
- **`OpenGraphImageConfig`, `OpenGraphImageMetadata`, `OpenGraphMetadata`, `createPageMetadata`, `openGraphTags`, `twitterTags`** — the Open Graph and Twitter card vocabulary, as Effect Schemas plus the emitters over them.
|
|
20
20
|
- **`attributionFacts(manifest)`** — author, maintainers, repository URL, homepage, SPDX license ids and per-license canonical URLs, and keywords, derived from an `@effected/package-json` `PackageManifest`. Total and synchronous: a manifest carrying none of these yields empty arrays and no optional properties.
|
|
21
21
|
- **`packageContext`, `derive`, `deriveScriptBody`** — the schema.org graph. `packageContext` is derived once per package; `derive` assembles a page's `@graph` (a `SoftwareSourceCode`, a `TechArticle` and an `APIReference`, linked by `isPartOf` and `mainEntity`, plus a `Person` per credited human).
|
|
22
22
|
|
package/Seo.js
CHANGED
|
@@ -29,6 +29,8 @@ function headTags(input) {
|
|
|
29
29
|
const metadata = createPageMetadata({
|
|
30
30
|
siteUrl: input.siteUrl,
|
|
31
31
|
pageRoute: input.pageRoute,
|
|
32
|
+
title: input.title,
|
|
33
|
+
...input.siteName != null ? { siteName: input.siteName } : {},
|
|
32
34
|
description: input.description,
|
|
33
35
|
publishedTime: input.publishedTime,
|
|
34
36
|
modifiedTime: input.modifiedTime,
|
package/index.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ interface AttributionFacts {
|
|
|
100
100
|
*
|
|
101
101
|
* @public
|
|
102
102
|
*/
|
|
103
|
-
declare function attributionFacts(manifest: PackageManifest): AttributionFacts;
|
|
103
|
+
export declare function attributionFacts(manifest: PackageManifest): AttributionFacts;
|
|
104
104
|
//#endregion
|
|
105
105
|
//#region src/Canonical.d.ts
|
|
106
106
|
/**
|
|
@@ -122,7 +122,7 @@ declare function attributionFacts(manifest: PackageManifest): AttributionFacts;
|
|
|
122
122
|
*
|
|
123
123
|
* @public
|
|
124
124
|
*/
|
|
125
|
-
declare function imageMimeType(type: string | undefined): string | undefined;
|
|
125
|
+
export declare function imageMimeType(type: string | undefined): string | undefined;
|
|
126
126
|
/**
|
|
127
127
|
* Turn a configured URL into an absolute one.
|
|
128
128
|
*
|
|
@@ -133,7 +133,7 @@ declare function imageMimeType(type: string | undefined): string | undefined;
|
|
|
133
133
|
*
|
|
134
134
|
* @public
|
|
135
135
|
*/
|
|
136
|
-
declare function resolveUrl(siteUrl: string, url: string): string | undefined;
|
|
136
|
+
export declare function resolveUrl(siteUrl: string, url: string): string | undefined;
|
|
137
137
|
/**
|
|
138
138
|
* Derive the site URL prefix from the framework's own config.
|
|
139
139
|
*
|
|
@@ -162,7 +162,7 @@ declare function resolveUrl(siteUrl: string, url: string): string | undefined;
|
|
|
162
162
|
*
|
|
163
163
|
* @public
|
|
164
164
|
*/
|
|
165
|
-
declare function deriveSiteUrl(siteOrigin: string | undefined, base: string | undefined): string;
|
|
165
|
+
export declare function deriveSiteUrl(siteOrigin: string | undefined, base: string | undefined): string;
|
|
166
166
|
/**
|
|
167
167
|
* The canonical URL for a page.
|
|
168
168
|
*
|
|
@@ -174,7 +174,7 @@ declare function deriveSiteUrl(siteOrigin: string | undefined, base: string | un
|
|
|
174
174
|
*
|
|
175
175
|
* @public
|
|
176
176
|
*/
|
|
177
|
-
declare function canonicalUrl(siteUrl: string, pageRoute: string): string;
|
|
177
|
+
export declare function canonicalUrl(siteUrl: string, pageRoute: string): string;
|
|
178
178
|
//#endregion
|
|
179
179
|
//#region src/HeadTag.d.ts
|
|
180
180
|
/**
|
|
@@ -223,15 +223,15 @@ interface HeadTag {
|
|
|
223
223
|
*
|
|
224
224
|
* @public
|
|
225
225
|
*/
|
|
226
|
-
declare function escapeScriptBody(json: string): string;
|
|
226
|
+
export declare function escapeScriptBody(json: string): string;
|
|
227
227
|
/** An Open Graph style `<meta property=… content=…>`. @public */
|
|
228
|
-
declare function meta(property: string, content: string): HeadTag;
|
|
228
|
+
export declare function meta(property: string, content: string): HeadTag;
|
|
229
229
|
/** A Twitter/standard style `<meta name=… content=…>`. @public */
|
|
230
|
-
declare function metaNamed(name: string, content: string): HeadTag;
|
|
230
|
+
export declare function metaNamed(name: string, content: string): HeadTag;
|
|
231
231
|
/** A `<link rel=… href=…>`. @public */
|
|
232
|
-
declare function link(rel: string, href: string): HeadTag;
|
|
232
|
+
export declare function link(rel: string, href: string): HeadTag;
|
|
233
233
|
/** A `<script type="application/ld+json">` carrying an escaped body. @public */
|
|
234
|
-
declare function jsonLd(json: string): HeadTag;
|
|
234
|
+
export declare function jsonLd(json: string): HeadTag;
|
|
235
235
|
//#endregion
|
|
236
236
|
//#region src/OpenGraph.d.ts
|
|
237
237
|
/**
|
|
@@ -239,7 +239,7 @@ declare function jsonLd(json: string): HeadTag;
|
|
|
239
239
|
*
|
|
240
240
|
* @public
|
|
241
241
|
*/
|
|
242
|
-
declare const OpenGraphImageMetadata: Schema.Struct<{
|
|
242
|
+
export declare const OpenGraphImageMetadata: Schema.Struct<{
|
|
243
243
|
/** Absolute URL of the image. */
|
|
244
244
|
readonly url: Schema.String;
|
|
245
245
|
/** HTTPS URL of the image (for secure contexts). */
|
|
@@ -254,13 +254,13 @@ declare const OpenGraphImageMetadata: Schema.Struct<{
|
|
|
254
254
|
readonly alt: Schema.optional<Schema.String>;
|
|
255
255
|
}>;
|
|
256
256
|
/** @public */
|
|
257
|
-
type OpenGraphImageMetadata = typeof OpenGraphImageMetadata.Type;
|
|
257
|
+
export type OpenGraphImageMetadata = typeof OpenGraphImageMetadata.Type;
|
|
258
258
|
/**
|
|
259
259
|
* Open Graph image: either a plain URL string or structured `OpenGraphImageMetadata`.
|
|
260
260
|
*
|
|
261
261
|
* @public
|
|
262
262
|
*/
|
|
263
|
-
declare const OpenGraphImageConfig: Schema.Union<readonly [Schema.String, Schema.Struct<{
|
|
263
|
+
export declare const OpenGraphImageConfig: Schema.Union<readonly [Schema.String, Schema.Struct<{
|
|
264
264
|
/** Absolute URL of the image. */
|
|
265
265
|
readonly url: Schema.String;
|
|
266
266
|
/** HTTPS URL of the image (for secure contexts). */
|
|
@@ -275,17 +275,21 @@ declare const OpenGraphImageConfig: Schema.Union<readonly [Schema.String, Schema
|
|
|
275
275
|
readonly alt: Schema.optional<Schema.String>;
|
|
276
276
|
}>]>;
|
|
277
277
|
/** @public */
|
|
278
|
-
type OpenGraphImageConfig = typeof OpenGraphImageConfig.Type;
|
|
278
|
+
export type OpenGraphImageConfig = typeof OpenGraphImageConfig.Type;
|
|
279
279
|
/**
|
|
280
280
|
* Resolved Open Graph metadata for one documentation page.
|
|
281
281
|
*
|
|
282
282
|
* @public
|
|
283
283
|
*/
|
|
284
|
-
declare const OpenGraphMetadata: Schema.Struct<{
|
|
284
|
+
export declare const OpenGraphMetadata: Schema.Struct<{
|
|
285
285
|
/** Canonical site base URL. */
|
|
286
286
|
readonly siteUrl: Schema.String;
|
|
287
287
|
/** Page route path (e.g. `/api/classes/myclass`). */
|
|
288
288
|
readonly pageRoute: Schema.String;
|
|
289
|
+
/** Page title for the `og:title` and `twitter:title` tags. */
|
|
290
|
+
readonly title: Schema.String;
|
|
291
|
+
/** Site name for the `og:site_name` tag, when the site declares one. */
|
|
292
|
+
readonly siteName: Schema.optional<Schema.String>;
|
|
289
293
|
/** Page description for the `og:description` tag. */
|
|
290
294
|
readonly description: Schema.String;
|
|
291
295
|
/** ISO 8601 date string for `article:published_time`. */
|
|
@@ -315,21 +319,17 @@ declare const OpenGraphMetadata: Schema.Struct<{
|
|
|
315
319
|
readonly ogType: Schema.String;
|
|
316
320
|
}>;
|
|
317
321
|
/** @public */
|
|
318
|
-
type OpenGraphMetadata = typeof OpenGraphMetadata.Type;
|
|
319
|
-
/**
|
|
320
|
-
* Descriptive alt text for a package's (or one API's) OG image.
|
|
321
|
-
*
|
|
322
|
-
* @public
|
|
323
|
-
*/
|
|
324
|
-
declare function ogAltText(packageName: string, apiName?: string): string;
|
|
322
|
+
export type OpenGraphMetadata = typeof OpenGraphMetadata.Type;
|
|
325
323
|
/**
|
|
326
324
|
* Assemble the complete Open Graph metadata for one documentation page.
|
|
327
325
|
*
|
|
328
326
|
* @public
|
|
329
327
|
*/
|
|
330
|
-
declare function createPageMetadata(options: {
|
|
328
|
+
export declare function createPageMetadata(options: {
|
|
331
329
|
siteUrl: string;
|
|
332
330
|
pageRoute: string;
|
|
331
|
+
title: string;
|
|
332
|
+
siteName?: string;
|
|
333
333
|
description: string;
|
|
334
334
|
publishedTime: string;
|
|
335
335
|
modifiedTime: string;
|
|
@@ -347,7 +347,7 @@ declare function createPageMetadata(options: {
|
|
|
347
347
|
*
|
|
348
348
|
* @public
|
|
349
349
|
*/
|
|
350
|
-
declare function openGraphTags(metadata: OpenGraphMetadata): ReadonlyArray<HeadTag>;
|
|
350
|
+
export declare function openGraphTags(metadata: OpenGraphMetadata): ReadonlyArray<HeadTag>;
|
|
351
351
|
/**
|
|
352
352
|
* Twitter card tags derived from the same metadata as the Open Graph block.
|
|
353
353
|
*
|
|
@@ -362,7 +362,7 @@ declare function openGraphTags(metadata: OpenGraphMetadata): ReadonlyArray<HeadT
|
|
|
362
362
|
*
|
|
363
363
|
* @public
|
|
364
364
|
*/
|
|
365
|
-
declare function twitterTags(metadata: OpenGraphMetadata, site?: string): ReadonlyArray<HeadTag>;
|
|
365
|
+
export declare function twitterTags(metadata: OpenGraphMetadata, site?: string): ReadonlyArray<HeadTag>;
|
|
366
366
|
//#endregion
|
|
367
367
|
//#region src/Seo.d.ts
|
|
368
368
|
/**
|
|
@@ -375,6 +375,10 @@ interface SeoPageInput {
|
|
|
375
375
|
readonly siteUrl: string;
|
|
376
376
|
/** Page route path, beginning with `/`. */
|
|
377
377
|
readonly pageRoute: string;
|
|
378
|
+
/** Page title, used for both `og:title` and `twitter:title`. */
|
|
379
|
+
readonly title: string;
|
|
380
|
+
/** Site name for the `og:site_name` tag, when the site declares one. */
|
|
381
|
+
readonly siteName?: string;
|
|
378
382
|
/** Page description, used for both `og:description` and `twitter:description`. */
|
|
379
383
|
readonly description: string;
|
|
380
384
|
/** ISO 8601 date string for `article:published_time`. */
|
|
@@ -403,7 +407,7 @@ interface SeoPageInput {
|
|
|
403
407
|
*
|
|
404
408
|
* @public
|
|
405
409
|
*/
|
|
406
|
-
declare function headTags(input: SeoPageInput): ReadonlyArray<HeadTag>;
|
|
410
|
+
export declare function headTags(input: SeoPageInput): ReadonlyArray<HeadTag>;
|
|
407
411
|
//#endregion
|
|
408
412
|
//#region src/StructuredData.d.ts
|
|
409
413
|
/**
|
|
@@ -500,7 +504,7 @@ interface PackageContext {
|
|
|
500
504
|
*
|
|
501
505
|
* @public
|
|
502
506
|
*/
|
|
503
|
-
declare function packageContext(input: PackageNodeInput): PackageContext;
|
|
507
|
+
export declare function packageContext(input: PackageNodeInput): PackageContext;
|
|
504
508
|
/**
|
|
505
509
|
* Derive the schema.org graph for one documentation page.
|
|
506
510
|
*
|
|
@@ -522,7 +526,7 @@ declare function packageContext(input: PackageNodeInput): PackageContext;
|
|
|
522
526
|
*
|
|
523
527
|
* @public
|
|
524
528
|
*/
|
|
525
|
-
declare function derive(pkg: PackageContext, page: PageNodeInput): Result.Result<JsonLdDocument, StructuredDataError>;
|
|
529
|
+
export declare function derive(pkg: PackageContext, page: PageNodeInput): Result.Result<JsonLdDocument, StructuredDataError>;
|
|
526
530
|
/**
|
|
527
531
|
* {@link derive}, serialized to the text an adapter embeds in a `<script>`.
|
|
528
532
|
*
|
|
@@ -537,7 +541,7 @@ declare function derive(pkg: PackageContext, page: PageNodeInput): Result.Result
|
|
|
537
541
|
*
|
|
538
542
|
* @public
|
|
539
543
|
*/
|
|
540
|
-
declare function deriveScriptBody(pkg: PackageContext, page: PageNodeInput): Result.Result<string, StructuredDataError>;
|
|
544
|
+
export declare function deriveScriptBody(pkg: PackageContext, page: PageNodeInput): Result.Result<string, StructuredDataError>;
|
|
541
545
|
//#endregion
|
|
542
|
-
export {
|
|
546
|
+
export type { AttributionFacts, HeadTag, PackageContext, PackageNodeInput, PageNodeInput, SeoPageInput, StructuredDataError };
|
|
543
547
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attributionFacts } from "./Attribution.js";
|
|
2
2
|
import { canonicalUrl, deriveSiteUrl, imageMimeType, resolveUrl } from "./Canonical.js";
|
|
3
3
|
import { escapeScriptBody, jsonLd, link, meta, metaNamed } from "./HeadTag.js";
|
|
4
|
-
import { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, createPageMetadata,
|
|
4
|
+
import { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, createPageMetadata, openGraphTags, twitterTags } from "./OpenGraph.js";
|
|
5
5
|
import { headTags } from "./Seo.js";
|
|
6
6
|
import { derive, deriveScriptBody, packageContext } from "./StructuredData.js";
|
|
7
7
|
|
|
8
|
-
export { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, attributionFacts, canonicalUrl, createPageMetadata, derive, deriveScriptBody, deriveSiteUrl, escapeScriptBody, headTags, imageMimeType, jsonLd, link, meta, metaNamed,
|
|
8
|
+
export { OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, attributionFacts, canonicalUrl, createPageMetadata, derive, deriveScriptBody, deriveSiteUrl, escapeScriptBody, headTags, imageMimeType, jsonLd, link, meta, metaNamed, openGraphTags, packageContext, resolveUrl, twitterTags };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsdoctor/seo",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Framework-neutral head metadata for static TypeScript API documentation: schema.org JSON-LD, Open Graph and Twitter card vocabulary, canonical URLs, and package attribution derived from an api.json model plus its manifest.",
|
|
6
6
|
"keywords": [
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@effected/package-json": "^0.
|
|
41
|
-
"@effected/schema-org": "^0.
|
|
42
|
-
"@effected/spdx": "^0.
|
|
43
|
-
"effect": "4.0.0-rc.
|
|
40
|
+
"@effected/package-json": "^0.14.0",
|
|
41
|
+
"@effected/schema-org": "^0.2.0",
|
|
42
|
+
"@effected/spdx": "^0.6.0",
|
|
43
|
+
"effect": "4.0.0-rc.112"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=24.11.0"
|