rapidkit 0.11.3 → 0.12.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 +99 -411
- package/dist/index.js +507 -640
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/templates/generator.js +175 -0
- package/templates/kits/fastapi-standard/.rapidkit/__init__.py.j2 +1 -0
- package/templates/kits/fastapi-standard/.rapidkit/activate.j2 +24 -0
- package/templates/kits/fastapi-standard/.rapidkit/cli.py.j2 +6 -4
- package/templates/kits/fastapi-standard/.rapidkit/project.json.j2 +3 -2
- package/templates/kits/fastapi-standard/.rapidkit/rapidkit.j2 +31 -0
- package/templates/kits/fastapi-standard/Makefile.j2 +41 -0
- package/templates/kits/fastapi-standard/pyproject.toml.j2 +1 -0
- package/templates/kits/fastapi-standard/rapidkit.j2 +50 -0
- package/templates/kits/nestjs-standard/.env.example.j2 +16 -0
- package/templates/kits/nestjs-standard/.eslintrc.js.j2 +25 -0
- package/templates/kits/nestjs-standard/.gitignore.j2 +26 -0
- package/templates/kits/nestjs-standard/.node-version.j2 +1 -0
- package/templates/kits/nestjs-standard/.nvmrc.j2 +1 -0
- package/templates/kits/nestjs-standard/.prettierrc.j2 +7 -0
- package/templates/kits/nestjs-standard/.rapidkit/activate.j2 +25 -0
- package/templates/kits/nestjs-standard/.rapidkit/project.json.j2 +7 -0
- package/templates/kits/nestjs-standard/.rapidkit/rapidkit.j2 +227 -0
- package/templates/kits/nestjs-standard/README.md.j2 +97 -0
- package/templates/kits/nestjs-standard/jest.config.ts.j2 +21 -0
- package/templates/kits/nestjs-standard/nest-cli.json.j2 +10 -0
- package/templates/kits/nestjs-standard/package.json.j2 +75 -0
- package/templates/kits/nestjs-standard/rapidkit.j2 +5 -0
- package/templates/kits/nestjs-standard/src/app.controller.ts.j2 +12 -0
- package/templates/kits/nestjs-standard/src/app.module.ts.j2 +23 -0
- package/templates/kits/nestjs-standard/src/app.service.ts.j2 +11 -0
- package/templates/kits/nestjs-standard/src/config/configuration.ts.j2 +9 -0
- package/templates/kits/nestjs-standard/src/config/index.ts.j2 +2 -0
- package/templates/kits/nestjs-standard/src/config/validation.ts.j2 +11 -0
- package/templates/kits/nestjs-standard/src/examples/dto/create-note.dto.ts.j2 +11 -0
- package/templates/kits/nestjs-standard/src/examples/examples.controller.ts.j2 +24 -0
- package/templates/kits/nestjs-standard/src/examples/examples.module.ts.j2 +10 -0
- package/templates/kits/nestjs-standard/src/examples/examples.service.ts.j2 +33 -0
- package/templates/kits/nestjs-standard/src/main.ts.j2 +51 -0
- package/templates/kits/nestjs-standard/src/modules/index.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/test/app.controller.spec.ts.j2 +22 -0
- package/templates/kits/nestjs-standard/test/app.e2e-spec.ts.j2 +48 -0
- package/templates/kits/nestjs-standard/test/examples.controller.spec.ts.j2 +28 -0
- package/templates/kits/nestjs-standard/test/jest-e2e.json.j2 +15 -0
- package/templates/kits/nestjs-standard/tsconfig.build.json.j2 +12 -0
- package/templates/kits/nestjs-standard/tsconfig.json.j2 +26 -0
package/dist/index.js
CHANGED
|
@@ -1,631 +1,443 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {Command}from'commander';import
|
|
3
|
-
[${
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
- Check your internet connection
|
|
7
|
-
- Verify Python/Poetry installation
|
|
8
|
-
- Try running with --debug flag for more details`;super(r,"INSTALLATION_ERROR",a);}},I=class extends u{constructor(){super("RapidKit Python package is not yet available on PyPI","RAPIDKIT_NOT_AVAILABLE",`Available options:
|
|
9
|
-
1. Demo mode: npx rapidkit my-workspace --demo
|
|
10
|
-
2. Test mode: npx rapidkit my-workspace --test-mode (requires local RapidKit)
|
|
11
|
-
3. Wait for official PyPI release (coming soon)`);}};async function U(t,e){let{skipGit:o=false,testMode:r=false,demoMode:a=false,dryRun:m=false,userConfig:d={}}=e,n=t,c=h.resolve(process.cwd(),n);if(await y.pathExists(c))throw new M(n);if(m){await ce(c,n,a,d);return}if(a){await se(c,n,o);return}let f=await oe.prompt([{type:"list",name:"pythonVersion",message:"Select Python version for RapidKit:",choices:["3.10","3.11","3.12"],default:d.pythonVersion||"3.11"},{type:"list",name:"installMethod",message:"How would you like to install RapidKit?",choices:[{name:"\u{1F3AF} Poetry (Recommended - includes virtual env)",value:"poetry"},{name:"\u{1F4E6} pip with venv (Standard)",value:"venv"},{name:"\u{1F527} pipx (Global isolated install)",value:"pipx"}],default:d.defaultInstallMethod||"poetry"}]);s.step(1,3,"Setting up RapidKit environment");let g=z("Creating directory").start();try{if(await y.ensureDir(c),g.succeed("Directory created"),f.installMethod==="poetry"?await ie(c,f.pythonVersion,g,r,d):f.installMethod==="venv"?await re(c,f.pythonVersion,g,r,d):await ae(c,g,r,d),await ne(c,f.installMethod),g.succeed("RapidKit environment ready!"),!e.skipGit){g.start("Initializing git repository");try{await execa("git",["init"],{cwd:c}),await y.outputFile(h.join(c,".gitignore"),`.venv/
|
|
12
|
-
__pycache__/
|
|
13
|
-
*.pyc
|
|
2
|
+
import {Command}from'commander';import a from'chalk';import P from'inquirer';import l,{dirname,join}from'path';import {execa}from'execa';import {readFileSync,promises}from'fs';import {fileURLToPath}from'url';import te from'os';import ae from'validate-npm-package-name';import*as k from'fs-extra';import N from'ora';var x=class{debugEnabled=false;setDebug(t){this.debugEnabled=t;}debug(t,...i){this.debugEnabled&&console.log(a.gray(`[DEBUG] ${t}`),...i);}info(t,...i){console.log(a.blue(t),...i);}success(t,...i){console.log(a.green(t),...i);}warn(t,...i){console.log(a.yellow(t),...i);}error(t,...i){console.error(a.red(t),...i);}step(t,i,o){console.log(a.cyan(`
|
|
3
|
+
[${t}/${i}]`),a.white(o));}},c=new x;var z="rapidkit",V=fileURLToPath(import.meta.url),q=dirname(V),X=join(q,"..","package.json"),Q=JSON.parse(readFileSync(X,"utf-8")),S=Q.version;async function T(){try{c.debug("Checking for updates...");let{stdout:e}=await execa("npm",["view",z,"version"],{timeout:3e3}),t=e.trim();t&&t!==S?(console.log(a.yellow(`
|
|
4
|
+
\u26A0\uFE0F Update available: ${S} \u2192 ${t}`)),console.log(a.cyan(`Run: npm install -g rapidkit@latest
|
|
5
|
+
`))):c.debug("You are using the latest version");}catch{c.debug("Could not check for updates");}}function w(){return S}var ie=".rapidkitrc.json";async function U(){let e=l.join(te.homedir(),ie);try{let t=await promises.readFile(e,"utf-8"),i=JSON.parse(t);return c.debug(`Loaded config from ${e}`),i}catch{return c.debug("No user config found, using defaults"),{}}}var v=class extends Error{constructor(i,o,n){super(i);this.code=o;this.details=n;this.name="RapidKitError",Error.captureStackTrace(this,this.constructor);}};var u=class extends v{constructor(t,i){super(`Invalid project name: "${t}"`,"INVALID_PROJECT_NAME",i);}};function O(e){let t=ae(e);if(!t.validForNewPackages){let o=t.errors||[],n=t.warnings||[],s=[...o,...n];throw new u(e,`NPM validation failed: ${s.join(", ")}`)}if(!/^[a-z][a-z0-9_-]*$/.test(e))throw new u(e,"Must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores");if(["test","tests","src","dist","build","lib","python","pip","poetry","node","npm","rapidkit","rapidkit"].includes(e.toLowerCase()))throw new u(e,`"${e}" is a reserved name. Please choose a different name.`);if(e.length<2)throw new u(e,"Name must be at least 2 characters long");if(e.length>214)throw new u(e,"Name must be less than 214 characters");return true}async function F(e,t){let i=N("Creating RapidKit workspace...").start();try{await promises.mkdir(e,{recursive:!0}),await promises.mkdir(l.join(e,".rapidkit"),{recursive:!0});let o={workspace_name:t.name,author:t.author,rapidkit_version:w(),created_at:new Date().toISOString(),type:"workspace"};await promises.writeFile(l.join(e,".rapidkit","config.json"),JSON.stringify(o,null,2));let n=re();await promises.writeFile(l.join(e,"rapidkit"),n),await promises.chmod(l.join(e,"rapidkit"),493);let s=oe(t.name);if(await promises.writeFile(l.join(e,"README.md"),s),await promises.writeFile(l.join(e,".gitignore"),`# RapidKit workspace
|
|
14
6
|
.env
|
|
15
|
-
.
|
|
16
|
-
|
|
17
|
-
\u2728 RapidKit environment created successfully!
|
|
18
|
-
`)),console.log(i.cyan("\u{1F4C2} Location:"),i.white(c)),console.log(i.cyan(`\u{1F680} Get started:
|
|
19
|
-
`)),console.log(i.white(` cd ${n}`)),f.installMethod==="poetry"){let v="source $(poetry env info --path)/bin/activate";try{let{stdout:K}=await execa("poetry",["--version"]),b=K.match(/Poetry.*?(\d+)\.(\d+)/);b&&(parseInt(b[1])>=2?v="source $(poetry env info --path)/bin/activate":v="poetry shell");}catch{}console.log(i.white(` ${v} # Or: poetry run rapidkit`)),console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && rapidkit init && rapidkit dev"));}else f.installMethod==="venv"?(console.log(i.white(" source .venv/bin/activate # On Windows: .venv\\Scripts\\activate")),console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && rapidkit init && rapidkit dev"))):(console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && rapidkit init && rapidkit dev")));console.log(i.white(`
|
|
20
|
-
\u{1F4A1} For more information, check the README.md file.`)),console.log(i.cyan(`
|
|
21
|
-
\u{1F4DA} RapidKit commands:`)),console.log(i.white(" rapidkit create - Create a new project (interactive)")),console.log(i.white(" rapidkit dev - Run development server")),console.log(i.white(" rapidkit add module <name> - Add a module (e.g., settings)")),console.log(i.white(" rapidkit list - List available kits")),console.log(i.white(" rapidkit modules - List available modules")),console.log(i.white(` rapidkit --help - Show all commands
|
|
22
|
-
`));}catch(v){g.fail("Failed to create RapidKit environment"),console.error(i.red(`
|
|
23
|
-
\u274C Error:`),v);try{await y.remove(c);}catch{}process.exit(1);}}async function ie(t,e,o,r,a){o.start("Checking Poetry installation");try{await execa("poetry",["--version"]),o.succeed("Poetry found");}catch{throw new T}o.start("Initializing Poetry project"),await execa("poetry",["init","--no-interaction","--python",`^${e}`],{cwd:t});let m=h.join(t,"pyproject.toml"),n=(await promises.readFile(m,"utf-8")).replace("[tool.poetry]",`[tool.poetry]
|
|
24
|
-
package-mode = false`);if(await promises.writeFile(m,n,"utf-8"),o.succeed("Poetry project initialized"),o.start("Installing RapidKit"),r){let c=F(a||{});if(!c)throw new j("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${c}`),o.text="Installing RapidKit from local path (test mode)",await execa("poetry",["add",c],{cwd:t});}else {o.text="Installing RapidKit from PyPI";try{await execa("poetry",["add","rapidkit"],{cwd:t});}catch{throw new I}}o.succeed("RapidKit installed");}async function re(t,e,o,r,a){o.start(`Checking Python ${e}`);let m="python3";try{let{stdout:n}=await execa(m,["--version"]),c=n.match(/Python (\d+\.\d+)/)?.[1];if(c&&parseFloat(c)<parseFloat(e))throw new P(e,c);o.succeed(`Python ${c} found`);}catch(n){throw n instanceof P?n:new P(e)}o.start("Creating virtual environment"),await execa(m,["-m","venv",".venv"],{cwd:t}),o.succeed("Virtual environment created"),o.start("Installing RapidKit");let d=h.join(t,".venv","bin","pip");if(await execa(d,["install","--upgrade","pip"],{cwd:t}),r){let n=F(a||{});if(!n)throw new j("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${n}`),o.text="Installing RapidKit from local path (test mode)",await execa(d,["install","-e",n],{cwd:t});}else {o.text="Installing RapidKit from PyPI";try{await execa(d,["install","rapidkit"],{cwd:t});}catch{throw new I}}o.succeed("RapidKit installed");}async function ae(t,e,o,r){e.start("Checking pipx installation");try{await execa("pipx",["--version"]),e.succeed("pipx found");}catch{throw new N}if(e.start("Installing RapidKit globally with pipx"),o){let a=F(r||{});if(!a)throw new j("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${a}`),e.text="Installing RapidKit from local path (test mode)",await execa("pipx",["install","-e",a]);}else {e.text="Installing RapidKit from PyPI";try{await execa("pipx",["install","rapidkit"]);}catch{throw new I}}e.succeed("RapidKit installed globally"),await y.outputFile(h.join(t,".rapidkit-global"),`RapidKit installed globally with pipx
|
|
25
|
-
`,"utf-8");}async function ne(t,e){let r=`# RapidKit Workspace
|
|
26
|
-
|
|
27
|
-
This directory contains a RapidKit development environment.
|
|
28
|
-
|
|
29
|
-
## Installation Method
|
|
30
|
-
|
|
31
|
-
**${e==="poetry"?"Poetry":e==="venv"?"Python venv + pip":"pipx (global)"}**
|
|
32
|
-
|
|
33
|
-
## Getting Started
|
|
34
|
-
|
|
35
|
-
### 1. Activate Environment
|
|
36
|
-
|
|
37
|
-
\`\`\`bash
|
|
38
|
-
${e==="poetry"?`source $(poetry env info --path)/bin/activate
|
|
39
|
-
# Or simply use: poetry run rapidkit <command>`:e==="venv"?"source .venv/bin/activate # On Windows: .venv\\Scripts\\activate":"N/A (globally installed)"}
|
|
40
|
-
\`\`\`
|
|
41
|
-
|
|
42
|
-
### 2. Create Your First Project
|
|
43
|
-
|
|
44
|
-
\`\`\`bash
|
|
45
|
-
# Interactive mode (recommended):
|
|
46
|
-
rapidkit create
|
|
47
|
-
# Follow the prompts to choose kit and project name
|
|
48
|
-
|
|
49
|
-
# Or specify directly:
|
|
50
|
-
rapidkit create project fastapi.standard my-project
|
|
51
|
-
|
|
52
|
-
# With poetry run (no activation needed):
|
|
53
|
-
poetry run rapidkit create
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
Interactive mode will guide you through selecting a kit and configuring your project.
|
|
57
|
-
|
|
58
|
-
### 3. Navigate and Run
|
|
59
|
-
|
|
60
|
-
\`\`\`bash
|
|
61
|
-
cd my-project
|
|
62
|
-
# Install dependencies (preferred):
|
|
63
|
-
rapidkit init
|
|
64
|
-
|
|
65
|
-
# Run the server (project-aware):
|
|
66
|
-
rapidkit dev
|
|
67
|
-
|
|
68
|
-
# Or with poetry run (manual / advanced):
|
|
69
|
-
poetry run rapidkit dev
|
|
70
|
-
|
|
71
|
-
# Or manually:
|
|
72
|
-
uvicorn src.main:app --reload
|
|
73
|
-
\`\`\`
|
|
74
|
-
|
|
75
|
-
### 4. Add Modules (Optional)
|
|
76
|
-
|
|
77
|
-
\`\`\`bash
|
|
78
|
-
# Add common modules to your project:
|
|
79
|
-
rapidkit add module settings
|
|
80
|
-
rapidkit add module logging
|
|
81
|
-
rapidkit add module database
|
|
82
|
-
|
|
83
|
-
# List available modules:
|
|
84
|
-
rapidkit modules list
|
|
85
|
-
\`\`\`
|
|
86
|
-
|
|
87
|
-
## Available Commands
|
|
88
|
-
|
|
89
|
-
- \`rapidkit create\` - Create a new project (interactive)
|
|
90
|
-
- \`rapidkit create project <kit> <name>\` - Create project with specific kit
|
|
91
|
-
- \`rapidkit dev\` - Run development server
|
|
92
|
-
- \`rapidkit add module <name>\` - Add a module (e.g., \`rapidkit add module settings\`)
|
|
93
|
-
- \`rapidkit list\` - List available kits
|
|
94
|
-
- \`rapidkit modules\` - List available modules
|
|
95
|
-
- \`rapidkit upgrade\` - Upgrade RapidKit
|
|
96
|
-
- \`rapidkit doctor\` - Check system requirements
|
|
97
|
-
- \`rapidkit --help\` - Show all commands
|
|
7
|
+
.env.*
|
|
8
|
+
!.env.example
|
|
98
9
|
|
|
99
|
-
|
|
10
|
+
# OS
|
|
11
|
+
.DS_Store
|
|
12
|
+
Thumbs.db
|
|
100
13
|
|
|
101
|
-
|
|
14
|
+
# IDEs
|
|
15
|
+
.vscode/
|
|
16
|
+
.idea/
|
|
102
17
|
|
|
103
|
-
|
|
18
|
+
# Logs
|
|
19
|
+
*.log
|
|
20
|
+
`),await ne(e),i.succeed("Workspace created!"),!t.skipGit){let d=N("Initializing git repository...").start();try{await execa("git",["init"],{cwd:e}),await execa("git",["add","."],{cwd:e}),await execa("git",["commit","-m","Initial commit: RapidKit workspace"],{cwd:e}),d.succeed("Git repository initialized");}catch{d.warn("Could not initialize git repository");}}console.log(`
|
|
21
|
+
${a.green("\u2728 RapidKit workspace created successfully!")}
|
|
104
22
|
|
|
105
|
-
|
|
106
|
-
${e
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
23
|
+
${a.bold("\u{1F4C2} Workspace structure:")}
|
|
24
|
+
${e}/
|
|
25
|
+
\u251C\u2500\u2500 rapidkit # Local CLI (add to PATH or use ./rapidkit)
|
|
26
|
+
\u251C\u2500\u2500 .rapidkit/ # Workspace configuration
|
|
27
|
+
\u2502 \u251C\u2500\u2500 config.json # Workspace settings
|
|
28
|
+
\u2502 \u2514\u2500\u2500 templates/ # Project templates
|
|
29
|
+
\u2514\u2500\u2500 README.md
|
|
111
30
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
31
|
+
${a.bold("\u{1F680} Get started:")}
|
|
32
|
+
${a.cyan(`cd ${t.name}`)}
|
|
33
|
+
${a.cyan('export PATH="$PWD:$PATH"')} ${a.gray("# Add rapidkit to PATH")}
|
|
34
|
+
${a.cyan("rapidkit create my-api --template fastapi")}
|
|
35
|
+
${a.cyan("cd my-api")}
|
|
36
|
+
${a.cyan("rapidkit dev")}
|
|
37
|
+
|
|
38
|
+
${a.bold("\u{1F4E6} Available templates:")}
|
|
39
|
+
fastapi - FastAPI + Python (default)
|
|
40
|
+
nestjs - NestJS + TypeScript
|
|
41
|
+
|
|
42
|
+
${a.bold("\u{1F4DA} Commands:")}
|
|
43
|
+
rapidkit create <name> Create a new project
|
|
44
|
+
rapidkit create --help Show create options
|
|
45
|
+
rapidkit help Show all commands
|
|
46
|
+
|
|
47
|
+
${a.gray("Tip: Add workspace to PATH for easier access:")}
|
|
48
|
+
${a.cyan(`echo 'export PATH="${e}:$PATH"' >> ~/.bashrc`)}
|
|
49
|
+
`);}catch(o){throw i.fail("Failed to create workspace"),o}}function re(){return `#!/usr/bin/env bash
|
|
50
|
+
#
|
|
51
|
+
# RapidKit CLI - Local workspace commands
|
|
52
|
+
# This script provides rapidkit commands within the workspace
|
|
53
|
+
#
|
|
54
|
+
|
|
55
|
+
set -e
|
|
56
|
+
|
|
57
|
+
# Find workspace root (where this script lives)
|
|
58
|
+
SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
59
|
+
|
|
60
|
+
# Check if we're in a project directory (has .rapidkit/project.json)
|
|
61
|
+
find_project_root() {
|
|
62
|
+
local dir="$PWD"
|
|
63
|
+
while [[ "$dir" != "/" ]]; do
|
|
64
|
+
if [[ -f "$dir/.rapidkit/project.json" ]]; then
|
|
65
|
+
echo "$dir"
|
|
66
|
+
return 0
|
|
67
|
+
fi
|
|
68
|
+
dir="$(dirname "$dir")"
|
|
69
|
+
done
|
|
70
|
+
return 1
|
|
146
71
|
}
|
|
147
72
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
73
|
+
# Check if we're in a workspace (has .rapidkit/config.json with type=workspace)
|
|
74
|
+
find_workspace_root() {
|
|
75
|
+
local dir="$PWD"
|
|
76
|
+
while [[ "$dir" != "/" ]]; do
|
|
77
|
+
if [[ -f "$dir/.rapidkit/config.json" ]]; then
|
|
78
|
+
if grep -q '"type": "workspace"' "$dir/.rapidkit/config.json" 2>/dev/null; then
|
|
79
|
+
echo "$dir"
|
|
80
|
+
return 0
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
dir="$(dirname "$dir")"
|
|
84
|
+
done
|
|
85
|
+
return 1
|
|
159
86
|
}
|
|
160
87
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const description = await ask('Description', 'FastAPI service generated with RapidKit');
|
|
175
|
-
|
|
176
|
-
rl.close();
|
|
177
|
-
|
|
178
|
-
// Create project structure
|
|
179
|
-
const dirs = [
|
|
180
|
-
'',
|
|
181
|
-
'src',
|
|
182
|
-
'src/routing',
|
|
183
|
-
'src/modules',
|
|
184
|
-
'tests',
|
|
185
|
-
'.rapidkit'
|
|
186
|
-
];
|
|
187
|
-
|
|
188
|
-
for (const dir of dirs) {
|
|
189
|
-
fs.mkdirSync(path.join(targetPath, dir), { recursive: true });
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Template files with content
|
|
193
|
-
const files = {
|
|
194
|
-
'src/__init__.py': '"""' + project_name + ' package."""\\n',
|
|
195
|
-
'src/modules/__init__.py': '"""Modules package."""\\n',
|
|
196
|
-
'tests/__init__.py': '"""Tests package."""\\n',
|
|
197
|
-
'src/main.py': \`"""\${project_name} application entrypoint."""
|
|
198
|
-
|
|
199
|
-
from __future__ import annotations
|
|
200
|
-
|
|
201
|
-
from contextlib import asynccontextmanager
|
|
202
|
-
from typing import AsyncIterator
|
|
203
|
-
|
|
204
|
-
from fastapi import FastAPI
|
|
205
|
-
from fastapi.middleware.cors import CORSMiddleware
|
|
206
|
-
|
|
207
|
-
from .routing import api_router
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
@asynccontextmanager
|
|
211
|
-
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|
212
|
-
"""Application lifespan context manager for startup/shutdown events."""
|
|
213
|
-
yield
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
app = FastAPI(
|
|
217
|
-
title="\${project_name}",
|
|
218
|
-
description="\${description}",
|
|
219
|
-
version="0.1.0",
|
|
220
|
-
docs_url="/docs",
|
|
221
|
-
redoc_url="/redoc",
|
|
222
|
-
lifespan=lifespan,
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
app.add_middleware(
|
|
226
|
-
CORSMiddleware,
|
|
227
|
-
allow_origins=["*"],
|
|
228
|
-
allow_credentials=True,
|
|
229
|
-
allow_methods=["*"],
|
|
230
|
-
allow_headers=["*"],
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
app.include_router(api_router, prefix="/api")
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if __name__ == "__main__":
|
|
237
|
-
import uvicorn
|
|
238
|
-
uvicorn.run("src.main:app", host="0.0.0.0", port=8001, reload=True)
|
|
239
|
-
\`,
|
|
240
|
-
'src/routing/__init__.py': \`"""API routing configuration."""
|
|
241
|
-
|
|
242
|
-
from fastapi import APIRouter
|
|
243
|
-
|
|
244
|
-
from .health import router as health_router
|
|
245
|
-
|
|
246
|
-
api_router = APIRouter()
|
|
247
|
-
|
|
248
|
-
api_router.include_router(health_router)
|
|
249
|
-
\`,
|
|
250
|
-
'src/routing/health.py': \`"""Health check endpoints."""
|
|
251
|
-
|
|
252
|
-
from __future__ import annotations
|
|
253
|
-
|
|
254
|
-
from fastapi import APIRouter
|
|
255
|
-
|
|
256
|
-
router = APIRouter(prefix="/health", tags=["health"])
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
@router.get("/", summary="Health check")
|
|
260
|
-
async def heartbeat() -> dict[str, str]:
|
|
261
|
-
"""Return basic service heartbeat."""
|
|
262
|
-
return {"status": "ok"}
|
|
263
|
-
\`,
|
|
264
|
-
'src/cli.py': \`"""CLI commands for \${project_name}."""
|
|
265
|
-
|
|
266
|
-
import subprocess
|
|
267
|
-
import sys
|
|
268
|
-
from pathlib import Path
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
def dev():
|
|
272
|
-
"""Start development server with hot reload."""
|
|
273
|
-
print("\u{1F680} Starting development server...")
|
|
274
|
-
subprocess.run([
|
|
275
|
-
sys.executable, "-m", "uvicorn",
|
|
276
|
-
"src.main:app", "--reload",
|
|
277
|
-
"--host", "0.0.0.0", "--port", "8000"
|
|
278
|
-
])
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def start():
|
|
282
|
-
"""Start production server."""
|
|
283
|
-
print("\u26A1 Starting production server...")
|
|
284
|
-
subprocess.run([
|
|
285
|
-
sys.executable, "-m", "uvicorn",
|
|
286
|
-
"src.main:app",
|
|
287
|
-
"--host", "0.0.0.0", "--port", "8000"
|
|
288
|
-
])
|
|
289
|
-
|
|
88
|
+
# Colors
|
|
89
|
+
RED='\\033[0;31m'
|
|
90
|
+
GREEN='\\033[0;32m'
|
|
91
|
+
YELLOW='\\033[0;33m'
|
|
92
|
+
BLUE='\\033[0;34m'
|
|
93
|
+
CYAN='\\033[0;36m'
|
|
94
|
+
NC='\\033[0m' # No Color
|
|
95
|
+
BOLD='\\033[1m'
|
|
96
|
+
|
|
97
|
+
print_banner() {
|
|
98
|
+
echo -e "\${BLUE}\${BOLD}\u{1F680} RapidKit CLI\${NC}"
|
|
99
|
+
echo ""
|
|
100
|
+
}
|
|
290
101
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
102
|
+
print_help() {
|
|
103
|
+
print_banner
|
|
104
|
+
echo -e "\${BOLD}Usage:\${NC} rapidkit <command> [options]"
|
|
105
|
+
echo ""
|
|
106
|
+
echo -e "\${BOLD}\u{1F3D7}\uFE0F Workspace Commands:\${NC}"
|
|
107
|
+
echo " create <name> Create a new project from template"
|
|
108
|
+
echo " create --help Show create command options"
|
|
109
|
+
echo ""
|
|
110
|
+
echo -e "\${BOLD}\u{1F680} Project Commands\${NC} (run inside a project):"
|
|
111
|
+
echo " init Install project dependencies"
|
|
112
|
+
echo " dev Start development server"
|
|
113
|
+
echo " start Start production server"
|
|
114
|
+
echo " build Build for production"
|
|
115
|
+
echo " test Run tests"
|
|
116
|
+
echo " lint Run linting"
|
|
117
|
+
echo " format Format code"
|
|
118
|
+
echo ""
|
|
119
|
+
echo -e "\${BOLD}\u{1F4DA} Other Commands:\${NC}"
|
|
120
|
+
echo " help Show this help message"
|
|
121
|
+
echo " version Show version"
|
|
122
|
+
echo ""
|
|
123
|
+
echo -e "\${BOLD}Examples:\${NC}"
|
|
124
|
+
echo -e " \${CYAN}rapidkit create my-api --template fastapi\${NC}"
|
|
125
|
+
echo -e " \${CYAN}rapidkit create my-app --template nestjs --yes\${NC}"
|
|
126
|
+
echo -e " \${CYAN}cd my-api && rapidkit dev\${NC}"
|
|
127
|
+
echo ""
|
|
128
|
+
}
|
|
295
129
|
|
|
130
|
+
print_create_help() {
|
|
131
|
+
print_banner
|
|
132
|
+
echo -e "\${BOLD}Usage:\${NC} rapidkit create <project-name> [options]"
|
|
133
|
+
echo ""
|
|
134
|
+
echo -e "\${BOLD}Options:\${NC}"
|
|
135
|
+
echo " -t, --template <name> Template to use (fastapi, nestjs)"
|
|
136
|
+
echo " -y, --yes Skip prompts, use defaults"
|
|
137
|
+
echo " --skip-git Skip git initialization"
|
|
138
|
+
echo " --skip-install Skip dependency installation"
|
|
139
|
+
echo ""
|
|
140
|
+
echo -e "\${BOLD}Templates:\${NC}"
|
|
141
|
+
echo " fastapi FastAPI + Python (default)"
|
|
142
|
+
echo " nestjs NestJS + TypeScript"
|
|
143
|
+
echo ""
|
|
144
|
+
echo -e "\${BOLD}Examples:\${NC}"
|
|
145
|
+
echo -e " \${CYAN}rapidkit create my-api\${NC}"
|
|
146
|
+
echo -e " \${CYAN}rapidkit create my-api --template fastapi\${NC}"
|
|
147
|
+
echo -e " \${CYAN}rapidkit create my-app --template nestjs --yes\${NC}"
|
|
148
|
+
echo ""
|
|
149
|
+
}
|
|
296
150
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
151
|
+
# Create project command
|
|
152
|
+
cmd_create() {
|
|
153
|
+
local project_name=""
|
|
154
|
+
local template="fastapi"
|
|
155
|
+
local yes_flag=""
|
|
156
|
+
local skip_git=""
|
|
157
|
+
local skip_install=""
|
|
158
|
+
|
|
159
|
+
# Parse arguments
|
|
160
|
+
while [[ $# -gt 0 ]]; do
|
|
161
|
+
case "$1" in
|
|
162
|
+
-h|--help)
|
|
163
|
+
print_create_help
|
|
164
|
+
exit 0
|
|
165
|
+
;;
|
|
166
|
+
-t|--template)
|
|
167
|
+
template="$2"
|
|
168
|
+
shift 2
|
|
169
|
+
;;
|
|
170
|
+
-y|--yes)
|
|
171
|
+
yes_flag="--yes"
|
|
172
|
+
shift
|
|
173
|
+
;;
|
|
174
|
+
--skip-git)
|
|
175
|
+
skip_git="--skip-git"
|
|
176
|
+
shift
|
|
177
|
+
;;
|
|
178
|
+
--skip-install)
|
|
179
|
+
skip_install="--skip-install"
|
|
180
|
+
shift
|
|
181
|
+
;;
|
|
182
|
+
-*)
|
|
183
|
+
echo -e "\${RED}\u274C Unknown option: $1\${NC}"
|
|
184
|
+
print_create_help
|
|
185
|
+
exit 1
|
|
186
|
+
;;
|
|
187
|
+
*)
|
|
188
|
+
if [[ -z "$project_name" ]]; then
|
|
189
|
+
project_name="$1"
|
|
190
|
+
fi
|
|
191
|
+
shift
|
|
192
|
+
;;
|
|
193
|
+
esac
|
|
194
|
+
done
|
|
195
|
+
|
|
196
|
+
# Validate template
|
|
197
|
+
if [[ "$template" != "fastapi" && "$template" != "nestjs" ]]; then
|
|
198
|
+
echo -e "\${RED}\u274C Invalid template: $template\${NC}"
|
|
199
|
+
echo -e "Available templates: fastapi, nestjs"
|
|
200
|
+
exit 1
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# If no project name, prompt for it or show help
|
|
204
|
+
if [[ -z "$project_name" ]]; then
|
|
205
|
+
if [[ -n "$yes_flag" ]]; then
|
|
206
|
+
project_name="my-\${template}-project"
|
|
207
|
+
else
|
|
208
|
+
echo -e "\${YELLOW}Project name required\${NC}"
|
|
209
|
+
echo ""
|
|
210
|
+
print_create_help
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# Find workspace root
|
|
216
|
+
local workspace_root
|
|
217
|
+
workspace_root=$(find_workspace_root) || {
|
|
218
|
+
echo -e "\${RED}\u274C Not in a RapidKit workspace\${NC}"
|
|
219
|
+
echo -e "Run this command from within a RapidKit workspace."
|
|
220
|
+
exit 1
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
local project_path="$PWD/$project_name"
|
|
224
|
+
|
|
225
|
+
# Check if project already exists
|
|
226
|
+
if [[ -d "$project_path" ]]; then
|
|
227
|
+
echo -e "\${RED}\u274C Directory '$project_name' already exists\${NC}"
|
|
228
|
+
exit 1
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
echo -e "\${BLUE}\${BOLD}\u{1F680} Creating $template project: $project_name\${NC}"
|
|
232
|
+
echo ""
|
|
233
|
+
|
|
234
|
+
# Use Node.js generator script
|
|
235
|
+
local generator_script="$workspace_root/.rapidkit/generator.js"
|
|
302
236
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
else:
|
|
311
|
-
print(f"Unknown command: {cmd}")
|
|
312
|
-
sys.exit(1)
|
|
313
|
-
\`,
|
|
314
|
-
'pyproject.toml': \`[tool.poetry]
|
|
315
|
-
name = "\${project_name}"
|
|
316
|
-
version = "0.1.0"
|
|
317
|
-
description = "\${description}"
|
|
318
|
-
authors = ["\${author}"]
|
|
319
|
-
license = "MIT"
|
|
320
|
-
readme = "README.md"
|
|
321
|
-
package-mode = false
|
|
322
|
-
|
|
323
|
-
[tool.poetry.dependencies]
|
|
324
|
-
python = "^3.11"
|
|
325
|
-
fastapi = "^0.115.0"
|
|
326
|
-
uvicorn = {extras = ["standard"], version = "^0.32.0"}
|
|
327
|
-
pydantic = "^2.0"
|
|
328
|
-
pydantic-settings = "^2.0"
|
|
329
|
-
|
|
330
|
-
[tool.poetry.group.dev.dependencies]
|
|
331
|
-
pytest = "^8.0"
|
|
332
|
-
pytest-asyncio = "^0.24.0"
|
|
333
|
-
pytest-cov = "^6.0"
|
|
334
|
-
httpx = "^0.27"
|
|
335
|
-
black = "^24.0"
|
|
336
|
-
ruff = "^0.8"
|
|
337
|
-
mypy = "^1.0"
|
|
338
|
-
|
|
339
|
-
[tool.poetry.scripts]
|
|
340
|
-
dev = "src.cli:dev"
|
|
341
|
-
start = "src.cli:start"
|
|
342
|
-
test = "src.cli:test"
|
|
343
|
-
|
|
344
|
-
[build-system]
|
|
345
|
-
requires = ["poetry-core"]
|
|
346
|
-
build-backend = "poetry.core.masonry.api"
|
|
347
|
-
|
|
348
|
-
[tool.pytest.ini_options]
|
|
349
|
-
asyncio_mode = "auto"
|
|
350
|
-
testpaths = ["tests"]
|
|
351
|
-
|
|
352
|
-
[tool.ruff]
|
|
353
|
-
line-length = 100
|
|
354
|
-
target-version = "py311"
|
|
355
|
-
|
|
356
|
-
[tool.black]
|
|
357
|
-
line-length = 100
|
|
358
|
-
target-version = ["py311"]
|
|
359
|
-
\`,
|
|
360
|
-
'README.md': \`# \${project_name}
|
|
361
|
-
|
|
362
|
-
\${description}
|
|
363
|
-
|
|
364
|
-
## Quick start
|
|
365
|
-
|
|
366
|
-
\\\`\\\`\\\`bash
|
|
367
|
-
rapidkit init # Install dependencies
|
|
368
|
-
rapidkit dev # Start dev server
|
|
369
|
-
\\\`\\\`\\\`
|
|
370
|
-
|
|
371
|
-
## Available commands
|
|
372
|
-
|
|
373
|
-
\\\`\\\`\\\`bash
|
|
374
|
-
rapidkit init # \u{1F527} Install dependencies
|
|
375
|
-
rapidkit dev # \u{1F680} Start development server with hot reload
|
|
376
|
-
rapidkit start # \u26A1 Start production server
|
|
377
|
-
rapidkit test # \u{1F9EA} Run tests
|
|
378
|
-
rapidkit help # \u{1F4DA} Show available commands
|
|
379
|
-
\\\`\\\`\\\`
|
|
380
|
-
|
|
381
|
-
## Project layout
|
|
382
|
-
|
|
383
|
-
\\\`\\\`\\\`
|
|
384
|
-
\${project_name}/
|
|
385
|
-
\u251C\u2500\u2500 src/
|
|
386
|
-
\u2502 \u251C\u2500\u2500 main.py # FastAPI application
|
|
387
|
-
\u2502 \u251C\u2500\u2500 cli.py # CLI commands
|
|
388
|
-
\u2502 \u251C\u2500\u2500 routing/ # API routes
|
|
389
|
-
\u2502 \u2514\u2500\u2500 modules/ # Module system
|
|
390
|
-
\u251C\u2500\u2500 tests/ # Test suite
|
|
391
|
-
\u251C\u2500\u2500 pyproject.toml # Poetry configuration
|
|
392
|
-
\u2514\u2500\u2500 README.md
|
|
393
|
-
\\\`\\\`\\\`
|
|
394
|
-
\`,
|
|
395
|
-
'.rapidkit/project.json': JSON.stringify({
|
|
396
|
-
kit_name: "fastapi.standard",
|
|
397
|
-
profile: "fastapi/standard",
|
|
398
|
-
created_at: new Date().toISOString(),
|
|
399
|
-
rapidkit_version: "npm-demo"
|
|
400
|
-
}, null, 2),
|
|
401
|
-
'.rapidkit/cli.py': \`#!/usr/bin/env python3
|
|
402
|
-
"""RapidKit CLI wrapper for demo projects."""
|
|
403
|
-
|
|
404
|
-
import subprocess
|
|
405
|
-
import sys
|
|
406
|
-
from pathlib import Path
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
def dev(port=8000, host="0.0.0.0"):
|
|
410
|
-
"""Start development server."""
|
|
411
|
-
print("\u{1F680} Starting development server with hot reload...")
|
|
412
|
-
subprocess.run([
|
|
413
|
-
sys.executable, "-m", "uvicorn",
|
|
414
|
-
"src.main:app", "--reload",
|
|
415
|
-
"--host", host, "--port", str(port)
|
|
416
|
-
])
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
def start(port=8000, host="0.0.0.0"):
|
|
420
|
-
"""Start production server."""
|
|
421
|
-
print("\u26A1 Starting production server...")
|
|
422
|
-
subprocess.run([
|
|
423
|
-
sys.executable, "-m", "uvicorn",
|
|
424
|
-
"src.main:app",
|
|
425
|
-
"--host", host, "--port", str(port)
|
|
426
|
-
])
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
def init():
|
|
430
|
-
"""Install dependencies."""
|
|
431
|
-
print("\u{1F4E6} Installing dependencies...")
|
|
432
|
-
subprocess.run(["poetry", "install"])
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
def test():
|
|
436
|
-
"""Run tests."""
|
|
437
|
-
print("\u{1F9EA} Running tests...")
|
|
438
|
-
subprocess.run([sys.executable, "-m", "pytest", "-q"])
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
def help_cmd():
|
|
442
|
-
"""Show help."""
|
|
443
|
-
print("\u{1F4DA} Available commands:")
|
|
444
|
-
print(" init - Install dependencies")
|
|
445
|
-
print(" dev - Start dev server")
|
|
446
|
-
print(" start - Start production server")
|
|
447
|
-
print(" test - Run tests")
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if __name__ == "__main__":
|
|
451
|
-
cmd = sys.argv[1] if len(sys.argv) > 1 else "help"
|
|
452
|
-
cmds = {"dev": dev, "start": start, "init": init, "test": test, "help": help_cmd}
|
|
453
|
-
cmds.get(cmd, help_cmd)()
|
|
454
|
-
\`,
|
|
455
|
-
'.rapidkit/rapidkit': '#!/usr/bin/env bash\\n# Local RapidKit launcher for demo projects\\nset -euo pipefail\\nSCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"\\nROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"\\ncd "$ROOT_DIR"\\n\\nif [ -f "pyproject.toml" ]; then\\n if command -v poetry >/dev/null 2>&1; then\\n exec poetry run python "$SCRIPT_DIR/cli.py" "$@"\\n fi\\nfi\\n\\necho "Poetry not found. Install with: pip install poetry"\\nexit 1\\n',
|
|
456
|
-
'.gitignore': \`# Python
|
|
457
|
-
__pycache__/
|
|
458
|
-
*.py[cod]
|
|
459
|
-
*.so
|
|
460
|
-
.Python
|
|
461
|
-
build/
|
|
462
|
-
dist/
|
|
463
|
-
*.egg-info/
|
|
464
|
-
|
|
465
|
-
# Virtual environments
|
|
466
|
-
.venv/
|
|
467
|
-
venv/
|
|
468
|
-
|
|
469
|
-
# IDEs
|
|
470
|
-
.vscode/
|
|
471
|
-
.idea/
|
|
472
|
-
|
|
473
|
-
# OS
|
|
474
|
-
.DS_Store
|
|
237
|
+
if [[ -f "$generator_script" ]]; then
|
|
238
|
+
node "$generator_script" "$project_path" "$template" "$yes_flag" "$skip_git" "$skip_install"
|
|
239
|
+
else
|
|
240
|
+
echo -e "\${RED}\u274C Generator script not found\${NC}"
|
|
241
|
+
exit 1
|
|
242
|
+
fi
|
|
243
|
+
}
|
|
475
244
|
|
|
476
|
-
# Project
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
245
|
+
# Project commands (dev, build, test, etc.)
|
|
246
|
+
cmd_project() {
|
|
247
|
+
local cmd="$1"
|
|
248
|
+
shift
|
|
249
|
+
|
|
250
|
+
# Find project root
|
|
251
|
+
local project_root
|
|
252
|
+
project_root=$(find_project_root) || {
|
|
253
|
+
echo -e "\${RED}\u274C Not in a RapidKit project\${NC}"
|
|
254
|
+
echo -e "Run this command from within a project directory."
|
|
255
|
+
echo -e "Use \${CYAN}rapidkit create <name>\${NC} to create a new project."
|
|
256
|
+
exit 1
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Read project type from project.json
|
|
260
|
+
local project_json="$project_root/.rapidkit/project.json"
|
|
261
|
+
local kit_name
|
|
262
|
+
kit_name=$(grep -o '"kit_name": *"[^"]*"' "$project_json" | cut -d'"' -f4)
|
|
263
|
+
|
|
264
|
+
cd "$project_root"
|
|
265
|
+
|
|
266
|
+
case "$kit_name" in
|
|
267
|
+
fastapi.standard|python)
|
|
268
|
+
# Python/FastAPI project
|
|
269
|
+
case "$cmd" in
|
|
270
|
+
init)
|
|
271
|
+
echo -e "\${BLUE}\u{1F4E6} Installing dependencies...\${NC}"
|
|
272
|
+
poetry install
|
|
273
|
+
echo -e "\${GREEN}\u2705 Dependencies installed!\${NC}"
|
|
274
|
+
;;
|
|
275
|
+
dev)
|
|
276
|
+
echo -e "\${BLUE}\u{1F680} Starting development server...\${NC}"
|
|
277
|
+
poetry run dev "$@"
|
|
278
|
+
;;
|
|
279
|
+
start)
|
|
280
|
+
echo -e "\${BLUE}\u26A1 Starting production server...\${NC}"
|
|
281
|
+
poetry run start "$@"
|
|
282
|
+
;;
|
|
283
|
+
build)
|
|
284
|
+
echo -e "\${BLUE}\u{1F4E6} Building project...\${NC}"
|
|
285
|
+
poetry run build
|
|
286
|
+
;;
|
|
287
|
+
test)
|
|
288
|
+
echo -e "\${BLUE}\u{1F9EA} Running tests...\${NC}"
|
|
289
|
+
poetry run test
|
|
290
|
+
;;
|
|
291
|
+
lint)
|
|
292
|
+
echo -e "\${BLUE}\u{1F527} Running linter...\${NC}"
|
|
293
|
+
poetry run lint
|
|
294
|
+
;;
|
|
295
|
+
format)
|
|
296
|
+
echo -e "\${BLUE}\u2728 Formatting code...\${NC}"
|
|
297
|
+
poetry run format
|
|
298
|
+
;;
|
|
299
|
+
*)
|
|
300
|
+
echo -e "\${RED}\u274C Unknown command: $cmd\${NC}"
|
|
301
|
+
exit 1
|
|
302
|
+
;;
|
|
303
|
+
esac
|
|
304
|
+
;;
|
|
305
|
+
nestjs.standard|node)
|
|
306
|
+
# Node/NestJS project
|
|
307
|
+
local pm="npm"
|
|
308
|
+
if command -v pnpm &>/dev/null && [[ -f "pnpm-lock.yaml" ]]; then
|
|
309
|
+
pm="pnpm"
|
|
310
|
+
elif command -v yarn &>/dev/null && [[ -f "yarn.lock" ]]; then
|
|
311
|
+
pm="yarn"
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
case "$cmd" in
|
|
315
|
+
init)
|
|
316
|
+
echo -e "\${BLUE}\u{1F4E6} Installing dependencies...\${NC}"
|
|
317
|
+
$pm install
|
|
318
|
+
echo -e "\${GREEN}\u2705 Dependencies installed!\${NC}"
|
|
319
|
+
;;
|
|
320
|
+
dev)
|
|
321
|
+
echo -e "\${BLUE}\u{1F680} Starting development server...\${NC}"
|
|
322
|
+
$pm run start:dev
|
|
323
|
+
;;
|
|
324
|
+
start)
|
|
325
|
+
echo -e "\${BLUE}\u26A1 Starting production server...\${NC}"
|
|
326
|
+
$pm run start:prod
|
|
327
|
+
;;
|
|
328
|
+
build)
|
|
329
|
+
echo -e "\${BLUE}\u{1F4E6} Building project...\${NC}"
|
|
330
|
+
$pm run build
|
|
331
|
+
;;
|
|
332
|
+
test)
|
|
333
|
+
echo -e "\${BLUE}\u{1F9EA} Running tests...\${NC}"
|
|
334
|
+
$pm test
|
|
335
|
+
;;
|
|
336
|
+
lint)
|
|
337
|
+
echo -e "\${BLUE}\u{1F527} Running linter...\${NC}"
|
|
338
|
+
$pm run lint
|
|
339
|
+
;;
|
|
340
|
+
format)
|
|
341
|
+
echo -e "\${BLUE}\u2728 Formatting code...\${NC}"
|
|
342
|
+
$pm run format
|
|
343
|
+
;;
|
|
344
|
+
*)
|
|
345
|
+
echo -e "\${RED}\u274C Unknown command: $cmd\${NC}"
|
|
346
|
+
exit 1
|
|
347
|
+
;;
|
|
348
|
+
esac
|
|
349
|
+
;;
|
|
350
|
+
*)
|
|
351
|
+
echo -e "\${RED}\u274C Unknown project type: $kit_name\${NC}"
|
|
352
|
+
exit 1
|
|
353
|
+
;;
|
|
354
|
+
esac
|
|
513
355
|
}
|
|
514
356
|
|
|
515
|
-
|
|
516
|
-
|
|
357
|
+
# Main command handler
|
|
358
|
+
main() {
|
|
359
|
+
local cmd="\${1:-help}"
|
|
360
|
+
shift || true
|
|
361
|
+
|
|
362
|
+
case "$cmd" in
|
|
363
|
+
create)
|
|
364
|
+
cmd_create "$@"
|
|
365
|
+
;;
|
|
366
|
+
init|dev|start|build|test|lint|format)
|
|
367
|
+
cmd_project "$cmd" "$@"
|
|
368
|
+
;;
|
|
369
|
+
help|-h|--help)
|
|
370
|
+
print_help
|
|
371
|
+
;;
|
|
372
|
+
version|-v|--version)
|
|
373
|
+
echo "RapidKit CLI (npm workspace) v${w()}"
|
|
374
|
+
;;
|
|
375
|
+
*)
|
|
376
|
+
echo -e "\${RED}\u274C Unknown command: $cmd\${NC}"
|
|
377
|
+
echo ""
|
|
378
|
+
print_help
|
|
379
|
+
exit 1
|
|
380
|
+
;;
|
|
381
|
+
esac
|
|
382
|
+
}
|
|
517
383
|
|
|
518
|
-
|
|
384
|
+
main "$@"
|
|
385
|
+
`}function oe(e){return `# ${e}
|
|
519
386
|
|
|
520
|
-
|
|
387
|
+
RapidKit workspace for building API projects.
|
|
521
388
|
|
|
522
|
-
|
|
389
|
+
## Quick Start
|
|
523
390
|
|
|
524
391
|
\`\`\`bash
|
|
525
|
-
#
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
# Navigate to the project:
|
|
529
|
-
cd my-api
|
|
392
|
+
# Add rapidkit to PATH (or use ./rapidkit)
|
|
393
|
+
export PATH="$PWD:$PATH"
|
|
530
394
|
|
|
531
|
-
#
|
|
532
|
-
rapidkit
|
|
395
|
+
# Create a FastAPI project
|
|
396
|
+
rapidkit create my-api --template fastapi
|
|
533
397
|
|
|
534
|
-
#
|
|
535
|
-
rapidkit
|
|
536
|
-
\`\`\`
|
|
398
|
+
# Or create a NestJS project
|
|
399
|
+
rapidkit create my-app --template nestjs
|
|
537
400
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
You can create multiple demo projects in this workspace:
|
|
543
|
-
|
|
544
|
-
\`\`\`bash
|
|
545
|
-
node generate-demo.js api-service
|
|
546
|
-
node generate-demo.js auth-service
|
|
547
|
-
node generate-demo.js data-service
|
|
401
|
+
# Enter project and start development
|
|
402
|
+
cd my-api
|
|
403
|
+
rapidkit init # Install dependencies
|
|
404
|
+
rapidkit dev # Start dev server
|
|
548
405
|
\`\`\`
|
|
549
406
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
## \u{1F3AF} What's Included
|
|
553
|
-
|
|
554
|
-
Each generated demo project contains:
|
|
555
|
-
|
|
556
|
-
- **FastAPI Application** - Modern async web framework
|
|
557
|
-
- **Routing System** - Organized API routes
|
|
558
|
-
- **Module System** - Extensible module architecture
|
|
559
|
-
- **CLI Commands** - Built-in command system
|
|
560
|
-
- **Testing Setup** - pytest configuration
|
|
561
|
-
- **Poetry Configuration** - Dependency management
|
|
407
|
+
## Available Templates
|
|
562
408
|
|
|
563
|
-
|
|
409
|
+
| Template | Stack | Description |
|
|
410
|
+
|----------|-------|-------------|
|
|
411
|
+
| \`fastapi\` | Python + FastAPI | High-performance Python API |
|
|
412
|
+
| \`nestjs\` | TypeScript + NestJS | Enterprise Node.js framework |
|
|
564
413
|
|
|
565
|
-
|
|
566
|
-
2. **Add Routes** - Create new endpoints in \`src/routing/\`
|
|
567
|
-
3. **Install Full RapidKit** - For advanced features: \`pipx install rapidkit\`
|
|
568
|
-
4. **Read the Documentation** - Visit [RapidKit Docs](https://rapidkit.top)
|
|
414
|
+
## Commands
|
|
569
415
|
|
|
570
|
-
|
|
416
|
+
### Workspace Commands
|
|
571
417
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
418
|
+
| Command | Description |
|
|
419
|
+
|---------|-------------|
|
|
420
|
+
| \`rapidkit create <name>\` | Create a new project |
|
|
421
|
+
| \`rapidkit create --help\` | Show create options |
|
|
422
|
+
| \`rapidkit help\` | Show all commands |
|
|
577
423
|
|
|
578
|
-
|
|
424
|
+
### Project Commands (run inside a project)
|
|
579
425
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
\u251C\u2500\u2500 README.md # This file
|
|
590
|
-
\u2514\u2500\u2500 my-api/ # Your generated projects go here
|
|
591
|
-
\`\`\`
|
|
592
|
-
|
|
593
|
-
## \u{1F4A1} Tips
|
|
594
|
-
|
|
595
|
-
- Run \`node generate-demo.js --help\` for more options (coming soon)
|
|
596
|
-
- Each project can have different configurations
|
|
597
|
-
- Demo projects are production-ready FastAPI applications
|
|
598
|
-
- You can copy and modify templates as needed
|
|
426
|
+
| Command | Description |
|
|
427
|
+
|---------|-------------|
|
|
428
|
+
| \`rapidkit init\` | Install dependencies |
|
|
429
|
+
| \`rapidkit dev\` | Start development server |
|
|
430
|
+
| \`rapidkit start\` | Start production server |
|
|
431
|
+
| \`rapidkit build\` | Build for production |
|
|
432
|
+
| \`rapidkit test\` | Run tests |
|
|
433
|
+
| \`rapidkit lint\` | Run linting |
|
|
434
|
+
| \`rapidkit format\` | Format code |
|
|
599
435
|
|
|
600
|
-
|
|
436
|
+
## Learn More
|
|
601
437
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
# Generated projects
|
|
607
|
-
*/
|
|
608
|
-
!generate-demo.js
|
|
609
|
-
!README.md
|
|
610
|
-
|
|
611
|
-
# Python
|
|
612
|
-
__pycache__/
|
|
613
|
-
*.pyc
|
|
614
|
-
.venv/
|
|
615
|
-
.env
|
|
616
|
-
`,"utf-8"),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","Initial commit: Demo workspace"],{cwd:t}),r.succeed("Git repository initialized");}catch{r.warn("Could not initialize git repository");}}console.log(i.green(`
|
|
617
|
-
\u2728 Demo workspace created successfully!
|
|
618
|
-
`)),console.log(i.cyan("\u{1F4C2} Location:"),i.white(t)),console.log(i.cyan(`\u{1F680} Get started:
|
|
619
|
-
`)),console.log(i.white(` cd ${e}`)),console.log(i.white(" node generate-demo.js my-api")),console.log(i.white(" cd my-api")),console.log(i.white(" rapidkit init")),console.log(i.white(" rapidkit dev")),console.log(),console.log(i.yellow("\u{1F4A1} Note:"),"This is a demo workspace. For full RapidKit features:"),console.log(i.cyan(" pipx install rapidkit")),console.log();}catch(a){throw r.fail("Failed to create demo workspace"),a}}async function ce(t,e,o,r){console.log(i.cyan(`
|
|
620
|
-
\u{1F50D} Dry-run mode - showing what would be created:
|
|
621
|
-
`)),console.log(i.white("\u{1F4C2} Project path:"),t),console.log(i.white("\u{1F4E6} Project type:"),o?"Demo workspace":"Full RapidKit environment"),o?(console.log(i.white(`
|
|
622
|
-
\u{1F4DD} Files to create:`)),console.log(i.gray(" - package.json")),console.log(i.gray(" - generate-demo.js (project generator)")),console.log(i.gray(" - README.md")),console.log(i.gray(" - .gitignore")),console.log(i.white(`
|
|
623
|
-
\u{1F3AF} Capabilities:`)),console.log(i.gray(" - Generate multiple FastAPI demo projects")),console.log(i.gray(" - No Python RapidKit installation required")),console.log(i.gray(" - Bundled templates included"))):(console.log(i.white(`
|
|
624
|
-
\u2699\uFE0F Configuration:`)),console.log(i.gray(` - Python version: ${r.pythonVersion||"3.11"}`)),console.log(i.gray(` - Install method: ${r.defaultInstallMethod||"poetry"}`)),console.log(i.gray(` - Git initialization: ${r.skipGit?"No":"Yes"}`)),console.log(i.white(`
|
|
625
|
-
\u{1F4DD} Files to create:`)),console.log(i.gray(" - pyproject.toml (Poetry) or .venv/ (venv)")),console.log(i.gray(" - README.md")),console.log(i.gray(" - .gitignore")),console.log(i.white(`
|
|
626
|
-
\u{1F3AF} Next steps after creation:`)),console.log(i.gray(" 1. Install RapidKit Python package")),console.log(i.gray(" 2. Create projects with rapidkit CLI")),console.log(i.gray(" 3. Add modules and customize"))),console.log(i.white(`
|
|
627
|
-
\u{1F4A1} To proceed with actual creation, run without --dry-run flag
|
|
628
|
-
`));}var me=fileURLToPath(import.meta.url),ue=h.dirname(me);async function q(t,e){let o=z("Generating FastAPI demo project...").start();try{let r=h.resolve(ue,".."),a=h.join(r,"templates","kits","fastapi-standard"),m=le.configure(a,{autoescape:!1,trimBlocks:!0,lstripBlocks:!0}),d={project_name:e.project_name,author:e.author||"RapidKit User",description:e.description||"FastAPI service generated with RapidKit",app_version:e.app_version||"0.1.0",license:e.license||"MIT"},n=["src/main.py.j2","src/__init__.py.j2","src/cli.py.j2","src/routing/__init__.py.j2","src/routing/health.py.j2","src/modules/__init__.py.j2","tests/__init__.py.j2","README.md.j2","pyproject.toml.j2",".rapidkit/project.json.j2",".rapidkit/cli.py.j2",".rapidkit/rapidkit.j2"];for(let f of n){let g=h.join(a,f),v=await promises.readFile(g,"utf-8"),K=m.renderString(v,d),b=f.replace(/\.j2$/,""),D=h.join(t,b);await promises.mkdir(h.dirname(D),{recursive:!0}),await promises.writeFile(D,K),(b===".rapidkit/rapidkit"||b===".rapidkit/cli.py")&&await promises.chmod(D,493);}await promises.writeFile(h.join(t,".gitignore"),`# Python
|
|
438
|
+
- [RapidKit Documentation](https://rapidkit.dev)
|
|
439
|
+
- [GitHub Repository](https://github.com/Baziar/rapidkit)
|
|
440
|
+
`}async function ne(e){let{fileURLToPath:t}=await import('url'),i=t(import.meta.url),o=l.dirname(i),n=l.resolve(o,".."),s=l.join(n,"templates","kits"),p=l.join(e,".rapidkit","templates"),{default:d}=await import('fs-extra');await d.copy(s,p);let g=l.join(n,"templates","generator.js"),j=l.join(e,".rapidkit","generator.js");await d.copy(g,j);}async function B(e,t){let i=t.template==="fastapi",o=i?"FastAPI":"NestJS",n=N(`Creating ${o} project...`).start();try{let{fileURLToPath:s}=await import('url'),p=s(import.meta.url),d=l.dirname(p),g=l.resolve(d,".."),j=i?"fastapi-standard":"nestjs-standard",C=l.join(g,"templates","kits",j);await promises.mkdir(e,{recursive:!0});let _={project_name:i?t.name.replace(/-/g,"_").toLowerCase():t.name.replace(/_/g,"-").toLowerCase(),author:t.author,description:t.description||`${o} application generated with RapidKit`,app_version:"0.1.0",license:"MIT",package_manager:t.package_manager||"npm",created_at:new Date().toISOString(),rapidkit_version:w()};await K(C,e,_);let G=i?`# Python
|
|
629
441
|
__pycache__/
|
|
630
442
|
*.py[cod]
|
|
631
443
|
*$py.class
|
|
@@ -667,15 +479,38 @@ Thumbs.db
|
|
|
667
479
|
# Project specific
|
|
668
480
|
.env
|
|
669
481
|
.env.local
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
482
|
+
`:`# Node artifacts
|
|
483
|
+
node_modules/
|
|
484
|
+
dist/
|
|
485
|
+
.tmp/
|
|
486
|
+
.env
|
|
487
|
+
.env.*
|
|
488
|
+
!.env.example
|
|
489
|
+
|
|
490
|
+
# Logs
|
|
491
|
+
logs/
|
|
492
|
+
*.log
|
|
493
|
+
npm-debug.log*
|
|
494
|
+
yarn-debug.log*
|
|
495
|
+
yarn-error.log*
|
|
496
|
+
pnpm-debug.log*
|
|
497
|
+
|
|
498
|
+
# OS
|
|
499
|
+
.DS_Store
|
|
500
|
+
Thumbs.db
|
|
501
|
+
|
|
502
|
+
# IDEs
|
|
503
|
+
.idea/
|
|
504
|
+
.vscode/
|
|
505
|
+
|
|
506
|
+
# Coverage
|
|
507
|
+
coverage/
|
|
508
|
+
`;if(await promises.writeFile(l.join(e,".gitignore"),G),n.succeed(`${o} project created!`),!t.skipGit){let y=N("Initializing git repository...").start();try{await execa("git",["init"],{cwd:e}),await execa("git",["add","."],{cwd:e}),await execa("git",["commit","-m",`Initial commit: ${o} project via RapidKit`],{cwd:e}),y.succeed("Git repository initialized");}catch{y.warn("Could not initialize git repository");}}if(!t.skipInstall&&!i){let y=t.package_manager||"npm",D=N(`Installing dependencies with ${y}...`).start();try{await execa(y,["install"],{cwd:e}),D.succeed("Dependencies installed");}catch{D.warn(`Could not install dependencies. Run '${y} install' manually.`);}}let A=l.basename(e);console.log(i?`
|
|
509
|
+
${a.green("\u2728 FastAPI project created successfully!")}
|
|
510
|
+
|
|
511
|
+
${a.bold("\u{1F4C2} Project structure:")}
|
|
512
|
+
${e}/
|
|
513
|
+
\u251C\u2500\u2500 .rapidkit/ # RapidKit CLI module
|
|
679
514
|
\u251C\u2500\u2500 src/
|
|
680
515
|
\u2502 \u251C\u2500\u2500 main.py # FastAPI application
|
|
681
516
|
\u2502 \u251C\u2500\u2500 cli.py # CLI commands
|
|
@@ -685,44 +520,76 @@ ${t}/
|
|
|
685
520
|
\u251C\u2500\u2500 pyproject.toml # Poetry configuration
|
|
686
521
|
\u2514\u2500\u2500 README.md
|
|
687
522
|
|
|
688
|
-
${
|
|
689
|
-
cd ${
|
|
690
|
-
|
|
691
|
-
rapidkit
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
rapidkit
|
|
696
|
-
rapidkit
|
|
697
|
-
rapidkit
|
|
698
|
-
rapidkit
|
|
699
|
-
rapidkit
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
523
|
+
${a.bold("\u{1F680} Get started:")}
|
|
524
|
+
${a.cyan(`cd ${A}`)}
|
|
525
|
+
${a.cyan("source .rapidkit/activate")} ${a.gray("# Enable rapidkit commands")}
|
|
526
|
+
${a.cyan("rapidkit init")} ${a.gray("# Install dependencies")}
|
|
527
|
+
${a.cyan("rapidkit dev")} ${a.gray("# Start dev server")}
|
|
528
|
+
|
|
529
|
+
${a.bold("\u{1F4DA} Available commands:")}
|
|
530
|
+
rapidkit init # Install dependencies (poetry install)
|
|
531
|
+
rapidkit dev # Start dev server with hot reload
|
|
532
|
+
rapidkit start # Start production server
|
|
533
|
+
rapidkit test # Run tests
|
|
534
|
+
rapidkit lint # Lint code
|
|
535
|
+
rapidkit format # Format code
|
|
536
|
+
|
|
537
|
+
${a.gray("Alternative: use make commands (make dev, make test, ...)")}
|
|
538
|
+
`:`
|
|
539
|
+
${a.green("\u2728 NestJS project created successfully!")}
|
|
540
|
+
|
|
541
|
+
${a.bold("\u{1F4C2} Project structure:")}
|
|
542
|
+
${e}/
|
|
543
|
+
\u251C\u2500\u2500 .rapidkit/ # RapidKit CLI module
|
|
544
|
+
\u251C\u2500\u2500 src/
|
|
545
|
+
\u2502 \u251C\u2500\u2500 main.ts # Application entry point
|
|
546
|
+
\u2502 \u251C\u2500\u2500 app.module.ts # Root module
|
|
547
|
+
\u2502 \u251C\u2500\u2500 config/ # Configuration
|
|
548
|
+
\u2502 \u2514\u2500\u2500 examples/ # Example module
|
|
549
|
+
\u251C\u2500\u2500 test/ # Test files
|
|
550
|
+
\u251C\u2500\u2500 package.json # Dependencies
|
|
551
|
+
\u2514\u2500\u2500 README.md
|
|
552
|
+
|
|
553
|
+
${a.bold("\u{1F680} Get started:")}
|
|
554
|
+
${a.cyan(`cd ${A}`)}
|
|
555
|
+
${a.cyan("source .rapidkit/activate")} ${a.gray("# Enable rapidkit commands")}
|
|
556
|
+
${t.skipInstall?a.cyan("rapidkit init")+a.gray(" # npm install")+`
|
|
557
|
+
`:""}${a.cyan("cp .env.example .env")}
|
|
558
|
+
${a.cyan("rapidkit dev")} ${a.gray("# Start dev server")}
|
|
559
|
+
|
|
560
|
+
${a.bold("\u{1F4DA} Available commands:")}
|
|
561
|
+
rapidkit init # Install dependencies
|
|
562
|
+
rapidkit dev # Start dev server with hot reload
|
|
563
|
+
rapidkit start # Start production server
|
|
564
|
+
rapidkit build # Build for production
|
|
565
|
+
rapidkit test # Run tests
|
|
566
|
+
rapidkit lint # Lint code
|
|
567
|
+
rapidkit format # Format code
|
|
568
|
+
|
|
569
|
+
${a.bold("\u{1F310} API endpoints:")}
|
|
570
|
+
http://localhost:3000/health # Health check
|
|
571
|
+
http://localhost:3000/docs # Swagger docs
|
|
572
|
+
http://localhost:3000/examples/notes # Example API
|
|
573
|
+
`);}catch(s){throw n.fail(`Failed to create ${o} project`),s}}async function K(e,t,i){let o=await promises.readdir(e,{withFileTypes:true});for(let n of o){let s=l.join(e,n.name),p=n.name.replace(/\.j2$/,""),d=l.join(t,p);if(n.isDirectory())await promises.mkdir(d,{recursive:true}),await K(s,d,i);else {let g=await promises.readFile(s,"utf-8");n.name.endsWith(".j2")&&(g=se(g,i)),await promises.writeFile(d,g),(p==="rapidkit"||p==="activate"||p.endsWith(".py")&&d.includes(".rapidkit"))&&await promises.chmod(d,493);}}}function se(e,t){let i=e;for(let[o,n]of Object.entries(t)){let s=new RegExp(`\\{\\{\\s*${o}\\s*\\}\\}`,"g");i=i.replace(s,String(n));let p=new RegExp(`\\{\\{\\s*${o}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\}\\}`,"g");i=i.replace(p,(j,C,_)=>String(n).replace(new RegExp(C,"g"),_));let d=new RegExp(`\\{\\{\\s*${o}\\s*\\|\\s*lower\\s*\\}\\}`,"g");i=i.replace(d,String(n).toLowerCase());let g=new RegExp(`\\{\\{\\s*${o}\\s*\\|\\s*replace\\s*\\(\\s*['"]([^'"]+)['"]\\s*,\\s*['"]([^'"]*)['"]\\s*\\)\\s*\\|\\s*lower\\s*\\}\\}`,"g");i=i.replace(g,(j,C,_)=>String(n).replace(new RegExp(C,"g"),_).toLowerCase());}return i}var h=null,E=false,I=new Command;I.name("rapidkit").description("Create RapidKit workspaces and projects").version(w());I.argument("[name]","Name of the workspace or project directory").option("-t, --template <template>","Create project with template (fastapi, nestjs) instead of workspace").option("-y, --yes","Skip prompts and use defaults").option("--skip-git","Skip git initialization").option("--skip-install","Skip installing dependencies").option("--debug","Enable debug logging").option("--dry-run","Show what would be created without creating it").option("--no-update-check","Skip checking for updates").action(async(e,t)=>{try{t.debug&&(c.setDebug(!0),c.debug("Debug mode enabled"));let i=await U();c.debug("User config loaded",i),t.updateCheck!==!1&&await T(),console.log(a.blue.bold(`
|
|
706
574
|
\u{1F680} Welcome to RapidKit!
|
|
707
|
-
`)),e.
|
|
708
|
-
\u274C ${
|
|
709
|
-
`),process.exit(1)),
|
|
575
|
+
`)),e||(le(),process.exit(0));try{O(e);}catch(p){throw p instanceof v&&(c.error(`
|
|
576
|
+
\u274C ${p.message}`),p.details&&c.warn(`\u{1F4A1} ${p.details}
|
|
577
|
+
`),process.exit(1)),p}let o=l.resolve(process.cwd(),e);h=o,await k.pathExists(o)&&(c.error(`
|
|
578
|
+
\u274C Directory "${e}" already exists`),console.log(a.cyan(`
|
|
579
|
+
\u{1F4A1} Choose a different name or delete the existing directory.
|
|
580
|
+
`)),process.exit(1));let n=!!t.template;if(n){let p=t.template.toLowerCase(),d=["fastapi","nestjs"];d.includes(p)||(c.error(`
|
|
581
|
+
\u274C Invalid template: ${t.template}`),console.log(a.cyan(`
|
|
582
|
+
\u{1F4E6} Available templates: ${d.join(", ")}
|
|
583
|
+
`)),process.exit(1));}if(t.dryRun){console.log(a.cyan(`
|
|
710
584
|
\u{1F50D} Dry-run mode - showing what would be created:
|
|
711
|
-
`)),console.log(
|
|
712
|
-
`))
|
|
713
|
-
\u274C ${
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
`)),
|
|
717
|
-
`)),console.log(
|
|
718
|
-
|
|
719
|
-
`)),console.log(
|
|
720
|
-
|
|
721
|
-
`)),console.log(
|
|
722
|
-
`)),e.testMode||(console.log(i.red(`\u274C Cannot proceed without --demo or --test-mode flag.
|
|
723
|
-
`)),process.exit(1)),console.log(i.yellow(`\u26A0\uFE0F Running in TEST MODE - Installing from local path
|
|
724
|
-
`)),await U(r,{skipGit:e.skipGit||o.skipGit,testMode:e.testMode,demoMode:!1,dryRun:e.dryRun,userConfig:o});}catch(o){o instanceof u?(s.error(`
|
|
725
|
-
\u274C ${o.message}`),o.details&&s.warn(`\u{1F4A1} ${o.details}`),s.debug("Error code:",o.code)):(s.error(`
|
|
726
|
-
\u274C An unexpected error occurred:`),console.error(o)),process.exit(1);}finally{w=null;}});process.on("SIGINT",async()=>{if(!O){if(O=true,console.log(i.yellow(`
|
|
727
|
-
|
|
728
|
-
\u26A0\uFE0F Interrupted by user`)),w&&await y.pathExists(w)){console.log(i.gray("Cleaning up partial installation..."));try{await y.remove(w),console.log(i.green("\u2713 Cleanup complete"));}catch(t){s.debug("Cleanup failed:",t);}}process.exit(130);}});process.on("SIGTERM",async()=>{if(!O){if(O=true,s.debug("Received SIGTERM"),w&&await y.pathExists(w))try{await y.remove(w);}catch(t){s.debug("Cleanup failed:",t);}process.exit(143);}});Q.parse();
|
|
585
|
+
`)),console.log(a.white("\u{1F4C2} Path:"),o),console.log(a.white("\u{1F4E6} Type:"),n?`Project (${t.template})`:"Workspace"),console.log();return}let s;t.yes?(s={author:process.env.USER||"RapidKit User",description:n?`${t.template==="nestjs"?"NestJS":"FastAPI"} application generated with RapidKit`:void 0,package_manager:"npm"},console.log(a.gray(`Using default values (--yes flag)
|
|
586
|
+
`))):n?t.template.toLowerCase()==="fastapi"?s=await P.prompt([{type:"input",name:"author",message:"Author name:",default:process.env.USER||"RapidKit User"},{type:"input",name:"description",message:"Project description:",default:"FastAPI service generated with RapidKit"}]):s=await P.prompt([{type:"input",name:"author",message:"Author name:",default:process.env.USER||"RapidKit User"},{type:"input",name:"description",message:"Project description:",default:"NestJS application generated with RapidKit"},{type:"list",name:"package_manager",message:"Package manager:",choices:["npm","yarn","pnpm"],default:"npm"}]):s=await P.prompt([{type:"input",name:"author",message:"Author name:",default:process.env.USER||"RapidKit User"}]),n?await B(o,{name:e,template:t.template.toLowerCase(),author:s.author,description:s.description,package_manager:s.package_manager,skipGit:t.skipGit,skipInstall:t.skipInstall}):await F(o,{name:e,author:s.author,skipGit:t.skipGit});}catch(i){i instanceof v?(c.error(`
|
|
587
|
+
\u274C ${i.message}`),i.details&&c.warn(`\u{1F4A1} ${i.details}`),c.debug("Error code:",i.code)):(c.error(`
|
|
588
|
+
\u274C An unexpected error occurred:`),console.error(i)),process.exit(1);}finally{h=null;}});function le(){console.log(a.white(`Usage: npx rapidkit <name> [options]
|
|
589
|
+
`)),console.log(a.bold("Create a workspace (recommended):")),console.log(a.cyan(" npx rapidkit my-workspace")),console.log(a.cyan(" cd my-workspace")),console.log(a.cyan(" rapidkit create my-api --template fastapi")),console.log(a.cyan(" cd my-api")),console.log(a.cyan(` rapidkit dev
|
|
590
|
+
`)),console.log(a.bold("Or create a project directly:")),console.log(a.cyan(" npx rapidkit my-project --template fastapi")),console.log(a.cyan(` npx rapidkit my-project --template nestjs
|
|
591
|
+
`)),console.log(a.bold("Options:")),console.log(a.gray(" -t, --template <template> Create project with template (fastapi, nestjs)")),console.log(a.gray(" -y, --yes Skip prompts and use defaults")),console.log(a.gray(" --skip-git Skip git initialization")),console.log(a.gray(" --skip-install Skip installing dependencies")),console.log(a.gray(" --debug Enable debug logging")),console.log(a.gray(` --dry-run Show what would be created
|
|
592
|
+
`)),console.log(a.bold("Templates:")),console.log(a.gray(" fastapi FastAPI + Python")),console.log(a.gray(` nestjs NestJS + TypeScript
|
|
593
|
+
`));}process.on("SIGINT",async()=>{if(!E){if(E=true,console.log(a.yellow(`
|
|
594
|
+
|
|
595
|
+
\u26A0\uFE0F Interrupted by user`)),h&&await k.pathExists(h)){console.log(a.gray("Cleaning up partial installation..."));try{await k.remove(h),console.log(a.green("\u2713 Cleanup complete"));}catch(e){c.debug("Cleanup failed:",e);}}process.exit(130);}});process.on("SIGTERM",async()=>{if(!E){if(E=true,c.debug("Received SIGTERM"),h&&await k.pathExists(h))try{await k.remove(h);}catch(e){c.debug("Cleanup failed:",e);}process.exit(143);}});I.parse();
|