@airdraft/plugin-seo 0.1.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/CHANGELOG.md +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/withSeo.d.ts +30 -0
- package/dist/withSeo.d.ts.map +1 -0
- package/dist/withSeo.js +63 -0
- package/dist/withSeo.js.map +1 -0
- package/package.json +41 -0
package/CHANGELOG.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Plugin } from '@airdraft/core';
|
|
2
|
+
export interface WithSeoOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Collection names to inject SEO fields into.
|
|
5
|
+
* Omit to apply to all collections.
|
|
6
|
+
*/
|
|
7
|
+
collections?: string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Injects a pre-defined `seo` object field into the specified collections
|
|
11
|
+
* (or all collections if none are specified).
|
|
12
|
+
*
|
|
13
|
+
* Added fields:
|
|
14
|
+
* - `seo.title` — Meta / OG title
|
|
15
|
+
* - `seo.description` — Meta description
|
|
16
|
+
* - `seo.image` — Open Graph image URL
|
|
17
|
+
* - `seo.noIndex` — Opt out of indexing (default: false)
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { withSeo } from '@airdraft/plugin-seo'
|
|
21
|
+
*
|
|
22
|
+
* plugins: [
|
|
23
|
+
* withSeo({ collections: ['posts', 'pages'] }),
|
|
24
|
+
* // or to apply to all:
|
|
25
|
+
* withSeo(),
|
|
26
|
+
* ]
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function withSeo(options?: WithSeoOptions): Plugin;
|
|
30
|
+
//# sourceMappingURL=withSeo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withSeo.d.ts","sourceRoot":"","sources":["../src/withSeo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,gBAAgB,CAAA;AAMvD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAsBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,CA2B5D"}
|
package/dist/withSeo.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// SEO field schema
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/** The `seo` object field injected by this plugin. */
|
|
5
|
+
const SEO_FIELD = {
|
|
6
|
+
type: 'object',
|
|
7
|
+
label: 'SEO',
|
|
8
|
+
fields: {
|
|
9
|
+
title: { type: 'string', label: 'Meta title' },
|
|
10
|
+
description: { type: 'text', label: 'Meta description' },
|
|
11
|
+
image: { type: 'image', label: 'OG image' },
|
|
12
|
+
noIndex: { type: 'boolean', label: 'No index', default: false },
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// withSeo
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Injects a pre-defined `seo` object field into the specified collections
|
|
20
|
+
* (or all collections if none are specified).
|
|
21
|
+
*
|
|
22
|
+
* Added fields:
|
|
23
|
+
* - `seo.title` — Meta / OG title
|
|
24
|
+
* - `seo.description` — Meta description
|
|
25
|
+
* - `seo.image` — Open Graph image URL
|
|
26
|
+
* - `seo.noIndex` — Opt out of indexing (default: false)
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { withSeo } from '@airdraft/plugin-seo'
|
|
30
|
+
*
|
|
31
|
+
* plugins: [
|
|
32
|
+
* withSeo({ collections: ['posts', 'pages'] }),
|
|
33
|
+
* // or to apply to all:
|
|
34
|
+
* withSeo(),
|
|
35
|
+
* ]
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function withSeo(options = {}) {
|
|
39
|
+
return {
|
|
40
|
+
name: 'seo',
|
|
41
|
+
schema(schema) {
|
|
42
|
+
const updatedCollections = { ...schema.collections };
|
|
43
|
+
for (const [name, col] of Object.entries(schema.collections)) {
|
|
44
|
+
// Skip if a target list is given and this collection isn't in it
|
|
45
|
+
// (explicitly empty array = no collections; omitting = all collections)
|
|
46
|
+
if (options.collections !== undefined && !options.collections.includes(name))
|
|
47
|
+
continue;
|
|
48
|
+
// Skip if this collection already has a `seo` field
|
|
49
|
+
if ('seo' in col.fields)
|
|
50
|
+
continue;
|
|
51
|
+
updatedCollections[name] = {
|
|
52
|
+
...col,
|
|
53
|
+
fields: {
|
|
54
|
+
...col.fields,
|
|
55
|
+
seo: SEO_FIELD,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return { ...schema, collections: updatedCollections };
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=withSeo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withSeo.js","sourceRoot":"","sources":["../src/withSeo.ts"],"names":[],"mappings":"AAcA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,sDAAsD;AACtD,MAAM,SAAS,GAAG;IAChB,IAAI,EAAE,QAAiB;IACvB,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE;QACN,KAAK,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,KAAK,EAAE,YAAY,EAAE;QACvD,WAAW,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,KAAK,EAAE,kBAAkB,EAAE;QACjE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAgB,EAAE,KAAK,EAAE,UAAU,EAAE;QACpD,OAAO,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE;KACzE;CACF,CAAA;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,OAAO,CAAC,UAA0B,EAAE;IAClD,OAAO;QACL,IAAI,EAAE,KAAK;QAEX,MAAM,CAAC,MAAiB;YACtB,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAA;YAEpD,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7D,iEAAiE;gBACjE,wEAAwE;gBACxE,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAAE,SAAQ;gBAEtF,oDAAoD;gBACpD,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM;oBAAE,SAAQ;gBAEjC,kBAAkB,CAAC,IAAI,CAAC,GAAG;oBACzB,GAAG,GAAG;oBACN,MAAM,EAAE;wBACN,GAAG,GAAG,CAAC,MAAM;wBACb,GAAG,EAAE,SAAS;qBACf;iBACF,CAAA;YACH,CAAC;YAED,OAAO,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAA;QACvD,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@airdraft/plugin-seo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Airdraft SEO plugin — meta fields, OG, sitemap generation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md", "CHANGELOG.md"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"release": "standard-version",
|
|
24
|
+
"release:patch": "standard-version --release-as patch",
|
|
25
|
+
"release:minor": "standard-version --release-as minor",
|
|
26
|
+
"release:major": "standard-version --release-as major"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": { "access": "public" },
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.0.0",
|
|
32
|
+
"standard-version": "^9.5.0",
|
|
33
|
+
"tsx": "^4.7.0",
|
|
34
|
+
"typescript": "^5.4.0",
|
|
35
|
+
"vitest": "^1.5.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@airdraft/core": "*"
|
|
39
|
+
},
|
|
40
|
+
"engines": { "node": ">=18.0.0" }
|
|
41
|
+
}
|