@tsdoctor/seo 0.1.1 → 0.2.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/OpenGraph.js +18 -14
- package/README.md +1 -1
- package/Seo.js +2 -0
- package/index.d.ts +11 -7
- package/index.js +2 -2
- package/package.json +1 -1
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
|
@@ -286,6 +286,10 @@ declare const OpenGraphMetadata: Schema.Struct<{
|
|
|
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`. */
|
|
@@ -316,12 +320,6 @@ declare const OpenGraphMetadata: Schema.Struct<{
|
|
|
316
320
|
}>;
|
|
317
321
|
/** @public */
|
|
318
322
|
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;
|
|
325
323
|
/**
|
|
326
324
|
* Assemble the complete Open Graph metadata for one documentation page.
|
|
327
325
|
*
|
|
@@ -330,6 +328,8 @@ declare function ogAltText(packageName: string, apiName?: string): string;
|
|
|
330
328
|
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;
|
|
@@ -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`. */
|
|
@@ -539,5 +543,5 @@ declare function derive(pkg: PackageContext, page: PageNodeInput): Result.Result
|
|
|
539
543
|
*/
|
|
540
544
|
declare function deriveScriptBody(pkg: PackageContext, page: PageNodeInput): Result.Result<string, StructuredDataError>;
|
|
541
545
|
//#endregion
|
|
542
|
-
export { type AttributionFacts, type HeadTag, OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, type PackageContext, type PackageNodeInput, type PageNodeInput, type SeoPageInput, type StructuredDataError, attributionFacts, canonicalUrl, createPageMetadata, derive, deriveScriptBody, deriveSiteUrl, escapeScriptBody, headTags, imageMimeType, jsonLd, link, meta, metaNamed,
|
|
546
|
+
export { type AttributionFacts, type HeadTag, OpenGraphImageConfig, OpenGraphImageMetadata, OpenGraphMetadata, type PackageContext, type PackageNodeInput, type PageNodeInput, type SeoPageInput, type StructuredDataError, attributionFacts, canonicalUrl, createPageMetadata, derive, deriveScriptBody, deriveSiteUrl, escapeScriptBody, headTags, imageMimeType, jsonLd, link, meta, metaNamed, openGraphTags, packageContext, resolveUrl, twitterTags };
|
|
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.
|
|
3
|
+
"version": "0.2.0",
|
|
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": [
|