@geekron/hono 0.0.5

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.
Files changed (83) hide show
  1. package/README.md +176 -0
  2. package/dist/contract.d.ts +5 -0
  3. package/dist/contract.d.ts.map +1 -0
  4. package/dist/contract.js +4 -0
  5. package/dist/route/index.d.ts +5 -0
  6. package/dist/route/index.d.ts.map +1 -0
  7. package/dist/route/index.js +4 -0
  8. package/dist/route/interfaces.d.ts +35 -0
  9. package/dist/route/interfaces.d.ts.map +1 -0
  10. package/dist/route/interfaces.js +1 -0
  11. package/dist/route/methods.d.ts +13 -0
  12. package/dist/route/methods.d.ts.map +1 -0
  13. package/dist/route/methods.js +79 -0
  14. package/dist/route/setup.d.ts +18 -0
  15. package/dist/route/setup.d.ts.map +1 -0
  16. package/dist/route/setup.js +11 -0
  17. package/dist/route/slot.d.ts +15 -0
  18. package/dist/route/slot.d.ts.map +1 -0
  19. package/dist/route/slot.js +28 -0
  20. package/dist/strapi/cms/cms.d.ts +17 -0
  21. package/dist/strapi/cms/cms.d.ts.map +1 -0
  22. package/dist/strapi/cms/cms.js +57 -0
  23. package/dist/strapi/cms/common.d.ts +9 -0
  24. package/dist/strapi/cms/common.d.ts.map +1 -0
  25. package/dist/strapi/cms/common.js +30 -0
  26. package/dist/strapi/cms/components.d.ts +20 -0
  27. package/dist/strapi/cms/components.d.ts.map +1 -0
  28. package/dist/strapi/cms/components.js +33 -0
  29. package/dist/strapi/cms/content-types.d.ts +48 -0
  30. package/dist/strapi/cms/content-types.d.ts.map +1 -0
  31. package/dist/strapi/cms/content-types.js +49 -0
  32. package/dist/strapi/cms/index.d.ts +10 -0
  33. package/dist/strapi/cms/index.d.ts.map +1 -0
  34. package/dist/strapi/cms/index.js +9 -0
  35. package/dist/strapi/cms/locales.d.ts +16 -0
  36. package/dist/strapi/cms/locales.d.ts.map +1 -0
  37. package/dist/strapi/cms/locales.js +33 -0
  38. package/dist/strapi/cms/menu.d.ts +19 -0
  39. package/dist/strapi/cms/menu.d.ts.map +1 -0
  40. package/dist/strapi/cms/menu.js +80 -0
  41. package/dist/strapi/cms/setup.d.ts +11 -0
  42. package/dist/strapi/cms/setup.d.ts.map +1 -0
  43. package/dist/strapi/cms/setup.js +25 -0
  44. package/dist/strapi/cms/site.d.ts +9 -0
  45. package/dist/strapi/cms/site.d.ts.map +1 -0
  46. package/dist/strapi/cms/site.js +30 -0
  47. package/dist/strapi/cms/translations.d.ts +25 -0
  48. package/dist/strapi/cms/translations.d.ts.map +1 -0
  49. package/dist/strapi/cms/translations.js +38 -0
  50. package/dist/strapi/index.d.ts +5 -0
  51. package/dist/strapi/index.d.ts.map +1 -0
  52. package/dist/strapi/index.js +4 -0
  53. package/dist/strapi/interfaces/index.d.ts +2 -0
  54. package/dist/strapi/interfaces/index.d.ts.map +1 -0
  55. package/dist/strapi/interfaces/index.js +1 -0
  56. package/dist/strapi/interfaces/media.d.ts +42 -0
  57. package/dist/strapi/interfaces/media.d.ts.map +1 -0
  58. package/dist/strapi/interfaces/media.js +1 -0
  59. package/dist/strapi/route.d.ts +3 -0
  60. package/dist/strapi/route.d.ts.map +1 -0
  61. package/dist/strapi/route.js +61 -0
  62. package/dist/strapi/utils/fileTitle.d.ts +3 -0
  63. package/dist/strapi/utils/fileTitle.d.ts.map +1 -0
  64. package/dist/strapi/utils/fileTitle.js +3 -0
  65. package/dist/strapi/utils/fileUrl.d.ts +3 -0
  66. package/dist/strapi/utils/fileUrl.d.ts.map +1 -0
  67. package/dist/strapi/utils/fileUrl.js +4 -0
  68. package/dist/strapi/utils/imgAlt.d.ts +3 -0
  69. package/dist/strapi/utils/imgAlt.d.ts.map +1 -0
  70. package/dist/strapi/utils/imgAlt.js +3 -0
  71. package/dist/strapi/utils/imgInfo.d.ts +9 -0
  72. package/dist/strapi/utils/imgInfo.d.ts.map +1 -0
  73. package/dist/strapi/utils/imgInfo.js +13 -0
  74. package/dist/strapi/utils/imgSrc.d.ts +8 -0
  75. package/dist/strapi/utils/imgSrc.d.ts.map +1 -0
  76. package/dist/strapi/utils/imgSrc.js +17 -0
  77. package/dist/strapi/utils/index.d.ts +7 -0
  78. package/dist/strapi/utils/index.d.ts.map +1 -0
  79. package/dist/strapi/utils/index.js +6 -0
  80. package/dist/strapi/utils/resource.d.ts +7 -0
  81. package/dist/strapi/utils/resource.d.ts.map +1 -0
  82. package/dist/strapi/utils/resource.js +17 -0
  83. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # @geekron/hono
