@idealyst/cli 1.0.91 → 1.0.93

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.
Files changed (71) hide show
  1. package/dist/generators/init.js +8 -13
  2. package/dist/generators/init.js.map +1 -1
  3. package/dist/generators/utils.js +3 -7
  4. package/dist/generators/utils.js.map +1 -1
  5. package/dist/template/.devcontainer/gitignore.template +2 -0
  6. package/dist/template/gitignore.template +56 -0
  7. package/dist/template/mcp.json.template +8 -0
  8. package/dist/template/packages/api/README.md +400 -164
  9. package/dist/template/packages/api/gitignore.template +35 -0
  10. package/dist/template/packages/api/package.json +11 -1
  11. package/dist/template/packages/api/src/context.ts +35 -2
  12. package/dist/template/packages/api/src/graphql/builder.ts +75 -0
  13. package/dist/template/packages/api/src/graphql/generated.ts +64 -0
  14. package/dist/template/packages/api/src/graphql/index.ts +75 -0
  15. package/dist/template/packages/api/src/graphql/types/index.ts +44 -0
  16. package/dist/template/packages/api/src/graphql/types/test.ts +245 -0
  17. package/dist/template/packages/api/src/index.ts +20 -3
  18. package/dist/template/packages/api/src/lib/database.ts +1 -1
  19. package/dist/template/packages/api/src/routers/test.ts +140 -38
  20. package/dist/template/packages/api/src/server.ts +23 -5
  21. package/dist/template/packages/api/tsconfig.json +1 -0
  22. package/dist/template/packages/database/gitignore.template +41 -0
  23. package/dist/template/packages/mobile/babel.config.js +1 -2
  24. package/dist/template/packages/mobile/gitignore.template +73 -0
  25. package/dist/template/packages/mobile/package.json +10 -2
  26. package/dist/template/packages/shared/gitignore.template +35 -0
  27. package/dist/template/packages/shared/package.json +6 -0
  28. package/dist/template/packages/shared/src/components/App.tsx +13 -2
  29. package/dist/template/packages/shared/src/components/HelloWorld.tsx +333 -106
  30. package/dist/template/packages/shared/src/graphql/client.ts +34 -0
  31. package/dist/template/packages/shared/src/index.ts +8 -0
  32. package/dist/template/packages/web/gitignore.template +35 -0
  33. package/dist/template/packages/web/vite.config.ts +2 -2
  34. package/dist/template/yarnrc.yml.template +4 -0
  35. package/package.json +1 -1
  36. package/template/packages/api/README.md +400 -164
  37. package/template/packages/api/package.json +11 -1
  38. package/template/packages/api/src/context.ts +35 -2
  39. package/template/packages/api/src/graphql/builder.ts +75 -0
  40. package/template/packages/api/src/graphql/generated.ts +64 -0
  41. package/template/packages/api/src/graphql/index.ts +75 -0
  42. package/template/packages/api/src/graphql/types/index.ts +44 -0
  43. package/template/packages/api/src/graphql/types/test.ts +245 -0
  44. package/template/packages/api/src/index.ts +20 -3
  45. package/template/packages/api/src/lib/database.ts +1 -1
  46. package/template/packages/api/src/routers/test.ts +140 -38
  47. package/template/packages/api/src/server.ts +23 -5
  48. package/template/packages/api/tsconfig.json +1 -0
  49. package/template/packages/mobile/babel.config.js +1 -2
  50. package/template/packages/mobile/package.json +10 -2
  51. package/template/packages/shared/package.json +6 -0
  52. package/template/packages/shared/src/components/App.tsx +13 -2
  53. package/template/packages/shared/src/components/HelloWorld.tsx +333 -106
  54. package/template/packages/shared/src/graphql/client.ts +34 -0
  55. package/template/packages/shared/src/index.ts +8 -0
  56. package/template/packages/web/vite.config.ts +2 -2
  57. package/dist/template/packages/api/src/lib/crud.ts +0 -150
  58. package/dist/template/packages/api/src/routers/user.example.ts +0 -83
  59. package/dist/template/packages/mobile/src/App-with-trpc-and-shared.tsx +0 -8
  60. package/dist/template/packages/mobile/src/App-with-trpc.tsx +0 -30
  61. package/dist/template/packages/web/src/App-with-trpc-and-shared.tsx +0 -14
  62. package/dist/template/packages/web/src/App-with-trpc.tsx +0 -32
  63. package/template/packages/api/src/lib/crud.ts +0 -150
  64. package/template/packages/api/src/routers/user.example.ts +0 -83
  65. package/template/packages/mobile/src/App-with-trpc-and-shared.tsx +0 -8
  66. package/template/packages/mobile/src/App-with-trpc.tsx +0 -30
  67. package/template/packages/web/src/App-with-trpc-and-shared.tsx +0 -14
  68. package/template/packages/web/src/App-with-trpc.tsx +0 -32
  69. /package/dist/template/{.dockerignore → dockerignore.template} +0 -0
  70. /package/dist/template/{.env.example → env.example.template} +0 -0
  71. /package/dist/template/packages/api/{.env.example → env.example.template} +0 -0
