create-nexwire 4.2.3 → 4.2.4
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/express/package.json +48 -23
- package/express/src/database/migrations/sqlite/0000_init.sql +47 -60
- package/express/src/database/migrations/sqlite/meta/0000_snapshot.json +1 -89
- package/express/src/database/migrations/sqlite/meta/_journal.json +1 -1
- package/express/src/database/schema.ts +2 -3
- package/express/src/framework/facade.ts +12 -1
- package/express/src/framework/maker-cli/db/core.mjs +291 -288
- package/express/src/framework/maker-cli/module/core.mjs +125 -87
- package/express/src/framework/maker-cli/module/index.mjs +3 -3
- package/express/src/framework/maker-cli/stubs/notification/controller.ts.stub +61 -62
- package/express/src/framework/maker-cli/stubs/notification/job.ts.stub +11 -13
- package/express/src/framework/maker-cli/stubs/notification/model.ts.stub +29 -0
- package/express/src/framework/maker-cli/stubs/notification/provider.ts.stub +174 -0
- package/express/src/framework/maker-cli/stubs/notification/route.api.ts.stub +11 -10
- package/express/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +1 -1
- package/express/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +25 -25
- package/express/src/framework/maker-cli/stubs/notification/schema.ts.stub +25 -25
- package/express/src/framework/notification/index.ts +49 -87
- package/express/src/framework/providers/adapter.ts +24 -10
- package/express/src/framework/providers/contracts.ts +80 -10
- package/express/src/framework/providers/registry.ts +27 -1
- package/express/src/resources/src/main.ts +1 -1
- package/express/src/resources/src/pages/auth/forgetPassword.vue +1 -1
- package/express/src/resources/src/pages/auth/login.vue +1 -1
- package/express/src/resources/src/pages/auth/register.vue +1 -1
- package/express/src/resources/src/pages/auth/resetPassword.vue +1 -1
- package/express/src/resources/src/pages/auth/verifyEmail.vue +1 -1
- package/express/src/resources/src/pages/dashboard/index.vue +66 -66
- package/express/src/storage/database/nexwire.sqlite +0 -0
- package/hono/package.json +44 -19
- package/hono/src/database/migrations/sqlite/0000_init.sql +47 -60
- package/hono/src/database/migrations/sqlite/meta/0000_snapshot.json +1 -89
- package/hono/src/database/migrations/sqlite/meta/_journal.json +1 -1
- package/hono/src/database/schema.ts +2 -3
- package/hono/src/framework/facade.ts +12 -1
- package/hono/src/framework/maker-cli/db/core.mjs +291 -288
- package/hono/src/framework/maker-cli/module/core.mjs +93 -52
- package/hono/src/framework/maker-cli/module/index.mjs +3 -3
- package/hono/src/framework/maker-cli/stubs/notification/controller.ts.stub +63 -58
- package/hono/src/framework/maker-cli/stubs/notification/job.ts.stub +10 -12
- package/hono/src/framework/maker-cli/stubs/notification/model.ts.stub +29 -0
- package/hono/src/framework/maker-cli/stubs/notification/provider.ts.stub +174 -0
- package/hono/src/framework/maker-cli/stubs/notification/route.api.ts.stub +11 -10
- package/hono/src/framework/maker-cli/stubs/notification/route.plain.ts.stub +1 -1
- package/hono/src/framework/maker-cli/stubs/notification/schema.plain.ts.stub +25 -25
- package/hono/src/framework/maker-cli/stubs/notification/schema.ts.stub +25 -25
- package/hono/src/framework/notification/index.ts +49 -87
- package/hono/src/framework/providers/adapter.ts +24 -10
- package/hono/src/framework/providers/contracts.ts +80 -10
- package/hono/src/framework/providers/registry.ts +27 -1
- package/hono/src/resources/src/main.ts +1 -1
- package/hono/src/resources/src/pages/auth/forgetPassword.vue +1 -1
- package/hono/src/resources/src/pages/auth/login.vue +1 -1
- package/hono/src/resources/src/pages/auth/register.vue +1 -1
- package/hono/src/resources/src/pages/auth/resetPassword.vue +1 -1
- package/hono/src/resources/src/pages/auth/verifyEmail.vue +1 -1
- package/hono/src/resources/src/pages/dashboard/index.vue +66 -66
- package/hono/src/storage/database/nexwire.sqlite +0 -0
- package/package.json +10 -10
- package/express/src/modules/auth/database/models/notification.ts +0 -24
- package/hono/src/modules/auth/database/models/notification.ts +0 -24
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Why: Defines the shapes a pluggable provider has to satisfy.
|
|
3
|
-
* When: A developer replaces a framework default (auth
|
|
3
|
+
* When: A developer replaces a framework default (auth, notifications, payments later).
|
|
4
4
|
* Where: Imported through the framework facade, never from framework internals.
|
|
5
5
|
* How: Interfaces stay deliberately loose so custom user shapes pass through.
|
|
6
6
|
*/
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
/** Registry key of the built-in auth provider contract. */
|
|
9
9
|
export const AUTH_PROVIDER_KEY = "auth";
|
|
10
10
|
|
|
11
|
+
/** Registry key of the built-in notification storage provider. */
|
|
12
|
+
export const NOTIFICATION_PROVIDER_KEY = "notification";
|
|
13
|
+
|
|
11
14
|
/**
|
|
12
15
|
* Registry key for any provider implementation.
|
|
13
16
|
*
|
|
@@ -15,25 +18,25 @@ export const AUTH_PROVIDER_KEY = "auth";
|
|
|
15
18
|
* still accepting any custom key, so a project can register its own contracts
|
|
16
19
|
* (payments, otp, storage, ...) without the framework having to know them.
|
|
17
20
|
*/
|
|
18
|
-
export type ProviderKey = typeof AUTH_PROVIDER_KEY | (string & {});
|
|
21
|
+
export type ProviderKey = typeof AUTH_PROVIDER_KEY | typeof NOTIFICATION_PROVIDER_KEY | (string & {});
|
|
19
22
|
|
|
20
23
|
export interface AuthProviderUser {
|
|
21
|
-
id: number;
|
|
24
|
+
id: number | string;
|
|
22
25
|
email?: string | null;
|
|
23
26
|
[key: string]: any;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export interface AuthProviderRefreshToken {
|
|
27
|
-
id: number;
|
|
30
|
+
id: number | string;
|
|
28
31
|
jti: string;
|
|
29
32
|
revoked?: boolean | null;
|
|
30
33
|
expiresAt?: Date | string | null;
|
|
31
|
-
userId?: number | null;
|
|
34
|
+
userId?: number | string | null;
|
|
32
35
|
[key: string]: any;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
export interface AuthUserContext {
|
|
36
|
-
id: number;
|
|
39
|
+
id: number | string;
|
|
37
40
|
email?: string | null;
|
|
38
41
|
roleId?: number | null;
|
|
39
42
|
role?: string | null;
|
|
@@ -47,10 +50,77 @@ export interface AuthUserContact {
|
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
export interface AuthProvider {
|
|
50
|
-
getUserById(id: number): Promise<AuthProviderUser | null>;
|
|
53
|
+
getUserById(id: number | string): Promise<AuthProviderUser | null>;
|
|
51
54
|
findRefreshToken(jti: string): Promise<AuthProviderRefreshToken | null>;
|
|
52
|
-
revokeRefreshToken?(tokenId: number): Promise<void>;
|
|
53
|
-
deleteRefreshToken?(tokenId: number): Promise<void>;
|
|
55
|
+
revokeRefreshToken?(tokenId: number | string): Promise<void>;
|
|
56
|
+
deleteRefreshToken?(tokenId: number | string): Promise<void>;
|
|
54
57
|
getAuthContext?(user: AuthProviderUser, payload?: any): Promise<AuthUserContext | any>;
|
|
55
|
-
getUserContact?(userId: number): Promise<AuthUserContact | null>;
|
|
58
|
+
getUserContact?(userId: number | string): Promise<AuthUserContact | null>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Who a notification belongs to. `id` accepts a numeric auth id and a string
|
|
63
|
+
* id (UUID, ULID, ...) so replacing auth does not force a notification change.
|
|
64
|
+
* The provider always stores the id as text.
|
|
65
|
+
*/
|
|
66
|
+
export interface NotifiableTarget {
|
|
67
|
+
/** Notifiable class. Defaults to "user". */
|
|
68
|
+
type?: string;
|
|
69
|
+
id: number | string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Payload accepted by `NotificationProvider.create()`. */
|
|
73
|
+
export interface NotificationCreateInput {
|
|
74
|
+
type?: string;
|
|
75
|
+
title: string;
|
|
76
|
+
body?: string | null;
|
|
77
|
+
link?: string | null;
|
|
78
|
+
data?: Record<string, unknown> | null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Normalized notification returned by every provider operation. */
|
|
82
|
+
export interface NotificationRecord {
|
|
83
|
+
id: string;
|
|
84
|
+
notifiableType: string;
|
|
85
|
+
notifiableId: string;
|
|
86
|
+
type: string;
|
|
87
|
+
title: string;
|
|
88
|
+
body: string | null;
|
|
89
|
+
data: Record<string, unknown> | null;
|
|
90
|
+
link: string | null;
|
|
91
|
+
readAt: string | null;
|
|
92
|
+
createdAt: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface NotificationListOptions {
|
|
96
|
+
page?: number;
|
|
97
|
+
perPage?: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface NotificationPage {
|
|
101
|
+
data: NotificationRecord[];
|
|
102
|
+
total: number;
|
|
103
|
+
unread: number;
|
|
104
|
+
page: number;
|
|
105
|
+
perPage: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Why: Keeps notification storage replaceable without touching `notify()` or
|
|
110
|
+
* the generated HTTP routes.
|
|
111
|
+
* When: The default `src/modules/notification` store is replaced by a custom
|
|
112
|
+
* implementation (a different table, another service, ...).
|
|
113
|
+
* Where: Registered through `registerNotificationProvider()`.
|
|
114
|
+
* How: The framework only reads through this contract; mail and realtime
|
|
115
|
+
* delivery stay in the runtime so a storage swap cannot disable them.
|
|
116
|
+
*/
|
|
117
|
+
export interface NotificationProvider {
|
|
118
|
+
create(target: NotifiableTarget, input: NotificationCreateInput): Promise<NotificationRecord>;
|
|
119
|
+
list(target: NotifiableTarget, options?: NotificationListOptions): Promise<NotificationPage>;
|
|
120
|
+
unreadCount(target: NotifiableTarget): Promise<number>;
|
|
121
|
+
markRead(target: NotifiableTarget, id: number | string): Promise<boolean>;
|
|
122
|
+
markAllRead(target: NotifiableTarget): Promise<number>;
|
|
123
|
+
remove(target: NotifiableTarget, id: number | string): Promise<boolean>;
|
|
124
|
+
/** Optional bulk cleanup when a notifiable target is deleted. */
|
|
125
|
+
deleteForTarget?(target: NotifiableTarget): Promise<number>;
|
|
56
126
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AUTH_PROVIDER_KEY,
|
|
3
|
+
type AuthProvider,
|
|
4
|
+
NOTIFICATION_PROVIDER_KEY,
|
|
5
|
+
type NotificationProvider,
|
|
6
|
+
type ProviderKey
|
|
7
|
+
} from "./contracts.js";
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* Why: Holds the app-wide provider implementations in one place.
|
|
@@ -60,3 +66,23 @@ export function hasAuthProvider(): boolean {
|
|
|
60
66
|
export function clearAuthProvider(): void {
|
|
61
67
|
clearProvider(AUTH_PROVIDER_KEY);
|
|
62
68
|
}
|
|
69
|
+
|
|
70
|
+
/** Registers the storage provider `notify()` and `/api/notification/*` use. */
|
|
71
|
+
export function registerNotificationProvider(provider: NotificationProvider): NotificationProvider {
|
|
72
|
+
return registerProvider(NOTIFICATION_PROVIDER_KEY, provider);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Returns the registered notification provider, or null when none was registered. */
|
|
76
|
+
export function getNotificationProvider(): NotificationProvider | null {
|
|
77
|
+
return getProvider<NotificationProvider>(NOTIFICATION_PROVIDER_KEY);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Reports whether a notification provider is registered. */
|
|
81
|
+
export function hasNotificationProvider(): boolean {
|
|
82
|
+
return hasProvider(NOTIFICATION_PROVIDER_KEY);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Removes the registered notification provider. Mainly useful in tests. */
|
|
86
|
+
export function clearNotificationProvider(): void {
|
|
87
|
+
clearProvider(NOTIFICATION_PROVIDER_KEY);
|
|
88
|
+
}
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
</template>
|
|
54
54
|
|
|
55
55
|
<script setup lang="ts">
|
|
56
|
-
import { useHead } from "@
|
|
56
|
+
import { useHead } from "@unhead/vue";
|
|
57
57
|
import { ref } from "vue";
|
|
58
58
|
import { useRoute, useRouter } from "vue-router";
|
|
59
59
|
import Button from "@/components/Button.vue";
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<Pagebar title="Dashboard" />
|
|
3
|
-
|
|
4
|
-
<div class="dashboard-placeholder">
|
|
5
|
-
<div class="row g-2 mb-2">
|
|
6
|
-
<div class="col-12 col-md-4">
|
|
7
|
-
<div class="placeholder-card"></div>
|
|
8
|
-
</div>
|
|
9
|
-
<div class="col-12 col-md-4">
|
|
10
|
-
<div class="placeholder-card"></div>
|
|
11
|
-
</div>
|
|
12
|
-
<div class="col-12 col-md-4">
|
|
13
|
-
<div class="placeholder-card"></div>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<div class="placeholder-panel"></div>
|
|
18
|
-
</div>
|
|
19
|
-
</template>
|
|
20
|
-
|
|
21
|
-
<script setup lang="ts">
|
|
22
|
-
import { useHead } from "@
|
|
23
|
-
import { onMounted, onUnmounted } from "vue";
|
|
24
|
-
import Pagebar from "@/components/Pagebar.vue";
|
|
25
|
-
import { useAuth } from "@/composables/useAuth";
|
|
26
|
-
import { pulse } from "@/plugins/pulse";
|
|
27
|
-
|
|
28
|
-
useHead({ title: "Dashboard" });
|
|
29
|
-
|
|
30
|
-
const { user } = useAuth();
|
|
31
|
-
|
|
32
|
-
onMounted(() => {
|
|
33
|
-
const ch = pulse.channel("user");
|
|
34
|
-
ch.listen("user.changed", () => alert("me"));
|
|
35
|
-
onUnmounted(() => ch.stopListening("user.changed"));
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// const hardRefresh = () => window.location.reload();
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<style scoped>
|
|
42
|
-
.placeholder-card,
|
|
43
|
-
.placeholder-panel {
|
|
44
|
-
border: 1px solid var(--app-border);
|
|
45
|
-
border-radius: 0.3rem;
|
|
46
|
-
background: var(--app-surface);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.placeholder-card {
|
|
50
|
-
min-height: 220px;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.placeholder-panel {
|
|
54
|
-
min-height: 520px;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@media (max-width: 768px) {
|
|
58
|
-
.placeholder-card {
|
|
59
|
-
min-height: 160px;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.placeholder-panel {
|
|
63
|
-
min-height: 360px;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<Pagebar title="Dashboard" />
|
|
3
|
+
|
|
4
|
+
<div class="dashboard-placeholder">
|
|
5
|
+
<div class="row g-2 mb-2">
|
|
6
|
+
<div class="col-12 col-md-4">
|
|
7
|
+
<div class="placeholder-card"></div>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="col-12 col-md-4">
|
|
10
|
+
<div class="placeholder-card"></div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="col-12 col-md-4">
|
|
13
|
+
<div class="placeholder-card"></div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="placeholder-panel"></div>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { useHead } from "@unhead/vue";
|
|
23
|
+
import { onMounted, onUnmounted } from "vue";
|
|
24
|
+
import Pagebar from "@/components/Pagebar.vue";
|
|
25
|
+
import { useAuth } from "@/composables/useAuth";
|
|
26
|
+
import { pulse } from "@/plugins/pulse";
|
|
27
|
+
|
|
28
|
+
useHead({ title: "Dashboard" });
|
|
29
|
+
|
|
30
|
+
const { user } = useAuth();
|
|
31
|
+
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
const ch = pulse.channel("user");
|
|
34
|
+
ch.listen("user.changed", () => alert("me"));
|
|
35
|
+
onUnmounted(() => ch.stopListening("user.changed"));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// const hardRefresh = () => window.location.reload();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
.placeholder-card,
|
|
43
|
+
.placeholder-panel {
|
|
44
|
+
border: 1px solid var(--app-border);
|
|
45
|
+
border-radius: 0.3rem;
|
|
46
|
+
background: var(--app-surface);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.placeholder-card {
|
|
50
|
+
min-height: 220px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.placeholder-panel {
|
|
54
|
+
min-height: 520px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@media (max-width: 768px) {
|
|
58
|
+
.placeholder-card {
|
|
59
|
+
min-height: 160px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.placeholder-panel {
|
|
63
|
+
min-height: 360px;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
Binary file
|
package/hono/package.json
CHANGED
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
"@aws-sdk/s3-request-presigner": "^3.1111.0",
|
|
33
33
|
"@bull-board/api": "^8.6.1",
|
|
34
34
|
"@bull-board/hono": "^8.6.1",
|
|
35
|
-
"@hono/node-server": "^2.1.
|
|
35
|
+
"@hono/node-server": "^2.1.5",
|
|
36
36
|
"@hono/zod-openapi": "~1.5.3",
|
|
37
37
|
"@libsql/client": "^0.17.4",
|
|
38
38
|
"@scalar/hono-api-reference": "^0.10.20",
|
|
39
39
|
"@socket.io/admin-ui": "^0.5.1",
|
|
40
40
|
"@socket.io/bun-engine": "^0.1.1",
|
|
41
41
|
"@socket.io/redis-adapter": "^8.3.0",
|
|
42
|
-
"@
|
|
42
|
+
"@unhead/vue": "^3.4.3",
|
|
43
|
+
"@vitejs/plugin-vue": "^6.0.10",
|
|
43
44
|
"@vuepic/vue-datepicker": "^14.0.0",
|
|
44
45
|
"@vueuse/core": "^14.4.0",
|
|
45
|
-
"@vueuse/head": "^2.0.0",
|
|
46
46
|
"axios": "^1.19.0",
|
|
47
47
|
"bcryptjs": "^3.0.3",
|
|
48
48
|
"bootstrap": "^5.3.8",
|
|
@@ -50,48 +50,73 @@
|
|
|
50
50
|
"bullmq": "^5.81.3",
|
|
51
51
|
"bullmq-durable": "^0.2.0",
|
|
52
52
|
"chalk": "^5.6.2",
|
|
53
|
-
"commander": "^
|
|
53
|
+
"commander": "^15.0.0",
|
|
54
54
|
"croner": "^10.0.1",
|
|
55
55
|
"dotenv": "^17.4.2",
|
|
56
56
|
"dotenv-expand": "^13.0.0",
|
|
57
|
-
"drizzle-orm": "^0.45.
|
|
57
|
+
"drizzle-orm": "^0.45.4",
|
|
58
58
|
"glob": "^13.0.6",
|
|
59
|
-
"hono": "^4.13.
|
|
59
|
+
"hono": "^4.13.14",
|
|
60
60
|
"hono-rate-limiter": "^0.5.3",
|
|
61
61
|
"ioredis": "^5.11.1",
|
|
62
62
|
"lodash-es": "^4.18.1",
|
|
63
63
|
"luxon": "^3.7.2",
|
|
64
|
-
"maildev": "^
|
|
64
|
+
"maildev": "^3.0.0",
|
|
65
65
|
"mysql2": "^3.23.3",
|
|
66
|
-
"nodemailer": "^
|
|
66
|
+
"nodemailer": "^10.2.1",
|
|
67
67
|
"pinia": "^3.0.4",
|
|
68
68
|
"pino": "^10.3.1",
|
|
69
69
|
"postgres": "^3.4.9",
|
|
70
70
|
"redis-commander": "^0.9.0",
|
|
71
71
|
"sass": "^1.100.0",
|
|
72
|
-
"socket.io": "^4.8.
|
|
73
|
-
"socket.io-client": "^4.8.
|
|
72
|
+
"socket.io": "^4.8.4",
|
|
73
|
+
"socket.io-client": "^4.8.4",
|
|
74
74
|
"stoker": "^2.0.1",
|
|
75
|
-
"vite": "^8.
|
|
75
|
+
"vite": "^8.3.5",
|
|
76
76
|
"vue": "^3.5.41",
|
|
77
77
|
"vue-router": "^5.2.0",
|
|
78
78
|
"vue-select": "^4.0.0-beta.6",
|
|
79
|
-
"zod": "^4.
|
|
79
|
+
"zod": "^4.6.7"
|
|
80
|
+
},
|
|
81
|
+
"overrides": {
|
|
82
|
+
"@esbuild-kit/core-utils": {
|
|
83
|
+
"esbuild": "^0.25.12"
|
|
84
|
+
},
|
|
85
|
+
"@maildev/mcp": {
|
|
86
|
+
"zod": "^4.6.7"
|
|
87
|
+
},
|
|
88
|
+
"@maildev/smtp": {
|
|
89
|
+
"jsdom": "^27.4.0",
|
|
90
|
+
"nodemailer": "^10.2.1"
|
|
91
|
+
},
|
|
92
|
+
"redis-commander": {
|
|
93
|
+
"express": "^4.22.3",
|
|
94
|
+
"body-parser": "^1.20.9",
|
|
95
|
+
"bcrypt": "npm:bcryptjs@^3.0.3",
|
|
96
|
+
"bcryptjs": "^3.0.3"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"allowScripts": {
|
|
100
|
+
"@parcel/watcher": true,
|
|
101
|
+
"esbuild": true,
|
|
102
|
+
"msgpackr-extract": true,
|
|
103
|
+
"redis-commander": true,
|
|
104
|
+
"vue-demi": true
|
|
80
105
|
},
|
|
81
106
|
"devDependencies": {
|
|
82
107
|
"@biomejs/biome": "^2.5.7",
|
|
83
108
|
"@types/bootstrap": "^5.2.11",
|
|
84
109
|
"@types/lodash-es": "^4.17.12",
|
|
85
|
-
"@types/node": "^25.9.
|
|
86
|
-
"@vitest/coverage-v8": "^
|
|
87
|
-
"drizzle-kit": "^0.31.
|
|
88
|
-
"tsc-alias": "^1.9.
|
|
89
|
-
"tsx": "^4.23.
|
|
110
|
+
"@types/node": "^25.9.9",
|
|
111
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
112
|
+
"drizzle-kit": "^0.31.11",
|
|
113
|
+
"tsc-alias": "^1.9.9",
|
|
114
|
+
"tsx": "^4.23.15",
|
|
90
115
|
"typescript": "^6.0.3",
|
|
91
|
-
"vitest": "^
|
|
116
|
+
"vitest": "^5.0.5"
|
|
92
117
|
},
|
|
93
118
|
"engines": {
|
|
94
|
-
"node": ">=22",
|
|
119
|
+
"node": ">=22.12.0",
|
|
95
120
|
"bun": ">=1.3",
|
|
96
121
|
"pnpm": ">=11",
|
|
97
122
|
"yarn": ">=4"
|
|
@@ -1,61 +1,48 @@
|
|
|
1
|
-
CREATE TABLE `
|
|
2
|
-
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
-
`
|
|
4
|
-
`
|
|
5
|
-
`
|
|
6
|
-
|
|
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
|
-
FOREIGN KEY (`
|
|
46
|
-
);
|
|
47
|
-
--> statement-breakpoint
|
|
48
|
-
CREATE UNIQUE INDEX `refresh_tokens_jti_unique` ON `refresh_tokens` (`jti`);--> statement-breakpoint
|
|
49
|
-
CREATE TABLE `users` (
|
|
50
|
-
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
51
|
-
`name` text NOT NULL,
|
|
52
|
-
`email` text NOT NULL,
|
|
53
|
-
`password` text NOT NULL,
|
|
54
|
-
`role_id` integer,
|
|
55
|
-
`email_verified_at` integer,
|
|
56
|
-
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
57
|
-
`updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
58
|
-
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE cascade ON DELETE set null
|
|
59
|
-
);
|
|
60
|
-
--> statement-breakpoint
|
|
1
|
+
CREATE TABLE `roles` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`name` text NOT NULL,
|
|
4
|
+
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
5
|
+
`updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
|
|
6
|
+
);
|
|
7
|
+
--> statement-breakpoint
|
|
8
|
+
CREATE UNIQUE INDEX `roles_name_unique` ON `roles` (`name`);--> statement-breakpoint
|
|
9
|
+
CREATE TABLE `email_verification_tokens` (
|
|
10
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
11
|
+
`email` text NOT NULL,
|
|
12
|
+
`token` text NOT NULL,
|
|
13
|
+
`expires_at` integer NOT NULL,
|
|
14
|
+
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE TABLE `password_reset_tokens` (
|
|
18
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
19
|
+
`email` text NOT NULL,
|
|
20
|
+
`token` text NOT NULL,
|
|
21
|
+
`expires_at` integer NOT NULL,
|
|
22
|
+
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL
|
|
23
|
+
);
|
|
24
|
+
--> statement-breakpoint
|
|
25
|
+
CREATE TABLE `refresh_tokens` (
|
|
26
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
27
|
+
`user_id` integer,
|
|
28
|
+
`jti` text NOT NULL,
|
|
29
|
+
`revoked` integer DEFAULT false,
|
|
30
|
+
`expires_at` integer NOT NULL,
|
|
31
|
+
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
32
|
+
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE set null
|
|
33
|
+
);
|
|
34
|
+
--> statement-breakpoint
|
|
35
|
+
CREATE UNIQUE INDEX `refresh_tokens_jti_unique` ON `refresh_tokens` (`jti`);--> statement-breakpoint
|
|
36
|
+
CREATE TABLE `users` (
|
|
37
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
38
|
+
`name` text NOT NULL,
|
|
39
|
+
`email` text NOT NULL,
|
|
40
|
+
`password` text NOT NULL,
|
|
41
|
+
`role_id` integer,
|
|
42
|
+
`email_verified_at` integer,
|
|
43
|
+
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
44
|
+
`updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
|
|
45
|
+
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON UPDATE cascade ON DELETE set null
|
|
46
|
+
);
|
|
47
|
+
--> statement-breakpoint
|
|
61
48
|
CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`);
|