create-bubbles 0.1.23 → 0.1.25

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 (232) hide show
  1. package/dist/index.js +21 -0
  2. package/index.js +1 -1
  3. package/package.json +24 -24
  4. package/template-taro-react-oxc/.env.development +1 -1
  5. package/template-taro-react-oxc/.env.production +1 -1
  6. package/template-taro-react-oxc/project.config.json +1 -1
  7. package/template-taro-vue-eslint/project.config.json +2 -2
  8. package/{template-vp-monorepo-react-nestjs → template-vp-monorepo-react-hono}/.spaces/server//347/231/273/345/275/225/JWT/344/270/216RefreshToken/350/275/256/346/215/242/351/211/264/346/235/203/346/236/266/346/236/204/345/256/236/347/216/260/346/214/207/345/215/227.md +588 -1133
  9. package/template-vp-monorepo-react-hono/.vite-hooks/commit-msg +2 -0
  10. package/template-vp-monorepo-react-hono/.vite-hooks/pre-commit +2 -0
  11. package/template-vp-monorepo-react-hono/.vscode/extensions.json +3 -0
  12. package/template-vp-monorepo-react-hono/.vscode/settings.json +23 -0
  13. package/template-vp-monorepo-react-hono/AGENTS.md +16 -0
  14. package/template-vp-monorepo-react-hono/README.md +54 -0
  15. package/template-vp-monorepo-react-hono/apps/server/.env.example +13 -0
  16. package/template-vp-monorepo-react-hono/apps/server/README.md +75 -0
  17. package/template-vp-monorepo-react-hono/apps/server/drizzle/0000_flaky_madame_masque.sql +18 -0
  18. package/template-vp-monorepo-react-hono/apps/server/drizzle/meta/0000_snapshot.json +153 -0
  19. package/template-vp-monorepo-react-hono/apps/server/drizzle/meta/_journal.json +13 -0
  20. package/template-vp-monorepo-react-hono/apps/server/drizzle.config.ts +19 -0
  21. package/template-vp-monorepo-react-hono/apps/server/package.json +46 -0
  22. package/template-vp-monorepo-react-hono/apps/server/src/app.test.ts +57 -0
  23. package/template-vp-monorepo-react-hono/apps/server/src/app.ts +68 -0
  24. package/template-vp-monorepo-react-hono/apps/server/src/common/errors/app-error.ts +23 -0
  25. package/template-vp-monorepo-react-hono/apps/server/src/common/http/response.ts +21 -0
  26. package/template-vp-monorepo-react-hono/apps/server/src/common/logger.ts +30 -0
  27. package/template-vp-monorepo-react-hono/apps/server/src/config/env.ts +54 -0
  28. package/template-vp-monorepo-react-hono/apps/server/src/index.bun.ts +60 -0
  29. package/template-vp-monorepo-react-hono/apps/server/src/index.ts +73 -0
  30. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/client.ts +46 -0
  31. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/schema/index.ts +1 -0
  32. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/schema/job-runs.ts +42 -0
  33. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/queue/connection.ts +6 -0
  34. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/redis/client.ts +39 -0
  35. package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/redis/options.ts +28 -0
  36. package/template-vp-monorepo-react-hono/apps/server/src/modules/health/health.routes.ts +17 -0
  37. package/template-vp-monorepo-react-hono/apps/server/src/modules/health/health.service.ts +59 -0
  38. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.queue.ts +46 -0
  39. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.repository.ts +101 -0
  40. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.routes.ts +46 -0
  41. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.schemas.ts +9 -0
  42. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.service.ts +57 -0
  43. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.types.ts +11 -0
  44. package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.worker.ts +108 -0
  45. package/template-vp-monorepo-react-hono/apps/server/src/runtime/shutdown.ts +38 -0
  46. package/template-vp-monorepo-react-hono/apps/server/src/worker.ts +48 -0
  47. package/template-vp-monorepo-react-hono/apps/server/tsconfig.json +15 -0
  48. package/template-vp-monorepo-react-hono/apps/server/vite.config.ts +15 -0
  49. package/template-vp-monorepo-react-hono/apps/web/.env +2 -0
  50. package/template-vp-monorepo-react-hono/apps/web/.env.dev +1 -0
  51. package/template-vp-monorepo-react-hono/apps/web/.env.prod +1 -0
  52. package/template-vp-monorepo-react-hono/apps/web/index.html +13 -0
  53. package/template-vp-monorepo-react-hono/apps/web/package.json +35 -0
  54. package/template-vp-monorepo-react-hono/apps/web/public/favicon.svg +1 -0
  55. package/template-vp-monorepo-react-hono/apps/web/public/icons.svg +24 -0
  56. package/template-vp-monorepo-react-hono/apps/web/src/App.tsx +25 -0
  57. package/template-vp-monorepo-react-hono/apps/web/src/assets/hero.png +0 -0
  58. package/template-vp-monorepo-react-hono/apps/web/src/assets/react.svg +1 -0
  59. package/template-vp-monorepo-react-hono/apps/web/src/assets/vite.svg +1 -0
  60. package/template-vp-monorepo-react-hono/apps/web/src/components/Loading/PageLoading.tsx +11 -0
  61. package/template-vp-monorepo-react-hono/apps/web/src/locales/en_US.json +4 -0
  62. package/template-vp-monorepo-react-hono/apps/web/src/locales/zh_CN.json +4 -0
  63. package/template-vp-monorepo-react-hono/apps/web/src/main.tsx +5 -0
  64. package/template-vp-monorepo-react-hono/apps/web/src/pages/home/index.tsx +47 -0
  65. package/template-vp-monorepo-react-hono/apps/web/src/router/index.tsx +25 -0
  66. package/template-vp-monorepo-react-hono/apps/web/src/router/modules/.gitkeep +0 -0
  67. package/template-vp-monorepo-react-hono/apps/web/src/styles/index.css +7 -0
  68. package/template-vp-monorepo-react-hono/apps/web/src/types/auto-imports.d.ts +58 -0
  69. package/template-vp-monorepo-react-hono/apps/web/src/utils/env/index.ts +6 -0
  70. package/template-vp-monorepo-react-hono/apps/web/src/utils/request/core/index.ts +420 -0
  71. package/template-vp-monorepo-react-hono/apps/web/src/utils/request/core/utils.ts +39 -0
  72. package/template-vp-monorepo-react-hono/apps/web/src/utils/request/index.ts +61 -0
  73. package/template-vp-monorepo-react-hono/apps/web/tsconfig.json +18 -0
  74. package/template-vp-monorepo-react-hono/apps/web/vite.config.ts +45 -0
  75. package/template-vp-monorepo-react-hono/commitlint.config.js +1 -0
  76. package/template-vp-monorepo-react-hono/docker-compose.yml +41 -0
  77. package/template-vp-monorepo-react-hono/mise.toml +4 -0
  78. package/template-vp-monorepo-react-hono/package.json +37 -0
  79. package/template-vp-monorepo-react-hono/packages/i18n/core/package.json +20 -0
  80. package/template-vp-monorepo-react-hono/packages/i18n/core/src/format.ts +9 -0
  81. package/template-vp-monorepo-react-hono/packages/i18n/core/src/i18n.ts +73 -0
  82. package/template-vp-monorepo-react-hono/packages/i18n/core/src/index.ts +24 -0
  83. package/template-vp-monorepo-react-hono/packages/i18n/core/src/storage.ts +47 -0
  84. package/template-vp-monorepo-react-hono/packages/i18n/core/src/store.ts +48 -0
  85. package/template-vp-monorepo-react-hono/packages/i18n/core/src/types.ts +36 -0
  86. package/template-vp-monorepo-react-hono/packages/i18n/core/tsconfig.json +4 -0
  87. package/template-vp-monorepo-react-hono/packages/i18n/core/vite.config.ts +13 -0
  88. package/template-vp-monorepo-react-hono/packages/i18n/react/package.json +28 -0
  89. package/template-vp-monorepo-react-hono/packages/i18n/react/src/index.tsx +26 -0
  90. package/template-vp-monorepo-react-hono/packages/i18n/react/src/use-store.ts +14 -0
  91. package/template-vp-monorepo-react-hono/packages/i18n/react/tsconfig.json +9 -0
  92. package/template-vp-monorepo-react-hono/packages/i18n/react/vite.config.ts +16 -0
  93. package/template-vp-monorepo-react-hono/packages/i18n/vue/package.json +27 -0
  94. package/template-vp-monorepo-react-hono/packages/i18n/vue/src/index.ts +52 -0
  95. package/template-vp-monorepo-react-hono/packages/i18n/vue/src/use-store.ts +19 -0
  96. package/template-vp-monorepo-react-hono/packages/i18n/vue/tsconfig.json +8 -0
  97. package/template-vp-monorepo-react-hono/packages/i18n/vue/vite.config.ts +16 -0
  98. package/template-vp-monorepo-react-hono/pnpm-workspace.yaml +57 -0
  99. package/template-vp-monorepo-react-hono/scripts/clean.mjs +48 -0
  100. package/template-vp-monorepo-react-hono/tsconfig.base.json +10 -0
  101. package/template-vp-monorepo-react-hono/tsconfig.bundler.json +12 -0
  102. package/template-vp-monorepo-react-hono/tsconfig.json +11 -0
  103. package/template-vp-monorepo-react-hono/tsconfig.lib.json +10 -0
  104. package/template-vp-monorepo-react-hono/vite.config.ts +20 -0
  105. package/template-vp-monorepo-react-nestjs/.spaces/server/todo.md +991 -0
  106. package/template-vp-monorepo-react-nestjs/.vscode/launch.json +16 -0
  107. package/template-vp-monorepo-react-nestjs/.vscode/settings.json +21 -18
  108. package/template-vp-monorepo-react-nestjs/apps/server/.env.development +3 -39
  109. package/template-vp-monorepo-react-nestjs/apps/server/.swcrc +8 -0
  110. package/template-vp-monorepo-react-nestjs/apps/server/drizzle.config.ts +8 -3
  111. package/template-vp-monorepo-react-nestjs/apps/server/nest-cli.json +8 -1
  112. package/template-vp-monorepo-react-nestjs/apps/server/package.json +11 -6
  113. package/template-vp-monorepo-react-nestjs/apps/server/src/app.controller.ts +2 -0
  114. package/template-vp-monorepo-react-nestjs/apps/server/src/app.module.ts +20 -15
  115. package/template-vp-monorepo-react-nestjs/apps/server/src/common/adapters/fastify.adapter.ts +16 -0
  116. package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/auth.ts +2 -0
  117. package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/response.ts +0 -4
  118. package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/session.constants.ts +28 -0
  119. package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/current-auth.decorator.ts +16 -0
  120. package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/public.decorator.ts +4 -0
  121. package/template-vp-monorepo-react-nestjs/apps/server/src/common/dto/api-failure.dto.ts +25 -0
  122. package/template-vp-monorepo-react-nestjs/apps/server/src/common/error/common.error.ts +40 -0
  123. package/template-vp-monorepo-react-nestjs/apps/server/src/common/exceptions/app.exception.ts +55 -0
  124. package/template-vp-monorepo-react-nestjs/apps/server/src/common/filters/global-exception.filter.ts +384 -0
  125. package/template-vp-monorepo-react-nestjs/apps/server/src/common/openapi/response-headers.ts +9 -0
  126. package/template-vp-monorepo-react-nestjs/apps/server/src/config/index.ts +1 -1
  127. package/template-vp-monorepo-react-nestjs/apps/server/src/config/session.config.ts +36 -0
  128. package/template-vp-monorepo-react-nestjs/apps/server/src/database/schema.ts +4 -64
  129. package/template-vp-monorepo-react-nestjs/apps/server/src/main.ts +29 -8
  130. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.controller.ts +55 -0
  131. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.errors.ts +42 -0
  132. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.module.ts +26 -0
  133. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.repository.ts +40 -0
  134. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.service.ts +129 -0
  135. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/auth-repsponse.dto.ts +31 -0
  136. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/login.dto.ts +11 -0
  137. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/register.dto.ts +17 -0
  138. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/guards/session-auth.guard.ts +50 -0
  139. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/password.service.ts +24 -0
  140. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session-store.service.ts +198 -0
  141. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session-token.service.ts +29 -0
  142. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session.script.ts +221 -0
  143. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session.types.ts +24 -0
  144. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/db/db.controller.ts +1 -1
  145. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/db/dto/create-user.dto.ts +3 -5
  146. package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/redis/redis.service.ts +1 -1
  147. package/template-vp-monorepo-react-nestjs/apps/server/src/utils/env-arr.ts +3 -0
  148. package/template-vp-monorepo-react-nestjs/apps/server/test/error-catalog.spec.ts +30 -0
  149. package/template-vp-monorepo-react-nestjs/apps/server/tsconfig.build.json +11 -1
  150. package/template-vp-monorepo-react-nestjs/apps/server/tsconfig.json +12 -20
  151. package/template-vp-monorepo-react-nestjs/apps/server/vite.config.ts +15 -0
  152. package/template-vp-monorepo-react-nestjs/apps/web/package.json +1 -0
  153. package/template-vp-monorepo-react-nestjs/apps/web/tsconfig.json +5 -15
  154. package/template-vp-monorepo-react-nestjs/apps/web-vue/commitlint.config.js +1 -1
  155. package/template-vp-monorepo-react-nestjs/apps/web-vue/lefthook.yml +1 -1
  156. package/template-vp-monorepo-react-nestjs/apps/web-vue/package.json +1 -3
  157. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/api/index.ts +5 -5
  158. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/components/Icon/svg-icon.vue +3 -3
  159. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/hooks/chart/lib.ts +6 -6
  160. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/hooks/chart/useEcharts.ts +34 -29
  161. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/i18n/instance.ts +2 -0
  162. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/layout/default/index.vue +17 -32
  163. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/locales/en_US.json +4 -1
  164. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/locales/zh_CN.json +4 -1
  165. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/guard/index.ts +3 -3
  166. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/guard/permissionGuard.ts +7 -7
  167. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/index.ts +7 -7
  168. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/interface.ts +6 -6
  169. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/store/index.ts +6 -6
  170. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/store/modules/user.ts +9 -9
  171. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/styles/index.scss +3 -3
  172. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/types/antdv-next.d.ts +1 -0
  173. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/env.ts +1 -1
  174. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/core/index.ts +63 -45
  175. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/core/utils.ts +12 -6
  176. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/index.ts +1 -1
  177. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/echart/config.ts +687 -687
  178. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/echart/index.vue +7 -7
  179. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/tree-chart.vue +2 -7
  180. package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/home/index.vue +13 -3
  181. package/template-vp-monorepo-react-nestjs/apps/web-vue/tsconfig.json +5 -17
  182. package/template-vp-monorepo-react-nestjs/apps/web-vue/uno.config.ts +5 -5
  183. package/template-vp-monorepo-react-nestjs/i18n.config.ts +22 -0
  184. package/template-vp-monorepo-react-nestjs/package.json +12 -1
  185. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/README.md +113 -0
  186. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/docs/excel-sync-plan.md +618 -0
  187. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/package.json +31 -0
  188. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/cli.ts +5 -0
  189. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/command.ts +512 -0
  190. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/config.ts +15 -0
  191. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/files.ts +67 -0
  192. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/index.ts +19 -0
  193. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/load-config.ts +228 -0
  194. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/report.ts +57 -0
  195. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.test.ts +81 -0
  196. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.ts +290 -0
  197. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/sync.ts +274 -0
  198. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/command.test.ts +209 -0
  199. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/config.test.ts +19 -0
  200. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/load-config.test.ts +194 -0
  201. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/report.test.ts +63 -0
  202. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/sync.test.ts +203 -0
  203. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/temporary-directory.ts +25 -0
  204. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/tsconfig.json +9 -0
  205. package/template-vp-monorepo-react-nestjs/packages/i18n/cli/vite.config.ts +18 -0
  206. package/template-vp-monorepo-react-nestjs/packages/i18n/core/tsconfig.json +1 -12
  207. package/template-vp-monorepo-react-nestjs/packages/i18n/react/tsconfig.json +3 -10
  208. package/template-vp-monorepo-react-nestjs/packages/i18n/vue/tsconfig.json +3 -10
  209. package/template-vp-monorepo-react-nestjs/packages/shared/package.json +40 -0
  210. package/template-vp-monorepo-react-nestjs/packages/shared/src/index.ts +13 -0
  211. package/template-vp-monorepo-react-nestjs/packages/shared/src/types/auth.ts +35 -0
  212. package/template-vp-monorepo-react-nestjs/packages/shared/src/types/common.ts +11 -0
  213. package/template-vp-monorepo-react-nestjs/packages/shared/src/types/index.ts +11 -0
  214. package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/account.ts +5 -0
  215. package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/index.ts +2 -0
  216. package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/session-terminal.ts +11 -0
  217. package/template-vp-monorepo-react-nestjs/packages/shared/tsconfig.json +4 -0
  218. package/template-vp-monorepo-react-nestjs/packages/shared/vite.config.ts +17 -0
  219. package/template-vp-monorepo-react-nestjs/pnpm-workspace.yaml +6 -6
  220. package/template-vp-monorepo-react-nestjs/scripts/clean.mjs +48 -0
  221. package/template-vp-monorepo-react-nestjs/tsconfig.base.json +10 -0
  222. package/template-vp-monorepo-react-nestjs/tsconfig.bundler.json +12 -0
  223. package/template-vp-monorepo-react-nestjs/tsconfig.json +8 -6
  224. package/template-vp-monorepo-react-nestjs/tsconfig.lib.json +10 -0
  225. package/dist/index.mjs +0 -422
  226. package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/decorator.ts +0 -2
  227. package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/bypass.ts +0 -12
  228. package/template-vp-monorepo-react-nestjs/apps/server/src/common/interceptors/transform.ts +0 -34
  229. package/template-vp-monorepo-react-nestjs/apps/server/src/common/model/response.ts +0 -23
  230. package/template-vp-monorepo-react-nestjs/apps/server/src/config/auth.config.ts +0 -64
  231. package/template-vp-monorepo-react-nestjs/apps/web-vue/pnpm-workspace.yaml +0 -16
  232. /package/{template-vp-monorepo-react-nestjs/apps/server/src/config/security.config.ts → template-vp-monorepo-react-hono/.agents/auth.config.ts} +0 -0
