create-arkos 2.0.0-next.13 → 2.0.0-next.16

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,94 +1,53 @@
1
- # create-arkos
1
+ ![Header Image](https://www.arkosjs.com/img/arkos-readme-header.webp?v=3)
2
2
 
3
3
  <div align="center">
4
4
 
5
+ [![Socket Badge](https://badge.socket.dev/npm/package/create-arkos)](https://badge.socket.dev/npm/package/create-arkos)
5
6
  ![npm](https://img.shields.io/npm/v/create-arkos)
6
7
  ![npm](https://img.shields.io/npm/dt/create-arkos)
7
8
  ![GitHub](https://img.shields.io/github/license/uanela/arkos)
9
+ ![GitHub Repo stars](https://img.shields.io/github/stars/uanela/arkos)
8
10
 
9
11
  </div>
10
12
 
11
13
  <div align="center">
12
- <h2>Scaffold Production-Ready APIs in Seconds</h2>
13
- <p>The official CLI tool for Arkos.js - Get from zero to authenticated REST API faster than your coffee gets cold</p>
14
+ <h2>Scaffold Your Arkos Project in Seconds</h2>
15
+ <p>The official CLI scaffolding tool for Arkos.js</p>
14
16
  </div>
15
17
 
16
- ---
17
-
18
- ## Why create-arkos?
19
-
20
- Skip the hours of boilerplate setup. Get a production-ready API with authentication, validation, and auto-generated docs in **under 5 minutes**.
18
+ <div align="center">
21
19
 
22
- **Perfect for:**
20
+ **[Installation](https://www.arkosjs.com/docs/getting-started/installation)**
21
+ **[Documentation](https://arkosjs.com/docs)** •
22
+ **[Website](https://arkosjs.com)** •
23
+ **[Tutorial](https://arkosjs.com/learn)** •
24
+ **[GitHub](https://github.com/uanela/arkos)** •
25
+ **[Blog](https://www.arkosjs.com/blog)** •
26
+ **[Npm](https://www.npmjs.com/package/create-arkos)**
23
27
 
24
- - Starting new backend projects without the setup headache
25
- - Prototyping APIs that need to scale later
26
- - Teams who want consistent project structure from day one
28
+ </div>
27
29
 
28
30
  ## Quick Start
29
31
 
30
32
  ```bash
31
- # Using pnpm (recommended)
32
33
  pnpm create arkos@latest my-project
33
-
34
- # Using npm
35
- npm create arkos@latest my-project
36
-
37
- # Using yarn
38
- yarn create arkos@latest my-project
39
34
  ```
40
35
 
41
- **That's it!** Follow the interactive prompts and you'll have a running API.
42
-
43
- ## What You Get
44
-
45
- ✅ **Production-ready REST API** with Express.js
46
- ✅ **JWT authentication** configured and ready
47
- ✅ **Auto-generated Swagger docs** at `/api/docs`
48
- ✅ **Database setup** with Prisma ORM
49
- ✅ **Input validation** (Zod or class-validator)
50
- ✅ **TypeScript support** (optional)
51
- ✅ **Best practices** and security middleware
36
+ Follow the interactive prompts. Your project comes with 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).
52
37
 
53
- ## Interactive Setup Experience
54
-
55
- The CLI guides you through a friendly setup process:
38
+ ## Interactive Setup
56
39
 
57
40
  ```bash
58
- ? What is the name of your project? my-arkos-project
41
+ ? What is the name of your project? my-project
59
42
  ? Would you like to use TypeScript? Yes
60
- ? What db provider will be used for Prisma? mongodb
61
- ? Would you like to set up Validation? Yes
62
- ? Choose validation library: zod
63
- ? Would you like to set up Authentication? Yes
64
- ? Choose authentication type: dynamic
65
- ? Would you like to use authentication with Multiple Roles? Yes
66
- ? Choose default username field for login: email
43
+ ? What db provider will be used for Prisma? postgresql
44
+ ? Which Validation library would you like to use? zod
45
+ ? Which Authentication mode would you like to use? static
46
+ ? Enter the Prisma field name to use as the login username: email
47
+ ? Would you like to use Strict Routing? No
67
48
  ```
68
49
 
69
- ### Configuration Options
70
-
71
- **Database Providers:**
72
-
73
- - PostgreSQL (recommended for production)
74
- - MongoDB
75
- - MySQL
76
- - SQLite (great for prototyping)
77
- - SQL Server
78
- - CockroachDB
79
-
80
- **Validation Libraries:**
81
-
82
- - **Zod** - TypeScript-first schema validation
83
- - **class-validator** - Decorator-based validation
84
-
85
- **Authentication Types:**
86
-
87
- - **Dynamic** - Database-level auth with roles and permissions tables
88
- - **Static** - File-based configuration for simpler projects
89
- - **Define Later** - Skip for now, add when ready
90
-
91
- ## From Scaffold to Running API
50
+ ## From Zero to Running API
92
51
 
93
52
  ```bash
94
53
  # 1. Create your project
@@ -100,101 +59,49 @@ cd my-project
100
59
  # 3. Configure your database
101
60
  # Edit .env with your DATABASE_URL
102
61
 
103
- # 4. Initialize the database
62
+ # 4. Push the schema
104
63
  npx prisma db push
105
64
 
106
65
  # 5. Start building
107
66
  npm run dev
108
67
  ```
109
68
 
110
- **Your API is now running at `http://localhost:3000`** with:
69
+ Your API is now running at `http://localhost:8000` — OpenAPI at `/api/docs`.
70
+
71
+ ## Configuration Options
72
+
73
+ **Database providers:** PostgreSQL · MongoDB · MySQL · SQLite · SQL Server · CockroachDB
111
74
 
112
- - Swagger docs at `/api/docs`
113
- - Health check at `/api/health`
114
- - Authentication endpoints ready to use
75
+ **Validation:** Zod · class-validator
76
+
77
+ **Authentication types:**
78
+
79
+ - **Static** — file-based, roles defined in code via `ArkosPolicy`
80
+ - **Dynamic** — database-level, roles and permissions stored in tables
81
+ - **None** — skip for now, add when ready
115
82
 
116
83
  ## Generated Project Structure
117
84
 
118
85
  ```
119
- my-arkos-project/
86
+ my-project/
120
87
  ├── prisma/
121
- │ └── schema.prisma # Database schema
88
+ │ └── schema.prisma
122
89
  ├── src/
90
+ │ ├── modules
123
91
  │ ├── utils/
124
92
  │ │ └── prisma/
125
- │ │ └── index.ts # Prisma client
126
- ├── app.ts # Main application
127
- ├── arkos.config.ts # Framework configuration
128
- │ └── server.ts # Server entry point
129
- ├── .env # Environment variables
130
- ├── .gitignore
93
+ │ │ └── index.ts
94
+ └── app.ts
95
+ ├── .env
96
+ ├── arkos.config.ts
131
97
  ├── package.json
132
- └── tsconfig.json # TypeScript config (if selected)
98
+ └── tsconfig.json
133
99
  ```
134
100
 
135
- ## Environment Setup
136
-
137
- Example `.env` configurations for different databases:
138
-
139
- ```env
140
- # PostgreSQL (recommended for production)
141
- DATABASE_URL="postgresql://username:password@localhost:5432/mydb"
142
-
143
- # MongoDB
144
- DATABASE_URL="mongodb://localhost:27017/mydb"
145
-
146
- # MySQL
147
- DATABASE_URL="mysql://username:password@localhost:3306/mydb"
148
-
149
- # SQLite (great for local development)
150
- DATABASE_URL="file:./dev.db"
151
- ```
152
-
153
- ## Authentication Out of the Box
154
-
155
- ### Dynamic Authentication (Recommended)
156
-
157
- Perfect for apps that need user management and role-based access:
158
-
159
- - `auth-role` table for managing roles
160
- - `auth-permission` table for granular permissions
161
- - Multi-role support
162
- - Database-level flexibility
163
-
164
- ### Static Authentication
165
-
166
- Great for simpler projects or when roles are predefined:
167
-
168
- - Configuration file-based
169
- - Faster setup
170
- - Easy to understand and modify
171
-
172
- ## Next Steps
173
-
174
- Once your project is created:
175
-
176
- 1. **Define your data models** in `prisma/schema.prisma`
177
- 2. **Run migrations** with `npx prisma db push`
178
- 3. **Start coding** - Arkos handles the CRUD operations automatically
179
- 4. **Add custom logic** with interceptors when needed
180
-
181
- ```bash
182
- # Generate CRUD for a new model
183
- arkos generate posts -m Post
184
-
185
- # Start development
186
- npm run dev
187
-
188
- # Build for production
189
- npm run build
190
- ```
191
-
192
- ## Get Cutting-Edge Features
193
-
194
- Try our canary releases for the latest features:
101
+ ## Getting Nightly Updates
195
102
 
196
103
  ```bash
197
- pnpm create arkos@canary my-project
104
+ pnpm create arkos@next my-project
198
105
  ```
199
106
 
200
107
  ## Requirements
@@ -202,36 +109,32 @@ pnpm create arkos@canary my-project
202
109
  - Node.js 20 or higher
203
110
  - npm, yarn, or pnpm
204
111
 
205
- ## Learn More
112
+ ## Support & Contributing
206
113
 
207
114
  - **Documentation:** [arkosjs.com/docs](https://arkosjs.com/docs)
208
- - **Main Framework:** [github.com/uanela/arkos](https://github.com/uanela/arkos)
209
- - **Community:** [Join our WhatsApp group](https://chat.whatsapp.com/EJ8cjb9hxau0EcOnI4fdpD)
210
- - **Examples:** [arkosjs.com/docs/examples](https://arkosjs.com/docs/examples)
211
-
212
- ## Support
213
-
214
115
  - **Bug Reports:** [GitHub Issues](https://github.com/uanela/arkos/issues)
215
116
  - **Feature Requests:** Open a GitHub issue
216
- - **Email:** [uanelaluiswayne@gmail.com](mailto:uanelaluiswayne@gmail.com)
117
+ - **Contact:** [uanelaluiswayne@gmail.com](mailto:uanelaluiswayne@gmail.com)
217
118
 
218
- ## License
119
+ Contributions are welcome! We appreciate all contributions, from bug fixes to new features.
219
120
 
220
- MIT License - see the [LICENSE](LICENSE) file for details.
121
+ ## License
221
122
 
222
- ---
123
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
223
124
 
224
125
  <div align="center">
225
126
 
127
+ **[Installation](https://www.arkosjs.com/docs/getting-started/installation)** •
226
128
  **[Documentation](https://arkosjs.com/docs)** •
227
129
  **[Website](https://arkosjs.com)** •
130
+ **[Tutorial](https://arkosjs.com/learn)** •
228
131
  **[GitHub](https://github.com/uanela/arkos)** •
229
- **[npm](https://www.npmjs.com/package/create-arkos)**
132
+ **[Blog](https://www.arkosjs.com/blog)**
133
+ **[Npm](https://www.npmjs.com/package/create-arkos)**
230
134
 
231
135
  Built with ❤️ by [Uanela Como](https://github.com/uanela) and contributors
232
136
 
233
- ---
234
-
235
- _From the Greek "ἀρχή" (Arkhē) - meaning "beginning" - your foundation for Express and Prisma backend development_
137
+ _The name "Arkos" comes from the Greek word "ἀρχή" (Arkhē), meaning "beginning" or "foundation", reflecting our goal of providing a solid foundation for backend development._
236
138
 
237
139
  </div>
140
+ ```
@@ -13,6 +13,7 @@ class ProjectConfigInquirer {
13
13
  await this.promptValidation();
14
14
  await this.promptAuthentication();
15
15
  await this.promptStrictRouting();
16
+ await this.promptEntryPoint();
16
17
  if (this.config.projectName === ".") {
17
18
  this.config.projectName = path.basename(process.cwd());
18
19
  this.config.projectPath = path.resolve(process.cwd());
@@ -21,6 +22,9 @@ class ProjectConfigInquirer {
21
22
  this.config.projectPath = path.resolve(process.cwd(), this.config.projectName);
22
23
  if (process?.argv?.includes?.("--advanced"))
23
24
  this.config.advanced = true;
25
+ if (this.config.prisma.defaultDatabaseUrl)
26
+ this.config.prisma.defaultDatabaseUrl =
27
+ this.config.prisma.defaultDatabaseUrl.replaceAll("{{projectName}}", this.config.projectName);
24
28
  return this.config;
25
29
  }
26
30
  async promptProjectName() {
@@ -77,7 +81,7 @@ class ProjectConfigInquirer {
77
81
  type: "confirm",
78
82
  name: "typescript",
79
83
  message: `Would you like to use ${chalk.cyan("TypeScript")}?`,
80
- default: false,
84
+ default: true,
81
85
  },
82
86
  ]);
83
87
  this.config.typescript = typescript;
@@ -95,126 +99,120 @@ class ProjectConfigInquirer {
95
99
  "sqlite",
96
100
  "sqlserver",
97
101
  "cockroachdb",
102
+ "none",
98
103
  ],
99
104
  },
100
105
  ]);
101
106
  let idDatabaseType;
102
- let defaultDBurl;
107
+ let defaultDatabaseUrl;
103
108
  switch (prismaProvider) {
104
109
  case "mongodb":
105
110
  idDatabaseType = '@id @default(auto()) @map("_id") @db.ObjectId';
106
- defaultDBurl = `mongodb://localhost:27017/${this.config.projectName}`;
111
+ defaultDatabaseUrl = `mongodb://localhost:27017/{{projectName}}`;
107
112
  break;
108
113
  case "sqlite":
109
114
  idDatabaseType = "@id @default(cuid())";
110
- defaultDBurl = "file:../../file.db";
115
+ defaultDatabaseUrl = "file:../../file.db";
111
116
  break;
112
117
  case "mysql":
113
118
  idDatabaseType = "@id @default(uuid())";
114
- defaultDBurl = `mysql://username:password@localhost:3306/${this.config.projectName}`;
119
+ defaultDatabaseUrl = `mysql://username:password@localhost:3306/{{projectName}}`;
115
120
  break;
116
121
  case "postgresql":
117
122
  idDatabaseType = "@id @default(uuid())";
118
- defaultDBurl = `postgresql://username:password@localhost:5432/${this.config.projectName}`;
123
+ defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;
119
124
  break;
120
125
  case "sqlserver":
121
126
  idDatabaseType = "@id @default(uuid())";
122
- defaultDBurl = `sqlserver://localhost:1433;database=${this.config.projectName};username=sa;password=password;encrypt=DANGER_PLAINTEXT`;
127
+ defaultDatabaseUrl = `sqlserver://localhost:1433;database={{projectName}};username=sa;password=password;encrypt=DANGER_PLAINTEXT`;
123
128
  break;
124
129
  case "cockroachdb":
125
130
  idDatabaseType = "@id @default(uuid())";
126
- defaultDBurl = `postgresql://username:password@localhost:26257/${this.config.projectName}?sslmode=require`;
131
+ defaultDatabaseUrl = `postgresql://username:password@localhost:26257/{{projectName}}?sslmode=require`;
127
132
  break;
128
133
  default:
129
134
  idDatabaseType = "@id @default(uuid())";
130
- defaultDBurl = `postgresql://username:password@localhost:5432/${this.config.projectName}`;
135
+ defaultDatabaseUrl = `postgresql://username:password@localhost:5432/{{projectName}}`;
131
136
  }
132
137
  this.config.prisma = {
133
138
  provider: prismaProvider,
134
- idDatabaseType: idDatabaseType,
135
- defaultDBurl: defaultDBurl,
139
+ idDatabaseType,
140
+ defaultDatabaseUrl,
136
141
  };
137
142
  }
138
143
  async promptValidation() {
139
- const { useValidation } = await inquirer.prompt([
144
+ const choices = this.config.typescript
145
+ ? ["zod", "class-validator", "none"]
146
+ : ["zod", "none"];
147
+ const { validationType } = await inquirer.prompt([
140
148
  {
141
- type: "confirm",
142
- name: "useValidation",
143
- message: `Would you like to set up ${chalk.cyan("Validation")}?`,
144
- default: true,
149
+ type: "list",
150
+ name: "validationType",
151
+ message: `Which ${chalk.cyan("Validation")} library would you like to use?`,
152
+ choices,
153
+ default: "zod",
145
154
  },
146
155
  ]);
147
- if (useValidation) {
148
- let validationTypeResponse = { validationType: "zod" };
149
- if (this.config.typescript)
150
- validationTypeResponse = await inquirer.prompt([
151
- {
152
- type: "list",
153
- name: "validationType",
154
- message: "Choose validation library:",
155
- choices: ["zod", "class-validator"],
156
- },
157
- ]);
158
- else {
159
- console.info(chalk.bold(`${chalk.greenBright("?")} Validation library set to zod (class-validator is not supported on JavaScript):`), chalk.cyan("zod"));
160
- }
156
+ if (validationType !== "none") {
161
157
  this.config.validation = {
162
- type: validationTypeResponse.validationType,
158
+ type: validationType,
163
159
  };
164
160
  }
165
- else if (!this.config.typescript) {
166
- }
167
161
  }
168
162
  async promptAuthentication() {
169
- const { useAuthentication } = await inquirer.prompt([
163
+ if (this.config.prisma.provider === "none") {
164
+ console.info(`Skipping authentication setup as it requires prisma.`);
165
+ return;
166
+ }
167
+ const { authenticationType } = await inquirer.prompt([
170
168
  {
171
- type: "confirm",
172
- name: "useAuthentication",
173
- message: `Would you like to set up ${chalk.cyan("Authentication")}?`,
174
- default: true,
169
+ type: "list",
170
+ name: "authenticationType",
171
+ message: `Which ${chalk.cyan("Authentication")} mode would you like to use?`,
172
+ choices: ["static", "dynamic", "none"],
173
+ default: "static",
175
174
  },
176
175
  ]);
177
- if (useAuthentication) {
178
- const { authenticationType } = await inquirer.prompt([
179
- {
180
- type: "list",
181
- name: "authenticationType",
182
- message: "Choose authentication type:",
183
- choices: ["static", "dynamic"],
176
+ if (authenticationType === "none") {
177
+ this.config.authentication = { type: "none", multipleRoles: false };
178
+ return;
179
+ }
180
+ const { usernameField } = await inquirer.prompt([
181
+ {
182
+ type: "input",
183
+ name: "usernameField",
184
+ message: "Enter the Prisma field name to use as the login username:",
185
+ default: "email",
186
+ validate: (input) => {
187
+ if (!input || input.length === 0)
188
+ return "Field name cannot be empty";
189
+ if (!/^[a-z][a-zA-Z0-9]*$/.test(input))
190
+ return "Must be a valid Prisma field name (camelCase, starts with lowercase, letters and numbers only)";
191
+ return true;
184
192
  },
185
- ]);
186
- const { usernameField } = await inquirer.prompt([
193
+ },
194
+ ]);
195
+ this.config.authentication = {
196
+ type: authenticationType,
197
+ usernameField,
198
+ multipleRoles: false,
199
+ };
200
+ if (authenticationType !== "static" &&
201
+ this.config.prisma.provider !== "sqlite") {
202
+ const { multipleRoles } = await inquirer.prompt([
187
203
  {
188
- type: "list",
189
- name: "usernameField",
190
- message: "Choose default username field for login:",
191
- choices: ["email", "username", "define later"],
204
+ type: "confirm",
205
+ name: "multipleRoles",
206
+ default: true,
207
+ message: `Would you like to use authentication with ${chalk.cyan("Multiple Roles")}?`,
192
208
  },
193
209
  ]);
194
210
  this.config.authentication = {
195
- type: authenticationType,
196
- usernameField: usernameField === "define later" ? "custom" : usernameField,
197
- multipleRoles: false,
211
+ ...this.config.authentication,
212
+ multipleRoles,
198
213
  };
199
- if (authenticationType !== "define later" &&
200
- this.config.prisma.provider !== "sqlite" &&
201
- authenticationType !== "static") {
202
- const { multipleRoles } = await inquirer.prompt([
203
- {
204
- type: "confirm",
205
- name: "multipleRoles",
206
- default: true,
207
- message: `Would you like to use authentication with ${chalk.cyan("Multiple Roles")}?`,
208
- },
209
- ]);
210
- this.config.authentication = {
211
- ...this.config.authentication,
212
- multipleRoles,
213
- };
214
- }
215
- else if (this.config.prisma.provider === "sqlite") {
216
- console.info(`Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.`);
217
- }
214
+ }
215
+ else if (this.config.prisma.provider === "sqlite") {
218
216
  }
219
217
  }
220
218
  async promptStrictRouting() {
@@ -230,6 +228,19 @@ class ProjectConfigInquirer {
230
228
  strict: strictRouting,
231
229
  };
232
230
  }
231
+ async promptEntryPoint() {
232
+ const ext = this.config.typescript ? "ts" : "js";
233
+ const { entryPoint } = await inquirer.prompt([
234
+ {
235
+ type: "list",
236
+ name: "entryPoint",
237
+ message: `Which ${chalk.cyan("Entry Point")} would you like to use?`,
238
+ choices: [`src/app.${ext}`, `src/server.${ext}`],
239
+ default: `src/app.${ext}`,
240
+ },
241
+ ]);
242
+ this.config.entryPoint = entryPoint.replace(`.${ext}`, "");
243
+ }
233
244
  }
234
245
  const projectConfigInquirer = new ProjectConfigInquirer();
235
246
  export default projectConfigInquirer;
@@ -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\" | \"define later\";\n usernameField?: \"username\" | \"email\" | \"custom\";\n multipleRoles: boolean;\n };\n prisma: {\n provider:\n | \"postgresql\"\n | \"mysql\"\n | \"sqlite\"\n | \"sqlserver\"\n | \"cockroachdb\"\n | \"mongodb\";\n idDatabaseType: string;\n defaultDBurl: string;\n };\n projectPath: string;\n routing?: {\n strict?: boolean;\n };\n advanced?: boolean;\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\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\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 // Validate the project name from command line args\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: false,\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 ],\n },\n ]);\n\n // Set the correct idDatabaseType based on provider\n let idDatabaseType: string;\n let defaultDBurl: string;\n\n switch (prismaProvider) {\n case \"mongodb\":\n idDatabaseType = '@id @default(auto()) @map(\"_id\") @db.ObjectId';\n defaultDBurl = `mongodb://localhost:27017/${this.config.projectName}`;\n break;\n case \"sqlite\":\n idDatabaseType = \"@id @default(cuid())\";\n defaultDBurl = \"file:../../file.db\";\n break;\n case \"mysql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDBurl = `mysql://username:password@localhost:3306/${this.config.projectName}`;\n break;\n case \"postgresql\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDBurl = `postgresql://username:password@localhost:5432/${this.config.projectName}`;\n break;\n case \"sqlserver\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDBurl = `sqlserver://localhost:1433;database=${this.config.projectName};username=sa;password=password;encrypt=DANGER_PLAINTEXT`;\n break;\n case \"cockroachdb\":\n idDatabaseType = \"@id @default(uuid())\";\n defaultDBurl = `postgresql://username:password@localhost:26257/${this.config.projectName}?sslmode=require`;\n break;\n default:\n idDatabaseType = \"@id @default(uuid())\";\n defaultDBurl = `postgresql://username:password@localhost:5432/${this.config.projectName}`;\n }\n\n this.config.prisma = {\n provider: prismaProvider,\n idDatabaseType: idDatabaseType,\n defaultDBurl: defaultDBurl,\n };\n }\n\n private async promptValidation() {\n const { useValidation } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"useValidation\",\n message: `Would you like to set up ${chalk.cyan(\"Validation\")}?`,\n default: true,\n },\n ]);\n\n if (useValidation) {\n let validationTypeResponse: {\n validationType: \"zod\" | \"class-validator\";\n } = { validationType: \"zod\" };\n\n if (this.config.typescript)\n validationTypeResponse = await inquirer.prompt([\n {\n type: \"list\",\n name: \"validationType\",\n message: \"Choose validation library:\",\n choices: [\"zod\", \"class-validator\"],\n },\n ]);\n else {\n console.info(\n chalk.bold(\n `${chalk.greenBright(\"?\")} Validation library set to zod (class-validator is not supported on JavaScript):`\n ),\n chalk.cyan(\"zod\")\n );\n }\n this.config.validation = {\n type: validationTypeResponse.validationType,\n };\n } else if (!this.config.typescript) {\n }\n }\n\n private async promptAuthentication() {\n const { useAuthentication } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"useAuthentication\",\n message: `Would you like to set up ${chalk.cyan(\"Authentication\")}?`,\n default: true,\n },\n ]);\n\n if (useAuthentication) {\n const { authenticationType } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"authenticationType\",\n message: \"Choose authentication type:\",\n choices: [\"static\", \"dynamic\"],\n },\n ]);\n\n const { usernameField } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"usernameField\",\n message: \"Choose default username field for login:\",\n choices: [\"email\", \"username\", \"define later\"],\n },\n ]);\n\n this.config.authentication = {\n type: authenticationType,\n usernameField:\n usernameField === \"define later\" ? \"custom\" : usernameField,\n multipleRoles: false,\n };\n\n if (\n authenticationType !== \"define later\" &&\n this.config.prisma.provider !== \"sqlite\" &&\n authenticationType !== \"static\"\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 `Skipping multiple roles option because it is not supported with sqlite prisma provider and static authentication mode.`\n );\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\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\";\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 // For JS projects, class-validator is not supported — skip the choice\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(`Skipping authentication setup as it requires prisma.`);\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 // `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"]}
@@ -55,17 +55,20 @@ class TemplateCompiler {
55
55
  "user.router.ts.hbs",
56
56
  "user.policy.ts.hbs",
57
57
  ];
58
- if (!config.authentication?.type ||
59
- config.authentication?.type === "define later")
58
+ if (config.prisma?.provider === "none")
59
+ files.push(...authSharedPrismaFiles, ...dynamicAuthPrismaFiles, "schema.prisma.hbs", ...userModuleComponents, ...authModuleComponents, ...authPermissionModuleComponents, ...authRoleModuleComponents, "file-upload.auth.ts.hbs", "index.ts.hbs");
60
+ if (!config.authentication?.type || config.authentication?.type === "none")
60
61
  files.push(...authSharedPrismaFiles, ...dynamicAuthPrismaFiles, ...sharedAuthDtoFiles, ...dynamicAuthDtoFiles, ...userModuleComponents, ...authModuleComponents, ...authPermissionModuleComponents, ...authRoleModuleComponents, ...userDtoFiles, "file-upload.policy.ts.hbs");
61
62
  if (config.authentication?.type === "static")
62
63
  files.push(...dynamicAuthPrismaFiles, ...dynamicAuthDtoFiles, ...authPermissionModuleComponents, ...authRoleModuleComponents);
63
64
  if (!config.validation?.type)
64
- files.push(...sharedAuthDtoFiles, ...dynamicAuthDtoFiles, ...userDtoFiles);
65
+ files.push(...sharedAuthDtoFiles, ...dynamicAuthDtoFiles, ...userDtoFiles, "api-actions.hbs.ts");
65
66
  if (!config.typescript)
66
67
  files.push(...["tsconfig.json.hbs"]);
67
68
  if (config?.typescript)
68
69
  files.push(...["jsconfig.json.hbs"]);
70
+ if (config.entryPoint === "src/app")
71
+ files.push("server.ts.hbs");
69
72
  return files;
70
73
  }
71
74
  async compile(templatesDir, config) {
@@ -95,6 +98,11 @@ class TemplateCompiler {
95
98
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
96
99
  fs.writeFileSync(outputPath, content);
97
100
  }
101
+ else {
102
+ const outputPath = path.join(outputDir, relativePath);
103
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
104
+ fs.copyFileSync(fullPath, outputPath);
105
+ }
98
106
  });
99
107
  }
100
108
  processTemplates(templatesDir);
@@ -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 userDtoFiles = [\n \"create-user.dto.ts.hbs\",\n \"update-user.dto.ts.hbs\",\n \"query-user.dto.ts.hbs\",\n ];\n\n const sharedAuthDtoFiles = [\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 dynamicAuthDtoFiles = [\n \"create-auth-permission.dto.ts.hbs\",\n \"update-auth-permission.dto.ts.hbs\",\n \"query-auth-permission.dto.ts.hbs\",\n \"create-auth-role.dto.ts.hbs\",\n \"update-auth-role.dto.ts.hbs\",\n \"query-auth-role.dto.ts.hbs\",\n ];\n\n const authModuleComponents = [\n \"auth.route-hook.ts.hbs\",\n \"auth.policy.ts.hbs\",\n \"auth.router.ts.hbs\",\n ];\n\n const authPermissionModuleComponents = [\n \"auth-permission.router.ts.hbs\",\n \"auth-permission.policy.ts.hbs\",\n \"auth-permission.route-hook.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.route-hook.ts.hbs\",\n \"auth-role.service.ts.hbs\",\n ];\n\n const userModuleComponents = [\n \"user.route-hook.ts.hbs\",\n \"user.service.ts.hbs\",\n \"user.router.ts.hbs\",\n \"user.policy.ts.hbs\",\n ];\n\n if (\n !config.authentication?.type ||\n config.authentication?.type === \"define later\"\n )\n files.push(\n ...authSharedPrismaFiles,\n ...dynamicAuthPrismaFiles,\n ...sharedAuthDtoFiles,\n ...dynamicAuthDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userDtoFiles,\n \"file-upload.policy.ts.hbs\"\n );\n\n if (config.authentication?.type === \"static\")\n files.push(\n ...dynamicAuthPrismaFiles,\n ...dynamicAuthDtoFiles,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents\n );\n\n if (!config.validation?.type)\n files.push(\n ...sharedAuthDtoFiles,\n ...dynamicAuthDtoFiles,\n ...userDtoFiles\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 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 }\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 ];\n\n const userDtoFiles = [\n \"create-user.dto.ts.hbs\",\n \"update-user.dto.ts.hbs\",\n \"query-user.dto.ts.hbs\",\n ];\n\n const sharedAuthDtoFiles = [\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 dynamicAuthDtoFiles = [\n \"create-auth-permission.dto.ts.hbs\",\n \"update-auth-permission.dto.ts.hbs\",\n \"query-auth-permission.dto.ts.hbs\",\n \"create-auth-role.dto.ts.hbs\",\n \"update-auth-role.dto.ts.hbs\",\n \"query-auth-role.dto.ts.hbs\",\n ];\n\n const authModuleComponents = [\n \"auth.route-hook.ts.hbs\",\n \"auth.policy.ts.hbs\",\n \"auth.router.ts.hbs\",\n ];\n\n const authPermissionModuleComponents = [\n \"auth-permission.router.ts.hbs\",\n \"auth-permission.policy.ts.hbs\",\n \"auth-permission.route-hook.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.route-hook.ts.hbs\",\n \"auth-role.service.ts.hbs\",\n ];\n\n const userModuleComponents = [\n \"user.route-hook.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 ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\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 ...sharedAuthDtoFiles,\n ...dynamicAuthDtoFiles,\n ...userModuleComponents,\n ...authModuleComponents,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents,\n ...userDtoFiles,\n \"file-upload.policy.ts.hbs\"\n );\n\n if (config.authentication?.type === \"static\")\n files.push(\n ...dynamicAuthPrismaFiles,\n ...dynamicAuthDtoFiles,\n ...authPermissionModuleComponents,\n ...authRoleModuleComponents\n );\n\n if (!config.validation?.type)\n files.push(\n ...sharedAuthDtoFiles,\n ...dynamicAuthDtoFiles,\n ...userDtoFiles,\n \"api-actions.hbs.ts\"\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,10 +1,10 @@
1
1
  {
2
2
  "name": "create-arkos",
3
- "version": "2.0.0-next.13",
3
+ "version": "2.0.0-next.16",
4
4
  "type": "module",
5
5
  "description": "CLI for creating Arkos.js projects, see docs at www.arkosjs.com",
6
6
  "bin": {
7
- "create-arkos": "./dist/index.js"
7
+ "create-arkos": "dist/index.js"
8
8
  },
9
9
  "scripts": {
10
10
  "test": "vitest --coverage",
@@ -26,23 +26,23 @@
26
26
  "bugs": {
27
27
  "url": "https://github.com/uanela/arkos/issues"
28
28
  },
29
- "homepage": "https://www.arkosjs.com/docs/tooling/cli/overviewcreate-arkos",
29
+ "homepage": "https://www.arkosjs.com/docs/cli/create-arkos",
30
30
  "files": ["dist", "templates", "cli.js", "README.md"],
31
31
  "devDependencies": {
32
- "@types/inquirer": "8.1.0",
32
+ "@types/inquirer": "9.0.9",
33
33
  "@types/node": "16.18.126",
34
- "@vitest/coverage-v8": "3.2.4",
34
+ "@vitest/coverage-v8": "4.1.7",
35
35
  "rimraf": "6.1.3",
36
36
  "ts-node": "10.9.2",
37
37
  "tsx": "4.21.0",
38
38
  "typescript": "4.9.5",
39
- "vitest": "3.2.4"
39
+ "vitest": "4.1.7"
40
40
  },
41
41
  "dependencies": {
42
42
  "@clack/prompts": "0.11.0",
43
- "@inquirer/prompts": "7.6.0",
43
+ "@inquirer/prompts": "7",
44
44
  "chalk": "5.4.1",
45
- "handlebars": "4.7.8",
45
+ "handlebars": "^4.7.9",
46
46
  "inquirer": "8.2.6"
47
47
  }
48
48
  }
@@ -1,9 +1,13 @@
1
+ {{#if (neq prisma.provider "none")}}
1
2
  # Database connection
2
- DATABASE_URL={{prisma.defaultDBurl}}
3
+ DATABASE_URL={{prisma.defaultDatabaseUrl}}
4
+ {{/if}}
3
5
 
6
+ {{#if (neq authentication.type "none")}}
4
7
  # JWT secrets
5
8
  # JWT_SECRET=
6
9
  # JWT_EXPIRES_IN=30d
10
+ {{/if}}
7
11
 
8
12
  # Server configuration
9
13
  PORT=8000
@@ -6,7 +6,12 @@ const arkosConfig = defineConfig({
6
6
  prisma: {
7
7
  instance: prisma
8
8
  },
9
- {{#if authentication.type}}
9
+ {{#if (eq entryPoint "src/server")}}
10
+ source: {
11
+ entryPoint: "{{entryPoint}}{{#if typescript}}.ts{{else}}.js{{/if}}"
12
+ },
13
+ {{/if}}
14
+ {{#if (neq authentication.type "none")}}
10
15
  authentication: {
11
16
  mode: '{{authentication.type}}',
12
17
  login: {
@@ -30,10 +35,18 @@ const arkosConfig = defineConfig({
30
35
  strict: false,
31
36
  },
32
37
  middlewares: {
33
- cors: {
34
- allowedOrigins: process.env.NODE_ENV !== "production" ? "*" : "your-production-url"
38
+ cors: {},
39
+ },
40
+ {{#if (eq prisma.provider "none")}}
41
+ warnings: {
42
+ suppress: {
43
+ prisma: {
44
+ noInstanceFound: true,
45
+ noSchemaFound: true,
46
+ },
35
47
  },
36
- }
48
+ },
49
+ {{/if}}
37
50
  })
38
51
 
39
52
  export default arkosConfig
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES6",
4
- "module": "es2020",
3
+ "target": "es2022",
4
+ "module": "es2022",
5
5
  "moduleResolution": "bundler",
6
6
  "rootDir": ".",
7
7
  "baseUrl": ".",
@@ -16,15 +16,19 @@
16
16
  "@types/node": "24.0.12",
17
17
  "@types/express": "5.0.0",
18
18
  {{/if}}
19
- "tsx-strict": "0.4.2",
20
- "tsx": "4.21.0",
19
+ "tsx-strict": "0.7.0",
20
+ "tsx": "4.21.0"{{#if (neq prisma.provider "none")}},
21
21
  "prisma": "6.19.2"
22
+ {{/if}}
22
23
  },
23
24
  "dependencies": {
24
- "arkos": "2.0.0-next.13",
25
+ "arkos": "2.0.0-next.16",
25
26
  "express": "4.22.1",
26
27
  "@scalar/express-api-reference": "0.8.35",
28
+ "@scalar/api-reference": "1.55.3",
29
+ {{#if (neq prisma.provider "none")}}
27
30
  "@prisma/client": "6.19.2"{{#if validation.type}},{{/if}}
31
+ {{/if}}
28
32
  {{#if (eq validation.type "class-validator")}}
29
33
  "reflect-metadata": "0.2.2",
30
34
  "class-transformer": "0.5.1",
@@ -27,7 +27,7 @@ describe("UserRole model template rendering", () => {
27
27
  // Test case 2: Define later authentication
28
28
  const context2 = {
29
29
  authentication: {
30
- type: "define later",
30
+ type: "none",
31
31
  multipleRoles: false,
32
32
  },
33
33
  prisma: {
@@ -65,10 +65,10 @@ describe("User model template rendering", () => {
65
65
  expect(result3).toContain("roles UserRole[]");
66
66
  });
67
67
 
68
- it('should handle "define later" authentication type', () => {
68
+ it('should handle "none" authentication type', () => {
69
69
  const context = {
70
70
  authentication: {
71
- type: "define later",
71
+ type: "none",
72
72
  usernameField: "email",
73
73
  },
74
74
  prisma: {
@@ -1,4 +1,4 @@
1
- {{#if (neq authentication.type "define later")}}
1
+ {{#if (neq authentication.type "none")}}
2
2
  model User {
3
3
  id String {{{prisma.idDatabaseType}}}
4
4
  {{authentication.usernameField}} String @unique
@@ -2,11 +2,15 @@ import arkos from "arkos";
2
2
  import router from "@/src/router"
3
3
  import loadables from "@/src/loadables"
4
4
 
5
- const app = arkos()
5
+ const app = arkos();
6
6
 
7
- app.set("trust proxy", 1)
7
+ app.set("trust proxy", 1);
8
8
 
9
9
  app.load(loadables)
10
- app.use(router)
10
+ app.use(router);
11
11
 
12
- app.listen()
12
+ {{#if (eq entryPoint "src/app")}}
13
+ app.listen();
14
+ {{else}}
15
+ export default app;
16
+ {{/if}}
@@ -1,6 +1,14 @@
1
- import { ArkosRouter } from "arkos";
1
+ import { ArkosRouter{{#if typescript}}, RouteHook{{/if}} } from "arkos";
2
2
  {{#if authentication}}
3
3
  import authPermissionPolicy from "@/src/modules/auth-permission/auth-permission.policy";
4
+
5
+ export const hook{{#if typescript}}: RouteHook{{/if}} = {
6
+ createOne: { authentication: authPermissionPolicy.Create },
7
+ findMany: { authentication: authPermissionPolicy.View },
8
+ findOne: { authentication: authPermissionPolicy.View },
9
+ updateOne: { authentication: authPermissionPolicy.Update },
10
+ deleteOne: { authentication: authPermissionPolicy.Delete },
11
+ };
4
12
  {{/if}}
5
13
 
6
14
  const authPermissionRouter = ArkosRouter({
@@ -1,6 +1,14 @@
1
- import { ArkosRouter } from "arkos";
1
+ import { ArkosRouter{{#if typescript}}, RouteHook{{/if}} } from "arkos";
2
2
  {{#if authentication}}
3
3
  import authRolePolicy from "@/src/modules/auth-role/auth-role.policy";
4
+
5
+ export const hook{{#if typescript}}: RouteHook{{/if}} = {
6
+ createOne: { authentication: authRolePolicy.Create },
7
+ findMany: { authentication: authRolePolicy.View },
8
+ findOne: { authentication: authRolePolicy.View },
9
+ updateOne: { authentication: authRolePolicy.Update },
10
+ deleteOne: { authentication: authRolePolicy.Delete },
11
+ };
4
12
  {{/if}}
5
13
 
6
14
  const authRoleRouter = ArkosRouter({
@@ -1,8 +1,15 @@
1
- import { ArkosRouter } from "arkos";
1
+ import { ArkosRouter{{#if typescript}}, RouteHook{{/if}} } from "arkos";
2
+ import config from "@/arkos.config"
2
3
  {{#if authentication}}
3
4
  import fileUploadPolicy from "@/src/modules/file-upload/file-upload.policy";
5
+
6
+ export const hook{{#if typescript}}: RouteHook<"file-upload">{{/if}} = {
7
+ findFile: { authentication: fileUploadPolicy.View },
8
+ uploadFile: { authentication: fileUploadPolicy.Create },
9
+ updateFile: { authentication: fileUploadPolicy.Update },
10
+ deleteFile: { authentication: fileUploadPolicy.Delete },
11
+ };
4
12
  {{/if}}
5
- import config from "@/arkos.config"
6
13
 
7
14
  const fileUploadRouter = ArkosRouter({
8
15
  prefix: config?.fileUpload?.baseRoute,
@@ -1,6 +1,14 @@
1
- import { ArkosRouter } from "arkos";
1
+ import { ArkosRouter{{#if typescript}}, RouteHook{{/if}} } from "arkos";
2
2
  {{#if authentication}}
3
3
  import userPolicy from "@/src/modules/user/user.policy";
4
+
5
+ export const hook{{#if typescript}}: RouteHook{{/if}} = {
6
+ createOne: { authentication: userPolicy.Create },
7
+ findMany: { authentication: userPolicy.View },
8
+ findOne: { authentication: userPolicy.View },
9
+ updateOne: { authentication: userPolicy.Update },
10
+ deleteOne: { authentication: userPolicy.Delete },
11
+ };
4
12
  {{/if}}
5
13
 
6
14
  const userRouter = ArkosRouter({
@@ -1,4 +1,5 @@
1
1
  import { ArkosRouter } from "arkos";
2
+ import arkosConfig from "@/arkos.config";
2
3
  import fileUploadRouter from "@/src/modules/file-upload/file-upload.router";
3
4
  {{#if authentication.type}}
4
5
  import authRouter from "@/src/modules/auth/auth.router";
@@ -9,7 +10,9 @@ import authRoleRouter from "@/src/modules/auth-role/auth-role.router";
9
10
  import authPermissionRouter from "@/src/modules/auth-permission/auth-permission.router";
10
11
  {{/if}}
11
12
 
12
- const router = ArkosRouter();
13
+ const router = ArkosRouter({
14
+ prefix: arkosConfig.globalPrefix || "/api",
15
+ })
13
16
 
14
17
  router.use(fileUploadRouter);
15
18
  {{#if authentication.type}}
@@ -0,0 +1,8 @@
1
+ import app from "@/src/app";
2
+ import http from "node:http";
3
+
4
+ await app.build();
5
+
6
+ const server = http.createServer(app);
7
+
8
+ app.listen(server);
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Is worth mentioning that this will be addded into `arkos` as an util.
6
6
  *
7
- * @see {@link https://www.arkosjs.com/docs/advanced-guide/handling-relation-fields-in-prisma-body-requests#the-apiaction-property}
7
+ * @see {@link https://www.arkosjs.com/docs/core-concepts/prisma-orm/handling-relations}
8
8
  */
9
9
  const apiActions = ["connect", "disconnect", "delete", "update", "create"]{{#if typescript}} as const{{/if}};
10
10
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES6",
4
- "module": "es2020",
3
+ "target": "es2022",
4
+ "module": "es2022",
5
5
  "moduleResolution": "bundler",
6
6
  "rootDir": ".",
7
7
  "baseUrl": ".",