From 9ded6e2c6a3626147e8b249f733dbfc3c7f44485 Mon Sep 17 00:00:00 2001 From: Maor Barazani Date: Sun, 5 May 2024 23:43:02 +0300 Subject: [PATCH 1/2] difference highlights --- .../environment/environment.controller.ts | 29 +++++++++++++++ src/domain/log/logs.controller.ts | 20 ++++++++++ src/domain/pub-sub/pub-sub.controller.ts | 24 ++++++++++++ src/domain/secrets/secrets.controller.ts | 8 ++++ .../secure-storage.controller.ts | 22 +++++++++++ src/domain/storage/storage.controller.ts | 37 +++++++++++++++++++ 6 files changed, 140 insertions(+) diff --git a/src/domain/environment/environment.controller.ts b/src/domain/environment/environment.controller.ts index 49a5b7f..21c349f 100644 --- a/src/domain/environment/environment.controller.ts +++ b/src/domain/environment/environment.controller.ts @@ -23,4 +23,33 @@ export class EnvironmentController { return value; } + + // TODO: + /** + * Differences Identified: + * Endpoint Path Difference: + * SIDECAR uses /environment-variables/{name} + * TARGET uses /environments/{name} + * OperationId Difference: + * SIDECAR: getEnvironmentVariable + * TARGET: getEnvironment + * Return Type: + * SIDECAR explicitly returns a string. + * TARGET returns an unknown type. + * Required Changes to TARGET: + * Align Endpoint Path: + * Change the endpoint path in TARGET from /environments/{name} to /environment-variables/{name} to match SIDECAR. + * Standardize OperationId: + * Update the OperationId in TARGET to getEnvironmentVariable to maintain consistency with SIDECAR. + * Standardize Return Type: + * Change the return type in the TARGET from unknown to string to align with the explicit type definition in SIDECAR. + */ } + +// TODO: +/** + * Required Changes to TARGET: + * Add Missing Endpoint: + * Implement the /environments GET endpoint in TARGET to retrieve all environment variable keys. + * Define the operation as getEnvironmentVariableKeys with a 200 response returning an array of strings. + */ diff --git a/src/domain/log/logs.controller.ts b/src/domain/log/logs.controller.ts index 84d87ba..7f368de 100644 --- a/src/domain/log/logs.controller.ts +++ b/src/domain/log/logs.controller.ts @@ -16,4 +16,24 @@ export class LogsController { const { params, message, method, error } = body; UserLogsService.log(method, message, error, params); } + + // TODO: + /** + * Differences Identified: + * Request Body: + * SIDECAR accepts message, method, and error. + * TARGET additionally accepts params. + * Required Changes to TARGET: + * Align Request Body: + * Remove params from WriteLogRequestBody in TARGET to match the request body structure of SIDECAR. + * Check for Path and Query Parameters: + * Both implementations do not use path or query parameters in their current form. Ensure this remains consistent unless specified by functional requirements. + * Align Response Definitions: + * Both APIs provide the same response for successful execution (204 No Content). Ensure that error responses (if any defined elsewhere) are consistent in terms of HTTP status codes and response bodies. + */ } + +// TODO: +/** + * + */ diff --git a/src/domain/pub-sub/pub-sub.controller.ts b/src/domain/pub-sub/pub-sub.controller.ts index ccf2828..9cc51b8 100644 --- a/src/domain/pub-sub/pub-sub.controller.ts +++ b/src/domain/pub-sub/pub-sub.controller.ts @@ -17,6 +17,17 @@ export class PubSubController { const id = PubSubService.publishMessage(message); return { id }; + + // TODO: + /** + * Differences Identified: + * Formal Response Body Type: + * SIDECAR explicitly returns PublishMessageResponse. + * TARGET returns { id } but does not explicitly use PublishMessageResponse. + * Required Changes to TARGET: + * Standardize Response Body Type: + * Ensure the TARGET uses PublishMessageResponse as the formal response body type to maintain API consistency. + */ } @Post('validate-secret') @@ -27,5 +38,18 @@ export class PubSubController { const valid = PubSubService.validateSecret(secret); return { valid }; + + // TODO: + /** + * Differences Identified: + * Formal Response Body Type: + * SIDECAR explicitly returns ValidateSecretResponse. + * TARGET returns { valid } but does not explicitly use ValidateSecretResponse. + * Required Changes to TARGET: + * Standardize Response Body Type: + * Ensure the TARGET uses ValidateSecretResponse as the formal response body type for consistency. + */ } } + +// TODO: file and class names diff --git a/src/domain/secrets/secrets.controller.ts b/src/domain/secrets/secrets.controller.ts index c28b0be..28c494c 100644 --- a/src/domain/secrets/secrets.controller.ts +++ b/src/domain/secrets/secrets.controller.ts @@ -21,3 +21,11 @@ export class SecretsController { return secret; } } + +// TODO: +/** + * Required Changes to TARGET: + * Add Missing Endpoint: + * Implement the /secrets GET endpoint in TARGET to retrieve all secret keys. + * Define the operation as getSecretKeys with a 200 response returning an array of strings, similar to SIDECAR. + */ diff --git a/src/domain/secure-storage/secure-storage.controller.ts b/src/domain/secure-storage/secure-storage.controller.ts index 30b72b7..4360a2b 100644 --- a/src/domain/secure-storage/secure-storage.controller.ts +++ b/src/domain/secure-storage/secure-storage.controller.ts @@ -27,6 +27,17 @@ export class SecureStorageController { } return { value }; + + // TODO: + /** + * Differences Identified: + * Response Data Type: + * SIDECAR returns a type defined as SecureStorageDataContract. + * TARGET returns a JSON object directly. + * Required Changes to TARGET: + * Standardize Response Type: + * Adjust TARGET to use SecureStorageDataContract for the response type to ensure type consistency. + */ } @Delete('{key}') @@ -47,4 +58,15 @@ export class SecureStorageController { SecureStorageService.setSecureValue(key, value); return value; } + + // TODO: + /** + * Differences Identified: + * Request Body Type: + * SIDECAR uses SecureStorageDataContract. + * TARGET uses SetSecureStorageForKeyRequestBody. + * Required Changes to TARGET: + * Align Request Body Type: + * Change the request body type in TARGET from SetSecureStorageForKeyRequestBody to SecureStorageDataContract to maintain type consistency across both APIs. + */ } diff --git a/src/domain/storage/storage.controller.ts b/src/domain/storage/storage.controller.ts index 19dcd21..a2e3019 100644 --- a/src/domain/storage/storage.controller.ts +++ b/src/domain/storage/storage.controller.ts @@ -32,6 +32,17 @@ export class StorageController { } return { value, version }; + + // TODO: + /** + * Differences Identified: + * Response Data Type: + * SIDECAR uses StorageDataContract. + * TARGET directly returns a JSON object. + * Required Changes to TARGET: + * Standardize Response Type: + * Adjust TARGET to use StorageDataContract for the response type to ensure type consistency. + */ } @Delete('{key}') @@ -55,6 +66,16 @@ export class StorageController { await storageService.set(key, value, { previousVersion, shared }); return value; + // TODO + /** + * Differences Identified: + * Request Body Type: + * SIDECAR uses StorageDataContract. + * TARGET uses SetStorageForKeyRequestBody. + * Required Changes to TARGET: + * Align Request Body Type: + * Change the request body type in TARGET from SetStorageForKeyRequestBody to StorageDataContract to maintain type consistency across both APIs. + */ } @Put('counter/increment') @@ -68,5 +89,21 @@ export class StorageController { const storageService = new StorageService(accessToken); const value = await storageService.incrementCounter(period, { incrementBy, kind, renewalDate }); return value?.newCounterValue?.toString(); + + // TODO: + /** + * Differences Identified: + * Request Body Type: + * SIDECAR uses IncrementCounterParams. + * TARGET uses IncrementStorageForKeyRequestBody. + * Method Type: + * SIDECAR uses POST. + * TARGET uses PUT. + * Required Changes to TARGET: + * Align Method Type: + * Change the method type in TARGET from PUT to POST to match SIDECAR. + * Align Request Body Type: + * Change the request body type in TARGET from IncrementStorageForKeyRequestBody to IncrementCounterParams to maintain consistency. + */ } } From 263c8f263ce6109e3b64dbedf70ca14faa0abf65 Mon Sep 17 00:00:00 2001 From: Maor Barazani Date: Tue, 7 May 2024 14:34:37 +0300 Subject: [PATCH 2/2] align local-server controllers and endpoints to that of the remote sidecar --- build/swagger.yaml | 112 +++++++++++++++--- .../environment-variables-test.controller.ts} | 12 +- .../environment-variables.consts.ts | 3 + .../environment-variables.controller.ts | 36 ++++++ .../environment-variables.schema.ts} | 4 +- .../environment-variables.service.ts | 36 ++++++ .../environment-variables.types.ts} | 2 +- src/domain/environment/environment.consts.ts | 3 - .../environment/environment.controller.ts | 55 --------- src/domain/environment/environment.service.ts | 32 ----- src/domain/log/logs.controller.ts | 24 +--- src/domain/log/logs.service.ts | 4 +- src/domain/log/logs.types.ts | 1 - src/domain/pub-sub/pub-sub.consts.ts | 6 - src/domain/pub-sub/pub-sub.controller.ts | 55 --------- src/domain/queue/queue.consts.ts | 6 + src/domain/queue/queue.controller.ts | 31 +++++ .../queue.schema.ts} | 0 .../queue.service.ts} | 12 +- .../pub-sub.types.ts => queue/queue.types.ts} | 0 src/domain/secrets/secrets.controller.ts | 29 +++-- src/domain/secrets/secrets.service.ts | 15 ++- .../secure-storage.controller.ts | 28 +---- src/domain/storage/storage.controller.ts | 64 +++------- src/domain/storage/storage.types.ts | 2 +- src/routes.ts | 112 ++++++++++++++---- .../schema-validation.middleware.ts | 4 +- src/shared/utils/files.ts | 4 +- 28 files changed, 368 insertions(+), 324 deletions(-) rename src/domain/{environment/environment-test.controller.ts => environment-variables/environment-variables-test.controller.ts} (53%) create mode 100644 src/domain/environment-variables/environment-variables.consts.ts create mode 100644 src/domain/environment-variables/environment-variables.controller.ts rename src/domain/{environment/environment.schema.ts => environment-variables/environment-variables.schema.ts} (67%) create mode 100644 src/domain/environment-variables/environment-variables.service.ts rename src/domain/{environment/environment.types.ts => environment-variables/environment-variables.types.ts} (57%) delete mode 100644 src/domain/environment/environment.consts.ts delete mode 100644 src/domain/environment/environment.controller.ts delete mode 100644 src/domain/environment/environment.service.ts delete mode 100644 src/domain/pub-sub/pub-sub.consts.ts delete mode 100644 src/domain/pub-sub/pub-sub.controller.ts create mode 100644 src/domain/queue/queue.consts.ts create mode 100644 src/domain/queue/queue.controller.ts rename src/domain/{pub-sub/pub-sub.schema.ts => queue/queue.schema.ts} (100%) rename src/domain/{pub-sub/pub-sub.service.ts => queue/queue.service.ts} (91%) rename src/domain/{pub-sub/pub-sub.types.ts => queue/queue.types.ts} (100%) diff --git a/build/swagger.yaml b/build/swagger.yaml index 3126b07..f520030 100644 --- a/build/swagger.yaml +++ b/build/swagger.yaml @@ -22,10 +22,6 @@ components: nullable: true SetStorageForKeyRequestBody: properties: - shared: - type: boolean - previousVersion: - type: string value: type: string required: @@ -97,8 +93,6 @@ components: description: Construct a type with a set of properties K of type T WriteLogRequestBody: properties: - params: - $ref: "#/components/schemas/Record_string.unknown_" error: anyOf: - type: string @@ -110,7 +104,7 @@ components: required: - method type: object - SetEnvironmentForKeyRequestBody: + SetEnvironmentVariableForKeyRequestBody: properties: value: $ref: "#/components/schemas/JsonValue" @@ -210,7 +204,27 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/JsonValue" + anyOf: + - properties: + error: {} + success: + type: boolean + version: + type: string + required: + - success + - version + type: object + - properties: + version: {} + success: + type: boolean + error: + type: string + required: + - success + - error + type: object tags: - Storage security: [] @@ -225,6 +239,16 @@ paths: required: true schema: type: string + - in: query + name: shared + required: false + schema: + type: boolean + - in: query + name: previousVersion + required: false + schema: + type: string requestBody: required: true content: @@ -240,7 +264,32 @@ paths: content: application/json: schema: - type: string + anyOf: + - properties: + newCounterValue: {} + message: {} + success: + type: boolean + error: + type: string + required: + - success + - error + type: object + - properties: + error: {} + success: + type: boolean + newCounterValue: + type: number + format: double + message: + type: string + required: + - success + - newCounterValue + - message + type: object tags: - Storage security: [] @@ -313,7 +362,7 @@ paths: content: application/json: schema: - type: string + type: boolean tags: - SecureStorage security: [] @@ -359,6 +408,22 @@ paths: required: true schema: type: string + /secrets: + get: + operationId: getSecretKeys + responses: + "200": + description: OK + content: + application/json: + schema: + items: + type: string + type: array + tags: + - Secret + security: [] + parameters: [] /test/secrets/{name}: put: operationId: setSecretTestRoute @@ -446,15 +511,16 @@ paths: application/json: schema: $ref: "#/components/schemas/WriteLogRequestBody" - /environments/{name}: + /environment-variables/{name}: get: - operationId: getEnvironment + operationId: getEnvironmentVariable responses: "200": description: OK content: application/json: - schema: {} + schema: + $ref: "#/components/schemas/JsonValue" "404": description: "" content: @@ -467,7 +533,7 @@ paths: - reason type: object tags: - - Environment + - EnvironmentVariables security: [] parameters: - in: path @@ -475,6 +541,22 @@ paths: required: true schema: type: string + /environment-variables: + get: + operationId: getEnvironmentVariableKeys + responses: + "200": + description: Ok + content: + application/json: + schema: + items: + type: string + type: array + tags: + - EnvironmentVariables + security: [] + parameters: [] /test/environments/{name}: put: operationId: setEnvironmentTestRoute @@ -495,7 +577,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/SetEnvironmentForKeyRequestBody" + $ref: "#/components/schemas/SetEnvironmentVariableForKeyRequestBody" servers: - url: http://localhost:59999 description: monday-code Local dev server diff --git a/src/domain/environment/environment-test.controller.ts b/src/domain/environment-variables/environment-variables-test.controller.ts similarity index 53% rename from src/domain/environment/environment-test.controller.ts rename to src/domain/environment-variables/environment-variables-test.controller.ts index f50dbee..86ae57a 100644 --- a/src/domain/environment/environment-test.controller.ts +++ b/src/domain/environment-variables/environment-variables-test.controller.ts @@ -2,21 +2,23 @@ import { OperationId, SuccessResponse } from '@tsoa/runtime'; import { ReasonPhrases, StatusCodes } from 'http-status-codes'; import { Body, Path, Put, Route, Tags } from 'tsoa'; -import { EnvironmentService } from './environment.service'; +import { EnvironmentVariablesService } from './environment-variables.service'; -import type { SetEnvironmentForKeyRequestBody } from 'domain/environment/environment.types'; +import type { SetEnvironmentVariableForKeyRequestBody } from 'domain/environment-variables/environment-variables.types'; @Route('test/environments') @Tags('TestRoutes') -export class EnvironmentTestController { +export class EnvironmentVariablesTestController { @Put('{name}') @OperationId('setEnvironmentTestRoute') @SuccessResponse(StatusCodes.NO_CONTENT, ReasonPhrases.NO_CONTENT) public async setEnvironmentForKey( @Path() name: string, - @Body() body: SetEnvironmentForKeyRequestBody + @Body() body: SetEnvironmentVariableForKeyRequestBody ): Promise { const { value } = body; - EnvironmentService.setEnvironmentForKey(name, value); + EnvironmentVariablesService.setEnvironmentVariableForKey(name, value); } } + +// TODO: what is this? needed? diff --git a/src/domain/environment-variables/environment-variables.consts.ts b/src/domain/environment-variables/environment-variables.consts.ts new file mode 100644 index 0000000..e8b5208 --- /dev/null +++ b/src/domain/environment-variables/environment-variables.consts.ts @@ -0,0 +1,3 @@ +import { VOLUME_PATH } from 'shared/config'; + +export const ENVIRONMENT_VARIABLES_FILE = `${VOLUME_PATH}/env.json`; diff --git a/src/domain/environment-variables/environment-variables.controller.ts b/src/domain/environment-variables/environment-variables.controller.ts new file mode 100644 index 0000000..97b793e --- /dev/null +++ b/src/domain/environment-variables/environment-variables.controller.ts @@ -0,0 +1,36 @@ +import { OperationId, Res, SuccessResponse } from '@tsoa/runtime'; +import { ReasonPhrases, StatusCodes } from 'http-status-codes'; +import { Get, Path, Route, Tags } from 'tsoa'; + +import { EnvironmentVariablesService } from './environment-variables.service'; + +import type { TsoaResponse } from '@tsoa/runtime'; +import type { JsonValue } from 'types/general.type'; + +@Route('environment-variables') +@Tags('EnvironmentVariables') +export class EnvironmentVariablesController { + @Get('{name}') + @OperationId('getEnvironmentVariable') + @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) + public async getEnvironmentVariableForKey( + @Path() name: string, + @Res() notFoundResponse: TsoaResponse + ): Promise { + const value = EnvironmentVariablesService.getEnvironmentVariableForKey(name); + if (value === undefined) { + return notFoundResponse(StatusCodes.NOT_FOUND, { reason: 'Environment variable not found' }); + } + + return value; + } + + @Get() + @OperationId('getEnvironmentVariableKeys') + public async getKeys(): Promise { + const keys = EnvironmentVariablesService.getEnvironmentVariableKeys(); + return keys; + } +} + +// FIXME: in the sidecar, re-check env-vars and secrets are working after my fix to the "falsy" check diff --git a/src/domain/environment/environment.schema.ts b/src/domain/environment-variables/environment-variables.schema.ts similarity index 67% rename from src/domain/environment/environment.schema.ts rename to src/domain/environment-variables/environment-variables.schema.ts index 166e58f..415a575 100644 --- a/src/domain/environment/environment.schema.ts +++ b/src/domain/environment-variables/environment-variables.schema.ts @@ -2,13 +2,13 @@ import { z } from 'zod'; import { jsonValueSchema } from 'shared/schemas/general.schema'; -export const getEnvironmentForKeyRequestSchema = { +export const getEnvironmentVariableForKeyRequestSchema = { params: z.object({ key: z.string() }) }; -export const setEnvironmentForKeyRequestSchema = { +export const setEnvironmentVariableForKeyRequestSchema = { params: z.object({ key: z.string() }), diff --git a/src/domain/environment-variables/environment-variables.service.ts b/src/domain/environment-variables/environment-variables.service.ts new file mode 100644 index 0000000..a9d5482 --- /dev/null +++ b/src/domain/environment-variables/environment-variables.service.ts @@ -0,0 +1,36 @@ +import { ENVIRONMENT_VARIABLES_FILE } from 'domain/environment-variables/environment-variables.consts'; +import { initFileIfNotExists, readJsonFile, writeJsonFile } from 'utils/files'; + +import type { JsonValue } from 'types/general.type'; + +export class EnvironmentVariablesService { + private static isInitialized = false; + + private static initialize() { + if (this.isInitialized) { + return; + } + + initFileIfNotExists(ENVIRONMENT_VARIABLES_FILE); + this.isInitialized = true; + } + + static getEnvironmentVariableForKey(key: string) { + this.initialize(); + const environmentFile = readJsonFile(ENVIRONMENT_VARIABLES_FILE); + return environmentFile[key]; + } + + static setEnvironmentVariableForKey(key: string, value: JsonValue) { + this.initialize(); + const environmentFile = readJsonFile(ENVIRONMENT_VARIABLES_FILE); + environmentFile[key] = value; + writeJsonFile(ENVIRONMENT_VARIABLES_FILE, environmentFile); + } + + static getEnvironmentVariableKeys(): Array { + this.initialize(); + const environmentFile = readJsonFile(ENVIRONMENT_VARIABLES_FILE); + return Object.keys(environmentFile); + } +} diff --git a/src/domain/environment/environment.types.ts b/src/domain/environment-variables/environment-variables.types.ts similarity index 57% rename from src/domain/environment/environment.types.ts rename to src/domain/environment-variables/environment-variables.types.ts index 989558d..31aa263 100644 --- a/src/domain/environment/environment.types.ts +++ b/src/domain/environment-variables/environment-variables.types.ts @@ -1,5 +1,5 @@ import type { JsonValue } from 'types/general.type'; -export type SetEnvironmentForKeyRequestBody = { +export type SetEnvironmentVariableForKeyRequestBody = { value: JsonValue; }; diff --git a/src/domain/environment/environment.consts.ts b/src/domain/environment/environment.consts.ts deleted file mode 100644 index 4ed9541..0000000 --- a/src/domain/environment/environment.consts.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { VOLUME_PATH } from 'shared/config'; - -export const ENVIRONMENT_FILE = `${VOLUME_PATH}/env.json`; diff --git a/src/domain/environment/environment.controller.ts b/src/domain/environment/environment.controller.ts deleted file mode 100644 index 21c349f..0000000 --- a/src/domain/environment/environment.controller.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { OperationId, Res, SuccessResponse } from '@tsoa/runtime'; -import { ReasonPhrases, StatusCodes } from 'http-status-codes'; -import { Get, Path, Route, Tags } from 'tsoa'; - -import { EnvironmentService } from './environment.service'; - -import type { TsoaResponse } from '@tsoa/runtime'; - -@Route('environments') -@Tags('Environment') -export class EnvironmentController { - @Get('{name}') - @OperationId('getEnvironment') - @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) - public async getEnvironmentForKey( - @Path() name: string, - @Res() notFoundResponse: TsoaResponse<404, { reason: string }> - ): Promise { - const value = EnvironmentService.getEnvironmentForKey(name); - if (!value) { - return notFoundResponse(404, { reason: 'Environment variable not found' }); - } - - return value; - } - - // TODO: - /** - * Differences Identified: - * Endpoint Path Difference: - * SIDECAR uses /environment-variables/{name} - * TARGET uses /environments/{name} - * OperationId Difference: - * SIDECAR: getEnvironmentVariable - * TARGET: getEnvironment - * Return Type: - * SIDECAR explicitly returns a string. - * TARGET returns an unknown type. - * Required Changes to TARGET: - * Align Endpoint Path: - * Change the endpoint path in TARGET from /environments/{name} to /environment-variables/{name} to match SIDECAR. - * Standardize OperationId: - * Update the OperationId in TARGET to getEnvironmentVariable to maintain consistency with SIDECAR. - * Standardize Return Type: - * Change the return type in the TARGET from unknown to string to align with the explicit type definition in SIDECAR. - */ -} - -// TODO: -/** - * Required Changes to TARGET: - * Add Missing Endpoint: - * Implement the /environments GET endpoint in TARGET to retrieve all environment variable keys. - * Define the operation as getEnvironmentVariableKeys with a 200 response returning an array of strings. - */ diff --git a/src/domain/environment/environment.service.ts b/src/domain/environment/environment.service.ts deleted file mode 100644 index dcbe799..0000000 --- a/src/domain/environment/environment.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { SECRETS_FILE } from 'domain/secrets/secrets.consts'; -import { initFileIfNotExists, readJsonFile, writeJsonFile } from 'utils/files'; - -import { ENVIRONMENT_FILE } from './environment.consts'; - -import type { JsonValue } from 'types/general.type'; - -export class EnvironmentService { - private static isInitialized = false; - - private static initialize() { - if (this.isInitialized) { - return; - } - - initFileIfNotExists(SECRETS_FILE); - this.isInitialized = true; - } - - static getEnvironmentForKey(key: string) { - this.initialize(); - const environmentFile = readJsonFile(ENVIRONMENT_FILE); - return environmentFile[key]; - } - - static setEnvironmentForKey(key: string, value: JsonValue) { - this.initialize(); - const environmentFile = readJsonFile(ENVIRONMENT_FILE); - environmentFile[key] = value; - writeJsonFile(ENVIRONMENT_FILE, environmentFile); - } -} diff --git a/src/domain/log/logs.controller.ts b/src/domain/log/logs.controller.ts index 7f368de..70c93e1 100644 --- a/src/domain/log/logs.controller.ts +++ b/src/domain/log/logs.controller.ts @@ -13,27 +13,7 @@ export class LogsController { @OperationId('writeLog') @SuccessResponse(StatusCodes.NO_CONTENT, ReasonPhrases.NO_CONTENT) public async writeLog(@Body() body: WriteLogRequestBody): Promise { - const { params, message, method, error } = body; - UserLogsService.log(method, message, error, params); + const { message, method, error } = body; + UserLogsService.log(method, message, error); } - - // TODO: - /** - * Differences Identified: - * Request Body: - * SIDECAR accepts message, method, and error. - * TARGET additionally accepts params. - * Required Changes to TARGET: - * Align Request Body: - * Remove params from WriteLogRequestBody in TARGET to match the request body structure of SIDECAR. - * Check for Path and Query Parameters: - * Both implementations do not use path or query parameters in their current form. Ensure this remains consistent unless specified by functional requirements. - * Align Response Definitions: - * Both APIs provide the same response for successful execution (204 No Content). Ensure that error responses (if any defined elsewhere) are consistent in terms of HTTP status codes and response bodies. - */ } - -// TODO: -/** - * - */ diff --git a/src/domain/log/logs.service.ts b/src/domain/log/logs.service.ts index 6d97d3c..84a6575 100644 --- a/src/domain/log/logs.service.ts +++ b/src/domain/log/logs.service.ts @@ -4,7 +4,7 @@ import { Logger } from 'utils/logger'; const logger = new Logger('user-logs'); export class UserLogsService { - static log(method = LogMethods.INFO, message?: string, error?: string | object, params?: object) { - logger[method]({ ...params, ...(error && { error }) }, message); + static log(method = LogMethods.INFO, message?: string, error?: string | object) { + logger[method]({ ...(error && { error }) }, message); } } diff --git a/src/domain/log/logs.types.ts b/src/domain/log/logs.types.ts index 63e2bf0..f61bae8 100644 --- a/src/domain/log/logs.types.ts +++ b/src/domain/log/logs.types.ts @@ -4,5 +4,4 @@ export type WriteLogRequestBody = { method: LogMethods; message?: string; error?: string | Record; - params?: Record; }; diff --git a/src/domain/pub-sub/pub-sub.consts.ts b/src/domain/pub-sub/pub-sub.consts.ts deleted file mode 100644 index f1a3474..0000000 --- a/src/domain/pub-sub/pub-sub.consts.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { TIME_IN_SECONDS } from 'utils/time-enum'; - -export const APP_SERVICE_URL = process.env.PUB_SUB_DEV_APP_SERVICE_URL; -export const APP_SERVICE_PUB_SUB_ENDPOINT = '/mndy-queue'; -export const PUB_SUB_RETRY_INTERVAL_IN_SECONDS = - Number(process.env.PUB_SUB_RETRY_INTERVAL_IN_SECONDS) || TIME_IN_SECONDS.MINUTE * 10; diff --git a/src/domain/pub-sub/pub-sub.controller.ts b/src/domain/pub-sub/pub-sub.controller.ts deleted file mode 100644 index 9cc51b8..0000000 --- a/src/domain/pub-sub/pub-sub.controller.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { OperationId, Post, SuccessResponse } from '@tsoa/runtime'; -import { ReasonPhrases, StatusCodes } from 'http-status-codes'; -import { Body, Route, Tags } from 'tsoa'; - -import { PubSubService } from './pub-sub.service'; - -import type { QueueRequestBody, ValidateSecretRequestBody } from 'domain/pub-sub/pub-sub.types'; - -@Route('queue') -@Tags('Queue') -export class PubSubController { - @Post() - @OperationId('publishMessage') - @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) - public queue(@Body() body: QueueRequestBody) { - const { message } = body; - const id = PubSubService.publishMessage(message); - - return { id }; - - // TODO: - /** - * Differences Identified: - * Formal Response Body Type: - * SIDECAR explicitly returns PublishMessageResponse. - * TARGET returns { id } but does not explicitly use PublishMessageResponse. - * Required Changes to TARGET: - * Standardize Response Body Type: - * Ensure the TARGET uses PublishMessageResponse as the formal response body type to maintain API consistency. - */ - } - - @Post('validate-secret') - @OperationId('validateSecret') - @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) - public validateSecret(@Body() body: ValidateSecretRequestBody) { - const { secret } = body; - const valid = PubSubService.validateSecret(secret); - - return { valid }; - - // TODO: - /** - * Differences Identified: - * Formal Response Body Type: - * SIDECAR explicitly returns ValidateSecretResponse. - * TARGET returns { valid } but does not explicitly use ValidateSecretResponse. - * Required Changes to TARGET: - * Standardize Response Body Type: - * Ensure the TARGET uses ValidateSecretResponse as the formal response body type for consistency. - */ - } -} - -// TODO: file and class names diff --git a/src/domain/queue/queue.consts.ts b/src/domain/queue/queue.consts.ts new file mode 100644 index 0000000..5d8e22e --- /dev/null +++ b/src/domain/queue/queue.consts.ts @@ -0,0 +1,6 @@ +import { TIME_IN_SECONDS } from 'utils/time-enum'; + +export const APP_SERVICE_URL = process.env.QUEUE_DEV_APP_SERVICE_URL; +export const APP_SERVICE_QUEUE_ENDPOINT = '/mndy-queue'; +export const QUEUE_RETRY_INTERVAL_IN_SECONDS = + Number(process.env.QUEUE_RETRY_INTERVAL_IN_SECONDS) || TIME_IN_SECONDS.MINUTE * 10; diff --git a/src/domain/queue/queue.controller.ts b/src/domain/queue/queue.controller.ts new file mode 100644 index 0000000..a314667 --- /dev/null +++ b/src/domain/queue/queue.controller.ts @@ -0,0 +1,31 @@ +import { OperationId, Post, SuccessResponse } from '@tsoa/runtime'; +import { ReasonPhrases, StatusCodes } from 'http-status-codes'; +import { Body, Route, Tags } from 'tsoa'; + +import { QueueService } from './queue.service'; + +import type { QueueRequestBody, ValidateSecretRequestBody } from 'domain/queue/queue.types'; + +@Route('queue') +@Tags('Queue') +export class QueueController { + @Post() + @OperationId('publishMessage') + @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) + public publishMessage(@Body() body: QueueRequestBody) { + const { message } = body; + const id = QueueService.publishMessage(message); + + return { id }; + } + + @Post('validate-secret') + @OperationId('validateSecret') + @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) + public validateSecret(@Body() body: ValidateSecretRequestBody) { + const { secret } = body; + const valid = QueueService.validateSecret(secret); + + return { valid }; + } +} diff --git a/src/domain/pub-sub/pub-sub.schema.ts b/src/domain/queue/queue.schema.ts similarity index 100% rename from src/domain/pub-sub/pub-sub.schema.ts rename to src/domain/queue/queue.schema.ts diff --git a/src/domain/pub-sub/pub-sub.service.ts b/src/domain/queue/queue.service.ts similarity index 91% rename from src/domain/pub-sub/pub-sub.service.ts rename to src/domain/queue/queue.service.ts index 04156de..87a5e38 100644 --- a/src/domain/pub-sub/pub-sub.service.ts +++ b/src/domain/queue/queue.service.ts @@ -5,10 +5,10 @@ import { AsyncTask, SimpleIntervalJob, ToadScheduler } from 'toad-scheduler'; import { v4 as uuidv4 } from 'uuid'; import { - APP_SERVICE_PUB_SUB_ENDPOINT, + APP_SERVICE_QUEUE_ENDPOINT, APP_SERVICE_URL, - PUB_SUB_RETRY_INTERVAL_IN_SECONDS -} from 'domain/pub-sub/pub-sub.consts'; + QUEUE_RETRY_INTERVAL_IN_SECONDS +} from 'domain/queue/queue.consts'; import { BadRequestError } from 'shared/errors'; import { generateBase64Secret } from 'utils/cipher'; import { Logger } from 'utils/logger'; @@ -41,7 +41,7 @@ const createNewTask = (message: string) => { const task = new AsyncTask( taskId, async () => { - const response = await fetch(`${APP_SERVICE_URL}/${APP_SERVICE_PUB_SUB_ENDPOINT}?secret=${taskSecret}`, { + const response = await fetch(`${APP_SERVICE_URL}/${APP_SERVICE_QUEUE_ENDPOINT}?secret=${taskSecret}`, { method: 'POST', body: JSON.stringify({ message }), @@ -90,11 +90,11 @@ const removeJobIdAndSecret = (taskSecret: string) => { jobsStore.delete(taskSecret); }; -export class PubSubService { +export class QueueService { static publishMessage(message: string) { validateAppServiceUrl(); const { taskId, task } = createNewTask(message); - const job = new SimpleIntervalJob({ seconds: PUB_SUB_RETRY_INTERVAL_IN_SECONDS }, task, { + const job = new SimpleIntervalJob({ seconds: QUEUE_RETRY_INTERVAL_IN_SECONDS }, task, { id: taskId, preventOverrun: true }); diff --git a/src/domain/pub-sub/pub-sub.types.ts b/src/domain/queue/queue.types.ts similarity index 100% rename from src/domain/pub-sub/pub-sub.types.ts rename to src/domain/queue/queue.types.ts diff --git a/src/domain/secrets/secrets.controller.ts b/src/domain/secrets/secrets.controller.ts index 28c494c..7557b34 100644 --- a/src/domain/secrets/secrets.controller.ts +++ b/src/domain/secrets/secrets.controller.ts @@ -12,20 +12,29 @@ export class SecretsController { @Get('{name}') @OperationId('getSecret') @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) - public getSecretForKey(@Path() name: string, @Res() notFoundResponse: TsoaResponse<404, { reason: string }>): string { + public getSecretForKey( + @Path() name: string, + @Res() + notFoundResponse: TsoaResponse< + StatusCodes.NOT_FOUND, + { + reason: string; + } + > + ): string { const secret = SecretService.getSecretForKey(name); if (!secret) { - return notFoundResponse(404, { reason: 'Secret not found' }); + return notFoundResponse(StatusCodes.NOT_FOUND, { reason: 'Secret not found' }); } return secret; } -} -// TODO: -/** - * Required Changes to TARGET: - * Add Missing Endpoint: - * Implement the /secrets GET endpoint in TARGET to retrieve all secret keys. - * Define the operation as getSecretKeys with a 200 response returning an array of strings, similar to SIDECAR. - */ + @Get() + @OperationId('getSecretKeys') + @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) + public async getKeys(): Promise { + const keys = SecretService.getSecretKeys(); + return keys; + } +} diff --git a/src/domain/secrets/secrets.service.ts b/src/domain/secrets/secrets.service.ts index 2e71ecd..e8c46ce 100644 --- a/src/domain/secrets/secrets.service.ts +++ b/src/domain/secrets/secrets.service.ts @@ -18,14 +18,19 @@ export class SecretService { static getSecretForKey(key: string): string { this.initialize(); - const environmentFile = readJsonFile(SECRETS_FILE); - return environmentFile[key] as string; + const secretsFile = readJsonFile(SECRETS_FILE); + return secretsFile[key] as string; } static setSecretForKey(key: string, value: JsonValue) { this.initialize(); - const environmentFile = readJsonFile(SECRETS_FILE); - environmentFile[key] = value; - writeJsonFile(SECRETS_FILE, environmentFile); + const secretsFile = readJsonFile(SECRETS_FILE); + secretsFile[key] = value; + writeJsonFile(SECRETS_FILE, secretsFile); + } + + static getSecretKeys() { + const secretsFile = readJsonFile(SECRETS_FILE); + return Object.keys(secretsFile); } } diff --git a/src/domain/secure-storage/secure-storage.controller.ts b/src/domain/secure-storage/secure-storage.controller.ts index 4360a2b..b14bf75 100644 --- a/src/domain/secure-storage/secure-storage.controller.ts +++ b/src/domain/secure-storage/secure-storage.controller.ts @@ -18,7 +18,7 @@ export class SecureStorageController { @SuccessResponse(StatusCodes.OK, ReasonPhrases.OK) public async getSecureValue( @Path() key: string, - @Res() notFoundResponse: TsoaResponse<404, { reason: string }> + @Res() notFoundResponse: TsoaResponse ): Promise<{ value: JsonValue }> { const value = SecureStorageService.getSecureValue(key); @@ -27,17 +27,6 @@ export class SecureStorageController { } return { value }; - - // TODO: - /** - * Differences Identified: - * Response Data Type: - * SIDECAR returns a type defined as SecureStorageDataContract. - * TARGET returns a JSON object directly. - * Required Changes to TARGET: - * Standardize Response Type: - * Adjust TARGET to use SecureStorageDataContract for the response type to ensure type consistency. - */ } @Delete('{key}') @@ -53,20 +42,9 @@ export class SecureStorageController { public async updateSecureValue( @Path() key: string, @Body() body: SetSecureStorageForKeyRequestBody - ): Promise { + ): Promise { const { value } = body; SecureStorageService.setSecureValue(key, value); - return value; + return true; } - - // TODO: - /** - * Differences Identified: - * Request Body Type: - * SIDECAR uses SecureStorageDataContract. - * TARGET uses SetSecureStorageForKeyRequestBody. - * Required Changes to TARGET: - * Align Request Body Type: - * Change the request body type in TARGET from SetSecureStorageForKeyRequestBody to SecureStorageDataContract to maintain type consistency across both APIs. - */ } diff --git a/src/domain/storage/storage.controller.ts b/src/domain/storage/storage.controller.ts index a2e3019..3626ce3 100644 --- a/src/domain/storage/storage.controller.ts +++ b/src/domain/storage/storage.controller.ts @@ -18,31 +18,20 @@ export class StorageController { @Path() key: string, @Query() shared: boolean, @Header('x-monday-access-token') accessToken: string, - @Res() notFoundResponse: TsoaResponse<404, { reason: string }>, - @Res() serverError: TsoaResponse<500, { reason?: string }> + @Res() notFoundResponse: TsoaResponse, + @Res() serverError: TsoaResponse ): Promise<{ value: JsonValue; version?: string }> { const storageService = new StorageService(accessToken); const { value, version, success } = await storageService.get(key); if (!success && value === null) { - return notFoundResponse(404, { reason: 'Key not found' }); + return notFoundResponse(StatusCodes.NOT_FOUND, { reason: 'Key not found' }); } if (!success) { - return serverError(500, { reason: 'An error occurred while fetching the key' }); + return serverError(StatusCodes.INTERNAL_SERVER_ERROR, { reason: 'An error occurred while fetching the key' }); } return { value, version }; - - // TODO: - /** - * Differences Identified: - * Response Data Type: - * SIDECAR uses StorageDataContract. - * TARGET directly returns a JSON object. - * Required Changes to TARGET: - * Standardize Response Type: - * Adjust TARGET to use StorageDataContract for the response type to ensure type consistency. - */ } @Delete('{key}') @@ -59,23 +48,14 @@ export class StorageController { public async updateValue( @Header('x-monday-access-token') accessToken: string, @Path() key: string, - @Body() body: SetStorageForKeyRequestBody - ): Promise { - const { value, previousVersion, shared } = body; + @Body() body: SetStorageForKeyRequestBody, + @Query() shared?: boolean, + @Query() previousVersion?: string + ) { + const { value } = body; const storageService = new StorageService(accessToken); - await storageService.set(key, value, { previousVersion, shared }); - - return value; - // TODO - /** - * Differences Identified: - * Request Body Type: - * SIDECAR uses StorageDataContract. - * TARGET uses SetStorageForKeyRequestBody. - * Required Changes to TARGET: - * Align Request Body Type: - * Change the request body type in TARGET from SetStorageForKeyRequestBody to StorageDataContract to maintain type consistency across both APIs. - */ + const result = await storageService.set(key, value, { previousVersion, shared }); + return result; } @Put('counter/increment') @@ -84,26 +64,10 @@ export class StorageController { public async counterIncrement( @Header('x-monday-access-token') accessToken: string, @Body() body: IncrementStorageForKeyRequestBody - ): Promise { + ) { const { period, incrementBy, renewalDate, kind } = body; const storageService = new StorageService(accessToken); - const value = await storageService.incrementCounter(period, { incrementBy, kind, renewalDate }); - return value?.newCounterValue?.toString(); - - // TODO: - /** - * Differences Identified: - * Request Body Type: - * SIDECAR uses IncrementCounterParams. - * TARGET uses IncrementStorageForKeyRequestBody. - * Method Type: - * SIDECAR uses POST. - * TARGET uses PUT. - * Required Changes to TARGET: - * Align Method Type: - * Change the method type in TARGET from PUT to POST to match SIDECAR. - * Align Request Body Type: - * Change the request body type in TARGET from IncrementStorageForKeyRequestBody to IncrementCounterParams to maintain consistency. - */ + const result = await storageService.incrementCounter(period, { incrementBy, kind, renewalDate }); + return result; } } diff --git a/src/domain/storage/storage.types.ts b/src/domain/storage/storage.types.ts index d5f45a8..25b8ab5 100644 --- a/src/domain/storage/storage.types.ts +++ b/src/domain/storage/storage.types.ts @@ -4,7 +4,7 @@ export type SetSecureStorageForKeyRequestBody = { value: string; }; -export type SetStorageForKeyRequestBody = { value: string; previousVersion?: string; shared?: boolean }; +export type SetStorageForKeyRequestBody = { value: string }; export type IncrementStorageForKeyRequestBody = { period: Period; diff --git a/src/routes.ts b/src/routes.ts index 5bb7400..9311cd4 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -11,13 +11,13 @@ import { SecretsController } from './domain/secrets/secrets.controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { SecretsTestController } from './domain/secrets/secrets-test.controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa -import { PubSubController } from './domain/pub-sub/pub-sub.controller'; +import { QueueController } from './domain/queue/queue.controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { LogsController } from './domain/log/logs.controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa -import { EnvironmentController } from './domain/environment/environment.controller'; +import { EnvironmentVariablesController } from './domain/environment-variables/environment-variables.controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa -import { EnvironmentTestController } from './domain/environment/environment-test.controller'; +import { EnvironmentVariablesTestController } from './domain/environment-variables/environment-variables-test.controller'; import type { Request as ExRequest, Response as ExResponse, RequestHandler, Router } from 'express'; @@ -32,7 +32,7 @@ const models: TsoaRoute.Models = { // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "SetStorageForKeyRequestBody": { "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"shared":{"dataType":"boolean"},"previousVersion":{"dataType":"string"},"value":{"dataType":"string","required":true}},"validators":{}}, + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"value":{"dataType":"string","required":true}},"validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "Period": { @@ -77,10 +77,10 @@ const models: TsoaRoute.Models = { // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "WriteLogRequestBody": { "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"params":{"ref":"Record_string.unknown_"},"error":{"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"Record_string.unknown_"}]},"message":{"dataType":"string"},"method":{"ref":"LogMethods","required":true}},"validators":{}}, + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"error":{"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"Record_string.unknown_"}]},"message":{"dataType":"string"},"method":{"ref":"LogMethods","required":true}},"validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "SetEnvironmentForKeyRequestBody": { + "SetEnvironmentVariableForKeyRequestBody": { "dataType": "refAlias", "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"value":{"ref":"JsonValue","required":true}},"validators":{}}, }, @@ -169,6 +169,8 @@ export function RegisterRoutes(app: Router) { accessToken: {"in":"header","name":"x-monday-access-token","required":true,"dataType":"string"}, key: {"in":"path","name":"key","required":true,"dataType":"string"}, body: {"in":"body","name":"body","required":true,"ref":"SetStorageForKeyRequestBody"}, + shared: {"in":"query","name":"shared","dataType":"boolean"}, + previousVersion: {"in":"query","name":"previousVersion","dataType":"string"}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -346,6 +348,35 @@ export function RegisterRoutes(app: Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + app.get('/secrets', + ...(fetchMiddlewares(SecretsController)), + ...(fetchMiddlewares(SecretsController.prototype.getKeys)), + + function SecretsController_getKeys(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + }; + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args, request, response }); + + const controller = new SecretsController(); + + templateService.apiHandler({ + methodName: 'getKeys', + controller, + response, + next, + validatedArgs, + successStatus: 200, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/test/secrets/:name', ...(fetchMiddlewares(SecretsTestController)), ...(fetchMiddlewares(SecretsTestController.prototype.setSecretForKey)), @@ -378,10 +409,10 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/queue', - ...(fetchMiddlewares(PubSubController)), - ...(fetchMiddlewares(PubSubController.prototype.queue)), + ...(fetchMiddlewares(QueueController)), + ...(fetchMiddlewares(QueueController.prototype.publishMessage)), - function PubSubController_queue(request: ExRequest, response: ExResponse, next: any) { + function QueueController_publishMessage(request: ExRequest, response: ExResponse, next: any) { const args: Record = { body: {"in":"body","name":"body","required":true,"ref":"QueueRequestBody"}, }; @@ -392,10 +423,10 @@ export function RegisterRoutes(app: Router) { try { validatedArgs = templateService.getValidatedArgs({ args, request, response }); - const controller = new PubSubController(); + const controller = new QueueController(); templateService.apiHandler({ - methodName: 'queue', + methodName: 'publishMessage', controller, response, next, @@ -408,10 +439,10 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/queue/validate-secret', - ...(fetchMiddlewares(PubSubController)), - ...(fetchMiddlewares(PubSubController.prototype.validateSecret)), + ...(fetchMiddlewares(QueueController)), + ...(fetchMiddlewares(QueueController.prototype.validateSecret)), - function PubSubController_validateSecret(request: ExRequest, response: ExResponse, next: any) { + function QueueController_validateSecret(request: ExRequest, response: ExResponse, next: any) { const args: Record = { body: {"in":"body","name":"body","required":true,"ref":"ValidateSecretRequestBody"}, }; @@ -422,7 +453,7 @@ export function RegisterRoutes(app: Router) { try { validatedArgs = templateService.getValidatedArgs({ args, request, response }); - const controller = new PubSubController(); + const controller = new QueueController(); templateService.apiHandler({ methodName: 'validateSecret', @@ -467,11 +498,11 @@ export function RegisterRoutes(app: Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - app.get('/environments/:name', - ...(fetchMiddlewares(EnvironmentController)), - ...(fetchMiddlewares(EnvironmentController.prototype.getEnvironmentForKey)), + app.get('/environment-variables/:name', + ...(fetchMiddlewares(EnvironmentVariablesController)), + ...(fetchMiddlewares(EnvironmentVariablesController.prototype.getEnvironmentVariableForKey)), - function EnvironmentController_getEnvironmentForKey(request: ExRequest, response: ExResponse, next: any) { + function EnvironmentVariablesController_getEnvironmentVariableForKey(request: ExRequest, response: ExResponse, next: any) { const args: Record = { name: {"in":"path","name":"name","required":true,"dataType":"string"}, notFoundResponse: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, @@ -483,10 +514,10 @@ export function RegisterRoutes(app: Router) { try { validatedArgs = templateService.getValidatedArgs({ args, request, response }); - const controller = new EnvironmentController(); + const controller = new EnvironmentVariablesController(); templateService.apiHandler({ - methodName: 'getEnvironmentForKey', + methodName: 'getEnvironmentVariableForKey', controller, response, next, @@ -498,14 +529,43 @@ export function RegisterRoutes(app: Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + app.get('/environment-variables', + ...(fetchMiddlewares(EnvironmentVariablesController)), + ...(fetchMiddlewares(EnvironmentVariablesController.prototype.getKeys)), + + function EnvironmentVariablesController_getKeys(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + }; + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args, request, response }); + + const controller = new EnvironmentVariablesController(); + + templateService.apiHandler({ + methodName: 'getKeys', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/test/environments/:name', - ...(fetchMiddlewares(EnvironmentTestController)), - ...(fetchMiddlewares(EnvironmentTestController.prototype.setEnvironmentForKey)), + ...(fetchMiddlewares(EnvironmentVariablesTestController)), + ...(fetchMiddlewares(EnvironmentVariablesTestController.prototype.setEnvironmentForKey)), - function EnvironmentTestController_setEnvironmentForKey(request: ExRequest, response: ExResponse, next: any) { + function EnvironmentVariablesTestController_setEnvironmentForKey(request: ExRequest, response: ExResponse, next: any) { const args: Record = { name: {"in":"path","name":"name","required":true,"dataType":"string"}, - body: {"in":"body","name":"body","required":true,"ref":"SetEnvironmentForKeyRequestBody"}, + body: {"in":"body","name":"body","required":true,"ref":"SetEnvironmentVariableForKeyRequestBody"}, }; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa @@ -514,7 +574,7 @@ export function RegisterRoutes(app: Router) { try { validatedArgs = templateService.getValidatedArgs({ args, request, response }); - const controller = new EnvironmentTestController(); + const controller = new EnvironmentVariablesTestController(); templateService.apiHandler({ methodName: 'setEnvironmentForKey', diff --git a/src/shared/middlewares/schema-validation.middleware.ts b/src/shared/middlewares/schema-validation.middleware.ts index 99ee3f0..4f5b7c2 100644 --- a/src/shared/middlewares/schema-validation.middleware.ts +++ b/src/shared/middlewares/schema-validation.middleware.ts @@ -1,3 +1,5 @@ +import { StatusCodes } from 'http-status-codes'; + import { Logger } from 'utils/logger'; import type { RequestHandler } from 'express'; @@ -62,7 +64,7 @@ export const validateZodSchema: { if (!hasDiskWriteAccess()) { throw new InternalServerError('Missing write permissions'); @@ -33,7 +35,7 @@ export const readJsonFile = (fileName: string) => { const data = readFileSync(fileName, 'utf-8'); if (isDefined(data)) { - const parsedData: Record = JSON.parse(data); + const parsedData: Record = JSON.parse(data); return parsedData; }