create-warlock 4.1.14 → 4.2.0
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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/esm/commands/create-new-app/get-app-path.mjs +1 -1
- package/esm/commands/create-new-app/index.mjs +1 -1
- package/esm/commands/create-new-app/index.mjs.map +1 -1
- package/esm/commands/create-new-app/types.d.mts +1 -1
- package/esm/commands/create-warlock-app/index.mjs +1 -1
- package/esm/commands/create-warlock-app/index.mjs.map +1 -1
- package/esm/features/database-drivers.mjs +1 -1
- package/esm/features/features-map.mjs +13 -1
- package/esm/features/features-map.mjs.map +1 -1
- package/esm/helpers/app.mjs +1 -1
- package/esm/helpers/app.mjs.map +1 -1
- package/esm/helpers/exec.mjs +1 -1
- package/esm/helpers/package-manager.mjs +1 -1
- package/esm/helpers/package-manager.mjs.map +1 -1
- package/esm/helpers/paths.mjs +1 -1
- package/esm/helpers/project-builder-helpers.mjs +1 -1
- package/esm/index.d.mts +1 -1
- package/esm/index.mjs +1 -1
- package/esm/index.mjs.map +1 -1
- package/esm/ui/banner.mjs +1 -1
- package/esm/ui/spinners.mjs +1 -1
- package/package.json +2 -2
- package/bin/create-app.js +0 -5
- package/templates/warlock/.env.example +0 -36
- package/templates/warlock/.gitattributes +0 -1
- package/templates/warlock/.husky/pre-commit +0 -4
- package/templates/warlock/.prettierignore +0 -4
- package/templates/warlock/.prettierrc.json +0 -10
- package/templates/warlock/.vscode/settings.json +0 -41
- package/templates/warlock/README.md +0 -57
- package/templates/warlock/_.gitignore +0 -6
- package/templates/warlock/docs/new-module.md +0 -551
- package/templates/warlock/eslint.config.js +0 -98
- package/templates/warlock/package.json +0 -74
- package/templates/warlock/public/home.css +0 -523
- package/templates/warlock/skills/api-design/SKILL.md +0 -461
- package/templates/warlock/skills/code-standards/SKILL.md +0 -595
- package/templates/warlock/skills/data-and-persistence/SKILL.md +0 -330
- package/templates/warlock/skills/git-workflow/SKILL.md +0 -282
- package/templates/warlock/skills/module-boundaries/SKILL.md +0 -283
- package/templates/warlock/skills/observability-and-resilience/SKILL.md +0 -306
- package/templates/warlock/skills/security-baseline/SKILL.md +0 -352
- package/templates/warlock/skills/testing-strategy/SKILL.md +0 -323
- package/templates/warlock/src/app/auth/controllers/forgot-password.controller.ts +0 -28
- package/templates/warlock/src/app/auth/controllers/login.controller.ts +0 -22
- package/templates/warlock/src/app/auth/controllers/logout-all.controller.ts +0 -16
- package/templates/warlock/src/app/auth/controllers/logout.controller.ts +0 -16
- package/templates/warlock/src/app/auth/controllers/me.controller.ts +0 -13
- package/templates/warlock/src/app/auth/controllers/refresh-token.controller.ts +0 -29
- package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +0 -23
- package/templates/warlock/src/app/auth/main.ts +0 -9
- package/templates/warlock/src/app/auth/models/otp/index.ts +0 -1
- package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +0 -30
- package/templates/warlock/src/app/auth/models/otp/otp.model.ts +0 -69
- package/templates/warlock/src/app/auth/requests/guarded.request.ts +0 -10
- package/templates/warlock/src/app/auth/routes.ts +0 -22
- package/templates/warlock/src/app/auth/schema/login.schema.ts +0 -8
- package/templates/warlock/src/app/auth/schema/reset-password.schema.ts +0 -9
- package/templates/warlock/src/app/auth/services/auth.service.ts +0 -66
- package/templates/warlock/src/app/auth/services/forgot-password.service.ts +0 -28
- package/templates/warlock/src/app/auth/services/otp.service.ts +0 -173
- package/templates/warlock/src/app/auth/services/reset-password.service.ts +0 -39
- package/templates/warlock/src/app/auth/utils/auth-error-code.ts +0 -6
- package/templates/warlock/src/app/auth/utils/locales.ts +0 -89
- package/templates/warlock/src/app/auth/utils/types.ts +0 -14
- package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +0 -21
- package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +0 -30
- package/templates/warlock/src/app/posts/models/post/migrations/09-01-2026_02-07-51-post.migration.ts +0 -15
- package/templates/warlock/src/app/posts/models/post/post.model.ts +0 -23
- package/templates/warlock/src/app/posts/resources/post.resource.ts +0 -14
- package/templates/warlock/src/app/posts/routes.ts +0 -8
- package/templates/warlock/src/app/posts/schema/create-post.schema.ts +0 -9
- package/templates/warlock/src/app/posts/schema/update-post.schema.ts +0 -9
- package/templates/warlock/src/app/shared/components/HomePageComponent.tsx +0 -229
- package/templates/warlock/src/app/shared/controllers/home-page.controller.ts +0 -18
- package/templates/warlock/src/app/shared/controllers/home-page.controller.tsx +0 -8
- package/templates/warlock/src/app/shared/routes.ts +0 -4
- package/templates/warlock/src/app/shared/services/scheduler.service.ts +0 -3
- package/templates/warlock/src/app/shared/tests/infrastructure.test.ts +0 -22
- package/templates/warlock/src/app/shared/utils/global-columns-schema.ts +0 -8
- package/templates/warlock/src/app/shared/utils/locales.ts +0 -766
- package/templates/warlock/src/app/shared/utils/router.ts +0 -30
- package/templates/warlock/src/app/uploads/controllers/fetch-uploaded-file.controller.ts +0 -33
- package/templates/warlock/src/app/uploads/routes.ts +0 -4
- package/templates/warlock/src/app/users/commands/hello-world.command.ts +0 -8
- package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +0 -27
- package/templates/warlock/src/app/users/controllers/list-users.controller.ts +0 -12
- package/templates/warlock/src/app/users/events/inject-created-by-user.into-model.event.ts +0 -32
- package/templates/warlock/src/app/users/events/sync.ts +0 -5
- package/templates/warlock/src/app/users/main.ts +0 -5
- package/templates/warlock/src/app/users/models/user/index.ts +0 -1
- package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +0 -15
- package/templates/warlock/src/app/users/models/user/user.model.ts +0 -64
- package/templates/warlock/src/app/users/repositories/users.repository.ts +0 -23
- package/templates/warlock/src/app/users/resources/user.resource.ts +0 -14
- package/templates/warlock/src/app/users/routes.ts +0 -8
- package/templates/warlock/src/app/users/schema/create-user.schema.ts +0 -11
- package/templates/warlock/src/app/users/seeds/users.seed.ts +0 -21
- package/templates/warlock/src/app/users/services/get-users.service.ts +0 -5
- package/templates/warlock/src/app/users/services/list-users.service.ts +0 -17
- package/templates/warlock/src/app/users/services/login-social.ts +0 -19
- package/templates/warlock/src/config/app.ts +0 -12
- package/templates/warlock/src/config/auth.ts +0 -20
- package/templates/warlock/src/config/cache.ts +0 -59
- package/templates/warlock/src/config/database.ts +0 -65
- package/templates/warlock/src/config/http.ts +0 -23
- package/templates/warlock/src/config/log.ts +0 -22
- package/templates/warlock/src/config/mail.ts +0 -16
- package/templates/warlock/src/config/repository.ts +0 -11
- package/templates/warlock/src/config/storage.ts +0 -34
- package/templates/warlock/src/config/tests.ts +0 -5
- package/templates/warlock/src/config/validation.ts +0 -7
- package/templates/warlock/storage/.gitignore +0 -2
- package/templates/warlock/tsconfig.json +0 -27
- package/templates/warlock/warlock.config.ts +0 -15
- package/templates/warlock/yarn.lock +0 -2332
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Warlock.js
|
|
2
|
-
|
|
3
|
-
A Blazing fast Nodejs framework to build comprehensive APIs.
|
|
4
|
-
|
|
5
|
-
For more knowledge about Warlock js, please visit Full documentation is in [Official Documentation](https://warlock.js.org).
|
|
6
|
-
|
|
7
|
-
## Start Development Server
|
|
8
|
-
|
|
9
|
-
To start the development server, run the following command
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
yarn start
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
OR
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm start
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Build for Production
|
|
22
|
-
|
|
23
|
-
To build the project for production, run the following command
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
yarn build
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
OR
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm run build
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Start Production Server
|
|
36
|
-
|
|
37
|
-
After building the project, run the following command to start the production server
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
yarn prod
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
To run it in background, run the following command
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
yarn serve
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
> Please note that you should have nohup installed on your system to run the server in background
|
|
50
|
-
|
|
51
|
-
## Tests
|
|
52
|
-
|
|
53
|
-
To run tests, run the following command
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
yarn test
|
|
57
|
-
```
|
|
@@ -1,551 +0,0 @@
|
|
|
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
|
|
@@ -1,98 +0,0 @@
|
|
|
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
|
-
];
|