@geekron/hono 0.1.0 → 0.1.2

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 (180) hide show
  1. package/dist/contract.d.ts +9 -1
  2. package/dist/contract.d.ts.map +1 -1
  3. package/dist/contract.js +14 -3
  4. package/dist/core/api/common.d.ts +2 -0
  5. package/dist/core/api/common.d.ts.map +1 -0
  6. package/dist/core/api/common.js +38 -0
  7. package/dist/core/api/inquiries.d.ts +2 -0
  8. package/dist/core/api/inquiries.d.ts.map +1 -0
  9. package/dist/core/api/inquiries.js +116 -0
  10. package/dist/core/api/inquiry.d.ts +2 -0
  11. package/dist/core/api/inquiry.d.ts.map +1 -0
  12. package/dist/core/api/inquiry.js +33 -0
  13. package/dist/core/api/visitor.d.ts +2 -0
  14. package/dist/core/api/visitor.d.ts.map +1 -0
  15. package/dist/core/api/visitor.js +152 -0
  16. package/dist/core/components/InquiryEmailTemplate.d.ts +30 -0
  17. package/dist/core/components/InquiryEmailTemplate.d.ts.map +1 -0
  18. package/dist/core/components/InquiryEmailTemplate.js +13 -0
  19. package/dist/core/components/Seo.d.ts +97 -0
  20. package/dist/core/components/Seo.d.ts.map +1 -0
  21. package/dist/core/components/Seo.js +365 -0
  22. package/dist/core/components/index.d.ts +3 -0
  23. package/dist/core/components/index.d.ts.map +1 -0
  24. package/dist/core/components/index.js +2 -0
  25. package/dist/core/index.d.ts +4 -0
  26. package/dist/core/index.d.ts.map +1 -0
  27. package/dist/core/index.js +3 -0
  28. package/dist/core/lib/constants/inquiry.d.ts +52 -0
  29. package/dist/core/lib/constants/inquiry.d.ts.map +1 -0
  30. package/dist/core/lib/constants/inquiry.js +51 -0
  31. package/dist/core/lib/constants/visitor.d.ts +29 -0
  32. package/dist/core/lib/constants/visitor.d.ts.map +1 -0
  33. package/dist/core/lib/constants/visitor.js +28 -0
  34. package/dist/core/lib/database/constants/database.d.ts +15 -0
  35. package/dist/core/lib/database/constants/database.d.ts.map +1 -0
  36. package/dist/core/lib/database/constants/database.js +14 -0
  37. package/dist/core/lib/database/database.service.d.ts +63 -0
  38. package/dist/core/lib/database/database.service.d.ts.map +1 -0
  39. package/dist/core/lib/database/database.service.js +108 -0
  40. package/dist/core/lib/database/index.d.ts +8 -0
  41. package/dist/core/lib/database/index.d.ts.map +1 -0
  42. package/dist/core/lib/database/index.js +7 -0
  43. package/dist/core/lib/database/managers/sqlite.d.ts +29 -0
  44. package/dist/core/lib/database/managers/sqlite.d.ts.map +1 -0
  45. package/dist/core/lib/database/managers/sqlite.js +55 -0
  46. package/dist/core/lib/database/managers/visitor-shard.d.ts +29 -0
  47. package/dist/core/lib/database/managers/visitor-shard.d.ts.map +1 -0
  48. package/dist/core/lib/database/managers/visitor-shard.js +83 -0
  49. package/dist/core/lib/database/repositories/inquiry.repository.d.ts +33 -0
  50. package/dist/core/lib/database/repositories/inquiry.repository.d.ts.map +1 -0
  51. package/dist/core/lib/database/repositories/inquiry.repository.js +173 -0
  52. package/dist/core/lib/database/repositories/visitor.repository.d.ts +51 -0
  53. package/dist/core/lib/database/repositories/visitor.repository.d.ts.map +1 -0
  54. package/dist/core/lib/database/repositories/visitor.repository.js +559 -0
  55. package/dist/core/lib/database/schemas/inquiry.schema.d.ts +323 -0
  56. package/dist/core/lib/database/schemas/inquiry.schema.d.ts.map +1 -0
  57. package/dist/core/lib/database/schemas/inquiry.schema.js +52 -0
  58. package/dist/core/lib/database/schemas/visitor.schema.d.ts +623 -0
  59. package/dist/core/lib/database/schemas/visitor.schema.d.ts.map +1 -0
  60. package/dist/core/lib/database/schemas/visitor.schema.js +162 -0
  61. package/dist/core/lib/services/captcha.service.d.ts +13 -0
  62. package/dist/core/lib/services/captcha.service.d.ts.map +1 -0
  63. package/dist/core/lib/services/captcha.service.js +40 -0
  64. package/dist/core/lib/services/geoip.service.d.ts +79 -0
  65. package/dist/core/lib/services/geoip.service.d.ts.map +1 -0
  66. package/dist/core/lib/services/geoip.service.js +144 -0
  67. package/dist/core/lib/services/index.d.ts +9 -0
  68. package/dist/core/lib/services/index.d.ts.map +1 -0
  69. package/dist/core/lib/services/index.js +8 -0
  70. package/dist/core/lib/services/inquiry.service.d.ts +56 -0
  71. package/dist/core/lib/services/inquiry.service.d.ts.map +1 -0
  72. package/dist/core/lib/services/inquiry.service.js +129 -0
  73. package/dist/core/lib/services/mailer.service.d.ts +23 -0
  74. package/dist/core/lib/services/mailer.service.d.ts.map +1 -0
  75. package/dist/core/lib/services/mailer.service.js +96 -0
  76. package/dist/core/lib/types/inquiry.d.ts +95 -0
  77. package/dist/core/lib/types/inquiry.d.ts.map +1 -0
  78. package/dist/core/lib/types/inquiry.js +1 -0
  79. package/dist/core/lib/types/visitor.d.ts +135 -0
  80. package/dist/core/lib/types/visitor.d.ts.map +1 -0
  81. package/dist/core/lib/types/visitor.js +1 -0
  82. package/dist/core/lib/utils/api.d.ts +25 -0
  83. package/dist/core/lib/utils/api.d.ts.map +1 -0
  84. package/dist/core/lib/utils/api.js +48 -0
  85. package/dist/core/lib/utils/request.d.ts +18 -0
  86. package/dist/core/lib/utils/request.d.ts.map +1 -0
  87. package/dist/core/lib/utils/request.js +25 -0
  88. package/dist/core/middlewares/api-guard.d.ts +39 -0
  89. package/dist/core/middlewares/api-guard.d.ts.map +1 -0
  90. package/dist/core/middlewares/api-guard.js +154 -0
  91. package/dist/core/middlewares/html-minifier.d.ts +55 -0
  92. package/dist/core/middlewares/html-minifier.d.ts.map +1 -0
  93. package/dist/core/middlewares/html-minifier.js +140 -0
  94. package/dist/core/middlewares/index.d.ts +5 -0
  95. package/dist/core/middlewares/index.d.ts.map +1 -0
  96. package/dist/core/middlewares/index.js +4 -0
  97. package/dist/core/middlewares/initializer.d.ts +11 -0
  98. package/dist/core/middlewares/initializer.d.ts.map +1 -0
  99. package/dist/core/middlewares/initializer.js +13 -0
  100. package/dist/core/middlewares/visitor-tracker.d.ts +85 -0
  101. package/dist/core/middlewares/visitor-tracker.d.ts.map +1 -0
  102. package/dist/core/middlewares/visitor-tracker.js +253 -0
  103. package/dist/core/template.d.ts +4 -0
  104. package/dist/core/template.d.ts.map +1 -0
  105. package/dist/core/template.js +7 -0
  106. package/dist/core/utils/formatDate.d.ts +3 -0
  107. package/dist/core/utils/formatDate.d.ts.map +1 -0
  108. package/dist/core/utils/formatDate.js +2 -0
  109. package/dist/core/utils/fullUrl.d.ts +2 -0
  110. package/dist/core/utils/fullUrl.d.ts.map +1 -0
  111. package/dist/core/utils/fullUrl.js +9 -0
  112. package/dist/core/utils/index.d.ts +6 -0
  113. package/dist/core/utils/index.d.ts.map +1 -0
  114. package/dist/core/utils/index.js +5 -0
  115. package/dist/core/utils/markdownify.d.ts +2 -0
  116. package/dist/core/utils/markdownify.d.ts.map +1 -0
  117. package/dist/core/utils/markdownify.js +4 -0
  118. package/dist/core/utils/params.d.ts +5 -0
  119. package/dist/core/utils/params.d.ts.map +1 -0
  120. package/dist/core/utils/params.js +14 -0
  121. package/dist/core/utils/routeUrl.d.ts +20 -0
  122. package/dist/core/utils/routeUrl.d.ts.map +1 -0
  123. package/dist/core/utils/routeUrl.js +111 -0
  124. package/dist/route/methods.d.ts +15 -0
  125. package/dist/route/methods.d.ts.map +1 -1
  126. package/dist/route/methods.js +45 -18
  127. package/dist/route/setup.d.ts +11 -12
  128. package/dist/route/setup.d.ts.map +1 -1
  129. package/dist/route/setup.js +26 -16
  130. package/dist/strapi/api/site.d.ts +2 -0
  131. package/dist/strapi/api/site.d.ts.map +1 -0
  132. package/dist/strapi/api/site.js +153 -0
  133. package/dist/strapi/cms/cms.js +1 -1
  134. package/dist/strapi/cms/common.d.ts.map +1 -1
  135. package/dist/strapi/cms/common.js +3 -1
  136. package/dist/strapi/cms/menu.d.ts +0 -9
  137. package/dist/strapi/cms/menu.d.ts.map +1 -1
  138. package/dist/strapi/cms/menu.js +3 -62
  139. package/dist/strapi/cms/setup.d.ts +2 -1
  140. package/dist/strapi/cms/setup.d.ts.map +1 -1
  141. package/dist/strapi/cms/setup.js +5 -0
  142. package/dist/strapi/cms/site.d.ts.map +1 -1
  143. package/dist/strapi/cms/site.js +3 -1
  144. package/dist/strapi/cms/translations.d.ts.map +1 -1
  145. package/dist/strapi/cms/translations.js +6 -2
  146. package/dist/strapi/i18n.d.ts +3 -0
  147. package/dist/strapi/i18n.d.ts.map +1 -0
  148. package/dist/strapi/i18n.js +27 -0
  149. package/dist/strapi/index.d.ts +1 -0
  150. package/dist/strapi/index.d.ts.map +1 -1
  151. package/dist/strapi/index.js +1 -0
  152. package/dist/strapi/interfaces/index.d.ts +1 -0
  153. package/dist/strapi/interfaces/index.d.ts.map +1 -1
  154. package/dist/strapi/interfaces/index.js +1 -0
  155. package/dist/strapi/interfaces/sitemap.d.ts +19 -0
  156. package/dist/strapi/interfaces/sitemap.d.ts.map +1 -0
  157. package/dist/strapi/interfaces/sitemap.js +1 -0
  158. package/dist/strapi/pages/sitemap/index.d.ts +2 -0
  159. package/dist/strapi/pages/sitemap/index.d.ts.map +1 -0
  160. package/dist/strapi/pages/sitemap/index.js +50 -0
  161. package/dist/strapi/pages/sitemap/index.xml +11 -0
  162. package/dist/strapi/pages/sitemap/list.d.ts +2 -0
  163. package/dist/strapi/pages/sitemap/list.d.ts.map +1 -0
  164. package/dist/strapi/pages/sitemap/list.js +123 -0
  165. package/dist/strapi/pages/sitemap/list.xml +28 -0
  166. package/dist/strapi/pages/sitemap/robots.d.ts +2 -0
  167. package/dist/strapi/pages/sitemap/robots.d.ts.map +1 -0
  168. package/dist/strapi/pages/sitemap/robots.js +19 -0
  169. package/dist/strapi/pages/sitemap/robots.txt +7 -0
  170. package/dist/strapi/pages/sitemap/style.d.ts +2 -0
  171. package/dist/strapi/pages/sitemap/style.d.ts.map +1 -0
  172. package/dist/strapi/pages/sitemap/style.js +17 -0
  173. package/dist/strapi/pages/sitemap/style.xsl +602 -0
  174. package/dist/strapi/utils/index.d.ts +1 -0
  175. package/dist/strapi/utils/index.d.ts.map +1 -1
  176. package/dist/strapi/utils/index.js +1 -0
  177. package/dist/strapi/utils/trans.d.ts +5 -0
  178. package/dist/strapi/utils/trans.d.ts.map +1 -0
  179. package/dist/strapi/utils/trans.js +7 -0
  180. package/package.json +20 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../../src/core/utils/params.ts"],"names":[],"mappings":"AAGA,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;AACxD,wBAAgB,MAAM,IAAI;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { getContext } from 'hono/context-storage';
