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.
- package/dist/index.js +21 -0
- package/index.js +1 -1
- package/package.json +24 -24
- package/template-taro-react-oxc/.env.development +1 -1
- package/template-taro-react-oxc/.env.production +1 -1
- package/template-taro-react-oxc/project.config.json +1 -1
- package/template-taro-vue-eslint/project.config.json +2 -2
- 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
- package/template-vp-monorepo-react-hono/.vite-hooks/commit-msg +2 -0
- package/template-vp-monorepo-react-hono/.vite-hooks/pre-commit +2 -0
- package/template-vp-monorepo-react-hono/.vscode/extensions.json +3 -0
- package/template-vp-monorepo-react-hono/.vscode/settings.json +23 -0
- package/template-vp-monorepo-react-hono/AGENTS.md +16 -0
- package/template-vp-monorepo-react-hono/README.md +54 -0
- package/template-vp-monorepo-react-hono/apps/server/.env.example +13 -0
- package/template-vp-monorepo-react-hono/apps/server/README.md +75 -0
- package/template-vp-monorepo-react-hono/apps/server/drizzle/0000_flaky_madame_masque.sql +18 -0
- package/template-vp-monorepo-react-hono/apps/server/drizzle/meta/0000_snapshot.json +153 -0
- package/template-vp-monorepo-react-hono/apps/server/drizzle/meta/_journal.json +13 -0
- package/template-vp-monorepo-react-hono/apps/server/drizzle.config.ts +19 -0
- package/template-vp-monorepo-react-hono/apps/server/package.json +46 -0
- package/template-vp-monorepo-react-hono/apps/server/src/app.test.ts +57 -0
- package/template-vp-monorepo-react-hono/apps/server/src/app.ts +68 -0
- package/template-vp-monorepo-react-hono/apps/server/src/common/errors/app-error.ts +23 -0
- package/template-vp-monorepo-react-hono/apps/server/src/common/http/response.ts +21 -0
- package/template-vp-monorepo-react-hono/apps/server/src/common/logger.ts +30 -0
- package/template-vp-monorepo-react-hono/apps/server/src/config/env.ts +54 -0
- package/template-vp-monorepo-react-hono/apps/server/src/index.bun.ts +60 -0
- package/template-vp-monorepo-react-hono/apps/server/src/index.ts +73 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/client.ts +46 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/schema/index.ts +1 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/database/schema/job-runs.ts +42 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/queue/connection.ts +6 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/redis/client.ts +39 -0
- package/template-vp-monorepo-react-hono/apps/server/src/infrastructure/redis/options.ts +28 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/health/health.routes.ts +17 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/health/health.service.ts +59 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.queue.ts +46 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.repository.ts +101 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.routes.ts +46 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.schemas.ts +9 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.service.ts +57 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.types.ts +11 -0
- package/template-vp-monorepo-react-hono/apps/server/src/modules/jobs/jobs.worker.ts +108 -0
- package/template-vp-monorepo-react-hono/apps/server/src/runtime/shutdown.ts +38 -0
- package/template-vp-monorepo-react-hono/apps/server/src/worker.ts +48 -0
- package/template-vp-monorepo-react-hono/apps/server/tsconfig.json +15 -0
- package/template-vp-monorepo-react-hono/apps/server/vite.config.ts +15 -0
- package/template-vp-monorepo-react-hono/apps/web/.env +2 -0
- package/template-vp-monorepo-react-hono/apps/web/.env.dev +1 -0
- package/template-vp-monorepo-react-hono/apps/web/.env.prod +1 -0
- package/template-vp-monorepo-react-hono/apps/web/index.html +13 -0
- package/template-vp-monorepo-react-hono/apps/web/package.json +35 -0
- package/template-vp-monorepo-react-hono/apps/web/public/favicon.svg +1 -0
- package/template-vp-monorepo-react-hono/apps/web/public/icons.svg +24 -0
- package/template-vp-monorepo-react-hono/apps/web/src/App.tsx +25 -0
- package/template-vp-monorepo-react-hono/apps/web/src/assets/hero.png +0 -0
- package/template-vp-monorepo-react-hono/apps/web/src/assets/react.svg +1 -0
- package/template-vp-monorepo-react-hono/apps/web/src/assets/vite.svg +1 -0
- package/template-vp-monorepo-react-hono/apps/web/src/components/Loading/PageLoading.tsx +11 -0
- package/template-vp-monorepo-react-hono/apps/web/src/locales/en_US.json +4 -0
- package/template-vp-monorepo-react-hono/apps/web/src/locales/zh_CN.json +4 -0
- package/template-vp-monorepo-react-hono/apps/web/src/main.tsx +5 -0
- package/template-vp-monorepo-react-hono/apps/web/src/pages/home/index.tsx +47 -0
- package/template-vp-monorepo-react-hono/apps/web/src/router/index.tsx +25 -0
- package/template-vp-monorepo-react-hono/apps/web/src/router/modules/.gitkeep +0 -0
- package/template-vp-monorepo-react-hono/apps/web/src/styles/index.css +7 -0
- package/template-vp-monorepo-react-hono/apps/web/src/types/auto-imports.d.ts +58 -0
- package/template-vp-monorepo-react-hono/apps/web/src/utils/env/index.ts +6 -0
- package/template-vp-monorepo-react-hono/apps/web/src/utils/request/core/index.ts +420 -0
- package/template-vp-monorepo-react-hono/apps/web/src/utils/request/core/utils.ts +39 -0
- package/template-vp-monorepo-react-hono/apps/web/src/utils/request/index.ts +61 -0
- package/template-vp-monorepo-react-hono/apps/web/tsconfig.json +18 -0
- package/template-vp-monorepo-react-hono/apps/web/vite.config.ts +45 -0
- package/template-vp-monorepo-react-hono/commitlint.config.js +1 -0
- package/template-vp-monorepo-react-hono/docker-compose.yml +41 -0
- package/template-vp-monorepo-react-hono/mise.toml +4 -0
- package/template-vp-monorepo-react-hono/package.json +37 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/package.json +20 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/format.ts +9 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/i18n.ts +73 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/index.ts +24 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/storage.ts +47 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/store.ts +48 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/src/types.ts +36 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/tsconfig.json +4 -0
- package/template-vp-monorepo-react-hono/packages/i18n/core/vite.config.ts +13 -0
- package/template-vp-monorepo-react-hono/packages/i18n/react/package.json +28 -0
- package/template-vp-monorepo-react-hono/packages/i18n/react/src/index.tsx +26 -0
- package/template-vp-monorepo-react-hono/packages/i18n/react/src/use-store.ts +14 -0
- package/template-vp-monorepo-react-hono/packages/i18n/react/tsconfig.json +9 -0
- package/template-vp-monorepo-react-hono/packages/i18n/react/vite.config.ts +16 -0
- package/template-vp-monorepo-react-hono/packages/i18n/vue/package.json +27 -0
- package/template-vp-monorepo-react-hono/packages/i18n/vue/src/index.ts +52 -0
- package/template-vp-monorepo-react-hono/packages/i18n/vue/src/use-store.ts +19 -0
- package/template-vp-monorepo-react-hono/packages/i18n/vue/tsconfig.json +8 -0
- package/template-vp-monorepo-react-hono/packages/i18n/vue/vite.config.ts +16 -0
- package/template-vp-monorepo-react-hono/pnpm-workspace.yaml +57 -0
- package/template-vp-monorepo-react-hono/scripts/clean.mjs +48 -0
- package/template-vp-monorepo-react-hono/tsconfig.base.json +10 -0
- package/template-vp-monorepo-react-hono/tsconfig.bundler.json +12 -0
- package/template-vp-monorepo-react-hono/tsconfig.json +11 -0
- package/template-vp-monorepo-react-hono/tsconfig.lib.json +10 -0
- package/template-vp-monorepo-react-hono/vite.config.ts +20 -0
- package/template-vp-monorepo-react-nestjs/.spaces/server/todo.md +991 -0
- package/template-vp-monorepo-react-nestjs/.vscode/launch.json +16 -0
- package/template-vp-monorepo-react-nestjs/.vscode/settings.json +21 -18
- package/template-vp-monorepo-react-nestjs/apps/server/.env.development +3 -39
- package/template-vp-monorepo-react-nestjs/apps/server/.swcrc +8 -0
- package/template-vp-monorepo-react-nestjs/apps/server/drizzle.config.ts +8 -3
- package/template-vp-monorepo-react-nestjs/apps/server/nest-cli.json +8 -1
- package/template-vp-monorepo-react-nestjs/apps/server/package.json +11 -6
- package/template-vp-monorepo-react-nestjs/apps/server/src/app.controller.ts +2 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/app.module.ts +20 -15
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/adapters/fastify.adapter.ts +16 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/auth.ts +2 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/response.ts +0 -4
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/session.constants.ts +28 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/current-auth.decorator.ts +16 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/public.decorator.ts +4 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/dto/api-failure.dto.ts +25 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/error/common.error.ts +40 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/exceptions/app.exception.ts +55 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/filters/global-exception.filter.ts +384 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/openapi/response-headers.ts +9 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/index.ts +1 -1
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/session.config.ts +36 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/database/schema.ts +4 -64
- package/template-vp-monorepo-react-nestjs/apps/server/src/main.ts +29 -8
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.controller.ts +55 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.errors.ts +42 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.module.ts +26 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.repository.ts +40 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/auth.service.ts +129 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/auth-repsponse.dto.ts +31 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/login.dto.ts +11 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/dto/register.dto.ts +17 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/guards/session-auth.guard.ts +50 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/password.service.ts +24 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session-store.service.ts +198 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session-token.service.ts +29 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session.script.ts +221 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/auth/session/session.types.ts +24 -0
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/db/db.controller.ts +1 -1
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/db/dto/create-user.dto.ts +3 -5
- package/template-vp-monorepo-react-nestjs/apps/server/src/modules/test/redis/redis.service.ts +1 -1
- package/template-vp-monorepo-react-nestjs/apps/server/src/utils/env-arr.ts +3 -0
- package/template-vp-monorepo-react-nestjs/apps/server/test/error-catalog.spec.ts +30 -0
- package/template-vp-monorepo-react-nestjs/apps/server/tsconfig.build.json +11 -1
- package/template-vp-monorepo-react-nestjs/apps/server/tsconfig.json +12 -20
- package/template-vp-monorepo-react-nestjs/apps/server/vite.config.ts +15 -0
- package/template-vp-monorepo-react-nestjs/apps/web/package.json +1 -0
- package/template-vp-monorepo-react-nestjs/apps/web/tsconfig.json +5 -15
- package/template-vp-monorepo-react-nestjs/apps/web-vue/commitlint.config.js +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/lefthook.yml +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/package.json +1 -3
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/api/index.ts +5 -5
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/components/Icon/svg-icon.vue +3 -3
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/hooks/chart/lib.ts +6 -6
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/hooks/chart/useEcharts.ts +34 -29
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/i18n/instance.ts +2 -0
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/layout/default/index.vue +17 -32
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/locales/en_US.json +4 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/locales/zh_CN.json +4 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/guard/index.ts +3 -3
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/guard/permissionGuard.ts +7 -7
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/index.ts +7 -7
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/router/interface.ts +6 -6
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/store/index.ts +6 -6
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/store/modules/user.ts +9 -9
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/styles/index.scss +3 -3
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/types/antdv-next.d.ts +1 -0
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/env.ts +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/core/index.ts +63 -45
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/core/utils.ts +12 -6
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/utils/request/index.ts +1 -1
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/echart/config.ts +687 -687
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/echart/index.vue +7 -7
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/example/tree-chart.vue +2 -7
- package/template-vp-monorepo-react-nestjs/apps/web-vue/src/views/home/index.vue +13 -3
- package/template-vp-monorepo-react-nestjs/apps/web-vue/tsconfig.json +5 -17
- package/template-vp-monorepo-react-nestjs/apps/web-vue/uno.config.ts +5 -5
- package/template-vp-monorepo-react-nestjs/i18n.config.ts +22 -0
- package/template-vp-monorepo-react-nestjs/package.json +12 -1
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/README.md +113 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/docs/excel-sync-plan.md +618 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/package.json +31 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/cli.ts +5 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/command.ts +512 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/config.ts +15 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/files.ts +67 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/index.ts +19 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/load-config.ts +228 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/report.ts +57 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.test.ts +81 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.ts +290 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/sync.ts +274 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/command.test.ts +209 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/config.test.ts +19 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/load-config.test.ts +194 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/report.test.ts +63 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/sync.test.ts +203 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/temporary-directory.ts +25 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/tsconfig.json +9 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/vite.config.ts +18 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/core/tsconfig.json +1 -12
- package/template-vp-monorepo-react-nestjs/packages/i18n/react/tsconfig.json +3 -10
- package/template-vp-monorepo-react-nestjs/packages/i18n/vue/tsconfig.json +3 -10
- package/template-vp-monorepo-react-nestjs/packages/shared/package.json +40 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/index.ts +13 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/types/auth.ts +35 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/types/common.ts +11 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/types/index.ts +11 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/account.ts +5 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/index.ts +2 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/src/utils/session-terminal.ts +11 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/tsconfig.json +4 -0
- package/template-vp-monorepo-react-nestjs/packages/shared/vite.config.ts +17 -0
- package/template-vp-monorepo-react-nestjs/pnpm-workspace.yaml +6 -6
- package/template-vp-monorepo-react-nestjs/scripts/clean.mjs +48 -0
- package/template-vp-monorepo-react-nestjs/tsconfig.base.json +10 -0
- package/template-vp-monorepo-react-nestjs/tsconfig.bundler.json +12 -0
- package/template-vp-monorepo-react-nestjs/tsconfig.json +8 -6
- package/template-vp-monorepo-react-nestjs/tsconfig.lib.json +10 -0
- package/dist/index.mjs +0 -422
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/decorator.ts +0 -2
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/decorators/bypass.ts +0 -12
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/interceptors/transform.ts +0 -34
- package/template-vp-monorepo-react-nestjs/apps/server/src/common/model/response.ts +0 -23
- package/template-vp-monorepo-react-nestjs/apps/server/src/config/auth.config.ts +0 -64
- package/template-vp-monorepo-react-nestjs/apps/web-vue/pnpm-workspace.yaml +0 -16
- /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,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Nest Attach 9229",
|
|
6
|
+
"type": "node",
|
|
7
|
+
"request": "attach",
|
|
8
|
+
"address": "127.0.0.1",
|
|
9
|
+
"port": 9229,
|
|
10
|
+
"restart": true,
|
|
11
|
+
"sourceMaps": true,
|
|
12
|
+
"outFiles": ["${workspaceFolder}/apps/server/dist/**/*.js"],
|
|
13
|
+
"skipFiles": ["<node_internals>/**", "${workspaceFolder}/**/node_modules/**"]
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
"eslint.enable":
|
|
2
|
+
"eslint.enable": true,
|
|
3
3
|
"prettier.enable": false,
|
|
4
4
|
"biome.enabled": false,
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
"editor.defaultFormatter": "oxc.oxc-vscode",
|
|
7
|
-
"[javascript]": {
|
|
8
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
9
|
-
},
|
|
10
|
-
"[javascriptreact]": {
|
|
11
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
12
|
-
},
|
|
13
|
-
"[typescript]": {
|
|
14
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
15
|
-
},
|
|
16
|
-
"[typescriptreact]": {
|
|
17
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
18
|
-
},
|
|
19
|
-
"oxc.fmt.configPath": "./vite.config.ts",
|
|
20
7
|
"editor.formatOnSave": true,
|
|
21
|
-
|
|
8
|
+
|
|
22
9
|
"editor.codeActionsOnSave": {
|
|
23
|
-
"source.organizeImports": "
|
|
24
|
-
"source.fixAll.oxc": "
|
|
10
|
+
"source.organizeImports": "explicit",
|
|
11
|
+
"source.fixAll.oxc": "explicit",
|
|
12
|
+
"source.fixAll.eslint": "explicit"
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
"oxc.typeAware": false,
|
|
16
|
+
"oxc.lint.run": "onType",
|
|
17
|
+
|
|
18
|
+
// ESLint 只把 web-vue 当作工作目录
|
|
19
|
+
"eslint.workingDirectories": ["./apps/web-vue"],
|
|
20
|
+
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "vue"],
|
|
21
|
+
|
|
22
|
+
"files.watcherExclude": {
|
|
23
|
+
"**/node_modules/**": true,
|
|
24
|
+
"**/.pnpm/**": true,
|
|
25
|
+
"**/dist/**": true,
|
|
26
|
+
"**/coverage/**": true,
|
|
27
|
+
"**/.vite/**": true
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -20,42 +20,6 @@ REDIS_PORT=6379
|
|
|
20
20
|
REDIS_PASSWORD=ml
|
|
21
21
|
REDIS_DB=0
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# JWT 的签发者,对应 JWT 中的 iss 字段:
|
|
27
|
-
JWT_ISSUER=bubbles-auth
|
|
28
|
-
# 验证 Token 时,服务器会检查它是不是由 bubbles-auth 签发的。它是标识符,不是密码。 JWT 的目标使用者,对应 aud 字段
|
|
29
|
-
# 表示这个 Token 是给 bubbles-api 使用的,避免一个系统签发的 JWT 被误用到另一个系统。
|
|
30
|
-
JWT_AUDIENCE=bubbles-api
|
|
31
|
-
# Access Token 的有效时间:
|
|
32
|
-
JWT_ACCESS_TTL_SECONDS=600
|
|
33
|
-
# JWT 时间校验的允许误差:
|
|
34
|
-
JWT_CLOCK_TOLERANCE_SECONDS=30
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
# Refresh Token 的服务端“椒值”,通常用于计算哈希:
|
|
38
|
-
REFRESH_TOKEN_PEPPER=ON-ECMSvcmjVryktpp-1BLpDl3r7Sl63-GXyy1uto2_1AbqCbNOndIfdtuBVe1o_
|
|
39
|
-
# Refresh Token 的有效时间: 30 天
|
|
40
|
-
REFRESH_TOKEN_TTL_SECONDS=2592000
|
|
41
|
-
# 保存 Refresh Token 的 Cookie 名称,浏览器中大致是:
|
|
42
|
-
# 生产环境如果使用 __Host- 安全前缀,可以改成: __Host-refresh_token
|
|
43
|
-
# REFRESH_COOKIE_PATH=/
|
|
44
|
-
# REFRESH_COOKIE_SECURE=true
|
|
45
|
-
# 并且不能设置 Domain。
|
|
46
|
-
REFRESH_COOKIE_NAME=refresh_token
|
|
47
|
-
# Cookie 只会自动发送给 /auth 路径下的接口 这样可以减少 Refresh Token 暴露给无关接口的机会。
|
|
48
|
-
REFRESH_COOKIE_PATH=/auth
|
|
49
|
-
# 表示这个 Cookie 不强制要求 HTTPS,适合本地 HTTP 开发
|
|
50
|
-
REFRESH_COOKIE_SECURE=false
|
|
51
|
-
|
|
52
|
-
# 认证状态在当前服务进程的本地内存中缓存
|
|
53
|
-
# 例如服务器查到“用户正常、会话有效”,可以缓存 30 秒,避免每个请求都查询数据库或 Redis。
|
|
54
|
-
# 本地缓存意味着每个 NestJS 实例都有自己的缓存,所以还需要下面的失效通知机制。
|
|
55
|
-
AUTH_LOCAL_CACHE_TTL_MS=30000
|
|
56
|
-
|
|
57
|
-
#
|
|
58
|
-
AUTH_TOMBSTONE_TTL_SECONDS=900
|
|
59
|
-
|
|
60
|
-
# 当修改密码或者踢人的时候通过这个通道 通知用户失效
|
|
61
|
-
AUTH_EVENT_CHANNEL=auth-state:invalidate
|
|
23
|
+
SESSION_TOKEN_PEPPER=EfN6+CbfvlXkxp9SeTkFpziHPtr0/krxZItsjqUCc7AnbH9cmnDXNSFeNpa78Z42
|
|
24
|
+
SESSION_IDLE_TTL_SECONDS=7200
|
|
25
|
+
SESSION_ABSOLUTE_TTL_SECONDS=604800
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { ENV_ARR } from '@/utils/env-arr'
|
|
1
2
|
import { config } from 'dotenv'
|
|
2
3
|
import { defineConfig } from 'drizzle-kit'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
path
|
|
6
|
-
}
|
|
5
|
+
for (const path of ENV_ARR) {
|
|
6
|
+
config({ path })
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (!process.env.DATABASE_URL) {
|
|
10
|
+
throw new Error('DATABASE_URL 未配置')
|
|
11
|
+
}
|
|
7
12
|
|
|
8
13
|
export default defineConfig({
|
|
9
14
|
schema: './src/database/schema.ts',
|
|
@@ -7,22 +7,22 @@
|
|
|
7
7
|
"author": "",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "nest build",
|
|
10
|
-
"format": "
|
|
10
|
+
"format": "vp fmt",
|
|
11
11
|
"dev": "nest start --watch",
|
|
12
12
|
"debug": "nest start --debug --watch",
|
|
13
|
+
"debug:start": "nest start --watch --exec \"node --inspect-brk\"",
|
|
13
14
|
"build:preview": "node dist/main",
|
|
14
15
|
"db:push": "drizzle-kit push",
|
|
15
16
|
"db:generate": "drizzle-kit generate",
|
|
16
17
|
"db:migrate": "drizzle-kit migrate",
|
|
17
|
-
"db:studio": "drizzle-kit studio"
|
|
18
|
+
"db:studio": "drizzle-kit studio",
|
|
19
|
+
"test": "vp test"
|
|
18
20
|
},
|
|
19
21
|
"dependencies": {
|
|
20
|
-
"@fastify/cookie": "catalog:",
|
|
21
22
|
"@nestjs-modules/ioredis": "catalog:",
|
|
22
23
|
"@nestjs/common": "catalog:",
|
|
23
24
|
"@nestjs/config": "catalog:",
|
|
24
25
|
"@nestjs/core": "catalog:",
|
|
25
|
-
"@nestjs/jwt": "catalog:",
|
|
26
26
|
"@nestjs/mapped-types": "catalog:",
|
|
27
27
|
"@nestjs/platform-fastify": "catalog:",
|
|
28
28
|
"argon2": "catalog:",
|
|
@@ -42,16 +42,21 @@
|
|
|
42
42
|
"@nestjs/schematics": "catalog:",
|
|
43
43
|
"@nestjs/swagger": "catalog:",
|
|
44
44
|
"@nestjs/testing": "catalog:",
|
|
45
|
+
"@swc/cli": "catalog:",
|
|
46
|
+
"@swc/core": "catalog:",
|
|
45
47
|
"@types/express": "catalog:",
|
|
46
|
-
"@types/node": "catalog:
|
|
48
|
+
"@types/node": "catalog:",
|
|
49
|
+
"@types/pg": "catalog:",
|
|
47
50
|
"cross-env": "catalog:",
|
|
48
51
|
"dotenv": "catalog:",
|
|
49
52
|
"drizzle-kit": "catalog:",
|
|
50
53
|
"globals": "catalog:",
|
|
54
|
+
"shared": "workspace:*",
|
|
51
55
|
"source-map-support": "catalog:",
|
|
52
56
|
"ts-loader": "catalog:",
|
|
53
57
|
"ts-node": "catalog:",
|
|
54
58
|
"tsconfig-paths": "catalog:",
|
|
55
|
-
"typescript": "catalog:"
|
|
59
|
+
"typescript": "catalog:",
|
|
60
|
+
"vite-plus": "catalog:"
|
|
56
61
|
}
|
|
57
62
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Controller, Get } from '@nestjs/common'
|
|
2
2
|
import { AppService } from './app.service'
|
|
3
|
+
import { Public } from './common/decorators/public.decorator'
|
|
3
4
|
|
|
4
5
|
@Controller()
|
|
5
6
|
export class AppController {
|
|
6
7
|
constructor(private readonly appService: AppService) {}
|
|
7
8
|
|
|
8
9
|
@Get()
|
|
10
|
+
@Public()
|
|
9
11
|
getHello(): string {
|
|
10
12
|
return this.appService.getHello()
|
|
11
13
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
+
import { appConfig, databaseConfig, llmConfig, redisConfig, sessionConfig } from '@/config'
|
|
2
|
+
import { RedisModule } from '@nestjs-modules/ioredis'
|
|
1
3
|
import { Module } from '@nestjs/common'
|
|
4
|
+
import { ConfigModule, ConfigService } from '@nestjs/config'
|
|
5
|
+
import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'
|
|
6
|
+
import { ZodSerializerInterceptor, ZodValidationPipe } from 'nestjs-zod'
|
|
2
7
|
import { AppController } from './app.controller'
|
|
3
8
|
import { AppService } from './app.service'
|
|
4
|
-
import {
|
|
5
|
-
import { appConfig, databaseConfig, llmConfig, redisConfig, authConfig } from '@/config'
|
|
6
|
-
import { ResponseInterceptor } from '@/common/interceptors/transform'
|
|
7
|
-
import { APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'
|
|
8
|
-
import { RedisModule } from '@nestjs-modules/ioredis'
|
|
9
|
-
import { TestRedisModule } from './modules/test/redis/redis.module'
|
|
9
|
+
import { GlobalExceptionFilter } from './common/filters/global-exception.filter'
|
|
10
10
|
import { DatabaseModule } from './database/db.module'
|
|
11
|
+
import { AuthModule } from './modules/auth/auth.module'
|
|
11
12
|
import { TestDbModule } from './modules/test/db/db.module'
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
const nodeEnv = process.env.NODE_ENV ?? 'development'
|
|
13
|
+
import { TestRedisModule } from './modules/test/redis/redis.module'
|
|
14
|
+
import { ENV_ARR } from './utils/env-arr'
|
|
15
15
|
|
|
16
16
|
@Module({
|
|
17
17
|
imports: [
|
|
18
18
|
ConfigModule.forRoot({
|
|
19
19
|
isGlobal: true,
|
|
20
|
-
envFilePath:
|
|
21
|
-
load: [appConfig, databaseConfig, llmConfig, redisConfig,
|
|
20
|
+
envFilePath: ENV_ARR,
|
|
21
|
+
load: [appConfig, databaseConfig, llmConfig, redisConfig, sessionConfig],
|
|
22
22
|
}),
|
|
23
23
|
DatabaseModule,
|
|
24
24
|
RedisModule.forRootAsync({
|
|
@@ -30,19 +30,20 @@ const nodeEnv = process.env.NODE_ENV ?? 'development'
|
|
|
30
30
|
port: config.get('redis.port'),
|
|
31
31
|
password: config.get('redis.password'),
|
|
32
32
|
db: config.get('redis.db'),
|
|
33
|
+
connectTimeout: 3000,
|
|
34
|
+
commandTimeout: 2000,
|
|
35
|
+
maxRetriesPerRequest: 1,
|
|
36
|
+
enableOfflineQueue: false,
|
|
33
37
|
},
|
|
34
38
|
}),
|
|
35
39
|
}),
|
|
36
40
|
TestRedisModule,
|
|
37
41
|
TestDbModule,
|
|
42
|
+
AuthModule,
|
|
38
43
|
],
|
|
39
44
|
controllers: [AppController],
|
|
40
45
|
providers: [
|
|
41
46
|
AppService,
|
|
42
|
-
{
|
|
43
|
-
provide: APP_INTERCEPTOR,
|
|
44
|
-
useClass: ResponseInterceptor,
|
|
45
|
-
},
|
|
46
47
|
// ZOD 全局校验管道
|
|
47
48
|
{
|
|
48
49
|
provide: APP_PIPE,
|
|
@@ -53,6 +54,10 @@ const nodeEnv = process.env.NODE_ENV ?? 'development'
|
|
|
53
54
|
provide: APP_INTERCEPTOR,
|
|
54
55
|
useClass: ZodSerializerInterceptor,
|
|
55
56
|
},
|
|
57
|
+
{
|
|
58
|
+
provide: APP_FILTER,
|
|
59
|
+
useClass: GlobalExceptionFilter,
|
|
60
|
+
},
|
|
56
61
|
],
|
|
57
62
|
})
|
|
58
63
|
export class AppModule {}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FastifyAdapter } from '@nestjs/platform-fastify'
|
|
2
|
+
import { randomUUID } from 'crypto'
|
|
3
|
+
|
|
4
|
+
export function createFastifyAdapter() {
|
|
5
|
+
const adapter = new FastifyAdapter({
|
|
6
|
+
trustProxy: true,
|
|
7
|
+
genReqId: () => randomUUID(),
|
|
8
|
+
logger: false,
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
adapter.getInstance().addHook('onRequest', (request, reply, done) => {
|
|
12
|
+
reply.header('x-request-id', request.id)
|
|
13
|
+
done()
|
|
14
|
+
})
|
|
15
|
+
return adapter
|
|
16
|
+
}
|
package/template-vp-monorepo-react-nestjs/apps/server/src/common/constants/session.constants.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SessionTerminalType } from 'shared/types'
|
|
2
|
+
|
|
3
|
+
export { isSessionTerminal, SESSION_TERMINALS } from 'shared/utils'
|
|
4
|
+
|
|
5
|
+
export const SESSION_KEY_PREFIX = 'auth:v1:session:'
|
|
6
|
+
export const SESSION_SLOT_PREFIX = 'auth:v1:slot:'
|
|
7
|
+
|
|
8
|
+
export function createSessionKey(tokenDigest: string) {
|
|
9
|
+
return `${SESSION_KEY_PREFIX}${tokenDigest}`
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createSessionSlotKey(userId: string, terminal: SessionTerminalType) {
|
|
13
|
+
return `${SESSION_SLOT_PREFIX}${userId}:${terminal}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function detectSessionTerminal(userAgent: string | undefined): SessionTerminalType {
|
|
17
|
+
const value = userAgent ?? ''
|
|
18
|
+
|
|
19
|
+
if (/\bElectron\//i.test(value)) {
|
|
20
|
+
return 'desktop'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (/Android|iPhone|iPad|iPod/i.test(value)) {
|
|
24
|
+
return 'mobile'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return 'web'
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AUTH_ERRORS } from '@/modules/auth/auth.errors'
|
|
2
|
+
import { AuthenticatedRequest, CurrentAuthType } from '@/modules/auth/session/session.types'
|
|
3
|
+
import { createParamDecorator, ExecutionContext } from '@nestjs/common'
|
|
4
|
+
import { AppException } from '../exceptions/app.exception'
|
|
5
|
+
|
|
6
|
+
export const CurrentAuth = createParamDecorator(
|
|
7
|
+
(_data: unknown, context: ExecutionContext): CurrentAuthType => {
|
|
8
|
+
const request = context.switchToHttp().getRequest<AuthenticatedRequest>()
|
|
9
|
+
|
|
10
|
+
if (!request.auth) {
|
|
11
|
+
throw new AppException(AUTH_ERRORS.CONTEXT_MISSING)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return request.auth
|
|
15
|
+
},
|
|
16
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
|
|
2
|
+
|
|
3
|
+
export class ApiErrorDetailDto {
|
|
4
|
+
@ApiPropertyOptional({ example: 'account' })
|
|
5
|
+
path?: string
|
|
6
|
+
|
|
7
|
+
@ApiProperty({ example: 'too_small' })
|
|
8
|
+
code!: string
|
|
9
|
+
|
|
10
|
+
@ApiProperty({ example: '账号至少需要 4 个字符' })
|
|
11
|
+
message!: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ApiFailureDto {
|
|
15
|
+
@ApiProperty({ example: 'COMMON.VALIDATION_FAILED' })
|
|
16
|
+
code!: string
|
|
17
|
+
|
|
18
|
+
@ApiProperty({ example: '请求参数校验失败' })
|
|
19
|
+
message!: string
|
|
20
|
+
|
|
21
|
+
@ApiPropertyOptional({
|
|
22
|
+
type: () => [ApiErrorDetailDto],
|
|
23
|
+
})
|
|
24
|
+
details?: ApiErrorDetailDto[]
|
|
25
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { AppErrorDefinition } from '../exceptions/app.exception'
|
|
3
|
+
|
|
4
|
+
export const COMMON_ERRORS = {
|
|
5
|
+
VALIDATION_FAILED: {
|
|
6
|
+
code: 'COMMON.VALIDATION_FAILED',
|
|
7
|
+
publicMessage: '请求参数校验失败',
|
|
8
|
+
status: HttpStatus.BAD_REQUEST,
|
|
9
|
+
},
|
|
10
|
+
BAD_REQUEST: {
|
|
11
|
+
code: 'COMMON.BAD_REQUEST',
|
|
12
|
+
publicMessage: '请求内容无效',
|
|
13
|
+
status: HttpStatus.BAD_REQUEST,
|
|
14
|
+
},
|
|
15
|
+
FORBIDDEN: {
|
|
16
|
+
code: 'COMMON.FORBIDDEN',
|
|
17
|
+
publicMessage: '没有权限执行此操作',
|
|
18
|
+
status: HttpStatus.FORBIDDEN,
|
|
19
|
+
},
|
|
20
|
+
NOT_FOUND: {
|
|
21
|
+
code: 'COMMON.NOT_FOUND',
|
|
22
|
+
publicMessage: '请求的资源不存在',
|
|
23
|
+
status: HttpStatus.NOT_FOUND,
|
|
24
|
+
},
|
|
25
|
+
TOO_MANY_REQUESTS: {
|
|
26
|
+
code: 'COMMON.TOO_MANY_REQUESTS',
|
|
27
|
+
publicMessage: '请求过于频繁,请稍后重试',
|
|
28
|
+
status: HttpStatus.TOO_MANY_REQUESTS,
|
|
29
|
+
},
|
|
30
|
+
SERVICE_UNAVAILABLE: {
|
|
31
|
+
code: 'COMMON.SERVICE_UNAVAILABLE',
|
|
32
|
+
publicMessage: '服务暂时不可用,请稍后重试',
|
|
33
|
+
status: HttpStatus.SERVICE_UNAVAILABLE,
|
|
34
|
+
},
|
|
35
|
+
INTERNAL_SERVER_ERROR: {
|
|
36
|
+
code: 'COMMON.INTERNAL_SERVER_ERROR',
|
|
37
|
+
publicMessage: '服务器内部错误',
|
|
38
|
+
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
39
|
+
},
|
|
40
|
+
} as const satisfies Record<string, AppErrorDefinition>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HttpException, HttpStatus } from '@nestjs/common'
|
|
2
|
+
import { ApiErrorDetail } from 'shared/types'
|
|
3
|
+
|
|
4
|
+
const ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]*(?:\.[A-Z][A-Z0-9_]*)+$/
|
|
5
|
+
|
|
6
|
+
export interface AppErrorDefinition<Code extends string = string> {
|
|
7
|
+
readonly code: Code
|
|
8
|
+
readonly publicMessage: string
|
|
9
|
+
readonly status: HttpStatus
|
|
10
|
+
readonly bearerChallenge?: true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AppExceptionOptions {
|
|
14
|
+
readonly cause?: unknown
|
|
15
|
+
readonly details?: readonly ApiErrorDetail[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function assertErrorDefinition(definition: AppErrorDefinition): void {
|
|
19
|
+
if (!ERROR_CODE_PATTERN.test(definition.code) || definition.code.length > 80) {
|
|
20
|
+
throw new TypeError('Invalid application error code: ' + definition.code)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (definition.status < 400 || definition.status > 599) {
|
|
24
|
+
throw new TypeError('Application error status must be between 400 and 599')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!definition.publicMessage.trim()) {
|
|
28
|
+
throw new TypeError('Application error publicMessage must not be empty')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (definition.bearerChallenge && definition.status !== 401) {
|
|
32
|
+
throw new TypeError('bearerChallenge is only valid for HTTP 401')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (definition.status === 401 && !definition.bearerChallenge) {
|
|
36
|
+
throw new TypeError('HTTP 401 errors must declare bearerChallenge')
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class AppException extends HttpException {
|
|
41
|
+
readonly definition: AppErrorDefinition
|
|
42
|
+
readonly details?: readonly ApiErrorDetail[]
|
|
43
|
+
|
|
44
|
+
constructor(definition: AppErrorDefinition, options: AppExceptionOptions = {}) {
|
|
45
|
+
assertErrorDefinition(definition)
|
|
46
|
+
|
|
47
|
+
super(definition.publicMessage, definition.status, {
|
|
48
|
+
cause: options.cause,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
this.name = AppException.name
|
|
52
|
+
this.definition = definition
|
|
53
|
+
this.details = options.details
|
|
54
|
+
}
|
|
55
|
+
}
|