From fd2a454b5d92403ff4f7ca6d79f35b5e9210c739 Mon Sep 17 00:00:00 2001 From: shay Date: Mon, 20 May 2024 16:43:15 +0300 Subject: [PATCH] feature: add support for multi region param --- src/commands-base/base-command.ts | 36 +++++------ src/commands/code/env.ts | 49 +++++++------- src/commands/code/logs.ts | 72 +++++++++++---------- src/commands/code/push.ts | 45 +++++++------ src/commands/code/status.ts | 21 +++--- src/commands/utils/region.ts | 24 +++++++ src/services/app-builds-service.ts | 13 +++- src/services/env-service.ts | 4 ++ src/services/manage-app-env-service.ts | 34 ++++++---- src/services/notification-service.ts | 5 ++ src/services/push-service.ts | 12 +++- src/services/schemas/app-releases-schema.ts | 2 + src/services/share/deploy.ts | 5 +- src/types/commands/push.ts | 3 + src/types/general/region.ts | 5 ++ src/types/utils/permissions.ts | 3 + src/utils/permissions.ts | 14 ++++ src/utils/region.ts | 9 +++ 18 files changed, 237 insertions(+), 119 deletions(-) create mode 100644 src/commands/utils/region.ts create mode 100644 src/types/general/region.ts create mode 100644 src/types/utils/permissions.ts create mode 100644 src/utils/permissions.ts create mode 100644 src/utils/region.ts diff --git a/src/commands-base/base-command.ts b/src/commands-base/base-command.ts index 7ba2e1e..10f4f78 100644 --- a/src/commands-base/base-command.ts +++ b/src/commands-base/base-command.ts @@ -1,9 +1,24 @@ import { Command, Flags } from '@oclif/core'; +import { regionFlag } from 'commands/utils/region'; import { PrintCommandContext } from 'types/commands/base-command'; import { printGeneratedCommand } from 'utils/command-printer'; import logger from 'utils/logger'; +export const sharedFlags = { + verbose: Flags.boolean({ + description: 'Print advanced logs (optional).', + default: false, + helpGroup: 'global', + }), + + 'print-command': Flags.boolean({ + aliases: ['pc'], + description: 'Print the command that was executed (optional).', + default: false, + helpGroup: 'global', + }), +}; export abstract class BaseCommand extends Command { protected static _withPrintCommand = true; private _printCommandCalled = false; @@ -30,28 +45,13 @@ export abstract class BaseCommand extends Command { this._printContext = { command, flags, args }; } - public static serializeFlags(flags: T): T & typeof this.sharedFlags { + public static serializeFlags(flags: T): T & typeof sharedFlags { return { - ...this.sharedFlags, + ...sharedFlags, ...flags, - } as typeof flags & typeof this.sharedFlags; + } as typeof flags & typeof sharedFlags; } - static sharedFlags? = { - verbose: Flags.boolean({ - description: 'Print advanced logs (optional).', - default: false, - helpGroup: 'global', - }), - - 'print-command': Flags.boolean({ - aliases: ['pc'], - description: 'Print the command that was executed (optional).', - default: false, - helpGroup: 'global', - }), - }; - protected catch(err: Error & { exitCode?: number }): any { err?.message && logger.error((err as Error).message); logger.debug(err); diff --git a/src/commands/code/env.ts b/src/commands/code/env.ts index 8d45f5c..4c71c8a 100644 --- a/src/commands/code/env.ts +++ b/src/commands/code/env.ts @@ -1,6 +1,7 @@ import { Flags } from '@oclif/core'; import { Relationship } from '@oclif/core/lib/interfaces/parser'; +import { addToRegionToFlags } from 'commands/utils/region'; import { AuthenticatedCommand } from 'commands-base/authenticated-command'; import { APP_ENV_MANAGEMENT_MODES } from 'consts/manage-app-env'; import { DynamicChoicesService } from 'services/dynamic-choices-service'; @@ -8,6 +9,7 @@ import { handleEnvironmentRequest, listAppEnvKeys } from 'services/manage-app-en import { PromptService } from 'services/prompt-service'; import { ManageAppEnvFlags } from 'types/commands/manage-app-env'; import { AppId } from 'types/general'; +import { Region } from 'types/general/region'; import logger from 'utils/logger'; const MODES_WITH_KEYS: Array = [ @@ -68,34 +70,37 @@ export default class Env extends AuthenticatedCommand { static examples = ['<%= config.bin %> <%= command.id %>']; - static flags = Env.serializeFlags({ - appId: Flags.integer({ - char: 'i', - aliases: ['a'], - description: 'The id of the app to manage environment variables for', + static flags = Env.serializeFlags( + addToRegionToFlags({ + appId: Flags.integer({ + char: 'i', + aliases: ['a'], + description: 'The id of the app to manage environment variables for', + }), + mode: Flags.string({ + char: 'm', + description: 'management mode', + options: Object.values(APP_ENV_MANAGEMENT_MODES), + }), + key: Flags.string({ + char: 'k', + description: 'variable key [required for set and delete]]', + relationships: [flagsWithModeRelationships], + }), + value: Flags.string({ + char: 'v', + description: 'variable value [required for set]', + relationships: [flagsWithModeRelationships], + }), }), - mode: Flags.string({ - char: 'm', - description: 'management mode', - options: Object.values(APP_ENV_MANAGEMENT_MODES), - }), - key: Flags.string({ - char: 'k', - description: 'variable key [required for set and delete]]', - relationships: [flagsWithModeRelationships], - }), - value: Flags.string({ - char: 'v', - description: 'variable value [required for set]', - relationships: [flagsWithModeRelationships], - }), - }); + ); static args = {}; DEBUG_TAG = 'env'; public async run(): Promise { try { const { flags } = await this.parse(Env); + const { region } = flags; let { mode, key, value, appId } = flags as ManageAppEnvFlags; if (!appId) { @@ -107,7 +112,7 @@ export default class Env extends AuthenticatedCommand { value = await promptForValueIfNotProvided(mode, value); this.preparePrintCommand(this, { appId, mode, key, value }); - await handleEnvironmentRequest(appId, mode, key, value); + await handleEnvironmentRequest(appId, mode, key, value, region as Region); } catch (error: any) { logger.debug(error, this.DEBUG_TAG); diff --git a/src/commands/code/logs.ts b/src/commands/code/logs.ts index d58ebb2..3f4de4e 100755 --- a/src/commands/code/logs.ts +++ b/src/commands/code/logs.ts @@ -1,6 +1,7 @@ import { Flags } from '@oclif/core'; import { Relationship } from '@oclif/core/lib/interfaces/parser'; +import { addToRegionToFlags } from 'commands/utils/region'; import { AuthenticatedCommand } from 'commands-base/authenticated-command'; import { APP_VERSION_ID_TO_ENTER } from 'consts/messages'; import { streamMessages } from 'services/client-channel-service'; @@ -8,6 +9,7 @@ import { DynamicChoicesService } from 'services/dynamic-choices-service'; import { logsStream } from 'services/notification-service'; import { PromptService } from 'services/prompt-service'; import { EventSource, LogType, LogsCommandArguments, LogsFilterCriteriaArguments } from 'types/commands/logs'; +import { Region } from 'types/general/region'; import { isDefined } from 'utils/guards'; import logger from 'utils/logger'; import { TIME_IN_MILLISECONDS } from 'utils/time-enum'; @@ -46,36 +48,38 @@ export default class Logs extends AuthenticatedCommand { static examples = ['<%= config.bin %> <%= command.id %> -i APP_VERSION_ID -t LOGS_TYPE']; - static flags = Logs.serializeFlags({ - appVersionId: Flags.integer({ - char: 'i', - aliases: ['v'], - description: APP_VERSION_ID_TO_ENTER, + static flags = Logs.serializeFlags( + addToRegionToFlags({ + appVersionId: Flags.integer({ + char: 'i', + aliases: ['v'], + description: APP_VERSION_ID_TO_ENTER, + }), + logsType: Flags.string({ + char: 't', + description: LOGS_TYPE_TO_LISTEN_PROMPT_MESSAGE, + }), + eventSource: Flags.string({ + char: 's', + description: EVENT_SOURCE, + }), + logsStartDate: Flags.string({ + char: 'f', + description: 'Start date (MM/DD/YYYY HH:mm) e.g. "03/24/1983 15:45"' + SUPPORTED_HISTORY_FLAGS, + relationships, + }), + logsEndDate: Flags.string({ + char: 'e', + description: 'End date (MM/DD/YYYY HH:mm) e.g. "03/25/1983 16:45"' + SUPPORTED_HISTORY_FLAGS, + relationships, + }), + logSearchFromText: Flags.string({ + char: 'r', + description: EVENT_SEARCH_FOR_TEXT, + relationships, + }), }), - logsType: Flags.string({ - char: 't', - description: LOGS_TYPE_TO_LISTEN_PROMPT_MESSAGE, - }), - eventSource: Flags.string({ - char: 's', - description: EVENT_SOURCE, - }), - logsStartDate: Flags.string({ - char: 'f', - description: 'Start date (MM/DD/YYYY HH:mm) e.g. "03/24/1983 15:45"' + SUPPORTED_HISTORY_FLAGS, - relationships, - }), - logsEndDate: Flags.string({ - char: 'e', - description: 'End date (MM/DD/YYYY HH:mm) e.g. "03/25/1983 16:45"' + SUPPORTED_HISTORY_FLAGS, - relationships, - }), - logSearchFromText: Flags.string({ - char: 'r', - description: EVENT_SEARCH_FOR_TEXT, - relationships, - }), - }); + ); static args = {}; DEBUG_TAG = 'logs'; @@ -83,16 +87,16 @@ export default class Logs extends AuthenticatedCommand { public async run(): Promise { try { const { flags } = await this.parse(Logs); - + const { logsStartDate, logsEndDate, logSearchFromText, region } = flags; const appVersionId = await this.getAppVersionId(flags.appVersionId); const eventSource = (flags.eventSource || (await eventSourcePrompt())) as EventSource; const logsType = await this.getLogType(eventSource, flags.logsType); const logsFilterCriteria = await this.getLogsFilterCriteria( eventSource, - flags.logsStartDate, - flags.logsEndDate, - flags.logSearchFromText, + logsStartDate, + logsEndDate, + logSearchFromText, ); const args: LogsCommandArguments = { @@ -110,7 +114,7 @@ export default class Logs extends AuthenticatedCommand { logSearchFromText: logsFilterCriteria?.text, }); - const clientChannel = await logsStream(args.appVersionId, args.logsType, logsFilterCriteria); + const clientChannel = await logsStream(args.appVersionId, args.logsType, logsFilterCriteria, region as Region); await streamMessages(clientChannel); } catch (error: any) { logger.debug(error, this.DEBUG_TAG); diff --git a/src/commands/code/push.ts b/src/commands/code/push.ts index 7f4f05a..5344a64 100644 --- a/src/commands/code/push.ts +++ b/src/commands/code/push.ts @@ -1,9 +1,11 @@ import { Flags } from '@oclif/core'; +import { addToRegionToFlags } from 'commands/utils/region'; import { AuthenticatedCommand } from 'commands-base/authenticated-command'; import { APP_ID_TO_ENTER, APP_VERSION_ID_TO_ENTER } from 'consts/messages'; import { DynamicChoicesService } from 'services/dynamic-choices-service'; import { getTasksForServerSide } from 'services/share/deploy'; +import { Region } from 'types/general/region'; import logger from 'utils/logger'; const MESSAGES = { @@ -21,31 +23,34 @@ export default class Push extends AuthenticatedCommand { '<%= config.bin %> <%= command.id %> -a APP_ID_TO_PUSH', ]; - static flags = Push.serializeFlags({ - directoryPath: Flags.string({ - char: 'd', - description: MESSAGES.directory, + static flags = Push.serializeFlags( + addToRegionToFlags({ + directoryPath: Flags.string({ + char: 'd', + description: MESSAGES.directory, + }), + appId: Flags.string({ + char: 'a', + description: MESSAGES.appId, + }), + appVersionId: Flags.integer({ + char: 'i', + aliases: ['v'], + description: MESSAGES.appVersionId, + }), + force: Flags.boolean({ + char: 'f', + description: MESSAGES.force, + }), }), - appId: Flags.string({ - char: 'a', - description: MESSAGES.appId, - }), - appVersionId: Flags.integer({ - char: 'i', - aliases: ['v'], - description: MESSAGES.appVersionId, - }), - force: Flags.boolean({ - char: 'f', - description: MESSAGES.force, - }), - }); + ); static args = {}; DEBUG_TAG = 'code_push'; public async run(): Promise { const { flags } = await this.parse(Push); + const { directoryPath, region } = flags; let appVersionId = flags.appVersionId; try { @@ -61,9 +66,9 @@ export default class Push extends AuthenticatedCommand { } logger.debug(`push code to appVersionId: ${appVersionId}`, this.DEBUG_TAG); - this.preparePrintCommand(this, { appVersionId, directoryPath: flags.directoryPath }); + this.preparePrintCommand(this, { appVersionId, directoryPath: directoryPath }); - const tasks = getTasksForServerSide(appVersionId, flags.directoryPath); + const tasks = getTasksForServerSide(appVersionId, directoryPath, region as Region); await tasks.run(); } catch (error: any) { diff --git a/src/commands/code/status.ts b/src/commands/code/status.ts index 851143c..9ff7a9d 100644 --- a/src/commands/code/status.ts +++ b/src/commands/code/status.ts @@ -1,12 +1,14 @@ import { Flags } from '@oclif/core'; import { StatusCodes } from 'http-status-codes'; +import { addToRegionToFlags } from 'commands/utils/region'; import { AuthenticatedCommand } from 'commands-base/authenticated-command'; import { APP_VERSION_ID_TO_ENTER, VAR_UNKNOWN } from 'consts/messages'; import { DynamicChoicesService } from 'services/dynamic-choices-service'; import { getAppVersionDeploymentStatus } from 'services/push-service'; import { getMondayCodeBuild } from 'src/services/app-builds-service'; import { HttpError } from 'types/errors'; +import { Region } from 'types/general/region'; import { AppVersionDeploymentStatus } from 'types/services/push-service'; import logger from 'utils/logger'; @@ -34,16 +36,19 @@ export default class Status extends AuthenticatedCommand { static examples = ['<%= config.bin %> <%= command.id %> -i APP_VERSION_ID']; - static flags = Status.serializeFlags({ - appVersionId: Flags.integer({ - char: 'i', - aliases: ['v'], - description: APP_VERSION_ID_TO_ENTER, + static flags = Status.serializeFlags( + addToRegionToFlags({ + appVersionId: Flags.integer({ + char: 'i', + aliases: ['v'], + description: APP_VERSION_ID_TO_ENTER, + }), }), - }); + ); public async run(): Promise { const { flags } = await this.parse(Status); + const { region } = flags; let appVersionId = flags.appVersionId; try { if (!appVersionId) { @@ -52,8 +57,8 @@ export default class Status extends AuthenticatedCommand { } this.preparePrintCommand(this, { appVersionId }); - const deploymentStatus = await getAppVersionDeploymentStatus(appVersionId); - const mondayCodeRelease = await getMondayCodeBuild(appVersionId); + const deploymentStatus = await getAppVersionDeploymentStatus(appVersionId, region as Region); + const mondayCodeRelease = await getMondayCodeBuild(appVersionId, region as Region); if (deploymentStatus.deployment) { deploymentStatus.deployment.liveUrl = mondayCodeRelease?.data?.liveUrl; diff --git a/src/commands/utils/region.ts b/src/commands/utils/region.ts new file mode 100644 index 0000000..3abc6e7 --- /dev/null +++ b/src/commands/utils/region.ts @@ -0,0 +1,24 @@ +import { Flags } from '@oclif/core'; + +import { Region } from 'types/general/region'; +import { Permissions } from 'types/utils/permissions'; +import { isPermitted } from 'utils/permissions'; + +export const regionFlag = { + region: Flags.string({ + char: 'z', + description: 'Region to use', + options: Object.values(Region), + }), +}; + +export function addToRegionToFlags(flags: T): T { + if (isPermitted(Permissions.MULTI_REGION)) { + return { + ...flags, + ...regionFlag, + }; + } + + return flags; +} diff --git a/src/services/app-builds-service.ts b/src/services/app-builds-service.ts index edaf5be..2c01dff 100644 --- a/src/services/app-builds-service.ts +++ b/src/services/app-builds-service.ts @@ -4,6 +4,7 @@ import { AppRelease, AppReleasesResponse, appReleasesSchema } from 'services/sch import { AppReleaseCategory } from 'src/consts/app-release'; import { HttpError } from 'types/errors'; import { AppVersionId } from 'types/general'; +import { Region } from 'types/general/region'; import { HttpMethodTypes } from 'types/services/api-service'; import { appsUrlBuilder } from 'utils/urls-builder'; @@ -29,7 +30,15 @@ export const listAppBuilds = async (appVersionId: AppVersionId): Promise => { +export const getMondayCodeBuild = async ( + appVersionId: AppVersionId, + region?: Region, +): Promise => { const appReleases = await listAppBuilds(appVersionId); - return appReleases.find(release => release.category === AppReleaseCategory.MondayCode); + const mondayCodeRelease = appReleases.filter(release => release.category === AppReleaseCategory.MondayCode); + if (region) { + return mondayCodeRelease.find(release => release.region === region); + } + + return mondayCodeRelease[0]; }; diff --git a/src/services/env-service.ts b/src/services/env-service.ts index 1934ba4..c797a59 100644 --- a/src/services/env-service.ts +++ b/src/services/env-service.ts @@ -15,3 +15,7 @@ export const initCurrentWorkingDirectory = (): string => { export const getCurrentWorkingDirectory = (): string => { return process.env.CURRENT_WORKING_DIRECTORY!; }; + +export const getIsSupportMultiRegion = (): boolean => { + return Boolean(process.env.MCDOE_SUPPRT_MULTIREGION); +}; diff --git a/src/services/manage-app-env-service.ts b/src/services/manage-app-env-service.ts index ffe5430..fbcdc10 100644 --- a/src/services/manage-app-env-service.ts +++ b/src/services/manage-app-env-service.ts @@ -6,9 +6,11 @@ import { execute } from 'services/api-service'; import { listAppEnvironmentKeysResponseSchema } from 'services/schemas/manage-app-env-service-schemas'; import { HttpError } from 'types/errors'; import { AppId } from 'types/general'; +import { Region } from 'types/general/region'; import { HttpMethodTypes } from 'types/services/api-service'; import { ListAppEnvironmentKeysResponse } from 'types/services/manage-app-env-service'; import logger from 'utils/logger'; +import { queryBuilderAddRegion } from 'utils/region'; import { appsUrlBuilder } from 'utils/urls-builder'; const handleHttpErrors = (error: HttpError) => { @@ -27,12 +29,15 @@ const handleHttpErrors = (error: HttpError) => { } }; -export const listAppEnvKeys = async (appId: AppId): Promise> => { +export const listAppEnvKeys = async (appId: AppId, region?: Region): Promise> => { try { const path = appEnvironmentKeysUrl(appId); const url = appsUrlBuilder(path); + const query = queryBuilderAddRegion({}, region); + const response = await execute( { + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.GET, @@ -50,11 +55,14 @@ export const listAppEnvKeys = async (appId: AppId): Promise> => { } }; -export const setEnv = async (appId: AppId, key: string, value: string) => { +export const setEnv = async (appId: AppId, key: string, value: string, region?: Region) => { try { const path = appEnvironmentUrl(appId, key); const url = appsUrlBuilder(path); + const query = queryBuilderAddRegion({}, region); + await execute({ + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.PUT, @@ -69,11 +77,14 @@ export const setEnv = async (appId: AppId, key: string, value: string) => { } }; -export const deleteEnv = async (appId: AppId, key: string) => { +export const deleteEnv = async (appId: AppId, key: string, region?: Region) => { try { const path = appEnvironmentUrl(appId, key); const url = appsUrlBuilder(path); + const query = queryBuilderAddRegion({}, region); + await execute({ + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.DELETE, @@ -89,26 +100,26 @@ export const deleteEnv = async (appId: AppId, key: string) => { } }; -const handleEnvironmentSet = async (appId: AppId, key: string, value: string) => { +const handleEnvironmentSet = async (appId: AppId, region: Region | undefined, key: string, value: string) => { if (!key || !value) { throw new Error('key and value are required'); } - await setEnv(appId, key, value); + await setEnv(appId, key, value, region); logger.info(`Environment variable connected to key: "${key}", was set`); }; -const handleEnvironmentDelete = async (appId: AppId, key: string) => { +const handleEnvironmentDelete = async (appId: AppId, region: Region | undefined, key: string) => { if (!key) { throw new Error('key is required'); } - await deleteEnv(appId, key); + await deleteEnv(appId, key, region); logger.info(`Environment variable connected to key: "${key}", was deleted`); }; -const handleEnvironmentListKeys = async (appId: AppId) => { - const response = await listAppEnvKeys(appId); +const handleEnvironmentListKeys = async (appId: AppId, region: Region | undefined) => { + const response = await listAppEnvKeys(appId, region); if (response?.length === 0) { logger.info('No environment variables found'); return; @@ -120,7 +131,7 @@ const handleEnvironmentListKeys = async (appId: AppId) => { const MAP_MODE_TO_HANDLER: Record< APP_ENV_MANAGEMENT_MODES, - (appId: AppId, key: string, value: string) => Promise + (appId: AppId, region: Region | undefined, key: string, value: string) => Promise > = { [APP_ENV_MANAGEMENT_MODES.SET]: handleEnvironmentSet, [APP_ENV_MANAGEMENT_MODES.DELETE]: handleEnvironmentDelete, @@ -132,6 +143,7 @@ export const handleEnvironmentRequest = async ( mode: APP_ENV_MANAGEMENT_MODES, key?: string, value?: string, + region?: Region, ) => { if (!appId || !mode) { throw new Error('appId and mode are required'); @@ -142,5 +154,5 @@ export const handleEnvironmentRequest = async ( throw new Error('invalid mode'); } - await modeHandler(appId, key!, value!); + await modeHandler(appId, region, key!, value!); }; diff --git a/src/services/notification-service.ts b/src/services/notification-service.ts index 8d843e1..d282308 100644 --- a/src/services/notification-service.ts +++ b/src/services/notification-service.ts @@ -5,22 +5,27 @@ import { execute } from 'services/api-service'; import { clientChannelSchema } from 'services/schemas/notification-schema'; import { LogType, LogsFilterCriteriaArguments } from 'types/commands/logs'; import { HttpError } from 'types/errors'; +import { Region } from 'types/general/region'; import { HttpMethodTypes } from 'types/services/api-service'; import { ClientChannel } from 'types/services/notification-service'; import logger from 'utils/logger'; +import { queryBuilderAddRegion } from 'utils/region'; import { appsUrlBuilder } from 'utils/urls-builder'; export const logsStream = async ( appVersionId: number, logsType: LogType, logsFilterCriteria?: LogsFilterCriteriaArguments | null, + region?: Region, ): Promise => { try { const logsStreamForUrl = getLogsStreamForAppVersionIdUrl(appVersionId, logsType, logsFilterCriteria); const url = appsUrlBuilder(logsStreamForUrl); logger.debug(`fetching logs url: ${url}`); + const query = queryBuilderAddRegion({}, region); const response = await execute( { + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.GET, diff --git a/src/services/push-service.ts b/src/services/push-service.ts index 3ec8e4f..9510763 100644 --- a/src/services/push-service.ts +++ b/src/services/push-service.ts @@ -18,6 +18,7 @@ import { pollPromise } from 'services/polling-service'; import { appVersionDeploymentStatusSchema, signedUrlSchema } from 'services/schemas/push-service-schemas'; import { PushCommandTasksContext } from 'types/commands/push'; import { HttpError } from 'types/errors'; +import { Region } from 'types/general/region'; import { TimeInMs } from 'types/general/time'; import { HttpMethodTypes } from 'types/services/api-service'; import { @@ -28,15 +29,19 @@ import { } from 'types/services/push-service'; import logger from 'utils/logger'; import { createProgressBarString } from 'utils/progress-bar'; +import { queryBuilderAddRegion } from 'utils/region'; import { appsUrlBuilder } from 'utils/urls-builder'; -export const getSignedStorageUrl = async (appVersionId: number): Promise => { +export const getSignedStorageUrl = async (appVersionId: number, region?: Region): Promise => { const DEBUG_TAG = 'get_signed_storage_url'; try { const baseSignUrl = getDeploymentSignedUrl(appVersionId); const url = appsUrlBuilder(baseSignUrl); + const query = queryBuilderAddRegion({}, region); + const response = await execute( { + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.POST, @@ -68,12 +73,15 @@ export const uploadClientZipFile = async (appVersionId: number, buffer: Buffer) return response.data; }; -export const getAppVersionDeploymentStatus = async (appVersionId: number) => { +export const getAppVersionDeploymentStatus = async (appVersionId: number, region?: Region) => { try { const baseAppVersionIdStatusUrl = getAppVersionDeploymentStatusUrl(appVersionId); const url = appsUrlBuilder(baseAppVersionIdStatusUrl); + const query = queryBuilderAddRegion({}, region); + const response = await execute( { + query, url, headers: { Accept: 'application/json' }, method: HttpMethodTypes.GET, diff --git a/src/services/schemas/app-releases-schema.ts b/src/services/schemas/app-releases-schema.ts index 1e5ee6e..e47b282 100644 --- a/src/services/schemas/app-releases-schema.ts +++ b/src/services/schemas/app-releases-schema.ts @@ -3,6 +3,7 @@ import { z } from 'zod'; import { AppReleaseCategory } from 'consts/app-release'; import { baseResponseHttpMetaDataSchema } from 'services/schemas/api-service-schemas'; import { appReleaseIdSchema, appVersionIdSchema } from 'services/schemas/general-schemas'; +import { Region } from 'types/general/region'; export const appReleaseSchema = z.object({ id: appReleaseIdSchema, @@ -11,6 +12,7 @@ export const appReleaseSchema = z.object({ kind: z.string(), category: z.nativeEnum(AppReleaseCategory), state: z.string(), + region: z.nativeEnum(Region), data: z .object({ url: z.string().optional(), diff --git a/src/services/share/deploy.ts b/src/services/share/deploy.ts index 1360ec5..ab1dd55 100644 --- a/src/services/share/deploy.ts +++ b/src/services/share/deploy.ts @@ -9,6 +9,7 @@ import { uploadAssetTask, } from 'services/push-service'; import { PushCommandTasksContext } from 'types/commands/push'; +import { Region } from 'types/general/region'; export const getTasksForClientSide = (appVersionId: number, directoryPath?: string) => { return new Listr( @@ -25,7 +26,7 @@ export const getTasksForClientSide = (appVersionId: number, directoryPath?: stri ); }; -export const getTasksForServerSide = (appVersionId: number, directoryPath?: string) => { +export const getTasksForServerSide = (appVersionId: number, directoryPath?: string, region?: Region) => { return new Listr( [ { title: 'Build asset to deploy', task: buildAssetToDeployTask }, @@ -45,6 +46,6 @@ export const getTasksForServerSide = (appVersionId: number, directoryPath?: stri enabled: ctx => Boolean(ctx.showHandleDeploymentTask), }, ], - { ctx: { appVersionId, directoryPath } }, + { ctx: { appVersionId, directoryPath, region } }, ); }; diff --git a/src/types/commands/push.ts b/src/types/commands/push.ts index b77c027..18561d1 100644 --- a/src/types/commands/push.ts +++ b/src/types/commands/push.ts @@ -1,3 +1,5 @@ +import { Region } from 'types/general/region'; + export type PushCommandTasksContext = { signedCloudStorageUrl?: string; archiveContent?: Buffer; @@ -7,4 +9,5 @@ export type PushCommandTasksContext = { showUploadAssetTask?: boolean; showHandleDeploymentTask?: boolean; directoryPath?: string; + region?: Region; }; diff --git a/src/types/general/region.ts b/src/types/general/region.ts new file mode 100644 index 0000000..b5ddfed --- /dev/null +++ b/src/types/general/region.ts @@ -0,0 +1,5 @@ +export enum Region { + US = 'us', + EU = 'eu', + AU = 'au', +} diff --git a/src/types/utils/permissions.ts b/src/types/utils/permissions.ts new file mode 100644 index 0000000..4ae082e --- /dev/null +++ b/src/types/utils/permissions.ts @@ -0,0 +1,3 @@ +export enum Permissions { + MULTI_REGION = 'mcodeMultiRegion', +} diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts new file mode 100644 index 0000000..8d7a31d --- /dev/null +++ b/src/utils/permissions.ts @@ -0,0 +1,14 @@ +import { getIsSupportMultiRegion } from 'services/env-service'; +import { Permissions } from 'types/utils/permissions'; + +export const isPermitted = (permission: Permissions): boolean => { + if (!permission) { + return false; + } + + if (permission === Permissions.MULTI_REGION) { + return getIsSupportMultiRegion(); + } + + return false; +}; diff --git a/src/utils/region.ts b/src/utils/region.ts new file mode 100644 index 0000000..6603b46 --- /dev/null +++ b/src/utils/region.ts @@ -0,0 +1,9 @@ +import { Region } from 'types/general/region'; + +export const queryBuilderAddRegion = (query: object | undefined, region?: Region) => { + if (region) { + return { ...query, region }; + } + + return query; +};