create-warlock 4.0.174 → 4.1.2

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 (173) hide show
  1. package/cjs/index.cjs +780 -0
  2. package/cjs/index.cjs.map +1 -0
  3. package/cjs/paths-Bl9Wn7qV.cjs +247 -0
  4. package/cjs/paths-Bl9Wn7qV.cjs.map +1 -0
  5. package/cjs/project-builder-helpers-DGcgf60P.cjs +27 -0
  6. package/cjs/project-builder-helpers-DGcgf60P.cjs.map +1 -0
  7. package/esm/commands/create-new-app/get-app-path.mjs +17 -0
  8. package/esm/commands/create-new-app/get-app-path.mjs.map +1 -0
  9. package/esm/commands/create-new-app/index.mjs +152 -0
  10. package/esm/commands/create-new-app/index.mjs.map +1 -0
  11. package/esm/commands/create-new-app/types.d.mts +18 -0
  12. package/esm/commands/create-warlock-app/index.mjs +57 -0
  13. package/esm/commands/create-warlock-app/index.mjs.map +1 -0
  14. package/esm/features/database-drivers.mjs +47 -0
  15. package/esm/features/database-drivers.mjs.map +1 -0
  16. package/esm/features/features-map.mjs +157 -0
  17. package/esm/features/features-map.mjs.map +1 -0
  18. package/esm/helpers/app.mjs +157 -0
  19. package/esm/helpers/app.mjs.map +1 -0
  20. package/esm/helpers/exec.mjs +58 -0
  21. package/esm/helpers/exec.mjs.map +1 -0
  22. package/esm/helpers/package-manager.mjs +84 -0
  23. package/esm/helpers/package-manager.mjs.map +1 -0
  24. package/esm/helpers/paths.mjs +16 -0
  25. package/esm/helpers/paths.mjs.map +1 -0
  26. package/esm/helpers/project-builder-helpers.mjs +28 -0
  27. package/esm/helpers/project-builder-helpers.mjs.map +1 -0
  28. package/esm/index.d.mts +14 -0
  29. package/esm/index.mjs +83 -0
  30. package/esm/index.mjs.map +1 -0
  31. package/esm/ui/{banner.js → banner.mjs} +51 -67
  32. package/esm/ui/banner.mjs.map +1 -0
  33. package/esm/ui/spinners.mjs +23 -0
  34. package/esm/ui/spinners.mjs.map +1 -0
  35. package/llms-full.txt +121 -0
  36. package/llms.txt +9 -0
  37. package/package.json +36 -40
  38. package/skills/create-a-warlock-project/SKILL.md +111 -0
  39. package/templates/warlock/.prettierrc.json +10 -11
  40. package/templates/warlock/_.gitignore +0 -1
  41. package/templates/warlock/package.json +71 -66
  42. package/templates/warlock/src/app/auth/controllers/login.controller.ts +5 -6
  43. package/templates/warlock/src/app/auth/controllers/reset-password.controller.ts +5 -6
  44. package/templates/warlock/src/app/auth/models/otp/migrations/22-12-2025_10-30-20.otp-migration.ts +33 -43
  45. package/templates/warlock/src/app/auth/requests/guarded.request.ts +5 -1
  46. package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +5 -6
  47. package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +4 -5
  48. package/templates/warlock/src/app/posts/models/post/migrations/09-01-2026_02-07-51-post.migration.ts +21 -34
  49. package/templates/warlock/src/app/posts/models/post/post.model.ts +0 -2
  50. package/templates/warlock/src/app/posts/{validation → schema}/create-post.schema.ts +1 -1
  51. package/templates/warlock/src/app/posts/{validation → schema}/update-post.schema.ts +1 -1
  52. package/templates/warlock/src/app/shared/utils/locales.ts +34 -0
  53. package/templates/warlock/src/app/shared/utils/router.ts +1 -1
  54. package/templates/warlock/src/app/uploads/controllers/fetch-uploaded-file.controller.ts +1 -1
  55. package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +4 -4
  56. package/templates/warlock/src/app/users/controllers/list-users.controller.ts +3 -12
  57. package/templates/warlock/src/app/users/models/user/migrations/11-12-2025_23-58-03-user.migration.ts +13 -33
  58. package/templates/warlock/src/app/users/{validation → schema}/create-user.schema.ts +1 -1
  59. package/templates/warlock/storage/.gitignore +2 -0
  60. package/templates/warlock/yarn.lock +2332 -0
  61. package/cjs/commands/create-new-app/get-app-path.d.ts +0 -2
  62. package/cjs/commands/create-new-app/get-app-path.d.ts.map +0 -1
  63. package/cjs/commands/create-new-app/get-app-path.js +0 -8
  64. package/cjs/commands/create-new-app/get-app-path.js.map +0 -1
  65. package/cjs/commands/create-new-app/index.d.ts +0 -2
  66. package/cjs/commands/create-new-app/index.d.ts.map +0 -1
  67. package/cjs/commands/create-new-app/index.js +0 -96
  68. package/cjs/commands/create-new-app/index.js.map +0 -1
  69. package/cjs/commands/create-new-app/types.d.ts +0 -16
  70. package/cjs/commands/create-new-app/types.d.ts.map +0 -1
  71. package/cjs/commands/create-warlock-app/index.d.ts +0 -3
  72. package/cjs/commands/create-warlock-app/index.d.ts.map +0 -1
  73. package/cjs/commands/create-warlock-app/index.js +0 -55
  74. package/cjs/commands/create-warlock-app/index.js.map +0 -1
  75. package/cjs/features/database-drivers.d.ts +0 -31
  76. package/cjs/features/database-drivers.d.ts.map +0 -1
  77. package/cjs/features/database-drivers.js +0 -53
  78. package/cjs/features/database-drivers.js.map +0 -1
  79. package/cjs/features/features-map.d.ts +0 -35
  80. package/cjs/features/features-map.d.ts.map +0 -1
  81. package/cjs/features/features-map.js +0 -120
  82. package/cjs/features/features-map.js.map +0 -1
  83. package/cjs/helpers/app.d.ts +0 -71
  84. package/cjs/helpers/app.d.ts.map +0 -1
  85. package/cjs/helpers/app.js +0 -196
  86. package/cjs/helpers/app.js.map +0 -1
  87. package/cjs/helpers/exec.d.ts +0 -10
  88. package/cjs/helpers/exec.d.ts.map +0 -1
  89. package/cjs/helpers/exec.js +0 -69
  90. package/cjs/helpers/exec.js.map +0 -1
  91. package/cjs/helpers/package-manager.d.ts +0 -18
  92. package/cjs/helpers/package-manager.d.ts.map +0 -1
  93. package/cjs/helpers/package-manager.js +0 -104
  94. package/cjs/helpers/package-manager.js.map +0 -1
  95. package/cjs/helpers/paths.d.ts +0 -4
  96. package/cjs/helpers/paths.d.ts.map +0 -1
  97. package/cjs/helpers/paths.js +0 -8
  98. package/cjs/helpers/paths.js.map +0 -1
  99. package/cjs/helpers/project-builder-helpers.d.ts +0 -6
  100. package/cjs/helpers/project-builder-helpers.d.ts.map +0 -1
  101. package/cjs/helpers/project-builder-helpers.js +0 -11
  102. package/cjs/helpers/project-builder-helpers.js.map +0 -1
  103. package/cjs/index.d.ts +0 -2
  104. package/cjs/index.d.ts.map +0 -1
  105. package/cjs/index.js +0 -3
  106. package/cjs/index.js.map +0 -1
  107. package/cjs/ui/banner.d.ts +0 -29
  108. package/cjs/ui/banner.d.ts.map +0 -1
  109. package/cjs/ui/banner.js +0 -142
  110. package/cjs/ui/banner.js.map +0 -1
  111. package/cjs/ui/spinners.d.ts +0 -18
  112. package/cjs/ui/spinners.d.ts.map +0 -1
  113. package/cjs/ui/spinners.js +0 -17
  114. package/cjs/ui/spinners.js.map +0 -1
  115. package/create-app.js +0 -5
  116. package/esm/commands/create-new-app/get-app-path.d.ts +0 -2
  117. package/esm/commands/create-new-app/get-app-path.d.ts.map +0 -1
  118. package/esm/commands/create-new-app/get-app-path.js +0 -8
  119. package/esm/commands/create-new-app/get-app-path.js.map +0 -1
  120. package/esm/commands/create-new-app/index.d.ts +0 -2
  121. package/esm/commands/create-new-app/index.d.ts.map +0 -1
  122. package/esm/commands/create-new-app/index.js +0 -96
  123. package/esm/commands/create-new-app/index.js.map +0 -1
  124. package/esm/commands/create-new-app/types.d.ts +0 -16
  125. package/esm/commands/create-new-app/types.d.ts.map +0 -1
  126. package/esm/commands/create-warlock-app/index.d.ts +0 -3
  127. package/esm/commands/create-warlock-app/index.d.ts.map +0 -1
  128. package/esm/commands/create-warlock-app/index.js +0 -55
  129. package/esm/commands/create-warlock-app/index.js.map +0 -1
  130. package/esm/features/database-drivers.d.ts +0 -31
  131. package/esm/features/database-drivers.d.ts.map +0 -1
  132. package/esm/features/database-drivers.js +0 -53
  133. package/esm/features/database-drivers.js.map +0 -1
  134. package/esm/features/features-map.d.ts +0 -35
  135. package/esm/features/features-map.d.ts.map +0 -1
  136. package/esm/features/features-map.js +0 -120
  137. package/esm/features/features-map.js.map +0 -1
  138. package/esm/helpers/app.d.ts +0 -71
  139. package/esm/helpers/app.d.ts.map +0 -1
  140. package/esm/helpers/app.js +0 -196
  141. package/esm/helpers/app.js.map +0 -1
  142. package/esm/helpers/exec.d.ts +0 -10
  143. package/esm/helpers/exec.d.ts.map +0 -1
  144. package/esm/helpers/exec.js +0 -69
  145. package/esm/helpers/exec.js.map +0 -1
  146. package/esm/helpers/package-manager.d.ts +0 -18
  147. package/esm/helpers/package-manager.d.ts.map +0 -1
  148. package/esm/helpers/package-manager.js +0 -104
  149. package/esm/helpers/package-manager.js.map +0 -1
  150. package/esm/helpers/paths.d.ts +0 -4
  151. package/esm/helpers/paths.d.ts.map +0 -1
  152. package/esm/helpers/paths.js +0 -8
  153. package/esm/helpers/paths.js.map +0 -1
  154. package/esm/helpers/project-builder-helpers.d.ts +0 -6
  155. package/esm/helpers/project-builder-helpers.d.ts.map +0 -1
  156. package/esm/helpers/project-builder-helpers.js +0 -11
  157. package/esm/helpers/project-builder-helpers.js.map +0 -1
  158. package/esm/index.d.ts +0 -2
  159. package/esm/index.d.ts.map +0 -1
  160. package/esm/index.js +0 -3
  161. package/esm/index.js.map +0 -1
  162. package/esm/ui/banner.d.ts +0 -29
  163. package/esm/ui/banner.d.ts.map +0 -1
  164. package/esm/ui/banner.js.map +0 -1
  165. package/esm/ui/spinners.d.ts +0 -18
  166. package/esm/ui/spinners.d.ts.map +0 -1
  167. package/esm/ui/spinners.js +0 -17
  168. package/esm/ui/spinners.js.map +0 -1
  169. package/templates/warlock/src/app/auth/requests/login.request.ts +0 -4
  170. package/templates/warlock/src/app/auth/requests/reset-password.request.ts +0 -4
  171. package/templates/warlock/src/app/posts/requests/create-post.request.ts +0 -4
  172. package/templates/warlock/src/app/posts/requests/update-post.request.ts +0 -4
  173. package/templates/warlock/src/app/users/requests/create-user.request.ts +0 -4
