@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
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// bin/commands/new.ts
|
|
4
|
+
import { mkdirSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
import { join, resolve } from "path";
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
function pascal(name) {
|
|
8
|
+
return name.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
9
|
+
}
|
|
10
|
+
function kebab(name) {
|
|
11
|
+
return name.replace(/([A-Z])/g, "-$1").replace(/^-/, "").replace(/_/g, "-").toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
function packageJsonTemplate(name) {
|
|
14
|
+
return JSON.stringify(
|
|
15
|
+
{
|
|
16
|
+
name: kebab(name),
|
|
17
|
+
version: "0.0.1",
|
|
18
|
+
private: true,
|
|
19
|
+
type: "module",
|
|
20
|
+
scripts: {
|
|
21
|
+
dev: "vite dev --host --port 4001",
|
|
22
|
+
"dev:cf": "wrangler dev --port 4001",
|
|
23
|
+
build: "vite build",
|
|
24
|
+
deploy: "vite build && wrangler deploy",
|
|
25
|
+
"cf-typegen": "wrangler types --env-interface CloudflareBindings",
|
|
26
|
+
test: "vitest --run",
|
|
27
|
+
"test:watch": "vitest --watch",
|
|
28
|
+
"db:gen": "drizzle-kit generate",
|
|
29
|
+
"db:migrate": "wrangler d1 migrations apply DB --local",
|
|
30
|
+
"db:migrate:remote": "wrangler d1 migrations apply DB --remote",
|
|
31
|
+
check: "tsc --noEmit",
|
|
32
|
+
wilt: "wilt"
|
|
33
|
+
},
|
|
34
|
+
dependencies: {
|
|
35
|
+
hono: "^4.12.0",
|
|
36
|
+
wilt: "^0.1.0",
|
|
37
|
+
"reflect-metadata": "^0.2.2",
|
|
38
|
+
tsyringe: "^4.10.0",
|
|
39
|
+
zod: "^4.0.0",
|
|
40
|
+
"drizzle-orm": "^0.45.0",
|
|
41
|
+
ulid: "^3.0.0"
|
|
42
|
+
},
|
|
43
|
+
devDependencies: {
|
|
44
|
+
"@cloudflare/vite-plugin": "^1.36.0",
|
|
45
|
+
"@cloudflare/workers-types": "^4.0.0",
|
|
46
|
+
"@cloudflare/vitest-pool-workers": "^0.16.0",
|
|
47
|
+
"@sohan_fahad/wilt": "^0.1.0",
|
|
48
|
+
"@types/node": "^22.0.0",
|
|
49
|
+
"drizzle-kit": "^0.31.0",
|
|
50
|
+
typescript: "^5.0.0",
|
|
51
|
+
vite: "^6.0.0",
|
|
52
|
+
vitest: "^4.1.0",
|
|
53
|
+
tsx: "^4.0.0",
|
|
54
|
+
wrangler: "^4.0.0"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
null,
|
|
58
|
+
2
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function wranglerTemplate(name) {
|
|
62
|
+
return `{
|
|
63
|
+
"$schema": "node_modules/wrangler/config-schema.json",
|
|
64
|
+
"name": "${kebab(name)}",
|
|
65
|
+
"main": "./src/index.ts",
|
|
66
|
+
"compatibility_date": "2025-06-17",
|
|
67
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
68
|
+
"vars": {
|
|
69
|
+
"MODE": "development"
|
|
70
|
+
},
|
|
71
|
+
"observability": { "enabled": true },
|
|
72
|
+
"d1_databases": [
|
|
73
|
+
{
|
|
74
|
+
"binding": "DB",
|
|
75
|
+
"database_name": "REPLACE_WITH_YOUR_D1_NAME",
|
|
76
|
+
"database_id": "00000000-0000-0000-0000-000000000001",
|
|
77
|
+
"migrations_dir": "migrations",
|
|
78
|
+
"preview_database_id": "00000000-0000-0000-0000-000000000002"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"dev": { "port": 4001 }
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
function tsconfigTemplate() {
|
|
86
|
+
return `{
|
|
87
|
+
"compilerOptions": {
|
|
88
|
+
"target": "ESNext",
|
|
89
|
+
"module": "ESNext",
|
|
90
|
+
"moduleResolution": "Bundler",
|
|
91
|
+
"strict": true,
|
|
92
|
+
"skipLibCheck": true,
|
|
93
|
+
"experimentalDecorators": true,
|
|
94
|
+
"emitDecoratorMetadata": true,
|
|
95
|
+
"lib": ["ESNext", "DOM"],
|
|
96
|
+
"types": ["vite/client", "@cloudflare/workers-types"],
|
|
97
|
+
"baseUrl": ".",
|
|
98
|
+
"paths": {
|
|
99
|
+
"@app/*": ["src/*"]
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"include": ["src/**/*", "worker-configuration.d.ts"],
|
|
103
|
+
"exclude": ["node_modules", "dist"]
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
function viteConfigTemplate() {
|
|
108
|
+
return `import { defineConfig } from "vite";
|
|
109
|
+
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
110
|
+
import { fileURLToPath, URL } from "node:url";
|
|
111
|
+
|
|
112
|
+
export default defineConfig({
|
|
113
|
+
plugins: [cloudflare()],
|
|
114
|
+
resolve: {
|
|
115
|
+
alias: {
|
|
116
|
+
"@app": fileURLToPath(new URL("./src", import.meta.url)),
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
`;
|
|
121
|
+
}
|
|
122
|
+
function workerTypesTemplate() {
|
|
123
|
+
return `// Generated by \`pnpm cf-typegen\`. Do not edit manually.
|
|
124
|
+
/// <reference types="@cloudflare/vitest-pool-workers/types" />
|
|
125
|
+
interface CloudflareBindings {
|
|
126
|
+
DB: D1Database;
|
|
127
|
+
MODE: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare namespace Cloudflare {
|
|
131
|
+
interface Env extends CloudflareBindings {
|
|
132
|
+
TEST_MIGRATIONS: string;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
function vitestConfigTemplate() {
|
|
138
|
+
return `import path from "path";
|
|
139
|
+
import { defineConfig } from "vitest/config";
|
|
140
|
+
import { cloudflarePool, cloudflareTest, readD1Migrations } from "@cloudflare/vitest-pool-workers";
|
|
141
|
+
|
|
142
|
+
export default defineConfig(async () => {
|
|
143
|
+
const migrations = await readD1Migrations("./migrations");
|
|
144
|
+
const poolOptions = {
|
|
145
|
+
wrangler: { configPath: "./wrangler.jsonc" },
|
|
146
|
+
miniflare: {
|
|
147
|
+
bindings: { TEST_MIGRATIONS: JSON.stringify(migrations) },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
plugins: [cloudflareTest(poolOptions)],
|
|
152
|
+
resolve: {
|
|
153
|
+
alias: { "@app": path.resolve("./src") },
|
|
154
|
+
},
|
|
155
|
+
test: {
|
|
156
|
+
pool: cloudflarePool(poolOptions),
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
function indexTemplate() {
|
|
163
|
+
return `import "reflect-metadata";
|
|
164
|
+
import { app } from "./app.module";
|
|
165
|
+
|
|
166
|
+
export default {
|
|
167
|
+
async fetch(request: Request, env: CloudflareBindings, ctx: ExecutionContext): Promise<Response> {
|
|
168
|
+
return app.fetch(request, env, ctx);
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
`;
|
|
172
|
+
}
|
|
173
|
+
function appModuleTemplate(name) {
|
|
174
|
+
const p = pascal(name);
|
|
175
|
+
return `import { cors } from "hono/cors";
|
|
176
|
+
import { secureHeaders } from "hono/secure-headers";
|
|
177
|
+
|
|
178
|
+
import { Module, createModule } from "wilt";
|
|
179
|
+
import { requestLogger } from "wilt/middleware";
|
|
180
|
+
import { HelloModule } from "./modules/app/hello/hello.module";
|
|
181
|
+
|
|
182
|
+
@Module({
|
|
183
|
+
imports: [HelloModule],
|
|
184
|
+
})
|
|
185
|
+
export class AppModule {}
|
|
186
|
+
|
|
187
|
+
const app = createModule(AppModule, {
|
|
188
|
+
middlewares: [cors(), secureHeaders(), requestLogger],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
app.get("/", (c) => c.json({ success: true, status: "healthy", timestamp: new Date().toISOString() }));
|
|
192
|
+
app.get("/health", (c) => c.json({ success: true, status: "healthy", timestamp: new Date().toISOString() }));
|
|
193
|
+
|
|
194
|
+
export { app };
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
function helloModuleTemplate() {
|
|
198
|
+
return `import { Module } from "wilt";
|
|
199
|
+
import { HelloController } from "./hello.controller";
|
|
200
|
+
import { HelloService } from "./hello.service";
|
|
201
|
+
|
|
202
|
+
@Module({
|
|
203
|
+
controllers: [HelloController],
|
|
204
|
+
providers: [HelloService],
|
|
205
|
+
})
|
|
206
|
+
export class HelloModule {}
|
|
207
|
+
`;
|
|
208
|
+
}
|
|
209
|
+
function helloControllerTemplate() {
|
|
210
|
+
return `import type { Context } from "hono";
|
|
211
|
+
import { Controller, Get, Inject } from "wilt";
|
|
212
|
+
import { ResponseUtil } from "wilt";
|
|
213
|
+
import { HelloService } from "./hello.service";
|
|
214
|
+
|
|
215
|
+
@Controller("/hello")
|
|
216
|
+
export class HelloController {
|
|
217
|
+
constructor(@Inject(HelloService) private helloService: HelloService) {}
|
|
218
|
+
|
|
219
|
+
@Get()
|
|
220
|
+
async greet(c: Context) {
|
|
221
|
+
const message = this.helloService.greet();
|
|
222
|
+
return ResponseUtil.success(c, { message });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
`;
|
|
226
|
+
}
|
|
227
|
+
function helloServiceTemplate() {
|
|
228
|
+
return `import { Injectable } from "wilt";
|
|
229
|
+
|
|
230
|
+
@Injectable()
|
|
231
|
+
export class HelloService {
|
|
232
|
+
greet() {
|
|
233
|
+
return "Hello from Wilt!";
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
function dbSchemaTemplate() {
|
|
239
|
+
return `// Register all your entity tables here so Drizzle can build relations and
|
|
240
|
+
// drizzle-kit can generate migrations from a single source of truth.
|
|
241
|
+
export const schema = {};
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
function dbConnectionTemplate() {
|
|
245
|
+
return `import { drizzle } from "drizzle-orm/d1";
|
|
246
|
+
import type { Context } from "hono";
|
|
247
|
+
import { schema } from "./schema";
|
|
248
|
+
export function getDb(c: Context) {
|
|
249
|
+
return drizzle(c.env.DB, { schema: schema });
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
function gitignoreTemplate() {
|
|
254
|
+
return `dist/
|
|
255
|
+
node_modules/
|
|
256
|
+
.wrangler
|
|
257
|
+
.env
|
|
258
|
+
.env.production
|
|
259
|
+
.dev.vars
|
|
260
|
+
.DS_Store
|
|
261
|
+
coverage/
|
|
262
|
+
*.log
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
function wiltConfigTemplate() {
|
|
266
|
+
return `import { defineConfig } from "wilt/config";
|
|
267
|
+
|
|
268
|
+
export default defineConfig({
|
|
269
|
+
// Directory where generated modules are placed (relative to project root)
|
|
270
|
+
modulesDir: "src/modules/app",
|
|
271
|
+
|
|
272
|
+
// Default files scaffolded by \`wilt generate module <name>\`
|
|
273
|
+
// Remove "test" to skip test files, or pass --no-test at the CLI
|
|
274
|
+
generate: {
|
|
275
|
+
files: ["module", "controller", "service", "dto", "entity", "test"],
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
`;
|
|
279
|
+
}
|
|
280
|
+
function envExampleTemplate() {
|
|
281
|
+
return `CLOUDFLARE_ACCOUNT_ID=
|
|
282
|
+
CLOUDFLARE_TOKEN=
|
|
283
|
+
|
|
284
|
+
CLOUDFLARE_DATABASE_ID=
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
function drizzleConfigTemplate() {
|
|
288
|
+
return `import { defineConfig } from "drizzle-kit";
|
|
289
|
+
|
|
290
|
+
export default defineConfig({
|
|
291
|
+
schema: "./src/database/schema.ts",
|
|
292
|
+
out: "./migrations",
|
|
293
|
+
dialect: "sqlite",
|
|
294
|
+
driver: "d1-http",
|
|
295
|
+
dbCredentials: {
|
|
296
|
+
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
|
|
297
|
+
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
|
|
298
|
+
token: process.env.CLOUDFLARE_TOKEN!,
|
|
299
|
+
},
|
|
300
|
+
verbose: true,
|
|
301
|
+
strict: true,
|
|
302
|
+
});
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
function migrationTemplate() {
|
|
306
|
+
return `-- Initial migration
|
|
307
|
+
-- Add your tables here
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
310
|
+
function migrationMetaTemplate(name) {
|
|
311
|
+
return JSON.stringify(
|
|
312
|
+
{
|
|
313
|
+
version: "5",
|
|
314
|
+
dialect: "sqlite",
|
|
315
|
+
entries: [
|
|
316
|
+
{
|
|
317
|
+
idx: 0,
|
|
318
|
+
version: "5",
|
|
319
|
+
when: Date.now(),
|
|
320
|
+
tag: "0000_initial",
|
|
321
|
+
breakpoints: true
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
},
|
|
325
|
+
null,
|
|
326
|
+
2
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
function write(path, content) {
|
|
330
|
+
writeFileSync(path, content, "utf-8");
|
|
331
|
+
console.log(` \u2714 ${path.replace(process.cwd() + "/", "")}`);
|
|
332
|
+
}
|
|
333
|
+
function dir(path) {
|
|
334
|
+
mkdirSync(path, { recursive: true });
|
|
335
|
+
}
|
|
336
|
+
function runNew(args) {
|
|
337
|
+
const [name] = args;
|
|
338
|
+
if (!name) {
|
|
339
|
+
console.error(" \u2717 Usage: wilt new <project-name>");
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
const projectDir = resolve(process.cwd(), name);
|
|
343
|
+
if (existsSync(projectDir)) {
|
|
344
|
+
console.error(` \u2717 Directory already exists: ${projectDir}`);
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
console.log(`
|
|
348
|
+
Creating Wilt app "${name}"...
|
|
349
|
+
`);
|
|
350
|
+
dir(join(projectDir, "src/modules/app/hello"));
|
|
351
|
+
dir(join(projectDir, "src/database"));
|
|
352
|
+
dir(join(projectDir, "migrations/meta"));
|
|
353
|
+
write(join(projectDir, "package.json"), packageJsonTemplate(name));
|
|
354
|
+
write(join(projectDir, "wrangler.jsonc"), wranglerTemplate(name));
|
|
355
|
+
write(join(projectDir, "tsconfig.json"), tsconfigTemplate());
|
|
356
|
+
write(join(projectDir, "vite.config.ts"), viteConfigTemplate());
|
|
357
|
+
write(join(projectDir, "vitest.config.ts"), vitestConfigTemplate());
|
|
358
|
+
write(join(projectDir, "worker-configuration.d.ts"), workerTypesTemplate());
|
|
359
|
+
write(join(projectDir, "wilt.config.ts"), wiltConfigTemplate());
|
|
360
|
+
write(join(projectDir, ".gitignore"), gitignoreTemplate());
|
|
361
|
+
write(join(projectDir, ".env.example"), envExampleTemplate());
|
|
362
|
+
write(join(projectDir, "drizzle.config.ts"), drizzleConfigTemplate());
|
|
363
|
+
write(join(projectDir, "src/index.ts"), indexTemplate());
|
|
364
|
+
write(join(projectDir, "src/app.module.ts"), appModuleTemplate(name));
|
|
365
|
+
write(join(projectDir, "src/modules/app/hello/hello.module.ts"), helloModuleTemplate());
|
|
366
|
+
write(join(projectDir, "src/modules/app/hello/hello.controller.ts"), helloControllerTemplate());
|
|
367
|
+
write(join(projectDir, "src/modules/app/hello/hello.service.ts"), helloServiceTemplate());
|
|
368
|
+
write(join(projectDir, "src/database/schema.ts"), dbSchemaTemplate());
|
|
369
|
+
write(join(projectDir, "src/database/connection.ts"), dbConnectionTemplate());
|
|
370
|
+
write(join(projectDir, "migrations/0000_initial.sql"), migrationTemplate());
|
|
371
|
+
write(join(projectDir, "migrations/meta/_journal.json"), migrationMetaTemplate(name));
|
|
372
|
+
console.log("\n Installing dependencies...\n");
|
|
373
|
+
try {
|
|
374
|
+
const pm = detectPackageManager();
|
|
375
|
+
execSync(`${pm} install`, { cwd: projectDir, stdio: "inherit" });
|
|
376
|
+
} catch {
|
|
377
|
+
console.log(" \u26A0 Could not auto-install. Run `pnpm install` manually.\n");
|
|
378
|
+
}
|
|
379
|
+
console.log(`
|
|
380
|
+
\u2714 Project created!
|
|
381
|
+
|
|
382
|
+
Next steps:
|
|
383
|
+
cd ${name}
|
|
384
|
+
cp .env.example .env # fill in Cloudflare credentials
|
|
385
|
+
# Edit wrangler.jsonc: set database_name + database_id
|
|
386
|
+
pnpm db:migrate # apply local D1 migrations
|
|
387
|
+
pnpm dev # http://localhost:4001
|
|
388
|
+
|
|
389
|
+
Try it:
|
|
390
|
+
curl http://localhost:4001/health
|
|
391
|
+
curl http://localhost:4001/hello
|
|
392
|
+
|
|
393
|
+
Generate a new module:
|
|
394
|
+
pnpm wilt generate module posts
|
|
395
|
+
`);
|
|
396
|
+
}
|
|
397
|
+
function detectPackageManager() {
|
|
398
|
+
try {
|
|
399
|
+
execSync("pnpm --version", { stdio: "ignore" });
|
|
400
|
+
return "pnpm";
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
execSync("bun --version", { stdio: "ignore" });
|
|
405
|
+
return "bun";
|
|
406
|
+
} catch {
|
|
407
|
+
}
|
|
408
|
+
return "npm";
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// bin/create-wilt-app.ts
|
|
412
|
+
runNew(process.argv.slice(2));
|
|
413
|
+
//# sourceMappingURL=create-wilt-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../bin/commands/new.ts","../../../bin/create-wilt-app.ts"],"sourcesContent":["import { mkdirSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\nfunction pascal(name: string) {\n return name\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase())\n .replace(/^(.)/, (_, c) => c.toUpperCase());\n}\n\nfunction kebab(name: string) {\n return name\n .replace(/([A-Z])/g, \"-$1\")\n .replace(/^-/, \"\")\n .replace(/_/g, \"-\")\n .toLowerCase();\n}\n\n// ─── File templates ───────────────────────────────────────────────────────────\n\nfunction packageJsonTemplate(name: string) {\n return JSON.stringify(\n {\n name: kebab(name),\n version: \"0.0.1\",\n private: true,\n type: \"module\",\n scripts: {\n dev: \"vite dev --host --port 4001\",\n \"dev:cf\": \"wrangler dev --port 4001\",\n build: \"vite build\",\n deploy: \"vite build && wrangler deploy\",\n \"cf-typegen\": \"wrangler types --env-interface CloudflareBindings\",\n test: \"vitest --run\",\n \"test:watch\": \"vitest --watch\",\n \"db:gen\": \"drizzle-kit generate\",\n \"db:migrate\": \"wrangler d1 migrations apply DB --local\",\n \"db:migrate:remote\": \"wrangler d1 migrations apply DB --remote\",\n check: \"tsc --noEmit\",\n wilt: \"wilt\",\n },\n dependencies: {\n hono: \"^4.12.0\",\n wilt: \"^0.1.0\",\n \"reflect-metadata\": \"^0.2.2\",\n tsyringe: \"^4.10.0\",\n zod: \"^4.0.0\",\n \"drizzle-orm\": \"^0.45.0\",\n ulid: \"^3.0.0\",\n },\n devDependencies: {\n \"@cloudflare/vite-plugin\": \"^1.36.0\",\n \"@cloudflare/workers-types\": \"^4.0.0\",\n \"@cloudflare/vitest-pool-workers\": \"^0.16.0\",\n \"@sohan_fahad/wilt\": \"^0.1.0\",\n \"@types/node\": \"^22.0.0\",\n \"drizzle-kit\": \"^0.31.0\",\n typescript: \"^5.0.0\",\n vite: \"^6.0.0\",\n vitest: \"^4.1.0\",\n tsx: \"^4.0.0\",\n wrangler: \"^4.0.0\",\n },\n },\n null,\n 2\n );\n}\n\nfunction wranglerTemplate(name: string) {\n return `{\n \"$schema\": \"node_modules/wrangler/config-schema.json\",\n \"name\": \"${kebab(name)}\",\n \"main\": \"./src/index.ts\",\n \"compatibility_date\": \"2025-06-17\",\n \"compatibility_flags\": [\"nodejs_compat\"],\n \"vars\": {\n \"MODE\": \"development\"\n },\n \"observability\": { \"enabled\": true },\n \"d1_databases\": [\n {\n \"binding\": \"DB\",\n \"database_name\": \"REPLACE_WITH_YOUR_D1_NAME\",\n \"database_id\": \"00000000-0000-0000-0000-000000000001\",\n \"migrations_dir\": \"migrations\",\n \"preview_database_id\": \"00000000-0000-0000-0000-000000000002\"\n }\n ],\n \"dev\": { \"port\": 4001 }\n}\n`;\n}\n\nfunction tsconfigTemplate() {\n return `{\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"Bundler\",\n \"strict\": true,\n \"skipLibCheck\": true,\n \"experimentalDecorators\": true,\n \"emitDecoratorMetadata\": true,\n \"lib\": [\"ESNext\", \"DOM\"],\n \"types\": [\"vite/client\", \"@cloudflare/workers-types\"],\n \"baseUrl\": \".\",\n \"paths\": {\n \"@app/*\": [\"src/*\"]\n }\n },\n \"include\": [\"src/**/*\", \"worker-configuration.d.ts\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n`;\n}\n\nfunction viteConfigTemplate() {\n return `import { defineConfig } from \"vite\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\nimport { fileURLToPath, URL } from \"node:url\";\n\nexport default defineConfig({\n plugins: [cloudflare()],\n resolve: {\n alias: {\n \"@app\": fileURLToPath(new URL(\"./src\", import.meta.url)),\n },\n },\n});\n`;\n}\n\nfunction workerTypesTemplate() {\n return `// Generated by \\`pnpm cf-typegen\\`. Do not edit manually.\n/// <reference types=\"@cloudflare/vitest-pool-workers/types\" />\ninterface CloudflareBindings {\n DB: D1Database;\n MODE: string;\n}\n\ndeclare namespace Cloudflare {\n interface Env extends CloudflareBindings {\n TEST_MIGRATIONS: string;\n }\n}\n`;\n}\n\nfunction vitestConfigTemplate() {\n return `import path from \"path\";\nimport { defineConfig } from \"vitest/config\";\nimport { cloudflarePool, cloudflareTest, readD1Migrations } from \"@cloudflare/vitest-pool-workers\";\n\nexport default defineConfig(async () => {\n const migrations = await readD1Migrations(\"./migrations\");\n const poolOptions = {\n wrangler: { configPath: \"./wrangler.jsonc\" },\n miniflare: {\n bindings: { TEST_MIGRATIONS: JSON.stringify(migrations) },\n },\n };\n return {\n plugins: [cloudflareTest(poolOptions)],\n resolve: {\n alias: { \"@app\": path.resolve(\"./src\") },\n },\n test: {\n pool: cloudflarePool(poolOptions),\n },\n };\n});\n`;\n}\n\nfunction indexTemplate() {\n return `import \"reflect-metadata\";\nimport { app } from \"./app.module\";\n\nexport default {\n async fetch(request: Request, env: CloudflareBindings, ctx: ExecutionContext): Promise<Response> {\n return app.fetch(request, env, ctx);\n },\n};\n`;\n}\n\nfunction appModuleTemplate(name: string) {\n const p = pascal(name);\n return `import { cors } from \"hono/cors\";\nimport { secureHeaders } from \"hono/secure-headers\";\n\nimport { Module, createModule } from \"wilt\";\nimport { requestLogger } from \"wilt/middleware\";\nimport { HelloModule } from \"./modules/app/hello/hello.module\";\n\n@Module({\n imports: [HelloModule],\n})\nexport class AppModule {}\n\nconst app = createModule(AppModule, {\n middlewares: [cors(), secureHeaders(), requestLogger],\n});\n\napp.get(\"/\", (c) => c.json({ success: true, status: \"healthy\", timestamp: new Date().toISOString() }));\napp.get(\"/health\", (c) => c.json({ success: true, status: \"healthy\", timestamp: new Date().toISOString() }));\n\nexport { app };\n`;\n}\n\nfunction helloModuleTemplate() {\n return `import { Module } from \"wilt\";\nimport { HelloController } from \"./hello.controller\";\nimport { HelloService } from \"./hello.service\";\n\n@Module({\n controllers: [HelloController],\n providers: [HelloService],\n})\nexport class HelloModule {}\n`;\n}\n\nfunction helloControllerTemplate() {\n return `import type { Context } from \"hono\";\nimport { Controller, Get, Inject } from \"wilt\";\nimport { ResponseUtil } from \"wilt\";\nimport { HelloService } from \"./hello.service\";\n\n@Controller(\"/hello\")\nexport class HelloController {\n constructor(@Inject(HelloService) private helloService: HelloService) {}\n\n @Get()\n async greet(c: Context) {\n const message = this.helloService.greet();\n return ResponseUtil.success(c, { message });\n }\n}\n`;\n}\n\nfunction helloServiceTemplate() {\n return `import { Injectable } from \"wilt\";\n\n@Injectable()\nexport class HelloService {\n greet() {\n return \"Hello from Wilt!\";\n }\n}\n`;\n}\n\nfunction dbSchemaTemplate() {\n return `// Register all your entity tables here so Drizzle can build relations and\n// drizzle-kit can generate migrations from a single source of truth.\nexport const schema = {};\n`;\n}\n\nfunction dbConnectionTemplate() {\n return `import { drizzle } from \"drizzle-orm/d1\";\nimport type { Context } from \"hono\";\nimport { schema } from \"./schema\";\nexport function getDb(c: Context) {\n return drizzle(c.env.DB, { schema: schema });\n}\n`;\n}\n\nfunction gitignoreTemplate() {\n return `dist/\nnode_modules/\n.wrangler\n.env\n.env.production\n.dev.vars\n.DS_Store\ncoverage/\n*.log\n`;\n}\n\n\nfunction wiltConfigTemplate() {\n return `import { defineConfig } from \"wilt/config\";\n\nexport default defineConfig({\n // Directory where generated modules are placed (relative to project root)\n modulesDir: \"src/modules/app\",\n\n // Default files scaffolded by \\`wilt generate module <name>\\`\n // Remove \"test\" to skip test files, or pass --no-test at the CLI\n generate: {\n files: [\"module\", \"controller\", \"service\", \"dto\", \"entity\", \"test\"],\n },\n});\n`;\n}\n\nfunction envExampleTemplate() {\n return `CLOUDFLARE_ACCOUNT_ID=\nCLOUDFLARE_TOKEN=\n\nCLOUDFLARE_DATABASE_ID=\n`;\n}\n\nfunction drizzleConfigTemplate() {\n return `import { defineConfig } from \"drizzle-kit\";\n\nexport default defineConfig({\n schema: \"./src/database/schema.ts\",\n out: \"./migrations\",\n dialect: \"sqlite\",\n driver: \"d1-http\",\n dbCredentials: {\n accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,\n databaseId: process.env.CLOUDFLARE_DATABASE_ID!,\n token: process.env.CLOUDFLARE_TOKEN!,\n },\n verbose: true,\n strict: true,\n});\n`;\n}\n\nfunction migrationTemplate() {\n return `-- Initial migration\n-- Add your tables here\n`;\n}\n\nfunction migrationMetaTemplate(name: string) {\n return JSON.stringify(\n {\n version: \"5\",\n dialect: \"sqlite\",\n entries: [\n {\n idx: 0,\n version: \"5\",\n when: Date.now(),\n tag: \"0000_initial\",\n breakpoints: true,\n },\n ],\n },\n null,\n 2\n );\n}\n\n// ─── Scaffold ─────────────────────────────────────────────────────────────────\n\nfunction write(path: string, content: string) {\n writeFileSync(path, content, \"utf-8\");\n console.log(` ✔ ${path.replace(process.cwd() + \"/\", \"\")}`);\n}\n\nfunction dir(path: string) {\n mkdirSync(path, { recursive: true });\n}\n\nexport function runNew(args: string[]): void {\n const [name] = args;\n\n if (!name) {\n console.error(\" ✗ Usage: wilt new <project-name>\");\n process.exit(1);\n }\n\n const projectDir = resolve(process.cwd(), name);\n\n if (existsSync(projectDir)) {\n console.error(` ✗ Directory already exists: ${projectDir}`);\n process.exit(1);\n }\n\n console.log(`\\n Creating Wilt app \"${name}\"...\\n`);\n\n // Directories\n dir(join(projectDir, \"src/modules/app/hello\"));\n dir(join(projectDir, \"src/database\"));\n dir(join(projectDir, \"migrations/meta\"));\n\n // Config files\n write(join(projectDir, \"package.json\"), packageJsonTemplate(name));\n write(join(projectDir, \"wrangler.jsonc\"), wranglerTemplate(name));\n write(join(projectDir, \"tsconfig.json\"), tsconfigTemplate());\n write(join(projectDir, \"vite.config.ts\"), viteConfigTemplate());\n write(join(projectDir, \"vitest.config.ts\"), vitestConfigTemplate());\n write(join(projectDir, \"worker-configuration.d.ts\"), workerTypesTemplate());\n write(join(projectDir, \"wilt.config.ts\"), wiltConfigTemplate());\n write(join(projectDir, \".gitignore\"), gitignoreTemplate());\n write(join(projectDir, \".env.example\"), envExampleTemplate());\n write(join(projectDir, \"drizzle.config.ts\"), drizzleConfigTemplate());\n\n // App entry\n write(join(projectDir, \"src/index.ts\"), indexTemplate());\n write(join(projectDir, \"src/app.module.ts\"), appModuleTemplate(name));\n\n // Hello module\n write(join(projectDir, \"src/modules/app/hello/hello.module.ts\"), helloModuleTemplate());\n write(join(projectDir, \"src/modules/app/hello/hello.controller.ts\"), helloControllerTemplate());\n write(join(projectDir, \"src/modules/app/hello/hello.service.ts\"), helloServiceTemplate());\n\n // Database\n write(join(projectDir, \"src/database/schema.ts\"), dbSchemaTemplate());\n write(join(projectDir, \"src/database/connection.ts\"), dbConnectionTemplate());\n\n // Migrations\n write(join(projectDir, \"migrations/0000_initial.sql\"), migrationTemplate());\n write(join(projectDir, \"migrations/meta/_journal.json\"), migrationMetaTemplate(name));\n\n // Try to install dependencies\n console.log(\"\\n Installing dependencies...\\n\");\n try {\n const pm = detectPackageManager();\n execSync(`${pm} install`, { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n console.log(\" ⚠ Could not auto-install. Run `pnpm install` manually.\\n\");\n }\n\n console.log(`\n ✔ Project created!\n\n Next steps:\n cd ${name}\n cp .env.example .env # fill in Cloudflare credentials\n # Edit wrangler.jsonc: set database_name + database_id\n pnpm db:migrate # apply local D1 migrations\n pnpm dev # http://localhost:4001\n\n Try it:\n curl http://localhost:4001/health\n curl http://localhost:4001/hello\n\n Generate a new module:\n pnpm wilt generate module posts\n`);\n}\n\nfunction detectPackageManager(): string {\n try {\n execSync(\"pnpm --version\", { stdio: \"ignore\" });\n return \"pnpm\";\n } catch { }\n try {\n execSync(\"bun --version\", { stdio: \"ignore\" });\n return \"bun\";\n } catch { }\n return \"npm\";\n}\n","import { runNew } from \"./commands/new.js\";\n\nrunNew(process.argv.slice(2));\n"],"mappings":"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","names":[]}
|