@ahmadjavaiddev/aura 1.0.1 β 1.0.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/README.md +64 -57
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,98 +1,105 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Aura
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**The High-Performance API Scaffolder.**
|
|
4
|
+
Aura is an interactive CLI designed for developers who want to build modern Express.js backendsβwithout the boilerplate. It abstracts framework complexities into a dedicated core while giving you total control over the features you need.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
[](https://www.npmjs.com/package/@ahmadjavaiddev/aura)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why Aura?
|
|
12
|
+
|
|
13
|
+
- **Zero Boilerplate**: Skip the setup. Get a production-ready API in 30 seconds.
|
|
14
|
+
- **Abstraction-First**: Your logic in `src/routes`, framework magic in `src/base`.
|
|
15
|
+
- **Full-Type Safety**: Built from the ground up with TypeScript and Zod.
|
|
16
|
+
- **Enterprise-Ready**: Built-in support for OpenTelemetry, Redis, Auth, and Inngest.
|
|
17
|
+
|
|
18
|
+
---
|
|
9
19
|
|
|
10
|
-
##
|
|
20
|
+
## Quick Start
|
|
11
21
|
|
|
12
|
-
|
|
22
|
+
Start your next project immediately with `npx`:
|
|
13
23
|
|
|
14
24
|
```bash
|
|
15
25
|
npx @ahmadjavaiddev/aura my-new-project
|
|
16
26
|
```
|
|
17
27
|
|
|
18
28
|
### Options
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
| Command | Description |
|
|
30
|
+
| :--- | :--- |
|
|
31
|
+
| `aura [name]` | Create a new project in the specified directory |
|
|
32
|
+
| `-v, --version` | Display current Aura version |
|
|
33
|
+
| `-h, --help` | Show usage information |
|
|
22
34
|
|
|
23
|
-
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Pick Your Stack
|
|
24
38
|
|
|
25
|
-
Aura is
|
|
39
|
+
Aura is modular by design. Select only the components you need for your project:
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- πͺ΅ **Logging**: Advanced OpenTelemetry (with PostHog integration) or standard Console logging.
|
|
31
|
-
- π₯ **Rate Limiting**: Redis-based (distributed) or Basic (memory-based) protection.
|
|
32
|
-
- π¨ **Emails**: Integration with Resend or traditional SMTP via Nodemailer.
|
|
33
|
-
- π **Background Jobs**: Built-in support for Inngest event-driven background functions.
|
|
34
|
-
- π **Linting & Formatting**: Biome (Ultra-fast) or the classic Prettier + ESLint combo.
|
|
35
|
-
- π **Pagination**: Pre-configured Zod schemas and pagination helpers.
|
|
41
|
+
### Database & Models
|
|
42
|
+
- **ORM Options**: Prisma (PostgreSQL), Drizzle (SQL), Mongoose (MongoDB).
|
|
43
|
+
- **Auto-Sync**: Pre-configured scripts for database migrations and client generation.
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
### Security & Auth
|
|
46
|
+
- **Providers**: Clerk (Hosted), Better-Auth (Self-hosted), Custom JWT.
|
|
47
|
+
- **Protection**: Optional Redis-based Rate Limiting and Role-based access skeletons.
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
### Performance & Scaling
|
|
50
|
+
- **Caching**: Choose between local In-memory or distributed Redis caching.
|
|
51
|
+
- **Background Jobs**: Native Inngest support for event-driven background functions.
|
|
52
|
+
|
|
53
|
+
### Observability & Tooling
|
|
54
|
+
- **Logging**: Console-based or OpenTelemetry + PostHog for production tracking.
|
|
55
|
+
- **Development**: Choice of **Biome** (Ultra-fast) or **ESLint + Prettier**.
|
|
56
|
+
- **Email**: Integrated **Resend** or traditional **SMTP** (Nodemailer).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## The Aura Blueprint
|
|
61
|
+
|
|
62
|
+
The generated project structure is designed to isolate framework code from your business logic:
|
|
40
63
|
|
|
41
64
|
```text
|
|
42
65
|
my-new-project/
|
|
43
66
|
βββ src/
|
|
44
|
-
β βββ app.ts #
|
|
45
|
-
β βββ routes/ #
|
|
46
|
-
β βββ base/ # Framework abstractions (
|
|
67
|
+
β βββ app.ts # Clean main entry point
|
|
68
|
+
β βββ routes/ # YOUR LOGIC: API endpoints live here
|
|
69
|
+
β βββ base/ # THE CORE: Framework abstractions (Internal)
|
|
47
70
|
β βββ config/ # Environment & service configurations
|
|
48
|
-
β βββ middlewares/ # Custom middlewares (Auth,
|
|
49
|
-
β βββ utils/ # Shared utilities (Zod
|
|
50
|
-
β βββ
|
|
51
|
-
βββ .env # Pre-configured environment
|
|
71
|
+
β βββ middlewares/ # Custom middlewares (Auth, Logger)
|
|
72
|
+
β βββ utils/ # Shared utilities (Zod, Errors, Email)
|
|
73
|
+
β βββ ... # Feature directories (models, inngest, etc.)
|
|
74
|
+
βββ .env # Pre-configured environment boilerplate
|
|
52
75
|
βββ package.json
|
|
53
76
|
βββ tsconfig.json
|
|
54
77
|
```
|
|
55
78
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Once generated, your project is ready to go:
|
|
59
|
-
|
|
60
|
-
1. **Install Dependencies**:
|
|
61
|
-
```bash
|
|
62
|
-
cd my-new-project
|
|
63
|
-
bun install
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
2. **Database Setup** (if applicable):
|
|
67
|
-
```bash
|
|
68
|
-
bun run db:generate # For Prisma
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
3. **Start Development**:
|
|
72
|
-
```bash
|
|
73
|
-
bun run dev
|
|
74
|
-
```
|
|
79
|
+
---
|
|
75
80
|
|
|
76
|
-
##
|
|
81
|
+
## Defining Routes
|
|
77
82
|
|
|
78
|
-
Aura makes route definition
|
|
83
|
+
Aura makes route definition declarative and type-safe using the `defineRoute` utility:
|
|
79
84
|
|
|
80
85
|
```typescript
|
|
81
86
|
import { defineRoute } from "../base";
|
|
82
87
|
import { z } from "zod";
|
|
83
88
|
|
|
84
89
|
export default defineRoute({
|
|
85
|
-
method: "
|
|
86
|
-
path: "/
|
|
90
|
+
method: "POST",
|
|
91
|
+
path: "/users",
|
|
87
92
|
schema: {
|
|
88
|
-
|
|
93
|
+
body: z.object({ name: z.string(), email: z.string().email() })
|
|
89
94
|
},
|
|
90
|
-
handler: async ({ req, res,
|
|
91
|
-
|
|
95
|
+
handler: async ({ req, res, body }) => {
|
|
96
|
+
// Body is fully typed!
|
|
97
|
+
const { name, email } = body;
|
|
98
|
+
res.status(201).json({ success: true, user: { name, email } });
|
|
92
99
|
},
|
|
93
100
|
});
|
|
94
101
|
```
|
|
95
102
|
|
|
96
103
|
---
|
|
97
104
|
|
|
98
|
-
Built
|
|
105
|
+
Built by [Ahmad Javaid](https://github.com/ahmadjavaiddev)
|
package/dist/index.js
CHANGED
|
@@ -1101,7 +1101,7 @@ ${r.caching==="redis"?" redis,":""}
|
|
|
1101
1101
|
};
|
|
1102
1102
|
},
|
|
1103
1103
|
});
|
|
1104
|
-
`}var Io=St(wt);async function Rr(r,t,o){let i=Le();i.start("Scaffolding your project...");let n=[r,c.join(r,"src"),c.join(r,"src","routes"),c.join(r,"src","base"),c.join(r,"src","config"),c.join(r,"src","middlewares"),c.join(r,"src","utils")];if(o.orm==="prisma")n.push(c.join(r,"prisma"));else if(o.orm==="drizzle")n.push(c.join(r,"src","db"));else if(o.orm==="mongoose")n.push(c.join(r,"src","models"));if(o.inngest!=="none")n.push(c.join(r,"src","inngest")),n.push(c.join(r,"src","inngest","functions"));for(let u of n)await p.mkdir(u,{recursive:!0});if(await p.writeFile(c.join(r,"package.json"),br(t,o)),await p.writeFile(c.join(r,"tsconfig.json"),Ge),await p.writeFile(c.join(r,".gitignore"),ke),await p.writeFile(c.join(r,".env"),xr(o,t)),o.formatter==="biome")await p.writeFile(c.join(r,"biome.json"),ze);else if(o.formatter==="prettier")await p.writeFile(c.join(r,".prettierrc"),qe),await p.writeFile(c.join(r,"eslint.config.js"),Ue);if(o.orm==="prisma")await p.writeFile(c.join(r,"prisma.config.ts"),Xe),await p.writeFile(c.join(r,"prisma","schema.prisma"),Ye);else if(o.orm==="drizzle")await p.writeFile(c.join(r,"drizzle.config.ts"),Fe);await p.writeFile(c.join(r,"src","app.ts"),ur(o)),await p.writeFile(c.join(r,"src","routes","health-route.ts"),yr(o));let s=c.join(r,"src"),e=c.join(s,"base"),a=c.join(s,"config"),d=c.join(s,"middlewares"),l=c.join(s,"utils");if(await p.writeFile(c.join(e,"index.ts"),Sr(o)),await p.writeFile(c.join(e,"define-route.ts"),hr(o)),await p.writeFile(c.join(e,"route-loader.ts"),Be),await p.writeFile(c.join(e,"route-registry.ts"),wr(o)),await p.writeFile(c.join(a,"env.ts"),Er(o,t)),await p.writeFile(c.join(l,"app-error.ts"),fe),await p.writeFile(c.join(l,"error-handler.ts"),vr(o)),o.caching!=="none"){if(o.caching==="redis")await p.writeFile(c.join(a,"redis.ts"),He),await p.writeFile(c.join(l,"cache.ts"),$e);else await p.writeFile(c.join(l,"cache.ts"),We);await p.writeFile(c.join(l,"cache-keys.ts"),Je)}if(o.logger!=="none"){if(o.logger==="otel")await p.writeFile(c.join(l,"logger.ts"),Ze);else await p.writeFile(c.join(l,"logger.ts"),Ve);await p.writeFile(c.join(d,"request-logger.ts"),Ke)}if(o.orm==="prisma")await p.writeFile(c.join(a,"prisma.ts"),Qe);else if(o.orm==="drizzle")await p.writeFile(c.join(a,"drizzle.ts"),De),await p.writeFile(c.join(r,"src","db","schema.ts"),er);else if(o.orm==="mongoose")await p.writeFile(c.join(a,"mongoose.ts"),rr),await p.writeFile(c.join(r,"src","models","user.model.ts"),tr);if(o.auth==="custom")await p.writeFile(c.join(d,"auth.ts"),or);else if(o.auth==="clerk")await p.writeFile(c.join(d,"auth.ts"),nr);else if(o.auth==="betterauth")await p.writeFile(c.join(d,"auth.ts"),ir);if(o.pagination)await p.writeFile(c.join(l,"pagination.ts"),ar);if(o.email==="resend")await p.writeFile(c.join(l,"email.ts"),sr);else if(o.email==="nodemailer")await p.writeFile(c.join(l,"email.ts"),mr);if(o.inngest!=="none"){let u=c.join(r,"src","inngest");await p.writeFile(c.join(u,"client.ts"),cr),await p.writeFile(c.join(u,"index.ts"),lr),await p.writeFile(c.join(u,"functions","hello-world.ts"),pr),await p.writeFile(c.join(r,"src","routes","inngest-route.ts"),dr)}return i.stop("Project generated successfully."),r}import Rt from"path";var Ir={name:"@ahmadjavaiddev/aura",version:"1.0.
|
|
1104
|
+
`}var Io=St(wt);async function Rr(r,t,o){let i=Le();i.start("Scaffolding your project...");let n=[r,c.join(r,"src"),c.join(r,"src","routes"),c.join(r,"src","base"),c.join(r,"src","config"),c.join(r,"src","middlewares"),c.join(r,"src","utils")];if(o.orm==="prisma")n.push(c.join(r,"prisma"));else if(o.orm==="drizzle")n.push(c.join(r,"src","db"));else if(o.orm==="mongoose")n.push(c.join(r,"src","models"));if(o.inngest!=="none")n.push(c.join(r,"src","inngest")),n.push(c.join(r,"src","inngest","functions"));for(let u of n)await p.mkdir(u,{recursive:!0});if(await p.writeFile(c.join(r,"package.json"),br(t,o)),await p.writeFile(c.join(r,"tsconfig.json"),Ge),await p.writeFile(c.join(r,".gitignore"),ke),await p.writeFile(c.join(r,".env"),xr(o,t)),o.formatter==="biome")await p.writeFile(c.join(r,"biome.json"),ze);else if(o.formatter==="prettier")await p.writeFile(c.join(r,".prettierrc"),qe),await p.writeFile(c.join(r,"eslint.config.js"),Ue);if(o.orm==="prisma")await p.writeFile(c.join(r,"prisma.config.ts"),Xe),await p.writeFile(c.join(r,"prisma","schema.prisma"),Ye);else if(o.orm==="drizzle")await p.writeFile(c.join(r,"drizzle.config.ts"),Fe);await p.writeFile(c.join(r,"src","app.ts"),ur(o)),await p.writeFile(c.join(r,"src","routes","health-route.ts"),yr(o));let s=c.join(r,"src"),e=c.join(s,"base"),a=c.join(s,"config"),d=c.join(s,"middlewares"),l=c.join(s,"utils");if(await p.writeFile(c.join(e,"index.ts"),Sr(o)),await p.writeFile(c.join(e,"define-route.ts"),hr(o)),await p.writeFile(c.join(e,"route-loader.ts"),Be),await p.writeFile(c.join(e,"route-registry.ts"),wr(o)),await p.writeFile(c.join(a,"env.ts"),Er(o,t)),await p.writeFile(c.join(l,"app-error.ts"),fe),await p.writeFile(c.join(l,"error-handler.ts"),vr(o)),o.caching!=="none"){if(o.caching==="redis")await p.writeFile(c.join(a,"redis.ts"),He),await p.writeFile(c.join(l,"cache.ts"),$e);else await p.writeFile(c.join(l,"cache.ts"),We);await p.writeFile(c.join(l,"cache-keys.ts"),Je)}if(o.logger!=="none"){if(o.logger==="otel")await p.writeFile(c.join(l,"logger.ts"),Ze);else await p.writeFile(c.join(l,"logger.ts"),Ve);await p.writeFile(c.join(d,"request-logger.ts"),Ke)}if(o.orm==="prisma")await p.writeFile(c.join(a,"prisma.ts"),Qe);else if(o.orm==="drizzle")await p.writeFile(c.join(a,"drizzle.ts"),De),await p.writeFile(c.join(r,"src","db","schema.ts"),er);else if(o.orm==="mongoose")await p.writeFile(c.join(a,"mongoose.ts"),rr),await p.writeFile(c.join(r,"src","models","user.model.ts"),tr);if(o.auth==="custom")await p.writeFile(c.join(d,"auth.ts"),or);else if(o.auth==="clerk")await p.writeFile(c.join(d,"auth.ts"),nr);else if(o.auth==="betterauth")await p.writeFile(c.join(d,"auth.ts"),ir);if(o.pagination)await p.writeFile(c.join(l,"pagination.ts"),ar);if(o.email==="resend")await p.writeFile(c.join(l,"email.ts"),sr);else if(o.email==="nodemailer")await p.writeFile(c.join(l,"email.ts"),mr);if(o.inngest!=="none"){let u=c.join(r,"src","inngest");await p.writeFile(c.join(u,"client.ts"),cr),await p.writeFile(c.join(u,"index.ts"),lr),await p.writeFile(c.join(u,"functions","hello-world.ts"),pr),await p.writeFile(c.join(r,"src","routes","inngest-route.ts"),dr)}return i.stop("Project generated successfully."),r}import Rt from"path";var Ir={name:"@ahmadjavaiddev/aura",version:"1.0.2",type:"module",description:"Interactive CLI scaffolder to generate custom API structures",main:"./dist/index.js",bin:{aura:"dist/index.js"},files:["dist"],publishConfig:{access:"public"},scripts:{start:"bun run src/cli.ts",build:"bun build ./src/cli.ts --outfile ./dist/index.js --target node --bundle --minify",prepublishOnly:"bun run build"},dependencies:{"@clack/prompts":"^0.8.2"},devDependencies:{"@types/bun":"latest","@types/node":"^22.0.0",typescript:"^5.0.0"}};async function It(){let r=process.argv.slice(2);if(r.includes("--version")||r.includes("-v"))console.log(`v${Ir.version}`),process.exit(0);if(r.includes("--help")||r.includes("-h"))console.log(`
|
|
1105
1105
|
Usage: aura [project-name]
|
|
1106
1106
|
|
|
1107
1107
|
Options:
|