package/llms-full.txt ADDED
@@ -0,0 +1,121 @@
1
+ # Warlock Create Warlock — full skills
2
+
3
+ > Package: `create-warlock`
4
+
5
+ > Generated artifact. Concatenates every SKILL.md and reference file under `create-warlock/skills/`. Re-run `node scripts/generate-llms.mjs` after any change.
6
+
7
+ ## create-a-warlock-project `create-warlock/create-a-warlock-project/SKILL.md`
8
+
9
+ ---
10
+ name: create-a-warlock-project
11
+ description: 'Scaffold a brand-new Warlock.js project with `create-warlock` — the interactive wizard and its non-interactive flag set. Every flag (`--name`, `--db`, `--pm`, `--features`, `--ai`, `--git/--no-git`, `--jwt/--no-jwt`, `--yes`), every valid database-driver / feature / AI-provider key, and the directory tree the template emits. Triggers: `create-warlock`, `yarn create warlock`, `npm create warlock`, `npx create-warlock`; "scaffold a warlock app", "start a new warlock project", "create-warlock flags", "non-interactive warlock scaffold", "which features can I pass to create-warlock". Skip: running an already-created project (`@warlock.js/core/run-app/SKILL.md`); adding a feature to an existing project (`warlock add`, `@warlock.js/core/add-connector/SKILL.md`); generating a module inside a project (`@warlock.js/core/create-module/SKILL.md`).'
12
+ ---
13
+
14
+ # create-warlock — scaffold a new project
15
+
16
+ `create-warlock` builds a fresh Warlock.js project: it copies the `warlock` template, substitutes the project name, wires the chosen database driver into `.env`, then delegates every optional package install to the project's own `warlock add` so dependency versions are never duplicated by the scaffolder.
17
+
18
+ ## The shape
19
+
20
+ ```bash
21
+ # Interactive wizard (recommended for humans)
22
+ yarn create warlock
23
+ # or: npm create warlock@latest / pnpm create warlock / npx create-warlock
24
+
25
+ # Non-interactive (CI, agents, reproducible setups)
26
+ npx create-warlock my-app --yes --db=postgres --features=test,redis --ai=openai
27
+ ```
28
+
29
+ The first positional argument is the project name; it also becomes the directory created under the current working directory. If that directory already exists, the command aborts — it never overwrites.
30
+
31
+ ## Interactive flow
32
+
33
+ The wizard asks, in order:
34
+
35
+ 1. **Project name** — required.
36
+ 2. **Package manager** — chosen from the managers detected on the system (npm is always offered; yarn / pnpm appear if installed).
37
+ 3. **Database driver** — a single select (see keys below).
38
+ 4. **Features** — a multiselect of optional packages (`react` is pre-checked).
39
+ 5. **AI providers** — a multiselect; picking any one pulls `@warlock.js/ai` automatically.
40
+ 6. **Initialize Git?** — yes/no.
41
+ 7. **Generate JWT secret keys?** — yes/no. If no, the cache is warmed instead.
42
+
43
+ ## Non-interactive flags
44
+
45
+ Pass `--yes` (or `-y`) to skip every prompt and build from flags with defaults.
46
+
47
+ | Flag | Takes value | Default | Purpose |
48
+ | ------------------------ | ----------- | -------------- | ------------------------------------------------------------------- |
49
+ | `<positional>` / `--name`| yes | — (required) | Project name + target directory. |
50
+ | `--db` | yes | `mongodb` | Database driver key. |
51
+ | `--pm` | yes | auto-detected | Package manager (`npm` / `yarn` / `pnpm`). |
52
+ | `--features` | yes (CSV) | none | Comma-separated optional feature keys. |
53
+ | `--ai` | yes (CSV) | none | Comma-separated AI provider keys (auto-pulls `@warlock.js/ai`). |
54
+ | `--git` / `--no-git` | no | off | Initialize a Git repo (`git init` + `main` branch + initial commit).|
55
+ | `--jwt` / `--no-jwt` | no | off | Generate JWT secrets via the project's `jwt` script. |
56
+ | `--yes` / `-y` | no | off | Non-interactive mode. |
57
+
58
+ Value flags accept either `--db=postgres` or `--db postgres`. Unknown `--features` / `--ai` keys fail fast before any install.
59
+
60
+ ## Valid keys
61
+
62
+ **Database drivers** (`--db`):
63
+
64
+ | Key | Default port | Status |
65
+ | ---------- | ------------ | ----------- |
66
+ | `mongodb` | 27017 | available |
67
+ | `postgres` | 5432 | available |
68
+ | `mysql` | 3306 | coming soon (disabled in the wizard) |
69
+
70
+ **Features** (`--features`): `react`, `react-email`, `mail`, `ses`, `image`, `s3`, `redis`, `scheduler`, `herald`, `socket`, `swagger`, `postman`, `test`.
71
+
72
+ **AI providers** (`--ai`): `openai`, `google`, `anthropic`, `bedrock`, `ollama`.
73
+
74
+ > The scaffolder holds **no dependency versions** for these — the keys map to `warlock add <key>`, whose feature map in `@warlock.js/core` is the single source of truth. A feature that resolves there will install; one that does not is rejected.
75
+
76
+ ## What gets generated
77
+
78
+ ```
79
+ my-app/
80
+ ├─ .env # copied from .env.example, name + DB driver/port substituted
81
+ ├─ .env.example
82
+ ├─ .gitignore # renamed from the template's _.gitignore
83
+ ├─ package.json # "name" set to the project name
84
+ ├─ tsconfig.json
85
+ ├─ warlock.config.ts
86
+ └─ src/
87
+ ├─ config/ # app, auth, cache, database, http, log, mail, repository, storage, tests, validation
88
+ └─ app/
89
+ ├─ auth/ # controllers, schema, services, requests, utils, OTP model + migration
90
+ ├─ users/ # model, migration, resource, repository, create + list controllers, schema, events, seeds, commands
91
+ ├─ posts/ # sample module — model, migration, resource, schema, create + update controllers
92
+ ├─ uploads/ # file-serving controller (fetch-uploaded-file)
93
+ └─ shared/ # router/locale utils, home page, scheduler, global columns schema
94
+ ```
95
+
96
+ The template ships a working auth module (login / logout / logout-all / refresh / me / forgot + reset password via OTP), a `users` module, and a sample `posts` module — all using the current framework surface: schemas via `v` from `@warlock.js/seal`, controllers typed with `GuardedRequestHandler` carrying a `.validation = { schema }`, models on `@warlock.js/cascade`, and declarative migrations via `Migration.create`.
97
+
98
+ ## Setup steps the scaffolder runs
99
+
100
+ 1. Copy template → substitute name → wire `DB_DRIVER` / `DB_PORT` into `.env`.
101
+ 2. Install base dependencies (so the `warlock` binary exists).
102
+ 3. `warlock add <driver> <features...> <ai...> --no-install`, then one batched install.
103
+ 4. `git init` (if `--git`).
104
+ 5. `jwt` script (if `--jwt`) — otherwise `warlock --warm-cache`.
105
+
106
+ Failures surface the error and halt; there is no rollback. After it finishes, `cd my-app` and run the dev server.
107
+
108
+ ## Gotchas
109
+
110
+ - **The target directory must not already exist** — the command exits rather than merge into it.
111
+ - **`--ai` never takes `ai` itself.** Pick a provider (`openai`, …); the core `@warlock.js/ai` package is pulled in transitively.
112
+ - **`mysql` is disabled** in the wizard; passing `--db=mysql` resolves the driver record but the driver is marked coming-soon.
113
+ - **Versions are not the scaffolder's job.** If a feature installs the wrong version, the fix is in core's `warlock add` feature map, not here.
114
+
115
+ ## See also
116
+
117
+ - `@warlock.js/core/run-app/SKILL.md` — `warlock dev` / `build` / `start` once the project exists.
118
+ - `@warlock.js/core/create-module/SKILL.md` — generate a new module inside the project.
119
+ - `@warlock.js/core/add-connector/SKILL.md` — what `warlock add` wires when a feature pulls a connector.
120
+
121
+
package/llms.txt ADDED
@@ -0,0 +1,9 @@
1
+ # Warlock Create Warlock
2
+
3
+ > Package: `create-warlock`
4
+
5
+ > Project scaffolder for the Warlock.js framework — interactive wizard and non-interactive CLI for creating new apps.
6
+
7
+ ## Skills
8
+
9
+ - [create-a-warlock-project](create-warlock/create-a-warlock-project/SKILL.md): Scaffold a brand-new Warlock.js project with `create-warlock` — the interactive wizard and its non-interactive flag set. Every flag (`--name`, `--db`, `--pm`, `--features`, `--ai`, `--git/--no-git`, `--jwt/--no-jwt`, `--yes`), every valid database-driver / feature / AI-provider key, and the directory tree the template emits. Triggers: `create-warlock`, `yarn create warlock`, `npm create warlock`, `npx create-warlock`; "scaffold a warlock app", "start a new warlock project", "create-warlock flags", "non-interactive warlock scaffold", "which features can I pass to create-warlock". Skip: running an already-created project (`@warlock.js/core/run-app/SKILL.md`); adding a feature to an existing project (`warlock add`, `@warlock.js/core/add-connector/SKILL.md`); generating a module inside a project (`@warlock.js/core/create-module/SKILL.md`).
package/package.json CHANGED
@@ -1,41 +1,37 @@
1
1
  {
2
- "name": "create-warlock",
3
- "version": "4.0.174",
4
- "main": "./esm/index.js",
5
- "license": "MIT",
6
- "type": "module",
7
- "bin": {
8
- "create-warlock": "./create-app.js"
9
- },
10
- "scripts": {
11
- "start": "npx tsx ./index.dev.ts",
12
- "lint": "npx eslint -c ./.eslintrc.json ./src",
13
- "fix": "npx eslint --fix -c ./.eslintrc.json ./src --max-warnings=0",
14
- "format": "npx prettier --write ./src/**/*.{js,jsx,ts,tsx,css,md,json} --config ./.prettierrc.json",
15
- "update": "npx tsx version-checker.ts"
16
- },
17
- "dependencies": {
18
- "@clack/prompts": "^0.7.0",
19
- "@mongez/copper": "^1.0.1",
20
- "@mongez/fs": "^3.0.5",
21
- "@mongez/reinforcements": "^2.3.17",
22
- "cross-spawn": "^7.0.3",
23
- "rimraf": "^6.0.1",
24
- "which-pm-runs": "^1.1.0"
25
- },
26
- "devDependencies": {
27
- "@types/node": "^20.12.7",
28
- "@typescript-eslint/eslint-plugin": "^7.7.0",
29
- "@typescript-eslint/parser": "^7.7.0",
30
- "eslint": "^8.56.0",
31
- "eslint-config-prettier": "^9.1.0",
32
- "eslint-plugin-prettier": "^5.1.3",
33
- "eslint-plugin-unused-imports": "^3.1.0",
34
- "prettier": "^3.2.5",
35
- "prettier-plugin-organize-imports": "^3.2.4",
36
- "tsx": "^4.21.0",
37
- "typescript": "^5.4.5"
38
- },
39
- "module": "./esm/index.js",
40
- "typings": "./esm/index.d.ts"
41
- }
2
+ "name": "create-warlock",
3
+ "description": "Project scaffolder for the Warlock.js framework — interactive wizard and non-interactive CLI for creating new apps.",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/warlockjs/create-warlock"
8
+ },
9
+ "dependencies": {
10
+ "@clack/prompts": "^0.7.0",
11
+ "@mongez/copper": "^2.1.2",
12
+ "@warlock.js/fs": "4.1.2",
13
+ "@mongez/reinforcements": "^3.2.0",
14
+ "cross-spawn": "^7.0.3",
15
+ "rimraf": "^6.0.1",
16
+ "which-pm-runs": "^1.1.0"
17
+ },
18
+ "bin": {
19
+ "create-warlock": "create-app.js"
20
+ },
21
+ "version": "4.1.2",
22
+ "main": "./cjs/index.cjs",
23
+ "module": "./esm/index.mjs",
24
+ "types": "./esm/index.d.mts",
25
+ "exports": {
26
+ ".": {
27
+ "import": {
28
+ "types": "./esm/index.d.mts",
29
+ "default": "./esm/index.mjs"
30
+ },
31
+ "require": {
32
+ "types": "./esm/index.d.mts",
33
+ "default": "./cjs/index.cjs"
34
+ }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: create-a-warlock-project
3
+ description: 'Scaffold a brand-new Warlock.js project with `create-warlock` — the interactive wizard and its non-interactive flag set. Every flag (`--name`, `--db`, `--pm`, `--features`, `--ai`, `--git/--no-git`, `--jwt/--no-jwt`, `--yes`), every valid database-driver / feature / AI-provider key, and the directory tree the template emits. Triggers: `create-warlock`, `yarn create warlock`, `npm create warlock`, `npx create-warlock`; "scaffold a warlock app", "start a new warlock project", "create-warlock flags", "non-interactive warlock scaffold", "which features can I pass to create-warlock". Skip: running an already-created project (`@warlock.js/core/run-app/SKILL.md`); adding a feature to an existing project (`warlock add`, `@warlock.js/core/add-connector/SKILL.md`); generating a module inside a project (`@warlock.js/core/create-module/SKILL.md`).'
4
+ ---
5
+
6
+ # create-warlock — scaffold a new project
7
+
8
+ `create-warlock` builds a fresh Warlock.js project: it copies the `warlock` template, substitutes the project name, wires the chosen database driver into `.env`, then delegates every optional package install to the project's own `warlock add` so dependency versions are never duplicated by the scaffolder.
9
+
10
+ ## The shape
11
+
12
+ ```bash
13
+ # Interactive wizard (recommended for humans)
14
+ yarn create warlock
15
+ # or: npm create warlock@latest / pnpm create warlock / npx create-warlock
16
+
17
+ # Non-interactive (CI, agents, reproducible setups)
18
+ npx create-warlock my-app --yes --db=postgres --features=test,redis --ai=openai
19
+ ```
20
+
21
+ The first positional argument is the project name; it also becomes the directory created under the current working directory. If that directory already exists, the command aborts — it never overwrites.
22
+
23
+ ## Interactive flow
24
+
25
+ The wizard asks, in order:
26
+
27
+ 1. **Project name** — required.
28
+ 2. **Package manager** — chosen from the managers detected on the system (npm is always offered; yarn / pnpm appear if installed).
29
+ 3. **Database driver** — a single select (see keys below).
30
+ 4. **Features** — a multiselect of optional packages (`react` is pre-checked).
31
+ 5. **AI providers** — a multiselect; picking any one pulls `@warlock.js/ai` automatically.
32
+ 6. **Initialize Git?** — yes/no.
33
+ 7. **Generate JWT secret keys?** — yes/no. If no, the cache is warmed instead.
34
+
35
+ ## Non-interactive flags
36
+
37
+ Pass `--yes` (or `-y`) to skip every prompt and build from flags with defaults.
38
+
39
+ | Flag | Takes value | Default | Purpose |
40
+ | ------------------------ | ----------- | -------------- | ------------------------------------------------------------------- |
41
+ | `<positional>` / `--name`| yes | — (required) | Project name + target directory. |
42
+ | `--db` | yes | `mongodb` | Database driver key. |
43
+ | `--pm` | yes | auto-detected | Package manager (`npm` / `yarn` / `pnpm`). |
44
+ | `--features` | yes (CSV) | none | Comma-separated optional feature keys. |
45
+ | `--ai` | yes (CSV) | none | Comma-separated AI provider keys (auto-pulls `@warlock.js/ai`). |
46
+ | `--git` / `--no-git` | no | off | Initialize a Git repo (`git init` + `main` branch + initial commit).|
47
+ | `--jwt` / `--no-jwt` | no | off | Generate JWT secrets via the project's `jwt` script. |
48
+ | `--yes` / `-y` | no | off | Non-interactive mode. |
49
+
50
+ Value flags accept either `--db=postgres` or `--db postgres`. Unknown `--features` / `--ai` keys fail fast before any install.
51
+
52
+ ## Valid keys
53
+
54
+ **Database drivers** (`--db`):
55
+
56
+ | Key | Default port | Status |
57
+ | ---------- | ------------ | ----------- |
58
+ | `mongodb` | 27017 | available |
59
+ | `postgres` | 5432 | available |
60
+ | `mysql` | 3306 | coming soon (disabled in the wizard) |
61
+
62
+ **Features** (`--features`): `react`, `react-email`, `mail`, `ses`, `image`, `s3`, `redis`, `scheduler`, `herald`, `socket`, `swagger`, `postman`, `test`.
63
+
64
+ **AI providers** (`--ai`): `openai`, `google`, `anthropic`, `bedrock`, `ollama`.
65
+
66
+ > The scaffolder holds **no dependency versions** for these — the keys map to `warlock add <key>`, whose feature map in `@warlock.js/core` is the single source of truth. A feature that resolves there will install; one that does not is rejected.
67
+
68
+ ## What gets generated
69
+
70
+ ```
71
+ my-app/
72
+ ├─ .env # copied from .env.example, name + DB driver/port substituted
73
+ ├─ .env.example
74
+ ├─ .gitignore # renamed from the template's _.gitignore
75
+ ├─ package.json # "name" set to the project name
76
+ ├─ tsconfig.json
77
+ ├─ warlock.config.ts
78
+ └─ src/
79
+ ├─ config/ # app, auth, cache, database, http, log, mail, repository, storage, tests, validation
80
+ └─ app/
81
+ ├─ auth/ # controllers, schema, services, requests, utils, OTP model + migration
82
+ ├─ users/ # model, migration, resource, repository, create + list controllers, schema, events, seeds, commands
83
+ ├─ posts/ # sample module — model, migration, resource, schema, create + update controllers
84
+ ├─ uploads/ # file-serving controller (fetch-uploaded-file)
85
+ └─ shared/ # router/locale utils, home page, scheduler, global columns schema
86
+ ```
87
+
88
+ The template ships a working auth module (login / logout / logout-all / refresh / me / forgot + reset password via OTP), a `users` module, and a sample `posts` module — all using the current framework surface: schemas via `v` from `@warlock.js/seal`, controllers typed with `GuardedRequestHandler` carrying a `.validation = { schema }`, models on `@warlock.js/cascade`, and declarative migrations via `Migration.create`.
89
+
90
+ ## Setup steps the scaffolder runs
91
+
92
+ 1. Copy template → substitute name → wire `DB_DRIVER` / `DB_PORT` into `.env`.
93
+ 2. Install base dependencies (so the `warlock` binary exists).
94
+ 3. `warlock add <driver> <features...> <ai...> --no-install`, then one batched install.
95
+ 4. `git init` (if `--git`).
96
+ 5. `jwt` script (if `--jwt`) — otherwise `warlock --warm-cache`.
97
+
98
+ Failures surface the error and halt; there is no rollback. After it finishes, `cd my-app` and run the dev server.
99
+
100
+ ## Gotchas
101
+
102
+ - **The target directory must not already exist** — the command exits rather than merge into it.
103
+ - **`--ai` never takes `ai` itself.** Pick a provider (`openai`, …); the core `@warlock.js/ai` package is pulled in transitively.
104
+ - **`mysql` is disabled** in the wizard; passing `--db=mysql` resolves the driver record but the driver is marked coming-soon.
105
+ - **Versions are not the scaffolder's job.** If a feature installs the wrong version, the fix is in core's `warlock add` feature map, not here.
106
+
107
+ ## See also
108
+
109
+ - `@warlock.js/core/run-app/SKILL.md` — `warlock dev` / `build` / `start` once the project exists.
110
+ - `@warlock.js/core/create-module/SKILL.md` — generate a new module inside the project.
111
+ - `@warlock.js/core/add-connector/SKILL.md` — what `warlock add` wires when a feature pulls a connector.
@@ -1,11 +1,10 @@
1
- {
2
- "semi": true,
3
- "tabWidth": 2,
4
- "printWidth": 80,
5
- "singleQuote": false,
6
- "arrowParens": "avoid",
7
- "trailingComma": "all",
8
- "bracketSameLine": true,
9
- "endOfLine": "lf",
10
- "plugins": ["prettier-plugin-organize-imports"]
11
- }
1
+ {
2
+ "semi": true,
3
+ "tabWidth": 2,
4
+ "printWidth": 100,
5
+ "singleQuote": false,
6
+ "arrowParens": "always",
7
+ "trailingComma": "all",
8
+ "endOfLine": "lf",
9
+ "plugins": ["prettier-plugin-organize-imports"]
10
+ }
@@ -1,7 +1,6 @@
1
1
  node_modules
2
2
  build
3
3
  dist
4
- storage/*
5
4
  .env
6
5
  .warlock/
7
6
  nohup.out
@@ -1,68 +1,73 @@
1
1
  {
2
- "name": "wow2",
3
- "version": "1.0.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "warlock dev",
8
- "build": "tsc && warlock build",
9
- "start": "warlock start",
10
- "seed": "warlock seed",
11
- "migrate": "warlock migrate",
12
- "migrate.fresh": "warlock migrate --fresh",
13
- "migrate.list": "warlock migrate --list",
14
- "jwt": "warlock jwt.generate",
15
- "gen": "warlock generate.module",
16
- "gen.s": "warlock.generate.service",
17
- "gen.m": "warlock.generate.model",
18
- "gen.c": "warlock.generate.controller",
19
- "gen.mig": "warlock generate.migration",
20
- "gen.md": "warlock generate.model",
21
- "gen.r": "warlock generate.repository",
22
- "gen.rs": "warlock generate.resource",
23
- "gen.v": "warlock generate.validation",
24
- "serve": "yarn build && nohup warlock start > /dev/null 2>&1",
25
- "lint": "npx eslint --fix ./src --max-warnings=0",
26
- "format": "npx prettier --write ./src/**/*.{js,jsx,ts,tsx,css,md,json} --config ./.prettierrc.json",
27
- "tsc": "npx tsc --noEmit",
28
- "prepare": "huskier-init && husky install",
29
- "lf": "find . -type d ( -name 'node_modules' -o -name '.git' ) -prune -o -type f -exec dos2unix {} ;"
30
- },
31
- "dependencies": {
32
- "@mongez/reinforcements": "^2.3.17",
33
- "@mongez/localization": "^3.2.1",
34
- "@mongez/supportive-is": "^2.0.4",
35
- "@warlock.js/auth": "4.0.174",
36
- "@warlock.js/cache": "4.0.174",
37
- "@warlock.js/cascade": "4.0.174",
38
- "@warlock.js/scheduler": "4.0.174",
39
- "@warlock.js/core": "4.0.174",
40
- "@warlock.js/logger": "4.0.174",
41
- "@warlock.js/seal": "4.0.174",
42
- "dayjs": "^1.11.19"
43
- },
44
- "devDependencies": {
45
- "@mongez/huskier": "^3.0.0",
46
- "@types/node": "^25.0.3",
47
- "@types/prettier": "^3.0.0",
48
- "@typescript-eslint/eslint-plugin": "^8.50.0",
49
- "@typescript-eslint/parser": "^8.50.0",
50
- "eslint": "^9.39.2",
51
- "eslint-config-prettier": "^10.1.8",
52
- "eslint-plugin-prettier": "^5.5.4",
53
- "eslint-plugin-unused-imports": "^4.3.0",
54
- "prettier": "^3.7.4",
55
- "prettier-plugin-organize-imports": "^4.3.0",
56
- "typescript": "^5.9.3",
57
- "husky": "^8.0.0"
58
- },
59
- "huskier": {
60
- "hooks": {
61
- "pre-commit": [
62
- "yarn format",
63
- "yarn lint",
64
- "yarn tsc"
65
- ]
66
- }
2
+ "name": "wow2",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "warlock dev",
8
+ "build": "tsc && warlock build",
9
+ "start": "warlock start",
10
+ "seed": "warlock seed",
11
+ "migrate": "warlock migrate",
12
+ "migrate.fresh": "warlock migrate --fresh",
13
+ "migrate.list": "warlock migrate --list",
14
+ "jwt": "warlock jwt.generate",
15
+ "gen": "warlock generate.module",
16
+ "gen.s": "warlock.generate.service",
17
+ "gen.m": "warlock.generate.model",
18
+ "gen.c": "warlock.generate.controller",
19
+ "gen.mig": "warlock generate.migration",
20
+ "gen.md": "warlock generate.model",
21
+ "gen.r": "warlock generate.repository",
22
+ "gen.rs": "warlock generate.resource",
23
+ "gen.v": "warlock generate.validation",
24
+ "serve": "yarn build && nohup warlock start > /dev/null 2>&1",
25
+ "lint": "npx eslint --fix ./src --max-warnings=0",
26
+ "format": "npx prettier --write ./src/**/*.{js,jsx,ts,tsx,css,md,json} --config ./.prettierrc.json",
27
+ "tsc": "npx tsc --noEmit",
28
+ "prepare": "huskier-init && husky install",
29
+ "postinstall": "agent-kit sync",
30
+ "skills:sync": "agent-kit sync",
31
+ "skills:watch": "agent-kit watch",
32
+ "lf": "find . -type d ( -name 'node_modules' -o -name '.git' ) -prune -o -type f -exec dos2unix {} ;"
33
+ },
34
+ "dependencies": {
35
+ "@mongez/reinforcements": "^3.1.16",
36
+ "@mongez/localization": "^3.4.6",
37
+ "@mongez/supportive-is": "^2.1.3",
38
+ "@warlock.js/auth": "4.0.119",
39
+ "@warlock.js/cache": "4.0.119",
40
+ "@warlock.js/cascade": "4.0.119",
41
+ "@warlock.js/scheduler": "4.0.119",
42
+ "@warlock.js/core": "4.0.119",
43
+ "@warlock.js/fs": "4.0.119",
44
+ "@warlock.js/logger": "4.0.119",
45
+ "@warlock.js/seal": "4.0.119",
46
+ "dayjs": "^1.11.19"
47
+ },
48
+ "devDependencies": {
49
+ "@mongez/agent-kit": "^1.0.17",
50
+ "@mongez/huskier": "^3.0.0",
51
+ "@types/node": "^25.0.3",
52
+ "@types/prettier": "^3.0.0",
53
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
54
+ "@typescript-eslint/parser": "^8.50.0",
55
+ "eslint": "^9.39.2",
56
+ "eslint-config-prettier": "^10.1.8",
57
+ "eslint-plugin-prettier": "^5.5.4",
58
+ "eslint-plugin-unused-imports": "^4.3.0",
59
+ "prettier": "^3.7.4",
60
+ "prettier-plugin-organize-imports": "^4.3.0",
61
+ "typescript": "^5.9.3",
62
+ "husky": "^8.0.0"
63
+ },
64
+ "huskier": {
65
+ "hooks": {
66
+ "pre-commit": [
67
+ "yarn format",
68
+ "yarn lint",
69
+ "yarn tsc"
70
+ ]
67
71
  }
68
- }
72
+ }
73
+ }
@@ -1,15 +1,14 @@
1
- import { type RequestHandler, type Response } from "@warlock.js/core";
2
- import { type LoginRequest } from "../requests/login.request";
3
- import { loginSchema } from "../schema/login.schema";
1
+ import { type Request, type RequestHandler } from "@warlock.js/core";
2
+ import { type LoginSchema, loginSchema } from "../schema/login.schema";
4
3
  import { loginService } from "../services/auth.service";