@@ -0,0 +1,221 @@
1
+ export const CREATE_OR_REPLACE_SESSION_SCRIPT = String.raw`
2
+ local function isValidTerminal(value)
3
+ return value == 'web' or value == 'desktop' or value == 'mobile'
4
+ end
5
+
6
+ local function isValidDigest(value)
7
+ return value
8
+ and string.len(value) == 64
9
+ and string.match(value, '^[0-9a-f]+$') ~= nil
10
+ end
11
+
12
+ local function isValidUserId(value)
13
+ return string.len(value) > 0
14
+ and string.len(value) <= 100
15
+ and string.match(value, '^[%w_-]+$') ~= nil
16
+ end
17
+
18
+ local newDigest = ARGV[1]
19
+ local userId = ARGV[2]
20
+ local terminal = ARGV[3]
21
+ local idleTtlMs = tonumber(ARGV[4])
22
+ local absoluteTtlMs = tonumber(ARGV[5])
23
+ local loginIp = ARGV[6]
24
+ local userAgent = ARGV[7]
25
+ local sessionKeyPrefix = ARGV[8]
26
+
27
+ if not isValidDigest(newDigest)
28
+ or not isValidUserId(userId)
29
+ or not isValidTerminal(terminal)
30
+ or not sessionKeyPrefix
31
+ or sessionKeyPrefix == ''
32
+ then
33
+ return { 0, 'INVALID_ARGUMENT' }
34
+ end
35
+
36
+
37
+ if not idleTtlMs or not absoluteTtlMs or idleTtlMs <= 0 or absoluteTtlMs <= idleTtlMs then
38
+ return { 0, 'INVALID_TTL' }
39
+ end
40
+
41
+ local redisTime = redis.call('TIME')
42
+ local nowMs = tonumber(redisTime[1]) * 1000 + math.floor(tonumber(redisTime[2]) / 1000)
43
+ local absoluteExpiresAtMs = nowMs + absoluteTtlMs
44
+ local initialExpiresAtMs = math.min(nowMs + idleTtlMs, absoluteExpiresAtMs)
45
+ local oldDigest = redis.call('GET', KEYS[1])
46
+ local oldSessionKey = nil
47
+
48
+
49
+ if oldDigest then
50
+ if not isValidDigest(oldDigest) then
51
+ return { 0, 'INVALID_SLOT_DATA' }
52
+ end
53
+
54
+ oldSessionKey = sessionKeyPrefix .. oldDigest
55
+ end
56
+
57
+
58
+ redis.call(
59
+ 'HSET',
60
+ KEYS[2],
61
+ 'userId', userId,
62
+ 'terminal', terminal,
63
+ 'createdAtMs', tostring(nowMs),
64
+ 'lastSeenAtMs', tostring(nowMs),
65
+ 'absoluteExpiresAtMs', tostring(absoluteExpiresAtMs),
66
+ 'loginIp', loginIp,
67
+ 'userAgent', userAgent
68
+ )
69
+
70
+ redis.call('PEXPIREAT', KEYS[2], initialExpiresAtMs)
71
+ redis.call('SET', KEYS[1], newDigest)
72
+ redis.call('PEXPIREAT', KEYS[1], initialExpiresAtMs)
73
+
74
+ if oldSessionKey and oldDigest ~= newDigest then
75
+ redis.call('DEL', oldSessionKey)
76
+ end
77
+
78
+
79
+
80
+ return {
81
+ 1,
82
+ oldDigest or '',
83
+ tostring(initialExpiresAtMs),
84
+ tostring(absoluteExpiresAtMs)
85
+ }
86
+ `
87
+
88
+ export const VALIDATE_AND_TOUCH_SESSION_SCRIPT = String.raw`
89
+ local function isValidTerminal(value)
90
+ return value == 'web' or value == 'desktop' or value == 'mobile'
91
+ end
92
+
93
+
94
+ local function isValidUserId(value)
95
+ return string.len(value) > 0
96
+ and string.len(value) <= 100
97
+ and string.match(value, '^[%w_-]+$') ~= nil
98
+ end
99
+
100
+ local currentDigest = ARGV[1]
101
+ local slotKeyPrefix = ARGV[2]
102
+ local idleTtlMs = tonumber(ARGV[3])
103
+
104
+ if not isValidDigest(currentDigest) or not idleTtlMs or idleTtlMs <= 0 then
105
+ return { 0, 'INVALID_ARGUMENT' }
106
+ end
107
+
108
+ local sessionValues = redis.call(
109
+ 'HMGET',
110
+ KEYS[1],
111
+ 'userId',
112
+ 'terminal',
113
+ 'absoluteExpiresAtMs'
114
+ )
115
+
116
+ local userId = sessionValues[1]
117
+ local terminal = sessionValues[2]
118
+ local absoluteExpiresAtMs = tonumber(sessionValues[3])
119
+
120
+ if not userId or not terminal or not absoluteExpiresAtMs then
121
+ return { 0, 'NOT_FOUND' }
122
+ end
123
+
124
+ if not isValidUserId(userId) or not isValidTerminal(terminal) then
125
+ return { 0, 'INVALID_SESSION_DATA' }
126
+ end
127
+
128
+ local slotKey = slotKeyPrefix .. userId .. ':' .. terminal
129
+ local slotDigest = redis.call('GET', slotKey)
130
+
131
+ if slotDigest ~= currentDigest then
132
+ redis.call('DEL', KEYS[1])
133
+ return { 0, 'REPLACED' }
134
+ end
135
+
136
+ local redisTime = redis.call('TIME')
137
+ local nowMs = tonumber(redisTime[1]) * 1000 + math.floor(tonumber(redisTime[2]) / 1000)
138
+
139
+
140
+ if nowMs >= absoluteExpiresAtMs then
141
+ redis.call('DEL', KEYS[1])
142
+ redis.call('DEL', slotKey)
143
+ return { 0, 'ABSOLUTE_EXPIRED' }
144
+ end
145
+
146
+ local expiresAtMs = math.min(nowMs + idleTtlMs, absoluteExpiresAtMs)
147
+ redis.call('HSET', KEYS[1], 'lastSeenAtMs', tostring(nowMs))
148
+ redis.call('PEXPIREAT', KEYS[1], expiresAtMs)
149
+ redis.call('PEXPIREAT', slotKey, expiresAtMs)
150
+
151
+ return {
152
+ 1,
153
+ userId,
154
+ terminal,
155
+ tostring(expiresAtMs)
156
+ }
157
+ `
158
+
159
+ export const LOGOUT_SESSION_SCRIPT = String.raw`
160
+ local function isValidTerminal(value)
161
+ return value == 'web' or value == 'desktop' or value == 'mobile'
162
+ end
163
+
164
+ local function isValidUserId(value)
165
+ return string.len(value) > 0
166
+ and string.len(value) <= 100
167
+ and string.match(value, '^[%w_-]+$') ~= nil
168
+ end
169
+
170
+ local currentDigest = ARGV[1]
171
+ local slotKeyPrefix = ARGV[2]
172
+
173
+ local sessionValues = redis.call(
174
+ 'HMGET',
175
+ KEYS[1],
176
+ 'userId',
177
+ 'terminal'
178
+ )
179
+
180
+ local userId = sessionValues[1]
181
+ local terminal = sessionValues[2]
182
+
183
+ if not userId or not terminal then
184
+ return { 1, 'ALREADY_GONE' }
185
+ end
186
+
187
+ if not isValidUserId(userId) or not isValidTerminal(terminal) then
188
+ return { 0, 'INVALID_SESSION_DATA' }
189
+ end
190
+
191
+ local slotKey = slotKeyPrefix .. userId .. ':' .. terminal
192
+ local slotDigest = redis.call('GET', slotKey)
193
+
194
+ if slotDigest == currentDigest then
195
+ redis.call('DEL', slotKey)
196
+ end
197
+
198
+ redis.call('DEL', KEYS[1])
199
+
200
+ return { 1, 'LOGGED_OUT' }
201
+ `
202
+
203
+ export const REVOKE_USER_SESSIONS_SCRIPT = String.raw`
204
+ local sessionKeyPrefix = ARGV[1]
205
+ local revokedCount = 0
206
+
207
+ for index = 1, #KEYS DO
208
+ local digest = redis.call('GET', KEYS[index])
209
+
210
+ if digest
211
+ and string.len(digest) == 64
212
+ and string.match(digest, '^[0-9a-f]+$') ~= nil then
213
+ redis.call('DEL', sessionKeyPrefix .. digest)
214
+ revokedCount = revokedCount + 1
215
+ end
216
+
217
+ redis.call('DEL', KEYS[index])
218
+ end
219
+
220
+ return { 1, tostring(revokedCount) }
221
+ `
@@ -0,0 +1,24 @@
1
+ import { FastifyRequest } from 'fastify'
2
+ import { SessionTerminalType } from 'shared/types'
3
+
4
+ export interface CurrentAuthType {
5
+ userId: string
6
+ terminal: SessionTerminalType
7
+ }
8
+
9
+ export type AuthenticatedRequest = FastifyRequest & {
10
+ auth?: CurrentAuthType
11
+ }
12
+
13
+ export interface CreateSessionInput {
14
+ tokenDigest: string
15
+ userId: string
16
+ terminal: SessionTerminalType
17
+ loginIp: string
18
+ userAgent: string
19
+ }
20
+
21
+ export interface CreatedSession {
22
+ initialExpiresAtMs: number
23
+ absoluteExpiresAtMs: number
24
+ }
@@ -1,6 +1,6 @@
1
1
  import { Body, Controller, Get, Post } from '@nestjs/common'
