create-aws-project 1.2.1

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 (181) hide show
  1. package/README.md +118 -0
  2. package/dist/__tests__/generator/replace-tokens.spec.d.ts +1 -0
  3. package/dist/__tests__/generator/replace-tokens.spec.js +281 -0
  4. package/dist/__tests__/generator.spec.d.ts +1 -0
  5. package/dist/__tests__/generator.spec.js +162 -0
  6. package/dist/__tests__/validation/project-name.spec.d.ts +1 -0
  7. package/dist/__tests__/validation/project-name.spec.js +57 -0
  8. package/dist/__tests__/wizard.spec.d.ts +1 -0
  9. package/dist/__tests__/wizard.spec.js +232 -0
  10. package/dist/aws/iam.d.ts +75 -0
  11. package/dist/aws/iam.js +264 -0
  12. package/dist/aws/organizations.d.ts +79 -0
  13. package/dist/aws/organizations.js +168 -0
  14. package/dist/cli.d.ts +4 -0
  15. package/dist/cli.js +206 -0
  16. package/dist/commands/setup-github.d.ts +4 -0
  17. package/dist/commands/setup-github.js +185 -0
  18. package/dist/generator/copy-file.d.ts +15 -0
  19. package/dist/generator/copy-file.js +56 -0
  20. package/dist/generator/generate-project.d.ts +14 -0
  21. package/dist/generator/generate-project.js +81 -0
  22. package/dist/generator/index.d.ts +4 -0
  23. package/dist/generator/index.js +3 -0
  24. package/dist/generator/replace-tokens.d.ts +29 -0
  25. package/dist/generator/replace-tokens.js +68 -0
  26. package/dist/github/secrets.d.ts +109 -0
  27. package/dist/github/secrets.js +275 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +6 -0
  30. package/dist/prompts/auth.d.ts +3 -0
  31. package/dist/prompts/auth.js +23 -0
  32. package/dist/prompts/aws-config.d.ts +2 -0
  33. package/dist/prompts/aws-config.js +14 -0
  34. package/dist/prompts/features.d.ts +2 -0
  35. package/dist/prompts/features.js +10 -0
  36. package/dist/prompts/github-setup.d.ts +53 -0
  37. package/dist/prompts/github-setup.js +208 -0
  38. package/dist/prompts/org-structure.d.ts +9 -0
  39. package/dist/prompts/org-structure.js +93 -0
  40. package/dist/prompts/platforms.d.ts +2 -0
  41. package/dist/prompts/platforms.js +12 -0
  42. package/dist/prompts/project-name.d.ts +2 -0
  43. package/dist/prompts/project-name.js +8 -0
  44. package/dist/prompts/theme.d.ts +2 -0
  45. package/dist/prompts/theme.js +14 -0
  46. package/dist/templates/index.d.ts +4 -0
  47. package/dist/templates/index.js +2 -0
  48. package/dist/templates/manifest.d.ts +11 -0
  49. package/dist/templates/manifest.js +99 -0
  50. package/dist/templates/tokens.d.ts +39 -0
  51. package/dist/templates/tokens.js +37 -0
  52. package/dist/templates/types.d.ts +52 -0
  53. package/dist/templates/types.js +1 -0
  54. package/dist/types.d.ts +27 -0
  55. package/dist/types.js +1 -0
  56. package/dist/validation/project-name.d.ts +1 -0
  57. package/dist/validation/project-name.js +12 -0
  58. package/dist/wizard.d.ts +2 -0
  59. package/dist/wizard.js +81 -0
  60. package/package.json +68 -0
  61. package/templates/.github/actions/build-and-test/action.yml +24 -0
  62. package/templates/.github/actions/deploy-cdk/action.yml +46 -0
  63. package/templates/.github/actions/deploy-web/action.yml +72 -0
  64. package/templates/.github/actions/setup/action.yml +29 -0
  65. package/templates/.github/pull_request_template.md +15 -0
  66. package/templates/.github/workflows/deploy-dev.yml +80 -0
  67. package/templates/.github/workflows/deploy-prod.yml +67 -0
  68. package/templates/.github/workflows/deploy-stage.yml +77 -0
  69. package/templates/.github/workflows/pull-request.yml +72 -0
  70. package/templates/.vscode/extensions.json +7 -0
  71. package/templates/.vscode/settings.json +67 -0
  72. package/templates/apps/api/.eslintrc.json +18 -0
  73. package/templates/apps/api/cdk/app.ts +93 -0
  74. package/templates/apps/api/cdk/auth/cognito-stack.ts +164 -0
  75. package/templates/apps/api/cdk/cdk.json +73 -0
  76. package/templates/apps/api/cdk/deployment-user-stack.ts +187 -0
  77. package/templates/apps/api/cdk/org-stack.ts +67 -0
  78. package/templates/apps/api/cdk/static-stack.ts +361 -0
  79. package/templates/apps/api/cdk/tsconfig.json +39 -0
  80. package/templates/apps/api/cdk/user-stack.ts +255 -0
  81. package/templates/apps/api/jest.config.ts +38 -0
  82. package/templates/apps/api/lambdas.yml +84 -0
  83. package/templates/apps/api/project.json.template +58 -0
  84. package/templates/apps/api/src/__tests__/setup.ts +10 -0
  85. package/templates/apps/api/src/handlers/users/create-user.ts +52 -0
  86. package/templates/apps/api/src/handlers/users/delete-user.ts +45 -0
  87. package/templates/apps/api/src/handlers/users/get-me.ts +72 -0
  88. package/templates/apps/api/src/handlers/users/get-user.ts +45 -0
  89. package/templates/apps/api/src/handlers/users/get-users.ts +23 -0
  90. package/templates/apps/api/src/handlers/users/index.ts +17 -0
  91. package/templates/apps/api/src/handlers/users/update-user.ts +72 -0
  92. package/templates/apps/api/src/lib/dynamo/dynamo-model.ts +504 -0
  93. package/templates/apps/api/src/lib/dynamo/index.ts +12 -0
  94. package/templates/apps/api/src/lib/dynamo/utils.ts +39 -0
  95. package/templates/apps/api/src/middleware/auth0-auth.ts +97 -0
  96. package/templates/apps/api/src/middleware/cognito-auth.ts +90 -0
  97. package/templates/apps/api/src/models/UserModel.ts +109 -0
  98. package/templates/apps/api/src/schemas/user.schema.ts +44 -0
  99. package/templates/apps/api/src/services/user-service.ts +108 -0
  100. package/templates/apps/api/src/utils/auth-context.ts +60 -0
  101. package/templates/apps/api/src/utils/common/helpers.ts +26 -0
  102. package/templates/apps/api/src/utils/lambda-handler.ts +148 -0
  103. package/templates/apps/api/src/utils/response.ts +52 -0
  104. package/templates/apps/api/src/utils/validator.ts +75 -0
  105. package/templates/apps/api/tsconfig.app.json +15 -0
  106. package/templates/apps/api/tsconfig.json +19 -0
  107. package/templates/apps/api/tsconfig.spec.json +17 -0
  108. package/templates/apps/mobile/.env.example +5 -0
  109. package/templates/apps/mobile/.eslintrc.json +33 -0
  110. package/templates/apps/mobile/app.json +33 -0
  111. package/templates/apps/mobile/assets/.gitkeep +0 -0
  112. package/templates/apps/mobile/babel.config.js +19 -0
  113. package/templates/apps/mobile/index.js +7 -0
  114. package/templates/apps/mobile/jest.config.ts +22 -0
  115. package/templates/apps/mobile/metro.config.js +35 -0
  116. package/templates/apps/mobile/package.json +22 -0
  117. package/templates/apps/mobile/project.json.template +64 -0
  118. package/templates/apps/mobile/src/App.tsx +367 -0
  119. package/templates/apps/mobile/src/__tests__/App.spec.tsx +46 -0
  120. package/templates/apps/mobile/src/__tests__/store/user-store.spec.ts +156 -0
  121. package/templates/apps/mobile/src/config/api.ts +16 -0
  122. package/templates/apps/mobile/src/store/user-store.ts +56 -0
  123. package/templates/apps/mobile/src/test-setup.ts +10 -0
  124. package/templates/apps/mobile/tsconfig.json +22 -0
  125. package/templates/apps/web/.env.example +13 -0
  126. package/templates/apps/web/.eslintrc.json +26 -0
  127. package/templates/apps/web/index.html +13 -0
  128. package/templates/apps/web/jest.config.ts +24 -0
  129. package/templates/apps/web/package.json +15 -0
  130. package/templates/apps/web/project.json.template +66 -0
  131. package/templates/apps/web/src/App.tsx +352 -0
  132. package/templates/apps/web/src/__mocks__/config/api.ts +41 -0
  133. package/templates/apps/web/src/__tests__/App.spec.tsx +240 -0
  134. package/templates/apps/web/src/__tests__/store/user-store.spec.ts +185 -0
  135. package/templates/apps/web/src/auth/auth0-provider.tsx +103 -0
  136. package/templates/apps/web/src/auth/cognito-provider.tsx +143 -0
  137. package/templates/apps/web/src/auth/index.ts +7 -0
  138. package/templates/apps/web/src/auth/use-auth.ts +16 -0
  139. package/templates/apps/web/src/config/amplify-config.ts +31 -0
  140. package/templates/apps/web/src/config/api.ts +38 -0
  141. package/templates/apps/web/src/config/auth0-config.ts +17 -0
  142. package/templates/apps/web/src/main.tsx +41 -0
  143. package/templates/apps/web/src/store/user-store.ts +56 -0
  144. package/templates/apps/web/src/styles.css +165 -0
  145. package/templates/apps/web/src/test-setup.ts +1 -0
  146. package/templates/apps/web/src/theme/index.ts +30 -0
  147. package/templates/apps/web/src/vite-env.d.ts +19 -0
  148. package/templates/apps/web/tsconfig.app.json +24 -0
  149. package/templates/apps/web/tsconfig.json +22 -0
  150. package/templates/apps/web/tsconfig.spec.json +28 -0
  151. package/templates/apps/web/vite.config.ts +87 -0
  152. package/templates/manifest.json +28 -0
  153. package/templates/packages/api-client/.eslintrc.json +18 -0
  154. package/templates/packages/api-client/jest.config.ts +13 -0
  155. package/templates/packages/api-client/package.json +8 -0
  156. package/templates/packages/api-client/project.json.template +34 -0
  157. package/templates/packages/api-client/src/__tests__/api-client.spec.ts +408 -0
  158. package/templates/packages/api-client/src/api-client.ts +201 -0
  159. package/templates/packages/api-client/src/config.ts +193 -0
  160. package/templates/packages/api-client/src/index.ts +9 -0
  161. package/templates/packages/api-client/tsconfig.json +22 -0
  162. package/templates/packages/api-client/tsconfig.lib.json +11 -0
  163. package/templates/packages/api-client/tsconfig.spec.json +14 -0
  164. package/templates/packages/common-types/.eslintrc.json +18 -0
  165. package/templates/packages/common-types/package.json +6 -0
  166. package/templates/packages/common-types/project.json.template +26 -0
  167. package/templates/packages/common-types/src/api.types.ts +24 -0
  168. package/templates/packages/common-types/src/auth.types.ts +36 -0
  169. package/templates/packages/common-types/src/common.types.ts +46 -0
  170. package/templates/packages/common-types/src/index.ts +19 -0
  171. package/templates/packages/common-types/src/lambda.types.ts +39 -0
  172. package/templates/packages/common-types/src/user.types.ts +31 -0
  173. package/templates/packages/common-types/tsconfig.json +19 -0
  174. package/templates/packages/common-types/tsconfig.lib.json +11 -0
  175. package/templates/root/.editorconfig +23 -0
  176. package/templates/root/.nvmrc +1 -0
  177. package/templates/root/eslint.config.js +61 -0
  178. package/templates/root/jest.preset.js +16 -0
  179. package/templates/root/nx.json +29 -0
  180. package/templates/root/package.json +131 -0
  181. package/templates/root/tsconfig.base.json +29 -0