@@ -1,57 +1,159 @@
1
- import { z } from "zod";
2
- import { createCrudRouter } from "../lib/crud.js";
3
-
4
- // Define Zod schemas for the Test model based on the Prisma schema
5
- const createTestSchema = z.object({
6
- name: z.string().min(1, "Name is required"),
7
- message: z.string().min(1, "Message is required"),
8
- status: z.string().optional().default("active"),
9
- });
1
+ import { z } from 'zod';
2
+ import { prisma } from '../lib/database.js';
3
+ import { publicProcedure, router } from '../trpc.js';
10
4
 
11
- const updateTestSchema = z.object({
12
- name: z.string().min(1, "Name is required").optional(),
13
- message: z.string().min(1, "Message is required").optional(),
14
- status: z.string().optional(),
15
- });
5
+ /**
6
+ * Test Router - tRPC CRUD operations for the Test model
7
+ *
8
+ * This router provides standard CRUD operations via tRPC.
9
+ * For the GraphQL equivalent, see src/graphql/types/test.ts
10
+ *
11
+ * Endpoints:
12
+ * - test.getById({ id }) - Get test by ID
13
+ * - test.getAll({ skip, take }) - Get all tests with pagination
14
+ * - test.count({ status }) - Get count of tests
15
+ * - test.create({ name, message }) - Create new test
16
+ * - test.update({ id, data }) - Update existing test
17
+ * - test.delete({ id }) - Delete test
18
+ */
19
+ export const testRouter = router({
20
+ // Get a single test by ID
21
+ getById: publicProcedure
22
+ .input(z.object({ id: z.string() }))
23
+ .query(async ({ input }) => {
24
+ const test = await prisma.test.findUnique({
25
+ where: { id: input.id },
26
+ });
27
+
28
+ if (!test) {
29
+ throw new Error('Test not found');
30
+ }
31
+
32
+ return test;
33
+ }),
34
+
35
+ // Get all tests with pagination
36
+ getAll: publicProcedure
37
+ .input(z.object({
38
+ skip: z.number().min(0).optional(),
39
+ take: z.number().min(1).max(100).optional(),
40
+ orderBy: z.enum(['createdAt', 'updatedAt', 'name']).optional(),
41
+ orderDir: z.enum(['asc', 'desc']).optional(),
42
+ }))
43
+ .query(async ({ input }) => {
44
+ const take = input.take ?? 10;
45
+ const orderField = input.orderBy ?? 'createdAt';
46
+ const orderDir = input.orderDir ?? 'desc';
47
+
48
+ return prisma.test.findMany({
49
+ ...(input.skip != null ? { skip: input.skip } : {}),
50
+ take,
51
+ orderBy: { [orderField]: orderDir },
52
+ });
53
+ }),
54
+
55
+ // Get count of tests
56
+ count: publicProcedure
57
+ .input(z.object({
58
+ status: z.string().optional(),
59
+ }))
60
+ .query(async ({ input }) => {
61
+ return prisma.test.count({
62
+ ...(input.status != null ? { where: { status: input.status } } : {}),
63
+ });
64
+ }),
16
65
 
17
- // Create the CRUD router for the Test model
18
- export const testRouter = createCrudRouter(
19
- "Test",
20
- createTestSchema,
21
- updateTestSchema
22
- );
66
+ // Create a new test
67
+ create: publicProcedure
68
+ .input(z.object({
69
+ name: z.string().min(1, 'Name is required'),
70
+ message: z.string().min(1, 'Message is required'),
71
+ status: z.string().optional().default('active'),
72
+ }))
73
+ .mutation(async ({ input }) => {
74
+ return prisma.test.create({
75
+ data: {
76
+ name: input.name,
77
+ message: input.message,
78
+ status: input.status,
79
+ },
80
+ });
81
+ }),
82
+
83
+ // Update an existing test
84
+ update: publicProcedure
85
+ .input(z.object({
86
+ id: z.string(),
87
+ data: z.object({
88
+ name: z.string().min(1).optional(),
89
+ message: z.string().min(1).optional(),
90
+ status: z.string().optional(),
91
+ }),
92
+ }))
93
+ .mutation(async ({ input }) => {
94
+ const existing = await prisma.test.findUnique({
95
+ where: { id: input.id },
96
+ });
97
+
98
+ if (!existing) {
99
+ throw new Error('Test not found');
100
+ }
101
+
102
+ // Build update data only with defined values
103
+ const updateData: { name?: string; message?: string; status?: string } = {};
104
+ if (input.data.name != null) updateData.name = input.data.name;
105
+ if (input.data.message != null) updateData.message = input.data.message;
106
+ if (input.data.status != null) updateData.status = input.data.status;
107
+
108
+ return prisma.test.update({
109
+ where: { id: input.id },
110
+ data: updateData,
111
+ });
112
+ }),
113
+
114
+ // Delete a test
115
+ delete: publicProcedure
116
+ .input(z.object({ id: z.string() }))
117
+ .mutation(async ({ input }) => {
118
+ const existing = await prisma.test.findUnique({
119
+ where: { id: input.id },
120
+ });
121
+
122
+ if (!existing) {
123
+ throw new Error('Test not found');
124
+ }
125
+
126
+ return prisma.test.delete({
127
+ where: { id: input.id },
128
+ });
129
+ }),
130
+ });
23
131
 
