@adriankulik/create-fullstack-app 1.9.5 → 1.11.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 CHANGED
@@ -12,7 +12,7 @@ Before running the CLI or the scaffolded applications, ensure you have the follo
12
12
 
13
13
  - **Node.js**: v20 or newer
14
14
  - **npm**: v10 or newer
15
- - **Python**: v3.11 or newer _(only required for FastAPI / Flask backends)_
15
+ - **Python**: The newest stable release _(only required for FastAPI / Flask backends. We frequently update frameworks to their latest versions, so using older Pythons may cause pip install errors)_
16
16
  - **[.NET 9 SDK](https://aka.ms/dotnet/download)** _(only required for the .NET backend — the CLI will offer to install it automatically on macOS/Linux if not found)_
17
17
 
18
18
  ## Quickstart
@@ -30,15 +30,16 @@ You will be prompted to choose a project name, your preferred frontend, and back
30
30
  ## Features
31
31
 
32
32
  - **Frontend Options**:
33
- - Next.js (v16.2.6)
34
- - Angular (v21.0.0) - _Configured with Zone.js_
35
- - Vue (v3.5.33)
36
- - Svelte (v5.55.7)
33
+ - Next.js (v16.3.2)
34
+ - Angular (v22.1.3) - _Configured with Zone.js_
35
+ - Vue (v3.5.41)
36
+ - Svelte (v5.56.10)
37
37
  - **Backend Options**:
38
- - FastAPI (v0.115.11)
38
+ - FastAPI (v0.141.1)
39
39
  - Flask (v3.1.3)
40
- - .NET (v9.0.0)
41
- - Node.js Express (v4.22.2)
40
+ - .NET (v10.0.11)
41
+ - Node.js Express (v5.2.1)
42
+ - **Database**: PostgreSQL (v15) with Alembic (v1.16.5), SQLAlchemy (v2.0.52), and Psycopg2 (v2.9.12).
42
43
  - **Opinionated Defaults**: We bake in sensible, predefined choices (e.g., Angular uses `zone.js`, testing is unified under Playwright and framework-native test runners).
43
44
  - **Unified Scripts**: `start.sh`, `test.sh`, and `lint.sh` available out of the box to manage both frontend and backend seamlessly.
44
45
  - **CI/CD Ready**: Includes a pre-configured `.github/workflows/cli-e2e.yml` that tests both ends. _Tip: To enforce this, enable branch protection in your GitHub repository settings and require the "test" status check to pass._
package/cli/build-date.js CHANGED
@@ -1 +1 @@
1
- module.exports = '2026-08-21 21:42:57';
1
+ module.exports = '2026-08-22 22:04:01';
package/cli/index.js CHANGED
@@ -47,19 +47,19 @@ async function main() {
47
47
  name: "frontend",
48
48
  message: "Which frontend framework would you like to use?",
49
49
  choices: [
50
- { title: "Next.js (v16.2.6)", value: "nextjs", description: "React framework" },
50
+ { title: "Next.js (v16.3.2)", value: "nextjs", description: "React framework" },
51
51
  {
52
- title: "Angular (v21.0.0)",
52
+ title: "Angular (v22.1.3)",
53
53
  value: "angular",
54
54
  description: "Enterprise-grade platform",
55
55
  },
56
56
  {
57
- title: "Vue (v3.5.33)",
57
+ title: "Vue (v3.5.41)",
58
58
  value: "vue",
59
59
  description: "Progressive JavaScript framework",
60
60
  },
61
61
  {
62
- title: "Svelte (v5.55.7)",
62
+ title: "Svelte (v5.56.10)",
63
63
  value: "svelte",
64
64
  description: "Cybernetically enhanced web apps",
65
65
  },
@@ -75,7 +75,7 @@ async function main() {
75
75
  message: "Which backend framework would you like to use?",
76
76
  choices: [
77
77
  {
78
- title: "FastAPI (v0.115.11)",
78
+ title: "FastAPI (v0.141.1)",
79
79
  value: "fastapi",
80
80
  description: "Modern, fast Python web framework",
81
81
  },
@@ -85,12 +85,12 @@ async function main() {
85
85
  description: "Lightweight Python WSGI web application framework",
86
86
  },
87
87
  {
88
- title: ".NET (v9.0.0)",
88
+ title: ".NET (v10.0.11)",
89
89
  value: "dotnet",
90
90
  description: "Robust, C#, high-performance framework by Microsoft",
91
91
  },
92
92
  {
93
- title: "Node.js Express (v4.22.2)",
93
+ title: "Node.js Express (v5.2.1)",
94
94
  value: "nodejs",
95
95
  description: "Minimalist web framework for Node.js",
96
96
  },
@@ -117,6 +117,7 @@ async function main() {
117
117
  }
118
118
 
119
119
  console.log(pc.blue(`\nScaffolding project in ${targetDir}...`));
120
+ console.log(pc.blue(`Configuring PostgreSQL (v15) database with Alembic, SQLAlchemy, and Psycopg2...`));
120
121
 
121
122
  // Determine paths to templates relative to the CLI script
122
123
  const templatesDir = path.resolve(__dirname, "../templates");
@@ -195,8 +196,23 @@ async function main() {
195
196
  } catch (e) {
196
197
  console.error(
197
198
  pc.red(
198
- " Failed to set up Python virtual environment or install dependencies.",
199
- ),
199
+ "\n Failed to set up Python virtual environment or install dependencies."
200
+ )
201
+ );
202
+ console.error(
203
+ pc.yellow(
204
+ " TIP: We frequently update templates to use the latest framework versions."
205
+ )
206
+ );
207
+ console.error(
208
+ pc.yellow(
209
+ " If pip failed to find a matching version, your default 'python3' version might be too old."
210
+ )
211
+ );
212
+ console.error(
213
+ pc.yellow(
214
+ " Please try updating to the newest version of Python and run this again."
215
+ )
200
216
  );
201
217
  process.exit(1);
202
218
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.9.5",
6
+ "version": "1.11.0",
7
7
  "description": "A CLI tool for scaffolding a full-stack web application with your choice of frontend and backend technologies.",
8
8
  "main": "cli/index.js",
9
9
  "bin": {
@@ -17,14 +17,16 @@
17
17
  "test": "tests"
18
18
  },
19
19
  "dependencies": {
20
- "fs-extra": "^11.3.4",
20
+ "fs-extra": "^11.4.0",
21
21
  "picocolors": "^1.1.1",
22
22
  "prompts": "^2.4.2"
23
23
  },
24
24
  "devDependencies": {
25
- "@playwright/test": "^1.60.0",
26
- "vitest": "^4.1.5",
27
- "wait-on": "^9.0.10"
25
+ "@playwright/test": "^1.62.1",
26
+ "@types/pg": "^8.23.1",
27
+ "pg": "^8.23.0",
28
+ "vitest": "^4.1.11",
29
+ "wait-on": "^9.1.0"
28
30
  },
29
31
  "scripts": {
30
32
  "prepublishOnly": "echo \"module.exports = '$(date -u +\"%Y-%m-%d %H:%M:%S\")';\" > cli/build-date.js",
@@ -1,4 +1,5 @@
1
1
  using Microsoft.AspNetCore.Mvc;
2
+ using Npgsql;
2
3
 
3
4
  var builder = WebApplication.CreateBuilder(args);
4
5
 
@@ -15,12 +16,33 @@ var app = builder.Build();
15
16
 
16
17
  app.UseCors();
17
18
 
18
- app.MapPost("/api/multiply", ([FromBody] MultiplyRequest request) =>
19
+ var dbUrl = Environment.GetEnvironmentVariable("DATABASE_URL") ?? "postgresql://user:password@localhost:5432/appdb";
20
+ var connStr = dbUrl;
21
+ if (dbUrl.StartsWith("postgres://") || dbUrl.StartsWith("postgresql://"))
19
22
  {
20
- return new { result = request.Number * 2 };
21
- });
22
-
23
+ var uri = new Uri(dbUrl);
24
+ var userInfo = uri.UserInfo.Split(':');
25
+ connStr = $"Host={uri.Host};Port={uri.Port};Username={userInfo[0]};Password={userInfo[1]};Database={uri.LocalPath.Substring(1)}";
26
+ }
23
27
 
28
+ app.MapPost("/api/multiply", async ([FromBody] MultiplyRequest request) =>
29
+ {
30
+ var result = request.Number * 2;
31
+ try
32
+ {
33
+ await using var dataSource = NpgsqlDataSource.Create(connStr);
34
+ await using var cmd = dataSource.CreateCommand("INSERT INTO calculations (input_number, result) VALUES (@input_number, @result)");
35
+ cmd.Parameters.AddWithValue("input_number", request.Number);
36
+ cmd.Parameters.AddWithValue("result", result);
37
+ await cmd.ExecuteNonQueryAsync();
38
+ }
39
+ catch (Exception e)
40
+ {
41
+ Console.WriteLine($"Error saving to db: {e.Message}");
42
+ }
43
+
44
+ return new { result };
45
+ });
24
46
 
25
47
  app.Run("http://localhost:8000");
26
48
 
@@ -10,14 +10,14 @@
10
10
  </PropertyGroup>
11
11
 
12
12
  <ItemGroup>
13
- <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
14
- <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
15
- <PackageReference Include="xunit" Version="2.4.2" />
16
- <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
13
+ <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.11" />
14
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
15
+ <PackageReference Include="xunit" Version="2.9.3" />
16
+ <PackageReference Include="xunit.runner.visualstudio" Version="4.0.0">
17
17
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18
18
  <PrivateAssets>all</PrivateAssets>
19
19
  </PackageReference>
20
- <PackageReference Include="coverlet.collector" Version="6.0.0">
20
+ <PackageReference Include="coverlet.collector" Version="10.0.1">
21
21
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22
22
  <PrivateAssets>all</PrivateAssets>
23
23
  </PackageReference>
@@ -14,4 +14,8 @@
14
14
  <None Remove="Tests\**" />
15
15
  </ItemGroup>
16
16
 
17
+ <ItemGroup>
18
+ <PackageReference Include="Npgsql" Version="10.0.3" />
19
+ </ItemGroup>
20
+
17
21
  </Project>
@@ -1,13 +1,14 @@
1
+ import os
1
2
  from fastapi import FastAPI
2
3
  from fastapi.middleware.cors import CORSMiddleware
3
4
  from pydantic import BaseModel
5
+ import psycopg2
4
6
 
5
7
  app = FastAPI()
6
8
 
7
- # Allow CORS for the frontend
8
9
  app.add_middleware(
9
10
  CORSMiddleware,
10
- allow_origins=["*"], # In production, specify the actual origin
11
+ allow_origins=["*"],
11
12
  allow_credentials=True,
12
13
  allow_methods=["*"],
13
14
  allow_headers=["*"],
@@ -19,8 +20,24 @@ class MultiplyRequest(BaseModel):
19
20
  class MultiplyResponse(BaseModel):
20
21
  result: float
21
22
 
22
- @app.post("/api/multiply", response_model=MultiplyResponse)
23
- def multiply_number(request: MultiplyRequest):
24
- return MultiplyResponse(result=request.number * 2)
23
+ DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://user:password@localhost:5432/appdb")
25
24
 
25
+ def save_calculation(number: float, result: float):
26
+ conn = psycopg2.connect(DATABASE_URL)
27
+ cursor = conn.cursor()
28
+ cursor.execute(
29
+ "INSERT INTO calculations (input_number, result) VALUES (%s, %s)",
30
+ (number, result)
31
+ )
32
+ conn.commit()
33
+ cursor.close()
34
+ conn.close()
26
35
 
36
+ @app.post("/api/multiply", response_model=MultiplyResponse)
37
+ def multiply_number(request: MultiplyRequest):
38
+ result = request.number * 2
39
+ try:
40
+ save_calculation(request.number, result)
41
+ except psycopg2.Error as e:
42
+ print(f"Error saving to db: {e}")
43
+ return MultiplyResponse(result=result)
@@ -1,5 +1,6 @@
1
- fastapi==0.115.11
2
- uvicorn==0.28.0
3
- pytest==8.1.1
4
- httpx==0.27.0
5
- ruff==0.15.13
1
+ fastapi
2
+ uvicorn
3
+ pytest
4
+ httpx
5
+ ruff
6
+ psycopg2-binary
@@ -1,9 +1,24 @@
1
+ import os
1
2
  from flask import Flask, request, jsonify
2
3
  from flask_cors import CORS
4
+ import psycopg2
3
5
 
4
6
  app = Flask(__name__)
5
7
  CORS(app)
6
8
 
9
+ DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://user:password@localhost:5432/appdb")
10
+
11
+ def save_calculation(number: float, result: float):
12
+ conn = psycopg2.connect(DATABASE_URL)
13
+ cursor = conn.cursor()
14
+ cursor.execute(
15
+ "INSERT INTO calculations (input_number, result) VALUES (%s, %s)",
16
+ (number, result)
17
+ )
18
+ conn.commit()
19
+ cursor.close()
20
+ conn.close()
21
+
7
22
  @app.route("/api/multiply", methods=["POST"])
8
23
  def multiply_number():
9
24
  data = request.get_json()
@@ -12,11 +27,14 @@ def multiply_number():
12
27
 
13
28
  try:
14
29
  number = float(data["number"])
15
- return jsonify({"result": number * 2})
30
+ result = number * 2
31
+ try:
32
+ save_calculation(number, result)
33
+ except psycopg2.Error as e:
34
+ print(f"Error saving to db: {e}")
35
+ return jsonify({"result": result})
16
36
  except ValueError:
17
37
  return jsonify({"error": "Invalid number"}), 400
18
38
 
19
-
20
-
21
39
  if __name__ == "__main__":
22
40
  app.run(port=8000)
@@ -1,5 +1,6 @@
1
1
  Flask==3.1.3
2
- Flask-Cors==4.0.0
3
- pytest==8.1.1
4
- httpx==0.27.0
5
- ruff==0.15.13
2
+ Flask-Cors==6.0.5
3
+ pytest==8.3.3
4
+ httpx==0.28.1
5
+ ruff==0.16.4
6
+ psycopg2-binary==2.9.12