async function evaluateLambdaFunctionProps()

in packages/@aws-cdk/toolkit-lib/lib/api/hotswap/lambda-functions.ts [164:242]


async function evaluateLambdaFunctionProps(
  hotswappablePropChanges: Record<string, PropertyDifference<any>>,
  runtime: string,
  evaluateCfnTemplate: EvaluateCloudFormationTemplate,
): Promise<LambdaFunctionChange | undefined> {
  /*
   * At first glance, we would want to initialize these using the "previous" values (change.oldValue),
   * in case only one of them changed, like the key, and the Bucket stayed the same.
   * However, that actually fails for old-style synthesis, which uses CFN Parameters!
   * Because the names of the Parameters depend on the hash of the Asset,
   * the Parameters used for the "old" values no longer exist in `assetParams` at this point,
   * which means we don't have the correct values available to evaluate the CFN expression with.
   * Fortunately, the diff will always include both the s3Bucket and s3Key parts of the Lambda's Code property,
   * even if only one of them was actually changed,
   * which means we don't need the "old" values at all, and we can safely initialize these with just `''`.
   */
  let code: LambdaFunctionCode | undefined = undefined;
  let description: string | undefined = undefined;
  let environment: { [key: string]: string } | undefined = undefined;

  for (const updatedPropName in hotswappablePropChanges) {
    const updatedProp = hotswappablePropChanges[updatedPropName];

    switch (updatedPropName) {
      case 'Code':
        let s3Bucket, s3Key, s3ObjectVersion, imageUri, functionCodeZip;

        for (const newPropName in updatedProp.newValue) {
          switch (newPropName) {
            case 'S3Bucket':
              s3Bucket = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
              break;
            case 'S3Key':
              s3Key = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
              break;
            case 'S3ObjectVersion':
              s3ObjectVersion = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
              break;
            case 'ImageUri':
              imageUri = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
              break;
            case 'ZipFile':
              // We must create a zip package containing a file with the inline code
              const functionCode = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue[newPropName]);
              const functionRuntime = await evaluateCfnTemplate.evaluateCfnExpression(runtime);
              if (!functionRuntime) {
                return undefined;
              }
              // file extension must be chosen depending on the runtime
              const codeFileExt = determineCodeFileExtFromRuntime(functionRuntime);
              functionCodeZip = await zipString(`index.${codeFileExt}`, functionCode);
              break;
          }
        }
        code = {
          s3Bucket,
          s3Key,
          s3ObjectVersion,
          imageUri,
          functionCodeZip,
        };
        break;
      case 'Description':
        description = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue);
        break;
      case 'Environment':
        environment = await evaluateCfnTemplate.evaluateCfnExpression(updatedProp.newValue);
        break;
      default:
        // we will never get here, but just in case we do throw an error
        throw new ToolkitError(
          'while apply()ing, found a property that cannot be hotswapped. Please report this at github.com/aws/aws-cdk/issues/new/choose',
        );
    }
  }

  const configurations = description || environment ? { description, environment } : undefined;
  return code || configurations ? { code, configurations } : undefined;
}