require("source-map-support").install(),(()=>{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var r in s)e.o(s,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:s[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>y});const s=require("mz"),r=require("fs");var i=e.n(r);const o=require("url");var n=e.n(o);const a=require("path");var l=e.n(a);const u=require("deepcopy");var h=e.n(u);const d=require("jsonwebtoken");var c=e.n(d);const p=require("request");var g=e.n(p);const f=require("common-tags");function w(e,t={}){const s={_stringifyToJson:JSON.stringify,maxLength:500,...t};let r=e;const i=s._stringifyToJson||JSON.stringify;if("object"==typeof r)try{r=i(r)}catch(e){}return"string"==typeof r&&r.length>s.maxLength&&(r=`${r.substring(0,s.maxLength)}...`),r.toString()}class m{constructor({apiKey:e,apiSecret:t,apiUrlPrefix:s,apiJwtExpiresIn:r=300,debugLogging:o=!1,statusCheckInterval:n=1e3,statusCheckTimeout:a=9e5,logger:l=console,downloadDir:u=process.cwd(),fs:h=i(),request:d=g(),proxyServer:c,requestConfig:p,progressBar:f,disableProgressBar:w=!1}){this.apiKey=e,this.apiSecret=t,this.apiUrlPrefix=s,this.apiJwtExpiresIn=r,this.statusCheckInterval=n,this.statusCheckTimeout=a,this.debugLogging=o,this.logger=l,this.downloadDir=u,this.proxyServer=c,this.requestConfig=p||{},w||(this._progressBar=f||new class{constructor({_clearInterval:e=clearInterval,_setInterval:t=setInterval,preamble:s="",stdout:r=process.stdout}={}){this.interval=null,this.motionCounter=1,this.setInterval=t,this.clearInterval=e,this.stdout=r,this.bucket=[],this.emptyBucketPointers=[],this.setPreamble(s)}setPreamble(e){this.preamble=`${e} [`,this.addendum="]";let t=80;this.stdout.isTTY&&(t=Number(this.stdout.columns)),this.emptyBucketPointers=[],this.bucket=[];const s=t-this.preamble.length-this.addendum.length;for(let e=0;e<s;e++)this.bucket.push(" "),this.emptyBucketPointers.push(e)}animate(e){const t={speed:100,...e};let s=!1;this.interval=this.setInterval((()=>{s?this.moveBucket():s=this.randomlyFillBucket()}),t.speed)}finish(){this.interval&&this.clearInterval(this.interval),this.fillBucket(),this.stdout.write("\n")}randomlyFillBucket(){const e=Math.floor(Math.random()*this.emptyBucketPointers.length);this.bucket[this.emptyBucketPointers[e]]=".",this.showBucket();let t=!0;const s=[];return this.emptyBucketPointers.forEach((e=>{" "===this.bucket[e]&&(t=!1,s.push(e))})),this.emptyBucketPointers=s,t}fillBucket(){this.bucket=this.bucket.map((function(){return"."})),this.showBucket()}moveBucket(){for(let e=0;e<this.bucket.length;e++)this.bucket[e]=(e-this.motionCounter)%3?" ":".";this.showBucket(),this.motionCounter++}showBucket(){this.stdout.write(`\r${this.preamble}${this.bucket.join("")}${this.addendum}`)}}({preamble:"Validating add-on"})),this._fs=h,this._request=d}sign({guid:e,version:t,channel:s,xpiPath:r}){const i={upload:this._fs.createReadStream(r)};let o="/addons/",n=this.put;return e?(o+=`${encodeURIComponent(e)}/versions/${encodeURIComponent(t)}/`,s&&(i.channel=s)):(this.debug("Signing add-on without an ID"),n=this.post,i.version=t,s&&this.logger.warn("Specifying a channel for a new add-on is unsupported. New add-ons are always in the unlisted channel.")),n.bind(this)({url:o,formData:i},{throwOnBadResponse:!1}).then((([e,t])=>{const s=t,r=!!s.error;if(-1===[200,201,202].indexOf(e.statusCode)||r){if(s.error)return this.logger.error(`Server response: ${s.error}`,`(status: ${e.statusCode})`),Promise.resolve({success:!1,id:null,downloadedFiles:null,errorCode:"SERVER_FAILURE",errorDetails:s.error});throw new Error(`Received bad response from the server while requesting ${this.absoluteURL(o)}\n\nstatus: ${e.statusCode}\nresponse: ${w(s)}\nheaders: ${JSON.stringify(e.headers||{})}\n`)}return this.waitForSignedAddon(s.url)}))}waitForSignedAddon(e,{_clearTimeout:t=clearTimeout,_setAbortTimeout:s=setTimeout,_setStatusCheckTimeout:r=setTimeout}={}){return new Promise(((i,o)=>{var n;let a;const l=s((()=>{var e;null===(e=this._progressBar)||void 0===e||e.finish(),t(a),o(new Error(f.oneLine`Signing is still pending, you will receive an email
            once there is an update on the status of your submission. If you
            don’t see the email after 24 hours, please check your Spam
            folder.`))}),this.statusCheckTimeout),u=async()=>{try{const[o,n]=await this.get({url:e}),h=n.automated_signing,d=n.valid&&n.active&&n.reviewed&&n.files&&n.files.length>0,c=n.valid&&!h;if(d||c){var s;if(null===(s=this._progressBar)||void 0===s||s.finish(),t(l),c)return this.logger.log(f.oneLine`Your add-on has been submitted for review.
              It passed validation but could not be automatically signed
              because this is a listed add-on.`),void i({success:!1,id:null,downloadedFiles:null,errorCode:"ADDON_NOT_AUTO_SIGNED",errorDetails:null});if(d){const e=await this.downloadSignedFiles(n.files);i({...e,id:n.guid})}}else a=r(u,this.statusCheckInterval)}catch(e){t(l),o(e)}},h=async()=>{try{const[o,c]=await this.get({url:e});var s,n,d;c.processed?(null===(s=this._progressBar)||void 0===s||s.finish(),this.logger.log("Validation results:",c.validation_url),null===(n=this._progressBar)||void 0===n||n.setPreamble("Signing add-on"),null===(d=this._progressBar)||void 0===d||d.animate(),c.valid?u():(this.logger.log("Your add-on failed validation and could not be signed"),t(l),i({success:!1,id:null,downloadedFiles:null,errorCode:"VALIDATION_FAILED",errorDetails:c.validation_url}))):a=r(h,this.statusCheckInterval)}catch(e){t(l),o(e)}};null===(n=this._progressBar)||void 0===n||n.animate(),h()}))}async downloadSignedFiles(e,{createWriteStream:t=i().createWriteStream,request:s=this._request,stdout:r=process.stdout}={}){const o=[];let a=null,u=0;function h(){let e="...";if(null!==a){const t=(u/a*100).toFixed();let s="";try{s=Array(4-t.length).join(" ")}catch(e){}e=`${s+t}% `}r.write(`\rDownloading signed files: ${e}`)}const d=e=>new Promise(((i,o)=>{const d=l().join(this.downloadDir,(c=e,l().basename(n().parse(c).path).split("?")[0]));var c;const p=t(d);s(this.configureRequest({method:"GET",url:e,followRedirect:!0})).on("error",o).on("response",(t=>{if(t.statusCode<200||t.statusCode>=300)throw new Error(`Got a ${t.statusCode} response when downloading ${e}`);const s=t.headers["content-length"];s&&(null!==a?a+=parseInt(s,10):a=parseInt(s,10))})).on("data",(e=>{u+=e.length,h()})).pipe(p).on("error",o),p.on("finish",(function(){r.write("\n"),i(d)}))}));let c,p=!1;if(e.forEach((e=>{e.signed?o.push(d(e.download_url)):(this.debug("This file was not signed:",e),p=!0)})),!o.length)throw new Error(f.oneLine`The XPI was processed but no signed files were
      found. Check your manifest and make sure it targets Firefox as an
      application.`);return p&&this.logger.log(f.oneLine`Some files were not signed. Re-run with
        --verbose for details.`),h(),c=await Promise.all(o),this.logger.log("Downloaded:"),c.forEach((e=>{this.logger.log(`    ${e.replace(process.cwd(),".")}`)})),{success:!0,id:null,downloadedFiles:c,errorCode:null,errorDetails:null}}get(e,t){return this.request("get",e,t)}post(e,t){return this.request("post",e,t)}put(e,t){return this.request("put",e,t)}patch(e,t){return this.request("patch",e,t)}delete(e,t){return this.request("delete",e,t)}absoluteURL(e){return e.match(/^http/i)?e:this.apiUrlPrefix+e}configureRequest(e,{jwt:t=c()}={}){const s={...this.requestConfig,...e};if(!s.url)throw new Error("request URL was not specified");s.url=this.absoluteURL(String(s.url)),this.proxyServer&&(s.proxy=this.proxyServer);const r=t.sign({iss:this.apiKey},this.apiSecret,{algorithm:"HS256",expiresIn:this.apiJwtExpiresIn});return s.timeout=1e3*this.apiJwtExpiresIn+500,s.headers={Authorization:`JWT ${r}`,Accept:"application/json",...s.headers},s}async request(e,t,{throwOnBadResponse:s=!0}={}){const r=e.toLowerCase(),i=this.configureRequest(t);let[o,n]=await new Promise(((e,t)=>{this.debug(`[API] ${r.toUpperCase()} request:\n`,i),this._request[r].bind(this._request)(i,((s,r,i)=>{s?t(s):e([r,i])}))}));if(s&&(o.statusCode>299||o.statusCode<200))throw new Error(`Received bad response from ${this.absoluteURL(String(i.url))}; status: ${o.statusCode}; response: ${w(n)}`);if(o.headers&&"application/json"===o.headers["content-type"]&&"string"==typeof n)try{n=JSON.parse(n)}catch(e){this.logger.log("Failed to parse JSON response from server:",e)}return this.debug(`[API] ${r.toUpperCase()} response:\n`,`Status: ${o.statusCode}\n`,{headers:o.headers,response:n}),[o,n]}debug(){if(!this.debugLogging)return;function e(t){return"object"==typeof t&&t?(t.headers&&["Authorization","cookie","set-cookie"].forEach((function(e){t.headers[e]&&(t.headers[e]="<REDACTED>")})),Object.keys(t).forEach((function(s){t[s]=e(t[s])})),t):t}const t=Array.prototype.map.call(arguments,(function(t){let s=t;return"object"==typeof s&&(s=h()(s),s=e(s)),s}));this.logger.log("[sign-addon]",...t)}}const v=async({xpiPath:e,id:t,version:r,apiKey:i,apiSecret:o,apiUrlPrefix:n="https://addons.mozilla.org/api/v4",apiJwtExpiresIn:a,verbose:l=!1,channel:u,timeout:h,downloadDir:d,apiProxy:c,apiRequestConfig:p,disableProgressBar:g=!1,AMOClient:f=m})=>{function w(e){throw new Error(`required argument was empty: ${e}`)}e||w("xpiPath"),r||w("version"),o||w("apiSecret"),i||w("apiKey");try{if(!(await s.fs.stat(e)).isFile)throw new Error(`not a file: ${e}`)}catch(t){throw new Error(`error with ${e}: ${t}`)}return new f({apiKey:i,apiSecret:o,apiUrlPrefix:n,apiJwtExpiresIn:a,downloadDir:d,debugLogging:l,statusCheckTimeout:h,proxyServer:c,requestConfig:p,disableProgressBar:g}).sign({xpiPath:e,guid:t,version:r,channel:u})},y={signAddon:v,signAddonAndExit:async(e,{systemProcess:t=process,throwError:s=!1,logger:r=console})=>{try{const s=await v(e);r.log(s.success?"SUCCESS":"FAIL"),t.exit(s.success?0:1)}catch(e){if(r.error("FAIL"),s)throw e;r.error(e.stack),t.exit(1)}}};module.exports=t.default})();
//# sourceMappingURL=sign-addon.js.map