@pcontext/api 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -0
- package/dist/app.d.mts +44779 -0
- package/dist/app.d.mts.map +1 -0
- package/dist/app.mjs +37 -0
- package/dist/app.mjs.map +1 -0
- package/dist/client.d.mts +22428 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +15 -0
- package/dist/client.mjs.map +1 -0
- package/dist/dev.d.mts +11 -0
- package/dist/dev.d.mts.map +1 -0
- package/dist/dev.mjs +16 -0
- package/dist/dev.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +10 -0
- package/dist/index.mjs.map +1 -0
- package/dist/modules/doc/chat.route.d.mts +18 -0
- package/dist/modules/doc/chat.route.d.mts.map +1 -0
- package/dist/modules/doc/chat.route.mjs +20 -0
- package/dist/modules/doc/chat.route.mjs.map +1 -0
- package/dist/modules/doc/chat.service.d.mts +10 -0
- package/dist/modules/doc/chat.service.d.mts.map +1 -0
- package/dist/modules/doc/chat.service.mjs +29 -0
- package/dist/modules/doc/chat.service.mjs.map +1 -0
- package/dist/modules/doc/doc.dto.d.mts +67 -0
- package/dist/modules/doc/doc.dto.d.mts.map +1 -0
- package/dist/modules/doc/doc.dto.mjs +43 -0
- package/dist/modules/doc/doc.dto.mjs.map +1 -0
- package/dist/modules/doc/doc.entity.d.mts +19 -0
- package/dist/modules/doc/doc.entity.d.mts.map +1 -0
- package/dist/modules/doc/doc.entity.mjs +1 -0
- package/dist/modules/doc/doc.repo.interface.d.mts +28 -0
- package/dist/modules/doc/doc.repo.interface.d.mts.map +1 -0
- package/dist/modules/doc/doc.repo.interface.mjs +1 -0
- package/dist/modules/doc/doc.route.d.mts +14193 -0
- package/dist/modules/doc/doc.route.d.mts.map +1 -0
- package/dist/modules/doc/doc.route.mjs +100 -0
- package/dist/modules/doc/doc.route.mjs.map +1 -0
- package/dist/modules/doc/doc.service.d.mts +38 -0
- package/dist/modules/doc/doc.service.d.mts.map +1 -0
- package/dist/modules/doc/doc.service.mjs +134 -0
- package/dist/modules/doc/doc.service.mjs.map +1 -0
- package/dist/modules/doc/doc.vo.d.mts +17 -0
- package/dist/modules/doc/doc.vo.d.mts.map +1 -0
- package/dist/modules/doc/doc.vo.mjs +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts +21 -0
- package/dist/modules/doc/infrastructure/agent/engine/chat.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/chat.mjs +36 -0
- package/dist/modules/doc/infrastructure/agent/engine/chat.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts +28 -0
- package/dist/modules/doc/infrastructure/agent/engine/generate.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/generate.mjs +135 -0
- package/dist/modules/doc/infrastructure/agent/engine/generate.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts +7 -0
- package/dist/modules/doc/infrastructure/agent/engine/query-filter.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs +12 -0
- package/dist/modules/doc/infrastructure/agent/engine/query-filter.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts +54 -0
- package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs +142 -0
- package/dist/modules/doc/infrastructure/agent/loaders/git-repository-reader.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/loaders/index.d.mts +3 -0
- package/dist/modules/doc/infrastructure/agent/loaders/index.mjs +4 -0
- package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts +42 -0
- package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs +104 -0
- package/dist/modules/doc/infrastructure/agent/loaders/website-crawl-reader.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/settings.d.mts +5 -0
- package/dist/modules/doc/infrastructure/agent/settings.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/settings.mjs +72 -0
- package/dist/modules/doc/infrastructure/agent/settings.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/storage/index.d.mts +7 -0
- package/dist/modules/doc/infrastructure/agent/storage/index.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/storage/index.mjs +12 -0
- package/dist/modules/doc/infrastructure/agent/storage/index.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts +14 -0
- package/dist/modules/doc/infrastructure/agent/storage/vector-store.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs +35 -0
- package/dist/modules/doc/infrastructure/agent/storage/vector-store.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/doc.po.d.mts +570 -0
- package/dist/modules/doc/infrastructure/doc.po.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/doc.po.mjs +54 -0
- package/dist/modules/doc/infrastructure/doc.po.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts +32 -0
- package/dist/modules/doc/infrastructure/doc.repo.pg.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/doc.repo.pg.mjs +157 -0
- package/dist/modules/doc/infrastructure/doc.repo.pg.mjs.map +1 -0
- package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts +32 -0
- package/dist/modules/doc/infrastructure/doc.repo.sqlite.d.mts.map +1 -0
- package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs +153 -0
- package/dist/modules/doc/infrastructure/doc.repo.sqlite.mjs.map +1 -0
- package/dist/modules/doc/mcp.route.d.mts +18 -0
- package/dist/modules/doc/mcp.route.d.mts.map +1 -0
- package/dist/modules/doc/mcp.route.mjs +39 -0
- package/dist/modules/doc/mcp.route.mjs.map +1 -0
- package/dist/modules/doc/mcp.service.d.mts +22 -0
- package/dist/modules/doc/mcp.service.d.mts.map +1 -0
- package/dist/modules/doc/mcp.service.mjs +119 -0
- package/dist/modules/doc/mcp.service.mjs.map +1 -0
- package/dist/modules/rank/rank.dto.d.mts +10 -0
- package/dist/modules/rank/rank.dto.d.mts.map +1 -0
- package/dist/modules/rank/rank.dto.mjs +8 -0
- package/dist/modules/rank/rank.dto.mjs.map +1 -0
- package/dist/modules/rank/rank.route.d.mts +2033 -0
- package/dist/modules/rank/rank.route.d.mts.map +1 -0
- package/dist/modules/rank/rank.route.mjs +20 -0
- package/dist/modules/rank/rank.route.mjs.map +1 -0
- package/dist/modules/rank/rank.service.d.mts +32 -0
- package/dist/modules/rank/rank.service.d.mts.map +1 -0
- package/dist/modules/rank/rank.service.mjs +3 -0
- package/dist/modules/rank/rank.vo.d.mts +9 -0
- package/dist/modules/rank/rank.vo.d.mts.map +1 -0
- package/dist/modules/rank/rank.vo.mjs +1 -0
- package/dist/modules/task/infrastructure/mq/task-context.d.mts +29 -0
- package/dist/modules/task/infrastructure/mq/task-context.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/mq/task-context.mjs +70 -0
- package/dist/modules/task/infrastructure/mq/task-context.mjs.map +1 -0
- package/dist/modules/task/infrastructure/mq/task-queue.d.mts +10 -0
- package/dist/modules/task/infrastructure/mq/task-queue.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/mq/task-queue.mjs +12 -0
- package/dist/modules/task/infrastructure/mq/task-queue.mjs.map +1 -0
- package/dist/modules/task/infrastructure/mq/task-worker.d.mts +13 -0
- package/dist/modules/task/infrastructure/mq/task-worker.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/mq/task-worker.mjs +35 -0
- package/dist/modules/task/infrastructure/mq/task-worker.mjs.map +1 -0
- package/dist/modules/task/infrastructure/task.po.d.mts +1147 -0
- package/dist/modules/task/infrastructure/task.po.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/task.po.mjs +55 -0
- package/dist/modules/task/infrastructure/task.po.mjs.map +1 -0
- package/dist/modules/task/infrastructure/task.repo.pg.d.mts +21 -0
- package/dist/modules/task/infrastructure/task.repo.pg.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/task.repo.pg.mjs +86 -0
- package/dist/modules/task/infrastructure/task.repo.pg.mjs.map +1 -0
- package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts +21 -0
- package/dist/modules/task/infrastructure/task.repo.sqlite.d.mts.map +1 -0
- package/dist/modules/task/infrastructure/task.repo.sqlite.mjs +89 -0
- package/dist/modules/task/infrastructure/task.repo.sqlite.mjs.map +1 -0
- package/dist/modules/task/task.dto.d.mts +26 -0
- package/dist/modules/task/task.dto.d.mts.map +1 -0
- package/dist/modules/task/task.dto.mjs +25 -0
- package/dist/modules/task/task.dto.mjs.map +1 -0
- package/dist/modules/task/task.entity.d.mts +43 -0
- package/dist/modules/task/task.entity.d.mts.map +1 -0
- package/dist/modules/task/task.entity.mjs +1 -0
- package/dist/modules/task/task.repo.interface.d.mts +17 -0
- package/dist/modules/task/task.repo.interface.d.mts.map +1 -0
- package/dist/modules/task/task.repo.interface.mjs +1 -0
- package/dist/modules/task/task.route.d.mts +4087 -0
- package/dist/modules/task/task.route.d.mts.map +1 -0
- package/dist/modules/task/task.route.mjs +63 -0
- package/dist/modules/task/task.route.mjs.map +1 -0
- package/dist/modules/task/task.service.d.mts +28 -0
- package/dist/modules/task/task.service.d.mts.map +1 -0
- package/dist/modules/task/task.service.mjs +202 -0
- package/dist/modules/task/task.service.mjs.map +1 -0
- package/dist/modules/task/task.vo.d.mts +18 -0
- package/dist/modules/task/task.vo.d.mts.map +1 -0
- package/dist/modules/task/task.vo.mjs +1 -0
- package/dist/modules/user/application/user.service.d.mts +24 -0
- package/dist/modules/user/application/user.service.d.mts.map +1 -0
- package/dist/modules/user/application/user.service.mjs +153 -0
- package/dist/modules/user/application/user.service.mjs.map +1 -0
- package/dist/modules/user/domain/user.entity.d.mts +24 -0
- package/dist/modules/user/domain/user.entity.d.mts.map +1 -0
- package/dist/modules/user/domain/user.entity.mjs +35 -0
- package/dist/modules/user/domain/user.entity.mjs.map +1 -0
- package/dist/modules/user/domain/user.repo.interface.d.mts +27 -0
- package/dist/modules/user/domain/user.repo.interface.d.mts.map +1 -0
- package/dist/modules/user/domain/user.repo.interface.mjs +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.d.mts +7 -0
- package/dist/modules/user/infrastructure/casbin/adapter.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.mjs +13 -0
- package/dist/modules/user/infrastructure/casbin/adapter.mjs.map +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts +19 -0
- package/dist/modules/user/infrastructure/casbin/adapter.pg.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs +129 -0
- package/dist/modules/user/infrastructure/casbin/adapter.pg.mjs.map +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts +19 -0
- package/dist/modules/user/infrastructure/casbin/adapter.sqlite.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs +129 -0
- package/dist/modules/user/infrastructure/casbin/adapter.sqlite.mjs.map +1 -0
- package/dist/modules/user/infrastructure/casbin/enforcer.d.mts +9 -0
- package/dist/modules/user/infrastructure/casbin/enforcer.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/casbin/enforcer.mjs +150 -0
- package/dist/modules/user/infrastructure/casbin/enforcer.mjs.map +1 -0
- package/dist/modules/user/infrastructure/casbin-rule.po.d.mts +643 -0
- package/dist/modules/user/infrastructure/casbin-rule.po.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/casbin-rule.po.mjs +30 -0
- package/dist/modules/user/infrastructure/casbin-rule.po.mjs.map +1 -0
- package/dist/modules/user/infrastructure/user.po.d.mts +392 -0
- package/dist/modules/user/infrastructure/user.po.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/user.po.mjs +34 -0
- package/dist/modules/user/infrastructure/user.po.mjs.map +1 -0
- package/dist/modules/user/infrastructure/user.repo.pg.d.mts +24 -0
- package/dist/modules/user/infrastructure/user.repo.pg.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/user.repo.pg.mjs +90 -0
- package/dist/modules/user/infrastructure/user.repo.pg.mjs.map +1 -0
- package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts +24 -0
- package/dist/modules/user/infrastructure/user.repo.sqlite.d.mts.map +1 -0
- package/dist/modules/user/infrastructure/user.repo.sqlite.mjs +88 -0
- package/dist/modules/user/infrastructure/user.repo.sqlite.mjs.map +1 -0
- package/dist/modules/user/interfaces/admin.route.d.mts +8270 -0
- package/dist/modules/user/interfaces/admin.route.d.mts.map +1 -0
- package/dist/modules/user/interfaces/admin.route.mjs +74 -0
- package/dist/modules/user/interfaces/admin.route.mjs.map +1 -0
- package/dist/modules/user/interfaces/role.route.d.mts +102 -0
- package/dist/modules/user/interfaces/role.route.d.mts.map +1 -0
- package/dist/modules/user/interfaces/role.route.mjs +60 -0
- package/dist/modules/user/interfaces/role.route.mjs.map +1 -0
- package/dist/modules/user/interfaces/user.dto.d.mts +106 -0
- package/dist/modules/user/interfaces/user.dto.d.mts.map +1 -0
- package/dist/modules/user/interfaces/user.dto.mjs +32 -0
- package/dist/modules/user/interfaces/user.dto.mjs.map +1 -0
- package/dist/modules/user/interfaces/user.route.d.mts +2093 -0
- package/dist/modules/user/interfaces/user.route.d.mts.map +1 -0
- package/dist/modules/user/interfaces/user.route.mjs +69 -0
- package/dist/modules/user/interfaces/user.route.mjs.map +1 -0
- package/dist/modules/user/interfaces/user.vo.d.mts +28 -0
- package/dist/modules/user/interfaces/user.vo.d.mts.map +1 -0
- package/dist/modules/user/interfaces/user.vo.mjs +18 -0
- package/dist/modules/user/interfaces/user.vo.mjs.map +1 -0
- package/dist/rank.service-D2h-2iJA.mjs +109 -0
- package/dist/rank.service-D2h-2iJA.mjs.map +1 -0
- package/dist/settings.d.mts +12 -0
- package/dist/settings.d.mts.map +1 -0
- package/dist/settings.mjs +27 -0
- package/dist/settings.mjs.map +1 -0
- package/dist/shared/create-app.d.mts +13 -0
- package/dist/shared/create-app.d.mts.map +1 -0
- package/dist/shared/create-app.mjs +45 -0
- package/dist/shared/create-app.mjs.map +1 -0
- package/dist/shared/db/bootstrap.d.mts +5 -0
- package/dist/shared/db/bootstrap.d.mts.map +1 -0
- package/dist/shared/db/bootstrap.mjs +51 -0
- package/dist/shared/db/bootstrap.mjs.map +1 -0
- package/dist/shared/db/connection.d.mts +1567 -0
- package/dist/shared/db/connection.d.mts.map +1 -0
- package/dist/shared/db/connection.mjs +59 -0
- package/dist/shared/db/connection.mjs.map +1 -0
- package/dist/shared/db/migrations/pg/0000_init.sql +74 -0
- package/dist/shared/db/migrations/pg/0001_snippets & tokens.sql +6 -0
- package/dist/shared/db/migrations/pg/0002_change_task_id_to_uuid_v7.sql +3 -0
- package/dist/shared/db/migrations/pg/meta/0000_snapshot.json +498 -0
- package/dist/shared/db/migrations/pg/meta/0001_snapshot.json +513 -0
- package/dist/shared/db/migrations/pg/meta/0002_snapshot.json +514 -0
- package/dist/shared/db/migrations/pg/meta/_journal.json +27 -0
- package/dist/shared/db/migrations/sqlite/0000_init.sql +72 -0
- package/dist/shared/db/migrations/sqlite/0001_snippets & tokens.sql +2 -0
- package/dist/shared/db/migrations/sqlite/0002_change_task_id_to_uuid_v7.sql +35 -0
- package/dist/shared/db/migrations/sqlite/meta/0000_snapshot.json +493 -0
- package/dist/shared/db/migrations/sqlite/meta/0001_snapshot.json +509 -0
- package/dist/shared/db/migrations/sqlite/meta/0002_snapshot.json +509 -0
- package/dist/shared/db/migrations/sqlite/meta/_journal.json +27 -0
- package/dist/shared/db/seed.d.mts +5 -0
- package/dist/shared/db/seed.d.mts.map +1 -0
- package/dist/shared/db/seed.mjs +42 -0
- package/dist/shared/db/seed.mjs.map +1 -0
- package/dist/shared/deps.d.mts +28 -0
- package/dist/shared/deps.d.mts.map +1 -0
- package/dist/shared/deps.mjs +69 -0
- package/dist/shared/deps.mjs.map +1 -0
- package/dist/shared/dto/index.d.mts +11 -0
- package/dist/shared/dto/index.d.mts.map +1 -0
- package/dist/shared/dto/index.mjs +11 -0
- package/dist/shared/dto/index.mjs.map +1 -0
- package/dist/shared/logger.d.mts +14 -0
- package/dist/shared/logger.d.mts.map +1 -0
- package/dist/shared/logger.mjs +37 -0
- package/dist/shared/logger.mjs.map +1 -0
- package/dist/shared/mcp/createTool.d.mts +15 -0
- package/dist/shared/mcp/createTool.d.mts.map +1 -0
- package/dist/shared/mcp/createTool.mjs +8 -0
- package/dist/shared/mcp/createTool.mjs.map +1 -0
- package/dist/shared/middleware/authorization.d.mts +15 -0
- package/dist/shared/middleware/authorization.d.mts.map +1 -0
- package/dist/shared/middleware/authorization.mjs +46 -0
- package/dist/shared/middleware/authorization.mjs.map +1 -0
- package/dist/shared/middleware/http-logger.d.mts +7 -0
- package/dist/shared/middleware/http-logger.d.mts.map +1 -0
- package/dist/shared/middleware/http-logger.mjs +40 -0
- package/dist/shared/middleware/http-logger.mjs.map +1 -0
- package/dist/shared/middleware/jwt.d.mts +7 -0
- package/dist/shared/middleware/jwt.d.mts.map +1 -0
- package/dist/shared/middleware/jwt.mjs +34 -0
- package/dist/shared/middleware/jwt.mjs.map +1 -0
- package/dist/shared/middleware/limiter.d.mts +7 -0
- package/dist/shared/middleware/limiter.d.mts.map +1 -0
- package/dist/shared/middleware/limiter.mjs +10 -0
- package/dist/shared/middleware/limiter.mjs.map +1 -0
- package/dist/shared/middleware/services.d.mts +8 -0
- package/dist/shared/middleware/services.d.mts.map +1 -0
- package/dist/shared/middleware/services.mjs +19 -0
- package/dist/shared/middleware/services.mjs.map +1 -0
- package/dist/shared/redis/decorator.d.mts +113 -0
- package/dist/shared/redis/decorator.d.mts.map +1 -0
- package/dist/shared/redis/decorator.mjs +203 -0
- package/dist/shared/redis/decorator.mjs.map +1 -0
- package/dist/shared/redis/factory.d.mts +18 -0
- package/dist/shared/redis/factory.d.mts.map +1 -0
- package/dist/shared/redis/factory.mjs +41 -0
- package/dist/shared/redis/factory.mjs.map +1 -0
- package/dist/shared/redis/index.d.mts +12 -0
- package/dist/shared/redis/index.d.mts.map +1 -0
- package/dist/shared/redis/index.mjs +14 -0
- package/dist/shared/redis/index.mjs.map +1 -0
- package/dist/shared/types.d.mts +36 -0
- package/dist/shared/types.d.mts.map +1 -0
- package/dist/shared/types.mjs +1 -0
- package/dist/shared/utils/date.d.mts +1 -0
- package/dist/shared/utils/date.mjs +1 -0
- package/dist/shared/utils/error-handler.d.mts +7 -0
- package/dist/shared/utils/error-handler.d.mts.map +1 -0
- package/dist/shared/utils/error-handler.mjs +22 -0
- package/dist/shared/utils/error-handler.mjs.map +1 -0
- package/dist/shared/utils/format.d.mts +8 -0
- package/dist/shared/utils/format.d.mts.map +1 -0
- package/dist/shared/utils/format.mjs +24 -0
- package/dist/shared/utils/format.mjs.map +1 -0
- package/dist/shared/utils/pagination.d.mts +9 -0
- package/dist/shared/utils/pagination.d.mts.map +1 -0
- package/dist/shared/utils/pagination.mjs +12 -0
- package/dist/shared/utils/pagination.mjs.map +1 -0
- package/dist/shared/utils/response-template.d.mts +69 -0
- package/dist/shared/utils/response-template.d.mts.map +1 -0
- package/dist/shared/utils/response-template.mjs +96 -0
- package/dist/shared/utils/response-template.mjs.map +1 -0
- package/dist/shared/utils/url.d.mts +18 -0
- package/dist/shared/utils/url.d.mts.map +1 -0
- package/dist/shared/utils/url.mjs +39 -0
- package/dist/shared/utils/url.mjs.map +1 -0
- package/dist/shared/utils/user.d.mts +8 -0
- package/dist/shared/utils/user.d.mts.map +1 -0
- package/dist/shared/utils/user.mjs +11 -0
- package/dist/shared/utils/user.mjs.map +1 -0
- package/dist/shared/utils/validator.d.mts +5984 -0
- package/dist/shared/utils/validator.d.mts.map +1 -0
- package/dist/shared/utils/validator.mjs +34 -0
- package/dist/shared/utils/validator.mjs.map +1 -0
- package/dist/shared/vo/index.d.mts +11 -0
- package/dist/shared/vo/index.d.mts.map +1 -0
- package/dist/shared/vo/index.mjs +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.route.d.mts","names":[],"sources":["../../../../src/modules/user/interfaces/user.route.ts"],"mappings":";;;;;;;;cAeM,MAAA,kBAAM,QAAA,CAmER,WAAA;;;;;;;;;;;;;;;;;;;oBAnEQ,OAAA,CAAA,aAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import AppSettings from "../../../settings.mjs";
|
|
2
|
+
import "../../../rank.service-D2h-2iJA.mjs";
|
|
3
|
+
import { createRouter } from "../../../shared/create-app.mjs";
|
|
4
|
+
import { Res200 } from "../../../shared/utils/response-template.mjs";
|
|
5
|
+
import { getCurrentUserId } from "../../../shared/utils/user.mjs";
|
|
6
|
+
import { jsonValidator } from "../../../shared/utils/validator.mjs";
|
|
7
|
+
import { getUserById, login } from "../application/user.service.mjs";
|
|
8
|
+
import { userLoginSchema } from "./user.dto.mjs";
|
|
9
|
+
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
|
|
12
|
+
//#region src/modules/user/interfaces/user.route.ts
|
|
13
|
+
const { config } = AppSettings;
|
|
14
|
+
const router = createRouter().post("/login", jsonValidator(userLoginSchema), async (c) => {
|
|
15
|
+
const { username, password } = c.req.valid("json");
|
|
16
|
+
const { user, token } = await login({
|
|
17
|
+
username,
|
|
18
|
+
password
|
|
19
|
+
});
|
|
20
|
+
const csrfToken = randomUUID();
|
|
21
|
+
setCookie(c, "access_token", token, {
|
|
22
|
+
httpOnly: true,
|
|
23
|
+
secure: !config.is_dev,
|
|
24
|
+
sameSite: "Strict",
|
|
25
|
+
path: "/",
|
|
26
|
+
maxAge: 86400
|
|
27
|
+
});
|
|
28
|
+
setCookie(c, "csrf_token", csrfToken, {
|
|
29
|
+
httpOnly: false,
|
|
30
|
+
secure: !config.is_dev,
|
|
31
|
+
sameSite: "Strict",
|
|
32
|
+
path: "/",
|
|
33
|
+
maxAge: 86400
|
|
34
|
+
});
|
|
35
|
+
return c.json(Res200(user), 200);
|
|
36
|
+
}).post("/logout", async (c) => {
|
|
37
|
+
getCookie(c, "csrf_token");
|
|
38
|
+
deleteCookie(c, "access_token", { path: "/" });
|
|
39
|
+
deleteCookie(c, "csrf_token", { path: "/" });
|
|
40
|
+
return c.json(Res200({ message: "退出登录成功" }), 200);
|
|
41
|
+
}).get("/me", async (c) => {
|
|
42
|
+
const userId = getCurrentUserId(c);
|
|
43
|
+
let me = {
|
|
44
|
+
id: null,
|
|
45
|
+
name: null,
|
|
46
|
+
role: "guest",
|
|
47
|
+
permissions: {}
|
|
48
|
+
};
|
|
49
|
+
if (userId) {
|
|
50
|
+
const user = await getUserById(userId);
|
|
51
|
+
if (user) me = {
|
|
52
|
+
id: user.id,
|
|
53
|
+
name: user.name,
|
|
54
|
+
role: user.role,
|
|
55
|
+
permissions: {}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return c.json(Res200(me), 200);
|
|
59
|
+
}).get("/profile", async (c) => {
|
|
60
|
+
const userId = getCurrentUserId(c);
|
|
61
|
+
if (!userId) return c.json({ message: "用户未登录" }, 401);
|
|
62
|
+
const user = await getUserById(userId);
|
|
63
|
+
if (!user) return c.json({ message: "用户不存在" }, 404);
|
|
64
|
+
return c.json(user);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
export { router as default };
|
|
69
|
+
//# sourceMappingURL=user.route.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.route.mjs","names":[],"sources":["../../../../src/modules/user/interfaces/user.route.ts"],"sourcesContent":["import type { UserVO } from './user.vo'\nimport type { UserLoginDTO } from '@/modules/user/interfaces/user.dto'\nimport type { ApiSuccess } from '@/shared/types'\nimport { randomUUID } from 'node:crypto'\nimport { deleteCookie, getCookie, setCookie } from 'hono/cookie'\nimport { getUserById, login } from '@/modules/user/application/user.service'\nimport { userLoginSchema } from '@/modules/user/interfaces/user.dto'\nimport AppSettings from '@/settings'\nimport { createRouter } from '@/shared/create-app'\nimport { Res200 } from '@/shared/utils/response-template'\nimport { getCurrentUserId } from '@/shared/utils/user'\nimport { jsonValidator } from '@/shared/utils/validator'\n\nconst { config } = AppSettings\n\nconst router = createRouter()\n .post('/login', jsonValidator(userLoginSchema), async (c) => {\n const { username, password } = c.req.valid('json') as UserLoginDTO\n const { user, token } = await login({ username, password })\n\n const csrfToken = randomUUID()\n\n // token 有效期 1天\n setCookie(c, 'access_token', token, {\n httpOnly: true,\n secure: !config.is_dev,\n sameSite: 'Strict',\n path: '/',\n maxAge: 86400,\n })\n\n setCookie(c, 'csrf_token', csrfToken, {\n httpOnly: false,\n secure: !config.is_dev,\n sameSite: 'Strict',\n path: '/',\n maxAge: 86400,\n })\n return c.json(Res200(user) as ApiSuccess<UserVO>, 200)\n })\n .post('/logout', async (c) => {\n const csrfToken = getCookie(c, 'csrf_token')\n\n deleteCookie(c, 'access_token', { path: '/' })\n deleteCookie(c, 'csrf_token', { path: '/' })\n\n return c.json(Res200({ message: '退出登录成功' }) as ApiSuccess<{ message: string }>, 200)\n })\n .get('/me', async (c) => {\n const userId = getCurrentUserId(c)\n\n let me = {\n id: null as number | null,\n name: null as string | null,\n role: 'guest',\n permissions: {\n },\n }\n if (userId) {\n const user = await getUserById(userId)\n if (user) {\n me = {\n id: user.id,\n name: user.name,\n role: user.role,\n permissions: { },\n }\n }\n }\n\n return c.json(Res200(me) as ApiSuccess<typeof me>, 200)\n })\n .get('/profile', async (c) => {\n const userId = getCurrentUserId(c)\n if (!userId)\n return c.json({ message: '用户未登录' }, 401)\n\n const user = await getUserById(userId)\n if (!user)\n return c.json({ message: '用户不存在' }, 404)\n\n return c.json(user)\n })\n\nexport default router\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,EAAE,WAAW;AAEnB,MAAM,SAAS,cAAc,CAC1B,KAAK,UAAU,cAAc,gBAAgB,EAAE,OAAO,MAAM;CAC3D,MAAM,EAAE,UAAU,aAAa,EAAE,IAAI,MAAM,OAAO;CAClD,MAAM,EAAE,MAAM,UAAU,MAAM,MAAM;EAAE;EAAU;EAAU,CAAC;CAE3D,MAAM,YAAY,YAAY;AAG9B,WAAU,GAAG,gBAAgB,OAAO;EAClC,UAAU;EACV,QAAQ,CAAC,OAAO;EAChB,UAAU;EACV,MAAM;EACN,QAAQ;EACT,CAAC;AAEF,WAAU,GAAG,cAAc,WAAW;EACpC,UAAU;EACV,QAAQ,CAAC,OAAO;EAChB,UAAU;EACV,MAAM;EACN,QAAQ;EACT,CAAC;AACF,QAAO,EAAE,KAAK,OAAO,KAAK,EAAwB,IAAI;EACtD,CACD,KAAK,WAAW,OAAO,MAAM;AACV,WAAU,GAAG,aAAa;AAE5C,cAAa,GAAG,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAC9C,cAAa,GAAG,cAAc,EAAE,MAAM,KAAK,CAAC;AAE5C,QAAO,EAAE,KAAK,OAAO,EAAE,SAAS,UAAU,CAAC,EAAqC,IAAI;EACpF,CACD,IAAI,OAAO,OAAO,MAAM;CACvB,MAAM,SAAS,iBAAiB,EAAE;CAElC,IAAI,KAAK;EACP,IAAI;EACJ,MAAM;EACN,MAAM;EACN,aAAa,EACZ;EACF;AACD,KAAI,QAAQ;EACV,MAAM,OAAO,MAAM,YAAY,OAAO;AACtC,MAAI,KACF,MAAK;GACH,IAAI,KAAK;GACT,MAAM,KAAK;GACX,MAAM,KAAK;GACX,aAAa,EAAG;GACjB;;AAIL,QAAO,EAAE,KAAK,OAAO,GAAG,EAA2B,IAAI;EACvD,CACD,IAAI,YAAY,OAAO,MAAM;CAC5B,MAAM,SAAS,iBAAiB,EAAE;AAClC,KAAI,CAAC,OACH,QAAO,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,IAAI;CAE1C,MAAM,OAAO,MAAM,YAAY,OAAO;AACtC,KAAI,CAAC,KACH,QAAO,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,IAAI;AAE1C,QAAO,EAAE,KAAK,KAAK;EACnB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z as z$1 } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/modules/user/interfaces/user.vo.d.ts
|
|
4
|
+
declare const userSchema: z$1.ZodObject<{
|
|
5
|
+
id: z$1.ZodNumber;
|
|
6
|
+
username: z$1.ZodString;
|
|
7
|
+
name: z$1.ZodString;
|
|
8
|
+
phone: z$1.ZodString;
|
|
9
|
+
email: z$1.ZodString;
|
|
10
|
+
role: z$1.ZodEnum<{
|
|
11
|
+
user: "user";
|
|
12
|
+
admin: "admin";
|
|
13
|
+
}>;
|
|
14
|
+
status: z$1.ZodEnum<{
|
|
15
|
+
active: "active";
|
|
16
|
+
inactive: "inactive";
|
|
17
|
+
}>;
|
|
18
|
+
createdAt: z$1.ZodNumber;
|
|
19
|
+
updatedAt: z$1.ZodNumber;
|
|
20
|
+
}, z$1.core.$strip>;
|
|
21
|
+
type UserVO = z$1.infer<typeof userSchema>;
|
|
22
|
+
interface LoginResultVO {
|
|
23
|
+
user: UserVO;
|
|
24
|
+
token: string;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { LoginResultVO, UserVO, userSchema };
|
|
28
|
+
//# sourceMappingURL=user.vo.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.vo.d.mts","names":[],"sources":["../../../../src/modules/user/interfaces/user.vo.ts"],"mappings":";;;cAEa,UAAA,EAAU,GAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;KAYX,MAAA,GAAS,GAAA,CAAE,KAAA,QAAa,UAAA;AAAA,UAEnB,aAAA;EAAgB,IAAA,EAAM,MAAA;EAAQ,KAAA;AAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z as z$1 } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/modules/user/interfaces/user.vo.ts
|
|
4
|
+
const userSchema = z$1.object({
|
|
5
|
+
id: z$1.number(),
|
|
6
|
+
username: z$1.string(),
|
|
7
|
+
name: z$1.string(),
|
|
8
|
+
phone: z$1.string(),
|
|
9
|
+
email: z$1.string(),
|
|
10
|
+
role: z$1.enum(["admin", "user"]),
|
|
11
|
+
status: z$1.enum(["active", "inactive"]),
|
|
12
|
+
createdAt: z$1.number(),
|
|
13
|
+
updatedAt: z$1.number()
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { userSchema };
|
|
18
|
+
//# sourceMappingURL=user.vo.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.vo.mjs","names":["z"],"sources":["../../../../src/modules/user/interfaces/user.vo.ts"],"sourcesContent":["import { z } from 'zod'\n\nexport const userSchema = z.object({\n id: z.number(),\n username: z.string(),\n name: z.string(),\n phone: z.string(),\n email: z.string(),\n role: z.enum(['admin', 'user']),\n status: z.enum(['active', 'inactive']),\n createdAt: z.number(),\n updatedAt: z.number(),\n})\n\nexport type UserVO = z.infer<typeof userSchema>\n\nexport interface LoginResultVO { user: UserVO, token: string }\n"],"mappings":";;;AAEA,MAAa,aAAaA,IAAE,OAAO;CACjC,IAAIA,IAAE,QAAQ;CACd,UAAUA,IAAE,QAAQ;CACpB,MAAMA,IAAE,QAAQ;CAChB,OAAOA,IAAE,QAAQ;CACjB,OAAOA,IAAE,QAAQ;CACjB,MAAMA,IAAE,KAAK,CAAC,SAAS,OAAO,CAAC;CAC/B,QAAQA,IAAE,KAAK,CAAC,UAAU,WAAW,CAAC;CACtC,WAAWA,IAAE,QAAQ;CACrB,WAAWA,IAAE,QAAQ;CACtB,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { getRedis } from "./shared/redis/factory.mjs";
|
|
2
|
+
import { Cache, CacheableService } from "./shared/redis/decorator.mjs";
|
|
3
|
+
|
|
4
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/decorateMetadata.js
|
|
5
|
+
function __decorateMetadata(k, v) {
|
|
6
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/decorate.js
|
|
11
|
+
function __decorate(decorators, target, key, desc) {
|
|
12
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
13
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
14
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
15
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/modules/rank/rank.service.ts
|
|
20
|
+
const RANK_DOCS_ALL_TIME_KEY = "rank:docs:all_time";
|
|
21
|
+
function toDocVO(entity) {
|
|
22
|
+
return {
|
|
23
|
+
...entity,
|
|
24
|
+
createdAt: entity.createdAt.getTime(),
|
|
25
|
+
updatedAt: entity.updatedAt.getTime()
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
let RankService = class RankService {
|
|
29
|
+
get cache() {
|
|
30
|
+
return getRedis();
|
|
31
|
+
}
|
|
32
|
+
constructor(docRepo) {
|
|
33
|
+
this.docRepo = docRepo;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 批量查询文档收藏状态(带缓存)
|
|
37
|
+
* @param userId 用户 ID
|
|
38
|
+
* @param docIds 文档 ID 列表
|
|
39
|
+
* @returns docId -> 是否收藏的映射
|
|
40
|
+
*/
|
|
41
|
+
async getFavoritesMap(userId, docIds) {
|
|
42
|
+
if (docIds.length === 0) return {};
|
|
43
|
+
const favoritePromises = docIds.map((docId) => this.docRepo.isFavorite(userId, docId));
|
|
44
|
+
const favoriteResults = await Promise.all(favoritePromises);
|
|
45
|
+
const map = {};
|
|
46
|
+
docIds.forEach((docId, index) => {
|
|
47
|
+
map[docId] = favoriteResults[index];
|
|
48
|
+
});
|
|
49
|
+
return map;
|
|
50
|
+
}
|
|
51
|
+
async incrementDocScore(slug, weight) {
|
|
52
|
+
if (!slug) return;
|
|
53
|
+
await this.cache.zincrby(RANK_DOCS_ALL_TIME_KEY, weight, slug);
|
|
54
|
+
}
|
|
55
|
+
async getRankedDocs(limit = 10) {
|
|
56
|
+
if (limit <= 0) return [];
|
|
57
|
+
const raw = await this.cache.zrevrange(RANK_DOCS_ALL_TIME_KEY, 0, limit - 1, "WITHSCORES");
|
|
58
|
+
const results = [];
|
|
59
|
+
for (let i = 0; i < raw.length; i += 2) {
|
|
60
|
+
const slug = raw[i];
|
|
61
|
+
const score = Number(raw[i + 1] ?? 0);
|
|
62
|
+
if (slug) results.push({
|
|
63
|
+
slug,
|
|
64
|
+
score
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 获取排序文档列表
|
|
71
|
+
* @param limit 返回数量限制
|
|
72
|
+
* @param userId 可选用户 ID,用于检查收藏状态
|
|
73
|
+
*/
|
|
74
|
+
async getRankedDocsWithDetails(limit, userId) {
|
|
75
|
+
const ranked = await this.getRankedDocs(limit);
|
|
76
|
+
const validDocs = (await Promise.all(ranked.map(async ({ slug, score }) => {
|
|
77
|
+
const doc = await this.docRepo.findBySlug(slug);
|
|
78
|
+
if (!doc) return null;
|
|
79
|
+
return {
|
|
80
|
+
...toDocVO(doc),
|
|
81
|
+
score
|
|
82
|
+
};
|
|
83
|
+
}))).filter((v) => Boolean(v));
|
|
84
|
+
if (userId) {
|
|
85
|
+
const docIds = validDocs.map((d) => d.id);
|
|
86
|
+
const favoritesMap = await this.getFavoritesMap(userId, docIds);
|
|
87
|
+
return validDocs.map((doc) => ({
|
|
88
|
+
...doc,
|
|
89
|
+
starred: favoritesMap[doc.id] ?? false
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
return validDocs;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
__decorate([
|
|
96
|
+
Cache({
|
|
97
|
+
key: (userId) => `getFavoritesMap:${userId}`,
|
|
98
|
+
tags: (userId) => [`favorites:${userId}`],
|
|
99
|
+
ttl: 600
|
|
100
|
+
}),
|
|
101
|
+
__decorateMetadata("design:type", Function),
|
|
102
|
+
__decorateMetadata("design:paramtypes", [Number, Array]),
|
|
103
|
+
__decorateMetadata("design:returntype", Promise)
|
|
104
|
+
], RankService.prototype, "getFavoritesMap", null);
|
|
105
|
+
RankService = __decorate([CacheableService("rank"), __decorateMetadata("design:paramtypes", [Object])], RankService);
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { __decorate as n, __decorateMetadata as r, RankService as t };
|
|
109
|
+
//# sourceMappingURL=rank.service-D2h-2iJA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rank.service-D2h-2iJA.mjs","names":[],"sources":["../src/modules/rank/rank.service.ts"],"sourcesContent":["import type { RankedDocVO } from './rank.vo'\nimport type { DocEntity } from '@/modules/doc/doc.entity'\nimport type { IDocRepository } from '@/modules/doc/doc.repo.interface'\nimport { getRedis } from '@/shared/redis'\nimport { Cache, CacheableService } from '@/shared/redis/decorator'\n\nconst RANK_DOCS_ALL_TIME_KEY = 'rank:docs:all_time'\n\nfunction toDocVO(entity: DocEntity<Date>) {\n return {\n ...entity,\n createdAt: entity.createdAt.getTime(),\n updatedAt: entity.updatedAt.getTime(),\n }\n}\n\n@CacheableService('rank')\nexport class RankService {\n private get cache() {\n return getRedis()\n }\n\n constructor(private docRepo: IDocRepository) {}\n\n /**\n * 批量查询文档收藏状态(带缓存)\n * @param userId 用户 ID\n * @param docIds 文档 ID 列表\n * @returns docId -> 是否收藏的映射\n */\n @Cache({ key: userId => `getFavoritesMap:${userId}`, tags: userId => [`favorites:${userId}`], ttl: 600 })\n async getFavoritesMap(userId: number, docIds: number[]): Promise<{ [docId: number]: boolean }> {\n if (docIds.length === 0)\n return {}\n\n const favoritePromises = docIds.map(docId => this.docRepo.isFavorite(userId, docId))\n const favoriteResults = await Promise.all(favoritePromises)\n\n const map: { [docId: number]: boolean } = {}\n docIds.forEach((docId, index) => {\n map[docId] = favoriteResults[index]\n })\n return map\n }\n\n async incrementDocScore(slug: string, weight: number): Promise<void> {\n if (!slug)\n return\n await this.cache.zincrby(RANK_DOCS_ALL_TIME_KEY, weight, slug)\n }\n\n async getRankedDocs(limit: number = 10): Promise<{ slug: string, score: number }[]> {\n if (limit <= 0)\n return []\n const raw = await this.cache.zrevrange(RANK_DOCS_ALL_TIME_KEY, 0, limit - 1, 'WITHSCORES')\n\n const results: { slug: string, score: number }[] = []\n for (let i = 0; i < raw.length; i += 2) {\n const slug = raw[i]\n const score = Number(raw[i + 1] ?? 0)\n if (slug)\n results.push({ slug, score })\n }\n return results\n }\n\n /**\n * 获取排序文档列表\n * @param limit 返回数量限制\n * @param userId 可选用户 ID,用于检查收藏状态\n */\n async getRankedDocsWithDetails(limit: number, userId?: number): Promise<RankedDocVO[]> {\n const ranked = await this.getRankedDocs(limit)\n\n // TODO: 优化,加redis缓存\n const docs = await Promise.all(ranked.map(async ({ slug, score }) => {\n const doc = await this.docRepo.findBySlug(slug)\n if (!doc)\n return null\n return { ...toDocVO(doc), score } satisfies RankedDocVO\n }))\n\n const validDocs = docs.filter((v): v is RankedDocVO => Boolean(v))\n\n if (userId) {\n const docIds = validDocs.map(d => d.id)\n const favoritesMap = await this.getFavoritesMap(userId, docIds)\n\n return validDocs.map(doc => ({\n ...doc,\n starred: favoritesMap[doc.id] ?? false,\n }))\n }\n\n return validDocs\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAMA,MAAM,yBAAyB;AAE/B,SAAS,QAAQ,QAAyB;AACxC,QAAO;EACL,GAAG;EACH,WAAW,OAAO,UAAU,SAAS;EACrC,WAAW,OAAO,UAAU,SAAS;EACtC;;AAII,wBAAM,YAAY;CACvB,IAAY,QAAQ;AAClB,SAAO,UAAU;;CAGnB,YAAY,AAAQ,SAAyB;EAAzB;;;;;;;;CAQpB,MACM,gBAAgB,QAAgB,QAAyD;AAC7F,MAAI,OAAO,WAAW,EACpB,QAAO,EAAE;EAEX,MAAM,mBAAmB,OAAO,KAAI,UAAS,KAAK,QAAQ,WAAW,QAAQ,MAAM,CAAC;EACpF,MAAM,kBAAkB,MAAM,QAAQ,IAAI,iBAAiB;EAE3D,MAAM,MAAoC,EAAE;AAC5C,SAAO,SAAS,OAAO,UAAU;AAC/B,OAAI,SAAS,gBAAgB;IAC7B;AACF,SAAO;;CAGT,MAAM,kBAAkB,MAAc,QAA+B;AACnE,MAAI,CAAC,KACH;AACF,QAAM,KAAK,MAAM,QAAQ,wBAAwB,QAAQ,KAAK;;CAGhE,MAAM,cAAc,QAAgB,IAAgD;AAClF,MAAI,SAAS,EACX,QAAO,EAAE;EACX,MAAM,MAAM,MAAM,KAAK,MAAM,UAAU,wBAAwB,GAAG,QAAQ,GAAG,aAAa;EAE1F,MAAM,UAA6C,EAAE;AACrD,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;GACtC,MAAM,OAAO,IAAI;GACjB,MAAM,QAAQ,OAAO,IAAI,IAAI,MAAM,EAAE;AACrC,OAAI,KACF,SAAQ,KAAK;IAAE;IAAM;IAAO,CAAC;;AAEjC,SAAO;;;;;;;CAQT,MAAM,yBAAyB,OAAe,QAAyC;EACrF,MAAM,SAAS,MAAM,KAAK,cAAc,MAAM;EAU9C,MAAM,aAPO,MAAM,QAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY;GACnE,MAAM,MAAM,MAAM,KAAK,QAAQ,WAAW,KAAK;AAC/C,OAAI,CAAC,IACH,QAAO;AACT,UAAO;IAAE,GAAG,QAAQ,IAAI;IAAE;IAAO;IACjC,CAAC,EAEoB,QAAQ,MAAwB,QAAQ,EAAE,CAAC;AAElE,MAAI,QAAQ;GACV,MAAM,SAAS,UAAU,KAAI,MAAK,EAAE,GAAG;GACvC,MAAM,eAAe,MAAM,KAAK,gBAAgB,QAAQ,OAAO;AAE/D,UAAO,UAAU,KAAI,SAAQ;IAC3B,GAAG;IACH,SAAS,aAAa,IAAI,OAAO;IAClC,EAAE;;AAGL,SAAO;;;;CAhER,MAAM;EAAE,MAAK,WAAU,mBAAmB;EAAU,OAAM,WAAU,CAAC,aAAa,SAAS;EAAE,KAAK;EAAK,CAAC;;;;;0BAd1G,iBAAiB,OAAO"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PContextConfig } from "@pcontext/shared";
|
|
2
|
+
|
|
3
|
+
//#region src/settings.d.ts
|
|
4
|
+
interface GlobalAppSettings {
|
|
5
|
+
config: PContextConfig;
|
|
6
|
+
global: Record<string, any>;
|
|
7
|
+
}
|
|
8
|
+
declare const AppSettings: GlobalAppSettings;
|
|
9
|
+
declare function loadSettingsConfig(customConfigPath: string): Promise<PContextConfig>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { AppSettings as default, loadSettingsConfig };
|
|
12
|
+
//# sourceMappingURL=settings.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.mts","names":[],"sources":["../src/settings.ts"],"mappings":";;;UAOU,iBAAA;EACR,MAAA,EAAQ,cAAA;EACR,MAAA,EAAQ,MAAA;AAAA;AAAA,cAGJ,WAAA,EAAa,iBAAA;AAAA,iBAKG,kBAAA,CAAmB,gBAAA,WAAwB,OAAA,CAAA,cAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { PContextConfigSchema, getDefaultPContextConfig, getDirname, loadPContextConfig } from "@pcontext/shared";
|
|
3
|
+
import { z as z$1 } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/settings.ts
|
|
6
|
+
const AppSettings = {
|
|
7
|
+
config: getDefaultPContextConfig(),
|
|
8
|
+
global: {}
|
|
9
|
+
};
|
|
10
|
+
async function loadSettingsConfig(customConfigPath) {
|
|
11
|
+
const __dirname = getDirname(import.meta.url);
|
|
12
|
+
const configPath = path.isAbsolute(customConfigPath) ? customConfigPath : path.join(__dirname, customConfigPath);
|
|
13
|
+
const cfg = await loadPContextConfig(configPath);
|
|
14
|
+
const parseResult = PContextConfigSchema.safeParse(cfg);
|
|
15
|
+
if (!parseResult.success) {
|
|
16
|
+
const details = z$1.treeifyError(parseResult.error);
|
|
17
|
+
throw new Error(`loadSettingsConfig 配置加载失败: ${JSON.stringify(details)}`);
|
|
18
|
+
}
|
|
19
|
+
const validatedConfig = parseResult.data;
|
|
20
|
+
Object.assign(AppSettings.config, validatedConfig);
|
|
21
|
+
console.log(`load pcontext config from ${configPath}`);
|
|
22
|
+
return AppSettings.config;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { AppSettings as default, loadSettingsConfig };
|
|
27
|
+
//# sourceMappingURL=settings.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.mjs","names":["z"],"sources":["../src/settings.ts"],"sourcesContent":["import type { PContextConfig } from '@pcontext/shared'\nimport path from 'node:path'\n\nimport { getDefaultPContextConfig, getDirname, loadPContextConfig, PContextConfigSchema } from '@pcontext/shared'\n\nimport { z } from 'zod'\n\ninterface GlobalAppSettings {\n config: PContextConfig\n global: Record<string, any>\n}\n\nconst AppSettings: GlobalAppSettings = {\n config: getDefaultPContextConfig(),\n global: {},\n}\n\nexport async function loadSettingsConfig(customConfigPath: string) {\n const __dirname = getDirname(import.meta.url)\n\n const configPath = path.isAbsolute(customConfigPath)\n ? customConfigPath\n : path.join(__dirname, customConfigPath)\n\n const cfg = await loadPContextConfig(configPath)\n\n // Zod 验证,确保安全性\n const parseResult = PContextConfigSchema.safeParse(cfg)\n if (!parseResult.success) {\n const details = z.treeifyError(parseResult.error)\n throw new Error(`loadSettingsConfig 配置加载失败: ${JSON.stringify(details)}`)\n }\n\n const validatedConfig = parseResult.data\n Object.assign(AppSettings.config, validatedConfig)\n\n console.log(`load pcontext config from ${configPath}`)\n return AppSettings.config\n}\n\nexport default AppSettings\n"],"mappings":";;;;;AAYA,MAAM,cAAiC;CACrC,QAAQ,0BAA0B;CAClC,QAAQ,EAAE;CACX;AAED,eAAsB,mBAAmB,kBAA0B;CACjE,MAAM,YAAY,WAAW,OAAO,KAAK,IAAI;CAE7C,MAAM,aAAa,KAAK,WAAW,iBAAiB,GAChD,mBACA,KAAK,KAAK,WAAW,iBAAiB;CAE1C,MAAM,MAAM,MAAM,mBAAmB,WAAW;CAGhD,MAAM,cAAc,qBAAqB,UAAU,IAAI;AACvD,KAAI,CAAC,YAAY,SAAS;EACxB,MAAM,UAAUA,IAAE,aAAa,YAAY,MAAM;AACjD,QAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,QAAQ,GAAG;;CAG1E,MAAM,kBAAkB,YAAY;AACpC,QAAO,OAAO,YAAY,QAAQ,gBAAgB;AAElD,SAAQ,IAAI,6BAA6B,aAAa;AACtD,QAAO,YAAY"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AppBindings } from "./types.mjs";
|
|
2
|
+
import { Hono } from "hono";
|
|
3
|
+
import { Cron } from "croner";
|
|
4
|
+
import * as hono_types0 from "hono/types";
|
|
5
|
+
import * as hono_hono_base0 from "hono/hono-base";
|
|
6
|
+
|
|
7
|
+
//#region src/shared/create-app.d.ts
|
|
8
|
+
declare function createRouter(limit?: number): Hono<AppBindings, hono_types0.BlankSchema, "/">;
|
|
9
|
+
declare function createCron(): Cron;
|
|
10
|
+
declare function createApp(): hono_hono_base0.HonoBase<AppBindings, hono_types0.BlankSchema, "/", any>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { createCron, createRouter, createApp as default };
|
|
13
|
+
//# sourceMappingURL=create-app.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app.d.mts","names":[],"sources":["../../src/shared/create-app.ts"],"mappings":";;;;;;;iBAegB,YAAA,CAAa,KAAA,YAAqC,IAAA,CAAA,WAAA,EAAA,WAAA,CAAA,WAAA;AAAA,iBAIlD,UAAA,CAAA,GAAU,IAAA;AAAA,iBAIF,SAAA,CAAA,GAAS,eAAA,CAAA,QAAA,CAAA,WAAA,EAAA,WAAA,CAAA,WAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import AppSettings from "../settings.mjs";
|
|
2
|
+
import { authorization } from "./middleware/authorization.mjs";
|
|
3
|
+
import { httpLogger } from "./middleware/http-logger.mjs";
|
|
4
|
+
import { jwt } from "./middleware/jwt.mjs";
|
|
5
|
+
import "../rank.service-D2h-2iJA.mjs";
|
|
6
|
+
import { services } from "./middleware/services.mjs";
|
|
7
|
+
import { errorHandler } from "./utils/error-handler.mjs";
|
|
8
|
+
import { Hono } from "hono";
|
|
9
|
+
import { Cron } from "croner";
|
|
10
|
+
import { cors } from "hono/cors";
|
|
11
|
+
import { requestId } from "hono/request-id";
|
|
12
|
+
import { notFound, serveEmojiFavicon } from "stoker/middlewares";
|
|
13
|
+
|
|
14
|
+
//#region src/shared/create-app.ts
|
|
15
|
+
const { config } = AppSettings;
|
|
16
|
+
function createRouter(limit = config.rate_limit_max) {
|
|
17
|
+
return new Hono();
|
|
18
|
+
}
|
|
19
|
+
function createCron() {
|
|
20
|
+
return new Cron("0 */5 * * * *", () => {});
|
|
21
|
+
}
|
|
22
|
+
function createApp() {
|
|
23
|
+
const app = createRouter().use(`${config.api_prefix}/*`, requestId()).use(`${config.api_prefix}/*`, httpLogger()).use(`${config.api_prefix}/*`, serveEmojiFavicon("🔥")).use(`${config.api_prefix}/*`, cors({
|
|
24
|
+
origin: "http://localhost:3001",
|
|
25
|
+
allowHeaders: [
|
|
26
|
+
"Content-Type",
|
|
27
|
+
"Authorization",
|
|
28
|
+
"X-CSRF-Token"
|
|
29
|
+
],
|
|
30
|
+
allowMethods: [
|
|
31
|
+
"GET",
|
|
32
|
+
"POST",
|
|
33
|
+
"HEAD",
|
|
34
|
+
"OPTIONS"
|
|
35
|
+
],
|
|
36
|
+
credentials: true
|
|
37
|
+
})).use(`/*`, services()).use(`${config.api_prefix}/*`, jwt()).use(`${config.api_prefix}/*`, authorization({}));
|
|
38
|
+
app.notFound(notFound);
|
|
39
|
+
app.onError(errorHandler);
|
|
40
|
+
return app;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { createCron, createRouter, createApp as default };
|
|
45
|
+
//# sourceMappingURL=create-app.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app.mjs","names":[],"sources":["../../src/shared/create-app.ts"],"sourcesContent":["import type { AppBindings } from '@/shared/types'\nimport { Cron } from 'croner'\nimport { Hono } from 'hono'\nimport { cors } from 'hono/cors'\nimport { requestId } from 'hono/request-id'\nimport { notFound, serveEmojiFavicon } from 'stoker/middlewares'\nimport AppSettings from '@/settings'\nimport { authorization } from '@/shared/middleware/authorization'\nimport { httpLogger } from '@/shared/middleware/http-logger'\nimport { jwt } from '@/shared/middleware/jwt'\nimport { services } from '@/shared/middleware/services'\nimport { errorHandler } from '@/shared/utils/error-handler'\n\nconst { config } = AppSettings\n\nexport function createRouter(limit: number = config.rate_limit_max) {\n return new Hono<AppBindings>()\n}\n\nexport function createCron() {\n return new Cron('0 */5 * * * *', () => {})\n}\n\nexport default function createApp() {\n const app = createRouter()\n .use(`${config.api_prefix}/*`, requestId())\n .use(`${config.api_prefix}/*`, httpLogger())\n .use(`${config.api_prefix}/*`, serveEmojiFavicon('🔥'))\n .use(`${config.api_prefix}/*`, cors({\n origin: 'http://localhost:3001',\n allowHeaders: ['Content-Type', 'Authorization', 'X-CSRF-Token'],\n allowMethods: ['GET', 'POST', 'HEAD', 'OPTIONS'],\n credentials: true,\n }))\n .use(`/*`, services())\n .use(`${config.api_prefix}/*`, jwt())\n .use(`${config.api_prefix}/*`, authorization({}))\n\n app.notFound(notFound)\n app.onError(errorHandler)\n\n // createCron()\n\n return app\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAM,EAAE,WAAW;AAEnB,SAAgB,aAAa,QAAgB,OAAO,gBAAgB;AAClE,QAAO,IAAI,MAAmB;;AAGhC,SAAgB,aAAa;AAC3B,QAAO,IAAI,KAAK,uBAAuB,GAAG;;AAG5C,SAAwB,YAAY;CAClC,MAAM,MAAM,cAAc,CACvB,IAAI,GAAG,OAAO,WAAW,KAAK,WAAW,CAAC,CAC1C,IAAI,GAAG,OAAO,WAAW,KAAK,YAAY,CAAC,CAC3C,IAAI,GAAG,OAAO,WAAW,KAAK,kBAAkB,KAAK,CAAC,CACtD,IAAI,GAAG,OAAO,WAAW,KAAK,KAAK;EAClC,QAAQ;EACR,cAAc;GAAC;GAAgB;GAAiB;GAAe;EAC/D,cAAc;GAAC;GAAO;GAAQ;GAAQ;GAAU;EAChD,aAAa;EACd,CAAC,CAAC,CACF,IAAI,MAAM,UAAU,CAAC,CACrB,IAAI,GAAG,OAAO,WAAW,KAAK,KAAK,CAAC,CACpC,IAAI,GAAG,OAAO,WAAW,KAAK,cAAc,EAAE,CAAC,CAAC;AAEnD,KAAI,SAAS,SAAS;AACtB,KAAI,QAAQ,aAAa;AAIzB,QAAO"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.mts","names":[],"sources":["../../../src/shared/db/bootstrap.ts"],"mappings":";iBAcsB,SAAA,CAAA,GAAS,OAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { logger } from "../logger.mjs";
|
|
2
|
+
import { getDbProvider, getPgDb, getSqliteDb } from "./connection.mjs";
|
|
3
|
+
import { runSeed } from "./seed.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { sql } from "drizzle-orm";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { migrate } from "drizzle-orm/libsql/migrator";
|
|
9
|
+
import { migrate as migrate$1 } from "drizzle-orm/node-postgres/migrator";
|
|
10
|
+
|
|
11
|
+
//#region src/shared/db/bootstrap.ts
|
|
12
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const migrationsBaseDir = path.join(__dirname, "migrations");
|
|
14
|
+
async function bootstrap() {
|
|
15
|
+
try {
|
|
16
|
+
if (getDbProvider() === "sqlite") {
|
|
17
|
+
const db = getSqliteDb();
|
|
18
|
+
const hasUserTableBefore = await hasSqliteUserTable();
|
|
19
|
+
logger.info("Running SQLite migrations with Drizzle");
|
|
20
|
+
await migrate(db, { migrationsFolder: path.join(migrationsBaseDir, "sqlite") });
|
|
21
|
+
logger.info("SQLite migrations applied");
|
|
22
|
+
if (hasUserTableBefore) logger.info("SQLite user table already exists, skip seeding");
|
|
23
|
+
else await runSeed("sqlite");
|
|
24
|
+
} else {
|
|
25
|
+
const db = getPgDb();
|
|
26
|
+
const hasUserTableBefore = await hasPostgresUserTable();
|
|
27
|
+
logger.info("Running PostgreSQL migrations with Drizzle");
|
|
28
|
+
await migrate$1(db, { migrationsFolder: path.join(migrationsBaseDir, "pg") });
|
|
29
|
+
logger.info("PostgreSQL migrations applied");
|
|
30
|
+
if (hasUserTableBefore) logger.info("PostgreSQL user table already exists, skip seeding");
|
|
31
|
+
else await runSeed("postgresql");
|
|
32
|
+
}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
logger.error(error, "Database bootstrap failed");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function hasSqliteUserTable() {
|
|
39
|
+
const result = await getSqliteDb().run(sql`SELECT name FROM sqlite_master WHERE type='table' AND (name='user' OR name='User')`);
|
|
40
|
+
const rows = result.rows ?? result;
|
|
41
|
+
return Array.isArray(rows) && rows.length > 0;
|
|
42
|
+
}
|
|
43
|
+
async function hasPostgresUserTable() {
|
|
44
|
+
const result = await getPgDb().execute(sql`SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_name='user'`);
|
|
45
|
+
const rows = result.rows ?? result;
|
|
46
|
+
return Array.isArray(rows) && rows.length > 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { bootstrap };
|
|
51
|
+
//# sourceMappingURL=bootstrap.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.mjs","names":["migrateSqlite","migratePg"],"sources":["../../../src/shared/db/bootstrap.ts"],"sourcesContent":["import path from 'node:path'\nimport process from 'node:process'\nimport { fileURLToPath } from 'node:url'\nimport { sql } from 'drizzle-orm'\nimport { migrate as migrateSqlite } from 'drizzle-orm/libsql/migrator'\nimport { migrate as migratePg } from 'drizzle-orm/node-postgres/migrator'\nimport { getDbProvider, getPgDb, getSqliteDb } from '@/shared/db/connection'\nimport { runSeed } from '@/shared/db/seed'\nimport { logger } from '@/shared/logger'\n\n// 获取当前文件所在目录,实现路径与运行工作目录无关\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst migrationsBaseDir = path.join(__dirname, 'migrations')\n\nexport async function bootstrap() {\n try {\n const provider = getDbProvider()\n if (provider === 'sqlite') {\n const db = getSqliteDb()\n const hasUserTableBefore = await hasSqliteUserTable()\n logger.info('Running SQLite migrations with Drizzle')\n await migrateSqlite(db, { migrationsFolder: path.join(migrationsBaseDir, 'sqlite') })\n logger.info('SQLite migrations applied')\n if (hasUserTableBefore) {\n logger.info('SQLite user table already exists, skip seeding')\n }\n else {\n await runSeed('sqlite')\n }\n }\n else {\n const db = getPgDb()\n const hasUserTableBefore = await hasPostgresUserTable()\n logger.info('Running PostgreSQL migrations with Drizzle')\n await migratePg(db, { migrationsFolder: path.join(migrationsBaseDir, 'pg') })\n logger.info('PostgreSQL migrations applied')\n if (hasUserTableBefore) {\n logger.info('PostgreSQL user table already exists, skip seeding')\n }\n else {\n await runSeed('postgresql')\n }\n }\n }\n catch (error) {\n logger.error(error, 'Database bootstrap failed')\n process.exit(1)\n }\n}\n\nasync function hasSqliteUserTable() {\n const db = getSqliteDb()\n const result = await db.run(\n sql`SELECT name FROM sqlite_master WHERE type='table' AND (name='user' OR name='User')`,\n )\n const rows = (result as any).rows ?? result\n return Array.isArray(rows) && rows.length > 0\n}\n\nasync function hasPostgresUserTable() {\n const db = getPgDb()\n const result = await db.execute(\n sql`SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_name='user'`,\n )\n const rows = (result as any).rows ?? result\n return Array.isArray(rows) && rows.length > 0\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,YAAY,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAC9D,MAAM,oBAAoB,KAAK,KAAK,WAAW,aAAa;AAE5D,eAAsB,YAAY;AAChC,KAAI;AAEF,MADiB,eAAe,KACf,UAAU;GACzB,MAAM,KAAK,aAAa;GACxB,MAAM,qBAAqB,MAAM,oBAAoB;AACrD,UAAO,KAAK,yCAAyC;AACrD,SAAMA,QAAc,IAAI,EAAE,kBAAkB,KAAK,KAAK,mBAAmB,SAAS,EAAE,CAAC;AACrF,UAAO,KAAK,4BAA4B;AACxC,OAAI,mBACF,QAAO,KAAK,iDAAiD;OAG7D,OAAM,QAAQ,SAAS;SAGtB;GACH,MAAM,KAAK,SAAS;GACpB,MAAM,qBAAqB,MAAM,sBAAsB;AACvD,UAAO,KAAK,6CAA6C;AACzD,SAAMC,UAAU,IAAI,EAAE,kBAAkB,KAAK,KAAK,mBAAmB,KAAK,EAAE,CAAC;AAC7E,UAAO,KAAK,gCAAgC;AAC5C,OAAI,mBACF,QAAO,KAAK,qDAAqD;OAGjE,OAAM,QAAQ,aAAa;;UAI1B,OAAO;AACZ,SAAO,MAAM,OAAO,4BAA4B;AAChD,UAAQ,KAAK,EAAE;;;AAInB,eAAe,qBAAqB;CAElC,MAAM,SAAS,MADJ,aAAa,CACA,IACtB,GAAG,qFACJ;CACD,MAAM,OAAQ,OAAe,QAAQ;AACrC,QAAO,MAAM,QAAQ,KAAK,IAAI,KAAK,SAAS;;AAG9C,eAAe,uBAAuB;CAEpC,MAAM,SAAS,MADJ,SAAS,CACI,QACtB,GAAG,qGACJ;CACD,MAAM,OAAQ,OAAe,QAAQ;AACrC,QAAO,MAAM,QAAQ,KAAK,IAAI,KAAK,SAAS"}
|