{"version":3,"file":"helper.cjs","names":["Predicate","AssertionError","fs","DEFAULT_EXTENSIONS"],"sources":["../../src/helper.ts"],"sourcesContent":["import assert, { AssertionError } from 'assert';\nimport { Predicate } from 'effect';\nimport os from 'os';\nimport path from 'path';\n\nimport { parse } from 'acorn';\nimport { simple as simpleWalk } from 'acorn-walk';\nimport fs from 'fs-extra';\nimport { uniq } from 'ramda';\n\nimport type Serverless from 'serverless';\nimport type ServerlessPlugin from 'serverless/classes/Plugin';\nimport type { Configuration, DependencyMap, FunctionEntry, IFile } from './types';\nimport type { SwcFunctionDefinitionHandler } from './types';\nimport { DEFAULT_EXTENSIONS } from './constants';\n\nexport function asArray<T>(data: T | T[]): T[] {\n  return Array.isArray(data) ? data : [data];\n}\n\nexport function assertIsString(input: unknown, message = 'input is not a string'): asserts input is string {\n  if (!Predicate.isString(input)) {\n    throw new AssertionError({ message, actual: input });\n  }\n}\n\nexport function extractFunctionEntries(\n  cwd: string,\n  provider: string,\n  functions: Record<string, Serverless.FunctionDefinitionHandler>,\n  resolveExtensions?: string[]\n): FunctionEntry[] {\n  // The Google provider will use the entrypoint not from the definition of the\n  // handler function, but instead from the package.json:main field, or via a\n  // index.js file. This check reads the current package.json in the same way\n  // that we already read the tsconfig.json file, by inspecting the current\n  // working directory. If the packageFile does not contain a valid main, then\n  // it instead selects the index.js file.\n  if (provider === 'google') {\n    const packageFilePath = path.join(cwd, 'package.json');\n\n    if (fs.existsSync(packageFilePath)) {\n      // Load in the package.json file.\n      const packageFile = JSON.parse(fs.readFileSync(packageFilePath).toString());\n\n      // Either grab the package.json:main field, or use the index.ts file.\n      // (This will be transpiled to index.js).\n      const entry = packageFile.main ? packageFile.main.replace(/\\.js$/, '.ts') : 'index.ts';\n\n      // Check that the file indeed exists.\n      if (!fs.existsSync(path.join(cwd, entry))) {\n        throw new Error(`Compilation failed. Cannot locate entrypoint, ${entry} not found`);\n      }\n\n      return [{ entry, func: null }];\n    }\n  }\n\n  return Object.keys(functions)\n    .filter((functionAlias) => {\n      return !(functions[functionAlias] as SwcFunctionDefinitionHandler).skipSwc;\n    })\n    .map((functionAlias) => {\n      const func = functions[functionAlias] as SwcFunctionDefinitionHandler;\n      assert(func, `${functionAlias} not found in functions`);\n\n      const { handler, swcEntrypoint } = func;\n      const entrypoint = swcEntrypoint || handler;\n\n      const fnName = path.extname(entrypoint);\n      const fnNameLastAppearanceIndex = entrypoint.lastIndexOf(fnName);\n      // replace only last instance to allow the same name for file and handler\n      const fileName = entrypoint.substring(0, fnNameLastAppearanceIndex);\n\n      const extensions = resolveExtensions ?? DEFAULT_EXTENSIONS;\n\n      for (const extension of extensions) {\n        // Check if the .{extension} files exists. If so return that to watch\n        if (fs.existsSync(path.join(cwd, fileName + extension))) {\n          const entry = path.relative(cwd, fileName + extension);\n\n          return {\n            func,\n            functionAlias,\n            entry: os.platform() === 'win32' ? entry.replace(/\\\\/g, '/') : entry,\n          };\n        }\n        if (fs.existsSync(path.join(cwd, path.join(fileName, 'index') + extension))) {\n          const entry = path.relative(cwd, path.join(fileName, 'index') + extension);\n\n          return {\n            func,\n            functionAlias,\n            entry: os.platform() === 'win32' ? entry.replace(/\\\\/g, '/') : entry,\n          };\n        }\n      }\n      // Can't find the files. Watch will have an exception anyway. So throw one with error.\n      throw new Error(\n        `Compilation failed for function alias ${functionAlias}. Please ensure you have an index file with ext .ts or .js, or have a path listed as main key in package.json`\n      );\n    });\n}\n\n/**\n * Takes a dependency graph and returns a flat list of required production dependencies for all or the filtered deps\n * @param root the root of the dependency tree\n * @param rootDeps array of top level root dependencies to whitelist\n */\nexport const flatDep = (root: DependencyMap, rootDepsFilter: string[]): string[] => {\n  const flattenedDependencies = new Set<string>();\n\n  /**\n   *\n   * @param deps the current tree\n   * @param filter the dependencies to get from this tree\n   */\n  const recursiveFind = (deps: DependencyMap | undefined, filter?: string[]) => {\n    if (!deps) return;\n\n    Object.entries(deps).forEach(([depName, details]) => {\n      // only for root level dependencies\n      if (filter && !filter.includes(depName)) {\n        return;\n      }\n\n      if (details.isRootDep || filter) {\n        // We already have this root dep and it's dependencies - skip this iteration\n        if (flattenedDependencies.has(depName)) {\n          return;\n        }\n\n        flattenedDependencies.add(depName);\n\n        const dep = root[depName];\n\n        dep && recursiveFind(dep.dependencies);\n\n        return;\n      }\n\n      // This is a nested dependency and will be included by default when we include it's parent\n      // We just need to check if we fulfil all it's dependencies\n      recursiveFind(details.dependencies);\n    });\n  };\n\n  recursiveFind(root, rootDepsFilter);\n\n  return Array.from(flattenedDependencies);\n};\n\n/**\n * Extracts the base package from a package string taking scope into consideration\n * @example getBaseDep('@scope/package/register') returns '@scope/package'\n * @example getBaseDep('package/register') returns 'package'\n * @example getBaseDep('package') returns 'package'\n * @param input\n */\nconst getBaseDep = (input: string): string | undefined => {\n  const result = /^@[^/]+\\/[^/\\n]+|^[^/\\n]+/.exec(input);\n\n  if (Array.isArray(result) && result[0]) {\n    return result[0];\n  }\n};\n\nexport const isESM = (buildOptions: Configuration | undefined): boolean => {\n  return buildOptions?.outputFileExtension === '.mjs';\n};\n\n/**\n * Extracts the list of dependencies that appear in a bundle as `import 'XXX'`, `import('XXX')`, or `require('XXX')`.\n * @param bundlePath Absolute path to a bundled JS file\n * @param useESM Should the bundle be treated as ESM\n */\nexport const getDepsFromBundle = (bundlePath: string, useESM: boolean): string[] => {\n  const bundleContent = fs.readFileSync(bundlePath, 'utf8');\n  const deps: string[] = [];\n\n  const ast = parse(bundleContent, {\n    ecmaVersion: 'latest',\n    sourceType: useESM ? 'module' : 'script',\n  });\n\n  // I'm using `node: any` since the type definition is not accurate.\n  // There are properties at runtime that do not exist in the `acorn.Node` type.\n  simpleWalk(ast, {\n    CallExpression(node: any) {\n      if (node.callee.name === 'require') {\n        deps.push(node.arguments[0].value);\n      }\n    },\n    ImportExpression(node: any) {\n      deps.push(node.source.value);\n    },\n    ImportDeclaration(node: any) {\n      deps.push(node.source.value);\n    },\n  });\n\n  const baseDeps = deps.map(getBaseDep).filter(Predicate.isString);\n\n  return uniq(baseDeps);\n};\n\nexport const doSharePath = (child: string, parent: string): boolean => {\n  if (child === parent) {\n    return true;\n  }\n\n  const parentTokens = parent.split('/');\n  const childToken = child.split('/');\n\n  return parentTokens.every((token, index) => childToken[index] === token);\n};\n\nexport type AwsNodeProviderRuntimeMatcher<Versions extends number> = {\n  [Version in Versions as `nodejs${Version}.x`]: `node${Version}`;\n};\n\nexport type AzureNodeProviderRuntimeMatcher<Versions extends number> = {\n  [Version in Versions as `nodejs${Version}`]: `node${Version}`;\n};\n\nexport type GoogleNodeProviderRuntimeMatcher<Versions extends number> = {\n  [Version in Versions as `nodejs${Version}`]: `node${Version}`;\n};\n\nexport type ScalewayNodeProviderRuntimeMatcher<Versions extends number> = {\n  [Version in Versions as `node${Version}`]: `node${Version}`;\n};\n\nexport type AwsNodeMatcher = AwsNodeProviderRuntimeMatcher<12 | 14 | 16 | 18 | 20 | 22 | 24>;\n\nexport type AzureNodeMatcher = AzureNodeProviderRuntimeMatcher<12 | 14 | 16 | 18>;\n\nexport type GoogleNodeMatcher = GoogleNodeProviderRuntimeMatcher<12 | 14 | 16 | 18 | 20 | 22 | 24>;\n\nexport type ScalewayNodeMatcher = ScalewayNodeProviderRuntimeMatcher<12 | 14 | 16 | 18 | 20 | 22>;\n\nexport type NodeMatcher = AwsNodeMatcher & AzureNodeMatcher & GoogleNodeMatcher & ScalewayNodeMatcher;\n\nexport type AwsNodeMatcherKey = keyof AwsNodeMatcher;\n\nexport type AzureNodeMatcherKey = keyof AzureNodeMatcher;\n\nexport type GoogleNodeMatcherKey = keyof GoogleNodeMatcher;\n\nexport type ScalewayNodeMatcherKey = keyof ScalewayNodeMatcher;\n\nexport type NodeMatcherKey = AwsNodeMatcherKey | AzureNodeMatcherKey | GoogleNodeMatcherKey | ScalewayNodeMatcherKey;\n\nconst awsNodeMatcher: AwsNodeMatcher = {\n  'nodejs24.x': 'node24',\n  'nodejs22.x': 'node22',\n  'nodejs20.x': 'node20',\n  'nodejs18.x': 'node18',\n  'nodejs16.x': 'node16',\n  'nodejs14.x': 'node14',\n  'nodejs12.x': 'node12',\n};\n\nconst azureNodeMatcher: AzureNodeMatcher = {\n  nodejs18: 'node18',\n  nodejs16: 'node16',\n  nodejs14: 'node14',\n  nodejs12: 'node12',\n};\n\nconst googleNodeMatcher: GoogleNodeMatcher = {\n  nodejs24: 'node24',\n  nodejs22: 'node22',\n  nodejs20: 'node20',\n  nodejs18: 'node18',\n  nodejs16: 'node16',\n  nodejs14: 'node14',\n  nodejs12: 'node12',\n};\n\nconst scalewayNodeMatcher: ScalewayNodeMatcher = {\n  node22: 'node22',\n  node20: 'node20',\n  node18: 'node18',\n  node16: 'node16',\n  node14: 'node14',\n  node12: 'node12',\n};\n\nconst nodeMatcher: NodeMatcher = {\n  ...googleNodeMatcher,\n  ...awsNodeMatcher,\n  ...azureNodeMatcher,\n  ...scalewayNodeMatcher,\n};\n\nexport const providerRuntimeMatcher = Object.freeze<Record<string, NodeMatcher>>({\n  aws: awsNodeMatcher as NodeMatcher,\n  azure: azureNodeMatcher as NodeMatcher,\n  google: googleNodeMatcher as NodeMatcher,\n  scaleway: scalewayNodeMatcher as NodeMatcher,\n});\n\nexport const isNodeMatcherKey = (input: unknown): input is NodeMatcherKey =>\n  typeof input === 'string' && Object.keys(nodeMatcher).includes(input);\n\nexport function assertIsSupportedRuntime(input: unknown): asserts input is NodeMatcherKey {\n  if (!isNodeMatcherKey(input)) {\n    throw new AssertionError({ actual: input, message: 'not a supported runtime' });\n  }\n}\n\nexport const buildServerlessV3LoggerFromLegacyLogger = (\n  legacyLogger: Serverless['cli'],\n  verbose?: boolean\n): ServerlessPlugin.Logging['log'] => ({\n  error: legacyLogger.log.bind(legacyLogger),\n  warning: legacyLogger.log.bind(legacyLogger),\n  notice: legacyLogger.log.bind(legacyLogger),\n  info: legacyLogger.log.bind(legacyLogger),\n  debug: verbose ? legacyLogger.log.bind(legacyLogger) : () => null,\n  verbose: legacyLogger.log.bind(legacyLogger),\n  success: legacyLogger.log.bind(legacyLogger),\n});\n\nexport const stripEntryResolveExtensions = (file: IFile, extensions: string[]): IFile => {\n  const resolveExtensionMatch = file.localPath.match(extensions.map((ext) => ext).join('|'));\n\n  if (resolveExtensionMatch?.length && !DEFAULT_EXTENSIONS.includes(resolveExtensionMatch[0])) {\n    const extensionParts = resolveExtensionMatch[0].split('.');\n\n    return {\n      ...file,\n      localPath: file.localPath.replace(resolveExtensionMatch[0], `.${extensionParts[extensionParts.length - 1]}`),\n    };\n  }\n\n  return file;\n};\n"],"mappings":"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"}