@idealyst/cli 1.0.32 → 1.0.34
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/api.js +28 -25
- package/dist/generators/api.js.map +1 -1
- package/dist/generators/index.js +33 -16
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/native.js +51 -48
- package/dist/generators/native.js.map +1 -1
- package/dist/generators/shared.js +25 -22
- package/dist/generators/shared.js.map +1 -1
- package/dist/generators/utils.js +146 -118
- package/dist/generators/utils.js.map +1 -1
- package/dist/generators/web.js +33 -30
- package/dist/generators/web.js.map +1 -1
- package/dist/generators/workspace.js +24 -21
- package/dist/generators/workspace.js.map +1 -1
- package/dist/index.js +82 -44
- package/dist/index.js.map +1 -1
- package/dist/templates/api/README.md +207 -0
- package/dist/templates/api/__tests__/api.test.ts +26 -0
- package/dist/templates/api/env.example +12 -0
- package/dist/templates/api/jest.config.js +23 -0
- package/dist/templates/api/jest.setup.js +9 -0
- package/dist/templates/api/package.json +62 -0
- package/dist/templates/api/prisma/schema.prisma +21 -0
- package/dist/templates/api/src/context.ts +23 -0
- package/dist/templates/api/src/controllers/UserController.ts +102 -0
- package/dist/templates/api/src/index.ts +14 -0
- package/dist/templates/api/src/lib/controller.ts +90 -0
- package/dist/templates/api/src/lib/middleware.ts +170 -0
- package/dist/templates/api/src/middleware/auth.ts +75 -0
- package/dist/templates/api/src/middleware/common.ts +103 -0
- package/dist/templates/api/src/router/index.ts +130 -0
- package/dist/templates/api/src/server.ts +50 -0
- package/dist/templates/api/src/trpc.ts +28 -0
- package/dist/templates/api/tsconfig.json +44 -0
- package/dist/templates/native/.yarnrc.yml +19 -0
- package/dist/templates/native/App.tsx +23 -0
- package/dist/templates/native/README.md +86 -0
- package/dist/templates/native/__tests__/App.test.tsx +156 -0
- package/dist/templates/native/__tests__/components.test.tsx +300 -0
- package/dist/templates/native/app.json +5 -0
- package/dist/templates/native/babel.config.js +10 -0
- package/dist/templates/native/index.js +6 -0
- package/dist/templates/native/jest.config.js +21 -0
- package/dist/templates/native/jest.setup.js +12 -0
- package/dist/templates/native/metro.config.js +27 -0
- package/dist/templates/native/package.json +44 -0
- package/dist/templates/native/src/App-with-trpc.tsx +59 -0
- package/dist/templates/native/src/utils/trpc.ts +127 -0
- package/dist/templates/native/tsconfig.json +30 -0
- package/dist/templates/shared/README.md +109 -0
- package/dist/templates/shared/__tests__/shared.test.ts +39 -0
- package/dist/templates/shared/jest.config.js +22 -0
- package/dist/templates/shared/package.json +50 -0
- package/dist/templates/shared/rollup.config.js +43 -0
- package/dist/templates/shared/src/index.ts +1 -0
- package/dist/templates/shared/tsconfig.json +25 -0
- package/dist/templates/web/README.md +90 -0
- package/dist/templates/web/__tests__/App.test.tsx +342 -0
- package/dist/templates/web/__tests__/components.test.tsx +564 -0
- package/dist/templates/web/index.html +13 -0
- package/dist/templates/web/jest.config.js +27 -0
- package/dist/templates/web/jest.setup.js +24 -0
- package/dist/templates/web/package.json +66 -0
- package/dist/templates/web/src/App-with-trpc.tsx +67 -0
- package/dist/templates/web/src/App.tsx +15 -0
- package/dist/templates/web/src/main.tsx +25 -0
- package/dist/templates/web/src/utils/trpc.ts +93 -0
- package/dist/templates/web/tsconfig.json +27 -0
- package/dist/templates/web/vite.config.ts +69 -0
- package/dist/templates/workspace/.devcontainer/devcontainer.json +140 -0
- package/dist/templates/workspace/.devcontainer/docker-compose.yml +74 -0
- package/dist/templates/workspace/.devcontainer/post-create.sh +89 -0
- package/dist/templates/workspace/.dockerignore +151 -0
- package/dist/templates/workspace/.env.example +36 -0
- package/dist/templates/workspace/.env.production +56 -0
- package/dist/templates/workspace/.yarnrc.yml +26 -0
- package/dist/templates/workspace/DOCKER.md +0 -0
- package/dist/templates/workspace/Dockerfile +93 -0
- package/dist/templates/workspace/README.md +179 -0
- package/dist/templates/workspace/docker/nginx/prod.conf +238 -0
- package/dist/templates/workspace/docker/nginx.conf +131 -0
- package/dist/templates/workspace/docker/postgres/init.sql +41 -0
- package/dist/templates/workspace/docker/prometheus/prometheus.yml +52 -0
- package/dist/templates/workspace/docker-compose.prod.yml +146 -0
- package/dist/templates/workspace/docker-compose.yml +144 -0
- package/dist/templates/workspace/jest.config.js +20 -0
- package/dist/templates/workspace/package.json +35 -0
- package/dist/templates/workspace/scripts/docker/db-backup.sh +230 -0
- package/dist/templates/workspace/scripts/docker/deploy.sh +212 -0
- package/dist/templates/workspace/scripts/docker-build.sh +151 -0
- package/dist/templates/workspace/scripts/test-runner.js +120 -0
- package/dist/templates/workspace/setup.sh +205 -0
- package/dist/types.js +2 -1
- package/package.json +3 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
3
|
+
import { httpBatchLink } from '@trpc/client';
|
|
4
|
+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
5
|
+
import { trpc } from './utils/trpc';
|
|
6
|
+
import { Screen, Text, View } from '@idealyst/components';
|
|
7
|
+
|
|
8
|
+
// Create tRPC client
|
|
9
|
+
const queryClient = new QueryClient();
|
|
10
|
+
|
|
11
|
+
const trpcClient = trpc.createClient({
|
|
12
|
+
links: [
|
|
13
|
+
httpBatchLink({
|
|
14
|
+
url: 'http://localhost:3000/trpc', // Update this to match your API URL
|
|
15
|
+
// Optional: Add headers for authentication
|
|
16
|
+
// headers() {
|
|
17
|
+
// return {
|
|
18
|
+
// authorization: getAuthToken(),
|
|
19
|
+
// };
|
|
20
|
+
// },
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function HomePage() {
|
|
26
|
+
// Example tRPC usage
|
|
27
|
+
const { data, isLoading, error } = trpc.hello.useQuery({ name: 'World' });
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Screen>
|
|
31
|
+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
32
|
+
<Text variant="h1">Welcome to {{projectName}}!</Text>
|
|
33
|
+
<Text variant="body">
|
|
34
|
+
This is a React Web app built with the Idealyst Framework
|
|
35
|
+
</Text>
|
|
36
|
+
|
|
37
|
+
{/* tRPC Example */}
|
|
38
|
+
<View style={{ marginTop: 20 }}>
|
|
39
|
+
<Text variant="h3">tRPC Example:</Text>
|
|
40
|
+
{isLoading && <Text>Loading...</Text>}
|
|
41
|
+
{error && <Text>Error: {error.message}</Text>}
|
|
42
|
+
{data && <Text>{data.greeting}</Text>}
|
|
43
|
+
</View>
|
|
44
|
+
|
|
45
|
+
<Text variant="caption" style={{ marginTop: 20 }}>
|
|
46
|
+
Edit src/App.tsx to get started
|
|
47
|
+
</Text>
|
|
48
|
+
</View>
|
|
49
|
+
</Screen>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function App() {
|
|
54
|
+
return (
|
|
55
|
+
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
|
56
|
+
<QueryClientProvider client={queryClient}>
|
|
57
|
+
<BrowserRouter>
|
|
58
|
+
<Routes>
|
|
59
|
+
<Route path="/" element={<HomePage />} />
|
|
60
|
+
</Routes>
|
|
61
|
+
</BrowserRouter>
|
|
62
|
+
</QueryClientProvider>
|
|
63
|
+
</trpc.Provider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default App;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
2
|
+
import { ExampleStackRouter, } from '@idealyst/navigation/examples';
|
|
3
|
+
import { NavigatorProvider } from '@idealyst/navigation';
|
|
4
|
+
|
|
5
|
+
function App() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="App">
|
|
8
|
+
<BrowserRouter>
|
|
9
|
+
<NavigatorProvider route={ExampleStackRouter} />
|
|
10
|
+
</BrowserRouter>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default App;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import '@idealyst/navigation/examples/unistyles';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import ReactDOM from 'react-dom/client';
|
|
5
|
+
import App from './App.tsx';
|
|
6
|
+
|
|
7
|
+
// Hydrate the app if it's SSR, otherwise render normally
|
|
8
|
+
const container = document.getElementById('root')!;
|
|
9
|
+
|
|
10
|
+
if (container.hasChildNodes()) {
|
|
11
|
+
// If the container has child nodes, it means we're hydrating SSR content
|
|
12
|
+
ReactDOM.hydrateRoot(container,
|
|
13
|
+
<React.StrictMode>
|
|
14
|
+
<App />
|
|
15
|
+
</React.StrictMode>
|
|
16
|
+
);
|
|
17
|
+
} else {
|
|
18
|
+
// Otherwise, render normally (for development)
|
|
19
|
+
const root = ReactDOM.createRoot(container);
|
|
20
|
+
root.render(
|
|
21
|
+
<React.StrictMode>
|
|
22
|
+
<App />
|
|
23
|
+
</React.StrictMode>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createTRPCReact } from '@trpc/react-query';
|
|
2
|
+
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
|
3
|
+
|
|
4
|
+
// Import your API types here when you have an API project
|
|
5
|
+
// Example: import type { AppRouter } from '@your-workspace/api';
|
|
6
|
+
|
|
7
|
+
// For now, we'll use a generic type that you can replace
|
|
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
|
+
*/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"moduleResolution": "node",
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"moduleDetection": "force",
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"jsx": "react-jsx",
|
|
13
|
+
"strict": true,
|
|
14
|
+
"noUnusedLocals": true,
|
|
15
|
+
"noUnusedParameters": true,
|
|
16
|
+
"noFallthroughCasesInSwitch": true,
|
|
17
|
+
"noUncheckedIndexedAccess": true,
|
|
18
|
+
"baseUrl": ".",
|
|
19
|
+
"paths": {
|
|
20
|
+
"@/*": ["./src/*"],
|
|
21
|
+
"react-native": ["node_modules/react-native-web"]
|
|
22
|
+
},
|
|
23
|
+
"types": ["vite/client"]
|
|
24
|
+
},
|
|
25
|
+
"include": ["src/**/*"],
|
|
26
|
+
"exclude": ["node_modules", "dist"]
|
|
27
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
import babel from 'vite-plugin-babel'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
|
|
6
|
+
// https://vitejs.dev/config/
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [
|
|
9
|
+
babel({
|
|
10
|
+
filter: (id) => id.includes('node_modules/@idealyst/') && /\.(js|jsx|ts|tsx)$/.test(id),
|
|
11
|
+
babelConfig: {
|
|
12
|
+
presets: [
|
|
13
|
+
['@babel/preset-typescript', {
|
|
14
|
+
isTSX: true,
|
|
15
|
+
allExtensions: true,
|
|
16
|
+
}]
|
|
17
|
+
],
|
|
18
|
+
plugins: [
|
|
19
|
+
['react-native-unistyles/plugin', {
|
|
20
|
+
root: 'src',
|
|
21
|
+
autoProcessPaths: ['@idealyst/components', '@idealyst/navigation', '@idealyst/theme'],
|
|
22
|
+
}],
|
|
23
|
+
['@idealyst/components/plugin/web', { root: 'src' }]
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}),
|
|
27
|
+
// Then process everything else with React plugin
|
|
28
|
+
react(),
|
|
29
|
+
],
|
|
30
|
+
resolve: {
|
|
31
|
+
alias: {
|
|
32
|
+
// Use absolute path to resolve react-native-web properly
|
|
33
|
+
'react-native': path.resolve(__dirname, 'node_modules/react-native-web'),
|
|
34
|
+
'@react-native/normalize-colors': path.resolve(__dirname, 'node_modules/@react-native/normalize-colors'),
|
|
35
|
+
},
|
|
36
|
+
// Platform-specific file resolution
|
|
37
|
+
extensions: ['.web.tsx', '.web.ts', '.tsx', '.ts', '.js', '.jsx'],
|
|
38
|
+
// Ensure proper resolution of package exports
|
|
39
|
+
conditions: ['browser', 'import', 'module', 'default'],
|
|
40
|
+
// Ensure workspace dependencies resolve properly
|
|
41
|
+
preserveSymlinks: false
|
|
42
|
+
},
|
|
43
|
+
define: {
|
|
44
|
+
global: 'globalThis',
|
|
45
|
+
__DEV__: JSON.stringify(true),
|
|
46
|
+
},
|
|
47
|
+
optimizeDeps: {
|
|
48
|
+
include: [
|
|
49
|
+
'react-native-web',
|
|
50
|
+
'@react-native/normalize-colors',
|
|
51
|
+
'react-native-unistyles',
|
|
52
|
+
'react-native-unistyles/web',
|
|
53
|
+
'@mdi/react',
|
|
54
|
+
'@mdi/js',
|
|
55
|
+
],
|
|
56
|
+
exclude: [
|
|
57
|
+
'react-native-edge-to-edge',
|
|
58
|
+
'react-native-nitro-modules',
|
|
59
|
+
'@idealyst/components',
|
|
60
|
+
'@idealyst/navigation',
|
|
61
|
+
'@idealyst/theme',
|
|
62
|
+
'@testproject/shared',
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
server: {
|
|
66
|
+
host: '0.0.0.0',
|
|
67
|
+
port: 5173,
|
|
68
|
+
},
|
|
69
|
+
})
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Idealyst Development Environment",
|
|
3
|
+
"dockerComposeFile": ["./docker-compose.yml"],
|
|
4
|
+
"service": "dev",
|
|
5
|
+
"workspaceFolder": "/app",
|
|
6
|
+
"shutdownAction": "stopCompose",
|
|
7
|
+
|
|
8
|
+
// VS Code configuration
|
|
9
|
+
"customizations": {
|
|
10
|
+
"vscode": {
|
|
11
|
+
"settings": {
|
|
12
|
+
"terminal.integrated.shell.linux": "/bin/bash",
|
|
13
|
+
"typescript.preferences.includePackageJsonAutoImports": "auto",
|
|
14
|
+
"editor.formatOnSave": true,
|
|
15
|
+
"editor.codeActionsOnSave": {
|
|
16
|
+
"source.fixAll.eslint": "explicit",
|
|
17
|
+
"source.organizeImports": "explicit"
|
|
18
|
+
},
|
|
19
|
+
"files.watcherExclude": {
|
|
20
|
+
"**/node_modules/**": true,
|
|
21
|
+
"**/.git/**": true,
|
|
22
|
+
"**/dist/**": true,
|
|
23
|
+
"**/coverage/**": true
|
|
24
|
+
},
|
|
25
|
+
"search.exclude": {
|
|
26
|
+
"**/node_modules": true,
|
|
27
|
+
"**/dist": true,
|
|
28
|
+
"**/coverage": true,
|
|
29
|
+
"**/.yarn": true
|
|
30
|
+
},
|
|
31
|
+
"typescript.preferences.importModuleSpecifier": "relative",
|
|
32
|
+
"jest.jestCommandLine": "yarn test",
|
|
33
|
+
"jest.autoRun": "off"
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
// Extensions to install
|
|
37
|
+
"extensions": [
|
|
38
|
+
"ms-vscode.vscode-typescript-next",
|
|
39
|
+
"bradlc.vscode-tailwindcss",
|
|
40
|
+
"esbenp.prettier-vscode",
|
|
41
|
+
"dbaeumer.vscode-eslint",
|
|
42
|
+
"ms-vscode.vscode-json",
|
|
43
|
+
"ms-vscode.test-adapter-converter",
|
|
44
|
+
"orta.vscode-jest",
|
|
45
|
+
"ms-vscode.vscode-npm-script",
|
|
46
|
+
"christian-kohler.path-intellisense",
|
|
47
|
+
"formulahendry.auto-rename-tag",
|
|
48
|
+
"bradlc.vscode-tailwindcss",
|
|
49
|
+
"ms-vscode.vscode-docker",
|
|
50
|
+
"ms-azuretools.vscode-docker",
|
|
51
|
+
"redhat.vscode-yaml",
|
|
52
|
+
"ms-vscode.vscode-markdown",
|
|
53
|
+
"yzhang.markdown-all-in-one",
|
|
54
|
+
"davidanson.vscode-markdownlint",
|
|
55
|
+
"ms-vscode.vscode-git-graph",
|
|
56
|
+
"eamodio.gitlens",
|
|
57
|
+
"github.vscode-pull-request-github",
|
|
58
|
+
"github.copilot",
|
|
59
|
+
"github.copilot-chat",
|
|
60
|
+
"ms-vscode.vscode-react-native",
|
|
61
|
+
"msjsdiag.vscode-react-native"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// Development container features
|
|
67
|
+
"features": {
|
|
68
|
+
"ghcr.io/devcontainers/features/git:1": {
|
|
69
|
+
"ppa": true,
|
|
70
|
+
"version": "latest"
|
|
71
|
+
},
|
|
72
|
+
"ghcr.io/devcontainers/features/github-cli:1": {
|
|
73
|
+
"version": "latest"
|
|
74
|
+
},
|
|
75
|
+
"ghcr.io/devcontainers/features/common-utils:2": {
|
|
76
|
+
"installZsh": true,
|
|
77
|
+
"configureZshAsDefaultShell": true,
|
|
78
|
+
"installOhMyZsh": true,
|
|
79
|
+
"username": "devuser",
|
|
80
|
+
"userUid": 1001,
|
|
81
|
+
"userGid": 1001
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// Port forwarding for development servers
|
|
86
|
+
"forwardPorts": [
|
|
87
|
+
3000, // Web dev server
|
|
88
|
+
3001, // API server
|
|
89
|
+
5173, // Vite dev server
|
|
90
|
+
8080, // Additional dev server
|
|
91
|
+
19006, // Expo dev tools
|
|
92
|
+
5432, // PostgreSQL
|
|
93
|
+
6379 // Redis
|
|
94
|
+
],
|
|
95
|
+
|
|
96
|
+
"portsAttributes": {
|
|
97
|
+
"3000": {
|
|
98
|
+
"label": "Web App",
|
|
99
|
+
"onAutoForward": "openBrowser"
|
|
100
|
+
},
|
|
101
|
+
"3001": {
|
|
102
|
+
"label": "API Server",
|
|
103
|
+
"onAutoForward": "silent"
|
|
104
|
+
},
|
|
105
|
+
"5173": {
|
|
106
|
+
"label": "Vite Dev Server",
|
|
107
|
+
"onAutoForward": "openBrowser"
|
|
108
|
+
},
|
|
109
|
+
"19006": {
|
|
110
|
+
"label": "Expo Dev Tools",
|
|
111
|
+
"onAutoForward": "openBrowser"
|
|
112
|
+
},
|
|
113
|
+
"5432": {
|
|
114
|
+
"label": "PostgreSQL",
|
|
115
|
+
"onAutoForward": "silent"
|
|
116
|
+
},
|
|
117
|
+
"6379": {
|
|
118
|
+
"label": "Redis",
|
|
119
|
+
"onAutoForward": "silent"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// Post-create commands
|
|
124
|
+
"postCreateCommand": "bash .devcontainer/post-create.sh",
|
|
125
|
+
|
|
126
|
+
// Development user
|
|
127
|
+
"remoteUser": "devuser",
|
|
128
|
+
|
|
129
|
+
// Environment variables
|
|
130
|
+
"remoteEnv": {
|
|
131
|
+
"NODE_ENV": "development",
|
|
132
|
+
"DATABASE_URL": "postgresql://postgres:postgres@postgres:5432/idealyst_db",
|
|
133
|
+
"REDIS_URL": "redis://redis:6379"
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
// Mount the workspace with proper permissions
|
|
137
|
+
"mounts": [
|
|
138
|
+
"source=${localWorkspaceFolder},target=/app,type=bind,consistency=cached"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
services:
|
|
2
|
+
# PostgreSQL Database
|
|
3
|
+
postgres:
|
|
4
|
+
image: postgres:15-alpine
|
|
5
|
+
container_name: ${PROJECT_NAME:-truday}-postgres
|
|
6
|
+
environment:
|
|
7
|
+
POSTGRES_DB: ${POSTGRES_DB:-idealyst_db}
|
|
8
|
+
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
9
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
|
|
10
|
+
ports:
|
|
11
|
+
- "${POSTGRES_PORT:-5432}:5432"
|
|
12
|
+
volumes:
|
|
13
|
+
- postgres_data:/var/lib/postgresql/data
|
|
14
|
+
- ../docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
|
|
15
|
+
healthcheck:
|
|
16
|
+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
|
|
17
|
+
interval: 30s
|
|
18
|
+
timeout: 10s
|
|
19
|
+
retries: 5
|
|
20
|
+
networks:
|
|
21
|
+
- idealyst-network
|
|
22
|
+
|
|
23
|
+
# Redis Cache
|
|
24
|
+
redis:
|
|
25
|
+
image: redis:7-alpine
|
|
26
|
+
container_name: ${PROJECT_NAME:-truday}-redis
|
|
27
|
+
ports:
|
|
28
|
+
- "${REDIS_PORT:-6379}:6379"
|
|
29
|
+
volumes:
|
|
30
|
+
- redis_data:/data
|
|
31
|
+
healthcheck:
|
|
32
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
33
|
+
interval: 30s
|
|
34
|
+
timeout: 10s
|
|
35
|
+
retries: 5
|
|
36
|
+
networks:
|
|
37
|
+
- idealyst-network
|
|
38
|
+
|
|
39
|
+
# Development Service (for devcontainer)
|
|
40
|
+
dev:
|
|
41
|
+
build:
|
|
42
|
+
context: ..
|
|
43
|
+
dockerfile: Dockerfile
|
|
44
|
+
target: dev
|
|
45
|
+
container_name: ${PROJECT_NAME:-truday}-dev
|
|
46
|
+
environment:
|
|
47
|
+
NODE_ENV: development
|
|
48
|
+
ports:
|
|
49
|
+
- "3000:3000" # Web dev server
|
|
50
|
+
- "3001:3001" # API dev server
|
|
51
|
+
- "5173:5173" # Vite dev server
|
|
52
|
+
- "8080:8080" # Additional dev server
|
|
53
|
+
- "19006:19006" # Expo dev tools
|
|
54
|
+
volumes:
|
|
55
|
+
- ..:/app
|
|
56
|
+
- /app/node_modules
|
|
57
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
58
|
+
depends_on:
|
|
59
|
+
postgres:
|
|
60
|
+
condition: service_healthy
|
|
61
|
+
redis:
|
|
62
|
+
condition: service_healthy
|
|
63
|
+
networks:
|
|
64
|
+
- idealyst-network
|
|
65
|
+
tty: true
|
|
66
|
+
stdin_open: true
|
|
67
|
+
|
|
68
|
+
volumes:
|
|
69
|
+
postgres_data:
|
|
70
|
+
redis_data:
|
|
71
|
+
|
|
72
|
+
networks:
|
|
73
|
+
idealyst-network:
|
|
74
|
+
driver: bridge
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Post-create script for Idealyst dev container
|
|
4
|
+
echo "🚀 Setting up Idealyst development environment..."
|
|
5
|
+
|
|
6
|
+
# Set proper permissions
|
|
7
|
+
sudo chown -R devuser:devuser /app
|
|
8
|
+
|
|
9
|
+
# Make scripts executable
|
|
10
|
+
chmod +x /app/scripts/*.sh
|
|
11
|
+
|
|
12
|
+
# Install dependencies if not already installed
|
|
13
|
+
if [ ! -d "/app/node_modules" ]; then
|
|
14
|
+
echo "📦 Installing dependencies..."
|
|
15
|
+
yarn install
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Set up git configuration (if not already set)
|
|
19
|
+
if [ -z "$(git config --global user.name)" ]; then
|
|
20
|
+
echo "⚙️ Please configure git:"
|
|
21
|
+
echo " git config --global user.name \"Your Name\""
|
|
22
|
+
echo " git config --global user.email \"your.email@example.com\""
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Create environment file if it doesn't exist
|
|
26
|
+
if [ ! -f "/app/.env" ]; then
|
|
27
|
+
echo "📝 Creating .env file..."
|
|
28
|
+
cat > /app/.env << EOF
|
|
29
|
+
# Database Configuration
|
|
30
|
+
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/idealyst_db
|
|
31
|
+
POSTGRES_DB=idealyst_db
|
|
32
|
+
POSTGRES_USER=postgres
|
|
33
|
+
POSTGRES_PASSWORD=postgres
|
|
34
|
+
|
|
35
|
+
# Redis Configuration
|
|
36
|
+
REDIS_URL=redis://redis:6379
|
|
37
|
+
|
|
38
|
+
# API Configuration
|
|
39
|
+
API_PORT=3001
|
|
40
|
+
JWT_SECRET=your-jwt-secret-here
|
|
41
|
+
|
|
42
|
+
# Web Configuration
|
|
43
|
+
WEB_PORT=3000
|
|
44
|
+
|
|
45
|
+
# Development Configuration
|
|
46
|
+
NODE_ENV=development
|
|
47
|
+
LOG_LEVEL=debug
|
|
48
|
+
|
|
49
|
+
# Project Configuration
|
|
50
|
+
PROJECT_NAME={{packageName}}
|
|
51
|
+
EOF
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Wait for database to be ready
|
|
55
|
+
echo "⏳ Waiting for database to be ready..."
|
|
56
|
+
until pg_isready -h postgres -p 5432 -U postgres; do
|
|
57
|
+
echo "Database is unavailable - sleeping"
|
|
58
|
+
sleep 1
|
|
59
|
+
done
|
|
60
|
+
|
|
61
|
+
echo "✅ Database is ready!"
|
|
62
|
+
|
|
63
|
+
# Run database migrations if they exist
|
|
64
|
+
if [ -d "/app/packages" ]; then
|
|
65
|
+
echo "🗄️ Setting up database..."
|
|
66
|
+
|
|
67
|
+
# Check if any package has prisma
|
|
68
|
+
for package_dir in /app/packages/*/; do
|
|
69
|
+
if [ -f "${package_dir}prisma/schema.prisma" ]; then
|
|
70
|
+
echo "Running Prisma setup for $(basename "$package_dir")..."
|
|
71
|
+
cd "$package_dir"
|
|
72
|
+
npx prisma generate
|
|
73
|
+
npx prisma db push
|
|
74
|
+
cd /app
|
|
75
|
+
fi
|
|
76
|
+
done
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Set up git hooks if husky is present
|
|
80
|
+
if [ -f "/app/package.json" ] && grep -q "husky" /app/package.json; then
|
|
81
|
+
echo "🐕 Setting up git hooks..."
|
|
82
|
+
yarn husky install
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Create helpful aliases
|
|
86
|
+
echo "⚡ Setting up helpful aliases..."
|
|
87
|
+
cat >> ~/.bashrc << EOF
|
|
88
|
+
|
|
89
|
+
source ~/.bashrc
|