2
+ import { ApiOperation, ApiTags } from '@nestjs/swagger'
2
3
  import { DbService } from './db.service'
3
- import { ApiBody, ApiOperation, ApiTags } from '@nestjs/swagger'
4
4
  import { CreateUserDto } from './dto/create-user.dto'
5
5
 
6
6
  @ApiTags('DB 测试')
@@ -1,24 +1,22 @@
1
1
  import { users } from '@/database/schema'
2
2
  import { createInsertSchema } from 'drizzle-zod'
3
3
  import { createZodDto } from 'nestjs-zod'
4
- import { z } from 'zod'
5
4
  /**
6
5
  * 1. 基于数据库表生成zod schema
7
6
  * drizzle-zod 会自动把 varchar({ length: 100 }) 翻成 .max(100)
8
7
  * 把notNull 翻成 必填字段
9
8
  */
10
9
 
11
- const baseSchema = createInsertSchema(users, {
12
- // 数据库不知道邮箱格式, 这里用zod增强
13
- email: z.email(),
14
- })
10
+ const baseSchema = createInsertSchema(users)
15
11
 
16
12
  /**
17
13
  * 2. 创建用户的入参不应该包括 id 和 createdAt(这两数据库自动生成)
18
14
  */
19
15
  export const createUserSchema = baseSchema.omit({
20
16
  id: true,
17
+ status: true,
21
18
  createdAt: true,
19
+ updatedAt: true,
22
20
  })
