aws-toolkit-vscode / packages /core /src /shared /sam /debugger /awsSamDebugConfiguration.ts
AbdulElahGwaith's picture
Upload folder using huggingface_hub
6582e08 verified
Raw
History Blame Contribute Delete
8.84 kB
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import * as vscode from 'vscode'
import * as path from 'path'
import { Runtime } from '@aws-sdk/client-lambda'
import { getNormalizedRelativePath } from '../../utilities/pathUtils'
import {
APIGatewayProperties,
AwsSamDebuggerConfiguration,
CodeTargetProperties,
TemplateTargetProperties,
} from './awsSamDebugConfiguration.gen'
import { getLogger } from '../../logger/logger'
export * from './awsSamDebugConfiguration.gen'
export const AWS_SAM_DEBUG_TYPE = 'aws-sam' // eslint-disable-line @typescript-eslint/naming-convention
export const DIRECT_INVOKE_TYPE = 'direct-invoke' // eslint-disable-line @typescript-eslint/naming-convention
export const TEMPLATE_TARGET_TYPE = 'template' as const // eslint-disable-line @typescript-eslint/naming-convention
export const CODE_TARGET_TYPE = 'code' as const // eslint-disable-line @typescript-eslint/naming-convention
export const API_TARGET_TYPE = 'api' as const // eslint-disable-line @typescript-eslint/naming-convention
export const awsSamDebugRequestTypes = [DIRECT_INVOKE_TYPE]
export const awsSamDebugTargetTypes = [TEMPLATE_TARGET_TYPE, CODE_TARGET_TYPE, API_TARGET_TYPE]
export type AwsSamTargetType = 'api' | 'code' | 'template'
export type TargetProperties = AwsSamDebuggerConfiguration['invokeTarget']
export interface ReadonlyJsonObject {
readonly [key: string]: string | number | boolean
}
export function isAwsSamDebugConfiguration(config: vscode.DebugConfiguration): config is AwsSamDebuggerConfiguration {
return config.type === AWS_SAM_DEBUG_TYPE
}
export function isTemplateTargetProperties(props: TargetProperties): props is TemplateTargetProperties {
return props.target === TEMPLATE_TARGET_TYPE || props.target === API_TARGET_TYPE
}
export function isCodeTargetProperties(props: TargetProperties): props is CodeTargetProperties {
return props.target === CODE_TARGET_TYPE
}
/**
* Ensures that the `projectRoot` or `templatePath` relative properties on
* the given `config` are relative (not absolute) paths.
*
* @param folder Workspace folder, or empty to use the workspace associated with `projectRoot` or `templatePath`.
* @param config
*/
export function ensureRelativePaths(
folder: vscode.WorkspaceFolder | undefined,
config: AwsSamDebuggerConfiguration
): void {
if (!config?.invokeTarget?.target) {
// User has an invalid type=aws-sam launch-config.
return
}
const filepath =
config.invokeTarget.target === CODE_TARGET_TYPE
? config.invokeTarget.projectRoot
: config.invokeTarget.templatePath
if (!path.isAbsolute(filepath)) {
return
}
const uri = vscode.Uri.file(filepath)
folder = folder ? folder : vscode.workspace.getWorkspaceFolder(uri)
if (!folder) {
getLogger().warn(`ensureRelativePaths: no workspace for path: "${filepath}"`)
return
}
const relPath = getNormalizedRelativePath(folder!.uri.fsPath, filepath)
if (config.invokeTarget.target === CODE_TARGET_TYPE) {
config.invokeTarget.projectRoot = relPath
} else {
config.invokeTarget.templatePath = relPath
}
}
/**
* Creates a description for a SAM debugconfig entry (in launch.json).
*
* Example: `makeName('foo', '/bar/baz', 'zub')` => `"baz:foo (zub)"
*
* @param primaryName
* @param parentDir Optional directory name (used as a prefix)
* @param suffix Optional info used to differentiate the name
*/
function makeName(primaryName: string, parentDir: string | undefined, suffix: string | undefined) {
const withPrefix = parentDir ? `${parentDir}:${primaryName}` : primaryName
return suffix ? `${withPrefix} (${suffix})` : withPrefix
}
/**
* Creates a description for a SAM debugconfig entry (in launch.json), preprending API
*
* see: makeName for the format
*/
function makeNameApi(primaryName: string, parentDir: string | undefined, suffix: string | undefined) {
return `API ${makeName(primaryName, parentDir, suffix)}`
}
/**
*
* @param folder
* @param runtimeName Optional runtime name used to enhance the config name
* @addRuntimeToConfig
* @param resourceName
* @param templatePath
* @param preloadedConfig
*/
export function createTemplateAwsSamDebugConfig(
folder: vscode.WorkspaceFolder | undefined,
runtimeName: string | undefined,
addRuntimeToConfig: boolean,
resourceName: string,
templatePath: string,
preloadedConfig?: {
eventJson?: ReadonlyJsonObject
environmentVariables?: { [key: string]: string }
dockerNetwork?: string
useContainer?: boolean
}
): AwsSamDebuggerConfiguration {
const workspaceRelativePath = makeWorkspaceRelativePath(folder, templatePath)
const templateParentDir = path.basename(path.dirname(templatePath))
const response: AwsSamDebuggerConfiguration = {
type: AWS_SAM_DEBUG_TYPE,
request: DIRECT_INVOKE_TYPE,
name: makeName(resourceName, templateParentDir, runtimeName),
invokeTarget: {
target: TEMPLATE_TARGET_TYPE,
templatePath: workspaceRelativePath,
logicalId: resourceName,
},
lambda: {
payload: {},
environmentVariables: {},
},
}
if (addRuntimeToConfig) {
response.lambda!.runtime = runtimeName
}
if (preloadedConfig) {
return {
...response,
lambda:
preloadedConfig.environmentVariables || preloadedConfig.eventJson
? {
payload: preloadedConfig.eventJson ? { json: preloadedConfig.eventJson } : {},
environmentVariables: preloadedConfig.environmentVariables,
}
: {
payload: {},
environmentVariables: {},
},
sam:
preloadedConfig.dockerNetwork || preloadedConfig.useContainer
? {
dockerNetwork: preloadedConfig.dockerNetwork,
containerBuild: preloadedConfig.useContainer,
}
: undefined,
}
}
return response
}
export function createCodeAwsSamDebugConfig(
folder: vscode.WorkspaceFolder | undefined,
lambdaHandler: string,
projectRoot: string,
runtime: Runtime
): AwsSamDebuggerConfiguration {
const workspaceRelativePath = makeWorkspaceRelativePath(folder, projectRoot)
const parentDir = path.basename(projectRoot)
return {
type: AWS_SAM_DEBUG_TYPE,
request: DIRECT_INVOKE_TYPE,
name: makeName(lambdaHandler, parentDir, runtime),
invokeTarget: {
target: CODE_TARGET_TYPE,
projectRoot: workspaceRelativePath,
lambdaHandler: lambdaHandler,
},
lambda: {
runtime,
payload: {},
environmentVariables: {},
},
}
}
export function createApiAwsSamDebugConfig(
folder: vscode.WorkspaceFolder | undefined,
runtimeName: string | undefined,
resourceName: string,
templatePath: string,
preloadedConfig?: {
path?: string
httpMethod?: string
payload?: APIGatewayProperties['payload']
}
): AwsSamDebuggerConfiguration {
const workspaceRelativePath = makeWorkspaceRelativePath(folder, templatePath)
const templateParentDir = path.basename(path.dirname(templatePath))
const withRuntime = runtimeName
? {
lambda: {
runtime: runtimeName,
},
}
: undefined
return {
type: AWS_SAM_DEBUG_TYPE,
request: DIRECT_INVOKE_TYPE,
name: makeNameApi(resourceName, templateParentDir, runtimeName),
invokeTarget: {
target: API_TARGET_TYPE,
templatePath: workspaceRelativePath,
logicalId: resourceName,
},
api: {
path: preloadedConfig?.path ?? '/',
// coerce it into the correct type. The types do not entirely overlap (there is an any)
// so in that case let the user decide
httpMethod: (preloadedConfig?.httpMethod as APIGatewayProperties['httpMethod']) ?? 'get',
payload: preloadedConfig?.payload ?? { json: {} },
},
...withRuntime,
}
}
function makeWorkspaceRelativePath(folder: vscode.WorkspaceFolder | undefined, target: string): string {
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length <= 1) {
return folder ? `\${workspaceFolder}/${getNormalizedRelativePath(folder.uri.fsPath, target)}` : target
}
return target
}