2
+
3
+ 一个基于 Hono 和 Strapi 的 CMS SDK,提供路由管理和 Strapi 集成功能。
4
+
5
+ ## 特性
6
+
7
+ - 🚀 基于 [Hono](https://hono.dev/) 的高性能路由系统
8
+ - 📦 与 [Strapi](https://strapi.io/) 深度集成
9
+ - 🛠️ TypeScript 支持
10
+ - 🔧 灵活的路由配置
11
+ - 🌐 多语言支持
12
+ - 📝 内容类型管理
13
+ - 🎨 组件化开发
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ bun install @geekron/hono
19
+ ```
20
+
21
+ ## 环境配置
22
+
23
+ 在项目根目录创建 `.env` 文件:
24
+
25
+ ```env
26
+ CMS_URL=http://localhost:1337
27
+ CMS_TOKEN=your_strapi_api_token
28
+ MEDIA_URL=http://localhost:1337 # 可选,默认使用 CMS_URL
29
+ URL_SUFFIX=.html # 可选,默认为 .html
30
+ ```
31
+
32
+ ## 使用方式
33
+
34
+ ### 导入模块
35
+
36
+ 项目提供两个主要模块:
37
+
38
+ ```typescript
39
+ // 导入 Strapi 相关功能
40
+ import { ... } from '@geekron/hono/strapi'
41
+
42
+ // 导入路由相关功能
43
+ import { ... } from '@geekron/hono/route'
44
+ ```
45
+
46
+ ### Strapi 模块
47
+
48
+ Strapi 模块提供了以下功能:
49
+
50
+ - **CMS 管理**: 站点配置、内容类型、组件管理
51
+ - **国际化**: 多语言和翻译支持
52
+ - **菜单管理**: 动态菜单系统
53
+ - **媒体处理**: 图片和文件资源管理
54
+ - **工具函数**: 文件 URL、图片信息等实用工具
55
+
56
+ ```typescript
57
+ import {
58
+ // CMS 核心
59
+ getCMS,
60
+ getSite,
61
+ getContentTypes,
62
+
63
+ // 国际化
64
+ getLocales,
65
+ getTranslations,
66
+
67
+ // 菜单
68
+ getMenu,
69
+
70
+ // 工具函数
71
+ fileUrl,
72
+ imgSrc,
73
+ imgAlt,
74
+ imgInfo,
75
+ } from '@geekron/hono/strapi'
76
+ ```
77
+
78
+ ### 路由模块
79
+
80
+ 路由模块提供灵活的路由配置和管理:
81
+
82
+ ```typescript
83
+ import {
84
+ type RouteItem,
85
+ type RouteItemHandler,
86
+ setupRoutes,
87
+ } from '@geekron/hono/route'
88
+
89
+ // 配置路由
90
+ const routes: RouteItem[] = [
91
+ {
92
+ method: 'GET',
93
+ path: '/',
94
+ name: 'home',
95
+ // ...
96
+ },
97
+ // 更多路由配置
98
+ ]
99
+
100
+ setupRoutes(app, routes)
101
+ ```
102
+
103
+ ### 路由配置选项
104
+
105
+ 路由支持以下配置:
106
+
107
+ - `method`: HTTP 方法(GET, POST 等)
108
+ - `path`: 路由路径
109
+ - `name`: 路由名称(可选,默认为路径的 kebab-case 形式)
110
+ - `suffix`: URL 后缀(可选,默认使用环境变量 `URL_SUFFIX`)
111
+ - `dataType`: 数据类型
112
+ - `sitemap`: 是否包含在站点地图中
113
+
114
+ ## 开发
115
+
116
+ ### 安装依赖
117
+
118
+ ```bash
119
+ bun install
120
+ ```
121
+
122
+ ### 代码格式化
123
+
124
+ ```bash
125
+ bun run format
126
+ ```
127
+
128
+ ### 代码检查
129
+
130
+ ```bash
131
+ bun run lint
132
+ ```
133
+
134
+ ### 完整检查
135
+
136
+ ```bash
137
+ bun run check
138
+ ```
139
+
140
+ ## 项目结构
141
+
142
+ ```
143
+ .
144
+ ├── src/
145
+ │ ├── route/ # 路由模块
146
+ │ │ ├── index.ts # 路由导出
147
+ │ │ ├── interfaces.ts # 路由接口定义
148
+ │ │ ├── methods.ts # HTTP 方法定义
149
+ │ │ ├── setup.ts # 路由设置
150
+ │ │ └── slot.ts # 路由插槽
151
+ │ ├── strapi/ # Strapi 集成模块
152
+ │ │ ├── cms/ # CMS 核心功能
153
+ │ │ ├── interfaces/ # 接口定义
154
+ │ │ ├── utils/ # 工具函数
155
+ │ │ ├── index.ts
156
+ │ │ └── route.ts # Strapi 路由处理
157
+ │ └── contract.ts # 环境变量和配置
158
+ ├── package.json
159
+ └── tsconfig.json
160
+ ```
161
+
162
+ ## 技术栈
163
+
164
+ - [Hono](https://hono.dev/) - 快速、轻量的 Web 框架
165
+ - [Strapi Client](https://www.npmjs.com/package/@strapi/client) - Strapi API 客户端
166
+ - [Voca](https://vocajs.com/) - 字符串处理库
167
+ - [TypeScript](https://www.typescriptlang.org/) - 类型安全
168
+ - [Biome](https://biomejs.dev/) - 代码格式化和检查
169
+
170
+ ## 许可证
171
+
172
+ MIT
173
+
174
+ ## 贡献
175
+
176
+ 欢迎提交 Issue 和 Pull Request!
@@ -0,0 +1,5 @@
1
+ export declare const CMS_URL: string;
2
+ export declare const MEDIA_URL: string;
3
+ export declare const CMS_TOKEN: string | undefined;
4
+ export declare const URL_SUFFIX: string;
5
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,QAAiD,CAAA;AACrE,eAAO,MAAM,SAAS,QAAmC,CAAA;AACzD,eAAO,MAAM,SAAS,oBAAwB,CAAA;AAC9C,eAAO,MAAM,UAAU,QAAoC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export const CMS_URL = process.env.CMS_URL || 'http://localhost:1337';
2
+ export const MEDIA_URL = process.env.MEDIA_URL || CMS_URL;
3
+ export const CMS_TOKEN = process.env.CMS_TOKEN;
4
+ export const URL_SUFFIX = process.env.URL_SUFFIX || '.html';
@@ -0,0 +1,5 @@
1
+ export * from './interfaces';
2
+ export * from './methods';
3
+ export * from './setup';
4
+ export * from './slot';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/route/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './interfaces';
2
+ export * from './methods';
3
+ export * from './setup';
4
+ export * from './slot';
@@ -0,0 +1,35 @@
1
+ import type { Context } from 'hono';
2
+ import type { Variables } from '../route/setup';
3
+ export type RouteHandler = (c: Context<{
4
+ Variables: Variables;
5
+ }>) => Promise<Response> | Response;
6
+ export type RouteMethod = 'get' | 'post' | 'put' | 'all' | 'notFound' | 'onError';
7
+ export interface RouteSitemap {
8
+ disabled?: boolean;
9
+ priority?: number;
10
+ paginate?: number;
11
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
12
+ }
13
+ export interface RouteOption {
14
+ sitemap?: RouteSitemap;
15
+ handler: RouteHandler;
16
+ dataType?: string;
17
+ suffix?: string;
18
+ name?: string;
19
+ }
20
+ export interface RouteItem {
21
+ dataType?: string;
22
+ sitemap?: RouteSitemap;
23
+ method: RouteMethod;
24
+ name: string;
25
+ path: string;
26
+ fullPath: string;
27
+ suffix: string;
28
+ params: string[];
29
+ }
30
+ export interface RouteType {
31
+ dataType: string;
32
+ items: Array<RouteItem>;
33
+ }
34
+ export type RouteItemHandler = (method: 'get' | 'post' | 'put' | 'all') => (path: string, option: RouteOption) => Promise<RouteItem> | RouteItem;
35
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/route/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,MAAM,MAAM,YAAY,GAAG,CAC1B,CAAC,EAAE,OAAO,CAAC;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC,KAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;AAEjC,MAAM,MAAM,WAAW,GACpB,KAAK,GACL,MAAM,GACN,KAAK,GACL,KAAK,GACL,UAAU,GACV,SAAS,CAAA;AAEZ,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EACR,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,CAAA;CACV;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,YAAY,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;CAChB;AACD,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,KAClC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { RouteHandler, RouteItem, RouteOption, RouteType } from './interfaces';
2
+ export declare const route: {
3
+ all: (path: string, option: RouteOption) => void;
4
+ get: (path: string, option: RouteOption) => void;
5
+ post: (path: string, option: RouteOption) => void;
6
+ put: (path: string, option: RouteOption) => void;
7
+ notFound: (handler: RouteHandler) => void;
8
+ onError: (handler: RouteHandler) => void;
9
+ };
10
+ export declare const getRouteItems: () => RouteItem[];
11
+ export declare const getRouteItemByName: (name: string) => RouteItem | undefined;
12
+ export declare const getRouteItemByType: (dataType: string) => RouteType | undefined;
13
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/route/methods.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,MAAM,cAAc,CAAA;AAErB,eAAO,MAAM,KAAK;gBA0CH,MAAM,UAAU,WAAW;gBAA3B,MAAM,UAAU,WAAW;iBAA3B,MAAM,UAAU,WAAW;gBAA3B,MAAM,UAAU,WAAW;wBArCrB,YAAY;uBAMb,YAAY;CAa/B,CAAA;AAKD,eAAO,MAAM,aAAa,mBAEzB,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,0BAE9C,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,0BAElD,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { HTTPException } from 'hono/http-exception';
2
+ import { setup } from '../route/setup';
3
+ import { getContentTypes } from '../strapi';
4
+ export const route = {
5
+ all: method('all'),
6
+ get: method('get'),
7
+ post: method('post'),
8
+ put: method('put'),
9
+ notFound: (handler) => {
10
+ setup.app.notFound(async (c) => {
11
+ c.status(404);
12
+ return handler(c);
13
+ });
14
+ },
15
+ onError: (handler) => {
16
+ setup.app.onError(async (error, c) => {
17
+ console.error(error);
18
+ if (error instanceof HTTPException) {
19
+ if (error.status < 500) {
20
+ c.status(error.status);
21
+ }
22
+ else {
23
+ c.status(400);
24
+ }
25
+ }
26
+ return handler(c);
27
+ });
28
+ },
29
+ };
30
+ const routeItems = [];
31
+ const routeItemByName = new Map();
32
+ const routeItemByType = new Map();
33
+ export const getRouteItems = () => {
34
+ return routeItems;
35
+ };
36
+ export const getRouteItemByName = (name) => {
37
+ return routeItemByName.get(name);
38
+ };
39
+ export const getRouteItemByType = (dataType) => {
40
+ return routeItemByType.get(dataType);
41
+ };
42
+ function method(method) {
43
+ return (path, option) => {
44
+ const types = getContentTypes();
45
+ const app = setup.app;
46
+ const methods = {
47
+ get: app.get.bind(app),
48
+ post: app.post.bind(app),
49
+ put: app.put.bind(app),
50
+ all: app.all.bind(app),
51
+ notFound: app.notFound.bind(app),
52
+ onError: app.onError.bind(app),
53
+ };
54
+ const route = methods[method];
55
+ const handler = setup.routeItemHandler(method);
56
+ Promise.resolve(handler(path, option)).then((routeItem) => {
57
+ const name = routeItem.name;
58
+ if (routeItemByName.has(name)) {
59
+ throw new Error(`Route item name "${name}" already exists`);
60
+ }
61
+ routeItemByName.set(name, routeItem);
62
+ const dataType = routeItem.dataType;
63
+ if (dataType) {
64
+ if (!types.has(dataType)) {
65
+ throw new Error(`Content type "${dataType}" not found`);
66
+ }
67
+ const items = routeItemByType.get(dataType)?.items || [];
68
+ routeItemByType.set(dataType, {
69
+ dataType,
70
+ items: [...items, routeItem],
71
+ });
72
+ }
73
+ routeItems.push(routeItem);
74
+ route(routeItem.fullPath, async (c) => {
75
+ return option.handler(c);
76
+ });
77
+ });
78
+ };
79
+ }
@@ -0,0 +1,18 @@
1
+ import type { Hono } from 'hono';
2
+ import type { Child } from 'hono/jsx';
3
+ import type { RouteItem, RouteItemHandler } from '../route/interfaces';
4
+ export type AppInstance = Hono<{
5
+ Variables: Variables;
6
+ }>;
7
+ export interface Variables {
8
+ app: AppInstance;
9
+ slots: Map<string, Child[]>;
10
+ route: RouteItem;
11
+ }
12
+ export interface SetupRoutesOption {
13
+ app: AppInstance;
14
+ routeItemHandler: RouteItemHandler;
15
+ }
16
+ export declare const setup: SetupRoutesOption;
17
+ export declare const setupRoutes: (paths: string | string[], option: SetupRoutesOption) => Promise<void>;
18
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/route/setup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErE,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC,CAAA;AAExD,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,WAAW,CAAA;IAChB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3B,KAAK,EAAE,SAAS,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,WAAW,CAAA;IAChB,gBAAgB,EAAE,gBAAgB,CAAA;CAClC;AAED,eAAO,MAAM,KAAK,EAAS,iBAAiB,CAAA;AAE5C,eAAO,MAAM,WAAW,GACvB,OAAO,MAAM,GAAG,MAAM,EAAE,EACxB,QAAQ,iBAAiB,kBASzB,CAAA"}
@@ -0,0 +1,11 @@
1
+ import * as fs from 'node:fs';
2
+ export const setup = {};
3
+ export const setupRoutes = async (paths, option) => {
4
+ const { app } = option;
5
+ setup.app = app;
6
+ setup.routeItemHandler = option.routeItemHandler;
7
+ const files = fs.globSync(paths);
8
+ files.forEach((file) => {
9
+ require(file);
10
+ });
11
+ };
@@ -0,0 +1,15 @@
1
+ import type { Context } from 'hono';
2
+ import type { Child } from 'hono/jsx';
3
+ import type { Variables } from '../route/setup';
4
+ export declare const slot: <SlotName extends string>(ctx: Context<{
5
+ Variables: Variables;
6
+ }>) => {
7
+ append: (name: SlotName, content: Child) => Child[];
8
+ parse: (render: (ctx: Context<{
9
+ Variables: Variables;
10
+ }>) => Promise<Child> | Child) => Promise<{
11
+ content: string | undefined;
12
+ slots: Map<SlotName, Child[]>;
13
+ }>;
14
+ };
15
+ //# sourceMappingURL=slot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../../src/route/slot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,eAAO,MAAM,IAAI,GAAI,QAAQ,SAAS,MAAM,EAC3C,KAAK,OAAO,CAAC;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,CAAC;mBAGtB,QAAQ,WAAW,KAAK;oBAe9B,CACP,GAAG,EAAE,OAAO,CAAC;QAAE,SAAS,EAAE,SAAS,CAAA;KAAE,CAAC,KAClC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK;;;;CAe7B,CAAA"}
@@ -0,0 +1,28 @@
1
+ export const slot = (ctx) => {
2
+ return {
3
+ append: (name, content) => {
4
+ const slots = ctx.get('slots') || new Map();
5
+ let slot = slots.get(name) || [];
6
+ if (!content)
7
+ return slot;
8
+ if (!Array.isArray(content)) {
9
+ content = [content];
10
+ }
11
+ slot = [...slot, ...content];
12
+ slot = slot.filter(Boolean);
13
+ slots.set(name, slot);
14
+ ctx.set('slots', slots);
15
+ return slot;
16
+ },
17
+ parse: async (render) => {
18
+ // 【第一阶段】渲染内容并强制执行,触发所有组件的 slot.append
19
+ const preContent = await render(ctx);
20
+ // 使用 toString() 方法强制渲染(支持异步组件)
21
+ // 这会触发所有子组件执行,slot.append 生效
22
+ const content = await preContent?.toString();
23
+ // 【第二阶段】获取已收集的 slots
24
+ const slots = (ctx.get('slots') || new Map());
25
+ return { content, slots };
26
+ },
27
+ };
28
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 创建CMS客户端
3
+ */
4
+ export declare const cms: import("@strapi/client").StrapiClient;
5
+ /**
6
+ * 获取CMS客户端
7
+ */
8
+ export declare const getCMS: () => import("@strapi/client").StrapiClient;
9
+ /**
10
+ * 检查CMS状态
11
+ */
12
+ export declare const cmsStatus: () => Promise<boolean>;
13
+ /**
14
+ * 检查CMS状态
15
+ */
16
+ export declare const checkCmsStatus: () => Promise<void>;
17
+ //# sourceMappingURL=cms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms.d.ts","sourceRoot":"","sources":["../../../src/strapi/cms/cms.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,GAAG,uCAGd,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,6CAElB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,wBAUrB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,qBAqB1B,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { strapi } from '@strapi/client';
2
+ import { CMS_TOKEN, CMS_URL } from '../../contract';
3
+ /**
4
+ * 创建CMS客户端
5
+ */
6
+ export const cms = strapi({
7
+ baseURL: `${CMS_URL}/api`,
8
+ auth: CMS_TOKEN,
9
+ });
10
+ /**
11
+ * 获取CMS客户端
12
+ */
13
+ export const getCMS = () => {
14
+ return cms;
15
+ };
16
+ /**
17
+ * 检查CMS状态
18
+ */
19
+ export const cmsStatus = async () => {
20
+ try {
21
+ const checkUrl = `${CMS_URL}/dashboard/website/hello`;
22
+ const response = await fetch(checkUrl);
23
+ console.log('✅ API health check response:', response.statusText);
24
+ return response.ok;
25
+ }
26
+ catch (error) {
27
+ console.error('❌ Error checking API health:', error);
28
+ return false;
29
+ }
30
+ };
31
+ /**
32
+ * 检查CMS状态
33
+ */
34
+ export const checkCmsStatus = async () => {
35
+ let attempts = 0;
36
+ const maxAttempts = 30; // 最多尝试30秒
37
+ while (attempts < maxAttempts) {
38
+ try {
39
+ console.log(`第 ${attempts + 1} 次尝试检查CMS状态...`);
40
+ const status = await cmsStatus();
41
+ if (status) {
42
+ console.log('✅ CMS状态:', 'OK');
43
+ return;
44
+ }
45
+ else {
46
+ console.log('❌ CMS状态:', '异常,继续检查...');
47
+ }
48
+ }
49
+ catch (error) {
50
+ console.error('❌ 获取CMS状态时发生错误:', error);
51
+ }
52
+ attempts++;
53
+ await new Promise((resolve) => setTimeout(resolve, 1000));
54
+ }
55
+ console.log('达到最大尝试次数');
56
+ throw new Error('CMS状态: 异常,请检查CMS是否正常启动');
57
+ };
@@ -0,0 +1,9 @@
1
+ export interface Common {
2
+ [key: string]: any;
3
+ }
4
+ export type CommonPopulate = string | string[] | Record<string, unknown>;
5
+ export declare const setCommon: (common: Common) => void;
6
+ export declare const getCommon: <T = Common>() => T;
7
+ export declare const fetchCommon: (populate?: CommonPopulate, refresh?: boolean) => Promise<Common>;
8
+ export declare const initCommon: (populate?: CommonPopulate, refresh?: boolean) => Promise<Common>;
9
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/strapi/cms/common.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAClB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAGxE,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,SAEvC,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,GAAG,MAAM,OAKlB,CACjB,CAAA;AAED,eAAO,MAAM,WAAW,GACvB,WAAU,cAAoB,EAC9B,iBAAe,oBAGf,CAAA;AAED,eAAO,MAAM,UAAU,GACtB,WAAU,cAAoB,EAC9B,iBAAc,oBAcd,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { cms } from './cms';
2
+ const cache = new Map();
3
+ export const setCommon = (common) => {
4
+ cache.set('common', common);
5
+ };
6
+ export const getCommon = () => {
7
+ const common = cache.get('common');
8
+ if (!common) {
9
+ throw new Error('common not found');
10
+ }
11
+ return common;
12
+ };
13
+ export const fetchCommon = async (populate = '*', refresh = false) => {
14
+ return await initCommon(populate, refresh);
15
+ };
16
+ export const initCommon = async (populate = '*', refresh = true) => {
17
+ if (refresh)
18
+ cache.clear();
19
+ if (cache.has('common')) {
20
+ return Promise.resolve(cache.get('common'));
21
+ }
22
+ const common = await cms
23
+ .single('common')
24
+ .find({
25
+ populate,
26
+ })
27
+ .then((res) => res.data);
28
+ setCommon(common);
29
+ return getCommon();
30
+ };
@@ -0,0 +1,20 @@
1
+ export interface ComponentSchema {
2
+ displayName: string;
3
+ description: string;
4
+ icon?: string;
5
+ collectionName: string;
6
+ attributes: {
7
+ [key: string]: Record<string, any>;
8
+ };
9
+ }
10
+ export interface Component {
11
+ uid: string;
12
+ category: string;
13
+ apiId: string;
14
+ schema: ComponentSchema;
15
+ }
16
+ export declare const getComponents: () => Map<string, Component>;
17
+ export declare const getComponent: (uid: string) => Component | undefined;
18
+ export declare const fetchComponents: (refresh?: boolean) => Promise<Map<string, Component>>;
19
+ export declare const initComponents: (refresh?: boolean) => Promise<Map<string, Component>>;
20
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/strapi/cms/components.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE;QACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAClC,CAAA;CACD;AAED,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,eAAe,CAAA;CACvB;AAID,eAAO,MAAM,aAAa,8BAKzB,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,0BAEvC,CAAA;AAED,eAAO,MAAM,eAAe,GAAU,iBAAe,oCAEpD,CAAA;AAED,eAAO,MAAM,cAAc,GAAU,iBAAc,oCAgBlD,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { cms } from './cms';
2
+ const components = new Map();
3
+ export const getComponents = () => {
4
+ if (components.size === 0) {
5
+ throw new Error('No components found');
6
+ }
7
+ return components;
8
+ };
9
+ export const getComponent = (uid) => {
10
+ return components.get(uid);
11
+ };
12
+ export const fetchComponents = async (refresh = false) => {
13
+ return await initComponents(refresh);
14
+ };
15
+ export const initComponents = async (refresh = true) => {
16
+ try {
17
+ if (refresh)
18
+ components.clear();
19
+ if (components.size > 0) {
20
+ return Promise.resolve(components);
21
+ }
22
+ const res = await cms.fetch('/content-type-builder/components');
23
+ const { data } = await res.json();
24
+ data?.forEach((item) => {
25
+ components.set(item.uid, item);
26
+ });
27
+ return components;
28
+ }
29
+ catch (error) {
30
+ console.error('components error', error);
31
+ return new Map();
32
+ }
33
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 内容类型定义
3
+ */
4
+ export interface ContentTypeSchema {
5
+ draftAndPublish: boolean;
6
+ displayName: string;
7
+ singularName: string;
8
+ pluralName: string;
9
+ description: string;
10
+ pluginOptions: {
11
+ 'content-manager': Record<string, any>;
12
+ 'content-type-builder': Record<string, any>;
13
+ };
14
+ kind: 'collectionType' | 'singleType';
15
+ collectionName: string;
16
+ attributes: {
17
+ [key: string]: Record<string, any>;
18
+ };
19
+ visible: boolean;
20
+ restrictRelationsTo: string[];
21
+ }
22
+ /**
23
+ * 内容类型
24
+ */
25
+ export interface ContentType {
26
+ uid: string;
27
+ plugin: string;
28
+ apiID: string;
29
+ schema: ContentTypeSchema;
30
+ }
31
+ /**
32
+ * 获取内容类型集合
33
+ */
34
+ export declare const getContentTypes: () => Map<string, ContentType>;
35
+ /**
36
+ * 获取内容类型
37
+ * @param uid
38
+ */
39
+ export declare const getContentType: (uid: string) => ContentType | undefined;
40
+ /**
41
+ * 获取内容类型
42
+ */
43
+ export declare const fetchContentTypes: (refresh?: boolean) => Promise<Map<string, ContentType>>;
44
+ /**
45
+ * 初始化内容类型
46
+ */
47
+ export declare const initContentTypes: (refresh?: boolean) => Promise<Map<string, ContentType>>;
48
+ //# sourceMappingURL=content-types.d.ts.map