23
21
 
24
22
  /**
@@ -1,5 +1,5 @@
1
- import { Injectable } from '@nestjs/common'
2
1
  import { InjectRedis } from '@nestjs-modules/ioredis'
2
+ import { Injectable } from '@nestjs/common'
3
3
  import Redis from 'ioredis'
4
4
 
5
5
  @Injectable()
@@ -0,0 +1,3 @@
1
+ const NODE_ENV = process.env.NODE_ENV ?? 'development'
2
+
3
+ export const ENV_ARR = [`.env.${NODE_ENV}.local`, `.env.local`, `.env.${NODE_ENV}`, `.env`]
@@ -0,0 +1,30 @@
1
+ import { COMMON_ERRORS } from '@/common/error/common.error'
2
+ import { AUTH_ERRORS } from '@/modules/auth/auth.errors'
3
+ import { describe, expect, it } from 'vite-plus/test'
4
+
5
+ const definitions = [...Object.values(COMMON_ERRORS), ...Object.values(AUTH_ERRORS)]
6
+
7
+ describe('error catalog', () => {
8
+ it('uses valid and globally unique error codes', () => {
9
+ const codes = definitions.map((definition) => definition.code)
10
+
11
+ expect(new Set(codes).size).toBe(codes.length)
12
+
13
+ for (const definition of definitions) {
14
+ expect(definition.code).toMatch(/^[A-Z][A-Z0-9_]*(?:\.[A-Z][A-Z0-9_]*)+$/)
15
+ expect(definition.code.length).toBeLessThanOrEqual(80)
16
+ expect(definition.status).toBeGreaterThanOrEqual(400)
17
+ expect(definition.status).toBeLessThanOrEqual(599)
18
+ expect(definition.publicMessage.trim()).not.toBe('')
19
+ }
20
+ })
21
+
22
+ it('keeps bearerChallenge and HTTP 401 in sync', () => {
23
+ for (const definition of definitions) {
24
+ const hasBearerChallenge =
25
+ 'bearerChallenge' in definition && definition.bearerChallenge === true
26
+
27
+ expect(hasBearerChallenge).toBe(definition.status === 401)
28
+ }
29
+ })
30
+ })
@@ -1,4 +1,14 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
- "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
3
+ "compilerOptions": {
4
+ "noEmit": false,
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+ "sourceMap": true,
8
+ "removeComments": true,
9
+ "incremental": false,
10
+ "declaration": false
11
+ },
12
+ "include": ["src/**/*.ts"],
13
+ "exclude": ["node_modules", "test", "dist", "**/*.spec.ts"]
4
14
  }
