{"version":3,"file":"pack.mjs","names":[],"sources":["../../src/pack.ts"],"sourcesContent":["import assert from 'assert';\nimport path from 'path';\n\nimport pMap from 'p-map';\nimport fs from 'fs-extra';\nimport globby from 'globby';\nimport { intersection, isEmpty, lensProp, map, over, pipe, reject, replace, test, without } from 'ramda';\nimport semver from 'semver';\nimport type Serverless from 'serverless';\n\nimport { ONLY_PREFIX, SERVERLESS_FOLDER } from './constants';\nimport { assertIsString, doSharePath, flatDep, getDepsFromBundle, isESM, stripEntryResolveExtensions } from './helper';\nimport { getPackager } from './packagers';\nimport { humanSize, trimExtension, zip } from './utils';\n\nimport type SwcServerlessPlugin from './index';\nimport type { SwcFunctionDefinitionHandler, FunctionBuildResult, FunctionReference, IFiles } from './types';\n\nfunction setFunctionArtifactPath(\n  this: SwcServerlessPlugin,\n  func: Serverless.FunctionDefinitionHandler,\n  artifactPath: string\n) {\n  const version = this.serverless.getVersion();\n\n  // Serverless changed the artifact path location in version 1.18\n  if (semver.lt(version, '1.18.0')) {\n    // eslint-disable-next-line no-param-reassign\n    (func as any).artifact = artifactPath;\n    // eslint-disable-next-line no-param-reassign, prefer-object-spread\n    func.package = Object.assign({}, func.package, { disable: true });\n    this.log.verbose(`${func.name} is packaged by the swc plugin. Ignore messages from SLS.`);\n  } else {\n    // eslint-disable-next-line no-param-reassign\n    func.package = {\n      artifact: artifactPath,\n    };\n  }\n}\n\nconst excludedFilesDefault = ['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'package.json'];\n\nexport const filterFilesForZipPackage = ({\n  files,\n  functionAlias,\n  includedFiles,\n  excludedFiles,\n  hasExternals,\n  isGoogleProvider,\n  depWhiteList,\n}: {\n  files: IFiles;\n  functionAlias: string;\n  includedFiles: string[];\n  excludedFiles: string[];\n  hasExternals: boolean;\n  isGoogleProvider: boolean;\n  depWhiteList: string[];\n}) => {\n  return files.filter(({ localPath }) => {\n    // if file is present in patterns it must be included\n    if (includedFiles.find((file) => file === localPath)) {\n      return true;\n    }\n\n    // exclude non individual files based on file path (and things that look derived, e.g. foo.js => foo.js.map)\n    if (excludedFiles.find((file) => localPath.startsWith(`${file}.`))) {\n      return false;\n    }\n\n    // exclude files that belong to individual functions\n    if (localPath.startsWith(ONLY_PREFIX) && !localPath.startsWith(`${ONLY_PREFIX}${functionAlias}/`)) return false;\n\n    // exclude non whitelisted dependencies\n    if (localPath.startsWith('node_modules')) {\n      // if no externals is set or if the provider is google, we do not need any files from node_modules\n      if (!hasExternals || isGoogleProvider) return false;\n      if (\n        // this is needed for dependencies that maps to a path (like scoped ones)\n        !depWhiteList.find((dep) => doSharePath(localPath, `node_modules/${dep}`))\n      )\n        return false;\n    }\n\n    return true;\n  });\n};\n\n// eslint-disable-next-line max-statements\nexport async function pack(this: SwcServerlessPlugin) {\n  // GOOGLE Provider requires a package.json and NO node_modules\n\n  const providerName = this.serverless?.service?.provider?.name;\n  const isGoogleProvider = this.serverless?.service?.provider?.name === 'google';\n  const isScalewayProvider = this.serverless?.service?.provider?.name === 'scaleway'; // Scaleway can not have package: individually\n  const excludedFiles = isGoogleProvider ? [] : excludedFilesDefault;\n\n  // Google and Scaleway providers cannot use individual packaging for now - this could be built in a future release\n  const isPackageIndividuallyNotSupported = isGoogleProvider || isScalewayProvider || false;\n  if (isPackageIndividuallyNotSupported && this.serverless?.service?.package?.individually) {\n    throw new Error(`Packaging failed: cannot package function individually when using ${providerName} provider`);\n  }\n\n  const { buildDirPath, workDirPath } = this;\n\n  assertIsString(buildDirPath, 'buildDirPath is not a string');\n  assertIsString(workDirPath, 'workDirPath is not a string');\n\n  // get a list of all path in build\n  const files: IFiles = globby\n    .sync('**', {\n      cwd: buildDirPath,\n      dot: true,\n      onlyFiles: true,\n    })\n    .filter((file) => !excludedFiles.includes(file))\n    .map((localPath) => ({ localPath, rootPath: path.join(buildDirPath, localPath) }))\n    .map((file) => {\n      if (this.buildOptions?.resolveExtensions && this.buildOptions.resolveExtensions.length > 0) {\n        if (this.buildOptions.stripEntryResolveExtensions) {\n          return stripEntryResolveExtensions(file, this.buildOptions.resolveExtensions);\n        }\n      }\n\n      return file;\n    });\n\n  if (isEmpty(files)) {\n    this.log.verbose('Packaging: No files found. Skipping swc.');\n    return;\n  }\n\n  // 1) If individually is not set, just zip the all build dir and return\n  if (!this.serverless?.service?.package?.individually) {\n    const zipName = `${this.serverless.service.service}.zip`;\n    const artifactPath = path.join(workDirPath, SERVERLESS_FOLDER, zipName);\n\n    // remove prefixes from individual extra files\n    const filesPathList = pipe(\n      reject(test(/^__only_[^/]+$/)) as (x: IFiles) => IFiles,\n      map(over(lensProp('localPath'), replace(/^__only_[^/]+\\//, '')))\n    )(files);\n\n    const startZip = Date.now();\n\n    await zip(artifactPath, filesPathList, this.buildOptions?.nativeZip);\n    const { size } = fs.statSync(artifactPath);\n\n    this.log.verbose(\n      `Zip service ${this.serverless.service.service} - ${humanSize(size)} [${Date.now() - startZip} ms]`\n    );\n    // defined present zip as output artifact\n    this.serverless.service.package.artifact = artifactPath;\n\n    return;\n  }\n\n  assertIsString(this.buildOptions?.packager, 'packager is not a string');\n\n  // 2) If individually is set, we'll optimize files and zip per-function\n  const packager = await getPackager.call(this, this.buildOptions.packager, this.buildOptions.packagerOptions);\n\n  // get a list of every function bundle\n  const { buildResults } = this;\n\n  assert(buildResults, 'buildResults is not an array');\n\n  const bundlePathList = buildResults.map((results) => results.bundlePath);\n\n  let externals: string[] = [];\n\n  // get the list of externals to include only if exclude is not set to *\n  if (this.buildOptions.exclude !== '*' && !this.buildOptions.exclude.includes('*')) {\n    externals = without<string>(this.buildOptions.exclude, this.buildOptions.external ?? []);\n  }\n\n  const hasExternals = !!externals?.length;\n\n  const { buildOptions } = this;\n\n  // get a tree of all production dependencies\n  const packagerDependenciesList = hasExternals ? await packager.getProdDependencies(buildDirPath) : {};\n\n  const packageFiles = await globby(this.serverless.service.package.patterns);\n\n  const zipMapper = async (buildResult: FunctionBuildResult) => {\n    const { func, functionAlias, bundlePath } = buildResult;\n\n    const bundleExcludedFiles = bundlePathList.filter((item) => !bundlePath.startsWith(item)).map(trimExtension);\n\n    const functionPackagePatterns = func.package?.patterns || [];\n\n    const functionExclusionPatterns = functionPackagePatterns\n      .filter((pattern) => pattern.charAt(0) === '!')\n      .map((pattern) => pattern.slice(1));\n\n    const functionFiles = await globby(functionPackagePatterns, { cwd: buildDirPath });\n    const functionExcludedFiles = (await globby(functionExclusionPatterns, { cwd: buildDirPath })).map(trimExtension);\n\n    const includedFiles = [...packageFiles, ...functionFiles];\n    const excludedPackageFiles = [...bundleExcludedFiles, ...functionExcludedFiles];\n\n    // allowed external dependencies in the final zip\n    let depWhiteList: string[] = [];\n\n    if (hasExternals && packagerDependenciesList.dependencies) {\n      const bundleDeps = getDepsFromBundle(path.join(buildDirPath, bundlePath), isESM(buildOptions));\n      const bundleExternals = intersection(bundleDeps, externals);\n\n      depWhiteList = flatDep(packagerDependenciesList.dependencies, bundleExternals);\n    }\n\n    const zipName = `${functionAlias}.zip`;\n    const artifactPath = path.join(workDirPath, SERVERLESS_FOLDER, zipName);\n\n    // filter files\n    const filesPathList = filterFilesForZipPackage({\n      files,\n      functionAlias,\n      includedFiles,\n      hasExternals,\n      isGoogleProvider,\n      depWhiteList,\n      excludedFiles: excludedPackageFiles,\n    })\n      // remove prefix from individual function extra files\n      .map(({ localPath, ...rest }) => ({\n        localPath: localPath.replace(`${ONLY_PREFIX}${functionAlias}/`, ''),\n        ...rest,\n      }));\n\n    const startZip = Date.now();\n    await zip(artifactPath, filesPathList, buildOptions.nativeZip);\n    const { size } = fs.statSync(artifactPath);\n    this.log.verbose(`Function zipped: ${functionAlias} - ${humanSize(size)} [${Date.now() - startZip} ms]`);\n\n    // defined present zip as output artifact\n    setFunctionArtifactPath.call(this, func, path.relative(this.serviceDirPath, artifactPath));\n  };\n\n  this.log.verbose(`Zipping with concurrency: ${buildOptions.zipConcurrency}`);\n  await pMap(buildResults, zipMapper, { concurrency: buildOptions.zipConcurrency });\n  this.log.verbose('All functions zipped.');\n}\n\nexport async function copyPreBuiltResources(this: SwcServerlessPlugin) {\n  this.log.verbose('Copying Prebuilt resources');\n\n  const { workDirPath, packageOutputPath } = this;\n\n  assertIsString(workDirPath, 'workDirPath is not a string');\n  assertIsString(packageOutputPath, 'packageOutputPath is not a string');\n\n  // 1) If individually is not set, just zip the all build dir and return\n  if (!this.serverless?.service?.package?.individually) {\n    const zipName = `${this.serverless.service.service}.zip`;\n    await fs.copy(path.join(packageOutputPath, zipName), path.join(workDirPath, SERVERLESS_FOLDER, zipName));\n    // defined present zip as output artifact\n    this.serverless.service.package.artifact = path.join(workDirPath, SERVERLESS_FOLDER, zipName);\n\n    return;\n  }\n\n  // get a list of every function bundle\n  const buildResults = Object.entries(this.functions)\n    .filter(([functionAlias, func]) => func && functionAlias)\n    .map(([functionAlias, func]) => ({ func, functionAlias })) as FunctionReference[];\n\n  assert(buildResults, 'buildResults is not an array');\n  const zipMapper = async (buildResult: FunctionReference) => {\n    const { func, functionAlias } = buildResult;\n\n    if ((func as SwcFunctionDefinitionHandler).skipSwc) {\n      const zipName = `${functionAlias}.zip`;\n      const artifactPath = path.join(workDirPath, SERVERLESS_FOLDER, zipName);\n\n      // defined present zip as output artifact\n      await fs.copy(path.join(packageOutputPath, zipName), artifactPath);\n      setFunctionArtifactPath.call(this, func, path.relative(this.serviceDirPath, artifactPath));\n    }\n  };\n\n  await pMap(buildResults, zipMapper, {});\n  this.log.verbose('All functions copied.');\n}\n"],"mappings":"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"}