@adriankulik/create-fullstack-app 1.4.0 → 1.6.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 -6
- package/cli/index.js +46 -19
- package/package.json +21 -4
- package/templates/backend/dotnet/Tests/Tests.csproj +2 -2
- package/templates/backend/dotnet/dotnet.csproj +1 -1
- package/templates/backend/dotnet/lint.sh +1 -0
- package/templates/backend/dotnet/start.sh +1 -0
- package/templates/backend/dotnet/test.sh +1 -0
- package/templates/backend/fastapi/lint.sh +1 -0
- package/templates/backend/fastapi/requirements.txt +1 -1
- package/templates/backend/fastapi/start.sh +1 -0
- package/templates/backend/fastapi/test.sh +1 -0
- package/templates/backend/flask/lint.sh +1 -0
- package/templates/backend/flask/requirements.txt +1 -1
- package/templates/backend/flask/start.sh +1 -0
- package/templates/backend/flask/test.sh +1 -0
- package/templates/backend/nodejs/eslint.config.js +15 -0
- package/templates/backend/nodejs/lint.sh +1 -0
- package/templates/backend/nodejs/package-lock.json +1121 -2112
- package/templates/backend/nodejs/package.json +7 -7
- package/templates/backend/nodejs/start.sh +1 -0
- package/templates/backend/nodejs/test.sh +1 -0
- package/templates/base/.editorconfig +18 -0
- package/templates/base/.github/workflows/test.yml +26 -10
- package/templates/base/gitignore +4 -0
- package/templates/frontend/angular/angular.json +6 -0
- package/templates/frontend/angular/eslint.config.js +35 -0
- package/templates/frontend/angular/lint.sh +1 -0
- package/templates/frontend/angular/package-lock.json +1420 -488
- package/templates/frontend/angular/package.json +9 -2
- package/templates/frontend/angular/src/app/app.component.html +32 -0
- package/templates/frontend/angular/src/app/app.component.ts +12 -35
- package/templates/frontend/angular/start.sh +1 -0
- package/templates/frontend/angular/test.sh +1 -0
- package/templates/frontend/nextjs/__tests__/page.test.tsx +4 -4
- package/templates/frontend/nextjs/app/page.tsx +8 -2
- package/templates/frontend/nextjs/eslint.config.mjs +7 -0
- package/templates/frontend/nextjs/lint.sh +1 -0
- package/templates/frontend/nextjs/package-lock.json +1336 -872
- package/templates/frontend/nextjs/package.json +11 -10
- package/templates/frontend/nextjs/start.sh +1 -0
- package/templates/frontend/nextjs/test.sh +1 -0
- package/templates/frontend/nextjs/tsconfig.json +2 -1
- package/templates/frontend/svelte/eslint.config.js +29 -0
- package/templates/frontend/svelte/lint.sh +1 -0
- package/templates/frontend/svelte/package-lock.json +1676 -3482
- package/templates/frontend/svelte/package.json +14 -13
- package/templates/frontend/svelte/src/App.spec.ts +7 -7
- package/templates/frontend/svelte/src/App.svelte +14 -7
- package/templates/frontend/svelte/start.sh +1 -0
- package/templates/frontend/svelte/test.sh +1 -0
- package/templates/frontend/svelte/vite.config.ts +2 -2
- package/templates/frontend/vue/eslint.config.js +26 -0
- package/templates/frontend/vue/lint.sh +1 -0
- package/templates/frontend/vue/package-lock.json +1598 -2755
- package/templates/frontend/vue/package.json +13 -13
- package/templates/frontend/vue/src/App.vue +30 -9
- package/templates/frontend/vue/src/__tests__/App.spec.ts +4 -4
- package/templates/frontend/vue/start.sh +1 -0
- package/templates/frontend/vue/test.sh +1 -0
- package/templates/frontend/vue/tsconfig.json +13 -5
- package/templates/frontend/vue/vite.config.ts +0 -1
- package/cli/package-lock.json +0 -1338
- package/cli/package.json +0 -23
- package/templates/backend/nodejs/.eslintrc.json +0 -15
- package/templates/frontend/nextjs/.eslintrc.json +0 -3
- package/templates/frontend/svelte/.eslintrc.cjs +0 -27
- package/templates/frontend/vue/.eslintrc.cjs +0 -18
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"build": "ng build",
|
|
8
8
|
"watch": "ng build --watch --configuration development",
|
|
9
9
|
"test": "ng test --watch=false --browsers=ChromeHeadlessCI",
|
|
10
|
-
"lint": "
|
|
10
|
+
"lint": "ng lint"
|
|
11
11
|
},
|
|
12
12
|
"private": true,
|
|
13
13
|
"dependencies": {
|
|
@@ -25,9 +25,15 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@angular-devkit/build-angular": "^21.0.0",
|
|
28
|
+
"@angular-eslint/builder": "^21.4.0",
|
|
29
|
+
"@angular-eslint/eslint-plugin": "^21.4.0",
|
|
30
|
+
"@angular-eslint/eslint-plugin-template": "^21.4.0",
|
|
31
|
+
"@angular-eslint/template-parser": "^21.4.0",
|
|
28
32
|
"@angular/cli": "^21.0.0",
|
|
29
33
|
"@angular/compiler-cli": "^21.0.0",
|
|
34
|
+
"@eslint/js": "^10.0.1",
|
|
30
35
|
"@types/jasmine": "~5.1.0",
|
|
36
|
+
"eslint": "^10.4.0",
|
|
31
37
|
"jasmine-core": "~5.1.0",
|
|
32
38
|
"karma": "~6.4.0",
|
|
33
39
|
"karma-chrome-launcher": "~3.2.0",
|
|
@@ -35,6 +41,7 @@
|
|
|
35
41
|
"karma-jasmine": "~5.1.0",
|
|
36
42
|
"karma-jasmine-html-reporter": "~2.1.0",
|
|
37
43
|
"puppeteer": "^22.0.0",
|
|
38
|
-
"typescript": "~5.9.0"
|
|
44
|
+
"typescript": "~5.9.0",
|
|
45
|
+
"typescript-eslint": "^8.59.3"
|
|
39
46
|
}
|
|
40
47
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<main style="padding: 2rem; font-family: sans-serif;">
|
|
2
|
+
<h1>Multiplier App (Angular)</h1>
|
|
3
|
+
<form (submit)="handleSubmit($event)" style="margin-bottom: 1rem;">
|
|
4
|
+
<label for="numberInput" style="display: block; margin-bottom: 0.5rem;">
|
|
5
|
+
Enter a number:
|
|
6
|
+
</label>
|
|
7
|
+
<input
|
|
8
|
+
id="numberInput"
|
|
9
|
+
type="number"
|
|
10
|
+
step="any"
|
|
11
|
+
[(ngModel)]="number"
|
|
12
|
+
name="number"
|
|
13
|
+
required
|
|
14
|
+
style="padding: 0.5rem; margin-right: 0.5rem;"
|
|
15
|
+
/>
|
|
16
|
+
<button type="submit" style="padding: 0.5rem 1rem;">
|
|
17
|
+
Multiply by 2
|
|
18
|
+
</button>
|
|
19
|
+
</form>
|
|
20
|
+
|
|
21
|
+
@if (result !== null) {
|
|
22
|
+
<div style="margin-top: 1rem; padding: 1rem; background-color: #e0ffe0; border: 1px solid #00cc00;">
|
|
23
|
+
<strong>Result:</strong> {{ result }}
|
|
24
|
+
</div>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@if (error) {
|
|
28
|
+
<div style="margin-top: 1rem; padding: 1rem; background-color: #ffe0e0; border: 1px solid #cc0000;">
|
|
29
|
+
<strong>Error:</strong> {{ error }}
|
|
30
|
+
</div>
|
|
31
|
+
}
|
|
32
|
+
</main>
|
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
import { Component, ChangeDetectorRef } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
2
|
import { FormsModule } from '@angular/forms';
|
|
4
3
|
|
|
4
|
+
interface MultiplyResponse {
|
|
5
|
+
result: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
5
8
|
@Component({
|
|
6
9
|
selector: 'app-root',
|
|
7
10
|
standalone: true,
|
|
8
|
-
imports: [
|
|
9
|
-
|
|
10
|
-
<main style="padding: 2rem; font-family: sans-serif;">
|
|
11
|
-
<h1>Multiplier App (Angular)</h1>
|
|
12
|
-
<form (submit)="handleSubmit($event)" style="margin-bottom: 1rem;">
|
|
13
|
-
<label for="numberInput" style="display: block; margin-bottom: 0.5rem;">
|
|
14
|
-
Enter a number:
|
|
15
|
-
</label>
|
|
16
|
-
<input
|
|
17
|
-
id="numberInput"
|
|
18
|
-
type="number"
|
|
19
|
-
step="any"
|
|
20
|
-
[(ngModel)]="number"
|
|
21
|
-
name="number"
|
|
22
|
-
required
|
|
23
|
-
style="padding: 0.5rem; margin-right: 0.5rem;"
|
|
24
|
-
/>
|
|
25
|
-
<button type="submit" style="padding: 0.5rem 1rem;">
|
|
26
|
-
Multiply by 2
|
|
27
|
-
</button>
|
|
28
|
-
</form>
|
|
29
|
-
|
|
30
|
-
<div *ngIf="result !== null" style="margin-top: 1rem; padding: 1rem; background-color: #e0ffe0; border: 1px solid #00cc00;">
|
|
31
|
-
<strong>Result:</strong> {{ result }}
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<div *ngIf="error" style="margin-top: 1rem; padding: 1rem; background-color: #ffe0e0; border: 1px solid #cc0000;">
|
|
35
|
-
<strong>Error:</strong> {{ error }}
|
|
36
|
-
</div>
|
|
37
|
-
</main>
|
|
38
|
-
`,
|
|
11
|
+
imports: [FormsModule],
|
|
12
|
+
templateUrl: './app.component.html',
|
|
39
13
|
})
|
|
40
14
|
export class AppComponent {
|
|
41
15
|
number: string = '';
|
|
42
16
|
result: number | null = null;
|
|
43
17
|
error: string | null = null;
|
|
44
18
|
|
|
19
|
+
// Configure via environment: defaults to localhost for development
|
|
20
|
+
private apiUrl = 'http://localhost:8000';
|
|
21
|
+
|
|
45
22
|
constructor(private cdr: ChangeDetectorRef) {}
|
|
46
23
|
|
|
47
24
|
async handleSubmit(event: Event) {
|
|
@@ -50,7 +27,7 @@ export class AppComponent {
|
|
|
50
27
|
this.result = null;
|
|
51
28
|
|
|
52
29
|
try {
|
|
53
|
-
const response = await fetch(
|
|
30
|
+
const response = await fetch(`${this.apiUrl}/api/multiply`, {
|
|
54
31
|
method: 'POST',
|
|
55
32
|
headers: {
|
|
56
33
|
'Content-Type': 'application/json',
|
|
@@ -62,12 +39,12 @@ export class AppComponent {
|
|
|
62
39
|
throw new Error('Network response was not ok');
|
|
63
40
|
}
|
|
64
41
|
|
|
65
|
-
const data = await response.json();
|
|
42
|
+
const data: MultiplyResponse = await response.json();
|
|
66
43
|
this.result = data.result;
|
|
67
44
|
} catch (err: unknown) {
|
|
68
45
|
this.error = (err as Error).message;
|
|
69
46
|
}
|
|
70
|
-
|
|
47
|
+
|
|
71
48
|
this.cdr.detectChanges();
|
|
72
49
|
}
|
|
73
50
|
}
|
|
@@ -2,16 +2,16 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
|
2
2
|
import Home from '../app/page';
|
|
3
3
|
|
|
4
4
|
// Mock fetch
|
|
5
|
-
|
|
5
|
+
globalThis.fetch = jest.fn(() =>
|
|
6
6
|
Promise.resolve({
|
|
7
7
|
ok: true,
|
|
8
8
|
json: () => Promise.resolve({ result: 10 }),
|
|
9
|
-
})
|
|
10
|
-
);
|
|
9
|
+
} as unknown as Response)
|
|
10
|
+
) as typeof fetch;
|
|
11
11
|
|
|
12
12
|
describe('Home', () => {
|
|
13
13
|
beforeEach(() => {
|
|
14
|
-
fetch.mockClear();
|
|
14
|
+
(fetch as jest.Mock).mockClear();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('renders a heading', () => {
|
|
@@ -2,18 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState, FormEvent } from 'react';
|
|
4
4
|
|
|
5
|
+
interface MultiplyResponse {
|
|
6
|
+
result: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
export default function Home() {
|
|
6
10
|
const [number, setNumber] = useState<string>('');
|
|
7
11
|
const [result, setResult] = useState<number | null>(null);
|
|
8
12
|
const [error, setError] = useState<string | null>(null);
|
|
9
13
|
|
|
14
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
|
|
15
|
+
|
|
10
16
|
const handleSubmit = async (e: FormEvent) => {
|
|
11
17
|
e.preventDefault();
|
|
12
18
|
setError(null);
|
|
13
19
|
setResult(null);
|
|
14
20
|
|
|
15
21
|
try {
|
|
16
|
-
const response = await fetch(
|
|
22
|
+
const response = await fetch(`${apiUrl}/api/multiply`, {
|
|
17
23
|
method: 'POST',
|
|
18
24
|
headers: {
|
|
19
25
|
'Content-Type': 'application/json',
|
|
@@ -25,7 +31,7 @@ export default function Home() {
|
|
|
25
31
|
throw new Error('Network response was not ok');
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
const data = await response.json();
|
|
34
|
+
const data: MultiplyResponse = await response.json();
|
|
29
35
|
setResult(data.result);
|
|
30
36
|
} catch (err: unknown) {
|
|
31
37
|
setError((err as Error).message);
|