@@ -1,28 +1,20 @@
1
1
  {
2
+ "extends": "../../tsconfig.base.json",
2
3
  "compilerOptions": {
3
- "module": "nodenext",
4
- "moduleResolution": "nodenext",
5
- "resolvePackageJsonExports": true,
6
- "esModuleInterop": true,
4
+ "target": "ES2023",
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "types": ["node"],
7
8
  "isolatedModules": true,
8
- "declaration": true,
9
- "removeComments": true,
10
- "emitDecoratorMetadata": true,
11
9
  "experimentalDecorators": true,
12
- "allowSyntheticDefaultImports": true,
13
- "target": "ES2023",
14
- "sourceMap": true,
15
- "outDir": "./dist",
16
- "rootDir": "./",
17
- "incremental": true,
18
- "skipLibCheck": true,
19
- "strictNullChecks": true,
20
- "forceConsistentCasingInFileNames": true,
21
- "noImplicitAny": false,
22
- "strictBindCallApply": false,
23
- "noFallthroughCasesInSwitch": false,
10
+ "emitDecoratorMetadata": true,
11
+ "esModuleInterop": true,
12
+ "noEmit": true,
13
+ "noUncheckedIndexedAccess": true,
24
14
  "paths": {
25
15
  "@/*": ["./src/*"]
26
16
  }
27
- }
17
+ },
18
+ "include": ["src/**/*.ts", "test/**/*.ts", "*.config.ts"],
19
+ "exclude": ["node_modules", "dist"]
28
20
  }
