{"version":3,"file":"impl-CZG9gzzR.mjs","names":[],"sources":["../src/commands/policy/download/impl.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport colors from 'colors';\nimport got from 'got';\n\nimport type { LocalContext } from '../../../context.js';\nimport { doneInputValidation } from '../../../lib/cli/done-input-validation.js';\nimport { logger } from '../../../logger.js';\nimport { EMPTY_CELL } from '../constants.js';\nimport {\n  buildPolicyEngineClient,\n  policyEngineRequest,\n  printResult,\n  resolveBundleByName,\n  resolvePolicyBundleVersion,\n  setPolicyEngineCliDebug,\n} from '../helpers/index.js';\nimport type { GetPolicyBundleVersionResponse } from '../types.js';\n\n/** CLI flags for `transcend policy download`. */\nexport interface DownloadCommandFlags {\n  /** Tenant-unique bundle name */\n  'bundle-name': string;\n  /**\n   * Caller-supplied version label to download.\n   * When omitted, downloads the bundle's currently active version.\n   */\n  version?: string;\n  /** Destination file path; defaults to `{bundleName}-{version}.tar.gz` */\n  output?: string;\n  /** Transcend API key */\n  auth: string;\n  /** Transcend API URL */\n  'transcend-url': string;\n  /** Print metadata + presigned URL as JSON without writing a file */\n  json: boolean;\n  /** Include technical error details when a command fails */\n  debug?: boolean;\n}\n\n/**\n * Builds the default output path for a downloaded policy bundle.\n *\n * @param bundleName - Tenant-unique bundle name\n * @param version - Caller-supplied version label\n * @returns Relative path `{bundleName}-{version}.tar.gz`\n */\nexport function defaultPolicyDownloadOutputPath(bundleName: string, version: string): string {\n  return `${bundleName}-${version}.tar.gz`;\n}\n\n/**\n * Formats download metadata for human-readable CLI output.\n *\n * @param body - Version metadata from the Policy Engine API\n * @param outputPath - Destination path written (or that would be written)\n * @returns Summary lines\n */\nfunction formatDownloadSummary(body: GetPolicyBundleVersionResponse, outputPath: string): string {\n  return [\n    `bundleName  ${body.bundleName}`,\n    `version     ${body.version}`,\n    `output      ${outputPath}`,\n    `sha256      ${body.sha256}`,\n    `sizeBytes   ${body.sizeBytes}`,\n    `uploadedAt  ${body.uploadedAt}`,\n    `activatedAt ${body.activatedAt ?? EMPTY_CELL}`,\n  ].join('\\n');\n}\n\n/**\n * Download a compiled policy bundle version to disk.\n *\n * Resolves `--bundle-name` and an optional `--version` to IDs, fetches a\n * short-lived presigned S3 URL from the monolith, then downloads the `.tar.gz`\n * bytes directly from S3 (the monolith does not proxy the artifact).\n *\n * When `--version` is omitted, downloads the bundle's currently active version.\n * If the bundle has no active version, exits with an error.\n *\n * @param this - CLI context\n * @param flags - Command flags\n */\nexport async function download(\n  this: LocalContext,\n  {\n    'bundle-name': bundleName,\n    version,\n    output,\n    auth,\n    'transcend-url': transcendUrl,\n    json,\n    debug = false,\n  }: DownloadCommandFlags,\n): Promise<void> {\n  doneInputValidation(this.process.exit);\n  setPolicyEngineCliDebug(debug);\n\n  const client = buildPolicyEngineClient(transcendUrl, auth);\n\n  const bundle = await resolveBundleByName(client, bundleName);\n  if (!bundle) {\n    throw new Error(`Policy bundle \"${bundleName}\" was not found for this organization.`);\n  }\n\n  let versionId: string;\n  if (version) {\n    const resolvedVersion = await resolvePolicyBundleVersion(client, bundle.id, { version });\n    versionId = resolvedVersion.id;\n  } else {\n    if (!bundle.activeVersionId) {\n      throw new Error(`Policy bundle \"${bundleName}\" has no active version.`);\n    }\n    versionId = bundle.activeVersionId;\n  }\n\n  logger.info(\n    colors.green(\n      version\n        ? `Fetching download URL for bundle \"${bundleName}\" version \"${version}\"...`\n        : `Fetching download URL for active version of bundle \"${bundleName}\"...`,\n    ),\n  );\n\n  const body = await policyEngineRequest(\n    client\n      .get(`v1/policy-engine/policy-bundles/${bundle.id}/versions/${versionId}`)\n      .json<GetPolicyBundleVersionResponse>(),\n  );\n\n  if (json) {\n    printResult(this.process.stdout, {\n      json: true,\n      data: body,\n    });\n    return;\n  }\n\n  const outputPath = path.resolve(\n    output ?? defaultPolicyDownloadOutputPath(bundleName, body.version),\n  );\n\n  logger.info(colors.green(`Downloading policy bundle to ${outputPath}...`));\n\n  let bundleBytes: Uint8Array;\n  try {\n    bundleBytes = await got(body.downloadUrl).buffer();\n  } catch (err) {\n    throw new Error(\n      `Failed to download policy bundle from the presigned URL: ${\n        err instanceof Error ? err.message : String(err)\n      }`,\n      { cause: err },\n    );\n  }\n\n  const outputDir = path.dirname(outputPath);\n  fs.mkdirSync(outputDir, { recursive: true });\n  fs.writeFileSync(outputPath, bundleBytes);\n\n  printResult(this.process.stdout, {\n    json: false,\n    data: body,\n    renderTable: () => formatDownloadSummary(body, outputPath),\n  });\n\n  logger.info(colors.green('Policy bundle downloaded successfully.'));\n}\n"],"mappings":"maAgDA,SAAgB,EAAgC,EAAoB,EAAyB,CAC3F,MAAO,GAAG,EAAW,GAAG,EAAQ,SAUlC,SAAS,EAAsB,EAAsC,EAA4B,CAC/F,MAAO,CACL,eAAe,EAAK,aACpB,eAAe,EAAK,UACpB,eAAe,IACf,eAAe,EAAK,SACpB,eAAe,EAAK,YACpB,eAAe,EAAK,aACpB,eAAe,EAAK,aAAA,MACrB,CAAC,KAAK;EAAK,CAgBd,eAAsB,EAEpB,CACE,cAAe,EACf,UACA,SACA,OACA,gBAAiB,EACjB,OACA,QAAQ,IAEK,CACf,EAAoB,KAAK,QAAQ,KAAK,CACtC,EAAwB,EAAM,CAE9B,IAAM,EAAS,EAAwB,EAAc,EAAK,CAEpD,EAAS,MAAM,EAAoB,EAAQ,EAAW,CAC5D,GAAI,CAAC,EACH,MAAU,MAAM,kBAAkB,EAAW,wCAAwC,CAGvF,IAAI,EACJ,GAAI,EAEF,GAAY,MADkB,EAA2B,EAAQ,EAAO,GAAI,CAAE,UAAS,CAAC,EAC5D,OACvB,CACL,GAAI,CAAC,EAAO,gBACV,MAAU,MAAM,kBAAkB,EAAW,0BAA0B,CAEzE,EAAY,EAAO,gBAGrB,EAAO,KACL,EAAO,MACL,EACI,qCAAqC,EAAW,aAAa,EAAQ,MACrE,uDAAuD,EAAW,MACvE,CACF,CAED,IAAM,EAAO,MAAM,EACjB,EACG,IAAI,mCAAmC,EAAO,GAAG,YAAY,IAAY,CACzE,MAAsC,CAC1C,CAED,GAAI,EAAM,CACR,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACP,CAAC,CACF,OAGF,IAAM,EAAa,EAAK,QACtB,GAAU,EAAgC,EAAY,EAAK,QAAQ,CACpE,CAED,EAAO,KAAK,EAAO,MAAM,gCAAgC,EAAW,KAAK,CAAC,CAE1E,IAAI,EACJ,GAAI,CACF,EAAc,MAAM,EAAI,EAAK,YAAY,CAAC,QAAQ,OAC3C,EAAK,CACZ,MAAU,MACR,4DACE,aAAe,MAAQ,EAAI,QAAU,OAAO,EAAI,GAElD,CAAE,MAAO,EAAK,CACf,CAGH,IAAM,EAAY,EAAK,QAAQ,EAAW,CAC1C,EAAG,UAAU,EAAW,CAAE,UAAW,GAAM,CAAC,CAC5C,EAAG,cAAc,EAAY,EAAY,CAEzC,EAAY,KAAK,QAAQ,OAAQ,CAC/B,KAAM,GACN,KAAM,EACN,gBAAmB,EAAsB,EAAM,EAAW,CAC3D,CAAC,CAEF,EAAO,KAAK,EAAO,MAAM,yCAAyC,CAAC"}