24
132
  /**
25
- * This generates the following endpoints:
26
- *
27
- * - test.getAll({ skip?, take?, orderBy? }) - Get all test records with pagination
28
- * - test.getById({ id }) - Get test record by ID
29
- * - test.create({ name, message, status? }) - Create new test record
30
- * - test.update({ id, data: { name?, message?, status? } }) - Update test record
31
- * - test.delete({ id }) - Delete test record
32
- * - test.count({ where? }) - Get test record count
33
- *
34
133
  * Example usage in frontend:
35
- *
134
+ *
36
135
  * ```typescript
37
136
  * // Get all tests
38
137
  * const { data: tests } = trpc.test.getAll.useQuery({ take: 10 });
39
- *
138
+ *
139
+ * // Get test by ID
140
+ * const { data: test } = trpc.test.getById.useQuery({ id: 'test-id' });
141
+ *
40
142
  * // Create a new test
41
143
  * const createTest = trpc.test.create.useMutation();
42
- * await createTest.mutateAsync({
43
- * name: 'My Test',
144
+ * await createTest.mutateAsync({
145
+ * name: 'My Test',
44
146
  * message: 'This is a test message',
45
147
  * status: 'active'
46
148
  * });
47
- *
149
+ *
48
150
  * // Update a test
49
151
  * const updateTest = trpc.test.update.useMutation();
50
- * await updateTest.mutateAsync({
51
- * id: 'test-id',
52
- * data: { name: 'Updated Test' }
152
+ * await updateTest.mutateAsync({
153
+ * id: 'test-id',
154
+ * data: { name: 'Updated Test' }
53
155
  * });
54
- *
156
+ *
55
157
  * // Delete a test
56
158
  * const deleteTest = trpc.test.delete.useMutation();
57
159
  * await deleteTest.mutateAsync({ id: 'test-id' });
@@ -3,6 +3,7 @@ import cors from 'cors';
3
3
  import { createExpressMiddleware } from '@trpc/server/adapters/express';
4
4
  import { appRouter } from './router/index.js';
5
5
  import { createContext } from './context.js';
6
+ import { yoga } from './graphql/index.js';
6
7
  import dotenv from 'dotenv';
7
8
 
8
9
  // Load environment variables
@@ -17,12 +18,15 @@ app.use(cors({
17
18
  credentials: true,
18
19
  }));
19
20
 
21
+ // Parse JSON bodies (needed for some GraphQL clients)
22
+ app.use(express.json());
23
+
20
24
  // Health check endpoint
21
- app.get('/health', (req, res) => {
25
+ app.get('/health', (_req, res) => {
22
26
  res.json({ status: 'OK', timestamp: new Date().toISOString() });
23
27
  });
24
28
 
25
- // tRPC middleware
29
+ // tRPC middleware - for internal TypeScript clients
26
30
  app.use(
27
31
  '/trpc',
28
32
  createExpressMiddleware({
@@ -31,20 +35,34 @@ app.use(
31
35
  })
32
36
  );
33
37
 
38
+ // GraphQL middleware - for public API, mobile clients, etc.
39
+ // GraphQL Yoga handles the /graphql endpoint
40
+ // Using all() to handle both GET (GraphiQL) and POST (queries)
41
+ app.all('/graphql', yoga as unknown as express.RequestHandler);
42
+
34
43
  // Default route
35
- app.get('/', (req, res) => {
44
+ app.get('/', (_req, res) => {
36
45
  res.json({
37
46
  message: 'Welcome to {{projectName}} API',
38
47
  endpoints: {
39
48
  health: '/health',
40
49
  trpc: '/trpc',
41
- playground: '/trpc-playground' // Available in development
42
- }
50
+ graphql: '/graphql',
51
+ graphiql: process.env.NODE_ENV !== 'production' ? '/graphql' : undefined,
52
+ },
53
+ documentation: {
54
+ trpc: 'Use tRPC for internal TypeScript clients with full type safety',
55
+ graphql: 'Use GraphQL for public APIs, mobile apps, and third-party integrations',
56
+ },
43
57
  });
44
58
  });
45
59
 
46
60
  app.listen(PORT, () => {
47
61
  console.log(`🚀 Server running on http://localhost:${PORT}`);
48
62
  console.log(`📡 tRPC API available at http://localhost:${PORT}/trpc`);
63
+ console.log(`📊 GraphQL API available at http://localhost:${PORT}/graphql`);
64
+ if (process.env.NODE_ENV !== 'production') {
65
+ console.log(`🎮 GraphiQL Playground at http://localhost:${PORT}/graphql`);
66
+ }
49
67
  console.log(`🏥 Health check at http://localhost:${PORT}/health`);
50
68
  });
@@ -2,6 +2,7 @@
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
4
  "module": "ESNext",
5
+ "moduleResolution": "bundler",
5
6
  "allowSyntheticDefaultImports": true,
6
7
  "esModuleInterop": true,
7
8
  "allowJs": true,
@@ -0,0 +1,41 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build outputs
5
+ dist/
6
+ build/
7
+ *.tsbuildinfo
8
+
9
+ # Database
10
+ *.db
11
+ *.sqlite
12
+
13
+ # Prisma
14
+ .env
15
+
16
+ # Environment variables
17
+ .env.local
18
+ .env.development.local
19
+ .env.test.local
20
+ .env.production.local
21
+
22
+ # Logs
23
+ npm-debug.log*
24
+ yarn-debug.log*
25
+ yarn-error.log*
26
+
27
+ # Coverage
28
+ coverage/
29
+ *.lcov
30
+ .nyc_output
31
+
32
+ # IDE
33
+ .vscode/
34
+ .idea/
35
+ *.swp
36
+ *.swo
37
+ *~
38
+
39
+ # OS
40
+ .DS_Store
41
+ Thumbs.db
@@ -5,7 +5,6 @@ module.exports = {
5
5
  root: 'src',
6
6
  autoProcessPaths: ['@idealyst/components', '@idealyst/navigation', '@idealyst/theme'],
7
7
  }],
8
- 'react-native-reanimated/plugin',
9
- 'react-native-worklets/plugin',
8
+ 'react-native-reanimated/plugin'
10
9
  ],
11
10
  };
@@ -0,0 +1,73 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # React Native
5
+
6
+ # Xcode
7
+ *.pbxuser
8
+ !default.pbxuser
9
+ *.mode1v3
10
+ !default.mode1v3
11
+ *.mode2v3
12
+ !default.mode2v3
13
+ *.perspectivev3
14
+ !default.perspectivev3
15
+ xcuserdata
16
+ *.xccheckout
17
+ *.moved-aside
18
+ DerivedData
19
+ *.hmap
20
+ *.ipa
21
+ *.xcuserstate
22
+ project.xcworkspace
23
+
24
+ # Android/IntelliJ
25
+ build/
26
+ .idea
27
+ .gradle
28
+ local.properties
29
+ *.iml
30
+ *.hprof
31
+ .cxx/
32
+
33
+ # BUCK
34
+ buck-out/
35
+ \.buckd/
36
+ *.keystore
37
+ !debug.keystore
38
+
39
+ # Bundle artifacts
40
+ *.jsbundle
41
+
42
+ # CocoaPods
43
+ /ios/Pods/
44
+
45
+ # Environment variables
46
+ .env
47
+ .env.local
48
+ .env.development.local
49
+ .env.test.local
50
+ .env.production.local
51
+
52
+ # Logs
53
+ npm-debug.log*
54
+ yarn-debug.log*
55
+ yarn-error.log*
56
+
57
+ # Coverage
58
+ coverage/
59
+ *.lcov
60
+ .nyc_output
61
+
62
+ # Metro
63
+ .metro-health-check*
64
+
65
+ # IDE
66
+ .vscode/
67
+ *.swp
68
+ *.swo
69
+ *~
70
+
71
+ # OS
72
+ .DS_Store
73
+ Thumbs.db
@@ -22,9 +22,17 @@
22
22
  "@trpc/client": "^11.5.1",
23
23
  "@trpc/react-query": "^11.5.1",
24
24
  "@trpc/server": "^11.5.1",
25
- "react": "^18.2.0",
26
- "react-native": "^0.73.0",
25
+ "react": "19.1.1",
26
+ "react-native": "0.82.1",
27
+ "react-native-edge-to-edge": "^1.6.2",
28
+ "react-native-gesture-handler": "^2.27.1",
29
+ "react-native-nitro-modules": "^0.30.0",
30
+ "react-native-reanimated": "^4.1.3",
31
+ "react-native-safe-area-context": "^5.5.1",
32
+ "react-native-screens": "^4.11.1",
27
33
  "react-native-svg": "^15.8.0",
34
+ "react-native-unistyles": "^3.0.4",
35
+ "react-native-vector-icons": "^10.2.0",
28
36
  "react-native-worklets": "^0.6.1"
29
37
  },
30
38
  "devDependencies": {
@@ -0,0 +1,35 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build outputs
5
+ dist/
6
+ build/
7
+ *.tsbuildinfo
8
+
9
+ # Environment variables
10
+ .env
11
+ .env.local
12
+ .env.development.local
13
+ .env.test.local
14
+ .env.production.local
15
+
16
+ # Logs
17
+ npm-debug.log*
18
+ yarn-debug.log*
19
+ yarn-error.log*
20
+
21
+ # Coverage
22
+ coverage/
23
+ *.lcov
24
+ .nyc_output
25
+
26
+ # IDE
27
+ .vscode/
28
+ .idea/
29
+ *.swp
30
+ *.swo
31
+ *~
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
@@ -35,6 +35,12 @@
35
35
  "optional": true
36
36
  }
37
37
  },
38
+ "dependencies": {
39
+ "@mdi/js": "^7.4.47",
40
+ "@mdi/react": "^1.6.1",
41
+ "graphql": "^16.9.0",
42
+ "graphql-request": "^7.1.2"
43
+ },
38
44
  "devDependencies": {
39
45
  "@idealyst/components": "^{{idealystVersion}}",
40
46
  "@idealyst/navigation": "^{{idealystVersion}}",
@@ -1,11 +1,13 @@
1
1
  import { NavigatorProvider } from "@idealyst/navigation";
2
2
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
- import React from "react";
3
+ import React, { useEffect } from "react";
4
+ import { createGraphQLClient } from "../graphql/client";
4
5
  import AppRouter from "../navigation/AppRouter";
5
6
  import { createTRPCClient, trpc } from "../trpc/client";
6
7
 
7
8
  interface AppProps {
8
9
  apiUrl?: string;
10
+ graphqlUrl?: string;
9
11
  queryClient?: QueryClient;
10
12
  headers?: () => Record<string, string>;
11
13
  }
@@ -20,11 +22,12 @@ const defaultQueryClient = new QueryClient({
20
22
  });
21
23
 
22
24
  /**
23
- * Unified App component that sets up tRPC, React Query providers, and Navigation
25
+ * Unified App component that sets up tRPC, GraphQL, React Query providers, and Navigation
24
26
  * This component can be used by both web and mobile platforms
25
27
  */
26
28
  export const App: React.FC<AppProps> = ({
27
29
  apiUrl = "http://localhost:3000/trpc",
30
+ graphqlUrl = "http://localhost:3000/graphql",
28
31
  queryClient = defaultQueryClient,
29
32
  headers,
30
33
  }) => {
@@ -34,6 +37,14 @@ export const App: React.FC<AppProps> = ({
34
37
  headers,
35
38
  });
36
39
 
40
+ // Initialize GraphQL client
41
+ useEffect(() => {
42
+ createGraphQLClient({
43
+ apiUrl: graphqlUrl,
44
+ headers,
45
+ });
46
+ }, [graphqlUrl, headers]);
47
+
37
48
  return (
38
49
  <trpc.Provider client={trpcClient} queryClient={queryClient}>
39
50
  <QueryClientProvider client={queryClient}>