@idealyst/cli 1.0.46 → 1.0.48
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/generators/fullstack.js +61 -3
- package/dist/generators/fullstack.js.map +1 -1
- package/dist/generators/native.js +12 -0
- package/dist/generators/native.js.map +1 -1
- package/dist/generators/utils.js +64 -31
- package/dist/generators/utils.js.map +1 -1
- package/dist/templates/api/README.md +207 -130
- package/dist/templates/api/package.json +5 -5
- package/dist/templates/api/src/controllers/TestController.ts +0 -0
- package/dist/templates/api/src/index.ts +2 -7
- package/dist/templates/api/src/lib/crud.ts +150 -0
- package/dist/templates/api/src/lib/database.ts +23 -0
- package/dist/templates/api/src/router/index.ts +104 -71
- package/dist/templates/api/src/routers/test.ts +59 -0
- package/dist/templates/api/src/routers/user.example.ts +83 -0
- package/dist/templates/api/src/server.ts +1 -1
- package/dist/templates/api/tsconfig.json +0 -1
- package/dist/templates/database/README.md +115 -1
- package/dist/templates/database/package.json +2 -0
- package/dist/templates/database/prisma/seed.ts +37 -1
- package/dist/templates/database/schema.prisma +11 -1
- package/dist/templates/native/index.js +1 -1
- package/dist/templates/native/metro.config.js +1 -1
- package/dist/templates/native/package.json +4 -0
- package/dist/templates/native/src/App.tsx +16 -0
- package/dist/templates/native/src/utils/trpc.ts +7 -127
- package/dist/templates/native/tsconfig.json +0 -2
- package/dist/templates/shared/package.json +8 -3
- package/dist/templates/shared/src/components/App.tsx +57 -0
- package/dist/templates/shared/src/components/HelloWorld.tsx +276 -86
- package/dist/templates/shared/src/components/index.ts +1 -1
- package/dist/templates/shared/src/index.ts +6 -2
- package/dist/templates/shared/src/trpc/client.ts +39 -0
- package/dist/templates/shared/tsconfig.json +1 -1
- package/dist/templates/web/README.md +65 -8
- package/dist/templates/web/package.json +3 -3
- package/dist/templates/web/src/App-with-trpc-and-shared.tsx +10 -6
- package/dist/templates/web/src/components/TestDemo.tsx +164 -0
- package/dist/templates/web/src/utils/trpc.ts +7 -93
- package/dist/templates/web/tsconfig.json +0 -1
- package/dist/templates/workspace/.devcontainer/devcontainer.json +4 -9
- package/dist/templates/workspace/.devcontainer/docker-compose.yml +1 -2
- package/dist/templates/workspace/.devcontainer/setup.sh +1 -1
- package/dist/templates/workspace/.env.example +1 -1
- package/dist/templates/workspace/Dockerfile +4 -4
- package/dist/templates/workspace/docker/nginx/prod.conf +2 -2
- package/dist/templates/workspace/docker/nginx.conf +1 -1
- package/dist/templates/workspace/docker/prometheus/prometheus.yml +1 -1
- package/dist/templates/workspace/docker-compose.yml +4 -5
- package/dist/templates/workspace/tsconfig.json +0 -1
- package/package.json +1 -1
- package/templates/api/README.md +207 -130
- package/templates/api/package.json +5 -5
- package/templates/api/src/controllers/TestController.ts +0 -0
- package/templates/api/src/index.ts +2 -7
- package/templates/api/src/lib/crud.ts +150 -0
- package/templates/api/src/lib/database.ts +23 -0
- package/templates/api/src/router/index.ts +104 -71
- package/templates/api/src/routers/test.ts +59 -0
- package/templates/api/src/routers/user.example.ts +83 -0
- package/templates/api/src/server.ts +1 -1
- package/templates/api/tsconfig.json +0 -1
- package/templates/database/README.md +115 -1
- package/templates/database/package.json +2 -0
- package/templates/database/prisma/seed.ts +37 -1
- package/templates/database/schema.prisma +11 -1
- package/templates/native/index.js +1 -1
- package/templates/native/metro.config.js +1 -1
- package/templates/native/package.json +4 -0
- package/templates/native/src/App.tsx +16 -0
- package/templates/native/src/utils/trpc.ts +7 -127
- package/templates/native/tsconfig.json +0 -2
- package/templates/shared/package.json +8 -3
- package/templates/shared/src/components/App.tsx +57 -0
- package/templates/shared/src/components/HelloWorld.tsx +276 -86
- package/templates/shared/src/components/index.ts +1 -1
- package/templates/shared/src/index.ts +6 -2
- package/templates/shared/src/trpc/client.ts +39 -0
- package/templates/shared/tsconfig.json +1 -1
- package/templates/web/README.md +65 -8
- package/templates/web/package.json +3 -3
- package/templates/web/src/App-with-trpc-and-shared.tsx +10 -6
- package/templates/web/src/components/TestDemo.tsx +164 -0
- package/templates/web/src/utils/trpc.ts +7 -93
- package/templates/web/tsconfig.json +0 -1
- package/templates/workspace/.devcontainer/devcontainer.json +4 -9
- package/templates/workspace/.devcontainer/docker-compose.yml +1 -2
- package/templates/workspace/.devcontainer/setup.sh +1 -1
- package/templates/workspace/.env.example +1 -1
- package/templates/workspace/Dockerfile +4 -4
- package/templates/workspace/docker/nginx/prod.conf +2 -2
- package/templates/workspace/docker/nginx.conf +1 -1
- package/templates/workspace/docker/prometheus/prometheus.yml +1 -1
- package/templates/workspace/docker-compose.yml +4 -5
- package/templates/workspace/tsconfig.json +0 -1
- package/dist/templates/api/src/controllers/UserController.ts +0 -102
- package/dist/templates/api/src/lib/controller.ts +0 -90
- package/dist/templates/api/src/lib/middleware.ts +0 -170
- package/dist/templates/api/src/middleware/auth.ts +0 -75
- package/dist/templates/api/src/middleware/common.ts +0 -103
- package/dist/templates/database/.env.example +0 -1
- package/dist/templates/native/App.tsx +0 -23
- package/dist/templates/native/src/App-with-trpc-and-shared.tsx +0 -12
- package/templates/api/src/controllers/UserController.ts +0 -102
- package/templates/api/src/lib/controller.ts +0 -90
- package/templates/api/src/lib/middleware.ts +0 -170
- package/templates/api/src/middleware/auth.ts +0 -75
- package/templates/api/src/middleware/common.ts +0 -103
- package/templates/database/.env.example +0 -1
- package/templates/native/App.tsx +0 -23
- package/templates/native/src/App-with-trpc-and-shared.tsx +0 -12
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createTRPCReact } from '@trpc/react-query';
|
|
2
|
+
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
|
3
|
+
import type { AppRouter } from '@{{workspaceScope}}/api';
|
|
4
|
+
|
|
5
|
+
// Create the tRPC React hooks with full type safety
|
|
6
|
+
export const trpc = createTRPCReact<AppRouter>();
|
|
7
|
+
|
|
8
|
+
// Configuration for tRPC client
|
|
9
|
+
export interface TRPCClientConfig {
|
|
10
|
+
apiUrl: string;
|
|
11
|
+
headers?: () => Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Create tRPC client factory
|
|
15
|
+
export function createTRPCClient(config: TRPCClientConfig) {
|
|
16
|
+
return trpc.createClient({
|
|
17
|
+
links: [
|
|
18
|
+
httpBatchLink({
|
|
19
|
+
url: config.apiUrl,
|
|
20
|
+
headers: config.headers,
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Create a vanilla client (for use outside of React components)
|
|
27
|
+
export function createVanillaTRPCClient(config: TRPCClientConfig) {
|
|
28
|
+
return createTRPCProxyClient<AppRouter>({
|
|
29
|
+
links: [
|
|
30
|
+
httpBatchLink({
|
|
31
|
+
url: config.apiUrl,
|
|
32
|
+
headers: config.headers,
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Export types
|
|
39
|
+
export type { AppRouter } from '@{{workspaceScope}}/api';
|
package/templates/web/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Getting Started
|
|
6
6
|
|
|
7
|
-
This is a React web application built with the Idealyst Framework and Vite.
|
|
7
|
+
This is a React web application built with the Idealyst Framework and Vite, with full-stack capabilities including database and API integration.
|
|
8
8
|
|
|
9
9
|
### Prerequisites
|
|
10
10
|
|
|
@@ -18,15 +18,53 @@ Install dependencies:
|
|
|
18
18
|
yarn install
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
### Database Setup
|
|
22
|
+
|
|
23
|
+
If your project includes a database, set it up:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Navigate to the database package
|
|
27
|
+
cd packages/database
|
|
28
|
+
|
|
29
|
+
# Install dependencies
|
|
30
|
+
yarn install
|
|
31
|
+
|
|
32
|
+
# Generate Prisma client
|
|
33
|
+
yarn prisma:generate
|
|
34
|
+
|
|
35
|
+
# Run database migrations
|
|
36
|
+
yarn prisma:migrate
|
|
37
|
+
|
|
38
|
+
# Seed the database with sample data
|
|
39
|
+
yarn prisma:seed
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### API Setup
|
|
43
|
+
|
|
44
|
+
If your project includes an API, start the API server:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Navigate to the API package
|
|
48
|
+
cd packages/api
|
|
49
|
+
|
|
50
|
+
# Install dependencies
|
|
51
|
+
yarn install
|
|
52
|
+
|
|
53
|
+
# Start the API server (usually on port 3000)
|
|
54
|
+
yarn dev
|
|
55
|
+
```
|
|
56
|
+
|
|
21
57
|
### Development
|
|
22
58
|
|
|
23
|
-
Start the development server:
|
|
59
|
+
Start the web development server:
|
|
24
60
|
```bash
|
|
25
61
|
yarn dev
|
|
26
62
|
```
|
|
27
63
|
|
|
28
64
|
The app will be available at `http://localhost:3000`
|
|
29
65
|
|
|
66
|
+
If you have both database and API packages, make sure to start them first before starting the web app for full functionality.
|
|
67
|
+
|
|
30
68
|
### Building for Production
|
|
31
69
|
|
|
32
70
|
Build the app:
|
|
@@ -43,24 +81,41 @@ yarn preview
|
|
|
43
81
|
|
|
44
82
|
```
|
|
45
83
|
{{projectName}}/
|
|
84
|
+
├── packages/
|
|
85
|
+
│ ├── database/ # Database schema and migrations (if included)
|
|
86
|
+
│ ├── api/ # tRPC API server (if included)
|
|
87
|
+
│ ├── shared/ # Shared components and utilities
|
|
88
|
+
│ └── web/ # React web application
|
|
46
89
|
├── src/
|
|
47
|
-
│ ├── App.tsx
|
|
48
|
-
│
|
|
49
|
-
├──
|
|
50
|
-
|
|
51
|
-
|
|
90
|
+
│ ├── App.tsx # Main app component
|
|
91
|
+
│ ├── main.tsx # App entry point
|
|
92
|
+
│ ├── components/ # React components
|
|
93
|
+
│ └── utils/ # Utility functions and tRPC client
|
|
94
|
+
├── index.html # HTML template
|
|
95
|
+
├── vite.config.ts # Vite configuration
|
|
96
|
+
└── tsconfig.json # TypeScript configuration
|
|
52
97
|
```
|
|
53
98
|
|
|
54
99
|
### Features
|
|
55
100
|
|
|
101
|
+
- **Full-Stack Type Safety**: End-to-end TypeScript from database to frontend
|
|
102
|
+
- **tRPC Integration**: Type-safe API calls with automatic TypeScript inference
|
|
103
|
+
- **Database Integration**: Prisma ORM with SQLite for development
|
|
56
104
|
- **Idealyst Components**: Cross-platform UI components
|
|
57
105
|
- **Idealyst Navigation**: Consistent navigation system
|
|
58
106
|
- **Idealyst Theme**: Unified theming across platforms
|
|
59
107
|
- **React 19.1**: Latest React version
|
|
60
108
|
- **Vite**: Fast build tool and dev server
|
|
61
|
-
- **TypeScript**: Full type safety
|
|
62
109
|
- **React Native Web**: Use React Native components on the web
|
|
63
110
|
|
|
111
|
+
### API Demo
|
|
112
|
+
|
|
113
|
+
If your project includes the API demo, you can access it at `/test-demo` to see:
|
|
114
|
+
- Real-time database queries
|
|
115
|
+
- CRUD operations (Create, Read, Update, Delete)
|
|
116
|
+
- Type-safe tRPC integration
|
|
117
|
+
- Form handling with validation
|
|
118
|
+
|
|
64
119
|
### Development
|
|
65
120
|
|
|
66
121
|
The app uses the Idealyst Framework for consistent UI and navigation that works across web and mobile platforms.
|
|
@@ -86,5 +141,7 @@ const styles = createStyleSheet({
|
|
|
86
141
|
### Learn More
|
|
87
142
|
|
|
88
143
|
- [Idealyst Framework Documentation](https://github.com/your-username/idealyst-framework)
|
|
144
|
+
- [tRPC Documentation](https://trpc.io/)
|
|
145
|
+
- [Prisma Documentation](https://prisma.io/)
|
|
89
146
|
- [React Documentation](https://react.dev/)
|
|
90
147
|
- [Vite Documentation](https://vitejs.dev/)
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"@mdi/react": "^1.6.1",
|
|
21
21
|
"@react-native/normalize-colors": "^0.80.1",
|
|
22
22
|
"@tanstack/react-query": "^5.83.0",
|
|
23
|
-
"@trpc/client": "^11.
|
|
24
|
-
"@trpc/react-query": "^11.
|
|
25
|
-
"@trpc/server": "^11.
|
|
23
|
+
"@trpc/client": "^11.5.1",
|
|
24
|
+
"@trpc/react-query": "^11.5.1",
|
|
25
|
+
"@trpc/server": "^11.5.1",
|
|
26
26
|
"@types/react-router-dom": "^5.3.3",
|
|
27
27
|
"compression": "^1.7.4",
|
|
28
28
|
"express": "^4.18.2",
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { App } from '@{{workspaceScope}}/shared';
|
|
2
3
|
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function App() {
|
|
4
|
+
// Main App component using shared App wrapper
|
|
5
|
+
function AppWithTrpcAndShared() {
|
|
7
6
|
return (
|
|
8
|
-
<
|
|
7
|
+
<App
|
|
8
|
+
apiUrl="http://localhost:3000/trpc"
|
|
9
|
+
name="{{projectName}} Developer"
|
|
10
|
+
platform="web"
|
|
11
|
+
projectName="{{projectName}}"
|
|
12
|
+
/>
|
|
9
13
|
);
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
export default
|
|
16
|
+
export default AppWithTrpcAndShared;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View, Text, Card, Button, Input } from '@idealyst/components';
|
|
3
|
+
import { trpc } from '../utils/trpc';
|
|
4
|
+
|
|
5
|
+
export const TestDemo: React.FC = () => {
|
|
6
|
+
const [newTestName, setNewTestName] = useState('');
|
|
7
|
+
const [newTestMessage, setNewTestMessage] = useState('');
|
|
8
|
+
|
|
9
|
+
// tRPC queries and mutations
|
|
10
|
+
const { data: tests, isLoading, refetch } = trpc.test.getAll.useQuery();
|
|
11
|
+
const createTestMutation = trpc.test.create.useMutation({
|
|
12
|
+
onSuccess: () => {
|
|
13
|
+
refetch();
|
|
14
|
+
setNewTestName('');
|
|
15
|
+
setNewTestMessage('');
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const deleteTestMutation = trpc.test.delete.useMutation({
|
|
19
|
+
onSuccess: () => {
|
|
20
|
+
refetch();
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const handleCreateTest = async () => {
|
|
25
|
+
if (!newTestName || !newTestMessage) return;
|
|
26
|
+
|
|
27
|
+
await createTestMutation.mutateAsync({
|
|
28
|
+
name: newTestName,
|
|
29
|
+
message: newTestMessage,
|
|
30
|
+
status: 'active',
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleDeleteTest = async (id: string) => {
|
|
35
|
+
await deleteTestMutation.mutateAsync({ id });
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (isLoading) {
|
|
39
|
+
return (
|
|
40
|
+
<Card variant="outlined" padding="large">
|
|
41
|
+
<Text size="medium">Loading tests...</Text>
|
|
42
|
+
</Card>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<View style={{ gap: 16 }}>
|
|
48
|
+
{/* Header */}
|
|
49
|
+
<Card variant="elevated" padding="large" intent="primary">
|
|
50
|
+
<View style={{ alignItems: 'center' }}>
|
|
51
|
+
<Text style={{ fontSize: 24, marginBottom: 8 }}>🧪</Text>
|
|
52
|
+
<Text size="large" weight="bold" style={{ marginBottom: 8, textAlign: 'center' }}>
|
|
53
|
+
tRPC + Database Test
|
|
54
|
+
</Text>
|
|
55
|
+
<Text size="medium" style={{ textAlign: 'center' }}>
|
|
56
|
+
This demonstrates end-to-end type-safe API calls from the web app to the database.
|
|
57
|
+
</Text>
|
|
58
|
+
</View>
|
|
59
|
+
</Card>
|
|
60
|
+
|
|
61
|
+
{/* Create Test Form */}
|
|
62
|
+
<Card variant="outlined" padding="large">
|
|
63
|
+
<Text size="medium" weight="bold" style={{ marginBottom: 16 }}>
|
|
64
|
+
Create New Test
|
|
65
|
+
</Text>
|
|
66
|
+
|
|
67
|
+
<View style={{ gap: 12 }}>
|
|
68
|
+
<Input
|
|
69
|
+
label="Test Name"
|
|
70
|
+
value={newTestName}
|
|
71
|
+
onChangeText={setNewTestName}
|
|
72
|
+
placeholder="Enter test name"
|
|
73
|
+
/>
|
|
74
|
+
<Input
|
|
75
|
+
label="Test Message"
|
|
76
|
+
value={newTestMessage}
|
|
77
|
+
onChangeText={setNewTestMessage}
|
|
78
|
+
placeholder="Enter test message"
|
|
79
|
+
multiline
|
|
80
|
+
/>
|
|
81
|
+
<Button
|
|
82
|
+
variant="contained"
|
|
83
|
+
intent="primary"
|
|
84
|
+
onPress={handleCreateTest}
|
|
85
|
+
disabled={!newTestName || !newTestMessage || createTestMutation.isPending}
|
|
86
|
+
>
|
|
87
|
+
{createTestMutation.isPending ? 'Creating...' : 'Create Test'}
|
|
88
|
+
</Button>
|
|
89
|
+
</View>
|
|
90
|
+
</Card>
|
|
91
|
+
|
|
92
|
+
{/* Test Results */}
|
|
93
|
+
<Card variant="outlined" padding="large">
|
|
94
|
+
<Text size="medium" weight="bold" style={{ marginBottom: 16 }}>
|
|
95
|
+
Test Entries ({tests?.count || 0})
|
|
96
|
+
</Text>
|
|
97
|
+
|
|
98
|
+
{tests?.data && tests.data.length > 0 ? (
|
|
99
|
+
<View style={{ gap: 12 }}>
|
|
100
|
+
{tests.data.map((test) => (
|
|
101
|
+
<Card key={test.id} variant="filled" padding="medium">
|
|
102
|
+
<View style={{
|
|
103
|
+
flexDirection: 'row',
|
|
104
|
+
justifyContent: 'space-between',
|
|
105
|
+
alignItems: 'flex-start',
|
|
106
|
+
gap: 12
|
|
107
|
+
}}>
|
|
108
|
+
<View style={{ flex: 1 }}>
|
|
109
|
+
<Text size="medium" weight="semibold" style={{ marginBottom: 4 }}>
|
|
110
|
+
{test.name}
|
|
111
|
+
</Text>
|
|
112
|
+
<Text size="small" style={{ marginBottom: 8, opacity: 0.8 }}>
|
|
113
|
+
{test.message}
|
|
114
|
+
</Text>
|
|
115
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
116
|
+
<Card
|
|
117
|
+
variant="filled"
|
|
118
|
+
padding="small"
|
|
119
|
+
intent={test.status === 'active' ? 'success' : 'neutral'}
|
|
120
|
+
>
|
|
121
|
+
<Text size="small" weight="semibold">
|
|
122
|
+
{test.status}
|
|
123
|
+
</Text>
|
|
124
|
+
</Card>
|
|
125
|
+
<Text size="small" style={{ opacity: 0.6 }}>
|
|
126
|
+
{new Date(test.createdAt).toLocaleDateString()}
|
|
127
|
+
</Text>
|
|
128
|
+
</View>
|
|
129
|
+
</View>
|
|
130
|
+
<Button
|
|
131
|
+
variant="outlined"
|
|
132
|
+
intent="error"
|
|
133
|
+
size="small"
|
|
134
|
+
onPress={() => handleDeleteTest(test.id)}
|
|
135
|
+
disabled={deleteTestMutation.isPending}
|
|
136
|
+
>
|
|
137
|
+
Delete
|
|
138
|
+
</Button>
|
|
139
|
+
</View>
|
|
140
|
+
</Card>
|
|
141
|
+
))}
|
|
142
|
+
</View>
|
|
143
|
+
) : (
|
|
144
|
+
<Card variant="filled" padding="medium" style={{ opacity: 0.6 }}>
|
|
145
|
+
<Text size="small" style={{ textAlign: 'center' }}>
|
|
146
|
+
No tests found. Create one above to get started!
|
|
147
|
+
</Text>
|
|
148
|
+
</Card>
|
|
149
|
+
)}
|
|
150
|
+
</Card>
|
|
151
|
+
|
|
152
|
+
{/* Type Safety Info */}
|
|
153
|
+
<Card variant="filled" intent="success" padding="medium">
|
|
154
|
+
<Text size="small" weight="semibold" style={{ marginBottom: 4 }}>
|
|
155
|
+
✨ Type Safety Features:
|
|
156
|
+
</Text>
|
|
157
|
+
<Text size="small">
|
|
158
|
+
• Full TypeScript types from database to frontend • tRPC ensures API type safety •
|
|
159
|
+
Prisma provides database schema validation • Real-time type checking across the stack
|
|
160
|
+
</Text>
|
|
161
|
+
</Card>
|
|
162
|
+
</View>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
@@ -1,93 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type AppRouter = any;
|
|
9
|
-
|
|
10
|
-
// Create the tRPC React hooks
|
|
11
|
-
export const trpc = createTRPCReact<AppRouter>();
|
|
12
|
-
|
|
13
|
-
// Create a vanilla client (for use outside of React components)
|
|
14
|
-
export const trpcClient = createTRPCProxyClient<AppRouter>({
|
|
15
|
-
links: [
|
|
16
|
-
httpBatchLink({
|
|
17
|
-
url: 'http://localhost:3000/trpc', // Update this to match your API URL
|
|
18
|
-
// Optional: Add headers
|
|
19
|
-
// headers() {
|
|
20
|
-
// return {
|
|
21
|
-
// authorization: getAuthToken(),
|
|
22
|
-
// };
|
|
23
|
-
// },
|
|
24
|
-
}),
|
|
25
|
-
],
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
/*
|
|
29
|
-
Usage Examples:
|
|
30
|
-
|
|
31
|
-
1. First, install the required dependencies:
|
|
32
|
-
yarn add @trpc/client @trpc/react-query @tanstack/react-query
|
|
33
|
-
|
|
34
|
-
2. Replace the AppRouter type import above with your actual API router:
|
|
35
|
-
import type { AppRouter } from '@your-workspace/api';
|
|
36
|
-
|
|
37
|
-
3. Set up the tRPC provider in your App component:
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
41
|
-
import { httpBatchLink } from '@trpc/client';
|
|
42
|
-
import { trpc } from './utils/trpc';
|
|
43
|
-
|
|
44
|
-
const queryClient = new QueryClient();
|
|
45
|
-
|
|
46
|
-
const trpcClient = trpc.createClient({
|
|
47
|
-
links: [
|
|
48
|
-
httpBatchLink({
|
|
49
|
-
url: 'http://localhost:3000/trpc',
|
|
50
|
-
}),
|
|
51
|
-
],
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
function App() {
|
|
55
|
-
return (
|
|
56
|
-
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
57
|
-
<QueryClientProvider client={queryClient}>
|
|
58
|
-
// Your app components
|
|
59
|
-
</QueryClientProvider>
|
|
60
|
-
</trpc.Provider>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
4. Use tRPC in your components:
|
|
66
|
-
|
|
67
|
-
```tsx
|
|
68
|
-
import { trpc } from '../utils/trpc';
|
|
69
|
-
|
|
70
|
-
function UsersList() {
|
|
71
|
-
const { data: users, isLoading } = trpc.users.getAll.useQuery();
|
|
72
|
-
const createUser = trpc.users.create.useMutation();
|
|
73
|
-
|
|
74
|
-
if (isLoading) return <div>Loading...</div>;
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<div>
|
|
78
|
-
{users?.map(user => (
|
|
79
|
-
<div key={user.id}>{user.name}</div>
|
|
80
|
-
))}
|
|
81
|
-
<button
|
|
82
|
-
onClick={() => createUser.mutate({
|
|
83
|
-
email: 'test@example.com',
|
|
84
|
-
name: 'Test User'
|
|
85
|
-
})}
|
|
86
|
-
>
|
|
87
|
-
Create User
|
|
88
|
-
</button>
|
|
89
|
-
</div>
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
*/
|
|
1
|
+
// Import tRPC client utilities from shared package
|
|
2
|
+
export {
|
|
3
|
+
trpc,
|
|
4
|
+
createTRPCClient,
|
|
5
|
+
createVanillaTRPCClient
|
|
6
|
+
} from '@{{workspaceScope}}/shared';
|
|
7
|
+
export type { TRPCClientConfig, AppRouter } from '@{{workspaceScope}}/shared';
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
// Forward ports
|
|
8
8
|
"forwardPorts": [
|
|
9
|
-
3000, //
|
|
10
|
-
3001, // API server
|
|
9
|
+
3000, // Api server
|
|
11
10
|
5173, // Vite dev server
|
|
12
|
-
|
|
11
|
+
8081, // Metro Bundler
|
|
13
12
|
19006, // Expo dev tools
|
|
14
13
|
5432, // PostgreSQL
|
|
15
14
|
6379, // Redis
|
|
@@ -19,10 +18,6 @@
|
|
|
19
18
|
// Port attributes
|
|
20
19
|
"portsAttributes": {
|
|
21
20
|
"3000": {
|
|
22
|
-
"label": "Web App",
|
|
23
|
-
"onAutoForward": "openBrowser"
|
|
24
|
-
},
|
|
25
|
-
"3001": {
|
|
26
21
|
"label": "API Server",
|
|
27
22
|
"onAutoForward": "notify"
|
|
28
23
|
},
|
|
@@ -30,8 +25,8 @@
|
|
|
30
25
|
"label": "Vite Dev Server",
|
|
31
26
|
"onAutoForward": "openBrowser"
|
|
32
27
|
},
|
|
33
|
-
"
|
|
34
|
-
"label": "
|
|
28
|
+
"8081": {
|
|
29
|
+
"label": "Metro Bundler",
|
|
35
30
|
"onAutoForward": "notify"
|
|
36
31
|
},
|
|
37
32
|
"19006": {
|
|
@@ -45,13 +45,13 @@ COPY --from=builder /app/node_modules ./node_modules
|
|
|
45
45
|
COPY --from=builder /app/package.json ./
|
|
46
46
|
|
|
47
47
|
USER apiuser
|
|
48
|
-
EXPOSE
|
|
48
|
+
EXPOSE 3000
|
|
49
49
|
ENV NODE_ENV=production
|
|
50
|
-
ENV PORT=
|
|
50
|
+
ENV PORT=3000
|
|
51
51
|
|
|
52
52
|
# Health check for API
|
|
53
53
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
54
|
-
CMD node -e "require('http').get('http://localhost:
|
|
54
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
|
|
55
55
|
|
|
56
56
|
CMD ["node", "packages/api/dist/server.js"]
|
|
57
57
|
|
|
@@ -98,7 +98,7 @@ COPY --chown=devuser:devuser packages/web/package.json ./packages/web/
|
|
|
98
98
|
# Install dependencies including dev dependencies
|
|
99
99
|
RUN yarn install
|
|
100
100
|
|
|
101
|
-
EXPOSE 3000
|
|
101
|
+
EXPOSE 3000 5173 1 19006
|
|
102
102
|
|
|
103
103
|
CMD ["tail", "-f", "/dev/null"]
|
|
104
104
|
|
|
@@ -76,8 +76,8 @@ http {
|
|
|
76
76
|
# Upstream servers with load balancing
|
|
77
77
|
upstream api_backend {
|
|
78
78
|
least_conn;
|
|
79
|
-
server {{PROJECT_NAME}}-api-1:
|
|
80
|
-
server {{PROJECT_NAME}}-api-2:
|
|
79
|
+
server {{PROJECT_NAME}}-api-1:3000 max_fails=3 fail_timeout=30s weight=1;
|
|
80
|
+
server {{PROJECT_NAME}}-api-2:3000 max_fails=3 fail_timeout=30s weight=1;
|
|
81
81
|
keepalive 32;
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -47,11 +47,11 @@ services:
|
|
|
47
47
|
container_name: ${PROJECT_NAME:-idealyst}-api
|
|
48
48
|
environment:
|
|
49
49
|
NODE_ENV: ${NODE_ENV:-production}
|
|
50
|
-
PORT:
|
|
50
|
+
PORT: 3000
|
|
51
51
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-idealyst_db}
|
|
52
52
|
REDIS_URL: redis://redis:6379
|
|
53
53
|
ports:
|
|
54
|
-
- "${API_PORT:-
|
|
54
|
+
- "${API_PORT:-3000}:3000"
|
|
55
55
|
depends_on:
|
|
56
56
|
postgres:
|
|
57
57
|
condition: service_healthy
|
|
@@ -61,7 +61,7 @@ services:
|
|
|
61
61
|
- ./uploads:/app/uploads
|
|
62
62
|
restart: unless-stopped
|
|
63
63
|
healthcheck:
|
|
64
|
-
test: ["CMD", "curl", "-f", "http://localhost:
|
|
64
|
+
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
65
65
|
interval: 30s
|
|
66
66
|
timeout: 10s
|
|
67
67
|
retries: 5
|
|
@@ -98,8 +98,7 @@ services:
|
|
|
98
98
|
environment:
|
|
99
99
|
NODE_ENV: development
|
|
100
100
|
ports:
|
|
101
|
-
- "3000:3000" #
|
|
102
|
-
- "3001:3001" # API dev server
|
|
101
|
+
- "3000:3000" # API dev server
|
|
103
102
|
- "5173:5173" # Vite dev server
|
|
104
103
|
- "8080:8080" # Additional dev server
|
|
105
104
|
- "19006:19006" # Expo dev tools
|