create-warlock 4.2.6 → 4.2.7

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 (95) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +2 -2
  3. package/templates/warlock/.env.example +36 -0
  4. package/templates/warlock/.gitattributes +1 -0
  5. package/templates/warlock/.husky/pre-commit +4 -0
  6. package/templates/warlock/.prettierignore +4 -0
  7. package/templates/warlock/.prettierrc.json +10 -0
  8. package/templates/warlock/.vscode/settings.json +41 -0
  9. package/templates/warlock/README.md +57 -0
  10. package/templates/warlock/_.gitignore +6 -0
  11. package/templates/warlock/docs/new-module.md +551 -0
  12. package/templates/warlock/eslint.config.js +98 -0
  13. package/templates/warlock/package.json +74 -0
  14. package/templates/warlock/public/home.css +523 -0
  15. package/templates/warlock/skills/api-design/SKILL.md +461 -0
  16. package/templates/warlock/skills/code-standards/SKILL.md +595 -0
  17. package/templates/warlock/skills/data-and-persistence/SKILL.md +330 -0
  18. package/templates/warlock/skills/git-workflow/SKILL.md +282 -0
  19. package/templates/warlock/skills/module-boundaries/SKILL.md +283 -0
  20. package/templates/warlock/skills/observability-and-resilience/SKILL.md +306 -0
  21. package/templates/warlock/skills/security-baseline/SKILL.md +352 -0
  22. package/templates/warlock/skills/testing-strategy/SKILL.md +323 -0
  23. package/templates/warlock/src/app/auth/controllers/forgot-password.controller.ts +28 -0
  24. package/templates/warlock/src/app/auth/controllers/login.controller.ts +22 -0
  25. package/templates/warlock/src/app/auth/controllers/logout-all.controller.ts +16 -0
  26. package/templates/warlock/src/app/auth/controllers/logout.controller.ts +16 -0
  27. package/templates/warlock/src/app/auth/controllers/me.controller.ts +13 -0
  28. package/templates/warlock/src/app/auth/controllers/refresh-token.controller.ts +29 -0
  29. package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +23 -0
  30. package/templates/warlock/src/app/auth/main.ts +9 -0
  31. package/templates/warlock/src/app/auth/models/otp/index.ts +1 -0
  32. package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +30 -0
  33. package/templates/warlock/src/app/auth/models/otp/otp.model.ts +69 -0
  34. package/templates/warlock/src/app/auth/requests/guarded.request.ts +10 -0
  35. package/templates/warlock/src/app/auth/routes.ts +22 -0
  36. package/templates/warlock/src/app/auth/schema/login.schema.ts +8 -0
  37. package/templates/warlock/src/app/auth/schema/reset-password.schema.ts +9 -0
  38. package/templates/warlock/src/app/auth/services/auth.service.ts +66 -0
  39. package/templates/warlock/src/app/auth/services/forgot-password.service.ts +28 -0
  40. package/templates/warlock/src/app/auth/services/otp.service.ts +173 -0
  41. package/templates/warlock/src/app/auth/services/reset-password.service.ts +39 -0
  42. package/templates/warlock/src/app/auth/utils/auth-error-code.ts +6 -0
  43. package/templates/warlock/src/app/auth/utils/locales.ts +89 -0
  44. package/templates/warlock/src/app/auth/utils/types.ts +14 -0
  45. package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +21 -0
  46. package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +30 -0
  47. package/templates/warlock/src/app/posts/models/post/migrations/09-01-2026_02-07-51-post.migration.ts +15 -0
  48. package/templates/warlock/src/app/posts/models/post/post.model.ts +23 -0
  49. package/templates/warlock/src/app/posts/resources/post.resource.ts +14 -0
  50. package/templates/warlock/src/app/posts/routes.ts +8 -0
  51. package/templates/warlock/src/app/posts/schema/create-post.schema.ts +9 -0
  52. package/templates/warlock/src/app/posts/schema/update-post.schema.ts +9 -0
  53. package/templates/warlock/src/app/shared/components/HomePageComponent.tsx +229 -0
  54. package/templates/warlock/src/app/shared/controllers/home-page.controller.ts +18 -0
  55. package/templates/warlock/src/app/shared/controllers/home-page.controller.tsx +8 -0
  56. package/templates/warlock/src/app/shared/routes.ts +4 -0
  57. package/templates/warlock/src/app/shared/services/scheduler.service.ts +3 -0
  58. package/templates/warlock/src/app/shared/tests/infrastructure.test.ts +22 -0
  59. package/templates/warlock/src/app/shared/utils/global-columns-schema.ts +8 -0
  60. package/templates/warlock/src/app/shared/utils/locales.ts +766 -0
  61. package/templates/warlock/src/app/shared/utils/router.ts +30 -0
  62. package/templates/warlock/src/app/uploads/controllers/fetch-uploaded-file.controller.ts +33 -0
  63. package/templates/warlock/src/app/uploads/routes.ts +4 -0
  64. package/templates/warlock/src/app/users/commands/hello-world.command.ts +8 -0
  65. package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +27 -0
  66. package/templates/warlock/src/app/users/controllers/list-users.controller.ts +12 -0
  67. package/templates/warlock/src/app/users/events/inject-created-by-user.into-model.event.ts +32 -0
  68. package/templates/warlock/src/app/users/events/sync.ts +5 -0
  69. package/templates/warlock/src/app/users/main.ts +5 -0
  70. package/templates/warlock/src/app/users/models/user/index.ts +1 -0
  71. package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +15 -0
  72. package/templates/warlock/src/app/users/models/user/user.model.ts +64 -0
  73. package/templates/warlock/src/app/users/repositories/users.repository.ts +23 -0
  74. package/templates/warlock/src/app/users/resources/user.resource.ts +14 -0
  75. package/templates/warlock/src/app/users/routes.ts +8 -0
  76. package/templates/warlock/src/app/users/schema/create-user.schema.ts +11 -0
  77. package/templates/warlock/src/app/users/seeds/users.seed.ts +21 -0
  78. package/templates/warlock/src/app/users/services/get-users.service.ts +5 -0
  79. package/templates/warlock/src/app/users/services/list-users.service.ts +17 -0
  80. package/templates/warlock/src/app/users/services/login-social.ts +19 -0
  81. package/templates/warlock/src/config/app.ts +12 -0
  82. package/templates/warlock/src/config/auth.ts +20 -0
  83. package/templates/warlock/src/config/cache.ts +59 -0
  84. package/templates/warlock/src/config/database.ts +65 -0
  85. package/templates/warlock/src/config/http.ts +23 -0
  86. package/templates/warlock/src/config/log.ts +22 -0
  87. package/templates/warlock/src/config/mail.ts +16 -0
  88. package/templates/warlock/src/config/repository.ts +11 -0
  89. package/templates/warlock/src/config/storage.ts +34 -0
  90. package/templates/warlock/src/config/tests.ts +5 -0
  91. package/templates/warlock/src/config/validation.ts +7 -0
  92. package/templates/warlock/storage/.gitignore +2 -0
  93. package/templates/warlock/tsconfig.json +27 -0
  94. package/templates/warlock/warlock.config.ts +15 -0
  95. package/templates/warlock/yarn.lock +2332 -0
