create-arkos 1.7.0-canary.38 → 1.7.0-rc
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 +181 -57
- package/dist/utils/project-config-inquirer.js +9 -6
- package/dist/utils/project-config-inquirer.js.map +1 -1
- package/dist/utils/template-compiler.js +1 -0
- package/dist/utils/template-compiler.js.map +1 -1
- package/package.json +1 -1
- package/templates/basic/README.md.hbs +2 -4
- package/templates/basic/package.json.hbs +6 -6
- package/templates/basic/prisma/schema/auth-permission.prisma.hbs +3 -17
- package/templates/basic/prisma/schema/auth-role.prisma.hbs +2 -2
- package/templates/basic/prisma/schema/user-permission.prisma.hbs +18 -0
- package/templates/basic/prisma/schema/user.prisma.hbs +3 -0
- package/templates/basic/src/modules/auth-permission/auth-permission.query.ts.hbs +1 -5
- package/templates/basic/src/modules/auth-permission/dtos/create-auth-permission.dto.ts.hbs +7 -21
- package/templates/basic/src/modules/auth-permission/dtos/update-auth-permission.dto.ts.hbs +13 -16
- package/templates/basic/src/modules/auth-permission/schemas/create-auth-permission.schema.ts.hbs +3 -16
- package/templates/basic/src/modules/auth-permission/schemas/update-auth-permission.schema.ts.hbs +4 -14
- package/templates/basic/src/modules/auth-role/dtos/create-auth-role.dto.ts.hbs +2 -18
- package/templates/basic/src/modules/auth-role/dtos/update-auth-role.dto.ts.hbs +5 -19
- package/templates/basic/src/modules/auth-role/schemas/create-auth-role.schema.ts.hbs +1 -1
- package/templates/basic/src/modules/auth-role/schemas/update-auth-role.schema.ts.hbs +2 -2
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
[](https://badge.socket.dev/npm/package/arkos)
|
|
6
|
+

|
|
7
|
+

|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
13
|
<div align="center">
|
|
14
|
-
<h2>
|
|
15
|
-
<p>
|
|
14
|
+
<h2>The Express & Prisma RESTful Framework</h2>
|
|
15
|
+
<p>A tool for backend developers and teams who ship software with complex business logic under tight deadlines</p>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div align="center">
|
|
@@ -23,91 +23,192 @@
|
|
|
23
23
|
**[Tutorial](https://arkosjs.com/learn)** •
|
|
24
24
|
**[GitHub](https://github.com/uanela/arkos)** •
|
|
25
25
|
**[Blog](https://www.arkosjs.com/blog)** •
|
|
26
|
-
**[Npm](https://www.npmjs.com/package/
|
|
26
|
+
**[Npm](https://www.npmjs.com/package/arkos)**
|
|
27
27
|
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
30
|
## Quick Start
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
|
|
33
|
+
npm create arkos@latest my-project
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Your new project already has JWT auth, customizable CRUD routes, Swagger docs at `/api/docs`, file uploads, validation, and a full security middleware stack. Understand the generated [Project Structure](https://www.arkosjs.com/docs/getting-started/project-structure).
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Your Entry Point
|
|
39
39
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
```typescript
|
|
41
|
+
// src/app.ts
|
|
42
|
+
import arkos from "arkos";
|
|
43
|
+
import postRouter from "@/src/modules/post/post.router"; // custom router
|
|
44
|
+
|
|
45
|
+
const app = arkos();
|
|
46
|
+
|
|
47
|
+
app.use(postRouter);
|
|
48
|
+
|
|
49
|
+
app.listen();
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
Arkos replaces the Express `app` — but it _is_ Express under the hood. You can still use `app.use()`, custom middleware, and raw Express code wherever you need it.
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
# 1. Create your project
|
|
54
|
-
pnpm create arkos@latest my-project
|
|
54
|
+
## Automatic CRUD: One Model, Full REST Endpoints
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
cd my-project
|
|
56
|
+
**Define The Prisma model:**
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
```prisma
|
|
59
|
+
model Post {
|
|
60
|
+
id String @id @default(uuid())
|
|
61
|
+
title String
|
|
62
|
+
content String
|
|
63
|
+
authorId String
|
|
64
|
+
author User @relation(fields: [authorId], references: [id])
|
|
65
|
+
createdAt DateTime @default(now())
|
|
66
|
+
updatedAt DateTime @updatedAt
|
|
67
|
+
}
|
|
68
|
+
```
|
|
61
69
|
|
|
62
|
-
|
|
63
|
-
npx prisma db push
|
|
70
|
+
**Get a full REST API — instantly:**
|
|
64
71
|
|
|
65
|
-
# 5. Start building
|
|
66
|
-
npm run dev
|
|
67
72
|
```
|
|
73
|
+
POST /api/posts Create a post
|
|
74
|
+
GET /api/posts List all posts
|
|
75
|
+
GET /api/posts/:id Get a post
|
|
76
|
+
PATCH /api/posts/:id Update a post
|
|
77
|
+
DELETE /api/posts/:id Delete a post
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Authenticated, validated, and documented. Zero boilerplate.
|
|
81
|
+
|
|
82
|
+
## Creating a Router Beyond Express
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// src/modules/post/post.router.ts
|
|
86
|
+
import { ArkosRouter } from "arkos";
|
|
87
|
+
import CreatePostSchema from "@/src/modules/post/schemas/create-post.schema";
|
|
88
|
+
import postService from "@/src/modules/post/post.service";
|
|
89
|
+
import postPolicy from "@/src/modules/post/post.policy"; // Authorization component
|
|
90
|
+
|
|
91
|
+
const postRouter = ArkosRouter({ prefix: "/api/posts" });
|
|
68
92
|
|
|
69
|
-
|
|
93
|
+
postRouter.post(
|
|
94
|
+
{
|
|
95
|
+
path: "/", // auto registered into openapi
|
|
96
|
+
authentication: postPolicy.Create, // Authentication and authorization with RBAC
|
|
97
|
+
validation: { body: CreatePostSchema }, // auto documented into openapi requestBody
|
|
98
|
+
},
|
|
99
|
+
async (req, res) => {
|
|
100
|
+
const post = await postService.createOne(req.body); // no error handling need, arkos already handles it
|
|
101
|
+
res.json({ data: post });
|
|
102
|
+
}
|
|
103
|
+
);
|
|
70
104
|
|
|
71
|
-
|
|
105
|
+
export default postRouter;
|
|
106
|
+
```
|
|
72
107
|
|
|
73
|
-
|
|
108
|
+
See more about the enhanced express-based router (ArkosRouter) at [ArkosRouter Guide](https://www.arkosjs.com/docs/core-concepts/components/routers).
|
|
74
109
|
|
|
75
|
-
|
|
110
|
+
## Define Permissions Once, Guard Everywhere
|
|
76
111
|
|
|
77
|
-
|
|
112
|
+
```typescript
|
|
113
|
+
// src/modules/post/post.policy.ts
|
|
114
|
+
import { ArkosPolicy } from "arkos";
|
|
78
115
|
|
|
79
|
-
|
|
80
|
-
- **Dynamic** — database-level, roles and permissions stored in tables
|
|
81
|
-
- **None** — skip for now, add when ready
|
|
116
|
+
const postPolicy: ArkosPolicy<"post"> = ArkosPolicy("post");
|
|
82
117
|
|
|
83
|
-
|
|
118
|
+
postPolicy.rule("Create", ["Writer", "Admin"]);
|
|
119
|
+
postPolicy.rule("View", ["Writer", "Admin", "User"]);
|
|
84
120
|
|
|
121
|
+
export default postPolicy;
|
|
85
122
|
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
123
|
+
|
|
124
|
+
Define who can do what, once, per resource. Arkos enforces it across every route that references the policy — no scattered middleware, no repeated role checks.
|
|
125
|
+
|
|
126
|
+
**Customize CRUD Routes just like normal router:**
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// src/modules/post/post.router.ts
|
|
130
|
+
import { ArkosRouter, RouteHook } from "arkos";
|
|
131
|
+
import postPolicy from "@/src/modules/post/post.policy";
|
|
132
|
+
import UpdatePostSchema from "@/src/modules/post/post.schema";
|
|
133
|
+
|
|
134
|
+
export const hook: RouteHook<"prisma"> = {
|
|
135
|
+
findMany: { authentication: false }, // Making GET /api/posts public
|
|
136
|
+
createOne: { authentication: postPolicy.Create },
|
|
137
|
+
updateOne: {
|
|
138
|
+
authentication: postPolicy.Update,
|
|
139
|
+
validation: { body: UpdatePostSchema },
|
|
140
|
+
},
|
|
141
|
+
deleteOne: { authentication: postPolicy.Delete },
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const postRouter = ArkosRouter({ prefix: "/api/posts" });
|
|
145
|
+
|
|
146
|
+
export default postRouter;
|
|
99
147
|
```
|
|
100
148
|
|
|
149
|
+
Your auto-generated CRUD routes accept the same config as any ArkosRouter route — authentication, validation, rate limiting, all in one place.
|
|
150
|
+
|
|
151
|
+
**Add business logic exactly where you need it:**
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// src/modules/post/post.interceptor.ts
|
|
155
|
+
import { ArkosRequest, ArkosResponse, ArkosNextFunction } from "arkos";
|
|
156
|
+
import { BadRequestError } from "arkos/error-handler";
|
|
157
|
+
|
|
158
|
+
export const beforeCreateOne = [
|
|
159
|
+
async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {
|
|
160
|
+
if (req.body.title.length < 5)
|
|
161
|
+
throw new BadRequestError("Title is too short", "TitleTooShort");
|
|
162
|
+
|
|
163
|
+
req.body.slug = req.body.title.toLowerCase().replace(/\s/g, "-");
|
|
164
|
+
req.body.authorId = req.user.id;
|
|
165
|
+
next();
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Name the file, export the hook, and Arkos picks it up automatically. No registration needed.
|
|
171
|
+
|
|
172
|
+
## What You Stop Building From Scratch
|
|
173
|
+
|
|
174
|
+
| What you'd normally write | What Arkos gives you |
|
|
175
|
+
| ---------------------------------------- | --------------------------------- |
|
|
176
|
+
| JWT setup, refresh tokens, bcrypt | ✅ Built-in auth system |
|
|
177
|
+
| 5 route handlers per Prisma model | ✅ Auto-generated CRUD |
|
|
178
|
+
| Zod/CV schemas per endpoint | ✅ Auto generate from your models |
|
|
179
|
+
| Swagger config + schema upkeep | ✅ Auto-generated OpenAPI docs |
|
|
180
|
+
| Multer setup + file type validation | ✅ File upload system |
|
|
181
|
+
| Rate limiting, CORS, Helmet, compression | ✅ Pre-configured security stack |
|
|
182
|
+
| **Total setup time** | **~5 minutes vs ~8–12 hours** |
|
|
183
|
+
|
|
184
|
+
## Documentation
|
|
185
|
+
|
|
186
|
+
For comprehensive guides, API reference, and examples, visit our [official documentation](https://arkosjs.com/docs).
|
|
187
|
+
|
|
188
|
+
**Quick Links:**
|
|
189
|
+
|
|
190
|
+
- [Getting Started Guide](https://arkosjs.com/docs)
|
|
191
|
+
- [Authentication Setup](https://arkosjs.com/docs/core-concepts/authentication/setup)
|
|
192
|
+
- [Using Interceptors](https://arkosjs.com/docs/core-concepts/components/interceptors)
|
|
193
|
+
- [File Uploads](https://arkosjs.com/docs/guides/file-handling/file-uploads/setup)
|
|
194
|
+
- [Validation](https://arkosjs.com/docs/guides/validation/setup)
|
|
195
|
+
- [Email Service](https://arkosjs.com/docs/guides/email-service)
|
|
196
|
+
|
|
101
197
|
## Getting Nightly Updates
|
|
102
198
|
|
|
199
|
+
You can get the latest features we're testing before releasing them:
|
|
200
|
+
|
|
103
201
|
```bash
|
|
104
202
|
pnpm create arkos@next my-project
|
|
105
203
|
```
|
|
106
204
|
|
|
107
|
-
##
|
|
205
|
+
## Built With
|
|
206
|
+
|
|
207
|
+
Arkos.js is built on top of industry-leading tools:
|
|
108
208
|
|
|
109
|
-
-
|
|
110
|
-
-
|
|
209
|
+
- **[Express](https://expressjs.com/)** - Fast, unopinionated, minimalist web framework for Node.js
|
|
210
|
+
- **[Prisma](https://www.prisma.io/)** - Next-generation ORM for Node.js and TypeScript
|
|
211
|
+
- **[Node.js](https://nodejs.org/)** - JavaScript runtime built on Chrome's V8 engine
|
|
111
212
|
|
|
112
213
|
## Support & Contributing
|
|
113
214
|
|
|
@@ -118,6 +219,30 @@ pnpm create arkos@next my-project
|
|
|
118
219
|
|
|
119
220
|
Contributions are welcome! We appreciate all contributions, from bug fixes to new features.
|
|
120
221
|
|
|
222
|
+
## What Developers Say
|
|
223
|
+
|
|
224
|
+
> "Arkos.js changed how I work on the backend: with a Prisma model I already get CRUD routes, auth, and validation out-of-the-box — I saved a lot of time and could focus on business logic."
|
|
225
|
+
>
|
|
226
|
+
> **— Gelson Matavela, Founder / Grupo Vergui**
|
|
227
|
+
|
|
228
|
+
> "It removes boilerplate and provides a clean structure to build products. Built-in auth is powerful and ready. Automatic CRUD and docs save time, while interceptors allow flexible business logic."
|
|
229
|
+
>
|
|
230
|
+
> **— Augusto Domingos, Tech Lead / DSAI For Moz**
|
|
231
|
+
|
|
232
|
+
> "With Arkos.js, I can build backends in just a few minutes. It removes the boilerplate and lets me focus entirely on the core logic. Fast, simple, and incredibly productive."
|
|
233
|
+
>
|
|
234
|
+
> **— Niuro Langa, Software Developer / SparkTech**
|
|
235
|
+
|
|
236
|
+
[See more testimonials →](https://arkosjs.com)
|
|
237
|
+
|
|
238
|
+
## Philosophy
|
|
239
|
+
|
|
240
|
+
Arkos sits between minimal frameworks like Express/Fastify and opinionated ones like NestJS/AdonisJS. It doesn't ask you to learn a new paradigm — it enhances the one most Node.js developers already use, by automating everything that's standardized and staying out of the way everywhere else.
|
|
241
|
+
|
|
242
|
+
Inspired by how Django and Laravel work in their ecosystems: batteries included, nothing forced on you.
|
|
243
|
+
|
|
244
|
+
> The name "Arkos" comes from the Greek word **ἀρχή** _(Arkhē)_, meaning "beginning" or "foundation".
|
|
245
|
+
|
|
121
246
|
## License
|
|
122
247
|
|
|
123
248
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -130,11 +255,10 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
130
255
|
**[Tutorial](https://arkosjs.com/learn)** •
|
|
131
256
|
**[GitHub](https://github.com/uanela/arkos)** •
|
|
132
257
|
**[Blog](https://www.arkosjs.com/blog)** •
|
|
133
|
-
**[Npm](https://www.npmjs.com/package/
|
|
258
|
+
**[Npm](https://www.npmjs.com/package/arkos)**
|
|
134
259
|
|
|
135
260
|
Built with ❤️ by [Uanela Como](https://github.com/uanela) and contributors
|
|
136
261
|
|
|
137
262
|
_The name "Arkos" comes from the Greek word "ἀρχή" (Arkhē), meaning "beginning" or "foundation", reflecting our goal of providing a solid foundation for backend development._
|
|
138
263
|
|
|
139
264
|
</div>
|
|
140
|
-
```
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import inquirer from "inquirer";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { detectPackageManagerFromUserAgent } from "./helpers/npm.helpers.js";
|
|
4
5
|
class ProjectConfigInquirer {
|
|
5
6
|
config;
|
|
6
7
|
constructor() {
|
|
7
|
-
this.config = {
|
|
8
|
+
this.config = {
|
|
9
|
+
packageManager: detectPackageManagerFromUserAgent(),
|
|
10
|
+
};
|
|
8
11
|
}
|
|
9
12
|
async run() {
|
|
10
13
|
await this.promptProjectName();
|
|
@@ -161,7 +164,7 @@ class ProjectConfigInquirer {
|
|
|
161
164
|
}
|
|
162
165
|
async promptAuthentication() {
|
|
163
166
|
if (this.config.prisma.provider === "none") {
|
|
164
|
-
console.info(`${chalk.
|
|
167
|
+
console.info(`${chalk.green("! ")}${chalk.bold("Skipping authentication setup as it requires prisma.")}`);
|
|
165
168
|
this.config.authentication = {
|
|
166
169
|
type: "none",
|
|
167
170
|
};
|
|
@@ -200,8 +203,9 @@ class ProjectConfigInquirer {
|
|
|
200
203
|
usernameField,
|
|
201
204
|
multipleRoles: false,
|
|
202
205
|
};
|
|
203
|
-
if (authenticationType !== "static"
|
|
204
|
-
|
|
206
|
+
if (authenticationType !== "static" ||
|
|
207
|
+
(authenticationType == "static" &&
|
|
208
|
+
this.config.prisma.provider !== "sqlite")) {
|
|
205
209
|
const { multipleRoles } = await inquirer.prompt([
|
|
206
210
|
{
|
|
207
211
|
type: "confirm",
|
|
@@ -216,8 +220,7 @@ class ProjectConfigInquirer {
|
|
|
216
220
|
};
|
|
217
221
|
}
|
|
218
222
|
else if (this.config.prisma.provider === "sqlite") {
|
|
219
|
-
console.info(`${chalk.
|
|
220
|
-
${chalk.bold("Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.")}`);
|
|
223
|
+
console.info(`${chalk.green("! ")}${chalk.bold("Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.")}`);
|
|
221
224
|
}
|
|
222
225
|
}
|
|
223
226
|
async promptStrictRouting() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-config-inquirer.js","sourceRoot":"","sources":["../../src/utils/project-config-inquirer.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\n\nexport interface ProjectConfig {\n projectName: string;\n argProjectName?: string;\n typescript: boolean;\n validation?: {\n type?: \"zod\" | \"class-validator\";\n };\n authentication?: {\n type?: \"static\" | \"dynamic\" | \"none\";\n usernameField?: string;\n multipleRoles?: boolean;\n };\n prisma: {\n provider:\n | \"postgresql\"\n | \"mysql\"\n | \"sqlite\"\n | \"sqlserver\"\n | \"cockroachdb\"\n | \"mongodb\"\n | \"none\";\n idDatabaseType: string;\n defaultDatabaseUrl: string;\n };\n projectPath: string;\n routing?: {\n strict?: boolean;\n };\n advanced?: boolean;\n entryPoint: \"src/app\" | \"src/server\";\n}\n\nclass ProjectConfigInquirer {\n private config: ProjectConfig;\n\n constructor() {\n this.config = {} as ProjectConfig;\n }\n\n async run() {\n await this.promptProjectName();\n await this.promptTypescript();\n await this.promptPrismaProvider();\n await this.promptValidation();\n await this.promptAuthentication();\n await this.promptStrictRouting();\n await this.promptEntryPoint();\n\n if (this.config.projectName === \".\") {\n this.config.projectName = path.basename(process.cwd());\n this.config.projectPath = path.resolve(process.cwd());\n } else\n this.config.projectPath = path.resolve(\n process.cwd(),\n this.config.projectName\n );\n\n if (process?.argv?.includes?.(\"--advanced\")) this.config.advanced = true;\n if (this.config.prisma.defaultDatabaseUrl)\n this.config.prisma.defaultDatabaseUrl =\n this.config.prisma.defaultDatabaseUrl.replaceAll(\n \"{{projectName}}\",\n this.config.projectName\n );\n\n return this.config;\n }\n\n private async promptProjectName() {\n let projectName = process?.argv?.[2];\n this.config.argProjectName = process?.argv?.[2];\n\n if (!projectName) {\n const result = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"What is the name of your project?\",\n default: \"my-arkos-project\",\n validate: this.validateProjectName,\n },\n ]);\n projectName = result.projectName;\n } else {\n const validation = this.validateProjectName(projectName);\n if (validation !== true) {\n console.error(chalk.red(`\\nError: ${validation}`));\n process.exit(1);\n }\n }\n\n this.config.projectName = projectName;\n }\n\n private validateProjectName(input: string): boolean | string {\n if (input === \".\") return true;\n\n if (!input || input.length === 0) {\n return \"Project name cannot be empty\";\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return \"Project name can only contain letters, numbers, hyphens, and underscores\";\n }\n\n if (!/^[a-zA-Z0-9]/.test(input)) {\n return \"Project name must start with a letter or number\";\n }\n\n if (!/[a-zA-Z0-9]$/.test(input)) {\n return \"Project name must end with a letter or number\";\n }\n\n if (input.length > 50) {\n return \"Project name must be 50 characters or less\";\n }\n\n const reservedNames = [\"node_modules\"];\n if (reservedNames.includes(input.toLowerCase())) {\n return \"Project name cannot be a reserved name\";\n }\n\n return true;\n }\n\n private async promptTypescript() {\n const { typescript } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"typescript\",\n message: `Would you like to use ${chalk.cyan(\"TypeScript\")}?`,\n default: true,\n },\n ]);\n this.config.typescript = typescript;\n }\n\n private async promptPrismaProvider() {\n const { prismaProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"prismaProvider\",\n message: `What db provider will be used for ${chalk.cyan(\"Prisma\")}?`,\n choices: [\n \"postgresql\",\n \"mongodb\",\n \"mysql\",\n \"sqlite\",\n \"sqlserver\",\n \"cockroachdb\",\n \"none\",\n ],\n },\n ]);\n\n let idDatabaseType: string;\n let defaultDatabaseUrl: string;\n\n switch (prismaProvider) {\n case \"mongodb\":\n idDatabaseType = '@id @default(auto()) @map(\"_id\") @db.ObjectId';\n defaultDatabaseUrl = `mongodb://localhost:27017/{{projectName}}`;\n break;\n case \"sqlite\":\n idDatabaseType = \"@id @default(cuid())\";\n defaultDatabaseUrl = \"file:../../file.db\";\n break;\n case \"mysql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `mysql://username:password@localhost:3306/{{projectName}}`;\n break;\n case \"postgresql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;\n break;\n case \"sqlserver\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `sqlserver://localhost:1433;database={{projectName}};username=sa;password=password;encrypt=DANGER_PLAINTEXT`;\n break;\n case \"cockroachdb\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:26257/{{projectName}}?sslmode=require`;\n break;\n default:\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;\n }\n\n this.config.prisma = {\n provider: prismaProvider,\n idDatabaseType,\n defaultDatabaseUrl,\n };\n }\n\n private async promptValidation() {\n const choices = this.config.typescript\n ? [\"zod\", \"class-validator\", \"none\"]\n : [\"zod\", \"none\"];\n\n const { validationType } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"validationType\",\n message: `Which ${chalk.cyan(\"Validation\")} library would you like to use?`,\n choices,\n default: \"zod\",\n },\n ]);\n\n if (validationType !== \"none\") {\n this.config.validation = {\n type: validationType as \"zod\" | \"class-validator\",\n };\n }\n // validation stays undefined when \"none\" is chosen — matches original behaviour\n }\n\n private async promptAuthentication() {\n if (this.config.prisma.provider === \"none\") {\n console.info(\n `${chalk.cyan(\"! \")} ${chalk.bold(\"Skipping authentication setup as it requires prisma.\")}`\n );\n this.config.authentication = {\n type: \"none\",\n };\n return;\n }\n\n const { authenticationType } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"authenticationType\",\n message: `Which ${chalk.cyan(\"Authentication\")} mode would you like to use?`,\n choices: [\"static\", \"dynamic\", \"none\"],\n default: \"static\",\n },\n ]);\n\n if (authenticationType === \"none\") {\n this.config.authentication = { type: \"none\", multipleRoles: false };\n return;\n }\n\n const { usernameField } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"usernameField\",\n message: \"Enter the Prisma field name to use as the login username:\",\n default: \"email\",\n validate: (input: string) => {\n if (!input || input.length === 0) return \"Field name cannot be empty\";\n if (!/^[a-z][a-zA-Z0-9]*$/.test(input))\n return \"Must be a valid Prisma field name (camelCase, starts with lowercase, letters and numbers only)\";\n return true;\n },\n },\n ]);\n\n this.config.authentication = {\n type: authenticationType as \"static\" | \"dynamic\",\n usernameField,\n multipleRoles: false,\n };\n\n if (\n authenticationType !== \"static\" &&\n this.config.prisma.provider !== \"sqlite\"\n ) {\n const { multipleRoles } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"multipleRoles\",\n default: true,\n message: `Would you like to use authentication with ${chalk.cyan(\"Multiple Roles\")}?`,\n },\n ]);\n\n this.config.authentication = {\n ...this.config.authentication,\n multipleRoles,\n };\n } else if (this.config.prisma.provider === \"sqlite\") {\n console.info(\n `${chalk.cyan(\"! \")} \n ${chalk.bold(\"Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.\")}`\n );\n }\n }\n\n private async promptStrictRouting() {\n const { strictRouting } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"strictRouting\",\n message: `Would you like to use ${chalk.cyan(\"Strict Routing\")}?`,\n default: false,\n },\n ]);\n this.config.routing = {\n strict: strictRouting,\n };\n }\n\n private async promptEntryPoint() {\n const ext = this.config.typescript ? \"ts\" : \"js\";\n const { entryPoint } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"entryPoint\",\n message: `Which ${chalk.cyan(\"Entry Point\")} would you like to use?`,\n choices: [`src/app.${ext}`, `src/server.${ext}`],\n default: `src/app.${ext}`,\n },\n ]);\n\n this.config.entryPoint = entryPoint.replace(`.${ext}`, \"\");\n }\n}\n\nconst projectConfigInquirer = new ProjectConfigInquirer();\n\nexport default projectConfigInquirer;\n"]}
|
|
1
|
+
{"version":3,"file":"project-config-inquirer.js","sourceRoot":"","sources":["../../src/utils/project-config-inquirer.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport { detectPackageManagerFromUserAgent } from \"./helpers/npm.helpers\";\n\nexport interface ProjectConfig {\n projectName: string;\n argProjectName?: string;\n typescript: boolean;\n validation?: {\n type?: \"zod\" | \"class-validator\";\n };\n authentication?: {\n type?: \"static\" | \"dynamic\" | \"none\";\n usernameField?: string;\n multipleRoles?: boolean;\n };\n prisma: {\n provider:\n | \"postgresql\"\n | \"mysql\"\n | \"sqlite\"\n | \"sqlserver\"\n | \"cockroachdb\"\n | \"mongodb\"\n | \"none\";\n idDatabaseType: string;\n defaultDatabaseUrl: string;\n };\n projectPath: string;\n routing?: {\n strict?: boolean;\n };\n advanced?: boolean;\n entryPoint: \"src/app\" | \"src/server\";\n packageManager: string;\n}\n\nclass ProjectConfigInquirer {\n private config: ProjectConfig;\n\n constructor() {\n this.config = {\n packageManager: detectPackageManagerFromUserAgent(),\n } as ProjectConfig;\n }\n\n async run() {\n await this.promptProjectName();\n await this.promptTypescript();\n await this.promptPrismaProvider();\n await this.promptValidation();\n await this.promptAuthentication();\n await this.promptStrictRouting();\n await this.promptEntryPoint();\n\n if (this.config.projectName === \".\") {\n this.config.projectName = path.basename(process.cwd());\n this.config.projectPath = path.resolve(process.cwd());\n } else\n this.config.projectPath = path.resolve(\n process.cwd(),\n this.config.projectName\n );\n\n if (process?.argv?.includes?.(\"--advanced\")) this.config.advanced = true;\n if (this.config.prisma.defaultDatabaseUrl)\n this.config.prisma.defaultDatabaseUrl =\n this.config.prisma.defaultDatabaseUrl.replaceAll(\n \"{{projectName}}\",\n this.config.projectName\n );\n\n return this.config;\n }\n\n private async promptProjectName() {\n let projectName = process?.argv?.[2];\n this.config.argProjectName = process?.argv?.[2];\n\n if (!projectName) {\n const result = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"What is the name of your project?\",\n default: \"my-arkos-project\",\n validate: this.validateProjectName,\n },\n ]);\n projectName = result.projectName;\n } else {\n const validation = this.validateProjectName(projectName);\n if (validation !== true) {\n console.error(chalk.red(`\\nError: ${validation}`));\n process.exit(1);\n }\n }\n\n this.config.projectName = projectName;\n }\n\n private validateProjectName(input: string): boolean | string {\n if (input === \".\") return true;\n\n if (!input || input.length === 0) {\n return \"Project name cannot be empty\";\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(input)) {\n return \"Project name can only contain letters, numbers, hyphens, and underscores\";\n }\n\n if (!/^[a-zA-Z0-9]/.test(input)) {\n return \"Project name must start with a letter or number\";\n }\n\n if (!/[a-zA-Z0-9]$/.test(input)) {\n return \"Project name must end with a letter or number\";\n }\n\n if (input.length > 50) {\n return \"Project name must be 50 characters or less\";\n }\n\n const reservedNames = [\"node_modules\"];\n if (reservedNames.includes(input.toLowerCase())) {\n return \"Project name cannot be a reserved name\";\n }\n\n return true;\n }\n\n private async promptTypescript() {\n const { typescript } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"typescript\",\n message: `Would you like to use ${chalk.cyan(\"TypeScript\")}?`,\n default: true,\n },\n ]);\n this.config.typescript = typescript;\n }\n\n private async promptPrismaProvider() {\n const { prismaProvider } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"prismaProvider\",\n message: `What db provider will be used for ${chalk.cyan(\"Prisma\")}?`,\n choices: [\n \"postgresql\",\n \"mongodb\",\n \"mysql\",\n \"sqlite\",\n \"sqlserver\",\n \"cockroachdb\",\n \"none\",\n ],\n },\n ]);\n\n let idDatabaseType: string;\n let defaultDatabaseUrl: string;\n\n switch (prismaProvider) {\n case \"mongodb\":\n idDatabaseType = '@id @default(auto()) @map(\"_id\") @db.ObjectId';\n defaultDatabaseUrl = `mongodb://localhost:27017/{{projectName}}`;\n break;\n case \"sqlite\":\n idDatabaseType = \"@id @default(cuid())\";\n defaultDatabaseUrl = \"file:../../file.db\";\n break;\n case \"mysql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `mysql://username:password@localhost:3306/{{projectName}}`;\n break;\n case \"postgresql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;\n break;\n case \"sqlserver\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `sqlserver://localhost:1433;database={{projectName}};username=sa;password=password;encrypt=DANGER_PLAINTEXT`;\n break;\n case \"cockroachdb\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:26257/{{projectName}}?sslmode=require`;\n break;\n default:\n idDatabaseType = \"@id @default(uuid())\";\n defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;\n }\n\n this.config.prisma = {\n provider: prismaProvider,\n idDatabaseType,\n defaultDatabaseUrl,\n };\n }\n\n private async promptValidation() {\n const choices = this.config.typescript\n ? [\"zod\", \"class-validator\", \"none\"]\n : [\"zod\", \"none\"];\n\n const { validationType } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"validationType\",\n message: `Which ${chalk.cyan(\"Validation\")} library would you like to use?`,\n choices,\n default: \"zod\",\n },\n ]);\n\n if (validationType !== \"none\") {\n this.config.validation = {\n type: validationType as \"zod\" | \"class-validator\",\n };\n }\n // validation stays undefined when \"none\" is chosen — matches original behaviour\n }\n\n private async promptAuthentication() {\n if (this.config.prisma.provider === \"none\") {\n console.info(\n `${chalk.green(\"! \")}${chalk.bold(\"Skipping authentication setup as it requires prisma.\")}`\n );\n this.config.authentication = {\n type: \"none\",\n };\n return;\n }\n\n const { authenticationType } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"authenticationType\",\n message: `Which ${chalk.cyan(\"Authentication\")} mode would you like to use?`,\n choices: [\"static\", \"dynamic\", \"none\"],\n default: \"static\",\n },\n ]);\n\n if (authenticationType === \"none\") {\n this.config.authentication = { type: \"none\", multipleRoles: false };\n return;\n }\n\n const { usernameField } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"usernameField\",\n message: \"Enter the Prisma field name to use as the login username:\",\n default: \"email\",\n validate: (input: string) => {\n if (!input || input.length === 0) return \"Field name cannot be empty\";\n if (!/^[a-z][a-zA-Z0-9]*$/.test(input))\n return \"Must be a valid Prisma field name (camelCase, starts with lowercase, letters and numbers only)\";\n return true;\n },\n },\n ]);\n\n this.config.authentication = {\n type: authenticationType as \"static\" | \"dynamic\",\n usernameField,\n multipleRoles: false,\n };\n\n if (\n authenticationType !== \"static\" ||\n (authenticationType == \"static\" &&\n this.config.prisma.provider !== \"sqlite\")\n ) {\n const { multipleRoles } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"multipleRoles\",\n default: true,\n message: `Would you like to use authentication with ${chalk.cyan(\"Multiple Roles\")}?`,\n },\n ]);\n\n this.config.authentication = {\n ...this.config.authentication,\n multipleRoles,\n };\n } else if (this.config.prisma.provider === \"sqlite\") {\n console.info(\n `${chalk.green(\"! \")}${chalk.bold(\"Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.\")}`\n );\n }\n }\n\n private async promptStrictRouting() {\n const { strictRouting } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"strictRouting\",\n message: `Would you like to use ${chalk.cyan(\"Strict Routing\")}?`,\n default: false,\n },\n ]);\n this.config.routing = {\n strict: strictRouting,\n };\n }\n\n private async promptEntryPoint() {\n const ext = this.config.typescript ? \"ts\" : \"js\";\n const { entryPoint } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"entryPoint\",\n message: `Which ${chalk.cyan(\"Entry Point\")} would you like to use?`,\n choices: [`src/app.${ext}`, `src/server.${ext}`],\n default: `src/app.${ext}`,\n },\n ]);\n\n this.config.entryPoint = entryPoint.replace(`.${ext}`, \"\");\n }\n}\n\nconst projectConfigInquirer = new ProjectConfigInquirer();\n\nexport default projectConfigInquirer;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template-compiler.js","sourceRoot":"","sources":["../../src/utils/template-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ProjectConfig } from \"./project-config-inquirer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport handlebars from \"handlebars\";\n\nclass TemplateCompiler {\n async canCompileAuthenticationTemplates(config: ProjectConfig) {\n return !!config.authentication;\n }\n\n filesToBeSkipped(config: ProjectConfig) {\n const files: string[] = [];\n const authSharedPrismaFiles = [\"user.prisma.hbs\"];\n\n const dynamicAuthPrismaFiles = [\n \"auth-permission.prisma.hbs\",\n \"auth-role.prisma.hbs\",\n \"user-role.prisma.hbs\",\n ];\n\n const sharedAuthZodSchemaFiles = [\n \"login.schema.ts.hbs\",\n \"signup.schema.ts.hbs\",\n \"update-password.schema.ts.hbs\",\n \"update-me.schema.ts.hbs\",\n ];\n\n const dynamicAuthZodSchemaFiles = [\n \"create-auth-permission.schema.ts.hbs\",\n \"update-auth-permission.schema.ts.hbs\",\n \"create-auth-role.schema.ts.hbs\",\n \"update-auth-role.schema.ts.hbs\",\n ];\n\n const userZodSchemaFiles = [\n \"create-user.schema.ts.hbs\",\n \"update-user.schema.ts.hbs\",\n ];\n\n const userClassValidatorDtoFiles = [\n \"create-user.dto.ts.hbs\",\n \"update-user.dto.ts.hbs\",\n ];\n\n const sharedAuthClassValidatorDtoFiles = [\n \"login.dto.ts.hbs\",\n \"signup.dto.ts.hbs\",\n \"update-password.dto.ts.hbs\",\n \"update-me.dto.ts.hbs\",\n ];\n\n const dynamicAuthClassValidatorDtoFiles = [\n \"create-auth-permission.dto.ts.hbs\",\n \"update-auth-permission.dto.ts.hbs\",\n \"create-auth-role.dto.ts.hbs\",\n \"update-auth-role.dto.ts.hbs\",\n ];\n\n const authModuleComponents = [\n \"auth.interceptors.ts.hbs\",\n \"auth.query.ts.hbs\",\n ];\n\n const authPermissionModuleComponents = [\n \"auth-permission.router.ts.hbs\",\n \"auth-permission.policy.ts.hbs\",\n \"auth-permission.query.ts.hbs\",\n\n \"auth-permission.query.ts.hbs\",\n \"auth-permission.service.ts.hbs\",\n ];\n\n const authRoleModuleComponents = [\n \"auth-role.router.ts.hbs\",\n \"auth-role.policy.ts.hbs\",\n \"auth-role.query.ts.hbs\",\n\n \"auth-role.query.ts.hbs\",\n \"auth-role.service.ts.hbs\",\n ];\n\n const userModuleComponents = [\n \"user.interceptors.ts.hbs\",\n \"user.query.ts.hbs\",\n \"user.service.ts.hbs\",\n \"user.router.ts.hbs\",\n \"user.policy.ts.hbs\",\n ];\n\n if (config.prisma?.provider === \"none\")\n files.push(\n ...authSharedPrismaFiles,\n ...dynamicAuthPrismaFiles,\n \"schema.prisma.hbs\",\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userZodSchemaFiles,\n ...userClassValidatorDtoFiles,\n \"file-upload.auth.ts.hbs\",\n \"index.ts.hbs\"\n );\n\n if (!config.authentication?.type || config.authentication?.type === \"none\")\n files.push(\n ...authSharedPrismaFiles,\n ...dynamicAuthPrismaFiles,\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userZodSchemaFiles,\n ...userClassValidatorDtoFiles,\n \"file-upload.router.ts.hbs\",\n \"file-upload.policy.ts.hbs\"\n );\n\n if (config.authentication?.type === \"static\")\n files.push(\n ...dynamicAuthPrismaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents\n );\n\n if (config.validation?.type !== \"zod\")\n files.push(\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...userZodSchemaFiles,\n \"api-actions.hbs.ts\"\n );\n\n // Ignore class-validator related files when validation is zod\n if (config.validation?.type !== \"class-validator\")\n files.push(\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userClassValidatorDtoFiles\n );\n\n // Ignoring typescript related files when typescript false\n if (!config.typescript) files.push(...[\"tsconfig.json.hbs\"]);\n\n // Ignoring javascript related files when typescript true\n if (config?.typescript) files.push(...[\"jsconfig.json.hbs\"]);\n\n if (config.entryPoint === \"src/app\") files.push(\"server.ts.hbs\");\n\n return files;\n }\n /**\n * Compiles the Arkos.js project with handlebars templates\n *\n * @param templatesDir {string} templates location\n * @param config {ProjectConfig} the project configuration\n * @returns void\n * */\n async compile(templatesDir: string, config: ProjectConfig) {\n const outputDir = config.projectPath;\n const isTypescript = config.typescript;\n const filesToBeSkipped = this.filesToBeSkipped(config);\n\n function processTemplates(dir: string, relativeDir = \"\") {\n fs.readdirSync(dir, { withFileTypes: true }).forEach(async (dirent) => {\n if (\n filesToBeSkipped.includes(dirent.name) ||\n dirent.name === \"__tests__\" ||\n dirent.name?.includes(\".test.ts\")\n )\n return;\n\n const fullPath = path.join(dir, dirent.name);\n const relativePath = path.join(relativeDir, dirent.name);\n\n if (dirent.isDirectory()) {\n processTemplates(fullPath, relativePath);\n } else if (dirent.name.endsWith(\".hbs\")) {\n const templatePath = fullPath;\n const template = handlebars.compile(\n fs.readFileSync(templatePath, \"utf8\")\n );\n\n let arkosCurrentVersion = \"{{arkosCurrentVersion}}\";\n\n const content = template({ ...config, arkosCurrentVersion });\n const ext = isTypescript ? \".ts\" : \".js\";\n\n let outputPath = path.join(\n outputDir,\n relativePath.replace(\".hbs\", \"\")\n );\n if (dirent.name.endsWith(\".ts.hbs\"))\n outputPath = path.join(\n outputDir,\n relativePath.replace(\".ts.hbs\", ext)\n );\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, content);\n } else {\n const outputPath = path.join(outputDir, relativePath);\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.copyFileSync(fullPath, outputPath);\n }\n });\n }\n\n processTemplates(templatesDir);\n }\n}\n\nconst templateCompiler = new TemplateCompiler();\n\nexport default templateCompiler;\n"]}
|
|
1
|
+
{"version":3,"file":"template-compiler.js","sourceRoot":"","sources":["../../src/utils/template-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["import { ProjectConfig } from \"./project-config-inquirer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport handlebars from \"handlebars\";\n\nclass TemplateCompiler {\n async canCompileAuthenticationTemplates(config: ProjectConfig) {\n return !!config.authentication;\n }\n\n filesToBeSkipped(config: ProjectConfig) {\n const files: string[] = [];\n const authSharedPrismaFiles = [\"user.prisma.hbs\"];\n\n const dynamicAuthPrismaFiles = [\n \"auth-permission.prisma.hbs\",\n \"auth-role.prisma.hbs\",\n \"user-role.prisma.hbs\",\n \"user-permission.prisma.hbs\",\n ];\n\n const sharedAuthZodSchemaFiles = [\n \"login.schema.ts.hbs\",\n \"signup.schema.ts.hbs\",\n \"update-password.schema.ts.hbs\",\n \"update-me.schema.ts.hbs\",\n ];\n\n const dynamicAuthZodSchemaFiles = [\n \"create-auth-permission.schema.ts.hbs\",\n \"update-auth-permission.schema.ts.hbs\",\n \"create-auth-role.schema.ts.hbs\",\n \"update-auth-role.schema.ts.hbs\",\n ];\n\n const userZodSchemaFiles = [\n \"create-user.schema.ts.hbs\",\n \"update-user.schema.ts.hbs\",\n ];\n\n const userClassValidatorDtoFiles = [\n \"create-user.dto.ts.hbs\",\n \"update-user.dto.ts.hbs\",\n ];\n\n const sharedAuthClassValidatorDtoFiles = [\n \"login.dto.ts.hbs\",\n \"signup.dto.ts.hbs\",\n \"update-password.dto.ts.hbs\",\n \"update-me.dto.ts.hbs\",\n ];\n\n const dynamicAuthClassValidatorDtoFiles = [\n \"create-auth-permission.dto.ts.hbs\",\n \"update-auth-permission.dto.ts.hbs\",\n \"create-auth-role.dto.ts.hbs\",\n \"update-auth-role.dto.ts.hbs\",\n ];\n\n const authModuleComponents = [\n \"auth.interceptors.ts.hbs\",\n \"auth.query.ts.hbs\",\n ];\n\n const authPermissionModuleComponents = [\n \"auth-permission.router.ts.hbs\",\n \"auth-permission.policy.ts.hbs\",\n \"auth-permission.query.ts.hbs\",\n \"auth-permission.query.ts.hbs\",\n \"auth-permission.service.ts.hbs\",\n ];\n\n const authRoleModuleComponents = [\n \"auth-role.router.ts.hbs\",\n \"auth-role.policy.ts.hbs\",\n \"auth-role.query.ts.hbs\",\n \"auth-role.query.ts.hbs\",\n \"auth-role.service.ts.hbs\",\n ];\n\n const userModuleComponents = [\n \"user.interceptors.ts.hbs\",\n \"user.query.ts.hbs\",\n \"user.service.ts.hbs\",\n \"user.router.ts.hbs\",\n \"user.policy.ts.hbs\",\n ];\n\n if (config.prisma?.provider === \"none\")\n files.push(\n ...authSharedPrismaFiles,\n ...dynamicAuthPrismaFiles,\n \"schema.prisma.hbs\",\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userZodSchemaFiles,\n ...userClassValidatorDtoFiles,\n \"file-upload.auth.ts.hbs\",\n \"index.ts.hbs\"\n );\n\n if (!config.authentication?.type || config.authentication?.type === \"none\")\n files.push(\n ...authSharedPrismaFiles,\n ...dynamicAuthPrismaFiles,\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userZodSchemaFiles,\n ...userClassValidatorDtoFiles,\n \"file-upload.router.ts.hbs\",\n \"file-upload.policy.ts.hbs\"\n );\n\n if (config.authentication?.type === \"static\")\n files.push(\n ...dynamicAuthPrismaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents\n );\n\n if (config.validation?.type !== \"zod\")\n files.push(\n ...sharedAuthZodSchemaFiles,\n ...dynamicAuthZodSchemaFiles,\n ...userZodSchemaFiles,\n \"api-actions.hbs.ts\"\n );\n\n // Ignore class-validator related files when validation is zod\n if (config.validation?.type !== \"class-validator\")\n files.push(\n ...sharedAuthClassValidatorDtoFiles,\n ...dynamicAuthClassValidatorDtoFiles,\n ...userClassValidatorDtoFiles\n );\n\n // Ignoring typescript related files when typescript false\n if (!config.typescript) files.push(...[\"tsconfig.json.hbs\"]);\n\n // Ignoring javascript related files when typescript true\n if (config?.typescript) files.push(...[\"jsconfig.json.hbs\"]);\n\n if (config.entryPoint === \"src/app\") files.push(\"server.ts.hbs\");\n\n return files;\n }\n /**\n * Compiles the Arkos.js project with handlebars templates\n *\n * @param templatesDir {string} templates location\n * @param config {ProjectConfig} the project configuration\n * @returns void\n * */\n async compile(templatesDir: string, config: ProjectConfig) {\n const outputDir = config.projectPath;\n const isTypescript = config.typescript;\n const filesToBeSkipped = this.filesToBeSkipped(config);\n\n function processTemplates(dir: string, relativeDir = \"\") {\n fs.readdirSync(dir, { withFileTypes: true }).forEach(async (dirent) => {\n if (\n filesToBeSkipped.includes(dirent.name) ||\n dirent.name === \"__tests__\" ||\n dirent.name?.includes(\".test.ts\")\n )\n return;\n\n const fullPath = path.join(dir, dirent.name);\n const relativePath = path.join(relativeDir, dirent.name);\n\n if (dirent.isDirectory()) {\n processTemplates(fullPath, relativePath);\n } else if (dirent.name.endsWith(\".hbs\")) {\n const templatePath = fullPath;\n const template = handlebars.compile(\n fs.readFileSync(templatePath, \"utf8\")\n );\n\n let arkosCurrentVersion = \"{{arkosCurrentVersion}}\";\n\n const content = template({ ...config, arkosCurrentVersion });\n const ext = isTypescript ? \".ts\" : \".js\";\n\n let outputPath = path.join(\n outputDir,\n relativePath.replace(\".hbs\", \"\")\n );\n if (dirent.name.endsWith(\".ts.hbs\"))\n outputPath = path.join(\n outputDir,\n relativePath.replace(\".ts.hbs\", ext)\n );\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, content);\n } else {\n const outputPath = path.join(outputDir, relativePath);\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.copyFileSync(fullPath, outputPath);\n }\n });\n }\n\n processTemplates(templatesDir);\n }\n}\n\nconst templateCompiler = new TemplateCompiler();\n\nexport default templateCompiler;\n"]}
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
This is
|
|
1
|
+
This is an [Arkos.js](https://arkosjs.com) project scaffolded with [`create-arkos`](https://arkosjs.com/docs/tooling/cli/overviewcreate-arkos).
|
|
2
2
|
|
|
3
3
|
## Getting Started
|
|
4
4
|
|
|
5
5
|
First, run the development server:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
9
|
-
# or
|
|
10
|
-
npm run dev
|
|
8
|
+
{{packageManager}} run dev
|
|
11
9
|
```
|
|
12
10
|
|
|
13
11
|
- Visit [http://localhost:8000/api/docs](http://localhost:8000/api/docs) with your browser to see the swagger api documentation.
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"@types/express": "5.0.0",
|
|
20
20
|
{{/if}}
|
|
21
21
|
"tsx-strict": "0.7.0",
|
|
22
|
-
"tsx": "4.
|
|
23
|
-
"prisma": "6.19.
|
|
22
|
+
"tsx": "4.23.1"{{#if (neq prisma.provider "none")}},
|
|
23
|
+
"prisma": "6.19.3"
|
|
24
24
|
{{/if}}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"arkos": "1.7.0-
|
|
28
|
-
"express": "4.22.
|
|
27
|
+
"arkos": "1.7.0-rc",
|
|
28
|
+
"express": "4.22.2",
|
|
29
29
|
"@scalar/express-api-reference": "0.10.2",
|
|
30
30
|
"@scalar/api-reference": "1.55.3"{{#if (or (neq prisma.provider "none") validation.type)}},{{/if}}
|
|
31
31
|
{{#if (neq prisma.provider "none")}}
|
|
32
|
-
"@prisma/client": "6.19.
|
|
32
|
+
"@prisma/client": "6.19.3"{{#if validation.type}},{{/if}}
|
|
33
33
|
{{/if}}
|
|
34
34
|
{{#if (eq validation.type "class-validator")}}
|
|
35
35
|
"reflect-metadata": "0.2.2",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"class-validator": "0.14.1"
|
|
38
38
|
{{/if}}
|
|
39
39
|
{{#if (eq validation.type "zod")}}
|
|
40
|
-
"zod": "3.
|
|
40
|
+
"zod": "3.25.76"
|
|
41
41
|
{{/if}}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -1,27 +1,13 @@
|
|
|
1
|
-
{{#if (neq prisma.provider "sqlite")}}
|
|
2
|
-
enum AuthPermissionAction {
|
|
3
|
-
View
|
|
4
|
-
Create
|
|
5
|
-
Update
|
|
6
|
-
Delete
|
|
7
|
-
// Add more custom actions
|
|
8
|
-
}
|
|
9
|
-
{{/if}}
|
|
10
|
-
|
|
11
1
|
model AuthPermission {
|
|
12
2
|
id String {{{prisma.idDatabaseType}}}
|
|
13
3
|
resource String
|
|
14
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
15
4
|
action String @default("View")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{{/if}}
|
|
19
|
-
roleId String {{#if (eq prisma.provider "mongodb")}}@db.ObjectId{{/if}}
|
|
20
|
-
role AuthRole @relation(fields: [roleId], references: [id])
|
|
5
|
+
roles AuthRole[]
|
|
6
|
+
users UserPermission[]
|
|
21
7
|
createdAt DateTime @default(now())
|
|
22
8
|
updatedAt DateTime @updatedAt
|
|
23
9
|
|
|
24
|
-
@@unique([resource, action
|
|
10
|
+
@@unique([resource, action])
|
|
25
11
|
}
|
|
26
12
|
|
|
27
13
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
model UserPermission {
|
|
2
|
+
id String @id @default(uuid())
|
|
3
|
+
createdAt DateTime @default(now())
|
|
4
|
+
updatedAt DateTime @updatedAt
|
|
5
|
+
|
|
6
|
+
effect UserPermissionEffect @default(Allow)
|
|
7
|
+
userId String
|
|
8
|
+
user User @relation(fields: [userId], references: [id])
|
|
9
|
+
permissionId String
|
|
10
|
+
permission AuthPermission @relation(fields: [permissionId], references: [id])
|
|
11
|
+
|
|
12
|
+
@@unique([userId, permissionId])
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
enum UserPermissionEffect {
|
|
16
|
+
Allow
|
|
17
|
+
Deny
|
|
18
|
+
}
|
|
@@ -10,11 +10,7 @@ const authPermissionQueryOptions: PrismaQueryOptions<Prisma.AuthPermissionDelega
|
|
|
10
10
|
const authPermissionQueryOptions = {
|
|
11
11
|
{{/if}}
|
|
12
12
|
global: {},
|
|
13
|
-
find: {
|
|
14
|
-
include: {
|
|
15
|
-
role: true
|
|
16
|
-
},
|
|
17
|
-
},
|
|
13
|
+
find: {},
|
|
18
14
|
findOne: {},
|
|
19
15
|
findMany: {},
|
|
20
16
|
update: {},
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import { IsString, IsNotEmpty, IsOptional,
|
|
1
|
+
import { IsString, IsNotEmpty, IsOptional, ValidateNested, IsArray } from 'class-validator';
|
|
2
2
|
import { Type, Transform } from 'class-transformer';
|
|
3
3
|
import 'reflect-metadata'
|
|
4
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
5
|
-
|
|
6
|
-
export enum AuthPermissionAction {
|
|
7
|
-
View = 'View',
|
|
8
|
-
Create = 'Create',
|
|
9
|
-
Update = 'Update',
|
|
10
|
-
Delete = 'Delete'
|
|
11
|
-
}
|
|
12
|
-
{{else}}
|
|
13
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
14
|
-
{{/if}}
|
|
15
4
|
|
|
16
5
|
class RoleConnectDto {
|
|
17
6
|
@IsString()
|
|
@@ -24,16 +13,13 @@ export default class CreateAuthPermissionDto {
|
|
|
24
13
|
@IsNotEmpty({ message: 'Resource is required' })
|
|
25
14
|
resource!: string;
|
|
26
15
|
|
|
27
|
-
@
|
|
28
|
-
@Transform(({ value }) => value
|
|
29
|
-
action
|
|
16
|
+
@IsString()
|
|
17
|
+
@Transform(({ value }) => String(value))
|
|
18
|
+
action!: string;
|
|
30
19
|
|
|
31
|
-
@ValidateNested()
|
|
20
|
+
@ValidateNested({ each: true })
|
|
21
|
+
@IsArray()
|
|
32
22
|
@Type(() => RoleConnectDto)
|
|
33
|
-
role!: RoleConnectDto;
|
|
34
|
-
|
|
35
23
|
@IsOptional()
|
|
36
|
-
|
|
37
|
-
@Transform(({ value }) => value)
|
|
38
|
-
description?: string;
|
|
24
|
+
roles?: RoleConnectDto[];
|
|
39
25
|
}
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import { IsString, IsOptional,
|
|
2
|
-
import { Transform } from 'class-transformer';
|
|
1
|
+
import { IsString, IsOptional, IsNotEmpty, IsArray, ValidateNested } from 'class-validator';
|
|
2
|
+
import { Transform, Type } from 'class-transformer';
|
|
3
3
|
import 'reflect-metadata'
|
|
4
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Delete = 'Delete'
|
|
5
|
+
class RoleConnectDto {
|
|
6
|
+
@IsString()
|
|
7
|
+
@IsNotEmpty({ message: 'Role ID is required' })
|
|
8
|
+
id!: string;
|
|
11
9
|
}
|
|
12
|
-
{{else}}
|
|
13
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
14
|
-
{{/if}}
|
|
15
10
|
|
|
16
11
|
export default class UpdateAuthPermissionDto {
|
|
17
12
|
@IsOptional()
|
|
@@ -19,11 +14,13 @@ export default class UpdateAuthPermissionDto {
|
|
|
19
14
|
resource?: string;
|
|
20
15
|
|
|
21
16
|
@IsOptional()
|
|
22
|
-
@
|
|
23
|
-
@Transform(({ value }) => value)
|
|
24
|
-
action?:
|
|
17
|
+
@IsString()
|
|
18
|
+
@Transform(({ value }) => String(value))
|
|
19
|
+
action?: string
|
|
25
20
|
|
|
21
|
+
@ValidateNested({ each: true })
|
|
22
|
+
@IsArray()
|
|
23
|
+
@Type(() => RoleConnectDto)
|
|
26
24
|
@IsOptional()
|
|
27
|
-
|
|
28
|
-
description?: string;
|
|
25
|
+
roles?: RoleConnectDto[];
|
|
29
26
|
}
|
package/templates/basic/src/modules/auth-permission/schemas/create-auth-permission.schema.ts.hbs
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
3
|
-
|
|
4
|
-
export const AuthPermissionActionEnum = z.enum([
|
|
5
|
-
'View',
|
|
6
|
-
'Create',
|
|
7
|
-
'Update',
|
|
8
|
-
'Delete'
|
|
9
|
-
]);
|
|
10
|
-
{{else}}
|
|
11
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
12
|
-
export const AuthPermissionActionEnum = z.nativeEnum(AuthPermissionAction);
|
|
13
|
-
{{/if}}
|
|
14
2
|
|
|
15
3
|
const CreateAuthPermissionSchema = z.object({
|
|
16
4
|
resource: z.string().min(1, 'Resource is required'),
|
|
17
|
-
action:
|
|
18
|
-
|
|
5
|
+
action: z.string().min(1),
|
|
6
|
+
roles: z.array(z.object({
|
|
19
7
|
id: z.string().min(1, 'Role ID is required'),
|
|
20
|
-
}),
|
|
21
|
-
description: z.string().optional().default("Allows to create a permission for a given role."),
|
|
8
|
+
})).optional(),
|
|
22
9
|
});
|
|
23
10
|
|
|
24
11
|
export default CreateAuthPermissionSchema
|
package/templates/basic/src/modules/auth-permission/schemas/update-auth-permission.schema.ts.hbs
CHANGED
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
3
|
-
|
|
4
|
-
export const AuthPermissionActionEnum = z.enum([
|
|
5
|
-
'View',
|
|
6
|
-
'Create',
|
|
7
|
-
'Update',
|
|
8
|
-
'Delete'
|
|
9
|
-
]);
|
|
10
|
-
{{else}}
|
|
11
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
12
|
-
export const AuthPermissionActionEnum = z.nativeEnum(AuthPermissionAction);
|
|
13
|
-
{{/if}}
|
|
14
2
|
|
|
15
3
|
const UpdateAuthPermissionSchema = z.object({
|
|
16
4
|
resource: z.string().optional(),
|
|
17
|
-
action:
|
|
18
|
-
|
|
5
|
+
action: z.string().min(1).optional(),
|
|
6
|
+
roles: z.array(z.object({
|
|
7
|
+
id: z.string().min(1, 'Role ID is required'),
|
|
8
|
+
})).optional(),
|
|
19
9
|
});
|
|
20
10
|
|
|
21
11
|
export default UpdateAuthPermissionSchema
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
import { IsString, IsNotEmpty, IsOptional, IsArray, ValidateNested, IsEnum } from 'class-validator';
|
|
2
2
|
import { Type, Transform } from 'class-transformer';
|
|
3
3
|
import 'reflect-metadata'
|
|
4
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
5
|
-
|
|
6
|
-
export enum AuthPermissionAction {
|
|
7
|
-
View = 'View',
|
|
8
|
-
Create = 'Create',
|
|
9
|
-
Update = 'Update',
|
|
10
|
-
Delete = 'Delete'
|
|
11
|
-
}
|
|
12
|
-
{{else}}
|
|
13
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
14
|
-
{{/if}}
|
|
15
4
|
|
|
16
5
|
class CreatePermissionForRoleDto {
|
|
17
6
|
@IsString()
|
|
18
7
|
@IsNotEmpty({ message: 'Resource is required' })
|
|
19
8
|
resource!: string;
|
|
20
9
|
|
|
21
|
-
@IsEnum(AuthPermissionAction)
|
|
22
|
-
@Transform(({ value }) => value || AuthPermissionAction.View)
|
|
23
|
-
action: AuthPermissionAction = AuthPermissionAction.View;
|
|
24
|
-
|
|
25
|
-
@IsOptional()
|
|
26
10
|
@IsString()
|
|
27
|
-
@Transform(({ value }) => value)
|
|
28
|
-
|
|
11
|
+
@Transform(({ value }) => String(value))
|
|
12
|
+
action!: string;
|
|
29
13
|
}
|
|
30
14
|
|
|
31
15
|
export default class CreateAuthRoleDto {
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
import { IsString, IsNotEmpty, IsOptional, IsArray, ValidateNested, IsEnum } from 'class-validator';
|
|
2
2
|
import { Type, Transform } from 'class-transformer';
|
|
3
3
|
import 'reflect-metadata'
|
|
4
|
-
{{#if (eq prisma.provider "sqlite")}}
|
|
5
|
-
|
|
6
|
-
export enum AuthPermissionAction {
|
|
7
|
-
View = 'View',
|
|
8
|
-
Create = 'Create',
|
|
9
|
-
Update = 'Update',
|
|
10
|
-
Delete = 'Delete'
|
|
11
|
-
}
|
|
12
|
-
{{else}}
|
|
13
|
-
import { AuthPermissionAction } from "@prisma/client"
|
|
14
|
-
{{/if}}
|
|
15
4
|
|
|
16
5
|
export enum ApiAction {
|
|
17
6
|
connect = 'connect',
|
|
18
|
-
|
|
7
|
+
disconnect = 'disconnect'
|
|
19
8
|
}
|
|
20
9
|
|
|
21
10
|
class UpdatePermissionForRoleDto {
|
|
@@ -25,16 +14,13 @@ class UpdatePermissionForRoleDto {
|
|
|
25
14
|
|
|
26
15
|
@IsString()
|
|
27
16
|
@IsNotEmpty({ message: 'Resource is required' })
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@IsEnum(AuthPermissionAction)
|
|
31
|
-
@Transform(({ value }) => value)
|
|
32
|
-
action!: AuthPermissionAction
|
|
17
|
+
@IsOptional()
|
|
18
|
+
resource?: string;
|
|
33
19
|
|
|
34
20
|
@IsOptional()
|
|
35
21
|
@IsString()
|
|
36
|
-
@Transform(({ value }) => value)
|
|
37
|
-
|
|
22
|
+
@Transform(({ value }) => String(value))
|
|
23
|
+
action?: string
|
|
38
24
|
|
|
39
25
|
@IsEnum(ApiAction)
|
|
40
26
|
@IsOptional()
|
|
@@ -4,7 +4,7 @@ import CreateAuthPermissionSchema from "@/src/modules/auth-permission/schemas/cr
|
|
|
4
4
|
const CreateAuthRoleSchema = z.object({
|
|
5
5
|
name: z.string().min(1, 'Role name is required'),
|
|
6
6
|
description: z.string().optional(),
|
|
7
|
-
permissions: z.array(CreateAuthPermissionSchema.omit({
|
|
7
|
+
permissions: z.array(CreateAuthPermissionSchema.omit({ roles: true })).optional().default([]),
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
export default CreateAuthRoleSchema
|
|
@@ -7,8 +7,8 @@ const UpdateAuthRoleSchema = z.object({
|
|
|
7
7
|
permissions: z
|
|
8
8
|
.array(
|
|
9
9
|
CreateAuthPermissionSchema.extend({
|
|
10
|
-
apiAction: z.enum(["connect", "
|
|
11
|
-
}).omit({
|
|
10
|
+
apiAction: z.enum(["connect", "disconnect"]).optional(),
|
|
11
|
+
}).omit({ roles: true })
|
|
12
12
|
)
|
|
13
13
|
.optional()
|
|
14
14
|
.default([]),
|