{"version":3,"file":"bucketLocation.js","sourceRoot":"","sources":["../../src/s3/bucketLocation.ts"],"names":[],"mappings":";;AAWA,8CAiEC;AA5ED,+BAA2B;AAC3B,iCAA+B;AAC/B,qDAAwD;AAExD;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,MAAc;IAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,MAAM,MAAM,GAAG,CAAC,EAAoB,EAAE,CAAM,EAAE,EAAE;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,CAAA;gBACd,EAAE,CAAC,CAAC,CAAC,CAAA;YACP,CAAC;QACH,CAAC,CAAA;QAED,MAAM,IAAI,GAAG,IAAA,WAAI,EACf;YACE,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,kBAAkB;YACxB,IAAI,EAAE,IAAI,MAAM,WAAW;SAC5B,EACD,IAAA,sCAAqB,GAAE,CACxB,CAAA;QAED,MAAM,GAAG,GAAG,IAAA,eAAO,EACjB;YACE,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,EACD,GAAG,CAAC,EAAE;YACJ,IAAI,IAAI,GAAG,EAAE,CAAA;YACb,IAAI,QAAQ,GAAG,CAAC,CAAA;YAChB,MAAM,QAAQ,GAAG,KAAK,CAAA;YACtB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAA;gBACxB,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;oBACxB,GAAG,CAAC,OAAO,EAAE,CAAA;oBACb,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAA;oBACjE,OAAM;gBACR,CAAC;gBACD,IAAI,IAAI,KAAK,CAAA;YACf,CAAC,CAAC,CAAA;YACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,UAAU,MAAM,IAAI,EAAE,CAAC,CAAC,CAAA;oBACvF,OAAM;gBACR,CAAC;gBACD,8FAA8F;gBAC9F,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAA;gBAClF,MAAM,SAAS,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,CAAC,CAAC,KAAI,EAAE,CAAA;gBAClC,sFAAsF;gBACtF,sFAAsF;gBACtF,4DAA4D;gBAC5D,MAAM,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC3D,IAAI,MAAM,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBACvD,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,iDAAiD,MAAM,EAAE,CAAC,CAAC,CAAA;oBACpF,OAAM;gBACR,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,WAAW,CAAC,CAAA;YACxC,CAAC,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;QAED,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;QACvC,GAAG,CAAC,GAAG,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { sign } from \"aws4\"\nimport { request } from \"https\"\nimport { resolveAwsCredentials } from \"./awsCredentials\"\n\n/**\n * Resolves the AWS region for a bucket via the S3 GetBucketLocation API (SigV4-signed).\n * Uses path-style endpoint so dotted bucket names pass TLS hostname validation.\n * Credentials are resolved via the standard provider chain (env vars → ~/.aws/credentials).\n * AWS returns an empty LocationConstraint element for us-east-1 (the implicit default region).\n * Mirrors the behaviour of the `get-bucket-location` app-builder subcommand.\n */\nexport function getBucketLocation(bucket: string): Promise<string> {\n  return new Promise((resolve, reject) => {\n    let settled = false\n    const settle = (fn: (v: any) => void, v: any) => {\n      if (!settled) {\n        settled = true\n        fn(v)\n      }\n    }\n\n    const opts = sign(\n      {\n        service: \"s3\",\n        region: \"us-east-1\",\n        method: \"GET\",\n        host: \"s3.amazonaws.com\",\n        path: `/${bucket}?location`,\n      },\n      resolveAwsCredentials()\n    )\n\n    const req = request(\n      {\n        hostname: opts.host,\n        path: opts.path,\n        method: opts.method,\n        headers: opts.headers,\n      },\n      res => {\n        let body = \"\"\n        let bodySize = 0\n        const MAX_BODY = 65536\n        res.on(\"data\", (chunk: string) => {\n          bodySize += chunk.length\n          if (bodySize > MAX_BODY) {\n            req.destroy()\n            settle(reject, new Error(\"GetBucketLocation response too large\"))\n            return\n          }\n          body += chunk\n        })\n        res.on(\"end\", () => {\n          if (res.statusCode !== 200) {\n            settle(reject, new Error(`GetBucketLocation failed (HTTP ${res.statusCode}): ${body}`))\n            return\n          }\n          // Response: <LocationConstraint>us-west-2</LocationConstraint> or empty element for us-east-1\n          const match = body.match(/<LocationConstraint[^>]*>([^<]*)<\\/LocationConstraint>/)\n          const rawRegion = match?.[1] || \"\"\n          // \"EU\" is the only non-standard token GetBucketLocation ever returns — a legacy alias\n          // for eu-west-1 used by buckets created before August 2014. Simple lowercasing is not\n          // sufficient because \"eu\" is not a valid region identifier.\n          const region = rawRegion === \"EU\" ? \"eu-west-1\" : rawRegion\n          if (region !== \"\" && !/^[a-z][a-z0-9-]+$/.test(region)) {\n            settle(reject, new Error(`GetBucketLocation returned unexpected region: ${region}`))\n            return\n          }\n          settle(resolve, region || \"us-east-1\")\n        })\n      }\n    )\n\n    req.on(\"error\", e => settle(reject, e))\n    req.end()\n  })\n}\n"]}