@@ -0,0 +1,551 @@
1
+ # Create a new module
2
+
3
+ You can create a new module using the following command:
4
+
5
+ ```bash
6
+ warlock create.module <module-name>
7
+ ```
8
+
9
+ Each module should consist of the following structure:
10
+
11
+ ```
12
+ src/app/[module-name]/
13
+ ├── main.ts # Entry point (auto-imported by Warlock.js)
14
+ ├── routes.ts # Main routing file (auto-imported by Warlock.js)
15
+ ├── controllers/ # Request handlers
16
+ │ ├── [feature]/ # Grouped by feature (e.g., auth, profile)
17
+ │ │ └── *.controller.ts
18
+ │ └── [module].restful.ts # RESTful resource controller (optional)
19
+ ├── services/ # Business logic layer
20
+ │ ├── *.service.ts
21
+ ├── mail/ # Business logic layer
22
+ │ └── *.ts
23
+ ├── repositories/ # Data access layer
24
+ │ └── [resource].repository.ts
25
+ ├── models/ # Database models
26
+ │ └── [model-name]/
27
+ │ ├── index.ts
28
+ │ ├── [model-name].model.ts
29
+ │ └── migrations/
30
+ │ └── [date]_[model-name].migration.ts
31
+ ├── requests/ # Request type definitions
32
+ │ └── *.request.ts # Individual request types
33
+ ├── validation/ # Validation schemas
34
+ │ ├── index.ts # Simple validations (if all in one file)
35
+ │ └── *.schema.ts # Individual validation schema files
36
+ ├── resources/ # Response resource transformers
37
+ │ └── *.resource.ts
38
+ ├── events/ # Event handlers/listeners (auto-imported by Warlock.js)
39
+ │ └── *.ts
40
+ ├── components/ # Reusable components for use within mails
41
+ │ └── *.ts
42
+ ├── types/ # TypeScript type definitions
43
+ │ └── *.ts
44
+ └── utils/ # Module-specific utilities
45
+ ├── locales.ts # Translations (auto-imported by Warlock.js)
46
+ └── flags.ts # Constants/flags
47
+ ```
48
+
49
+ ## Directory Structure Details
50
+
51
+ ### 1. main.ts (Auto-imported)
52
+
53
+ Entry point file that is automatically imported by Warlock.js when the module loads. Use this for module initialization, event listeners, or setup code that should run when the module is loaded.
54
+
55
+ **Example:**
56
+
57
+ ```typescript
58
+ import { onceConnected } from "@warlock.js/cascade";
59
+
60
+ // This function will be called once the app is connected to the database
61
+ onceConnected(async () => {
62
+ // Module initialization code
63
+ // Register event listeners
64
+ // Setup module-specific configurations
65
+ });
66
+ ```
67
+
68
+ ### 2. routes.ts (Auto-imported)
69
+
70
+ Main routing file that defines all module endpoints. This file is automatically imported by Warlock.js. Use router guards (`guarded`, `guardedAdmin`, `guardedGuest`, etc.) to protect routes.
71
+
72
+ **Example:**
73
+
74
+ ```typescript
75
+ import { router } from "@warlock.js/core";
76
+ import { guarded, guardedGuest } from "app/utils/router";
77
+ import { createAccountController } from "./controllers/auth/create-account.controller";
78
+ import { myProfile } from "./controllers/profile/my-profile.controller";
79
+
80
+ guardedGuest(() => {
81
+ router.post("/register", createAccountController);
82
+ });
83
+
84
+ guarded(() => {
85
+ router.get("/me", myProfile);
86
+ });
87
+ ```
88
+
89
+ ### 3. controllers/
90
+
91
+ Request handlers that process HTTP requests. Organize controllers by feature (e.g., `auth/`, `profile/`).
92
+
93
+ **Controller Structure:**
94
+
95
+ ```typescript
96
+ import type { Request, RequestHandler, Response } from "@warlock.js/core";
97
+ import { someService } from "app/[module]/services/some.service";
98
+ import { someRequestSchema } from "app/[module]/validation/some.schema";
99
+ import { type SomeRequest } from "app/[module]/requests/some.request";
100
+
101
+ export const someController: RequestHandler = async (
102
+ request: SomeRequest,
103
+ response: Response,
104
+ ) => {
105
+ const data = await someService(request.validated());
106
+ return response.success({ data });
107
+ };
108
+
109
+ someController.validation = {
110
+ schema: someRequestSchema,
111
+ };
112
+ ```
113
+
114
+ **For RESTful Resources:**
115
+
116
+ ```typescript
117
+ import { Restful, type RouteResource, v } from "@warlock.js/core";
118
+ import { SomeModel } from "../models/some";
119
+ import { someRepository } from "../repositories/some.repository";
120
+
121
+ class RestfulSome extends Restful<SomeModel> implements RouteResource {
122
+ protected repository = someRepository;
123
+
124
+ public validation: RouteResource["validation"] = {
125
+ create: {
126
+ schema: v.object({
127
+ name: v.string().required(),
128
+ }),
129
+ },
130
+ };
131
+ }
132
+
133
+ export const restfulSome = new RestfulSome();
134
+ ```
135
+
136
+ ### 4. services/
137
+
138
+ Business logic layer. Services handle the core functionality and interact with repositories.
139
+
140
+ **Service Structure:**
141
+
142
+ ```typescript
143
+ import type { SomeModel } from "app/[module]/models/some";
144
+ import { someRepository } from "app/[module]/repositories/some.repository";
145
+
146
+ export async function someService(
147
+ data: Record<string, any>,
148
+ ): Promise<SomeModel> {
149
+ return await someRepository.create(data);
150
+ }
151
+ ```
152
+
153
+ ### 5. repositories/
154
+
155
+ Data access layer that extends `RepositoryManager`. Handles database queries and filtering.
156
+
157
+ **Repository Structure:**
158
+
159
+ ```typescript
160
+ import type { FilterRules, RepositoryOptions } from "@warlock.js/core";
161
+ import { RepositoryManager } from "@warlock.js/core";
162
+ import { SomeModel } from "../models/some";
163
+
164
+ export class SomeRepository extends RepositoryManager<SomeModel> {
165
+ public source = SomeModel;
166
+
167
+ protected defaultOptions: RepositoryOptions = {};
168
+
169
+ protected filterBy: FilterRules = {
170
+ name: "like",
171
+ isActive: "bool",
172
+ };
173
+ }
174
+
175
+ export const someRepository = new SomeRepository();
176
+ ```
177
+
178
+ ### 6. models/
179
+
180
+ Database models that extend base model classes (e.g., `Model`, `Auth`). Include migrations in the `migrations/` subdirectory.
181
+
182
+ **Model Structure:**
183
+
184
+ ```typescript
185
+ import { Model } from "@warlock.js/core";
186
+ import type { StrictMode } from "@warlock.js/cascade";
187
+ import { SomeResource } from "../../resources/some.resource";
188
+ import { v, type Infer } from "@warlock.js/seal";
189
+
190
+ const someModelSchema = v.object({
191
+ name: v.string().required(),
192
+ email: v.email().required(),
193
+ });
194
+
195
+ type SomeModelType = Infer<typeof someModelSchema>;
196
+
197
+ export class SomeModel extends Model<SomeModelType> {
198
+ public static table = "somes";
199
+ public static strictMode: StrictMode = "fail";
200
+ public static resource = SomeResource;
201
+
202
+ public static schema = someModelSchema;
203
+
204
+ public embed = ["id", "name"];
205
+ }
206
+ ```
207
+
208
+ ### 7. validation/
209
+
210
+ Validation schemas should be defined here.
211
+
212
+ **Validation Structure:**
213
+
214
+ ```typescript
215
+ import { v, type Infer } from "@warlock.js/seal";
216
+
217
+ export const createAccountSchema = v.object({
218
+ name: v.string().minLength(2).required(),
219
+ email: v.email().required(),
220
+ password: v.string().required().strongPassword(),
221
+ });
222
+
223
+ export type CreateAccountSchema = Infer<typeof createAccountSchema>;
224
+ ```
225
+
226
+ **Important Rules:**
227
+
228
+ - If a module has simple validations, use `index.ts` to export all schemas
229
+ - If requests are complex or numerous, use separate `.schema.ts` files
230
+ - Always export the schema and its inferred type
231
+ - Use `Infer<typeof schema>` (similar to Zod) to generate TypeScript types
232
+
233
+ **Simple Validation (index.ts):**
234
+
235
+ ```typescript
236
+ import { v, type Infer } from "@warlock.js/seal";
237
+
238
+ export const createSchema = v.object({
239
+ name: v.string().minLength(2).required(),
240
+ });
241
+
242
+ export const updateSchema = v.object({
243
+ name: v.string().minLength(2).optional(),
244
+ });
245
+
246
+ export type CreateData = Infer<typeof createSchema>;
247
+ export type UpdateData = Infer<typeof updateSchema>;
248
+ ```
249
+
250
+ **Individual Validation Files:**
251
+
252
+ ```typescript
253
+ // validation/create-account.schema.ts
254
+ import { v, type Infer } from "@warlock.js/seal";
255
+
256
+ export const createAccountSchema = v.object({
257
+ name: v.string().minLength(2).required(),
258
+ email: v.email().required(),
259
+ password: v.string().required().strongPassword(),
260
+ });
261
+
262
+ export type CreateAccountSchema = Infer<typeof createAccountSchema>;
263
+ ```
264
+
265
+ ### 8. requests/
266
+
267
+ High level Request types that link validation schemas to the Request object.
268
+
269
+ **Request Structure:**
270
+
271
+ ```typescript
272
+ import type { Request } from "@warlock.js/core";
273
+ import { type CreateAccountSchema } from "app/[module]/validation/create-account.schema";
274
+
275
+ export type CreateAccountRequest = Request<CreateAccountSchema>;
276
+ ```
277
+
278
+ **Usage in Controller:**
279
+
280
+ ```typescript
281
+ import type { RequestHandler, Response } from "@warlock.js/core";
282
+ import { type CreateAccountRequest } from "app/[module]/requests/create-account.request";
283
+ import { createAccountSchema } from "app/[module]/validation/create-account.schema";
284
+
285
+ export const createAccountController: RequestHandler = async (
286
+ request: CreateAccountRequest,
287
+ response: Response,
288
+ ) => {
289
+ const data = request.validated(); // data is typed as CreateAccountSchema
290
+ // ...
291
+ };
292
+
293
+ createAccountController.validation = {
294
+ schema: createAccountSchema,
295
+ };
296
+ ```
297
+
298
+ ### 9. resources/
299
+
300
+ Resources define how data is transformed before being sent to clients.
301
+
302
+ **Resource Structure:**
303
+
304
+ ```typescript
305
+ **import** { Resource, RegisterResource } from "@warlock.js/core";
306
+
307
+ @RegisterResource()
308
+ export class SomeResource extends Resource {
309
+ public static schema = {
310
+ name: "string",
311
+ id: "int",
312
+ type: () => "user", // custom output value
313
+ image: value => (value.startsWith("/") ? value : "/" + value),
314
+ };
315
+ }
316
+ ```
317
+
318
+ Or even making it simpler by using `defineResource` function (FP style, recommended for most resources)
319
+
320
+ ```typescript
321
+ import { defineResource } from "@warlock.js/core";
322
+
323
+ export const SomeResource = defineResource({
324
+ schema: {
325
+ name: "string",
326
+ id: "int",
327
+ type: () => "user", // custom output value
328
+ image: value => (value.startsWith("/") ? value : "/" + value),
329
+ },
330
+ });
331
+ ```
332
+
333
+ ### 10. events/ (Auto-imported)
334
+
335
+ Event handlers and listeners for model events or application events. **All files in this folder are automatically imported by Warlock.js** - no need to manually import them elsewhere.
336
+
337
+ > During development server, It's very important to use export const cleanup for events unbinding to prevent duplicate events registery on hmr.
338
+
339
+ **Event Structure:**
340
+
341
+ ```typescript
342
+ import { Response } from "@warlock.js/core";
343
+
344
+ export function someEventHandler(response: Response) {
345
+ // Event handling logic
346
+ }
347
+
348
+ const event = Response.on("sending", someEventHandler);
349
+
350
+ export const cleanup = [event];
351
+ // or use a callback if the event is not an unsubscribe function
352
+ export const cleanup = () => event.unsbcribe();
353
+ ```
354
+
355
+ **Note:** Files in the `events/` folder are auto-imported, similar to `routes.ts`, `main.ts`, and `utils/locales.ts`. Just create the file and it will be loaded automatically.
356
+
357
+ ### 11. services/mail/ (or separate mail/ folder)
358
+
359
+ Email service functions for sending notifications. **Mail files should be suffixed with `.mail.ts`** (e.g., `welcome.mail.ts`, `reset-password.mail.ts`).
360
+
361
+ You can organize mail services either as:
362
+
363
+ - Files in `services/mail/` folder (if you have multiple mail-related services) - **Recommended**
364
+ - Individual files in `services/` folder (if you have few mail services)
365
+ - A separate `mail/` folder at module root (legacy pattern, still supported)
366
+
367
+ **Mail Structure:**
368
+
369
+ ```tsx
370
+ // services/mail/welcome.mail.ts
371
+ import { sendMail } from "@warlock.js/core";
372
+ import type { SomeModel } from "../models/some";
373
+ import { SomeEmailComponent } from "../components/some-email.component";
374
+
375
+ export default async function sendWelcomeEmail(model: SomeModel) {
376
+ await sendMail({
377
+ to: model.get("email"),
378
+ subject: "Subject",
379
+ component: <SomeEmailComponent name={model.get("name")} />,
380
+ });
381
+ }
382
+ ```
383
+
384
+ **Recommendation:** Use `services/mail/` folder for better organization when you have multiple mail templates, and always suffix mail files with `.mail.ts`.
385
+
386
+ ### 12. components/
387
+
388
+ Reusable components for use within email templates. These are typically functions that return HTML strings or React-like components that can be used in mail services.
389
+
390
+ **Component Structure:**
391
+
392
+ ```tsx
393
+ export function WelcomeEmailComponent(data: { name: string; email: string }) {
394
+ return `
395
+ <div>
396
+ <h1>Welcome, ${data.name}!</h1>
397
+ <p>Your email: ${data.email}</p>
398
+ </div>
399
+ `;
400
+ }
401
+ ```
402
+
403
+ **Usage in Mail:**
404
+
405
+ ```tsx
406
+ import { sendMail } from "@warlock.js/core";
407
+ import { WelcomeEmailComponent } from "../components/welcome-email.component";
408
+
409
+ export default async function sendWelcomeEmail(user: User) {
410
+ await sendMail({
411
+ to: user.get("email"),
412
+ subject: "Welcome",
413
+ component: (
414
+ <WelcomeEmailComponent
415
+ name={user.get("name")}
416
+ email={user.get("email")}
417
+ />
418
+ ),
419
+ });
420
+ }
421
+ ```
422
+
423
+ ### 13. types/
424
+
425
+ TypeScript type definitions specific to the module. Use this folder for:
426
+
427
+ - Request/response types
428
+ - Service parameter types
429
+ - Module-specific interfaces
430
+ - Type utilities
431
+
432
+ **Types Structure:**
433
+
434
+ ```typescript
435
+ // types/user.types.ts
436
+ export interface UserPreferences {
437
+ theme: "light" | "dark";
438
+ notifications: boolean;
439
+ }
440
+
441
+ export type UserRole = "admin" | "user" | "guest";
442
+ ```
443
+
444
+ ### 14. utils/
445
+
446
+ Module-specific utility functions. **Must include `locales.ts`** which is automatically imported by Warlock.js.
447
+
448
+ **utils/locales.ts (Auto-imported):**
449
+
450
+ ```typescript
451
+ import { groupedTranslations } from "@mongez/localization";
452
+
453
+ groupedTranslations("moduleName", {
454
+ key1: {
455
+ en: "English translation",
456
+ ar: "Arabic translation",
457
+ },
458
+ invalidCredentials: {
459
+ en: "Invalid credentials",
460
+ ar: "بيانات الدخول غير صحيحة",
461
+ },
462
+ });
463
+ ```
464
+
465
+ **utils/flags.ts (Constants):**
466
+
467
+ ```typescript
468
+ // Module-specific constants and flags
469
+ export const USER_STATUS = {
470
+ ACTIVE: "active",
471
+ INACTIVE: "inactive",
472
+ PENDING: "pending",
473
+ } as const;
474
+
475
+ export const USER_ROLES = {
476
+ ADMIN: "admin",
477
+ USER: "user",
478
+ GUEST: "guest",
479
+ } as const;
480
+ ```
481
+
482
+ **Other Utilities:**
483
+
484
+ ```typescript
485
+ // utils/helpers.ts or similar
486
+ export function formatUserName(user: User): string {
487
+ return `${user.get("firstName")} ${user.get("lastName")}`;
488
+ }
489
+ ```
490
+
491
+ **Note:** The `utils/locales.ts` file is automatically imported by Warlock.js, similar to `routes.ts`, `main.ts`, and files in the `events/` folder.
492
+
493
+ ## Best Practices
494
+
495
+ 1. **Naming Conventions:**
496
+
497
+ - Use kebab-case for file names
498
+ - Use PascalCase for class names
499
+ - Use camelCase for functions and variables
500
+
501
+ 2. **Controller Organization:**
502
+
503
+ - Group related controllers in subdirectories (e.g., `auth/`, `profile/`)
504
+ - Keep controllers thin - delegate business logic to services
505
+
506
+ 3. **Service Layer:**
507
+
508
+ - Services should contain reusable business logic
509
+ - Services interact with repositories, not directly with models
510
+
511
+ 4. **Repository Pattern:**
512
+
513
+ - All database operations should go through repositories
514
+ - Define filter options in the repository class
515
+
516
+ 5. **Validation:**
517
+
518
+ - **All validation schemas must be in the `validation/` folder**
519
+ - **All request types must be in the `requests/` folder**
520
+ - Always attach validation to controllers using `controller.validation = { schema }`
521
+ - Export TypeScript types from validation files using `Infer<typeof schema>`
522
+ - Import validation schema in controller from `validation/` folder
523
+ - Import request type in controller from `requests/` folder
524
+ - Use `index.ts` for simple validations, separate `.schema.ts` files for complex ones
525
+
526
+ 6. **Models:**
527
+
528
+ - Define casts for all fields
529
+ - Specify embedded fields for performance
530
+ - Include default values when needed
531
+
532
+ 7. **Routes:**
533
+
534
+ - Use appropriate guards (`guarded`, `guardedAdmin`, `guardedGuest`)
535
+ - Group related routes together
536
+ - Use RESTful resources when appropriate
537
+ - Routes file is auto-imported by Warlock.js
538
+
539
+ 8. **Auto-imported Files:**
540
+
541
+ - `main.ts` - Module entry point
542
+ - `routes.ts` - Route definitions
543
+ - `utils/locales.ts` - Translations
544
+ - All files in `events/` folder - Event handlers
545
+ - No need to manually import these files elsewhere
546
+
547
+ 9. **Organization:**
548
+ - Keep mail services organized: use `services/mail/` folder if multiple, or individual files in `services/` if few
549
+ - Use `components/` folder for reusable email components
550
+ - Define module-specific types in `types/` folder
551
+ - Use `utils/flags.ts` for constants and configuration flags
@@ -0,0 +1,98 @@
1
+ import tsPlugin from "@typescript-eslint/eslint-plugin";
2
+ import tsParser from "@typescript-eslint/parser";
3
+ import prettierConfig from "eslint-config-prettier";
4
+ import prettierPlugin from "eslint-plugin-prettier";
5
+ import unusedImports from "eslint-plugin-unused-imports";
6
+
7
+ export default [
8
+ // Global configuration
9
+ {
10
+ languageOptions: {
11
+ ecmaVersion: "latest",
12
+ sourceType: "module",
13
+ globals: {
14
+ // Node.js globals
15
+ console: "readonly",
16
+ process: "readonly",
17
+ Buffer: "readonly",
18
+ __dirname: "readonly",
19
+ __filename: "readonly",
20
+ global: "readonly",
21
+ module: "readonly",
22
+ require: "readonly",
23
+ exports: "readonly",
24
+ // ES2021 globals
25
+ Promise: "readonly",
26
+ // Jest globals
27
+ describe: "readonly",
28
+ it: "readonly",
29
+ test: "readonly",
30
+ expect: "readonly",
31
+ beforeEach: "readonly",
32
+ afterEach: "readonly",
33
+ beforeAll: "readonly",
34
+ afterAll: "readonly",
35
+ jest: "readonly",
36
+ },
37
+ },
38
+ },
39
+
40
+ // TypeScript files configuration
41
+ {
42
+ files: ["**/*.ts", "**/*.tsx", "**/*.css"],
43
+ languageOptions: {
44
+ parser: tsParser,
45
+ parserOptions: {
46
+ ecmaVersion: "latest",
47
+ sourceType: "module",
48
+ },
49
+ },
50
+ plugins: {
51
+ "@typescript-eslint": tsPlugin,
52
+ prettier: prettierPlugin,
53
+ "unused-imports": unusedImports,
54
+ },
55
+ rules: {
56
+ // Prettier integration
57
+ ...prettierConfig.rules,
58
+ "prettier/prettier": "error",
59
+
60
+ // TypeScript rules
61
+ "@typescript-eslint/no-explicit-any": "off",
62
+ "@typescript-eslint/no-unused-vars": "off",
63
+ "no-unused-vars": "off",
64
+ "unused-imports/no-unused-vars": [
65
+ "warn",
66
+ {
67
+ vars: "all",
68
+ varsIgnorePattern: "^_",
69
+ args: "after-used",
70
+ argsIgnorePattern: "^_",
71
+ },
72
+ ],
73
+ "unused-imports/no-unused-imports": "error",
74
+ "@typescript-eslint/explicit-member-accessibility": [
75
+ "error",
76
+ { accessibility: "explicit" },
77
+ ],
78
+ "@typescript-eslint/consistent-type-imports": [
79
+ "error",
80
+ {
81
+ prefer: "type-imports",
82
+ disallowTypeAnnotations: false,
83
+ },
84
+ ],
85
+ },
86
+ },
87
+
88
+ // Ignore patterns
89
+ {
90
+ ignores: [
91
+ "dist/",
92
+ "node_modules/",
93
+ "**/*.js",
94
+ "!**/*.config.js",
95
+ "!eslint.config.js",
96
+ ],
97
+ },
98
+ ];