@@ -0,0 +1,26 @@
1
+ {
2
+ "extends": ["../../.eslintrc.js", "plugin:react/recommended", "plugin:react-hooks/recommended"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "settings": {
5
+ "react": {
6
+ "version": "detect"
7
+ }
8
+ },
9
+ "overrides": [
10
+ {
11
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
12
+ "rules": {
13
+ "react/react-in-jsx-scope": "off",
14
+ "react/prop-types": "off"
15
+ }
16
+ },
17
+ {
18
+ "files": ["*.ts", "*.tsx"],
19
+ "rules": {}
20
+ },
21
+ {
22
+ "files": ["*.js", "*.jsx"],
23
+ "rules": {}
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>{{PROJECT_NAME_TITLE}}</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,24 @@
1
+ export default {
2
+ displayName: 'web',
3
+ preset: '../../jest.preset.js',
4
+ transform: {
5
+ '^.+\\.(ts|tsx|js|jsx)$': [
6
+ 'ts-jest',
7
+ {
8
+ tsconfig: '<rootDir>/tsconfig.spec.json',
9
+ },
10
+ ],
11
+ },
12
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
13
+ coverageDirectory: '../../coverage/apps/web',
14
+ testEnvironment: 'jsdom',
15
+ setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
16
+ moduleNameMapper: {
17
+ '^\\.\\./config/api$': '<rootDir>/src/__mocks__/config/api.ts',
18
+ '^\\.\\./\\.\\./config/api$': '<rootDir>/src/__mocks__/config/api.ts',
19
+ '^\\.\\./src/config/api$': '<rootDir>/src/__mocks__/config/api.ts',
20
+ '^./config/api$': '<rootDir>/src/__mocks__/config/api.ts',
21
+ '^{{PACKAGE_SCOPE}}/common-types$': '<rootDir>/../../packages/common-types/src/index.ts',
22
+ '^{{PACKAGE_SCOPE}}/api-client$': '<rootDir>/../../packages/api-client/src/index.ts',
23
+ },
24
+ };
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "web",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "nx serve web",
8
+ "build": "nx build web",
9
+ "test": "nx test web"
10
+ },
11
+ "dependencies": {
12
+ "@auth0/auth0-react": "^2.2.0",
13
+ "aws-amplify": "^6.0.0"
14
+ }
15
+ }
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "web",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "apps/web/src",
5
+ "projectType": "application",
6
+ "tags": ["type:app"],
7
+ "targets": {
8
+ "lint": {
9
+ "executor": "@nx/eslint:lint",
10
+ "outputs": ["{options.outputFile}"],
11
+ "options": {
12
+ "lintFilePatterns": ["apps/web/**/*.{ts,tsx,js,jsx}"]
13
+ }
14
+ },
15
+ "build": {
16
+ "executor": "@nx/vite:build",
17
+ "outputs": ["{options.outputPath}"],
18
+ "defaultConfiguration": "production",
19
+ "options": {
20
+ "outputPath": "dist/apps/web"
21
+ },
22
+ "configurations": {
23
+ "development": {
24
+ "mode": "development"
25
+ },
26
+ "production": {
27
+ "mode": "production"
28
+ }
29
+ }
30
+ },
31
+ "serve": {
32
+ "executor": "@nx/vite:dev-server",
33
+ "defaultConfiguration": "development",
34
+ "options": {
35
+ "buildTarget": "web:build",
36
+ "port": 3000
37
+ },
38
+ "configurations": {
39
+ "development": {
40
+ "buildTarget": "web:build:development",
41
+ "hmr": true
42
+ },
43
+ "production": {
44
+ "buildTarget": "web:build:production",
45
+ "hmr": false
46
+ }
47
+ }
48
+ },
49
+ "preview": {
50
+ "executor": "@nx/vite:preview-server",
51
+ "defaultConfiguration": "development",
52
+ "options": {
53
+ "buildTarget": "web:build",
54
+ "port": 3001
55
+ }
56
+ },
57
+ "test": {
58
+ "executor": "@nx/jest:jest",
59
+ "outputs": ["{workspaceRoot}/coverage/apps/web"],
60
+ "options": {
61
+ "jestConfig": "apps/web/jest.config.ts",
62
+ "passWithNoTests": true
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,352 @@
1
+ import {
2
+ Box,
3
+ Container,
4
+ Heading,
5
+ Text,
6
+ VStack,
7
+ HStack,
8
+ Button,
9
+ Card,
10
+ CardHeader,
11
+ CardBody,
12
+ List,
13
+ ListItem,
14
+ ListIcon,
15
+ Badge,
16
+ useToast,
17
+ Spinner,
18
+ } from '@chakra-ui/react';
19
+ import { CheckCircleIcon } from '@chakra-ui/icons';
20
+ import { useUserStore } from './store/user-store';
21
+ import type { User } from '{{PACKAGE_SCOPE}}/common-types';
22
+ import { apiClient } from './config/api';
23
+ import { ApiError } from '{{PACKAGE_SCOPE}}/api-client';
24
+ import { useEffect } from 'react';
25
+ // {{#if AUTH_COGNITO}}
26
+ import { useAuth } from './auth';
27
+ // {{/if AUTH_COGNITO}}
28
+ // {{#if AUTH_AUTH0}}
29
+ import { useAuth } from './auth';
30
+ // {{/if AUTH_AUTH0}}
31
+
32
+ function App() {
33
+ const { user, users, setUser, addUser, setUsers, isLoading, error } = useUserStore();
34
+ const toast = useToast();
35
+ // {{#if AUTH_COGNITO}}
36
+ const { user: authUser, isAuthenticated, isLoading: authLoading, signIn, signOut } = useAuth();
37
+ // {{/if AUTH_COGNITO}}
38
+ // {{#if AUTH_AUTH0}}
39
+ const { user: authUser, isAuthenticated, isLoading: authLoading, signIn, signOut } = useAuth();
40
+ // {{/if AUTH_AUTH0}}
41
+
42
+ // Fetch users on mount
43
+ useEffect(() => {
44
+ handleFetchUsers();
45
+ }, []);
46
+
47
+ const handleLoadDemoUser = () => {
48
+ const demoUser: User = {
49
+ id: crypto.randomUUID(),
50
+ email: 'demo@example.com',
51
+ name: 'Demo User',
52
+ createdAt: new Date().toISOString(),
53
+ };
54
+ setUser(demoUser);
55
+ addUser(demoUser);
56
+ toast({
57
+ title: 'User loaded',
58
+ description: 'Demo user has been loaded successfully',
59
+ status: 'success',
60
+ duration: 3000,
61
+ isClosable: true,
62
+ });
63
+ };
64
+
65
+ const handleClearUser = () => {
66
+ setUser(null);
67
+ toast({
68
+ title: 'User cleared',
69
+ description: 'Current user has been cleared',
70
+ status: 'info',
71
+ duration: 3000,
72
+ isClosable: true,
73
+ });
74
+ };
75
+
76
+ const handleFetchUsers = async () => {
77
+ try {
78
+ const fetchedUsers = await apiClient.getUsers();
79
+ setUsers(fetchedUsers);
80
+ toast({
81
+ title: 'Users fetched',
82
+ description: `Loaded ${fetchedUsers.length} users from API`,
83
+ status: 'success',
84
+ duration: 3000,
85
+ isClosable: true,
86
+ });
87
+ } catch (err) {
88
+ const message = err instanceof ApiError ? err.message : 'Failed to fetch users';
89
+ toast({
90
+ title: 'Error',
91
+ description: message,
92
+ status: 'error',
93
+ duration: 5000,
94
+ isClosable: true,
95
+ });
96
+ }
97
+ };
98
+
99
+ const handleCreateUser = async () => {
100
+ try {
101
+ const newUser = await apiClient.createUser({
102
+ email: `user${Date.now()}@example.com`,
103
+ name: `User ${Date.now()}`,
104
+ });
105
+ addUser(newUser);
106
+ toast({
107
+ title: 'User created',
108
+ description: `Created ${newUser.name}`,
109
+ status: 'success',
110
+ duration: 3000,
111
+ isClosable: true,
112
+ });
113
+ } catch (err) {
114
+ const message = err instanceof ApiError ? err.message : 'Failed to create user';
115
+ toast({
116
+ title: 'Error',
117
+ description: message,
118
+ status: 'error',
119
+ duration: 5000,
120
+ isClosable: true,
121
+ });
122
+ }
123
+ };
124
+
125
+ return (
126
+ <Box minH="100vh" display="flex" flexDirection="column">
127
+ {/* Header */}
128
+ <Box
129
+ bgGradient="linear(to-r, brand.500, purple.500)"
130
+ py={8}
131
+ boxShadow="lg"
132
+ position="relative"
133
+ >
134
+ {/* {{#if AUTH_COGNITO}} */}
135
+ <HStack position="absolute" top={4} right={4}>
136
+ {authLoading ? (
137
+ <Spinner size="sm" />
138
+ ) : isAuthenticated && authUser ? (
139
+ <HStack>
140
+ <Badge colorScheme="green">{authUser.email}</Badge>
141
+ <Button size="sm" colorScheme="red" variant="outline" onClick={() => signOut()}>
142
+ Sign Out
143
+ </Button>
144
+ </HStack>
145
+ ) : (
146
+ <Button size="sm" colorScheme="brand" onClick={() => signIn('', '')}>
147
+ Sign In
148
+ </Button>
149
+ )}
150
+ </HStack>
151
+ {/* {{/if AUTH_COGNITO}} */}
152
+ {/* {{#if AUTH_AUTH0}} */}
153
+ <HStack position="absolute" top={4} right={4}>
154
+ {authLoading ? (
155
+ <Spinner size="sm" />
156
+ ) : isAuthenticated && authUser ? (
157
+ <HStack>
158
+ <Badge colorScheme="green">{authUser.email}</Badge>
159
+ <Button size="sm" colorScheme="red" variant="outline" onClick={() => signOut()}>
160
+ Sign Out
161
+ </Button>
162
+ </HStack>
163
+ ) : (
164
+ <Button size="sm" colorScheme="brand" onClick={() => signIn('', '')}>
165
+ Sign In
166
+ </Button>
167
+ )}
168
+ </HStack>
169
+ {/* {{/if AUTH_AUTH0}} */}
170
+ <Container maxW="container.xl">
171
+ <VStack spacing={2}>
172
+ <Heading size="2xl">{{PROJECT_NAME_TITLE}}</Heading>
173
+ <Text fontSize="lg" opacity={0.9}>
174
+ Nx Monorepo with React, AWS Lambda, and Shared Types
175
+ </Text>
176
+ </VStack>
177
+ </Container>
178
+ </Box>
179
+
180
+ {/* Main Content */}
181
+ <Container maxW="container.xl" flex="1" py={8}>
182
+ <Card>
183
+ <CardHeader>
184
+ <Heading size="lg">Welcome to the Web Client</Heading>
185
+ </CardHeader>
186
+ <CardBody>
187
+ <VStack spacing={6} align="stretch">
188
+ <Text color="gray.400">
189
+ This is a React application built with Vite and TypeScript,
190
+ managed by Nx in a monorepo structure.
191
+ </Text>
192
+
193
+ {/* Features */}
194
+ <Box
195
+ bg="rgba(59, 130, 246, 0.1)"
196
+ p={6}
197
+ borderRadius="lg"
198
+ borderWidth="1px"
199
+ borderColor="brand.700"
200
+ >
201
+ <Heading size="md" mb={4} color="brand.400">
202
+ Features:
203
+ </Heading>
204
+ <List spacing={3}>
205
+ <ListItem>
206
+ <ListIcon as={CheckCircleIcon} color="green.400" />
207
+ React 18 with TypeScript
208
+ </ListItem>
209
+ <ListItem>
210
+ <ListIcon as={CheckCircleIcon} color="green.400" />
211
+ Vite for fast development
212
+ </ListItem>
213
+ <ListItem>
214
+ <ListIcon as={CheckCircleIcon} color="green.400" />
215
+ Chakra UI component library
216
+ </ListItem>
217
+ <ListItem>
218
+ <ListIcon as={CheckCircleIcon} color="green.400" />
219
+ Zustand for state management
220
+ </ListItem>
221
+ <ListItem>
222
+ <ListIcon as={CheckCircleIcon} color="green.400" />
223
+ Jest for testing
224
+ </ListItem>
225
+ <ListItem>
226
+ <ListIcon as={CheckCircleIcon} color="green.400" />
227
+ Shared types from common-types library
228
+ </ListItem>
229
+ <ListItem>
230
+ <ListIcon as={CheckCircleIcon} color="green.400" />
231
+ Nx for monorepo management
232
+ </ListItem>
233
+ <ListItem>
234
+ <ListIcon as={CheckCircleIcon} color="green.400" />
235
+ Type-safe API client with Axios
236
+ </ListItem>
237
+ <ListItem>
238
+ <ListIcon as={CheckCircleIcon} color="green.400" />
239
+ AWS CDK infrastructure deployment
240
+ </ListItem>
241
+ </List>
242
+ </Box>
243
+
244
+ {/* API Actions */}
245
+ <Box
246
+ bg="rgba(139, 92, 246, 0.1)"
247
+ p={6}
248
+ borderRadius="lg"
249
+ borderWidth="1px"
250
+ borderColor="purple.700"
251
+ >
252
+ <Heading size="md" mb={4} color="purple.400">
253
+ API Actions:
254
+ </Heading>
255
+ <HStack spacing={4}>
256
+ <Button
257
+ colorScheme="purple"
258
+ onClick={handleFetchUsers}
259
+ isLoading={isLoading}
260
+ >
261
+ Fetch Users from API
262
+ </Button>
263
+ <Button
264
+ colorScheme="green"
265
+ onClick={handleCreateUser}
266
+ isLoading={isLoading}
267
+ >
268
+ Create Test User
269
+ </Button>
270
+ </HStack>
271
+ {error && (
272
+ <Text color="red.400" mt={2} fontSize="sm">
273
+ Error: {error}
274
+ </Text>
275
+ )}
276
+ </Box>
277
+
278
+ {/* User Info or Load Button */}
279
+ {user ? (
280
+ <Box
281
+ bg="rgba(16, 185, 129, 0.1)"
282
+ p={6}
283
+ borderRadius="lg"
284
+ borderWidth="1px"
285
+ borderColor="green.700"
286
+ >
287
+ <Heading size="md" mb={4} color="green.400">
288
+ Current User:
289
+ </Heading>
290
+ <VStack align="start" spacing={2}>
291
+ <HStack>
292
+ <Badge colorScheme="green">ID</Badge>
293
+ <Text>{user.id}</Text>
294
+ </HStack>
295
+ <HStack>
296
+ <Badge colorScheme="blue">Email</Badge>
297
+ <Text>{user.email}</Text>
298
+ </HStack>
299
+ <HStack>
300
+ <Badge colorScheme="purple">Name</Badge>
301
+ <Text>{user.name}</Text>
302
+ </HStack>
303
+ <HStack>
304
+ <Badge colorScheme="orange">Created</Badge>
305
+ <Text>{new Date(user.createdAt).toLocaleString()}</Text>
306
+ </HStack>
307
+ </VStack>
308
+ <Button
309
+ mt={4}
310
+ colorScheme="red"
311
+ onClick={handleClearUser}
312
+ size="sm"
313
+ >
314
+ Clear User
315
+ </Button>
316
+ </Box>
317
+ ) : (
318
+ <Button
319
+ colorScheme="brand"
320
+ size="lg"
321
+ onClick={handleLoadDemoUser}
322
+ >
323
+ Load Demo User
324
+ </Button>
325
+ )}
326
+
327
+ {/* Users Count */}
328
+ {users.length > 0 && (
329
+ <Box>
330
+ <Text color="gray.400">
331
+ Total users in store: <Badge ml={2}>{users.length}</Badge>
332
+ </Text>
333
+ </Box>
334
+ )}
335
+ </VStack>
336
+ </CardBody>
337
+ </Card>
338
+ </Container>
339
+
340
+ {/* Footer */}
341
+ <Box bg="gray.800" py={6} borderTop="1px" borderColor="gray.700">
342
+ <Container maxW="container.xl">
343
+ <Text textAlign="center" color="gray.400">
344
+ Built with React, TypeScript, Chakra UI, and Zustand
345
+ </Text>
346
+ </Container>
347
+ </Box>
348
+ </Box>
349
+ );
350
+ }
351
+
352
+ export default App;
@@ -0,0 +1,41 @@
1
+ import type { User, CreateUserRequest, UpdateUserRequest } from '{{PACKAGE_SCOPE}}/common-types';
2
+ import { Axios } from 'axios';
3
+
4
+ /**
5
+ * Mock API Client for tests
6
+ * Provides a simple mock implementation without external dependencies
7
+ */
8
+ export const apiClient = {
9
+ getUsers: (): Promise<User[]> => Promise.resolve([]),
10
+ getUser: (_id: string): Promise<User> => Promise.resolve({
11
+ id: '1',
12
+ email: 'test@example.com',
13
+ name: 'Test User',
14
+ createdAt: new Date().toISOString(),
15
+ }),
16
+ createUser: (_data: CreateUserRequest): Promise<User> => Promise.resolve({
17
+ id: '1',
18
+ email: _data.email,
19
+ name: _data.name,
20
+ createdAt: new Date().toISOString(),
21
+ }),
22
+ updateUser: (_id: string, _data: UpdateUserRequest): Promise<User> => Promise.resolve({
23
+ id: _id,
24
+ email: 'test@example.com',
25
+ name: _data.name || 'Test User',
26
+ createdAt: new Date().toISOString(),
27
+ }),
28
+ deleteUser: (_id: string): Promise<void> => Promise.resolve(),
29
+ setAuthToken: (_token: string) => { console.log('setAuthToken', _token); },
30
+ clearAuthToken: () => { console.log('clearAuthToken'); },
31
+ setBaseURL: (_url: string) => { console.log('setBaseURL', _url); },
32
+ getAxiosInstance: () => ({}) as Axios,
33
+ };
34
+
35
+ export function setAuthToken(_token: string): void {
36
+ // Mock implementation
37
+ }
38
+
39
+ export function clearAuthToken(): void {
40
+ // Mock implementation
41
+ }