export async function getUserFunction()

in src/loader.ts [85:172]


export async function getUserFunction(
  codeLocation: string,
  functionTarget: string,
  signatureType: SignatureType,
): Promise<{
  userFunction: HandlerFunction;
  signatureType: SignatureType;
} | null> {
  try {
    const functionModulePath = getFunctionModulePath(codeLocation);
    if (functionModulePath === null) {
      console.error(
        `Provided code location '${codeLocation}' is not a loadable module.` +
          '\nDid you specify the correct location for the module defining ' +
          'your function?',
      );
      return null;
    }

    let functionModule;
    const esModule = await isEsModule(functionModulePath);
    if (esModule) {
      if (semver.lt(process.version, MIN_NODE_VERSION_ESMODULES)) {
        console.error(
          `Cannot load ES Module on Node.js ${process.version}. ` +
            `Please upgrade to Node.js v${MIN_NODE_VERSION_ESMODULES} and up.`,
        );
        return null;
      }
      // Resolve module path to file:// URL. Required for windows support.
      const fpath = pathToFileURL(functionModulePath);
      functionModule = await dynamicImport(fpath.href);
    } else {
      functionModule = require(functionModulePath);
    }

    // If the customer declaratively registered a function matching the target
    // return that.
    const registeredFunction = getRegisteredFunction(functionTarget);
    if (registeredFunction) {
      return registeredFunction;
    }

    const userFunction = functionTarget
      .split('.')
      .reduce((code, functionTargetPart) => {
        if (typeof code === 'undefined') {
          return undefined;
        } else {
          return code[functionTargetPart];
        }
      }, functionModule);

    if (typeof userFunction === 'undefined') {
      console.error(
        `Function '${functionTarget}' is not defined in the provided ` +
          'module.\nDid you specify the correct target function to execute?',
      );
      return null;
    }

    if (typeof userFunction !== 'function') {
      console.error(
        `'${functionTarget}' needs to be of type function. Got: ` +
          `${typeof userFunction}`,
      );
      return null;
    }

    return {userFunction: userFunction as HandlerFunction, signatureType};
  } catch (ex) {
    const err: Error = <Error>ex;
    let additionalHint: string;
    // TODO: this should be done based on ex.code rather than string matching.
    if (err.stack && err.stack.includes('Cannot find module')) {
      additionalHint =
        'Did you list all required modules in the package.json ' +
        'dependencies?\n';
    } else {
      additionalHint = 'Is there a syntax error in your code?\n';
    }
    console.error(
      `Provided module can't be loaded.\n${additionalHint}` +
        `Detailed stack trace: ${err.stack}`,
    );
    return null;
  }
}