5
4
 
6
5
  /**
7
6
  * Login controller
8
7
  * POST /auth/login
9
8
  */
10
- export const loginController: RequestHandler = async (
11
- request: LoginRequest,
12
- response: Response,
9
+ export const loginController: RequestHandler<Request<LoginSchema>> = async (
10
+ request,
11
+ response,
13
12
  ) => {
14
13
  const result = await loginService(request.validated(), {
15
14
  userAgent: request.userAgent,
@@ -1,14 +1,13 @@
1
- import { t, type Response } from "@warlock.js/core";
2
- import { type ResetPasswordRequest } from "../requests/reset-password.request";
3
- import { resetPasswordSchema } from "../schema/reset-password.schema";
1
+ import { t, type Request, type RequestHandler } from "@warlock.js/core";
2
+ import { type ResetPasswordSchema, resetPasswordSchema } from "../schema/reset-password.schema";
4
3
  import { resetPasswordService } from "../services/reset-password.service";
5
4
 
6
5
  /**
7
6
  * Reset password controller
8
7
  */
9
- export const resetPasswordController = async (
10
- request: ResetPasswordRequest,
11
- response: Response,
8
+ export const resetPasswordController: RequestHandler<Request<ResetPasswordSchema>> = async (
9
+ request,
10
+ response,
12
11
  ) => {
13
12
  await resetPasswordService(request.validated());
14
13
 
@@ -1,47 +1,37 @@
1
- import { migrate } from "@warlock.js/cascade";
1
+ import {
2
+ bool,
3
+ integer,
4
+ json,
5
+ Migration,
6
+ string,
7
+ timestamp,
8
+ } from "@warlock.js/cascade";
2
9
  import { OTP } from "../otp.model";
3
10
 
4
- export default migrate(OTP, {
5
- name: "otp",
6
- createdAt: "2025-12-22T10:30:20",
7
- up() {
8
- // Create table
9
- this.createTableIfNotExists();
10
-
11
- // Primary key
12
- this.id();
13
-
14
- // OTP fields
15
- this.string("code", 20);
16
- this.string("type", 50);
17
- this.string("target", 255);
18
- this.string("channel", 50);
19
- this.integer("userId");
20
- this.string("userType", 50);
21
- this.timestamp("expiresAt");
22
- this.timestamp("usedAt").nullable();
23
- this.integer("attempts").default(0);
24
- this.integer("maxAttempts").default(5);
25
- this.json("metadata").nullable();
26
-
27
- // Status
28
- this.boolean("isActive").default(true);
29
-
30
- // Embedded user references (JSONB)
31
- this.json("createdBy").nullable();
32
- this.json("updatedBy").nullable();
33
- this.json("deletedBy").nullable();
34
-
35
- // Timestamps
36
- this.timestamps();
37
-
38
- // Indexes for common queries
39
- this.index("code");
40
- this.index(["target", "type"]);
41
- this.index("expiresAt");
42
- this.index("userId");
11
+ export default Migration.create(
12
+ OTP,
13
+ {
14
+ code: string(20).index(),
15
+ type: string(50),
16
+ target: string(255),
17
+ channel: string(50),
18
+ userId: integer().index(),
19
+ userType: string(50),
20
+ expiresAt: timestamp().index(),
21
+ usedAt: timestamp().nullable(),
22
+ attempts: integer(),
23
+ maxAttempts: integer(),
24
+ metadata: json().nullable(),
25
+ isActive: bool(),
26
+ createdBy: json().nullable(),
27
+ updatedBy: json().nullable(),
28
+ deletedBy: json().nullable(),
43
29
  },
44
- down() {
45
- this.dropTableIfExists();
30
+ {
31
+ index: [
32
+ {
33
+ columns: ["target", "type"],
34
+ },
35
+ ],
46
36
  },
47
- });
37
+ );
@@ -1,7 +1,11 @@
1
- import type { Request } from "@warlock.js/core";
1
+ import type { Request, RequestHandler } from "@warlock.js/core";
2
2
  import type { User } from "app/users/models/user";
3
3
 
4
4
  export type GuardedRequest<RequestPayload = unknown> =
5
5
  Request<RequestPayload> & {
6
6
  user: User;
7
7
  };
8
+
9
+ export type GuardedRequestHandler<RequestPayload = unknown> = RequestHandler<
10
+ GuardedRequest<RequestPayload>
11
+ >;