"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/handler/secrets/action-environment-secrets/action-environment-secret-handler.lambda.ts
var action_environment_secret_handler_lambda_exports = {};
__export(action_environment_secret_handler_lambda_exports, {
  handler: () => handler
});
module.exports = __toCommonJS(action_environment_secret_handler_lambda_exports);
var import_client_secrets_manager = require("@aws-sdk/client-secrets-manager");
var import_core = require("@octokit/core");

// src/handler/secrets/aws-secret-helper.ts
var getSecretString = async (secretId, smClient, jsonField) => {
  const secretToEncrypt = await smClient.getSecretValue({ SecretId: secretId });
  let secretString = secretToEncrypt.SecretString;
  if (!secretString) {
    throw new Error("SecretString is empty from secret with id: " + secretId);
  }
  if (jsonField) {
    try {
      secretString = JSON.parse(secretString)[jsonField];
    } catch (error) {
      if (error instanceof Error) {
        throw new Error("Error while parsing SecretString with id: " + secretId + " and jsonField: " + jsonField + ": " + error.message);
      }
      throw error;
    }
  }
  if (!secretString) {
    throw new Error("SecretString is empty from secret with id: " + secretId);
  }
  return secretString;
};

// src/handler/secrets/github-helper.ts
var cachedOwner;
var getOwner = async (octokit, owner) => {
  if (owner) {
    return owner;
  } else if (cachedOwner) {
    return cachedOwner;
  }
  const fetchedOwner = await octokit.request("GET /user").then(({ data }) => data.login);
  cachedOwner = fetchedOwner;
  return fetchedOwner;
};

// src/handler/secrets/github-secret-encryptor.ts
var _sodium = require("libsodium-wrappers");
async function async_encrypt(messageBytes, publicKey) {
  await _sodium.ready;
  const libsodium = _sodium;
  return libsodium.crypto_box_seal(messageBytes, publicKey);
}
var encryptValue = async (valueToEncrypt, key) => {
  const messageBytes = Buffer.from(valueToEncrypt);
  const keyBytes = Buffer.from(key, "base64");
  const encryptedBytes = await async_encrypt(messageBytes, keyBytes);
  const encrypted = Buffer.from(encryptedBytes).toString("base64");
  return encrypted;
};

// src/handler/secrets/github-secret-name-validator.ts
var isValidSecretName = (secretName) => {
  if (secretName.startsWith("GITHUB_")) {
    return false;
  }
  const secretNameRegex = /^[a-zA-Z0-9_]+$/;
  return secretNameRegex.test(secretName);
};
var validateSecretName = (secretName) => {
  if (!isValidSecretName(secretName)) {
    throw new Error(`Invalid GitHub secret name: ${secretName}`);
  }
};

// src/handler/secrets/action-environment-secrets/action-environment-secret-handler.lambda.ts
var onEvent = async (event) => {
  console.log(`Event: ${JSON.stringify(event)}`);
  validateSecretName(event.ResourceProperties.repositorySecretName);
  const smClient = new import_client_secrets_manager.SecretsManager({ region: event.ResourceProperties.awsRegion });
  const githubTokenSecret = await smClient.getSecretValue({ SecretId: event.ResourceProperties.githubTokenSecret });
  const octokit = new import_core.Octokit({ auth: githubTokenSecret.SecretString });
  const requestType = event.RequestType;
  switch (requestType) {
    case "Create":
      return onCreate(event, octokit, smClient);
    case "Update":
      return onUpdate(event, octokit, smClient);
    case "Delete":
      return onDelete(event, octokit);
    default:
      throw new Error(`Unexpected request type: '${requestType}'`);
  }
};
var onCreate = async (event, octokit, smClient) => {
  console.log("Create new ActionEnvironmentSecret with props " + JSON.stringify(event.ResourceProperties));
  await createOrUpdateEnvironmentSecret(event, octokit, smClient);
  const PhysicalResourceId = await buildPhysicalResourceId(event, octokit);
  return { PhysicalResourceId };
};
var onUpdate = async (event, octokit, smClient) => {
  const props = event.ResourceProperties;
  console.log(`Update ActionEnvironmentSecret ${props.repositorySecretName} with props ${JSON.stringify(props)}`);
  await createOrUpdateEnvironmentSecret(event, octokit, smClient);
  const PhysicalResourceId = await buildPhysicalResourceId(event, octokit);
  return { PhysicalResourceId };
};
var onDelete = async (event, octokit) => {
  console.log("Delete ActionEnvironmentSecret " + event.ResourceProperties.repositorySecretName);
  await deleteEnvironmentSecret(event, octokit);
  const PhysicalResourceId = await buildPhysicalResourceId(event, octokit);
  return { PhysicalResourceId };
};
var createOrUpdateEnvironmentSecret = async (event, octokit, smClient) => {
  const {
    repositoryOwner,
    repositorySecretName: secret_name,
    environment: environment_name,
    sourceSecretArn: secretId,
    sourceSecretJsonField
  } = event.ResourceProperties;
  console.log(`Encrypt value of secret with id: ${secretId}`);
  const secretString = await getSecretString(secretId, smClient, sourceSecretJsonField);
  const owner = await getOwner(octokit, repositoryOwner);
  const repository_id = await getRepositoryId(event, octokit, owner);
  const { data } = await octokit.request("GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key", { repository_id, environment_name });
  const encryptedSecret = await encryptValue(secretString, data.key);
  console.log("Encrypted secret, attempting to create/update github secret");
  const secretResponse = await octokit.request("PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}", {
    repository_id,
    environment_name,
    secret_name,
    encrypted_value: encryptedSecret,
    key_id: data.key_id
  });
  console.log(JSON.stringify(secretResponse));
  return secretResponse;
};
var deleteEnvironmentSecret = async (event, octokit) => {
  const { environment: environment_name, repositorySecretName: secret_name, repositoryOwner } = event.ResourceProperties;
  const repository_id = await getRepositoryId(event, octokit, repositoryOwner);
  const deleteSecretResponse = await octokit.request("DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}", {
    repository_id,
    environment_name,
    secret_name
  });
  console.log(`Delete: ${JSON.stringify(deleteSecretResponse)}`);
  return deleteSecretResponse;
};
var getRepositoryId = async (event, octokit, repositoryOwner) => {
  const { repositoryName: repo } = event.ResourceProperties;
  const owner = await getOwner(octokit, repositoryOwner);
  const { data } = await octokit.request("GET /repos/{owner}/{repo}", {
    owner,
    repo
  });
  return data.id;
};
var buildPhysicalResourceId = async (event, octokit) => {
  const { environment, repositorySecretName: secret, repositoryOwner, repositoryName: repo } = event.ResourceProperties;
  const owner = await getOwner(octokit, repositoryOwner);
  return [environment, secret, owner, repo].join("/");
};
var handler = onEvent;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  handler
});
