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,84 @@
1
+ # Lambda Function Configurations
2
+ # This file defines the Lambda functions and their API Gateway mappings
3
+
4
+ lambdas:
5
+ user-lambdas:
6
+ - name: GetUsers
7
+ source: src/handlers/users/get-users.ts
8
+ handler: handler
9
+ method: GET
10
+ path: /api/users
11
+ description: Get all users
12
+ memorySize: 256
13
+ timeout: 30
14
+ environment:
15
+ LOG_LEVEL: info
16
+
17
+ # {{#if AUTH_COGNITO}}
18
+ - name: GetMe
19
+ source: src/handlers/users/get-me.ts
20
+ handler: handler
21
+ method: GET
22
+ path: /api/users/me
23
+ description: Get current authenticated user
24
+ memorySize: 256
25
+ timeout: 30
26
+ environment:
27
+ LOG_LEVEL: info
28
+ # {{/if AUTH_COGNITO}}
29
+ # {{#if AUTH_AUTH0}}
30
+ - name: GetMe
31
+ source: src/handlers/users/get-me.ts
32
+ handler: handler
33
+ method: GET
34
+ path: /api/users/me
35
+ description: Get current authenticated user
36
+ memorySize: 256
37
+ timeout: 30
38
+ environment:
39
+ LOG_LEVEL: info
40
+ # {{/if AUTH_AUTH0}}
41
+
42
+ - name: GetUser
43
+ source: src/handlers/users/get-user.ts
44
+ handler: handler
45
+ method: GET
46
+ path: /api/users/{id}
47
+ description: Get user by ID
48
+ memorySize: 256
49
+ timeout: 30
50
+ environment:
51
+ LOG_LEVEL: info
52
+
53
+ - name: CreateUser
54
+ source: src/handlers/users/create-user.ts
55
+ handler: handler
56
+ method: POST
57
+ path: /api/users
58
+ description: Create a new user
59
+ memorySize: 256
60
+ timeout: 30
61
+ environment:
62
+ LOG_LEVEL: info
63
+
64
+ - name: UpdateUser
65
+ source: src/handlers/users/update-user.ts
66
+ handler: handler
67
+ method: PUT
68
+ path: /api/users/{id}
69
+ description: Update an existing user
70
+ memorySize: 256
71
+ timeout: 30
72
+ environment:
73
+ LOG_LEVEL: info
74
+
75
+ - name: DeleteUser
76
+ source: src/handlers/users/delete-user.ts
77
+ handler: handler
78
+ method: DELETE
79
+ path: /api/users/{id}
80
+ description: Delete a user
81
+ memorySize: 256
82
+ timeout: 30
83
+ environment:
84
+ LOG_LEVEL: info
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "api",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "apps/api/src",
5
+ "projectType": "application",
6
+ "tags": ["type:api"],
7
+ "targets": {
8
+ "lint": {
9
+ "executor": "@nx/eslint:lint",
10
+ "outputs": ["{options.outputFile}"],
11
+ "options": {
12
+ "lintFilePatterns": ["apps/api/**/*.ts"]
13
+ }
14
+ },
15
+ "build": {
16
+ "executor": "@nx/esbuild:esbuild",
17
+ "outputs": ["{options.outputPath}"],
18
+ "options": {
19
+ "outputPath": "dist/apps/api",
20
+ "main": "apps/api/src/handlers/users/get-users.ts",
21
+ "tsConfig": "apps/api/tsconfig.app.json",
22
+ "assets": [],
23
+ "bundle": true,
24
+ "platform": "node",
25
+ "target": "node20",
26
+ "format": ["cjs"],
27
+ "external": ["aws-sdk", "@aws-sdk/*"],
28
+ "additionalEntryPoints": [
29
+ "apps/api/src/handlers/users/get-user.ts",
30
+ "apps/api/src/handlers/users/create-user.ts",
31
+ "apps/api/src/handlers/users/update-user.ts",
32
+ "apps/api/src/handlers/users/delete-user.ts"
33
+ ],
34
+ "esbuildOptions": {
35
+ "sourcemap": true,
36
+ "minify": true,
37
+ "outExtension": {
38
+ ".js": ".js"
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "serve": {
44
+ "executor": "nx:run-commands",
45
+ "options": {
46
+ "command": "echo 'Use SAM CLI or CDK to test Lambda functions locally'"
47
+ }
48
+ },
49
+ "test": {
50
+ "executor": "@nx/jest:jest",
51
+ "outputs": ["{workspaceRoot}/coverage/apps/api"],
52
+ "options": {
53
+ "jestConfig": "apps/api/jest.config.ts",
54
+ "passWithNoTests": true
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Jest test setup file
3
+ * Runs before all tests
4
+ */
5
+
6
+ // Set test environment variables
7
+ process.env['NODE_ENV'] = 'test';
8
+ process.env['AWS_REGION'] = 'us-east-1';
9
+ process.env['DYNAMODB_TABLE'] = 'test-table';
10
+ process.env['LOG_LEVEL'] = 'ERROR'; // Reduce log noise in tests
@@ -0,0 +1,52 @@
1
+ import type {
2
+ ApiGatewayProxyResult,
3
+ CreateUserRequest,
4
+ } from '{{PACKAGE_SCOPE}}/common-types';
5
+ import { HTTP_STATUS, ERROR_CODES } from '{{PACKAGE_SCOPE}}/common-types';
6
+ import { successResponse } from '../../utils/response';
7
+ import { validate, getValidationErrors } from '../../utils/validator';
8
+ import { userService } from '../../services/user-service';
9
+ import {
10
+ createLambdaHandler,
11
+ createErrorResult,
12
+ validateBodyPresent,
13
+ type ParsedRequest,
14
+ } from '../../utils/lambda-handler';
15
+ import { createUserSchema } from '../../schemas/user.schema';
16
+
17
+ /**
18
+ * POST /users - Create a new user
19
+ */
20
+ async function createUserHandler(
21
+ request: ParsedRequest<CreateUserRequest>
22
+ ): Promise<ApiGatewayProxyResult> {
23
+ // Validate body is present
24
+ const bodyValidation = validateBodyPresent(request.body, request.rawBody);
25
+ if (!bodyValidation.valid) {
26
+ throw createErrorResult(
27
+ ERROR_CODES.VALIDATION_ERROR,
28
+ bodyValidation.error || 'Request body is required',
29
+ HTTP_STATUS.BAD_REQUEST
30
+ );
31
+ }
32
+
33
+ // Validate request data with AJV schema
34
+ const validation = validate(createUserSchema, request.body);
35
+ if (!validation.valid) {
36
+ throw createErrorResult(
37
+ ERROR_CODES.VALIDATION_ERROR,
38
+ getValidationErrors(validation.errors),
39
+ HTTP_STATUS.BAD_REQUEST,
40
+ { errors: validation.errors }
41
+ );
42
+ }
43
+
44
+ const user = await userService.createUser(request.body as CreateUserRequest);
45
+
46
+ return successResponse(user, HTTP_STATUS.CREATED, 'User created successfully');
47
+ }
48
+
49
+ /**
50
+ * Lambda handler wrapper
51
+ */
52
+ export const handler = createLambdaHandler(createUserHandler, 'CreateUser');
@@ -0,0 +1,45 @@
1
+ import type { ApiGatewayProxyResult } from '{{PACKAGE_SCOPE}}/common-types';
2
+ import { HTTP_STATUS, ERROR_CODES } from '{{PACKAGE_SCOPE}}/common-types';
3
+ import { successResponse } from '../../utils/response';
4
+ import { userService } from '../../services/user-service';
5
+ import {
6
+ createLambdaHandler,
7
+ createErrorResult,
8
+ validatePathParameters,
9
+ type ParsedRequest,
10
+ } from '../../utils/lambda-handler';
11
+
12
+ /**
13
+ * DELETE /users/{id} - Delete user
14
+ */
15
+ async function deleteUserHandler(
16
+ request: ParsedRequest
17
+ ): Promise<ApiGatewayProxyResult> {
18
+ // Validate required path parameters
19
+ const validation = validatePathParameters(request.pathParameters, ['id']);
20
+ if (!validation.valid) {
21
+ throw createErrorResult(
22
+ ERROR_CODES.VALIDATION_ERROR,
23
+ 'User ID is required',
24
+ HTTP_STATUS.BAD_REQUEST
25
+ );
26
+ }
27
+
28
+ const userId = request.pathParameters['id'];
29
+ const deleted = await userService.deleteUser(userId);
30
+
31
+ if (!deleted) {
32
+ throw createErrorResult(
33
+ ERROR_CODES.NOT_FOUND,
34
+ 'User not found',
35
+ HTTP_STATUS.NOT_FOUND
36
+ );
37
+ }
38
+
39
+ return successResponse(null, HTTP_STATUS.OK, 'User deleted successfully');
40
+ }
41
+
42
+ /**
43
+ * Lambda handler wrapper
44
+ */
45
+ export const handler = createLambdaHandler(deleteUserHandler, 'DeleteUser');
@@ -0,0 +1,72 @@
1
+ import type { ApiGatewayProxyResult } from '{{PACKAGE_SCOPE}}/common-types';
2
+ import { HTTP_STATUS } from '{{PACKAGE_SCOPE}}/common-types';
3
+ import { successResponse } from '../../utils/response';
4
+ import {
5
+ createLambdaHandler,
6
+ type ParsedRequest,
7
+ } from '../../utils/lambda-handler';
8
+ // {{#if AUTH_COGNITO}}
9
+ import { requireAuth, type AuthUser } from '../../middleware/cognito-auth';
10
+ // {{/if AUTH_COGNITO}}
11
+ // {{#if AUTH_AUTH0}}
12
+ import { requireAuth, type AuthUser } from '../../middleware/auth0-auth';
13
+ // {{/if AUTH_AUTH0}}
14
+
15
+ /**
16
+ * Extended request type that includes authenticated user
17
+ */
18
+ // {{#if AUTH_COGNITO}}
19
+ interface AuthenticatedRequest extends ParsedRequest {
20
+ user: AuthUser;
21
+ }
22
+ // {{/if AUTH_COGNITO}}
23
+ // {{#if AUTH_AUTH0}}
24
+ interface AuthenticatedRequest extends ParsedRequest {
25
+ user: AuthUser;
26
+ }
27
+ // {{/if AUTH_AUTH0}}
28
+
29
+ /**
30
+ * GET /users/me - Get current authenticated user
31
+ * This endpoint requires authentication
32
+ */
33
+ async function getMeHandler(
34
+ request: ParsedRequest
35
+ ): Promise<ApiGatewayProxyResult> {
36
+ // {{#if AUTH_COGNITO}}
37
+ const authRequest = request as AuthenticatedRequest;
38
+ const user = authRequest.user;
39
+
40
+ return successResponse({
41
+ id: user.sub,
42
+ email: user.email,
43
+ emailVerified: user.tokenPayload.email_verified,
44
+ groups: user.groups || [],
45
+ }, HTTP_STATUS.OK);
46
+ // {{/if AUTH_COGNITO}}
47
+ // {{#if AUTH_AUTH0}}
48
+ const authRequest = request as AuthenticatedRequest;
49
+ const user = authRequest.user;
50
+
51
+ return successResponse({
52
+ id: user.sub,
53
+ email: user.email,
54
+ emailVerified: user.tokenPayload.email_verified,
55
+ permissions: user.permissions || [],
56
+ }, HTTP_STATUS.OK);
57
+ // {{/if AUTH_AUTH0}}
58
+ }
59
+
60
+ /**
61
+ * Lambda handler with authentication middleware
62
+ */
63
+ // {{#if AUTH_COGNITO}}
64
+ export const handler = requireAuth(
65
+ createLambdaHandler(getMeHandler, 'GetMe')
66
+ );
67
+ // {{/if AUTH_COGNITO}}
68
+ // {{#if AUTH_AUTH0}}
69
+ export const handler = requireAuth(
70
+ createLambdaHandler(getMeHandler, 'GetMe')
71
+ );
72
+ // {{/if AUTH_AUTH0}}
@@ -0,0 +1,45 @@
1
+ import type { ApiGatewayProxyResult } from '{{PACKAGE_SCOPE}}/common-types';
2
+ import { HTTP_STATUS, ERROR_CODES } from '{{PACKAGE_SCOPE}}/common-types';
3
+ import { successResponse } from '../../utils/response';
4
+ import { userService } from '../../services/user-service';
5
+ import {
6
+ createLambdaHandler,
7
+ createErrorResult,
8
+ validatePathParameters,
9
+ type ParsedRequest,
10
+ } from '../../utils/lambda-handler';
11
+
12
+ /**
13
+ * GET /users/{id} - Get user by ID
14
+ */
15
+ async function getUserHandler(
16
+ request: ParsedRequest
17
+ ): Promise<ApiGatewayProxyResult> {
18
+ // Validate required path parameters
19
+ const validation = validatePathParameters(request.pathParameters, ['id']);
20
+ if (!validation.valid) {
21
+ throw createErrorResult(
22
+ ERROR_CODES.VALIDATION_ERROR,
23
+ 'User ID is required',
24
+ HTTP_STATUS.BAD_REQUEST
25
+ );
26
+ }
27
+
28
+ const userId = request.pathParameters['id'];
29
+ const user = await userService.getUserById(userId);
30
+
31
+ if (!user) {
32
+ throw createErrorResult(
33
+ ERROR_CODES.NOT_FOUND,
34
+ 'User not found',
35
+ HTTP_STATUS.NOT_FOUND
36
+ );
37
+ }
38
+
39
+ return successResponse(user, HTTP_STATUS.OK);
40
+ }
41
+
42
+ /**
43
+ * Lambda handler wrapper
44
+ */
45
+ export const handler = createLambdaHandler(getUserHandler, 'GetUser');
@@ -0,0 +1,23 @@
1
+ import type { ApiGatewayProxyResult } from '{{PACKAGE_SCOPE}}/common-types';
2
+ import { HTTP_STATUS } from '{{PACKAGE_SCOPE}}/common-types';
3
+ import { successResponse } from '../../utils/response';
4
+ import { userService } from '../../services/user-service';
5
+ import {
6
+ createLambdaHandler,
7
+ type ParsedRequest,
8
+ } from '../../utils/lambda-handler';
9
+
10
+ /**
11
+ * GET /users - Get all users
12
+ */
13
+ async function getUsersHandler(
14
+ request: ParsedRequest
15
+ ): Promise<ApiGatewayProxyResult> {
16
+ const userList = await userService.getAllUsers();
17
+ return successResponse(userList, HTTP_STATUS.OK);
18
+ }
19
+
20
+ /**
21
+ * Lambda handler wrapper
22
+ */
23
+ export const handler = createLambdaHandler(getUsersHandler, 'GetUsers');
@@ -0,0 +1,17 @@
1
+ /**
2
+ * User Handlers
3
+ *
4
+ * Individual Lambda handlers for user operations
5
+ */
6
+
7
+ export { handler as getUsersHandler } from './get-users';
8
+ export { handler as getUserHandler } from './get-user';
9
+ export { handler as createUserHandler } from './create-user';
10
+ export { handler as updateUserHandler } from './update-user';
11
+ export { handler as deleteUserHandler } from './delete-user';
12
+ // {{#if AUTH_COGNITO}}
13
+ export { handler as getMeHandler } from './get-me';
14
+ // {{/if AUTH_COGNITO}}
15
+ // {{#if AUTH_AUTH0}}
16
+ export { handler as getMeHandler } from './get-me';
17
+ // {{/if AUTH_AUTH0}}
@@ -0,0 +1,72 @@
1
+ import type {
2
+ ApiGatewayProxyResult,
3
+ UpdateUserRequest,
4
+ } from '{{PACKAGE_SCOPE}}/common-types';
5
+ import { HTTP_STATUS, ERROR_CODES } from '{{PACKAGE_SCOPE}}/common-types';
6
+ import { successResponse } from '../../utils/response';
7
+ import { validate, getValidationErrors } from '../../utils/validator';
8
+ import { userService } from '../../services/user-service';
9
+ import {
10
+ createLambdaHandler,
11
+ createErrorResult,
12
+ validatePathParameters,
13
+ validateBodyPresent,
14
+ type ParsedRequest,
15
+ } from '../../utils/lambda-handler';
16
+ import { updateUserSchema } from '../../schemas/user.schema';
17
+
18
+ /**
19
+ * PUT /users/{id} - Update user
20
+ */
21
+ async function updateUserHandler(
22
+ request: ParsedRequest<UpdateUserRequest>
23
+ ): Promise<ApiGatewayProxyResult> {
24
+ // Validate required path parameters
25
+ const pathValidation = validatePathParameters(request.pathParameters, ['id']);
26
+ if (!pathValidation.valid) {
27
+ throw createErrorResult(
28
+ ERROR_CODES.VALIDATION_ERROR,
29
+ 'User ID is required',
30
+ HTTP_STATUS.BAD_REQUEST
31
+ );
32
+ }
33
+
34
+ // Validate body is present
35
+ const bodyValidation = validateBodyPresent(request.body, request.rawBody);
36
+ if (!bodyValidation.valid) {
37
+ throw createErrorResult(
38
+ ERROR_CODES.VALIDATION_ERROR,
39
+ bodyValidation.error || 'Request body is required',
40
+ HTTP_STATUS.BAD_REQUEST
41
+ );
42
+ }
43
+
44
+ // Validate request data with AJV schema
45
+ const validation = validate(updateUserSchema, request.body);
46
+ if (!validation.valid) {
47
+ throw createErrorResult(
48
+ ERROR_CODES.VALIDATION_ERROR,
49
+ getValidationErrors(validation.errors),
50
+ HTTP_STATUS.BAD_REQUEST,
51
+ { errors: validation.errors }
52
+ );
53
+ }
54
+
55
+ const userId = request.pathParameters['id'];
56
+ const updatedUser = await userService.updateUser(userId, request.body as UpdateUserRequest);
57
+
58
+ if (!updatedUser) {
59
+ throw createErrorResult(
60
+ ERROR_CODES.NOT_FOUND,
61
+ 'User not found',
62
+ HTTP_STATUS.NOT_FOUND
63
+ );
64
+ }
65
+
66
+ return successResponse(updatedUser, HTTP_STATUS.OK, 'User updated successfully');
67
+ }
68
+
69
+ /**
70
+ * Lambda handler wrapper
71
+ */
72
+ export const handler = createLambdaHandler(updateUserHandler, 'UpdateUser');