{"version":3,"file":"bundle.cjs","names":["isESM","asArray","Predicate"],"sources":["../../src/bundle.ts"],"sourcesContent":["import assert from 'assert';\nimport { Predicate } from 'effect';\nimport { bundle as swcBundle } from '@swc/core';\nimport type { BundleOptions } from '@swc/core/spack';\nimport fs from 'fs-extra';\nimport pMap from 'p-map';\nimport path from 'path';\nimport { uniq } from 'ramda';\n\nimport type SwcServerlessPlugin from './index';\nimport { asArray, assertIsString, isESM } from './helper';\nimport type { Configuration, FileBuildResult, FunctionBuildResult } from './types';\n\nconst getStringArray = (input: unknown): string[] => asArray(input).filter(Predicate.isString);\n\nexport async function bundle(this: SwcServerlessPlugin): Promise<void> {\n  assert(this.buildOptions, 'buildOptions is not defined');\n\n  this.prepare();\n\n  this.log.verbose(`Compiling to ${this.buildOptions?.target} bundle with swc...`);\n\n  const exclude = getStringArray(this.buildOptions?.exclude);\n\n  const optionsList: (keyof Configuration)[] = [\n    'concurrency',\n    'zipConcurrency',\n    'exclude',\n    'nativeZip',\n    'packager',\n    'packagePath',\n    'watch',\n    'keepOutputDirectory',\n    'packagerOptions',\n    'installExtraArgs',\n    'outputFileExtension',\n    'outputBuildFolder',\n    'outputWorkFolder',\n    'nodeExternals',\n    'skipBuild',\n    'skipBuildExcludeFns',\n    'stripEntryResolveExtensions',\n  ];\n\n  const swcOptions = optionsList.reduce<Record<string, any>>((options, optionName) => {\n    const { [optionName]: _, ...rest } = options;\n\n    return rest;\n  }, this.buildOptions) as BundleOptions;\n\n  const config: Omit<BundleOptions, 'watch' | 'plugins' | 'entry' | 'output'> = {\n    ...swcOptions,\n    externalModules: [...getStringArray(this.buildOptions?.external), ...(exclude.includes('*') ? [] : exclude)],\n  };\n\n  const { buildOptions, buildDirPath } = this;\n\n  assert(buildOptions, 'buildOptions is not defined');\n\n  assertIsString(buildDirPath, 'buildDirPath is not a string');\n\n  if (isESM(buildOptions) && buildOptions.outputFileExtension === '.cjs') {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore Serverless typings (as of v3.0.2) are incorrect\n    throw new this.serverless.classes.Error(\n      'ERROR: format \"esm\" or platform \"neutral\" should not output a file with extension \".cjs\".'\n    );\n  }\n\n  if (!isESM(buildOptions) && buildOptions.outputFileExtension === '.mjs') {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore Serverless typings (as of v3.0.2) are incorrect\n    throw new this.serverless.classes.Error('ERROR: Non esm builds should not output a file with extension \".mjs\".');\n  }\n\n  /** Build the files */\n  const bundleMapper = async (entry: string): Promise<FileBuildResult> => {\n    const bundlePath = entry.slice(0, entry.lastIndexOf('.')) + buildOptions.outputFileExtension;\n\n    // TODO\n    // if (this.buildCache) {\n    //   const { result } = this.buildCache[entry] ?? {};\n    //   if (result) {\n    //     return { bundlePath, entry, result };\n    //   }\n    // }\n\n    const outFile = path.basename(bundlePath);\n    const options: BundleOptions = {\n      ...config,\n      entry,\n      output: {\n        path: path.join(buildDirPath, path.dirname(entry)),\n        name: outFile,\n      },\n    };\n\n    try {\n      const result = await swcBundle(options).then((out) => out[path.basename(entry)]);\n\n      if (!result) throw new Error(`Failed to bundle ${entry}`);\n\n      const { code, map } = result;\n      const { path: outPath, name } = options.output;\n      fs.mkdirSync(outPath, { recursive: true });\n\n      const sourceMaps = options.options?.sourceMaps ?? true;\n\n      const outFilePath = path.join(outPath, outFile);\n      let finalCode = code;\n\n      if (map && sourceMaps === 'inline') {\n        const base64Map = Buffer.from(map).toString('base64');\n        finalCode += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}`;\n      } else if (map && sourceMaps) {\n        fs.writeFileSync(`${outFilePath}.map`, map);\n        finalCode += `\\n//# sourceMappingURL=${name}.map`;\n      }\n\n      if (finalCode) fs.writeFileSync(outFilePath, finalCode);\n\n      return { bundlePath, entry, result };\n    } catch (err: any) {\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore Serverless typings (as of v3.0.2) are incorrect\n      throw new this.serverless.classes.Error(`SWC bundle failed: ${err.message}`);\n    }\n  };\n\n  // Files can contain multiple handlers for multiple functions, we want to get only the unique ones\n  const uniqueFiles: string[] = uniq(this.functionEntries.map(({ entry }) => entry));\n\n  this.log.verbose(`Compiling with concurrency: ${buildOptions.concurrency}`);\n\n  const fileBuildResults = await pMap(uniqueFiles, bundleMapper, {\n    concurrency: buildOptions.concurrency,\n  });\n\n  // Create a cache with entry as key\n  this.buildCache = fileBuildResults.reduce<Record<string, FileBuildResult>>((acc, fileBuildResult) => {\n    acc[fileBuildResult.entry] = fileBuildResult;\n\n    return acc;\n  }, {});\n\n  // Map function entries back to bundles\n  this.buildResults = this.functionEntries\n    .map(({ entry, func, functionAlias }) => {\n      const { bundlePath } = this.buildCache[entry] ?? {};\n\n      if (typeof bundlePath !== 'string' || func === null) {\n        return;\n      }\n\n      return { bundlePath, func, functionAlias };\n    })\n    .filter((result): result is FunctionBuildResult => typeof result === 'object');\n\n  this.log.verbose('Compiling completed.');\n}\n"],"mappings":"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"}