@getjusto/team-cli 0.0.6 → 0.0.7
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 +100 -73
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function
|
|
3
|
-
`)}function
|
|
4
|
-
`)}function
|
|
2
|
+
function re(e){let t=[],o={},r={};for(let a=0;a<e.length;a++)if(e[a].startsWith("--")&&e[a+1]&&!e[a+1].startsWith("--")){let n=e[a].slice(2);if(o[n]=e[a+1],!r[n])r[n]=[];r[n].push(e[a+1]),a++}else if(e[a].startsWith("--"))o[e[a].slice(2)]="true";else t.push(e[a]);return{positional:t,flags:o,arrayFlags:r}}function F(e,t){let o=e[t];if(!o)throw Error(`--${t} es requerido.`);return o}var Mo={comma:",",tab:"\t",pipe:"|"},Y=Mo.comma;function Xe(e){return e.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function Po(e){return e==="true"||e==="false"||e==="null"}function E(e){if(e===null)return null;if(typeof e==="object"&&e!==null&&"toJSON"in e&&typeof e.toJSON==="function"){let t=e.toJSON();if(t!==e)return E(t)}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(E);if(e instanceof Set)return Array.from(e).map(E);if(e instanceof Map)return Object.fromEntries(Array.from(e,([t,o])=>[String(t),E(o)]));if(Go(e)){let t={};for(let o in e)if(Object.prototype.hasOwnProperty.call(e,o))t[o]=E(e[o]);return t}return null}function U(e){return e===null||typeof e==="string"||typeof e==="number"||typeof e==="boolean"}function T(e){return Array.isArray(e)}function q(e){return e!==null&&typeof e==="object"&&!Array.isArray(e)}function X(e){return Object.keys(e).length===0}function Go(e){if(e===null||typeof e!=="object")return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function H(e){return e.length===0||e.every((t)=>U(t))}function Fo(e){return e.length===0||e.every((t)=>T(t))}function He(e){return e.length===0||e.every((t)=>q(t))}function Xo(e){return/^[A-Z_][\w.]*$/i.test(e)}function Ho(e){return/^[A-Z_]\w*$/i.test(e)}function Zo(e,t=Y){if(!e)return!1;if(e!==e.trim())return!1;if(Po(e)||Yo(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(t))return!1;if(e.startsWith("-"))return!1;return!0}function Yo(e){return/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(e)||/^0\d+$/.test(e)}var Ha=Symbol("quotedKey");function Do(e,t,o,r,a,n,i){if(r.keyFolding!=="safe")return;if(!q(t))return;let{segments:s,tail:c,leafValue:m}=zo(e,t,i??r.flattenDepth);if(s.length<2)return;if(!s.every((p)=>Ho(p)))return;let l=ko(s),g=n?`${n}.${l}`:l;if(o.includes(l))return;if(a&&a.has(g))return;return{foldedKey:l,remainder:c,leafValue:m,segmentCount:s.length}}function zo(e,t,o){let r=[e],a=t;while(r.length<o){if(!q(a))break;let n=Object.keys(a);if(n.length!==1)break;let i=n[0],s=a[i];r.push(i),a=s}if(!q(a)||X(a))return{segments:r,tail:void 0,leafValue:a};return{segments:r,tail:a,leafValue:a}}function ko(e){return e.join(".")}function B(e,t){if(e===null)return"null";if(typeof e==="boolean")return String(e);if(typeof e==="number")return String(e);return Ko(e,t)}function Ko(e,t=Y){if(Zo(e,t))return e;return`"${Xe(e)}"`}function Z(e){if(Xo(e))return e;return`"${Xe(e)}"`}function Ze(e,t=Y){return e.map((o)=>B(o,t)).join(t)}function j(e,t){let o=t?.key,r=t?.fields,a=t?.delimiter??",",n="";if(o)n+=Z(o);if(n+=`[${e}${a!==Y?a:""}]`,r){let i=r.map((s)=>Z(s));n+=`{${i.join(a)}}`}return n+=":",n}function*Vo(e,t,o){if(U(e)){let r=B(e,t.delimiter);if(r!=="")yield r;return}if(T(e))yield*he(void 0,e,o,t);else if(q(e))yield*_(e,o,t)}function*_(e,t,o,r,a,n){let i=Object.keys(e);if(t===0&&!r)r=new Set(i.filter((c)=>c.includes(".")));let s=n??o.flattenDepth;for(let[c,m]of Object.entries(e))yield*Lo(c,m,t,o,i,r,a,s)}function*Lo(e,t,o,r,a,n,i,s){let c=i?`${i}.${e}`:e,m=s??r.flattenDepth;if(r.keyFolding==="safe"&&a){let g=Do(e,t,a,r,n,i,m);if(g){let{foldedKey:p,remainder:y,leafValue:w,segmentCount:oe}=g,W=Z(p);if(y===void 0){if(U(w)){yield b(o,`${W}: ${B(w,r.delimiter)}`,r.indent);return}else if(T(w)){yield*he(p,w,o,r);return}else if(q(w)&&X(w)){yield b(o,`${W}:`,r.indent);return}}if(q(y)){yield b(o,`${W}:`,r.indent);let R=m-oe,G=i?`${i}.${p}`:p;yield*_(y,o+1,r,n,G,R);return}}}let l=Z(e);if(U(t))yield b(o,`${l}: ${B(t,r.delimiter)}`,r.indent);else if(T(t))yield*he(e,t,o,r);else if(q(t)){if(yield b(o,`${l}:`,r.indent),!X(t))yield*_(t,o+1,r,n,c,m)}}function*he(e,t,o,r){if(t.length===0){yield b(o,j(0,{key:e,delimiter:r.delimiter}),r.indent);return}if(H(t)){yield b(o,ne(t,r.delimiter,e),r.indent);return}if(Fo(t)){if(t.every((a)=>H(a))){yield*er(e,t,o,r);return}}if(He(t)){let a=Ye(t);if(a)yield*tr(e,t,a,o,r);else yield*Fe(e,t,o,r);return}yield*Fe(e,t,o,r)}function*er(e,t,o,r){yield b(o,j(t.length,{key:e,delimiter:r.delimiter}),r.indent);for(let a of t)if(H(a)){let n=ne(a,r.delimiter);yield x(o+1,n,r.indent)}}function ne(e,t,o){let r=j(e.length,{key:o,delimiter:t}),a=Ze(e,t);if(e.length===0)return r;return`${r} ${a}`}function*tr(e,t,o,r,a){yield b(r,j(t.length,{key:e,fields:o,delimiter:a.delimiter}),a.indent),yield*De(t,o,r+1,a)}function Ye(e){if(e.length===0)return;let t=e[0],o=Object.keys(t);if(o.length===0)return;if(or(e,o))return o}function or(e,t){for(let o of e){if(Object.keys(o).length!==t.length)return!1;for(let r of t){if(!(r in o))return!1;if(!U(o[r]))return!1}}return!0}function*De(e,t,o,r){for(let a of e)yield b(o,Ze(t.map((n)=>a[n]),r.delimiter),r.indent)}function*Fe(e,t,o,r){yield b(o,j(t.length,{key:e,delimiter:r.delimiter}),r.indent);for(let a of t)yield*$e(a,o+1,r)}function*rr(e,t,o){if(X(e)){yield b(t,"-",o.indent);return}let r=Object.entries(e),[a,n]=r[0],i=r.slice(1);if(T(n)&&He(n)){let c=Ye(n);if(c){if(yield x(t,j(n.length,{key:a,fields:c,delimiter:o.delimiter}),o.indent),yield*De(n,c,t+2,o),i.length>0)yield*_(Object.fromEntries(i),t+1,o);return}}let s=Z(a);if(U(n))yield x(t,`${s}: ${B(n,o.delimiter)}`,o.indent);else if(T(n))if(n.length===0)yield x(t,`${s}${j(0,{delimiter:o.delimiter})}`,o.indent);else if(H(n))yield x(t,`${s}${ne(n,o.delimiter)}`,o.indent);else{yield x(t,`${s}${j(n.length,{delimiter:o.delimiter})}`,o.indent);for(let c of n)yield*$e(c,t+2,o)}else if(q(n)){if(yield x(t,`${s}:`,o.indent),!X(n))yield*_(n,t+2,o)}if(i.length>0)yield*_(Object.fromEntries(i),t+1,o)}function*$e(e,t,o){if(U(e))yield x(t,B(e,o.delimiter),o.indent);else if(T(e))if(H(e))yield x(t,ne(e,o.delimiter),o.indent);else{yield x(t,j(e.length,{delimiter:o.delimiter}),o.indent);for(let r of e)yield*$e(r,t+1,o)}else if(q(e))yield*rr(e,t,o)}function b(e,t,o){return" ".repeat(o*e)+t}function x(e,t,o){return b(e,"- "+t,o)}function ar(e,t){let o=t("",e,[]);if(o===void 0)return ae(e,t,[]);return ae(E(o),t,[])}function ae(e,t,o){if(q(e))return nr(e,t,o);if(T(e))return ir(e,t,o);return e}function nr(e,t,o){let r={};for(let[a,n]of Object.entries(e)){let i=[...o,a],s=t(a,n,i);if(s===void 0)continue;r[a]=ae(E(s),t,i)}return r}function ir(e,t,o){let r=[];for(let a=0;a<e.length;a++){let n=e[a],i=[...o,a],s=t(String(a),n,i);if(s===void 0)continue;let c=E(s);r.push(ae(c,t,i))}return r}function xe(e,t){return Array.from(sr(e,t)).join(`
|
|
3
|
+
`)}function sr(e,t){let o=E(e),r=cr(t);return Vo(r.replacer?ar(o,r.replacer):o,r,0)}function cr(e){return{indent:e?.indent??2,delimiter:e?.delimiter??Y,keyFolding:e?.keyFolding??"off",flattenDepth:e?.flattenDepth??Number.POSITIVE_INFINITY,replacer:e?.replacer}}function ur(e){let t=e.format??"toon";if(t!=="toon"&&t!=="json")throw Error("--format debe ser toon o json.");return t}function ze(e,t){if(ur(t)==="json"){console.log(JSON.stringify(e,null,2));return}console.log(xe(e))}function ke(e){process.stdout.write(`${e}
|
|
4
|
+
`)}function Ke(e,t){let r={ok:!1,error:e instanceof Error?e.message:String(e)};if((t.format==="json"?"json":"toon")==="json"){console.error(JSON.stringify(r,null,2));return}console.error(xe(r))}function C(e){process.stderr.write(e)}import{existsSync as ce,mkdirSync as dr,readFileSync as Le,writeFileSync as pr,unlinkSync as gr}from"node:fs";import{join as et}from"node:path";import{homedir as fr}from"node:os";import{AsyncLocalStorage as mr}from"node:async_hooks";var lr=new mr;function I(){return lr.getStore()}var ie={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"}},Se="prod";function Ve(e){Se=e}function se(){let e=process.env.JUSTO_TEAM_CLI_ENV;if(e)return e;let t=I()?.environment;if(t)return t;return Se}function h(e){return ie[e][Se]}var Ee=et(fr(),".justo-team");function tt(e){let t=e==="prod"?"credentials.json":`credentials.${e}.json`;return et(Ee,t)}function je(){return tt(se())}function wr(){if(!ce(Ee))dr(Ee,{recursive:!0})}function ue(e){let t=I();if(t&&t.canPersistCredentials===!1)throw Error("Este entorno no permite guardar credenciales.");wr(),pr(je(),JSON.stringify(e,null,2))}function d(){let e=process.env.JUSTO_TEAM_CLI_TOKEN,t=process.env.JUSTO_TEAM_CLI_EMAIL,o=process.env.JUSTO_TEAM_CLI_REFRESH_TOKEN;if(e&&t)return{email:t,token:e,refreshToken:o||""};let r=I()?.credentials;if(r!==void 0)return r?{email:r.email,token:r.token,refreshToken:r.refreshToken||""}:null;let a=je();if(!ce(a))return null;try{let n=Le(a,"utf-8");return JSON.parse(n)}catch{return null}}function ot(e){let t=tt(e);if(!ce(t))return null;try{let o=Le(t,"utf-8");return JSON.parse(o)}catch{return null}}function Ae(){let e=I();if(e&&e.canPersistCredentials===!1)throw Error("Este entorno no permite borrar credenciales.");let t=je();if(ce(t))gr(t)}import{existsSync as rt,readFileSync as br,writeFileSync as Cr,mkdirSync as yr}from"node:fs";import{join as at}from"node:path";import{homedir as qr}from"node:os";function Ir(){let e=process.env.JUSTO_TEAM_CLI_DEVICE_ID;if(e)return e;let t=I()?.deviceId;if(t)return t;let o=at(qr(),".justo-team"),r=at(o,"device-id");if(rt(r))return br(r,"utf-8").trim();let a=crypto.randomUUID();if(!rt(o))yr(o,{recursive:!0});return Cr(r,a),a}var it={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 hr(e,t){let o=it[e];if(!o)return`${t}: ${e}`;if(typeof o==="function")return o({label:t});return o}function nt(e){return Object.entries(e).map(([t,o])=>hr(o,t)).join(", ")}function $r(e){if(e.error==="validationError"&&e.validationErrors)return nt(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} (${nt(e.validationErrors)})`;let t=e.message||"Error desconocido",o=it[t];if(o)return typeof o==="function"?o({label:""}).trim():o;let r=e.error||e.code||e.type;return r?`${t} [${r}]`:t}function xr(e){try{return JSON.parse(Buffer.from(e.split(".")[1],"base64").toString()).exp*1000<Date.now()}catch{return!0}}async function Sr(){let e=d();if(!e?.refreshToken)return null;let t=`${h("auth")}/refresh-token`,r=await(await fetch(t,{method:"POST",headers:{"X-ORION-REFRESH":e.refreshToken}})).json();if(!r.token)return null;if(I()?.canPersistCredentials!==!1)ue({...e,token:r.token});return r.token}async function Ne(){let e=d();if(!e?.token)return;if(!xr(e.token))return e.token;return await Sr()??void 0}async function ve(e="application/json"){let t=await Ne(),o={"Content-Type":e,"X-ORION-DEVICEID":Ir(),"X-ORION-PLATFORM":"web"};if(t)o["x-orion-jwt"]=t;return o}async function u(e){let t=`${h(e.service)}/graphql`,o=await ve(),r;try{r=await fetch(t,{method:"POST",headers:o,body:JSON.stringify({query:e.query,variables:e.variables}),signal:AbortSignal.timeout(15000)})}catch{throw Error("La solicitud tardó demasiado. Intenta de nuevo.")}let a=await r.json();if(a.errors?.length)throw Error($r(a.errors[0]));if(!a.data)throw Error("No data returned from server");return a.data}function Er(e){return e.replace(/^https?:\/\//,"").replace(/^www\./,"").replace(/\/.*$/,"")}function jr(e){return e.includes(".")||e.startsWith("http://")||e.startsWith("https://")}async function M(e){if(jr(e)){let t=Er(e),o=await fetch(`${h("main")}/website-id/${t}`,{signal:AbortSignal.timeout(1e4)});if(!o.ok)throw Error(`No se encontro el sitio "${t}"`);let r=await o.json();if(!r.websiteId)throw Error(`No se pudo resolver el websiteId para "${t}"`);return{input:e,websiteId:r.websiteId,targetType:"domain"}}return{input:e,websiteId:e,targetType:"websiteId"}}async function st(e){let t=await u({service:"main",query:`query ($websiteId: ID) {
|
|
5
5
|
website(websiteId: $websiteId) {
|
|
6
6
|
_id
|
|
7
7
|
name
|
|
@@ -13,7 +13,7 @@ function L(e){let t=[],o={},r={};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(!t.website)throw Error(`No se encontro el website "${e}"`);return t.website}function
|
|
16
|
+
}`,variables:{websiteId:e}});if(!t.website)throw Error(`No se encontro el website "${e}"`);return t.website}function Ar(){if(!d())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 ct(e){if(Ar(),!e)throw Error("Uso: team-cli admin <websiteId|domain> show");let t=await M(e),o=await st(t.websiteId);return{context:t,website:o}}function me(){return`team-cli admin
|
|
17
17
|
|
|
18
18
|
Comandos administrativos con contexto de website.
|
|
19
19
|
|
|
@@ -35,7 +35,7 @@ Modulos:
|
|
|
35
35
|
|
|
36
36
|
coupons
|
|
37
37
|
Administrar cupones y sus códigos.
|
|
38
|
-
Uso: team-cli admin <websiteId|domain> coupons <accion> [opciones]`}var
|
|
38
|
+
Uso: team-cli admin <websiteId|domain> coupons <accion> [opciones]`}var ut=`
|
|
39
39
|
availableAtPeriods
|
|
40
40
|
closedDays
|
|
41
41
|
closedUntilDate
|
|
@@ -51,7 +51,7 @@ Modulos:
|
|
|
51
51
|
fromMinute
|
|
52
52
|
toMinute
|
|
53
53
|
}
|
|
54
|
-
`,
|
|
54
|
+
`,le=`
|
|
55
55
|
_id
|
|
56
56
|
websiteId
|
|
57
57
|
name
|
|
@@ -86,13 +86,13 @@ Modulos:
|
|
|
86
86
|
requiredBINs
|
|
87
87
|
extraRequirementsForPaymentTypes
|
|
88
88
|
schedule {
|
|
89
|
-
${
|
|
89
|
+
${ut}
|
|
90
90
|
}
|
|
91
91
|
scheduleAtUse {
|
|
92
|
-
${
|
|
92
|
+
${ut}
|
|
93
93
|
}
|
|
94
94
|
codesCode
|
|
95
|
-
`,
|
|
95
|
+
`,mt=`
|
|
96
96
|
_id
|
|
97
97
|
code
|
|
98
98
|
couponId
|
|
@@ -101,28 +101,28 @@ Modulos:
|
|
|
101
101
|
sentToEmail
|
|
102
102
|
totalRedemptions
|
|
103
103
|
createdAt
|
|
104
|
-
`;function
|
|
104
|
+
`;function Re(){if(!d())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 P(e,t){let o=e[t];if(!o)throw Error(`--${t} es requerido.`);try{return JSON.parse(o)}catch{throw Error(`--${t} debe ser un JSON válido.`)}}function S(e,t){let o=e[t];if(!o)return;let r=Number.parseInt(o,10);if(Number.isNaN(r))throw Error(`--${t} debe ser un número entero.`);return r}function lt(e,t){let o=e[t];if(!o)return;if(o==="true")return!0;if(o==="false")return!1;throw Error(`--${t} debe ser true o false.`)}async function $(e){if(Re(),!e)throw Error("Debes indicar <websiteId|domain>.");return M(e)}async function A(e,t){let o=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(!o.coupon)throw Error(`No se encontró el cupón "${e}"`);if(o.coupon.websiteId!==t)throw Error(`El cupón "${e}" no pertenece al website seleccionado.`);return o.coupon}function
|
|
109
|
+
}`,variables:{couponId:e}});if(!o.coupon)throw Error(`No se encontró el cupón "${e}"`);if(o.coupon.websiteId!==t)throw Error(`El cupón "${e}" no pertenece al website seleccionado.`);return o.coupon}function Nr(e){if(!Array.isArray(e))throw Error("--input debe ser un arreglo JSON.");return e.map((t)=>{if(!t||typeof t!=="object"||typeof t.code!=="string")throw Error('Cada item de --input debe tener al menos { "code": "..." }.');if(t.userEmail!=null&&typeof t.userEmail!=="string")throw Error("userEmail debe ser string cuando viene informado.");return{code:t.code,userEmail:t.userEmail}})}function vr(e){if(!Array.isArray(e)||e.some((t)=>typeof t!=="string"))throw Error("--ids debe ser un arreglo JSON de strings.");return e}async function dt(e,t,o){let r=await $(e);await A(t,r.websiteId);let a=S(o,"limit"),n=S(o,"page"),i=o.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
|
+
${mt}
|
|
113
113
|
}
|
|
114
114
|
totalCount
|
|
115
115
|
totalPages
|
|
116
116
|
hasNextPage
|
|
117
117
|
hasPreviousPage
|
|
118
118
|
}
|
|
119
|
-
}`,variables:{couponId:t,filter:
|
|
119
|
+
}`,variables:{couponId:t,filter:i,limit:a,page:n}});return{context:r,couponId:t,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:n??1,limit:a??null}}}async function pt(e,t,o){let r=await $(e);await A(t,r.websiteId);let a=Nr(P(o,"input")),n=a.some((s)=>s.userEmail),i=await u({service:"main",query:`mutation ($couponId: ID, $codesWithEmail: [CodeWithEmailInput], $useCodeWithEmail: Boolean) {
|
|
120
120
|
createCouponCodes(couponId: $couponId, codesWithEmail: $codesWithEmail, useCodeWithEmail: $useCodeWithEmail)
|
|
121
|
-
}`,variables:{couponId:t,codesWithEmail:a,useCodeWithEmail:
|
|
121
|
+
}`,variables:{couponId:t,codesWithEmail:a,useCodeWithEmail:n}});return{context:r,couponId:t,requestedCount:a.length,result:i.createCouponCodes}}async function gt(e,t,o){let r=await $(e);await A(t,r.websiteId);let a=S(o,"quantity");if(!a)throw Error("--quantity es requerido.");let n=await u({service:"main",query:`mutation ($couponId: ID, $couponQuantity: Float, $couponCodePrefix: String) {
|
|
122
122
|
createRandomCouponCodes(couponId: $couponId, couponQuantity: $couponQuantity, couponCodePrefix: $couponCodePrefix)
|
|
123
|
-
}`,variables:{couponId:t,couponQuantity:a,couponCodePrefix:o.prefix}});return{context:r,couponId:t,quantity:a,prefix:o.prefix??null,result:
|
|
123
|
+
}`,variables:{couponId:t,couponQuantity:a,couponCodePrefix:o.prefix}});return{context:r,couponId:t,quantity:a,prefix:o.prefix??null,result:n.createRandomCouponCodes}}async function ft(e,t,o){let r=await $(e);await A(t,r.websiteId);let a=vr(P(o,"ids")),n=await u({service:"main",query:`mutation ($couponId: ID, $couponCodesIds: [ID]) {
|
|
124
124
|
deleteCouponCodes(couponId: $couponId, couponCodesIds: $couponCodesIds, globalCoupon: false)
|
|
125
|
-
}`,variables:{couponId:t,couponCodesIds:a}});return{context:r,couponId:t,deleted:
|
|
125
|
+
}`,variables:{couponId:t,couponCodesIds:a}});return{context:r,couponId:t,deleted:n.deleteCouponCodes,couponCodesIds:a}}function wt(){return`team-cli admin coupons codes create
|
|
126
126
|
|
|
127
127
|
Crea códigos explícitos para un cupón.
|
|
128
128
|
|
|
@@ -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
|
|
148
|
+
couponId se valida contra el website seleccionado antes de ejecutar la mutation.`}var bt={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 Rr(e){let t=Object.entries(e).filter(([,n])=>n!==void 0),o=t.map(([n])=>n).filter((n)=>!bt[n]);if(o.length)throw Error(`Campos no soportados para create: ${o.join(", ")}`);let r=t.map(([n])=>`$${n}: ${bt[n]}`).join(", "),a=t.map(([n])=>`${n}: $${n}`).join(", ");return`mutation (${r}) {
|
|
149
149
|
createCoupon(${a}) {
|
|
150
|
-
${
|
|
150
|
+
${le}
|
|
151
151
|
}
|
|
152
|
-
}`}async function
|
|
152
|
+
}`}async function Ct(e,t){let o=await $(e),r=S(t,"limit"),a=S(t,"page"),n=t.filter,i=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:o.websiteId,filter:
|
|
172
|
+
}`,variables:{websiteId:o.websiteId,filter:n,limit:r,page:a}});return{context:o,coupons:i.coupons.items??[],pagination:{totalCount:i.coupons.totalCount??0,totalPages:i.coupons.totalPages??0,hasNextPage:Boolean(i.coupons.hasNextPage),hasPreviousPage:Boolean(i.coupons.hasPreviousPage),page:a??1,limit:r??null}}}async function yt(e,t){let o=await $(e);await A(t,o.websiteId);let r=await u({service:"main",query:`query ($couponId: ID) {
|
|
173
173
|
coupon(couponId: $couponId) {
|
|
174
|
-
${
|
|
174
|
+
${le}
|
|
175
175
|
}
|
|
176
|
-
}`,variables:{couponId:t}});return{context:o,coupon:r.coupon}}async function
|
|
176
|
+
}`,variables:{couponId:t}});return{context:o,coupon:r.coupon}}async function qt(e,t){let o=await $(e),r=P(t,"input");if(r.websiteId&&r.websiteId!==o.websiteId)throw Error("El websiteId del input no coincide con el website seleccionado.");let a={...r,websiteId:o.websiteId},n=Rr(a),i=await u({service:"main",query:n,variables:a});return{context:o,coupon:i.createCoupon}}async function It(e,t,o){let r=await $(e);await A(t,r.websiteId);let a=P(o,"input"),n=await u({service:"main",query:`mutation ($couponId: ID, $coupon: UpdateCouponInput) {
|
|
177
177
|
updateCoupon(couponId: $couponId, coupon: $coupon) {
|
|
178
|
-
${
|
|
178
|
+
${le}
|
|
179
179
|
}
|
|
180
|
-
}`,variables:{couponId:t,coupon:a}});return{context:r,coupon:
|
|
180
|
+
}`,variables:{couponId:t,coupon:a}});return{context:r,coupon:n.updateCoupon}}async function ht(e,t){let o=await $(e);await A(t,o.websiteId);let r=await u({service:"main",query:`mutation ($couponsIds: [ID]) {
|
|
181
181
|
deleteCoupons(couponsIds: $couponsIds, globalCoupon: false)
|
|
182
|
-
}`,variables:{couponsIds:[t]}});return{context:o,couponId:t,deleted:r.deleteCoupons}}function
|
|
182
|
+
}`,variables:{couponsIds:[t]}});return{context:o,couponId:t,deleted:r.deleteCoupons}}function D(){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 $t(){return`team-cli admin coupons create
|
|
231
231
|
|
|
232
232
|
Crea un cupón para el website seleccionado.
|
|
233
233
|
|
|
@@ -276,7 +276,7 @@ Ejemplo con schedule:
|
|
|
276
276
|
Tips:
|
|
277
277
|
Usa comillas simples afuera del JSON en shell.
|
|
278
278
|
Usa arrays JSON reales para ids o listas.
|
|
279
|
-
Si necesitas el shape exacto de un cupón existente, parte con: team-cli admin <web> coupons show <couponId>`}function
|
|
279
|
+
Si necesitas el shape exacto de un cupón existente, parte con: team-cli admin <web> coupons show <couponId>`}function xt(){return`team-cli admin coupons update
|
|
280
280
|
|
|
281
281
|
Actualiza un cupón existente.
|
|
282
282
|
|
|
@@ -318,7 +318,7 @@ Ejemplo reemplazando restricciones:
|
|
|
318
318
|
team-cli admin <web> coupons update <couponId> --input '{"requiresStoresIds":["store1"],"requiresPaymentTypes":["card"]}'
|
|
319
319
|
|
|
320
320
|
Tip:
|
|
321
|
-
Primero mira el cupón actual con: team-cli admin <web> coupons show <couponId>`}async function
|
|
321
|
+
Primero mira el cupón actual con: team-cli admin <web> coupons show <couponId>`}async function St(e,t){Re();let o=e[2]??t.filter;if(!o)throw Error("Debes indicar un término de búsqueda. Uso: team-cli admin search <texto>");let r=S(t,"limit"),a=S(t,"page"),n=lt(t,"only-active"),i=await u({service:"main",query:`query ($filter: String, $limit: BigInt, $page: BigInt, $onlyActiveWebsites: Boolean) {
|
|
322
322
|
websites(filter: $filter, limit: $limit, page: $page, onlyActiveWebsites: $onlyActiveWebsites) {
|
|
323
323
|
items {
|
|
324
324
|
_id
|
|
@@ -334,7 +334,7 @@ Tip:
|
|
|
334
334
|
hasNextPage
|
|
335
335
|
hasPreviousPage
|
|
336
336
|
}
|
|
337
|
-
}`,variables:{filter:o,limit:r,page:a,onlyActiveWebsites:
|
|
337
|
+
}`,variables:{filter:o,limit:r,page:a,onlyActiveWebsites:n}});return{searchTerm:o,websites:i.websites.items??[],pagination:{totalCount:i.websites.totalCount??0,totalPages:i.websites.totalPages??0,hasNextPage:Boolean(i.websites.hasNextPage),hasPreviousPage:Boolean(i.websites.hasPreviousPage),page:a??1,limit:r??null}}}function Et(){return`team-cli admin search
|
|
338
338
|
|
|
339
339
|
Buscar websites en admin.
|
|
340
340
|
|
|
@@ -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 Tr(){if(!d())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 Or(e){let t=[e.address?.streetAddress,e.address?.extendedAddress,e.address?.locality].filter(Boolean);if(!t.length)return null;return t.join(", ")}async function jt(e){if(Tr(),!e)throw Error("Uso: team-cli admin <websiteId|domain> stores list");let t=await M(e),r=((await u({service:"main",query:`query ($websiteId: ID) {
|
|
358
358
|
stores(websiteId: $websiteId) {
|
|
359
359
|
items {
|
|
360
360
|
_id
|
|
@@ -366,17 +366,17 @@ Ejemplos:
|
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
|
-
}`,variables:{websiteId:t.websiteId}})).stores.items??[]).map((a)=>({_id:a._id,name:a.name,address:
|
|
369
|
+
}`,variables:{websiteId:t.websiteId}})).stores.items??[]).map((a)=>({_id:a._id,name:a.name,address:Or(a)})).sort((a,n)=>a.name.localeCompare(n.name,"es",{sensitivity:"base"}));return{context:t,stores:r,totalCount:r.length}}import{createInterface as Ur}from"node:readline";function z(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 t=Ur({input:process.stdin,output:process.stderr});return new Promise((o)=>{t.question(e,(r)=>{t.close(),o(r.trim())})})}async function At(e){return(await u({service:"auth",query:`mutation ($email: String!) {
|
|
370
370
|
requestLoginCode(email: $email)
|
|
371
|
-
}`,variables:{email:e}})).requestLoginCode}async function
|
|
371
|
+
}`,variables:{email:e}})).requestLoginCode}async function Nt(e,t,o){let r=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:t,code:o.toUpperCase()}});
|
|
377
|
-
`);let t=await
|
|
378
|
-
`);let o=await
|
|
379
|
-
`);let o=await
|
|
376
|
+
}`,variables:{email:e,token:t,code:o.toUpperCase()}});ue({email:e,token:r.loginWithCode.token,refreshToken:r.loginWithCode.refreshToken}),await Qr()}async function Qr(){if(!(await u({service:"main",query:"query { me { roles } }"})).me?.roles?.length)throw Ae(),Error("Solo miembros del equipo Justo pueden usar esta herramienta.")}async function vt(){let e=await z("Email: ");C(`Enviando codigo de verificacion...
|
|
377
|
+
`);let t=await At(e);C(`Codigo enviado a tu email.
|
|
378
|
+
`);let o=await z("Codigo: ");return await Nt(e,t,o),{ok:!0,authenticated:!0,email:e}}async function Rt(e){let t=F(e,"email"),o=F(e,"token"),r=F(e,"code");return await Nt(t,o,r),{ok:!0,authenticated:!0,email:t}}async function Tt(e){let t=F(e,"email");C(`Enviando codigo de verificacion...
|
|
379
|
+
`);let o=await At(t);return{ok:!0,email:t,token:o,nextCommand:`npx @getjusto/team-cli auth login-with-token --email ${t} --token ${o} --code <CODIGO>`}}async function Ot(){return Ae(),{ok:!0,authenticated:!1}}async function Ut(){let e=d();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 Te(){return`team-cli auth
|
|
380
380
|
|
|
381
381
|
Gestion de sesion.
|
|
382
382
|
|
|
@@ -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
|
|
405
|
+
Uso: team-cli auth login-with-token --email <email> --token <token> --code <codigo>`}import{spawn as Ce}from"node:child_process";import{createServer as Vt}from"node:http";import{existsSync as Zr,mkdirSync as Yr,openSync as Dr,readFileSync as zr,rmSync as kr,writeFileSync as Kr}from"node:fs";import{dirname as Vr,join as ye,resolve as Lt}from"node:path";import{request as Lr}from"node:http";import{request as ea}from"node:https";import{execFileSync as Jr}from"node:child_process";import{existsSync as fe,mkdirSync as Wr,readFileSync as we,readdirSync as _r,rmSync as Oe,writeFileSync as N}from"node:fs";import{basename as Bt,dirname as Mt,join as f,resolve as Pt}from"node:path";var de="iUzDOAFCUx33tmT6OCea",k="VITE_JUSTO_MAP_TILER_TOKEN";function Qt(){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'
|
|
@@ -419,7 +419,9 @@ import {justoCli} from '@/lib/justo'
|
|
|
419
419
|
|
|
420
420
|
const defaultCommand = 'auth status'
|
|
421
421
|
const queryExample = "data queries preview <queryId> --params '{\\"limit\\":10}'"
|
|
422
|
-
const mapTilerToken =
|
|
422
|
+
const mapTilerToken =
|
|
423
|
+
(import.meta.env as {${k}?: string}).${k} ||
|
|
424
|
+
'${de}'
|
|
423
425
|
const chartData = [
|
|
424
426
|
{day: 'Lun', sessions: 12},
|
|
425
427
|
{day: 'Mar', sessions: 18},
|
|
@@ -622,7 +624,7 @@ export function App() {
|
|
|
622
624
|
}
|
|
623
625
|
|
|
624
626
|
export default App
|
|
625
|
-
`}function
|
|
627
|
+
`}function Jt(){return`type JustoCliFunction = <T = unknown>(command: string) => Promise<T>
|
|
626
628
|
type JustoStreamFunction = <T = unknown>(
|
|
627
629
|
command: string,
|
|
628
630
|
onRow: (row: T) => Promise<void> | void,
|
|
@@ -724,7 +726,25 @@ async function callLocalPreviewStream<T>(
|
|
|
724
726
|
return {rowCount}
|
|
725
727
|
}
|
|
726
728
|
|
|
729
|
+
function ensurePreviewWindowJusto() {
|
|
730
|
+
if (window.justo) return window.justo
|
|
731
|
+
|
|
732
|
+
const env = import.meta.env as ImportMetaEnvWithJusto
|
|
733
|
+
if (!env.VITE_JUSTO_CLI_ENDPOINT || !env.VITE_JUSTO_STREAM_ENDPOINT) {
|
|
734
|
+
return undefined
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
window.justo = {
|
|
738
|
+
cli: callLocalPreviewCli,
|
|
739
|
+
stream: callLocalPreviewStream,
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return window.justo
|
|
743
|
+
}
|
|
744
|
+
|
|
727
745
|
export async function justoCli<T = unknown>(command: string) {
|
|
746
|
+
ensurePreviewWindowJusto()
|
|
747
|
+
|
|
728
748
|
if (window.justo?.cli) {
|
|
729
749
|
return await window.justo.cli<T>(command)
|
|
730
750
|
}
|
|
@@ -736,13 +756,17 @@ export async function justoStream<T = unknown>(
|
|
|
736
756
|
command: string,
|
|
737
757
|
onRow: (row: T) => Promise<void> | void,
|
|
738
758
|
) {
|
|
759
|
+
ensurePreviewWindowJusto()
|
|
760
|
+
|
|
739
761
|
if (window.justo?.stream) {
|
|
740
762
|
return await window.justo.stream<T>(command, onRow)
|
|
741
763
|
}
|
|
742
764
|
|
|
743
765
|
return await callLocalPreviewStream<T>(command, onRow)
|
|
744
766
|
}
|
|
745
|
-
|
|
767
|
+
|
|
768
|
+
ensurePreviewWindowJusto()
|
|
769
|
+
`}function Wt(e){return`# ${e}
|
|
746
770
|
|
|
747
771
|
Starter de Justo Spaces generado por \`team-cli spaces init\`.
|
|
748
772
|
|
|
@@ -769,10 +793,11 @@ Flujo recomendado:
|
|
|
769
793
|
|
|
770
794
|
Tip:
|
|
771
795
|
- usa \`spaces preview --open\` para abrir el dashboard en el navegador por defecto y mostrárselo al usuario mientras lo iteras
|
|
772
|
-
`}function
|
|
796
|
+
`}function _t(){return`import {StrictMode} from 'react'
|
|
773
797
|
import {createRoot} from 'react-dom/client'
|
|
774
798
|
import App from './App.tsx'
|
|
775
799
|
import './index.css'
|
|
800
|
+
import './lib/justo'
|
|
776
801
|
import {ThemeProvider} from '@/components/theme-provider.tsx'
|
|
777
802
|
|
|
778
803
|
createRoot(document.getElementById('root')!).render(
|
|
@@ -782,14 +807,14 @@ createRoot(document.getElementById('root')!).render(
|
|
|
782
807
|
</ThemeProvider>
|
|
783
808
|
</StrictMode>,
|
|
784
809
|
)
|
|
785
|
-
`}var
|
|
786
|
-
base: './',`);
|
|
787
|
-
`)}function
|
|
788
|
-
${o}`)}function
|
|
789
|
-
`),
|
|
790
|
-
`),await new Promise((i
|
|
791
|
-
`);let
|
|
792
|
-
`);let a=`${t} ${
|
|
810
|
+
`}function pe(){return process.execPath}function Q(e){if(process.platform==="win32")return`${e}.cmd`;return e}var Gt=".justo-space.json";function ge(e,t,o){Jr(e,t,{cwd:o,stdio:"inherit",env:{...process.env,CI:"1"}})}function Br(e){if(!e)throw Error("Falta --path. Ejemplo: team-cli spaces init --path ./mi-space-app");let t=Pt(e);if(fe(t)){if(_r(t).length>0)throw Error(`La carpeta ya existe y no está vacía: ${t}`);Oe(t,{recursive:!0,force:!0})}return Wr(Mt(t),{recursive:!0}),t}function Mr(e){let t=f(e,"vite.config.ts"),o=we(t,"utf-8");if(o.includes("base: './'"))return;let r=o.replace("export default defineConfig({",`export default defineConfig({
|
|
811
|
+
base: './',`);N(t,r)}function Pr(e){let t=f(e,"tsconfig.app.json"),r=we(t,"utf-8").replace('"noUnusedLocals": true,','"noUnusedLocals": false,').replace('"noUnusedParameters": true,','"noUnusedParameters": false,');N(t,r)}function Gr(e){let t=f(e,"package.json"),o=JSON.parse(we(t,"utf-8"));o.dependencies=o.dependencies||{},o.devDependencies=o.devDependencies||{},o.dependencies.leaflet="^1.9.4",o.dependencies["react-leaflet"]="^5.0.0",o.devDependencies["@types/leaflet"]="^1.9.20",o.justoSpaceApp=!0,N(t,`${JSON.stringify(o,null,2)}
|
|
812
|
+
`)}function Fr(e){let t=f(e,"src","index.css"),o=we(t,"utf-8");if(o.includes("leaflet/dist/leaflet.css"))return;N(t,`@import "leaflet/dist/leaflet.css";
|
|
813
|
+
${o}`)}function Xr(e){let t=Bt(e);N(f(e,"README.md"),Wt(t)),N(f(e,"src","App.tsx"),Qt()),N(f(e,"src","main.tsx"),_t()),N(f(e,"src","lib","justo.ts"),Jt()),N(f(e,Gt),`${JSON.stringify({template:"react-vite-shadcn",version:1},null,2)}
|
|
814
|
+
`),Oe(f(e,".git"),{recursive:!0,force:!0})}function Hr(e){Oe(f(e,"package-lock.json"),{force:!0})}function Ue(e){let t=Pt(e);if(!fe(t))throw Error(`No existe la app del space: ${t}`);if(!fe(f(t,Gt)))throw Error("Este publish solo acepta apps creadas con team-cli spaces init. Debes apuntar al root de esa app.");return t}function Ft(e){let t=Ue(e);ge(Q("yarn"),["build"],t);let o=f(t,"dist");if(!fe(f(o,"index.html")))throw Error("El build no generó dist/index.html");return o}function Xt(e){let t=Br(e),o=Mt(t),r=Bt(t);return ge(Q("npx"),["shadcn@latest","init","-t","vite","-d","-y","-n",r],o),ge(Q("npx"),["shadcn@latest","add","-a","-y"],t),Hr(t),Gr(t),ge(Q("yarn"),["install"],t),Mr(t),Pr(t),Fr(t),Xr(t),{path:t,nextSteps:[`cd ${t}`,"team-cli spaces create --name '...' --description '...' --slug mi-space","team-cli spaces publish <spaceId> --path ."]}}function Ht(e){let t=[],o="",r=null,a=!1;for(let n of e){if(a){o+=n,a=!1;continue}if(n==="\\"){a=!0;continue}if(r){if(n===r)r=null;else o+=n;continue}if(n==='"'||n==="'"){r=n;continue}if(/\s/.test(n)){if(o)t.push(o),o="";continue}o+=n}if(r)throw Error("Comando inválido: falta cerrar una comilla");if(o)t.push(o);return t}var ta=".justo-space-preview",oa="preview.json",ra=30000;function qe(e){return ye(e,ta)}function eo(e){return ye(qe(e),oa)}function Zt(e){return ye(qe(e),"bridge.log")}function Yt(e){return ye(qe(e),"vite.log")}function to(e){Yr(qe(e),{recursive:!0})}function be(e){if(!e)return;try{process.kill(e,"SIGTERM")}catch{return}}function aa(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 na(e,t){if(!t)return{attempted:!1,opened:!1};let o=aa(e);return await new Promise((r)=>{let a=Ce(o.command,o.args,{stdio:"ignore",detached:!0});a.once("error",()=>{r({attempted:!0,opened:!1,message:"No se pudo abrir el navegador por defecto automáticamente. Abre la URL manualmente."})}),a.once("spawn",()=>{a.unref(),r({attempted:!0,opened:!0})})})}function ia(e){let t=eo(e);if(!Zr(t))return;try{let o=JSON.parse(zr(t,"utf-8"));be(o.appPid),be(o.bridgePid)}catch{}kr(t,{force:!0})}function Dt(){return new Promise((e,t)=>{let o=Vt();o.listen(0,"127.0.0.1",()=>{let r=o.address();if(!r||typeof r==="string"){o.close(),t(Error("No se pudo obtener un puerto libre"));return}let{port:a}=r;o.close((n)=>{if(n){t(n);return}e(a)})}),o.on("error",t)})}function zt(e){return new Promise((t)=>setTimeout(t,e))}function sa(e){return new Promise((t,o)=>{let n=(new URL(e).protocol==="https:"?ea:Lr)(e,{method:"GET"},(i)=>{t(i.statusCode||0),i.resume()});n.on("error",o),n.end()})}async function kt(e,t=ra){let o=Date.now();while(Date.now()-o<t){try{if(await sa(e)>0)return}catch{await zt(500);continue}await zt(500)}throw Error(`Timeout esperando que el preview responda en ${e}`)}function ca(e){return to(Vr(e)),Dr(e,"a")}function Kt(e,t,o,r,a){let n=ca(r),i=Ce(e,t,{cwd:o,detached:!0,stdio:["ignore",n,n],env:{...process.env,...a}});if(!i.pid)throw Error(`No se pudo iniciar el proceso ${e}`);return i.unref(),i.pid}function oo(){let e=ot("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 ua(e){let t=[];for await(let o of e)t.push(Buffer.isBuffer(o)?o:Buffer.from(o));return Buffer.concat(t).toString("utf-8")}function K(e,t,o){e.writeHead(t,{"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(o))}function Qe(e){let t=e.trim(),o=new Set([0]);for(let a=0;a<t.length;a++)if(t[a]==="{"||t[a]==="[")o.add(a);let r=[...o].sort((a,n)=>n-a);for(let a of r)try{return JSON.parse(t.slice(a))}catch{continue}return t}function ro(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 ma(e,t){return{VITE_JUSTO_CLI_ENDPOINT:e,VITE_JUSTO_STREAM_ENDPOINT:t,VITE_JUSTO_CLI_MODE:"preview",[k]:de}}function la(e,t,o,r){return new Promise((a,n)=>{let i=Ce(pe(),[t,"--env","prod",...r,"--format","json"],{cwd:process.cwd(),env:ro(o),stdio:["ignore","pipe","pipe"]}),s="";i.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)}),i.stderr.on("data",(c)=>{s+=Buffer.from(c).toString("utf-8")}),i.on("error",n),i.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 m=Qe(s.trim());n(Error(m.error||s.trim()||"justoStream failed"))})})}async function ao(e){let t=Number(e.port);if(!t)throw Error("Falta --port para el bridge interno de preview");let o=oo(),r=Lt(e["cli-path"]||process.argv[1]||""),a=Vt(async(n,i)=>{if(n.method==="OPTIONS"){K(i,200,{ok:!0});return}if(n.method==="GET"&&n.url==="/__justo/health"){K(i,200,{ok:!0});return}if(n.method!=="POST"||n.url!=="/__justo/cli"&&n.url!=="/__justo/stream"){K(i,404,{ok:!1,error:"Not found"});return}try{let s=await ua(n),m=JSON.parse(s||"{}").command;if(!m)throw Error("Debes indicar un comando");let l=Array.isArray(m)?m:Ht(m);if(n.url==="/__justo/stream"){await la(i,r,o,l);return}let g=await new Promise((p,y)=>{let w=Ce(pe(),[r,"--env","prod",...l,"--format","json"],{cwd:process.cwd(),env:ro(o),stdio:["ignore","pipe","pipe"]}),oe=[],W=[];w.stdout.on("data",(R)=>oe.push(Buffer.from(R))),w.stderr.on("data",(R)=>W.push(Buffer.from(R))),w.on("error",y),w.on("close",(R)=>{let G=Buffer.concat(oe).toString("utf-8")||Buffer.concat(W).toString("utf-8");if(R&&R!==0){let Bo=Qe(G);y(Error(Bo.error||G||"justoCli failed"));return}p(Qe(G))})});K(i,200,{result:g})}catch(s){let c=s instanceof Error?s.message:"Unexpected error";K(i,400,{error:c})}});await new Promise((n,i)=>{a.listen(t,"127.0.0.1",()=>n()),a.on("error",i)}),C(`Space preview bridge listening on http://127.0.0.1:${t}
|
|
815
|
+
`),await new Promise((n,i)=>{a.on("close",()=>n()),a.on("error",i)})}async function no(e){let t=e.path;if(!t)throw Error("Falta --path. Ejemplo: team-cli spaces preview --path ./mi-space-app");let o=Ue(t);oo(),to(o),ia(o);let r=Number(e.port)||await Dt(),a=Number(e["bridge-port"])||await Dt(),n=e.open==="true",i=`http://127.0.0.1:${r}`,s=`http://127.0.0.1:${a}/__justo/cli`,c=`http://127.0.0.1:${a}/__justo/stream`,m=Lt(process.argv[1]||""),l=Kt(pe(),[m,"__spaces-preview-bridge","--port",String(a),"--cli-path",m],process.cwd(),Zt(o),{}),g=Kt(Q("yarn"),["dev","--host","127.0.0.1","--port",String(r)],o,Yt(o),ma(s,c));try{await kt(`http://127.0.0.1:${a}/__justo/health`),await kt(i)}catch(w){throw be(g),be(l),w}let p={appPid:g,bridgePid:l,previewUrl:i,bridgeUrl:s,streamUrl:c,cliEnv:"prod"};Kr(eo(o),`${JSON.stringify(p,null,2)}
|
|
816
|
+
`);let y=await na(i,n);return{ok:!0,path:o,previewUrl:i,bridgeUrl:s,streamUrl:c,cliEnv:"prod",appPid:g,bridgePid:l,logs:{app:Yt(o),bridge:Zt(o)},open:y}}import{writeFileSync as ha}from"node:fs";import{mkdtempSync as da,readFileSync as pa,rmSync as ga,writeFileSync as fa}from"node:fs";import{tmpdir as wa}from"node:os";import{join as io}from"node:path";import{spawnSync as ba}from"node:child_process";function Ca(e){return`'${e.replaceAll("'",`'"'"'`)}'`}function so(e,t){if(e==null)return;if(!Array.isArray(e)||e.some((o)=>typeof o!=="string"))throw Error(`${t} debe ser un arreglo de strings.`);return e}function ya(e){if(!Array.isArray(e))throw Error("variables debe ser un arreglo.");return e.map((t,o)=>{if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`variables[${o}] debe ser un objeto.`);let r=t;if(typeof r.key!=="string"||!r.key)throw Error(`variables[${o}].key debe ser un string no vacío.`);if(typeof r.fieldType!=="string"||!r.fieldType)throw Error(`variables[${o}].fieldType debe ser un string no vacío.`);if(r.fieldParams!=null&&typeof r.fieldParams!=="string")throw Error(`variables[${o}].fieldParams debe ser un string.`);return{key:r.key,fieldType:r.fieldType,fieldParams:typeof r.fieldParams==="string"?r.fieldParams:void 0}})}function qa(e){if(!e||typeof e!=="object"||Array.isArray(e))throw Error("El archivo editado debe contener un objeto JSON.");let t=e;if(typeof t.name!=="string"||!t.name.trim())throw Error("name debe ser un string no vacío.");if(t.description!=null&&typeof t.description!=="string")throw Error("description debe ser un string.");if(typeof t.collection!=="string"||!t.collection.trim())throw Error("collection debe ser un string no vacío.");if(typeof t.pipeline!=="string")throw Error("pipeline debe ser un string.");return{name:t.name.trim(),description:t.description?.trim()||void 0,collection:t.collection.trim(),allowedUsersIds:so(t.allowedUsersIds,"allowedUsersIds")??[],tags:so(t.tags,"tags")??[],pipeline:t.pipeline,variables:ya(t.variables)}}function co(e){let t=process.env.VISUAL||process.env.EDITOR||"vi",o=da(io(wa(),"team-cli-query-")),r=io(o,"aggregation-query.json");fa(r,`${JSON.stringify(e,null,2)}
|
|
817
|
+
`);let a=`${t} ${Ca(r)}`,n=ba(a,{shell:!0,stdio:"inherit"});if(n.error)throw Error(`No se pudo abrir el editor "${t}": ${n.error.message}`);if(n.status!==0)throw Error(`El editor terminó con código ${n.status}.`);try{let i=pa(r,"utf-8");if(!i.trim())throw Error("El archivo quedó vacío.");let s;try{s=JSON.parse(i)}catch{throw Error("El archivo editado no contiene JSON válido.")}return qa(s)}finally{ga(o,{recursive:!0,force:!0})}}function v(){if(!d())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 O(e,t){let o=e[3];if(!o)throw Error(`Uso: ${t}`);return o}function V(e){if(!e.params)return{};try{return JSON.parse(e.params)}catch{throw Error("--params debe ser un JSON válido.")}}function uo(e){let t=e.limit;if(!t)throw Error("--limit es requerido. Ejemplo: --limit 1000");let o=Number(t);if(!Number.isInteger(o)||o<=0)throw Error("--limit debe ser un entero positivo.");return o}function Je(e){if(typeof e!=="string")return e;try{return JSON.parse(e)}catch{return{value:e}}}async function L(e){return(await u({service:"data",query:`query ($aggregationQueryId: String) {
|
|
793
818
|
aggregationQuery(aggregationQueryId: $aggregationQueryId) {
|
|
794
819
|
_id
|
|
795
820
|
name
|
|
@@ -805,11 +830,11 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
805
830
|
fieldParams
|
|
806
831
|
}
|
|
807
832
|
}
|
|
808
|
-
}`,variables:{aggregationQueryId:e}})).aggregationQuery}function
|
|
833
|
+
}`,variables:{aggregationQueryId:e}})).aggregationQuery}function mo(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 We(e,t){let o=await u({service:"data",query:`mutation ($aggregationQueryId: String, $params: JSON) {
|
|
809
834
|
testAggregationQuery(aggregationQueryId: $aggregationQueryId, params: $params)
|
|
810
|
-
}`,variables:{aggregationQueryId:e,params:t}});return
|
|
811
|
-
`);while(p>=0){if(
|
|
812
|
-
`)}}let c=
|
|
835
|
+
}`,variables:{aggregationQueryId:e,params:t}});return Je(o.testAggregationQuery)}function Ia(e){try{return JSON.parse(e).error||e}catch{return e}}async function lo(e,t,o){let r=await fetch(`${h("data")}/aggregation-queries/${e}/run`,{method:"POST",headers:await ve(),body:JSON.stringify({params:t,limit:o}),signal:AbortSignal.timeout(315000)});if(!r.ok){let m=await r.text();throw Error(Ia(m)||"No se pudo ejecutar el query.")}if(!r.body)throw Error("El servidor no devolvió un stream de datos.");let a=r.body.getReader(),n=new TextDecoder,i="",s=0;while(!0){let{done:m,value:l}=await a.read();if(m)break;let g=n.decode(l,{stream:!0});process.stdout.write(g),i+=g;let p=i.indexOf(`
|
|
836
|
+
`);while(p>=0){if(i.slice(0,p).trim())s++;i=i.slice(p+1),p=i.indexOf(`
|
|
837
|
+
`)}}let c=n.decode();if(c)process.stdout.write(c),i+=c;if(i.trim())s++;return{ok:!0,queryId:e,limit:o,rows:s}}async function _e(e,t){await u({service:"data",query:`mutation ($aggregationQueryId: String, $aggregationQuery: UpdateAggregationQueryInput) {
|
|
813
838
|
updateAggregationQuery(
|
|
814
839
|
aggregationQueryId: $aggregationQueryId
|
|
815
840
|
aggregationQuery: $aggregationQuery
|
|
@@ -822,7 +847,7 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
822
847
|
tags
|
|
823
848
|
currentVersionIndex
|
|
824
849
|
}
|
|
825
|
-
}`,variables:{aggregationQueryId:e,aggregationQuery:{name:t.name,description:t.description,collection:t.collection,allowedUsersIds:t.allowedUsersIds,tags:t.tags}}}),await
|
|
850
|
+
}`,variables:{aggregationQueryId:e,aggregationQuery:{name:t.name,description:t.description,collection:t.collection,allowedUsersIds:t.allowedUsersIds,tags:t.tags}}}),await u({service:"data",query:`mutation ($aggregationQueryId: String, $pipeline: String, $variables: [AggregationQueryVariableInput]) {
|
|
826
851
|
addAggregationQueryVersion(
|
|
827
852
|
aggregationQueryId: $aggregationQueryId
|
|
828
853
|
pipeline: $pipeline
|
|
@@ -831,7 +856,7 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
831
856
|
_id
|
|
832
857
|
currentVersionIndex
|
|
833
858
|
}
|
|
834
|
-
}`,variables:{aggregationQueryId:e,pipeline:t.pipeline,variables:t.variables}})}async function
|
|
859
|
+
}`,variables:{aggregationQueryId:e,pipeline:t.pipeline,variables:t.variables}})}async function po(){return(await u({service:"data",query:`mutation {
|
|
835
860
|
createAggregationQuery {
|
|
836
861
|
_id
|
|
837
862
|
name
|
|
@@ -847,7 +872,7 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
847
872
|
fieldParams
|
|
848
873
|
}
|
|
849
874
|
}
|
|
850
|
-
}`})).createAggregationQuery}function
|
|
875
|
+
}`})).createAggregationQuery}function $a(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 t=await u({service:"messenger",query:`mutation generateAdminQuery(
|
|
851
876
|
$prompt: String
|
|
852
877
|
$name: String
|
|
853
878
|
$description: String
|
|
@@ -873,13 +898,13 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
873
898
|
aggregationDescription
|
|
874
899
|
aggregationName
|
|
875
900
|
}
|
|
876
|
-
}`,variables:e});if(!t.generateAdminQuery?.pipeline||!t.generateAdminQuery.fullCollectionName)throw Error("La IA no devolvió una versión válida del query.");return t.generateAdminQuery}async function
|
|
877
|
-
`);try{let c=await
|
|
878
|
-
`);let s=await
|
|
879
|
-
`);let
|
|
901
|
+
}`,variables:e});if(!t.generateAdminQuery?.pipeline||!t.generateAdminQuery.fullCollectionName)throw Error("La IA no devolvió una versión válida del query.");return t.generateAdminQuery}async function go(){return v(),await po()}async function fo(e){v();let t=O(e,"team-cli data queries edit <queryId>"),o=await L(t),r=co(mo(o));return await _e(t,r),{ok:!0,queryId:t,name:r.name,collection:r.collection}}async function wo(e,t){v();let o=O(e,"team-cli data queries ai-edit <queryId> --prompt '<texto>' [--params '<json>']"),r=await L(o),a=t.prompt||await z("Describe los cambios para la IA: ");if(!a)throw Error("Debes indicar un prompt para AI edit.");let n=V(t),i;if(t.params){C(`Obteniendo preview del query actual...
|
|
902
|
+
`);try{let c=await We(o,n);i=$a(c)}catch(c){let m=c instanceof Error?c.message:String(c);throw Error(`No se pudo obtener el preview para AI edit: ${m}`)}}C(`Generando propuesta con IA...
|
|
903
|
+
`);let s=await xa({prompt:a,fullCollectionName:r.collection,pipeline:r.pipeline,preview:i,description:r.description,name:r.name,variables:r.variables});return await _e(o,{name:r.name==="Nuevo query"?s.aggregationName||r.name:r.name,description:r.description||s.aggregationDescription,collection:s.fullCollectionName,allowedUsersIds:r.allowedUsersIds??[],tags:r.tags??[],pipeline:s.pipeline,variables:s.variables??[]}),{ok:!0,queryId:o,responseText:s.responseText,collection:s.fullCollectionName,name:s.aggregationName,description:s.aggregationDescription}}async function bo(e){v();let t=O(e,"team-cli data queries view <queryId>");return await L(t)}async function Co(e){v();let t=O(e,"team-cli data queries view-pipeline <queryId>"),o=await L(t);return{queryId:t,pipeline:o.pipeline}}async function yo(e,t){v();let o=O(e,"team-cli data queries preview <queryId> --params '<json>'"),r=V(t),a=await We(o,r);return Je(a)}async function qo(e,t){v();let o=O(e,"team-cli data queries run <queryId> --limit <n> --params '<json>'"),r=V(t),a=uo(t);return await lo(o,r,a),{__streamHandled:!0}}function Sa(e){return new Promise((t)=>setTimeout(t,e))}async function Io(e,t){v();let o=O(e,"team-cli data queries download <queryId> --params '<json>'"),r=V(t);if(!t.path)throw Error("--path es requerido. Ejemplo: --path resultado.xlsx");C(`Iniciando descarga...
|
|
904
|
+
`);let n=(await u({service:"data",query:`mutation ($aggregationQueryId: String, $params: JSON) {
|
|
880
905
|
downloadAggregationQueryData(aggregationQueryId: $aggregationQueryId, params: $params)
|
|
881
|
-
}`,variables:{aggregationQueryId:o,params:r}})).downloadAggregationQueryData;
|
|
882
|
-
`);let
|
|
906
|
+
}`,variables:{aggregationQueryId:o,params:r}})).downloadAggregationQueryData;C(`Reporte en proceso (${n})...
|
|
907
|
+
`);let i=null;while(!i){await Sa(1000);let m=await u({service:"data",query:`query ($id: String) {
|
|
883
908
|
getAsyncReport(id: $id) {
|
|
884
909
|
_id
|
|
885
910
|
status
|
|
@@ -887,9 +912,9 @@ ${o}`)}function Jr(e){let t=Ot(e);A(f(e,"README.md"),Rt(t)),A(f(e,"src","App.tsx
|
|
|
887
912
|
fileUrl
|
|
888
913
|
}
|
|
889
914
|
getAsyncReportRecordsCount(id: $id)
|
|
890
|
-
}`,variables:{id:
|
|
915
|
+
}`,variables:{id:n}}),l=m.getAsyncReport,g=m.getAsyncReportRecordsCount;if(l.status==="error")throw Error("El reporte falló al generarse.");if(l.fileUrl)i=l.fileUrl;else{let p=l.estimatedRecordsCount?` (~${l.estimatedRecordsCount} registros)`:"",y=g!=null?` ${g} procesados`:"";C(`\rGenerando...${p}${y}`)}}C(`
|
|
891
916
|
Descargando archivo...
|
|
892
|
-
`);let s=await fetch(
|
|
917
|
+
`);let s=await fetch(i);if(!s.ok)throw Error(`Error descargando archivo: ${s.status}`);let c=Buffer.from(await s.arrayBuffer());return ha(t.path,c),{ok:!0,queryId:o,asyncReportId:n,outputPath:t.path,fileUrl:i}}function Be(){return`team-cli data
|
|
893
918
|
|
|
894
919
|
Comandos de datos y reportes.
|
|
895
920
|
|
|
@@ -948,7 +973,7 @@ Ejemplos:
|
|
|
948
973
|
team-cli data queries ai-edit abc123 --prompt 'Ajusta el pipeline' --params '{"websiteId":"w1"}'
|
|
949
974
|
team-cli data queries preview abc123 --params '{"startDate": "2026-01-01"}'
|
|
950
975
|
team-cli data queries run abc123 --limit 1000 --params '{"startDate": "2026-01-01"}'
|
|
951
|
-
team-cli data queries download abc123 --params '{"startDate": "2026-01-01"}' --path resultado.xlsx`}var
|
|
976
|
+
team-cli data queries download abc123 --params '{"startDate": "2026-01-01"}' --path resultado.xlsx`}var ho=["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"],$o=`
|
|
952
977
|
query ResolverInfo($name: ID!, $mutation: Boolean!) {
|
|
953
978
|
params(name: $name, mutation: $mutation) {
|
|
954
979
|
name
|
|
@@ -957,8 +982,8 @@ Ejemplos:
|
|
|
957
982
|
basicResultQuery
|
|
958
983
|
}
|
|
959
984
|
}
|
|
960
|
-
`;function
|
|
961
|
-
`)}function
|
|
985
|
+
`;function Ea(e){if(!e)throw Error("Uso: team-cli graphql <servicio> '<query>' [--variables '<json>'] [--format toon|json]");if(!ho.includes(e))throw Error(`Servicio "${e}" no válido. Servicios disponibles: ${ho.join(", ")}`)}async function ja(e,t){let o;try{let r=await u({service:e,query:$o,variables:{name:t,mutation:!1}});return{service:e,operationName:t,operationType:"query",info:r.params}}catch(r){o=r}try{let r=await u({service:e,query:$o,variables:{name:t,mutation:!0}});return{service:e,operationName:t,operationType:"mutation",info:r.params}}catch(r){let a=o instanceof Error?o.message:"",n=r instanceof Error?r.message:"";if(a.includes('Cannot query field "params"')||n.includes('Cannot query field "params"'))throw Error(`El servicio "${e}" no expone metadata de resolvers por GraphQL.`);throw o instanceof Error?o:r}}async function xo(e,t){let o=e[1],r=e[2],a=e[2];if(!d())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(Ea(o),r==="info"){let s=e[3];if(!s)throw Error("Uso: team-cli graphql <servicio> info <queryName|mutationName> [--format toon|json]");return await ja(o,s)}if(!a)throw Error("Uso: team-cli graphql <servicio> '<query>' [--variables '<json>'] [--format toon|json]");let n;if(t.variables)try{n=JSON.parse(t.variables)}catch{throw Error("Las variables deben ser un JSON válido.")}return await u({service:o,query:a,variables:n})}function So(){return Object.keys(ie)}function Aa(){return So().map((e)=>{let t=ie[e].prod;return`- \`${e}\`: \`${t}/graphql\``}).join(`
|
|
986
|
+
`)}function Eo(){let t=So().join(", "),o=Aa();return`team-cli graphql
|
|
962
987
|
|
|
963
988
|
Ejecutar queries y mutations GraphQL.
|
|
964
989
|
|
|
@@ -1009,7 +1034,7 @@ npx @getjusto/team-cli graphql auth info requestLoginCode --format json
|
|
|
1009
1034
|
|
|
1010
1035
|
Usa esto para mapear una URL GraphQL al valor correcto de \`team-cli graphql <service>\`.
|
|
1011
1036
|
|
|
1012
|
-
${o}`}import{
|
|
1037
|
+
${o}`}import{resolve as Pa}from"node:path";import{readdirSync as Na,readFileSync as va,statSync as Ra}from"node:fs";import{gzipSync as Ta}from"node:zlib";import{join as Oa,relative as Ua,resolve as Qa}from"node:path";var Ie=512,Ja=2;function Wa(e){let t=e.replaceAll("\\","/");if(t.startsWith("/")||t.includes("../"))throw Error(`Ruta inválida en el space: ${e}`);return t}function _a(e){let t=Wa(e);if(Buffer.from(t).length<=100)return{name:t,prefix:""};let r=t.lastIndexOf("/");if(r<=0)throw Error(`La ruta es demasiado larga para el paquete del space: ${e}`);let a=t.slice(0,r),n=t.slice(r+1);if(Buffer.from(a).length>155||Buffer.from(n).length>100)throw Error(`La ruta es demasiado larga para el paquete del space: ${e}`);return{name:n,prefix:a}}function J(e,t,o,r){let a=Buffer.from(r);a.copy(e,t,0,Math.min(a.length,o))}function ee(e,t,o,r){let a=Math.max(0,Math.trunc(r)).toString(8).padStart(o-1,"0");J(e,t,o,`${a}\x00`)}function Ba(e){let t=Buffer.alloc(Ie,0),{name:o,prefix:r}=_a(e.path);J(t,0,100,o),ee(t,100,8,e.mode),ee(t,108,8,0),ee(t,116,8,0),ee(t,124,12,e.content.length),ee(t,136,12,e.mtime),t.fill(32,148,156),J(t,156,1,"0"),J(t,257,6,"ustar"),J(t,263,2,"00"),J(t,345,155,r);let a=0;for(let i of t)a+=i;let n=`${a.toString(8).padStart(6,"0")}\x00 `;return J(t,148,8,n),t}function Ma(e){let t=e%Ie;return t===0?0:Ie-t}function jo(e,t=e){return Na(t,{withFileTypes:!0}).sort((r,a)=>r.name.localeCompare(a.name)).flatMap((r)=>{let a=Oa(t,r.name);if(r.isDirectory())return jo(e,a);if(!r.isFile())return[];let n=Ua(e,a),i=Ra(a);return[{path:n,content:va(a),mode:i.mode&511,mtime:Math.floor(i.mtimeMs/1000)}]})}function Ao(e){let t=Qa(e),o=jo(t);if(!o.length)throw Error("El build del space no contiene archivos para publicar");let r=[];for(let a of o){r.push(Ba(a)),r.push(a.content);let n=Ma(a.content.length);if(n>0)r.push(Buffer.alloc(n,0))}return r.push(Buffer.alloc(Ie*Ja,0)),Ta(Buffer.concat(r))}function Me(){if(!d())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 te(e,t,o){let r=e[t];if(!r)throw Error(`Falta --${t}. Ejemplo: ${o}`);return r}function No(e,t){let o=e[2];if(!o)throw Error(`Uso: ${t}`);return o}function Pe(){let e=se();if(e==="local")return"http://intra.localhost:5173";if(e==="develop")return"https://intra.bejusto.com";return"https://intra.getjusto.com"}async function Ga(e,t){let o=await Ne(),r=await fetch(`${h("data")}/spaces/publish/${e}`,{method:"POST",headers:{"Content-Type":"application/gzip",...o?{"X-ORION-JWT":o}:{}},body:t}),a=await r.json();if(!r.ok||a.error)throw Error(a.error||"No se pudo publicar el space.");return a}function Ge(){return`team-cli spaces
|
|
1013
1038
|
|
|
1014
1039
|
Spaces son aplicaciones internas en React, pensadas para que las construyan agentes.
|
|
1015
1040
|
El flujo oficial parte con \`spaces init\` y \`spaces publish\` solo acepta apps creadas así.
|
|
@@ -1029,6 +1054,7 @@ Cada space:
|
|
|
1029
1054
|
- \`window.justo.cli(...)\` devuelve Promises, entrega JSON parseado y hace throw en errores
|
|
1030
1055
|
- para queries grandes también reciben \`window.justo.stream(command, onRow)\`
|
|
1031
1056
|
- \`window.justo.stream(...)\` consume NDJSON, parsea cada fila a JSON y llama tu callback
|
|
1057
|
+
- \`spaces init\`, \`spaces preview\` y \`spaces publish\` funcionan en macOS, Linux y Windows sin depender de \`tar\` global
|
|
1032
1058
|
|
|
1033
1059
|
Flujo sugerido para agentes:
|
|
1034
1060
|
1. \`team-cli spaces init --path ./mi-space-app\`
|
|
@@ -1036,7 +1062,7 @@ Flujo sugerido para agentes:
|
|
|
1036
1062
|
3. \`team-cli spaces preview --path ./mi-space-app\`
|
|
1037
1063
|
4. desarrollar la app React dentro de esa carpeta
|
|
1038
1064
|
5. \`team-cli spaces publish <spaceId> --path ./mi-space-app\`
|
|
1039
|
-
6. abrir \`${
|
|
1065
|
+
6. abrir \`${Pe()}/spaces/<slug>\`
|
|
1040
1066
|
|
|
1041
1067
|
Qué crea \`spaces init\`:
|
|
1042
1068
|
- Vite + React + TypeScript
|
|
@@ -1086,7 +1112,8 @@ Comandos:
|
|
|
1086
1112
|
- \`spaces create --name '...' --description '...' --slug my-space\`
|
|
1087
1113
|
- \`spaces preview --path ./mi-space-app [--open]\`
|
|
1088
1114
|
- \`spaces publish <spaceId> --path ./mi-space-app\`
|
|
1089
|
-
- \`spaces archive <spaceId
|
|
1115
|
+
- \`spaces archive <spaceId>\`
|
|
1116
|
+
`}async function vo(e){let t=te(e,"path","team-cli spaces init --path ./mi-space-app");return Xt(t)}async function Ro(e){return await no(e)}async function To(e){Me();let t=te(e,"name","team-cli spaces create --name 'Mi space' --description '...' --slug mi-space"),o=te(e,"description","team-cli spaces create --name 'Mi space' --description 'Sitio interno' --slug mi-space"),r=te(e,"slug","team-cli spaces create --name 'Mi space' --description '...' --slug mi-space"),a=await u({service:"data",query:`mutation ($name: String, $description: String, $slug: String) {
|
|
1090
1117
|
createSpace(name: $name, description: $description, slug: $slug) {
|
|
1091
1118
|
_id
|
|
1092
1119
|
name
|
|
@@ -1097,7 +1124,7 @@ Comandos:
|
|
|
1097
1124
|
createdByEmail
|
|
1098
1125
|
createdById
|
|
1099
1126
|
}
|
|
1100
|
-
}`,variables:{name:t,description:o,slug:r}});return{...a.createSpace,intraUrl:`${
|
|
1127
|
+
}`,variables:{name:t,description:o,slug:r}});return{...a.createSpace,intraUrl:`${Pe()}/spaces/${a.createSpace.slug}`,serveUrl:`${h("data")}/spaces/${a.createSpace.slug}`}}async function Oo(e,t){Me();let o=No(e,"team-cli spaces publish <spaceId> --path ./mi-space-app"),r=te(t,"path","team-cli spaces publish <spaceId> --path ./mi-space-app"),a=Ft(r),n=Ao(a),i=await Ga(o,n);return{...i,intraUrl:i.slug?`${Pe()}/spaces/${i.slug}`:void 0,serveUrl:i.slug?`${h("data")}/spaces/${i.slug}`:void 0,builtFrom:Pa(r)}}async function Uo(e){Me();let t=No(e,"team-cli spaces archive <spaceId>");return(await u({service:"data",query:`mutation ($spaceId: String) {
|
|
1101
1128
|
archiveSpace(spaceId: $spaceId) {
|
|
1102
1129
|
_id
|
|
1103
1130
|
name
|
|
@@ -1109,7 +1136,7 @@ Comandos:
|
|
|
1109
1136
|
createdById
|
|
1110
1137
|
archivedAt
|
|
1111
1138
|
}
|
|
1112
|
-
}`,variables:{spaceId:t}})).archiveSpace}function
|
|
1139
|
+
}`,variables:{spaceId:t}})).archiveSpace}function Qo(e){return`team-cli
|
|
1113
1140
|
|
|
1114
1141
|
Herramienta CLI para el equipo Justo.
|
|
1115
1142
|
|
|
@@ -1158,4 +1185,4 @@ Crea queries personalizadas usando \`create\` y \`ai-edit\` para generar consult
|
|
|
1158
1185
|
para mostrar datos. Usa \`preview\` para iterar rápido, \`run\` para consumir NDJSON en streaming y \`download\` para Excel.
|
|
1159
1186
|
También puedes usar queries para poblar selectores y otras partes de la interfaz del space.
|
|
1160
1187
|
|
|
1161
|
-
`}function
|
|
1188
|
+
`}function Jo(){let e=d(),t=e?`Sesión: ${e.email}`:"Sesión: no iniciada";return Qo(t)}async function Wo(e){let{positional:t,flags:o}=re(e);if(o.env)Ve(o.env);let r=t[0],a=t[1];if(r==="__spaces-preview-bridge")return await ao(o);if(o.version)return{version:"0.0.6"};if(o.help&&!r)return Jo();if(r==="auth"){if(a==="--help"||o.help)return Te();if(a==="login")return await vt();if(a==="login-with-token")return await Rt(o);if(a==="request-code")return await Tt(o);if(a==="logout")return await Ot();if(a==="status")return await Ut();return Te()}if(r==="admin"){let n=t[1],i=t[2],s=t[3],c=t[4];if(!n||n==="--help")return me();if(n==="search"&&o.help)return Et();if(n==="search")return await St(t,o);if(!i||i==="--help")return me();if(i==="show")return await ct(n);if(i==="stores"&&s==="list")return await jt(n);if(i==="coupons"&&(!s||s==="--help"))return D();if(i==="coupons"&&s==="create"&&o.help)return $t();if(i==="coupons"&&s==="update"&&o.help)return xt();if(i==="coupons"&&s==="codes"&&t[4]==="create"&&o.help)return wt();if(i==="coupons"&&o.help)return D();if(i==="coupons"&&s==="list")return await Ct(n,o);if(i==="coupons"&&s==="show"){if(!c)throw Error("Uso: team-cli admin <web> coupons show <couponId>");return await yt(n,c)}if(i==="coupons"&&s==="create")return await qt(n,o);if(i==="coupons"&&s==="update"){if(!c)throw Error("Uso: team-cli admin <web> coupons update <couponId> --input '<json>'");return await It(n,c,o)}if(i==="coupons"&&s==="delete"){if(!c)throw Error("Uso: team-cli admin <web> coupons delete <couponId>");return await ht(n,c)}if(i==="coupons"&&s==="codes"){let m=t[4],l=t[5];if(!m||m==="--help")return D();if(m==="list"){if(!l)throw Error("Uso: team-cli admin <web> coupons codes list <couponId>");return await dt(n,l,o)}if(m==="create"){if(!l)throw Error("Uso: team-cli admin <web> coupons codes create <couponId> --input '<json>'");return await pt(n,l,o)}if(m==="create-random"){if(!l)throw Error("Uso: team-cli admin <web> coupons codes create-random <couponId> --quantity <n>");return await gt(n,l,o)}if(m==="delete"){if(!l)throw Error(`Uso: team-cli admin <web> coupons codes delete <couponId> --ids '["id1"]'`);return await ft(n,l,o)}return D()}return me()}if(r==="graphql"){if(a==="--help"||o.help)return Eo();return await xo(t,o)}if(r==="data"){let n=t[1],i=t[2];if(o.help||a==="--help")return Be();if(n==="queries"&&i==="create")return await go();if(n==="queries"&&i==="edit")return await fo(t);if(n==="queries"&&i==="ai-edit")return await wo(t,o);if(n==="queries"&&i==="view")return await bo(t);if(n==="queries"&&i==="view-pipeline")return await Co(t);if(n==="queries"&&i==="preview")return await yo(t,o);if(n==="queries"&&i==="run")return await qo(t,o);if(n==="queries"&&i==="download")return await Io(t,o);return Be()}if(r==="spaces"){let n=t[1];if(!n||n==="--help"||o.help)return Ge();if(n==="init")return await vo(o);if(n==="create")return await To(o);if(n==="preview")return await Ro(o);if(n==="publish")return await Oo(t,o);if(n==="archive")return await Uo(t);return Ge()}return Jo()}var{flags:_o}=re(process.argv.slice(2));async function Fa(){try{let e=await Wo(process.argv.slice(2));if(e&&typeof e==="object"&&"__streamHandled"in e&&e.__streamHandled)return;if(typeof e==="string"){ke(e);return}ze(e,_o)}catch(e){Ke(e,_o),process.exit(1)}}Fa();
|