From e42e7c808b59d6f8c676d6dfc0456294c5da77aa Mon Sep 17 00:00:00 2001 From: JohnGrisham Date: Fri, 1 Dec 2023 16:15:36 -0600 Subject: [PATCH] feat(resolveExtensions): added stripResolveExtensions option to remove file extension prefixes --- src/helper.ts | 17 ++++++++++++++++- src/pack.ts | 13 +++++++++++-- src/tests/helper.test.ts | 16 ++++++++++++++-- src/types.ts | 1 + 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/helper.ts b/src/helper.ts index c0fee898..624475d4 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -9,7 +9,7 @@ import { uniq } from 'ramda'; import type Serverless from 'serverless'; import type ServerlessPlugin from 'serverless/classes/Plugin'; -import type { Configuration, DependencyMap, FunctionEntry } from './types'; +import type { Configuration, DependencyMap, FunctionEntry, IFile } from './types'; import type { EsbuildFunctionDefinitionHandler } from './types'; import { DEFAULT_EXTENSIONS } from './constants'; @@ -315,3 +315,18 @@ export const buildServerlessV3LoggerFromLegacyLogger = ( verbose: legacyLogger.log.bind(legacyLogger), success: legacyLogger.log.bind(legacyLogger), }); + +export const stripResolveExtensions = (file: IFile, extensions: string[]): IFile => { + const resolveExtensionMatch = file.localPath.match(extensions.map((ext) => ext).join('|')); + + if (resolveExtensionMatch?.length && !DEFAULT_EXTENSIONS.includes(resolveExtensionMatch[0])) { + const extensionParts = resolveExtensionMatch[0].split('.'); + + return { + ...file, + localPath: file.localPath.replace(resolveExtensionMatch[0], `.${extensionParts[extensionParts.length - 1]}`), + }; + } + + return file; +}; diff --git a/src/pack.ts b/src/pack.ts index 649eafc1..86d3fe77 100644 --- a/src/pack.ts +++ b/src/pack.ts @@ -9,7 +9,7 @@ import semver from 'semver'; import type Serverless from 'serverless'; import { ONLY_PREFIX, SERVERLESS_FOLDER } from './constants'; -import { assertIsString, doSharePath, flatDep, getDepsFromBundle, isESM } from './helper'; +import { assertIsString, doSharePath, flatDep, getDepsFromBundle, isESM, stripResolveExtensions } from './helper'; import { getPackager } from './packagers'; import { humanSize, trimExtension, zip } from './utils'; @@ -114,7 +114,16 @@ export async function pack(this: EsbuildServerlessPlugin) { onlyFiles: true, }) .filter((file) => !excludedFiles.includes(file)) - .map((localPath) => ({ localPath, rootPath: path.join(buildDirPath, localPath) })); + .map((localPath) => ({ localPath, rootPath: path.join(buildDirPath, localPath) })) + .map((file) => { + if (this.buildOptions?.resolveExtensions && this.buildOptions.resolveExtensions.length > 0) { + if (this.options.stripResolveExtensions) { + return stripResolveExtensions(file, this.buildOptions.resolveExtensions); + } + } + + return file; + }); if (isEmpty(files)) { this.log.verbose('Packaging: No files found. Skipping esbuild.'); diff --git a/src/tests/helper.test.ts b/src/tests/helper.test.ts index d58fb6cf..54d960d4 100644 --- a/src/tests/helper.test.ts +++ b/src/tests/helper.test.ts @@ -2,9 +2,9 @@ import fs from 'fs-extra'; import os from 'os'; import path from 'path'; -import { extractFunctionEntries, flatDep, getDepsFromBundle, isESM } from '../helper'; +import { extractFunctionEntries, flatDep, getDepsFromBundle, isESM, stripResolveExtensions } from '../helper'; -import type { Configuration, DependencyMap } from '../types'; +import type { Configuration, DependencyMap, IFile } from '../types'; jest.mock('fs-extra'); @@ -643,3 +643,15 @@ describe('flatDeps', () => { }); }); }); + +describe('stripResolveExtensions', () => { + it('should remove custom extension prefixes', () => { + const result = stripResolveExtensions({ localPath: 'test.custom.js' } as IFile, ['.custom.js']); + expect(result.localPath).toEqual('test.js'); + }); + + it('should ignore prefixes not inside the resolve extensions list', () => { + const result = stripResolveExtensions({ localPath: 'test.other.js' } as IFile, ['.custom.js']); + expect(result.localPath).toEqual('test.other.js'); + }); +}); diff --git a/src/types.ts b/src/types.ts index e6a16722..8990b122 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,6 +9,7 @@ export type ReturnPluginsFn = (sls: Serverless) => Plugins; export interface ImprovedServerlessOptions extends Serverless.Options { package?: string; + stripResolveExtensions?: boolean; } export interface WatchConfiguration {