@@ -0,0 +1,15 @@
1
+ import { resolve } from 'path'
2
+ import { defineConfig } from 'vite-plus'
3
+
4
+ export default defineConfig({
5
+ resolve: {
6
+ alias: {
7
+ '@': resolve(__dirname, 'src'),
8
+ },
9
+ },
10
+ test: {
11
+ environment: 'node',
12
+ include: ['test/**/*.spec.ts'],
13
+ restoreMocks: true,
14
+ },
15
+ })
@@ -21,6 +21,7 @@
21
21
  "react": "catalog:",
22
22
  "react-dom": "catalog:",
23
23
  "react-router": "catalog:",
24
+ "shared": "workspace:*",
24
25
  "tailwindcss": "catalog:"
25
26
  },
26
27
  "devDependencies": {
@@ -1,28 +1,18 @@
1
1
  {
2
- "extends": "../../tsconfig.json",
2
+ "extends": "../../tsconfig.bundler.json",
3
3
  "compilerOptions": {
4
- "target": "es2023",
5
- "module": "esnext",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
6
6
  "jsx": "react-jsx",
7
- "lib": ["ES2023", "DOM"],
8
7
  "types": ["vite-plus/client"],
9
8
  "paths": {
10
9
  "@/*": ["./src/*"]
11
10
  },
12
- "skipLibCheck": true,
13
-
14
- /* Bundler mode */
15
- "moduleResolution": "bundler",
16
11
  "allowImportingTsExtensions": true,
17
- "verbatimModuleSyntax": true,
18
- "moduleDetection": "force",
19
- "noEmit": true,
20
-
21
- /* Linting */
12
+ "erasableSyntaxOnly": true,
22
13
  "noUnusedLocals": true,
23
14
  "noUnusedParameters": true,
24
- "erasableSyntaxOnly": true,
25
- "noFallthroughCasesInSwitch": true
15
+ "noUncheckedIndexedAccess": true
26
16
  },
27
17
  "include": ["src"]
28
18
  }
@@ -1 +1 @@
1
- export default { extends: ["@commitlint/config-conventional"] };
1
+ export default { extends: ['@commitlint/config-conventional'] }
@@ -1,7 +1,7 @@
1
1
  pre-commit:
2
2
  commands:
3
3
  check:
4
- glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,vue}"
4
+ glob: '*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,vue}'
5
5
  run: pnpm eslint --fix {staged_files}