2
+ export function params(name) {
3
+ const ctx = getContext();
4
+ const params = ctx.req.param();
5
+ for (const key in params) {
6
+ params[key] = params[key].split('.')[0] || '';
7
+ }
8
+ if (name) {
9
+ return (name in params ? params[name] : undefined);
10
+ }
11
+ else {
12
+ return params;
13
+ }
14
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 构建路由URL
3
+ * @param paths 路由路径数组,例如 ['/articles/:slug', '/articles/:slug/:page', '/articles/:page']
4
+ * @param params 路径参数对象,例如 { slug: 'haha', page: 1 }
5
+ * @param query 额外的query参数对象
6
+ * @param option 配置选项,包含 suffix 后缀(默认 '.html')
7
+ * @returns 构建好的URL字符串
8
+ *
9
+ * 实现逻辑:
10
+ * 1. 从多个路径中选择能匹配最多参数的路径
11
+ * 2. 如果路径参数缺失,则该路径不可用
12
+ * 3. 当多个路径得分相同时,优先选择不包含分页参数的路径
13
+ * 4. 未在路径中使用的参数作为query参数
14
+ */
15
+ export interface RouteUrlOption {
16
+ suffix?: string;
17
+ baseUrl?: string;
18
+ }
19
+ export declare const routeUrl: (path: string | string[], params?: any, query?: any, option?: RouteUrlOption) => string;
20
+ //# sourceMappingURL=routeUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeUrl.d.ts","sourceRoot":"","sources":["../../../src/core/utils/routeUrl.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,cAAc;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AA4ID,eAAO,MAAM,QAAQ,GACpB,MAAM,MAAM,GAAG,MAAM,EAAE,EACvB,SAAQ,GAAQ,EAChB,QAAO,GAAQ,EACf,SAAQ,cAAmB,WAO3B,CAAA"}
@@ -0,0 +1,111 @@
1
+ import { trim } from 'radash';
2
+ import { URL_SUFFIX } from '../../contract';
3
+ const buildRouteUrl = (paths, params = {}, query = {}, option = {
4
+ suffix: URL_SUFFIX,
5
+ }) => {
6
+ // 删除路径参数中值为undefined的参数
7
+ for (const key in params) {
8
+ if (key in params && params[key] === undefined) {
9
+ delete params[key];
10
+ }
11
+ }
12
+ // 删除query参数中值为undefined的参数
13
+ for (const key in query) {
14
+ if (key in query && query[key] === undefined) {
15
+ delete query[key];
16
+ }
17
+ }
18
+ // 提取路径中的参数
19
+ const extractParams = (path) => {
20
+ const matches = path.match(/:[a-zA-Z_][a-zA-Z0-9_]*/g);
21
+ return matches ? matches.map((m) => m.slice(1)) : [];
22
+ };
23
+ // 分页相关参数列表
24
+ const paginationParams = ['page', 'pageNum', 'pageSize', 'limit', 'offset'];
25
+ const paramKeys = Object.keys(params);
26
+ // 为每个路径计算匹配分数
27
+ const pathScores = paths.map((path) => {
28
+ const pathParams = extractParams(path);
29
+ // 检查路径参数是否都能被满足
30
+ const allParamsSatisfied = pathParams.every((param) => params[param] !== undefined);
31
+ // 如果有参数缺失,这个路径不可用
32
+ if (!allParamsSatisfied) {
33
+ return { path, score: -1, pathParams, canUse: false };
34
+ }
35
+ // 计算匹配的参数数量
36
+ const score = pathParams.length;
37
+ return { path, score, pathParams, canUse: true };
38
+ });
39
+ // 过滤掉不可用的路径
40
+ const validPaths = pathScores.filter((p) => p.canUse);
41
+ if (validPaths.length === 0) {
42
+ throw new Error('No valid path found for the given parameters');
43
+ }
44
+ // 选择分数最高的路径
45
+ let selectedPath = validPaths.reduce((best, current) => {
46
+ return current.score > best.score ? current : best;
47
+ });
48
+ // 检查特殊情况:当有多个路径得分相同时,优先选择不包含分页参数的路径
49
+ const maxScore = selectedPath.score;
50
+ const sameScoringPaths = validPaths.filter((p) => p.score === maxScore);
51
+ if (sameScoringPaths.length > 1) {
52
+ const userHasPagination = paramKeys.some((p) => paginationParams.includes(p));
53
+ const userHasNonPagination = paramKeys.some((p) => !paginationParams.includes(p));
54
+ // 如果用户同时提供了分页和非分页参数
55
+ if (userHasPagination && userHasNonPagination) {
56
+ // 优先选择不包含分页参数的路径
57
+ for (const pathInfo of sameScoringPaths) {
58
+ const thisHasPagination = pathInfo.pathParams.some((p) => paginationParams.includes(p));
59
+ if (!thisHasPagination) {
60
+ selectedPath = pathInfo;
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ // 构建URL
67
+ let url = selectedPath.path;
68
+ const usedParams = new Set();
69
+ // 替换路径参数
70
+ for (const param of selectedPath.pathParams) {
71
+ const value = params[param];
72
+ if (value !== undefined) {
73
+ url = url.replace(`:${param}`, String(value));
74
+ usedParams.add(param);
75
+ }
76
+ }
77
+ // 处理query参数:未使用的params作为query
78
+ const queryParams = { ...query };
79
+ for (const [key, value] of Object.entries(params)) {
80
+ if (!usedParams.has(key)) {
81
+ queryParams[key] = value;
82
+ }
83
+ }
84
+ // 构建query字符串
85
+ const queryString = Object.entries(queryParams)
86
+ .map(([key, value]) => `${key}=${value}`)
87
+ .join('&');
88
+ // 去除多余的斜杠
89
+ url = `/${trim(url, '/')}`;
90
+ // 添加 baseUrl
91
+ if (option.baseUrl) {
92
+ url = `${trim(option.baseUrl, '/')}/${trim(url, '/')}`;
93
+ }
94
+ // 如果有query参数,不添加后缀
95
+ if (queryString) {
96
+ return `${url}?${queryString}`;
97
+ }
98
+ // 没有query参数时才添加后缀
99
+ if (option.suffix && url !== '/' && url) {
100
+ url = `${url}.${trim(option.suffix, '.').toLowerCase()}`;
101
+ }
102
+ return url;
103
+ };
104
+ export const routeUrl = (path, params = {}, query = {}, option = {}) => {
105
+ if (typeof path === 'string')
106
+ path = [path];
107
+ if (option.suffix === undefined) {
108
+ option.suffix = URL_SUFFIX;
109
+ }
110
+ return buildRouteUrl(path, params, query, option);
111
+ };
@@ -1,4 +1,15 @@
1
1
  import type { RouteHandler, RouteItem, RouteOption, RouteType } from './interfaces';
2
+ interface PendingRoute {
3
+ method: 'get' | 'post' | 'put' | 'all';
4
+ path: string;
5
+ option: RouteOption;
6
+ }
7
+ declare global {
8
+ var __pendingRoutes: PendingRoute[];
9
+ }
10
+ declare global {
11
+ var __route_module_initialized: boolean;
12
+ }
2
13
  export declare const route: {
3
14
  all: (path: string, option: RouteOption) => void;
4
15
  get: (path: string, option: RouteOption) => void;
@@ -8,6 +19,10 @@ export declare const route: {
8
19
  onError: (handler: RouteHandler) => void;
9
20
  };
10
21
  export declare const getRouteItems: () => RouteItem[];
22
+ export declare const getRouteTypes: () => Map<string, RouteType>;
11
23
  export declare const getRouteItemByName: (name: string) => RouteItem | undefined;
12
24
  export declare const getRouteItemByType: (dataType: string) => RouteType | undefined;
25
+ export declare const getPendingRoutes: () => PendingRoute[];
26
+ export declare const bindRoutes: (app: any, routeItemHandler: any) => Promise<void>;
27
+ export {};
13
28
  //# sourceMappingURL=methods.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/route/methods.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,MAAM,cAAc,CAAA;AAMrB,UAAU,YAAY;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAA;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,WAAW,CAAA;CACnB;AAGD,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,eAAe,EAAE,YAAY,EAAE,CAAA;CACnC;AAQD,OAAO,CAAC,MAAM,CAAC;IACd,IAAI,0BAA0B,EAAE,OAAO,CAAA;CACvC;AAaD,eAAO,MAAM,KAAK;gBAyFH,MAAM,UAAU,WAAW;gBAA3B,MAAM,UAAU,WAAW;iBAA3B,MAAM,UAAU,WAAW;gBAA3B,MAAM,UAAU,WAAW;wBApFrB,YAAY;uBAMb,YAAY;CAa/B,CAAA;AAED,eAAO,MAAM,aAAa,mBAEzB,CAAA;AACD,eAAO,MAAM,aAAa,8BAEzB,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,0BAE9C,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,0BAElD,CAAA;AAED,eAAO,MAAM,gBAAgB,sBAE5B,CAAA;AAED,eAAO,MAAM,UAAU,GAAU,KAAK,GAAG,EAAE,kBAAkB,GAAG,kBAyC/D,CAAA"}
@@ -1,6 +1,22 @@
1
1
  import { HTTPException } from 'hono/http-exception';
2
2
  import { setup } from '../route/setup';
3
- import { getContentTypes } from '../strapi';
3
+ import { fetchContentTypes } from '../strapi';
4
+ const routeItems = [];
5
+ const routeItemByName = new Map();
6
+ const routeItemByType = new Map();
7
+ if (!global.__pendingRoutes) {
8
+ global.__pendingRoutes = [];
9
+ }
10
+ const pendingRoutes = global.__pendingRoutes;
11
+ if (typeof global !== 'undefined' && global) {
12
+ if (!global.__route_module_initialized) {
13
+ global.__route_module_initialized = true;
14
+ console.log('Route module initialized');
15
+ }
16
+ else {
17
+ console.log('Route module re-initialized, but using persistent pendingRoutes');
18
+ }
19
+ }
4
20
  export const route = {
5
21
  all: method('all'),
6
22
  get: method('get'),
@@ -27,32 +43,32 @@ export const route = {
27
43
  });
28
44
  },
29
45
  };
30
- const routeItems = [];
31
- const routeItemByName = new Map();
32
- const routeItemByType = new Map();
33
46
  export const getRouteItems = () => {
34
47
  return routeItems;
35
48
  };
49
+ export const getRouteTypes = () => {
50
+ return routeItemByType;
51
+ };
36
52
  export const getRouteItemByName = (name) => {
37
53
  return routeItemByName.get(name);
38
54
  };
39
55
  export const getRouteItemByType = (dataType) => {
40
56
  return routeItemByType.get(dataType);
41
57
  };
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);
58
+ export const getPendingRoutes = () => {
59
+ return pendingRoutes;
60
+ };
61
+ export const bindRoutes = async (app, routeItemHandler) => {
62
+ const types = await fetchContentTypes();
63
+ const methods = {
64
+ get: app.get.bind(app),
65
+ post: app.post.bind(app),
66
+ put: app.put.bind(app),
67
+ all: app.all.bind(app),
68
+ };
69
+ pendingRoutes.forEach(({ method: methodType, path, option }) => {
70
+ const route = methods[methodType];
71
+ const handler = routeItemHandler(methodType);
56
72
  Promise.resolve(handler(path, option)).then((routeItem) => {
57
73
  const name = routeItem.name;
58
74
  if (routeItemByName.has(name)) {
@@ -75,5 +91,16 @@ function method(method) {
75
91
  return option.handler(c);
76
92
  });
77
93
  });
94
+ });
95
+ // 清空已处理的路由,防止重复处理
96
+ pendingRoutes.length = 0;
97
+ };
98
+ function method(method) {
99
+ return (path, option) => {
100
+ pendingRoutes.push({
101
+ method,
102
+ path,
103
+ option,
104
+ });
78
105
  };
79
106
  }
@@ -2,28 +2,27 @@ import type { Hono } from 'hono';
2
2
  import type { Child } from 'hono/jsx';
3
3
  import type { RouteItem, RouteItemHandler } from '../route/interfaces';
4
4
  declare const providers: {
5
- strapi: {
6
- routeItemHandler: RouteItemHandler;
7
- checkCmsStatus: () => Promise<void>;
8
- };
5
+ strapi: {};
9
6
  };
10
- export type AppInstance = Hono<{
11
- Variables: Variables;
12
- }>;
13
7
  export interface Variables {
14
- app: AppInstance;
8
+ app: Hono<{
9
+ Variables: Variables;
10
+ }>;
15
11
  slots: Map<string, Child[]>;
16
12
  route: RouteItem;
17
13
  }
18
14
  export interface SetupRoutesSetup {
19
- app: AppInstance;
20
15
  cms: keyof typeof providers;
16
+ app: Hono<{
17
+ Variables: Variables;
18
+ }>;
21
19
  routeItemHandler: RouteItemHandler;
22
20
  }
23
- export interface SetupRoutesOption extends Partial<SetupRoutesSetup> {
24
- app: AppInstance;
21
+ export interface SetupRoutesOption {
22
+ cms: keyof typeof providers;
23
+ routeItemHandler: RouteItemHandler;
25
24
  }
26
25
  export declare const setup: SetupRoutesSetup;
27
- export declare const setupRoutes: (paths: string | string[], option: SetupRoutesOption) => Promise<void>;
26
+ export declare const setupRoutes: (app: Hono, paths: string | string[], option: SetupRoutesOption) => Promise<void>;
28
27
  export {};
29
28
  //# sourceMappingURL=setup.d.ts.map
@@ -1 +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;AAKrE,QAAA,MAAM,SAAS;;;;;CAKd,CAAA;AAED,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,gBAAgB;IAChC,GAAG,EAAE,WAAW,CAAA;IAChB,GAAG,EAAE,MAAM,OAAO,SAAS,CAAA;IAC3B,gBAAgB,EAAE,gBAAgB,CAAA;CAClC;AAED,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IACnE,GAAG,EAAE,WAAW,CAAA;CAChB;AAED,eAAO,MAAM,KAAK,EAAS,gBAAgB,CAAA;AAC3C,eAAO,MAAM,WAAW,GACvB,OAAO,MAAM,GAAG,MAAM,EAAE,EACxB,QAAQ,iBAAiB,kBAYzB,CAAA"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/route/setup.ts"],"names":[],"mappings":"AAEA,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;AAGrE,QAAA,MAAM,SAAS;;CAEd,CAAA;AAED,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,IAAI,CAAC;QAAE,SAAS,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;IACnC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3B,KAAK,EAAE,SAAS,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE,MAAM,OAAO,SAAS,CAAA;IAC3B,GAAG,EAAE,IAAI,CAAC;QAAE,SAAS,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;IACnC,gBAAgB,EAAE,gBAAgB,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,OAAO,SAAS,CAAA;IAC3B,gBAAgB,EAAE,gBAAgB,CAAA;CAClC;AAED,eAAO,MAAM,KAAK,EAAS,gBAAgB,CAAA;AAC3C,eAAO,MAAM,WAAW,GACvB,KAAK,IAAI,EACT,OAAO,MAAM,GAAG,MAAM,EAAE,EACxB,QAAQ,iBAAiB,kBAiCzB,CAAA"}
@@ -1,23 +1,33 @@
1
1
  import * as fs from 'node:fs';
2
- import { checkCmsStatus as strapiCheckCmsStatus } from '../strapi/cms';
3
- // 导入默认的 routeItemHandler
4
- import { routeItemHandler as strapiRouteItemHandler } from '../strapi/route';
2
+ import path from 'node:path';
3
+ import { bindRoutes } from '../route/methods';
5
4
  const providers = {
6
- strapi: {
7
- routeItemHandler: strapiRouteItemHandler,
8
- checkCmsStatus: strapiCheckCmsStatus,
9
- },
5
+ strapi: {},
10
6
  };
11
7
  export const setup = {};
12
- export const setupRoutes = async (paths, option) => {
13
- const { app, routeItemHandler, cms = 'strapi' } = option;
14
- const provider = providers[cms];
15
- setup.routeItemHandler = routeItemHandler || provider.routeItemHandler;
8
+ export const setupRoutes = async (app, paths, option) => {
9
+ setup.cms = option.cms;
16
10
  setup.app = app;
17
- setup.cms = cms;
18
- await provider.checkCmsStatus();
11
+ setup.routeItemHandler = option.routeItemHandler;
12
+ const coreApiFiles = fs.globSync(path.join(__dirname, '../core/api/**/*.js'));
13
+ const strapiApiFiles = fs.globSync(path.join(__dirname, '../strapi/api/**/*.js'));
14
+ const strapiPagesFiles = fs.globSync(path.join(__dirname, '../strapi/pages/**/*.js'));
19
15
  const files = fs.globSync(paths);
20
- files.forEach((file) => {
21
- require(file);
22
- });
16
+ const routeFiles = [
17
+ ...coreApiFiles,
18
+ ...strapiApiFiles,
19
+ ...strapiPagesFiles,
20
+ ...files,
21
+ ];
22
+ // 导入所有路由文件,包括处理 .tsx 文件
23
+ await Promise.all(routeFiles.map(async (file) => {
24
+ try {
25
+ await import(file);
26
+ }
27
+ catch (error) {
28
+ console.error(`Failed to import ${file}:`, error);
29
+ throw error;
30
+ }
31
+ }));
32
+ await bindRoutes(setup.app, setup.routeItemHandler);
23
33
  };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=site.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../../../src/strapi/api/site.ts"],"names":[],"mappings":""}
@@ -0,0 +1,153 @@
1
+ import { routeUrl } from '../../core/utils';
2
+ import { getRouteItems, getRouteTypes, route } from '../../route';
3
+ import { cms, getContentTypes, getSite, resetStrapi } from '../../strapi/cms';
4
+ import { resource } from '../../strapi/utils';
5
+ const fetchSingleItems = async () => {
6
+ const site = getSite();
7
+ const types = getContentTypes();
8
+ const routeTypes = getRouteTypes();
9
+ const singleTypes = Array.from(routeTypes.values()).filter(({ dataType }) => {
10
+ return types.get(dataType)?.schema?.kind === 'singleType';
11
+ });
12
+ getRouteItems();
13
+ const promises = singleTypes.map(async (route) => {
14
+ const dataType = types.get(route.dataType);
15
+ const schema = dataType?.schema;
16
+ const res = await cms.single(resource(route.dataType)).find({
17
+ status: 'published',
18
+ populate: schema?.attributes.keyword ? ['keyword'] : undefined,
19
+ });
20
+ if (res.data) {
21
+ return route.items.map((item) => {
22
+ const sitemap = (item.sitemap || res.data.sitemap || {});
23
+ sitemap.paginate = item.sitemap?.paginate;
24
+ const result = {
25
+ id: res.data.id,
26
+ isItem: true,
27
+ itemId: res.data.id,
28
+ apiId: String(dataType?.apiID),
29
+ documentType: 'single',
30
+ document: route.dataType,
31
+ documentId: res.data.documentId,
32
+ documentName: String(schema?.displayName),
33
+ resource: resource(route.dataType),
34
+ title: String(schema?.displayName),
35
+ locale: res.data.locale,
36
+ keywords: res.data?.keyword?.title || '',
37
+ url: routeUrl(item.name, {}, {}, { baseUrl: site.url, suffix: item.suffix }),
38
+ };
39
+ return result;
40
+ });
41
+ }
42
+ return [];
43
+ });
44
+ return Promise.all(promises).then((items) => items.flat());
45
+ };
46
+ const fetchCollectionItems = async (uid) => {
47
+ const site = getSite();
48
+ const types = getContentTypes();
49
+ const routeTypes = getRouteTypes();
50
+ const dataType = types.get(uid);
51
+ const routeType = routeTypes.get(String(dataType?.uid));
52
+ const collection = resource(uid);
53
+ const { data, meta: { pagination }, } = await cms.collection(collection).find({
54
+ status: 'published',
55
+ populate: dataType?.schema?.attributes.keyword ? ['keyword'] : undefined,
56
+ });
57
+ // 这里需要根据 routeType 从 CMS 或数据源获取所有页面
58
+ return data.reduce((result, item) => {
59
+ routeType?.items?.forEach((route) => {
60
+ const sitemap = (item.sitemap || route.sitemap || {});
61
+ sitemap.paginate = route.sitemap?.paginate;
62
+ const params = {};
63
+ route.params.forEach((param) => {
64
+ params[param] = item[param];
65
+ });
66
+ if (sitemap.disabled)
67
+ return;
68
+ if (sitemap.paginate && pagination) {
69
+ const totalPages = Math.ceil(pagination.total / sitemap.paginate);
70
+ for (let page = 1; page <= totalPages; page++) {
71
+ params.page = page;
72
+ try {
73
+ if (page < 2)
74
+ return;
75
+ result.push({
76
+ id: item.id,
77
+ itemId: item.id,
78
+ isItem: Boolean(params?.slug),
79
+ apiId: String(dataType?.apiID),
80
+ documentType: 'collection',
81
+ document: uid,
82
+ documentId: item.documentId,
83
+ documentName: String(dataType?.schema.displayName),
84
+ resource: collection,
85
+ title: item.title,
86
+ locale: item.locale,
87
+ keywords: item?.keyword?.title || '',
88
+ url: routeUrl(route.name, params, {}, { baseUrl: site.url, suffix: route.suffix }),
89
+ });
90
+ }
91
+ catch (error) {
92
+ console.error(route.name, params, error);
93
+ }
94
+ }
95
+ }
96
+ else {
97
+ try {
98
+ result.push({
99
+ id: item.id,
100
+ itemId: item.id,
101
+ isItem: Boolean(params?.slug),
102
+ apiId: String(dataType?.apiID),
103
+ documentType: 'collection',
104
+ document: uid,
105
+ documentId: item.documentId,
106
+ documentName: String(dataType?.schema.displayName),
107
+ resource: collection,
108
+ title: item.title,
109
+ locale: item.locale,
110
+ keywords: item?.keyword?.title || '',
111
+ url: routeUrl(route.name, params, {}, { baseUrl: site.url, suffix: route.suffix }),
112
+ });
113
+ }
114
+ catch (error) {
115
+ console.error(route.name, params, error);
116
+ }
117
+ }
118
+ });
119
+ return result;
120
+ }, []);
121
+ };
122
+ route.get('/api/site/pages', {
123
+ suffix: '',
124
+ async handler(c) {
125
+ const site = getSite();
126
+ const types = getContentTypes();
127
+ const routeTypes = getRouteTypes();
128
+ const pageItems = await fetchSingleItems();
129
+ try {
130
+ await Promise.all(Array.from(types.values())
131
+ .filter((type) => type.schema.kind === 'collectionType' && routeTypes.has(type.uid))
132
+ .map(async (type) => {
133
+ pageItems.push(...(await fetchCollectionItems(type.uid)));
134
+ }));
135
+ }
136
+ catch (error) {
137
+ console.error('Failed to fetch collection items:', error);
138
+ }
139
+ const pages = Array.from(new Map(pageItems.map((item) => [item.url, item])).values());
140
+ return c.json({
141
+ locale: site.locale,
142
+ total: pages.length,
143
+ pages: pages.map((item, i) => ({ ...item, id: i + 1 })),
144
+ });
145
+ },
146
+ });
147
+ route.get('/api/site/refresh', {
148
+ suffix: '',
149
+ async handler(c) {
150
+ await resetStrapi();
151
+ return c.json({ msg: 'ok' });
152
+ },
153
+ });
@@ -18,7 +18,7 @@ export const getCMS = () => {
18
18
  */
19
19
  export const cmsStatus = async () => {
20
20
  try {
21
- const checkUrl = `${CMS_URL}/website/common/hello`;
21
+ const checkUrl = `${CMS_URL}/website/hello`;
22
22
  const response = await fetch(checkUrl);
23
23
  console.log('✅ API health check response:', response.statusText);
24
24
  return response.ok;
@@ -1 +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"}
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,oBAgBd,CAAA"}
@@ -20,7 +20,9 @@ export const initCommon = async (populate = '*', refresh = true) => {
20
20
  return Promise.resolve(cache.get('common'));
21
21
  }
22
22
  const common = await cms
23
- .single('common')
23
+ .single('common', {
24
+ plugin: { name: 'website' },
25
+ })
24
26
  .find({
25
27
  populate,
26
28
  })
@@ -2,15 +2,6 @@ export interface Menu {
2
2
  items: any[];
3
3
  [key: string]: any;
4
4
  }
5
- /**
6
- * 获取菜单项
7
- */
8
- export declare const getMenuItems: () => Promise<any[] | undefined>;
9
- /**
10
- * 获取菜单项
11
- * @param refresh
12
- */
13
- export declare const fetchMenuItems: (refresh?: boolean) => Promise<any[]>;
14
5
  /**
15
6
  * 初始化菜单项
16
7
  * @param refresh
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/strapi/cms/menu.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,IAAI;IACpB,KAAK,EAAE,GAAG,EAAE,CAAA;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAClB;AAmCD;;GAEG;AACH,eAAO,MAAM,YAAY,kCAKxB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,iBAAe,mBAEnD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,iBAAc,mBA+BjD,CAAA"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/strapi/cms/menu.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACpB,KAAK,EAAE,GAAG,EAAE,CAAA;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAClB;AAID;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,iBAAc,mBAajD,CAAA"}