create-warlock 4.0.29 → 4.0.31
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/package.json +1 -1
- package/templates/warlock/package.json +7 -7
- package/templates/warlock/src/app/auth/controllers/forgot-password.controller.ts +46 -0
- package/templates/warlock/src/app/auth/controllers/login.controller.ts +31 -0
- package/templates/warlock/src/app/auth/controllers/logout-all.controller.ts +16 -0
- package/templates/warlock/src/app/auth/controllers/logout.controller.ts +16 -0
- package/templates/warlock/src/app/auth/controllers/me.controller.ts +13 -0
- package/templates/warlock/src/app/auth/controllers/refresh-token.controller.ts +31 -0
- package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +25 -0
- package/templates/warlock/src/app/auth/main.ts +9 -0
- package/templates/warlock/src/app/auth/models/otp/index.ts +1 -0
- package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +22 -0
- package/templates/warlock/src/app/auth/models/otp/otp.model.ts +75 -0
- package/templates/warlock/src/app/auth/requests/login.request.ts +10 -0
- package/templates/warlock/src/app/auth/requests/reset-password.request.ts +11 -0
- package/templates/warlock/src/app/auth/routes.ts +22 -0
- package/templates/warlock/src/app/auth/services/auth.service.ts +47 -0
- package/templates/warlock/src/app/auth/services/otp.service.ts +174 -0
- package/templates/warlock/src/app/auth/services/reset-password.service.ts +35 -0
- package/templates/warlock/src/app/auth/utils/auth-error-code.ts +6 -0
- package/templates/warlock/src/app/auth/utils/locales.ts +89 -0
- package/templates/warlock/src/app/auth/utils/types.ts +14 -0
- package/templates/warlock/src/app/shared/services/scheduler.service.ts +3 -0
- package/templates/warlock/src/app/shared/utils/locales.ts +728 -0
- package/templates/warlock/src/app/users/commands/hello-world.command.ts +8 -0
- package/templates/warlock/src/app/users/controllers/get-users.controller.ts +10 -0
- package/templates/warlock/src/app/users/main.ts +0 -0
- package/templates/warlock/src/app/users/models/user/index.ts +1 -0
- package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +14 -0
- package/templates/warlock/src/app/users/models/user/user.model.ts +46 -0
- package/templates/warlock/src/app/users/repositories/users-repository.ts +66 -0
- package/templates/warlock/src/app/users/repositories/users.repository.ts +27 -0
- package/templates/warlock/src/app/users/routes.ts +4 -0
- package/templates/warlock/src/app/users/services/get-new-customers.ts +5 -0
- package/templates/warlock/src/app/users/services/get-users.service.ts +5 -0
- package/templates/warlock/src/app/users/services/list-users.service.ts +7 -0
- package/templates/warlock/src/app/users/services/login-social.ts +19 -0
- package/templates/warlock/src/app/utils/output.ts +5 -0
- package/templates/warlock/src/app/utils/router.ts +30 -0
- package/templates/warlock/src/config/app.ts +12 -0
- package/templates/warlock/src/config/auth.ts +18 -0
- package/templates/warlock/src/config/cache.ts +60 -0
- package/templates/warlock/src/config/database.ts +19 -0
- package/templates/warlock/src/config/http.ts +23 -0
- package/templates/warlock/src/config/log.ts +22 -0
- package/templates/warlock/src/config/mail.ts +16 -0
- package/templates/warlock/src/config/notifications.ts +11 -0
- package/templates/warlock/src/config/storage.ts +21 -0
- package/templates/warlock/src/config/tests.ts +5 -0
- package/templates/warlock/src/config/validation.ts +7 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Request, type RequestHandler, type Response } from "@warlock.js/core";
|
|
2
|
+
import { getUsersService } from "../services/get-users.service";
|
|
3
|
+
|
|
4
|
+
export const getUsersController: RequestHandler = async (request: Request, response: Response) => {
|
|
5
|
+
return response.success({
|
|
6
|
+
users: await getUsersService(),
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
getUsersController.description = "Get Users Controller";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./user.model";
|
package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { migrationOffice, type Blueprint } from "@warlock.js/cascade";
|
|
2
|
+
import { User } from "../user.model";
|
|
3
|
+
|
|
4
|
+
export default migrationOffice.register({
|
|
5
|
+
name: "userMigration",
|
|
6
|
+
createdAt: "11-12-2025_23-58-03",
|
|
7
|
+
blueprint: User.blueprint(),
|
|
8
|
+
up: (blueprint: Blueprint) => {
|
|
9
|
+
blueprint.unique("id");
|
|
10
|
+
},
|
|
11
|
+
down: (blueprint: Blueprint) => {
|
|
12
|
+
blueprint.dropUniqueIndex("id");
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Auth } from "@warlock.js/auth";
|
|
2
|
+
import { type Casts, type Document, type ModelSync } from "@warlock.js/cascade";
|
|
3
|
+
|
|
4
|
+
export class User extends Auth {
|
|
5
|
+
/**
|
|
6
|
+
* Collection name
|
|
7
|
+
*/
|
|
8
|
+
public static collection = "users";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* List of models to sync with
|
|
12
|
+
* To sync with a single embedded document use: [User.sync("city")],
|
|
13
|
+
* this will update the city sub-document to all users when city model is updated.
|
|
14
|
+
* To sync with multiple embedded documents use: [Post.syncMany("keywords")],
|
|
15
|
+
* This will update the keywords sub-document to all posts when keywords model is updated.
|
|
16
|
+
*/
|
|
17
|
+
public syncWith: ModelSync[] = [];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default value for model data
|
|
21
|
+
* Works only when creating new records
|
|
22
|
+
*/
|
|
23
|
+
public defaultValue: Document = {};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* User type
|
|
27
|
+
*/
|
|
28
|
+
public userType = "user";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Cast data types before saving documents into database
|
|
32
|
+
*/
|
|
33
|
+
protected casts: Casts = {
|
|
34
|
+
name: "string",
|
|
35
|
+
age: "number",
|
|
36
|
+
email: "string",
|
|
37
|
+
isActive: "boolean",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Define what columns should be used when model document is embedded in another document.
|
|
42
|
+
* Make sure to set only the needed columns to reduce the document size.
|
|
43
|
+
* This is useful for better performance when fetching data from database.
|
|
44
|
+
*/
|
|
45
|
+
public embedded = ["id", "name"];
|
|
46
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { FilterByOptions, RepositoryOptions } from "@warlock.js/core";
|
|
2
|
+
import { RepositoryManager } from "@warlock.js/core";
|
|
3
|
+
import { User } from "../models/user";
|
|
4
|
+
|
|
5
|
+
export class UsersRepository extends RepositoryManager<User> {
|
|
6
|
+
/**
|
|
7
|
+
* {@inheritDoc}
|
|
8
|
+
*/
|
|
9
|
+
public model = User;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* List default options
|
|
13
|
+
*/
|
|
14
|
+
protected defaultOptions: RepositoryOptions = this.withDefaultOptions({});
|
|
15
|
+
|
|
16
|
+
protected cacheDriverName = "redis";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Filter By options
|
|
20
|
+
*/
|
|
21
|
+
protected filterBy: FilterByOptions = {
|
|
22
|
+
isActive: "bool",
|
|
23
|
+
email: "like",
|
|
24
|
+
id: "int",
|
|
25
|
+
month: "int",
|
|
26
|
+
year: "int",
|
|
27
|
+
phoneNumber: "like",
|
|
28
|
+
isAdmin: "bool",
|
|
29
|
+
isVendor: "bool",
|
|
30
|
+
isCustomer: "bool",
|
|
31
|
+
gender: "=",
|
|
32
|
+
name: ["like", ["name", "username"]],
|
|
33
|
+
except: ["!int", "id"],
|
|
34
|
+
affiliateCode: ["=", "affiliate.code"],
|
|
35
|
+
affiliateStatus: ["=", "affiliate.status"],
|
|
36
|
+
activationToken: "=",
|
|
37
|
+
instagramHash: "=",
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get all administrators
|
|
42
|
+
*/
|
|
43
|
+
public getAdmins() {
|
|
44
|
+
return this.list({
|
|
45
|
+
paginate: false,
|
|
46
|
+
isAdmin: true,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* List pending affiliate partners
|
|
52
|
+
*/
|
|
53
|
+
public listAffiliatePartners(status?: "pending" | "active" | "rejected") {
|
|
54
|
+
return this.listActive({
|
|
55
|
+
perform(query) {
|
|
56
|
+
query.whereNotNull("affiliate");
|
|
57
|
+
},
|
|
58
|
+
affiliateStatus: status,
|
|
59
|
+
deselect: ["lastLogin", "group", "cartProducts", "total", "totalWishList", "totalCompare"],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const usersRepository = new UsersRepository();
|
|
65
|
+
|
|
66
|
+
export default usersRepository;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RepositoryManager, type FilterByOptions, type RepositoryOptions } from "@warlock.js/core";
|
|
2
|
+
import { User } from "./../models/user";
|
|
3
|
+
|
|
4
|
+
export class UsersRepository extends RepositoryManager<User> {
|
|
5
|
+
/**
|
|
6
|
+
* {@inheritDoc}
|
|
7
|
+
*/
|
|
8
|
+
public model = User;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Simple columns selections
|
|
12
|
+
* Set the columns that need to be selected when passing 'simple' option with 'true'
|
|
13
|
+
*/
|
|
14
|
+
public simpleSelectColumns = ["id"];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* List default options
|
|
18
|
+
*/
|
|
19
|
+
protected defaultOptions: RepositoryOptions = this.withDefaultOptions({});
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Filter By options
|
|
23
|
+
*/
|
|
24
|
+
protected filterBy: FilterByOptions = this.withDefaultFilters({});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const usersRepository = new UsersRepository();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Request, Response } from "@warlock.js/core";
|
|
2
|
+
|
|
3
|
+
export default async function loginSocial(request: Request, response: Response) {
|
|
4
|
+
const user = request.user;
|
|
5
|
+
|
|
6
|
+
const auth = await user.generateAccessToken();
|
|
7
|
+
|
|
8
|
+
user.save({
|
|
9
|
+
lastLogin: new Date(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return response.success({
|
|
13
|
+
user: {
|
|
14
|
+
...(await user.toJSON()),
|
|
15
|
+
accessToken: auth,
|
|
16
|
+
userType: user.userType,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { authMiddleware } from "@warlock.js/auth";
|
|
2
|
+
import { router } from "@warlock.js/core";
|
|
3
|
+
|
|
4
|
+
export function publicRoutes(callback: () => void) {
|
|
5
|
+
router.group(
|
|
6
|
+
{
|
|
7
|
+
prefix: "/",
|
|
8
|
+
},
|
|
9
|
+
callback,
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function guardedAdmin(callback: () => void) {
|
|
14
|
+
router.group(
|
|
15
|
+
{
|
|
16
|
+
prefix: "/admin",
|
|
17
|
+
middleware: [authMiddleware()],
|
|
18
|
+
},
|
|
19
|
+
callback,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function guarded(callback: () => void) {
|
|
24
|
+
router.group(
|
|
25
|
+
{
|
|
26
|
+
middleware: [authMiddleware()],
|
|
27
|
+
},
|
|
28
|
+
callback,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import type { AppConfigurations } from "@warlock.js/core";
|
|
3
|
+
|
|
4
|
+
const appConfigurations: AppConfigurations = {
|
|
5
|
+
appName: env("APP_NAME", "Mongez"),
|
|
6
|
+
timezone: env("TIMEZONE", "UTC"),
|
|
7
|
+
baseUrl: env("BASE_URL", "http://localhost:3000"),
|
|
8
|
+
localeCode: env("LOCALE_CODE", "en"),
|
|
9
|
+
localeCodes: ["en", "ar"],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default appConfigurations;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import { NO_EXPIRATION, type AuthConfigurations } from "@warlock.js/auth";
|
|
3
|
+
import { User } from "app/users/models/user";
|
|
4
|
+
|
|
5
|
+
const authConfigurations: AuthConfigurations = {
|
|
6
|
+
userType: {
|
|
7
|
+
user: User,
|
|
8
|
+
},
|
|
9
|
+
jwt: {
|
|
10
|
+
secret: env("JWT_SECRET"),
|
|
11
|
+
expiresIn: NO_EXPIRATION,
|
|
12
|
+
refresh: {
|
|
13
|
+
expiresIn: "7d",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default authConfigurations;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import {
|
|
3
|
+
FileCacheDriver,
|
|
4
|
+
MemoryCacheDriver,
|
|
5
|
+
MemoryExtendedCacheDriver,
|
|
6
|
+
RedisCacheDriver,
|
|
7
|
+
type CacheConfigurations,
|
|
8
|
+
} from "@warlock.js/cache";
|
|
9
|
+
import { DatabaseCacheDriver, useRequestStore } from "@warlock.js/core";
|
|
10
|
+
|
|
11
|
+
const globalPrefix = () => {
|
|
12
|
+
const { request } = useRequestStore();
|
|
13
|
+
|
|
14
|
+
let cachePrefix = "store";
|
|
15
|
+
|
|
16
|
+
if (!request) return cachePrefix;
|
|
17
|
+
|
|
18
|
+
if (request.client) {
|
|
19
|
+
cachePrefix = `${cachePrefix}.${request.client.get("username")}`;
|
|
20
|
+
|
|
21
|
+
return cachePrefix;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const domain = request.originDomain || request.header("domain") || request.input("domain");
|
|
25
|
+
|
|
26
|
+
if (!domain) return cachePrefix;
|
|
27
|
+
|
|
28
|
+
cachePrefix = `${cachePrefix}.${domain}`;
|
|
29
|
+
|
|
30
|
+
return cachePrefix;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const cacheConfigurations: CacheConfigurations<"database"> = {
|
|
34
|
+
default: "memoryExtended",
|
|
35
|
+
drivers: {
|
|
36
|
+
file: FileCacheDriver,
|
|
37
|
+
memory: MemoryCacheDriver,
|
|
38
|
+
redis: RedisCacheDriver,
|
|
39
|
+
memoryExtended: MemoryExtendedCacheDriver,
|
|
40
|
+
database: DatabaseCacheDriver,
|
|
41
|
+
},
|
|
42
|
+
options: {
|
|
43
|
+
redis: {
|
|
44
|
+
host: env("REDIS_HOST"),
|
|
45
|
+
port: env("REDIS_PORT"),
|
|
46
|
+
url: env("REDIS_URL"),
|
|
47
|
+
globalPrefix,
|
|
48
|
+
},
|
|
49
|
+
memory: {
|
|
50
|
+
globalPrefix,
|
|
51
|
+
ttl: 3 * 60 * 60, // 3 hours
|
|
52
|
+
},
|
|
53
|
+
memoryExtended: {
|
|
54
|
+
globalPrefix,
|
|
55
|
+
ttl: 30 * 60, // 30 minutes
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default cacheConfigurations;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import type { DatabaseConfigurations } from "@warlock.js/cascade";
|
|
3
|
+
|
|
4
|
+
const databaseConfigurations: DatabaseConfigurations = {
|
|
5
|
+
host: env("DB_HOST", "localhost"),
|
|
6
|
+
port: env("DB_PORT", 27017),
|
|
7
|
+
username: env("DB_USERNAME"),
|
|
8
|
+
password: env("DB_PASSWORD"),
|
|
9
|
+
database: env("DB_NAME"),
|
|
10
|
+
dbAuth: env("DB_AUTH"),
|
|
11
|
+
url: env("DB_URL"),
|
|
12
|
+
replicaSet: env("DB_REPLICA_SET"),
|
|
13
|
+
model: {
|
|
14
|
+
randomIncrement: true,
|
|
15
|
+
initialId: 1,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default databaseConfigurations;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import type { HttpConfigurations } from "@warlock.js/core";
|
|
3
|
+
|
|
4
|
+
const httpConfigurations: HttpConfigurations = {
|
|
5
|
+
port: env("HTTP_PORT", 3000),
|
|
6
|
+
host: env("HTTP_HOST", "localhost"),
|
|
7
|
+
log: true,
|
|
8
|
+
fileUploadLimit: 12 * 1024 * 1024 * 1024,
|
|
9
|
+
rateLimit: {
|
|
10
|
+
max: 260,
|
|
11
|
+
duration: 60 * 1000, // 1 minute
|
|
12
|
+
},
|
|
13
|
+
cors: {
|
|
14
|
+
// allowed origins
|
|
15
|
+
// origin: ["127.0.0.1:5173", "localhost:5173"],
|
|
16
|
+
// origin: ["http://127.0.0.1:5173"],
|
|
17
|
+
origin: "*",
|
|
18
|
+
// allowed methods
|
|
19
|
+
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default httpConfigurations;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type LogConfigurations } from "@warlock.js/core";
|
|
2
|
+
import { ConsoleLog } from "@warlock.js/logger";
|
|
3
|
+
|
|
4
|
+
const consoleLog = new ConsoleLog();
|
|
5
|
+
|
|
6
|
+
const logConfigurations: LogConfigurations = {
|
|
7
|
+
enabled: true,
|
|
8
|
+
development: {
|
|
9
|
+
channels: [consoleLog],
|
|
10
|
+
// channels: [consoleLog],
|
|
11
|
+
// channels: [],
|
|
12
|
+
},
|
|
13
|
+
test: {
|
|
14
|
+
// channels: [consoleLog],
|
|
15
|
+
channels: [consoleLog],
|
|
16
|
+
},
|
|
17
|
+
production: {
|
|
18
|
+
channels: [consoleLog],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default logConfigurations;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import type { MailConfigurations } from "@warlock.js/core";
|
|
3
|
+
|
|
4
|
+
const mailConfigurations: MailConfigurations = {
|
|
5
|
+
host: env("MAIL_HOST"),
|
|
6
|
+
username: env("MAIL_USERNAME"),
|
|
7
|
+
password: env("MAIL_PASSWORD"),
|
|
8
|
+
port: env("MAIL_PORT"),
|
|
9
|
+
secure: env("MAIL_SECURE"),
|
|
10
|
+
from: {
|
|
11
|
+
name: env("MAIL_FROM_NAME"),
|
|
12
|
+
address: env("MAIL_FROM_ADDRESS"),
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default mailConfigurations;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { env } from "@mongez/dotenv";
|
|
2
|
+
import { type StorageConfigurations, uploadsPath } from "@warlock.js/core";
|
|
3
|
+
|
|
4
|
+
const storageOptions: StorageConfigurations = {
|
|
5
|
+
default: "rafaat",
|
|
6
|
+
drivers: {
|
|
7
|
+
rafaat: {
|
|
8
|
+
driver: "local",
|
|
9
|
+
root: uploadsPath(),
|
|
10
|
+
},
|
|
11
|
+
aws: {
|
|
12
|
+
driver: "s3",
|
|
13
|
+
accessKeyId: env("AWS_ACCESS_KEY_ID"),
|
|
14
|
+
secretAccessKey: env("AWS_SECRET_ACCESS_KEY"),
|
|
15
|
+
region: env("AWS_REGION"),
|
|
16
|
+
bucket: env("AWS_BUCKET"),
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default storageOptions;
|