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.
- package/README.md +118 -0
- package/dist/__tests__/generator/replace-tokens.spec.d.ts +1 -0
- package/dist/__tests__/generator/replace-tokens.spec.js +281 -0
- package/dist/__tests__/generator.spec.d.ts +1 -0
- package/dist/__tests__/generator.spec.js +162 -0
- package/dist/__tests__/validation/project-name.spec.d.ts +1 -0
- package/dist/__tests__/validation/project-name.spec.js +57 -0
- package/dist/__tests__/wizard.spec.d.ts +1 -0
- package/dist/__tests__/wizard.spec.js +232 -0
- package/dist/aws/iam.d.ts +75 -0
- package/dist/aws/iam.js +264 -0
- package/dist/aws/organizations.d.ts +79 -0
- package/dist/aws/organizations.js +168 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +206 -0
- package/dist/commands/setup-github.d.ts +4 -0
- package/dist/commands/setup-github.js +185 -0
- package/dist/generator/copy-file.d.ts +15 -0
- package/dist/generator/copy-file.js +56 -0
- package/dist/generator/generate-project.d.ts +14 -0
- package/dist/generator/generate-project.js +81 -0
- package/dist/generator/index.d.ts +4 -0
- package/dist/generator/index.js +3 -0
- package/dist/generator/replace-tokens.d.ts +29 -0
- package/dist/generator/replace-tokens.js +68 -0
- package/dist/github/secrets.d.ts +109 -0
- package/dist/github/secrets.js +275 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/dist/prompts/auth.d.ts +3 -0
- package/dist/prompts/auth.js +23 -0
- package/dist/prompts/aws-config.d.ts +2 -0
- package/dist/prompts/aws-config.js +14 -0
- package/dist/prompts/features.d.ts +2 -0
- package/dist/prompts/features.js +10 -0
- package/dist/prompts/github-setup.d.ts +53 -0
- package/dist/prompts/github-setup.js +208 -0
- package/dist/prompts/org-structure.d.ts +9 -0
- package/dist/prompts/org-structure.js +93 -0
- package/dist/prompts/platforms.d.ts +2 -0
- package/dist/prompts/platforms.js +12 -0
- package/dist/prompts/project-name.d.ts +2 -0
- package/dist/prompts/project-name.js +8 -0
- package/dist/prompts/theme.d.ts +2 -0
- package/dist/prompts/theme.js +14 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +2 -0
- package/dist/templates/manifest.d.ts +11 -0
- package/dist/templates/manifest.js +99 -0
- package/dist/templates/tokens.d.ts +39 -0
- package/dist/templates/tokens.js +37 -0
- package/dist/templates/types.d.ts +52 -0
- package/dist/templates/types.js +1 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.js +1 -0
- package/dist/validation/project-name.d.ts +1 -0
- package/dist/validation/project-name.js +12 -0
- package/dist/wizard.d.ts +2 -0
- package/dist/wizard.js +81 -0
- package/package.json +68 -0
- package/templates/.github/actions/build-and-test/action.yml +24 -0
- package/templates/.github/actions/deploy-cdk/action.yml +46 -0
- package/templates/.github/actions/deploy-web/action.yml +72 -0
- package/templates/.github/actions/setup/action.yml +29 -0
- package/templates/.github/pull_request_template.md +15 -0
- package/templates/.github/workflows/deploy-dev.yml +80 -0
- package/templates/.github/workflows/deploy-prod.yml +67 -0
- package/templates/.github/workflows/deploy-stage.yml +77 -0
- package/templates/.github/workflows/pull-request.yml +72 -0
- package/templates/.vscode/extensions.json +7 -0
- package/templates/.vscode/settings.json +67 -0
- package/templates/apps/api/.eslintrc.json +18 -0
- package/templates/apps/api/cdk/app.ts +93 -0
- package/templates/apps/api/cdk/auth/cognito-stack.ts +164 -0
- package/templates/apps/api/cdk/cdk.json +73 -0
- package/templates/apps/api/cdk/deployment-user-stack.ts +187 -0
- package/templates/apps/api/cdk/org-stack.ts +67 -0
- package/templates/apps/api/cdk/static-stack.ts +361 -0
- package/templates/apps/api/cdk/tsconfig.json +39 -0
- package/templates/apps/api/cdk/user-stack.ts +255 -0
- package/templates/apps/api/jest.config.ts +38 -0
- package/templates/apps/api/lambdas.yml +84 -0
- package/templates/apps/api/project.json.template +58 -0
- package/templates/apps/api/src/__tests__/setup.ts +10 -0
- package/templates/apps/api/src/handlers/users/create-user.ts +52 -0
- package/templates/apps/api/src/handlers/users/delete-user.ts +45 -0
- package/templates/apps/api/src/handlers/users/get-me.ts +72 -0
- package/templates/apps/api/src/handlers/users/get-user.ts +45 -0
- package/templates/apps/api/src/handlers/users/get-users.ts +23 -0
- package/templates/apps/api/src/handlers/users/index.ts +17 -0
- package/templates/apps/api/src/handlers/users/update-user.ts +72 -0
- package/templates/apps/api/src/lib/dynamo/dynamo-model.ts +504 -0
- package/templates/apps/api/src/lib/dynamo/index.ts +12 -0
- package/templates/apps/api/src/lib/dynamo/utils.ts +39 -0
- package/templates/apps/api/src/middleware/auth0-auth.ts +97 -0
- package/templates/apps/api/src/middleware/cognito-auth.ts +90 -0
- package/templates/apps/api/src/models/UserModel.ts +109 -0
- package/templates/apps/api/src/schemas/user.schema.ts +44 -0
- package/templates/apps/api/src/services/user-service.ts +108 -0
- package/templates/apps/api/src/utils/auth-context.ts +60 -0
- package/templates/apps/api/src/utils/common/helpers.ts +26 -0
- package/templates/apps/api/src/utils/lambda-handler.ts +148 -0
- package/templates/apps/api/src/utils/response.ts +52 -0
- package/templates/apps/api/src/utils/validator.ts +75 -0
- package/templates/apps/api/tsconfig.app.json +15 -0
- package/templates/apps/api/tsconfig.json +19 -0
- package/templates/apps/api/tsconfig.spec.json +17 -0
- package/templates/apps/mobile/.env.example +5 -0
- package/templates/apps/mobile/.eslintrc.json +33 -0
- package/templates/apps/mobile/app.json +33 -0
- package/templates/apps/mobile/assets/.gitkeep +0 -0
- package/templates/apps/mobile/babel.config.js +19 -0
- package/templates/apps/mobile/index.js +7 -0
- package/templates/apps/mobile/jest.config.ts +22 -0
- package/templates/apps/mobile/metro.config.js +35 -0
- package/templates/apps/mobile/package.json +22 -0
- package/templates/apps/mobile/project.json.template +64 -0
- package/templates/apps/mobile/src/App.tsx +367 -0
- package/templates/apps/mobile/src/__tests__/App.spec.tsx +46 -0
- package/templates/apps/mobile/src/__tests__/store/user-store.spec.ts +156 -0
- package/templates/apps/mobile/src/config/api.ts +16 -0
- package/templates/apps/mobile/src/store/user-store.ts +56 -0
- package/templates/apps/mobile/src/test-setup.ts +10 -0
- package/templates/apps/mobile/tsconfig.json +22 -0
- package/templates/apps/web/.env.example +13 -0
- package/templates/apps/web/.eslintrc.json +26 -0
- package/templates/apps/web/index.html +13 -0
- package/templates/apps/web/jest.config.ts +24 -0
- package/templates/apps/web/package.json +15 -0
- package/templates/apps/web/project.json.template +66 -0
- package/templates/apps/web/src/App.tsx +352 -0
- package/templates/apps/web/src/__mocks__/config/api.ts +41 -0
- package/templates/apps/web/src/__tests__/App.spec.tsx +240 -0
- package/templates/apps/web/src/__tests__/store/user-store.spec.ts +185 -0
- package/templates/apps/web/src/auth/auth0-provider.tsx +103 -0
- package/templates/apps/web/src/auth/cognito-provider.tsx +143 -0
- package/templates/apps/web/src/auth/index.ts +7 -0
- package/templates/apps/web/src/auth/use-auth.ts +16 -0
- package/templates/apps/web/src/config/amplify-config.ts +31 -0
- package/templates/apps/web/src/config/api.ts +38 -0
- package/templates/apps/web/src/config/auth0-config.ts +17 -0
- package/templates/apps/web/src/main.tsx +41 -0
- package/templates/apps/web/src/store/user-store.ts +56 -0
- package/templates/apps/web/src/styles.css +165 -0
- package/templates/apps/web/src/test-setup.ts +1 -0
- package/templates/apps/web/src/theme/index.ts +30 -0
- package/templates/apps/web/src/vite-env.d.ts +19 -0
- package/templates/apps/web/tsconfig.app.json +24 -0
- package/templates/apps/web/tsconfig.json +22 -0
- package/templates/apps/web/tsconfig.spec.json +28 -0
- package/templates/apps/web/vite.config.ts +87 -0
- package/templates/manifest.json +28 -0
- package/templates/packages/api-client/.eslintrc.json +18 -0
- package/templates/packages/api-client/jest.config.ts +13 -0
- package/templates/packages/api-client/package.json +8 -0
- package/templates/packages/api-client/project.json.template +34 -0
- package/templates/packages/api-client/src/__tests__/api-client.spec.ts +408 -0
- package/templates/packages/api-client/src/api-client.ts +201 -0
- package/templates/packages/api-client/src/config.ts +193 -0
- package/templates/packages/api-client/src/index.ts +9 -0
- package/templates/packages/api-client/tsconfig.json +22 -0
- package/templates/packages/api-client/tsconfig.lib.json +11 -0
- package/templates/packages/api-client/tsconfig.spec.json +14 -0
- package/templates/packages/common-types/.eslintrc.json +18 -0
- package/templates/packages/common-types/package.json +6 -0
- package/templates/packages/common-types/project.json.template +26 -0
- package/templates/packages/common-types/src/api.types.ts +24 -0
- package/templates/packages/common-types/src/auth.types.ts +36 -0
- package/templates/packages/common-types/src/common.types.ts +46 -0
- package/templates/packages/common-types/src/index.ts +19 -0
- package/templates/packages/common-types/src/lambda.types.ts +39 -0
- package/templates/packages/common-types/src/user.types.ts +31 -0
- package/templates/packages/common-types/tsconfig.json +19 -0
- package/templates/packages/common-types/tsconfig.lib.json +11 -0
- package/templates/root/.editorconfig +23 -0
- package/templates/root/.nvmrc +1 -0
- package/templates/root/eslint.config.js +61 -0
- package/templates/root/jest.preset.js +16 -0
- package/templates/root/nx.json +29 -0
- package/templates/root/package.json +131 -0
- 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');
|