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.
Files changed (50) hide show
  1. package/package.json +1 -1
  2. package/templates/warlock/package.json +7 -7
  3. package/templates/warlock/src/app/auth/controllers/forgot-password.controller.ts +46 -0
  4. package/templates/warlock/src/app/auth/controllers/login.controller.ts +31 -0
  5. package/templates/warlock/src/app/auth/controllers/logout-all.controller.ts +16 -0
  6. package/templates/warlock/src/app/auth/controllers/logout.controller.ts +16 -0
  7. package/templates/warlock/src/app/auth/controllers/me.controller.ts +13 -0
  8. package/templates/warlock/src/app/auth/controllers/refresh-token.controller.ts +31 -0
  9. package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +25 -0
  10. package/templates/warlock/src/app/auth/main.ts +9 -0
  11. package/templates/warlock/src/app/auth/models/otp/index.ts +1 -0
  12. package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +22 -0
  13. package/templates/warlock/src/app/auth/models/otp/otp.model.ts +75 -0
  14. package/templates/warlock/src/app/auth/requests/login.request.ts +10 -0
  15. package/templates/warlock/src/app/auth/requests/reset-password.request.ts +11 -0
  16. package/templates/warlock/src/app/auth/routes.ts +22 -0
  17. package/templates/warlock/src/app/auth/services/auth.service.ts +47 -0
  18. package/templates/warlock/src/app/auth/services/otp.service.ts +174 -0
  19. package/templates/warlock/src/app/auth/services/reset-password.service.ts +35 -0
  20. package/templates/warlock/src/app/auth/utils/auth-error-code.ts +6 -0
  21. package/templates/warlock/src/app/auth/utils/locales.ts +89 -0
  22. package/templates/warlock/src/app/auth/utils/types.ts +14 -0
  23. package/templates/warlock/src/app/shared/services/scheduler.service.ts +3 -0
  24. package/templates/warlock/src/app/shared/utils/locales.ts +728 -0
  25. package/templates/warlock/src/app/users/commands/hello-world.command.ts +8 -0
  26. package/templates/warlock/src/app/users/controllers/get-users.controller.ts +10 -0
  27. package/templates/warlock/src/app/users/main.ts +0 -0
  28. package/templates/warlock/src/app/users/models/user/index.ts +1 -0
  29. package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +14 -0
  30. package/templates/warlock/src/app/users/models/user/user.model.ts +46 -0
  31. package/templates/warlock/src/app/users/repositories/users-repository.ts +66 -0
  32. package/templates/warlock/src/app/users/repositories/users.repository.ts +27 -0
  33. package/templates/warlock/src/app/users/routes.ts +4 -0
  34. package/templates/warlock/src/app/users/services/get-new-customers.ts +5 -0
  35. package/templates/warlock/src/app/users/services/get-users.service.ts +5 -0
  36. package/templates/warlock/src/app/users/services/list-users.service.ts +7 -0
  37. package/templates/warlock/src/app/users/services/login-social.ts +19 -0
  38. package/templates/warlock/src/app/utils/output.ts +5 -0
  39. package/templates/warlock/src/app/utils/router.ts +30 -0
  40. package/templates/warlock/src/config/app.ts +12 -0
  41. package/templates/warlock/src/config/auth.ts +18 -0
  42. package/templates/warlock/src/config/cache.ts +60 -0
  43. package/templates/warlock/src/config/database.ts +19 -0
  44. package/templates/warlock/src/config/http.ts +23 -0
  45. package/templates/warlock/src/config/log.ts +22 -0
  46. package/templates/warlock/src/config/mail.ts +16 -0
  47. package/templates/warlock/src/config/notifications.ts +11 -0
  48. package/templates/warlock/src/config/storage.ts +21 -0
  49. package/templates/warlock/src/config/tests.ts +5 -0
  50. package/templates/warlock/src/config/validation.ts +7 -0
@@ -0,0 +1,8 @@
1
+ import { command } from "@warlock.js/core";
2
+
3
+ export default command({
4
+ name: "hello.world",
5
+ action: () => {
6
+ console.log("Hello World Guys!");
7
+ },
8
+ });
@@ -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";
@@ -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,4 @@
1
+ import { router } from "@warlock.js/core";
2
+ import { getUsersController } from "./controllers/get-users.controller";
3
+
4
+ router.get("/users", getUsersController);
@@ -0,0 +1,5 @@
1
+ import { User } from "../models/user";
2
+
3
+ export default function getNewCustomers() {
4
+ return User.aggregate().where("isCustomer", true).limit(6).get();
5
+ }
@@ -0,0 +1,5 @@
1
+ import { usersRepository } from "../repositories/users.repository";
2
+
3
+ export async function getUsersService() {
4
+ return usersRepository.allActiveCached();
5
+ }
@@ -0,0 +1,7 @@
1
+ import { usersRepository } from "../repositories/users.repository";
2
+
3
+ export async function listUsersService() {
4
+ return usersRepository.allActiveCached({
5
+ select: ["id", "name", "email", "isActive", "age"],
6
+ });
7
+ }
@@ -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,5 @@
1
+ import type { FinalOutput } from "@warlock.js/core";
2
+
3
+ export function withBaseOutputDetails(output: FinalOutput) {
4
+ return output;
5
+ }
@@ -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,11 @@
1
+ export type NotificationConfig = {
2
+ channels: string[];
3
+ default: string;
4
+ };
5
+
6
+ const notifications: NotificationConfig = {
7
+ channels: ["mail", "database", "slack", "telegram"],
8
+ default: "mail",
9
+ };
10
+
11
+ export default notifications;
@@ -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;
@@ -0,0 +1,5 @@
1
+ const testsConfigurations = {
2
+ //
3
+ };
4
+
5
+ export default testsConfigurations;
@@ -0,0 +1,7 @@
1
+ import type { ValidationConfiguration } from "@warlock.js/core";
2
+
3
+ const validationConfigurations: ValidationConfiguration = {
4
+ firstErrorOnly: true,
5
+ };
6
+
7
+ export default validationConfigurations;