@getjusto/team-cli 0.0.9 → 0.0.10
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/bin/cli.js +65 -48
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function ie(e){let r=[],t={},o={};for(let a=0;a<e.length;a++)if(e[a].startsWith("--")&&e[a+1]&&!e[a+1].startsWith("--")){let i=e[a].slice(2);if(t[i]=e[a+1],!o[i])o[i]=[];o[i].push(e[a+1]),a++}else if(e[a].startsWith("--"))t[e[a].slice(2)]="true";else r.push(e[a]);return{positional:r,flags:t,arrayFlags:o}}function
|
|
3
|
-
`)}function
|
|
4
|
-
`)}function er(e,r){let o={ok:!1,error:e instanceof Error?e.message:String(e)};if((r.format==="json"?"json":"toon")==="json"){console.error(JSON.stringify(o,null,2));return}console.error(ve(o))}function C(e){process.stderr.write(e)}import{existsSync as le,mkdirSync as
|
|
2
|
+
function ie(e){let r=[],t={},o={};for(let a=0;a<e.length;a++)if(e[a].startsWith("--")&&e[a+1]&&!e[a+1].startsWith("--")){let i=e[a].slice(2);if(t[i]=e[a+1],!o[i])o[i]=[];o[i].push(e[a+1]),a++}else if(e[a].startsWith("--"))t[e[a].slice(2)]="true";else r.push(e[a]);return{positional:r,flags:t,arrayFlags:o}}function X(e,r){let t=e[r];if(!t)throw Error(`--${r} es requerido.`);return t}var no={comma:",",tab:"\t",pipe:"|"},Y=no.comma;function He(e){return e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function so(e){return e==="true"||e==="false"||e==="null"}function j(e){if(e===null)return null;if(typeof e==="object"&&e!==null&&"toJSON"in e&&typeof e.toJSON==="function"){let r=e.toJSON();if(r!==e)return j(r)}if(typeof e==="string"||typeof e==="boolean")return e;if(typeof e==="number"){if(Object.is(e,-0))return 0;if(!Number.isFinite(e))return null;return e}if(typeof e==="bigint"){if(e>=Number.MIN_SAFE_INTEGER&&e<=Number.MAX_SAFE_INTEGER)return Number(e);return e.toString()}if(e instanceof Date)return e.toISOString();if(Array.isArray(e))return e.map(j);if(e instanceof Set)return Array.from(e).map(j);if(e instanceof Map)return Object.fromEntries(Array.from(e,([r,t])=>[String(r),j(t)]));if(co(e)){let r={};for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t))r[t]=j(e[t]);return r}return null}function B(e){return e===null||typeof e==="string"||typeof e==="number"||typeof e==="boolean"}function Q(e){return Array.isArray(e)}function q(e){return e!==null&&typeof e==="object"&&!Array.isArray(e)}function H(e){return Object.keys(e).length===0}function co(e){if(e===null||typeof e!=="object")return!1;let r=Object.getPrototypeOf(e);return r===null||r===Object.prototype}function Z(e){return e.length===0||e.every((r)=>B(r))}function uo(e){return e.length===0||e.every((r)=>Q(r))}function Ze(e){return e.length===0||e.every((r)=>q(r))}function lo(e){return/^[A-Z_][\w.]*$/i.test(e)}function mo(e){return/^[A-Z_]\w*$/i.test(e)}function po(e,r=Y){if(!e)return!1;if(e!==e.trim())return!1;if(so(e)||go(e))return!1;if(e.includes(":"))return!1;if(e.includes('"')||e.includes("\\"))return!1;if(/[[\]{}]/.test(e))return!1;if(/[\n\r\t]/.test(e))return!1;if(e.includes(r))return!1;if(e.startsWith("-"))return!1;return!0}function go(e){return/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(e)||/^0\d+$/.test(e)}var Ni=Symbol("quotedKey");function fo(e,r,t,o,a,i,n){if(o.keyFolding!=="safe")return;if(!q(r))return;let{segments:s,tail:c,leafValue:l}=wo(e,r,n??o.flattenDepth);if(s.length<2)return;if(!s.every((d)=>mo(d)))return;let m=bo(s),p=i?`${i}.${m}`:m;if(t.includes(m))return;if(a&&a.has(p))return;return{foldedKey:m,remainder:c,leafValue:l,segmentCount:s.length}}function wo(e,r,t){let o=[e],a=r;while(o.length<t){if(!q(a))break;let i=Object.keys(a);if(i.length!==1)break;let n=i[0],s=a[n];o.push(n),a=s}if(!q(a)||H(a))return{segments:o,tail:void 0,leafValue:a};return{segments:o,tail:a,leafValue:a}}function bo(e){return e.join(".")}function P(e,r){if(e===null)return"null";if(typeof e==="boolean")return String(e);if(typeof e==="number")return String(e);return yo(e,r)}function yo(e,r=Y){if(po(e,r))return e;return`"${He(e)}"`}function k(e){if(lo(e))return e;return`"${He(e)}"`}function ke(e,r=Y){return e.map((t)=>P(t,r)).join(r)}function v(e,r){let t=r?.key,o=r?.fields,a=r?.delimiter??",",i="";if(t)i+=k(t);if(i+=`[${e}${a!==Y?a:""}]`,o){let n=o.map((s)=>k(s));i+=`{${n.join(a)}}`}return i+=":",i}function*Co(e,r,t){if(B(e)){let o=P(e,r.delimiter);if(o!=="")yield o;return}if(Q(e))yield*Se(void 0,e,t,r);else if(q(e))yield*W(e,t,r)}function*W(e,r,t,o,a,i){let n=Object.keys(e);if(r===0&&!o)o=new Set(n.filter((c)=>c.includes(".")));let s=i??t.flattenDepth;for(let[c,l]of Object.entries(e))yield*ho(c,l,r,t,n,o,a,s)}function*ho(e,r,t,o,a,i,n,s){let c=n?`${n}.${e}`:e,l=s??o.flattenDepth;if(o.keyFolding==="safe"&&a){let p=fo(e,r,a,o,i,n,l);if(p){let{foldedKey:d,remainder:b,leafValue:f,segmentCount:T}=p,O=k(d);if(b===void 0){if(B(f)){yield y(t,`${O}: ${P(f,o.delimiter)}`,o.indent);return}else if(Q(f)){yield*Se(d,f,t,o);return}else if(q(f)&&H(f)){yield y(t,`${O}:`,o.indent);return}}if(q(b)){yield y(t,`${O}:`,o.indent);let U=l-T,D=n?`${n}.${d}`:d;yield*W(b,t+1,o,i,D,U);return}}}let m=k(e);if(B(r))yield y(t,`${m}: ${P(r,o.delimiter)}`,o.indent);else if(Q(r))yield*Se(e,r,t,o);else if(q(r)){if(yield y(t,`${m}:`,o.indent),!H(r))yield*W(r,t+1,o,i,c,l)}}function*Se(e,r,t,o){if(r.length===0){yield y(t,v(0,{key:e,delimiter:o.delimiter}),o.indent);return}if(Z(r)){yield y(t,se(r,o.delimiter,e),o.indent);return}if(uo(r)){if(r.every((a)=>Z(a))){yield*qo(e,r,t,o);return}}if(Ze(r)){let a=Ye(r);if(a)yield*Io(e,r,a,t,o);else yield*Xe(e,r,t,o);return}yield*Xe(e,r,t,o)}function*qo(e,r,t,o){yield y(t,v(r.length,{key:e,delimiter:o.delimiter}),o.indent);for(let a of r)if(Z(a)){let i=se(a,o.delimiter);yield E(t+1,i,o.indent)}}function se(e,r,t){let o=v(e.length,{key:t,delimiter:r}),a=ke(e,r);if(e.length===0)return o;return`${o} ${a}`}function*Io(e,r,t,o,a){yield y(o,v(r.length,{key:e,fields:t,delimiter:a.delimiter}),a.indent),yield*Ve(r,t,o+1,a)}function Ye(e){if(e.length===0)return;let r=e[0],t=Object.keys(r);if(t.length===0)return;if(xo(e,t))return t}function xo(e,r){for(let t of e){if(Object.keys(t).length!==r.length)return!1;for(let o of r){if(!(o in t))return!1;if(!B(t[o]))return!1}}return!0}function*Ve(e,r,t,o){for(let a of e)yield y(t,ke(r.map((i)=>a[i]),o.delimiter),o.indent)}function*Xe(e,r,t,o){yield y(t,v(r.length,{key:e,delimiter:o.delimiter}),o.indent);for(let a of r)yield*je(a,t+1,o)}function*$o(e,r,t){if(H(e)){yield y(r,"-",t.indent);return}let o=Object.entries(e),[a,i]=o[0],n=o.slice(1);if(Q(i)&&Ze(i)){let c=Ye(i);if(c){if(yield E(r,v(i.length,{key:a,fields:c,delimiter:t.delimiter}),t.indent),yield*Ve(i,c,r+2,t),n.length>0)yield*W(Object.fromEntries(n),r+1,t);return}}let s=k(a);if(B(i))yield E(r,`${s}: ${P(i,t.delimiter)}`,t.indent);else if(Q(i))if(i.length===0)yield E(r,`${s}${v(0,{delimiter:t.delimiter})}`,t.indent);else if(Z(i))yield E(r,`${s}${se(i,t.delimiter)}`,t.indent);else{yield E(r,`${s}${v(i.length,{delimiter:t.delimiter})}`,t.indent);for(let c of i)yield*je(c,r+2,t)}else if(q(i)){if(yield E(r,`${s}:`,t.indent),!H(i))yield*W(i,r+2,t)}if(n.length>0)yield*W(Object.fromEntries(n),r+1,t)}function*je(e,r,t){if(B(e))yield E(r,P(e,t.delimiter),t.indent);else if(Q(e))if(Z(e))yield E(r,se(e,t.delimiter),t.indent);else{yield E(r,v(e.length,{delimiter:t.delimiter}),t.indent);for(let o of e)yield*je(o,r+1,t)}else if(q(e))yield*$o(e,r,t)}function y(e,r,t){return" ".repeat(t*e)+r}function E(e,r,t){return y(e,"- "+r,t)}function Eo(e,r){let t=r("",e,[]);if(t===void 0)return ne(e,r,[]);return ne(j(t),r,[])}function ne(e,r,t){if(q(e))return So(e,r,t);if(Q(e))return jo(e,r,t);return e}function So(e,r,t){let o={};for(let[a,i]of Object.entries(e)){let n=[...t,a],s=r(a,i,n);if(s===void 0)continue;o[a]=ne(j(s),r,n)}return o}function jo(e,r,t){let o=[];for(let a=0;a<e.length;a++){let i=e[a],n=[...t,a],s=r(String(a),i,n);if(s===void 0)continue;let c=j(s);o.push(ne(c,r,n))}return o}function ve(e,r){return Array.from(vo(e,r)).join(`
|
|
3
|
+
`)}function vo(e,r){let t=j(e),o=Ao(r);return Co(o.replacer?Eo(t,o.replacer):t,o,0)}function Ao(e){return{indent:e?.indent??2,delimiter:e?.delimiter??Y,keyFolding:e?.keyFolding??"off",flattenDepth:e?.flattenDepth??Number.POSITIVE_INFINITY,replacer:e?.replacer}}function Ro(e){let r=e.format??"toon";if(r!=="toon"&&r!=="json")throw Error("--format debe ser toon o json.");return r}function Ke(e,r){if(Ro(r)==="json"){console.log(JSON.stringify(e,null,2));return}console.log(ve(e))}function Le(e){process.stdout.write(`${e}
|
|
4
|
+
`)}function er(e,r){let o={ok:!1,error:e instanceof Error?e.message:String(e)};if((r.format==="json"?"json":"toon")==="json"){console.error(JSON.stringify(o,null,2));return}console.error(ve(o))}function C(e){process.stderr.write(e)}import{existsSync as le,mkdirSync as Oo,readFileSync as tr,writeFileSync as Uo,unlinkSync as Qo}from"node:fs";import{join as or}from"node:path";import{homedir as Bo}from"node:os";import{AsyncLocalStorage as No}from"node:async_hooks";var To=new No;function I(){return To.getStore()}var ce={main:{local:"http://localhost:3000",develop:"https://api.bejusto.com",prod:"https://api.getjusto.com"},auth:{local:"http://localhost:4112",develop:"https://auth.service.bejusto.com",prod:"https://auth.service.getjusto.com"},webdata:{local:"http://localhost:4125",develop:"https://webdata.service.bejusto.com",prod:"https://webdatacdn.getjusto.com"},preferences:{local:"http://localhost:4120",develop:"https://preferences.service.bejusto.com",prod:"https://preferences.service.getjusto.com"},buckets:{local:"http://localhost:4106",develop:"https://buckets.service.bejusto.com",prod:"https://buckets.service.getjusto.com"},reservations:{local:"http://localhost:4113",develop:"https://reservations.service.bejusto.com",prod:"https://reservations.service.getjusto.com"},data:{local:"http://localhost:4107",develop:"https://data.service.bejusto.com",prod:"https://data.service.getjusto.com"},finances:{local:"http://localhost:4105",develop:"https://finances.service.bejusto.com",prod:"https://finances.service.getjusto.com"},"url-shortener":{local:"http://localhost:4102",develop:"https://url-shortener.service.bejusto.com",prod:"https://url-shortener.service.getjusto.com"},files:{local:"http://localhost:4108",develop:"https://files.service.bejusto.com",prod:"https://files.service.getjusto.com"},tabs:{local:"http://localhost:4115",develop:"https://tabs.service.bejusto.com",prod:"https://tabs.service.getjusto.com"},commander:{local:"http://localhost:4109",develop:"https://commander.service.bejusto.com",prod:"https://commander.service.getjusto.com"},experiments:{local:"http://localhost:4114",develop:"https://experiments.service.bejusto.com",prod:"https://experiments.service.getjusto.com"},sales:{local:"http://localhost:4117",develop:"https://sales.service.bejusto.com",prod:"https://sales.service.getjusto.com"},delivery:{local:"http://localhost:3410",develop:"https://api-delivery.bejusto.com",prod:"https://api-delivery-2.getjusto.com"},payments:{local:"http://localhost:4118",develop:"https://payments.service.bejusto.com",prod:"https://payments.service.getjusto.com"},addresses:{local:"http://localhost:4051",develop:"https://addresses.service.bejusto.com",prod:"https://addresses.service.getjusto.com"},royalty:{local:"http://localhost:4121",develop:"https://royalty.service.bejusto.com",prod:"https://royalty.service.getjusto.com"},marketing:{local:"http://localhost:4005",develop:"https://marketing.service.bejusto.com",prod:"https://marketing.service.getjusto.com"},api:{local:"http://localhost:4119",develop:"https://api.service.bejusto.com",prod:"https://api.service.getjusto.com"},messenger:{local:"http://localhost:4122",develop:"https://messenger.service.bejusto.com",prod:"https://messenger.service.getjusto.com"},invoice:{local:"http://localhost:4123",develop:"https://invoice.service.bejusto.com",prod:"https://invoice.service.getjusto.com"},"drivers-server":{local:"http://localhost:3410",develop:"https://api-delivery.bejusto.com",prod:"https://api-delivery-2.getjusto.com"}},Ae="prod";function rr(e){Ae=e}function ue(){let e=process.env.JUSTO_TEAM_CLI_ENV;if(e)return e;let r=I()?.environment;if(r)return r;return Ae}function h(e){return ce[e][Ae]}var Re=or(Bo(),".justo-team");function ar(e){let r=e==="prod"?"credentials.json":`credentials.${e}.json`;return or(Re,r)}function Ne(){return ar(ue())}function _o(){if(!le(Re))Oo(Re,{recursive:!0})}function me(e){let r=I();if(r&&r.canPersistCredentials===!1)throw Error("Este entorno no permite guardar credenciales.");_o(),Uo(Ne(),JSON.stringify(e,null,2))}function g(){let e=process.env.JUSTO_TEAM_CLI_TOKEN,r=process.env.JUSTO_TEAM_CLI_EMAIL,t=process.env.JUSTO_TEAM_CLI_REFRESH_TOKEN;if(e&&r)return{email:r,token:e,refreshToken:t||""};let o=I()?.credentials;if(o!==void 0)return o?{email:o.email,token:o.token,refreshToken:o.refreshToken||""}:null;let a=Ne();if(!le(a))return null;try{let i=tr(a,"utf-8");return JSON.parse(i)}catch{return null}}function ir(e){let r=ar(e);if(!le(r))return null;try{let t=tr(r,"utf-8");return JSON.parse(t)}catch{return null}}function Te(){let e=I();if(e&&e.canPersistCredentials===!1)throw Error("Este entorno no permite borrar credenciales.");let r=Ne();if(le(r))Qo(r)}import{existsSync as nr,readFileSync as Jo,writeFileSync as Wo,mkdirSync as Po}from"node:fs";import{join as sr}from"node:path";import{homedir as Mo}from"node:os";function Go(){let e=process.env.JUSTO_TEAM_CLI_DEVICE_ID;if(e)return e;let r=I()?.deviceId;if(r)return r;let t=sr(Mo(),".justo-team"),o=sr(t,"device-id");if(nr(o))return Jo(o,"utf-8").trim();let a=crypto.randomUUID();if(!nr(t))Po(t,{recursive:!0});return Wo(o,a),a}var ur={required:({label:e})=>`${e} no es opcional`,notAString:({label:e})=>`${e} no es un texto`,notANumber:({label:e})=>`${e} no es un número`,notAnInteger:({label:e})=>`${e} no es un número entero`,notABoolean:({label:e})=>`${e} no es un valor verdadero o falso`,notAnEmail:({label:e})=>`${e} no es un email`,notAnId:({label:e})=>`${e} no es un ID válido`,notADate:({label:e})=>`${e} no es una fecha válida`,notAnArray:({label:e})=>`${e} no es un arreglo`,notAnObject:({label:e})=>`${e} no es un objeto`,stringTooShort:({label:e})=>`${e} no tiene el largo suficiente`,stringTooLong:"El largo es mayor al permitido",numberTooSmall:({label:e})=>`${e} es un número muy pequeño`,numberTooBig:({label:e})=>`${e} es un número muy grande`,notInSchema:({label:e})=>`${e} no esta permitido`,notUnique:({label:e})=>`${e} no es único`,notFound:({label:e})=>`${e} no se encontró`,invalid:"No es válido",rateLimitExceeded:"Has excedido el límite de intentos. Intenta de nuevo más tarde.",incorrectLoginCode:"El código es incorrecto",loginCodeExpired:"El código expiró. Solicita un nuevo",loginCodeLocked:"El código se bloqueó. Genera un nuevo código para continuar",userNotFound:"No existe una cuenta con este email"};function Fo(e,r){let t=ur[e];if(!t)return`${r}: ${e}`;if(typeof t==="function")return t({label:r});return t}function cr(e){return Object.entries(e).map(([r,t])=>Fo(t,r)).join(", ")}function zo(e){if(e.error==="validationError"&&e.validationErrors)return cr(e.validationErrors);if(e.extensions?.code==="PermissionsError"){let a=e.extensions.info?.type;if(a?.includes("User doesn't have permissions for "))return`Tu usuario no tiene permisos para [${a.split("User doesn't have permissions for ")[1]}]`;return e.message}if(e.validationErrors)return`${e.message} (${cr(e.validationErrors)})`;let r=e.message||"Error desconocido",t=ur[r];if(t)return typeof t==="function"?t({label:""}).trim():t;let o=e.error||e.code||e.type;return o?`${r} [${o}]`:r}function Do(e){try{return JSON.parse(Buffer.from(e.split(".")[1],"base64").toString()).exp*1000<Date.now()}catch{return!0}}async function Xo(){let e=g();if(!e?.refreshToken)return null;let r=`${h("auth")}/refresh-token`,o=await(await fetch(r,{method:"POST",headers:{"X-ORION-REFRESH":e.refreshToken}})).json();if(!o.token)return null;if(I()?.canPersistCredentials!==!1)me({...e,token:o.token});return o.token}async function de(){let e=g();if(!e?.token)return;if(!Do(e.token))return e.token;return await Xo()??void 0}async function Oe(e="application/json"){let r=await de(),t={"Content-Type":e,"X-ORION-DEVICEID":Go(),"X-ORION-PLATFORM":"web"};if(r)t["x-orion-jwt"]=r;return t}async function u(e){let r=`${h(e.service)}/graphql`,t=await Oe(),o;try{o=await fetch(r,{method:"POST",headers:t,body:JSON.stringify({query:e.query,variables:e.variables}),signal:AbortSignal.timeout(e.timeoutMs||15000)})}catch{throw Error("La solicitud tardó demasiado. Intenta de nuevo.")}let a=await o.json();if(a.errors?.length)throw Error(zo(a.errors[0]));if(!a.data)throw Error("No data returned from server");return a.data}function Ho(e){return e.replace(/^https?:\/\//,"").replace(/^www\./,"").replace(/\/.*$/,"")}function Zo(e){return e.includes(".")||e.startsWith("http://")||e.startsWith("https://")}async function M(e){if(Zo(e)){let r=Ho(e),t=await fetch(`${h("main")}/website-id/${r}`,{signal:AbortSignal.timeout(1e4)});if(!t.ok)throw Error(`No se encontro el sitio "${r}"`);let o=await t.json();if(!o.websiteId)throw Error(`No se pudo resolver el websiteId para "${r}"`);return{input:e,websiteId:o.websiteId,targetType:"domain"}}return{input:e,websiteId:e,targetType:"websiteId"}}async function lr(e){let r=await u({service:"main",query:`query ($websiteId: ID) {
|
|
5
5
|
website(websiteId: $websiteId) {
|
|
6
6
|
_id
|
|
7
7
|
name
|
|
@@ -13,7 +13,7 @@ function ie(e){let r=[],t={},o={};for(let a=0;a<e.length;a++)if(e[a].startsWith(
|
|
|
13
13
|
timezone
|
|
14
14
|
defaultMenuId
|
|
15
15
|
}
|
|
16
|
-
}`,variables:{websiteId:e}});if(!r.website)throw Error(`No se encontro el website "${e}"`);return r.website}function
|
|
16
|
+
}`,variables:{websiteId:e}});if(!r.website)throw Error(`No se encontro el website "${e}"`);return r.website}function ko(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}async function mr(e){if(ko(),!e)throw Error("Uso: team-cli admin <websiteId|domain> show");let r=await M(e),t=await lr(r.websiteId);return{context:r,website:t}}function pe(){return`team-cli admin
|
|
17
17
|
|
|
18
18
|
Comandos administrativos con contexto de website.
|
|
19
19
|
|
|
@@ -101,12 +101,12 @@ Modulos:
|
|
|
101
101
|
sentToEmail
|
|
102
102
|
totalRedemptions
|
|
103
103
|
createdAt
|
|
104
|
-
`;function Ue(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}function G(e,r){let t=e[r];if(!t)throw Error(`--${r} es requerido.`);try{return JSON.parse(t)}catch{throw Error(`--${r} debe ser un JSON válido.`)}}function S(e,r){let t=e[r];if(!t)return;let o=Number.parseInt(t,10);if(Number.isNaN(o))throw Error(`--${r} debe ser un número entero.`);return o}function gr(e,r){let t=e[r];if(!t)return;if(t==="true")return!0;if(t==="false")return!1;throw Error(`--${r} debe ser true o false.`)}async function
|
|
104
|
+
`;function Ue(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}function G(e,r){let t=e[r];if(!t)throw Error(`--${r} es requerido.`);try{return JSON.parse(t)}catch{throw Error(`--${r} debe ser un JSON válido.`)}}function S(e,r){let t=e[r];if(!t)return;let o=Number.parseInt(t,10);if(Number.isNaN(o))throw Error(`--${r} debe ser un número entero.`);return o}function gr(e,r){let t=e[r];if(!t)return;if(t==="true")return!0;if(t==="false")return!1;throw Error(`--${r} debe ser true o false.`)}async function x(e){if(Ue(),!e)throw Error("Debes indicar <websiteId|domain>.");return M(e)}async function A(e,r){let t=await u({service:"main",query:`query ($couponId: ID) {
|
|
105
105
|
coupon(couponId: $couponId) {
|
|
106
106
|
_id
|
|
107
107
|
websiteId
|
|
108
108
|
}
|
|
109
|
-
}`,variables:{couponId:e}});if(!t.coupon)throw Error(`No se encontró el cupón "${e}"`);if(t.coupon.websiteId!==r)throw Error(`El cupón "${e}" no pertenece al website seleccionado.`);return t.coupon}function
|
|
109
|
+
}`,variables:{couponId:e}});if(!t.coupon)throw Error(`No se encontró el cupón "${e}"`);if(t.coupon.websiteId!==r)throw Error(`El cupón "${e}" no pertenece al website seleccionado.`);return t.coupon}function Yo(e){if(!Array.isArray(e))throw Error("--input debe ser un arreglo JSON.");return e.map((r)=>{if(!r||typeof r!=="object"||typeof r.code!=="string")throw Error('Cada item de --input debe tener al menos { "code": "..." }.');if(r.userEmail!=null&&typeof r.userEmail!=="string")throw Error("userEmail debe ser string cuando viene informado.");return{code:r.code,userEmail:r.userEmail}})}function Vo(e){if(!Array.isArray(e)||e.some((r)=>typeof r!=="string"))throw Error("--ids debe ser un arreglo JSON de strings.");return e}async function fr(e,r,t){let o=await x(e);await A(r,o.websiteId);let a=S(t,"limit"),i=S(t,"page"),n=t.filter,s=await u({service:"main",query:`query ($couponId: ID, $filter: String, $limit: BigInt, $page: BigInt) {
|
|
110
110
|
couponCodes(couponId: $couponId, filter: $filter, limit: $limit, page: $page) {
|
|
111
111
|
items {
|
|
112
112
|
${pr}
|
|
@@ -116,11 +116,11 @@ Modulos:
|
|
|
116
116
|
hasNextPage
|
|
117
117
|
hasPreviousPage
|
|
118
118
|
}
|
|
119
|
-
}`,variables:{couponId:r,filter:n,limit:a,page:i}});return{context:o,couponId:r,codes:s.couponCodes.items??[],pagination:{totalCount:s.couponCodes.totalCount??0,totalPages:s.couponCodes.totalPages??0,hasNextPage:Boolean(s.couponCodes.hasNextPage),hasPreviousPage:Boolean(s.couponCodes.hasPreviousPage),page:i??1,limit:a??null}}}async function wr(e,r,t){let o=await
|
|
119
|
+
}`,variables:{couponId:r,filter:n,limit:a,page:i}});return{context:o,couponId:r,codes:s.couponCodes.items??[],pagination:{totalCount:s.couponCodes.totalCount??0,totalPages:s.couponCodes.totalPages??0,hasNextPage:Boolean(s.couponCodes.hasNextPage),hasPreviousPage:Boolean(s.couponCodes.hasPreviousPage),page:i??1,limit:a??null}}}async function wr(e,r,t){let o=await x(e);await A(r,o.websiteId);let a=Yo(G(t,"input")),i=a.some((s)=>s.userEmail),n=await u({service:"main",query:`mutation ($couponId: ID, $codesWithEmail: [CodeWithEmailInput], $useCodeWithEmail: Boolean) {
|
|
120
120
|
createCouponCodes(couponId: $couponId, codesWithEmail: $codesWithEmail, useCodeWithEmail: $useCodeWithEmail)
|
|
121
|
-
}`,variables:{couponId:r,codesWithEmail:a,useCodeWithEmail:i}});return{context:o,couponId:r,requestedCount:a.length,result:n.createCouponCodes}}async function br(e,r,t){let o=await
|
|
121
|
+
}`,variables:{couponId:r,codesWithEmail:a,useCodeWithEmail:i}});return{context:o,couponId:r,requestedCount:a.length,result:n.createCouponCodes}}async function br(e,r,t){let o=await x(e);await A(r,o.websiteId);let a=S(t,"quantity");if(!a)throw Error("--quantity es requerido.");let i=await u({service:"main",query:`mutation ($couponId: ID, $couponQuantity: Float, $couponCodePrefix: String) {
|
|
122
122
|
createRandomCouponCodes(couponId: $couponId, couponQuantity: $couponQuantity, couponCodePrefix: $couponCodePrefix)
|
|
123
|
-
}`,variables:{couponId:r,couponQuantity:a,couponCodePrefix:t.prefix}});return{context:o,couponId:r,quantity:a,prefix:t.prefix??null,result:i.createRandomCouponCodes}}async function yr(e,r,t){let o=await
|
|
123
|
+
}`,variables:{couponId:r,couponQuantity:a,couponCodePrefix:t.prefix}});return{context:o,couponId:r,quantity:a,prefix:t.prefix??null,result:i.createRandomCouponCodes}}async function yr(e,r,t){let o=await x(e);await A(r,o.websiteId);let a=Vo(G(t,"ids")),i=await u({service:"main",query:`mutation ($couponId: ID, $couponCodesIds: [ID]) {
|
|
124
124
|
deleteCouponCodes(couponId: $couponId, couponCodesIds: $couponCodesIds, globalCoupon: false)
|
|
125
125
|
}`,variables:{couponId:r,couponCodesIds:a}});return{context:o,couponId:r,deleted:i.deleteCouponCodes,couponCodesIds:a}}function Cr(){return`team-cli admin coupons codes create
|
|
126
126
|
|
|
@@ -145,11 +145,11 @@ Ejemplo:
|
|
|
145
145
|
|
|
146
146
|
Notas:
|
|
147
147
|
Si algún item trae userEmail, team-cli activa useCodeWithEmail automáticamente.
|
|
148
|
-
couponId se valida contra el website seleccionado antes de ejecutar la mutation.`}var hr={active:"Boolean",allowedEmails:"[String]",applyDeliveryDiscount:"Boolean",code:"ID",deliveryDiscountPercentage:"Float",deliveryDiscountType:"String",deliveryDiscountValue:"Float",description:"String",discountAmount:"Float",dontApplyToProductsIds:"[ID]",endDate:"Date",externalId:"String",extraRequirementsForPaymentTypes:"JSON",fixedAmount:"Float",fromDate:"Date",isBirthdayCoupon:"Boolean",isHidden:"Boolean",maxPercentageOffDiscount:"Float",maxProductsPerOrder:"Float",maxRedemptions:"Float",maxRedemptionsPerUser:"Float",maxRedemptionsPerUserPerDay:"Boolean",maximumOrderPrice:"Float",minimumOrderPrice:"Float",name:"String",onlyForNewUsers:"Boolean",onlyForProductsWithoutDiscount:"Boolean",onlyRedeemOnBirthday:"Boolean",percentageOff:"Float",requireChannels:"[ID]",requirePhoneVerification:"Boolean",requiredBINs:"[String]",requiresCategoriesIds:"[ID]",requiresMenusIds:"[ID]",requiresPaymentTypes:"[ID]",requiresProductsIds:"[ID]",requiresStoresIds:"[ID]",schedule:"ScheduleInput",scheduleAtUse:"ScheduleInput",type:"ID",websiteId:"ID"};function
|
|
148
|
+
couponId se valida contra el website seleccionado antes de ejecutar la mutation.`}var hr={active:"Boolean",allowedEmails:"[String]",applyDeliveryDiscount:"Boolean",code:"ID",deliveryDiscountPercentage:"Float",deliveryDiscountType:"String",deliveryDiscountValue:"Float",description:"String",discountAmount:"Float",dontApplyToProductsIds:"[ID]",endDate:"Date",externalId:"String",extraRequirementsForPaymentTypes:"JSON",fixedAmount:"Float",fromDate:"Date",isBirthdayCoupon:"Boolean",isHidden:"Boolean",maxPercentageOffDiscount:"Float",maxProductsPerOrder:"Float",maxRedemptions:"Float",maxRedemptionsPerUser:"Float",maxRedemptionsPerUserPerDay:"Boolean",maximumOrderPrice:"Float",minimumOrderPrice:"Float",name:"String",onlyForNewUsers:"Boolean",onlyForProductsWithoutDiscount:"Boolean",onlyRedeemOnBirthday:"Boolean",percentageOff:"Float",requireChannels:"[ID]",requirePhoneVerification:"Boolean",requiredBINs:"[String]",requiresCategoriesIds:"[ID]",requiresMenusIds:"[ID]",requiresPaymentTypes:"[ID]",requiresProductsIds:"[ID]",requiresStoresIds:"[ID]",schedule:"ScheduleInput",scheduleAtUse:"ScheduleInput",type:"ID",websiteId:"ID"};function Ko(e){let r=Object.entries(e).filter(([,i])=>i!==void 0),t=r.map(([i])=>i).filter((i)=>!hr[i]);if(t.length)throw Error(`Campos no soportados para create: ${t.join(", ")}`);let o=r.map(([i])=>`$${i}: ${hr[i]}`).join(", "),a=r.map(([i])=>`${i}: $${i}`).join(", ");return`mutation (${o}) {
|
|
149
149
|
createCoupon(${a}) {
|
|
150
150
|
${ge}
|
|
151
151
|
}
|
|
152
|
-
}`}async function qr(e,r){let t=await
|
|
152
|
+
}`}async function qr(e,r){let t=await x(e),o=S(r,"limit"),a=S(r,"page"),i=r.filter,n=await u({service:"main",query:`query ($websiteId: ID, $filter: String, $limit: BigInt, $page: BigInt) {
|
|
153
153
|
coupons(websiteId: $websiteId, filter: $filter, limit: $limit, page: $page) {
|
|
154
154
|
items {
|
|
155
155
|
_id
|
|
@@ -169,17 +169,17 @@ Notas:
|
|
|
169
169
|
hasNextPage
|
|
170
170
|
hasPreviousPage
|
|
171
171
|
}
|
|
172
|
-
}`,variables:{websiteId:t.websiteId,filter:i,limit:o,page:a}});return{context:t,coupons:n.coupons.items??[],pagination:{totalCount:n.coupons.totalCount??0,totalPages:n.coupons.totalPages??0,hasNextPage:Boolean(n.coupons.hasNextPage),hasPreviousPage:Boolean(n.coupons.hasPreviousPage),page:a??1,limit:o??null}}}async function Ir(e,r){let t=await
|
|
172
|
+
}`,variables:{websiteId:t.websiteId,filter:i,limit:o,page:a}});return{context:t,coupons:n.coupons.items??[],pagination:{totalCount:n.coupons.totalCount??0,totalPages:n.coupons.totalPages??0,hasNextPage:Boolean(n.coupons.hasNextPage),hasPreviousPage:Boolean(n.coupons.hasPreviousPage),page:a??1,limit:o??null}}}async function Ir(e,r){let t=await x(e);await A(r,t.websiteId);let o=await u({service:"main",query:`query ($couponId: ID) {
|
|
173
173
|
coupon(couponId: $couponId) {
|
|
174
174
|
${ge}
|
|
175
175
|
}
|
|
176
|
-
}`,variables:{couponId:r}});return{context:t,coupon:o.coupon}}async function
|
|
176
|
+
}`,variables:{couponId:r}});return{context:t,coupon:o.coupon}}async function xr(e,r){let t=await x(e),o=G(r,"input");if(o.websiteId&&o.websiteId!==t.websiteId)throw Error("El websiteId del input no coincide con el website seleccionado.");let a={...o,websiteId:t.websiteId},i=Ko(a),n=await u({service:"main",query:i,variables:a});return{context:t,coupon:n.createCoupon}}async function $r(e,r,t){let o=await x(e);await A(r,o.websiteId);let a=G(t,"input"),i=await u({service:"main",query:`mutation ($couponId: ID, $coupon: UpdateCouponInput) {
|
|
177
177
|
updateCoupon(couponId: $couponId, coupon: $coupon) {
|
|
178
178
|
${ge}
|
|
179
179
|
}
|
|
180
|
-
}`,variables:{couponId:r,coupon:a}});return{context:o,coupon:i.updateCoupon}}async function
|
|
180
|
+
}`,variables:{couponId:r,coupon:a}});return{context:o,coupon:i.updateCoupon}}async function Er(e,r){let t=await x(e);await A(r,t.websiteId);let o=await u({service:"main",query:`mutation ($couponsIds: [ID]) {
|
|
181
181
|
deleteCoupons(couponsIds: $couponsIds, globalCoupon: false)
|
|
182
|
-
}`,variables:{couponsIds:[r]}});return{context:t,couponId:r,deleted:o.deleteCoupons}}function
|
|
182
|
+
}`,variables:{couponsIds:[r]}});return{context:t,couponId:r,deleted:o.deleteCoupons}}function V(){return`team-cli admin coupons
|
|
183
183
|
|
|
184
184
|
Administracion de cupones para el website seleccionado.
|
|
185
185
|
|
|
@@ -227,7 +227,7 @@ Acciones:
|
|
|
227
227
|
Uso: team-cli admin <web> coupons codes delete <couponId> --ids '["id1","id2"]'
|
|
228
228
|
|
|
229
229
|
Nota:
|
|
230
|
-
El schema actual no expone update para coupon codes.`}function
|
|
230
|
+
El schema actual no expone update para coupon codes.`}function Sr(){return`team-cli admin coupons create
|
|
231
231
|
|
|
232
232
|
Crea un cupón para el website seleccionado.
|
|
233
233
|
|
|
@@ -354,7 +354,7 @@ Opciones:
|
|
|
354
354
|
Ejemplos:
|
|
355
355
|
team-cli admin search milas
|
|
356
356
|
team-cli admin search buffalo --limit 5
|
|
357
|
-
team-cli admin search pizza --only-active true`}function
|
|
357
|
+
team-cli admin search pizza --only-active true`}function Lo(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}function ea(e){let r=[e.address?.streetAddress,e.address?.extendedAddress,e.address?.locality].filter(Boolean);if(!r.length)return null;return r.join(", ")}async function Rr(e){if(Lo(),!e)throw Error("Uso: team-cli admin <websiteId|domain> stores list");let r=await M(e),o=((await u({service:"main",query:`query ($websiteId: ID) {
|
|
358
358
|
stores(websiteId: $websiteId) {
|
|
359
359
|
items {
|
|
360
360
|
_id
|
|
@@ -366,16 +366,16 @@ Ejemplos:
|
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
|
-
}`,variables:{websiteId:r.websiteId}})).stores.items??[]).map((a)=>({_id:a._id,name:a.name,address:
|
|
369
|
+
}`,variables:{websiteId:r.websiteId}})).stores.items??[]).map((a)=>({_id:a._id,name:a.name,address:ea(a)})).sort((a,i)=>a.name.localeCompare(i.name,"es",{sensitivity:"base"}));return{context:r,stores:o,totalCount:o.length}}import{createInterface as ra}from"node:readline";function F(e){if(process.env.JUSTO_TEAM_CLI_INTERACTIVE==="false")throw Error("Este entorno no soporta prompts interactivos.");if(I()?.interactive===!1)throw Error("Este entorno no soporta prompts interactivos.");let r=ra({input:process.stdin,output:process.stderr});return new Promise((t)=>{r.question(e,(o)=>{r.close(),t(o.trim())})})}async function Nr(e){return(await u({service:"auth",query:`mutation ($email: String!) {
|
|
370
370
|
requestLoginCode(email: $email)
|
|
371
371
|
}`,variables:{email:e}})).requestLoginCode}async function Tr(e,r,t){let o=await u({service:"auth",query:`mutation ($email: String!, $token: String!, $code: String!) {
|
|
372
372
|
loginWithCode(email: $email, token: $token, code: $code) {
|
|
373
373
|
token
|
|
374
374
|
refreshToken
|
|
375
375
|
}
|
|
376
|
-
}`,variables:{email:e,token:r,code:t.toUpperCase()}});me({email:e,token:o.loginWithCode.token,refreshToken:o.loginWithCode.refreshToken}),await
|
|
376
|
+
}`,variables:{email:e,token:r,code:t.toUpperCase()}});me({email:e,token:o.loginWithCode.token,refreshToken:o.loginWithCode.refreshToken}),await ta()}async function ta(){if(!(await u({service:"main",query:"query { me { roles } }"})).me?.roles?.length)throw Te(),Error("Solo miembros del equipo Justo pueden usar esta herramienta.")}async function Or(){let e=await F("Email: ");C(`Enviando codigo de verificacion...
|
|
377
377
|
`);let r=await Nr(e);C(`Codigo enviado a tu email.
|
|
378
|
-
`);let t=await
|
|
378
|
+
`);let t=await F("Codigo: ");return await Tr(e,r,t),{ok:!0,authenticated:!0,email:e}}async function Ur(e){let r=X(e,"email"),t=X(e,"token"),o=X(e,"code");return await Tr(r,t,o),{ok:!0,authenticated:!0,email:r}}async function Qr(e){let r=X(e,"email");C(`Enviando codigo de verificacion...
|
|
379
379
|
`);let t=await Nr(r);return{ok:!0,email:r,token:t,nextCommand:`npx @getjusto/team-cli auth login-with-token --email ${r} --token ${t} --code <CODIGO>`}}async function Br(){return Te(),{ok:!0,authenticated:!1}}async function _r(){let e=g();if(!e)return{authenticated:!1,loginCommand:"npx @getjusto/team-cli auth request-code --email <email>",nextCommand:"npx @getjusto/team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>"};return{authenticated:!0,email:e.email}}function Qe(){return`team-cli auth
|
|
380
380
|
|
|
381
381
|
Gestion de sesion.
|
|
@@ -402,7 +402,7 @@ Subcomandos:
|
|
|
402
402
|
|
|
403
403
|
login-with-token
|
|
404
404
|
Iniciar sesion sin prompts. Recomendado para agentes.
|
|
405
|
-
Uso: team-cli auth login-with-token --email <email> --token <token> --code <codigo>`}import{spawn as he}from"node:child_process";import{createServer as rt}from"node:http";import{existsSync as
|
|
405
|
+
Uso: team-cli auth login-with-token --email <email> --token <token> --code <codigo>`}import{spawn as he}from"node:child_process";import{createServer as rt}from"node:http";import{existsSync as ga,mkdirSync as fa,openSync as wa,readFileSync as ba,rmSync as ya,writeFileSync as Ca}from"node:fs";import{dirname as ha,join as qe,resolve as tt}from"node:path";import{request as qa}from"node:http";import{request as Ia}from"node:https";import{execFileSync as oa}from"node:child_process";import{existsSync as be,mkdirSync as aa,readFileSync as ye,readdirSync as ia,rmSync as Be,writeFileSync as R}from"node:fs";import{basename as Gr,dirname as Fr,join as w,resolve as zr}from"node:path";var fe="iUzDOAFCUx33tmT6OCea",K="VITE_JUSTO_MAP_TILER_TOKEN";function Jr(){return`import {useState, type FormEvent} from 'react'
|
|
406
406
|
import {Badge} from '@/components/ui/badge'
|
|
407
407
|
import {Button} from '@/components/ui/button'
|
|
408
408
|
import {Card, CardContent, CardDescription, CardHeader, CardTitle} from '@/components/ui/card'
|
|
@@ -823,14 +823,14 @@ createRoot(document.getElementById('root')!).render(
|
|
|
823
823
|
</ThemeProvider>
|
|
824
824
|
</StrictMode>,
|
|
825
825
|
)
|
|
826
|
-
`}function we(){return process.execPath}function _(e){if(process.platform==="win32")return`${e}.cmd`;return e}var Dr=".justo-space.json";function L(e,r,t){
|
|
827
|
-
base: './',`);R(r,o)}function
|
|
828
|
-
`)}function
|
|
829
|
-
${t}`)}function
|
|
830
|
-
`),Be(w(e,".git"),{recursive:!0,force:!0})}function
|
|
831
|
-
`),await new Promise((i,n)=>{a.on("close",()=>i()),a.on("error",n)})}async function ct(e){let r=e.path;if(!r)throw Error("Falta --path. Ejemplo: team-cli spaces preview --path ./mi-space-app");let t=_e(r);it(),at(t),
|
|
832
|
-
`);let b=await
|
|
833
|
-
`);let a=`${r} ${
|
|
826
|
+
`}function we(){return process.execPath}function _(e){if(process.platform==="win32")return`${e}.cmd`;return e}var Dr=".justo-space.json";function L(e,r,t){oa(e,r,{cwd:t,stdio:"inherit",env:{...process.env,CI:"1"}})}function na(e){if(!e)throw Error("Falta --path. Ejemplo: team-cli spaces init --path ./mi-space-app");let r=zr(e);if(be(r)){if(ia(r).length>0)throw Error(`La carpeta ya existe y no está vacía: ${r}`);Be(r,{recursive:!0,force:!0})}return aa(Fr(r),{recursive:!0}),r}function sa(e){let r=w(e,"vite.config.ts"),t=ye(r,"utf-8");if(t.includes("base: './'"))return;let o=t.replace("export default defineConfig({",`export default defineConfig({
|
|
827
|
+
base: './',`);R(r,o)}function ca(e){let r=w(e,"tsconfig.app.json"),o=ye(r,"utf-8").replace('"noUnusedLocals": true,','"noUnusedLocals": false,').replace('"noUnusedParameters": true,','"noUnusedParameters": false,');R(r,o)}function ua(e){let r=w(e,"package.json"),t=JSON.parse(ye(r,"utf-8"));t.dependencies=t.dependencies||{},t.devDependencies=t.devDependencies||{},t.dependencies.leaflet="^1.9.4",t.dependencies["react-leaflet"]="^5.0.0",t.devDependencies["@types/leaflet"]="^1.9.20",t.justoSpaceApp=!0,R(r,`${JSON.stringify(t,null,2)}
|
|
828
|
+
`)}function la(e){let r=w(e,"src","index.css"),t=ye(r,"utf-8");if(t.includes("leaflet/dist/leaflet.css"))return;R(r,`@import "leaflet/dist/leaflet.css";
|
|
829
|
+
${t}`)}function ma(e){let r=Gr(e);R(w(e,"README.md"),Pr(r)),R(w(e,"src","App.tsx"),Jr()),R(w(e,"src","main.tsx"),Mr()),R(w(e,"src","lib","justo.ts"),Wr()),R(w(e,Dr),`${JSON.stringify({template:"react-vite-shadcn",version:1},null,2)}
|
|
830
|
+
`),Be(w(e,".git"),{recursive:!0,force:!0})}function da(e){L("git",["init"],e)}function pa(e){Be(w(e,"package-lock.json"),{force:!0})}function _e(e){let r=zr(e);if(!be(r))throw Error(`No existe la app del space: ${r}`);if(!be(w(r,Dr)))throw Error("Este publish solo acepta apps creadas con team-cli spaces init. Debes apuntar al root de esa app.");return r}function Xr(e){let r=_e(e);L(_("yarn"),["build"],r);let t=w(r,"dist");if(!be(w(t,"index.html")))throw Error("El build no generó dist/index.html");return t}function Hr(e){let r=na(e),t=Fr(r),o=Gr(r);return L(_("npx"),["shadcn@latest","init","-t","vite","-d","-y","-n",o],t),L(_("npx"),["shadcn@latest","add","-a","-y"],r),pa(r),ua(r),L(_("yarn"),["install"],r),sa(r),ca(r),la(r),ma(r),da(r),{path:r,nextSteps:[`cd ${r}`,'git add . && git commit -m "chore: initial space scaffold"',"team-cli spaces create --name '...' --description '...' --slug dashboard-1234","team-cli spaces publish <spaceId> --path .",'git add . && git commit -m "feat: update published space"']}}function Zr(e){let r=[],t="",o=null,a=!1;for(let i of e){if(a){t+=i,a=!1;continue}if(i==="\\"){a=!0;continue}if(o){if(i===o)o=null;else t+=i;continue}if(i==='"'||i==="'"){o=i;continue}if(/\s/.test(i)){if(t)r.push(t),t="";continue}t+=i}if(o)throw Error("Comando inválido: falta cerrar una comilla");if(t)r.push(t);return r}var xa=".justo-space-preview",$a="preview.json",Ea=30000;function Ie(e){return qe(e,xa)}function ot(e){return qe(Ie(e),$a)}function kr(e){return qe(Ie(e),"bridge.log")}function Yr(e){return qe(Ie(e),"vite.log")}function at(e){fa(Ie(e),{recursive:!0})}function Ce(e){if(!e)return;try{process.kill(e,"SIGTERM")}catch{return}}function Sa(e){if(process.platform==="darwin")return{command:"open",args:[e]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",e]};return{command:"xdg-open",args:[e]}}async function ja(e,r){if(!r)return{attempted:!1,opened:!1};let t=Sa(e);return await new Promise((o)=>{let a=he(t.command,t.args,{stdio:"ignore",detached:!0});a.once("error",()=>{o({attempted:!0,opened:!1,message:"No se pudo abrir el navegador por defecto automáticamente. Abre la URL manualmente."})}),a.once("spawn",()=>{a.unref(),o({attempted:!0,opened:!0})})})}function va(e){let r=ot(e);if(!ga(r))return;try{let t=JSON.parse(ba(r,"utf-8"));Ce(t.appPid),Ce(t.bridgePid)}catch{}ya(r,{force:!0})}function Vr(){return new Promise((e,r)=>{let t=rt();t.listen(0,"127.0.0.1",()=>{let o=t.address();if(!o||typeof o==="string"){t.close(),r(Error("No se pudo obtener un puerto libre"));return}let{port:a}=o;t.close((i)=>{if(i){r(i);return}e(a)})}),t.on("error",r)})}function Kr(e){return new Promise((r)=>setTimeout(r,e))}function Aa(e){return new Promise((r,t)=>{let i=(new URL(e).protocol==="https:"?Ia:qa)(e,{method:"GET"},(n)=>{r(n.statusCode||0),n.resume()});i.on("error",t),i.end()})}async function Lr(e,r=Ea){let t=Date.now();while(Date.now()-t<r){try{if(await Aa(e)>0)return}catch{await Kr(500);continue}await Kr(500)}throw Error(`Timeout esperando que el preview responda en ${e}`)}function Ra(e){return at(ha(e)),wa(e,"a")}function et(e,r,t,o,a){let i=Ra(o),n=he(e,r,{cwd:t,detached:!0,stdio:["ignore",i,i],env:{...process.env,...a}});if(!n.pid)throw Error(`No se pudo iniciar el proceso ${e}`);return n.unref(),n.pid}function it(){let e=ir("prod");if(!e)throw Error("Debes iniciar sesión en prod antes de usar spaces preview. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>");return e}async function Na(e){let r=[];for await(let t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return Buffer.concat(r).toString("utf-8")}function ee(e,r,t){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8","Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"Content-Type","Access-Control-Allow-Methods":"POST,OPTIONS,GET"}),e.end(JSON.stringify(t))}function Je(e){let r=e.trim(),t=new Set([0]);for(let a=0;a<r.length;a++)if(r[a]==="{"||r[a]==="[")t.add(a);let o=[...t].sort((a,i)=>i-a);for(let a of o)try{return JSON.parse(r.slice(a))}catch{continue}return r}function nt(e){return{...process.env,NODE_OPTIONS:"",__JUSTO_REPL_PORT:"",JUSTO_TEAM_CLI_EMAIL:e.email,JUSTO_TEAM_CLI_TOKEN:e.token,JUSTO_TEAM_CLI_REFRESH_TOKEN:e.refreshToken,JUSTO_TEAM_CLI_INTERACTIVE:"false",JUSTO_TEAM_CLI_DEVICE_ID:"spaces-preview"}}function Ta(e,r){return{VITE_JUSTO_CLI_ENDPOINT:e,VITE_JUSTO_STREAM_ENDPOINT:r,VITE_JUSTO_CLI_MODE:"preview",[K]:fe}}function Oa(e,r,t,o){return new Promise((a,i)=>{let n=he(we(),[r,"--env","prod",...o,"--format","json"],{cwd:process.cwd(),env:nt(t),stdio:["ignore","pipe","pipe"]}),s="";n.stdout.on("data",(c)=>{if(!e.headersSent)e.writeHead(200,{"Content-Type":"application/x-ndjson; charset=utf-8","Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"Content-Type","Access-Control-Allow-Methods":"POST,OPTIONS,GET"});e.write(c)}),n.stderr.on("data",(c)=>{s+=Buffer.from(c).toString("utf-8")}),n.on("error",i),n.on("close",(c)=>{if(!c){if(!e.headersSent)e.writeHead(200,{"Content-Type":"application/x-ndjson; charset=utf-8","Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"Content-Type","Access-Control-Allow-Methods":"POST,OPTIONS,GET"});e.end(),a();return}let l=Je(s.trim());i(Error(l.error||s.trim()||"justoStream failed"))})})}async function st(e){let r=Number(e.port);if(!r)throw Error("Falta --port para el bridge interno de preview");let t=it(),o=tt(e["cli-path"]||process.argv[1]||""),a=rt(async(i,n)=>{if(i.method==="OPTIONS"){ee(n,200,{ok:!0});return}if(i.method==="GET"&&i.url==="/__justo/health"){ee(n,200,{ok:!0});return}if(i.method!=="POST"||i.url!=="/__justo/cli"&&i.url!=="/__justo/stream"){ee(n,404,{ok:!1,error:"Not found"});return}try{let s=await Na(i),l=JSON.parse(s||"{}").command;if(!l)throw Error("Debes indicar un comando");let m=Array.isArray(l)?l:Zr(l);if(i.url==="/__justo/stream"){await Oa(n,o,t,m);return}let p=await new Promise((d,b)=>{let f=he(we(),[o,"--env","prod",...m,"--format","json"],{cwd:process.cwd(),env:nt(t),stdio:["ignore","pipe","pipe"]}),T=[],O=[];f.stdout.on("data",(U)=>T.push(Buffer.from(U))),f.stderr.on("data",(U)=>O.push(Buffer.from(U))),f.on("error",b),f.on("close",(U)=>{let D=Buffer.concat(T).toString("utf-8")||Buffer.concat(O).toString("utf-8");if(U&&U!==0){let io=Je(D);b(Error(io.error||D||"justoCli failed"));return}d(Je(D))})});ee(n,200,{result:p})}catch(s){let c=s instanceof Error?s.message:"Unexpected error";ee(n,400,{error:c})}});await new Promise((i,n)=>{a.listen(r,"127.0.0.1",()=>i()),a.on("error",n)}),C(`Space preview bridge listening on http://127.0.0.1:${r}
|
|
831
|
+
`),await new Promise((i,n)=>{a.on("close",()=>i()),a.on("error",n)})}async function ct(e){let r=e.path;if(!r)throw Error("Falta --path. Ejemplo: team-cli spaces preview --path ./mi-space-app");let t=_e(r);it(),at(t),va(t);let o=Number(e.port)||await Vr(),a=Number(e["bridge-port"])||await Vr(),i=e.open==="true",n=`http://127.0.0.1:${o}`,s=`http://127.0.0.1:${a}/__justo/cli`,c=`http://127.0.0.1:${a}/__justo/stream`,l=tt(process.argv[1]||""),m=et(we(),[l,"__spaces-preview-bridge","--port",String(a),"--cli-path",l],process.cwd(),kr(t),{}),p=et(_("yarn"),["dev","--host","127.0.0.1","--port",String(o)],t,Yr(t),Ta(s,c));try{await Lr(`http://127.0.0.1:${a}/__justo/health`),await Lr(n)}catch(f){throw Ce(p),Ce(m),f}let d={appPid:p,bridgePid:m,previewUrl:n,bridgeUrl:s,streamUrl:c,cliEnv:"prod"};Ca(ot(t),`${JSON.stringify(d,null,2)}
|
|
832
|
+
`);let b=await ja(n,i);return{ok:!0,path:t,previewUrl:n,bridgeUrl:s,streamUrl:c,cliEnv:"prod",appPid:p,bridgePid:m,logs:{app:Yr(t),bridge:kr(t)},open:b}}import{writeFileSync as za}from"node:fs";import{mkdtempSync as Ua,readFileSync as Qa,rmSync as Ba,writeFileSync as _a}from"node:fs";import{tmpdir as Ja}from"node:os";import{join as ut}from"node:path";import{spawnSync as Wa}from"node:child_process";function Pa(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function lt(e,r){if(e==null)return;if(!Array.isArray(e)||e.some((t)=>typeof t!=="string"))throw Error(`${r} debe ser un arreglo de strings.`);return e}function Ma(e){if(!Array.isArray(e))throw Error("variables debe ser un arreglo.");return e.map((r,t)=>{if(!r||typeof r!=="object"||Array.isArray(r))throw Error(`variables[${t}] debe ser un objeto.`);let o=r;if(typeof o.key!=="string"||!o.key)throw Error(`variables[${t}].key debe ser un string no vacío.`);if(typeof o.fieldType!=="string"||!o.fieldType)throw Error(`variables[${t}].fieldType debe ser un string no vacío.`);if(o.fieldParams!=null&&typeof o.fieldParams!=="string")throw Error(`variables[${t}].fieldParams debe ser un string.`);return{key:o.key,fieldType:o.fieldType,fieldParams:typeof o.fieldParams==="string"?o.fieldParams:void 0}})}function Ga(e){if(!e||typeof e!=="object"||Array.isArray(e))throw Error("El archivo editado debe contener un objeto JSON.");let r=e;if(typeof r.name!=="string"||!r.name.trim())throw Error("name debe ser un string no vacío.");if(r.description!=null&&typeof r.description!=="string")throw Error("description debe ser un string.");if(typeof r.collection!=="string"||!r.collection.trim())throw Error("collection debe ser un string no vacío.");if(typeof r.pipeline!=="string")throw Error("pipeline debe ser un string.");return{name:r.name.trim(),description:r.description?.trim()||void 0,collection:r.collection.trim(),allowedUsersIds:lt(r.allowedUsersIds,"allowedUsersIds")??[],tags:lt(r.tags,"tags")??[],pipeline:r.pipeline,variables:Ma(r.variables)}}function mt(e){let r=process.env.VISUAL||process.env.EDITOR||"vi",t=Ua(ut(Ja(),"team-cli-query-")),o=ut(t,"aggregation-query.json");_a(o,`${JSON.stringify(e,null,2)}
|
|
833
|
+
`);let a=`${r} ${Pa(o)}`,i=Wa(a,{shell:!0,stdio:"inherit"});if(i.error)throw Error(`No se pudo abrir el editor "${r}": ${i.error.message}`);if(i.status!==0)throw Error(`El editor terminó con código ${i.status}.`);try{let n=Qa(o,"utf-8");if(!n.trim())throw Error("El archivo quedó vacío.");let s;try{s=JSON.parse(n)}catch{throw Error("El archivo editado no contiene JSON válido.")}return Ga(s)}finally{Ba(t,{recursive:!0,force:!0})}}function $(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}function N(e,r){let t=e[3];if(!t)throw Error(`Uso: ${r}`);return t}function re(e){if(!e.params)return{};try{return JSON.parse(e.params)}catch{throw Error("--params debe ser un JSON válido.")}}function dt(e){let r=e.limit;if(!r)throw Error("--limit es requerido. Ejemplo: --limit 1000");let t=Number(r);if(!Number.isInteger(t)||t<=0)throw Error("--limit debe ser un entero positivo.");return t}function pt(e){let r=e.emails;if(!r)throw Error("--emails es requerido. Ejemplo: --emails ana@justo.com,bob@justo.com");let t=r.split(",").map((a)=>a.trim().toLowerCase()).filter(Boolean);if(!t.length)throw Error("--emails debe contener al menos un email.");let o=t.find((a)=>!a.includes("@"));if(o)throw Error(`Email inválido: ${o}`);return[...new Set(t)]}function We(e){if(typeof e!=="string")return e;try{return JSON.parse(e)}catch{return{value:e}}}async function z(e){return(await u({service:"data",query:`query ($aggregationQueryId: String) {
|
|
834
834
|
aggregationQuery(aggregationQueryId: $aggregationQueryId) {
|
|
835
835
|
_id
|
|
836
836
|
name
|
|
@@ -856,7 +856,7 @@ ${t}`)}function la(e){let r=Gr(e);R(w(e,"README.md"),Pr(r)),R(w(e,"src","App.tsx
|
|
|
856
856
|
}
|
|
857
857
|
}`,variables:{filter:t,limit:10}})).justoUsers?.items?.find((i)=>i.email?.toLowerCase()===t);if(!a?._id)throw Error(`No encontramos un usuario de Justo para ${t}`);return a}))}function ft(e){return{name:e.name,description:e.description,collection:e.collection,allowedUsersIds:e.allowedUsersIds??[],tags:e.tags??[],pipeline:e.pipeline,variables:e.variables??[]}}async function Pe(e,r){let t=await u({service:"data",query:`mutation ($aggregationQueryId: String, $params: JSON) {
|
|
858
858
|
testAggregationQuery(aggregationQueryId: $aggregationQueryId, params: $params)
|
|
859
|
-
}`,variables:{aggregationQueryId:e,params:r}});return We(t.testAggregationQuery)}function
|
|
859
|
+
}`,variables:{aggregationQueryId:e,params:r}});return We(t.testAggregationQuery)}function Fa(e){try{return JSON.parse(e).error||e}catch{return e}}async function wt(e,r,t){let o=await fetch(`${h("data")}/aggregation-queries/${e}/run`,{method:"POST",headers:await Oe(),body:JSON.stringify({params:r,limit:t}),signal:AbortSignal.timeout(315000)});if(!o.ok){let l=await o.text();throw Error(Fa(l)||"No se pudo ejecutar el query.")}if(!o.body)throw Error("El servidor no devolvió un stream de datos.");let a=o.body.getReader(),i=new TextDecoder,n="",s=0;while(!0){let{done:l,value:m}=await a.read();if(l)break;let p=i.decode(m,{stream:!0});process.stdout.write(p),n+=p;let d=n.indexOf(`
|
|
860
860
|
`);while(d>=0){if(n.slice(0,d).trim())s++;n=n.slice(d+1),d=n.indexOf(`
|
|
861
861
|
`)}}let c=i.decode();if(c)process.stdout.write(c),n+=c;if(n.trim())s++;return{ok:!0,queryId:e,limit:t,rows:s}}async function Me(e,r){await Ge(e,{name:r.name,description:r.description,collection:r.collection,allowedUsersIds:r.allowedUsersIds,tags:r.tags}),await u({service:"data",query:`mutation ($aggregationQueryId: String, $pipeline: String, $variables: [AggregationQueryVariableInput]) {
|
|
862
862
|
addAggregationQueryVersion(
|
|
@@ -896,7 +896,7 @@ ${t}`)}function la(e){let r=Gr(e);R(w(e,"README.md"),Pr(r)),R(w(e,"src","App.tsx
|
|
|
896
896
|
fieldParams
|
|
897
897
|
}
|
|
898
898
|
}
|
|
899
|
-
}`})).createAggregationQuery}function
|
|
899
|
+
}`})).createAggregationQuery}function Da(e){if(!Array.isArray(e))throw Error("El preview del query debe devolver un arreglo para usar AI edit.");return e}async function Xa(e){let r=await u({service:"messenger",query:`mutation generateAdminQuery(
|
|
900
900
|
$prompt: String
|
|
901
901
|
$name: String
|
|
902
902
|
$description: String
|
|
@@ -922,13 +922,17 @@ ${t}`)}function la(e){let r=Gr(e);R(w(e,"README.md"),Pr(r)),R(w(e,"src","App.tsx
|
|
|
922
922
|
aggregationDescription
|
|
923
923
|
aggregationName
|
|
924
924
|
}
|
|
925
|
-
}`,variables:e});if(!r.generateAdminQuery?.pipeline||!r.generateAdminQuery.fullCollectionName)throw Error("La IA no devolvió una versión válida del query.");return r.generateAdminQuery}async function
|
|
926
|
-
|
|
927
|
-
|
|
925
|
+
}`,variables:e});if(!r.generateAdminQuery?.pipeline||!r.generateAdminQuery.fullCollectionName)throw Error("La IA no devolvió una versión válida del query.");return r.generateAdminQuery}async function Ha(e){let r=await u({service:"messenger",timeoutMs:120000,query:`mutation explainAdminQuery($prompt: String) {
|
|
926
|
+
explainAdminQuery(prompt: $prompt) {
|
|
927
|
+
responseText
|
|
928
|
+
}
|
|
929
|
+
}`,variables:{prompt:e}});if(!r.explainAdminQuery?.responseText)throw Error("La IA no devolvió una explicación válida.");return r.explainAdminQuery}async function yt(){return $(),await bt()}async function Ct(e){$();let r=e.prompt||await F("Explica qué query quieres investigar o construir: ");if(!r)throw Error("Debes indicar un prompt para explain.");return(await Ha(r)).responseText}async function ht(e){$();let r=N(e,"team-cli data queries edit <queryId>"),t=await z(r),o=mt(ft(t));return await Me(r,o),{ok:!0,queryId:r,name:o.name,collection:o.collection}}async function qt(e,r){$();let t=N(e,"team-cli data queries ai-edit <queryId> --prompt '<texto>' [--params '<json>']"),o=await z(t),a=r.prompt||await F("Describe los cambios para la IA: ");if(!a)throw Error("Debes indicar un prompt para AI edit.");let i=re(r),n;if(r.params){C(`Obteniendo preview del query actual...
|
|
930
|
+
`);try{let c=await Pe(t,i);n=Da(c)}catch(c){let l=c instanceof Error?c.message:String(c);throw Error(`No se pudo obtener el preview para AI edit: ${l}`)}}C(`Generando propuesta con IA...
|
|
931
|
+
`);let s=await Xa({prompt:a,fullCollectionName:o.collection,pipeline:o.pipeline,preview:n,description:o.description,name:o.name,variables:o.variables});return await Me(t,{name:o.name==="Nuevo query"?s.aggregationName||o.name:o.name,description:o.description||s.aggregationDescription,collection:s.fullCollectionName,allowedUsersIds:o.allowedUsersIds??[],tags:o.tags??[],pipeline:s.pipeline,variables:s.variables??[]}),{ok:!0,queryId:t,responseText:s.responseText,collection:s.fullCollectionName,name:s.aggregationName,description:s.aggregationDescription}}async function It(e){$();let r=N(e,"team-cli data queries view <queryId>");return await z(r)}async function xt(e){$();let r=N(e,"team-cli data queries view-pipeline <queryId>"),t=await z(r);return{queryId:r,pipeline:t.pipeline}}async function $t(e,r){$();let t=N(e,"team-cli data queries preview <queryId> --params '<json>'"),o=re(r),a=await Pe(t,o);return We(a)}async function Et(e,r){$();let t=N(e,"team-cli data queries run <queryId> --limit <n> --params '<json>'"),o=re(r),a=dt(r);return await wt(t,o,a),{__streamHandled:!0}}async function St(e,r){$();let t=N(e,"team-cli data queries add-viewers <queryId> --emails 'ana@justo.com,bob@justo.com'"),o=pt(r),a=await z(t),i=await gt(o),n=[...new Set([...a.allowedUsersIds??[],...i.map((s)=>s._id)])];return await Ge(t,{name:a.name,description:a.description,collection:a.collection,allowedUsersIds:n,tags:a.tags??[]}),{ok:!0,queryId:t,addedViewers:i.map((s)=>({_id:s._id,email:s.email,fullName:s.fullName})),allowedUsersIds:n}}function Za(e){return new Promise((r)=>setTimeout(r,e))}async function jt(e,r){$();let t=N(e,"team-cli data queries download <queryId> --params '<json>'"),o=re(r);if(!r.path)throw Error("--path es requerido. Ejemplo: --path resultado.xlsx");C(`Iniciando descarga...
|
|
928
932
|
`);let i=(await u({service:"data",query:`mutation ($aggregationQueryId: String, $params: JSON) {
|
|
929
933
|
downloadAggregationQueryData(aggregationQueryId: $aggregationQueryId, params: $params)
|
|
930
934
|
}`,variables:{aggregationQueryId:t,params:o}})).downloadAggregationQueryData;C(`Reporte en proceso (${i})...
|
|
931
|
-
`);let n=null;while(!n){await
|
|
935
|
+
`);let n=null;while(!n){await Za(1000);let l=await u({service:"data",query:`query ($id: String) {
|
|
932
936
|
getAsyncReport(id: $id) {
|
|
933
937
|
_id
|
|
934
938
|
status
|
|
@@ -938,20 +942,32 @@ ${t}`)}function la(e){let r=Gr(e);R(w(e,"README.md"),Pr(r)),R(w(e,"src","App.tsx
|
|
|
938
942
|
getAsyncReportRecordsCount(id: $id)
|
|
939
943
|
}`,variables:{id:i}}),m=l.getAsyncReport,p=l.getAsyncReportRecordsCount;if(m.status==="error")throw Error("El reporte falló al generarse.");if(m.fileUrl)n=m.fileUrl;else{let d=m.estimatedRecordsCount?` (~${m.estimatedRecordsCount} registros)`:"",b=p!=null?` ${p} procesados`:"";C(`\rGenerando...${d}${b}`)}}C(`
|
|
940
944
|
Descargando archivo...
|
|
941
|
-
`);let s=await fetch(n);if(!s.ok)throw Error(`Error descargando archivo: ${s.status}`);let c=Buffer.from(await s.arrayBuffer());return
|
|
945
|
+
`);let s=await fetch(n);if(!s.ok)throw Error(`Error descargando archivo: ${s.status}`);let c=Buffer.from(await s.arrayBuffer());return za(r.path,c),{ok:!0,queryId:t,asyncReportId:i,outputPath:r.path,fileUrl:n}}function Fe(){return`team-cli data
|
|
942
946
|
|
|
943
947
|
Comandos de datos y reportes.
|
|
944
948
|
|
|
945
949
|
Recomendado:
|
|
946
|
-
Si necesitas obtener data y no existe un query listo, usa create
|
|
947
|
-
Flujo sugerido: create -> ai-edit -> preview -> run o download.
|
|
950
|
+
Si necesitas obtener data y no existe un query listo, usa explain -> create -> ai-edit.
|
|
951
|
+
Flujo sugerido: explain -> create -> ai-edit -> preview -> run o download.
|
|
948
952
|
Siempre que puedas, prefiere varias queries simples antes que un solo pipeline con lookup.
|
|
949
953
|
Para dashboards suele ser mejor resolver joins en la UI o con queries separadas.
|
|
950
954
|
|
|
951
955
|
Uso:
|
|
952
|
-
team-cli data
|
|
956
|
+
team-cli data <subcomando> [opciones]
|
|
953
957
|
|
|
954
958
|
Subcomandos:
|
|
959
|
+
explain
|
|
960
|
+
Pedir una explicación guiada para investigar cómo construir un query usando el subagente de repo.
|
|
961
|
+
Uso: team-cli data explain --prompt '<texto>' [--format toon|json]
|
|
962
|
+
Solo disponible para usuarios con rol queries.
|
|
963
|
+
|
|
964
|
+
queries
|
|
965
|
+
Administrar y ejecutar aggregation queries.
|
|
966
|
+
|
|
967
|
+
Uso de queries:
|
|
968
|
+
team-cli data queries <subcomando> [opciones]
|
|
969
|
+
|
|
970
|
+
Subcomandos de queries:
|
|
955
971
|
create
|
|
956
972
|
Crear un query nuevo.
|
|
957
973
|
Devuelve el _id para seguir con edit, ai-edit, view o preview.
|
|
@@ -999,6 +1015,7 @@ Opciones:
|
|
|
999
1015
|
--path <filepath> Requerido para download
|
|
1000
1016
|
|
|
1001
1017
|
Ejemplos:
|
|
1018
|
+
team-cli data explain --prompt 'Quiero entender dónde viven los campos de courier de los pedidos'
|
|
1002
1019
|
team-cli data queries create
|
|
1003
1020
|
team-cli data queries edit abc123
|
|
1004
1021
|
team-cli data queries ai-edit abc123 --prompt 'Filtra solo ordenes canceladas'
|
|
@@ -1006,7 +1023,7 @@ Ejemplos:
|
|
|
1006
1023
|
team-cli data queries preview abc123 --params '{"startDate": "2026-01-01"}'
|
|
1007
1024
|
team-cli data queries run abc123 --limit 1000 --params '{"startDate": "2026-01-01"}'
|
|
1008
1025
|
team-cli data queries download abc123 --params '{"startDate": "2026-01-01"}' --path resultado.xlsx
|
|
1009
|
-
team-cli data queries add-viewers abc123 --emails 'ana@justo.com,bob@justo.com'`}var
|
|
1026
|
+
team-cli data queries add-viewers abc123 --emails 'ana@justo.com,bob@justo.com'`}var vt=["main","auth","webdata","preferences","buckets","reservations","data","finances","url-shortener","files","tabs","commander","experiments","sales","delivery","payments","addresses","royalty","marketing","api","messenger","invoice","drivers-server"],At=`
|
|
1010
1027
|
query ResolverInfo($name: ID!, $mutation: Boolean!) {
|
|
1011
1028
|
params(name: $name, mutation: $mutation) {
|
|
1012
1029
|
name
|
|
@@ -1015,8 +1032,8 @@ Ejemplos:
|
|
|
1015
1032
|
basicResultQuery
|
|
1016
1033
|
}
|
|
1017
1034
|
}
|
|
1018
|
-
`;function
|
|
1019
|
-
`)}function
|
|
1035
|
+
`;function ka(e){if(!e)throw Error("Uso: team-cli graphql <servicio> '<query>' [--variables '<json>'] [--format toon|json]");if(!vt.includes(e))throw Error(`Servicio "${e}" no válido. Servicios disponibles: ${vt.join(", ")}`)}async function Ya(e,r){let t;try{let o=await u({service:e,query:At,variables:{name:r,mutation:!1}});return{service:e,operationName:r,operationType:"query",info:o.params}}catch(o){t=o}try{let o=await u({service:e,query:At,variables:{name:r,mutation:!0}});return{service:e,operationName:r,operationType:"mutation",info:o.params}}catch(o){let a=t instanceof Error?t.message:"",i=o instanceof Error?o.message:"";if(a.includes('Cannot query field "params"')||i.includes('Cannot query field "params"'))throw Error(`El servicio "${e}" no expone metadata de resolvers por GraphQL.`);throw t instanceof Error?t:o}}async function Rt(e,r){let t=e[1],o=e[2],a=e[2];if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>");if(ka(t),o==="info"){let s=e[3];if(!s)throw Error("Uso: team-cli graphql <servicio> info <queryName|mutationName> [--format toon|json]");return await Ya(t,s)}if(!a)throw Error("Uso: team-cli graphql <servicio> '<query>' [--variables '<json>'] [--format toon|json]");let i;if(r.variables)try{i=JSON.parse(r.variables)}catch{throw Error("Las variables deben ser un JSON válido.")}return await u({service:t,query:a,variables:i})}function Nt(){return Object.keys(ce)}function Va(){return Nt().map((e)=>{let r=ce[e].prod;return`- \`${e}\`: \`${r}/graphql\``}).join(`
|
|
1036
|
+
`)}function Tt(){let r=Nt().join(", "),t=Va();return`team-cli graphql
|
|
1020
1037
|
|
|
1021
1038
|
Ejecutar queries y mutations GraphQL.
|
|
1022
1039
|
|
|
@@ -1067,7 +1084,7 @@ npx @getjusto/team-cli graphql auth info requestLoginCode --format json
|
|
|
1067
1084
|
|
|
1068
1085
|
Usa esto para mapear una URL GraphQL al valor correcto de \`team-cli graphql <service>\`.
|
|
1069
1086
|
|
|
1070
|
-
${t}`}import{existsSync as
|
|
1087
|
+
${t}`}import{existsSync as xi,mkdirSync as $i,readdirSync as Ei}from"node:fs";import{resolve as Ht}from"node:path";import{readdirSync as Bt,readFileSync as _t,statSync as Jt}from"node:fs";import{gzipSync as ni}from"node:zlib";import{join as Wt,relative as Pt,resolve as Ut}from"node:path";import{existsSync as Ka,readFileSync as La}from"node:fs";import{join as ei}from"node:path";var ri=[".git","node_modules","dist",".justo-space-preview",".DS_Store"];function ti(e){return e.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}function oi(e){let r="";for(let t=0;t<e.length;t++){let o=e[t],a=e[t+1];if(o==="*"){if(a==="*"){r+=".*",t+=1;continue}r+="[^/]*";continue}if(o==="?"){r+="[^/]";continue}r+=ti(o)}return r}function ai(e){let r=e.trim();if(!r||r.startsWith("#"))return null;let t=r.startsWith("!"),o=t?r.slice(1).trim():r;if(!o)return null;let a=o.endsWith("/"),i=o.replace(/^\/+/,"").replace(/\/+$/,"");if(!i)return null;let n=i.includes("/"),s=oi(i),c=n?`^${s}${a?"(?:/.*)?":""}$`:`(?:^|/)${s}${a?"(?:/.*)?":"(?:$|/)"}`;return{negate:t,directoryOnly:a,regex:new RegExp(c)}}function ii(e){let r=ei(e,".gitignore"),t=[...ri];if(Ka(r))t.push(...La(r,"utf-8").split(/\r?\n/));return t.map(ai).filter((o)=>Boolean(o))}function Ot(e){let r=ii(e);return(t,o)=>{let a=t.replaceAll("\\","/").replace(/^\/+/,""),i=!1;for(let n of r){if(!n.regex.test(a))continue;i=!n.negate}return i}}var xe=512,si=2,ci="repo",ui="dist";function li(e){let r=e.replaceAll("\\","/");if(r.startsWith("/")||r.includes("../"))throw Error(`Ruta inválida en el space: ${e}`);return r}function mi(e){let r=li(e);if(Buffer.from(r).length<=100)return{name:r,prefix:""};let o=r.lastIndexOf("/");if(o<=0)throw Error(`La ruta es demasiado larga para el paquete del space: ${e}`);let a=r.slice(0,o),i=r.slice(o+1);if(Buffer.from(a).length>155||Buffer.from(i).length>100)throw Error(`La ruta es demasiado larga para el paquete del space: ${e}`);return{name:i,prefix:a}}function J(e,r,t,o){let a=Buffer.from(o);a.copy(e,r,0,Math.min(a.length,t))}function te(e,r,t,o){let a=Math.max(0,Math.trunc(o)).toString(8).padStart(t-1,"0");J(e,r,t,`${a}\x00`)}function di(e){let r=Buffer.alloc(xe,0),{name:t,prefix:o}=mi(e.path);J(r,0,100,t),te(r,100,8,e.mode),te(r,108,8,0),te(r,116,8,0),te(r,124,12,e.content.length),te(r,136,12,e.mtime),r.fill(32,148,156),J(r,156,1,"0"),J(r,257,6,"ustar"),J(r,263,2,"00"),J(r,345,155,o);let a=0;for(let n of r)a+=n;let i=`${a.toString(8).padStart(6,"0")}\x00 `;return J(r,148,8,i),r}function pi(e){let r=e%xe;return r===0?0:xe-r}function Mt(e,r=e){return Bt(r,{withFileTypes:!0}).sort((o,a)=>o.name.localeCompare(a.name)).flatMap((o)=>{let a=Wt(r,o.name);if(o.isDirectory())return Mt(e,a);if(!o.isFile())return[];let i=Pt(e,a),n=Jt(a);return[{path:i,content:_t(a),mode:n.mode&511,mtime:Math.floor(n.mtimeMs/1000)}]})}function Qt(e,r){return e.map((t)=>({...t,path:`${r}/${t.path.replaceAll("\\","/")}`}))}function Gt(e,r=e){let t=Ot(e);return Bt(r,{withFileTypes:!0}).sort((a,i)=>a.name.localeCompare(i.name)).flatMap((a)=>{let i=Wt(r,a.name),n=Pt(e,i).replaceAll("\\","/");if(t(n,a.isDirectory()))return[];if(a.isDirectory())return Gt(e,i);if(!a.isFile())return[];let s=Jt(i);return[{path:n,content:_t(i),mode:s.mode&511,mtime:Math.floor(s.mtimeMs/1000)}]})}function Ft(e,r){let t=Ut(e),o=Ut(r),a=[...Qt(Gt(t),ci),...Qt(Mt(o),ui)];if(!a.length)throw Error("El build del space no contiene archivos para publicar");let i=[];for(let n of a){i.push(di(n)),i.push(n.content);let s=pi(n.content.length);if(s>0)i.push(Buffer.alloc(s,0))}return i.push(Buffer.alloc(xe*si,0)),ni(Buffer.concat(i))}import{mkdirSync as zt,writeFileSync as gi}from"node:fs";import{dirname as fi,join as wi,normalize as bi,sep as Dt}from"node:path";import{gunzipSync as yi}from"node:zlib";var oe=512;function $e(e,r,t){let o=e.subarray(r,r+t),a=o.indexOf(0);return(a>=0?o.subarray(0,a):o).toString("utf-8").trim()}function Ci(e,r,t){let o=$e(e,r,t).replaceAll("\x00","").trim();if(!o)return 0;return Number.parseInt(o,8)}function hi(e){let r=e%oe;return r===0?0:oe-r}function qi(e){let r=$e(e,0,100),t=$e(e,345,155);return t?`${t}/${r}`:r}function Ii(e){let r=bi(e);if(!e||e.startsWith("/")||r.startsWith("..")||r.includes(`${Dt}..${Dt}`)||r==="..")throw Error("El paquete del space contiene rutas inválidas")}function Xt(e,r,t){let o=yi(e),a=r.replaceAll("\\","/").replace(/^\/+|\/+$/g,""),i=`${a}/`,n=0,s=0;while(n+oe<=o.length){let c=o.subarray(n,n+oe),l=c.every((O)=>O===0);if(n+=oe,l)break;let m=qi(c),p=$e(c,156,1)||"0",d=Ci(c,124,12),b=o.subarray(n,n+d);if(n+=d+hi(d),!m.startsWith(i))continue;let f=m.slice(i.length);if(!f)continue;Ii(f);let T=wi(t,...f.split("/"));if(p==="5"){zt(T,{recursive:!0});continue}if(p!=="0")continue;zt(fi(T),{recursive:!0}),gi(T,b),s+=1}if(!s)throw Error(`El paquete del space no contiene la carpeta ${a}/`);return s}function Ee(){if(!g())throw Error("Debes iniciar sesión primero. Recomendado: team-cli auth request-code --email <email> y luego team-cli auth login-with-token --email <email> --token <token> --code <CODIGO>")}function ae(e,r,t){let o=e[r];if(!o)throw Error(`Falta --${r}. Ejemplo: ${t}`);return o}function Zt(e,r){let t=e[2];if(!t)throw Error(`Uso: ${r}`);return t}function ze(){let e=ue();if(e==="local")return"http://intra.localhost:5173";if(e==="develop")return"https://intra.bejusto.com";return"https://intra.getjusto.com"}async function Si(e,r){let t=await de(),o=await fetch(`${h("data")}/spaces/publish/${e}`,{method:"POST",headers:{"Content-Type":"application/gzip",...t?{"X-ORION-JWT":t}:{}},body:r}),a=await o.json();if(!o.ok||a.error)throw Error(a.error||"No se pudo publicar el space.");return a}async function ji(e){let r=await de(),t=await fetch(`${h("data")}/spaces/fork/${e}`,{method:"GET",headers:r?{"X-ORION-JWT":r}:{}});if(!t.ok){let o=await t.json().catch(()=>({}));throw Error(o.error||"No se pudo descargar el repo del space.")}return Buffer.from(await t.arrayBuffer())}function vi(e){let r=Ht(e);if(xi(r)&&Ei(r).length>0)throw Error(`La carpeta ya existe y no está vacía: ${r}`);return $i(r,{recursive:!0}),r}function De(){return`team-cli spaces
|
|
1071
1088
|
|
|
1072
1089
|
Spaces son aplicaciones internas en React, pensadas para que las construyan agentes.
|
|
1073
1090
|
El flujo oficial parte con \`spaces init\` y \`spaces publish\` solo acepta apps creadas así.
|
|
@@ -1169,7 +1186,7 @@ Comandos:
|
|
|
1169
1186
|
- \`spaces publish <spaceId> --path ./mi-space-app\`
|
|
1170
1187
|
- \`spaces fork <slug> --path ./mi-space-app\`
|
|
1171
1188
|
- \`spaces archive <spaceId>\`
|
|
1172
|
-
`}async function
|
|
1189
|
+
`}async function kt(e){let r=ae(e,"path","team-cli spaces init --path ./mi-space-app");return Hr(r)}async function Yt(e){return await ct(e)}async function Vt(e){Ee();let r=ae(e,"name","team-cli spaces create --name 'Mi space' --description '...' --slug dashboard-1234"),t=ae(e,"description","team-cli spaces create --name 'Mi space' --description 'Sitio interno' --slug dashboard-1234"),o=ae(e,"slug","team-cli spaces create --name 'Mi space' --description '...' --slug dashboard-1234"),a=await u({service:"data",query:`mutation ($name: String, $description: String, $slug: String) {
|
|
1173
1190
|
createSpace(name: $name, description: $description, slug: $slug) {
|
|
1174
1191
|
_id
|
|
1175
1192
|
name
|
|
@@ -1180,7 +1197,7 @@ Comandos:
|
|
|
1180
1197
|
createdByEmail
|
|
1181
1198
|
createdById
|
|
1182
1199
|
}
|
|
1183
|
-
}`,variables:{name:r,description:t,slug:o}});return{...a.createSpace,intraUrl:`${ze()}/spaces/${a.createSpace.slug}`,serveUrl:`${h("data")}/spaces/${a.createSpace.slug}`}}async function
|
|
1200
|
+
}`,variables:{name:r,description:t,slug:o}});return{...a.createSpace,intraUrl:`${ze()}/spaces/${a.createSpace.slug}`,serveUrl:`${h("data")}/spaces/${a.createSpace.slug}`}}async function Kt(e,r){Ee();let t=Zt(e,"team-cli spaces publish <spaceId> --path ./mi-space-app"),o=ae(r,"path","team-cli spaces publish <spaceId> --path ./mi-space-app"),a=Xr(o),i=Ft(o,a),n=await Si(t,i);return{...n,intraUrl:n.slug?`${ze()}/spaces/${n.slug}`:void 0,serveUrl:n.slug?`${h("data")}/spaces/${n.slug}`:void 0,builtFrom:Ht(o)}}async function Lt(e,r){Ee();let t=e[2];if(!t)throw Error("Uso: team-cli spaces fork <slug> --path ./mi-space-app");let o=vi(r.path||`./${t}`),a=await ji(t),i=Xt(a,"repo",o);return{ok:!0,slug:t,path:o,extractedFiles:i,nextSteps:[`cd ${o}`,"yarn install","team-cli spaces preview --path . --open"]}}async function eo(e){Ee();let r=Zt(e,"team-cli spaces archive <spaceId>");return(await u({service:"data",query:`mutation ($spaceId: String) {
|
|
1184
1201
|
archiveSpace(spaceId: $spaceId) {
|
|
1185
1202
|
_id
|
|
1186
1203
|
name
|
|
@@ -1192,7 +1209,7 @@ Comandos:
|
|
|
1192
1209
|
createdById
|
|
1193
1210
|
archivedAt
|
|
1194
1211
|
}
|
|
1195
|
-
}`,variables:{spaceId:r}})).archiveSpace}function
|
|
1212
|
+
}`,variables:{spaceId:r}})).archiveSpace}function ro(e){return`team-cli
|
|
1196
1213
|
|
|
1197
1214
|
Herramienta CLI para el equipo Justo.
|
|
1198
1215
|
|
|
@@ -1237,11 +1254,11 @@ npx @getjusto/team-cli admin search <text> [--limit <n>] [--page <n>] [--only-ac
|
|
|
1237
1254
|
|
|
1238
1255
|
### Crea queries para usar en los dashboards
|
|
1239
1256
|
|
|
1240
|
-
Crea queries personalizadas usando \`create\` y \`ai-edit\` para generar consultas a la base de datos y luego crear un dashboard que las use
|
|
1257
|
+
Crea queries personalizadas usando \`data explain\`, \`data queries create\` y \`data queries ai-edit\` para generar consultas a la base de datos y luego crear un dashboard que las use
|
|
1241
1258
|
para mostrar datos. Usa \`preview\` para iterar rápido, \`run\` para consumir NDJSON en streaming y \`download\` para Excel.
|
|
1242
1259
|
También puedes usar queries para poblar selectores y otras partes de la interfaz del space.
|
|
1243
1260
|
Siempre que puedas, prefiere varias queries simples antes que un solo query con \`lookup\`.
|
|
1244
1261
|
Eso suele ser más fácil de iterar, más claro para agentes y menos frágil para dashboards.
|
|
1245
1262
|
Si el usuario pide compartir un dashboard con otra persona, normalmente lo que hay que hacer es compartir las queries que usa ese dashboard con \`data queries add-viewers\`.
|
|
1246
1263
|
|
|
1247
|
-
`}function
|
|
1264
|
+
`}function to(){let e=g(),r=e?`Sesión: ${e.email}`:"Sesión: no iniciada";return ro(r)}async function oo(e){let{positional:r,flags:t}=ie(e);if(t.env)rr(t.env);let o=r[0],a=r[1];if(o==="__spaces-preview-bridge")return await st(t);if(t.version)return{version:"0.0.10"};if(t.help&&!o)return to();if(o==="auth"){if(a==="--help"||t.help)return Qe();if(a==="login")return await Or();if(a==="login-with-token")return await Ur(t);if(a==="request-code")return await Qr(t);if(a==="logout")return await Br();if(a==="status")return await _r();return Qe()}if(o==="admin"){let i=r[1],n=r[2],s=r[3],c=r[4];if(!i||i==="--help")return pe();if(i==="search"&&t.help)return Ar();if(i==="search")return await vr(r,t);if(!n||n==="--help")return pe();if(n==="show")return await mr(i);if(n==="stores"&&s==="list")return await Rr(i);if(n==="coupons"&&(!s||s==="--help"))return V();if(n==="coupons"&&s==="create"&&t.help)return Sr();if(n==="coupons"&&s==="update"&&t.help)return jr();if(n==="coupons"&&s==="codes"&&r[4]==="create"&&t.help)return Cr();if(n==="coupons"&&t.help)return V();if(n==="coupons"&&s==="list")return await qr(i,t);if(n==="coupons"&&s==="show"){if(!c)throw Error("Uso: team-cli admin <web> coupons show <couponId>");return await Ir(i,c)}if(n==="coupons"&&s==="create")return await xr(i,t);if(n==="coupons"&&s==="update"){if(!c)throw Error("Uso: team-cli admin <web> coupons update <couponId> --input '<json>'");return await $r(i,c,t)}if(n==="coupons"&&s==="delete"){if(!c)throw Error("Uso: team-cli admin <web> coupons delete <couponId>");return await Er(i,c)}if(n==="coupons"&&s==="codes"){let l=r[4],m=r[5];if(!l||l==="--help")return V();if(l==="list"){if(!m)throw Error("Uso: team-cli admin <web> coupons codes list <couponId>");return await fr(i,m,t)}if(l==="create"){if(!m)throw Error("Uso: team-cli admin <web> coupons codes create <couponId> --input '<json>'");return await wr(i,m,t)}if(l==="create-random"){if(!m)throw Error("Uso: team-cli admin <web> coupons codes create-random <couponId> --quantity <n>");return await br(i,m,t)}if(l==="delete"){if(!m)throw Error(`Uso: team-cli admin <web> coupons codes delete <couponId> --ids '["id1"]'`);return await yr(i,m,t)}return V()}return pe()}if(o==="graphql"){if(a==="--help"||t.help)return Tt();return await Rt(r,t)}if(o==="data"){let i=r[1],n=r[2];if(t.help||a==="--help")return Fe();if(i==="explain")return await Ct(t);if(i==="queries"&&n==="create")return await yt();if(i==="queries"&&n==="edit")return await ht(r);if(i==="queries"&&n==="ai-edit")return await qt(r,t);if(i==="queries"&&n==="view")return await It(r);if(i==="queries"&&n==="view-pipeline")return await xt(r);if(i==="queries"&&n==="preview")return await $t(r,t);if(i==="queries"&&n==="run")return await Et(r,t);if(i==="queries"&&n==="add-viewers")return await St(r,t);if(i==="queries"&&n==="download")return await jt(r,t);return Fe()}if(o==="spaces"){let i=r[1];if(!i||i==="--help"||t.help)return De();if(i==="init")return await kt(t);if(i==="create")return await Vt(t);if(i==="preview")return await Yt(t);if(i==="publish")return await Kt(r,t);if(i==="fork")return await Lt(r,t);if(i==="archive")return await eo(r);return De()}return to()}var{flags:ao}=ie(process.argv.slice(2));async function Ai(){try{let e=await oo(process.argv.slice(2));if(e&&typeof e==="object"&&"__streamHandled"in e&&e.__streamHandled)return;if(typeof e==="string"){Le(e);return}Ke(e,ao)}catch(e){er(e,ao),process.exit(1)}}Ai();
|