@ubean/seo 0.2.2 → 0.3.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/dist/conventions.d.ts +10 -1
- package/dist/conventions.js +34 -8
- package/package.json +4 -4
package/dist/conventions.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ interface LoadedConvention {
|
|
|
58
58
|
* 不存在的文件被静默跳过。
|
|
59
59
|
*/
|
|
60
60
|
declare function discoverSeoConventions(options: RegisterSeoConventionsOptions): Promise<LoadedConvention[]>;
|
|
61
|
+
/** Map `sitemap.ts` / `/src/robots.js` to a convention kind. */
|
|
62
|
+
declare function conventionKindFromPath(filePath: string): SeoConventionKind | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Register convention handlers already loaded (production `import.meta.glob`).
|
|
65
|
+
* Keys may be absolute or vite-style paths; the basename selects the kind.
|
|
66
|
+
*/
|
|
67
|
+
declare function registerSeoConventionModules(app: SeoConventionApp, modules: Record<string, {
|
|
68
|
+
default?: unknown;
|
|
69
|
+
}>): Promise<SeoConventionKind[]>;
|
|
61
70
|
/**
|
|
62
71
|
* 扫描 srcDir 下的 SEO 约定文件,为每个发现的文件注册 GET 路由。
|
|
63
72
|
*
|
|
@@ -74,4 +83,4 @@ declare function registerSeoConventions(app: SeoConventionApp, options: Register
|
|
|
74
83
|
*/
|
|
75
84
|
declare function listSeoConventions(options: Pick<RegisterSeoConventionsOptions, 'srcDir' | 'extensions'>): SeoConventionKind[];
|
|
76
85
|
//#endregion
|
|
77
|
-
export { RegisterSeoConventionsOptions, SEO_CONVENTIONS, SeoConventionApp, SeoConventionContext, SeoConventionDescriptor, SeoConventionKind, discoverSeoConventions, listSeoConventions, registerSeoConventions };
|
|
86
|
+
export { RegisterSeoConventionsOptions, SEO_CONVENTIONS, SeoConventionApp, SeoConventionContext, SeoConventionDescriptor, SeoConventionKind, conventionKindFromPath, discoverSeoConventions, listSeoConventions, registerSeoConventionModules, registerSeoConventions };
|
package/dist/conventions.js
CHANGED
|
@@ -19,9 +19,9 @@ import { isAbsolute, join, resolve } from "pathe";
|
|
|
19
19
|
* 设计要点:
|
|
20
20
|
* - 纯运行时实现(无 Vite 插件依赖):用 `fs.access` 检测文件存在,`import()` 加载。
|
|
21
21
|
* - 不强依赖 `@ubean/app` —— 通过最小化的 `SeoConventionApp` 结构类型避免循环依赖。
|
|
22
|
-
* -
|
|
23
|
-
* `
|
|
24
|
-
*
|
|
22
|
+
* - 调用方也可手动 `registerSeoConventions(app, { srcDir })`。`createUbeanApp`
|
|
23
|
+
* 在 `init()` 默认调用(`seoConventions: false` 关闭);生产可传入已 glob 的
|
|
24
|
+
* `seoConventionModules`,避免 serverless 依赖读盘。
|
|
25
25
|
* - 文件不存在时静默跳过(不报错),允许项目按需采用约定。
|
|
26
26
|
* - 已注册的路由(用户在 `routes/` 显式定义)优先级不变 —— 约定文件在 `init()` 中
|
|
27
27
|
* 于用户路由 *之后* 注册,因此 Hono 路由匹配时显式路由优先。
|
|
@@ -114,6 +114,35 @@ async function discoverSeoConventions(options) {
|
|
|
114
114
|
}
|
|
115
115
|
return loaded;
|
|
116
116
|
}
|
|
117
|
+
function basenameWithoutExt(filePath) {
|
|
118
|
+
return (filePath.replaceAll("\\", "/").split("/").pop() || "").replace(/\.(ts|js|mjs|mts|cjs)$/i, "");
|
|
119
|
+
}
|
|
120
|
+
/** Map `sitemap.ts` / `/src/robots.js` to a convention kind. */
|
|
121
|
+
function conventionKindFromPath(filePath) {
|
|
122
|
+
const name = basenameWithoutExt(filePath);
|
|
123
|
+
return SEO_CONVENTIONS.find((d) => d.fileName === name)?.kind;
|
|
124
|
+
}
|
|
125
|
+
function mountConvention(app, descriptor, handler) {
|
|
126
|
+
app.get(descriptor.routePath, async (c) => toResponse(descriptor, handler, c));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Register convention handlers already loaded (production `import.meta.glob`).
|
|
130
|
+
* Keys may be absolute or vite-style paths; the basename selects the kind.
|
|
131
|
+
*/
|
|
132
|
+
async function registerSeoConventionModules(app, modules) {
|
|
133
|
+
const registered = [];
|
|
134
|
+
for (const [filePath, mod] of Object.entries(modules)) {
|
|
135
|
+
const kind = conventionKindFromPath(filePath);
|
|
136
|
+
if (!kind) continue;
|
|
137
|
+
const descriptor = SEO_CONVENTIONS.find((d) => d.kind === kind);
|
|
138
|
+
if (!descriptor) continue;
|
|
139
|
+
const handler = mod?.default;
|
|
140
|
+
if (typeof handler !== "function") continue;
|
|
141
|
+
mountConvention(app, descriptor, handler);
|
|
142
|
+
registered.push(kind);
|
|
143
|
+
}
|
|
144
|
+
return registered;
|
|
145
|
+
}
|
|
117
146
|
/**
|
|
118
147
|
* 把单个约定文件的 default export 转换为 Hono GET handler。
|
|
119
148
|
*
|
|
@@ -151,10 +180,7 @@ async function registerSeoConventions(app, options) {
|
|
|
151
180
|
const loaded = await discoverSeoConventions(options);
|
|
152
181
|
const registered = [];
|
|
153
182
|
for (const { descriptor, handler } of loaded) {
|
|
154
|
-
|
|
155
|
-
app.get(routePath, async (c) => {
|
|
156
|
-
return await toResponse(descriptor, handler, c);
|
|
157
|
-
});
|
|
183
|
+
mountConvention(app, descriptor, handler);
|
|
158
184
|
registered.push(descriptor.kind);
|
|
159
185
|
}
|
|
160
186
|
return registered;
|
|
@@ -174,4 +200,4 @@ function listSeoConventions(options) {
|
|
|
174
200
|
return found;
|
|
175
201
|
}
|
|
176
202
|
//#endregion
|
|
177
|
-
export { SEO_CONVENTIONS, discoverSeoConventions, listSeoConventions, registerSeoConventions };
|
|
203
|
+
export { SEO_CONVENTIONS, conventionKindFromPath, discoverSeoConventions, listSeoConventions, registerSeoConventionModules, registerSeoConventions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubean/seo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "SEO utilities for ubean (useSeoMeta, robots, sitemap, manifest, file conventions, JSON-LD, OG image)",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@unhead/vue": "^3.
|
|
31
|
+
"@unhead/vue": "^3.4.0",
|
|
32
32
|
"pathe": "^2.0.3"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/node": "^26.
|
|
35
|
+
"@types/node": "^26.4.0",
|
|
36
36
|
"typescript": "7.0.2",
|
|
37
|
-
"vite-plus": "0.
|
|
37
|
+
"vite-plus": "0.3.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@resvg/resvg-js": "^2.6.0",
|