@hotglue/cli 1.0.40 → 1.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cjs/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var e=require("fs"),t=require("path"),n=require("os"),o=require("yargs"),s=require("util");require("assert");var r=require("url"),a=require("fs/promises"),i=require("cosmiconfig"),c=require("chalk"),l=require("aws-sdk"),d=require("debug"),u=require("yaml"),f=require("cli-table"),p=require("ora"),g=require("micromatch"),y=require("axios");require("progress");var h=require("node:fs/promises"),m=require("crypto"),w="undefined"!=typeof document?document.currentScript:null;function b(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var $,v,j,k,_,E,x,S={};function O(){if($)return S;$=1;const o=e,s=t,r=n;function a(e){console.log(`[dotenv][DEBUG] ${e}`)}const i=/^\s*([\w.-]+)\s*=\s*("[^"]*"|'[^']*'|[^#]*)?(\s*|\s*#.*)?$/,c=/\\n/g,l=/\r\n|\n|\r/;function d(e,t){const n=Boolean(t&&t.debug),o={};return e.toString().split(l).forEach(function(e,t){const s=e.match(i);if(null!=s){const e=s[1];let t=s[2]||"";const n=t.length-1,r='"'===t[0]&&'"'===t[n];"'"===t[0]&&"'"===t[n]||r?(t=t.substring(1,n),r&&(t=t.replace(c,"\n"))):t=t.trim(),o[e]=t}else if(n){const n=e.trim();n.length&&"#"!==n[0]&&a(`Failed to match key and value when parsing line ${t+1}: ${e}`)}}),o}return S.config=function(e){let t=s.resolve(process.cwd(),".env"),n="utf8";const i=Boolean(e&&e.debug),c=Boolean(e&&e.override);var l;e&&(null!=e.path&&(t="~"===(l=e.path)[0]?s.join(r.homedir(),l.slice(1)):l),null!=e.encoding&&(n=e.encoding));try{const e=d(o.readFileSync(t,{encoding:n}),{debug:i});return Object.keys(e).forEach(function(t){Object.prototype.hasOwnProperty.call(process.env,t)?(!0===c&&(process.env[t]=e[t]),i&&a(!0===c?`"${t}" is already defined in \`process.env\` and WAS overwritten`:`"${t}" is already defined in \`process.env\` and was NOT overwritten`)):process.env[t]=e[t]}),{parsed:e}}catch(e){return i&&a(`Failed to load ${t} ${e.message}`),{error:e}}},S.parse=d,S}function I(){return process.versions.electron&&!process.defaultApp?0:1}
2
+ "use strict";var e=require("fs"),t=require("path"),n=require("os"),o=require("yargs"),s=require("util");require("assert");var r=require("url"),a=require("fs/promises"),i=require("cosmiconfig"),c=require("chalk"),l=require("aws-sdk"),d=require("debug"),u=require("yaml"),f=require("cli-table"),p=require("ora"),g=require("micromatch"),y=require("axios"),h=require("stream/promises");require("progress");var m=require("node:fs/promises"),b=require("crypto"),w="undefined"!=typeof document?document.currentScript:null;function $(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var v,j,k,_,E,x,S,O={};function I(){if(v)return O;v=1;const o=e,s=t,r=n;function a(e){console.log(`[dotenv][DEBUG] ${e}`)}const i=/^\s*([\w.-]+)\s*=\s*("[^"]*"|'[^']*'|[^#]*)?(\s*|\s*#.*)?$/,c=/\\n/g,l=/\r\n|\n|\r/;function d(e,t){const n=Boolean(t&&t.debug),o={};return e.toString().split(l).forEach(function(e,t){const s=e.match(i);if(null!=s){const e=s[1];let t=s[2]||"";const n=t.length-1,r='"'===t[0]&&'"'===t[n];"'"===t[0]&&"'"===t[n]||r?(t=t.substring(1,n),r&&(t=t.replace(c,"\n"))):t=t.trim(),o[e]=t}else if(n){const n=e.trim();n.length&&"#"!==n[0]&&a(`Failed to match key and value when parsing line ${t+1}: ${e}`)}}),o}return O.config=function(e){let t=s.resolve(process.cwd(),".env"),n="utf8";const i=Boolean(e&&e.debug),c=Boolean(e&&e.override);var l;e&&(null!=e.path&&(t="~"===(l=e.path)[0]?s.join(r.homedir(),l.slice(1)):l),null!=e.encoding&&(n=e.encoding));try{const e=d(o.readFileSync(t,{encoding:n}),{debug:i});return Object.keys(e).forEach(function(t){Object.prototype.hasOwnProperty.call(process.env,t)?(!0===c&&(process.env[t]=e[t]),i&&a(!0===c?`"${t}" is already defined in \`process.env\` and WAS overwritten`:`"${t}" is already defined in \`process.env\` and was NOT overwritten`)):process.env[t]=e[t]}),{parsed:e}}catch(e){return i&&a(`Failed to load ${t} ${e.message}`),{error:e}}},O.parse=d,O}function T(){return process.versions.electron&&!process.defaultApp?0:1}
3
3
  /**
4
4
  * @license
5
5
  * Copyright (c) 2016, Contributors
6
6
  * SPDX-License-Identifier: ISC
7
7
  */
8
- function T(e){if(e!==e.toLowerCase()&&e!==e.toUpperCase()||(e=e.toLowerCase()),-1===e.indexOf("-")&&-1===e.indexOf("_"))return e;{let t="",n=!1;const o=e.match(/^-+/);for(let s=o?o[0].length:0;s<e.length;s++){let o=e.charAt(s);n&&(n=!1,o=o.toUpperCase()),0===s||"-"!==o&&"_"!==o?"-"!==o&&"_"!==o&&(t+=o):n=!0}return t}}
8
+ function F(e){if(e!==e.toLowerCase()&&e!==e.toUpperCase()||(e=e.toLowerCase()),-1===e.indexOf("-")&&-1===e.indexOf("_"))return e;{let t="",n=!1;const o=e.match(/^-+/);for(let s=o?o[0].length:0;s<e.length;s++){let o=e.charAt(s);n&&(n=!1,o=o.toUpperCase()),0===s||"-"!==o&&"_"!==o?"-"!==o&&"_"!==o&&(t+=o):n=!0}return t}}
9
9
  /**
10
10
  * @license
11
11
  * Copyright (c) 2016, Contributors
12
12
  * SPDX-License-Identifier: ISC
13
13
  */
14
- let F;E||(E=1,O().config(Object.assign({},function(){if(j)return v;j=1;const e={};return null!=process.env.DOTENV_CONFIG_ENCODING&&(e.encoding=process.env.DOTENV_CONFIG_ENCODING),null!=process.env.DOTENV_CONFIG_PATH&&(e.path=process.env.DOTENV_CONFIG_PATH),null!=process.env.DOTENV_CONFIG_DEBUG&&(e.debug=process.env.DOTENV_CONFIG_DEBUG),null!=process.env.DOTENV_CONFIG_OVERRIDE&&(e.override=process.env.DOTENV_CONFIG_OVERRIDE),v=e}(),function(){if(_)return k;_=1;const e=/^dotenv_config_(encoding|path|debug|override)=(.+)$/;return k=function(t){return t.reduce(function(t,n){const o=n.match(e);return o&&(t[o[1]]=o[2]),t},{})}}()(process.argv)))),function(e){e.BOOLEAN="boolean",e.STRING="string",e.NUMBER="number",e.ARRAY="array"}(x||(x={}));function A(e){return void 0!==e?e+1:1}function U(e){return"__proto__"===e?"___proto___":e}
14
+ let A;x||(x=1,I().config(Object.assign({},function(){if(k)return j;k=1;const e={};return null!=process.env.DOTENV_CONFIG_ENCODING&&(e.encoding=process.env.DOTENV_CONFIG_ENCODING),null!=process.env.DOTENV_CONFIG_PATH&&(e.path=process.env.DOTENV_CONFIG_PATH),null!=process.env.DOTENV_CONFIG_DEBUG&&(e.debug=process.env.DOTENV_CONFIG_DEBUG),null!=process.env.DOTENV_CONFIG_OVERRIDE&&(e.override=process.env.DOTENV_CONFIG_OVERRIDE),j=e}(),function(){if(E)return _;E=1;const e=/^dotenv_config_(encoding|path|debug|override)=(.+)$/;return _=function(t){return t.reduce(function(t,n){const o=n.match(e);return o&&(t[o[1]]=o[2]),t},{})}}()(process.argv)))),function(e){e.BOOLEAN="boolean",e.STRING="string",e.NUMBER="number",e.ARRAY="array"}(S||(S={}));function U(e){return void 0!==e?e+1:1}function N(e){return"__proto__"===e?"___proto___":e}
15
15
  /**
16
16
  * @fileoverview Main entrypoint for libraries using yargs-parser in Node.js
17
17
  * CJS and ESM environments.
@@ -20,7 +20,7 @@ let F;E||(E=1,O().config(Object.assign({},function(){if(j)return v;j=1;const e={
20
20
  * Copyright (c) 2016, Contributors
21
21
  * SPDX-License-Identifier: ISC
22
22
  */
23
- const N=process&&process.env&&process.env.YARGS_MIN_NODE_VERSION?Number(process.env.YARGS_MIN_NODE_VERSION):12;if(process&&process.version){if(Number(process.version.match(/v([^.]+)/)[1])<N)throw Error(`yargs parser supports a minimum Node.js version of ${N}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`)}const R=process?process.env:{};new class{constructor(e){F=e}parse(e,t){const n=Object.assign({alias:void 0,array:void 0,boolean:void 0,config:void 0,configObjects:void 0,configuration:void 0,coerce:void 0,count:void 0,default:void 0,envPrefix:void 0,narg:void 0,normalize:void 0,string:void 0,number:void 0,__:void 0,key:void 0},t),o=
23
+ const R=process&&process.env&&process.env.YARGS_MIN_NODE_VERSION?Number(process.env.YARGS_MIN_NODE_VERSION):12;if(process&&process.version){if(Number(process.version.match(/v([^.]+)/)[1])<R)throw Error(`yargs parser supports a minimum Node.js version of ${R}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`)}const D=process?process.env:{};new class{constructor(e){A=e}parse(e,t){const n=Object.assign({alias:void 0,array:void 0,boolean:void 0,config:void 0,configObjects:void 0,configuration:void 0,coerce:void 0,count:void 0,default:void 0,envPrefix:void 0,narg:void 0,normalize:void 0,string:void 0,number:void 0,__:void 0,key:void 0},t),o=
24
24
  /**
25
25
  * @license
26
26
  * Copyright (c) 2016, Contributors
@@ -31,5 +31,5 @@ function(e){if(Array.isArray(e))return e.map(e=>"string"!=typeof e?e+"":e);e=e.t
31
31
  * @license
32
32
  * Copyright (c) 2016, Contributors
33
33
  * SPDX-License-Identifier: ISC
34
- */(e),s="string"==typeof e,r=function(e){const t=[],n=Object.create(null);let o=!0;Object.keys(e).forEach(function(n){t.push([].concat(e[n],n))});for(;o;){o=!1;for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){if(t[e].filter(function(e){return-1!==t[n].indexOf(e)}).length){t[e]=t[e].concat(t[n]),t.splice(n,1),o=!0;break}}}return t.forEach(function(e){const t=(e=e.filter(function(e,t,n){return n.indexOf(e)===t})).pop();void 0!==t&&"string"==typeof t&&(n[t]=e)}),n}(Object.assign(Object.create(null),n.alias)),a=Object.assign({"boolean-negation":!0,"camel-case-expansion":!0,"combine-arrays":!1,"dot-notation":!0,"duplicate-arguments-array":!0,"flatten-duplicate-arrays":!0,"greedy-arrays":!0,"halt-at-non-option":!1,"nargs-eats-options":!1,"negation-prefix":"no-","parse-numbers":!0,"parse-positional-numbers":!0,"populate--":!1,"set-placeholder-key":!1,"short-option-groups":!0,"strip-aliased":!1,"strip-dashed":!1,"unknown-options-as-args":!1},n.configuration),i=Object.assign(Object.create(null),n.default),c=n.configObjects||[],l=n.envPrefix,d=a["populate--"],u=d?"--":"_",f=Object.create(null),p=Object.create(null),g=n.__||F.format,y={aliases:Object.create(null),arrays:Object.create(null),bools:Object.create(null),strings:Object.create(null),numbers:Object.create(null),counts:Object.create(null),normalize:Object.create(null),configs:Object.create(null),nargs:Object.create(null),coercions:Object.create(null),keys:[]},h=/^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/,m=new RegExp("^--"+a["negation-prefix"]+"(.+)");[].concat(n.array||[]).filter(Boolean).forEach(function(e){const t="object"==typeof e?e.key:e,n=Object.keys(e).map(function(e){return{boolean:"bools",string:"strings",number:"numbers"}[e]}).filter(Boolean).pop();n&&(y[n][t]=!0),y.arrays[t]=!0,y.keys.push(t)}),[].concat(n.boolean||[]).filter(Boolean).forEach(function(e){y.bools[e]=!0,y.keys.push(e)}),[].concat(n.string||[]).filter(Boolean).forEach(function(e){y.strings[e]=!0,y.keys.push(e)}),[].concat(n.number||[]).filter(Boolean).forEach(function(e){y.numbers[e]=!0,y.keys.push(e)}),[].concat(n.count||[]).filter(Boolean).forEach(function(e){y.counts[e]=!0,y.keys.push(e)}),[].concat(n.normalize||[]).filter(Boolean).forEach(function(e){y.normalize[e]=!0,y.keys.push(e)}),"object"==typeof n.narg&&Object.entries(n.narg).forEach(([e,t])=>{"number"==typeof t&&(y.nargs[e]=t,y.keys.push(e))}),"object"==typeof n.coerce&&Object.entries(n.coerce).forEach(([e,t])=>{"function"==typeof t&&(y.coercions[e]=t,y.keys.push(e))}),void 0!==n.config&&(Array.isArray(n.config)||"string"==typeof n.config?[].concat(n.config).filter(Boolean).forEach(function(e){y.configs[e]=!0}):"object"==typeof n.config&&Object.entries(n.config).forEach(([e,t])=>{"boolean"!=typeof t&&"function"!=typeof t||(y.configs[e]=t)})),function(...e){e.forEach(function(e){Object.keys(e||{}).forEach(function(e){y.aliases[e]||(y.aliases[e]=[].concat(r[e]||[]),y.aliases[e].concat(e).forEach(function(t){if(/-/.test(t)&&a["camel-case-expansion"]){const n=T(t);n!==e&&-1===y.aliases[e].indexOf(n)&&(y.aliases[e].push(n),f[n]=!0)}}),y.aliases[e].concat(e).forEach(function(t){if(t.length>1&&/[A-Z]/.test(t)&&a["camel-case-expansion"]){const n=function(e,t){const n=e.toLowerCase();t=t||"-";let o="";for(let s=0;s<e.length;s++){const r=n.charAt(s),a=e.charAt(s);o+=r!==a&&s>0?`${t}${n.charAt(s)}`:a}return o}(t,"-");n!==e&&-1===y.aliases[e].indexOf(n)&&(y.aliases[e].push(n),f[n]=!0)}}),y.aliases[e].forEach(function(t){y.aliases[t]=[e].concat(y.aliases[e].filter(function(e){return t!==e}))}))})})}(n.key,r,n.default,y.arrays),Object.keys(i).forEach(function(e){(y.aliases[e]||[]).forEach(function(t){i[t]=i[e]})});let w=null;Object.keys(y.counts).find(e=>B(e,y.arrays)?(w=Error(g("Invalid configuration: %s, opts.count excludes opts.array.",e)),!0):!!B(e,y.nargs)&&(w=Error(g("Invalid configuration: %s, opts.count excludes opts.narg.",e)),!0));let b=[];const $=Object.assign(Object.create(null),{_:[]}),v={};for(let e=0;e<o.length;e++){const t=o[e],n=t.replace(/^-{3,}/,"---");let s,r,i,c,l,d;if("--"!==t&&K(t))j(t);else{if(n.match(/---+(=|$)/)){j(t);continue}if(t.match(/^--.+=/)||!a["short-option-groups"]&&t.match(/^-.+=/))c=t.match(/^--?([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&(B(c[1],y.arrays)?e=_(e,c[1],o,c[2]):!1!==B(c[1],y.nargs)?e=k(e,c[1],o,c[2]):E(c[1],c[2],!0));else if(t.match(m)&&a["boolean-negation"])c=t.match(m),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],E(r,!!B(r,y.arrays)&&[!1]));else if(t.match(/^--.+/)||!a["short-option-groups"]&&t.match(/^-[^-]+/))c=t.match(/^--?(.+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],B(r,y.arrays)?e=_(e,r,o):!1!==B(r,y.nargs)?e=k(e,r,o):(l=o[e+1],void 0===l||l.match(/^-/)&&!l.match(h)||B(r,y.bools)||B(r,y.counts)?/^(true|false)$/.test(l)?(E(r,l),e++):E(r,L(r)):(E(r,l),e++)));else if(t.match(/^-.\..+=/))c=t.match(/^-([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&E(c[1],c[2]);else if(t.match(/^-.\..+/)&&!t.match(h))l=o[e+1],c=t.match(/^-(.\..+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],void 0===l||l.match(/^-/)||B(r,y.bools)||B(r,y.counts)?E(r,L(r)):(E(r,l),e++));else if(t.match(/^-[^-]+/)&&!t.match(h)){i=t.slice(1,-1).split(""),s=!1;for(let n=0;n<i.length;n++){if(l=t.slice(n+2),i[n+1]&&"="===i[n+1]){d=t.slice(n+3),r=i[n],B(r,y.arrays)?e=_(e,r,o,d):!1!==B(r,y.nargs)?e=k(e,r,o,d):E(r,d),s=!0;break}if("-"!==l){if(/[A-Za-z]/.test(i[n])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(l)&&!1===B(l,y.bools)){E(i[n],l),s=!0;break}if(i[n+1]&&i[n+1].match(/\W/)){E(i[n],l),s=!0;break}E(i[n],L(i[n]))}else E(i[n],l)}r=t.slice(-1)[0],s||"-"===r||(B(r,y.arrays)?e=_(e,r,o):!1!==B(r,y.nargs)?e=k(e,r,o):(l=o[e+1],void 0===l||/^(-|--)[^-]/.test(l)&&!l.match(h)||B(r,y.bools)||B(r,y.counts)?/^(true|false)$/.test(l)?(E(r,l),e++):E(r,L(r)):(E(r,l),e++)))}else if(t.match(/^-[0-9]$/)&&t.match(h)&&B(t.slice(1),y.bools))r=t.slice(1),E(r,L(r));else{if("--"===t){b=o.slice(e+1);break}if(a["halt-at-non-option"]){b=o.slice(e);break}j(t)}}}function j(e){const t=I("_",e);"string"!=typeof t&&"number"!=typeof t||$._.push(t)}function k(e,t,n,o){let s,r=B(t,y.nargs);if(r="number"!=typeof r||isNaN(r)?1:r,0===r)return q(o)||(w=Error(g("Argument unexpected for: %s",t))),E(t,L(t)),e;let i=q(o)?0:1;if(a["nargs-eats-options"])n.length-(e+1)+i<r&&(w=Error(g("Not enough arguments following: %s",t))),i=r;else{for(s=e+1;s<n.length&&(!n[s].match(/^-[^0-9]/)||n[s].match(h)||K(n[s]));s++)i++;i<r&&(w=Error(g("Not enough arguments following: %s",t)))}let c=Math.min(i,r);for(!q(o)&&c>0&&(E(t,o),c--),s=e+1;s<c+e+1;s++)E(t,n[s]);return e+c}function _(e,t,n,o){let r=[],c=o||n[e+1];const l=B(t,y.nargs);if(B(t,y.bools)&&!/^(true|false)$/.test(c))r.push(!0);else if(q(c)||q(o)&&/^-/.test(c)&&!h.test(c)&&!K(c)){if(void 0!==i[t]){const e=i[t];r=Array.isArray(e)?e:[e]}}else{q(o)||r.push(O(t,o,!0));for(let o=e+1;o<n.length&&!(!a["greedy-arrays"]&&r.length>0||l&&"number"==typeof l&&r.length>=l)&&(c=n[o],!/^-/.test(c)||h.test(c)||K(c));o++)e=o,r.push(O(t,c,s))}return"number"==typeof l&&(l&&r.length<l||isNaN(l)&&0===r.length)&&(w=Error(g("Not enough arguments following: %s",t))),E(t,r),e}function E(e,t,n=s){if(/-/.test(e)&&a["camel-case-expansion"]){const t=e.split(".").map(function(e){return T(e)}).join(".");S(e,t)}const o=O(e,t,n),r=e.split(".");if(P($,r,o),y.aliases[e]&&y.aliases[e].forEach(function(e){const t=e.split(".");P($,t,o)}),r.length>1&&a["dot-notation"]&&(y.aliases[r[0]]||[]).forEach(function(t){let n=t.split(".");const s=[].concat(r);s.shift(),n=n.concat(s),(y.aliases[e]||[]).includes(n.join("."))||P($,n,o)}),B(e,y.normalize)&&!B(e,y.arrays)){[e].concat(y.aliases[e]||[]).forEach(function(e){Object.defineProperty(v,e,{enumerable:!0,get:()=>t,set(e){t="string"==typeof e?F.normalize(e):e}})})}}function S(e,t){y.aliases[e]&&y.aliases[e].length||(y.aliases[e]=[t],f[t]=!0),y.aliases[t]&&y.aliases[t].length||S(t,e)}function O(e,t,n){n&&(t=function(e){return"string"!=typeof e||"'"!==e[0]&&'"'!==e[0]||e[e.length-1]!==e[0]?e:e.substring(1,e.length-1)}(t)),(B(e,y.bools)||B(e,y.counts))&&"string"==typeof t&&(t="true"===t);let o=Array.isArray(t)?t.map(function(t){return I(e,t)}):I(e,t);return B(e,y.counts)&&(q(o)||"boolean"==typeof o)&&(o=A()),B(e,y.normalize)&&B(e,y.arrays)&&(o=Array.isArray(t)?t.map(e=>F.normalize(e)):F.normalize(t)),o}function I(e,t){if(!a["parse-positional-numbers"]&&"_"===e)return t;if(!B(e,y.strings)&&!B(e,y.bools)&&!Array.isArray(t)){(null!=(n=t)&&("number"==typeof n||!!/^0x[0-9a-f]+$/i.test(n)||!/^0[^.]/.test(n)&&/^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(n))&&a["parse-numbers"]&&Number.isSafeInteger(Math.floor(parseFloat(`${t}`)))||!q(t)&&B(e,y.numbers))&&(t=Number(t))}var n;return t}function N(e,t){Object.keys(e).forEach(function(n){const o=e[n],s=t?t+"."+n:n;"object"==typeof o&&null!==o&&!Array.isArray(o)&&a["dot-notation"]?N(o,s):(!C($,s.split("."))||B(s,y.arrays)&&a["combine-arrays"])&&E(s,o)})}function R(e,t){if(void 0===l)return;const n="string"==typeof l?l:"",o=F.env();Object.keys(o).forEach(function(s){if(""===n||0===s.lastIndexOf(n,0)){const r=s.split("__").map(function(e,t){return 0===t&&(e=e.substring(n.length)),T(e)});(t&&y.configs[r.join(".")]||!t)&&!C(e,r)&&E(r.join("."),o[s])}})}function D(e,t,n,o=!1){Object.keys(n).forEach(function(s){C(e,s.split("."))||(P(e,s.split("."),n[s]),o&&(p[s]=!0),(t[s]||[]).forEach(function(t){C(e,t.split("."))||P(e,t.split("."),n[s])}))})}function C(e,t){let n=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){n=n[e]||{}});const o=t[t.length-1];return"object"==typeof n&&o in n}function P(e,t,n){let o=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){e=U(e),"object"==typeof o&&void 0===o[e]&&(o[e]={}),"object"!=typeof o[e]||Array.isArray(o[e])?(Array.isArray(o[e])?o[e].push({}):o[e]=[o[e],{}],o=o[e][o[e].length-1]):o=o[e]});const s=U(t[t.length-1]),r=B(t.join("."),y.arrays),i=Array.isArray(n);let c=a["duplicate-arguments-array"];!c&&B(s,y.nargs)&&(c=!0,(!q(o[s])&&1===y.nargs[s]||Array.isArray(o[s])&&o[s].length===y.nargs[s])&&(o[s]=void 0)),n===A()?o[s]=A(o[s]):Array.isArray(o[s])?c&&r&&i?o[s]=a["flatten-duplicate-arrays"]?o[s].concat(n):(Array.isArray(o[s][0])?o[s]:[o[s]]).concat([n]):c||Boolean(r)!==Boolean(i)?o[s]=o[s].concat([n]):o[s]=n:void 0===o[s]&&r?o[s]=i?n:[n]:!c||void 0===o[s]||B(s,y.counts)||B(s,y.bools)?o[s]=n:o[s]=[o[s],n]}function B(e,t){const n=[].concat(y.aliases[e]||[],e),o=Object.keys(t),s=n.find(e=>o.includes(e));return!!s&&t[s]}function M(e){const t=Object.keys(y);return[].concat(t.map(e=>y[e])).some(function(t){return Array.isArray(t)?t.includes(e):t[e]})}function K(e){return a["unknown-options-as-args"]&&function(e){if(e=e.replace(/^-{3,}/,"--"),e.match(h))return!1;if(function(e){if(e.match(h)||!e.match(/^-[^-]+/))return!1;let t,n=!0;const o=e.slice(1).split("");for(let s=0;s<o.length;s++){if(t=e.slice(s+2),!M(o[s])){n=!1;break}if(o[s+1]&&"="===o[s+1]||"-"===t||/[A-Za-z]/.test(o[s])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(t)||o[s+1]&&o[s+1].match(/\W/))break}return n}(e))return!1;return!function(e,...t){return[].concat(...t).some(function(t){const n=e.match(t);return n&&M(n[1])})}(e,/^-+([^=]+?)=[\s\S]*$/,m,/^-+([^=]+?)$/,/^-+([^=]+?)-$/,/^-+([^=]+?\d+)$/,/^-+([^=]+?)\W+.*$/)}(e)}function L(e){return B(e,y.bools)||B(e,y.counts)||!(`${e}`in i)?(t=function(e){let t=x.BOOLEAN;return B(e,y.strings)?t=x.STRING:B(e,y.numbers)?t=x.NUMBER:B(e,y.bools)?t=x.BOOLEAN:B(e,y.arrays)&&(t=x.ARRAY),t}(e),{[x.BOOLEAN]:!0,[x.STRING]:"",[x.NUMBER]:void 0,[x.ARRAY]:[]}[t]):i[e];var t}function q(e){return void 0===e}return R($,!0),R($,!1),function(e){const t=Object.create(null);D(t,y.aliases,i),Object.keys(y.configs).forEach(function(n){const o=e[n]||t[n];if(o)try{let e=null;const t=F.resolve(F.cwd(),o),s=y.configs[n];if("function"==typeof s){try{e=s(t)}catch(t){e=t}if(e instanceof Error)return void(w=e)}else e=F.require(t);N(e)}catch(t){"PermissionDenied"===t.name?w=t:e[n]&&(w=Error(g("Invalid JSON config file: %s",o)))}})}($),void 0!==c&&c.forEach(function(e){N(e)}),D($,y.aliases,i,!0),function(e){let t;const n=new Set;Object.keys(e).forEach(function(o){if(!n.has(o)&&(t=B(o,y.coercions),"function"==typeof t))try{const s=I(o,t(e[o]));[].concat(y.aliases[o]||[],o).forEach(t=>{n.add(t),e[t]=s})}catch(e){w=e}})}($),a["set-placeholder-key"]&&function(e){y.keys.forEach(t=>{~t.indexOf(".")||void 0===e[t]&&(e[t]=void 0)})}($),Object.keys(y.counts).forEach(function(e){C($,e.split("."))||E(e,0)}),d&&b.length&&($[u]=[]),b.forEach(function(e){$[u].push(e)}),a["camel-case-expansion"]&&a["strip-dashed"]&&Object.keys($).filter(e=>"--"!==e&&e.includes("-")).forEach(e=>{delete $[e]}),a["strip-aliased"]&&[].concat(...Object.keys(r).map(e=>r[e])).forEach(e=>{a["camel-case-expansion"]&&e.includes("-")&&delete $[e.split(".").map(e=>T(e)).join(".")],delete $[e]}),{aliases:Object.assign({},y.aliases),argv:Object.assign(v,$),configuration:a,defaulted:Object.assign({},p),error:w,newAliases:Object.assign({},f)}}}({cwd:process.cwd,env:()=>R,format:s.format,normalize:t.normalize,resolve:t.resolve,require:t=>{if("undefined"!=typeof require)return require(t);if(t.match(/\.json$/))return JSON.parse(e.readFileSync(t,"utf8"));throw Error("only .json config files are supported in ESM")}});var D={fs:{readFileSync:e.readFileSync,writeFile:e.writeFile},format:s.format,resolve:t.resolve,exists:t=>{try{return e.statSync(t).isFile()}catch(e){return!1}}};let C;class P{constructor(e){e=e||{},this.directory=e.directory||"./locales",this.updateFiles="boolean"!=typeof e.updateFiles||e.updateFiles,this.locale=e.locale||"en",this.fallbackToLanguage="boolean"!=typeof e.fallbackToLanguage||e.fallbackToLanguage,this.cache=Object.create(null),this.writeQueue=[]}__(...e){if("string"!=typeof arguments[0])return this._taggedLiteral(arguments[0],...arguments);const t=e.shift();let n=function(){};return"function"==typeof e[e.length-1]&&(n=e.pop()),n=n||function(){},this.cache[this.locale]||this._readLocaleFile(),!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]=t,this._enqueueWrite({directory:this.directory,locale:this.locale,cb:n})):n(),C.format.apply(C.format,[this.cache[this.locale][t]||t].concat(e))}__n(){const e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),o=e.shift();let s=function(){};"function"==typeof e[e.length-1]&&(s=e.pop()),this.cache[this.locale]||this._readLocaleFile();let r=1===o?t:n;if(this.cache[this.locale][t]){r=this.cache[this.locale][t][1===o?"one":"other"]}!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]={one:t,other:n},this._enqueueWrite({directory:this.directory,locale:this.locale,cb:s})):s();const a=[r];return~r.indexOf("%d")&&a.push(o),C.format.apply(C.format,a.concat(e))}setLocale(e){this.locale=e}getLocale(){return this.locale}updateLocale(e){this.cache[this.locale]||this._readLocaleFile();for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.cache[this.locale][t]=e[t])}_taggedLiteral(e,...t){let n="";return e.forEach(function(e,o){const s=t[o+1];n+=e,void 0!==s&&(n+="%s")}),this.__.apply(this,[n].concat([].slice.call(t,1)))}_enqueueWrite(e){this.writeQueue.push(e),1===this.writeQueue.length&&this._processWriteQueue()}_processWriteQueue(){const e=this,t=this.writeQueue[0],n=t.directory,o=t.locale,s=t.cb,r=this._resolveLocaleFile(n,o),a=JSON.stringify(this.cache[o],null,2);C.fs.writeFile(r,a,"utf-8",function(t){e.writeQueue.shift(),e.writeQueue.length>0&&e._processWriteQueue(),s(t)})}_readLocaleFile(){let e={};const t=this._resolveLocaleFile(this.directory,this.locale);try{C.fs.readFileSync&&(e=JSON.parse(C.fs.readFileSync(t,"utf-8")))}catch(n){if(n instanceof SyntaxError&&(n.message="syntax error in "+t),"ENOENT"!==n.code)throw n;e={}}this.cache[this.locale]=e}_resolveLocaleFile(e,t){let n=C.resolve(e,"./",t+".json");if(this.fallbackToLanguage&&!this._fileExistsSync(n)&&~t.lastIndexOf("_")){const o=C.resolve(e,"./",t.split("_")[0]+".json");this._fileExistsSync(o)&&(n=o)}return n}_fileExistsSync(e){return C.exists(e)}}let B;try{B=r.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:w&&"SCRIPT"===w.tagName.toUpperCase()&&w.src||new URL("index.js",document.baseURI).href)}catch(e){B=process.cwd()}B.split("node_modules")[0]||process.cwd(),process.cwd,process.exit,process.nextTick,void 0!==process.stdout.columns&&process.stdout.columns,function(e,t){C=t;const n=new P(e);n.__.bind(n),n.__n.bind(n),n.setLocale.bind(n),n.getLocale.bind(n),n.updateLocale.bind(n),n.locale}({directory:t.resolve(B,"../../../locales"),updateFiles:!1},D);const M={hg:{appName:"hotglue",clientApiBaseUri:process.env.HOTGLUE_CLIENT_API_BASE_URI||"https://api.hotglue.com",defaultConfigFileName:"config.yaml"}},K={},L=()=>t.resolve(n.homedir(),`.${M.hg.appName}`,M.hg.defaultConfigFileName),q=async()=>{const{appName:e}=M.hg;try{return await i.cosmiconfig(e).load(L())||{}}catch(e){return{}}},z=async()=>{const{appName:e}=M.hg,t=i.cosmiconfig(e,{searchPlaces:[`${e}.yaml`,`.${e}.yaml`,`.${e}rc.yaml`,`.${e}rc.yml`,`.${e}rc`,`.${e}rc.json`,`.${e}rc.js`]});try{return await t.search()||{}}catch(e){throw console.log(e),new Error(`Malformed configuration file: ${e.message}`)}},J={primary:e=>c.whiteBright(e),secondary:e=>c.white(e),info:e=>c.green(e),warn:e=>c.yellow(e),error:e=>c.redBright(e),success:e=>c.greenBright(e)};let V=J,W="primary";function Y(e){return V={...J,...e},ee}function G(e){process.stdout.write(e)}const Q=(e,t=W)=>{if(!e)return"";if("string"==typeof e)return V[t]?V[t](e):V[W](e);const n=s.inspect(e,{colors:!0});return V[t]?V[t](n):n};function H(...e){return console.log(...e),ee}function Z(e,t){return G(Q(e,t)),G("\n"),ee}function X(e,t){return G(Q(e,t)),ee}const ee={cl:H,pr:Z,pp:X,setTheme:Y,setDefault:function(e="primary"){return V[e]&&(W=e),ee}},te=e=>{console.log(JSON.stringify(e))},ne=d("hotglue-cli");function oe(e){return ne.extend(e)}const se=oe("commands:config:set"),re="set <setting> <value>";var ae=Object.freeze({__proto__:null,builder:async e=>(se("builder",re,e),e.option("setting",{describe:"The configuration parameter you wish to set",type:"string"}).option("value",{describe:"The configuration parameter's value",type:"string"}),e),command:re,desc:"Set configuration key-value pairs",handler:async e=>{se("handler",re,e);const{json:n,setting:o,value:s}=e;if(["apikey"].includes(o))try{const e=await q();e&&e.config?!n&&X("Updating profile config file..."):!n&&X("Creating profile config file...");const r=e&&e.config?{...e.config,[o]:s}:{[o]:s},i=u.stringify(r),c=e&&e.filepath?e.filepath:L();await(async(e,n)=>{await a.mkdir(t.dirname(e),{recursive:!0}),await a.writeFile(e,n)})(c,i),n?te({status:"success"}):X("Done").pr()}catch(e){n?te({status:"error",error:e}):console.log(e)}else n?te({status:"error",error:"Invalid settings parameter"}):console.error("Invalid settings parameter")}});const ie=[ae],ce=oe("commands:config"),le="config [action]";var de=Object.freeze({__proto__:null,builder:async function(e){return ce("builder",le),e.command(ie)},command:le,desc:"Configure your hotglue CLI",handler:async function(e){ce("handler",le,e);const{action:n}=e;if(!n)try{const e=await q();e.config&&0!==Object.keys(e.config).length||Z("No profile configuration found. Run config set to configure the hotglue CLI.");const n=new f({head:["Setting","Value","Config File","Type"]});e.config&&Object.entries(e.config).forEach(([t,o])=>n.push([t,o,e.filepath,"Profile"]));const o=await z();o.config&&Object.entries(o.config).forEach(([e,s])=>n.push([e,s,t.relative(process.cwd(),o.filepath),"Project"])),n.length>0&&console.log(n.toString())}catch(e){throw console.log(e),e}}}),ue={env:{config:{describe:"Environment Id",type:"string",alias:["e"]},demandText:'The "env" parameter (Environment Id) is required. Either pass here using `-e [env_id]` or add an env property in your rc file.'},apikey:{config:{describe:"API key",type:"string",alias:["k"]},demandText:"API key is required. Either pass here using -k [key] or configure your profile using config set."},dataFilePath:{config:{describe:"Singer data file path",type:"string",alias:["data","data-file-path"],default:"data.singer"}},json:{config:{describe:"Makes the output format to be JSON",type:"boolean",default:!1},demandText:""},tenant:{config:{describe:"Tenant (user) ID",type:"string",alias:["u"]},demandText:"TenantId is required. You can pass it using -u [tenantId]."},flow:{config:{describe:"Flow ID",type:"string",alias:["f"]},demandText:"FlowId is required. You can pass it using -f [flow_id]."},tap:{config:{describe:"Tap name",type:"string",alias:["t"]},demandText:"Tap name is required. You can pass it using -t <tap_name>."},connector:{config:{describe:"Connector ID",type:"string",alias:["c"]},demandText:"Connector ID is required. You can pass it using -c <connector>."},all:{config:{describe:"Run command for all taps/connectors",type:"boolean",default:!1,alias:["a"]},demandText:'This "all" flag is required. You can pass it using -a or --all.'},jobroot:{config:{describe:"Job Root (S3 prefix)",type:"string",alias:["j"]},demandText:"JobRoot key is required. You can pass it using -j [job_root]."},count:{config:{describe:"Max returned records",type:"number"}},downloadTo:{config:{describe:"Download folder",default:".",type:"string",alias:["d"]},demandText:"A destination folder is required. You can pass it using -d [folder] and can be either relative from cwd or absolute."},sourceFolder:{config:{describe:"Source folder",type:"string",default:".",alias:["s"]},demandText:""},configFilePath:{config:{describe:"Config file path",type:"string",default:"./config.json",alias:["p"]},demandText:'Local path of the config (with .json extension). Example: "/home/hotglue/config.json"'},overwrite:{config:{describe:"Overwrite existing",type:"boolean",default:!1,alias:["o"]},demandText:""},cleanup:{config:{describe:"Clean up target prior to action",type:"boolean",default:!1,alias:["c"]},demandText:""},includeConfigs:{config:{describe:"Include configs in the download folder (source-config.json, target-config.json, tenant-config.json)",type:"boolean",default:!1},demandText:""}};const fe=oe("base"),pe=async e=>{fe("builder");const t=await(async()=>{const e=await q(),t=await z();return{...K,...e.config,...t.config}})();return e.option("apikey",ue.apikey.config).option("env",ue.env.config).option("json",ue.json.config).config(t).demandOption(["env"],ue.env.demandText).demandOption(["apikey"],ue.apikey.demandText).strictCommands()},ge=oe("utils.js"),ye=async(e,n,o=[])=>{const{includeSymLinks:s,recursive:r,filter:i}=n,{matcher:c}=i,l=t.resolve(e),d=await a.readdir(l,{withFileTypes:!0});for(const e of d){const a=t.resolve(l,e.name);e.isSymbolicLink()&&!s||(!c||c(a)?e.isFile()?o.push(t.resolve(l,e.name)):e.isDirectory()&&r&&await ye(t.resolve(l,e.name),n,o):ge("skip",a))}return o},he=async(e,t)=>{const n={includeSymLinks:!1,recursive:!1,filter:{},...t},{pattern:o}=n.filter;return o&&(n.filter.matcher=g.matcher(o,{dot:!0})),ye(e,n)},me=(e,t)=>{ge("filter-in",e);const{pattern:n}={...t};let o=e;return n&&(o=g(o,n)),ge("filter-out",o),o};const we=e=>{const t=[];return new Promise((n,o)=>{e.on("error",o),e.on("data",e=>t.push(Buffer.from(e))),e.on("end",()=>n(Buffer.concat(t).toString("utf8")))})},be=(e,t=10)=>{const n=[];for(let o=0;o<e.length;o+=t){const s=e.slice(o,o+t);n.push(s)}return n},$e=async({debug:e,baseUri:t,env:n,apiKey:o})=>{const s=new URL(`${t}/${n}/resetAvailableEntities`),{data:r}=await y.delete(s,{headers:{"x-api-key":o,"Content-type":"application/json"}});e({data:r})},ve=async({debug:e,baseUri:t,task:n,env:o,apikey:s,...r})=>{const a=new URL(`${t}/credentials/${n}/${o}`);r&&Object.entries(r).forEach(([e,t])=>{a.searchParams.set(e,t)});const i=a.toString();e&&e("uri:",i);const{data:c}=await y.get(i,{headers:{"x-api-key":s}}),{accessKeyId:l,secretAccessKey:d,sessionToken:u}=c;return{accessKeyId:l,secretAccessKey:d,sessionToken:u}},je=async({debug:e,baseUri:t,env:n,apikey:o,requestSecret:s=!1})=>{const r=new URL(`${t}/${n}/config`);s&&r.searchParams.set("secret","true");const a=r.toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:{"x-api-key":o}});return i},ke=async({debug:e,baseUri:t,env:n,apikey:o})=>{const s=`${t}/tenants/${n}`;e("requesting:",s);const{data:r}=await y.get(s,{headers:{"x-api-key":o}});return e("response-data",r),r},_e=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/${o}/supportedSources`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},Ee=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/v2/${n}/${o}/supportedConnectors`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},xe=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,config:a})=>{const i=new URL(`${t}/${n}/${o}/${s}/linkedSources`);a&&i.searchParams.set("config","true");const c={"x-api-key":r},l=i.toString();e&&e("uri:",l);const{data:d}=await y.get(l,{headers:c});return d},Se=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,config:a})=>{const i=new URL(`${t}/v2/${n}/${o}/${s}/linkedConnectors`);a&&i.searchParams.set("config","true");const c={"x-api-key":r},l=i.toString();e&&e("uri:",l);const{data:d}=await y.get(l,{headers:c});return d},Oe=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,connectorId:a,config:i})=>{const c={"x-api-key":r},l=new URL(`${t}/${n}/${o}/${s}/linkedSources`).toString(),d={tap:a,config:i};e&&e("uri:",l);const{data:u}=await y.patch(l,d,{headers:c});return u},Ie=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,connectorId:a,config:i})=>{const c={"x-api-key":r},l=new URL(`${t}/v2/${n}/${o}/${s}/linkedConnectors`).toString(),d={connector_id:a,config:i};e&&e("uri:",l);const{data:u}=await y.patch(l,d,{headers:c});return u},Te=async({debug:e,baseUri:t,env:n,apikey:o})=>{const s={"x-api-key":o},r=new URL(`${t}/${n}/flows/supported`).toString();e&&e("uri:",r);const{data:a}=await y.get(r,{headers:s});return a},Fe=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/flows/${o}/supported`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},Ae=async({debug:e,baseUri:t,env:n,apikey:o,from:s,to:r,count:a=1e4,...i})=>{const c={"x-api-key":o},l="string"==typeof a?parseInt(a,10):a;let d=[],u=0,f=1,p=!0;for(;p;){const o=new URL(`${t}/${n}/jobs`);o.searchParams.set("from",s),r&&o.searchParams.set("to",r),o.searchParams.set("count",l.toString()),o.searchParams.set("page",f.toString()),i&&Object.entries(i).forEach(([e,t])=>{null!=t&&"count"!==e&&"page"!==e&&o.searchParams.set(e,t)}),o.searchParams.set("include_export_details","false"),o.searchParams.set("skip_cache","true");const a=o.toString();e&&e(`Fetching page ${f}, uri:`,a);const{data:g}=await y.get(a,{headers:c});e&&e(`Page ${f} response:`,{jobsCount:g.jobs?.length||0,total:g.total||0});const h=g.jobs||[];d=d.concat(h),1===f&&(u=g.total||0),h.length<l?p=!1:f++}return e&&e(`Fetched ${d.length} jobs across ${f} page(s)`),{jobs:d,total:u}},Ue=async({debug:e,baseUri:t,env:n,apikey:o,tenant:s,flow:r,...a})=>{const i={"x-api-key":o},c=new URL(`${t}/${n}/${r}/${s}/jobs/retrigger`).toString(),l=a;e&&e("uri:",c),e&&e("payload:",l);const{data:d}=await y.post(c,l,{headers:i});return d},Ne=async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,schedule_expression:a,state:i,job_type:c,connector_id:l,extra_args:d})=>{const u={"x-api-key":r},f=new URL(`${t}/${n}/${o}/${s}/jobs/schedule`).toString(),p={schedule_expression:a,state:i};c&&(p.job_type=c),l&&(p.connector_id=l),d&&Object.assign(p,d),e&&e("uri:",f),e&&e("body:",p);const{data:g}=await y.put(f,p,{headers:u});return g},Re=async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,include_export_details:i=!1})=>{const c=new URL(`${t}/${n}/${o}/${s}/jobs/status`);c.searchParams.set("job_root",a),c.searchParams.set("include_export_details",i?"true":"false");const l={"x-api-key":r},d=c.toString();e&&e("uri:",d);const{data:u}=await y.get(d,{headers:l});return u},De=d("commands:env:validators"),Ce=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableSources.json must be an array of objects");const r=(await Promise.all(o.filter(e=>1==e.version).map(async e=>await _e({debug:De,baseUri:t,env:s,flow:e.id,apikey:n})))).flat(),a=e.map(e=>{if(!e.tap)throw new Error(`Source ${JSON.stringify(e)} has no tap id`);return e.tap}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate source id(s) found in availableSources.json: ${i.join(", ")}. All sources must have a unique tap id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.tap));if(c.length>0)throw new Error(`Sources ${c.map(e=>e.label).join(", ")} are linked, but missing from your availableSources.json`)},Pe=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableTargets.json must be an array of objects");const r=(await Promise.all(o.filter(e=>1==e.version).map(async e=>{const o=await(async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/${o}/supportedTargets`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i})({debug:De,baseUri:t,env:s,flow:e.id,apikey:n});return o}))).flat(),a=e.map(e=>{if(!e.target)throw new Error(`Target ${JSON.stringify(e)} has no target id`);return e.target}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate target id(s) found in availableTargets.json: ${i.join(", ")}. All targets must have a unique target id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.target));if(c.length>0)throw new Error(`Targets ${c.map(e=>e.label).join(", ")} are linked, but missing from your availableTargets.json`)},Be=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableConnectors.json must be an array of objects");const r=(await Promise.all(o.filter(e=>2==e.version).map(async e=>await Ee({debug:De,baseUri:t,env:s,flow:e.id,apikey:n})))).flat(),a=e.map(e=>{if(!e.id)throw new Error(`Connector ${JSON.stringify(e)} has no id`);return e.id}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate connector id(s) found in availableConnectors.json: ${i.join(", ")}. All connectors must have a unique id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.id));if(c.length>0)throw new Error(`Connectors ${c.map(e=>e.id).join(", ")} are linked, but missing from your availableConnectors.json`)},Me=oe("commands:env:deploy"),Ke="deploy";var Le=Object.freeze({__proto__:null,builder:async e=>(Me("builder",Ke),e.option("sourceFolder",ue.sourceFolder.config).demandOption("sourceFolder",ue.sourceFolder.demandText)),command:Ke,desc:"Deploy Environment settings",handler:async e=>{Me("handler",Ke,e);const{hg:n,json:o,apikey:s,env:r,sourceFolder:i}=e,{clientApiBaseUri:c}=n,d=t.resolve(process.cwd(),i);let u,g=p();try{u=Q(`Scanning ${Q(d,"info")} for deployable files`),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const e=await he(d,{filter:{pattern:"((**/requirements.txt)|(**/availableSources.json)|(**/availableTargets.json)|(**/availableConnectors.json)|(**/customTaps.json))"}});if(0===e.length)return void(o?te({status:"error",error:"There are no files to deploy at the specified location!"}):(g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q("There are no files to deploy at the specified location!")}`,"secondary"))));!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));for(const t of e)if(t.endsWith(".json"))try{const e=await a.readFile(t,{encoding:"utf-8"});JSON.parse(e)}catch(e){throw new Error(`File ${t} is not a valid JSON: ${String(e)}`)}const n=await Te({debug:Me,baseUri:c,env:r,apikey:s});for(const t of e){if(t.endsWith("availableSources.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Ce(e,c,s,n,r)}if(t.endsWith("availableTargets.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Pe(e,c,s,n,r)}if(t.endsWith("availableConnectors.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Be(e,c,s,n,r)}}u=Q("Verifying user and authorizing"),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const{accessKeyId:i,secretAccessKey:p,sessionToken:y}=await ve({debug:Me,baseUri:c,task:"env-deploy",env:r,apikey:s});!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));const h=new l.S3({accessKeyId:i,secretAccessKey:p,sessionToken:y});u=Q("Deploying environment files"),!o&&g.info(Q(`Info: ${u}.`,"secondary"));const m="config/",w=new f({head:["File","Status"]});for await(const n of e){const e=t.basename(n);u=Q(`Pushing file: ${Q(e,"info")}`),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const i={Bucket:r,Key:`${m}${e}`,Body:await a.readFile(n)},l=await h.putObject(i).promise();!o&&g.succeed(Q(`Finished: ${u}.`,"secondary")),Me("s3-put-res",l),w.push([e,"Deployed"]),await $e({debug:Me,baseUri:c,env:r,apiKey:s})}o?te({status:"success",deployedFiles:e}):H(w.toString())}catch(e){!o&&g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Me(e),e&&e.response&&e.response.data&&Me("response",e.response.data),process.exit(1)}}});const qe=oe("commands:env:download"),ze="download";var Je=Object.freeze({__proto__:null,builder:async e=>(qe("builder",ze),e.option("downloadTo",ue.downloadTo.config)),command:ze,desc:"Download Environment settings",handler:async e=>{qe("handler",ze,e);const{hg:n,json:o,apikey:s,env:r,downloadTo:i}=e,{clientApiBaseUri:c}=n,d=t.resolve(process.cwd(),i);let u,g=p();try{u=Q("Verifying user and authorizing"),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const{accessKeyId:e,secretAccessKey:n,sessionToken:i}=await ve({debug:qe,baseUri:c,task:"env-download",env:r,apikey:s});!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));const p=new l.S3({accessKeyId:e,secretAccessKey:n,sessionToken:i});u=Q(`Scanning environment ${Q(r,"info")}`),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const y={Bucket:r,Prefix:"config/"},{Contents:h}=await p.listObjectsV2(y).promise();!o&&g.succeed(Q(`Finished: ${u}.`,"secondary")),qe("s3-files",h);const m=h?me(h.map(e=>e.Key),{pattern:"((*/requirements.txt)|(*/availableSources.json)|(*/availableTargets.json)|(*/availableConnectors.json)|(*/customTaps.json))"}):[];if(!m||0===m.length)return void(o?te({status:"success",downloadedFiles:[]}):g.warn(Q(`Warning: ${Q("Nothing to download!")}`,"secondary")));u=Q(`Downloading to ${Q(d,"info")}`),!o&&g.info(Q(`Info: ${u}.`,"secondary"));const w=new f({head:["File","Status"]});for await(const e of m){const n=t.basename(e),s=t.resolve(d,n);qe("local-file",s),await a.mkdir(t.dirname(s),{recursive:!0}),u=Q(`Downloading file: ${Q(n,"info")}`),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const i=p.getObject({Bucket:r,Key:e}).createReadStream();await a.writeFile(s,await we(i)),!o&&g.succeed(Q(`Finished: ${u}.`,"secondary")),w.push([n,"Downloaded"])}o?te({status:"success",downloadedFiles:m}):H(w.toString())}catch(e){o?te({status:"error",error:e}):(g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),qe(e),e&&e.response&&e.response.data&&qe("response",e.response.data)),process.exit(1)}}});const Ve=[Le,Je],We=oe("commands:env"),Ye="env <action>";var Ge=Object.freeze({__proto__:null,builder:async function(e){We("builder",Ye);return(await pe(e)).command(Ve)},command:Ye,desc:"Manage environment settings",handler:async function(e){We("handler",Ye,e)}});const Qe=async(e,t,n,o)=>{try{const s=e.getObject({Bucket:t,Key:`${n}/flows/${o}/flow.json`}).createReadStream(),r=await we(s);return 2===JSON.parse(r).version}catch(e){return!1}},He=async(e,t,n,o,s=void 0)=>s??await Qe(e,t,n,o)?"connectors":"taps",Ze=oe("commands:etl:delete"),Xe="delete";var et=Object.freeze({__proto__:null,builder:async e=>(Ze("builder",Xe),e.option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText).option("tap",ue.tap.config).demandOption("tap",ue.tap.demandText).option("tenant",{...ue.tenant.config}).demandOption("tenant",ue.tenant.demandText)),command:Xe,desc:"Delete ETL scripts",handler:async e=>{Ze("handler",Xe,e);const{hg:t,json:n,apikey:o,env:s,flow:r,tap:a,tenant:i}=e,{clientApiBaseUri:c}=t;let d,u=p();try{d=Q(`Deleting ETL scripts for Tenant ${Q(i,"info")} Flow ${Q(r,"info")} and Tap ${Q(a,"info")} to ${Q(s,"info")}`),!n&&u.info(Q(`Info: ${d}.`,"secondary")),d=Q("Verifying user and authorizing"),!n&&u.start(Q(`In progress: ${d}...`,"secondary"));const{accessKeyId:e,secretAccessKey:t,sessionToken:p}=await ve({debug:Ze,baseUri:c,task:"etl-deploy",env:s,tenant:i,flow:r,tap:a,apikey:o}),g=new l.S3({accessKeyId:e,secretAccessKey:t,sessionToken:p});!n&&u.succeed(Q(`Finished: ${d}.`,"secondary")),d=Q("Deleting ETL scripts"),!n&&u.start(Q(`In progress: ${d}...`,"secondary"));const y=`${i}/flows/${r}/${await He(g,s,i,r)}/${a}/etl/`,h=await g.listObjectsV2({Bucket:s,Prefix:y}).promise();if(Ze("s3-list-objects-res",h),h.Contents?.length>0){const e=await g.deleteObjects({Bucket:s,Delete:{Objects:h.Contents.map(e=>({Key:e.Key}))}}).promise();Ze("s3-list-objects-res",e)}const m=await g.deleteObject({Bucket:s,Key:y}).promise();if(Ze("s3-delete-object-res",m),!n&&u.succeed(Q(`Finished: ${d}.`,"secondary")),h.Contents?.length>0){const e=new f({head:["File","Status"]});h.Contents.filter(({Key:e})=>e!==y).forEach(({Key:t})=>{const n=t.split("/"),o=n[n.length-1];e.push([o,Q("Deleted","info")])}),n?te({status:"success",deletedObjects:(h.Contents??[]).map(({Key:e})=>e)}):H(e.toString())}else d=Q("There was no file or folder to be deleted"),n?te({status:"success",deletedObjects:[]}):u.info(Q(`Info: ${d}.`,"secondary"))}catch(e){n?te({status:"error",error:e}):(u.fail(Q(`Error: ${d}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Ze(e),e&&e.response&&e.response.data&&Ze("response",e.response.data)),process.exit(1)}}});const tt=oe("commands:etl:deploy"),nt="deploy";var ot=Object.freeze({__proto__:null,builder:async e=>(tt("builder",nt),e.option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText).option("tap",ue.tap.config).option("all",ue.all.config).option("tenant",{...ue.tenant.config,default:"default"}).option("sourceFolder",ue.sourceFolder.config).demandOption("sourceFolder",ue.sourceFolder.demandText)),command:nt,desc:"Deploy ETL scripts",handler:async e=>{tt("handler",nt,e);const{hg:n,json:o,apikey:s,env:r,flow:i,tap:c,all:d,tenant:u,sourceFolder:g}=e,{clientApiBaseUri:y}=n;if(!d&&!c)throw new Error(`${ue.tap.demandText} Or you can pass the --all flag to run this command for all taps/connectors.`);let h,m=p();const w=t.resolve(process.cwd(),g);try{h=Q(`Deploying script for Tenant ${Q(u,"info")} Flow ${Q(i,"info")}${c?` and Tap ${Q(c,"info")}`:""} to ${Q(r,"info")}`),!o&&m.info(Q(`Info: ${h}.`,"secondary"));const e=await he(w,{recursive:!0,filter:{pattern:"!((**/sync-output)|(**/etl-output)|(**/snapshots))"}});if(0===e.length)return void(o?te({status:"error",error:"There are no files to deploy at the specified location!"}):m.fail(Q(`Error: ${Q("There are no files to deploy at the specified location!")}.`,"secondary")));(e=>{const t=["config.json","source-config.json","target-config.json","catalog.json","target-catalog.json","state.json"],n=["sync-output","snapshots","etl-output",".venv"];for(const o of e){if(t.includes(o))throw new Error(`File ${o} is a reserved file name and cannot be used in the ETL script.`);const e=n.find(e=>o.startsWith(`${e}/`));if(e)throw new Error(`Directory ${e} is a reserved directory name and cannot be used in the ETL script.`)}})(e.map(e=>t.relative(g,e))),h=Q("Verifying user and authorizing"),!o&&m.start(Q(`In progress: ${h}...`,"secondary"));const n={debug:tt,baseUri:y,task:"etl-deploy",env:r,tenant:u,flow:i,apikey:s};c&&(n.tap=c);const{accessKeyId:d,secretAccessKey:p,sessionToken:b}=await ve(n);!o&&m.succeed(Q(`Finished: ${h}.`,"secondary"));const $=new l.S3({accessKeyId:d,secretAccessKey:p,sessionToken:b}),v=await Qe($,r,u,i);h=Q("Validating flow and tap location"),!o&&m.start(Q(`In progress: ${h}...`,"secondary"));const j=(await Te({debug:tt,baseUri:y,apikey:s,env:r})).find(({id:e})=>e===i);let k=[];try{if("default"===u||j?.type){if(k=((v?await Ee({debug:tt,baseUri:y,env:r,flow:i,apikey:s}):await _e({debug:tt,baseUri:y,env:r,flow:i,apikey:s}))??[]).filter(e=>!c||e[v?"id":"tap"]===c),c&&0===k.length)throw new Error("Tap is not supported")}else{if(k=((v?await Se({debug:tt,baseUri:y,env:r,flow:i,tenant:u,apikey:s}):await xe({debug:tt,baseUri:y,env:r,flow:i,tenant:u,apikey:s}))??[]).filter(e=>!c||e[v?"id":"tap"]===c),c&&0===k.length)throw new Error("Tap is not linked")}}catch(e){throw tt("err",e),new Error("Target location doesn't exist. Check your tenant, flow and tap arguments.")}!o&&m.succeed(Q(`Finished: ${h}.`,"secondary"));const _=new f({head:["File","Status"]});for(const n of k){const s=n[v?"id":"tap"];h=Q(`Preparing ${s} deployment target`),!o&&m.start(Q(`In progress: ${h}...`,"secondary"));const c=`${u}/flows/${i}/${await He(null,null,null,null,v)}/${s}/etl/`,{Contents:l}=await $.listObjectsV2({Bucket:r,Prefix:`${c}`}).promise();!o&&m.succeed(Q(`Finished: ${h}.`,"secondary")),tt("contents",l);const d=l.map(e=>({Key:e.Key}));if(d.length>0){h=Q(`Removing old ${s} ETL files`),!o&&m.start(Q(`In progress: ${h}...`,"secondary"));const e={Bucket:r,Delete:{Objects:d,Quiet:!0}};await $.deleteObjects(e).promise(),d.forEach(({Key:e})=>_.push([`${s}/${e.substring(c.length)}`,Q("Deleted","warn")])),!o&&m.succeed(Q(`Finished: ${h}.`,"secondary"))}for await(const n of e){const e="win32"===process.platform?t.relative(g,n).replace(/\\/g,"/"):t.relative(g,n),i=`${c}${e}`;h=Q(`Deploying file: ${Q(`${s}/${e}`,"info")}`),!o&&m.start(Q(`In progress: ${h}...`,"secondary"));const l={Bucket:r,Key:i,Body:await a.readFile(n)},d=await $.putObject(l).promise();!o&&m.succeed(Q(`Finished: ${h}.`,"secondary")),tt("s3-put-res",d),_.push([`${s}/${e}`,Q("Deployed","info")])}}o?te({status:"success",deployedFiles:e}):H(_.toString())}catch(e){o?te({status:"error",error:e}):(m.fail(Q(`Error: ${h}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),tt(e),e&&e.response&&e.response.data&&tt("response",e.response.data)),process.exit(1)}}});const st=oe("commands:etl:download"),rt="download";var at,it=Object.freeze({__proto__:null,builder:async e=>(st("builder",rt),e.option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText).option("tap",ue.tap.config).demandOption("tap",ue.tap.demandText).option("downloadTo",ue.downloadTo.config).demandOption("downloadTo",ue.downloadTo.demandText).option("tenant",{...ue.tenant.config,default:"default"}).option("overwrite",ue.overwrite.config).demandOption("overwrite",ue.overwrite.demandText)),command:rt,desc:"Download ETL scripts",handler:async n=>{st("handler",rt,n);const{hg:o,json:s,apikey:r,env:i,flow:c,tap:d,tenant:u,downloadTo:g,overwrite:y}=n,{clientApiBaseUri:h}=o;let m,w=p();const b=t.resolve(process.cwd(),g);try{m=Q("Verifying user and authorizing"),!s&&w.start(Q(`In progress: ${m}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:p}=await ve({debug:st,baseUri:h,task:"etl-download",env:i,tenant:u,flow:c,tap:d,apikey:r}),g=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:p});!s&&w.succeed(Q(`Finished: ${m}.`,"secondary")),m=Q("Scanning for downloadable files"),!s&&w.start(Q(`In progress: ${m}...`,"secondary"));const $=`${u}/flows/${c}/${await He(g,i,u,c)}/${d}/etl/`,v={Bucket:i,Prefix:$},{Contents:j}=await g.listObjectsV2(v).promise();!s&&w.succeed(Q(`Finished: ${m}.`,"secondary")),st("s3-list-res",j);const k=j?me(j.map(e=>e.Key),{pattern:"!(.ipynb_checkpoints/*)"}):[];if(!k||0===k.length)return void(s?te({status:"success",downloadedFiles:[]}):w.warn(Q(`Warning: ${Q("Nothing to download!")}`,"secondary")));m=Q(`Downloading script files to ${Q(b,"info")}`),!s&&w.info(Q(`Info: ${m}.`,"secondary"));const _=new f({head:["File","Status"]});for await(const n of k){const o=n.substring($.length),r=t.resolve(b,o);if(st("file",r),n.endsWith("/")){!e.existsSync(r)&&await a.mkdir(r,{recursive:!0});continue}if(!y)try{await a.stat(r),st("exists, skipping"),_.push([o,"Skipped"]);continue}catch(e){"ENOENT"!==e.code&&H(e)}m=Q(`Downloading file: ${Q(o,"info")}`),!s&&w.start(Q(`In progress: ${m}...`,"secondary")),await a.mkdir(t.dirname(r),{recursive:!0});const c=g.getObject({Bucket:i,Key:n}).createReadStream();await a.writeFile(r,await we(c)),!s&&w.succeed(Q(`Finished: ${m}.`,"secondary")),_.push([o,"Downloaded"])}s?te({status:"success",downloadedFiles:k}):H(_.toString())}catch(e){s?te({status:"error",error:e}):(w.fail(Q(`Error: ${m}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),st(e),e&&e.response&&e.response.data&&st("response",e.response.data)),process.exit(1)}}}),ct={exports:{}},lt={exports:{}},dt={exports:{}},ut={exports:{}};var ft,pt={exports:{}},gt={exports:{}};var yt,ht,mt={exports:{}};function wt(){return ht||(ht=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){if((0,o.default)(e))return function(e){var t=-1,n=e.length;return function(){return++t<n?{value:e[t],key:t}:null}}(e);var t=(0,r.default)(e);return t?function(e){var t=-1;return function(){var n=e.next();return n.done?null:(t++,{value:n.value,key:t})}}(t):(n=e,s=n?Object.keys(n):[],a=-1,i=s.length,function e(){var t=s[++a];return"__proto__"===t?e():a<i?{value:n[t],key:t}:null});var n,s,a,i};var n=function(){return ft||(ft=1,e=gt,t=gt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e&&"number"==typeof e.length&&e.length>=0&&e.length%1==0},e.exports=t.default),gt.exports;var e,t}(),o=a(n),s=function(){return yt||(yt=1,e=mt,t=mt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e[Symbol.iterator]&&e[Symbol.iterator]()},e.exports=t.default),mt.exports;var e,t}(),r=a(s);function a(e){return e&&e.__esModule?e:{default:e}}e.exports=t.default}(pt,pt.exports)),pt.exports}var bt,$t={exports:{}};var vt,jt={},kt={exports:{}},_t={exports:{}};var Et,xt,St,Ot={};function It(){return xt||(xt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){if((0,r.isAsync)(e))return function(...t){const n=t.pop();return i(e.apply(this,t),n)};return(0,o.default)(function(t,n){var o;try{o=e.apply(this,t)}catch(e){return n(e)}if(o&&"function"==typeof o.then)return i(o,n);n(null,o)})};var n=function(){return vt||(vt=1,e=_t,t=_t.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return function(...t){var n=t.pop();return e.call(this,t,n)}},e.exports=t.default),_t.exports;var e,t}(),o=a(n),s=a(function(){if(Et)return Ot;Et=1,Object.defineProperty(Ot,"__esModule",{value:!0}),Ot.fallback=s,Ot.wrap=r;var e,t=Ot.hasQueueMicrotask="function"==typeof queueMicrotask&&queueMicrotask,n=Ot.hasSetImmediate="function"==typeof setImmediate&&setImmediate,o=Ot.hasNextTick="object"==typeof process&&"function"==typeof process.nextTick;function s(e){setTimeout(e,0)}function r(e){return(t,...n)=>e(()=>t(...n))}return e=t?queueMicrotask:n?setImmediate:o?process.nextTick:s,Ot.default=r(e),Ot}()),r=Tt();function a(e){return e&&e.__esModule?e:{default:e}}function i(e,t){return e.then(e=>{c(t,null,e)},e=>{c(t,e&&(e instanceof Error||e.message)?e:new Error(e))})}function c(e,t,n){try{e(t,n)}catch(e){(0,s.default)(e=>{throw e},e)}}e.exports=t.default}(kt,kt.exports)),kt.exports}function Tt(){if(St)return jt;St=1,Object.defineProperty(jt,"__esModule",{value:!0}),jt.isAsyncIterable=jt.isAsyncGenerator=jt.isAsync=void 0;var e,t=It(),n=(e=t)&&e.__esModule?e:{default:e};function o(e){return"AsyncFunction"===e[Symbol.toStringTag]}return jt.default=function(e){if("function"!=typeof e)throw new Error("expected a function");return o(e)?(0,n.default)(e):e},jt.isAsync=o,jt.isAsyncGenerator=function(e){return"AsyncGenerator"===e[Symbol.toStringTag]},jt.isAsyncIterable=function(e){return"function"==typeof e[Symbol.asyncIterator]},jt}var Ft,At,Ut,Nt={exports:{}},Rt={exports:{}};function Dt(){return Ft||(Ft=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});t.default={},e.exports=t.default}(Rt,Rt.exports)),Rt.exports}function Ct(){return Ut||(Ut=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){return at||(at=1,e=ut,t=ut.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){function t(...t){if(null!==e){var n=e;e=null,n.apply(this,t)}}return Object.assign(t,e),t},e.exports=t.default),ut.exports;var e,t}(),o=u(n),s=u(wt()),r=function(){return bt||(bt=1,e=$t,t=$t.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return function(...t){if(null===e)throw new Error("Callback was already called.");var n=e;e=null,n.apply(this,t)}},e.exports=t.default),$t.exports;var e,t}(),a=u(r),i=Tt(),c=(At||(At=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,s){let r=!1,a=!1,i=!1,c=0,l=0;function d(){c>=t||i||r||(i=!0,e.next().then(({value:e,done:t})=>{if(!a&&!r){if(i=!1,t)return r=!0,void(c<=0&&s(null));c++,n(e,l,u),l++,d()}}).catch(f))}function u(e,t){if(c-=1,!a)return e?f(e):!1===e?(r=!0,void(a=!0)):t===o.default||r&&c<=0?(r=!0,s(null)):void d()}function f(e){a||(i=!1,r=!0,s(e))}d()};var n,o=(n=Dt())&&n.__esModule?n:{default:n};e.exports=t.default}(Nt,Nt.exports)),Nt.exports),l=u(c),d=u(Dt());function u(e){return e&&e.__esModule?e:{default:e}}t.default=e=>(t,n,r)=>{if(r=(0,o.default)(r),e<=0)throw new RangeError("concurrency limit cannot be less than 1");if(!t)return r(null);if((0,i.isAsyncGenerator)(t))return(0,l.default)(t,e,n,r);if((0,i.isAsyncIterable)(t))return(0,l.default)(t[Symbol.asyncIterator](),e,n,r);var c=(0,s.default)(t),u=!1,f=!1,p=0,g=!1;function y(e,t){if(!f)if(p-=1,e)u=!0,r(e);else if(!1===e)u=!0,f=!0;else{if(t===d.default||u&&p<=0)return u=!0,r(null);g||h()}}function h(){for(g=!0;p<e&&!u;){var t=c();if(null===t)return u=!0,void(p<=0&&r(null));p+=1,n(t.value,t.key,(0,a.default)(y))}g=!1}h()},e.exports=t.default}(dt,dt.exports)),dt.exports}var Pt,Bt={exports:{}};var Mt,Kt,Lt,qt={exports:{}};function zt(){return Mt||(Mt=1,e=qt,t=qt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(t||(t=e.length),!t)throw new Error("arity is undefined");return function(...n){return"function"==typeof n[t-1]?e.apply(this,n):new Promise((o,s)=>{n[t-1]=(e,...t)=>{if(e)return s(e);o(t.length>1?t:t[0])},e.apply(this,n)})}},e.exports=t.default),qt.exports;var e,t}function Jt(){return Kt||(Kt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=i(Ct()),o=function(){return Pt||(Pt=1,e=Bt,t=Bt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return(t,n,o)=>e(t,o)},e.exports=t.default),Bt.exports;var e,t}(),s=i(o),r=i(Tt()),a=i(zt());function i(e){return e&&e.__esModule?e:{default:e}}t.default=(0,a.default)(function(e,t,o,a){return(0,n.default)(t)(e,(0,s.default)((0,r.default)(o)),a)},4),e.exports=t.default}(lt,lt.exports)),lt.exports}var Vt=b((Lt||(Lt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=s(Jt()),o=s(zt());function s(e){return e&&e.__esModule?e:{default:e}}t.default=(0,o.default)(function(e,t,o){return(0,n.default)(e,1,t,o)},3),e.exports=t.default}(ct,ct.exports)),ct.exports));const Wt=oe("commands:etl:setup-local-run"),Yt=e=>{if(e instanceof Error){const t={message:e.message,name:e.name,stack:e.stack};return e.response&&(t.response={status:e.response.status,statusText:e.response.statusText,data:e.response.data}),Object.keys(e).forEach(n=>{t[n]||(t[n]=e[n])}),t}return e},Gt="setup-local-run <jobroot>",Qt=async(e,t,n,o)=>{let s=p(),r=Q(`Scanning for downloadable files (${e})`);!o&&s.start(Q(`In progress: ${r}...`,"secondary"));try{const a={Bucket:e,Prefix:n};let i,c=[],l=!0,d=0;for(;l;){d+=1;const e={...a};i&&(e.ContinuationToken=i);const n=await t.listObjectsV2(e).promise();Wt(`Page ${d} response:`,{keyCount:n.Contents?.length||0,isTruncated:n.IsTruncated,hasNextToken:!!n.NextContinuationToken}),n.Contents&&n.Contents.length>0&&(c=c.concat(n.Contents)),l=!0===n.IsTruncated,i=n.NextContinuationToken,!o&&d>1&&(s.text=Q(`In progress: ${r}... (found ${c.length} files so far)`,"secondary"))}return Wt("Total files found:",c.length,"across",d,"pages"),0===c.length?(o||(s.fail(Q(`Error: ${r}.`,"secondary")),Z(Q(`Message: ${Q("Nothing to download!")}`,"secondary"))),[]):(c.forEach(n=>{n.BucketName=e,n.S3Instance=t}),!o&&s.succeed(Q(`Finished: ${r}. Found ${c.length} file${1!==c.length?"s":""}`,"secondary")),c)}catch(e){o?te({status:"error",error:Yt(e)}):(s.fail(Q(`Error: ${r}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Wt(e),e&&e.response&&e.response.data&&Wt("response",e.response.data)),process.exit(1)}},Ht=async(e,n,o,s,r)=>{let i=p(),c=Q("Creating .env file");!r&&i.start(Q(`In progress: ${c}...`,"secondary"));try{let d={TENANT:n.tenant??"",FLOW:n.flow_id??"",ENV_ID:n.env_id??"",JOB_ID:n.job_id??"",API_URL:"https://api.hotglue.com",JOB_ROOT:n.s3_root??"",ROOT_DIR:o,JOB_TYPE:n.job_type??"",CONNECTOR_ID:n.connector_id??"",TAP:n.tap??"",TARGET:n.target??""};if(s&&(d.API_KEY=e.api_key),!(null==(l=e.custom_env_vars)||Array.isArray(l)&&0===l.length))for(const t of e.custom_env_vars)d[t.name]=t.value;const u=t.resolve(o,".env");await a.writeFile(u,Object.entries(d).map(([e,t])=>`${e}=${t}`).join("\n")),!r&&i.succeed(Q(`Finished: ${c}.`,"secondary"))}catch(e){r?te({status:"error",error:Yt(e)}):(i.fail(Q(`Error: ${c}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Wt(e),e&&e.response&&e.response.data&&Wt("response",e.response.data)),process.exit(1)}var l};var Zt=Object.freeze({__proto__:null,builder:async e=>(Wt("builder",Gt),e.option("downloadTo",{...ue.downloadTo.config,default:"."}).option("overwrite",{...ue.overwrite.config,default:!1}).option("include-configs",{...ue.includeConfigs.config,default:!1})),command:Gt,desc:"Setup job data to run ETL locally",handler:async n=>{Wt("handler",Gt,n);let{hg:o,json:s,apikey:r,env:i,jobroot:c,downloadTo:d,overwrite:u,includeConfigs:g}=n;const{clientApiBaseUri:y}=o;let h;c.endsWith("/")&&(c=c.slice(0,-1));let m=p();const w="."!==d?t.resolve(process.cwd(),d):t.resolve(process.cwd());try{h=Q("Verifying user and authorizing"),!s&&m.start(Q(`In progress: ${h}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:d}=await ve({debug:Wt,baseUri:y,task:"job-download",env:i,apikey:r,jobroot:c}),b=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:d});!s&&m.succeed(Q(`Finished: ${h}.`,"secondary")),h=Q("Fetching environment config"),!s&&m.start(Q(`In progress: ${h}...`,"secondary"));const $=await je({debug:Wt,baseUri:y,env:i,apikey:r});!s&&m.succeed(Q(`Finished: ${h}.`,"secondary")),h=Q("Fetching job details"),!s&&m.start(Q(`In progress: ${h}...`,"secondary"));let v=null;try{const e=b.getObject({Bucket:i,Key:`${c}/job-details.json`}).createReadStream(),t=await we(e);v=JSON.parse(t)}catch(e){const t="No job with that jobroot found, job roots can be copied from the job page and are structured as tenant_id/flows/flow_id/jobs/YYYY/MM/DD/HH/MM/job_id";s?te({status:"error",error:t}):m.fail(Q(`Error: ${t}.`,"secondary")),process.exit(1)}!s&&m.succeed(Q(`Finished: ${h}.`,"secondary")),h=Q(`Fetching job files (${i})`),!s&&m.start(Q(`In progress: ${h}...`,"secondary"));let j=await Qt(i,b,c,s);!s&&m.succeed(Q(`Finished: ${h}.`,"secondary"));const k=$.cache_bucket_name;let _=null;if(k){let e,t;h=Q(`Found custom cache bucket (${k}). Setting up custom cache S3 instance...`);try{const n=await je({debug:Wt,baseUri:y,env:i,apikey:r,requestSecret:!0});e=n.cache_bucket_access_key_id,t=n.cache_bucket_secret_access_key}catch(e){const t="Insufficient permissions to access custom cache bucket";s?te({status:"error",error:t}):m.fail(Q(`Error: ${t}.`,"secondary")),process.exit(1)}!s&&m.start(Q(`In progress: ${h}...`,"secondary")),_=new l.S3({accessKeyId:e,secretAccessKey:t}),!s&&m.succeed(Q(`Finished: ${h}.`,"secondary"));let n=await Qt(k,_,c,s);j=[...j,...n]}h=Q("Filtering job files"),!s&&m.start(Q(`In progress: ${h}...`,"secondary"));const E=((e,t,n)=>{const o=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let s=[new RegExp(`${o}/snapshots/.*`),new RegExp(`${o}/etl-output/.*`),new RegExp(`${o}/sync-output/.*`),new RegExp(`${o}/catalog-selected\\.json`),new RegExp(`${o}/state\\.json`),new RegExp(`${o}/fieldMap\\.json`)];const r=new RegExp(`${o}/snapshots/tenant-config\\.json`);return n&&s.push(new RegExp(`${o}/([^/]+)-config\\.json`)),e.filter(({Key:e})=>!(!n&&r.test(e))&&s.some(t=>t.test(e)))})(j,c,g);if(!s&&m.succeed(Q(`Finished: ${h}.`,"secondary")),!s){const e=new f({head:["File","Size","LastModified"]});E.forEach(t=>{const n=t.Key.substring(c.length+1);e.push([n,t.Size,t.LastModified.toLocaleString("en-US")])}),console.log(e.toString())}const{downloadedFiles:x,skippedFiles:S}=await(async(n,o,s,r,i)=>{let c,l=p(),d=[],u=[];try{const f=o.length;let p=0;return await Vt(o,async o=>{p+=1;let g=o.Key.substring(n.length+1);g=g.replace(/^etl-output\//,"etl-output-reference/"),g=g.replace(/^catalog-selected\.json$/,"catalog.json"),g=g.replace(/^state\.json$/,"source-state.json"),c=Q(`Downloading ${g} (${p}/${f})`),!s&&l.start(Q(`In progress: ${c}...`,"secondary"));const y=t.resolve(r,g);if(Wt("file",y),e.existsSync(y)&&!i)return d.push(g),void(!s&&l.warn(Q(`Warning: ${g} already exists in the local directory. Skipping download.`,"secondary")));await a.mkdir(t.dirname(y),{recursive:!0});const h=o.S3Instance.getObject({Bucket:o.BucketName,Key:o.Key}).createReadStream(),m=e.createWriteStream(y,{flags:"w"});let w=0;return h.on("data",e=>{w+=e.length;const t=(w/o.Size*100).toFixed(2);!s&&(l.text=Q(`In progress: ${c} ${t}% complete (${(w/1024/1024).toFixed(2)} MB / ${(o.Size/1024/1024).toFixed(2)} MB)`,"secondary"))}),h.pipe(m),new Promise((t,n)=>{const o=async t=>{if(h.destroyed||h.destroy(),m.destroyed||m.destroy(),t&&e.existsSync(y))try{await a.unlink(y),Wt(`Cleaned up partial file: ${y}`)}catch(e){Wt(`Failed to delete partial file ${y}:`,e)}};m.on("finish",()=>{u.push(g),!s&&l.succeed(`Successfully downloaded to ${g}`),t()}),h.on("error",async e=>{!s&&l.fail(`Download failed: ${e.message}`),await o(e),n(e)}),m.on("error",async e=>{!s&&l.fail(`File system error: ${e.message}`),await o(e),n(e)})})}),c=Q("Downloading job files."),!s&&l.succeed(Q(`Finished: ${c}`,"secondary")),{downloadedFiles:u,skippedFiles:d}}catch(e){s?te({status:"error",error:Yt(e)}):(l.fail(Q(`Error: ${c}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Wt(e),e&&e.response&&e.response.data&&Wt("response",e.response.data)),process.exit(1)}})(c,E,s,w,u),O=v.tap,I=v.target,T=t.resolve(w,`${O}-config.json`),F=t.resolve(w,`${I}-config.json`);if(e.existsSync(T)){const e=T,n="source-config.json";h=Q(`Renaming ${e} to ${n}`),!s&&m.start(Q(`In progress: ${h}...`,"secondary")),await a.rename(e,t.resolve(w,n)),!s&&m.succeed(Q(`Finished: ${h}.`,"secondary"))}if(e.existsSync(F)){const e=F,n="target-config.json";h=Q(`Renaming ${e} to ${n}`),!s&&m.start(Q(`In progress: ${h}...`,"secondary")),await a.rename(e,t.resolve(w,n)),!s&&m.succeed(Q(`Finished: ${h}.`,"secondary"))}await(async(e,n,o)=>{let s=p(),r=Q("Creating state.json file");try{if(null!=e.state&&Object.keys(e.state).length>0){!o&&s.start(Q(`In progress: ${r}...`,"secondary"));const i=t.resolve(n,"state.json");await a.writeFile(i,JSON.stringify(e.state,null,2)),!o&&s.succeed(Q(`Finished: ${r}.`,"secondary"))}}catch(e){o?te({status:"error",error:Yt(e)}):(s.fail(Q(`Error: ${r}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Wt(e),e&&e.response&&e.response.data&&Wt("response",e.response.data)),process.exit(1)}})(v,w,s),await Ht($,v,w,g,s),s?te({status:"success",downloadedFiles:x,skippedFiles:S}):(h=Q("Setting up local job files."),m.succeed(Q(`Finished: ${h}`,"secondary")))}catch(e){s?te({status:"error",error:Yt(e)}):(m.fail(Q(`Error: ${h}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Wt(e),e&&e.response&&e.response.data&&Wt("response",e.response.data)),process.exit(1)}}});const Xt=[et,ot,it,Zt],en=oe("commands:etl"),tn="etl <action>";var nn=Object.freeze({__proto__:null,builder:async function(e){en("builder",tn);return(await pe(e)).command(Xt)},command:tn,desc:"Manage ETL scripts",handler:async function(e){en("handler",tn,e)}});const on=oe("commands:flows:list"),sn="list";var rn=Object.freeze({__proto__:null,builder:async e=>(on("builder",sn),e.option("tenant",{...ue.tenant.config})),command:sn,desc:"List flows",handler:async e=>{on("handler",sn,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e,{clientApiBaseUri:a}=t;let i,c=p();try{i=Q(`Retrieving ${r?`${Q(r,"info")} tenant's`:"the"} flows for environment: ${Q(s,"info")}`);const e=`${a}/${s}/flows/${r?`linked?user_id=${r}`:"supported"}`;on("requesting:",e),!n&&c.start(Q(`In progress: ${i}...`,"secondary"));const{data:t}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&c.succeed(Q(`Finished: ${i}.`,"secondary")),on("response-data",t),!t||0===t.length)return void(n?te([]):c.warn(Q(`Warning: ${Q("No flows for specified environment and tenant")}.`,"secondary")));if(n)te(t);else{const e=new f({head:["ID","Name","Flow Type","Taps","Targets","Connectors"]});t.sort((e,t)=>(e.name||"").localeCompare(t.name||"")),t.forEach(t=>{return e.push([t.id,t.name||"",2==t.version?"Bidirectional":t.type?"Target Flow":"Source Flow",(n=t.taps,null==n||Array.isArray(n)&&0===n.length?t.sources?t.sources:[]:t.taps).join("\n"),(t.targets?t.targets:[]).join("\n"),(t.connectors?t.connectors:[]).join("\n")]);var n}),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(c.fail(Q(`Error: ${i}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),on(e),e&&e.response&&e.response.data&&on("response",e.response.data)),process.exit(1)}}});const an=[rn],cn=oe("commands:flows"),ln="flows <action>";var dn=Object.freeze({__proto__:null,builder:async function(e){cn("builder",ln);return(await pe(e)).command(an)},command:ln,desc:"Manage flows",handler:async function(e){cn("handler",ln,e)}});const un=oe("commands:jobs:download"),fn="download <jobroot>";var pn=Object.freeze({__proto__:null,builder:async e=>(un("builder",fn),e.option("downloadTo",ue.downloadTo.config)),command:fn,desc:"Download Job files",handler:async n=>{un("handler",fn,n);const{hg:o,json:s,apikey:r,env:a,jobroot:i,downloadTo:c}=n,{clientApiBaseUri:d}=o;let u,g=p();try{u=Q("Verifying user and authorizing"),!s&&g.start(Q(`In progress: ${u}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:p}=await ve({debug:un,baseUri:d,task:"job-download",env:a,apikey:r,jobroot:i}),y=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:p});!s&&g.succeed(Q(`Finished: ${u}.`,"secondary")),u=Q("Scanning for downloadable files"),!s&&g.start(Q(`In progress: ${u}...`,"secondary"));const m={Bucket:a,Prefix:i},{Contents:w}=await y.listObjectsV2(m).promise();if(un("res",w),!w||0===w.length)return void(s?te({status:"error",error:"Nothing to download!"}):(g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q("Nothing to download!")}`,"secondary"))));if(!s&&g.succeed(Q(`Finished: ${u}.`,"secondary")),!s){const e=new f({head:["File","Size","LastModified"]});w.forEach(t=>{const n=t.Key.substring(i.length+1);e.push([n,t.Size,t.LastModified.toLocaleString("en-US")])}),console.log(e.toString())}const b=t.resolve(process.cwd(),c,t.basename(i));await Vt(w.filter(({Key:e})=>!new RegExp(`${i}/([^/]+)-config.json`).test(e)),async n=>{u=Q(`Downloading file: ${Q(n.Key,"info")}`),!s&&g.start(Q(`In progress: ${u}...`,"secondary"));const o=t.resolve(b,n.Key.substring(i.length+1));un("file",o),await h.mkdir(t.dirname(o),{recursive:!0});const r=y.getObject({Bucket:a,Key:n.Key}).createReadStream(),c=e.createWriteStream(o,{flags:"w"});r.pipe(c),!s&&g.succeed(Q(`Finished: ${u}.`,"secondary"))}),s?te({status:"success",downloadedFiles:w.map(({Key:e})=>e)}):(u=Q("Downloading job files."),g.succeed(Q(`Finished: ${u}`,"secondary")))}catch(e){s?te({status:"error",error:e}):(g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),un(e),e&&e.response&&e.response.data&&un("response",e.response.data)),process.exit(1)}}});const gn=(...e)=>{oe("commands:jobs:list")(...e)},yn="list";var hn=Object.freeze({__proto__:null,builder:async e=>(gn("builder",yn),e.option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText).option("tenant",{...ue.tenant.config,default:"default"}).option("count",ue.count.config)),command:yn,desc:"List jobs",handler:async e=>{gn("handler",yn,e);const{hg:t,json:n,apikey:o,env:s,flow:r,tenant:a,count:i}=e,{clientApiBaseUri:c}=t;let l,d=p();try{l=Q(`Retrieving jobs for environment: ${Q(s,"info")} flow: ${Q(r,"info")} tenant: ${Q(a,"info")}...`);const e=`${c}/${s}/${r}/${a}/jobs${i?`?count=${i}`:""}`;gn("requesting:",e),!n&&d.start(Q(`In progress: ${l}...`,"secondary"));const{data:t}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&d.succeed(Q(`Finished: ${l}.`,"secondary")),gn("response-data",t),!t||0===t.length)return void(n?te([]):d.warn(Q(`Warning: ${Q("No jobs for the specified environment, flow and tenant")}.`,"secondary")));if(n)te(t);else{const e=new f({head:["name","details"]});t.forEach(t=>e.push([t.job_name,JSON.stringify(t,void 0,2)])),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(d.fail(Q(`Error: ${l}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),gn(e),e&&e.response&&e.response.data&&gn("response",e.response.data)),process.exit(1)}}});const mn=(...e)=>{oe("commands:jobs:bulkRun")(...e)},wn="bulk-run";var bn=Object.freeze({__proto__:null,builder:async e=>(mn("builder",wn),e.option("file",{describe:"Path to JSON file containing array of jobs to run",type:"string",alias:["f"],demandOption:!0}).demandOption("file","Path to JSON file is required. Example: -f ./jobs.json")),command:wn,desc:"Run jobs in bulk",handler:async t=>{mn("handler",wn,t);const{hg:n,json:o,apikey:s,env:r,file:a}=t,{clientApiBaseUri:i}=n;let c,l=p();try{if(c=Q(`Reading jobs file: ${Q(a,"info")}`),!o&&l.start(Q(`In progress: ${c}...`,"secondary")),!e.existsSync(a))throw new Error(`File not found: ${a}`);const t=e.readFileSync(a,{encoding:"utf-8"}),n=JSON.parse(t);if(!Array.isArray(n))throw new Error("JSON file must contain an array of job objects");if(0===n.length)return void(o?te({status:"error",error:"No jobs found in file"}):l.warn(Q(`Warning: ${Q("No jobs found in file")}.`,"secondary")));for(let e=0;e<n.length;e++){const t=n[e];if(!t.flow)throw new Error(`Job at index ${e} is missing required field: flow`);if(!t.tenant)throw new Error(`Job at index ${e} is missing required field: tenant`)}!o&&l.succeed(Q(`Finished: ${c}.`,"secondary")),c=Q("Checking flow versions..."),!o&&l.start(Q(`In progress: ${c}...`,"secondary"));const d=[...new Set(n.map(e=>e.flow))],u={};await Promise.all(d.map(async e=>{try{const t=await Fe({debug:mn,baseUri:i,apikey:s,env:r,flow:e});u[e]=2===t?.version}catch(t){mn(`Error checking flow ${e}:`,t),u[e]=!1}})),!o&&l.succeed(Q(`Finished: ${c}.`,"secondary")),c=Q(`Running ${Q(n.length,"info")} job(s)...`),!o&&l.start(Q(`In progress: ${c}...`,"secondary"));const p=await Promise.all(n.map(async(e,t)=>{const{flow:n,tenant:o,...a}=e,c=u[n]||!1;try{const e=await(async({debug:e,baseUri:t,env:n,apikey:o,tenant:s,flow:r,...a})=>{const{isV2Flow:i=!1,...c}=a,l={"x-api-key":o},d=new URL(`${t}/${i?"v2/":""}${n}/${r}/${s}/jobs`).toString();e&&e("uri:",d);const{data:u}=await y.post(d,c,{headers:l});return u})({debug:mn,baseUri:i,env:r,apikey:s,tenant:o,flow:n,isV2Flow:c,...a});return{index:t,flow:n,tenant:o,ok:!0,response:e}}catch(e){let s;if(e.response){const t=e.response.status,n=e.response.statusText,o=e.response.data,r=e.message;mn("Error response:",{statusCode:t,statusText:n,message:r,data:o}),s={statusCode:t,statusText:n,message:r,data:o}}else e.request?(mn("Error: No response received",e.message),s={message:e.message,request:e.request}):(mn("Error:",e.message),s={message:e.message});return{index:t,flow:n,tenant:o,ok:!1,error:s}}}));if(!o&&l.succeed(Q(`Finished: ${c}.`,"secondary")),o)te(p);else{const e=new f({head:["Index","Flow","Tenant","Status","Response/Error"]});p.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow,t.tenant,n,o])}),console.log(e.toString());const t=p.filter(e=>e.ok).length,n=p.filter(e=>!e.ok).length;Z(Q(`Summary: ${Q(String(t),"info")} succeeded, ${Q(String(n),"error")} failed out of ${Q(String(p.length),"info")} total.`,"secondary"))}}catch(e){o?te({status:"error",error:e.message,stack:e.stack}):(l.fail(Q(`Error: ${c||"Failed to run jobs"}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),mn(e)),process.exit(1)}}});const $n=(...e)=>{oe("commands:jobs:bulkRetrigger")(...e)},vn="bulk-retrigger";var jn=Object.freeze({__proto__:null,builder:async e=>($n("builder",vn),e.option("file",{describe:"Path to JSON file containing array of jobRoots to retrigger",type:"string",alias:["f"],demandOption:!0}).demandOption("file","Path to JSON file is required. Example: -f ./jobRoots.json")),command:vn,desc:"Retrigger jobs in bulk",handler:async t=>{$n("handler",vn,t);const{hg:n,json:o,apikey:s,env:r,file:a}=t,{clientApiBaseUri:i}=n;let c,l=p();try{if(c=Q(`Reading jobRoots file: ${Q(a,"info")}`),!o&&l.start(Q(`In progress: ${c}...`,"secondary")),!e.existsSync(a))throw new Error(`File not found: ${a}`);const t=e.readFileSync(a,{encoding:"utf-8"}),n=JSON.parse(t);if(!Array.isArray(n))throw new Error("JSON file must contain an array of jobRoot strings");if(0===n.length)return void(o?te({status:"error",error:"No jobRoots found in file"}):l.warn(Q(`Warning: ${Q("No jobRoots found in file")}.`,"secondary")));for(let e=0;e<n.length;e++)if("string"!=typeof n[e])throw new Error(`JobRoot at index ${e} must be a string, got ${typeof n[e]}`);!o&&l.succeed(Q(`Finished: ${c}.`,"secondary"));const d={};for(const e of n){const t=e.split("/");if(t.length<3||"flows"!==t[1])throw new Error(`Invalid jobRoot format: ${e}. Expected format: {tenantId}/flows/{flowId}/...`);const n=t[0],o=t[2],s=`${n}/flows/${o}`;d[s]||(d[s]={tenant:n,flow:o,jobRoots:[]}),d[s].jobRoots.push(e)}const u=Object.keys(d);!o&&Z(Q(`Found ${Q(String(n.length),"info")} jobRoot(s) grouped into ${Q(String(u.length),"info")} tenant/flow group(s).`,"secondary"));const p=async(e,t,n,o=36e5)=>{const a=Date.now();for(;Date.now()-a<o;)try{const o=await Re({debug:$n,baseUri:i,env:r,apikey:s,flow:t,user_id:e,job_root:n}),a=o.status||o.state;if("JOB_COMPLETED"===a||"string"==typeof a&&a.endsWith("_FAILED"))return{completed:!0,status:a};await new Promise(e=>setTimeout(e,5e3))}catch(e){$n(`Error checking job status for ${n}:`,e),await new Promise(e=>setTimeout(e,5e3))}return{completed:!1,status:"TIMEOUT"}};c=Q(`Retriggering ${Q(String(n.length),"info")} job(s) across ${Q(String(u.length),"info")} group(s)...`),!o&&l.start(Q(`In progress: ${c}...`,"secondary"));const g=[];if(await Promise.all(u.map(async e=>{const t=d[e],{tenant:n,flow:a,jobRoots:c}=t,u=[];for(let e=0;e<c.length;e++){const t=c[e];try{const d=await Ue({debug:$n,baseUri:i,env:r,apikey:s,tenant:n,flow:a,job_root:t});if(e<c.length-1){o||(l.text=Q(`Waiting for job ${e+1}/${c.length} in group ${n}/${a} to complete...`,"secondary"));(await p(n,a,t)).completed||$n(`Warning: Job ${t} did not complete within timeout period`)}u.push({tenant:n,flow:a,jobRoot:t,ok:!0,response:d})}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;$n("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?($n("Error: No response received",e.message),o={message:e.message,request:e.request}):($n("Error:",e.message),o={message:e.message});u.push({tenant:n,flow:a,jobRoot:t,ok:!1,error:o})}}g.push(...u)})),!o&&l.succeed(Q(`Finished: ${c}.`,"secondary")),o)te(g);else{const e=new f({head:["Tenant","Flow","Job Root","Status","Response/Error"]});g.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.tenant||"N/A",t.flow||"N/A",t.jobRoot||"N/A",n,o])}),console.log(e.toString());const t=g.filter(e=>e.ok).length,n=g.filter(e=>!e.ok).length;Z(Q(`Summary: ${Q(String(t),"info")} succeeded, ${Q(String(n),"error")} failed out of ${Q(String(g.length),"info")} total.`,"secondary"))}}catch(e){o?te({status:"error",error:e.message,stack:e.stack}):(l.fail(Q(`Error: ${c||"Failed to retrigger jobs"}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),$n(e)),process.exit(1)}}});const kn=(...e)=>{oe("commands:jobs:bulkKill")(...e)},_n="bulk-kill";var En=Object.freeze({__proto__:null,builder:async e=>(kn("builder",_n),e.option("tenant-ids",{describe:"Comma-separated list of tenant IDs to filter by",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs to filter by",type:"string",alias:["flows"]}).option("reason",{describe:"Reason for killing the jobs",type:"string"})),command:_n,desc:"Kill jobs in bulk",handler:async e=>{kn("handler",_n,e);const{hg:t,json:n,apikey:o,env:s,tenantIds:r,flowIds:a,reason:i}=e,{clientApiBaseUri:c}=t;let l,d=p();try{const e="JOB_CREATED,SYNC_STARTED,SYNC_SUCCESS,ETL_STARTED,ETL_SUCCESS,EXPORT_STARTED";l=Q("Fetching running jobs..."),!n&&d.start(Q(`In progress: ${l}...`,"secondary"));const t=new Date,u=new Date(t);u.setMonth(t.getMonth()-1);const p=u.toISOString().split("T")[0],g=await Ae({debug:kn,baseUri:c,env:s,apikey:o,from:p,status:e,count:100});let h=g.jobs||[];const m=g.total||0;if(!n&&d.succeed(Q(`Found ${Q(m,"info")} job(s) with specified status.`,"secondary")),r){const e=r.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(h=h.filter(t=>{const n=t.tenant;return e.includes(n)}))}if(a){const e=a.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(h=h.filter(t=>{const n=t.flow_id;return e.includes(n)}))}if(0===h.length)return void(n?te({status:"info",message:"No jobs found matching the filters"}):d.warn(Q(`Warning: ${Q("No jobs found matching the specified filters")}.`,"secondary")));l=Q(`Killing ${Q(h.length,"info")} job(s)...`),!n&&d.start(Q(`In progress: ${l}...`,"secondary"));const w=await Promise.all(h.map(async(e,t)=>{const n=e.s3_root,r=e.flow_id,a=e.tenant;if(!n)return{index:t,flow:r,tenant:a,ok:!1,error:{message:"Job root (s3_root) not found in job data"}};try{const e=await(async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,reason:i,task_arn:c,skip_webhooks:l})=>{const d=new URL(`${t}/${n}/${o}/${s}/jobs/kill`);d.searchParams.set("job_root",a),i&&d.searchParams.set("reason",i),c&&d.searchParams.set("task_arn",c),l&&d.searchParams.set("skip_webhooks",!0===l?"true":"false");const u={"x-api-key":r},f=d.toString();e&&e("uri:",f);const{data:p}=await y.get(f,{headers:u});return p})({debug:kn,baseUri:c,env:s,apikey:o,flow:r,user_id:a,job_root:n,reason:i});return{index:t,flow:r,tenant:a,jobRoot:n,ok:!0,response:e}}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;kn("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?(kn("Error: No response received",e.message),o={message:e.message,request:e.request}):(kn("Error:",e.message),o={message:e.message});return{index:t,flow:r,tenant:a,jobRoot:n,ok:!1,error:o}}}));if(!n&&d.succeed(Q(`Finished: ${l}.`,"secondary")),n)te(w);else{const e=new f({head:["Index","Flow","Tenant","Job Root","Status","Response/Error"]});w.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow||"N/A",t.tenant||"N/A",t.jobRoot||"N/A",n,o])}),console.log(e.toString());const t=w.filter(e=>e.ok).length,n=w.filter(e=>!e.ok).length;Z(Q(`Summary: ${Q(String(t),"info")} succeeded, ${Q(String(n),"error")} failed out of ${Q(String(w.length),"info")} total.`,"secondary"))}}catch(e){n?te({status:"error",error:e.message,stack:e.stack}):(d.fail(Q(`Error: ${l||"Failed to kill jobs"}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),kn(e)),process.exit(1)}}});const xn=(...e)=>{oe("commands:jobs:bulkRollback")(...e)},Sn="bulk-rollback";var On=Object.freeze({__proto__:null,builder:async e=>(xn("builder",Sn),e.option("from-utc-iso",{describe:"Start date for job search (YYYY-MM-DD)",type:"string",alias:["from"],demandOption:!0}).demandOption("from-utc-iso","Date from is required. Example: --from-utc-iso 2024-01-01").option("to-utc-iso",{describe:"End date for job search (YYYY-MM-DD)",type:"string",alias:["to"],demandOption:!0}).demandOption("to-utc-iso","Date to is required. Example: --to-utc-iso 2024-01-31").option("tenant-ids",{describe:"Comma-separated list of tenant IDs to filter by",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs to filter by",type:"string",alias:["flows"]})),command:Sn,desc:"Rollback jobs in bulk",handler:async e=>{xn("handler",Sn,e);const{hg:t,json:n,apikey:o,env:s,fromUtcIso:r,toUtcIso:a,tenantIds:i,flowIds:c}=e,{clientApiBaseUri:l}=t;let d,u=p();try{if(10!==r.length){const e="Date from must be in YYYY-MM-DD format";n?te({status:"error",error:e}):u.fail(Q(`Error: ${e}`,"secondary")),process.exit(1)}if(10!==a.length){const e="Date to must be in YYYY-MM-DD format";n?te({status:"error",error:e}):u.fail(Q(`Error: ${e}`,"secondary")),process.exit(1)}const e=`${r}T00:00:00Z`,t=`${a}T23:59:59.999Z`;d=Q(`Fetching jobs from ${Q(r,"info")} to ${Q(a,"info")}...`),!n&&u.start(Q(`In progress: ${d}...`,"secondary"));const p=await Ae({debug:xn,baseUri:l,env:s,apikey:o,from:e,to:t,count:100});!n&&u.stop();let g=p.jobs||[];if(i){const e=i.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(g=g.filter(t=>{const n=t.tenant;return e.includes(n)}))}if(c){const e=c.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(g=g.filter(t=>{const n=t.flow_id||t.flowId||t.flow;return e.includes(n)}))}if(!n&&Z(Q(`Found ${Q(String(g.length),"info")} job(s) after filtering.`,"secondary")),0===g.length)return void(n?te({status:"info",message:"No jobs found matching the filters"}):u.warn(Q(`Warning: ${Q("No jobs found matching the specified filters")}.`,"secondary")));d=Q(`Rolling back ${Q(g.length,"info")} job(s)...`),!n&&u.start(Q(`In progress: ${d}...`,"secondary"));const h=await Promise.all(g.map(async(e,t)=>{const n=e.s3_root||e.s3Root||e.job_root||e.jobRoot,r=e.flow_id||e.flowId||e.flow,a=e.tenant||e.tenant_id||e.tenantId||e.user_id;let i=e.tap;if(!i&&e.taps&&Array.isArray(e.taps)&&e.taps.length>0&&(i=e.taps[0]),!i&&e.tap_name&&(i=e.tap_name),!i&&e.connector&&(i=e.connector),!n)return{index:t,flow:r,tenant:a,ok:!1,error:{message:"Job root (s3_root) not found in job data"}};if(!i)return{index:t,flow:r,tenant:a,jobRoot:n,ok:!1,error:{message:"Tap not found in job data"}};try{const e=await(async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,tap:i})=>{const c={"x-api-key":r},l=new URL(`${t}/${n}/${o}/${s}/jobs/rollback`).toString(),d={job_root:a,tap:i};e&&e("uri:",l),e&&e("body:",d);const{data:u}=await y.post(l,d,{headers:c});return u})({debug:xn,baseUri:l,env:s,apikey:o,flow:r,user_id:a,job_root:n,tap:i});return{index:t,flow:r,tenant:a,jobRoot:n,tap:i,ok:!0,response:e}}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;xn("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?(xn("Error: No response received",e.message),o={message:e.message,request:e.request}):(xn("Error:",e.message),o={message:e.message});return{index:t,flow:r,tenant:a,jobRoot:n,tap:i,ok:!1,error:o}}}));if(!n&&u.succeed(Q(`Finished: ${d}.`,"secondary")),n)te(h);else{const e=new f({head:["Index","Flow","Tenant","Job Root","Tap","Status","Response/Error"]});h.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow||"N/A",t.tenant||"N/A",t.jobRoot||"N/A",t.tap||"N/A",n,o])}),console.log(e.toString());const t=h.filter(e=>e.ok).length,n=h.filter(e=>!e.ok).length;Z(Q(`Summary: ${Q(String(t),"info")} succeeded, ${Q(String(n),"error")} failed out of ${Q(String(h.length),"info")} total.`,"secondary"))}}catch(e){n?te({status:"error",error:e.message,stack:e.stack}):(u.fail(Q(`Error: ${d||"Failed to rollback jobs"}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),xn(e)),process.exit(1)}}});const In=[pn,hn,bn,jn,En,On],Tn=oe("commands:jobs"),Fn="jobs <action>";var An=Object.freeze({__proto__:null,builder:async function(e){Tn("builder",Fn);return(await pe(e)).command(In)},command:Fn,desc:"Manage ETL jobs",handler:async function(e){Tn("handler",Fn,e)}});const Un=oe("commands:schedules:bulkUpdate"),Nn="bulk-update";var Rn=Object.freeze({__proto__:null,builder:async e=>(Un("builder",Nn),e.option("tenant-ids",{describe:"Comma-separated list of tenant IDs",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs",type:"string",alias:["flows"]}).option("status",{describe:'Schedule status: "enable" or "disable"',type:"string",choices:["enable","disable"]}).option("expression",{describe:"Cron schedule expression",type:"string"}).option("connector",{describe:"Filter by connector ID",type:"string"}).option("job-type",{describe:'Filter by job type: "read" or "write"',type:"string",choices:["read","write"]})),command:Nn,desc:"Update schedules in bulk",handler:async e=>{Un("handler",Nn,e);const{hg:t,json:n,apikey:o,env:s,tenantIds:r,flowIds:a,status:i,expression:c,connector:l,"job-type":d}=e,{clientApiBaseUri:u}=t;let g,h=p();try{if(!i&&!c){const e='Either "status" or "expression" must be provided';n?te({status:"error",error:e}):h.fail(Q(`Error: ${e}`,"secondary")),process.exit(1)}const e=r?r.split(",").map(e=>e.trim()).filter(Boolean):null,t=a?a.split(",").map(e=>e.trim()).filter(Boolean):null;g=Q(`Retrieving schedules for environment: ${Q(s,"info")}`),!n&&h.start(Q(`In progress: ${g}...`,"secondary"));const p=await(async({debug:e,baseUri:t,env:n,apikey:o,includeDisabled:s})=>{const r=new URL(`${t}/tenants/${n}/schedule`);r.searchParams.set("includeDisabled","true");const a={"x-api-key":o},i=r.toString();e&&e("uri:",i);const{data:c}=await y.get(i,{headers:a});return c})({debug:Un,baseUri:u,env:s,apikey:o,includeDisabled:!0});!n&&h.succeed(Q(`Finished: ${g}.`,"secondary")),Un("response-data",p);const m="string"==typeof p?JSON.parse(p):p;if(!m||0===m.length)return void(n?te({updated:0,schedules:[]}):h.warn(Q(`Warning: ${Q("No schedules found for the specified environment")}.`,"secondary")));let w=m.filter(n=>{if(e&&e.length>0&&!e.includes(n.tenantId))return!1;if(t&&t.length>0&&!t.includes(n.flowId))return!1;if(null!=l&&""!==l){if(n.connectorId!==l)return!1}else if(null!==n.connectorId&&void 0!==n.connectorId)return!1;return!d||n.jobType===d});if(0===w.length)return void(n?te({updated:0,schedules:[]}):h.warn(Q(`Warning: ${Q("No schedules match the specified filters")}.`,"secondary")));const b=w,$=i?"enable"===i?"ENABLED":"DISABLED":void 0;n||Z(Q(`Found ${Q(b.length.toString(),"info")} schedule(s) to update`,"secondary"));const v=20,j=[],k=[];for(let e=0;e<b.length;e+=v){const t=b.slice(e,e+v),s=Math.floor(e/v)+1,r=Math.ceil(b.length/v);g=Q(`Updating batch ${Q(`${s}/${r}`,"info")} (${t.length} schedule(s))`),!n&&h.start(Q(`In progress: ${g}...`,"secondary"));const a=t.map(async e=>{try{const t=c||e.expression,n=$||(e.isActive?"ENABLED":"DISABLED");if(!t)throw new Error("Schedule expression is required but not found");const s=await Ne({debug:Un,baseUri:u,env:e.envId,flow:e.flowId,user_id:e.tenantId,apikey:o,schedule_expression:t,state:n,job_type:e.jobType||d,connector_id:e.connectorId||l});return{success:!0,schedule:{envId:e.envId,flowId:e.flowId,tenantId:e.tenantId,connectorId:e.connectorId,jobType:e.jobType,expression:t,state:n},result:s}}catch(t){return Un("Error updating schedule:",t),{success:!1,schedule:{envId:e.envId,flowId:e.flowId,tenantId:e.tenantId,connectorId:e.connectorId,jobType:e.jobType},error:t.message||t.toString()}}});(await Promise.all(a)).forEach(e=>{e.success?j.push(e.schedule):k.push(e)}),!n&&h.succeed(Q(`Finished: ${g}.`,"secondary"))}if(n)te({total:b.length,updated:j.length,failed:k.length,schedules:j,errors:k});else if(Z(Q(`\nUpdated ${Q(j.length.toString(),"info")} schedule(s) successfully`,"secondary")),k.length>0&&Z(Q(`Failed to update ${Q(k.length.toString(),"error")} schedule(s)`,"secondary")),j.length>0||k.length>0){const e=new f({head:["Environment","Flow","Tenant","Connector","Job Type","Expression","State","Updated"]});j.forEach(t=>{e.push([t.envId,t.flowId,t.tenantId,t.connectorId||"N/A",t.jobType||"N/A",t.expression,t.state,"yes"])}),k.forEach(t=>{const n=t.schedule,o=b.find(e=>e.envId===n.envId&&e.flowId===n.flowId&&e.tenantId===n.tenantId&&e.connectorId===n.connectorId&&e.jobType===n.jobType);e.push([n.envId,n.flowId,n.tenantId,n.connectorId||"N/A",n.jobType||"N/A",o?.expression||"N/A",o?.isActive?"ENABLED":"DISABLED",`no: ${t.error}`])}),console.log("\n"+e.toString())}}catch(e){n?te({status:"error",error:e.message||e.toString()}):(h.fail(Q(`Error: ${g||"Failed to update schedules"}.`,"secondary")),Z(Q(`Message: ${Q(e.message||e.toString())}`,"secondary")),Un(e),e&&e.response&&e.response.data&&Un("response",e.response.data)),process.exit(1)}}});const Dn=[Rn],Cn=oe("commands:schedules"),Pn="schedules <action>";var Bn=Object.freeze({__proto__:null,builder:async function(e){Cn("builder",Pn);return(await pe(e)).command(Dn)},command:Pn,desc:"Manage schedules",handler:async function(e){Cn("handler",Pn,e)}});const Mn=oe("commands:snapshots:deploy"),Kn="deploy";var Ln=Object.freeze({__proto__:null,builder:async e=>(Mn("builder",Kn),e.option("tenant",{...ue.tenant.config,default:"default"}).option("sourceFolder",ue.sourceFolder.config).demandOption("sourceFolder",ue.sourceFolder.demandText)),command:Kn,desc:"Deploy Snapshots",handler:async e=>{Mn("handler",Kn,e);const{hg:n,json:o,apikey:s,env:r,tenant:i,sourceFolder:c}=e,{clientApiBaseUri:d}=n;let u,g=p();const y=t.resolve(process.cwd(),c);try{u=Q(`Deploying Snapshots for Tenant ${Q(i,"info")} to ${Q(r,"info")}`),!o&&g.info(Q(`Info: ${u}.`,"secondary"));const e=await he(y,{recursive:!0});if(0===e.length)return void(o?te({status:"error",error:"There are no files to deploy at the specified location!"}):g.fail(Q(`Error: ${Q("There are no files to deploy at the specified location!")}.`,"secondary")));u=Q("Verifying user and authorizing");const{accessKeyId:n,secretAccessKey:p,sessionToken:h}=await ve({debug:Mn,baseUri:d,task:"snapshot-deploy",env:r,tenant:i,apikey:s});!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));const m=new l.S3({accessKeyId:n,secretAccessKey:p,sessionToken:h});u=Q("Validating tenant exists"),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));try{const{CommonPrefixes:e}=await m.listObjectsV2({Bucket:r,Prefix:`${i}/`,Delimiter:"/"}).promise();if(0===e.length)throw new Error("Invalid tenant")}catch(e){throw Mn("err",e),new Error("Tenant doesn't exist. Please check your tenant (-u) argument.")}!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));const w=`${i}/snapshots/`,b=new f({head:["File","Status"]});u=Q("Preparing deployment target"),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const{Contents:$}=await m.listObjectsV2({Bucket:r,Prefix:`${w}`}).promise();!o&&g.stop(),Mn("contents",$),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const v=$.map(e=>({Key:e.Key}));if(v.length>0){const e={Bucket:r,Delete:{Objects:v,Quiet:!0}};await m.deleteObjects(e).promise(),v.forEach(({Key:e})=>b.push([e.substring(w.length),Q("Deleted","warn")]))}!o&&g.succeed(Q(`Finished: ${u}.`,"secondary"));for await(const n of e){const e=t.relative(c,n),s=`${w}${e}`;u=Q(`Deploying file: ${Q(e,"info")}`),!o&&g.start(Q(`In progress: ${u}...`,"secondary"));const i={Bucket:r,Key:s,Body:await a.readFile(n)},l=await m.putObject(i).promise();!o&&g.succeed(Q(`Finished: ${u}.`,"secondary")),Mn("s3-put-res",l),b.push([e,Q("Deployed","info")])}o?te({status:"success",deployedFiles:e}):H(b.toString())}catch(e){o?te({status:"error",error:e}):(g.fail(Q(`Error: ${u}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Mn(e),e&&e.response&&e.response.data&&Mn("response",e.response.data)),process.exit(1)}}});const qn=oe("commands:snapshots:download"),zn="download";var Jn=Object.freeze({__proto__:null,builder:async e=>(qn("builder",zn),e.option("downloadTo",ue.downloadTo.config).demandOption("downloadTo",ue.downloadTo.demandText).option("tenant",{...ue.tenant.config,default:"default"}).option("overwrite",ue.overwrite.config).demandOption("overwrite",ue.overwrite.demandText)),command:zn,desc:"Download Snapshots",handler:async n=>{qn("handler",zn,n);const{hg:o,json:s,apikey:r,env:i,tenant:c,downloadTo:d,overwrite:u}=n,{clientApiBaseUri:g}=o;let y,h=p();const m=t.resolve(process.cwd(),function(e){function t(e){return process.argv.indexOf(e)>-1}if(t(`--${e}`))return!0;const n=ue[e]?.config?.alias||[];for(let e in n)if(t(`-${n[e]}`))return!0;return!1}("downloadTo")?d:"snapshots");try{y=Q("Verifying user and authorizing"),!s&&h.start(Q(`In progress: ${y}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:d}=await ve({debug:qn,baseUri:g,task:"snapshot-download",env:i,tenant:c,apikey:r}),p=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:d});!s&&h.succeed(Q(`Finished: ${y}.`,"secondary")),y=Q("Validating tenant exists"),!s&&h.start(Q(`In progress: ${y}...`,"secondary"));try{const{CommonPrefixes:e}=await p.listObjectsV2({Bucket:i,Prefix:`${c}/`,Delimiter:"/"}).promise();if(0===e.length)throw new Error("Invalid tenant")}catch(e){throw qn("err",e),new Error("Tenant doesn't exist. Please check your tenant (-u) argument.")}!s&&h.succeed(Q(`Finished: ${y}.`,"secondary")),y=Q("Scanning for downloadable files"),!s&&h.start(Q(`In progress: ${y}...`,"secondary"));const w=`${c}/snapshots/`,b={Bucket:i,Prefix:w},{Contents:$}=await p.listObjectsV2(b).promise();!s&&h.succeed(Q(`Finished: ${y}.`,"secondary")),qn("s3-list-res",$);const v=$?$.map(e=>e.Key).filter(e=>e!==w):[];if(!v||0===v.length)return void(s?te({status:"success",downloadedFiles:[]}):h.warn(Q(`Warning: ${Q("Nothing to download!")}`,"secondary")));y=Q(`Downloading snapshot files to ${Q(m,"info")}`),!s&&h.info(Q(`Info: ${y}.`,"secondary"));const j=new f({head:["File","Status"]});for await(const n of v){const o=n.substring(w.length),r=t.resolve(m,o);if(qn("file",r),n.endsWith("/")){!e.existsSync(r)&&await a.mkdir(r,{recursive:!0});continue}if(!u)try{await a.stat(r),qn("exists, skipping"),j.push([o,"Skipped"]);continue}catch(e){"ENOENT"!==e.code&&H(e)}y=Q(`Downloading file: ${Q(o,"info")}`),!s&&h.start(Q(`In progress: ${y}...`,"secondary")),await a.mkdir(t.dirname(r),{recursive:!0});const c=p.getObject({Bucket:i,Key:n}).createReadStream();await a.writeFile(r,await we(c)),!s&&h.succeed(Q(`Finished: ${y}.`,"secondary")),j.push([o,"Downloaded"])}s?te({status:"success",downloadedFiles:v}):H(j.toString())}catch(e){s?te({status:"error",error:e}):(h.fail(Q(`Error: ${y}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),qn(e),e&&e.response&&e.response.data&&qn("response",e.response.data)),process.exit(1)}}});const Vn=[Ln,Jn],Wn=oe("commands:snapshots"),Yn="snapshots <action>";var Gn=Object.freeze({__proto__:null,builder:async function(e){Wn("builder",Yn,e);return(await pe(e)).command(Vn)},command:Yn,desc:"Manage tenant snapshots",handler:async function(e){Wn("handler",Yn,e)}});const Qn=oe("commands:tenants:custom-etl"),Hn="custom-etl",Zn=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,supportedSources:a})=>{const i=await xe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n});let c=null;for(const{tap:d}of[...i,...a]){const{accessKeyId:a,secretAccessKey:i,sessionToken:u}=await ve({debug:e,baseUri:t,task:"etl-download",env:o,tenant:r,flow:s,tap:d,apikey:n}),f=new l.S3({accessKeyId:a,secretAccessKey:i,sessionToken:u}),p={Bucket:o,Prefix:`${r}/flows/${s}/taps/${d}/etl/`},{Contents:g}=await f.listObjectsV2(p).promise();if(g.some(({Key:e})=>e.endsWith("etl.py")||e.endsWith("etl.ipynb"))&&(c=r),null!==c)break}return c};var Xn=Object.freeze({__proto__:null,builder:async e=>(Qn("builder",Hn),e.option("tenant",ue.tenant.config).option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText)),command:Hn,desc:"List tenants with custom ETL in a specific flow",handler:async e=>{Qn("handler",Hn,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=Q(`Retrieving tenants for environment ${Q(s,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([ke({debug:Qn,baseUri:t.clientApiBaseUri,apikey:o,env:s}),_e({debug:Qn,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]);!n&&i.succeed(Q(`Finished: ${a}.`,"secondary"));let l=[];a=Q(`Querying for custom ETL scripts for flow ${Q(r,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));for(const n of be(e)){const e=await Promise.all(n.map(e=>Zn({debug:Qn,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,supportedSources:c})));l=l.concat(e.filter(Boolean))}if(!n&&i.succeed(Q(`Finished: ${a}.`,"secondary")),n)te(l);else{const e=new f({head:["Tenant ID"]});e.push(...l.map(e=>[e])),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(i.fail(Q(`Error: ${a}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),Qn(e),e&&e.response&&e.response.data&&Qn("response",e.response.data)),process.exit(1)}}});const eo=oe("commands:tenants:custom-field-map"),to="custom-field-map",no=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,isV2Flow:a})=>{const i=a?await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}):await xe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}),c=[],{accessKeyId:d,secretAccessKey:u,sessionToken:f}=await ve({debug:e,baseUri:t,task:"field-map-download",env:o,tenant:r,flow:s,apikey:n}),p=new l.S3({accessKeyId:d,secretAccessKey:u,sessionToken:f});for(const{id:e,tap:t}of i){const n={Bucket:o,Key:`${r}/flows/${s}/${a?"connectors":"taps"}/${a?e:t}/fieldMap.json`};try{await p.headObject(n).promise(),c.push(a?e:t)}catch(e){}}return{tenant:r,connectors:c}};var oo=Object.freeze({__proto__:null,builder:async e=>(eo("builder",to),e.option("tenant",ue.tenant.config).option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText)),command:to,desc:"List tenants with custom field map in a specific flow",handler:async e=>{eo("handler",to,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=Q(`Retrieving tenants for environment ${Q(s,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([ke({debug:eo,baseUri:t.clientApiBaseUri,apikey:o,env:s}),Fe({debug:eo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]),l=2===c?.version;!n&&i.succeed(Q(`Finished: ${a}.`,"secondary"));const d=[];a=Q(`Querying for custom field maps for flow ${Q(r,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));for(const n of be(e)){const e=await Promise.all(n.map(e=>no({debug:eo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,isV2Flow:l})));d.push(...e.filter(({connectors:e})=>e.length>0))}if(!n&&i.succeed(Q(`Finished: ${a}.`,"secondary")),n)te(d);else{const e=new f({head:["Tenant ID","Connector IDs"]});e.push(...d.map(({tenant:e,connectors:t})=>[e,t.join(", ")])),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(i.fail(Q(`Error: ${a}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),eo(e),e&&e.response&&e.response.data&&eo("response",e.response.data)),process.exit(1)}}});const so=oe("commands:tenants:delete"),ro="delete";var ao=Object.freeze({__proto__:null,builder:async e=>(so("builder",ro),e.option("tenant",ue.tenant.config)),command:ro,desc:"Delete tenant",handler:async e=>{so("handler",ro,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e,{clientApiBaseUri:a}=t;let i,c=p();try{if("default"===r)throw new Error('It\'s not possible to delete "default" tenant!');i=Q(`Deleting tenant ${r} schedules`),!n&&c.start(Q(`In progress: ${i}...`,"secondary")),await(async({debug:e,baseUri:t,env:n,apikey:o,tenant:s})=>{const r={"x-api-key":o},a=new URL(`${t}/tenant/${n}/${s}?schedules_only=true`).toString();e&&e("uri:",a);const{data:i}=await y.delete(a,{headers:r});return i})({debug:so,baseUri:a,env:s,apikey:o,tenant:r}),!n&&c.succeed(Q(`Finished: ${i}.`,"secondary")),i=Q("Verifying user and authorizing"),!n&&c.start(Q(`In progress: ${i}...`,"secondary"));const{accessKeyId:e,secretAccessKey:t,sessionToken:d}=await ve({debug:so,baseUri:a,task:"tenant-delete",env:s,tenant:r,apikey:o});!n&&c.succeed(Q(`Finished: ${i}.`,"secondary"));const u=new l.S3({accessKeyId:e,secretAccessKey:t,sessionToken:d});for(i=Q(`Deleting tenant ${r} for environment ${Q(s,"info")}`),!n&&c.start(Q(`In progress: ${i}...`,"secondary"));;){const e=((await u.listObjectsV2({Bucket:s,Prefix:`${r}/`}).promise()).Contents||[]).map(({Key:e})=>({Key:e}));if(0===e.length)break;await u.deleteObjects({Bucket:s,Delete:{Objects:e}}).promise()}if(!n&&c.succeed(Q(`Finished: ${i}.`,"secondary")),n)te({statu:"success",tenantDeleted:r});else{const e=new f({head:["Tenant ID"]});e.push([r]),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(c.fail(Q(`Error: ${i}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),so(e),e&&e.response&&e.response.data&&so("response",e.response.data)),process.exit(1)}}});const io=oe("commands:tenants:list"),co="list";var lo=Object.freeze({__proto__:null,builder:async e=>(io("builder",co),e.option("tenant",ue.tenant.config)),command:co,desc:"List tenants",handler:async e=>{io("handler",co,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e;let a,i=p();try{a=Q(`Retrieving tenants for environment ${Q(s,"info")}`);const e=`${t.clientApiBaseUri}/tenants/${s}${r?`?tenant=${r}`:""}`;io("requesting:",e),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));const{data:c}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&i.succeed(Q(`Finished: ${a}.`,"secondary")),io("response-data",c),!c||0===c.length)return void(n?te([]):i.info(Q(`Info: ${Q("No tenants found in the specified environment")}.`,"secondary")));if(n)te(c);else{const e=new f({head:["tenant ID"]});e.push(...c.map(e=>[e])),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(i.fail(Q(`Error: ${a}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),io(e),e&&e.response&&e.response.data&&io("response",e.response.data)),process.exit(1)}}});const uo=oe("commands:tenants:custom-catalog"),fo="custom-catalog",po=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,isV2Flow:a})=>{try{const i=a?await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}):await xe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}),c=[],{accessKeyId:d,secretAccessKey:u,sessionToken:f}=await ve({debug:e,baseUri:t,task:"field-map-download",env:o,tenant:r,flow:s,apikey:n}),p=new l.S3({accessKeyId:d,secretAccessKey:u,sessionToken:f});for(const{id:e,tap:t}of i){const n={Bucket:o,Key:`${r}/flows/${s}/${a?"connectors":"taps"}/${a?e:t}/catalog.json`};try{await p.headObject(n).promise(),c.push(a?e:t)}catch(e){}}return{tenant:r,connectors:c}}catch(e){return console.error(e),{tenant:r,connectors:[]}}};var go=Object.freeze({__proto__:null,builder:async e=>(uo("builder",fo),e.option("tenant",ue.tenant.config).option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText)),command:fo,desc:"List tenants with custom catalog in a specific flow",handler:async e=>{uo("handler",fo,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=Q(`Retrieving tenants for environment ${Q(s,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([ke({debug:uo,baseUri:t.clientApiBaseUri,apikey:o,env:s}),Fe({debug:uo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]),l=2===c?.version;!n&&i.succeed(Q(`Finished: ${a}.`,"secondary"));const d=[];a=Q(`Querying for custom catalogs for flow ${Q(r,"info")}`),!n&&i.start(Q(`In progress: ${a}...`,"secondary"));for(const n of be(e)){const e=await Promise.all(n.map(e=>po({debug:uo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,isV2Flow:l})));d.push(...e.filter(({connectors:e})=>e.length>0))}if(!n&&i.succeed(Q(`Finished: ${a}.`,"secondary")),n)te(d);else{const e=new f({head:["Tenant ID","Connector IDs"]});e.push(...d.map(({tenant:e,connectors:t})=>[e,t.join(", ")])),console.log(e.toString())}}catch(e){n?te({status:"error",error:e}):(i.fail(Q(`Error: ${a}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),uo(e),e&&e.response&&e.response.data&&uo("response",e.response.data)),process.exit(1)}}});const yo=oe("commands:tenants:update-config"),ho="update-config",mo=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,connectorId:a,config:i,isV2Flow:c})=>{const l=c?"id":"tap";if(!(c?await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,config:!0}):await xe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,config:!0})).find(e=>e[l]===a))return null;const d=c?Ie:Oe;try{await d({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,connectorId:a,config:i})}catch(e){console.log(Q(`Error patching: ${r}. ${e}`,"secondary"))}return r};var wo=Object.freeze({__proto__:null,builder:async e=>(yo("builder",ho),e.option("flow",ue.flow.config).demandOption("flow",ue.flow.demandText).option("connector",ue.connector.config).demandOption("connector",ue.connector.demandText).option("configFilePath",ue.configFilePath.config).demandOption("configFilePath",ue.configFilePath.demandText)),command:ho,desc:"Update the config of a specific connector and flow for all tenants",handler:async t=>{yo("handler",ho,t);const{hg:n,json:o,apikey:s,env:r,flow:a,connector:i,configFilePath:c}=t;let l,d=p();try{if(!c)throw new Error("Config file path not provided");if(!c.endsWith(".json"))throw new Error("Config file must have .json extension");if(!e.existsSync(c))throw new Error("Config file not found");const t=JSON.parse(e.readFileSync(c,{encoding:"utf-8"}));l=Q(`Retrieving tenants for environment ${Q(r,"info")}`),!o&&d.start(Q(`In progress: ${l}...`,"secondary"));const[u,p]=await Promise.all([ke({debug:yo,baseUri:n.clientApiBaseUri,apikey:s,env:r}),Fe({debug:yo,baseUri:n.clientApiBaseUri,apikey:s,env:r,flow:a})]),g=2===p?.version;!o&&d.succeed(Q(`Finished: ${l}.`,"secondary"));const y=[];l=Q(`Updating config for connector ${Q(i,"info")} and flow ${Q(a,"info")}`),!o&&d.start(Q(`In progress: ${l}...`,"secondary"));for(const e of be(u)){const o=await Promise.all(e.map(e=>mo({debug:yo,baseUri:n.clientApiBaseUri,apikey:s,env:r,flow:a,tenant:e,connectorId:i,config:t,isV2Flow:g})));y.push(...o.filter(Boolean))}if(!o&&d.succeed(Q(`Finished: ${l}.`,"secondary")),o)te(y);else{const e=new f({head:["Tenant ID"]});y.forEach(t=>e.push([t])),console.log(e.toString())}}catch(e){o?te({status:"error",error:e}):(d.fail(Q(`Error: ${l}.`,"secondary")),Z(Q(`Message: ${Q(e.message)}`,"secondary")),yo(e),e&&e.response&&e.response.data&&yo("response",e.response.data)),process.exit(1)}}});const bo=[Xn,oo,ao,lo,go,wo],$o=oe("commands:tenants"),vo="tenants <action>";var jo=Object.freeze({__proto__:null,builder:async function(e){$o("builder",vo);return(await pe(e)).command(bo)},command:vo,desc:"Manage tenants",handler:async function(e){$o("handler",vo,e)}});const ko=oe("commands:singer:validate"),_o="validate",Eo=(e,t,n,o)=>{let s=o.type;Array.isArray(s)||(s=[s]);const r=s.filter(e=>"null"!==e)[0];if(!s.includes("null")||null!==n){if("string"===r&&"string"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type string.`);if("number"===r&&"number"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type number.`);if("boolean"===r&&"boolean"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type boolean.`);if("array"===r&&!Array.isArray(n))throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type array.`);if("object"===r&&"object"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type object.`)}},xo=(e,t,n)=>{const o=t.stream;if(!o)throw new Error("Schema record is missing stream name");if(!t.schema)throw new Error(`Schema record for ${o} is missing schema field`);if(e[o]){for(const n of t.key_properties)if(!e[o].keyProperties.includes(n))throw new Error(`Schema for ${o} has different key properties: ${e[o].keyProperties.join(", ")} and ${t.key_properties.join(", ")}`);const n=e[o].schema;((e,t,n)=>{for(const[o,s]of Object.entries(t.properties))if(n.properties[o]){const t=n.properties[o].type,r=s.type;if(t.length!=r.length||t.some(e=>!r.includes(e)))throw new Error(`Schema for ${e} has different typing for field ${o}: ${t} and ${r}`)}})(o,t.schema,n)}else e[o]={schema:t.schema,keyProperties:t.key_properties||[],keySet:new Set,count:0};return((e,t,n)=>{for(const[o,s]of Object.entries(t.properties)){let t=s.type;Array.isArray(t)||(t=[t]);const r=t.filter(e=>"null"!==e);if(r.length>1&&!n)throw new Error(`Schema for ${e} has multiple non-null types for field ${o}: ${r.join(", ")}`)}})(o,t.schema,n),e},So=(e,t,n)=>{const o=t.stream,s=t.record;if(!s)throw new Error("Record is missing record field");if("object"!=typeof s)throw new Error(`Record has invalid type ${typeof s} for record field. Expected type object.`);if(!o)throw new Error("Record record is missing stream name");if(!e[o])throw new Error(`Record was written for stream ${o} before schema row was written.`);const r=e[o].keyProperties;for(const t of r){if(!s[t])throw new Error(`Record for ${o} is missing key property ${t}`);e[o].keySet.add(s[t])}if(r.length>0&&!n){const t=m.createHash("sha256").update(r.map(e=>`${e}:${s[e]}`).join("")).digest("hex");if(e[o].keySet.has(t))throw new Error(`Duplicate record for ${o} with primary keys: ${r.map(e=>`${e}: ${s[e]}`).join(", ")}`);e[o].keySet.add(t)}((e,t,n)=>{for(const[o,s]of Object.entries(t)){const t=n.properties[o];if(!t)throw new Error(`Record for ${e} has unknown field ${o}`);Eo(e,o,s,t)}})(o,s,e[o].schema),e[o].count++},Oo=(e,t)=>{if(!t.value)throw new Error("State record is missing value");if("object"!=typeof t.value)throw new Error(`State record has invalid type ${typeof t.value} for value. Expected type object.`)},Io=async(t,n)=>{const o={},{allowDuplicateRecords:s,allowFuzzyTypes:r}=n;for await(const a of async function*(t){const n=e.createReadStream(t,{encoding:"utf8"});let o="";for await(const e of n){const t=(o+e).split("\n");o=t.pop();for(const e of t)e.trim()&&(yield JSON.parse(e))}o.trim()&&(yield JSON.parse(o))}(t))try{if(!a.type)throw new Error(`Singer row is missing type: ${JSON.stringify(a)}`);"SCHEMA"==a.type?xo(o,a,r):"RECORD"==a.type?So(o,a,s):"STATE"==a.type&&Oo(0,a)}catch(e){throw n.json?e.message=`${e.message}. Error occured on line: ${JSON.stringify(a)}.`:console.log(`Error occured on line: ${JSON.stringify(a)} \n `),e}return o};var To=Object.freeze({__proto__:null,builder:async e=>(ko("builder",_o),e.option("dataFilePath",{...ue.dataFilePath.config}).option("allowDuplicateRecords",{type:"boolean",default:!1,description:"Allow duplicate records"}).option("allowFuzzyTypes",{type:"boolean",default:!1,description:"Allow fields to have multiple non-null types"})),command:_o,desc:"Validate Singer data",handler:async t=>{ko("handler",_o,t);const{allowDuplicateRecords:n,allowFuzzyTypes:o,dataFilePath:s,json:r}=t,a={allowDuplicateRecords:n,allowFuzzyTypes:o,json:r};if(!s)throw new Error("Data file path is required");if(!e.existsSync(s))throw new Error(`Data file path ${s} does not exist`);try{const e=await Io(s,a);r?console.log(JSON.stringify({streams:Object.keys(e).map(t=>({stream:t,count:e[t].count}))},null,2)):console.log(`\n \nšŸŽ‰šŸŽ‰šŸŽ‰ Singer validation passed šŸŽ‰šŸŽ‰šŸŽ‰\n--------------------------------------\n\n${Object.keys(e).length} streams validated\n\nRecord count by stream:\n${Object.keys(e).map(t=>`\n ${t}: ${e[t].count}`).join("")}\n\n `)}catch(e){r?console.log(JSON.stringify({error:e.message},null,2)):console.log(`\n\n🚨🚨🚨 Singer validation failed 🚨🚨🚨\n--------------------------------------\n\n${e.message}\n\n `),process.exit(1)}}});const Fo=[To],Ao=oe("commands:singer"),Uo="singer <action>";var No=Object.freeze({__proto__:null,builder:async function(e){Ao("builder",Uo);return(await e).command(Fo)},command:Uo,desc:"Develop and test singer taps and targets",handler:async function(e){Ao("handler",Uo,e)}});const Ro=[de,Ge,nn,dn,An,Bn,Gn,jo,No];process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE="1";Y({});const Do=o(process.argv.slice(2));Do.usage(Q("Usage: $0 <command>")).command(Ro).demandCommand().alias("v","version").alias("h","help").string("_").strictCommands().epilogue(Q("For more information, visit https://docs.hotglue.xyz/docs/cli-overview")).wrap(Math.min(Do.terminalWidth(),90)).parse(process.argv.slice(I()+1),M);
34
+ */(e),s="string"==typeof e,r=function(e){const t=[],n=Object.create(null);let o=!0;Object.keys(e).forEach(function(n){t.push([].concat(e[n],n))});for(;o;){o=!1;for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){if(t[e].filter(function(e){return-1!==t[n].indexOf(e)}).length){t[e]=t[e].concat(t[n]),t.splice(n,1),o=!0;break}}}return t.forEach(function(e){const t=(e=e.filter(function(e,t,n){return n.indexOf(e)===t})).pop();void 0!==t&&"string"==typeof t&&(n[t]=e)}),n}(Object.assign(Object.create(null),n.alias)),a=Object.assign({"boolean-negation":!0,"camel-case-expansion":!0,"combine-arrays":!1,"dot-notation":!0,"duplicate-arguments-array":!0,"flatten-duplicate-arrays":!0,"greedy-arrays":!0,"halt-at-non-option":!1,"nargs-eats-options":!1,"negation-prefix":"no-","parse-numbers":!0,"parse-positional-numbers":!0,"populate--":!1,"set-placeholder-key":!1,"short-option-groups":!0,"strip-aliased":!1,"strip-dashed":!1,"unknown-options-as-args":!1},n.configuration),i=Object.assign(Object.create(null),n.default),c=n.configObjects||[],l=n.envPrefix,d=a["populate--"],u=d?"--":"_",f=Object.create(null),p=Object.create(null),g=n.__||A.format,y={aliases:Object.create(null),arrays:Object.create(null),bools:Object.create(null),strings:Object.create(null),numbers:Object.create(null),counts:Object.create(null),normalize:Object.create(null),configs:Object.create(null),nargs:Object.create(null),coercions:Object.create(null),keys:[]},h=/^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/,m=new RegExp("^--"+a["negation-prefix"]+"(.+)");[].concat(n.array||[]).filter(Boolean).forEach(function(e){const t="object"==typeof e?e.key:e,n=Object.keys(e).map(function(e){return{boolean:"bools",string:"strings",number:"numbers"}[e]}).filter(Boolean).pop();n&&(y[n][t]=!0),y.arrays[t]=!0,y.keys.push(t)}),[].concat(n.boolean||[]).filter(Boolean).forEach(function(e){y.bools[e]=!0,y.keys.push(e)}),[].concat(n.string||[]).filter(Boolean).forEach(function(e){y.strings[e]=!0,y.keys.push(e)}),[].concat(n.number||[]).filter(Boolean).forEach(function(e){y.numbers[e]=!0,y.keys.push(e)}),[].concat(n.count||[]).filter(Boolean).forEach(function(e){y.counts[e]=!0,y.keys.push(e)}),[].concat(n.normalize||[]).filter(Boolean).forEach(function(e){y.normalize[e]=!0,y.keys.push(e)}),"object"==typeof n.narg&&Object.entries(n.narg).forEach(([e,t])=>{"number"==typeof t&&(y.nargs[e]=t,y.keys.push(e))}),"object"==typeof n.coerce&&Object.entries(n.coerce).forEach(([e,t])=>{"function"==typeof t&&(y.coercions[e]=t,y.keys.push(e))}),void 0!==n.config&&(Array.isArray(n.config)||"string"==typeof n.config?[].concat(n.config).filter(Boolean).forEach(function(e){y.configs[e]=!0}):"object"==typeof n.config&&Object.entries(n.config).forEach(([e,t])=>{"boolean"!=typeof t&&"function"!=typeof t||(y.configs[e]=t)})),function(...e){e.forEach(function(e){Object.keys(e||{}).forEach(function(e){y.aliases[e]||(y.aliases[e]=[].concat(r[e]||[]),y.aliases[e].concat(e).forEach(function(t){if(/-/.test(t)&&a["camel-case-expansion"]){const n=F(t);n!==e&&-1===y.aliases[e].indexOf(n)&&(y.aliases[e].push(n),f[n]=!0)}}),y.aliases[e].concat(e).forEach(function(t){if(t.length>1&&/[A-Z]/.test(t)&&a["camel-case-expansion"]){const n=function(e,t){const n=e.toLowerCase();t=t||"-";let o="";for(let s=0;s<e.length;s++){const r=n.charAt(s),a=e.charAt(s);o+=r!==a&&s>0?`${t}${n.charAt(s)}`:a}return o}(t,"-");n!==e&&-1===y.aliases[e].indexOf(n)&&(y.aliases[e].push(n),f[n]=!0)}}),y.aliases[e].forEach(function(t){y.aliases[t]=[e].concat(y.aliases[e].filter(function(e){return t!==e}))}))})})}(n.key,r,n.default,y.arrays),Object.keys(i).forEach(function(e){(y.aliases[e]||[]).forEach(function(t){i[t]=i[e]})});let b=null;Object.keys(y.counts).find(e=>B(e,y.arrays)?(b=Error(g("Invalid configuration: %s, opts.count excludes opts.array.",e)),!0):!!B(e,y.nargs)&&(b=Error(g("Invalid configuration: %s, opts.count excludes opts.narg.",e)),!0));let w=[];const $=Object.assign(Object.create(null),{_:[]}),v={};for(let e=0;e<o.length;e++){const t=o[e],n=t.replace(/^-{3,}/,"---");let s,r,i,c,l,d;if("--"!==t&&K(t))j(t);else{if(n.match(/---+(=|$)/)){j(t);continue}if(t.match(/^--.+=/)||!a["short-option-groups"]&&t.match(/^-.+=/))c=t.match(/^--?([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&(B(c[1],y.arrays)?e=_(e,c[1],o,c[2]):!1!==B(c[1],y.nargs)?e=k(e,c[1],o,c[2]):E(c[1],c[2],!0));else if(t.match(m)&&a["boolean-negation"])c=t.match(m),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],E(r,!!B(r,y.arrays)&&[!1]));else if(t.match(/^--.+/)||!a["short-option-groups"]&&t.match(/^-[^-]+/))c=t.match(/^--?(.+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],B(r,y.arrays)?e=_(e,r,o):!1!==B(r,y.nargs)?e=k(e,r,o):(l=o[e+1],void 0===l||l.match(/^-/)&&!l.match(h)||B(r,y.bools)||B(r,y.counts)?/^(true|false)$/.test(l)?(E(r,l),e++):E(r,L(r)):(E(r,l),e++)));else if(t.match(/^-.\..+=/))c=t.match(/^-([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&E(c[1],c[2]);else if(t.match(/^-.\..+/)&&!t.match(h))l=o[e+1],c=t.match(/^-(.\..+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(r=c[1],void 0===l||l.match(/^-/)||B(r,y.bools)||B(r,y.counts)?E(r,L(r)):(E(r,l),e++));else if(t.match(/^-[^-]+/)&&!t.match(h)){i=t.slice(1,-1).split(""),s=!1;for(let n=0;n<i.length;n++){if(l=t.slice(n+2),i[n+1]&&"="===i[n+1]){d=t.slice(n+3),r=i[n],B(r,y.arrays)?e=_(e,r,o,d):!1!==B(r,y.nargs)?e=k(e,r,o,d):E(r,d),s=!0;break}if("-"!==l){if(/[A-Za-z]/.test(i[n])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(l)&&!1===B(l,y.bools)){E(i[n],l),s=!0;break}if(i[n+1]&&i[n+1].match(/\W/)){E(i[n],l),s=!0;break}E(i[n],L(i[n]))}else E(i[n],l)}r=t.slice(-1)[0],s||"-"===r||(B(r,y.arrays)?e=_(e,r,o):!1!==B(r,y.nargs)?e=k(e,r,o):(l=o[e+1],void 0===l||/^(-|--)[^-]/.test(l)&&!l.match(h)||B(r,y.bools)||B(r,y.counts)?/^(true|false)$/.test(l)?(E(r,l),e++):E(r,L(r)):(E(r,l),e++)))}else if(t.match(/^-[0-9]$/)&&t.match(h)&&B(t.slice(1),y.bools))r=t.slice(1),E(r,L(r));else{if("--"===t){w=o.slice(e+1);break}if(a["halt-at-non-option"]){w=o.slice(e);break}j(t)}}}function j(e){const t=I("_",e);"string"!=typeof t&&"number"!=typeof t||$._.push(t)}function k(e,t,n,o){let s,r=B(t,y.nargs);if(r="number"!=typeof r||isNaN(r)?1:r,0===r)return q(o)||(b=Error(g("Argument unexpected for: %s",t))),E(t,L(t)),e;let i=q(o)?0:1;if(a["nargs-eats-options"])n.length-(e+1)+i<r&&(b=Error(g("Not enough arguments following: %s",t))),i=r;else{for(s=e+1;s<n.length&&(!n[s].match(/^-[^0-9]/)||n[s].match(h)||K(n[s]));s++)i++;i<r&&(b=Error(g("Not enough arguments following: %s",t)))}let c=Math.min(i,r);for(!q(o)&&c>0&&(E(t,o),c--),s=e+1;s<c+e+1;s++)E(t,n[s]);return e+c}function _(e,t,n,o){let r=[],c=o||n[e+1];const l=B(t,y.nargs);if(B(t,y.bools)&&!/^(true|false)$/.test(c))r.push(!0);else if(q(c)||q(o)&&/^-/.test(c)&&!h.test(c)&&!K(c)){if(void 0!==i[t]){const e=i[t];r=Array.isArray(e)?e:[e]}}else{q(o)||r.push(O(t,o,!0));for(let o=e+1;o<n.length&&!(!a["greedy-arrays"]&&r.length>0||l&&"number"==typeof l&&r.length>=l)&&(c=n[o],!/^-/.test(c)||h.test(c)||K(c));o++)e=o,r.push(O(t,c,s))}return"number"==typeof l&&(l&&r.length<l||isNaN(l)&&0===r.length)&&(b=Error(g("Not enough arguments following: %s",t))),E(t,r),e}function E(e,t,n=s){if(/-/.test(e)&&a["camel-case-expansion"]){const t=e.split(".").map(function(e){return F(e)}).join(".");x(e,t)}const o=O(e,t,n),r=e.split(".");if(P($,r,o),y.aliases[e]&&y.aliases[e].forEach(function(e){const t=e.split(".");P($,t,o)}),r.length>1&&a["dot-notation"]&&(y.aliases[r[0]]||[]).forEach(function(t){let n=t.split(".");const s=[].concat(r);s.shift(),n=n.concat(s),(y.aliases[e]||[]).includes(n.join("."))||P($,n,o)}),B(e,y.normalize)&&!B(e,y.arrays)){[e].concat(y.aliases[e]||[]).forEach(function(e){Object.defineProperty(v,e,{enumerable:!0,get:()=>t,set(e){t="string"==typeof e?A.normalize(e):e}})})}}function x(e,t){y.aliases[e]&&y.aliases[e].length||(y.aliases[e]=[t],f[t]=!0),y.aliases[t]&&y.aliases[t].length||x(t,e)}function O(e,t,n){n&&(t=function(e){return"string"!=typeof e||"'"!==e[0]&&'"'!==e[0]||e[e.length-1]!==e[0]?e:e.substring(1,e.length-1)}(t)),(B(e,y.bools)||B(e,y.counts))&&"string"==typeof t&&(t="true"===t);let o=Array.isArray(t)?t.map(function(t){return I(e,t)}):I(e,t);return B(e,y.counts)&&(q(o)||"boolean"==typeof o)&&(o=U()),B(e,y.normalize)&&B(e,y.arrays)&&(o=Array.isArray(t)?t.map(e=>A.normalize(e)):A.normalize(t)),o}function I(e,t){if(!a["parse-positional-numbers"]&&"_"===e)return t;if(!B(e,y.strings)&&!B(e,y.bools)&&!Array.isArray(t)){(null!=(n=t)&&("number"==typeof n||!!/^0x[0-9a-f]+$/i.test(n)||!/^0[^.]/.test(n)&&/^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(n))&&a["parse-numbers"]&&Number.isSafeInteger(Math.floor(parseFloat(`${t}`)))||!q(t)&&B(e,y.numbers))&&(t=Number(t))}var n;return t}function T(e,t){Object.keys(e).forEach(function(n){const o=e[n],s=t?t+"."+n:n;"object"==typeof o&&null!==o&&!Array.isArray(o)&&a["dot-notation"]?T(o,s):(!C($,s.split("."))||B(s,y.arrays)&&a["combine-arrays"])&&E(s,o)})}function R(e,t){if(void 0===l)return;const n="string"==typeof l?l:"",o=A.env();Object.keys(o).forEach(function(s){if(""===n||0===s.lastIndexOf(n,0)){const r=s.split("__").map(function(e,t){return 0===t&&(e=e.substring(n.length)),F(e)});(t&&y.configs[r.join(".")]||!t)&&!C(e,r)&&E(r.join("."),o[s])}})}function D(e,t,n,o=!1){Object.keys(n).forEach(function(s){C(e,s.split("."))||(P(e,s.split("."),n[s]),o&&(p[s]=!0),(t[s]||[]).forEach(function(t){C(e,t.split("."))||P(e,t.split("."),n[s])}))})}function C(e,t){let n=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){n=n[e]||{}});const o=t[t.length-1];return"object"==typeof n&&o in n}function P(e,t,n){let o=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){e=N(e),"object"==typeof o&&void 0===o[e]&&(o[e]={}),"object"!=typeof o[e]||Array.isArray(o[e])?(Array.isArray(o[e])?o[e].push({}):o[e]=[o[e],{}],o=o[e][o[e].length-1]):o=o[e]});const s=N(t[t.length-1]),r=B(t.join("."),y.arrays),i=Array.isArray(n);let c=a["duplicate-arguments-array"];!c&&B(s,y.nargs)&&(c=!0,(!q(o[s])&&1===y.nargs[s]||Array.isArray(o[s])&&o[s].length===y.nargs[s])&&(o[s]=void 0)),n===U()?o[s]=U(o[s]):Array.isArray(o[s])?c&&r&&i?o[s]=a["flatten-duplicate-arrays"]?o[s].concat(n):(Array.isArray(o[s][0])?o[s]:[o[s]]).concat([n]):c||Boolean(r)!==Boolean(i)?o[s]=o[s].concat([n]):o[s]=n:void 0===o[s]&&r?o[s]=i?n:[n]:!c||void 0===o[s]||B(s,y.counts)||B(s,y.bools)?o[s]=n:o[s]=[o[s],n]}function B(e,t){const n=[].concat(y.aliases[e]||[],e),o=Object.keys(t),s=n.find(e=>o.includes(e));return!!s&&t[s]}function M(e){const t=Object.keys(y);return[].concat(t.map(e=>y[e])).some(function(t){return Array.isArray(t)?t.includes(e):t[e]})}function K(e){return a["unknown-options-as-args"]&&function(e){if(e=e.replace(/^-{3,}/,"--"),e.match(h))return!1;if(function(e){if(e.match(h)||!e.match(/^-[^-]+/))return!1;let t,n=!0;const o=e.slice(1).split("");for(let s=0;s<o.length;s++){if(t=e.slice(s+2),!M(o[s])){n=!1;break}if(o[s+1]&&"="===o[s+1]||"-"===t||/[A-Za-z]/.test(o[s])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(t)||o[s+1]&&o[s+1].match(/\W/))break}return n}(e))return!1;return!function(e,...t){return[].concat(...t).some(function(t){const n=e.match(t);return n&&M(n[1])})}(e,/^-+([^=]+?)=[\s\S]*$/,m,/^-+([^=]+?)$/,/^-+([^=]+?)-$/,/^-+([^=]+?\d+)$/,/^-+([^=]+?)\W+.*$/)}(e)}function L(e){return B(e,y.bools)||B(e,y.counts)||!(`${e}`in i)?(t=function(e){let t=S.BOOLEAN;return B(e,y.strings)?t=S.STRING:B(e,y.numbers)?t=S.NUMBER:B(e,y.bools)?t=S.BOOLEAN:B(e,y.arrays)&&(t=S.ARRAY),t}(e),{[S.BOOLEAN]:!0,[S.STRING]:"",[S.NUMBER]:void 0,[S.ARRAY]:[]}[t]):i[e];var t}function q(e){return void 0===e}return R($,!0),R($,!1),function(e){const t=Object.create(null);D(t,y.aliases,i),Object.keys(y.configs).forEach(function(n){const o=e[n]||t[n];if(o)try{let e=null;const t=A.resolve(A.cwd(),o),s=y.configs[n];if("function"==typeof s){try{e=s(t)}catch(t){e=t}if(e instanceof Error)return void(b=e)}else e=A.require(t);T(e)}catch(t){"PermissionDenied"===t.name?b=t:e[n]&&(b=Error(g("Invalid JSON config file: %s",o)))}})}($),void 0!==c&&c.forEach(function(e){T(e)}),D($,y.aliases,i,!0),function(e){let t;const n=new Set;Object.keys(e).forEach(function(o){if(!n.has(o)&&(t=B(o,y.coercions),"function"==typeof t))try{const s=I(o,t(e[o]));[].concat(y.aliases[o]||[],o).forEach(t=>{n.add(t),e[t]=s})}catch(e){b=e}})}($),a["set-placeholder-key"]&&function(e){y.keys.forEach(t=>{~t.indexOf(".")||void 0===e[t]&&(e[t]=void 0)})}($),Object.keys(y.counts).forEach(function(e){C($,e.split("."))||E(e,0)}),d&&w.length&&($[u]=[]),w.forEach(function(e){$[u].push(e)}),a["camel-case-expansion"]&&a["strip-dashed"]&&Object.keys($).filter(e=>"--"!==e&&e.includes("-")).forEach(e=>{delete $[e]}),a["strip-aliased"]&&[].concat(...Object.keys(r).map(e=>r[e])).forEach(e=>{a["camel-case-expansion"]&&e.includes("-")&&delete $[e.split(".").map(e=>F(e)).join(".")],delete $[e]}),{aliases:Object.assign({},y.aliases),argv:Object.assign(v,$),configuration:a,defaulted:Object.assign({},p),error:b,newAliases:Object.assign({},f)}}}({cwd:process.cwd,env:()=>D,format:s.format,normalize:t.normalize,resolve:t.resolve,require:t=>{if("undefined"!=typeof require)return require(t);if(t.match(/\.json$/))return JSON.parse(e.readFileSync(t,"utf8"));throw Error("only .json config files are supported in ESM")}});var C={fs:{readFileSync:e.readFileSync,writeFile:e.writeFile},format:s.format,resolve:t.resolve,exists:t=>{try{return e.statSync(t).isFile()}catch(e){return!1}}};let P;class B{constructor(e){e=e||{},this.directory=e.directory||"./locales",this.updateFiles="boolean"!=typeof e.updateFiles||e.updateFiles,this.locale=e.locale||"en",this.fallbackToLanguage="boolean"!=typeof e.fallbackToLanguage||e.fallbackToLanguage,this.cache=Object.create(null),this.writeQueue=[]}__(...e){if("string"!=typeof arguments[0])return this._taggedLiteral(arguments[0],...arguments);const t=e.shift();let n=function(){};return"function"==typeof e[e.length-1]&&(n=e.pop()),n=n||function(){},this.cache[this.locale]||this._readLocaleFile(),!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]=t,this._enqueueWrite({directory:this.directory,locale:this.locale,cb:n})):n(),P.format.apply(P.format,[this.cache[this.locale][t]||t].concat(e))}__n(){const e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),o=e.shift();let s=function(){};"function"==typeof e[e.length-1]&&(s=e.pop()),this.cache[this.locale]||this._readLocaleFile();let r=1===o?t:n;if(this.cache[this.locale][t]){r=this.cache[this.locale][t][1===o?"one":"other"]}!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]={one:t,other:n},this._enqueueWrite({directory:this.directory,locale:this.locale,cb:s})):s();const a=[r];return~r.indexOf("%d")&&a.push(o),P.format.apply(P.format,a.concat(e))}setLocale(e){this.locale=e}getLocale(){return this.locale}updateLocale(e){this.cache[this.locale]||this._readLocaleFile();for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.cache[this.locale][t]=e[t])}_taggedLiteral(e,...t){let n="";return e.forEach(function(e,o){const s=t[o+1];n+=e,void 0!==s&&(n+="%s")}),this.__.apply(this,[n].concat([].slice.call(t,1)))}_enqueueWrite(e){this.writeQueue.push(e),1===this.writeQueue.length&&this._processWriteQueue()}_processWriteQueue(){const e=this,t=this.writeQueue[0],n=t.directory,o=t.locale,s=t.cb,r=this._resolveLocaleFile(n,o),a=JSON.stringify(this.cache[o],null,2);P.fs.writeFile(r,a,"utf-8",function(t){e.writeQueue.shift(),e.writeQueue.length>0&&e._processWriteQueue(),s(t)})}_readLocaleFile(){let e={};const t=this._resolveLocaleFile(this.directory,this.locale);try{P.fs.readFileSync&&(e=JSON.parse(P.fs.readFileSync(t,"utf-8")))}catch(n){if(n instanceof SyntaxError&&(n.message="syntax error in "+t),"ENOENT"!==n.code)throw n;e={}}this.cache[this.locale]=e}_resolveLocaleFile(e,t){let n=P.resolve(e,"./",t+".json");if(this.fallbackToLanguage&&!this._fileExistsSync(n)&&~t.lastIndexOf("_")){const o=P.resolve(e,"./",t.split("_")[0]+".json");this._fileExistsSync(o)&&(n=o)}return n}_fileExistsSync(e){return P.exists(e)}}let M;try{M=r.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:w&&"SCRIPT"===w.tagName.toUpperCase()&&w.src||new URL("index.js",document.baseURI).href)}catch(e){M=process.cwd()}M.split("node_modules")[0]||process.cwd(),process.cwd,process.exit,process.nextTick,void 0!==process.stdout.columns&&process.stdout.columns,function(e,t){P=t;const n=new B(e);n.__.bind(n),n.__n.bind(n),n.setLocale.bind(n),n.getLocale.bind(n),n.updateLocale.bind(n),n.locale}({directory:t.resolve(M,"../../../locales"),updateFiles:!1},C);const K={hg:{appName:"hotglue",clientApiBaseUri:process.env.HOTGLUE_CLIENT_API_BASE_URI||"https://api.hotglue.com",defaultConfigFileName:"config.yaml"}},L={},q=()=>t.resolve(n.homedir(),`.${K.hg.appName}`,K.hg.defaultConfigFileName),z=async()=>{const{appName:e}=K.hg;try{return await i.cosmiconfig(e).load(q())||{}}catch(e){return{}}},J=async()=>{const{appName:e}=K.hg,t=i.cosmiconfig(e,{searchPlaces:[`${e}.yaml`,`.${e}.yaml`,`.${e}rc.yaml`,`.${e}rc.yml`,`.${e}rc`,`.${e}rc.json`,`.${e}rc.js`]});try{return await t.search()||{}}catch(e){throw console.log(e),new Error(`Malformed configuration file: ${e.message}`)}},V={primary:e=>c.whiteBright(e),secondary:e=>c.white(e),info:e=>c.green(e),warn:e=>c.yellow(e),error:e=>c.redBright(e),success:e=>c.greenBright(e)};let W=V,Y="primary";function G(e){return W={...V,...e},te}function Q(e){process.stdout.write(e)}const H=(e,t=Y)=>{if(!e)return"";if("string"==typeof e)return W[t]?W[t](e):W[Y](e);const n=s.inspect(e,{colors:!0});return W[t]?W[t](n):n};function Z(...e){return console.log(...e),te}function X(e,t){return Q(H(e,t)),Q("\n"),te}function ee(e,t){return Q(H(e,t)),te}const te={cl:Z,pr:X,pp:ee,setTheme:G,setDefault:function(e="primary"){return W[e]&&(Y=e),te}},ne=e=>{console.log(JSON.stringify(e))},oe=d("hotglue-cli");function se(e){return oe.extend(e)}const re=se("commands:config:set"),ae="set <setting> <value>";var ie=Object.freeze({__proto__:null,builder:async e=>(re("builder",ae,e),e.option("setting",{describe:"The configuration parameter you wish to set",type:"string"}).option("value",{describe:"The configuration parameter's value",type:"string"}),e),command:ae,desc:"Set configuration key-value pairs",handler:async e=>{re("handler",ae,e);const{json:n,setting:o,value:s}=e;if(["apikey"].includes(o))try{const e=await z();e&&e.config?!n&&ee("Updating profile config file..."):!n&&ee("Creating profile config file...");const r=e&&e.config?{...e.config,[o]:s}:{[o]:s},i=u.stringify(r),c=e&&e.filepath?e.filepath:q();await(async(e,n)=>{await a.mkdir(t.dirname(e),{recursive:!0}),await a.writeFile(e,n)})(c,i),n?ne({status:"success"}):ee("Done").pr()}catch(e){n?ne({status:"error",error:e}):console.log(e)}else n?ne({status:"error",error:"Invalid settings parameter"}):console.error("Invalid settings parameter")}});const ce=[ie],le=se("commands:config"),de="config [action]";var ue=Object.freeze({__proto__:null,builder:async function(e){return le("builder",de),e.command(ce)},command:de,desc:"Configure your hotglue CLI",handler:async function(e){le("handler",de,e);const{action:n}=e;if(!n)try{const e=await z();e.config&&0!==Object.keys(e.config).length||X("No profile configuration found. Run config set to configure the hotglue CLI.");const n=new f({head:["Setting","Value","Config File","Type"]});e.config&&Object.entries(e.config).forEach(([t,o])=>n.push([t,o,e.filepath,"Profile"]));const o=await J();o.config&&Object.entries(o.config).forEach(([e,s])=>n.push([e,s,t.relative(process.cwd(),o.filepath),"Project"])),n.length>0&&console.log(n.toString())}catch(e){throw console.log(e),e}}}),fe={env:{config:{describe:"Environment Id",type:"string",alias:["e"]},demandText:'The "env" parameter (Environment Id) is required. Either pass here using `-e [env_id]` or add an env property in your rc file.'},apikey:{config:{describe:"API key",type:"string",alias:["k"]},demandText:"API key is required. Either pass here using -k [key] or configure your profile using config set."},dataFilePath:{config:{describe:"Singer data file path",type:"string",alias:["data","data-file-path"],default:"data.singer"}},json:{config:{describe:"Makes the output format to be JSON",type:"boolean",default:!1},demandText:""},tenant:{config:{describe:"Tenant (user) ID",type:"string",alias:["u"]},demandText:"TenantId is required. You can pass it using -u [tenantId]."},flow:{config:{describe:"Flow ID",type:"string",alias:["f"]},demandText:"FlowId is required. You can pass it using -f [flow_id]."},tap:{config:{describe:"Tap name",type:"string",alias:["t"]},demandText:"Tap name is required. You can pass it using -t <tap_name>."},connector:{config:{describe:"Connector ID",type:"string",alias:["c"]},demandText:"Connector ID is required. You can pass it using -c <connector>."},all:{config:{describe:"Run command for all taps/connectors",type:"boolean",default:!1,alias:["a"]},demandText:'This "all" flag is required. You can pass it using -a or --all.'},jobroot:{config:{describe:"Job Root (S3 prefix)",type:"string",alias:["j"]},demandText:"JobRoot key is required. You can pass it using -j [job_root]."},count:{config:{describe:"Max returned records",type:"number"}},downloadTo:{config:{describe:"Download folder",default:".",type:"string",alias:["d"]},demandText:"A destination folder is required. You can pass it using -d [folder] and can be either relative from cwd or absolute."},sourceFolder:{config:{describe:"Source folder",type:"string",default:".",alias:["s"]},demandText:""},configFilePath:{config:{describe:"Config file path",type:"string",default:"./config.json",alias:["p"]},demandText:'Local path of the config (with .json extension). Example: "/home/hotglue/config.json"'},overwrite:{config:{describe:"Overwrite existing",type:"boolean",default:!1,alias:["o"]},demandText:""},cleanup:{config:{describe:"Clean up target prior to action",type:"boolean",default:!1,alias:["c"]},demandText:""},includeConfigs:{config:{describe:"Include configs in the download folder (source-config.json, target-config.json, tenant-config.json)",type:"boolean",default:!1},demandText:""}};const pe=se("base"),ge=async e=>{pe("builder");const t=await(async()=>{const e=await z(),t=await J();return{...L,...e.config,...t.config}})();return e.option("apikey",fe.apikey.config).option("env",fe.env.config).option("json",fe.json.config).config(t).demandOption(["env"],fe.env.demandText).demandOption(["apikey"],fe.apikey.demandText).strictCommands()},ye=se("utils.js"),he=async(e,n,o=[])=>{const{includeSymLinks:s,recursive:r,filter:i}=n,{matcher:c}=i,l=t.resolve(e),d=await a.readdir(l,{withFileTypes:!0});for(const e of d){const a=t.resolve(l,e.name);e.isSymbolicLink()&&!s||(!c||c(a)?e.isFile()?o.push(t.resolve(l,e.name)):e.isDirectory()&&r&&await he(t.resolve(l,e.name),n,o):ye("skip",a))}return o},me=async(e,t)=>{const n={includeSymLinks:!1,recursive:!1,filter:{},...t},{pattern:o}=n.filter;return o&&(n.filter.matcher=g.matcher(o,{dot:!0})),he(e,n)},be=(e,t)=>{ye("filter-in",e);const{pattern:n}={...t};let o=e;return n&&(o=g(o,n)),ye("filter-out",o),o};const we=e=>{const t=[];return new Promise((n,o)=>{e.on("error",o),e.on("data",e=>t.push(Buffer.from(e))),e.on("end",()=>n(Buffer.concat(t).toString("utf8")))})},$e=(e,t=10)=>{const n=[];for(let o=0;o<e.length;o+=t){const s=e.slice(o,o+t);n.push(s)}return n},ve=async({debug:e,baseUri:t,env:n,apiKey:o})=>{const s=new URL(`${t}/${n}/resetAvailableEntities`),{data:r}=await y.delete(s,{headers:{"x-api-key":o,"Content-type":"application/json"}});e({data:r})},je=async({debug:e,baseUri:t,task:n,env:o,apikey:s,...r})=>{const a=new URL(`${t}/credentials/${n}/${o}`);r&&Object.entries(r).forEach(([e,t])=>{a.searchParams.set(e,t)});const i=a.toString();e&&e("uri:",i);const{data:c}=await y.get(i,{headers:{"x-api-key":s}}),{accessKeyId:l,secretAccessKey:d,sessionToken:u}=c;return{accessKeyId:l,secretAccessKey:d,sessionToken:u}},ke=async({debug:e,baseUri:t,env:n,apikey:o,requestSecret:s=!1})=>{const r=new URL(`${t}/${n}/config`);s&&r.searchParams.set("secret","true");const a=r.toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:{"x-api-key":o}});return i},_e=async({debug:e,baseUri:t,env:n,apikey:o})=>{const s=`${t}/tenants/${n}`;e("requesting:",s);const{data:r}=await y.get(s,{headers:{"x-api-key":o}});return e("response-data",r),r},Ee=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/${o}/supportedSources`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},xe=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/v2/${n}/${o}/supportedConnectors`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},Se=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,config:a})=>{const i=new URL(`${t}/${n}/${o}/${s}/linkedSources`);a&&i.searchParams.set("config","true");const c={"x-api-key":r},l=i.toString();e&&e("uri:",l);const{data:d}=await y.get(l,{headers:c});return d},Oe=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,config:a})=>{const i=new URL(`${t}/v2/${n}/${o}/${s}/linkedConnectors`);a&&i.searchParams.set("config","true");const c={"x-api-key":r},l=i.toString();e&&e("uri:",l);const{data:d}=await y.get(l,{headers:c});return d},Ie=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,connectorId:a,config:i})=>{const c={"x-api-key":r},l=new URL(`${t}/${n}/${o}/${s}/linkedSources`).toString(),d={tap:a,config:i};e&&e("uri:",l);const{data:u}=await y.patch(l,d,{headers:c});return u},Te=async({debug:e,baseUri:t,env:n,flow:o,tenant:s,apikey:r,connectorId:a,config:i})=>{const c={"x-api-key":r},l=new URL(`${t}/v2/${n}/${o}/${s}/linkedConnectors`).toString(),d={connector_id:a,config:i};e&&e("uri:",l);const{data:u}=await y.patch(l,d,{headers:c});return u},Fe=async({debug:e,baseUri:t,env:n,apikey:o})=>{const s={"x-api-key":o},r=new URL(`${t}/${n}/flows/supported`).toString();e&&e("uri:",r);const{data:a}=await y.get(r,{headers:s});return a},Ae=async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/flows/${o}/supported`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i},Ue=async({debug:e,baseUri:t,env:n,apikey:o,from:s,to:r,count:a=1e4,...i})=>{const c={"x-api-key":o},l="string"==typeof a?parseInt(a,10):a;let d=[],u=0,f=1,p=!0;for(;p;){const o=new URL(`${t}/${n}/jobs`);o.searchParams.set("from",s),r&&o.searchParams.set("to",r),o.searchParams.set("count",l.toString()),o.searchParams.set("page",f.toString()),i&&Object.entries(i).forEach(([e,t])=>{null!=t&&"count"!==e&&"page"!==e&&o.searchParams.set(e,t)}),o.searchParams.set("include_export_details","false"),o.searchParams.set("skip_cache","true");const a=o.toString();e&&e(`Fetching page ${f}, uri:`,a);const{data:g}=await y.get(a,{headers:c});e&&e(`Page ${f} response:`,{jobsCount:g.jobs?.length||0,total:g.total||0});const h=g.jobs||[];d=d.concat(h),1===f&&(u=g.total||0),h.length<l?p=!1:f++}return e&&e(`Fetched ${d.length} jobs across ${f} page(s)`),{jobs:d,total:u}},Ne=async({debug:e,baseUri:t,env:n,apikey:o,tenant:s,flow:r,...a})=>{const i={"x-api-key":o},c=new URL(`${t}/${n}/${r}/${s}/jobs/retrigger`).toString(),l=a;e&&e("uri:",c),e&&e("payload:",l);const{data:d}=await y.post(c,l,{headers:i});return d},Re=async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,schedule_expression:a,state:i,job_type:c,connector_id:l,extra_args:d})=>{const u={"x-api-key":r},f=new URL(`${t}/${n}/${o}/${s}/jobs/schedule`).toString(),p={schedule_expression:a,state:i};c&&(p.job_type=c),l&&(p.connector_id=l),d&&Object.assign(p,d),e&&e("uri:",f),e&&e("body:",p);const{data:g}=await y.put(f,p,{headers:u});return g},De=async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,include_export_details:i=!1})=>{const c=new URL(`${t}/${n}/${o}/${s}/jobs/status`);c.searchParams.set("job_root",a),c.searchParams.set("include_export_details",i?"true":"false");const l={"x-api-key":r},d=c.toString();e&&e("uri:",d);const{data:u}=await y.get(d,{headers:l});return u},Ce=d("commands:env:validators"),Pe=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableSources.json must be an array of objects");const r=(await Promise.all(o.filter(e=>1==e.version).map(async e=>await Ee({debug:Ce,baseUri:t,env:s,flow:e.id,apikey:n})))).flat(),a=e.map(e=>{if(!e.tap)throw new Error(`Source ${JSON.stringify(e)} has no tap id`);return e.tap}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate source id(s) found in availableSources.json: ${i.join(", ")}. All sources must have a unique tap id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.tap));if(c.length>0)throw new Error(`Sources ${c.map(e=>e.label).join(", ")} are linked, but missing from your availableSources.json`)},Be=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableTargets.json must be an array of objects");const r=(await Promise.all(o.filter(e=>1==e.version).map(async e=>{const o=await(async({debug:e,baseUri:t,env:n,flow:o,apikey:s})=>{const r={"x-api-key":s},a=new URL(`${t}/${n}/${o}/supportedTargets`).toString();e&&e("uri:",a);const{data:i}=await y.get(a,{headers:r});return i})({debug:Ce,baseUri:t,env:s,flow:e.id,apikey:n});return o}))).flat(),a=e.map(e=>{if(!e.target)throw new Error(`Target ${JSON.stringify(e)} has no target id`);return e.target}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate target id(s) found in availableTargets.json: ${i.join(", ")}. All targets must have a unique target id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.target));if(c.length>0)throw new Error(`Targets ${c.map(e=>e.label).join(", ")} are linked, but missing from your availableTargets.json`)},Me=async(e,t,n,o,s)=>{if(!Array.isArray(e))throw new Error("availableConnectors.json must be an array of objects");const r=(await Promise.all(o.filter(e=>2==e.version).map(async e=>await xe({debug:Ce,baseUri:t,env:s,flow:e.id,apikey:n})))).flat(),a=e.map(e=>{if(!e.id)throw new Error(`Connector ${JSON.stringify(e)} has no id`);return e.id}),i=a.filter((e,t)=>a.indexOf(e)!==t);if(i.length>0)throw new Error(`Duplicate connector id(s) found in availableConnectors.json: ${i.join(", ")}. All connectors must have a unique id.`);const c=r.filter(e=>e.isForked&&!a.includes(e.id));if(c.length>0)throw new Error(`Connectors ${c.map(e=>e.id).join(", ")} are linked, but missing from your availableConnectors.json`)},Ke=se("commands:env:deploy"),Le="deploy";var qe=Object.freeze({__proto__:null,builder:async e=>(Ke("builder",Le),e.option("sourceFolder",fe.sourceFolder.config).demandOption("sourceFolder",fe.sourceFolder.demandText)),command:Le,desc:"Deploy Environment settings",handler:async e=>{Ke("handler",Le,e);const{hg:n,json:o,apikey:s,env:r,sourceFolder:i}=e,{clientApiBaseUri:c}=n,d=t.resolve(process.cwd(),i);let u,g=p();try{u=H(`Scanning ${H(d,"info")} for deployable files`),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const e=await me(d,{filter:{pattern:"((**/requirements.txt)|(**/availableSources.json)|(**/availableTargets.json)|(**/availableConnectors.json)|(**/customTaps.json))"}});if(0===e.length)return void(o?ne({status:"error",error:"There are no files to deploy at the specified location!"}):(g.fail(H(`Error: ${u}.`,"secondary")),X(H(`Message: ${H("There are no files to deploy at the specified location!")}`,"secondary"))));!o&&g.succeed(H(`Finished: ${u}.`,"secondary"));for(const t of e)if(t.endsWith(".json"))try{const e=await a.readFile(t,{encoding:"utf-8"});JSON.parse(e)}catch(e){throw new Error(`File ${t} is not a valid JSON: ${String(e)}`)}const n=await Fe({debug:Ke,baseUri:c,env:r,apikey:s});for(const t of e){if(t.endsWith("availableSources.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Pe(e,c,s,n,r)}if(t.endsWith("availableTargets.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Be(e,c,s,n,r)}if(t.endsWith("availableConnectors.json")){const e=JSON.parse(await a.readFile(t,{encoding:"utf-8"}));await Me(e,c,s,n,r)}}u=H("Verifying user and authorizing"),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const{accessKeyId:i,secretAccessKey:p,sessionToken:y}=await je({debug:Ke,baseUri:c,task:"env-deploy",env:r,apikey:s});!o&&g.succeed(H(`Finished: ${u}.`,"secondary"));const h=new l.S3({accessKeyId:i,secretAccessKey:p,sessionToken:y});u=H("Deploying environment files"),!o&&g.info(H(`Info: ${u}.`,"secondary"));const m="config/",b=new f({head:["File","Status"]});for await(const n of e){const e=t.basename(n);u=H(`Pushing file: ${H(e,"info")}`),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const i={Bucket:r,Key:`${m}${e}`,Body:await a.readFile(n)},l=await h.putObject(i).promise();!o&&g.succeed(H(`Finished: ${u}.`,"secondary")),Ke("s3-put-res",l),b.push([e,"Deployed"]),await ve({debug:Ke,baseUri:c,env:r,apiKey:s})}o?ne({status:"success",deployedFiles:e}):Z(b.toString())}catch(e){!o&&g.fail(H(`Error: ${u}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Ke(e),e&&e.response&&e.response.data&&Ke("response",e.response.data),process.exit(1)}}});const ze=se("commands:env:download"),Je="download";var Ve=Object.freeze({__proto__:null,builder:async e=>(ze("builder",Je),e.option("downloadTo",fe.downloadTo.config)),command:Je,desc:"Download Environment settings",handler:async n=>{ze("handler",Je,n);const{hg:o,json:s,apikey:r,env:i,downloadTo:c}=n,{clientApiBaseUri:d}=o,u=t.resolve(process.cwd(),c);let g,y=p();try{g=H("Verifying user and authorizing"),!s&&y.start(H(`In progress: ${g}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:c}=await je({debug:ze,baseUri:d,task:"env-download",env:i,apikey:r});!s&&y.succeed(H(`Finished: ${g}.`,"secondary"));const p=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:c});g=H(`Scanning environment ${H(i,"info")}`),!s&&y.start(H(`In progress: ${g}...`,"secondary"));const m={Bucket:i,Prefix:"config/"},{Contents:b}=await p.listObjectsV2(m).promise();!s&&y.succeed(H(`Finished: ${g}.`,"secondary")),ze("s3-files",b);const w=b?be(b.map(e=>e.Key),{pattern:"((*/requirements.txt)|(*/availableSources.json)|(*/availableTargets.json)|(*/availableConnectors.json)|(*/customTaps.json))"}):[];if(!w||0===w.length)return void(s?ne({status:"success",downloadedFiles:[]}):y.warn(H(`Warning: ${H("Nothing to download!")}`,"secondary")));g=H(`Downloading to ${H(u,"info")}`),!s&&y.info(H(`Info: ${g}.`,"secondary"));const $=new f({head:["File","Status"]});for await(const n of w){const o=t.basename(n),r=t.resolve(u,o);ze("local-file",r),await a.mkdir(t.dirname(r),{recursive:!0}),g=H(`Downloading file: ${H(o,"info")}`),!s&&y.start(H(`In progress: ${g}...`,"secondary"));const c=p.getObject({Bucket:i,Key:n}).createReadStream();await h.pipeline(c,e.createWriteStream(r)),!s&&y.succeed(H(`Finished: ${g}.`,"secondary")),$.push([o,"Downloaded"])}s?ne({status:"success",downloadedFiles:w}):Z($.toString())}catch(e){s?ne({status:"error",error:e}):(y.fail(H(`Error: ${g}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),ze(e),e&&e.response&&e.response.data&&ze("response",e.response.data)),process.exit(1)}}});const We=[qe,Ve],Ye=se("commands:env"),Ge="env <action>";var Qe=Object.freeze({__proto__:null,builder:async function(e){Ye("builder",Ge);return(await ge(e)).command(We)},command:Ge,desc:"Manage environment settings",handler:async function(e){Ye("handler",Ge,e)}});const He=async(e,t,n,o)=>{try{const s=e.getObject({Bucket:t,Key:`${n}/flows/${o}/flow.json`}).createReadStream(),r=await we(s);return 2===JSON.parse(r).version}catch(e){return!1}},Ze=async(e,t,n,o,s=void 0)=>s??await He(e,t,n,o)?"connectors":"taps",Xe=se("commands:etl:delete"),et="delete";var tt=Object.freeze({__proto__:null,builder:async e=>(Xe("builder",et),e.option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText).option("tap",fe.tap.config).demandOption("tap",fe.tap.demandText).option("tenant",{...fe.tenant.config}).demandOption("tenant",fe.tenant.demandText)),command:et,desc:"Delete ETL scripts",handler:async e=>{Xe("handler",et,e);const{hg:t,json:n,apikey:o,env:s,flow:r,tap:a,tenant:i}=e,{clientApiBaseUri:c}=t;let d,u=p();try{d=H(`Deleting ETL scripts for Tenant ${H(i,"info")} Flow ${H(r,"info")} and Tap ${H(a,"info")} to ${H(s,"info")}`),!n&&u.info(H(`Info: ${d}.`,"secondary")),d=H("Verifying user and authorizing"),!n&&u.start(H(`In progress: ${d}...`,"secondary"));const{accessKeyId:e,secretAccessKey:t,sessionToken:p}=await je({debug:Xe,baseUri:c,task:"etl-deploy",env:s,tenant:i,flow:r,tap:a,apikey:o}),g=new l.S3({accessKeyId:e,secretAccessKey:t,sessionToken:p});!n&&u.succeed(H(`Finished: ${d}.`,"secondary")),d=H("Deleting ETL scripts"),!n&&u.start(H(`In progress: ${d}...`,"secondary"));const y=`${i}/flows/${r}/${await Ze(g,s,i,r)}/${a}/etl/`,h=await g.listObjectsV2({Bucket:s,Prefix:y}).promise();if(Xe("s3-list-objects-res",h),h.Contents?.length>0){const e=await g.deleteObjects({Bucket:s,Delete:{Objects:h.Contents.map(e=>({Key:e.Key}))}}).promise();Xe("s3-list-objects-res",e)}const m=await g.deleteObject({Bucket:s,Key:y}).promise();if(Xe("s3-delete-object-res",m),!n&&u.succeed(H(`Finished: ${d}.`,"secondary")),h.Contents?.length>0){const e=new f({head:["File","Status"]});h.Contents.filter(({Key:e})=>e!==y).forEach(({Key:t})=>{const n=t.split("/"),o=n[n.length-1];e.push([o,H("Deleted","info")])}),n?ne({status:"success",deletedObjects:(h.Contents??[]).map(({Key:e})=>e)}):Z(e.toString())}else d=H("There was no file or folder to be deleted"),n?ne({status:"success",deletedObjects:[]}):u.info(H(`Info: ${d}.`,"secondary"))}catch(e){n?ne({status:"error",error:e}):(u.fail(H(`Error: ${d}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Xe(e),e&&e.response&&e.response.data&&Xe("response",e.response.data)),process.exit(1)}}});const nt=se("commands:etl:deploy"),ot="deploy";var st=Object.freeze({__proto__:null,builder:async e=>(nt("builder",ot),e.option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText).option("tap",fe.tap.config).option("all",fe.all.config).option("tenant",{...fe.tenant.config,default:"default"}).option("sourceFolder",fe.sourceFolder.config).demandOption("sourceFolder",fe.sourceFolder.demandText)),command:ot,desc:"Deploy ETL scripts",handler:async e=>{nt("handler",ot,e);const{hg:n,json:o,apikey:s,env:r,flow:i,tap:c,all:d,tenant:u,sourceFolder:g}=e,{clientApiBaseUri:y}=n;if(!d&&!c)throw new Error(`${fe.tap.demandText} Or you can pass the --all flag to run this command for all taps/connectors.`);let h,m=p();const b=t.resolve(process.cwd(),g);try{h=H(`Deploying script for Tenant ${H(u,"info")} Flow ${H(i,"info")}${c?` and Tap ${H(c,"info")}`:""} to ${H(r,"info")}`),!o&&m.info(H(`Info: ${h}.`,"secondary"));const e=await me(b,{recursive:!0,filter:{pattern:"!((**/sync-output)|(**/etl-output)|(**/snapshots))"}});if(0===e.length)return void(o?ne({status:"error",error:"There are no files to deploy at the specified location!"}):m.fail(H(`Error: ${H("There are no files to deploy at the specified location!")}.`,"secondary")));(e=>{const t=["config.json","source-config.json","target-config.json","catalog.json","target-catalog.json","state.json"],n=["sync-output","snapshots","etl-output",".venv"];for(const o of e){if(t.includes(o))throw new Error(`File ${o} is a reserved file name and cannot be used in the ETL script.`);const e=n.find(e=>o.startsWith(`${e}/`));if(e)throw new Error(`Directory ${e} is a reserved directory name and cannot be used in the ETL script.`)}})(e.map(e=>t.relative(g,e))),h=H("Verifying user and authorizing"),!o&&m.start(H(`In progress: ${h}...`,"secondary"));const n={debug:nt,baseUri:y,task:"etl-deploy",env:r,tenant:u,flow:i,apikey:s};c&&(n.tap=c);const{accessKeyId:d,secretAccessKey:p,sessionToken:w}=await je(n);!o&&m.succeed(H(`Finished: ${h}.`,"secondary"));const $=new l.S3({accessKeyId:d,secretAccessKey:p,sessionToken:w}),v=await He($,r,u,i);h=H("Validating flow and tap location"),!o&&m.start(H(`In progress: ${h}...`,"secondary"));const j=(await Fe({debug:nt,baseUri:y,apikey:s,env:r})).find(({id:e})=>e===i);let k=[];try{if("default"===u||j?.type){if(k=((v?await xe({debug:nt,baseUri:y,env:r,flow:i,apikey:s}):await Ee({debug:nt,baseUri:y,env:r,flow:i,apikey:s}))??[]).filter(e=>!c||e[v?"id":"tap"]===c),c&&0===k.length)throw new Error("Tap is not supported")}else{if(k=((v?await Oe({debug:nt,baseUri:y,env:r,flow:i,tenant:u,apikey:s}):await Se({debug:nt,baseUri:y,env:r,flow:i,tenant:u,apikey:s}))??[]).filter(e=>!c||e[v?"id":"tap"]===c),c&&0===k.length)throw new Error("Tap is not linked")}}catch(e){throw nt("err",e),new Error("Target location doesn't exist. Check your tenant, flow and tap arguments.")}!o&&m.succeed(H(`Finished: ${h}.`,"secondary"));const _=new f({head:["File","Status"]});for(const n of k){const s=n[v?"id":"tap"];h=H(`Preparing ${s} deployment target`),!o&&m.start(H(`In progress: ${h}...`,"secondary"));const c=`${u}/flows/${i}/${await Ze(null,null,null,null,v)}/${s}/etl/`,{Contents:l}=await $.listObjectsV2({Bucket:r,Prefix:`${c}`}).promise();!o&&m.succeed(H(`Finished: ${h}.`,"secondary")),nt("contents",l);const d=l.map(e=>({Key:e.Key}));if(d.length>0){h=H(`Removing old ${s} ETL files`),!o&&m.start(H(`In progress: ${h}...`,"secondary"));const e={Bucket:r,Delete:{Objects:d,Quiet:!0}};await $.deleteObjects(e).promise(),d.forEach(({Key:e})=>_.push([`${s}/${e.substring(c.length)}`,H("Deleted","warn")])),!o&&m.succeed(H(`Finished: ${h}.`,"secondary"))}for await(const n of e){const e="win32"===process.platform?t.relative(g,n).replace(/\\/g,"/"):t.relative(g,n),i=`${c}${e}`;h=H(`Deploying file: ${H(`${s}/${e}`,"info")}`),!o&&m.start(H(`In progress: ${h}...`,"secondary"));const l={Bucket:r,Key:i,Body:await a.readFile(n)},d=await $.putObject(l).promise();!o&&m.succeed(H(`Finished: ${h}.`,"secondary")),nt("s3-put-res",d),_.push([`${s}/${e}`,H("Deployed","info")])}}o?ne({status:"success",deployedFiles:e}):Z(_.toString())}catch(e){o?ne({status:"error",error:e}):(m.fail(H(`Error: ${h}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),nt(e),e&&e.response&&e.response.data&&nt("response",e.response.data)),process.exit(1)}}});const rt=se("commands:etl:download"),at="download";var it,ct=Object.freeze({__proto__:null,builder:async e=>(rt("builder",at),e.option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText).option("tap",fe.tap.config).demandOption("tap",fe.tap.demandText).option("downloadTo",fe.downloadTo.config).demandOption("downloadTo",fe.downloadTo.demandText).option("tenant",{...fe.tenant.config,default:"default"}).option("overwrite",fe.overwrite.config).demandOption("overwrite",fe.overwrite.demandText)),command:at,desc:"Download ETL scripts",handler:async n=>{rt("handler",at,n);const{hg:o,json:s,apikey:r,env:i,flow:c,tap:d,tenant:u,downloadTo:g,overwrite:y}=n,{clientApiBaseUri:m}=o;let b,w=p();const $=t.resolve(process.cwd(),g);try{b=H("Verifying user and authorizing"),!s&&w.start(H(`In progress: ${b}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:p}=await je({debug:rt,baseUri:m,task:"etl-download",env:i,tenant:u,flow:c,tap:d,apikey:r}),g=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:p});!s&&w.succeed(H(`Finished: ${b}.`,"secondary")),b=H("Scanning for downloadable files"),!s&&w.start(H(`In progress: ${b}...`,"secondary"));const v=`${u}/flows/${c}/${await Ze(g,i,u,c)}/${d}/etl/`,j={Bucket:i,Prefix:v},{Contents:k}=await g.listObjectsV2(j).promise();!s&&w.succeed(H(`Finished: ${b}.`,"secondary")),rt("s3-list-res",k);const _=k?be(k.map(e=>e.Key),{pattern:"!(.ipynb_checkpoints/*)"}):[];if(!_||0===_.length)return void(s?ne({status:"success",downloadedFiles:[]}):w.warn(H(`Warning: ${H("Nothing to download!")}`,"secondary")));b=H(`Downloading script files to ${H($,"info")}`),!s&&w.info(H(`Info: ${b}.`,"secondary"));const E=new f({head:["File","Status"]});for await(const n of _){const o=n.substring(v.length),r=t.resolve($,o);if(rt("file",r),n.endsWith("/")){!e.existsSync(r)&&await a.mkdir(r,{recursive:!0});continue}if(!y)try{await a.stat(r),rt("exists, skipping"),E.push([o,"Skipped"]);continue}catch(e){"ENOENT"!==e.code&&Z(e)}b=H(`Downloading file: ${H(o,"info")}`),!s&&w.start(H(`In progress: ${b}...`,"secondary")),await a.mkdir(t.dirname(r),{recursive:!0});const c=g.getObject({Bucket:i,Key:n}).createReadStream();await h.pipeline(c,e.createWriteStream(r)),!s&&w.succeed(H(`Finished: ${b}.`,"secondary")),E.push([o,"Downloaded"])}s?ne({status:"success",downloadedFiles:_}):Z(E.toString())}catch(e){s?ne({status:"error",error:e}):(w.fail(H(`Error: ${b}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),rt(e),e&&e.response&&e.response.data&&rt("response",e.response.data)),process.exit(1)}}}),lt={exports:{}},dt={exports:{}},ut={exports:{}},ft={exports:{}};var pt,gt={exports:{}},yt={exports:{}};var ht,mt,bt={exports:{}};function wt(){return mt||(mt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){if((0,o.default)(e))return function(e){var t=-1,n=e.length;return function(){return++t<n?{value:e[t],key:t}:null}}(e);var t=(0,r.default)(e);return t?function(e){var t=-1;return function(){var n=e.next();return n.done?null:(t++,{value:n.value,key:t})}}(t):(n=e,s=n?Object.keys(n):[],a=-1,i=s.length,function e(){var t=s[++a];return"__proto__"===t?e():a<i?{value:n[t],key:t}:null});var n,s,a,i};var n=function(){return pt||(pt=1,e=yt,t=yt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e&&"number"==typeof e.length&&e.length>=0&&e.length%1==0},e.exports=t.default),yt.exports;var e,t}(),o=a(n),s=function(){return ht||(ht=1,e=bt,t=bt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e[Symbol.iterator]&&e[Symbol.iterator]()},e.exports=t.default),bt.exports;var e,t}(),r=a(s);function a(e){return e&&e.__esModule?e:{default:e}}e.exports=t.default}(gt,gt.exports)),gt.exports}var $t,vt={exports:{}};var jt,kt={},_t={exports:{}},Et={exports:{}};var xt,St,Ot,It={};function Tt(){return St||(St=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){if((0,r.isAsync)(e))return function(...t){const n=t.pop();return i(e.apply(this,t),n)};return(0,o.default)(function(t,n){var o;try{o=e.apply(this,t)}catch(e){return n(e)}if(o&&"function"==typeof o.then)return i(o,n);n(null,o)})};var n=function(){return jt||(jt=1,e=Et,t=Et.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return function(...t){var n=t.pop();return e.call(this,t,n)}},e.exports=t.default),Et.exports;var e,t}(),o=a(n),s=a(function(){if(xt)return It;xt=1,Object.defineProperty(It,"__esModule",{value:!0}),It.fallback=s,It.wrap=r;var e,t=It.hasQueueMicrotask="function"==typeof queueMicrotask&&queueMicrotask,n=It.hasSetImmediate="function"==typeof setImmediate&&setImmediate,o=It.hasNextTick="object"==typeof process&&"function"==typeof process.nextTick;function s(e){setTimeout(e,0)}function r(e){return(t,...n)=>e(()=>t(...n))}return e=t?queueMicrotask:n?setImmediate:o?process.nextTick:s,It.default=r(e),It}()),r=Ft();function a(e){return e&&e.__esModule?e:{default:e}}function i(e,t){return e.then(e=>{c(t,null,e)},e=>{c(t,e&&(e instanceof Error||e.message)?e:new Error(e))})}function c(e,t,n){try{e(t,n)}catch(e){(0,s.default)(e=>{throw e},e)}}e.exports=t.default}(_t,_t.exports)),_t.exports}function Ft(){if(Ot)return kt;Ot=1,Object.defineProperty(kt,"__esModule",{value:!0}),kt.isAsyncIterable=kt.isAsyncGenerator=kt.isAsync=void 0;var e,t=Tt(),n=(e=t)&&e.__esModule?e:{default:e};function o(e){return"AsyncFunction"===e[Symbol.toStringTag]}return kt.default=function(e){if("function"!=typeof e)throw new Error("expected a function");return o(e)?(0,n.default)(e):e},kt.isAsync=o,kt.isAsyncGenerator=function(e){return"AsyncGenerator"===e[Symbol.toStringTag]},kt.isAsyncIterable=function(e){return"function"==typeof e[Symbol.asyncIterator]},kt}var At,Ut,Nt,Rt={exports:{}},Dt={exports:{}};function Ct(){return At||(At=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});t.default={},e.exports=t.default}(Dt,Dt.exports)),Dt.exports}function Pt(){return Nt||(Nt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=function(){return it||(it=1,e=ft,t=ft.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){function t(...t){if(null!==e){var n=e;e=null,n.apply(this,t)}}return Object.assign(t,e),t},e.exports=t.default),ft.exports;var e,t}(),o=u(n),s=u(wt()),r=function(){return $t||($t=1,e=vt,t=vt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return function(...t){if(null===e)throw new Error("Callback was already called.");var n=e;e=null,n.apply(this,t)}},e.exports=t.default),vt.exports;var e,t}(),a=u(r),i=Ft(),c=(Ut||(Ut=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n,s){let r=!1,a=!1,i=!1,c=0,l=0;function d(){c>=t||i||r||(i=!0,e.next().then(({value:e,done:t})=>{if(!a&&!r){if(i=!1,t)return r=!0,void(c<=0&&s(null));c++,n(e,l,u),l++,d()}}).catch(f))}function u(e,t){if(c-=1,!a)return e?f(e):!1===e?(r=!0,void(a=!0)):t===o.default||r&&c<=0?(r=!0,s(null)):void d()}function f(e){a||(i=!1,r=!0,s(e))}d()};var n,o=(n=Ct())&&n.__esModule?n:{default:n};e.exports=t.default}(Rt,Rt.exports)),Rt.exports),l=u(c),d=u(Ct());function u(e){return e&&e.__esModule?e:{default:e}}t.default=e=>(t,n,r)=>{if(r=(0,o.default)(r),e<=0)throw new RangeError("concurrency limit cannot be less than 1");if(!t)return r(null);if((0,i.isAsyncGenerator)(t))return(0,l.default)(t,e,n,r);if((0,i.isAsyncIterable)(t))return(0,l.default)(t[Symbol.asyncIterator](),e,n,r);var c=(0,s.default)(t),u=!1,f=!1,p=0,g=!1;function y(e,t){if(!f)if(p-=1,e)u=!0,r(e);else if(!1===e)u=!0,f=!0;else{if(t===d.default||u&&p<=0)return u=!0,r(null);g||h()}}function h(){for(g=!0;p<e&&!u;){var t=c();if(null===t)return u=!0,void(p<=0&&r(null));p+=1,n(t.value,t.key,(0,a.default)(y))}g=!1}h()},e.exports=t.default}(ut,ut.exports)),ut.exports}var Bt,Mt={exports:{}};var Kt,Lt,qt,zt={exports:{}};function Jt(){return Kt||(Kt=1,e=zt,t=zt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){if(t||(t=e.length),!t)throw new Error("arity is undefined");return function(...n){return"function"==typeof n[t-1]?e.apply(this,n):new Promise((o,s)=>{n[t-1]=(e,...t)=>{if(e)return s(e);o(t.length>1?t:t[0])},e.apply(this,n)})}},e.exports=t.default),zt.exports;var e,t}function Vt(){return Lt||(Lt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=i(Pt()),o=function(){return Bt||(Bt=1,e=Mt,t=Mt.exports,Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return(t,n,o)=>e(t,o)},e.exports=t.default),Mt.exports;var e,t}(),s=i(o),r=i(Ft()),a=i(Jt());function i(e){return e&&e.__esModule?e:{default:e}}t.default=(0,a.default)(function(e,t,o,a){return(0,n.default)(t)(e,(0,s.default)((0,r.default)(o)),a)},4),e.exports=t.default}(dt,dt.exports)),dt.exports}var Wt=$((qt||(qt=1,function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=s(Vt()),o=s(Jt());function s(e){return e&&e.__esModule?e:{default:e}}t.default=(0,o.default)(function(e,t,o){return(0,n.default)(e,1,t,o)},3),e.exports=t.default}(lt,lt.exports)),lt.exports));const Yt=se("commands:etl:setup-local-run"),Gt=e=>{if(e instanceof Error){const t={message:e.message,name:e.name,stack:e.stack};return e.response&&(t.response={status:e.response.status,statusText:e.response.statusText,data:e.response.data}),Object.keys(e).forEach(n=>{t[n]||(t[n]=e[n])}),t}return e},Qt="setup-local-run <jobroot>",Ht=async(e,t,n,o)=>{let s=p(),r=H(`Scanning for downloadable files (${e})`);!o&&s.start(H(`In progress: ${r}...`,"secondary"));try{const a={Bucket:e,Prefix:n};let i,c=[],l=!0,d=0;for(;l;){d+=1;const e={...a};i&&(e.ContinuationToken=i);const n=await t.listObjectsV2(e).promise();Yt(`Page ${d} response:`,{keyCount:n.Contents?.length||0,isTruncated:n.IsTruncated,hasNextToken:!!n.NextContinuationToken}),n.Contents&&n.Contents.length>0&&(c=c.concat(n.Contents)),l=!0===n.IsTruncated,i=n.NextContinuationToken,!o&&d>1&&(s.text=H(`In progress: ${r}... (found ${c.length} files so far)`,"secondary"))}return Yt("Total files found:",c.length,"across",d,"pages"),0===c.length?(o||(s.fail(H(`Error: ${r}.`,"secondary")),X(H(`Message: ${H("Nothing to download!")}`,"secondary"))),[]):(c.forEach(n=>{n.BucketName=e,n.S3Instance=t}),!o&&s.succeed(H(`Finished: ${r}. Found ${c.length} file${1!==c.length?"s":""}`,"secondary")),c)}catch(e){o?ne({status:"error",error:Gt(e)}):(s.fail(H(`Error: ${r}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Yt(e),e&&e.response&&e.response.data&&Yt("response",e.response.data)),process.exit(1)}},Zt=async(e,n,o,s,r)=>{let i=p(),c=H("Creating .env file");!r&&i.start(H(`In progress: ${c}...`,"secondary"));try{let d={TENANT:n.tenant??"",FLOW:n.flow_id??"",ENV_ID:n.env_id??"",JOB_ID:n.job_id??"",API_URL:"https://api.hotglue.com",API_KEY:s,JOB_ROOT:n.s3_root??"",ROOT_DIR:o,JOB_TYPE:n.job_type??"",CONNECTOR_ID:n.connector_id??"",TAP:n.tap??"",TARGET:n.target??""};if(!(null==(l=e.custom_env_vars)||Array.isArray(l)&&0===l.length))for(const t of e.custom_env_vars)d[t.name]=t.value;const u=t.resolve(o,".env");await a.writeFile(u,Object.entries(d).map(([e,t])=>`${e}=${t}`).join("\n")),!r&&i.succeed(H(`Finished: ${c}.`,"secondary"))}catch(e){r?ne({status:"error",error:Gt(e)}):(i.fail(H(`Error: ${c}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Yt(e),e&&e.response&&e.response.data&&Yt("response",e.response.data)),process.exit(1)}var l};var Xt=Object.freeze({__proto__:null,builder:async e=>(Yt("builder",Qt),e.option("downloadTo",{...fe.downloadTo.config,default:"."}).option("overwrite",{...fe.overwrite.config,default:!1}).option("include-configs",{...fe.includeConfigs.config,default:!1})),command:Qt,desc:"Setup job data to run ETL locally",handler:async n=>{Yt("handler",Qt,n);let{hg:o,json:s,apikey:r,env:i,jobroot:c,downloadTo:d,overwrite:u,includeConfigs:g}=n;const{clientApiBaseUri:y}=o;let h;c.endsWith("/")&&(c=c.slice(0,-1));let m=p();const b="."!==d?t.resolve(process.cwd(),d):t.resolve(process.cwd());try{h=H("Verifying user and authorizing"),!s&&m.start(H(`In progress: ${h}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:d}=await je({debug:Yt,baseUri:y,task:"job-download",env:i,apikey:r,jobroot:c}),w=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:d});!s&&m.succeed(H(`Finished: ${h}.`,"secondary")),h=H("Fetching environment config"),!s&&m.start(H(`In progress: ${h}...`,"secondary"));const $=await ke({debug:Yt,baseUri:y,env:i,apikey:r});!s&&m.succeed(H(`Finished: ${h}.`,"secondary")),h=H("Fetching job details"),!s&&m.start(H(`In progress: ${h}...`,"secondary"));let v=null;try{const e=w.getObject({Bucket:i,Key:`${c}/job-details.json`}).createReadStream(),t=await we(e);v=JSON.parse(t)}catch(e){const t="No job with that jobroot found, job roots can be copied from the job page and are structured as tenant_id/flows/flow_id/jobs/YYYY/MM/DD/HH/MM/job_id";s?ne({status:"error",error:t}):m.fail(H(`Error: ${t}.`,"secondary")),process.exit(1)}!s&&m.succeed(H(`Finished: ${h}.`,"secondary")),h=H(`Fetching job files (${i})`),!s&&m.start(H(`In progress: ${h}...`,"secondary"));let j=await Ht(i,w,c,s);!s&&m.succeed(H(`Finished: ${h}.`,"secondary"));const k=$.cache_bucket_name;let _=null;if(k){let e,t;h=H(`Found custom cache bucket (${k}). Setting up custom cache S3 instance...`);try{const n=await ke({debug:Yt,baseUri:y,env:i,apikey:r,requestSecret:!0});e=n.cache_bucket_access_key_id,t=n.cache_bucket_secret_access_key}catch(e){const t="Insufficient permissions to access custom cache bucket";s?ne({status:"error",error:t}):m.fail(H(`Error: ${t}.`,"secondary")),process.exit(1)}!s&&m.start(H(`In progress: ${h}...`,"secondary")),_=new l.S3({accessKeyId:e,secretAccessKey:t}),!s&&m.succeed(H(`Finished: ${h}.`,"secondary"));let n=await Ht(k,_,c,s);j=[...j,...n]}h=H("Filtering job files"),!s&&m.start(H(`In progress: ${h}...`,"secondary"));const E=((e,t,n)=>{const o=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let s=[new RegExp(`${o}/snapshots/.*`),new RegExp(`${o}/etl-output/.*`),new RegExp(`${o}/sync-output/.*`),new RegExp(`${o}/catalog-selected\\.json`),new RegExp(`${o}/state\\.json`),new RegExp(`${o}/fieldMap\\.json`)];const r=new RegExp(`${o}/snapshots/tenant-config\\.json`);return n&&s.push(new RegExp(`${o}/([^/]+)-config\\.json`)),e.filter(({Key:e})=>!(!n&&r.test(e))&&s.some(t=>t.test(e)))})(j,c,g);if(!s&&m.succeed(H(`Finished: ${h}.`,"secondary")),!s){const e=new f({head:["File","Size","LastModified"]});E.forEach(t=>{const n=t.Key.substring(c.length+1);e.push([n,t.Size,t.LastModified.toLocaleString("en-US")])}),console.log(e.toString())}const{downloadedFiles:x,skippedFiles:S}=await(async(n,o,s,r,i)=>{let c,l=p(),d=[],u=[];try{const f=o.length;let p=0;return await Wt(o,async o=>{p+=1;let g=o.Key.substring(n.length+1);g=g.replace(/^etl-output\//,"etl-output-reference/"),g=g.replace(/^catalog-selected\.json$/,"catalog.json"),g=g.replace(/^state\.json$/,"source-state.json"),c=H(`Downloading ${g} (${p}/${f})`),!s&&l.start(H(`In progress: ${c}...`,"secondary"));const y=t.resolve(r,g);if(Yt("file",y),e.existsSync(y)&&!i)return d.push(g),void(!s&&l.warn(H(`Warning: ${g} already exists in the local directory. Skipping download.`,"secondary")));await a.mkdir(t.dirname(y),{recursive:!0});const h=o.S3Instance.getObject({Bucket:o.BucketName,Key:o.Key}).createReadStream(),m=e.createWriteStream(y,{flags:"w"});let b=0;return h.on("data",e=>{b+=e.length;const t=(b/o.Size*100).toFixed(2);!s&&(l.text=H(`In progress: ${c} ${t}% complete (${(b/1024/1024).toFixed(2)} MB / ${(o.Size/1024/1024).toFixed(2)} MB)`,"secondary"))}),h.pipe(m),new Promise((t,n)=>{const o=async t=>{if(h.destroyed||h.destroy(),m.destroyed||m.destroy(),t&&e.existsSync(y))try{await a.unlink(y),Yt(`Cleaned up partial file: ${y}`)}catch(e){Yt(`Failed to delete partial file ${y}:`,e)}};m.on("finish",()=>{u.push(g),!s&&l.succeed(`Successfully downloaded to ${g}`),t()}),h.on("error",async e=>{!s&&l.fail(`Download failed: ${e.message}`),await o(e),n(e)}),m.on("error",async e=>{!s&&l.fail(`File system error: ${e.message}`),await o(e),n(e)})})}),c=H("Downloading job files."),!s&&l.succeed(H(`Finished: ${c}`,"secondary")),{downloadedFiles:u,skippedFiles:d}}catch(e){s?ne({status:"error",error:Gt(e)}):(l.fail(H(`Error: ${c}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Yt(e),e&&e.response&&e.response.data&&Yt("response",e.response.data)),process.exit(1)}})(c,E,s,b,u),O=v.tap,I=v.target,T=t.resolve(b,`${O}-config.json`),F=t.resolve(b,`${I}-config.json`);if(e.existsSync(T)){const e=T,n="source-config.json";h=H(`Renaming ${e} to ${n}`),!s&&m.start(H(`In progress: ${h}...`,"secondary")),await a.rename(e,t.resolve(b,n)),!s&&m.succeed(H(`Finished: ${h}.`,"secondary"))}if(e.existsSync(F)){const e=F,n="target-config.json";h=H(`Renaming ${e} to ${n}`),!s&&m.start(H(`In progress: ${h}...`,"secondary")),await a.rename(e,t.resolve(b,n)),!s&&m.succeed(H(`Finished: ${h}.`,"secondary"))}await(async(e,n,o)=>{let s=p(),r=H("Creating state.json file");try{if(null!=e.state&&Object.keys(e.state).length>0){!o&&s.start(H(`In progress: ${r}...`,"secondary"));const i=t.resolve(n,"state.json");await a.writeFile(i,JSON.stringify(e.state,null,2)),!o&&s.succeed(H(`Finished: ${r}.`,"secondary"))}}catch(e){o?ne({status:"error",error:Gt(e)}):(s.fail(H(`Error: ${r}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Yt(e),e&&e.response&&e.response.data&&Yt("response",e.response.data)),process.exit(1)}})(v,b,s),await Zt($,v,b,r,s);const A=t.resolve(b,"etl-output");e.existsSync(A)||await a.mkdir(A,{recursive:!0}),s?ne({status:"success",downloadedFiles:x,skippedFiles:S}):(h=H("Setting up local job files."),m.succeed(H(`Finished: ${h}`,"secondary")))}catch(e){s?ne({status:"error",error:Gt(e)}):(m.fail(H(`Error: ${h}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Yt(e),e&&e.response&&e.response.data&&Yt("response",e.response.data)),process.exit(1)}}});const en=[tt,st,ct,Xt],tn=se("commands:etl"),nn="etl <action>";var on=Object.freeze({__proto__:null,builder:async function(e){tn("builder",nn);return(await ge(e)).command(en)},command:nn,desc:"Manage ETL scripts",handler:async function(e){tn("handler",nn,e)}});const sn=se("commands:flows:list"),rn="list";var an=Object.freeze({__proto__:null,builder:async e=>(sn("builder",rn),e.option("tenant",{...fe.tenant.config})),command:rn,desc:"List flows",handler:async e=>{sn("handler",rn,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e,{clientApiBaseUri:a}=t;let i,c=p();try{i=H(`Retrieving ${r?`${H(r,"info")} tenant's`:"the"} flows for environment: ${H(s,"info")}`);const e=`${a}/${s}/flows/${r?`linked?user_id=${r}`:"supported"}`;sn("requesting:",e),!n&&c.start(H(`In progress: ${i}...`,"secondary"));const{data:t}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&c.succeed(H(`Finished: ${i}.`,"secondary")),sn("response-data",t),!t||0===t.length)return void(n?ne([]):c.warn(H(`Warning: ${H("No flows for specified environment and tenant")}.`,"secondary")));if(n)ne(t);else{const e=new f({head:["ID","Name","Flow Type","Taps","Targets","Connectors"]});t.sort((e,t)=>(e.name||"").localeCompare(t.name||"")),t.forEach(t=>{return e.push([t.id,t.name||"",2==t.version?"Bidirectional":t.type?"Target Flow":"Source Flow",(n=t.taps,null==n||Array.isArray(n)&&0===n.length?t.sources?t.sources:[]:t.taps).join("\n"),(t.targets?t.targets:[]).join("\n"),(t.connectors?t.connectors:[]).join("\n")]);var n}),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(c.fail(H(`Error: ${i}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),sn(e),e&&e.response&&e.response.data&&sn("response",e.response.data)),process.exit(1)}}});const cn=[an],ln=se("commands:flows"),dn="flows <action>";var un=Object.freeze({__proto__:null,builder:async function(e){ln("builder",dn);return(await ge(e)).command(cn)},command:dn,desc:"Manage flows",handler:async function(e){ln("handler",dn,e)}});const fn=se("commands:jobs:download"),pn="download <jobroot>";var gn=Object.freeze({__proto__:null,builder:async e=>(fn("builder",pn),e.option("downloadTo",fe.downloadTo.config)),command:pn,desc:"Download Job files",handler:async n=>{fn("handler",pn,n);const{hg:o,json:s,apikey:r,env:a,jobroot:i,downloadTo:c}=n,{clientApiBaseUri:d}=o;let u,g=p();try{u=H("Verifying user and authorizing"),!s&&g.start(H(`In progress: ${u}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:p}=await je({debug:fn,baseUri:d,task:"job-download",env:a,apikey:r,jobroot:i}),y=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:p});!s&&g.succeed(H(`Finished: ${u}.`,"secondary")),u=H("Scanning for downloadable files"),!s&&g.start(H(`In progress: ${u}...`,"secondary"));const h={Bucket:a,Prefix:i},{Contents:b}=await y.listObjectsV2(h).promise();if(fn("res",b),!b||0===b.length)return void(s?ne({status:"error",error:"Nothing to download!"}):(g.fail(H(`Error: ${u}.`,"secondary")),X(H(`Message: ${H("Nothing to download!")}`,"secondary"))));if(!s&&g.succeed(H(`Finished: ${u}.`,"secondary")),!s){const e=new f({head:["File","Size","LastModified"]});b.forEach(t=>{const n=t.Key.substring(i.length+1);e.push([n,t.Size,t.LastModified.toLocaleString("en-US")])}),console.log(e.toString())}const w=t.resolve(process.cwd(),c,t.basename(i));await Wt(b.filter(({Key:e})=>!new RegExp(`${i}/([^/]+)-config.json`).test(e)),async n=>{u=H(`Downloading file: ${H(n.Key,"info")}`),!s&&g.start(H(`In progress: ${u}...`,"secondary"));const o=t.resolve(w,n.Key.substring(i.length+1));fn("file",o),await m.mkdir(t.dirname(o),{recursive:!0});const r=y.getObject({Bucket:a,Key:n.Key}).createReadStream(),c=e.createWriteStream(o,{flags:"w"});r.pipe(c),!s&&g.succeed(H(`Finished: ${u}.`,"secondary"))}),s?ne({status:"success",downloadedFiles:b.map(({Key:e})=>e)}):(u=H("Downloading job files."),g.succeed(H(`Finished: ${u}`,"secondary")))}catch(e){s?ne({status:"error",error:e}):(g.fail(H(`Error: ${u}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),fn(e),e&&e.response&&e.response.data&&fn("response",e.response.data)),process.exit(1)}}});const yn=(...e)=>{se("commands:jobs:list")(...e)},hn="list";var mn=Object.freeze({__proto__:null,builder:async e=>(yn("builder",hn),e.option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText).option("tenant",{...fe.tenant.config,default:"default"}).option("count",fe.count.config)),command:hn,desc:"List jobs",handler:async e=>{yn("handler",hn,e);const{hg:t,json:n,apikey:o,env:s,flow:r,tenant:a,count:i}=e,{clientApiBaseUri:c}=t;let l,d=p();try{l=H(`Retrieving jobs for environment: ${H(s,"info")} flow: ${H(r,"info")} tenant: ${H(a,"info")}...`);const e=`${c}/${s}/${r}/${a}/jobs${i?`?count=${i}`:""}`;yn("requesting:",e),!n&&d.start(H(`In progress: ${l}...`,"secondary"));const{data:t}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&d.succeed(H(`Finished: ${l}.`,"secondary")),yn("response-data",t),!t||0===t.length)return void(n?ne([]):d.warn(H(`Warning: ${H("No jobs for the specified environment, flow and tenant")}.`,"secondary")));if(n)ne(t);else{const e=new f({head:["name","details"]});t.forEach(t=>e.push([t.job_name,JSON.stringify(t,void 0,2)])),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(d.fail(H(`Error: ${l}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),yn(e),e&&e.response&&e.response.data&&yn("response",e.response.data)),process.exit(1)}}});const bn=(...e)=>{se("commands:jobs:bulkRun")(...e)},wn="bulk-run";var $n=Object.freeze({__proto__:null,builder:async e=>(bn("builder",wn),e.option("file",{describe:"Path to JSON file containing array of jobs to run",type:"string",alias:["f"],demandOption:!0}).demandOption("file","Path to JSON file is required. Example: -f ./jobs.json")),command:wn,desc:"Run jobs in bulk",handler:async t=>{bn("handler",wn,t);const{hg:n,json:o,apikey:s,env:r,file:a}=t,{clientApiBaseUri:i}=n;let c,l=p();try{if(c=H(`Reading jobs file: ${H(a,"info")}`),!o&&l.start(H(`In progress: ${c}...`,"secondary")),!e.existsSync(a))throw new Error(`File not found: ${a}`);const t=e.readFileSync(a,{encoding:"utf-8"}),n=JSON.parse(t);if(!Array.isArray(n))throw new Error("JSON file must contain an array of job objects");if(0===n.length)return void(o?ne({status:"error",error:"No jobs found in file"}):l.warn(H(`Warning: ${H("No jobs found in file")}.`,"secondary")));for(let e=0;e<n.length;e++){const t=n[e];if(!t.flow)throw new Error(`Job at index ${e} is missing required field: flow`);if(!t.tenant)throw new Error(`Job at index ${e} is missing required field: tenant`)}!o&&l.succeed(H(`Finished: ${c}.`,"secondary")),c=H("Checking flow versions..."),!o&&l.start(H(`In progress: ${c}...`,"secondary"));const d=[...new Set(n.map(e=>e.flow))],u={};await Promise.all(d.map(async e=>{try{const t=await Ae({debug:bn,baseUri:i,apikey:s,env:r,flow:e});u[e]=2===t?.version}catch(t){bn(`Error checking flow ${e}:`,t),u[e]=!1}})),!o&&l.succeed(H(`Finished: ${c}.`,"secondary")),c=H(`Running ${H(n.length,"info")} job(s)...`),!o&&l.start(H(`In progress: ${c}...`,"secondary"));const p=await Promise.all(n.map(async(e,t)=>{const{flow:n,tenant:o,...a}=e,c=u[n]||!1;try{const e=await(async({debug:e,baseUri:t,env:n,apikey:o,tenant:s,flow:r,...a})=>{const{isV2Flow:i=!1,...c}=a,l={"x-api-key":o},d=new URL(`${t}/${i?"v2/":""}${n}/${r}/${s}/jobs`).toString();e&&e("uri:",d);const{data:u}=await y.post(d,c,{headers:l});return u})({debug:bn,baseUri:i,env:r,apikey:s,tenant:o,flow:n,isV2Flow:c,...a});return{index:t,flow:n,tenant:o,ok:!0,response:e}}catch(e){let s;if(e.response){const t=e.response.status,n=e.response.statusText,o=e.response.data,r=e.message;bn("Error response:",{statusCode:t,statusText:n,message:r,data:o}),s={statusCode:t,statusText:n,message:r,data:o}}else e.request?(bn("Error: No response received",e.message),s={message:e.message,request:e.request}):(bn("Error:",e.message),s={message:e.message});return{index:t,flow:n,tenant:o,ok:!1,error:s}}}));if(!o&&l.succeed(H(`Finished: ${c}.`,"secondary")),o)ne(p);else{const e=new f({head:["Index","Flow","Tenant","Status","Response/Error"]});p.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow,t.tenant,n,o])}),console.log(e.toString());const t=p.filter(e=>e.ok).length,n=p.filter(e=>!e.ok).length;X(H(`Summary: ${H(String(t),"info")} succeeded, ${H(String(n),"error")} failed out of ${H(String(p.length),"info")} total.`,"secondary"))}}catch(e){o?ne({status:"error",error:e.message,stack:e.stack}):(l.fail(H(`Error: ${c||"Failed to run jobs"}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),bn(e)),process.exit(1)}}});const vn=(...e)=>{se("commands:jobs:bulkRetrigger")(...e)},jn="bulk-retrigger";var kn=Object.freeze({__proto__:null,builder:async e=>(vn("builder",jn),e.option("file",{describe:"Path to JSON file containing array of jobRoots to retrigger",type:"string",alias:["f"],demandOption:!0}).demandOption("file","Path to JSON file is required. Example: -f ./jobRoots.json")),command:jn,desc:"Retrigger jobs in bulk",handler:async t=>{vn("handler",jn,t);const{hg:n,json:o,apikey:s,env:r,file:a}=t,{clientApiBaseUri:i}=n;let c,l=p();try{if(c=H(`Reading jobRoots file: ${H(a,"info")}`),!o&&l.start(H(`In progress: ${c}...`,"secondary")),!e.existsSync(a))throw new Error(`File not found: ${a}`);const t=e.readFileSync(a,{encoding:"utf-8"}),n=JSON.parse(t);if(!Array.isArray(n))throw new Error("JSON file must contain an array of jobRoot strings");if(0===n.length)return void(o?ne({status:"error",error:"No jobRoots found in file"}):l.warn(H(`Warning: ${H("No jobRoots found in file")}.`,"secondary")));for(let e=0;e<n.length;e++)if("string"!=typeof n[e])throw new Error(`JobRoot at index ${e} must be a string, got ${typeof n[e]}`);!o&&l.succeed(H(`Finished: ${c}.`,"secondary"));const d={};for(const e of n){const t=e.split("/");if(t.length<3||"flows"!==t[1])throw new Error(`Invalid jobRoot format: ${e}. Expected format: {tenantId}/flows/{flowId}/...`);const n=t[0],o=t[2],s=`${n}/flows/${o}`;d[s]||(d[s]={tenant:n,flow:o,jobRoots:[]}),d[s].jobRoots.push(e)}const u=Object.keys(d);!o&&X(H(`Found ${H(String(n.length),"info")} jobRoot(s) grouped into ${H(String(u.length),"info")} tenant/flow group(s).`,"secondary"));const p=async(e,t,n,o=36e5)=>{const a=Date.now();for(;Date.now()-a<o;)try{const o=await De({debug:vn,baseUri:i,env:r,apikey:s,flow:t,user_id:e,job_root:n}),a=o.status||o.state;if("JOB_COMPLETED"===a||"string"==typeof a&&a.endsWith("_FAILED"))return{completed:!0,status:a};await new Promise(e=>setTimeout(e,5e3))}catch(e){vn(`Error checking job status for ${n}:`,e),await new Promise(e=>setTimeout(e,5e3))}return{completed:!1,status:"TIMEOUT"}};c=H(`Retriggering ${H(String(n.length),"info")} job(s) across ${H(String(u.length),"info")} group(s)...`),!o&&l.start(H(`In progress: ${c}...`,"secondary"));const g=[];if(await Promise.all(u.map(async e=>{const t=d[e],{tenant:n,flow:a,jobRoots:c}=t,u=[];for(let e=0;e<c.length;e++){const t=c[e];try{const d=await Ne({debug:vn,baseUri:i,env:r,apikey:s,tenant:n,flow:a,job_root:t});if(e<c.length-1){o||(l.text=H(`Waiting for job ${e+1}/${c.length} in group ${n}/${a} to complete...`,"secondary"));(await p(n,a,t)).completed||vn(`Warning: Job ${t} did not complete within timeout period`)}u.push({tenant:n,flow:a,jobRoot:t,ok:!0,response:d})}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;vn("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?(vn("Error: No response received",e.message),o={message:e.message,request:e.request}):(vn("Error:",e.message),o={message:e.message});u.push({tenant:n,flow:a,jobRoot:t,ok:!1,error:o})}}g.push(...u)})),!o&&l.succeed(H(`Finished: ${c}.`,"secondary")),o)ne(g);else{const e=new f({head:["Tenant","Flow","Job Root","Status","Response/Error"]});g.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.tenant||"N/A",t.flow||"N/A",t.jobRoot||"N/A",n,o])}),console.log(e.toString());const t=g.filter(e=>e.ok).length,n=g.filter(e=>!e.ok).length;X(H(`Summary: ${H(String(t),"info")} succeeded, ${H(String(n),"error")} failed out of ${H(String(g.length),"info")} total.`,"secondary"))}}catch(e){o?ne({status:"error",error:e.message,stack:e.stack}):(l.fail(H(`Error: ${c||"Failed to retrigger jobs"}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),vn(e)),process.exit(1)}}});const _n=(...e)=>{se("commands:jobs:bulkKill")(...e)},En="bulk-kill";var xn=Object.freeze({__proto__:null,builder:async e=>(_n("builder",En),e.option("tenant-ids",{describe:"Comma-separated list of tenant IDs to filter by",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs to filter by",type:"string",alias:["flows"]}).option("reason",{describe:"Reason for killing the jobs",type:"string"})),command:En,desc:"Kill jobs in bulk",handler:async e=>{_n("handler",En,e);const{hg:t,json:n,apikey:o,env:s,tenantIds:r,flowIds:a,reason:i}=e,{clientApiBaseUri:c}=t;let l,d=p();try{const e="JOB_CREATED,SYNC_STARTED,SYNC_SUCCESS,ETL_STARTED,ETL_SUCCESS,EXPORT_STARTED";l=H("Fetching running jobs..."),!n&&d.start(H(`In progress: ${l}...`,"secondary"));const t=new Date,u=new Date(t);u.setMonth(t.getMonth()-1);const p=u.toISOString().split("T")[0],g=await Ue({debug:_n,baseUri:c,env:s,apikey:o,from:p,status:e,count:100});let h=g.jobs||[];const m=g.total||0;if(!n&&d.succeed(H(`Found ${H(m,"info")} job(s) with specified status.`,"secondary")),r){const e=r.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(h=h.filter(t=>{const n=t.tenant;return e.includes(n)}))}if(a){const e=a.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(h=h.filter(t=>{const n=t.flow_id;return e.includes(n)}))}if(0===h.length)return void(n?ne({status:"info",message:"No jobs found matching the filters"}):d.warn(H(`Warning: ${H("No jobs found matching the specified filters")}.`,"secondary")));l=H(`Killing ${H(h.length,"info")} job(s)...`),!n&&d.start(H(`In progress: ${l}...`,"secondary"));const b=await Promise.all(h.map(async(e,t)=>{const n=e.s3_root,r=e.flow_id,a=e.tenant;if(!n)return{index:t,flow:r,tenant:a,ok:!1,error:{message:"Job root (s3_root) not found in job data"}};try{const e=await(async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,reason:i,task_arn:c,skip_webhooks:l})=>{const d=new URL(`${t}/${n}/${o}/${s}/jobs/kill`);d.searchParams.set("job_root",a),i&&d.searchParams.set("reason",i),c&&d.searchParams.set("task_arn",c),l&&d.searchParams.set("skip_webhooks",!0===l?"true":"false");const u={"x-api-key":r},f=d.toString();e&&e("uri:",f);const{data:p}=await y.get(f,{headers:u});return p})({debug:_n,baseUri:c,env:s,apikey:o,flow:r,user_id:a,job_root:n,reason:i});return{index:t,flow:r,tenant:a,jobRoot:n,ok:!0,response:e}}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;_n("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?(_n("Error: No response received",e.message),o={message:e.message,request:e.request}):(_n("Error:",e.message),o={message:e.message});return{index:t,flow:r,tenant:a,jobRoot:n,ok:!1,error:o}}}));if(!n&&d.succeed(H(`Finished: ${l}.`,"secondary")),n)ne(b);else{const e=new f({head:["Index","Flow","Tenant","Job Root","Status","Response/Error"]});b.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow||"N/A",t.tenant||"N/A",t.jobRoot||"N/A",n,o])}),console.log(e.toString());const t=b.filter(e=>e.ok).length,n=b.filter(e=>!e.ok).length;X(H(`Summary: ${H(String(t),"info")} succeeded, ${H(String(n),"error")} failed out of ${H(String(b.length),"info")} total.`,"secondary"))}}catch(e){n?ne({status:"error",error:e.message,stack:e.stack}):(d.fail(H(`Error: ${l||"Failed to kill jobs"}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),_n(e)),process.exit(1)}}});const Sn=(...e)=>{se("commands:jobs:bulkRollback")(...e)},On="bulk-rollback";var In=Object.freeze({__proto__:null,builder:async e=>(Sn("builder",On),e.option("from-utc-iso",{describe:"Start date for job search (YYYY-MM-DD)",type:"string",alias:["from"],demandOption:!0}).demandOption("from-utc-iso","Date from is required. Example: --from-utc-iso 2024-01-01").option("to-utc-iso",{describe:"End date for job search (YYYY-MM-DD)",type:"string",alias:["to"],demandOption:!0}).demandOption("to-utc-iso","Date to is required. Example: --to-utc-iso 2024-01-31").option("tenant-ids",{describe:"Comma-separated list of tenant IDs to filter by",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs to filter by",type:"string",alias:["flows"]})),command:On,desc:"Rollback jobs in bulk",handler:async e=>{Sn("handler",On,e);const{hg:t,json:n,apikey:o,env:s,fromUtcIso:r,toUtcIso:a,tenantIds:i,flowIds:c}=e,{clientApiBaseUri:l}=t;let d,u=p();try{if(10!==r.length){const e="Date from must be in YYYY-MM-DD format";n?ne({status:"error",error:e}):u.fail(H(`Error: ${e}`,"secondary")),process.exit(1)}if(10!==a.length){const e="Date to must be in YYYY-MM-DD format";n?ne({status:"error",error:e}):u.fail(H(`Error: ${e}`,"secondary")),process.exit(1)}const e=`${r}T00:00:00Z`,t=`${a}T23:59:59.999Z`;d=H(`Fetching jobs from ${H(r,"info")} to ${H(a,"info")}...`),!n&&u.start(H(`In progress: ${d}...`,"secondary"));const p=await Ue({debug:Sn,baseUri:l,env:s,apikey:o,from:e,to:t,count:100});!n&&u.stop();let g=p.jobs||[];if(i){const e=i.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(g=g.filter(t=>{const n=t.tenant;return e.includes(n)}))}if(c){const e=c.split(",").map(e=>e.trim()).filter(e=>e);e.length>0&&(g=g.filter(t=>{const n=t.flow_id||t.flowId||t.flow;return e.includes(n)}))}if(!n&&X(H(`Found ${H(String(g.length),"info")} job(s) after filtering.`,"secondary")),0===g.length)return void(n?ne({status:"info",message:"No jobs found matching the filters"}):u.warn(H(`Warning: ${H("No jobs found matching the specified filters")}.`,"secondary")));d=H(`Rolling back ${H(g.length,"info")} job(s)...`),!n&&u.start(H(`In progress: ${d}...`,"secondary"));const h=await Promise.all(g.map(async(e,t)=>{const n=e.s3_root||e.s3Root||e.job_root||e.jobRoot,r=e.flow_id||e.flowId||e.flow,a=e.tenant||e.tenant_id||e.tenantId||e.user_id;let i=e.tap;if(!i&&e.taps&&Array.isArray(e.taps)&&e.taps.length>0&&(i=e.taps[0]),!i&&e.tap_name&&(i=e.tap_name),!i&&e.connector&&(i=e.connector),!n)return{index:t,flow:r,tenant:a,ok:!1,error:{message:"Job root (s3_root) not found in job data"}};if(!i)return{index:t,flow:r,tenant:a,jobRoot:n,ok:!1,error:{message:"Tap not found in job data"}};try{const e=await(async({debug:e,baseUri:t,env:n,flow:o,user_id:s,apikey:r,job_root:a,tap:i})=>{const c={"x-api-key":r},l=new URL(`${t}/${n}/${o}/${s}/jobs/rollback`).toString(),d={job_root:a,tap:i};e&&e("uri:",l),e&&e("body:",d);const{data:u}=await y.post(l,d,{headers:c});return u})({debug:Sn,baseUri:l,env:s,apikey:o,flow:r,user_id:a,job_root:n,tap:i});return{index:t,flow:r,tenant:a,jobRoot:n,tap:i,ok:!0,response:e}}catch(e){let o;if(e.response){const t=e.response.status,n=e.response.statusText,s=e.response.data,r=e.message;Sn("Error response:",{statusCode:t,statusText:n,message:r,data:s}),o={statusCode:t,statusText:n,message:r,data:s}}else e.request?(Sn("Error: No response received",e.message),o={message:e.message,request:e.request}):(Sn("Error:",e.message),o={message:e.message});return{index:t,flow:r,tenant:a,jobRoot:n,tap:i,ok:!1,error:o}}}));if(!n&&u.succeed(H(`Finished: ${d}.`,"secondary")),n)ne(h);else{const e=new f({head:["Index","Flow","Tenant","Job Root","Tap","Status","Response/Error"]});h.forEach(t=>{const n=t.ok?"SUCCESS":"FAILED",o=t.ok?JSON.stringify(t.response,void 0,2):JSON.stringify(t.error,void 0,2);e.push([t.index,t.flow||"N/A",t.tenant||"N/A",t.jobRoot||"N/A",t.tap||"N/A",n,o])}),console.log(e.toString());const t=h.filter(e=>e.ok).length,n=h.filter(e=>!e.ok).length;X(H(`Summary: ${H(String(t),"info")} succeeded, ${H(String(n),"error")} failed out of ${H(String(h.length),"info")} total.`,"secondary"))}}catch(e){n?ne({status:"error",error:e.message,stack:e.stack}):(u.fail(H(`Error: ${d||"Failed to rollback jobs"}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Sn(e)),process.exit(1)}}});const Tn=[gn,mn,$n,kn,xn,In],Fn=se("commands:jobs"),An="jobs <action>";var Un=Object.freeze({__proto__:null,builder:async function(e){Fn("builder",An);return(await ge(e)).command(Tn)},command:An,desc:"Manage ETL jobs",handler:async function(e){Fn("handler",An,e)}});const Nn=se("commands:schedules:bulkUpdate"),Rn="bulk-update";var Dn=Object.freeze({__proto__:null,builder:async e=>(Nn("builder",Rn),e.option("tenant-ids",{describe:"Comma-separated list of tenant IDs",type:"string",alias:["tenants"]}).option("flow-ids",{describe:"Comma-separated list of flow IDs",type:"string",alias:["flows"]}).option("status",{describe:'Schedule status: "enable" or "disable"',type:"string",choices:["enable","disable"]}).option("expression",{describe:"Cron schedule expression",type:"string"}).option("connector",{describe:"Filter by connector ID",type:"string"}).option("job-type",{describe:'Filter by job type: "read" or "write"',type:"string",choices:["read","write"]})),command:Rn,desc:"Update schedules in bulk",handler:async e=>{Nn("handler",Rn,e);const{hg:t,json:n,apikey:o,env:s,tenantIds:r,flowIds:a,status:i,expression:c,connector:l,"job-type":d}=e,{clientApiBaseUri:u}=t;let g,h=p();try{if(!i&&!c){const e='Either "status" or "expression" must be provided';n?ne({status:"error",error:e}):h.fail(H(`Error: ${e}`,"secondary")),process.exit(1)}const e=r?r.split(",").map(e=>e.trim()).filter(Boolean):null,t=a?a.split(",").map(e=>e.trim()).filter(Boolean):null;g=H(`Retrieving schedules for environment: ${H(s,"info")}`),!n&&h.start(H(`In progress: ${g}...`,"secondary"));const p=await(async({debug:e,baseUri:t,env:n,apikey:o,includeDisabled:s})=>{const r=new URL(`${t}/tenants/${n}/schedule`);r.searchParams.set("includeDisabled","true");const a={"x-api-key":o},i=r.toString();e&&e("uri:",i);const{data:c}=await y.get(i,{headers:a});return c})({debug:Nn,baseUri:u,env:s,apikey:o,includeDisabled:!0});!n&&h.succeed(H(`Finished: ${g}.`,"secondary")),Nn("response-data",p);const m="string"==typeof p?JSON.parse(p):p;if(!m||0===m.length)return void(n?ne({updated:0,schedules:[]}):h.warn(H(`Warning: ${H("No schedules found for the specified environment")}.`,"secondary")));let b=m.filter(n=>{if(e&&e.length>0&&!e.includes(n.tenantId))return!1;if(t&&t.length>0&&!t.includes(n.flowId))return!1;if(null!=l&&""!==l){if(n.connectorId!==l)return!1}else if(null!==n.connectorId&&void 0!==n.connectorId)return!1;return!d||n.jobType===d});if(0===b.length)return void(n?ne({updated:0,schedules:[]}):h.warn(H(`Warning: ${H("No schedules match the specified filters")}.`,"secondary")));const w=b,$=i?"enable"===i?"ENABLED":"DISABLED":void 0;n||X(H(`Found ${H(w.length.toString(),"info")} schedule(s) to update`,"secondary"));const v=20,j=[],k=[];for(let e=0;e<w.length;e+=v){const t=w.slice(e,e+v),s=Math.floor(e/v)+1,r=Math.ceil(w.length/v);g=H(`Updating batch ${H(`${s}/${r}`,"info")} (${t.length} schedule(s))`),!n&&h.start(H(`In progress: ${g}...`,"secondary"));const a=t.map(async e=>{try{const t=c||e.expression,n=$||(e.isActive?"ENABLED":"DISABLED");if(!t)throw new Error("Schedule expression is required but not found");const s=await Re({debug:Nn,baseUri:u,env:e.envId,flow:e.flowId,user_id:e.tenantId,apikey:o,schedule_expression:t,state:n,job_type:e.jobType||d,connector_id:e.connectorId||l});return{success:!0,schedule:{envId:e.envId,flowId:e.flowId,tenantId:e.tenantId,connectorId:e.connectorId,jobType:e.jobType,expression:t,state:n},result:s}}catch(t){return Nn("Error updating schedule:",t),{success:!1,schedule:{envId:e.envId,flowId:e.flowId,tenantId:e.tenantId,connectorId:e.connectorId,jobType:e.jobType},error:t.message||t.toString()}}});(await Promise.all(a)).forEach(e=>{e.success?j.push(e.schedule):k.push(e)}),!n&&h.succeed(H(`Finished: ${g}.`,"secondary"))}if(n)ne({total:w.length,updated:j.length,failed:k.length,schedules:j,errors:k});else if(X(H(`\nUpdated ${H(j.length.toString(),"info")} schedule(s) successfully`,"secondary")),k.length>0&&X(H(`Failed to update ${H(k.length.toString(),"error")} schedule(s)`,"secondary")),j.length>0||k.length>0){const e=new f({head:["Environment","Flow","Tenant","Connector","Job Type","Expression","State","Updated"]});j.forEach(t=>{e.push([t.envId,t.flowId,t.tenantId,t.connectorId||"N/A",t.jobType||"N/A",t.expression,t.state,"yes"])}),k.forEach(t=>{const n=t.schedule,o=w.find(e=>e.envId===n.envId&&e.flowId===n.flowId&&e.tenantId===n.tenantId&&e.connectorId===n.connectorId&&e.jobType===n.jobType);e.push([n.envId,n.flowId,n.tenantId,n.connectorId||"N/A",n.jobType||"N/A",o?.expression||"N/A",o?.isActive?"ENABLED":"DISABLED",`no: ${t.error}`])}),console.log("\n"+e.toString())}}catch(e){n?ne({status:"error",error:e.message||e.toString()}):(h.fail(H(`Error: ${g||"Failed to update schedules"}.`,"secondary")),X(H(`Message: ${H(e.message||e.toString())}`,"secondary")),Nn(e),e&&e.response&&e.response.data&&Nn("response",e.response.data)),process.exit(1)}}});const Cn=[Dn],Pn=se("commands:schedules"),Bn="schedules <action>";var Mn=Object.freeze({__proto__:null,builder:async function(e){Pn("builder",Bn);return(await ge(e)).command(Cn)},command:Bn,desc:"Manage schedules",handler:async function(e){Pn("handler",Bn,e)}});const Kn=se("commands:snapshots:deploy"),Ln="deploy";var qn=Object.freeze({__proto__:null,builder:async e=>(Kn("builder",Ln),e.option("tenant",{...fe.tenant.config,default:"default"}).option("sourceFolder",fe.sourceFolder.config).demandOption("sourceFolder",fe.sourceFolder.demandText)),command:Ln,desc:"Deploy Snapshots",handler:async e=>{Kn("handler",Ln,e);const{hg:n,json:o,apikey:s,env:r,tenant:i,sourceFolder:c}=e,{clientApiBaseUri:d}=n;let u,g=p();const y=t.resolve(process.cwd(),c);try{u=H(`Deploying Snapshots for Tenant ${H(i,"info")} to ${H(r,"info")}`),!o&&g.info(H(`Info: ${u}.`,"secondary"));const e=await me(y,{recursive:!0});if(0===e.length)return void(o?ne({status:"error",error:"There are no files to deploy at the specified location!"}):g.fail(H(`Error: ${H("There are no files to deploy at the specified location!")}.`,"secondary")));u=H("Verifying user and authorizing");const{accessKeyId:n,secretAccessKey:p,sessionToken:h}=await je({debug:Kn,baseUri:d,task:"snapshot-deploy",env:r,tenant:i,apikey:s});!o&&g.succeed(H(`Finished: ${u}.`,"secondary"));const m=new l.S3({accessKeyId:n,secretAccessKey:p,sessionToken:h});u=H("Validating tenant exists"),!o&&g.start(H(`In progress: ${u}...`,"secondary"));try{const{CommonPrefixes:e}=await m.listObjectsV2({Bucket:r,Prefix:`${i}/`,Delimiter:"/"}).promise();if(0===e.length)throw new Error("Invalid tenant")}catch(e){throw Kn("err",e),new Error("Tenant doesn't exist. Please check your tenant (-u) argument.")}!o&&g.succeed(H(`Finished: ${u}.`,"secondary"));const b=`${i}/snapshots/`,w=new f({head:["File","Status"]});u=H("Preparing deployment target"),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const{Contents:$}=await m.listObjectsV2({Bucket:r,Prefix:`${b}`}).promise();!o&&g.stop(),Kn("contents",$),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const v=$.map(e=>({Key:e.Key}));if(v.length>0){const e={Bucket:r,Delete:{Objects:v,Quiet:!0}};await m.deleteObjects(e).promise(),v.forEach(({Key:e})=>w.push([e.substring(b.length),H("Deleted","warn")]))}!o&&g.succeed(H(`Finished: ${u}.`,"secondary"));for await(const n of e){const e=t.relative(c,n),s=`${b}${e}`;u=H(`Deploying file: ${H(e,"info")}`),!o&&g.start(H(`In progress: ${u}...`,"secondary"));const i={Bucket:r,Key:s,Body:await a.readFile(n)},l=await m.putObject(i).promise();!o&&g.succeed(H(`Finished: ${u}.`,"secondary")),Kn("s3-put-res",l),w.push([e,H("Deployed","info")])}o?ne({status:"success",deployedFiles:e}):Z(w.toString())}catch(e){o?ne({status:"error",error:e}):(g.fail(H(`Error: ${u}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Kn(e),e&&e.response&&e.response.data&&Kn("response",e.response.data)),process.exit(1)}}});const zn=se("commands:snapshots:download"),Jn="download";var Vn=Object.freeze({__proto__:null,builder:async e=>(zn("builder",Jn),e.option("downloadTo",fe.downloadTo.config).demandOption("downloadTo",fe.downloadTo.demandText).option("tenant",{...fe.tenant.config,default:"default"}).option("overwrite",fe.overwrite.config).demandOption("overwrite",fe.overwrite.demandText)),command:Jn,desc:"Download Snapshots",handler:async n=>{zn("handler",Jn,n);const{hg:o,json:s,apikey:r,env:i,tenant:c,downloadTo:d,overwrite:u}=n,{clientApiBaseUri:g}=o;let y,m=p();const b=t.resolve(process.cwd(),function(e){function t(e){return process.argv.indexOf(e)>-1}if(t(`--${e}`))return!0;const n=fe[e]?.config?.alias||[];for(let e in n)if(t(`-${n[e]}`))return!0;return!1}("downloadTo")?d:"snapshots");try{y=H("Verifying user and authorizing"),!s&&m.start(H(`In progress: ${y}...`,"secondary"));const{accessKeyId:n,secretAccessKey:o,sessionToken:d}=await je({debug:zn,baseUri:g,task:"snapshot-download",env:i,tenant:c,apikey:r}),p=new l.S3({accessKeyId:n,secretAccessKey:o,sessionToken:d});!s&&m.succeed(H(`Finished: ${y}.`,"secondary")),y=H("Validating tenant exists"),!s&&m.start(H(`In progress: ${y}...`,"secondary"));try{const{CommonPrefixes:e}=await p.listObjectsV2({Bucket:i,Prefix:`${c}/`,Delimiter:"/"}).promise();if(0===e.length)throw new Error("Invalid tenant")}catch(e){throw zn("err",e),new Error("Tenant doesn't exist. Please check your tenant (-u) argument.")}!s&&m.succeed(H(`Finished: ${y}.`,"secondary")),y=H("Scanning for downloadable files"),!s&&m.start(H(`In progress: ${y}...`,"secondary"));const w=`${c}/snapshots/`,$={Bucket:i,Prefix:w},{Contents:v}=await p.listObjectsV2($).promise();!s&&m.succeed(H(`Finished: ${y}.`,"secondary")),zn("s3-list-res",v);const j=v?v.map(e=>e.Key).filter(e=>e!==w):[];if(!j||0===j.length)return void(s?ne({status:"success",downloadedFiles:[]}):m.warn(H(`Warning: ${H("Nothing to download!")}`,"secondary")));y=H(`Downloading snapshot files to ${H(b,"info")}`),!s&&m.info(H(`Info: ${y}.`,"secondary"));const k=new f({head:["File","Status"]});for await(const n of j){const o=n.substring(w.length),r=t.resolve(b,o);if(zn("file",r),n.endsWith("/")){!e.existsSync(r)&&await a.mkdir(r,{recursive:!0});continue}if(!u)try{await a.stat(r),zn("exists, skipping"),k.push([o,"Skipped"]);continue}catch(e){"ENOENT"!==e.code&&Z(e)}y=H(`Downloading file: ${H(o,"info")}`),!s&&m.start(H(`In progress: ${y}...`,"secondary")),await a.mkdir(t.dirname(r),{recursive:!0});const c=p.getObject({Bucket:i,Key:n}).createReadStream();await h.pipeline(c,e.createWriteStream(r)),!s&&m.succeed(H(`Finished: ${y}.`,"secondary")),k.push([o,"Downloaded"])}s?ne({status:"success",downloadedFiles:j}):Z(k.toString())}catch(e){s?ne({status:"error",error:e}):(m.fail(H(`Error: ${y}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),zn(e),e&&e.response&&e.response.data&&zn("response",e.response.data)),process.exit(1)}}});const Wn=[qn,Vn],Yn=se("commands:snapshots"),Gn="snapshots <action>";var Qn=Object.freeze({__proto__:null,builder:async function(e){Yn("builder",Gn,e);return(await ge(e)).command(Wn)},command:Gn,desc:"Manage tenant snapshots",handler:async function(e){Yn("handler",Gn,e)}});const Hn=se("commands:tenants:custom-etl"),Zn="custom-etl",Xn=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,supportedSources:a})=>{const i=await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n});let c=null;for(const{tap:d}of[...i,...a]){const{accessKeyId:a,secretAccessKey:i,sessionToken:u}=await je({debug:e,baseUri:t,task:"etl-download",env:o,tenant:r,flow:s,tap:d,apikey:n}),f=new l.S3({accessKeyId:a,secretAccessKey:i,sessionToken:u}),p={Bucket:o,Prefix:`${r}/flows/${s}/taps/${d}/etl/`},{Contents:g}=await f.listObjectsV2(p).promise();if(g.some(({Key:e})=>e.endsWith("etl.py")||e.endsWith("etl.ipynb"))&&(c=r),null!==c)break}return c};var eo=Object.freeze({__proto__:null,builder:async e=>(Hn("builder",Zn),e.option("tenant",fe.tenant.config).option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText)),command:Zn,desc:"List tenants with custom ETL in a specific flow",handler:async e=>{Hn("handler",Zn,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=H(`Retrieving tenants for environment ${H(s,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([_e({debug:Hn,baseUri:t.clientApiBaseUri,apikey:o,env:s}),Ee({debug:Hn,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]);!n&&i.succeed(H(`Finished: ${a}.`,"secondary"));let l=[];a=H(`Querying for custom ETL scripts for flow ${H(r,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));for(const n of $e(e)){const e=await Promise.all(n.map(e=>Xn({debug:Hn,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,supportedSources:c})));l=l.concat(e.filter(Boolean))}if(!n&&i.succeed(H(`Finished: ${a}.`,"secondary")),n)ne(l);else{const e=new f({head:["Tenant ID"]});e.push(...l.map(e=>[e])),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(i.fail(H(`Error: ${a}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),Hn(e),e&&e.response&&e.response.data&&Hn("response",e.response.data)),process.exit(1)}}});const to=se("commands:tenants:custom-field-map"),no="custom-field-map",oo=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,isV2Flow:a})=>{const i=a?await Oe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}):await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}),c=[],{accessKeyId:d,secretAccessKey:u,sessionToken:f}=await je({debug:e,baseUri:t,task:"field-map-download",env:o,tenant:r,flow:s,apikey:n}),p=new l.S3({accessKeyId:d,secretAccessKey:u,sessionToken:f});for(const{id:e,tap:t}of i){const n={Bucket:o,Key:`${r}/flows/${s}/${a?"connectors":"taps"}/${a?e:t}/fieldMap.json`};try{await p.headObject(n).promise(),c.push(a?e:t)}catch(e){}}return{tenant:r,connectors:c}};var so=Object.freeze({__proto__:null,builder:async e=>(to("builder",no),e.option("tenant",fe.tenant.config).option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText)),command:no,desc:"List tenants with custom field map in a specific flow",handler:async e=>{to("handler",no,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=H(`Retrieving tenants for environment ${H(s,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([_e({debug:to,baseUri:t.clientApiBaseUri,apikey:o,env:s}),Ae({debug:to,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]),l=2===c?.version;!n&&i.succeed(H(`Finished: ${a}.`,"secondary"));const d=[];a=H(`Querying for custom field maps for flow ${H(r,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));for(const n of $e(e)){const e=await Promise.all(n.map(e=>oo({debug:to,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,isV2Flow:l})));d.push(...e.filter(({connectors:e})=>e.length>0))}if(!n&&i.succeed(H(`Finished: ${a}.`,"secondary")),n)ne(d);else{const e=new f({head:["Tenant ID","Connector IDs"]});e.push(...d.map(({tenant:e,connectors:t})=>[e,t.join(", ")])),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(i.fail(H(`Error: ${a}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),to(e),e&&e.response&&e.response.data&&to("response",e.response.data)),process.exit(1)}}});const ro=se("commands:tenants:delete"),ao="delete";var io=Object.freeze({__proto__:null,builder:async e=>(ro("builder",ao),e.option("tenant",fe.tenant.config)),command:ao,desc:"Delete tenant",handler:async e=>{ro("handler",ao,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e,{clientApiBaseUri:a}=t;let i,c=p();try{if("default"===r)throw new Error('It\'s not possible to delete "default" tenant!');i=H(`Deleting tenant ${r} schedules`),!n&&c.start(H(`In progress: ${i}...`,"secondary")),await(async({debug:e,baseUri:t,env:n,apikey:o,tenant:s})=>{const r={"x-api-key":o},a=new URL(`${t}/tenant/${n}/${s}?schedules_only=true`).toString();e&&e("uri:",a);const{data:i}=await y.delete(a,{headers:r});return i})({debug:ro,baseUri:a,env:s,apikey:o,tenant:r}),!n&&c.succeed(H(`Finished: ${i}.`,"secondary")),i=H("Verifying user and authorizing"),!n&&c.start(H(`In progress: ${i}...`,"secondary"));const{accessKeyId:e,secretAccessKey:t,sessionToken:d}=await je({debug:ro,baseUri:a,task:"tenant-delete",env:s,tenant:r,apikey:o});!n&&c.succeed(H(`Finished: ${i}.`,"secondary"));const u=new l.S3({accessKeyId:e,secretAccessKey:t,sessionToken:d});for(i=H(`Deleting tenant ${r} for environment ${H(s,"info")}`),!n&&c.start(H(`In progress: ${i}...`,"secondary"));;){const e=((await u.listObjectsV2({Bucket:s,Prefix:`${r}/`}).promise()).Contents||[]).map(({Key:e})=>({Key:e}));if(0===e.length)break;await u.deleteObjects({Bucket:s,Delete:{Objects:e}}).promise()}if(!n&&c.succeed(H(`Finished: ${i}.`,"secondary")),n)ne({statu:"success",tenantDeleted:r});else{const e=new f({head:["Tenant ID"]});e.push([r]),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(c.fail(H(`Error: ${i}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),ro(e),e&&e.response&&e.response.data&&ro("response",e.response.data)),process.exit(1)}}});const co=se("commands:tenants:list"),lo="list";var uo=Object.freeze({__proto__:null,builder:async e=>(co("builder",lo),e.option("tenant",fe.tenant.config)),command:lo,desc:"List tenants",handler:async e=>{co("handler",lo,e);const{hg:t,json:n,apikey:o,env:s,tenant:r}=e;let a,i=p();try{a=H(`Retrieving tenants for environment ${H(s,"info")}`);const e=`${t.clientApiBaseUri}/tenants/${s}${r?`?tenant=${r}`:""}`;co("requesting:",e),!n&&i.start(H(`In progress: ${a}...`,"secondary"));const{data:c}=await y.get(e,{headers:{"x-api-key":o}});if(!n&&i.succeed(H(`Finished: ${a}.`,"secondary")),co("response-data",c),!c||0===c.length)return void(n?ne([]):i.info(H(`Info: ${H("No tenants found in the specified environment")}.`,"secondary")));if(n)ne(c);else{const e=new f({head:["tenant ID"]});e.push(...c.map(e=>[e])),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(i.fail(H(`Error: ${a}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),co(e),e&&e.response&&e.response.data&&co("response",e.response.data)),process.exit(1)}}});const fo=se("commands:tenants:custom-catalog"),po="custom-catalog",go=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,isV2Flow:a})=>{try{const i=a?await Oe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}):await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n}),c=[],{accessKeyId:d,secretAccessKey:u,sessionToken:f}=await je({debug:e,baseUri:t,task:"field-map-download",env:o,tenant:r,flow:s,apikey:n}),p=new l.S3({accessKeyId:d,secretAccessKey:u,sessionToken:f});for(const{id:e,tap:t}of i){const n={Bucket:o,Key:`${r}/flows/${s}/${a?"connectors":"taps"}/${a?e:t}/catalog.json`};try{await p.headObject(n).promise(),c.push(a?e:t)}catch(e){}}return{tenant:r,connectors:c}}catch(e){return console.error(e),{tenant:r,connectors:[]}}};var yo=Object.freeze({__proto__:null,builder:async e=>(fo("builder",po),e.option("tenant",fe.tenant.config).option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText)),command:po,desc:"List tenants with custom catalog in a specific flow",handler:async e=>{fo("handler",po,e);const{hg:t,json:n,apikey:o,env:s,flow:r}=e;let a,i=p();try{a=H(`Retrieving tenants for environment ${H(s,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));const[e,c]=await Promise.all([_e({debug:fo,baseUri:t.clientApiBaseUri,apikey:o,env:s}),Ae({debug:fo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r})]),l=2===c?.version;!n&&i.succeed(H(`Finished: ${a}.`,"secondary"));const d=[];a=H(`Querying for custom catalogs for flow ${H(r,"info")}`),!n&&i.start(H(`In progress: ${a}...`,"secondary"));for(const n of $e(e)){const e=await Promise.all(n.map(e=>go({debug:fo,baseUri:t.clientApiBaseUri,apikey:o,env:s,flow:r,tenant:e,isV2Flow:l})));d.push(...e.filter(({connectors:e})=>e.length>0))}if(!n&&i.succeed(H(`Finished: ${a}.`,"secondary")),n)ne(d);else{const e=new f({head:["Tenant ID","Connector IDs"]});e.push(...d.map(({tenant:e,connectors:t})=>[e,t.join(", ")])),console.log(e.toString())}}catch(e){n?ne({status:"error",error:e}):(i.fail(H(`Error: ${a}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),fo(e),e&&e.response&&e.response.data&&fo("response",e.response.data)),process.exit(1)}}});const ho=se("commands:tenants:update-config"),mo="update-config",bo=async({debug:e,baseUri:t,apikey:n,env:o,flow:s,tenant:r,connectorId:a,config:i,isV2Flow:c})=>{const l=c?"id":"tap";if(!(c?await Oe({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,config:!0}):await Se({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,config:!0})).find(e=>e[l]===a))return null;const d=c?Te:Ie;try{await d({debug:e,baseUri:t,env:o,flow:s,tenant:r,apikey:n,connectorId:a,config:i})}catch(e){console.log(H(`Error patching: ${r}. ${e}`,"secondary"))}return r};var wo=Object.freeze({__proto__:null,builder:async e=>(ho("builder",mo),e.option("flow",fe.flow.config).demandOption("flow",fe.flow.demandText).option("connector",fe.connector.config).demandOption("connector",fe.connector.demandText).option("configFilePath",fe.configFilePath.config).demandOption("configFilePath",fe.configFilePath.demandText)),command:mo,desc:"Update the config of a specific connector and flow for all tenants",handler:async t=>{ho("handler",mo,t);const{hg:n,json:o,apikey:s,env:r,flow:a,connector:i,configFilePath:c}=t;let l,d=p();try{if(!c)throw new Error("Config file path not provided");if(!c.endsWith(".json"))throw new Error("Config file must have .json extension");if(!e.existsSync(c))throw new Error("Config file not found");const t=JSON.parse(e.readFileSync(c,{encoding:"utf-8"}));l=H(`Retrieving tenants for environment ${H(r,"info")}`),!o&&d.start(H(`In progress: ${l}...`,"secondary"));const[u,p]=await Promise.all([_e({debug:ho,baseUri:n.clientApiBaseUri,apikey:s,env:r}),Ae({debug:ho,baseUri:n.clientApiBaseUri,apikey:s,env:r,flow:a})]),g=2===p?.version;!o&&d.succeed(H(`Finished: ${l}.`,"secondary"));const y=[];l=H(`Updating config for connector ${H(i,"info")} and flow ${H(a,"info")}`),!o&&d.start(H(`In progress: ${l}...`,"secondary"));for(const e of $e(u)){const o=await Promise.all(e.map(e=>bo({debug:ho,baseUri:n.clientApiBaseUri,apikey:s,env:r,flow:a,tenant:e,connectorId:i,config:t,isV2Flow:g})));y.push(...o.filter(Boolean))}if(!o&&d.succeed(H(`Finished: ${l}.`,"secondary")),o)ne(y);else{const e=new f({head:["Tenant ID"]});y.forEach(t=>e.push([t])),console.log(e.toString())}}catch(e){o?ne({status:"error",error:e}):(d.fail(H(`Error: ${l}.`,"secondary")),X(H(`Message: ${H(e.message)}`,"secondary")),ho(e),e&&e.response&&e.response.data&&ho("response",e.response.data)),process.exit(1)}}});const $o=[eo,so,io,uo,yo,wo],vo=se("commands:tenants"),jo="tenants <action>";var ko=Object.freeze({__proto__:null,builder:async function(e){vo("builder",jo);return(await ge(e)).command($o)},command:jo,desc:"Manage tenants",handler:async function(e){vo("handler",jo,e)}});const _o=se("commands:singer:validate"),Eo="validate",xo=(e,t,n,o)=>{let s=o.type;Array.isArray(s)||(s=[s]);const r=s.filter(e=>"null"!==e)[0];if(!s.includes("null")||null!==n){if("string"===r&&"string"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type string.`);if("number"===r&&"number"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type number.`);if("boolean"===r&&"boolean"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type boolean.`);if("array"===r&&!Array.isArray(n))throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type array.`);if("object"===r&&"object"!=typeof n)throw new Error(`Record for ${e} has invalid type ${typeof n} for field ${t}. Expected type object.`)}},So=(e,t,n)=>{const o=t.stream;if(!o)throw new Error("Schema record is missing stream name");if(!t.schema)throw new Error(`Schema record for ${o} is missing schema field`);if(e[o]){for(const n of t.key_properties)if(!e[o].keyProperties.includes(n))throw new Error(`Schema for ${o} has different key properties: ${e[o].keyProperties.join(", ")} and ${t.key_properties.join(", ")}`);const n=e[o].schema;((e,t,n)=>{for(const[o,s]of Object.entries(t.properties))if(n.properties[o]){const t=n.properties[o].type,r=s.type;if(t.length!=r.length||t.some(e=>!r.includes(e)))throw new Error(`Schema for ${e} has different typing for field ${o}: ${t} and ${r}`)}})(o,t.schema,n)}else e[o]={schema:t.schema,keyProperties:t.key_properties||[],keySet:new Set,count:0};return((e,t,n)=>{for(const[o,s]of Object.entries(t.properties)){let t=s.type;Array.isArray(t)||(t=[t]);const r=t.filter(e=>"null"!==e);if(r.length>1&&!n)throw new Error(`Schema for ${e} has multiple non-null types for field ${o}: ${r.join(", ")}`)}})(o,t.schema,n),e},Oo=(e,t,n)=>{const o=t.stream,s=t.record;if(!s)throw new Error("Record is missing record field");if("object"!=typeof s)throw new Error(`Record has invalid type ${typeof s} for record field. Expected type object.`);if(!o)throw new Error("Record record is missing stream name");if(!e[o])throw new Error(`Record was written for stream ${o} before schema row was written.`);const r=e[o].keyProperties;for(const t of r){if(!s[t])throw new Error(`Record for ${o} is missing key property ${t}`);e[o].keySet.add(s[t])}if(r.length>0&&!n){const t=b.createHash("sha256").update(r.map(e=>`${e}:${s[e]}`).join("")).digest("hex");if(e[o].keySet.has(t))throw new Error(`Duplicate record for ${o} with primary keys: ${r.map(e=>`${e}: ${s[e]}`).join(", ")}`);e[o].keySet.add(t)}((e,t,n)=>{for(const[o,s]of Object.entries(t)){const t=n.properties[o];if(!t)throw new Error(`Record for ${e} has unknown field ${o}`);xo(e,o,s,t)}})(o,s,e[o].schema),e[o].count++},Io=(e,t)=>{if(!t.value)throw new Error("State record is missing value");if("object"!=typeof t.value)throw new Error(`State record has invalid type ${typeof t.value} for value. Expected type object.`)},To=async(t,n)=>{const o={},{allowDuplicateRecords:s,allowFuzzyTypes:r}=n;for await(const a of async function*(t){const n=e.createReadStream(t,{encoding:"utf8"});let o="";for await(const e of n){const t=(o+e).split("\n");o=t.pop();for(const e of t)e.trim()&&(yield JSON.parse(e))}o.trim()&&(yield JSON.parse(o))}(t))try{if(!a.type)throw new Error(`Singer row is missing type: ${JSON.stringify(a)}`);"SCHEMA"==a.type?So(o,a,r):"RECORD"==a.type?Oo(o,a,s):"STATE"==a.type&&Io(0,a)}catch(e){throw n.json?e.message=`${e.message}. Error occured on line: ${JSON.stringify(a)}.`:console.log(`Error occured on line: ${JSON.stringify(a)} \n `),e}return o};var Fo=Object.freeze({__proto__:null,builder:async e=>(_o("builder",Eo),e.option("dataFilePath",{...fe.dataFilePath.config}).option("allowDuplicateRecords",{type:"boolean",default:!1,description:"Allow duplicate records"}).option("allowFuzzyTypes",{type:"boolean",default:!1,description:"Allow fields to have multiple non-null types"})),command:Eo,desc:"Validate Singer data",handler:async t=>{_o("handler",Eo,t);const{allowDuplicateRecords:n,allowFuzzyTypes:o,dataFilePath:s,json:r}=t,a={allowDuplicateRecords:n,allowFuzzyTypes:o,json:r};if(!s)throw new Error("Data file path is required");if(!e.existsSync(s))throw new Error(`Data file path ${s} does not exist`);try{const e=await To(s,a);r?console.log(JSON.stringify({streams:Object.keys(e).map(t=>({stream:t,count:e[t].count}))},null,2)):console.log(`\n \nšŸŽ‰šŸŽ‰šŸŽ‰ Singer validation passed šŸŽ‰šŸŽ‰šŸŽ‰\n--------------------------------------\n\n${Object.keys(e).length} streams validated\n\nRecord count by stream:\n${Object.keys(e).map(t=>`\n ${t}: ${e[t].count}`).join("")}\n\n `)}catch(e){r?console.log(JSON.stringify({error:e.message},null,2)):console.log(`\n\n🚨🚨🚨 Singer validation failed 🚨🚨🚨\n--------------------------------------\n\n${e.message}\n\n `),process.exit(1)}}});const Ao=[Fo],Uo=se("commands:singer"),No="singer <action>";var Ro=Object.freeze({__proto__:null,builder:async function(e){Uo("builder",No);return(await e).command(Ao)},command:No,desc:"Develop and test singer taps and targets",handler:async function(e){Uo("handler",No,e)}});const Do=[ue,Qe,on,un,Un,Mn,Qn,ko,Ro];process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE="1";G({});const Co=o(process.argv.slice(2));Co.usage(H("Usage: $0 <command>")).command(Do).demandCommand().alias("v","version").alias("h","help").string("_").strictCommands().epilogue(H("For more information, visit https://docs.hotglue.xyz/docs/cli-overview")).wrap(Math.min(Co.terminalWidth(),90)).parse(process.argv.slice(T()+1),K);
35
35
  //# sourceMappingURL=index.js.map