From cdb7fcb0fb72c657213afa010e63f2a1ff0e0120 Mon Sep 17 00:00:00 2001 From: Torbjorn van Heeswijck Date: Fri, 22 Aug 2025 16:01:45 +0930 Subject: [PATCH] MI-246: Retain relative path for bundled handlers This will handle nested folders in a more predictable way when bundling and resolving paths --- .../general-files/src/index.ts.template | 57 ++++++++++++------- .../general-files/vite.config.mjs.template | 9 ++- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/tools/cdk-service-plugin/src/generators/service/general-files/src/index.ts.template b/tools/cdk-service-plugin/src/generators/service/general-files/src/index.ts.template index 5b76bc8a..fa532327 100644 --- a/tools/cdk-service-plugin/src/generators/service/general-files/src/index.ts.template +++ b/tools/cdk-service-plugin/src/generators/service/general-files/src/index.ts.template @@ -8,6 +8,26 @@ export interface <%= name.split('-').map(part => part.charAt(0).toUpperCase() + description: string; } +/** + * Entrypoint for the <%= name %> service + * + * Instantiate in a CDK Application Stage to deploy to AWS. + * + * Use 'resolve' helpers below when referencing lambda handlers, step function files etc. + */ +export class <%= name.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') %>Stack extends Stack { + constructor(scope: Construct, id: typeof SERVICE_NAME | (string & {}), props?: <%= name.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') %>StackProps) { + super(scope, id, props); + + const STAGE = Stage.of(this)?.stageName; + if (!STAGE) { + throw new Error('This construct must be used within a CDK Stage'); + } + + Tags.of(this).add('SERVICE', id); + } +} + /** * Resolves a path to infra assets relative to this stack * @@ -19,28 +39,27 @@ export function resolveAssetPath(assetPath: `${'infra/'}${string}`) { } /** - * Resolves a path to runtime assets relative to this stack + * Return an object with the default bundled code asset and + * handler property for use with the NodejsFunction construct. * - * @param assetPath - The path to the asset. - * @returns The resolved bundled code path. + * @example + * ```ts + * new NodejsFunction(this, 'FetchData', { + * ...resolveLambdaHandler('runtime/handlers/fetch-data.ts'), + * }); + * ``` + * + * @param assetPath - The path to the typescript handler file. + * @returns The resolved bundled code path and handler name. */ -export function resolveRuntimeAssetPath(assetPath: `${'runtime/'}${string}${'.ts'}`) { - const bundledPath = path.basename(assetPath).replace(path.extname(assetPath), ''); +export function resolveLambdaHandler(assetPath: `${'runtime/handlers/'}${string}${'.ts'}`) { + // Replace 'runtime/handlers/' with '..dist/' and remove the file extension + const bundledPath = assetPath.replace( + /^runtime\/handlers\/(?.*)\.ts$/, + '../dist/$' + ); return { - code: Code.fromAsset(path.resolve(import.meta.dirname, '../dist', bundledPath)), + code: Code.fromAsset(path.resolve(import.meta.dirname, bundledPath)), handler: 'index.handler', }; } - -export class <%= name.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') %>Stack extends Stack { - constructor(scope: Construct, id: typeof SERVICE_NAME | (string & {}), props?: <%= name.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('') %>StackProps) { - super(scope, id, props); - - const STAGE = Stage.of(this)?.stageName; - if (!STAGE) { - throw new Error('This construct must be used within a CDK Stage'); - } - - Tags.of(this).add('SERVICE', id); - } -} diff --git a/tools/cdk-service-plugin/src/generators/service/general-files/vite.config.mjs.template b/tools/cdk-service-plugin/src/generators/service/general-files/vite.config.mjs.template index d7413672..9b7558b8 100644 --- a/tools/cdk-service-plugin/src/generators/service/general-files/vite.config.mjs.template +++ b/tools/cdk-service-plugin/src/generators/service/general-files/vite.config.mjs.template @@ -6,9 +6,14 @@ import { viteBaseConfig } from '../../vite.config.base.mjs'; const HANDLERS_PATH = 'src/runtime/handlers'; export default defineConfig(configEnv => { - const handlers = fg.sync(`${resolve(import.meta.dirname, HANDLERS_PATH)}/**/*.ts`); + const basePath = resolve(import.meta.dirname, HANDLERS_PATH); + const handlers = fg.sync(`${basePath}/**/*.ts`); const input = Object.fromEntries( - handlers.map(handler => [basename(handler, extname(handler)), handler]) + handlers.map(handler => { + const bundledPath = handler.replace(`${basePath}/`, ''); + const entryName = bundledPath.replace(extname(bundledPath), ''); + return [entryName, handler]; + }) ); return mergeConfig(