@nubase/create 0.1.28 → 0.1.31
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/dist/index.js +17 -16
- package/package.json +3 -3
- package/templates/{frontend/e2e → e2e}/fixtures/test-api.ts +20 -10
- package/templates/{frontend/e2e → e2e}/global-setup.ts +7 -7
- package/templates/nubase/migrations/.gitkeep +0 -0
- package/templates/nubase/nubase.config.ts +14 -0
- package/templates/root/README.md +13 -10
- package/templates/{backend → root}/drizzle.config.ts +1 -1
- package/templates/{frontend → root}/index.html +1 -1
- package/templates/root/package.json +57 -23
- package/templates/{frontend → root}/playwright.config.ts +8 -21
- package/templates/root/tsconfig.backend.json +12 -0
- package/templates/root/tsconfig.frontend.json +9 -0
- package/templates/{backend → root}/tsconfig.json +2 -4
- package/templates/root/vite-env.d.ts +1 -0
- package/templates/root/vite.config.ts +65 -0
- package/templates/{backend/src → src/backend}/api/handler-factory.ts +1 -1
- package/templates/{backend/src → src/backend}/api/routes/test-utils.ts +5 -5
- package/templates/{backend/src/index.ts → src/backend/app.ts} +10 -31
- package/templates/{backend/src → src/backend}/middleware/workspace-middleware.ts +1 -1
- package/templates/src/backend/server.ts +18 -0
- package/templates/{frontend/src → src/frontend}/config.tsx +3 -4
- package/templates/{frontend/src → src/frontend}/dashboards/analytics.ts +1 -1
- package/templates/{frontend/src → src/frontend}/resources/ticket.ts +1 -1
- package/templates/{frontend/src → src/frontend}/resources/user.ts +1 -1
- package/templates/backend/package.json +0 -48
- package/templates/frontend/.env.development.template +0 -1
- package/templates/frontend/.env.test.template +0 -1
- package/templates/frontend/package.json +0 -38
- package/templates/frontend/postcss.config.js +0 -5
- package/templates/frontend/src/vite-env.d.ts +0 -9
- package/templates/frontend/tsconfig.json +0 -17
- package/templates/frontend/vite.config.ts +0 -14
- package/templates/root/turbo.json +0 -25
- package/templates/schema/package.json +0 -28
- package/templates/schema/tsconfig.json +0 -14
- /package/templates/{backend/db → db}/schema.sql +0 -0
- /package/templates/{backend/docker → docker}/dev/docker-compose.yml +0 -0
- /package/templates/{backend/docker → docker}/dev/postgresql-init/dump.sql +0 -0
- /package/templates/{backend/docker → docker}/test/docker-compose.yml +0 -0
- /package/templates/{backend/docker → docker}/test/postgresql-init/dump.sql +0 -0
- /package/templates/{frontend/e2e → e2e}/auth.spec.ts +0 -0
- /package/templates/{frontend/e2e → e2e}/fixtures/base.ts +0 -0
- /package/templates/{frontend/e2e → e2e}/ticket.spec.ts +0 -0
- /package/templates/{frontend/e2e → e2e}/utils/test-reporter.ts +0 -0
- /package/templates/{backend → root}/.env.development.template +0 -0
- /package/templates/{backend → root}/.env.test.template +0 -0
- /package/templates/{backend → root}/vitest.config.ts +0 -0
- /package/templates/{backend/src → src/backend}/api/routes/auth.ts +0 -0
- /package/templates/{backend/src → src/backend}/api/routes/dashboard.ts +0 -0
- /package/templates/{backend/src → src/backend}/api/routes/index.ts +0 -0
- /package/templates/{backend/src → src/backend}/api/routes/ticket.ts +0 -0
- /package/templates/{backend/src → src/backend}/api/routes/user.ts +0 -0
- /package/templates/{backend/src → src/backend}/auth/index.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/helpers/drizzle.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/schema/index.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/schema/ticket.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/schema/user-workspace.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/schema/user.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/schema/workspace.ts +0 -0
- /package/templates/{backend/src → src/backend}/db/seed.ts +0 -0
- /package/templates/{backend/src → src/backend}/helpers/env.ts +0 -0
- /package/templates/{backend/src → src/backend}/preflight.ts +0 -0
- /package/templates/{schema/src → src/common}/api-endpoints.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/get-me.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/index.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/login-complete.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/login-start.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/login.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/logout.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/auth/signup.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/active-users.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/browser-stats.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/index.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/recent-activity.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/revenue-chart.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/sales-chart.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/dashboard/total-revenue.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/index.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/delete-ticket.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/get-ticket.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/get-tickets.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/index.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/patch-ticket.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/ticket/post-ticket.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/delete-user.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/get-user.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/get-users.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/index.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/lookup-users.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/patch-user.ts +0 -0
- /package/templates/{schema/src → src/common}/endpoints/user/post-user.ts +0 -0
- /package/templates/{schema/src → src/common}/index.ts +0 -0
- /package/templates/{schema/src → src/common}/resources/index.ts +0 -0
- /package/templates/{schema/src → src/common}/resources/ticket.ts +0 -0
- /package/templates/{schema/src → src/common}/resources/user.ts +0 -0
- /package/templates/{schema/src → src/common}/resources/workspace.ts +0 -0
- /package/templates/{frontend/src → src/frontend}/auth/__PROJECT_NAME_PASCAL__AuthController.ts +0 -0
- /package/templates/{frontend/src → src/frontend}/main.tsx +0 -0
- /package/templates/{frontend/src → src/frontend}/styles/theme.css +0 -0
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ function replaceInContent(content, options) {
|
|
|
27
27
|
const pascalName = toPascalCase(options.name);
|
|
28
28
|
const camelName = toCamelCase(options.name);
|
|
29
29
|
const nubaseVersion = options.nubaseTag === "latest" ? "*" : options.nubaseTag;
|
|
30
|
-
return content.replace(/__PROJECT_NAME__/g, kebabName).replace(/__PROJECT_NAME_PASCAL__/g, pascalName).replace(/__PROJECT_NAME_CAMEL__/g, camelName).replace(/__DB_NAME__/g, options.dbName).replace(/__DB_USER__/g, options.dbUser).replace(/__DB_PASSWORD__/g, options.dbPassword).replace(/__DEV_PORT__/g, String(options.devPort)).replace(/__TEST_PORT__/g, String(options.testPort)).replace(/
|
|
30
|
+
return content.replace(/__PROJECT_NAME__/g, kebabName).replace(/__PROJECT_NAME_PASCAL__/g, pascalName).replace(/__PROJECT_NAME_CAMEL__/g, camelName).replace(/__DB_NAME__/g, options.dbName).replace(/__DB_USER__/g, options.dbUser).replace(/__DB_PASSWORD__/g, options.dbPassword).replace(/__DEV_PORT__/g, String(options.devPort)).replace(/__TEST_PORT__/g, String(options.testPort)).replace(/__PORT__/g, String(options.port)).replace(/__TEST_PORT_APP__/g, String(options.testPortApp)).replace(/"@nubase\/core": "\*"/g, `"@nubase/core": "${nubaseVersion}"`).replace(/"@nubase\/frontend": "\*"/g, `"@nubase/frontend": "${nubaseVersion}"`).replace(/"@nubase\/backend": "\*"/g, `"@nubase/backend": "${nubaseVersion}"`).replace(/"@nubase\/create": "\*"/g, `"@nubase/create": "${nubaseVersion}"`);
|
|
31
31
|
}
|
|
32
32
|
function copyTemplateDir(src, dest, options) {
|
|
33
33
|
fse.ensureDirSync(dest);
|
|
@@ -52,7 +52,7 @@ function copyTemplateDir(src, dest, options) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
async function main() {
|
|
55
|
-
program.name("@nubase/create").description("Create a new Nubase application").argument("[project-name]", "Name of the project").option("--db-name <name>", "Database name").option("--db-user <user>", "Database user").option("--db-password <password>", "Database password").option("--dev-port <port>", "Development database port", "5434").option("--test-port <port>", "Test database port", "5435").option("--
|
|
55
|
+
program.name("@nubase/create").description("Create a new Nubase application").argument("[project-name]", "Name of the project").option("--db-name <name>", "Database name").option("--db-user <user>", "Database user").option("--db-password <password>", "Database password").option("--dev-port <port>", "Development database port", "5434").option("--test-port <port>", "Test database port", "5435").option("--port <port>", "Application server port", "3000").option("--test-port-app <port>", "Test application server port", "4000").option("--skip-install", "Skip npm install").option("--tag <tag>", "npm tag for @nubase/* packages (latest, dev)", "latest").parse();
|
|
56
56
|
const args = program.args;
|
|
57
57
|
const opts = program.opts();
|
|
58
58
|
console.log(chalk.bold.cyan("\n Welcome to Nubase!\n"));
|
|
@@ -81,10 +81,8 @@ async function main() {
|
|
|
81
81
|
dbPassword,
|
|
82
82
|
devPort: Number.parseInt(opts.devPort, 10),
|
|
83
83
|
testPort: Number.parseInt(opts.testPort, 10),
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
testBackendPort: Number.parseInt(opts.testBackendPort, 10),
|
|
87
|
-
testFrontendPort: Number.parseInt(opts.testFrontendPort, 10),
|
|
84
|
+
port: Number.parseInt(opts.port, 10),
|
|
85
|
+
testPortApp: Number.parseInt(opts.testPortApp, 10),
|
|
88
86
|
nubaseTag: opts.tag
|
|
89
87
|
};
|
|
90
88
|
const targetDir = path.join(process.cwd(), projectName);
|
|
@@ -104,20 +102,23 @@ async function main() {
|
|
|
104
102
|
console.log(chalk.blue(`
|
|
105
103
|
Creating project in ${chalk.bold(targetDir)}...
|
|
106
104
|
`));
|
|
107
|
-
const templates = [
|
|
105
|
+
const templates = [
|
|
106
|
+
{ name: "root", dest: "" },
|
|
107
|
+
{ name: "src", dest: "src" },
|
|
108
|
+
{ name: "docker", dest: "docker" },
|
|
109
|
+
{ name: "db", dest: "db" },
|
|
110
|
+
{ name: "e2e", dest: "e2e" },
|
|
111
|
+
{ name: "nubase", dest: "nubase" }
|
|
112
|
+
];
|
|
108
113
|
for (const template of templates) {
|
|
109
|
-
const templatePath = path.join(TEMPLATE_DIR, template);
|
|
114
|
+
const templatePath = path.join(TEMPLATE_DIR, template.name);
|
|
110
115
|
if (!fs.existsSync(templatePath)) {
|
|
111
|
-
console.log(chalk.yellow(`Template ${template} not found, skipping...`));
|
|
116
|
+
console.log(chalk.yellow(`Template ${template.name} not found, skipping...`));
|
|
112
117
|
continue;
|
|
113
118
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const destPath = path.join(targetDir, template);
|
|
118
|
-
copyTemplateDir(templatePath, destPath, options);
|
|
119
|
-
}
|
|
120
|
-
console.log(chalk.green(` \u2713 Created ${template}`));
|
|
119
|
+
const destPath = template.dest ? path.join(targetDir, template.dest) : targetDir;
|
|
120
|
+
copyTemplateDir(templatePath, destPath, options);
|
|
121
|
+
console.log(chalk.green(` \u2713 Created ${template.name}`));
|
|
121
122
|
}
|
|
122
123
|
if (!opts.skipInstall) {
|
|
123
124
|
console.log(chalk.blue("\nInstalling dependencies...\n"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nubase/create",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Create a new Nubase application",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"publish:dev": "npm publish --access public --tag dev"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"chalk": "^5.
|
|
24
|
+
"chalk": "^5.6.2",
|
|
25
25
|
"commander": "^12.1.0",
|
|
26
|
-
"fs-extra": "^11.3.
|
|
26
|
+
"fs-extra": "^11.3.4",
|
|
27
27
|
"prompts": "^2.4.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
@@ -10,8 +10,8 @@ export const TEST_USER = {
|
|
|
10
10
|
// Test workspace for path-based multi-workspace
|
|
11
11
|
export const TEST_WORKSPACE = "tavern";
|
|
12
12
|
|
|
13
|
-
//
|
|
14
|
-
const API_BASE_URL = "http://localhost:
|
|
13
|
+
// API base URL - same origin, all API routes are under /api
|
|
14
|
+
const API_BASE_URL = "http://localhost:__TEST_PORT_APP__";
|
|
15
15
|
|
|
16
16
|
export class TestAPI {
|
|
17
17
|
constructor(private request: APIRequestContext) {}
|
|
@@ -45,9 +45,12 @@ export class TestAPI {
|
|
|
45
45
|
password: string = TEST_USER.password,
|
|
46
46
|
workspace: string = TEST_WORKSPACE,
|
|
47
47
|
) {
|
|
48
|
-
const response = await this.request.post(
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const response = await this.request.post(
|
|
49
|
+
`${API_BASE_URL}/api/auth/login`,
|
|
50
|
+
{
|
|
51
|
+
data: { email, password, workspace },
|
|
52
|
+
},
|
|
53
|
+
);
|
|
51
54
|
|
|
52
55
|
if (!response.ok()) {
|
|
53
56
|
const body = await response.text();
|
|
@@ -76,9 +79,12 @@ export class TestAPI {
|
|
|
76
79
|
async seedTestData(data: {
|
|
77
80
|
tickets?: Array<{ title: string; description?: string }>;
|
|
78
81
|
}) {
|
|
79
|
-
const response = await this.request.post(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
const response = await this.request.post(
|
|
83
|
+
`${API_BASE_URL}/api/test/seed`,
|
|
84
|
+
{
|
|
85
|
+
data,
|
|
86
|
+
},
|
|
87
|
+
);
|
|
82
88
|
if (!response.ok()) {
|
|
83
89
|
throw new Error(`Failed to seed test data: ${response.status()}`);
|
|
84
90
|
}
|
|
@@ -86,7 +92,9 @@ export class TestAPI {
|
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
async getDatabaseStats() {
|
|
89
|
-
const response = await this.request.get(
|
|
95
|
+
const response = await this.request.get(
|
|
96
|
+
`${API_BASE_URL}/api/test/stats`,
|
|
97
|
+
);
|
|
90
98
|
if (!response.ok()) {
|
|
91
99
|
const body = await response.text();
|
|
92
100
|
throw new Error(
|
|
@@ -97,7 +105,9 @@ export class TestAPI {
|
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
async getTicket(id: number) {
|
|
100
|
-
const response = await this.request.get(
|
|
108
|
+
const response = await this.request.get(
|
|
109
|
+
`${API_BASE_URL}/api/tickets/${id}`,
|
|
110
|
+
);
|
|
101
111
|
if (!response.ok()) {
|
|
102
112
|
throw new Error(`Failed to get ticket: ${response.status()}`);
|
|
103
113
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import type { FullConfig } from "@playwright/test";
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
const API_BASE_URL = "http://localhost:
|
|
3
|
+
// API base URL - same origin in unified architecture
|
|
4
|
+
const API_BASE_URL = "http://localhost:__TEST_PORT_APP__";
|
|
5
5
|
|
|
6
6
|
async function globalSetup(_config: FullConfig) {
|
|
7
7
|
console.log("Running global setup...");
|
|
8
8
|
|
|
9
|
-
// Wait for
|
|
9
|
+
// Wait for server to be ready
|
|
10
10
|
const maxRetries = 30;
|
|
11
11
|
let retries = 0;
|
|
12
12
|
|
|
13
13
|
while (retries < maxRetries) {
|
|
14
14
|
try {
|
|
15
|
-
const response = await fetch(`${API_BASE_URL}/`);
|
|
15
|
+
const response = await fetch(`${API_BASE_URL}/api/`);
|
|
16
16
|
if (response.ok) {
|
|
17
|
-
console.log("
|
|
17
|
+
console.log("Server is ready");
|
|
18
18
|
break;
|
|
19
19
|
}
|
|
20
20
|
} catch (_error) {
|
|
21
|
-
//
|
|
21
|
+
// Server not ready yet
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
retries++;
|
|
25
25
|
if (retries === maxRetries) {
|
|
26
|
-
throw new Error("
|
|
26
|
+
throw new Error("Server failed to start within timeout");
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "@nubase/cli";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
environments: {
|
|
5
|
+
local: {
|
|
6
|
+
url: "postgres://__DB_USER__:__DB_PASSWORD__@localhost:__DEV_PORT__/__DB_NAME__",
|
|
7
|
+
},
|
|
8
|
+
production: {
|
|
9
|
+
url: process.env.PRODUCTION_DATABASE_URL!,
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
defaultEnvironment: "local",
|
|
13
|
+
schemas: ["public"],
|
|
14
|
+
});
|
package/templates/root/README.md
CHANGED
|
@@ -30,15 +30,13 @@ npm run db:up
|
|
|
30
30
|
npm run db:seed
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
4. Start the development
|
|
33
|
+
4. Start the development server:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
npm run dev
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
The application will be available at:
|
|
40
|
-
- Frontend: http://localhost:__FRONTEND_PORT__/default
|
|
41
|
-
- Backend API: http://localhost:__BACKEND_PORT__
|
|
39
|
+
The application will be available at http://localhost:__PORT__/tavern
|
|
42
40
|
|
|
43
41
|
### Default Credentials
|
|
44
42
|
|
|
@@ -49,16 +47,21 @@ The application will be available at:
|
|
|
49
47
|
|
|
50
48
|
```
|
|
51
49
|
__PROJECT_NAME__/
|
|
52
|
-
├──
|
|
53
|
-
├── backend/ #
|
|
54
|
-
├── frontend/ # React frontend (Vite + Nubase)
|
|
55
|
-
└──
|
|
50
|
+
├── src/
|
|
51
|
+
│ ├── backend/ # Hono API server
|
|
52
|
+
│ ├── frontend/ # React frontend (Vite + Nubase)
|
|
53
|
+
│ └── common/ # Shared API schemas and types
|
|
54
|
+
├── docker/ # Docker Compose configs
|
|
55
|
+
├── e2e/ # Playwright E2E tests
|
|
56
|
+
├── vite.config.ts # Unified Vite config (dev + build)
|
|
57
|
+
└── package.json # Project configuration
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
## Available Scripts
|
|
59
61
|
|
|
60
|
-
- `npm run dev` - Start
|
|
61
|
-
- `npm run build` - Build
|
|
62
|
+
- `npm run dev` - Start development server (frontend + backend on single port)
|
|
63
|
+
- `npm run build` - Build for production (client + server)
|
|
64
|
+
- `npm run start` - Start production server
|
|
62
65
|
- `npm run db:up` - Start PostgreSQL database
|
|
63
66
|
- `npm run db:down` - Stop PostgreSQL database
|
|
64
67
|
- `npm run db:seed` - Seed database with sample data
|
|
@@ -3,33 +3,67 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"workspaces": [
|
|
7
|
-
"schema",
|
|
8
|
-
"backend",
|
|
9
|
-
"frontend"
|
|
10
|
-
],
|
|
11
6
|
"scripts": {
|
|
12
|
-
"dev": "
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"db:
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build --mode client && vite build --mode server",
|
|
9
|
+
"start": "node dist/server/index.js",
|
|
10
|
+
"typecheck": "tsc --noEmit -p tsconfig.backend.json && tsc --noEmit -p tsconfig.frontend.json",
|
|
11
|
+
"lint": "biome check .",
|
|
12
|
+
"lint:fix": "biome check . --write --unsafe",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"db:up": "./scripts/check-docker.sh docker compose -f docker/dev/docker-compose.yml up -d",
|
|
16
|
+
"db:down": "docker compose -f docker/dev/docker-compose.yml down",
|
|
17
|
+
"db:kill": "docker compose -f docker/dev/docker-compose.yml down -v && rm -rf docker/dev/postgresql-data",
|
|
18
|
+
"db:seed": "NODE_ENV=development tsx src/backend/db/seed.ts",
|
|
19
|
+
"db:reset": "npm run db:kill && npm run db:schema-sync && npm run db:up && sleep 5 && npm run db:seed",
|
|
20
|
+
"db:schema-sync": "cp db/schema.sql docker/dev/postgresql-init/dump.sql && cp db/schema.sql docker/test/postgresql-init/dump.sql",
|
|
21
|
+
"db:test:up": "./scripts/check-docker.sh docker compose -f docker/test/docker-compose.yml up -d",
|
|
22
|
+
"db:test:down": "docker compose -f docker/test/docker-compose.yml down",
|
|
23
|
+
"db:test:kill": "docker compose -f docker/test/docker-compose.yml down -v && rm -rf docker/test/postgresql-data",
|
|
24
|
+
"db:test:reset": "npm run db:test:kill && npm run db:schema-sync && npm run db:test:up",
|
|
25
|
+
"dev:test": "NODE_ENV=test vite --mode test --port __TEST_PORT_APP__",
|
|
26
|
+
"e2e": "playwright test",
|
|
27
|
+
"e2e:ui": "playwright test --ui",
|
|
28
|
+
"e2e:headed": "playwright test --headed",
|
|
29
|
+
"e2e:install": "playwright install"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@hono/node-server": "^1.19.9",
|
|
33
|
+
"@nubase/backend": "*",
|
|
34
|
+
"@nubase/core": "*",
|
|
35
|
+
"@nubase/frontend": "*",
|
|
36
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
37
|
+
"@tanstack/react-router": "^1.150.0",
|
|
38
|
+
"bcrypt": "^6.0.0",
|
|
39
|
+
"dotenv": "^17.2.3",
|
|
40
|
+
"drizzle-orm": "^0.45.1",
|
|
41
|
+
"hono": "^4.11.4",
|
|
42
|
+
"jsonwebtoken": "^9.0.3",
|
|
43
|
+
"lucide-react": "^0.539.0",
|
|
44
|
+
"pg": "^8.17.1",
|
|
45
|
+
"react": "^19.2.3",
|
|
46
|
+
"react-dom": "^19.2.3",
|
|
47
|
+
"tailwindcss": "^4.1.18"
|
|
28
48
|
},
|
|
29
49
|
"devDependencies": {
|
|
30
50
|
"@biomejs/biome": "^2.3.11",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
51
|
+
"@faker-js/faker": "^9.9.0",
|
|
52
|
+
"@hono/vite-build": "^1.5.0",
|
|
53
|
+
"@hono/vite-dev-server": "^0.19.0",
|
|
54
|
+
"@playwright/test": "^1.49.0",
|
|
55
|
+
"@types/bcrypt": "^6.0.0",
|
|
56
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
57
|
+
"@types/node": "^22.19.7",
|
|
58
|
+
"@types/pg": "^8.16.0",
|
|
59
|
+
"@types/react": "^19.2.8",
|
|
60
|
+
"@types/react-dom": "^19.2.3",
|
|
61
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
62
|
+
"drizzle-kit": "^0.31.8",
|
|
63
|
+
"tsx": "^4.21.0",
|
|
64
|
+
"typescript": "^5.9.3",
|
|
65
|
+
"vite": "^7.3.1",
|
|
66
|
+
"vitest": "^4.0.17"
|
|
33
67
|
},
|
|
34
68
|
"engines": {
|
|
35
69
|
"node": ">=18",
|
|
@@ -20,7 +20,7 @@ export default defineConfig({
|
|
|
20
20
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
21
21
|
use: {
|
|
22
22
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
|
23
|
-
baseURL: "http://localhost:
|
|
23
|
+
baseURL: "http://localhost:__TEST_PORT_APP__",
|
|
24
24
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
25
25
|
trace: "on-first-retry",
|
|
26
26
|
/* Screenshot on failure */
|
|
@@ -37,24 +37,11 @@ export default defineConfig({
|
|
|
37
37
|
},
|
|
38
38
|
],
|
|
39
39
|
|
|
40
|
-
/* Run
|
|
41
|
-
webServer:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
command: "cd ../backend && npm run dev:test",
|
|
50
|
-
url: "http://localhost:__TEST_BACKEND_PORT__",
|
|
51
|
-
reuseExistingServer: true,
|
|
52
|
-
timeout: 120 * 1000,
|
|
53
|
-
env: {
|
|
54
|
-
NODE_ENV: "test",
|
|
55
|
-
DATABASE_URL:
|
|
56
|
-
"postgresql://__DB_NAME__:__DB_PASSWORD__@localhost:__TEST_PORT__/__DB_NAME__",
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
],
|
|
40
|
+
/* Run the unified dev server before starting the tests */
|
|
41
|
+
webServer: {
|
|
42
|
+
command: "npm run dev:test",
|
|
43
|
+
url: "http://localhost:__TEST_PORT_APP__/tavern",
|
|
44
|
+
reuseExistingServer: true,
|
|
45
|
+
timeout: 120 * 1000,
|
|
46
|
+
},
|
|
60
47
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"types": ["node"],
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"jsxImportSource": "hono/jsx",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"outDir": "./dist/server"
|
|
10
|
+
},
|
|
11
|
+
"include": ["src/backend/**/*", "src/common/**/*"]
|
|
12
|
+
}
|
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
"esModuleInterop": true,
|
|
7
7
|
"strict": true,
|
|
8
8
|
"skipLibCheck": true,
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"rootDir": "./src"
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"isolatedModules": true
|
|
12
11
|
},
|
|
13
|
-
"include": ["src/**/*"],
|
|
14
12
|
"exclude": ["node_modules", "dist"]
|
|
15
13
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import devServer, { defaultOptions } from "@hono/vite-dev-server";
|
|
2
|
+
import build from "@hono/vite-build/node";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
import react from "@vitejs/plugin-react";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
|
|
7
|
+
export default defineConfig(({ mode }) => {
|
|
8
|
+
if (mode === "client") {
|
|
9
|
+
return {
|
|
10
|
+
plugins: [react(), tailwindcss()],
|
|
11
|
+
build: {
|
|
12
|
+
outDir: "dist/client",
|
|
13
|
+
emptyOutDir: true,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (mode === "server") {
|
|
19
|
+
return {
|
|
20
|
+
plugins: [
|
|
21
|
+
build({
|
|
22
|
+
entry: "src/backend/server.ts",
|
|
23
|
+
output: "index.js",
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
26
|
+
build: {
|
|
27
|
+
outDir: "dist/server",
|
|
28
|
+
emptyOutDir: true,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Development mode
|
|
34
|
+
return {
|
|
35
|
+
plugins: [
|
|
36
|
+
react(),
|
|
37
|
+
tailwindcss(),
|
|
38
|
+
devServer({
|
|
39
|
+
entry: "src/backend/app.ts",
|
|
40
|
+
exclude: [
|
|
41
|
+
// Only send /api/* requests to Hono; everything else goes to Vite
|
|
42
|
+
/^(?!\/api\/).+/,
|
|
43
|
+
...defaultOptions.exclude,
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
ssr: {
|
|
48
|
+
external: [
|
|
49
|
+
"@nubase/core",
|
|
50
|
+
"@nubase/backend",
|
|
51
|
+
"@nubase/frontend",
|
|
52
|
+
"pg",
|
|
53
|
+
"drizzle-orm",
|
|
54
|
+
"bcrypt",
|
|
55
|
+
"jsonwebtoken",
|
|
56
|
+
"dotenv",
|
|
57
|
+
"@hono/node-server",
|
|
58
|
+
"@faker-js/faker",
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
server: {
|
|
62
|
+
port: __PORT__,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
});
|
|
@@ -32,7 +32,7 @@ async function getWorkspaceBySlug(slug: string) {
|
|
|
32
32
|
export const handleClearDatabase = createHttpHandler({
|
|
33
33
|
endpoint: {
|
|
34
34
|
method: "POST" as const,
|
|
35
|
-
path: "/
|
|
35
|
+
path: "/test/clear-database",
|
|
36
36
|
requestParams: emptySchema,
|
|
37
37
|
requestBody: nu.object({
|
|
38
38
|
workspace: nu.string().optional(),
|
|
@@ -97,7 +97,7 @@ export const handleClearDatabase = createHttpHandler({
|
|
|
97
97
|
export const handleSeedTestData = createHttpHandler({
|
|
98
98
|
endpoint: {
|
|
99
99
|
method: "POST" as const,
|
|
100
|
-
path: "/
|
|
100
|
+
path: "/test/seed",
|
|
101
101
|
requestParams: emptySchema,
|
|
102
102
|
requestBody: nu.object({
|
|
103
103
|
workspace: nu.string().optional(),
|
|
@@ -162,7 +162,7 @@ export const handleSeedTestData = createHttpHandler({
|
|
|
162
162
|
export const handleGetDatabaseStats = createHttpHandler({
|
|
163
163
|
endpoint: {
|
|
164
164
|
method: "GET" as const,
|
|
165
|
-
path: "/
|
|
165
|
+
path: "/test/stats",
|
|
166
166
|
requestParams: nu.object({
|
|
167
167
|
workspace: nu.string().optional(),
|
|
168
168
|
}),
|
|
@@ -199,7 +199,7 @@ export const handleGetDatabaseStats = createHttpHandler({
|
|
|
199
199
|
export const handleEnsureWorkspace = createHttpHandler({
|
|
200
200
|
endpoint: {
|
|
201
201
|
method: "POST" as const,
|
|
202
|
-
path: "/
|
|
202
|
+
path: "/test/ensure-workspace",
|
|
203
203
|
requestParams: emptySchema,
|
|
204
204
|
requestBody: nu.object({
|
|
205
205
|
workspace: nu.string().optional(),
|
|
@@ -271,7 +271,7 @@ export const handleEnsureWorkspace = createHttpHandler({
|
|
|
271
271
|
export const handleSeedMultiWorkspaceUser = createHttpHandler({
|
|
272
272
|
endpoint: {
|
|
273
273
|
method: "POST" as const,
|
|
274
|
-
path: "/
|
|
274
|
+
path: "/test/seed-multi-workspace-user",
|
|
275
275
|
requestParams: emptySchema,
|
|
276
276
|
requestBody: nu.object({
|
|
277
277
|
email: nu.string(),
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { serve } from "@hono/node-server";
|
|
2
1
|
import { createAuthMiddleware, registerHandlers } from "@nubase/backend";
|
|
3
2
|
import { Hono } from "hono";
|
|
4
|
-
import { cors } from "hono/cors";
|
|
5
3
|
import { authHandlers } from "./api/routes/auth";
|
|
6
4
|
import { dashboardHandlers } from "./api/routes/dashboard";
|
|
7
5
|
import { testUtilsHandlers } from "./api/routes/test-utils";
|
|
@@ -21,21 +19,6 @@ const app = new Hono();
|
|
|
21
19
|
// Auth controller
|
|
22
20
|
const authController = new __PROJECT_NAME_PASCAL__AuthController();
|
|
23
21
|
|
|
24
|
-
// CORS configuration
|
|
25
|
-
app.use(
|
|
26
|
-
"*",
|
|
27
|
-
cors({
|
|
28
|
-
origin: (origin) => {
|
|
29
|
-
// Allow localhost origins
|
|
30
|
-
if (origin?.match(/^http:\/\/localhost(:\d+)?$/)) {
|
|
31
|
-
return origin;
|
|
32
|
-
}
|
|
33
|
-
return null;
|
|
34
|
-
},
|
|
35
|
-
credentials: true,
|
|
36
|
-
}),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
22
|
// Workspace middleware - handles login path (gets workspace from body)
|
|
40
23
|
app.use("*", createWorkspaceMiddleware());
|
|
41
24
|
|
|
@@ -45,24 +28,20 @@ app.use("*", createAuthMiddleware({ controller: authController }));
|
|
|
45
28
|
// Post-auth workspace middleware - sets context from authenticated user's workspace
|
|
46
29
|
app.use("*", createPostAuthWorkspaceMiddleware());
|
|
47
30
|
|
|
48
|
-
//
|
|
49
|
-
|
|
31
|
+
// API routes - all handlers are mounted under /api
|
|
32
|
+
const api = new Hono();
|
|
33
|
+
|
|
34
|
+
api.get("/", (c) => c.json({ message: "Welcome to __PROJECT_NAME_PASCAL__ API" }));
|
|
50
35
|
|
|
51
|
-
|
|
52
|
-
registerHandlers(
|
|
53
|
-
registerHandlers(
|
|
54
|
-
registerHandlers(app, dashboardHandlers);
|
|
36
|
+
registerHandlers(api, authHandlers);
|
|
37
|
+
registerHandlers(api, ticketHandlers);
|
|
38
|
+
registerHandlers(api, dashboardHandlers);
|
|
55
39
|
|
|
56
40
|
// Register test utility handlers (only in test environment)
|
|
57
41
|
if (process.env.NODE_ENV === "test") {
|
|
58
|
-
registerHandlers(
|
|
42
|
+
registerHandlers(api, testUtilsHandlers);
|
|
59
43
|
}
|
|
60
44
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
console.log(`Server is running on http://localhost:${port}`);
|
|
45
|
+
app.route("/api", api);
|
|
64
46
|
|
|
65
|
-
|
|
66
|
-
fetch: app.fetch,
|
|
67
|
-
port,
|
|
68
|
-
});
|
|
47
|
+
export default app;
|
|
@@ -13,7 +13,7 @@ export interface Workspace {
|
|
|
13
13
|
const WORKSPACE_BYPASS_PATHS = ["/"];
|
|
14
14
|
|
|
15
15
|
// Paths where workspace comes from request body (login) instead of JWT
|
|
16
|
-
const WORKSPACE_FROM_BODY_PATHS = ["/auth/login"];
|
|
16
|
+
const WORKSPACE_FROM_BODY_PATHS = ["/api/auth/login"];
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Workspace middleware for path-based multi-workspace.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { serve } from "@hono/node-server";
|
|
3
|
+
import { serveStatic } from "@hono/node-server/serve-static";
|
|
4
|
+
import app from "./app";
|
|
5
|
+
|
|
6
|
+
// Serve built frontend assets
|
|
7
|
+
app.use("/assets/*", serveStatic({ root: "./dist/client" }));
|
|
8
|
+
app.use("/favicon.ico", serveStatic({ root: "./dist/client" }));
|
|
9
|
+
|
|
10
|
+
// SPA fallback - serve index.html for all non-API routes
|
|
11
|
+
const indexHtml = await readFile("./dist/client/index.html", "utf-8");
|
|
12
|
+
app.get("*", (c) => c.html(indexHtml));
|
|
13
|
+
|
|
14
|
+
const port = Number(process.env.PORT) || __PORT__;
|
|
15
|
+
|
|
16
|
+
serve({ fetch: app.fetch, port }, (info) => {
|
|
17
|
+
console.log(`Server running on http://localhost:${info.port}`);
|
|
18
|
+
});
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { NubaseFrontendConfig } from "@nubase/frontend";
|
|
2
2
|
import { defaultKeybindings, resourceLink } from "@nubase/frontend";
|
|
3
3
|
import { Home, TicketIcon, UsersIcon } from "lucide-react";
|
|
4
|
-
import { apiEndpoints } from "
|
|
4
|
+
import { apiEndpoints } from "../common";
|
|
5
5
|
import { __PROJECT_NAME_PASCAL__AuthController } from "./auth/__PROJECT_NAME_PASCAL__AuthController";
|
|
6
6
|
import { analyticsDashboard } from "./dashboards/analytics";
|
|
7
7
|
import { ticketResource } from "./resources/ticket";
|
|
8
8
|
import { userResource } from "./resources/user";
|
|
9
9
|
|
|
10
|
-
const apiBaseUrl =
|
|
11
|
-
import.meta.env.VITE_API_BASE_URL || "http://localhost:__BACKEND_PORT__";
|
|
10
|
+
const apiBaseUrl = "/api";
|
|
12
11
|
|
|
13
12
|
// Preserve auth controller across HMR to prevent losing authentication state during development
|
|
14
13
|
const authController: __PROJECT_NAME_PASCAL__AuthController = (import.meta.hot
|
|
@@ -47,7 +46,7 @@ export const config: NubaseFrontendConfig<typeof apiEndpoints> = {
|
|
|
47
46
|
[userResource.id]: userResource,
|
|
48
47
|
},
|
|
49
48
|
keybindings: defaultKeybindings.extend(),
|
|
50
|
-
apiBaseUrl
|
|
49
|
+
apiBaseUrl,
|
|
51
50
|
apiEndpoints,
|
|
52
51
|
themeIds: ["dark", "light"],
|
|
53
52
|
defaultThemeId: "dark",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createResource, showToast } from "@nubase/frontend";
|
|
2
2
|
import { TrashIcon } from "lucide-react";
|
|
3
|
-
import { apiEndpoints } from "
|
|
3
|
+
import { apiEndpoints } from "../../common";
|
|
4
4
|
|
|
5
5
|
export const ticketResource = createResource("ticket")
|
|
6
6
|
.withApiEndpoints(apiEndpoints)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createResource, showToast } from "@nubase/frontend";
|
|
2
2
|
import { TrashIcon } from "lucide-react";
|
|
3
|
-
import { apiEndpoints } from "
|
|
3
|
+
import { apiEndpoints } from "../../common";
|
|
4
4
|
|
|
5
5
|
export const userResource = createResource("user")
|
|
6
6
|
.withApiEndpoints(apiEndpoints)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "backend",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "NODE_ENV=development tsx src/preflight.ts && NODE_ENV=development tsx watch src/index.ts",
|
|
7
|
-
"dev:test": "PORT=__TEST_BACKEND_PORT__ DB_PORT=__TEST_PORT__ NODE_ENV=test tsx watch src/index.ts",
|
|
8
|
-
"build": "tsc",
|
|
9
|
-
"start": "node dist/index.js",
|
|
10
|
-
"db:dev:up": "docker compose -f docker/dev/docker-compose.yml up -d",
|
|
11
|
-
"db:dev:down": "docker compose -f docker/dev/docker-compose.yml down",
|
|
12
|
-
"db:dev:kill": "docker compose -f docker/dev/docker-compose.yml down -v && rm -rf docker/dev/postgresql-data",
|
|
13
|
-
"db:dev:seed": "NODE_ENV=development tsx src/db/seed.ts",
|
|
14
|
-
"db:dev:reset": "npm run db:dev:kill && npm run db:schema-sync && npm run db:dev:up && sleep 5 && npm run db:dev:seed",
|
|
15
|
-
"db:test:up": "docker compose -f docker/test/docker-compose.yml up -d",
|
|
16
|
-
"db:test:down": "docker compose -f docker/test/docker-compose.yml down",
|
|
17
|
-
"db:test:kill": "docker compose -f docker/test/docker-compose.yml down -v && rm -rf docker/test/postgresql-data",
|
|
18
|
-
"db:test:reset": "npm run db:test:kill && npm run db:schema-sync && npm run db:test:up",
|
|
19
|
-
"db:schema-sync": "cp db/schema.sql docker/dev/postgresql-init/dump.sql && cp db/schema.sql docker/test/postgresql-init/dump.sql",
|
|
20
|
-
"typecheck": "tsc --noEmit",
|
|
21
|
-
"lint": "biome check .",
|
|
22
|
-
"lint:fix": "biome check . --write --unsafe",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"@hono/node-server": "^1.19.9",
|
|
28
|
-
"@nubase/backend": "*",
|
|
29
|
-
"bcrypt": "^6.0.0",
|
|
30
|
-
"dotenv": "^17.2.3",
|
|
31
|
-
"drizzle-orm": "^0.45.1",
|
|
32
|
-
"hono": "^4.11.4",
|
|
33
|
-
"jsonwebtoken": "^9.0.3",
|
|
34
|
-
"pg": "^8.17.1",
|
|
35
|
-
"schema": "*"
|
|
36
|
-
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"@faker-js/faker": "^9.9.0",
|
|
39
|
-
"@types/bcrypt": "^6.0.0",
|
|
40
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
41
|
-
"@types/node": "^22.19.7",
|
|
42
|
-
"@types/pg": "^8.16.0",
|
|
43
|
-
"drizzle-kit": "^0.31.8",
|
|
44
|
-
"tsx": "^4.21.0",
|
|
45
|
-
"typescript": "^5.9.3",
|
|
46
|
-
"vitest": "^4.0.17"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VITE_API_BASE_URL=http://localhost:__BACKEND_PORT__
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VITE_API_BASE_URL=http://localhost:__TEST_BACKEND_PORT__
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "frontend",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "0.1.0",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"dev:test": "vite --mode test --port __TEST_FRONTEND_PORT__",
|
|
9
|
-
"dev:e2e": "playwright test --ui",
|
|
10
|
-
"build": "tsc -b && vite build",
|
|
11
|
-
"preview": "vite preview",
|
|
12
|
-
"typecheck": "tsc --noEmit",
|
|
13
|
-
"lint": "biome check .",
|
|
14
|
-
"lint:fix": "biome check . --write --unsafe",
|
|
15
|
-
"e2e": "playwright test",
|
|
16
|
-
"e2e:ui": "playwright test --ui",
|
|
17
|
-
"e2e:headed": "playwright test --headed",
|
|
18
|
-
"e2e:install": "playwright install"
|
|
19
|
-
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@nubase/frontend": "*",
|
|
22
|
-
"@tailwindcss/vite": "^4.1.18",
|
|
23
|
-
"@tanstack/react-router": "^1.150.0",
|
|
24
|
-
"lucide-react": "^0.539.0",
|
|
25
|
-
"react": "^19.2.3",
|
|
26
|
-
"react-dom": "^19.2.3",
|
|
27
|
-
"tailwindcss": "^4.1.18",
|
|
28
|
-
"schema": "*"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@playwright/test": "^1.49.0",
|
|
32
|
-
"@types/react": "^19.2.8",
|
|
33
|
-
"@types/react-dom": "^19.2.3",
|
|
34
|
-
"@vitejs/plugin-react": "^5.1.2",
|
|
35
|
-
"typescript": "^5.9.3",
|
|
36
|
-
"vite": "^7.3.1"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"moduleResolution": "bundler",
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"strict": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"noEmit": true,
|
|
11
|
-
"jsx": "react-jsx",
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true
|
|
14
|
-
},
|
|
15
|
-
"include": ["src/**/*"],
|
|
16
|
-
"exclude": ["node_modules"]
|
|
17
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
2
|
-
import react from "@vitejs/plugin-react";
|
|
3
|
-
import { defineConfig } from "vite";
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
plugins: [react(), tailwindcss()],
|
|
7
|
-
build: {
|
|
8
|
-
outDir: "dist",
|
|
9
|
-
},
|
|
10
|
-
server: {
|
|
11
|
-
port: __FRONTEND_PORT__,
|
|
12
|
-
open: "http://localhost:__FRONTEND_PORT__/tavern",
|
|
13
|
-
},
|
|
14
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://turbo.build/schema.json",
|
|
3
|
-
"tasks": {
|
|
4
|
-
"build": {
|
|
5
|
-
"dependsOn": ["^build"],
|
|
6
|
-
"outputs": ["dist/**"]
|
|
7
|
-
},
|
|
8
|
-
"dev": {
|
|
9
|
-
"cache": false,
|
|
10
|
-
"persistent": true
|
|
11
|
-
},
|
|
12
|
-
"dev:e2e": {
|
|
13
|
-
"cache": false,
|
|
14
|
-
"persistent": true
|
|
15
|
-
},
|
|
16
|
-
"typecheck": {
|
|
17
|
-
"dependsOn": ["^build"]
|
|
18
|
-
},
|
|
19
|
-
"lint": {},
|
|
20
|
-
"lint:fix": {},
|
|
21
|
-
"e2e": {
|
|
22
|
-
"cache": false
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "schema",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "Schema for __PROJECT_NAME_PASCAL__",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"files": [
|
|
7
|
-
"src"
|
|
8
|
-
],
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./src/index.ts",
|
|
12
|
-
"import": "./src/index.ts",
|
|
13
|
-
"require": "./src/index.ts"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"license": "MIT",
|
|
17
|
-
"scripts": {
|
|
18
|
-
"typecheck": "tsc --noEmit",
|
|
19
|
-
"lint": "biome check .",
|
|
20
|
-
"lint:fix": "biome check . --write --unsafe"
|
|
21
|
-
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"@nubase/core": "*"
|
|
24
|
-
},
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"typescript": "^5.9.3"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"strict": true,
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"noEmit": true
|
|
11
|
-
},
|
|
12
|
-
"include": ["src/**/*"],
|
|
13
|
-
"exclude": ["node_modules"]
|
|
14
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/{frontend/src → src/frontend}/auth/__PROJECT_NAME_PASCAL__AuthController.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|