6
6
  stage_fixed: true
7
7
 
@@ -13,7 +13,6 @@
13
13
  "dependencies": {
14
14
  "@alova/adapter-axios": "catalog:",
15
15
  "@antdv-next/icons": "catalog:",
16
- "@bubblesjs/i18n-vue": "workspace:*",
17
16
  "alova": "catalog:",
18
17
  "antdv-next": "catalog:",
19
18
  "axios": "catalog:",
@@ -34,7 +33,6 @@
34
33
  "@commitlint/config-conventional": "catalog:",
35
34
  "@types/node": "catalog:",
36
35
  "@types/nprogress": "catalog:",
37
- "@typescript/native": "catalog:",
38
36
  "@unocss/eslint-plugin": "catalog:",
39
37
  "@unocss/preset-attributify": "catalog:",
40
38
  "@unocss/preset-wind4": "catalog:",
@@ -47,7 +45,7 @@
47
45
  "lefthook": "catalog:",
48
46
  "oxlint": "catalog:",
49
47
  "sass": "catalog:",
50
- "typescript": "catalog:typescript6",
48
+ "typescript": "catalog:",
51
49
  "unocss": "catalog:",
52
50
  "unplugin-auto-import": "catalog:",
53
51
  "unplugin-vue-components": "catalog:",
@@ -1,12 +1,12 @@
1
- import request from "@/utils/request";
1
+ import request from '@/utils/request'
2
2
 
3
- export const EXPIRE_TIME = 60 * 10 * 1000;
3
+ export const EXPIRE_TIME = 60 * 10 * 1000
4
4
 
5
5
  export function getTree() {
6
- return request.Get("/xxx/xx", {
6
+ return request.Get('/xxx/xx', {
7
7
  cacheFor: {
8
- mode: "restore",
8
+ mode: 'restore',
9
9
  expire: EXPIRE_TIME,
10
10
  },
11
- });
11
+ })
12
12
  }
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  defineProps<{
3
- icon: string;
4
- }>();
5
- const attrs = useAttrs();
3
+ icon: string
4
+ }>()
5
+ const attrs = useAttrs()
6
6
  </script>
