@sohan_fahad/wilt 0.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.
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/bin/commands/add.ts +155 -0
- package/bin/commands/generate.ts +74 -0
- package/bin/commands/new.ts +457 -0
- package/bin/create-wilt-app.ts +3 -0
- package/bin/generators/module.generator.ts +266 -0
- package/bin/utils/config.ts +46 -0
- package/bin/utils/paths.ts +32 -0
- package/bin/utils/wrangler.ts +216 -0
- package/bin/wilt.ts +79 -0
- package/dist/lib/bin/create-wilt-app.js +413 -0
- package/dist/lib/bin/create-wilt-app.js.map +1 -0
- package/dist/lib/bin/wilt.js +1151 -0
- package/dist/lib/bin/wilt.js.map +1 -0
- package/dist/lib/chunk-EUXUH3YW.js +15 -0
- package/dist/lib/chunk-EUXUH3YW.js.map +1 -0
- package/dist/lib/chunk-FIEODUMV.js +234 -0
- package/dist/lib/chunk-FIEODUMV.js.map +1 -0
- package/dist/lib/chunk-MOVXD653.cjs +234 -0
- package/dist/lib/chunk-MOVXD653.cjs.map +1 -0
- package/dist/lib/chunk-ZBDE64SD.cjs +15 -0
- package/dist/lib/chunk-ZBDE64SD.cjs.map +1 -0
- package/dist/lib/config.cjs +10 -0
- package/dist/lib/config.cjs.map +1 -0
- package/dist/lib/config.d.cts +13 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.js +10 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/index.cjs +974 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +255 -0
- package/dist/lib/index.d.ts +255 -0
- package/dist/lib/index.js +974 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/middleware/index.cjs +10 -0
- package/dist/lib/middleware/index.cjs.map +1 -0
- package/dist/lib/middleware/index.d.cts +18 -0
- package/dist/lib/middleware/index.d.ts +18 -0
- package/dist/lib/middleware/index.js +10 -0
- package/dist/lib/middleware/index.js.map +1 -0
- package/package.json +78 -0
- package/src/wilt/README.md +285 -0
- package/src/wilt/config.ts +14 -0
- package/src/wilt/context/execution-context.ts +36 -0
- package/src/wilt/context/index.ts +1 -0
- package/src/wilt/decorators/core/exception-filters.decorator.ts +24 -0
- package/src/wilt/decorators/core/index.ts +6 -0
- package/src/wilt/decorators/core/injectable.decorator.ts +41 -0
- package/src/wilt/decorators/core/optional.decorator.ts +9 -0
- package/src/wilt/decorators/core/set-metadata.decorator.ts +20 -0
- package/src/wilt/decorators/core/use-guards.decorator.ts +14 -0
- package/src/wilt/decorators/core/use-interceptors.decorator.ts +16 -0
- package/src/wilt/decorators/http/controller.decorator.ts +230 -0
- package/src/wilt/decorators/http/header.decorator.ts +11 -0
- package/src/wilt/decorators/http/http-code.decorator.ts +8 -0
- package/src/wilt/decorators/http/index.ts +6 -0
- package/src/wilt/decorators/http/redirect.decorator.ts +13 -0
- package/src/wilt/decorators/http/route-mapping.decorator.ts +22 -0
- package/src/wilt/decorators/http/route-params.decorator.ts +60 -0
- package/src/wilt/decorators/index.ts +3 -0
- package/src/wilt/decorators/modules/global.decorator.ts +8 -0
- package/src/wilt/decorators/modules/index.ts +2 -0
- package/src/wilt/decorators/modules/module.decorator.ts +16 -0
- package/src/wilt/exceptions/http-exception.ts +17 -0
- package/src/wilt/exceptions/http-exceptions.ts +85 -0
- package/src/wilt/exceptions/index.ts +2 -0
- package/src/wilt/index.ts +11 -0
- package/src/wilt/injector/index.ts +1 -0
- package/src/wilt/injector/injector.ts +103 -0
- package/src/wilt/injector/module-compiler.ts +48 -0
- package/src/wilt/injector/module.factory.ts +74 -0
- package/src/wilt/interfaces/core/filter.interface.ts +5 -0
- package/src/wilt/interfaces/core/guard.interface.ts +5 -0
- package/src/wilt/interfaces/core/index.ts +5 -0
- package/src/wilt/interfaces/core/interceptor.interface.ts +9 -0
- package/src/wilt/interfaces/core/lifecycle.interface.ts +19 -0
- package/src/wilt/interfaces/core/pipe.interface.ts +9 -0
- package/src/wilt/interfaces/http/index.ts +1 -0
- package/src/wilt/interfaces/http/response.interface.ts +27 -0
- package/src/wilt/interfaces/index.ts +3 -0
- package/src/wilt/interfaces/modules/index.ts +1 -0
- package/src/wilt/interfaces/modules/module.interface.ts +17 -0
- package/src/wilt/middleware/error-handler.middleware.ts +63 -0
- package/src/wilt/middleware/index.ts +2 -0
- package/src/wilt/middleware/request-logger.middleware.ts +17 -0
- package/src/wilt/pipes/index.ts +3 -0
- package/src/wilt/pipes/validate.pipe.ts +79 -0
- package/src/wilt/pipes/zod-query.pipe.ts +42 -0
- package/src/wilt/pipes/zod-validate.pipe.ts +49 -0
- package/src/wilt/services/index.ts +1 -0
- package/src/wilt/services/reflector.service.ts +24 -0
- package/src/wilt/utils/apply-decorators.util.ts +17 -0
- package/src/wilt/utils/forward-ref.util.ts +14 -0
- package/src/wilt/utils/index.ts +22 -0
- package/src/wilt/utils/logger.util.ts +189 -0
- package/src/wilt/utils/response.util.ts +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wilt Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Wilt
|
|
2
|
+
|
|
3
|
+
A NestJS-like framework for **Cloudflare Workers** built on [Hono](https://hono.dev). Write modular, decorator-driven APIs that deploy to the edge — no server required.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx wilt new my-app
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Module system** — `@Module`, `@Controller`, `@Injectable` decorators like NestJS
|
|
12
|
+
- **Dependency injection** — powered by [tsyringe](https://github.com/microsoft/tsyringe)
|
|
13
|
+
- **Validation** — Zod schema decorators for body, query, and params
|
|
14
|
+
- **Built-in middleware** — request logger, CORS, secure headers
|
|
15
|
+
- **CLI** — scaffold projects, modules, services, controllers, and Cloudflare service bindings
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Node 20+
|
|
20
|
+
- [pnpm](https://pnpm.io/), npm, or bun
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx wilt new my-app
|
|
26
|
+
cd my-app
|
|
27
|
+
pnpm db:migrate # apply local D1 migrations
|
|
28
|
+
pnpm dev # http://localhost:4001
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
curl http://localhost:4001/health
|
|
33
|
+
curl http://localhost:4001/hello
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## CLI
|
|
37
|
+
|
|
38
|
+
### `wilt new`
|
|
39
|
+
|
|
40
|
+
Scaffold a new Wilt project with a Hello module, D1 setup, Drizzle config, and Wrangler config.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx wilt new <project-name>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `wilt generate`
|
|
47
|
+
|
|
48
|
+
Scaffold files inside an existing project.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx wilt generate module <name> # module + controller + service + dto
|
|
52
|
+
npx wilt generate service <name>
|
|
53
|
+
npx wilt generate controller <name>
|
|
54
|
+
|
|
55
|
+
# --path to target a specific directory
|
|
56
|
+
npx wilt generate service payment --path src/modules/app/payment
|
|
57
|
+
|
|
58
|
+
# Short aliases
|
|
59
|
+
npx wilt g m <name>
|
|
60
|
+
npx wilt g s <name>
|
|
61
|
+
npx wilt g c <name>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `wilt add`
|
|
65
|
+
|
|
66
|
+
Add a Cloudflare service binding directly to `wrangler.jsonc`.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx wilt add d1 <BINDING> <database-name>
|
|
70
|
+
npx wilt add r2 <BINDING> <bucket-name>
|
|
71
|
+
npx wilt add kv <BINDING>
|
|
72
|
+
npx wilt add queue <BINDING> <queue-name>
|
|
73
|
+
npx wilt add ai <BINDING>
|
|
74
|
+
npx wilt add durable-object <BINDING> <ClassName>
|
|
75
|
+
npx wilt add vectorize <BINDING> <index-name> [dimensions]
|
|
76
|
+
npx wilt add browser <BINDING>
|
|
77
|
+
npx wilt add hyperdrive <BINDING> <connection-string>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Examples:**
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx wilt add d1 PAYMENTS_DB payments-db
|
|
84
|
+
npx wilt add r2 ASSETS_BUCKET my-assets
|
|
85
|
+
npx wilt add kv SESSION_KV
|
|
86
|
+
npx wilt add queue MAIL_QUEUE mailer
|
|
87
|
+
npx wilt add durable-object CHAT_ROOM ChatRoom
|
|
88
|
+
npx wilt add vectorize VECTOR_IDX my-index 1536
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Framework API
|
|
92
|
+
|
|
93
|
+
### Decorators
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { Module, Controller, Injectable, Inject, Get, Post, Put, Delete } from "wilt";
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
| Decorator | Target | Description |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| `@Module({ imports, controllers, providers })` | Class | Define a module |
|
|
102
|
+
| `@Controller(prefix)` | Class | Register HTTP routes under a prefix |
|
|
103
|
+
| `@Injectable()` | Class | Mark a class for DI |
|
|
104
|
+
| `@Inject(token)` | Constructor param | Inject a dependency |
|
|
105
|
+
| `@Get(path?)` | Method | GET route |
|
|
106
|
+
| `@Post(path?)` | Method | POST route |
|
|
107
|
+
| `@Put(path?)` | Method | PUT route |
|
|
108
|
+
| `@Delete(path?)` | Method | DELETE route |
|
|
109
|
+
|
|
110
|
+
### Validation
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { ZodBody, ZodQuery } from "wilt";
|
|
114
|
+
import { z } from "zod";
|
|
115
|
+
|
|
116
|
+
const CreatePostDto = z.object({ title: z.string(), body: z.string() });
|
|
117
|
+
|
|
118
|
+
@Post()
|
|
119
|
+
@ZodBody(CreatePostDto)
|
|
120
|
+
async create(c: Context) { ... }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `createModule`
|
|
124
|
+
|
|
125
|
+
Bootstrap your app from the root module.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { createModule } from "wilt";
|
|
129
|
+
import { cors } from "hono/cors";
|
|
130
|
+
import { requestLogger } from "wilt/middleware";
|
|
131
|
+
import { AppModule } from "./app.module";
|
|
132
|
+
|
|
133
|
+
const app = createModule(AppModule, {
|
|
134
|
+
middlewares: [cors(), requestLogger],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
export default { fetch: app.fetch };
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `ResponseUtil`
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { ResponseUtil } from "wilt";
|
|
144
|
+
|
|
145
|
+
return ResponseUtil.success(c, data);
|
|
146
|
+
return ResponseUtil.error(c, "Not found", 404);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Example Module
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// posts/posts.module.ts
|
|
153
|
+
import { Module } from "wilt";
|
|
154
|
+
import { PostsController } from "./posts.controller";
|
|
155
|
+
import { PostsService } from "./posts.service";
|
|
156
|
+
|
|
157
|
+
@Module({
|
|
158
|
+
controllers: [PostsController],
|
|
159
|
+
providers: [PostsService],
|
|
160
|
+
})
|
|
161
|
+
export class PostsModule {}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
// posts/posts.controller.ts
|
|
166
|
+
import type { Context } from "hono";
|
|
167
|
+
import { Controller, Get, Post, Inject } from "wilt";
|
|
168
|
+
import { ResponseUtil } from "wilt";
|
|
169
|
+
import { ZodBody } from "wilt";
|
|
170
|
+
import { PostsService } from "./posts.service";
|
|
171
|
+
import { CreatePostDto } from "./posts.dto";
|
|
172
|
+
|
|
173
|
+
@Controller("/posts")
|
|
174
|
+
export class PostsController {
|
|
175
|
+
constructor(@Inject(PostsService) private postsService: PostsService) {}
|
|
176
|
+
|
|
177
|
+
@Get()
|
|
178
|
+
async list(c: Context) {
|
|
179
|
+
const posts = await this.postsService.findAll();
|
|
180
|
+
return ResponseUtil.success(c, posts);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Post()
|
|
184
|
+
@ZodBody(CreatePostDto)
|
|
185
|
+
async create(c: Context) {
|
|
186
|
+
const body = await c.req.json();
|
|
187
|
+
const post = await this.postsService.create(body);
|
|
188
|
+
return ResponseUtil.success(c, post, 201);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// posts/posts.service.ts
|
|
195
|
+
import { Injectable } from "wilt";
|
|
196
|
+
|
|
197
|
+
@Injectable()
|
|
198
|
+
export class PostsService {
|
|
199
|
+
async findAll() { ... }
|
|
200
|
+
async create(data: unknown) { ... }
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Project Structure (generated)
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
my-app/
|
|
208
|
+
├── src/
|
|
209
|
+
│ ├── index.ts # Worker entry
|
|
210
|
+
│ ├── app.module.ts # Root module
|
|
211
|
+
│ ├── database/
|
|
212
|
+
│ │ └── connection.ts # Drizzle + D1
|
|
213
|
+
│ └── modules/
|
|
214
|
+
│ └── hello/ # Starter module
|
|
215
|
+
├── migrations/ # D1 SQL migrations
|
|
216
|
+
├── worker-configuration.d.ts # Cloudflare binding types (includes TEST_MIGRATIONS for tests)
|
|
217
|
+
├── wrangler.jsonc # Cloudflare Worker config
|
|
218
|
+
├── tsconfig.json
|
|
219
|
+
├── vite.config.ts
|
|
220
|
+
└── .dev.vars.example # Local secrets template (only needed for auth features)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Peer Dependencies
|
|
224
|
+
|
|
225
|
+
Installed automatically in generated projects:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"hono": ">=4",
|
|
230
|
+
"reflect-metadata": ">=0.2",
|
|
231
|
+
"tsyringe": ">=4",
|
|
232
|
+
"zod": ">=3"
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Deploy
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
pnpm deploy
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Set your Cloudflare secrets before deploying to production:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
wrangler secret put JWT_SECRET
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addD1,
|
|
3
|
+
addR2,
|
|
4
|
+
addKv,
|
|
5
|
+
addQueue,
|
|
6
|
+
addAi,
|
|
7
|
+
addDurableObject,
|
|
8
|
+
addVectorize,
|
|
9
|
+
addBrowser,
|
|
10
|
+
addHyperdrive,
|
|
11
|
+
} from "../utils/wrangler.js";
|
|
12
|
+
|
|
13
|
+
const USAGE = `
|
|
14
|
+
Usage:
|
|
15
|
+
pnpm wilt add d1 <BINDING_NAME> <database-name>
|
|
16
|
+
pnpm wilt add r2 <BINDING_NAME> <bucket-name>
|
|
17
|
+
pnpm wilt add kv <BINDING_NAME>
|
|
18
|
+
pnpm wilt add queue <BINDING_NAME> <queue-name>
|
|
19
|
+
pnpm wilt add ai <BINDING_NAME>
|
|
20
|
+
pnpm wilt add durable-object <BINDING_NAME> <ClassName>
|
|
21
|
+
pnpm wilt add vectorize <BINDING_NAME> <index-name> [dimensions]
|
|
22
|
+
pnpm wilt add browser <BINDING_NAME>
|
|
23
|
+
pnpm wilt add hyperdrive <BINDING_NAME> <connection-string>
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
pnpm wilt add d1 PAYMENTS_DB payments-db
|
|
27
|
+
pnpm wilt add r2 ASSETS_BUCKET my-assets
|
|
28
|
+
pnpm wilt add kv SESSION_KV
|
|
29
|
+
pnpm wilt add queue MAIL_QUEUE mailer
|
|
30
|
+
pnpm wilt add ai AI
|
|
31
|
+
pnpm wilt add durable-object CHAT_ROOM ChatRoom
|
|
32
|
+
pnpm wilt add vectorize VECTOR_IDX my-index 1536
|
|
33
|
+
pnpm wilt add browser BROWSER
|
|
34
|
+
pnpm wilt add hyperdrive HYPERDRIVE postgres://user:pass@host/db
|
|
35
|
+
`.trim();
|
|
36
|
+
|
|
37
|
+
export function runAdd(args: string[]): void {
|
|
38
|
+
const [service, ...rest] = args;
|
|
39
|
+
|
|
40
|
+
if (!service) {
|
|
41
|
+
console.error(` ✗ Missing service type.\n\n${USAGE}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const svc = service.toLowerCase();
|
|
46
|
+
|
|
47
|
+
switch (svc) {
|
|
48
|
+
case "d1": {
|
|
49
|
+
const [binding, dbName] = rest;
|
|
50
|
+
if (!binding || !dbName) {
|
|
51
|
+
console.error(` ✗ Usage: pnpm wilt add d1 <BINDING_NAME> <database-name>`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
console.log(`\n Adding D1 binding to wrangler.jsonc...\n`);
|
|
55
|
+
addD1(binding, dbName);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
case "r2": {
|
|
60
|
+
const [binding, bucketName] = rest;
|
|
61
|
+
if (!binding || !bucketName) {
|
|
62
|
+
console.error(` ✗ Usage: pnpm wilt add r2 <BINDING_NAME> <bucket-name>`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
console.log(`\n Adding R2 binding to wrangler.jsonc...\n`);
|
|
66
|
+
addR2(binding, bucketName);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
case "kv": {
|
|
71
|
+
const [binding] = rest;
|
|
72
|
+
if (!binding) {
|
|
73
|
+
console.error(` ✗ Usage: pnpm wilt add kv <BINDING_NAME>`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
console.log(`\n Adding KV namespace binding to wrangler.jsonc...\n`);
|
|
77
|
+
addKv(binding);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
case "queue": {
|
|
82
|
+
const [binding, queueName] = rest;
|
|
83
|
+
if (!binding || !queueName) {
|
|
84
|
+
console.error(` ✗ Usage: pnpm wilt add queue <BINDING_NAME> <queue-name>`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
console.log(`\n Adding Queue binding to wrangler.jsonc...\n`);
|
|
88
|
+
addQueue(binding, queueName);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
case "ai": {
|
|
93
|
+
const [binding] = rest;
|
|
94
|
+
if (!binding) {
|
|
95
|
+
console.error(` ✗ Usage: pnpm wilt add ai <BINDING_NAME>`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
console.log(`\n Adding AI binding to wrangler.jsonc...\n`);
|
|
99
|
+
addAi(binding);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
case "durable-object":
|
|
104
|
+
case "do": {
|
|
105
|
+
const [binding, className] = rest;
|
|
106
|
+
if (!binding || !className) {
|
|
107
|
+
console.error(` ✗ Usage: pnpm wilt add durable-object <BINDING_NAME> <ClassName>`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
console.log(`\n Adding Durable Object binding to wrangler.jsonc...\n`);
|
|
111
|
+
addDurableObject(binding, className);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case "vectorize":
|
|
116
|
+
case "vector": {
|
|
117
|
+
const [binding, indexName, rawDimensions] = rest;
|
|
118
|
+
if (!binding || !indexName) {
|
|
119
|
+
console.error(` ✗ Usage: pnpm wilt add vectorize <BINDING_NAME> <index-name> [dimensions]`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const dimensions = rawDimensions ? parseInt(rawDimensions, 10) : 1536;
|
|
123
|
+
console.log(`\n Adding Vectorize binding to wrangler.jsonc...\n`);
|
|
124
|
+
addVectorize(binding, indexName, dimensions);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case "browser": {
|
|
129
|
+
const [binding] = rest;
|
|
130
|
+
if (!binding) {
|
|
131
|
+
console.error(` ✗ Usage: pnpm wilt add browser <BINDING_NAME>`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
console.log(`\n Adding Browser rendering binding to wrangler.jsonc...\n`);
|
|
135
|
+
addBrowser(binding);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
case "hyperdrive": {
|
|
140
|
+
const [binding, connectionString] = rest;
|
|
141
|
+
if (!binding || !connectionString) {
|
|
142
|
+
console.error(` ✗ Usage: pnpm wilt add hyperdrive <BINDING_NAME> <connection-string>`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
console.log(`\n Adding Hyperdrive binding to wrangler.jsonc...\n`);
|
|
146
|
+
addHyperdrive(binding, connectionString);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
default: {
|
|
151
|
+
console.error(` ✗ Unknown service type: "${service}"\n\n${USAGE}`);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateModule,
|
|
3
|
+
generateService,
|
|
4
|
+
generateController,
|
|
5
|
+
} from "../generators/module.generator.js";
|
|
6
|
+
import { loadConfig } from "../utils/config.js";
|
|
7
|
+
|
|
8
|
+
const USAGE = `
|
|
9
|
+
Usage:
|
|
10
|
+
pnpm wilt generate module <name> [--path <dir>] [--no-test]
|
|
11
|
+
pnpm wilt generate service <name> [--path <dir>]
|
|
12
|
+
pnpm wilt generate controller <name> [--path <dir>]
|
|
13
|
+
|
|
14
|
+
Aliases:
|
|
15
|
+
g m → generate module
|
|
16
|
+
g s → generate service
|
|
17
|
+
g c → generate controller
|
|
18
|
+
|
|
19
|
+
Flags:
|
|
20
|
+
--no-test Skip generating the .test.ts file for a module
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
pnpm wilt generate module payment
|
|
24
|
+
pnpm wilt g m payment
|
|
25
|
+
pnpm wilt generate module payment --no-test
|
|
26
|
+
pnpm wilt generate service payment --path src/modules/app/payment
|
|
27
|
+
`.trim();
|
|
28
|
+
|
|
29
|
+
function parsePath(args: string[]): { args: string[]; path?: string } {
|
|
30
|
+
const idx = args.indexOf("--path");
|
|
31
|
+
if (idx === -1) return { args };
|
|
32
|
+
const path = args[idx + 1];
|
|
33
|
+
const cleaned = args.filter((_, i) => i !== idx && i !== idx + 1);
|
|
34
|
+
return { args: cleaned, path };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseNoTest(args: string[]): { args: string[]; noTest: boolean } {
|
|
38
|
+
const idx = args.indexOf("--no-test");
|
|
39
|
+
if (idx === -1) return { args, noTest: false };
|
|
40
|
+
return { args: args.filter((_, i) => i !== idx), noTest: true };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function runGenerate(args: string[]): Promise<void> {
|
|
44
|
+
const { args: withoutPath, path: targetPath } = parsePath(args);
|
|
45
|
+
const { args: cleanArgs, noTest } = parseNoTest(withoutPath);
|
|
46
|
+
const [subcommand, name] = cleanArgs;
|
|
47
|
+
|
|
48
|
+
if (!subcommand || !name) {
|
|
49
|
+
console.error(` ✗ Missing arguments.\n\n${USAGE}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const config = await loadConfig();
|
|
54
|
+
const sub = subcommand.toLowerCase();
|
|
55
|
+
|
|
56
|
+
if (sub === "module" || sub === "m") {
|
|
57
|
+
console.log(`\n Generating module "${name}"...\n`);
|
|
58
|
+
generateModule(name, {
|
|
59
|
+
dir: targetPath,
|
|
60
|
+
modulesDir: config.modulesDir,
|
|
61
|
+
defaultFiles: config.generate.files,
|
|
62
|
+
noTest,
|
|
63
|
+
});
|
|
64
|
+
} else if (sub === "service" || sub === "s") {
|
|
65
|
+
console.log(`\n Generating service "${name}"...\n`);
|
|
66
|
+
generateService(name, targetPath, config.modulesDir);
|
|
67
|
+
} else if (sub === "controller" || sub === "c") {
|
|
68
|
+
console.log(`\n Generating controller "${name}"...\n`);
|
|
69
|
+
generateController(name, targetPath, config.modulesDir);
|
|
70
|
+
} else {
|
|
71
|
+
console.error(` ✗ Unknown generate subcommand: "${subcommand}"\n\n${USAGE}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|