@paragraphcms/seo 0.2.0 → 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/README.md +1 -1
- package/dist/routes.d.ts +1 -2
- package/dist/routes.d.ts.map +1 -1
- package/dist/seo.d.ts +4 -5
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +28 -8
- package/dist/types.d.ts +19 -30
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
SEO document generators for Paragraph CMS sites.
|
|
4
4
|
|
|
5
|
-
`@paragraphcms/seo` builds `robots.txt`, `sitemap.xml`, `rss.xml`, and `llms.txt` from a single `@paragraphcms/client`
|
|
5
|
+
`@paragraphcms/seo` builds `robots.txt`, `sitemap.xml`, `rss.xml`, and `llms.txt` from a single `Client` instance from `@paragraphcms/client` plus your route definitions.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { PageSummary } from "@paragraphcms/client";
|
|
2
1
|
import type { SeoLocalizedContentRouteDefinition, SeoRouteContext } from "./types.js";
|
|
3
2
|
export declare function buildLocalizedPath(context: Pick<SeoRouteContext, "locale" | "defaultLocale">, ...parts: string[]): string;
|
|
4
3
|
export declare function localizedRoute(basePath?: string): (context: Pick<SeoRouteContext, "locale" | "defaultLocale">) => string;
|
|
5
|
-
export declare function localizedContentRoute
|
|
4
|
+
export declare function localizedContentRoute(basePath: string, options?: Omit<SeoLocalizedContentRouteDefinition, "basePath">): SeoLocalizedContentRouteDefinition;
|
|
6
5
|
//# sourceMappingURL=routes.d.ts.map
|
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,eAAe,EAChB,MAAM,YAAY,CAAC;AAyCpB,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,eAAe,CAAC,EAC1D,GAAG,KAAK,EAAE,MAAM,EAAE,UAQnB;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,IAc5C,SAAS,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,eAAe,CAAC,YAE7D;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,IAAI,CAAC,kCAAkC,EAAE,UAAU,CAAM,GACjE,kCAAkC,CAKpC"}
|
package/dist/seo.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { PageSummary } from "@paragraphcms/client";
|
|
2
1
|
import type { CreateSeoOptions, SeoApi } from "./types.js";
|
|
3
|
-
export declare class SEO
|
|
2
|
+
export declare class SEO implements SeoApi {
|
|
4
3
|
private readonly client;
|
|
5
4
|
private readonly homeRoute;
|
|
6
5
|
private readonly namedRoutes;
|
|
@@ -9,7 +8,7 @@ export declare class SEO<TPage extends PageSummary = PageSummary> implements Seo
|
|
|
9
8
|
private readonly siteUrl;
|
|
10
9
|
private readonly siteDescription?;
|
|
11
10
|
private readonly siteDefaultLocale?;
|
|
12
|
-
constructor(options: CreateSeoOptions
|
|
11
|
+
constructor(options: CreateSeoOptions);
|
|
13
12
|
private resolveDefaultLocale;
|
|
14
13
|
private makeResolvedSite;
|
|
15
14
|
private listLocales;
|
|
@@ -28,7 +27,7 @@ export declare class SEO<TPage extends PageSummary = PageSummary> implements Seo
|
|
|
28
27
|
private resolveRssRoute;
|
|
29
28
|
robotsTxt: () => Promise<string>;
|
|
30
29
|
sitemapXml: () => Promise<string>;
|
|
31
|
-
rssXml: SeoApi
|
|
32
|
-
llmsTxt: SeoApi
|
|
30
|
+
rssXml: SeoApi["rssXml"];
|
|
31
|
+
llmsTxt: SeoApi["llmsTxt"];
|
|
33
32
|
}
|
|
34
33
|
//# sourceMappingURL=seo.d.ts.map
|
package/dist/seo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gBAAgB,EAEhB,MAAM,EASP,MAAM,YAAY,CAAC;AAmQpB,qBAAa,GAAI,YAAW,MAAM;IAEhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAS;gBAEhC,OAAO,EAAE,gBAAgB;YA8IvB,oBAAoB;IAclC,OAAO,CAAC,gBAAgB;YAWV,WAAW;IAiBzB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAejC,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,eAAe;YAOT,mBAAmB;YAsBnB,oBAAoB;IASlC,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,eAAe;IA8BvB,SAAS,wBAWP;IAEF,UAAU,wBAgHR;IAEF,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CA+FtB;IAEF,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CA4ExB;CACH"}
|
package/dist/seo.js
CHANGED
|
@@ -127,6 +127,27 @@ function isPlainObject(value) {
|
|
|
127
127
|
value !== null &&
|
|
128
128
|
!Array.isArray(value));
|
|
129
129
|
}
|
|
130
|
+
function unwrapClientResult(result, fieldName) {
|
|
131
|
+
if (result.error) {
|
|
132
|
+
throw result.error;
|
|
133
|
+
}
|
|
134
|
+
if (result.data === null) {
|
|
135
|
+
throw new TypeError(`${fieldName} returned no data.`);
|
|
136
|
+
}
|
|
137
|
+
return result.data;
|
|
138
|
+
}
|
|
139
|
+
function isListResponse(value) {
|
|
140
|
+
return (typeof value === "object" &&
|
|
141
|
+
value !== null &&
|
|
142
|
+
"data" in value &&
|
|
143
|
+
Array.isArray(value.data));
|
|
144
|
+
}
|
|
145
|
+
function toSeoPage(page) {
|
|
146
|
+
return {
|
|
147
|
+
...page,
|
|
148
|
+
slug: page.slug.trim(),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
130
151
|
export class SEO {
|
|
131
152
|
client;
|
|
132
153
|
homeRoute;
|
|
@@ -231,7 +252,7 @@ export class SEO {
|
|
|
231
252
|
if (this.siteDefaultLocale) {
|
|
232
253
|
return this.siteDefaultLocale;
|
|
233
254
|
}
|
|
234
|
-
return assertNonEmptyString(await this.client.locales.getDefaultLocale(), "client.locales.getDefaultLocale() result");
|
|
255
|
+
return assertNonEmptyString(unwrapClientResult(await this.client.locales.getDefaultLocale(), "client.locales.getDefaultLocale()"), "client.locales.getDefaultLocale() result");
|
|
235
256
|
}
|
|
236
257
|
makeResolvedSite(defaultLocale) {
|
|
237
258
|
return {
|
|
@@ -242,7 +263,7 @@ export class SEO {
|
|
|
242
263
|
};
|
|
243
264
|
}
|
|
244
265
|
async listLocales(defaultLocale, extra = []) {
|
|
245
|
-
const locales = await this.client.locales.list();
|
|
266
|
+
const locales = unwrapClientResult(await this.client.locales.list(), "client.locales.list()");
|
|
246
267
|
const localeCodes = dedupeStrings([
|
|
247
268
|
...locales.map((locale) => locale.code),
|
|
248
269
|
defaultLocale,
|
|
@@ -292,18 +313,17 @@ export class SEO {
|
|
|
292
313
|
return normalizePath(this.artifacts?.llmsPath, DEFAULT_LLMS_PATH);
|
|
293
314
|
}
|
|
294
315
|
async listNamedRoutePages(locale, route) {
|
|
295
|
-
const
|
|
316
|
+
const pageQuery = {
|
|
296
317
|
published: true,
|
|
297
318
|
...route.params,
|
|
298
319
|
language: locale,
|
|
299
320
|
requiredSlug: true,
|
|
300
|
-
}
|
|
321
|
+
};
|
|
322
|
+
const result = unwrapClientResult(await this.client.pages.list(pageQuery), "client.pages.list()");
|
|
323
|
+
const data = isListResponse(result) ? result.data : result;
|
|
301
324
|
return data
|
|
302
325
|
.filter(hasSlug)
|
|
303
|
-
.map((page) => (
|
|
304
|
-
...page,
|
|
305
|
-
slug: page.slug.trim(),
|
|
306
|
-
}))
|
|
326
|
+
.map((page) => toSeoPage(page))
|
|
307
327
|
.sort(comparePagesForFeed);
|
|
308
328
|
}
|
|
309
329
|
async listLocaleRoutePages(locale) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type SeoPage
|
|
3
|
-
slug: string;
|
|
4
|
-
};
|
|
5
|
-
export interface SeoClient<TPage extends PageSummary = PageSummary> {
|
|
6
|
-
locales: {
|
|
7
|
-
list(): Promise<Locale[]>;
|
|
8
|
-
getDefaultLocale(): Promise<string>;
|
|
9
|
-
};
|
|
10
|
-
pages: {
|
|
11
|
-
list(query?: PageListQuery): Promise<ListResponse<TPage>>;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
1
|
+
import type { Client, PageListQuery, PageSummaryWithSlug } from "@paragraphcms/client";
|
|
2
|
+
export type SeoPage = PageSummaryWithSlug;
|
|
14
3
|
export interface SeoSiteConfig {
|
|
15
4
|
url: string;
|
|
16
5
|
name: string;
|
|
@@ -31,12 +20,12 @@ export interface SeoRouteContext {
|
|
|
31
20
|
export interface SeoNamedRouteContext extends SeoRouteContext {
|
|
32
21
|
route: string;
|
|
33
22
|
}
|
|
34
|
-
export interface SeoPostRouteContext
|
|
35
|
-
page: SeoPage
|
|
23
|
+
export interface SeoPostRouteContext extends SeoNamedRouteContext {
|
|
24
|
+
page: SeoPage;
|
|
36
25
|
slug: string;
|
|
37
26
|
}
|
|
38
27
|
export type SeoRouteParams = Omit<PageListQuery, "language" | "requiredSlug" | "page" | "limit">;
|
|
39
|
-
export interface SeoContentRouteDefinition
|
|
28
|
+
export interface SeoContentRouteDefinition {
|
|
40
29
|
/**
|
|
41
30
|
* Forwarded to `client.pages.list()`.
|
|
42
31
|
* `published` defaults to `true` unless you override it here.
|
|
@@ -44,11 +33,11 @@ export interface SeoContentRouteDefinition<TPage extends PageSummary = PageSumma
|
|
|
44
33
|
*/
|
|
45
34
|
params?: SeoRouteParams;
|
|
46
35
|
index: (params: SeoNamedRouteContext) => string;
|
|
47
|
-
post: (params: SeoPostRouteContext
|
|
48
|
-
title?: (page: SeoPage
|
|
49
|
-
description?: (page: SeoPage
|
|
36
|
+
post: (params: SeoPostRouteContext) => string;
|
|
37
|
+
title?: (page: SeoPage) => string;
|
|
38
|
+
description?: (page: SeoPage) => string | null | undefined;
|
|
50
39
|
}
|
|
51
|
-
export interface SeoLocalizedContentRouteDefinition
|
|
40
|
+
export interface SeoLocalizedContentRouteDefinition {
|
|
52
41
|
/**
|
|
53
42
|
* Localized base path for the route, without the locale prefix
|
|
54
43
|
* and without the trailing post slug.
|
|
@@ -61,14 +50,14 @@ export interface SeoLocalizedContentRouteDefinition<TPage extends PageSummary =
|
|
|
61
50
|
* Supports client filters such as `statusId` and `statusType`.
|
|
62
51
|
*/
|
|
63
52
|
params?: SeoRouteParams;
|
|
64
|
-
title?: (page: SeoPage
|
|
65
|
-
description?: (page: SeoPage
|
|
53
|
+
title?: (page: SeoPage) => string;
|
|
54
|
+
description?: (page: SeoPage) => string | null | undefined;
|
|
66
55
|
}
|
|
67
|
-
export type SeoNamedRouteDefinition
|
|
68
|
-
export type SeoRouteEntry
|
|
69
|
-
export interface SeoRoutes
|
|
56
|
+
export type SeoNamedRouteDefinition = SeoContentRouteDefinition | SeoLocalizedContentRouteDefinition;
|
|
57
|
+
export type SeoRouteEntry = ((params: SeoRouteContext) => string) | SeoNamedRouteDefinition;
|
|
58
|
+
export interface SeoRoutes {
|
|
70
59
|
home: (params: SeoRouteContext) => string;
|
|
71
|
-
[routeName: string]: SeoRouteEntry
|
|
60
|
+
[routeName: string]: SeoRouteEntry;
|
|
72
61
|
}
|
|
73
62
|
export interface SeoArtifactPathContext extends SeoRouteContext {
|
|
74
63
|
route?: string;
|
|
@@ -80,10 +69,10 @@ export interface SeoArtifactsConfig {
|
|
|
80
69
|
llmsPath?: string;
|
|
81
70
|
rssPath?: (params: SeoArtifactPathContext) => string;
|
|
82
71
|
}
|
|
83
|
-
export interface CreateSeoOptions
|
|
84
|
-
client:
|
|
72
|
+
export interface CreateSeoOptions {
|
|
73
|
+
client: Client;
|
|
85
74
|
site: SeoSiteConfig;
|
|
86
|
-
routes: SeoRoutes
|
|
75
|
+
routes: SeoRoutes;
|
|
87
76
|
artifacts?: SeoArtifactsConfig;
|
|
88
77
|
}
|
|
89
78
|
export interface SeoRssXmlOptions {
|
|
@@ -93,7 +82,7 @@ export interface SeoRssXmlOptions {
|
|
|
93
82
|
export interface SeoLlmsTxtOptions {
|
|
94
83
|
locale?: string;
|
|
95
84
|
}
|
|
96
|
-
export interface SeoApi
|
|
85
|
+
export interface SeoApi {
|
|
97
86
|
robotsTxt(): Promise<string>;
|
|
98
87
|
sitemapXml(): Promise<string>;
|
|
99
88
|
rssXml(options?: SeoRssXmlOptions): Promise<string>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,mBAAmB,EAEpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,OAAO,GAAG,mBAAmB,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED,MAAM,WAAW,oBACf,SAAQ,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBACf,SAAQ,oBAAoB;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,aAAa,EACb,UAAU,GAAG,cAAc,GAAG,MAAM,GAAG,OAAO,CAC/C,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,MAAM,CAAC;IAC9C,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,OAAO,KACV,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,kCAAkC;IACjD;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,OAAO,KACV,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,MAAM,uBAAuB,GAC/B,yBAAyB,GACzB,kCAAkC,CAAC;AAEvC,MAAM,MAAM,aAAa,GACrB,CAAC,CAAC,MAAM,EAAE,eAAe,KAAK,MAAM,CAAC,GACrC,uBAAuB,CAAC;AAE5B,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,MAAM,CAAC;IAC1C,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAAC;CACpC;AAED,MAAM,WAAW,sBACf,SAAQ,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,MAAM,CAAC;CACtD;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paragraphcms/seo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "SEO document generators for Paragraph CMS sites.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Paragraph CMS",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"robots"
|
|
39
39
|
],
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@paragraphcms/client": "3.0.
|
|
41
|
+
"@paragraphcms/client": "3.0.6"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@paragraphcms/client": "3.0.
|
|
44
|
+
"@paragraphcms/client": "3.0.6",
|
|
45
45
|
"typescript": "^5.9.3"
|
|
46
46
|
}
|
|
47
47
|
}
|