create-warlock 4.0.115 → 4.0.118
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/cjs/helpers/app.d.ts +1 -2
- package/cjs/helpers/app.d.ts.map +1 -1
- package/cjs/helpers/app.js +3 -2
- package/cjs/helpers/app.js.map +1 -1
- package/esm/helpers/app.d.ts +1 -2
- package/esm/helpers/app.d.ts.map +1 -1
- package/esm/helpers/app.js +3 -2
- package/esm/helpers/app.js.map +1 -1
- package/package.json +1 -1
- package/templates/warlock/.husky/pre-commit +4 -0
- package/templates/warlock/.vscode/settings.json +41 -0
- package/templates/warlock/docs/new-module.md +509 -509
- package/templates/warlock/package.json +12 -10
- package/templates/warlock/src/app/auth/controllers/forgot-password.controller.ts +11 -2
- package/templates/warlock/src/app/auth/controllers/login.controller.ts +4 -1
- package/templates/warlock/src/app/auth/controllers/logout-all.controller.ts +10 -2
- package/templates/warlock/src/app/auth/controllers/logout.controller.ts +10 -2
- package/templates/warlock/src/app/auth/controllers/me.controller.ts +9 -2
- package/templates/warlock/src/app/auth/controllers/refresh-token.controller.ts +11 -2
- package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +4 -1
- package/templates/warlock/src/app/auth/main.ts +6 -2
- package/templates/warlock/src/app/auth/routes.ts +1 -1
- package/templates/warlock/src/app/auth/services/otp.service.ts +15 -5
- package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +5 -2
- package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +7 -3
- package/templates/warlock/src/app/posts/models/post/migrations/09-01-2026_02-07-51-post.migration.ts +1 -1
- package/templates/warlock/src/app/posts/models/post/post.model.ts +25 -0
- package/templates/warlock/src/app/posts/resources/post.resource.ts +14 -0
- package/templates/warlock/src/app/posts/routes.ts +5 -2
- package/templates/warlock/src/app/{utils → shared/utils}/router.ts +0 -10
- package/templates/warlock/src/app/uploads/controllers/fetch-uploaded-file.controller.ts +4 -1
- package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +4 -1
- package/templates/warlock/src/app/users/controllers/get-users.controller.ts +9 -2
- package/templates/warlock/src/app/users/events/inject-created-by-user.into-model.event.ts +1 -1
- package/templates/warlock/src/app/users/events/sync.ts +1 -1
- package/templates/warlock/src/app/users/main.ts +1 -20
- package/templates/warlock/src/app/users/models/user/user.model.ts +14 -6
- package/templates/warlock/src/app/users/routes.ts +1 -1
- package/templates/warlock/src/app/users/services/login-social.ts +4 -1
- package/templates/warlock/src/config/app.ts +1 -1
- package/templates/warlock/src/config/auth.ts +1 -1
- package/templates/warlock/src/config/cache.ts +3 -2
- package/templates/warlock/src/config/database.ts +6 -3
- package/templates/warlock/src/config/http.ts +1 -1
- package/templates/warlock/src/config/mail.ts +1 -1
- package/templates/warlock/src/config/storage.ts +6 -1
- package/templates/warlock/.env +0 -39
- package/templates/warlock/.prettierrc +0 -8
- package/templates/warlock/AGENTS.md +0 -11
- package/templates/warlock/_.gitignore +0 -7
- package/templates/warlock/src/app/posts/models/post/psot.model.ts +0 -42
- package/templates/warlock/src/app/utils/cloud-upload.middleware.ts +0 -14
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
2
|
+
"name": "wow2",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
@@ -24,14 +24,15 @@
|
|
|
24
24
|
"@mongez/reinforcements": "^2.3.17",
|
|
25
25
|
"@mongez/localization": "^3.2.1",
|
|
26
26
|
"@mongez/supportive-is": "^2.0.4",
|
|
27
|
-
"@warlock.js/auth": "4.0.
|
|
28
|
-
"@warlock.js/cache": "4.0.
|
|
29
|
-
"@warlock.js/cascade": "4.0.
|
|
30
|
-
"@warlock.js/scheduler": "4.0.
|
|
31
|
-
"@warlock.js/core": "4.0.
|
|
32
|
-
"@warlock.js/logger": "4.0.
|
|
33
|
-
"@warlock.js/seal": "4.0.
|
|
34
|
-
"dayjs": "^1.11.19"
|
|
27
|
+
"@warlock.js/auth": "4.0.118",
|
|
28
|
+
"@warlock.js/cache": "4.0.118",
|
|
29
|
+
"@warlock.js/cascade": "4.0.118",
|
|
30
|
+
"@warlock.js/scheduler": "4.0.118",
|
|
31
|
+
"@warlock.js/core": "4.0.118",
|
|
32
|
+
"@warlock.js/logger": "4.0.118",
|
|
33
|
+
"@warlock.js/seal": "4.0.118",
|
|
34
|
+
"dayjs": "^1.11.19",
|
|
35
|
+
"mongodb": "^7.0.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"@mongez/huskier": "^3.0.0",
|
|
@@ -48,7 +49,8 @@
|
|
|
48
49
|
"prettier": "^3.7.4",
|
|
49
50
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
50
51
|
"tsx": "^4.21.0",
|
|
51
|
-
"typescript": "^5.9.3"
|
|
52
|
+
"typescript": "^5.9.3",
|
|
53
|
+
"husky": "^8.0.0"
|
|
52
54
|
},
|
|
53
55
|
"huskier": {
|
|
54
56
|
"hooks": {
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
t,
|
|
3
|
+
v,
|
|
4
|
+
type Request,
|
|
5
|
+
type RequestHandler,
|
|
6
|
+
type Response,
|
|
7
|
+
} from "@warlock.js/core";
|
|
2
8
|
import { usersRepository } from "app/users/repositories/users.repository";
|
|
3
9
|
import { createOtpService } from "../services/otp.service";
|
|
4
10
|
|
|
@@ -6,7 +12,10 @@ import { createOtpService } from "../services/otp.service";
|
|
|
6
12
|
* Forgot password controller
|
|
7
13
|
* POST /auth/forgot-password
|
|
8
14
|
*/
|
|
9
|
-
export const forgotPassword: RequestHandler = async (
|
|
15
|
+
export const forgotPassword: RequestHandler = async (
|
|
16
|
+
request: Request,
|
|
17
|
+
response: Response,
|
|
18
|
+
) => {
|
|
10
19
|
const { email } = request.validated();
|
|
11
20
|
|
|
12
21
|
// Find user by email (silent fail for security)
|
|
@@ -6,7 +6,10 @@ import { loginService } from "../services/auth.service";
|
|
|
6
6
|
* Login controller
|
|
7
7
|
* POST /auth/login
|
|
8
8
|
*/
|
|
9
|
-
export const login: RequestHandler = async (
|
|
9
|
+
export const login: RequestHandler = async (
|
|
10
|
+
request: LoginRequest,
|
|
11
|
+
response: Response,
|
|
12
|
+
) => {
|
|
10
13
|
const result = await loginService(request.validated(), {
|
|
11
14
|
userAgent: request.userAgent,
|
|
12
15
|
ip: request.ip,
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
t,
|
|
3
|
+
type Request,
|
|
4
|
+
type RequestHandler,
|
|
5
|
+
type Response,
|
|
6
|
+
} from "@warlock.js/core";
|
|
2
7
|
import { logoutAllService } from "../services/auth.service";
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
* Logout from all devices controller
|
|
6
11
|
* POST /auth/logout-all
|
|
7
12
|
*/
|
|
8
|
-
export const logoutAll: RequestHandler = async (
|
|
13
|
+
export const logoutAll: RequestHandler = async (
|
|
14
|
+
request: Request,
|
|
15
|
+
response: Response,
|
|
16
|
+
) => {
|
|
9
17
|
await logoutAllService(request.user);
|
|
10
18
|
|
|
11
19
|
return response.success({
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
t,
|
|
3
|
+
type Request,
|
|
4
|
+
type RequestHandler,
|
|
5
|
+
type Response,
|
|
6
|
+
} from "@warlock.js/core";
|
|
2
7
|
import { logoutService } from "../services/auth.service";
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
* Logout controller
|
|
6
11
|
* POST /auth/logout
|
|
7
12
|
*/
|
|
8
|
-
export const logout: RequestHandler = async (
|
|
13
|
+
export const logout: RequestHandler = async (
|
|
14
|
+
request: Request,
|
|
15
|
+
response: Response,
|
|
16
|
+
) => {
|
|
9
17
|
await logoutService(request.user);
|
|
10
18
|
|
|
11
19
|
return response.success({
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Request,
|
|
3
|
+
type RequestHandler,
|
|
4
|
+
type Response,
|
|
5
|
+
} from "@warlock.js/core";
|
|
2
6
|
|
|
3
7
|
/**
|
|
4
8
|
* Get current user controller
|
|
5
9
|
* GET /auth/me
|
|
6
10
|
*/
|
|
7
|
-
export const me: RequestHandler = async (
|
|
11
|
+
export const me: RequestHandler = async (
|
|
12
|
+
request: Request,
|
|
13
|
+
response: Response,
|
|
14
|
+
) => {
|
|
8
15
|
return response.success({
|
|
9
16
|
user: request.user,
|
|
10
17
|
});
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
t,
|
|
3
|
+
v,
|
|
4
|
+
type Request,
|
|
5
|
+
type RequestHandler,
|
|
6
|
+
type Response,
|
|
7
|
+
} from "@warlock.js/core";
|
|
2
8
|
import { refreshTokensService } from "../services/auth.service";
|
|
3
9
|
|
|
4
10
|
/**
|
|
5
11
|
* Refresh token controller
|
|
6
12
|
* POST /auth/refresh-token
|
|
7
13
|
*/
|
|
8
|
-
export const refreshToken: RequestHandler = async (
|
|
14
|
+
export const refreshToken: RequestHandler = async (
|
|
15
|
+
request: Request,
|
|
16
|
+
response: Response,
|
|
17
|
+
) => {
|
|
9
18
|
const token = request.input("refreshToken");
|
|
10
19
|
|
|
11
20
|
const result = await refreshTokensService(token, {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { t, type Response } from "@warlock.js/core";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
resetPasswordSchema,
|
|
4
|
+
type ResetPasswordRequest,
|
|
5
|
+
} from "../requests/reset-password.request";
|
|
3
6
|
import { resetPasswordService } from "../services/reset-password.service";
|
|
4
7
|
|
|
5
8
|
/**
|
|
@@ -5,8 +5,12 @@ import { cleanupExpiredOtpsService } from "./services/otp.service";
|
|
|
5
5
|
|
|
6
6
|
onceConnected(() => {
|
|
7
7
|
// Cleanup expired OTPs every hour
|
|
8
|
-
scheduler
|
|
8
|
+
scheduler
|
|
9
|
+
.newJob("cleanup-expired-otps", cleanupExpiredOtpsService)
|
|
10
|
+
.everyHour();
|
|
9
11
|
|
|
10
12
|
// Cleanup expired refresh tokens every hour
|
|
11
|
-
scheduler
|
|
13
|
+
scheduler
|
|
14
|
+
.newJob("cleanup-expired-tokens", () => authService.cleanupExpiredTokens())
|
|
15
|
+
.everyHour();
|
|
12
16
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { router } from "@warlock.js/core";
|
|
2
|
-
import { guarded } from "app/utils/router";
|
|
2
|
+
import { guarded } from "app/shared/utils/router";
|
|
3
3
|
import { forgotPassword } from "./controllers/forgot-password.controller";
|
|
4
4
|
import { login } from "./controllers/login.controller";
|
|
5
5
|
import { logoutAll } from "./controllers/logout-all.controller";
|
|
@@ -35,7 +35,10 @@ export type CreateOTPOptions = {
|
|
|
35
35
|
/**
|
|
36
36
|
* Generate OTP code
|
|
37
37
|
*/
|
|
38
|
-
function generateCode(
|
|
38
|
+
function generateCode(
|
|
39
|
+
length: number = 6,
|
|
40
|
+
alphanumeric: boolean = false,
|
|
41
|
+
): string {
|
|
39
42
|
if (alphanumeric) {
|
|
40
43
|
// Generate alphanumeric code
|
|
41
44
|
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
@@ -54,7 +57,9 @@ function generateCode(length: number = 6, alphanumeric: boolean = false): string
|
|
|
54
57
|
/**
|
|
55
58
|
* Create a new OTP
|
|
56
59
|
*/
|
|
57
|
-
export async function createOtpService(
|
|
60
|
+
export async function createOtpService(
|
|
61
|
+
options: CreateOTPOptions,
|
|
62
|
+
): Promise<OTP> {
|
|
58
63
|
const {
|
|
59
64
|
target,
|
|
60
65
|
channel,
|
|
@@ -126,7 +131,10 @@ export async function verifyOtpService(
|
|
|
126
131
|
return otp;
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
export async function cleanupOtpService(
|
|
134
|
+
export async function cleanupOtpService(
|
|
135
|
+
target: string,
|
|
136
|
+
type: OTPType,
|
|
137
|
+
): Promise<void> {
|
|
130
138
|
await OTP.delete({
|
|
131
139
|
target,
|
|
132
140
|
type,
|
|
@@ -156,9 +164,11 @@ export async function resendOtpService(
|
|
|
156
164
|
* Cleanup expired OTPs
|
|
157
165
|
*/
|
|
158
166
|
export async function cleanupExpiredOtpsService(): Promise<number> {
|
|
159
|
-
const expiredOtps = await OTP.query()
|
|
167
|
+
const expiredOtps = await OTP.query()
|
|
168
|
+
.where("expiresAt", "<", new Date())
|
|
169
|
+
.get();
|
|
160
170
|
|
|
161
|
-
await Promise.all(expiredOtps.map(
|
|
171
|
+
await Promise.all(expiredOtps.map(otp => otp.destroy()));
|
|
162
172
|
|
|
163
173
|
return expiredOtps.length;
|
|
164
174
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { type RequestHandler, v } from "@warlock.js/core";
|
|
2
|
-
import { Post } from "../models/post/
|
|
2
|
+
import { Post } from "../models/post/post.model";
|
|
3
3
|
|
|
4
|
-
export const createNewPostController: RequestHandler = async (
|
|
4
|
+
export const createNewPostController: RequestHandler = async (
|
|
5
|
+
request,
|
|
6
|
+
response,
|
|
7
|
+
) => {
|
|
5
8
|
const post = await Post.create({
|
|
6
9
|
...request.validated(),
|
|
7
10
|
authorId: request.user.id,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { type RequestHandler
|
|
2
|
-
import {
|
|
1
|
+
import { type RequestHandler } from "@warlock.js/core";
|
|
2
|
+
import { v } from "@warlock.js/seal";
|
|
3
|
+
import { Post } from "../models/post/post.model";
|
|
3
4
|
|
|
4
|
-
export const updatePostController: RequestHandler = async (
|
|
5
|
+
export const updatePostController: RequestHandler = async (
|
|
6
|
+
request,
|
|
7
|
+
response,
|
|
8
|
+
) => {
|
|
5
9
|
const post = await Post.find(request.int("id"));
|
|
6
10
|
|
|
7
11
|
if (!post) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Model, RegisterModel } from "@warlock.js/cascade";
|
|
2
|
+
import { useComputedSlug } from "@warlock.js/core";
|
|
3
|
+
import { type Infer, v } from "@warlock.js/seal";
|
|
4
|
+
import { PostResource } from "app/posts/resources/post.resource";
|
|
5
|
+
import { globalColumnsSchema } from "app/shared/utils/global-columns-schema";
|
|
6
|
+
|
|
7
|
+
export const postSchema = globalColumnsSchema.extend({
|
|
8
|
+
title: v.string().required(),
|
|
9
|
+
description: v.string().required(),
|
|
10
|
+
slug: v.computed(useComputedSlug()),
|
|
11
|
+
image: v.string().required(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
type PostSchema = Infer<typeof postSchema>;
|
|
15
|
+
|
|
16
|
+
@RegisterModel()
|
|
17
|
+
export class Post extends Model<PostSchema> {
|
|
18
|
+
public static table = "posts";
|
|
19
|
+
|
|
20
|
+
public static schema = postSchema;
|
|
21
|
+
|
|
22
|
+
public static relations = {};
|
|
23
|
+
|
|
24
|
+
public static resource = PostResource;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineResource } from "@warlock.js/core";
|
|
2
|
+
|
|
3
|
+
export const PostResource = defineResource({
|
|
4
|
+
schema: {
|
|
5
|
+
id: "number",
|
|
6
|
+
slug: "string",
|
|
7
|
+
title: "string",
|
|
8
|
+
description: "string",
|
|
9
|
+
image: "storageUrl",
|
|
10
|
+
createdBy: "object",
|
|
11
|
+
updatedBy: "object",
|
|
12
|
+
isActive: "boolean",
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { router } from "@warlock.js/core";
|
|
2
|
-
import { guarded } from "app/utils/router";
|
|
2
|
+
import { guarded } from "app/shared/utils/router";
|
|
3
3
|
import { createNewPostController } from "./controllers/create-new-post.controller";
|
|
4
4
|
import { updatePostController } from "./controllers/update-post.controller";
|
|
5
5
|
|
|
6
6
|
guarded(() => {
|
|
7
|
-
router
|
|
7
|
+
router
|
|
8
|
+
.route("/posts")
|
|
9
|
+
.create(createNewPostController)
|
|
10
|
+
.update(updatePostController);
|
|
8
11
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { authMiddleware } from "@warlock.js/auth";
|
|
2
2
|
import { router } from "@warlock.js/core";
|
|
3
|
-
import { cloudUploadMiddleware } from "./cloud-upload.middleware";
|
|
4
3
|
|
|
5
4
|
export function publicRoutes(callback: () => void) {
|
|
6
5
|
router.group(
|
|
@@ -29,12 +28,3 @@ export function guarded(callback: () => void) {
|
|
|
29
28
|
callback,
|
|
30
29
|
);
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
export function cloudUpload(callback: () => void) {
|
|
34
|
-
router.group(
|
|
35
|
-
{
|
|
36
|
-
middleware: [authMiddleware("user"), cloudUploadMiddleware],
|
|
37
|
-
},
|
|
38
|
-
callback,
|
|
39
|
-
);
|
|
40
|
-
}
|
|
@@ -2,7 +2,10 @@ import { fileExistsAsync } from "@mongez/fs";
|
|
|
2
2
|
import { CACHE_FOR } from "@warlock.js/cache";
|
|
3
3
|
import { Image, type RequestHandler, storage, v } from "@warlock.js/core";
|
|
4
4
|
|
|
5
|
-
export const fetchUploadedFileController: RequestHandler = async (
|
|
5
|
+
export const fetchUploadedFileController: RequestHandler = async (
|
|
6
|
+
request,
|
|
7
|
+
response,
|
|
8
|
+
) => {
|
|
6
9
|
const absolutePath = storage.root(request.input("*"));
|
|
7
10
|
|
|
8
11
|
const { w: width, h: height } = request.validated();
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { v, type RequestHandler } from "@warlock.js/core";
|
|
2
2
|
import { User } from "../models/user";
|
|
3
3
|
|
|
4
|
-
export const createNewUserController: RequestHandler = async (
|
|
4
|
+
export const createNewUserController: RequestHandler = async (
|
|
5
|
+
request,
|
|
6
|
+
response,
|
|
7
|
+
) => {
|
|
5
8
|
const file = request.file("image")!;
|
|
6
9
|
|
|
7
10
|
const output = await file.save("images");
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Request,
|
|
3
|
+
type RequestHandler,
|
|
4
|
+
type Response,
|
|
5
|
+
} from "@warlock.js/core";
|
|
2
6
|
import { usersRepository } from "../repositories/users.repository";
|
|
3
7
|
|
|
4
|
-
export const getUsersController: RequestHandler = async (
|
|
8
|
+
export const getUsersController: RequestHandler = async (
|
|
9
|
+
request: Request,
|
|
10
|
+
response: Response,
|
|
11
|
+
) => {
|
|
5
12
|
const users = await usersRepository.listCached({
|
|
6
13
|
...request.all(),
|
|
7
14
|
simpleSelect: true,
|
|
@@ -19,7 +19,7 @@ const saveSubscription = globalEvents.onSaving(async (model, { isInsert }) => {
|
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
const deleteSubscription = globalEvents.onDeleting(async
|
|
22
|
+
const deleteSubscription = globalEvents.onDeleting(async model => {
|
|
23
23
|
const user = useCurrentUser();
|
|
24
24
|
|
|
25
25
|
if (!user) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { modelSync } from "@warlock.js/cascade";
|
|
2
|
-
import { Post } from "app/posts/models/post/
|
|
2
|
+
import { Post } from "app/posts/models/post/post.model";
|
|
3
3
|
import { User } from "../models/user";
|
|
4
4
|
|
|
5
5
|
export const cleanup = [modelSync.sync(User, Post, "createdBy")];
|
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
import { onceConnected } from "@warlock.js/cascade";
|
|
2
|
-
import { Post } from "app/posts/models/post/psot.model";
|
|
3
2
|
|
|
4
3
|
onceConnected(async () => {
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
// // Lazy loading
|
|
8
|
-
// const user = (await User.first())!;
|
|
9
|
-
// await user.load("posts");
|
|
10
|
-
|
|
11
|
-
// console.log(user.posts!.length);
|
|
12
|
-
|
|
13
|
-
// // Eager loading
|
|
14
|
-
// const user2 = await User.with("posts").first();
|
|
15
|
-
|
|
16
|
-
// console.log(user2?.posts?.length);
|
|
17
|
-
|
|
18
|
-
// const post = await Post.with("author").first();
|
|
19
|
-
|
|
20
|
-
// console.log(post?.author);
|
|
21
|
-
const post = await Post.joinWith("author").first();
|
|
22
|
-
console.log(post?.data); // { id, title, authorId, ... } - no author
|
|
23
|
-
console.log(post?.author); // User model instance
|
|
4
|
+
//
|
|
24
5
|
});
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { Auth } from "@warlock.js/auth";
|
|
2
2
|
import { hasMany, RegisterModel } from "@warlock.js/cascade";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
defineResource,
|
|
5
|
+
uploadedFileMetadataSchema,
|
|
6
|
+
useHashedPassword,
|
|
7
|
+
} from "@warlock.js/core";
|
|
4
8
|
import { type Infer, v } from "@warlock.js/seal";
|
|
5
|
-
import { type Post } from "app/posts/models/post/
|
|
9
|
+
import { type Post } from "app/posts/models/post/post.model";
|
|
6
10
|
import { globalColumnsSchema } from "app/shared/utils/global-columns-schema";
|
|
7
11
|
|
|
8
12
|
const UserResource = defineResource({
|
|
@@ -23,7 +27,11 @@ export const userSchema = globalColumnsSchema.extend({
|
|
|
23
27
|
email: v.email().requiredIfEmpty("id").unique("User"),
|
|
24
28
|
image: v.string(),
|
|
25
29
|
imageMetadata: uploadedFileMetadataSchema,
|
|
26
|
-
password: v
|
|
30
|
+
password: v
|
|
31
|
+
.string()
|
|
32
|
+
.min(6)
|
|
33
|
+
.requiredIfEmpty("id")
|
|
34
|
+
.addTransformer(useHashedPassword()),
|
|
27
35
|
});
|
|
28
36
|
|
|
29
37
|
export type UserSchema = Infer<typeof userSchema>;
|
|
@@ -65,15 +73,15 @@ export class User extends Auth<UserSchema> {
|
|
|
65
73
|
|
|
66
74
|
static {
|
|
67
75
|
// Local scopes
|
|
68
|
-
this.addScope("active",
|
|
76
|
+
this.addScope("active", query => {
|
|
69
77
|
query.where("isActive", true);
|
|
70
78
|
});
|
|
71
79
|
|
|
72
|
-
this.addScope("admins",
|
|
80
|
+
this.addScope("admins", query => {
|
|
73
81
|
query.where("role", "admin");
|
|
74
82
|
});
|
|
75
83
|
|
|
76
|
-
this.addScope("verified",
|
|
84
|
+
this.addScope("verified", query => {
|
|
77
85
|
query.where("emailVerified", true);
|
|
78
86
|
});
|
|
79
87
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { router } from "@warlock.js/core";
|
|
2
|
-
import { guarded } from "app/utils/router";
|
|
2
|
+
import { guarded } from "app/shared/utils/router";
|
|
3
3
|
import { createNewUserController } from "./controllers/create-new-user.controller";
|
|
4
4
|
import { getUsersController } from "./controllers/get-users.controller";
|
|
5
5
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Request, Response } from "@warlock.js/core";
|
|
2
2
|
|
|
3
|
-
export default async function loginSocial(
|
|
3
|
+
export default async function loginSocial(
|
|
4
|
+
request: Request,
|
|
5
|
+
response: Response,
|
|
6
|
+
) {
|
|
4
7
|
const user = request.user;
|
|
5
8
|
|
|
6
9
|
const auth = await user.generateAccessToken();
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
RedisCacheDriver,
|
|
6
6
|
type CacheConfigurations,
|
|
7
7
|
} from "@warlock.js/cache";
|
|
8
|
-
import {
|
|
8
|
+
import { DatabaseCacheDriver, env, useRequestStore } from "@warlock.js/core";
|
|
9
9
|
|
|
10
10
|
const globalPrefix = () => {
|
|
11
11
|
const { request } = useRequestStore();
|
|
@@ -20,7 +20,8 @@ const globalPrefix = () => {
|
|
|
20
20
|
return cachePrefix;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const domain =
|
|
23
|
+
const domain =
|
|
24
|
+
request.originDomain || request.header("domain") || request.input("domain");
|
|
24
25
|
|
|
25
26
|
if (!domain) return cachePrefix;
|
|
26
27
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { env } from "@warlock.js/core";
|
|
2
1
|
import type {
|
|
3
2
|
ConnectionOptions,
|
|
4
3
|
MongoClientOptions,
|
|
5
4
|
MongoDriverOptions,
|
|
6
5
|
} from "@warlock.js/cascade";
|
|
6
|
+
import { env } from "@warlock.js/core";
|
|
7
7
|
|
|
8
|
-
const databaseConfigurations: ConnectionOptions<
|
|
9
|
-
|
|
8
|
+
const databaseConfigurations: ConnectionOptions<
|
|
9
|
+
MongoDriverOptions,
|
|
10
|
+
MongoClientOptions
|
|
11
|
+
> = {
|
|
12
|
+
driver: env("DB_DRIVER", "mongodb"),
|
|
10
13
|
name: "default",
|
|
11
14
|
database: env("DB_NAME"),
|
|
12
15
|
host: env("DB_HOST", "localhost"),
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
env,
|
|
3
|
+
type StorageConfigurations,
|
|
4
|
+
storageConfigurations,
|
|
5
|
+
uploadsPath,
|
|
6
|
+
} from "@warlock.js/core";
|
|
2
7
|
|
|
3
8
|
const storageOptions: StorageConfigurations = {
|
|
4
9
|
default: "local",
|
package/templates/warlock/.env
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# App Configurations
|
|
2
|
-
APP_NAME="gym-management"
|
|
3
|
-
LOCALE_CODE=en
|
|
4
|
-
|
|
5
|
-
TIMEZONE=UTC
|
|
6
|
-
|
|
7
|
-
# Http Configurations
|
|
8
|
-
HTTP_HOST=127.0.0.1
|
|
9
|
-
HTTP_PORT=2030
|
|
10
|
-
BASE_URL=http://${HTTP_HOST}:${HTTP_PORT}
|
|
11
|
-
|
|
12
|
-
# Database Configurations
|
|
13
|
-
DB_AUTH=admin
|
|
14
|
-
DB_PORT=27017
|
|
15
|
-
DB_HOST=127.0.0.1
|
|
16
|
-
DB_NAME=gym-management
|
|
17
|
-
DB_USERNAME=root
|
|
18
|
-
DB_PASSWORD=root
|
|
19
|
-
|
|
20
|
-
# Cache
|
|
21
|
-
CACHE_DRIVER=memory
|
|
22
|
-
## Redis
|
|
23
|
-
REDIS_HOST=127.0.0.1
|
|
24
|
-
REDIS_PORT=6379
|
|
25
|
-
# or using redis url
|
|
26
|
-
#REDIS_URL=
|
|
27
|
-
|
|
28
|
-
# Mail
|
|
29
|
-
MAIL_HOST=
|
|
30
|
-
MAIL_PORT=465
|
|
31
|
-
MAIL_ENCRYPTION=ssl
|
|
32
|
-
MAIL_SECURE=true
|
|
33
|
-
MAIL_USERNAME=
|
|
34
|
-
MAIL_PASSWORD=
|
|
35
|
-
MAIL_FROM_NAME=${APP_NAME}
|
|
36
|
-
MAIL_FROM_ADDRESS=
|
|
37
|
-
|
|
38
|
-
# JWT Secret
|
|
39
|
-
JWT_SECRET=5Ulrs4caSEMqL5SwH41QdBOAC0NFCGnf
|