create-nexwire 4.3.0 → 4.4.0
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 +10 -5
- package/express/src/framework/facade.ts +1 -0
- package/express/src/framework/http/logger.ts +13 -4
- package/express/src/framework/maker-cli/runtime/core.mjs +1 -2
- package/express/src/framework/notification/channels/mail.ts +8 -6
- package/express/src/middlewares/auth-middleware.ts +1 -2
- package/express/src/middlewares/role-middleware.ts +3 -13
- package/express/src/modules/auth/routes/index.ts +1 -2
- package/express/src/providers/notification.ts +2 -2
- package/express/src/resources/src/components/Switch.vue +60 -65
- package/express/src/resources/src/pages/auth/forgetPassword.vue +23 -30
- package/express/src/resources/src/pages/auth/login.vue +25 -28
- package/express/src/resources/src/pages/auth/register.vue +35 -39
- package/express/src/resources/src/pages/auth/resetPassword.vue +29 -37
- package/express/src/resources/src/pages/auth/verifyEmail.vue +15 -19
- package/express/src/resources/src/plugins/gum.ts +519 -203
- package/express/src/resources/src/stores/auth.ts +9 -6
- package/express/src/storage/database/nexwire.sqlite +0 -0
- package/fastify/.dockerignore +14 -0
- package/fastify/.env +44 -0
- package/fastify/.env.example +42 -0
- package/fastify/.vscode/extensions.json +6 -0
- package/fastify/.vscode/settings.json +37 -0
- package/fastify/LICENSE +21 -0
- package/fastify/README.md +232 -0
- package/fastify/biome.json +99 -0
- package/fastify/drizzle.config.ts +25 -0
- package/fastify/gitignore-stub +31 -0
- package/fastify/package.json +130 -0
- package/fastify/public/.gitkeep +0 -0
- package/fastify/src/config/app.ts +41 -0
- package/fastify/src/config/auth.ts +12 -0
- package/fastify/src/config/cache.ts +16 -0
- package/fastify/src/config/cookie.ts +15 -0
- package/fastify/src/config/cors.ts +12 -0
- package/fastify/src/config/database.ts +48 -0
- package/fastify/src/config/index.ts +83 -0
- package/fastify/src/config/jwt.ts +19 -0
- package/fastify/src/config/logging.ts +13 -0
- package/fastify/src/config/mail.ts +24 -0
- package/fastify/src/config/openapi.ts +36 -0
- package/fastify/src/config/queue.ts +30 -0
- package/fastify/src/config/rateLimit.ts +17 -0
- package/fastify/src/config/realtime.ts +15 -0
- package/fastify/src/config/redis.ts +18 -0
- package/fastify/src/config/security.ts +44 -0
- package/fastify/src/config/session.ts +17 -0
- package/fastify/src/config/storage.ts +22 -0
- package/fastify/src/config/validate.ts +50 -0
- package/fastify/src/database/migrations/sqlite/0000_init.sql +48 -0
- package/fastify/src/database/migrations/sqlite/meta/0000_snapshot.json +324 -0
- package/fastify/src/database/migrations/sqlite/meta/_journal.json +13 -0
- package/fastify/src/database/schema.ts +2 -0
- package/fastify/src/env.ts +76 -0
- package/fastify/src/framework/cache/cache.ts +114 -0
- package/fastify/src/framework/circuit-breaker/cb.ts +88 -0
- package/fastify/src/framework/database/app-schema.ts +37 -0
- package/fastify/src/framework/database/connection.ts +223 -0
- package/fastify/src/framework/database/migrate-hooks.ts +87 -0
- package/fastify/src/framework/database/paginate.ts +226 -0
- package/fastify/src/framework/database/schema.ts +20 -0
- package/fastify/src/framework/database/seed.ts +152 -0
- package/fastify/src/framework/events/dispatcher.ts +61 -0
- package/fastify/src/framework/facade.ts +96 -0
- package/fastify/src/framework/http/app.ts +176 -0
- package/fastify/src/framework/http/cors.ts +13 -0
- package/fastify/src/framework/http/fastify.d.ts +13 -0
- package/fastify/src/framework/http/logger.ts +110 -0
- package/fastify/src/framework/http/metrics.ts +22 -0
- package/fastify/src/framework/http/openapi.ts +48 -0
- package/fastify/src/framework/http/ratelimiter.ts +47 -0
- package/fastify/src/framework/http/security.ts +25 -0
- package/fastify/src/framework/http/static.ts +83 -0
- package/fastify/src/framework/http/validation.ts +49 -0
- package/fastify/src/framework/kernel.ts +43 -0
- package/fastify/src/framework/maker-cli/db/core.mjs +291 -0
- package/fastify/src/framework/maker-cli/db/index.mjs +204 -0
- package/fastify/src/framework/maker-cli/deploy/core.mjs +1046 -0
- package/fastify/src/framework/maker-cli/deploy/index.mjs +91 -0
- package/fastify/src/framework/maker-cli/index.mjs +65 -0
- package/fastify/src/framework/maker-cli/middleware/core.mjs +41 -0
- package/fastify/src/framework/maker-cli/middleware/index.mjs +17 -0
- package/fastify/src/framework/maker-cli/module/core.mjs +1066 -0
- package/fastify/src/framework/maker-cli/module/index.mjs +211 -0
- package/fastify/src/framework/maker-cli/provider/core.mjs +49 -0
- package/fastify/src/framework/maker-cli/provider/index.mjs +12 -0
- package/fastify/src/framework/maker-cli/runtime/build-ui.mjs +16 -0
- package/fastify/src/framework/maker-cli/runtime/core.mjs +560 -0
- package/fastify/src/framework/maker-cli/runtime/index.mjs +120 -0
- package/fastify/src/framework/maker-cli/runtime/redis-commander-patch.cjs +20 -0
- package/fastify/src/framework/maker-cli/stubs/controller/openapi.ts.stub +74 -0
- package/fastify/src/framework/maker-cli/stubs/controller/plain.ts.stub +77 -0
- package/fastify/src/framework/maker-cli/stubs/controller/standalone.ts.stub +51 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.bun.stub +52 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.pnpm.stub +55 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.stub +51 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/Dockerfile.yarn.stub +55 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/README.stub +59 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/compose/mysql.server.stub +45 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/compose/postgres.server.stub +45 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/compose/sqlite.stub +45 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/env/mysql.server.stub +68 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/env/postgres.server.stub +68 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/env/sqlite.stub +67 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/scripts/auto-migrate.sh.stub +41 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/README.stub +78 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/noredis.stub +120 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/redis.dev.stub +133 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/compose/redis.stub +131 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/env/local.example.stub +11 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/env/noredis.stub +25 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/env/redis.stub +25 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/README.stub +16 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/nginx-vhost/app.example.com.stub +13 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/pgadmin/servers.stub +14 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/server/redis/redis.conf.stub +7 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/supervisor/noredis.stub +54 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/supervisor/redis.stub +70 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/workflow/local.json.stub +25 -0
- package/fastify/src/framework/maker-cli/stubs/deploy/workflow/remote.json.stub +24 -0
- package/fastify/src/framework/maker-cli/stubs/facade/name.ts.stub +12 -0
- package/fastify/src/framework/maker-cli/stubs/helper/name.ts.stub +14 -0
- package/fastify/src/framework/maker-cli/stubs/job/name.ts.stub +25 -0
- package/fastify/src/framework/maker-cli/stubs/middleware/name.local.ts.stub +15 -0
- package/fastify/src/framework/maker-cli/stubs/middleware/name.ts.stub +15 -0
- package/fastify/src/framework/maker-cli/stubs/model/name.mysql.ts.stub +10 -0
- package/fastify/src/framework/maker-cli/stubs/model/name.postgresql.ts.stub +10 -0
- package/fastify/src/framework/maker-cli/stubs/model/name.sqlite.ts.stub +10 -0
- package/fastify/src/framework/maker-cli/stubs/notification/controller.ts.stub +79 -0
- package/fastify/src/framework/maker-cli/stubs/notification/job.ts.stub +11 -0
- package/fastify/src/framework/maker-cli/stubs/notification/model.ts.stub +29 -0
- package/fastify/src/framework/maker-cli/stubs/notification/provider.ts.stub +174 -0
- package/fastify/src/framework/maker-cli/stubs/notification/route.api.ts.stub +71 -0
- package/fastify/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +15 -0
- package/fastify/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +26 -0
- package/fastify/src/framework/maker-cli/stubs/notification/schema.ts.stub +26 -0
- package/fastify/src/framework/maker-cli/stubs/provider/module-barrel.ts.stub +19 -0
- package/fastify/src/framework/maker-cli/stubs/provider/module.ts.stub +21 -0
- package/fastify/src/framework/maker-cli/stubs/provider/name.ts.stub +21 -0
- package/fastify/src/framework/maker-cli/stubs/route/api.ts.stub +101 -0
- package/fastify/src/framework/maker-cli/stubs/route/plain.ts.stub +23 -0
- package/fastify/src/framework/maker-cli/stubs/route/standalone.api.ts.stub +120 -0
- package/fastify/src/framework/maker-cli/stubs/route/standalone.plain.ts.stub +50 -0
- package/fastify/src/framework/maker-cli/stubs/schedule/name.ts.stub +36 -0
- package/fastify/src/framework/maker-cli/stubs/schema/name.plain.ts.stub +14 -0
- package/fastify/src/framework/maker-cli/stubs/schema/name.ts.stub +33 -0
- package/fastify/src/framework/maker-cli/stubs/seeder/name.ts.stub +18 -0
- package/fastify/src/framework/maker-cli/stubs/seeder/standalone.ts.stub +22 -0
- package/fastify/src/framework/maker-cli/stubs/service/name.plain.ts.stub +67 -0
- package/fastify/src/framework/maker-cli/stubs/service/name.ts.stub +65 -0
- package/fastify/src/framework/maker-cli/stubs/test/unit.ts.stub +22 -0
- package/fastify/src/framework/maker-cli/stubs/type/name.ts.stub +22 -0
- package/fastify/src/framework/maker-cli/utils/env-config.mjs +44 -0
- package/fastify/src/framework/maker-cli/utils/env-db.mjs +61 -0
- package/fastify/src/framework/maker-cli/utils/file-ops.mjs +30 -0
- package/fastify/src/framework/maker-cli/utils/flags.mjs +14 -0
- package/fastify/src/framework/maker-cli/utils/help.mjs +379 -0
- package/fastify/src/framework/maker-cli/utils/naming.mjs +119 -0
- package/fastify/src/framework/maker-cli/utils/process.mjs +52 -0
- package/fastify/src/framework/maker-cli/utils/project-commands.mjs +201 -0
- package/fastify/src/framework/modules/discover.ts +57 -0
- package/fastify/src/framework/modules/routes.ts +31 -0
- package/fastify/src/framework/notification/channels/broadcast.ts +15 -0
- package/fastify/src/framework/notification/channels/mail.ts +42 -0
- package/fastify/src/framework/notification/contracts.ts +29 -0
- package/fastify/src/framework/notification/index.ts +59 -0
- package/fastify/src/framework/notification/registry.ts +15 -0
- package/fastify/src/framework/providers/adapter.ts +149 -0
- package/fastify/src/framework/providers/contracts.ts +126 -0
- package/fastify/src/framework/providers/loader.ts +105 -0
- package/fastify/src/framework/providers/registry.ts +88 -0
- package/fastify/src/framework/queue/clear.ts +22 -0
- package/fastify/src/framework/queue/queue.ts +401 -0
- package/fastify/src/framework/queue/ui.ts +194 -0
- package/fastify/src/framework/queue/worker.ts +61 -0
- package/fastify/src/framework/realtime/broadcast.ts +70 -0
- package/fastify/src/framework/realtime/index.ts +2 -0
- package/fastify/src/framework/realtime/socket-cookie.ts +72 -0
- package/fastify/src/framework/realtime/socket.ts +149 -0
- package/fastify/src/framework/realtime/types.ts +6 -0
- package/fastify/src/framework/realtime/ui.ts +16 -0
- package/fastify/src/framework/redis/client.ts +148 -0
- package/fastify/src/framework/runtime/runtime.ts +23 -0
- package/fastify/src/framework/runtime/server-adapter.ts +33 -0
- package/fastify/src/framework/scheduler/lock.ts +128 -0
- package/fastify/src/framework/scheduler/run.ts +48 -0
- package/fastify/src/framework/scheduler/scheduler.ts +155 -0
- package/fastify/src/framework/server.ts +162 -0
- package/fastify/src/framework/session/session.ts +160 -0
- package/fastify/src/framework/storage/storage.ts +744 -0
- package/fastify/src/framework/support/cookie.ts +71 -0
- package/fastify/src/framework/support/jwt.ts +33 -0
- package/fastify/src/framework/support/lifecycle.ts +35 -0
- package/fastify/src/framework/support/logger.ts +148 -0
- package/fastify/src/framework/support/mail.ts +56 -0
- package/fastify/src/framework/support/password.ts +23 -0
- package/fastify/src/framework/support/status-codes.ts +75 -0
- package/fastify/src/framework/support/upload.ts +181 -0
- package/fastify/src/framework/support/url.ts +41 -0
- package/fastify/src/middlewares/auth-middleware.ts +134 -0
- package/fastify/src/middlewares/role-middleware.ts +19 -0
- package/fastify/src/modules/auth/__tests__/forgetpass.test.ts +200 -0
- package/fastify/src/modules/auth/__tests__/login.test.ts +171 -0
- package/fastify/src/modules/auth/__tests__/logout.test.ts +60 -0
- package/fastify/src/modules/auth/__tests__/logoutalldevices.test.ts +49 -0
- package/fastify/src/modules/auth/__tests__/me.test.ts +91 -0
- package/fastify/src/modules/auth/__tests__/refreshtoken.test.ts +305 -0
- package/fastify/src/modules/auth/__tests__/register.test.ts +291 -0
- package/fastify/src/modules/auth/__tests__/resetpass.test.ts +206 -0
- package/fastify/src/modules/auth/__tests__/verifyemail.test.ts +183 -0
- package/fastify/src/modules/auth/controllers/auth.ts +252 -0
- package/fastify/src/modules/auth/controllers/role.ts +35 -0
- package/fastify/src/modules/auth/database/models/role.ts +14 -0
- package/fastify/src/modules/auth/database/models/user.ts +46 -0
- package/fastify/src/modules/auth/database/seeders/role.ts +18 -0
- package/fastify/src/modules/auth/database/seeders/user.ts +35 -0
- package/fastify/src/modules/auth/facade.ts +12 -0
- package/fastify/src/modules/auth/helpers/auth.ts +115 -0
- package/fastify/src/modules/auth/jobs/forgetpass.ts +20 -0
- package/fastify/src/modules/auth/jobs/registeruser.ts +23 -0
- package/fastify/src/modules/auth/jobs/verifyemail.ts +18 -0
- package/fastify/src/modules/auth/routes/index.ts +185 -0
- package/fastify/src/modules/auth/routes/role.ts +56 -0
- package/fastify/src/modules/auth/schemas/auth.ts +116 -0
- package/fastify/src/modules/auth/services/forgetpassword.ts +66 -0
- package/fastify/src/modules/auth/services/login.ts +63 -0
- package/fastify/src/modules/auth/services/logout.ts +25 -0
- package/fastify/src/modules/auth/services/logoutalldevices.ts +19 -0
- package/fastify/src/modules/auth/services/me.ts +31 -0
- package/fastify/src/modules/auth/services/refreshtoken.ts +110 -0
- package/fastify/src/modules/auth/services/register.ts +141 -0
- package/fastify/src/modules/auth/services/resetpassword.ts +69 -0
- package/fastify/src/modules/auth/services/verifyemail.ts +77 -0
- package/fastify/src/modules/auth/types/auth.ts +31 -0
- package/fastify/src/providers/README.md +107 -0
- package/fastify/src/providers/notification.ts +4 -0
- package/fastify/src/resources/index.html +17 -0
- package/fastify/src/resources/src/App.vue +5 -0
- package/fastify/src/resources/src/assets/css/styles.css +14761 -0
- package/fastify/src/resources/src/assets/css/styles.css.map +1 -0
- package/fastify/src/resources/src/assets/fonts/public-sans/public-sans-latin-ext.woff2 +0 -0
- package/fastify/src/resources/src/assets/fonts/public-sans/public-sans-latin.woff2 +0 -0
- package/fastify/src/resources/src/assets/images/favicon/favicon.ico +0 -0
- package/fastify/src/resources/src/assets/images/logo.png +0 -0
- package/fastify/src/resources/src/assets/scss/custom.css +217 -0
- package/fastify/src/resources/src/assets/scss/custom.css.map +1 -0
- package/fastify/src/resources/src/assets/scss/custom.scss +1346 -0
- package/fastify/src/resources/src/components/Button.vue +32 -0
- package/fastify/src/resources/src/components/Checkbox.vue +32 -0
- package/fastify/src/resources/src/components/Datepicker.vue +106 -0
- package/fastify/src/resources/src/components/FeatureButton.vue +53 -0
- package/fastify/src/resources/src/components/FloatButton.vue +33 -0
- package/fastify/src/resources/src/components/Href.vue +32 -0
- package/fastify/src/resources/src/components/Input.vue +243 -0
- package/fastify/src/resources/src/components/InputGroup.vue +147 -0
- package/fastify/src/resources/src/components/InputPasswordToggle.vue +229 -0
- package/fastify/src/resources/src/components/Modal.vue +71 -0
- package/fastify/src/resources/src/components/Pagebar.vue +26 -0
- package/fastify/src/resources/src/components/Refresh.vue +19 -0
- package/fastify/src/resources/src/components/Select.vue +384 -0
- package/fastify/src/resources/src/components/Spinner.vue +42 -0
- package/fastify/src/resources/src/components/Switch.vue +60 -0
- package/fastify/src/resources/src/components/TextArea.vue +117 -0
- package/fastify/src/resources/src/components/Toast.vue +56 -0
- package/fastify/src/resources/src/components/datatable/DataTableSkeleton.vue +98 -0
- package/fastify/src/resources/src/components/datatable/Pagination.vue +147 -0
- package/fastify/src/resources/src/components/datatable/SelectOpption.vue +64 -0
- package/fastify/src/resources/src/components/datatable/index.vue +199 -0
- package/fastify/src/resources/src/composables/useAuth.ts +52 -0
- package/fastify/src/resources/src/helpers/assets.ts +51 -0
- package/fastify/src/resources/src/helpers/nformatter.ts +10 -0
- package/fastify/src/resources/src/helpers/utils.ts +75 -0
- package/fastify/src/resources/src/layouts/AuthLayout.vue +20 -0
- package/fastify/src/resources/src/layouts/Layout/Footer.vue +23 -0
- package/fastify/src/resources/src/layouts/Layout/Header.vue +124 -0
- package/fastify/src/resources/src/layouts/Layout/Sidebar.vue +137 -0
- package/fastify/src/resources/src/layouts/Layout/index.vue +87 -0
- package/fastify/src/resources/src/main.ts +28 -0
- package/fastify/src/resources/src/pages/auth/forgetPassword.vue +76 -0
- package/fastify/src/resources/src/pages/auth/login.vue +96 -0
- package/fastify/src/resources/src/pages/auth/register.vue +129 -0
- package/fastify/src/resources/src/pages/auth/resetPassword.vue +110 -0
- package/fastify/src/resources/src/pages/auth/verifyEmail.vue +64 -0
- package/fastify/src/resources/src/pages/dashboard/index.vue +66 -0
- package/fastify/src/resources/src/plugins/axios.ts +31 -0
- package/fastify/src/resources/src/plugins/browserDetect.ts +55 -0
- package/fastify/src/resources/src/plugins/dialog.ts +216 -0
- package/fastify/src/resources/src/plugins/gum.ts +683 -0
- package/fastify/src/resources/src/plugins/pulse.ts +157 -0
- package/fastify/src/resources/src/plugins/routeProgress.ts +87 -0
- package/fastify/src/resources/src/router/index.ts +85 -0
- package/fastify/src/resources/src/stores/admin-ui.ts +148 -0
- package/fastify/src/resources/src/stores/auth.ts +187 -0
- package/fastify/src/resources/tsconfig.json +19 -0
- package/fastify/src/resources/vite.config.ts +64 -0
- package/fastify/src/storage/app/private/.gitkeep +0 -0
- package/fastify/src/storage/app/public/.gitkeep +0 -0
- package/fastify/src/storage/app/tmp/generated/.gitkeep +0 -0
- package/fastify/src/storage/database/nexwire.sqlite +0 -0
- package/fastify/src/storage/logs/.gitkeep +0 -0
- package/fastify/src/storage/logs/app.log +0 -0
- package/fastify/src/storage/logs/fatal.log +0 -0
- package/fastify/src/storage/tmp/.gitkeep +0 -0
- package/fastify/src/storage/trash/modules/.gitkeep +0 -0
- package/fastify/src/types/global.d.ts +32 -0
- package/fastify/tsconfig.json +19 -0
- package/fastify/vitest.config.ts +38 -0
- package/hono/src/framework/facade.ts +1 -0
- package/hono/src/framework/http/logger.ts +86 -81
- package/hono/src/framework/maker-cli/runtime/core.mjs +1 -2
- package/hono/src/framework/notification/channels/mail.ts +8 -6
- package/hono/src/middlewares/auth-middleware.ts +1 -2
- package/hono/src/middlewares/role-middleware.ts +3 -13
- package/hono/src/modules/auth/routes/index.ts +1 -2
- package/hono/src/providers/notification.ts +2 -2
- package/hono/src/resources/src/components/Switch.vue +60 -65
- package/hono/src/resources/src/pages/auth/forgetPassword.vue +23 -29
- package/hono/src/resources/src/pages/auth/login.vue +26 -29
- package/hono/src/resources/src/pages/auth/register.vue +36 -40
- package/hono/src/resources/src/pages/auth/resetPassword.vue +29 -37
- package/hono/src/resources/src/pages/auth/verifyEmail.vue +15 -19
- package/hono/src/resources/src/plugins/gum.ts +519 -203
- package/hono/src/resources/src/stores/auth.ts +9 -6
- package/hono/src/storage/database/nexwire.sqlite +0 -0
- package/package.json +3 -2
- package/src/index.js +11 -8
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath, URL } from "node:url";
|
|
3
|
+
import vue from "@vitejs/plugin-vue";
|
|
4
|
+
import { defineConfig, loadEnv } from "vite";
|
|
5
|
+
|
|
6
|
+
const configDir = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const projectRoot = path.resolve(configDir, "../..");
|
|
8
|
+
|
|
9
|
+
export default defineConfig(({ mode }) => {
|
|
10
|
+
// 1. Load the .env file just like the backend does. Resolve it from the
|
|
11
|
+
// config file so a different process cwd cannot point Vite at the wrong .env.
|
|
12
|
+
const env = loadEnv(mode, projectRoot, "");
|
|
13
|
+
|
|
14
|
+
const cacheBase = process.env.LOCALAPPDATA || process.env.TEMP || ".";
|
|
15
|
+
const apiUrl = env.APP_URL || "http://localhost:3000";
|
|
16
|
+
|
|
17
|
+
// Match the backend default: Socket.IO is off unless SOCKET=true
|
|
18
|
+
const socketEnabled = env.SOCKET === "true";
|
|
19
|
+
|
|
20
|
+
const proxy: Record<string, any> = {
|
|
21
|
+
"/api": { target: apiUrl, changeOrigin: true },
|
|
22
|
+
"/health": { target: apiUrl, changeOrigin: true },
|
|
23
|
+
"/storage": { target: apiUrl, changeOrigin: true }
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (socketEnabled) {
|
|
27
|
+
proxy["/socket.io"] = { target: apiUrl, changeOrigin: true, ws: true, timeout: 10000 };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
define: {
|
|
32
|
+
// 3. ALWAYS stringify the value when using Vite define
|
|
33
|
+
// `import.meta.env.*` is inlined into every module in dev as well as in
|
|
34
|
+
// the production bundle, so the UI never depends on a stale global.
|
|
35
|
+
"import.meta.env.VITE_SOCKET_ENABLED": JSON.stringify(socketEnabled),
|
|
36
|
+
__SOCKET_ENABLED__: JSON.stringify(socketEnabled),
|
|
37
|
+
__API_URL__: JSON.stringify(apiUrl)
|
|
38
|
+
},
|
|
39
|
+
root: fileURLToPath(new URL(".", import.meta.url)),
|
|
40
|
+
cacheDir: path.join(cacheBase, "nexwire", "vite-cache", "resources"),
|
|
41
|
+
plugins: [vue()],
|
|
42
|
+
css: {
|
|
43
|
+
preprocessorOptions: {
|
|
44
|
+
scss: {
|
|
45
|
+
quietDeps: true,
|
|
46
|
+
silenceDeprecations: ["import", "if-function", "global-builtin", "color-functions", "slash-div"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
resolve: {
|
|
51
|
+
alias: {
|
|
52
|
+
"@": fileURLToPath(new URL("./src", import.meta.url))
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
build: {
|
|
56
|
+
outDir: "../../public",
|
|
57
|
+
emptyOutDir: true
|
|
58
|
+
},
|
|
59
|
+
server: {
|
|
60
|
+
port: 5173,
|
|
61
|
+
proxy // /socket.io is only proxied when SOCKET=true
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
declare module "*.vue" {
|
|
2
|
+
import type { DefineComponent } from "vue";
|
|
3
|
+
|
|
4
|
+
const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>;
|
|
5
|
+
export default component;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare module "bootstrap/js/dist/modal.js" {
|
|
9
|
+
export default class Modal {
|
|
10
|
+
constructor(element: Element, options?: { backdrop?: boolean | "static"; keyboard?: boolean });
|
|
11
|
+
show(): void;
|
|
12
|
+
hide(): void;
|
|
13
|
+
dispose(): void;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare module "bootstrap/js/dist/toast.js" {
|
|
18
|
+
export default class Toast {
|
|
19
|
+
static getOrCreateInstance(element: Element): Toast;
|
|
20
|
+
show(): void;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare module "luxon";
|
|
25
|
+
declare module "nodemailer";
|
|
26
|
+
declare module "vue-select";
|
|
27
|
+
|
|
28
|
+
interface ImportMetaEnv {
|
|
29
|
+
readonly VITE_API_URL?: string;
|
|
30
|
+
readonly VITE_SOCKET_URL?: string;
|
|
31
|
+
readonly VITE_SOCKET_ENABLED?: boolean;
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"paths": {
|
|
8
|
+
"@/*": ["./src/*"]
|
|
9
|
+
},
|
|
10
|
+
"strict": false,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"allowSyntheticDefaultImports": true,
|
|
13
|
+
"outDir": "./dist",
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"types": ["node"]
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/framework/maker-cli/**/*.mjs", "drizzle.config.ts"],
|
|
18
|
+
"exclude": ["node_modules", "dist", "src/resources", "src/storage/trash"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { defineConfig } from "vitest/config";
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
resolve: {
|
|
6
|
+
alias: {
|
|
7
|
+
"@": fileURLToPath(new URL("./src", import.meta.url))
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
test: {
|
|
11
|
+
globals: true,
|
|
12
|
+
include: ["src/**/*.test.ts", "src/**/*.spec.ts"],
|
|
13
|
+
exclude: ["src/resources/**", "src/storage/**", "node_modules/**", "dist/**"],
|
|
14
|
+
environment: "node",
|
|
15
|
+
coverage: {
|
|
16
|
+
provider: "v8",
|
|
17
|
+
reporter: ["text", "json", "html"],
|
|
18
|
+
include: ["src/**/*.ts"],
|
|
19
|
+
exclude: ["src/resources/**", "src/storage/**", "src/framework/maker-cli/**", "src/**/*.d.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
|
20
|
+
// No `thresholds` here on purpose.
|
|
21
|
+
//
|
|
22
|
+
// This file is published inside the package, so any floor written here also
|
|
23
|
+
// becomes every scaffolded project's floor - and it would fail them on the
|
|
24
|
+
// first run. A new project ships with only the auth module's tests: the
|
|
25
|
+
// framework's own tests under `src/framework/**/__tests__/` are not
|
|
26
|
+
// published, because they test the framework rather than the application.
|
|
27
|
+
// That measures 8.49% statements, so a floor calibrated for this repository
|
|
28
|
+
// reports a failure for a developer who has done nothing wrong and whose
|
|
29
|
+
// 56 tests all pass.
|
|
30
|
+
//
|
|
31
|
+
// The floor is a guard on this repository, not on yours, so it is passed on
|
|
32
|
+
// the command line when the framework's own suite is run - it is never read
|
|
33
|
+
// from this file. That keeps this file byte-identical across both engines,
|
|
34
|
+
// keeps it free of a number that would be meaningless in someone else's
|
|
35
|
+
// project, and still fails when untested code is added here.
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
@@ -28,6 +28,7 @@ export { command, dispatchCommand, dispatchEvent } from "@/framework/events/disp
|
|
|
28
28
|
// ==========================================
|
|
29
29
|
// 3. HTTP & Routing
|
|
30
30
|
// ==========================================
|
|
31
|
+
export { loginLimiter } from "@/framework/http/ratelimiter.js";
|
|
31
32
|
export { createRouter, group } from "@/framework/http/router.js";
|
|
32
33
|
export { validate } from "@/framework/http/validation.js";
|
|
33
34
|
export { broadcastChannel } from "@/framework/notification/channels/broadcast.js";
|
|
@@ -1,81 +1,86 @@
|
|
|
1
|
-
import type { Context, Next } from "hono";
|
|
2
|
-
import { loggingConfig } from "@/config/index.js";
|
|
3
|
-
import { logger } from "@/framework/support/logger.js";
|
|
4
|
-
|
|
5
|
-
function ip(c: Context) {
|
|
6
|
-
return c.req.header("cf-connecting-ip") || c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || null;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
1
|
+
import type { Context, Next } from "hono";
|
|
2
|
+
import { loggingConfig } from "@/config/index.js";
|
|
3
|
+
import { logger } from "@/framework/support/logger.js";
|
|
4
|
+
|
|
5
|
+
function ip(c: Context) {
|
|
6
|
+
return c.req.header("cf-connecting-ip") || c.req.header("x-forwarded-for") || c.req.header("x-real-ip") || null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Probe endpoints and the queue dashboard are infrastructure traffic, not
|
|
10
|
+
// application requests. Skip them on every engine so the access log stays
|
|
11
|
+
// useful (the dev CLI polls /health while it boots).
|
|
12
|
+
const PROBE_PATHS = new Set(["/health", "/ready", "/live"]);
|
|
13
|
+
|
|
14
|
+
function shouldSkipHttpLog(pathname: string) {
|
|
15
|
+
return PROBE_PATHS.has(pathname) || pathname.startsWith("/queues");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Why: Logs each HTTP request with latency and request metadata.
|
|
20
|
+
* When: Applied globally to app routes.
|
|
21
|
+
* Where: HTTP middleware stack.
|
|
22
|
+
* How: Captures start time, assigns request id, logs after downstream response.
|
|
23
|
+
*/
|
|
24
|
+
export async function loggerMiddleware(c: Context, next: Next) {
|
|
25
|
+
const start = Date.now();
|
|
26
|
+
const requestId = crypto.randomUUID();
|
|
27
|
+
|
|
28
|
+
c.set("requestId", requestId);
|
|
29
|
+
await next();
|
|
30
|
+
|
|
31
|
+
if (!loggingConfig.httpRequests || shouldSkipHttpLog(c.req.path)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
logger.info("HTTP Request", {
|
|
36
|
+
requestId,
|
|
37
|
+
method: c.req.method,
|
|
38
|
+
path: c.req.path,
|
|
39
|
+
url: c.req.url,
|
|
40
|
+
status: c.res.status,
|
|
41
|
+
duration_ms: Date.now() - start,
|
|
42
|
+
ip: ip(c),
|
|
43
|
+
userAgent: c.req.header("user-agent") || null
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Why: Standard 404 handler with structured log context.
|
|
49
|
+
* When: No route matches request path.
|
|
50
|
+
* Where: App notFound handler registration.
|
|
51
|
+
* How: Emits warning log and returns JSON 404 payload.
|
|
52
|
+
*/
|
|
53
|
+
export function notFound(c: Context) {
|
|
54
|
+
logger.warn("404 Not Found", {
|
|
55
|
+
requestId: c.get("requestId") || null,
|
|
56
|
+
method: c.req.method,
|
|
57
|
+
path: c.req.path,
|
|
58
|
+
url: c.req.url,
|
|
59
|
+
ip: ip(c),
|
|
60
|
+
userAgent: c.req.header("user-agent") || null
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return c.json({ message: "Not Found" }, 404);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Why: Centralized unhandled error responder and logger.
|
|
68
|
+
* When: Route/middleware throws uncaught error.
|
|
69
|
+
* Where: App onError handler registration.
|
|
70
|
+
* How: Logs stack + request context and returns status/message JSON.
|
|
71
|
+
*/
|
|
72
|
+
export function onError(error: any, c: Context) {
|
|
73
|
+
logger.error("Unhandled Application Error", {
|
|
74
|
+
requestId: c.get("requestId") || null,
|
|
75
|
+
name: error?.name || "Error",
|
|
76
|
+
message: error?.message,
|
|
77
|
+
stack: error?.stack,
|
|
78
|
+
method: c.req.method,
|
|
79
|
+
path: c.req.path,
|
|
80
|
+
url: c.req.url,
|
|
81
|
+
ip: ip(c),
|
|
82
|
+
userAgent: c.req.header("user-agent") || null
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return c.json({ message: error?.message || "Internal Server Error" }, error?.status || 500);
|
|
86
|
+
}
|
|
@@ -120,7 +120,7 @@ function serveRedisUnavailablePage(port, endpoint) {
|
|
|
120
120
|
</html>
|
|
121
121
|
`;
|
|
122
122
|
|
|
123
|
-
return new Promise((
|
|
123
|
+
return new Promise((_resolve, reject) => {
|
|
124
124
|
const server = http.createServer((_req, res) => {
|
|
125
125
|
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
126
126
|
res.end(body);
|
|
@@ -558,4 +558,3 @@ export async function clearViteCache() {
|
|
|
558
558
|
|
|
559
559
|
console.log("Vite cache cleared.");
|
|
560
560
|
}
|
|
561
|
-
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { mail } from "@/framework/support/mail.js";
|
|
2
|
-
import { resolveAuthProvider } from "@/framework/providers/adapter.js";
|
|
3
|
-
import { redisClientIfReady } from "@/framework/redis/client.js";
|
|
4
1
|
import { dispatchEvent } from "@/framework/events/dispatcher.js";
|
|
5
2
|
import type { NotificationChannel } from "@/framework/notification/contracts.js";
|
|
3
|
+
import { resolveAuthProvider } from "@/framework/providers/adapter.js";
|
|
4
|
+
import { redisClientIfReady } from "@/framework/redis/client.js";
|
|
5
|
+
import { mail } from "@/framework/support/mail.js";
|
|
6
6
|
|
|
7
7
|
function escapeHtml(str: string) {
|
|
8
8
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -21,13 +21,15 @@ export const mailChannel: NotificationChannel = {
|
|
|
21
21
|
const contact = await provider.getUserContact(target.id);
|
|
22
22
|
if (contact?.email) to = contact.email as string;
|
|
23
23
|
}
|
|
24
|
-
} catch {
|
|
24
|
+
} catch {}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
if (!to) return false;
|
|
28
28
|
|
|
29
29
|
const subject = options.mail.subject || notification.title;
|
|
30
|
-
const html =
|
|
30
|
+
const html =
|
|
31
|
+
options.mail.html ||
|
|
32
|
+
`<h2>${escapeHtml(notification.title)}</h2>${notification.body ? `<p>${escapeHtml(notification.body)}</p>` : ""}`;
|
|
31
33
|
|
|
32
34
|
if (redisClientIfReady()) {
|
|
33
35
|
await dispatchEvent("notification:mail", { to, subject, html }, { queue: "mail" });
|
|
@@ -37,4 +39,4 @@ export const mailChannel: NotificationChannel = {
|
|
|
37
39
|
|
|
38
40
|
return true;
|
|
39
41
|
}
|
|
40
|
-
};
|
|
42
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Context, Next } from "hono";
|
|
2
|
-
import { cookie, HttpStatusCodes, jwt } from "@/framework/facade.js";
|
|
3
|
-
import { resolveAuthProvider } from "@/framework/providers/adapter.js";
|
|
2
|
+
import { cookie, HttpStatusCodes, jwt, resolveAuthProvider } from "@/framework/facade.js";
|
|
4
3
|
|
|
5
4
|
export async function authMiddleware(c: Context, next: Next) {
|
|
6
5
|
const provider = await resolveAuthProvider();
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
import type { Context, Next } from "hono";
|
|
2
2
|
import { HttpStatusCodes } from "@/framework/facade.js";
|
|
3
3
|
|
|
4
|
-
type AuthPayload = {
|
|
5
|
-
role?: string | null;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
4
|
export function requireRole(...allowedRoles: string[]) {
|
|
9
|
-
const roles = allowedRoles.map((role) => role.toLowerCase());
|
|
10
|
-
|
|
11
5
|
return async (c: Context, next: Next) => {
|
|
12
|
-
const auth = c.get("auth")
|
|
13
|
-
|
|
14
|
-
if (!auth) {
|
|
15
|
-
return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
|
|
16
|
-
}
|
|
6
|
+
const auth = c.get("auth");
|
|
7
|
+
if (!auth) return c.json({ message: "Unauthorized" }, HttpStatusCodes.UNAUTHORIZED);
|
|
17
8
|
|
|
18
|
-
|
|
19
|
-
if (!roles.includes(userRole)) {
|
|
9
|
+
if (!allowedRoles.includes(auth.role?.name)) {
|
|
20
10
|
return c.json({ message: "Forbidden: Insufficient permissions" }, HttpStatusCodes.FORBIDDEN);
|
|
21
11
|
}
|
|
22
12
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { createRoute, createRouter, HttpStatusCodes, jsonContent, z } from "@/framework/facade.js";
|
|
2
|
-
import { loginLimiter } from "@/framework/http/ratelimiter.js";
|
|
1
|
+
import { createRoute, createRouter, HttpStatusCodes, jsonContent, loginLimiter, z } from "@/framework/facade.js";
|
|
3
2
|
import { authMiddleware } from "@/middlewares/auth-middleware.js";
|
|
4
3
|
import {
|
|
5
4
|
forgotPassword,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { broadcastChannel, mailChannel, registerChannel } from "@/framework/facade.js";
|
|
2
2
|
|
|
3
3
|
registerChannel(mailChannel);
|
|
4
|
-
registerChannel(broadcastChannel);
|
|
4
|
+
registerChannel(broadcastChannel);
|
|
@@ -1,65 +1,60 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="wrapperClass">
|
|
3
|
-
<label :class="props.vertical ? 'form-check-label d-block' : 'd-none'">
|
|
4
|
-
<span v-html="statusHtml"></span>
|
|
5
|
-
</label>
|
|
6
|
-
<div class="form-check form-switch d-inline-block">
|
|
7
|
-
<input
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
label,
|
|
62
|
-
input {
|
|
63
|
-
cursor: pointer;
|
|
64
|
-
}
|
|
65
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="wrapperClass">
|
|
3
|
+
<label :class="props.vertical ? 'form-check-label d-block' : 'd-none'">
|
|
4
|
+
<span v-html="statusHtml"></span>
|
|
5
|
+
</label>
|
|
6
|
+
<div class="form-check form-switch d-inline-block">
|
|
7
|
+
<input class="form-check-input shadow-none border-primary" type="checkbox" :checked="isChecked" v-bind="$attrs">
|
|
8
|
+
<label :class="props.vertical ? 'd-none' : 'form-check-label'">
|
|
9
|
+
<span v-html="statusHtml"></span>
|
|
10
|
+
</label>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { computed, useAttrs } from "vue";
|
|
17
|
+
|
|
18
|
+
defineOptions({ name: "Switch", inheritAttrs: false });
|
|
19
|
+
|
|
20
|
+
interface SwitchProps {
|
|
21
|
+
modelValue?: string | number | boolean;
|
|
22
|
+
value?: unknown[] | Record<string, unknown> | string | number | boolean;
|
|
23
|
+
vertical?: boolean;
|
|
24
|
+
checked?: boolean | number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const $attrs = useAttrs();
|
|
28
|
+
const props = defineProps<SwitchProps>();
|
|
29
|
+
|
|
30
|
+
const textLabel = computed(() => ($attrs.text as string | undefined) || "");
|
|
31
|
+
const blankLabel = computed(() => ($attrs.blank as string | undefined) || "");
|
|
32
|
+
const topclass = computed(() => ($attrs.topclass as string | undefined) || "");
|
|
33
|
+
|
|
34
|
+
const isChecked = computed(() => Boolean(props.checked));
|
|
35
|
+
|
|
36
|
+
const wrapperClass = computed(() => (props.vertical ? `text-center ${topclass.value}`.trim() : ""));
|
|
37
|
+
|
|
38
|
+
const statusHtml = computed(() => {
|
|
39
|
+
if (isChecked.value) {
|
|
40
|
+
return `<div class='d-flex justify-content-center'><span>${textLabel.value}</span><div class='rounded-circle bg-success indicator'></div></div>`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return `<div class='d-flex justify-content-center'><span>${blankLabel.value}</span><div class='rounded-circle bg-danger indicator'></div></div>`;
|
|
44
|
+
});
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<style lang="scss" scoped>
|
|
48
|
+
.indicator {
|
|
49
|
+
width: 4px;
|
|
50
|
+
height: 4px;
|
|
51
|
+
margin-left: 2px;
|
|
52
|
+
margin-top: 5px;
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
<style lang="scss" scoped>
|
|
56
|
+
label,
|
|
57
|
+
input {
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
}
|
|
60
|
+
</style>
|