nural 0.2.0 ā 0.3.0
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 +16 -0
- package/dist/cli/index.cjs +209 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +200 -0
- package/dist/cli/index.js.map +1 -0
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -43,6 +43,22 @@ npm install nural fastify
|
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
+
## š ļø CLI
|
|
47
|
+
|
|
48
|
+
Nural comes with a built-in CLI to help you scaffold projects and generate resources.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Create a new project
|
|
52
|
+
npx nural new my-api
|
|
53
|
+
|
|
54
|
+
# Generate resources
|
|
55
|
+
npx nural generate route users
|
|
56
|
+
npx nural generate middleware auth
|
|
57
|
+
npx nural generate service user
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
46
62
|
## Quick Start
|
|
47
63
|
|
|
48
64
|
```typescript
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var commander = require('commander');
|
|
5
|
+
var inquirer = require('inquirer');
|
|
6
|
+
var chalk = require('chalk');
|
|
7
|
+
var fs = require('fs-extra');
|
|
8
|
+
var path = require('path');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
13
|
+
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
14
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
15
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
16
|
+
|
|
17
|
+
var program = new commander.Command();
|
|
18
|
+
program.name("nural").description("Nural Framework CLI").version("0.3.0");
|
|
19
|
+
program.command("new <project-name>").description("Create a new Nural project").action(async (projectName) => {
|
|
20
|
+
const projectPath = path__default.default.join(process.cwd(), projectName);
|
|
21
|
+
if (fs__default.default.existsSync(projectPath)) {
|
|
22
|
+
console.error(
|
|
23
|
+
chalk__default.default.red(`Error: Directory ${projectName} already exists.`)
|
|
24
|
+
);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const { framework } = await inquirer__default.default.prompt([
|
|
28
|
+
{
|
|
29
|
+
type: "list",
|
|
30
|
+
name: "framework",
|
|
31
|
+
message: "Select a framework:",
|
|
32
|
+
choices: ["express", "fastify"],
|
|
33
|
+
default: "express"
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
console.log(
|
|
37
|
+
chalk__default.default.blue(`
|
|
38
|
+
Initializing new Nural project in ${projectName}...`)
|
|
39
|
+
);
|
|
40
|
+
fs__default.default.ensureDirSync(path__default.default.join(projectPath, "src/config"));
|
|
41
|
+
fs__default.default.ensureDirSync(path__default.default.join(projectPath, "src/routes"));
|
|
42
|
+
fs__default.default.ensureDirSync(path__default.default.join(projectPath, "src/middleware"));
|
|
43
|
+
fs__default.default.ensureDirSync(path__default.default.join(projectPath, "src/services"));
|
|
44
|
+
const packageJson = {
|
|
45
|
+
name: projectName,
|
|
46
|
+
version: "1.0.0",
|
|
47
|
+
main: "dist/index.js",
|
|
48
|
+
scripts: {
|
|
49
|
+
dev: "tsx watch src/index.ts",
|
|
50
|
+
build: "tsup src/index.ts --format cjs,esm --dts",
|
|
51
|
+
start: "node dist/index.js"
|
|
52
|
+
},
|
|
53
|
+
dependencies: {
|
|
54
|
+
nural: "^0.2.0",
|
|
55
|
+
[framework]: framework === "express" ? "^5.0.0" : "^5.0.0",
|
|
56
|
+
// Using explicit versions for peer deps
|
|
57
|
+
zod: "^3.22.4"
|
|
58
|
+
},
|
|
59
|
+
devDependencies: {
|
|
60
|
+
tsx: "^4.7.1",
|
|
61
|
+
tsup: "^8.0.2",
|
|
62
|
+
typescript: "^5.3.3",
|
|
63
|
+
"@types/node": "^20.11.24",
|
|
64
|
+
...framework === "express" ? { "@types/express": "^5.0.0" } : {}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
fs__default.default.writeJsonSync(path__default.default.join(projectPath, "package.json"), packageJson, {
|
|
68
|
+
spaces: 2
|
|
69
|
+
});
|
|
70
|
+
const tsconfig = {
|
|
71
|
+
compilerOptions: {
|
|
72
|
+
target: "ES2020",
|
|
73
|
+
module: "CommonJS",
|
|
74
|
+
moduleResolution: "node",
|
|
75
|
+
strict: true,
|
|
76
|
+
esModuleInterop: true,
|
|
77
|
+
skipLibCheck: true,
|
|
78
|
+
forceConsistentCasingInFileNames: true,
|
|
79
|
+
outDir: "./dist"
|
|
80
|
+
},
|
|
81
|
+
include: ["src/**/*"],
|
|
82
|
+
exclude: ["node_modules"]
|
|
83
|
+
};
|
|
84
|
+
fs__default.default.writeJsonSync(path__default.default.join(projectPath, "tsconfig.json"), tsconfig, {
|
|
85
|
+
spaces: 2
|
|
86
|
+
});
|
|
87
|
+
const indexContent = `import { Nural } from "nural";
|
|
88
|
+
import { appConfig } from "./config/app.config";
|
|
89
|
+
|
|
90
|
+
const app = new Nural(appConfig);
|
|
91
|
+
|
|
92
|
+
app.start(3000).then(() => {
|
|
93
|
+
console.log("Server is running on http://localhost:3000");
|
|
94
|
+
});
|
|
95
|
+
`;
|
|
96
|
+
fs__default.default.writeFileSync(path__default.default.join(projectPath, "src/index.ts"), indexContent);
|
|
97
|
+
const configContent = `import { NuralConfig } from "nural";
|
|
98
|
+
|
|
99
|
+
export const appConfig: NuralConfig = {
|
|
100
|
+
framework: "${framework}",
|
|
101
|
+
docs: true,
|
|
102
|
+
logger: {
|
|
103
|
+
enabled: true,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
`;
|
|
107
|
+
fs__default.default.writeFileSync(
|
|
108
|
+
path__default.default.join(projectPath, "src/config/app.config.ts"),
|
|
109
|
+
configContent
|
|
110
|
+
);
|
|
111
|
+
console.log(
|
|
112
|
+
chalk__default.default.green(`
|
|
113
|
+
\u2714 Project ${projectName} created successfully!`)
|
|
114
|
+
);
|
|
115
|
+
console.log(chalk__default.default.white(`
|
|
116
|
+
Next steps:`));
|
|
117
|
+
console.log(chalk__default.default.cyan(` cd ${projectName}`));
|
|
118
|
+
console.log(chalk__default.default.cyan(` npm install`));
|
|
119
|
+
console.log(chalk__default.default.cyan(` npm run dev`));
|
|
120
|
+
});
|
|
121
|
+
program.command("generate <type> <name>").alias("g").description("Generate a resource (route, middleware, service)").action((typeArg, nameArg) => {
|
|
122
|
+
const type = typeArg.toLowerCase();
|
|
123
|
+
const name = nameArg.toLowerCase();
|
|
124
|
+
const srcDir = path__default.default.join(process.cwd(), "src");
|
|
125
|
+
if (!fs__default.default.existsSync(srcDir)) {
|
|
126
|
+
console.error(
|
|
127
|
+
chalk__default.default.red(
|
|
128
|
+
"Error: src directory not found. Are you in a Nural project root?"
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
134
|
+
switch (type) {
|
|
135
|
+
case "route": {
|
|
136
|
+
const routeContent = `import { createRoute, z } from "nural";
|
|
137
|
+
|
|
138
|
+
export const ${name}Route = createRoute({
|
|
139
|
+
method: "GET",
|
|
140
|
+
path: "/${name}",
|
|
141
|
+
summary: "${capitalize(name)} route",
|
|
142
|
+
responses: {
|
|
143
|
+
200: z.object({ message: z.string() }),
|
|
144
|
+
},
|
|
145
|
+
handler: async () => {
|
|
146
|
+
return { message: "Hello from ${name}" };
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
`;
|
|
150
|
+
const routesDir = path__default.default.join(srcDir, "routes");
|
|
151
|
+
fs__default.default.ensureDirSync(routesDir);
|
|
152
|
+
fs__default.default.writeFileSync(
|
|
153
|
+
path__default.default.join(routesDir, `${name}.routes.ts`),
|
|
154
|
+
routeContent
|
|
155
|
+
);
|
|
156
|
+
console.log(chalk__default.default.green(`Created src/routes/${name}.routes.ts`));
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "middleware": {
|
|
160
|
+
const middlewareContent = `import { defineMiddleware } from "nural";
|
|
161
|
+
|
|
162
|
+
export const ${name}Middleware = defineMiddleware(async (req, res) => {
|
|
163
|
+
// TODO: Implement middleware logic
|
|
164
|
+
return { ${name}: true };
|
|
165
|
+
});
|
|
166
|
+
`;
|
|
167
|
+
const middlewareDir = path__default.default.join(srcDir, "middleware");
|
|
168
|
+
fs__default.default.ensureDirSync(middlewareDir);
|
|
169
|
+
fs__default.default.writeFileSync(
|
|
170
|
+
path__default.default.join(middlewareDir, `${name}.middleware.ts`),
|
|
171
|
+
middlewareContent
|
|
172
|
+
);
|
|
173
|
+
console.log(
|
|
174
|
+
chalk__default.default.green(`Created src/middleware/${name}.middleware.ts`)
|
|
175
|
+
);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case "service": {
|
|
179
|
+
const serviceContent = `export class ${capitalize(name)}Service {
|
|
180
|
+
constructor() {}
|
|
181
|
+
|
|
182
|
+
async findAll() {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const ${name}Service = new ${capitalize(name)}Service();
|
|
188
|
+
`;
|
|
189
|
+
const servicesDir = path__default.default.join(srcDir, "services");
|
|
190
|
+
fs__default.default.ensureDirSync(servicesDir);
|
|
191
|
+
fs__default.default.writeFileSync(
|
|
192
|
+
path__default.default.join(servicesDir, `${name}.service.ts`),
|
|
193
|
+
serviceContent
|
|
194
|
+
);
|
|
195
|
+
console.log(chalk__default.default.green(`Created src/services/${name}.service.ts`));
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
default:
|
|
199
|
+
console.error(
|
|
200
|
+
chalk__default.default.red(
|
|
201
|
+
`Unknown type: ${type}. Supported: route, middleware, service`
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
program.parse(process.argv);
|
|
208
|
+
//# sourceMappingURL=index.cjs.map
|
|
209
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts"],"names":["Command","path","fs","chalk","inquirer"],"mappings":"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","file":"index.cjs","sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\n\nconst program = new Command();\n\nprogram.name(\"nural\").description(\"Nural Framework CLI\").version(\"0.3.0\");\n\nprogram\n .command(\"new <project-name>\")\n .description(\"Create a new Nural project\")\n .action(async (projectName) => {\n const projectPath = path.join(process.cwd(), projectName);\n\n if (fs.existsSync(projectPath)) {\n console.error(\n chalk.red(`Error: Directory ${projectName} already exists.`),\n );\n process.exit(1);\n }\n\n const { framework } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"framework\",\n message: \"Select a framework:\",\n choices: [\"express\", \"fastify\"],\n default: \"express\",\n },\n ]);\n\n console.log(\n chalk.blue(`\\nInitializing new Nural project in ${projectName}...`),\n );\n\n // Create directories\n fs.ensureDirSync(path.join(projectPath, \"src/config\"));\n fs.ensureDirSync(path.join(projectPath, \"src/routes\"));\n fs.ensureDirSync(path.join(projectPath, \"src/middleware\"));\n fs.ensureDirSync(path.join(projectPath, \"src/services\"));\n\n // Create package.json\n const packageJson = {\n name: projectName,\n version: \"1.0.0\",\n main: \"dist/index.js\",\n scripts: {\n dev: \"tsx watch src/index.ts\",\n build: \"tsup src/index.ts --format cjs,esm --dts\",\n start: \"node dist/index.js\",\n },\n dependencies: {\n nural: \"^0.2.0\",\n [framework]: framework === \"express\" ? \"^5.0.0\" : \"^5.0.0\", // Using explicit versions for peer deps\n zod: \"^3.22.4\",\n },\n devDependencies: {\n tsx: \"^4.7.1\",\n tsup: \"^8.0.2\",\n typescript: \"^5.3.3\",\n \"@types/node\": \"^20.11.24\",\n ...(framework === \"express\" ? { \"@types/express\": \"^5.0.0\" } : {}),\n },\n };\n\n fs.writeJsonSync(path.join(projectPath, \"package.json\"), packageJson, {\n spaces: 2,\n });\n\n // Create tsconfig.json\n const tsconfig = {\n compilerOptions: {\n target: \"ES2020\",\n module: \"CommonJS\",\n moduleResolution: \"node\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n outDir: \"./dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n };\n\n fs.writeJsonSync(path.join(projectPath, \"tsconfig.json\"), tsconfig, {\n spaces: 2,\n });\n\n // Create src/index.ts\n const indexContent = `import { Nural } from \"nural\";\nimport { appConfig } from \"./config/app.config\";\n\nconst app = new Nural(appConfig);\n\napp.start(3000).then(() => {\n console.log(\"Server is running on http://localhost:3000\");\n});\n`;\n fs.writeFileSync(path.join(projectPath, \"src/index.ts\"), indexContent);\n\n // Create src/config/app.config.ts\n const configContent = `import { NuralConfig } from \"nural\";\n\nexport const appConfig: NuralConfig = {\n framework: \"${framework}\",\n docs: true,\n logger: {\n enabled: true,\n },\n};\n`;\n fs.writeFileSync(\n path.join(projectPath, \"src/config/app.config.ts\"),\n configContent,\n );\n\n console.log(\n chalk.green(`\\nā Project ${projectName} created successfully!`),\n );\n console.log(chalk.white(`\\nNext steps:`));\n console.log(chalk.cyan(` cd ${projectName}`));\n console.log(chalk.cyan(` npm install`));\n console.log(chalk.cyan(` npm run dev`));\n });\n\nprogram\n .command(\"generate <type> <name>\")\n .alias(\"g\")\n .description(\"Generate a resource (route, middleware, service)\")\n .action((typeArg, nameArg) => {\n const type = typeArg.toLowerCase();\n const name = nameArg.toLowerCase();\n const srcDir = path.join(process.cwd(), \"src\");\n\n if (!fs.existsSync(srcDir)) {\n console.error(\n chalk.red(\n \"Error: src directory not found. Are you in a Nural project root?\",\n ),\n );\n process.exit(1);\n }\n\n const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\n switch (type) {\n case \"route\": {\n const routeContent = `import { createRoute, z } from \"nural\";\n\nexport const ${name}Route = createRoute({\n method: \"GET\",\n path: \"/${name}\",\n summary: \"${capitalize(name)} route\",\n responses: {\n 200: z.object({ message: z.string() }),\n },\n handler: async () => {\n return { message: \"Hello from ${name}\" };\n },\n});\n`;\n const routesDir = path.join(srcDir, \"routes\");\n fs.ensureDirSync(routesDir);\n fs.writeFileSync(\n path.join(routesDir, `${name}.routes.ts`),\n routeContent,\n );\n console.log(chalk.green(`Created src/routes/${name}.routes.ts`));\n break;\n }\n case \"middleware\": {\n const middlewareContent = `import { defineMiddleware } from \"nural\";\n\nexport const ${name}Middleware = defineMiddleware(async (req, res) => {\n // TODO: Implement middleware logic\n return { ${name}: true };\n});\n`;\n const middlewareDir = path.join(srcDir, \"middleware\");\n fs.ensureDirSync(middlewareDir);\n fs.writeFileSync(\n path.join(middlewareDir, `${name}.middleware.ts`),\n middlewareContent,\n );\n console.log(\n chalk.green(`Created src/middleware/${name}.middleware.ts`),\n );\n break;\n }\n case \"service\": {\n const serviceContent = `export class ${capitalize(name)}Service {\n constructor() {}\n\n async findAll() {\n return [];\n }\n}\n\nexport const ${name}Service = new ${capitalize(name)}Service();\n`;\n const servicesDir = path.join(srcDir, \"services\");\n fs.ensureDirSync(servicesDir);\n fs.writeFileSync(\n path.join(servicesDir, `${name}.service.ts`),\n serviceContent,\n );\n console.log(chalk.green(`Created src/services/${name}.service.ts`));\n break;\n }\n default:\n console.error(\n chalk.red(\n `Unknown type: ${type}. Supported: route, middleware, service`,\n ),\n );\n process.exit(1);\n }\n });\n\nprogram.parse(process.argv);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
var program = new Command();
|
|
9
|
+
program.name("nural").description("Nural Framework CLI").version("0.3.0");
|
|
10
|
+
program.command("new <project-name>").description("Create a new Nural project").action(async (projectName) => {
|
|
11
|
+
const projectPath = path.join(process.cwd(), projectName);
|
|
12
|
+
if (fs.existsSync(projectPath)) {
|
|
13
|
+
console.error(
|
|
14
|
+
chalk.red(`Error: Directory ${projectName} already exists.`)
|
|
15
|
+
);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const { framework } = await inquirer.prompt([
|
|
19
|
+
{
|
|
20
|
+
type: "list",
|
|
21
|
+
name: "framework",
|
|
22
|
+
message: "Select a framework:",
|
|
23
|
+
choices: ["express", "fastify"],
|
|
24
|
+
default: "express"
|
|
25
|
+
}
|
|
26
|
+
]);
|
|
27
|
+
console.log(
|
|
28
|
+
chalk.blue(`
|
|
29
|
+
Initializing new Nural project in ${projectName}...`)
|
|
30
|
+
);
|
|
31
|
+
fs.ensureDirSync(path.join(projectPath, "src/config"));
|
|
32
|
+
fs.ensureDirSync(path.join(projectPath, "src/routes"));
|
|
33
|
+
fs.ensureDirSync(path.join(projectPath, "src/middleware"));
|
|
34
|
+
fs.ensureDirSync(path.join(projectPath, "src/services"));
|
|
35
|
+
const packageJson = {
|
|
36
|
+
name: projectName,
|
|
37
|
+
version: "1.0.0",
|
|
38
|
+
main: "dist/index.js",
|
|
39
|
+
scripts: {
|
|
40
|
+
dev: "tsx watch src/index.ts",
|
|
41
|
+
build: "tsup src/index.ts --format cjs,esm --dts",
|
|
42
|
+
start: "node dist/index.js"
|
|
43
|
+
},
|
|
44
|
+
dependencies: {
|
|
45
|
+
nural: "^0.2.0",
|
|
46
|
+
[framework]: framework === "express" ? "^5.0.0" : "^5.0.0",
|
|
47
|
+
// Using explicit versions for peer deps
|
|
48
|
+
zod: "^3.22.4"
|
|
49
|
+
},
|
|
50
|
+
devDependencies: {
|
|
51
|
+
tsx: "^4.7.1",
|
|
52
|
+
tsup: "^8.0.2",
|
|
53
|
+
typescript: "^5.3.3",
|
|
54
|
+
"@types/node": "^20.11.24",
|
|
55
|
+
...framework === "express" ? { "@types/express": "^5.0.0" } : {}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
fs.writeJsonSync(path.join(projectPath, "package.json"), packageJson, {
|
|
59
|
+
spaces: 2
|
|
60
|
+
});
|
|
61
|
+
const tsconfig = {
|
|
62
|
+
compilerOptions: {
|
|
63
|
+
target: "ES2020",
|
|
64
|
+
module: "CommonJS",
|
|
65
|
+
moduleResolution: "node",
|
|
66
|
+
strict: true,
|
|
67
|
+
esModuleInterop: true,
|
|
68
|
+
skipLibCheck: true,
|
|
69
|
+
forceConsistentCasingInFileNames: true,
|
|
70
|
+
outDir: "./dist"
|
|
71
|
+
},
|
|
72
|
+
include: ["src/**/*"],
|
|
73
|
+
exclude: ["node_modules"]
|
|
74
|
+
};
|
|
75
|
+
fs.writeJsonSync(path.join(projectPath, "tsconfig.json"), tsconfig, {
|
|
76
|
+
spaces: 2
|
|
77
|
+
});
|
|
78
|
+
const indexContent = `import { Nural } from "nural";
|
|
79
|
+
import { appConfig } from "./config/app.config";
|
|
80
|
+
|
|
81
|
+
const app = new Nural(appConfig);
|
|
82
|
+
|
|
83
|
+
app.start(3000).then(() => {
|
|
84
|
+
console.log("Server is running on http://localhost:3000");
|
|
85
|
+
});
|
|
86
|
+
`;
|
|
87
|
+
fs.writeFileSync(path.join(projectPath, "src/index.ts"), indexContent);
|
|
88
|
+
const configContent = `import { NuralConfig } from "nural";
|
|
89
|
+
|
|
90
|
+
export const appConfig: NuralConfig = {
|
|
91
|
+
framework: "${framework}",
|
|
92
|
+
docs: true,
|
|
93
|
+
logger: {
|
|
94
|
+
enabled: true,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
`;
|
|
98
|
+
fs.writeFileSync(
|
|
99
|
+
path.join(projectPath, "src/config/app.config.ts"),
|
|
100
|
+
configContent
|
|
101
|
+
);
|
|
102
|
+
console.log(
|
|
103
|
+
chalk.green(`
|
|
104
|
+
\u2714 Project ${projectName} created successfully!`)
|
|
105
|
+
);
|
|
106
|
+
console.log(chalk.white(`
|
|
107
|
+
Next steps:`));
|
|
108
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
|
109
|
+
console.log(chalk.cyan(` npm install`));
|
|
110
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
111
|
+
});
|
|
112
|
+
program.command("generate <type> <name>").alias("g").description("Generate a resource (route, middleware, service)").action((typeArg, nameArg) => {
|
|
113
|
+
const type = typeArg.toLowerCase();
|
|
114
|
+
const name = nameArg.toLowerCase();
|
|
115
|
+
const srcDir = path.join(process.cwd(), "src");
|
|
116
|
+
if (!fs.existsSync(srcDir)) {
|
|
117
|
+
console.error(
|
|
118
|
+
chalk.red(
|
|
119
|
+
"Error: src directory not found. Are you in a Nural project root?"
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
125
|
+
switch (type) {
|
|
126
|
+
case "route": {
|
|
127
|
+
const routeContent = `import { createRoute, z } from "nural";
|
|
128
|
+
|
|
129
|
+
export const ${name}Route = createRoute({
|
|
130
|
+
method: "GET",
|
|
131
|
+
path: "/${name}",
|
|
132
|
+
summary: "${capitalize(name)} route",
|
|
133
|
+
responses: {
|
|
134
|
+
200: z.object({ message: z.string() }),
|
|
135
|
+
},
|
|
136
|
+
handler: async () => {
|
|
137
|
+
return { message: "Hello from ${name}" };
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
`;
|
|
141
|
+
const routesDir = path.join(srcDir, "routes");
|
|
142
|
+
fs.ensureDirSync(routesDir);
|
|
143
|
+
fs.writeFileSync(
|
|
144
|
+
path.join(routesDir, `${name}.routes.ts`),
|
|
145
|
+
routeContent
|
|
146
|
+
);
|
|
147
|
+
console.log(chalk.green(`Created src/routes/${name}.routes.ts`));
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "middleware": {
|
|
151
|
+
const middlewareContent = `import { defineMiddleware } from "nural";
|
|
152
|
+
|
|
153
|
+
export const ${name}Middleware = defineMiddleware(async (req, res) => {
|
|
154
|
+
// TODO: Implement middleware logic
|
|
155
|
+
return { ${name}: true };
|
|
156
|
+
});
|
|
157
|
+
`;
|
|
158
|
+
const middlewareDir = path.join(srcDir, "middleware");
|
|
159
|
+
fs.ensureDirSync(middlewareDir);
|
|
160
|
+
fs.writeFileSync(
|
|
161
|
+
path.join(middlewareDir, `${name}.middleware.ts`),
|
|
162
|
+
middlewareContent
|
|
163
|
+
);
|
|
164
|
+
console.log(
|
|
165
|
+
chalk.green(`Created src/middleware/${name}.middleware.ts`)
|
|
166
|
+
);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case "service": {
|
|
170
|
+
const serviceContent = `export class ${capitalize(name)}Service {
|
|
171
|
+
constructor() {}
|
|
172
|
+
|
|
173
|
+
async findAll() {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export const ${name}Service = new ${capitalize(name)}Service();
|
|
179
|
+
`;
|
|
180
|
+
const servicesDir = path.join(srcDir, "services");
|
|
181
|
+
fs.ensureDirSync(servicesDir);
|
|
182
|
+
fs.writeFileSync(
|
|
183
|
+
path.join(servicesDir, `${name}.service.ts`),
|
|
184
|
+
serviceContent
|
|
185
|
+
);
|
|
186
|
+
console.log(chalk.green(`Created src/services/${name}.service.ts`));
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
console.error(
|
|
191
|
+
chalk.red(
|
|
192
|
+
`Unknown type: ${type}. Supported: route, middleware, service`
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
program.parse(process.argv);
|
|
199
|
+
//# sourceMappingURL=index.js.map
|
|
200
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\n\nconst program = new Command();\n\nprogram.name(\"nural\").description(\"Nural Framework CLI\").version(\"0.3.0\");\n\nprogram\n .command(\"new <project-name>\")\n .description(\"Create a new Nural project\")\n .action(async (projectName) => {\n const projectPath = path.join(process.cwd(), projectName);\n\n if (fs.existsSync(projectPath)) {\n console.error(\n chalk.red(`Error: Directory ${projectName} already exists.`),\n );\n process.exit(1);\n }\n\n const { framework } = await inquirer.prompt([\n {\n type: \"list\",\n name: \"framework\",\n message: \"Select a framework:\",\n choices: [\"express\", \"fastify\"],\n default: \"express\",\n },\n ]);\n\n console.log(\n chalk.blue(`\\nInitializing new Nural project in ${projectName}...`),\n );\n\n // Create directories\n fs.ensureDirSync(path.join(projectPath, \"src/config\"));\n fs.ensureDirSync(path.join(projectPath, \"src/routes\"));\n fs.ensureDirSync(path.join(projectPath, \"src/middleware\"));\n fs.ensureDirSync(path.join(projectPath, \"src/services\"));\n\n // Create package.json\n const packageJson = {\n name: projectName,\n version: \"1.0.0\",\n main: \"dist/index.js\",\n scripts: {\n dev: \"tsx watch src/index.ts\",\n build: \"tsup src/index.ts --format cjs,esm --dts\",\n start: \"node dist/index.js\",\n },\n dependencies: {\n nural: \"^0.2.0\",\n [framework]: framework === \"express\" ? \"^5.0.0\" : \"^5.0.0\", // Using explicit versions for peer deps\n zod: \"^3.22.4\",\n },\n devDependencies: {\n tsx: \"^4.7.1\",\n tsup: \"^8.0.2\",\n typescript: \"^5.3.3\",\n \"@types/node\": \"^20.11.24\",\n ...(framework === \"express\" ? { \"@types/express\": \"^5.0.0\" } : {}),\n },\n };\n\n fs.writeJsonSync(path.join(projectPath, \"package.json\"), packageJson, {\n spaces: 2,\n });\n\n // Create tsconfig.json\n const tsconfig = {\n compilerOptions: {\n target: \"ES2020\",\n module: \"CommonJS\",\n moduleResolution: \"node\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n outDir: \"./dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n };\n\n fs.writeJsonSync(path.join(projectPath, \"tsconfig.json\"), tsconfig, {\n spaces: 2,\n });\n\n // Create src/index.ts\n const indexContent = `import { Nural } from \"nural\";\nimport { appConfig } from \"./config/app.config\";\n\nconst app = new Nural(appConfig);\n\napp.start(3000).then(() => {\n console.log(\"Server is running on http://localhost:3000\");\n});\n`;\n fs.writeFileSync(path.join(projectPath, \"src/index.ts\"), indexContent);\n\n // Create src/config/app.config.ts\n const configContent = `import { NuralConfig } from \"nural\";\n\nexport const appConfig: NuralConfig = {\n framework: \"${framework}\",\n docs: true,\n logger: {\n enabled: true,\n },\n};\n`;\n fs.writeFileSync(\n path.join(projectPath, \"src/config/app.config.ts\"),\n configContent,\n );\n\n console.log(\n chalk.green(`\\nā Project ${projectName} created successfully!`),\n );\n console.log(chalk.white(`\\nNext steps:`));\n console.log(chalk.cyan(` cd ${projectName}`));\n console.log(chalk.cyan(` npm install`));\n console.log(chalk.cyan(` npm run dev`));\n });\n\nprogram\n .command(\"generate <type> <name>\")\n .alias(\"g\")\n .description(\"Generate a resource (route, middleware, service)\")\n .action((typeArg, nameArg) => {\n const type = typeArg.toLowerCase();\n const name = nameArg.toLowerCase();\n const srcDir = path.join(process.cwd(), \"src\");\n\n if (!fs.existsSync(srcDir)) {\n console.error(\n chalk.red(\n \"Error: src directory not found. Are you in a Nural project root?\",\n ),\n );\n process.exit(1);\n }\n\n const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\n switch (type) {\n case \"route\": {\n const routeContent = `import { createRoute, z } from \"nural\";\n\nexport const ${name}Route = createRoute({\n method: \"GET\",\n path: \"/${name}\",\n summary: \"${capitalize(name)} route\",\n responses: {\n 200: z.object({ message: z.string() }),\n },\n handler: async () => {\n return { message: \"Hello from ${name}\" };\n },\n});\n`;\n const routesDir = path.join(srcDir, \"routes\");\n fs.ensureDirSync(routesDir);\n fs.writeFileSync(\n path.join(routesDir, `${name}.routes.ts`),\n routeContent,\n );\n console.log(chalk.green(`Created src/routes/${name}.routes.ts`));\n break;\n }\n case \"middleware\": {\n const middlewareContent = `import { defineMiddleware } from \"nural\";\n\nexport const ${name}Middleware = defineMiddleware(async (req, res) => {\n // TODO: Implement middleware logic\n return { ${name}: true };\n});\n`;\n const middlewareDir = path.join(srcDir, \"middleware\");\n fs.ensureDirSync(middlewareDir);\n fs.writeFileSync(\n path.join(middlewareDir, `${name}.middleware.ts`),\n middlewareContent,\n );\n console.log(\n chalk.green(`Created src/middleware/${name}.middleware.ts`),\n );\n break;\n }\n case \"service\": {\n const serviceContent = `export class ${capitalize(name)}Service {\n constructor() {}\n\n async findAll() {\n return [];\n }\n}\n\nexport const ${name}Service = new ${capitalize(name)}Service();\n`;\n const servicesDir = path.join(srcDir, \"services\");\n fs.ensureDirSync(servicesDir);\n fs.writeFileSync(\n path.join(servicesDir, `${name}.service.ts`),\n serviceContent,\n );\n console.log(chalk.green(`Created src/services/${name}.service.ts`));\n break;\n }\n default:\n console.error(\n chalk.red(\n `Unknown type: ${type}. Supported: route, middleware, service`,\n ),\n );\n process.exit(1);\n }\n });\n\nprogram.parse(process.argv);\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nural",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The intelligent, schema-first REST framework for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"nural": "./dist/cli/index.js"
|
|
18
|
+
},
|
|
16
19
|
"files": [
|
|
17
20
|
"dist",
|
|
18
21
|
"README.md",
|
|
@@ -62,11 +65,17 @@
|
|
|
62
65
|
},
|
|
63
66
|
"dependencies": {
|
|
64
67
|
"@asteasolutions/zod-to-openapi": "^7.3.4",
|
|
68
|
+
"chalk": "^5.6.2",
|
|
69
|
+
"commander": "^14.0.3",
|
|
70
|
+
"fs-extra": "^11.3.3",
|
|
71
|
+
"inquirer": "^13.2.2",
|
|
65
72
|
"swagger-ui-express": "^5.0.1",
|
|
66
73
|
"zod": "^3.25.76"
|
|
67
74
|
},
|
|
68
75
|
"devDependencies": {
|
|
69
76
|
"@types/express": "^5.0.6",
|
|
77
|
+
"@types/fs-extra": "^11.0.4",
|
|
78
|
+
"@types/inquirer": "^9.0.9",
|
|
70
79
|
"@types/node": "^25.2.1",
|
|
71
80
|
"@types/swagger-ui-express": "^4.1.8",
|
|
72
81
|
"fastify": "^5.7.4",
|