create-celsian 0.3.12 → 0.3.14

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/README.md CHANGED
@@ -1,596 +1,15 @@
1
- # CelsianJS
1
+ # Create Celsian
2
2
 
3
- TypeScript backend framework built on Web Standard APIs. Ships runtime adapters for Node.js, Bun, Deno, Cloudflare Workers, AWS Lambda, and Vercel.
3
+ Scaffold new CelsianJS applications.
4
4
 
5
- - **Multi-runtime** -- Write once for Web Standard `Request`/`Response`, then deploy with the adapter that matches your target runtime.
6
- - **Significantly faster than Express** -- Radix-tree router, zero-copy request building, pre-stringified error paths. 1.3x-1.7x faster across all scenarios.
7
- - **First-party batteries** -- Background tasks, cron, WebSocket, CORS, CSRF protection, security headers, DB analytics, rate limiting, JWT, caching, compression, and OpenAPI docs via core APIs plus first-party packages.
8
- - **Fastify-style plugin encapsulation** -- Scoped hooks and decorations by default. No accidental middleware leaks.
9
- - **Schema-agnostic validation** -- Auto-detects Zod, TypeBox, or Valibot. No config, no adapters.
5
+ This package is part of the [CelsianJS](https://github.com/CelsianJs/celsian) monorepo. See the root repository README for framework documentation, examples, and release notes.
10
6
 
11
- ## Local pnpm note
12
-
13
- This monorepo is pinned to `pnpm@9.15.0`. For local release verification, prefer:
14
-
15
- ```bash
16
- npm run setup:pnpm
17
- # or, if Corepack is unavailable locally:
18
- npx -y pnpm@9.15.0 <script>
19
- ```
20
-
21
- CI and release gates should use the pinned package manager version, not an older global pnpm.
22
-
23
- ## Quick Start
24
-
25
- ```bash
26
- npx create-celsian my-api
27
- cd my-api
28
- npm install
29
- npm run dev
30
- ```
31
-
32
- Or manually for the core router/runtime:
33
-
34
- ```bash
35
- npm install @celsian/core
36
- ```
37
-
38
- ```typescript
39
- import { createApp, serve } from '@celsian/core';
40
-
41
- const app = createApp({ logger: true });
42
-
43
- // ─── Background tasks with retries ───
44
- app.task({
45
- name: 'sendWelcomeEmail',
46
- retries: 3,
47
- async handler(input: { to: string }) {
48
- await sendEmail(input.to, 'Welcome!');
49
- },
50
- });
51
-
52
- // ─── Cron job: clean up expired sessions every night ───
53
- app.cron('cleanup', '0 3 * * *', async () => {
54
- await db.query('DELETE FROM sessions WHERE expires_at < NOW()');
55
- });
56
-
57
- // ─── API routes ───
58
- app.post('/users', async (req, reply) => {
59
- const body = req.parsedBody as { name: string; email: string };
60
- const user = await db.createUser(body);
61
- await app.enqueue('sendWelcomeEmail', { to: body.email });
62
- return reply.status(201).json(user);
63
- });
64
-
65
- app.get('/users/:id', (req, reply) => {
66
- return reply.json({ id: req.params.id, name: 'Alice' });
67
- });
68
-
69
- serve(app, { port: 3000 });
70
- ```
71
-
72
- Tasks, cron, and API routes in one file -- no separate worker process needed. On Bun or Deno, `serve()` auto-detects the runtime. No code changes needed.
7
+ ## Installation
73
8
 
74
9
  ```bash
75
- bun run server.ts # Uses Bun.serve() automatically
76
- deno run server.ts # Uses Deno.serve() automatically
77
- ```
78
-
79
- ## Why CelsianJS
80
-
81
- ### Multi-Runtime
82
-
83
- Built on Web Standard `Request`/`Response` -- not Node.js `IncomingMessage`/`ServerResponse`. One adapter line deploys anywhere:
84
-
85
- ```typescript
86
- export default createCloudflareHandler(app); // Cloudflare Workers
87
- export const handler = createLambdaHandler(app); // AWS Lambda
88
- export default createVercelEdgeHandler(app); // Vercel Edge
89
- ```
90
-
91
- ### Honest Benchmarks
92
-
93
- Benchmarked on Node.js v22, Apple Silicon, 10 connections for 10 seconds per scenario:
94
-
95
- | Scenario | Fastify (req/s) | CelsianJS (req/s) | Express (req/s) |
96
- | --------------------- | ---------------: | -----------------: | --------------: |
97
- | JSON response | 45,866 | 27,996 | 16,321 |
98
- | Route params | 45,440 | 27,026 | 16,288 |
99
- | Middleware (5 layers) | 41,380 | 24,445 | 15,751 |
100
- | JSON body parsing | 29,998 | 19,074 | 14,648 |
101
- | Error handling | 32,398 | 18,542 | 14,765 |
102
-
103
- **Fastify is faster.** It operates directly on Node.js internals with `fast-json-stringify` — hard to beat. CelsianJS pays a performance tax for Web Standard API compatibility (`Request`/`Response` object creation per request).
104
-
105
- **CelsianJS is 1.3-1.7x faster than Express** while shipping batteries that neither Fastify nor Express include: background task queues, cron scheduling, multi-runtime deployment, and DB analytics. If raw throughput is your only concern, use Fastify. If you need application infrastructure in a single framework, that's where CelsianJS fits.
106
-
107
- ### Built-In Everything
108
-
109
- Celsian's batteries ship as first-party packages. Install the extras you use:
110
-
111
- ```bash
112
- npm install @celsian/core @celsian/rate-limit @celsian/jwt @celsian/compress
113
- ```
114
-
115
- ```typescript
116
- import { createApp, security, cors, csrf, openapi } from '@celsian/core';
117
- import { rateLimit } from '@celsian/rate-limit';
118
- import { jwt } from '@celsian/jwt';
119
- import { compress } from '@celsian/compress';
120
-
121
- const app = createApp();
122
-
123
- await app.register(security(), { encapsulate: false }); // Helmet-style headers
124
- await app.register(cors({ origin: 'https://myapp.com' }));
125
- await app.register(csrf(), { encapsulate: false }); // CSRF token protection
126
- await app.register(rateLimit({ max: 100, window: 60_000, keyGenerator: req => req.headers.get("x-api-key") ?? "public" }));
127
- await app.register(compress());
128
- await app.register(jwt({ secret: process.env.JWT_SECRET! }));
129
- await app.register(openapi({ title: 'My API' }));
130
-
131
- app.health(); // /health + /ready
132
- app.task({ name: 'email', handler, retries: 3 }); // Background tasks
133
- app.cron('cleanup', '0 3 * * *', cleanupHandler); // Cron jobs
134
- app.ws('/chat', { open, message, close }); // WebSocket
135
- ```
136
-
137
- ### Plugin Encapsulation
138
-
139
- Plugins get isolated scopes by default. Hooks and decorations registered inside a plugin do not leak to sibling plugins or the parent scope.
140
-
141
- ```typescript
142
- // Auth plugin -- hooks only apply to routes registered inside
143
- async function authPlugin(app) {
144
- app.addHook('onRequest', async (req, reply) => {
145
- const token = req.headers.get('authorization');
146
- if (!token) return reply.unauthorized();
147
- });
148
-
149
- app.get('/me', (req, reply) => {
150
- return reply.json({ user: req.user });
151
- });
152
- }
153
-
154
- // Public routes -- no auth required
155
- app.get('/health', (req, reply) => reply.json({ status: 'ok' }));
156
-
157
- // Register auth plugin under /api prefix
158
- await app.register(authPlugin, { prefix: '/api' });
159
- ```
160
-
161
- Use `{ encapsulate: false }` when a plugin should affect all routes (e.g., CORS, database):
162
-
163
- ```typescript
164
- await app.register(cors(), { encapsulate: false });
165
- ```
166
-
167
- ### Type-Safe Schema Validation
168
-
169
- Pass any Zod, TypeBox, or Valibot schema. CelsianJS auto-detects the library.
170
-
171
- ```typescript
172
- app.route({
173
- method: 'POST',
174
- url: '/users',
175
- schema: {
176
- body: z.object({ name: z.string().min(1), email: z.string().email() }),
177
- },
178
- handler(req, reply) {
179
- const { name, email } = req.parsedBody as { name: string; email: string };
180
- return reply.status(201).json({ id: '1', name, email });
181
- },
182
- });
183
- // Invalid input returns 400 with structured issues automatically
184
- ```
185
-
186
- ### JSX Server Rendering
187
-
188
- CelsianJS includes a built-in JSX runtime for server-side HTML rendering -- no React dependency needed. Supports both automatic and classic transforms.
189
-
190
- **Setup (automatic transform -- recommended):**
191
-
192
- ```jsonc
193
- // tsconfig.json
194
- {
195
- "compilerOptions": {
196
- "jsx": "react-jsx",
197
- "jsxImportSource": "@celsian/core"
198
- }
199
- }
200
- ```
201
-
202
- **Setup (classic transform):**
203
-
204
- ```jsonc
205
- // tsconfig.json
206
- {
207
- "compilerOptions": {
208
- "jsx": "react",
209
- "jsxFactory": "h",
210
- "jsxFragmentFactory": "Fragment"
211
- }
212
- }
213
- ```
214
-
215
- ```typescript
216
- import { h, Fragment } from '@celsian/core/jsx';
10
+ npm install create-celsian
217
11
  ```
218
12
 
219
- **Usage:**
220
-
221
- ```tsx
222
- import { renderToString, renderToDocument } from '@celsian/core';
223
-
224
- // Function components work like React
225
- function Layout({ title, children }: { title: string; children: any }) {
226
- return (
227
- <html>
228
- <head><title>{title}</title></head>
229
- <body>{children}</body>
230
- </html>
231
- );
232
- }
233
-
234
- function UserCard({ name, email }: { name: string; email: string }) {
235
- return (
236
- <div className="card">
237
- <h2>{name}</h2>
238
- <p>{email}</p>
239
- </div>
240
- );
241
- }
242
-
243
- app.get('/page', (req, reply) => {
244
- const html = renderToDocument(
245
- <Layout title="Users">
246
- <UserCard name="Alice" email="alice@example.com" />
247
- </Layout>
248
- );
249
- return reply.html(html);
250
- });
251
- ```
252
-
253
- Supports `className`/`htmlFor` mapping, style objects, boolean attributes, void elements, `dangerouslySetInnerHTML`, Fragments, and XSS-safe escaping.
254
-
255
- ## Features at a Glance
256
-
257
- | Category | Features |
258
- | -------- | -------- |
259
- | **Routing** | Radix-tree router, params, wildcards, HEAD fallback, 405, route tagging |
260
- | **Hooks** | 8-hook lifecycle (onRequest through onResponse), route-level hooks |
261
- | **Plugins** | Scoped encapsulation, app/request/reply decorators |
262
- | **Validation** | Zod, TypeBox, Valibot auto-detect; body, querystring, params schemas |
263
- | **Reply** | json, html, stream, redirect, sendFile (Range/ETag/304), download, cookies, 9 error helpers, JSX SSR |
264
- | **Security** | Helmet-style headers, CORS, CSRF protection, JWT, fixed-window rate limiting |
265
- | **Background** | Task queue with retries, cron scheduling, Redis queue backend |
266
- | **Real-time** | WebSocket with broadcast and connection management |
267
- | **Database** | Connection pool plugin, transactions, query analytics, Server-Timing |
268
- | **Caching** | Response cache, session management (KV store) |
269
- | **Infra** | Brotli/gzip/deflate compression, OpenAPI 3.1 + Swagger UI, structured logging, inject() testing |
270
- | **Deploy** | Node, Bun, Deno, Workers, Lambda, Vercel, Fly.io, Railway, graceful shutdown |
271
-
272
- ## Core Concepts
273
-
274
- ### Routes and Handlers
275
-
276
- ```typescript
277
- app.get('/users/:id', (req, reply) => {
278
- return reply.json({ id: req.params.id, include: req.query.include });
279
- });
280
-
281
- // Full route options with schema, hooks, and deployment tagging
282
- app.route({
283
- method: 'POST',
284
- url: '/items',
285
- kind: 'serverless',
286
- schema: { body: mySchema },
287
- preHandler: [authHook],
288
- handler(req, reply) { return reply.status(201).json(req.parsedBody); },
289
- });
290
- ```
291
-
292
- ### Hooks Lifecycle
293
-
294
- 8 hooks run in order: `onRequest` > `preParsing` > `preValidation` > `preHandler` > `handler` > `preSerialization` > `onSend` > `onResponse`. Plus `onError` for error handling. Any hook can short-circuit by returning a `Response`.
295
-
296
- ```typescript
297
- // Global hook
298
- app.addHook('onRequest', async (req, reply) => {
299
- reply.header('x-request-id', crypto.randomUUID());
300
- });
301
-
302
- // Route-level hook
303
- app.route({
304
- method: 'POST',
305
- url: '/admin/users',
306
- onRequest: [requireAdmin],
307
- handler(req, reply) { return reply.json({ created: true }); },
308
- });
309
- ```
310
-
311
- See [Hooks Lifecycle](docs/hooks.md) for the complete guide.
312
-
313
- ### Reply Helpers
314
-
315
- ```typescript
316
- reply.json({ data: [] }); // JSON response
317
- reply.html('<h1>Hello</h1>'); // HTML response
318
- reply.stream(readableStream); // Streaming
319
- reply.redirect('/new-path', 301); // Redirect
320
- await reply.sendFile('/path/to/report.pdf'); // Serve file
321
- await reply.download('/path/to/data.csv', 'export'); // Download
322
-
323
- // Structured error responses
324
- reply.notFound('User not found'); // 404
325
- reply.badRequest('Missing email'); // 400
326
- reply.unauthorized('Token expired'); // 401
327
- reply.forbidden(); // 403
328
- reply.conflict(); // 409
329
- reply.tooManyRequests(); // 429
330
-
331
- // Cookies + chaining
332
- reply.cookie('session', token, { httpOnly: true, secure: true });
333
- return reply.status(201).header('x-custom', 'value').json({ id: '1' });
334
- ```
335
-
336
- #### File Serving with Range Requests
337
-
338
- `sendFile` and `download` support Range requests (HTTP 206), conditional GET (304), ETag, and Last-Modified headers. Pass `options.request` to enable these features:
339
-
340
- ```typescript
341
- app.get('/files/:name', async (req, reply) => {
342
- return reply.sendFile(req.params.name, {
343
- root: './uploads', // Resolve relative to this directory (with traversal protection)
344
- request: req, // Enable Range requests + conditional GET (304)
345
- cacheControl: 'public, max-age=3600', // Set Cache-Control header
346
- });
347
- });
348
-
349
- // Download with Range support (for resumable downloads)
350
- app.get('/export/:id', async (req, reply) => {
351
- return reply.download(`./data/${req.params.id}.csv`, 'export.csv', {
352
- request: req,
353
- });
354
- });
355
- ```
356
-
357
- Supported Range formats: `bytes=0-499`, `bytes=500-`, `bytes=-500`, and multi-range (`bytes=0-499, 1000-1499`). Invalid ranges return 416 Range Not Satisfiable.
358
-
359
- #### Compression with Brotli
360
-
361
- The compression plugin prefers Brotli over gzip when the client supports it, providing better compression ratios for text content:
362
-
363
- ```typescript
364
- import { compress } from '@celsian/compress';
365
-
366
- // Brotli + gzip + deflate (default)
367
- await app.register(compress());
368
-
369
- // Custom Brotli quality (0-11, default 4)
370
- await app.register(compress({ brotliQuality: 6 }));
371
-
372
- // Gzip/deflate only (disable Brotli)
373
- await app.register(compress({ encodings: ['gzip', 'deflate'] }));
374
- ```
375
-
376
- ### Error Handling
377
-
378
- Thrown errors are caught and returned as structured JSON. Stack traces are stripped in production.
379
-
380
- ```typescript
381
- import { HttpError } from '@celsian/core';
382
-
383
- // Throw HTTP errors anywhere
384
- throw new HttpError(403, 'Forbidden');
385
- // { "error": "Forbidden", "statusCode": 403, "code": "FORBIDDEN" }
386
-
387
- // Custom error handler
388
- app.setErrorHandler((error, req, reply) => {
389
- if (error.message.includes('UNIQUE constraint')) return reply.conflict();
390
- return reply.internalServerError();
391
- });
392
- ```
393
-
394
- ### Type-Safe RPC
395
-
396
- `@celsian/rpc` provides tRPC-style procedures with type inference, middleware, and OpenAPI generation.
397
-
398
- ```typescript
399
- // server.ts
400
- import { procedure, router, RPCHandler } from '@celsian/rpc';
401
-
402
- const appRouter = router({
403
- users: {
404
- list: procedure
405
- .input(z.object({ limit: z.number().optional() }))
406
- .query(async ({ input }) => [{ id: '1', name: 'Alice' }]),
407
- create: procedure
408
- .input(z.object({ name: z.string(), email: z.string().email() }))
409
- .mutation(async ({ input }) => ({ id: '2', ...input })),
410
- },
411
- });
412
-
413
- const rpc = new RPCHandler(appRouter);
414
- app.route({ method: ['GET', 'POST'], url: '/_rpc/*path', handler: (req) => rpc.handle(req) });
415
- export type AppRouter = typeof appRouter;
416
-
417
- // client.ts
418
- const client = createRPCClient<AppRouter>({ baseUrl: 'http://localhost:3000/_rpc' });
419
- const users = await client.users.list.query({ limit: 10 });
420
- const newUser = await client.users.create.mutate({ name: 'Bob', email: 'bob@example.com' });
421
- ```
422
-
423
- ## Try the Demo
424
-
425
- The [SaaS Demo](examples/saas-demo/) builds a complete backend in one file (~250 lines): JWT auth, users CRUD, background tasks, cron, SSE, and OpenAPI docs.
426
-
427
- ```bash
428
- cd examples/saas-demo
429
- npm install
430
- npx tsx src/index.ts
431
- ```
432
-
433
- Then hit `http://localhost:3000/docs` for the Swagger UI, or:
434
-
435
- ```bash
436
- # Register
437
- curl -X POST http://localhost:3000/register \
438
- -H 'Content-Type: application/json' \
439
- -d '{"email":"alice@example.com","password":"secret123","name":"Alice"}'
440
-
441
- # Login and grab the token
442
- curl -X POST http://localhost:3000/login \
443
- -H 'Content-Type: application/json' \
444
- -d '{"email":"alice@example.com","password":"secret123"}'
445
- ```
446
-
447
- ## Ecosystem
448
-
449
- ### Core Packages
450
-
451
- | Package | Description |
452
- | ------- | ----------- |
453
- | `@celsian/core` | Server runtime, routing, hooks, plugins, task queue, cron, WebSocket, CORS, security, database, OpenAPI |
454
- | `@celsian/schema` | Standard Schema adapters -- auto-detects Zod, TypeBox, Valibot |
455
- | `@celsian/rpc` | Type-safe RPC procedures, middleware, OpenAPI generation, typed client |
456
- | `@celsian/jwt` | JWT sign/verify plugin with route guard helper |
457
- | `@celsian/cache` | KV store, response caching, session management |
458
- | `@celsian/rate-limit` | Fixed-window rate limiter with pluggable store |
459
- | `@celsian/compress` | Response compression (Brotli, gzip, deflate) |
460
- | `@celsian/queue-redis` | Redis-backed task queue for production |
461
-
462
- ### Deployment Adapters
463
-
464
- | Package | Target |
465
- | ------- | ------ |
466
- | `@celsian/adapter-cloudflare` | Cloudflare Workers (env bindings, execution context) |
467
- | `@celsian/adapter-lambda` | AWS Lambda + API Gateway v2 |
468
- | `@celsian/adapter-vercel` | Vercel Serverless + Edge Functions |
469
- | `@celsian/adapter-node` | Standalone Node.js server |
470
- | `@celsian/adapter-fly` | Fly.io (generates fly.toml, Dockerfile, multi-region) |
471
- | `@celsian/adapter-railway` | Railway (generates railway.json, Procfile) |
472
-
473
- ### Tooling
474
-
475
- | Package | Description |
476
- | ------- | ----------- |
477
- | `create-celsian` | Project scaffolder (`npx create-celsian my-api`) |
478
- | `@celsian/cli` | Dev server, route listing, code generation |
479
- | `celsian` | Meta-package for single-import convenience |
480
-
481
- ## Production Features
482
-
483
- ### Graceful Shutdown
484
-
485
- On SIGTERM/SIGINT: stops accepting connections, drains in-flight requests, stops workers and cron, runs cleanup.
486
-
487
- ```typescript
488
- serve(app, {
489
- shutdownTimeout: 15_000,
490
- onShutdown: () => db.close(),
491
- });
492
- ```
493
-
494
- ### Health Checks and Route Manifest
495
-
496
- ```typescript
497
- app.health({ check: () => pool.isHealthy() }); // /health + /ready
498
-
499
- // Tag routes for deployment tooling
500
- app.route({ method: 'GET', url: '/api/users', kind: 'serverless', handler });
501
- app.route({ method: 'GET', url: '/ws', kind: 'hot', handler });
502
- const manifest = app.getRouteManifest(); // { serverless: [...], hot: [...], task: [...] }
503
- ```
504
-
505
- ### Database Analytics
506
-
507
- Wrap your pool with `trackedPool()` for per-request query metrics, `Server-Timing` headers, and slow query logging -- zero handler changes. See [Database Plugin](docs/database.md).
508
-
509
- ```typescript
510
- const pool = trackedPool(pgPool);
511
- await app.register(database({ createPool: () => pool }), { encapsulate: false });
512
- await app.register(dbAnalytics({ slowThreshold: 100 }), { encapsulate: false });
513
- // Response: Server-Timing: db;dur=12.5;desc="3 queries"
514
- ```
515
-
516
- ### Testing Without a Server
517
-
518
- ```typescript
519
- const response = await app.inject({ method: 'GET', url: '/hello' });
520
- const body = await response.json(); // { hello: 'world' }
521
- ```
522
-
523
- ## Deployment
524
-
525
- Swap the entry point for the JavaScript runtime you are deploying to. See [Deployment Guide](docs/deployment.md) for full instructions and provider-specific credential/config requirements.
526
-
527
- ```typescript
528
- serve(app, { port: 3000 }); // Node / Bun / Deno
529
-
530
- export default createCloudflareHandler(app); // Cloudflare Workers
531
- export const handler = createLambdaHandler(app); // AWS Lambda
532
- export default createVercelHandler(app); // Vercel Serverless
533
- export default createVercelEdgeHandler(app); // Vercel Edge
534
- ```
535
-
536
- Fly.io and Railway adapters auto-generate deployment configs (`fly.toml`, Dockerfile, `railway.json`). Adapter packages are covered by local generation/package smoke tests; live cloud deployment still depends on each provider's credentials and project configuration.
537
-
538
- ## Benchmark Results
539
-
540
- Node.js v22.13.1, macOS Darwin (Apple Silicon), 10 connections, 10s per scenario.
541
-
542
- | Scenario | Fastify (req/s) | CelsianJS (req/s) | Express (req/s) |
543
- | --------------------- | ---------------: | -----------------: | --------------: |
544
- | JSON response | 45,866 | 27,996 | 16,321 |
545
- | Route params | 45,440 | 27,026 | 16,288 |
546
- | Middleware (5) | 41,380 | 24,445 | 15,751 |
547
- | JSON body parsing | 29,998 | 19,074 | 14,648 |
548
- | Error handling | 32,398 | 18,542 | 14,765 |
549
-
550
- Fastify is the fastest Node.js framework. CelsianJS is 1.3-1.7x faster than Express. The gap with Fastify comes from Web Standard API overhead (`Request`/`Response` per request). CelsianJS trades some throughput for multi-runtime portability and built-in application infrastructure.
551
-
552
- ## Configuration
553
-
554
- CelsianJS loads `celsian.config.ts` (or `.js`/`.mjs`) automatically:
555
-
556
- ```typescript
557
- import { defineConfig } from '@celsian/core';
558
-
559
- export default defineConfig({
560
- server: { port: 3000, host: 'localhost', trustProxy: true },
561
- schema: { provider: 'auto' }, // or 'zod' | 'typebox' | 'valibot'
562
- });
563
- ```
564
-
565
- ## Documentation
566
-
567
- - [Quick Start Guide](docs/quickstart.md)
568
- - [Hooks Lifecycle](docs/hooks.md)
569
- - [Plugins and Encapsulation](docs/plugins.md)
570
- - [Deployment Guide](docs/deployment.md)
571
- - [Database Plugin](docs/database.md)
572
-
573
- ## WhatStack
574
-
575
- CelsianJS is the backend half of [WhatStack](https://whatfw.com) — the agent-first full-stack framework:
576
-
577
- | Layer | Framework | What It Does |
578
- |-------|-----------|-------------|
579
- | Frontend | [WhatFW](https://whatfw.com) | Signals, fine-grained rendering, MCP DevTools |
580
- | Backend | **CelsianJS** | Hooks, plugins, tasks, cron, RPC, multi-runtime |
581
- | Deploy | [Vura](https://github.com/zvndev/vura) | Platform deployment (coming soon) |
582
-
583
- ## Contributing
584
-
585
- ```bash
586
- git clone https://github.com/CelsianJs/celsian.git
587
- cd celsian
588
- pnpm install
589
- pnpm test
590
- ```
591
-
592
- The project uses pnpm workspaces. All packages are in `packages/`. Tests use Vitest.
593
-
594
13
  ## License
595
14
 
596
15
  MIT
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export type Template = "full" | "basic" | "rest-api" | "rpc-api";
3
- export declare function scaffold(name: string, template: string, pm: string): void;
2
+ export {};
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAgBA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AA6DjE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAqCzE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  // create-celsian — Project scaffolder
3
3
  // Zero external dependencies. Interactive prompts via raw stdin.
4
- import { existsSync, mkdirSync, readdirSync, realpathSync, writeFileSync } from "node:fs";
5
- import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
6
  import { createInterface } from "node:readline";
7
- import { fileURLToPath } from "node:url";
8
7
  import { basicTemplate } from "./templates/basic.js";
9
8
  import { fullTemplate } from "./templates/full.js";
10
9
  import { restApiTemplate } from "./templates/rest-api.js";
11
10
  import { rpcApiTemplate } from "./templates/rpc-api.js";
11
+ // ─── Template Registry ───
12
12
  const templates = {
13
13
  full: fullTemplate,
14
14
  basic: basicTemplate,
@@ -21,6 +21,17 @@ const templateDescriptions = {
21
21
  "rest-api": "REST API with TypeBox schemas",
22
22
  "rpc-api": "RPC-first with typed client",
23
23
  };
24
+ // ─── CLI Argument Parsing ───
25
+ const args = process.argv.slice(2);
26
+ // Handle --help
27
+ if (args.includes("--help") || args.includes("-h")) {
28
+ printUsage();
29
+ process.exit(0);
30
+ }
31
+ // Extract flags
32
+ const templateFlag = args.indexOf("--template");
33
+ const templateArg = templateFlag !== -1 ? args[templateFlag + 1] : undefined;
34
+ const nameArg = args.find((a) => !a.startsWith("--") && (templateFlag === -1 || args.indexOf(a) !== templateFlag + 1));
24
35
  // ─── Interactive Mode ───
25
36
  async function prompt(question, defaultValue) {
26
37
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -58,14 +69,27 @@ async function interactiveMode() {
58
69
  return { name, template, pm };
59
70
  }
60
71
  // ─── Scaffold ───
61
- export function scaffold(name, template, pm) {
72
+ function scaffold(name, template, pm) {
62
73
  const files = templates[template];
63
74
  if (!files) {
64
75
  console.error(`\n Unknown template: ${template}`);
65
76
  console.error(` Available: ${Object.keys(templates).join(", ")}\n`);
66
77
  process.exit(1);
67
78
  }
68
- const { dir, projectName } = validateTarget(name);
79
+ // Sanitize: reject names containing path traversal
80
+ if (name.includes("..")) {
81
+ console.error("\n Invalid project name: must not contain '..'.\n");
82
+ process.exit(1);
83
+ }
84
+ const cwd = process.cwd();
85
+ const dir = isAbsolute(name) ? name : join(cwd, name);
86
+ const resolved = resolve(dir);
87
+ // Ensure the resolved path is a child of cwd
88
+ if (!resolved.startsWith(cwd + "/") && resolved !== cwd) {
89
+ console.error("\n Invalid project name: resolved path must be inside the current directory.\n");
90
+ process.exit(1);
91
+ }
92
+ const projectName = basename(dir);
69
93
  console.log(`\n Creating Celsian project: ${projectName}`);
70
94
  console.log(` Template: ${template}`);
71
95
  console.log("");
@@ -91,57 +115,8 @@ export function scaffold(name, template, pm) {
91
115
  }
92
116
  console.log("");
93
117
  }
94
- function validateTarget(name) {
95
- const trimmedName = name.trim();
96
- if (!trimmedName) {
97
- console.error("\n Invalid project name: name is required.\n");
98
- process.exit(1);
99
- }
100
- if (trimmedName.split(/[\\/]+/).includes("..")) {
101
- console.error("\n Invalid project name: must not contain '..'.\n");
102
- process.exit(1);
103
- }
104
- const cwd = resolve(process.cwd());
105
- const dir = resolve(isAbsolute(trimmedName) ? trimmedName : join(cwd, trimmedName));
106
- const rel = relative(cwd, dir);
107
- if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
108
- console.error("\n Invalid project name: resolved path must be inside the current directory.\n");
109
- process.exit(1);
110
- }
111
- if (existsSync(dir)) {
112
- const entries = readdirSync(dir);
113
- if (entries.length > 0) {
114
- console.error("\n Refusing to create project: target directory already exists and is not empty.\n");
115
- process.exit(1);
116
- }
117
- }
118
- const projectName = sanitizePackageName(basename(dir));
119
- if (!projectName) {
120
- console.error("\n Invalid project name: cannot derive a valid package name.\n");
121
- process.exit(1);
122
- }
123
- return { dir, projectName };
124
- }
125
- function sanitizePackageName(name) {
126
- return name
127
- .trim()
128
- .toLowerCase()
129
- .replace(/^[._-]+/, "")
130
- .replace(/[._\s]+/g, "-")
131
- .replace(/[^a-z0-9-]/g, "")
132
- .replace(/-+/g, "-")
133
- .replace(/-+$/g, "");
134
- }
135
118
  // ─── Main ───
136
119
  async function main() {
137
- const args = process.argv.slice(2);
138
- if (args.includes("--help") || args.includes("-h")) {
139
- printUsage();
140
- process.exit(0);
141
- }
142
- const templateFlag = args.indexOf("--template");
143
- const templateArg = templateFlag !== -1 ? args[templateFlag + 1] : undefined;
144
- const nameArg = args.find((a) => !a.startsWith("--") && (templateFlag === -1 || args.indexOf(a) !== templateFlag + 1));
145
120
  // If both name and template are provided via CLI args, skip interactive mode
146
121
  if (nameArg) {
147
122
  const template = templateArg ?? "full";
@@ -173,10 +148,8 @@ function printUsage() {
173
148
  console.log(" Run without arguments for interactive mode.");
174
149
  console.log("");
175
150
  }
176
- if (process.argv[1] && realpathSync(resolve(process.argv[1])) === fileURLToPath(import.meta.url)) {
177
- main().catch((err) => {
178
- console.error(err);
179
- process.exit(1);
180
- });
181
- }
151
+ main().catch((err) => {
152
+ console.error(err);
153
+ process.exit(1);
154
+ });
182
155
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,sCAAsC;AACtC,iEAAiE;AAEjE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,4BAA4B;AAE5B,MAAM,SAAS,GAA2C;IACxD,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,aAAa;IACpB,UAAU,EAAE,eAAe;IAC3B,SAAS,EAAE,cAAc;CAC1B,CAAC;AAEF,MAAM,oBAAoB,GAA2B;IACnD,IAAI,EAAE,mEAAmE;IACzE,KAAK,EAAE,oBAAoB;IAC3B,UAAU,EAAE,+BAA+B;IAC3C,SAAS,EAAE,6BAA6B;CACzC,CAAC;AAEF,+BAA+B;AAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,gBAAgB;AAChB,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,UAAU,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,gBAAgB;AAChB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AAChD,MAAM,WAAW,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;AAEvH,2BAA2B;AAE3B,KAAK,UAAU,MAAM,CAAC,QAAgB,EAAE,YAAoB;IAC1D,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,KAAK,YAAY,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1D,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,YAAY,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAC1D,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAE5D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAElD,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAC;IACxC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAErD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAChC,CAAC;AAED,mBAAmB;AAEnB,SAAS,QAAQ,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAU;IAC1D,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mDAAmD;IACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,6CAA6C;IAC7C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAElC,OAAO,CAAC,GAAG,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC;IAC/D,MAAM,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,QAAQ,WAAW,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAC5B,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACxB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,eAAe;AAEf,KAAK,UAAU,IAAI;IACjB,6EAA6E;IAC7E,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,WAAW,IAAI,MAAM,CAAC;QACvC,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAC;QAClC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,2CAA2C;IAC3C,yCAAyC;IACzC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,MAAM,eAAe,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC/D,MAAM,aAAa,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/templates/basic.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;CAyEzB,CAAC"}
1
+ {"version":3,"file":"basic.d.ts","sourceRoot":"","sources":["../../src/templates/basic.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;CAuEzB,CAAC"}
@@ -9,7 +9,7 @@ export const basicTemplate = {
9
9
  start: "node dist/index.js",
10
10
  },
11
11
  dependencies: {
12
- celsian: "^0.3.12",
12
+ celsian: "latest",
13
13
  },
14
14
  devDependencies: {
15
15
  typescript: "^5.7.0",
@@ -22,8 +22,6 @@ export const basicTemplate = {
22
22
  target: "ES2022",
23
23
  module: "ESNext",
24
24
  moduleResolution: "bundler",
25
- lib: ["ES2022"],
26
- types: ["node"],
27
25
  strict: true,
28
26
  esModuleInterop: true,
29
27
  skipLibCheck: true,
@@ -61,7 +59,7 @@ app.get('/hello/:name', (req, reply) => {
61
59
  return reply.json({ message: \`Hello, \${req.params.name}!\` });
62
60
  });
63
61
 
64
- serve(app, { port: 3000 });
62
+ serve(app);
65
63
  `,
66
64
  };
67
65
  //# sourceMappingURL=basic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/templates/basic.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,SAAS;SACnB;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,GAAG,EAAE,CAAC,QAAQ,CAAC;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BjB;CACA,CAAC"}
1
+ {"version":3,"file":"basic.js","sourceRoot":"","sources":["../../src/templates/basic.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,QAAQ;SAClB;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BjB;CACA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"full.d.ts","sourceRoot":"","sources":["../../src/templates/full.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAq4B/C,CAAC"}
1
+ {"version":3,"file":"full.d.ts","sourceRoot":"","sources":["../../src/templates/full.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAm4B/C,CAAC"}
@@ -11,11 +11,11 @@ export const fullTemplate = {
11
11
  lint: "npx tsc --noEmit",
12
12
  },
13
13
  dependencies: {
14
- celsian: "^0.3.12",
15
- "@celsian/core": "^0.3.11",
16
- "@celsian/jwt": "^0.3.11",
17
- "@celsian/rpc": "^0.3.11",
18
- "@celsian/rate-limit": "^0.3.11",
14
+ celsian: "latest",
15
+ "@celsian/core": "latest",
16
+ "@celsian/jwt": "latest",
17
+ "@celsian/rpc": "latest",
18
+ "@celsian/rate-limit": "latest",
19
19
  "@sinclair/typebox": "^0.34.0",
20
20
  },
21
21
  devDependencies: {
@@ -216,7 +216,9 @@ export function securityPlugins(): PluginFunction[] {
216
216
  rateLimit({
217
217
  max: 100,
218
218
  window: 60_000,
219
- keyGenerator: (req) => req.headers.get('x-forwarded-for') ?? 'local',
219
+ // Local scaffold default: use a stable single-process key without trusting proxy headers.
220
+ // In production, replace this with a user/session/IP key appropriate for your deployment.
221
+ keyGenerator: () => 'local-scaffold',
220
222
  }),
221
223
  ];
222
224
  }
@@ -249,7 +251,7 @@ export default function healthRoutes(): PluginFunction {
249
251
 
250
252
  import { Type } from '@sinclair/typebox';
251
253
  import type { CelsianReply, CelsianRequest, PluginFunction } from '@celsian/core';
252
- import type { UpdateUserInput, User, CreateUserInput } from '../types.js';
254
+ import type { User } from '../types.js';
253
255
  import { db } from '../plugins/database.js';
254
256
  import { requireAuth } from '../plugins/auth.js';
255
257
 
@@ -275,7 +277,7 @@ export default function userRoutes(): PluginFunction {
275
277
  app.post('/users', {
276
278
  schema: { body: CreateUserSchema },
277
279
  }, (req, reply) => {
278
- const { name, email } = req.parsedBody as CreateUserInput;
280
+ const { name, email } = req.parsedBody as { name: string; email: string };
279
281
  const user: User = {
280
282
  id: db.generateId(),
281
283
  name,
@@ -300,7 +302,7 @@ export default function userRoutes(): PluginFunction {
300
302
  }, (req, reply) => {
301
303
  const user = db.users.get(req.params.id);
302
304
  if (!user) return reply.status(404).json({ error: 'User not found' });
303
- const updates = req.parsedBody as UpdateUserInput;
305
+ const updates = req.parsedBody as { name?: string; email?: string };
304
306
  if (updates.name !== undefined) user.name = updates.name;
305
307
  if (updates.email !== undefined) user.email = updates.email;
306
308
  db.users.set(user.id, user);
@@ -315,7 +317,7 @@ export default function userRoutes(): PluginFunction {
315
317
  handler(req: CelsianRequest, reply: CelsianReply) {
316
318
  const existed = db.users.delete(req.params.id);
317
319
  if (!existed) return reply.status(404).json({ error: 'User not found' });
318
- return reply.status(204).send(null);
320
+ return reply.status(204).json({ deleted: true });
319
321
  },
320
322
  });
321
323
  };
@@ -333,24 +335,21 @@ import type { PluginFunction } from '@celsian/core';
333
335
  const appRouter = router({
334
336
  greeting: {
335
337
  hello: procedure
336
- .input(Type.Object({ name: Type.String() }))
338
+ .input<{ name: string }>(Type.Object({ name: Type.String() }))
337
339
  .query(({ input }) => {
338
- const data = input as { name: string };
339
- return { message: \`Hello, \${data.name}!\` };
340
+ return { message: \`Hello, \${input.name}!\` };
340
341
  }),
341
342
  },
342
343
  math: {
343
344
  add: procedure
344
- .input(Type.Object({ a: Type.Number(), b: Type.Number() }))
345
+ .input<{ a: number; b: number }>(Type.Object({ a: Type.Number(), b: Type.Number() }))
345
346
  .query(({ input }) => {
346
- const data = input as { a: number; b: number };
347
- return { result: data.a + data.b };
347
+ return { result: input.a + input.b };
348
348
  }),
349
349
  multiply: procedure
350
- .input(Type.Object({ a: Type.Number(), b: Type.Number() }))
350
+ .input<{ a: number; b: number }>(Type.Object({ a: Type.Number(), b: Type.Number() }))
351
351
  .mutation(({ input }) => {
352
- const data = input as { a: number; b: number };
353
- return { result: data.a * data.b };
352
+ return { result: input.a * input.b };
354
353
  }),
355
354
  },
356
355
  system: {
@@ -509,19 +508,18 @@ import healthRoutes from '../src/routes/health.js';
509
508
  import userRoutes from '../src/routes/users.js';
510
509
  import rpcRoutes from '../src/routes/rpc.js';
511
510
 
512
- async function createTestApp() {
511
+ function createTestApp() {
513
512
  const app = createApp();
514
513
  // Register just what we need — skip auth/security for tests
515
- await app.register(healthRoutes());
516
- await app.register(userRoutes());
517
- await app.register(rpcRoutes());
518
- await app.ready();
514
+ app.register(healthRoutes());
515
+ app.register(userRoutes());
516
+ app.register(rpcRoutes());
519
517
  return app;
520
518
  }
521
519
 
522
520
  describe('Health', () => {
523
521
  it('GET /health returns status ok', async () => {
524
- const app = await createTestApp();
522
+ const app = createTestApp();
525
523
  const res = await app.inject({ url: '/health' });
526
524
  expect(res.status).toBe(200);
527
525
  const body = await res.json();
@@ -533,7 +531,7 @@ describe('Health', () => {
533
531
 
534
532
  describe('Users CRUD', () => {
535
533
  it('GET /users returns the seeded user', async () => {
536
- const app = await createTestApp();
534
+ const app = createTestApp();
537
535
  const res = await app.inject({ url: '/users' });
538
536
  expect(res.status).toBe(200);
539
537
  const users = await res.json();
@@ -543,7 +541,7 @@ describe('Users CRUD', () => {
543
541
  });
544
542
 
545
543
  it('POST /users creates a new user', async () => {
546
- const app = await createTestApp();
544
+ const app = createTestApp();
547
545
  const res = await app.inject({
548
546
  method: 'POST',
549
547
  url: '/users',
@@ -558,7 +556,7 @@ describe('Users CRUD', () => {
558
556
  });
559
557
 
560
558
  it('GET /users/:id returns a specific user', async () => {
561
- const app = await createTestApp();
559
+ const app = createTestApp();
562
560
 
563
561
  // Create a user first
564
562
  const createRes = await app.inject({
@@ -576,13 +574,13 @@ describe('Users CRUD', () => {
576
574
  });
577
575
 
578
576
  it('GET /users/:id returns 404 for unknown user', async () => {
579
- const app = await createTestApp();
577
+ const app = createTestApp();
580
578
  const res = await app.inject({ url: '/users/99999' });
581
579
  expect(res.status).toBe(404);
582
580
  });
583
581
 
584
582
  it('DELETE /users/:id without auth returns 401', async () => {
585
- const app = await createTestApp();
583
+ const app = createTestApp();
586
584
  const res = await app.inject({ method: 'DELETE', url: '/users/1' });
587
585
  // Without the JWT guard registered in test mode, the route handler runs directly.
588
586
  // In the full app with auth, this would return 401.
@@ -593,7 +591,7 @@ describe('Users CRUD', () => {
593
591
 
594
592
  describe('RPC', () => {
595
593
  it('GET /_rpc/system.ping returns pong', async () => {
596
- const app = await createTestApp();
594
+ const app = createTestApp();
597
595
  const res = await app.inject({ url: '/_rpc/system.ping' });
598
596
  expect(res.status).toBe(200);
599
597
  const body = await res.json();
@@ -601,7 +599,7 @@ describe('RPC', () => {
601
599
  });
602
600
 
603
601
  it('GET /_rpc/greeting.hello returns greeting', async () => {
604
- const app = await createTestApp();
602
+ const app = createTestApp();
605
603
  const res = await app.inject({
606
604
  url: '/_rpc/greeting.hello?input=' + encodeURIComponent(JSON.stringify({ name: 'World' })),
607
605
  });
@@ -611,7 +609,7 @@ describe('RPC', () => {
611
609
  });
612
610
 
613
611
  it('POST /_rpc/math.multiply performs mutation', async () => {
614
- const app = await createTestApp();
612
+ const app = createTestApp();
615
613
  const res = await app.inject({
616
614
  method: 'POST',
617
615
  url: '/_rpc/math.multiply',
@@ -1 +1 @@
1
- {"version":3,"file":"full.js","sourceRoot":"","sources":["../../src/templates/full.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"full.js","sourceRoot":"","sources":["../../src/templates/full.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/templates/rest-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe;;;;CA8F3B,CAAC"}
1
+ {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/templates/rest-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe;;;;CA4F3B,CAAC"}
@@ -9,7 +9,7 @@ export const restApiTemplate = {
9
9
  start: "node dist/index.js",
10
10
  },
11
11
  dependencies: {
12
- celsian: "^0.3.12",
12
+ celsian: "latest",
13
13
  "@sinclair/typebox": "^0.34.0",
14
14
  },
15
15
  devDependencies: {
@@ -23,8 +23,6 @@ export const restApiTemplate = {
23
23
  target: "ES2022",
24
24
  module: "ESNext",
25
25
  moduleResolution: "bundler",
26
- lib: ["ES2022"],
27
- types: ["node"],
28
26
  strict: true,
29
27
  esModuleInterop: true,
30
28
  skipLibCheck: true,
@@ -82,7 +80,7 @@ app.get('/users/:id', (req, reply) => {
82
80
  return reply.json(user);
83
81
  });
84
82
 
85
- serve(app, { port: 3000 });
83
+ serve(app);
86
84
  `,
87
85
  };
88
86
  //# sourceMappingURL=rest-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.js","sourceRoot":"","sources":["../../src/templates/rest-api.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,SAAS;YAClB,mBAAmB,EAAE,SAAS;SAC/B;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,GAAG,EAAE,CAAC,QAAQ,CAAC;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDjB;CACA,CAAC"}
1
+ {"version":3,"file":"rest-api.js","sourceRoot":"","sources":["../../src/templates/rest-api.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,QAAQ;YACjB,mBAAmB,EAAE,SAAS;SAC/B;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDjB;CACA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-api.d.ts","sourceRoot":"","sources":["../../src/templates/rpc-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;;CAoG1B,CAAC"}
1
+ {"version":3,"file":"rpc-api.d.ts","sourceRoot":"","sources":["../../src/templates/rpc-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;;CAgG1B,CAAC"}
@@ -9,8 +9,8 @@ export const rpcApiTemplate = {
9
9
  start: "node dist/index.js",
10
10
  },
11
11
  dependencies: {
12
- celsian: "^0.3.12",
13
- "@celsian/rpc": "^0.3.11",
12
+ celsian: "latest",
13
+ "@celsian/rpc": "latest",
14
14
  "@sinclair/typebox": "^0.34.0",
15
15
  },
16
16
  devDependencies: {
@@ -24,8 +24,6 @@ export const rpcApiTemplate = {
24
24
  target: "ES2022",
25
25
  module: "ESNext",
26
26
  moduleResolution: "bundler",
27
- lib: ["ES2022"],
28
- types: ["node"],
29
27
  strict: true,
30
28
  esModuleInterop: true,
31
29
  skipLibCheck: true,
@@ -60,18 +58,16 @@ await app.register(security({
60
58
  const appRouter = router({
61
59
  greeting: {
62
60
  hello: procedure
63
- .input(Type.Object({ name: Type.String() }))
61
+ .input<{ name: string }>(Type.Object({ name: Type.String() }))
64
62
  .query(({ input }) => {
65
- const data = input as { name: string };
66
- return { message: \`Hello, \${data.name}!\` };
63
+ return { message: 'Hello, ' + input.name + '!' };
67
64
  }),
68
65
  },
69
66
  math: {
70
67
  add: procedure
71
- .input(Type.Object({ a: Type.Number(), b: Type.Number() }))
68
+ .input<{ a: number; b: number }>(Type.Object({ a: Type.Number(), b: Type.Number() }))
72
69
  .query(({ input }) => {
73
- const data = input as { a: number; b: number };
74
- return { result: data.a + data.b };
70
+ return { result: input.a + input.b };
75
71
  }),
76
72
  },
77
73
  });
@@ -86,7 +82,7 @@ app.route({
86
82
  },
87
83
  });
88
84
 
89
- serve(app, { port: 3000 });
85
+ serve(app);
90
86
 
91
87
  export type AppRouter = typeof appRouter;
92
88
  `,
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-api.js","sourceRoot":"","sources":["../../src/templates/rpc-api.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,SAAS;YAClB,cAAc,EAAE,SAAS;YACzB,mBAAmB,EAAE,SAAS;SAC/B;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,GAAG,EAAE,CAAC,QAAQ,CAAC;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDjB;CACA,CAAC"}
1
+ {"version":3,"file":"rpc-api.js","sourceRoot":"","sources":["../../src/templates/rpc-api.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,8BAA8B;YACnC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,oBAAoB;SAC5B;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,QAAQ;YACjB,cAAc,EAAE,QAAQ;YACxB,mBAAmB,EAAE,SAAS;SAC/B;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,SAAS,CAC7B;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;SACf;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,EACD,IAAI,EACJ,CAAC,CACF;IACD,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDjB;CACA,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-celsian",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "create-celsian": "dist/index.js"
@@ -14,16 +14,16 @@
14
14
  "engines": {
15
15
  "node": ">=20"
16
16
  },
17
- "sideEffects": false,
18
- "description": "Scaffold new CelsianJS applications",
19
17
  "repository": {
20
18
  "type": "git",
21
- "url": "git+https://github.com/CelsianJs/celsian.git"
19
+ "url": "git+https://github.com/CelsianJs/celsian.git",
20
+ "directory": "packages/create-celsian"
22
21
  },
23
22
  "homepage": "https://github.com/CelsianJs/celsian#readme",
24
23
  "bugs": {
25
24
  "url": "https://github.com/CelsianJs/celsian/issues"
26
25
  },
26
+ "description": "Scaffold new CelsianJS applications",
27
27
  "keywords": [
28
28
  "celsian",
29
29
  "create",
@@ -31,6 +31,7 @@
31
31
  "cli",
32
32
  "typescript"
33
33
  ],
34
+ "sideEffects": false,
34
35
  "scripts": {
35
36
  "build": "tsc -b"
36
37
  }