vợ bảo okeoke
This commit is contained in:
90
auto-imports.d.ts
vendored
Normal file
90
auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
const EffectScope: typeof import('vue').EffectScope
|
||||||
|
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
||||||
|
const computed: typeof import('vue').computed
|
||||||
|
const createApp: typeof import('vue').createApp
|
||||||
|
const createPinia: typeof import('pinia').createPinia
|
||||||
|
const customRef: typeof import('vue').customRef
|
||||||
|
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
|
||||||
|
const defineComponent: typeof import('vue').defineComponent
|
||||||
|
const defineStore: typeof import('pinia').defineStore
|
||||||
|
const effectScope: typeof import('vue').effectScope
|
||||||
|
const getActivePinia: typeof import('pinia').getActivePinia
|
||||||
|
const getCurrentInstance: typeof import('vue').getCurrentInstance
|
||||||
|
const getCurrentScope: typeof import('vue').getCurrentScope
|
||||||
|
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
|
||||||
|
const h: typeof import('vue').h
|
||||||
|
const inject: typeof import('vue').inject
|
||||||
|
const isProxy: typeof import('vue').isProxy
|
||||||
|
const isReactive: typeof import('vue').isReactive
|
||||||
|
const isReadonly: typeof import('vue').isReadonly
|
||||||
|
const isRef: typeof import('vue').isRef
|
||||||
|
const isShallow: typeof import('vue').isShallow
|
||||||
|
const mapActions: typeof import('pinia').mapActions
|
||||||
|
const mapGetters: typeof import('pinia').mapGetters
|
||||||
|
const mapState: typeof import('pinia').mapState
|
||||||
|
const mapStores: typeof import('pinia').mapStores
|
||||||
|
const mapWritableState: typeof import('pinia').mapWritableState
|
||||||
|
const markRaw: typeof import('vue').markRaw
|
||||||
|
const nextTick: typeof import('vue').nextTick
|
||||||
|
const onActivated: typeof import('vue').onActivated
|
||||||
|
const onBeforeMount: typeof import('vue').onBeforeMount
|
||||||
|
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
|
||||||
|
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
|
||||||
|
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
|
||||||
|
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
|
||||||
|
const onDeactivated: typeof import('vue').onDeactivated
|
||||||
|
const onErrorCaptured: typeof import('vue').onErrorCaptured
|
||||||
|
const onMounted: typeof import('vue').onMounted
|
||||||
|
const onRenderTracked: typeof import('vue').onRenderTracked
|
||||||
|
const onRenderTriggered: typeof import('vue').onRenderTriggered
|
||||||
|
const onScopeDispose: typeof import('vue').onScopeDispose
|
||||||
|
const onServerPrefetch: typeof import('vue').onServerPrefetch
|
||||||
|
const onUnmounted: typeof import('vue').onUnmounted
|
||||||
|
const onUpdated: typeof import('vue').onUpdated
|
||||||
|
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
|
||||||
|
const provide: typeof import('vue').provide
|
||||||
|
const reactive: typeof import('vue').reactive
|
||||||
|
const readonly: typeof import('vue').readonly
|
||||||
|
const ref: typeof import('vue').ref
|
||||||
|
const resolveComponent: typeof import('vue').resolveComponent
|
||||||
|
const setActivePinia: typeof import('pinia').setActivePinia
|
||||||
|
const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
|
||||||
|
const shallowReactive: typeof import('vue').shallowReactive
|
||||||
|
const shallowReadonly: typeof import('vue').shallowReadonly
|
||||||
|
const shallowRef: typeof import('vue').shallowRef
|
||||||
|
const storeToRefs: typeof import('pinia').storeToRefs
|
||||||
|
const toRaw: typeof import('vue').toRaw
|
||||||
|
const toRef: typeof import('vue').toRef
|
||||||
|
const toRefs: typeof import('vue').toRefs
|
||||||
|
const toValue: typeof import('vue').toValue
|
||||||
|
const triggerRef: typeof import('vue').triggerRef
|
||||||
|
const unref: typeof import('vue').unref
|
||||||
|
const useAttrs: typeof import('vue').useAttrs
|
||||||
|
const useCssModule: typeof import('vue').useCssModule
|
||||||
|
const useCssVars: typeof import('vue').useCssVars
|
||||||
|
const useId: typeof import('vue').useId
|
||||||
|
const useLink: typeof import('vue-router').useLink
|
||||||
|
const useModel: typeof import('vue').useModel
|
||||||
|
const useRoute: typeof import('vue-router').useRoute
|
||||||
|
const useRouter: typeof import('vue-router').useRouter
|
||||||
|
const useSlots: typeof import('vue').useSlots
|
||||||
|
const useTemplateRef: typeof import('vue').useTemplateRef
|
||||||
|
const watch: typeof import('vue').watch
|
||||||
|
const watchEffect: typeof import('vue').watchEffect
|
||||||
|
const watchPostEffect: typeof import('vue').watchPostEffect
|
||||||
|
const watchSyncEffect: typeof import('vue').watchSyncEffect
|
||||||
|
}
|
||||||
|
// for type re-export
|
||||||
|
declare global {
|
||||||
|
// @ts-ignore
|
||||||
|
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
|
import('vue')
|
||||||
|
}
|
||||||
21
bun.lock
21
bun.lock
@@ -30,6 +30,7 @@
|
|||||||
"@vitejs/plugin-vue": "^6.0.3",
|
"@vitejs/plugin-vue": "^6.0.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.3",
|
"@vitejs/plugin-vue-jsx": "^5.1.3",
|
||||||
"unocss": "^66.5.12",
|
"unocss": "^66.5.12",
|
||||||
|
"unplugin-auto-import": "^20.3.0",
|
||||||
"unplugin-vue-components": "^30.0.0",
|
"unplugin-vue-components": "^30.0.0",
|
||||||
"vite": "^7.3.0",
|
"vite": "^7.3.0",
|
||||||
"vite-ssr-components": "^0.5.2",
|
"vite-ssr-components": "^0.5.2",
|
||||||
@@ -654,7 +655,9 @@
|
|||||||
|
|
||||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||||
|
|
||||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
||||||
|
|
||||||
|
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||||
|
|
||||||
"exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="],
|
"exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="],
|
||||||
|
|
||||||
@@ -752,6 +755,8 @@
|
|||||||
|
|
||||||
"rollup": ["rollup@4.54.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.54.0", "@rollup/rollup-android-arm64": "4.54.0", "@rollup/rollup-darwin-arm64": "4.54.0", "@rollup/rollup-darwin-x64": "4.54.0", "@rollup/rollup-freebsd-arm64": "4.54.0", "@rollup/rollup-freebsd-x64": "4.54.0", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", "@rollup/rollup-linux-arm-musleabihf": "4.54.0", "@rollup/rollup-linux-arm64-gnu": "4.54.0", "@rollup/rollup-linux-arm64-musl": "4.54.0", "@rollup/rollup-linux-loong64-gnu": "4.54.0", "@rollup/rollup-linux-ppc64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-musl": "4.54.0", "@rollup/rollup-linux-s390x-gnu": "4.54.0", "@rollup/rollup-linux-x64-gnu": "4.54.0", "@rollup/rollup-linux-x64-musl": "4.54.0", "@rollup/rollup-openharmony-arm64": "4.54.0", "@rollup/rollup-win32-arm64-msvc": "4.54.0", "@rollup/rollup-win32-ia32-msvc": "4.54.0", "@rollup/rollup-win32-x64-gnu": "4.54.0", "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw=="],
|
"rollup": ["rollup@4.54.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.54.0", "@rollup/rollup-android-arm64": "4.54.0", "@rollup/rollup-darwin-arm64": "4.54.0", "@rollup/rollup-darwin-x64": "4.54.0", "@rollup/rollup-freebsd-arm64": "4.54.0", "@rollup/rollup-freebsd-x64": "4.54.0", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", "@rollup/rollup-linux-arm-musleabihf": "4.54.0", "@rollup/rollup-linux-arm64-gnu": "4.54.0", "@rollup/rollup-linux-arm64-musl": "4.54.0", "@rollup/rollup-linux-loong64-gnu": "4.54.0", "@rollup/rollup-linux-ppc64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-musl": "4.54.0", "@rollup/rollup-linux-s390x-gnu": "4.54.0", "@rollup/rollup-linux-x64-gnu": "4.54.0", "@rollup/rollup-linux-x64-musl": "4.54.0", "@rollup/rollup-openharmony-arm64": "4.54.0", "@rollup/rollup-win32-arm64-msvc": "4.54.0", "@rollup/rollup-win32-ia32-msvc": "4.54.0", "@rollup/rollup-win32-x64-gnu": "4.54.0", "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw=="],
|
||||||
|
|
||||||
|
"scule": ["scule@1.3.0", "", {}, "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="],
|
||||||
|
|
||||||
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
|
"sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
|
||||||
@@ -766,6 +771,8 @@
|
|||||||
|
|
||||||
"stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="],
|
"stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="],
|
||||||
|
|
||||||
|
"strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="],
|
||||||
|
|
||||||
"strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
"strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
|
||||||
|
|
||||||
"superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="],
|
"superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="],
|
||||||
@@ -796,10 +803,14 @@
|
|||||||
|
|
||||||
"unhead": ["unhead@2.1.1", "", { "dependencies": { "hookable": "^5.5.3" } }, "sha512-NOt8n2KybAOxSLfNXegAVai4SGU8bPKqWnqCzNAvnRH2i8mW+0bbFjN/L75LBgCSTiOjJSpANe5w2V34Grr7Cw=="],
|
"unhead": ["unhead@2.1.1", "", { "dependencies": { "hookable": "^5.5.3" } }, "sha512-NOt8n2KybAOxSLfNXegAVai4SGU8bPKqWnqCzNAvnRH2i8mW+0bbFjN/L75LBgCSTiOjJSpANe5w2V34Grr7Cw=="],
|
||||||
|
|
||||||
|
"unimport": ["unimport@5.6.0", "", { "dependencies": { "acorn": "^8.15.0", "escape-string-regexp": "^5.0.0", "estree-walker": "^3.0.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.21", "mlly": "^1.8.0", "pathe": "^2.0.3", "picomatch": "^4.0.3", "pkg-types": "^2.3.0", "scule": "^1.3.0", "strip-literal": "^3.1.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.11", "unplugin-utils": "^0.3.1" } }, "sha512-8rqAmtJV8o60x46kBAJKtHpJDJWkA2xcBqWKPI14MgUb05o1pnpnCnXSxedUXyeq7p8fR5g3pTo2BaswZ9lD9A=="],
|
||||||
|
|
||||||
"unocss": ["unocss@66.5.12", "", { "dependencies": { "@unocss/astro": "66.5.12", "@unocss/cli": "66.5.12", "@unocss/core": "66.5.12", "@unocss/postcss": "66.5.12", "@unocss/preset-attributify": "66.5.12", "@unocss/preset-icons": "66.5.12", "@unocss/preset-mini": "66.5.12", "@unocss/preset-tagify": "66.5.12", "@unocss/preset-typography": "66.5.12", "@unocss/preset-uno": "66.5.12", "@unocss/preset-web-fonts": "66.5.12", "@unocss/preset-wind": "66.5.12", "@unocss/preset-wind3": "66.5.12", "@unocss/preset-wind4": "66.5.12", "@unocss/transformer-attributify-jsx": "66.5.12", "@unocss/transformer-compile-class": "66.5.12", "@unocss/transformer-directives": "66.5.12", "@unocss/transformer-variant-group": "66.5.12", "@unocss/vite": "66.5.12" }, "peerDependencies": { "@unocss/webpack": "66.5.12", "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" }, "optionalPeers": ["@unocss/webpack", "vite"] }, "sha512-3WdSuM+SOjVpXDtffTuSvYTMuufpFzBehu2b4Tr7DcoIUxGouZn3mdxCLx3PiEuK0ih40Fo7Sjm+J4mccHfwLg=="],
|
"unocss": ["unocss@66.5.12", "", { "dependencies": { "@unocss/astro": "66.5.12", "@unocss/cli": "66.5.12", "@unocss/core": "66.5.12", "@unocss/postcss": "66.5.12", "@unocss/preset-attributify": "66.5.12", "@unocss/preset-icons": "66.5.12", "@unocss/preset-mini": "66.5.12", "@unocss/preset-tagify": "66.5.12", "@unocss/preset-typography": "66.5.12", "@unocss/preset-uno": "66.5.12", "@unocss/preset-web-fonts": "66.5.12", "@unocss/preset-wind": "66.5.12", "@unocss/preset-wind3": "66.5.12", "@unocss/preset-wind4": "66.5.12", "@unocss/transformer-attributify-jsx": "66.5.12", "@unocss/transformer-compile-class": "66.5.12", "@unocss/transformer-directives": "66.5.12", "@unocss/transformer-variant-group": "66.5.12", "@unocss/vite": "66.5.12" }, "peerDependencies": { "@unocss/webpack": "66.5.12", "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0-0" }, "optionalPeers": ["@unocss/webpack", "vite"] }, "sha512-3WdSuM+SOjVpXDtffTuSvYTMuufpFzBehu2b4Tr7DcoIUxGouZn3mdxCLx3PiEuK0ih40Fo7Sjm+J4mccHfwLg=="],
|
||||||
|
|
||||||
"unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="],
|
"unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="],
|
||||||
|
|
||||||
|
"unplugin-auto-import": ["unplugin-auto-import@20.3.0", "", { "dependencies": { "local-pkg": "^1.1.2", "magic-string": "^0.30.21", "picomatch": "^4.0.3", "unimport": "^5.5.0", "unplugin": "^2.3.11", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "@nuxt/kit": "^4.0.0", "@vueuse/core": "*" }, "optionalPeers": ["@nuxt/kit", "@vueuse/core"] }, "sha512-RcSEQiVv7g0mLMMXibYVKk8mpteKxvyffGuDKqZZiFr7Oq3PB1HwgHdK5O7H4AzbhzHoVKG0NnMnsk/1HIVYzQ=="],
|
||||||
|
|
||||||
"unplugin-utils": ["unplugin-utils@0.3.1", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog=="],
|
"unplugin-utils": ["unplugin-utils@0.3.1", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog=="],
|
||||||
|
|
||||||
"unplugin-vue-components": ["unplugin-vue-components@30.0.0", "", { "dependencies": { "chokidar": "^4.0.3", "debug": "^4.4.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.19", "mlly": "^1.8.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.10", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "@babel/parser": "^7.15.8", "@nuxt/kit": "^3.2.2 || ^4.0.0", "vue": "2 || 3" }, "optionalPeers": ["@babel/parser", "@nuxt/kit"] }, "sha512-4qVE/lwCgmdPTp6h0qsRN2u642tt4boBQtcpn4wQcWZAsr8TQwq+SPT3NDu/6kBFxzo/sSEK4ioXhOOBrXc3iw=="],
|
"unplugin-vue-components": ["unplugin-vue-components@30.0.0", "", { "dependencies": { "chokidar": "^4.0.3", "debug": "^4.4.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.19", "mlly": "^1.8.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.10", "unplugin-utils": "^0.3.1" }, "peerDependencies": { "@babel/parser": "^7.15.8", "@nuxt/kit": "^3.2.2 || ^4.0.0", "vue": "2 || 3" }, "optionalPeers": ["@babel/parser", "@nuxt/kit"] }, "sha512-4qVE/lwCgmdPTp6h0qsRN2u642tt4boBQtcpn4wQcWZAsr8TQwq+SPT3NDu/6kBFxzo/sSEK4ioXhOOBrXc3iw=="],
|
||||||
@@ -856,6 +867,10 @@
|
|||||||
|
|
||||||
"@vitejs/plugin-vue-jsx/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5", "", {}, "sha512-8sExkWRK+zVybw3+2/kBkYBFeLnEUWz1fT7BLHplpzmtqkOfTbAQ9gkt4pzwGIIZmg4Qn5US5ACjUBenrhezwQ=="],
|
"@vitejs/plugin-vue-jsx/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5", "", {}, "sha512-8sExkWRK+zVybw3+2/kBkYBFeLnEUWz1fT7BLHplpzmtqkOfTbAQ9gkt4pzwGIIZmg4Qn5US5ACjUBenrhezwQ=="],
|
||||||
|
|
||||||
|
"@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
|
"@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
"@vue/devtools-kit/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
"@vue/devtools-kit/perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
||||||
|
|
||||||
"miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="],
|
"miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="],
|
||||||
@@ -866,10 +881,14 @@
|
|||||||
|
|
||||||
"sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||||
|
|
||||||
|
"strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
|
||||||
|
|
||||||
"unconfig/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
|
"unconfig/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
|
||||||
|
|
||||||
"unconfig-core/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
|
"unconfig-core/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
|
||||||
|
|
||||||
|
"unimport/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
"unplugin/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
"unplugin/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
"vue-router/@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="],
|
"vue-router/@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="],
|
||||||
|
|||||||
58
components.d.ts
vendored
Normal file
58
components.d.ts
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
// oxlint-disable
|
||||||
|
// ------
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
import { GlobalComponents } from 'vue'
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
Add: typeof import('./src/components/icons/Add.vue')['default']
|
||||||
|
AddFilled: typeof import('./src/components/icons/AddFilled.vue')['default']
|
||||||
|
Bell: typeof import('./src/components/icons/Bell.vue')['default']
|
||||||
|
BellFilled: typeof import('./src/components/icons/BellFilled.vue')['default']
|
||||||
|
Button: typeof import('primevue/button')['default']
|
||||||
|
Checkbox: typeof import('primevue/checkbox')['default']
|
||||||
|
DashboardLayout: typeof import('./src/components/DashboardLayout.vue')['default']
|
||||||
|
Home: typeof import('./src/components/icons/Home.vue')['default']
|
||||||
|
HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default']
|
||||||
|
InputText: typeof import('primevue/inputtext')['default']
|
||||||
|
Layout: typeof import('./src/components/icons/Layout.vue')['default']
|
||||||
|
LayoutFilled: typeof import('./src/components/icons/LayoutFilled.vue')['default']
|
||||||
|
Message: typeof import('primevue/message')['default']
|
||||||
|
Password: typeof import('primevue/password')['default']
|
||||||
|
RootLayout: typeof import('./src/components/RootLayout.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
TestIcon: typeof import('./src/components/icons/TestIcon.vue')['default']
|
||||||
|
VueHead: typeof import('./src/components/VueHead.tsx')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For TSX support
|
||||||
|
declare global {
|
||||||
|
const Add: typeof import('./src/components/icons/Add.vue')['default']
|
||||||
|
const AddFilled: typeof import('./src/components/icons/AddFilled.vue')['default']
|
||||||
|
const Bell: typeof import('./src/components/icons/Bell.vue')['default']
|
||||||
|
const BellFilled: typeof import('./src/components/icons/BellFilled.vue')['default']
|
||||||
|
const Button: typeof import('primevue/button')['default']
|
||||||
|
const Checkbox: typeof import('primevue/checkbox')['default']
|
||||||
|
const DashboardLayout: typeof import('./src/components/DashboardLayout.vue')['default']
|
||||||
|
const Home: typeof import('./src/components/icons/Home.vue')['default']
|
||||||
|
const HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default']
|
||||||
|
const InputText: typeof import('primevue/inputtext')['default']
|
||||||
|
const Layout: typeof import('./src/components/icons/Layout.vue')['default']
|
||||||
|
const LayoutFilled: typeof import('./src/components/icons/LayoutFilled.vue')['default']
|
||||||
|
const Message: typeof import('primevue/message')['default']
|
||||||
|
const Password: typeof import('primevue/password')['default']
|
||||||
|
const RootLayout: typeof import('./src/components/RootLayout.vue')['default']
|
||||||
|
const RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
const RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
const TestIcon: typeof import('./src/components/icons/TestIcon.vue')['default']
|
||||||
|
const VueHead: typeof import('./src/components/VueHead.tsx')['default']
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
"@vitejs/plugin-vue": "^6.0.3",
|
"@vitejs/plugin-vue": "^6.0.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.3",
|
"@vitejs/plugin-vue-jsx": "^5.1.3",
|
||||||
"unocss": "^66.5.12",
|
"unocss": "^66.5.12",
|
||||||
|
"unplugin-auto-import": "^20.3.0",
|
||||||
"unplugin-vue-components": "^30.0.0",
|
"unplugin-vue-components": "^30.0.0",
|
||||||
"vite": "^7.3.0",
|
"vite": "^7.3.0",
|
||||||
"vite-ssr-components": "^0.5.2",
|
"vite-ssr-components": "^0.5.2",
|
||||||
|
|||||||
57
src/api/httpClientAdapter.client.ts
Normal file
57
src/api/httpClientAdapter.client.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { TinyRpcClientAdapter, TinyRpcError } from "@hiogawa/tiny-rpc";
|
||||||
|
import { Result } from "@hiogawa/utils";
|
||||||
|
|
||||||
|
const GET_PAYLOAD_PARAM = "payload";
|
||||||
|
|
||||||
|
export function httpClientAdapter(opts: {
|
||||||
|
url: string;
|
||||||
|
pathsForGET?: string[];
|
||||||
|
}): TinyRpcClientAdapter {
|
||||||
|
return {
|
||||||
|
send: async (data) => {
|
||||||
|
const url = [opts.url, data.path].join("/");
|
||||||
|
const payload = JSON.stringify(data.args);
|
||||||
|
const method = opts.pathsForGET?.includes(data.path)
|
||||||
|
? "GET"
|
||||||
|
: "POST";
|
||||||
|
let req: Request;
|
||||||
|
if (method === "GET") {
|
||||||
|
req = new Request(
|
||||||
|
url +
|
||||||
|
"?" +
|
||||||
|
new URLSearchParams({ [GET_PAYLOAD_PARAM]: payload })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
req = new Request(url, {
|
||||||
|
method: "POST",
|
||||||
|
body: payload,
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let res: Response;
|
||||||
|
res = await fetch(req);
|
||||||
|
if (!res.ok) {
|
||||||
|
// throw new Error(`HTTP error: ${res.status}`);
|
||||||
|
throw new Error(
|
||||||
|
JSON.stringify({
|
||||||
|
status: res.status,
|
||||||
|
statusText: res.statusText,
|
||||||
|
data: { message: await res.text() },
|
||||||
|
internal: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// throw TinyRpcError.deserialize(res.status);
|
||||||
|
}
|
||||||
|
const result: Result<unknown, unknown> = JSON.parse(
|
||||||
|
await res.text()
|
||||||
|
);
|
||||||
|
if (!result.ok) {
|
||||||
|
throw TinyRpcError.deserialize(result.value);
|
||||||
|
}
|
||||||
|
return result.value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
69
src/api/httpClientAdapter.server.ts
Normal file
69
src/api/httpClientAdapter.server.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { TinyRpcClientAdapter, TinyRpcError } from "@hiogawa/tiny-rpc";
|
||||||
|
import { Result } from "@hiogawa/utils";
|
||||||
|
import { tryGetContext } from "hono/context-storage";
|
||||||
|
|
||||||
|
const GET_PAYLOAD_PARAM = "payload";
|
||||||
|
|
||||||
|
export function httpClientAdapter(opts: {
|
||||||
|
url: string;
|
||||||
|
pathsForGET?: string[];
|
||||||
|
}): TinyRpcClientAdapter {
|
||||||
|
return {
|
||||||
|
send: async (data) => {
|
||||||
|
const url = [opts.url, data.path].join("/");
|
||||||
|
const payload = JSON.stringify(data.args);
|
||||||
|
const method = opts.pathsForGET?.includes(data.path)
|
||||||
|
? "GET"
|
||||||
|
: "POST";
|
||||||
|
let req: Request;
|
||||||
|
if (method === "GET") {
|
||||||
|
req = new Request(
|
||||||
|
url +
|
||||||
|
"?" +
|
||||||
|
new URLSearchParams({ [GET_PAYLOAD_PARAM]: payload })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
req = new Request(url, {
|
||||||
|
method: "POST",
|
||||||
|
body: payload,
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let res: Response;
|
||||||
|
if (import.meta.env.SSR) {
|
||||||
|
const c = tryGetContext<any>();
|
||||||
|
if (!c) {
|
||||||
|
throw new Error("Hono context not found in SSR");
|
||||||
|
}
|
||||||
|
Object.entries(c.req.header()).forEach(([k, v]) => {
|
||||||
|
req.headers.append(k, v);
|
||||||
|
});
|
||||||
|
res = await c.get("fetch")(req);
|
||||||
|
} else {
|
||||||
|
res = await fetch(req);
|
||||||
|
}
|
||||||
|
if (!res.ok) {
|
||||||
|
// throw new Error(`HTTP error: ${res.status}`);
|
||||||
|
throw new Error(
|
||||||
|
JSON.stringify({
|
||||||
|
status: res.status,
|
||||||
|
statusText: res.statusText,
|
||||||
|
data: { message: await res.text() },
|
||||||
|
internal: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// throw TinyRpcError.deserialize(res.status);
|
||||||
|
}
|
||||||
|
const result: Result<unknown, unknown> = JSON.parse(
|
||||||
|
await res.text()
|
||||||
|
);
|
||||||
|
if (!result.ok) {
|
||||||
|
throw TinyRpcError.deserialize(result.value);
|
||||||
|
}
|
||||||
|
return result.value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -164,13 +164,14 @@ const login = async (username: string, password: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function checkAuth() {
|
async function checkAuth() {
|
||||||
|
console.log("Check auth called");
|
||||||
const context = getContext<HonoVarTypes>();
|
const context = getContext<HonoVarTypes>();
|
||||||
const token = getCookie(context, 'auth_token');
|
const token = getCookie(context, 'auth_token');
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return { authenticated: false, user: null };
|
return { authenticated: false, user: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const payload = await verify(token, JWT_SECRET) as any;
|
const payload = await verify(token, JWT_SECRET) as any;
|
||||||
|
|
||||||
@@ -178,10 +179,11 @@ async function checkAuth() {
|
|||||||
const userRecord = Array.from(mockUsers.values()).find(
|
const userRecord = Array.from(mockUsers.values()).find(
|
||||||
record => record.user.id === payload.sub
|
record => record.user.id === payload.sub
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!userRecord) {
|
if (!userRecord) {
|
||||||
return { authenticated: false, user: null };
|
return { authenticated: false, user: null };
|
||||||
}
|
}
|
||||||
|
// console.log("Check auth called 2", userRecord);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
authenticated: true,
|
authenticated: true,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
} from "@hiogawa/tiny-rpc";
|
} from "@hiogawa/tiny-rpc";
|
||||||
import type { RpcRoutes } from "./rpc";
|
import type { RpcRoutes } from "./rpc";
|
||||||
import { Result } from "@hiogawa/utils";
|
import { Result } from "@hiogawa/utils";
|
||||||
|
import {httpClientAdapter} from "@httpClientAdapter";
|
||||||
|
// console.log("httpClientAdapter module:", httpClientAdapter.toString());
|
||||||
declare let __host__: string;
|
declare let __host__: string;
|
||||||
const endpoint = "/rpc";
|
const endpoint = "/rpc";
|
||||||
const url = import.meta.env.SSR ? "http://localhost" : "";
|
const url = import.meta.env.SSR ? "http://localhost" : "";
|
||||||
@@ -15,65 +17,3 @@ export const client = proxyTinyRpc<RpcRoutes>({
|
|||||||
pathsForGET: [],
|
pathsForGET: [],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const GET_PAYLOAD_PARAM = "payload";
|
|
||||||
function httpClientAdapter(opts: {
|
|
||||||
url: string;
|
|
||||||
pathsForGET?: string[];
|
|
||||||
}): TinyRpcClientAdapter {
|
|
||||||
return {
|
|
||||||
send: async (data) => {
|
|
||||||
const url = [opts.url, data.path].join("/");
|
|
||||||
const payload = JSON.stringify(data.args);
|
|
||||||
const method = opts.pathsForGET?.includes(data.path)
|
|
||||||
? "GET"
|
|
||||||
: "POST";
|
|
||||||
let req: Request;
|
|
||||||
if (method === "GET") {
|
|
||||||
req = new Request(
|
|
||||||
url +
|
|
||||||
"?" +
|
|
||||||
new URLSearchParams({ [GET_PAYLOAD_PARAM]: payload })
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
req = new Request(url, {
|
|
||||||
method: "POST",
|
|
||||||
body: payload,
|
|
||||||
headers: {
|
|
||||||
"content-type": "application/json; charset=utf-8",
|
|
||||||
},
|
|
||||||
credentials: "include",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let res: Response;
|
|
||||||
if (import.meta.env.SSR) {
|
|
||||||
const { getContext } = await import("hono/context-storage");
|
|
||||||
const c = getContext<any>();
|
|
||||||
Object.entries(c.req.header()).forEach(([k, v]) => {
|
|
||||||
req.headers.append(k, v);
|
|
||||||
});
|
|
||||||
res = await c.get("fetch")(req);
|
|
||||||
} else {
|
|
||||||
res = await fetch(req);
|
|
||||||
}
|
|
||||||
if (!res.ok) {
|
|
||||||
// throw new Error(`HTTP error: ${res.status}`);
|
|
||||||
throw new Error(
|
|
||||||
JSON.stringify({
|
|
||||||
status: res.status,
|
|
||||||
statusText: res.statusText,
|
|
||||||
data: { message: await res.text() },
|
|
||||||
internal: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// throw TinyRpcError.deserialize(res.status);
|
|
||||||
}
|
|
||||||
const result: Result<unknown, unknown> = JSON.parse(
|
|
||||||
await res.text()
|
|
||||||
);
|
|
||||||
if (!result.ok) {
|
|
||||||
throw TinyRpcError.deserialize(result.value);
|
|
||||||
}
|
|
||||||
return result.value;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
15
src/components/VueHead.tsx
Normal file
15
src/components/VueHead.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { useHead, UseHeadInput, UseHeadOptions } from "@unhead/vue";
|
||||||
|
import { defineComponent, toRef } from "vue";
|
||||||
|
interface VueHeadProps {
|
||||||
|
input: UseHeadInput;
|
||||||
|
options?: UseHeadOptions;
|
||||||
|
}
|
||||||
|
export const VueHead = defineComponent<VueHeadProps>({
|
||||||
|
name: "VueHead",
|
||||||
|
props: ["input", "options"],
|
||||||
|
setup(props) {
|
||||||
|
useHead(toRef(props, "input") as any, props.options);
|
||||||
|
return () => null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
export default VueHead;
|
||||||
@@ -8,11 +8,12 @@ import { contextStorage } from 'hono/context-storage';
|
|||||||
import { cors } from "hono/cors";
|
import { cors } from "hono/cors";
|
||||||
import { jwtRpc, rpcServer } from './api/rpc';
|
import { jwtRpc, rpcServer } from './api/rpc';
|
||||||
import isMobile from 'is-mobile';
|
import isMobile from 'is-mobile';
|
||||||
|
import { useAuthStore } from './stores/auth';
|
||||||
|
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
|
|
||||||
// app.use(renderer)
|
// app.use(renderer)
|
||||||
|
app.use('*', contextStorage());
|
||||||
app.use(cors(), async (c, next) => {
|
app.use(cors(), async (c, next) => {
|
||||||
c.set("fetch", app.request.bind(app));
|
c.set("fetch", app.request.bind(app));
|
||||||
const ua = c.req.header("User-Agent")
|
const ua = c.req.header("User-Agent")
|
||||||
@@ -21,15 +22,20 @@ app.use(cors(), async (c, next) => {
|
|||||||
};
|
};
|
||||||
c.set("isMobile", isMobile({ ua }));
|
c.set("isMobile", isMobile({ ua }));
|
||||||
await next();
|
await next();
|
||||||
}, contextStorage(), rpcServer);
|
}, rpcServer);
|
||||||
app.get("/.well-known/*", (c) => {
|
app.get("/.well-known/*", (c) => {
|
||||||
return c.json({ ok: true });
|
return c.json({ ok: true });
|
||||||
});
|
});
|
||||||
app.get("*", async (c) => {
|
app.get("*", async (c) => {
|
||||||
const url = new URL(c.req.url);
|
const url = new URL(c.req.url);
|
||||||
const { app, router, head } = createApp();
|
const { app, router, head, pinia } = createApp();
|
||||||
router.push(url.pathname);
|
app.provide("honoContext", c);
|
||||||
await router.isReady();
|
await router.push(url.pathname);
|
||||||
|
await router.isReady().then(() => {
|
||||||
|
const auth = useAuthStore();
|
||||||
|
auth.initialized = false;
|
||||||
|
auth.init();
|
||||||
|
});
|
||||||
return streamText(c, async (stream) => {
|
return streamText(c, async (stream) => {
|
||||||
c.header("Content-Type", "text/html; charset=utf-8");
|
c.header("Content-Type", "text/html; charset=utf-8");
|
||||||
c.header("Content-Encoding", "Identity");
|
c.header("Content-Encoding", "Identity");
|
||||||
@@ -43,8 +49,8 @@ app.get("*", async (c) => {
|
|||||||
await stream.write(buildBootstrapScript());
|
await stream.write(buildBootstrapScript());
|
||||||
await stream.write("</head><body class='font-sans bg-[#f9fafd] text-gray-800 antialiased flex flex-col min-h-screen'>");
|
await stream.write("</head><body class='font-sans bg-[#f9fafd] text-gray-800 antialiased flex flex-col min-h-screen'>");
|
||||||
await stream.pipe(appStream);
|
await stream.pipe(appStream);
|
||||||
let json = htmlEscape(JSON.stringify(JSON.stringify(ctx)));
|
await stream.write(`<script>window.__SSR_STATE__ = JSON.parse(${htmlEscape(JSON.stringify(JSON.stringify(ctx)))});</script>`);
|
||||||
await stream.write(`<script>window.__SSR_STATE__ = JSON.parse(${json});</script>`);
|
await stream.write(`<script>window.__PINIA_STATE__ = JSON.parse(${htmlEscape(JSON.stringify(JSON.stringify(pinia.state.value)))});</script>`);
|
||||||
await stream.write("</body></html>");
|
await stream.write("</body></html>");
|
||||||
});
|
});
|
||||||
// return c.body(renderToWebStream(app, {}));
|
// return c.body(renderToWebStream(app, {}));
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ export function withErrorBoundary(WrappedComponent: any) {
|
|||||||
<div class="p-8 space-y-lg max-w-lg w-full">
|
<div class="p-8 space-y-lg max-w-lg w-full">
|
||||||
<p>
|
<p>
|
||||||
<b>500. </b>
|
<b>500. </b>
|
||||||
<ins class="text-gray-500 decoration-none">Đã xảy ra lỗi.</ins>
|
<ins class="text-gray-500 decoration-none">Something went wrong.</ins>
|
||||||
</p>
|
</p>
|
||||||
<div class="font-thin">
|
<div class="font-thin">
|
||||||
<p>Máy chủ đang gặp sự cố tạm thời và không thể xử lý yêu cầu của bạn. Vui lòng <a class="underline text-primary" href="/">thử lại</a> sau vài phút.</p>
|
<p>The server is currently experiencing temporary issues and cannot process your request. Please <a class="underline text-primary" href="/">try again</a> in a few minutes.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,18 +10,21 @@ import Aura from '@primeuix/themes/aura';
|
|||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import { useAuthStore } from './stores/auth';
|
import { useAuthStore } from './stores/auth';
|
||||||
|
|
||||||
const pinia = createPinia();
|
|
||||||
|
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
|
const pinia = createPinia();
|
||||||
const app = createSSRApp(withErrorBoundary(RouterView));
|
const app = createSSRApp(withErrorBoundary(RouterView));
|
||||||
const head = import.meta.env.SSR ? SSRHead() : CSRHead();
|
const head = import.meta.env.SSR ? SSRHead() : CSRHead();
|
||||||
|
|
||||||
app.use(head);
|
app.use(head);
|
||||||
app.use(PrimeVue, {
|
app.use(PrimeVue, {
|
||||||
|
// unstyled: true,
|
||||||
theme: {
|
theme: {
|
||||||
preset: Aura,
|
preset: Aura,
|
||||||
options: {
|
options: {
|
||||||
darkModeSelector: '.my-app-dark',
|
darkModeSelector: '.my-app-dark',
|
||||||
|
cssLayer: false,
|
||||||
|
prefix: 'pv-',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -42,5 +45,5 @@ export function createApp() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { app, router, head };
|
return { app, router, head, pinia };
|
||||||
}
|
}
|
||||||
12
src/routes/NotFound.vue
Normal file
12
src/routes/NotFound.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<vue-head :input="{title: '404 - Page Not Found'}"/>
|
||||||
|
<div class="mx-auto text-center mt-20 flex flex-col items-center gap-4">
|
||||||
|
<h1>404 - Page Not Found</h1>
|
||||||
|
<p>The page you are looking for does not exist.</p>
|
||||||
|
<router-link class="btn btn-primary" to="/">Go back to Home</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { VueHead } from "@/components/VueHead";
|
||||||
|
</script>
|
||||||
@@ -75,6 +75,11 @@ const routes: RouteData[] = [
|
|||||||
component: () => import("./add/Add.vue"),
|
component: () => import("./add/Add.vue"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/:pathMatch(.*)*",
|
||||||
|
name: "not-found",
|
||||||
|
component: () => import("./NotFound.vue"),
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -88,6 +93,7 @@ const router = createRouter({
|
|||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
|
console.log("Call on server:", Math.random());
|
||||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||||
if (!auth.user) {
|
if (!auth.user) {
|
||||||
next({ name: "login" });
|
next({ name: "login" });
|
||||||
|
|||||||
@@ -20,10 +20,15 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
|
|
||||||
// Check auth status on init (reads from cookie)
|
// Check auth status on init (reads from cookie)
|
||||||
async function init() {
|
async function init() {
|
||||||
if (initialized.value) return;
|
console.log("Auth store init called");
|
||||||
|
// if (initialized.value) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.checkAuth();
|
const response = await client.checkAuth().then((res) => {
|
||||||
|
|
||||||
|
console.log("call", res);
|
||||||
|
return res;
|
||||||
|
});
|
||||||
if (response.authenticated && response.user) {
|
if (response.authenticated && response.user) {
|
||||||
user.value = response.user;
|
user.value = response.user;
|
||||||
// Get CSRF token if authenticated
|
// Get CSRF token if authenticated
|
||||||
|
|||||||
10
src/type.d.ts
vendored
Normal file
10
src/type.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="unplugin-vue-components/types/vue" />
|
||||||
|
|
||||||
|
declare module "@httpClientAdapter" {
|
||||||
|
import { TinyRpcClientAdapter } from "@hiogawa/tiny-rpc";
|
||||||
|
export function httpClientAdapter(opts: {
|
||||||
|
url: string;
|
||||||
|
pathsForGET?: string[];
|
||||||
|
}): TinyRpcClientAdapter;
|
||||||
|
}
|
||||||
11
ssrPlugin.ts
11
ssrPlugin.ts
@@ -32,6 +32,7 @@ export function clientFirstBuild(): Plugin {
|
|||||||
// Client build first
|
// Client build first
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (clientEnvironment) {
|
if (clientEnvironment) {
|
||||||
|
// console.log("Client First Build Plugin: Building client...", clientEnvironment.resolve);
|
||||||
await builder.build(clientEnvironment);
|
await builder.build(clientEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +108,16 @@ export default function ssrPlugin(): Plugin[] {
|
|||||||
config(config) {
|
config(config) {
|
||||||
config.define = config.define || {};
|
config.define = config.define || {};
|
||||||
},
|
},
|
||||||
|
resolveId(id, importer, options) {
|
||||||
|
if (!id.startsWith('@httpClientAdapter')) return
|
||||||
|
|
||||||
|
return path.resolve(
|
||||||
|
__dirname,
|
||||||
|
options?.ssr
|
||||||
|
? "./src/api/httpClientAdapter.server.ts"
|
||||||
|
: "./src/api/httpClientAdapter.client.ts"
|
||||||
|
);
|
||||||
|
},
|
||||||
async configResolved(config) {
|
async configResolved(config) {
|
||||||
const viteConfig = config as any;
|
const viteConfig = config as any;
|
||||||
|
|
||||||
|
|||||||
@@ -16,4 +16,11 @@
|
|||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue",
|
||||||
|
"auto-imports.d.ts",
|
||||||
|
"components.d.ts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,47 @@
|
|||||||
import { cloudflare } from "@cloudflare/vite-plugin";
|
import { cloudflare } from "@cloudflare/vite-plugin";
|
||||||
import { defineConfig, Manifest, Plugin } from "vite";
|
import { PrimeVueResolver } from "@primevue/auto-import-resolver";
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from "@vitejs/plugin-vue";
|
||||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||||
import unocss from "unocss/vite";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import unocss from "unocss/vite";
|
||||||
|
import Components from "unplugin-vue-components/vite";
|
||||||
|
import AutoImport from "unplugin-auto-import/vite";
|
||||||
|
import { defineConfig } from "vite";
|
||||||
import ssrPlugin from "./ssrPlugin";
|
import ssrPlugin from "./ssrPlugin";
|
||||||
import Components from 'unplugin-vue-components/vite';
|
|
||||||
import {PrimeVueResolver} from '@primevue/auto-import-resolver';
|
|
||||||
export default defineConfig((env) => {
|
export default defineConfig((env) => {
|
||||||
|
// console.log("env:", env, import.meta.env);
|
||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [
|
||||||
unocss(),
|
unocss(),
|
||||||
vue(),
|
vue(),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
|
AutoImport({
|
||||||
|
imports: ["vue", "vue-router", "pinia"], // Common presets
|
||||||
|
dts: true, // Generate TypeScript declaration file
|
||||||
|
}),
|
||||||
|
Components({
|
||||||
|
dirs: ["src/components"],
|
||||||
|
extensions: ["vue", "tsx"],
|
||||||
|
dts: true,
|
||||||
|
dtsTsx: true,
|
||||||
|
directives: false,
|
||||||
|
resolvers: [PrimeVueResolver()],
|
||||||
|
}),
|
||||||
ssrPlugin(),
|
ssrPlugin(),
|
||||||
cloudflare(),
|
cloudflare(),
|
||||||
Components({
|
|
||||||
resolvers: [
|
|
||||||
PrimeVueResolver()
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
// "httpClientAdapter": path.resolve(__dirname, "./src/api/httpClientAdapter.server.ts")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
exclude: ["vue"],
|
||||||
|
},
|
||||||
|
|
||||||
|
ssr: {
|
||||||
|
noExternal: ["vue"],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user