7
7
 
8
8
  <template>
@@ -6,7 +6,7 @@ import {
6
6
  PictorialBarChart,
7
7
  PieChart,
8
8
  RadarChart,
9
- } from "echarts/charts";
9
+ } from 'echarts/charts'
10
10
  import {
11
11
  AriaComponent,
12
12
  CalendarComponent,
@@ -22,11 +22,11 @@ import {
22
22
  ToolboxComponent,
23
23
  TooltipComponent,
24
24
  VisualMapComponent,
25
- } from "echarts/components";
26
- import * as echarts from "echarts/core";
25
+ } from 'echarts/components'
26
+ import * as echarts from 'echarts/core'
27
27
  // TODO 如果想换成SVG渲染,就导出SVGRenderer,
28
28
  // 并且放到 echarts.use 里,注释掉 CanvasRenderer
29
- import { /* SVGRenderer */ CanvasRenderer } from "echarts/renderers";
29
+ import { /* SVGRenderer */ CanvasRenderer } from 'echarts/renderers'
30
30
 
31
31
  echarts.use([
32
32
  LegendComponent,
@@ -52,6 +52,6 @@ echarts.use([
52
52
  TimelineComponent,
53
53
  CalendarComponent,
54
54
  GraphicComponent,
55
- ]);
55
+ ])
56
56
 
57
- export default echarts;
57
+ export default echarts
@@ -1,27 +1,29 @@
1
- import type { EChartsOption } from "echarts";
1
+ import type { EChartsOption } from 'echarts'
2
2
 
3
- import type { ShallowRef } from "vue";
3
+ import type { ShallowRef } from 'vue'
4
4
 
5
- import { debounce } from "radashi";
5
+ import { debounce } from 'radashi'
6
6
 
7
- import echarts from "./lib";
7
+ import echarts from './lib'
8
8
 
9
- type setOptionsType = (options: EChartsOption, clear?: boolean) => void;
9
+ type setOptionsType = (options: EChartsOption, clear?: boolean) => void
10
10
 
11
11
  export function useECharts(
12
12
  elRef: Ref<HTMLDivElement> | Readonly<ShallowRef<HTMLDivElement | null>>,
13
13
  ) {
14
- let chartInstance: echarts.ECharts | null = null;
15
- let resizeObserver: ResizeObserver | undefined;
14
+ let chartInstance: echarts.ECharts | null = null
15
+ let resizeObserver: ResizeObserver | undefined
16
16
 
17
17
  const resize = () => {
18
- chartInstance?.resize();
19
- };
18
+ chartInstance?.resize()
19
+ }
20
20
 
21
21
  const initCharts = () => {
22
- if (!elRef) return;
23
- const el = unref(elRef);
24
- if (!el) return;
22
+ if (!elRef)
23
+ return
24
+ const el = unref(elRef)
25
+ if (!el)
26
+ return
25
27
 
26
28
  resizeObserver = new ResizeObserver(
27
29
  debounce(
@@ -30,36 +32,39 @@ export function useECharts(
30
32
  },
31
33
  resize,
32
34
  ),
33
- );
34
- resizeObserver.observe(el);
35
+ )
36
+ resizeObserver.observe(el)
35
37
 
36
- chartInstance = echarts.init(el);
37
- };
38
+ chartInstance = echarts.init(el)
39
+ }
38
40
 
39
41
  const setOptions: setOptionsType = (options, clear = true) => {
40
42
  if (!chartInstance) {
41
- initCharts();
42
- if (!chartInstance) return;
43
+ initCharts()
44
+ if (!chartInstance)
45
+ return
43
46
  }
44
- clear && chartInstance?.clear();
45
- chartInstance?.setOption(options);
46
- };
47
+ if (clear)
48
+ chartInstance.clear()
49
+ chartInstance?.setOption(options)
50
+ }
47
51
 
48
52
  const getInstance: () => echarts.ECharts | null = () => {
49
- if (!chartInstance) initCharts();
50
- return chartInstance;
51
- };
53
+ if (!chartInstance)
54
+ initCharts()
55
+ return chartInstance
56
+ }
52
57
 
53
58
  onUnmounted(() => {
54
- chartInstance?.dispose();
55
- resizeObserver?.disconnect();
56
- resizeObserver = undefined;
57
- });
59
+ chartInstance?.dispose()
60
+ resizeObserver?.disconnect()
61
+ resizeObserver = undefined
62
+ })
58
63
 
59
64
  return {
60
65
  setOptions,
61
66
  resize,
62
67
  echarts,
63
68
  getInstance,
64
- };
69
+ }
65
70
  }
@@ -1,5 +1,7 @@
1
1
  import { createJsonStorage, i18n } from '@bubblesjs/i18n-core'
2
2
 
3
+ // Initialization must finish before App renders so the first locale is available synchronously.
4
+ // eslint-disable-next-line antfu/no-top-level-await
3
5
  export const leftStore = await i18n.init({
4
6
  locale: 'zh_CN',
5
7
  loaderMessage: async (locale?: string) => (await import(`@/locales/${locale}.json`))?.default,