@tailor-platform/sdk 2.14.1 → 2.14.2
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/CHANGELOG.md +6 -0
- package/dist/{application-CfevPO-k.mjs → application-BAqZFMWP.mjs} +2 -2
- package/dist/{application-CfevPO-k.mjs.map → application-BAqZFMWP.mjs.map} +1 -1
- package/dist/application-BKlOiD1x.mjs +1 -0
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/main.mjs +3 -3
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/{register-ts-hook-DZ1Kpt4s.mjs → register-ts-hook-Cphn4r8s.mjs} +3 -3
- package/dist/{register-ts-hook-DZ1Kpt4s.mjs.map → register-ts-hook-Cphn4r8s.mjs.map} +1 -1
- package/dist/{service_pb-CxHztLk1.mjs → service_pb-BdzjiHfC.mjs} +2 -2
- package/dist/{service_pb-CxHztLk1.mjs.map → service_pb-BdzjiHfC.mjs.map} +1 -1
- package/dist/service_pb-p68oLtp9.mjs +1 -0
- package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +5 -1
- package/dist/{workspace_resource_pb-u9bj6p3i.mjs → workspace_resource_pb-C4EY-Gns.mjs} +2 -2
- package/dist/{workspace_resource_pb-u9bj6p3i.mjs.map → workspace_resource_pb-C4EY-Gns.mjs.map} +1 -1
- package/package.json +1 -1
- package/dist/application-BWOMdL3D.mjs +0 -1
- package/dist/service_pb-CFVlGYdr.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,t}from"./application-BAqZFMWP.mjs";export{t as defineApplication,e as generatePluginFilesIfNeeded};
|
package/dist/cli/lib.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as ee,r as e}from"../logger-CCjs1DuH.mjs";import{$n as t,$r as n,A as r,An as i,At as a,B as o,Bn as s,Bt as c,D as l,Er as u,Et as d,F as f,G as p,Gt as m,H as h,Hn as g,In as _,It as v,J as y,Jt as b,Kr as x,Lt as S,M as C,N as w,Ot as T,P as E,Pt as D,Q as O,Qn as k,Qr as A,Qt as j,Rr as M,Rt as N,S as P,Sr as F,St as I,T as L,Tr as R,Tt as z,U as B,Un as V,Ut as H,Vn as U,Vt as W,Wn as G,Xn as K,Xr as q,Y as J,Yn as Y,Yr as X,Zn as Z,Zr as Q,Zt as te,_ as ne,ai as $,b as re,cr as ie,ct as ae,d as oe,dn as se,et as ce,ft as le,h as ue,hr as de,ht as fe,i as pe,it as me,jr as he,jt as ge,k as _e,l as ve,mr as ye,mt as be,n as xe,nt as Se,on as Ce,ot as we,p as Te,pn as Ee,pr as De,qn as Oe,qt as ke,r as Ae,rn as je,rr as Me,s as Ne,sr as Pe,t as Fe,un as Ie,ut as Le,vt as Re,wn as ze,wr as Be,wt as Ve,y as He,yt as Ue,zn as We}from"../register-ts-hook-
|
|
1
|
+
import{n as ee,r as e}from"../logger-CCjs1DuH.mjs";import{$n as t,$r as n,A as r,An as i,At as a,B as o,Bn as s,Bt as c,D as l,Er as u,Et as d,F as f,G as p,Gt as m,H as h,Hn as g,In as _,It as v,J as y,Jt as b,Kr as x,Lt as S,M as C,N as w,Ot as T,P as E,Pt as D,Q as O,Qn as k,Qr as A,Qt as j,Rr as M,Rt as N,S as P,Sr as F,St as I,T as L,Tr as R,Tt as z,U as B,Un as V,Ut as H,Vn as U,Vt as W,Wn as G,Xn as K,Xr as q,Y as J,Yn as Y,Yr as X,Zn as Z,Zr as Q,Zt as te,_ as ne,ai as $,b as re,cr as ie,ct as ae,d as oe,dn as se,et as ce,ft as le,h as ue,hr as de,ht as fe,i as pe,it as me,jr as he,jt as ge,k as _e,l as ve,mr as ye,mt as be,n as xe,nt as Se,on as Ce,ot as we,p as Te,pn as Ee,pr as De,qn as Oe,qt as ke,r as Ae,rn as je,rr as Me,s as Ne,sr as Pe,t as Fe,un as Ie,ut as Le,vt as Re,wn as ze,wr as Be,wt as Ve,y as He,yt as Ue,zn as We}from"../register-ts-hook-Cphn4r8s.mjs";import{$ as Ge}from"../application-BAqZFMWP.mjs";import{t as Ke}from"../type-source--ZNcV8RJ.mjs";import{arg as qe,defineCommand as Je,runCommand as Ye,runMain as Xe}from"politty";await Fe(new URL(`./ts-hook.mjs`,import.meta.url));export{s as DB_TYPES_FILE_NAME,U as DIFF_FILE_NAME,g as INITIAL_SCHEMA_NUMBER,V as MIGRATE_FILE_NAME,G as MIGRATE_TEST_FILE_NAME,Me as MIGRATION_LABEL_KEY,Oe as SCHEMA_FILE_NAME,Be as apiCall,j as apply,j as deploy,qe as arg,R as assertWritable,ze as bundleMigrationScript,E as bundleSeedScript,w as chunkSeedData,Pe as compareLocalTypesWithSnapshot,ie as compareSnapshots,X as configArg,q as confirmationArgs,Q as createCommonArgs,Le as createFolder,_ as createSnapshotFromLocalTypes,Ce as createWorkspace,x as defineAppCommand,Je as defineCommand,ae as deleteFolder,He as deleteWorkspace,h as deployStaticWebsite,A as deploymentArgs,se as ensureConfigId,xe as errorToJson,z as executeScript,Ve as extractOwnedNamespaces,De as formatDiffSummary,ye as formatMigrationDiff,Ue as generate,Ee as generateUserTypes,P as getAppHealth,te as getExecutor,S as getExecutorJob,N as getExecutorWaitFailureMessage,we as getFolder,a as getFunctionRegistry,Y as getLatestMigrationNumber,fe as getMachineUserToken,K as getMigrationDirPath,Z as getMigrationFilePath,k as getMigrationFiles,i as getNamespacesWithMigrations,t as getNextMigrationNumber,be as getOAuth2Client,ce as getOrganization,m as getWorkflow,ke as getWorkflowExecution,ne as getWorkspace,de as hasChanges,Ge as initOperatorClient,Te as inviteUser,Ke as isPluginGeneratedTable,re as listApps,c as listExecutorJobs,v as listExecutors,me as listFolders,T as listFunctionRegistries,Re as listMachineUsers,le as listOAuth2Clients,O as listOrganizations,oe as listUsers,ge as listWebhookExecutors,b as listWorkflowExecutions,_e as listWorkflows,je as listWorkspaces,he as loadAccessToken,u as loadConfig,n as loadEnvFiles,C as loadSeedContext,I as loadTailorDBNamespaces,M as loadWorkspaceId,o as logBetaWarning,ee as logger,f as migrateGenerate,J as organizationTree,F as prompt,pe as query,We as reconstructSnapshotFromMigrations,p as remove,ve as removeUser,ue as restoreWorkspace,l as resumeWorkflow,Ye as runCommand,Xe as runMain,Ae as serializeError,B as show,H as startWorkflow,e as styles,D as triggerExecutor,r as truncate,Se as updateFolder,y as updateOrganization,Ne as updateUser,d as waitForExecution,L as waitWorkflowExecution,W as watchExecutorJob,$ as workspaceArgs,Ie as workspaceNameSchema};
|
|
2
2
|
//# sourceMappingURL=lib.mjs.map
|
package/dist/cli/main.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{r as e}from"../schema-DMlLMsWA.mjs";import{E as t,Ft as n,Ht as r,Ot as i,q as a}from"../workspace_resource_pb-
|
|
2
|
+
import{r as e}from"../schema-DMlLMsWA.mjs";import{E as t,Ft as n,Ht as r,Ot as i,q as a}from"../workspace_resource_pb-C4EY-Gns.mjs";import{t as o}from"../assert-WeXvmG4j.mjs";import{a as s,n as c,r as l}from"../logger-CCjs1DuH.mjs";import{$ as u,$t as d,An as f,Ar as p,B as m,Br as h,C as g,Cn as _,Cr as v,Ct as y,Dn as b,Dr as x,Dt as S,E as C,En as ee,Er as w,Fn as T,Fr as te,Ft as ne,Gn as re,Gr as E,Hr as ie,Ht as ae,I as oe,In as se,Ir as ce,Jn as le,Jr as ue,K as de,Kn as fe,Kr as D,Kt as pe,L as me,Ln as he,Lr as ge,M as _e,Mn as ve,Mr as ye,Mt as be,N as xe,Nn as Se,Nr as Ce,Nt as we,O as Te,On as Ee,Or as De,P as Oe,Pn as ke,Pr as Ae,Qn as je,Qr as O,R as Me,Rn as k,Rr as Ne,Sn as Pe,Sr as A,St as Fe,Tn as Ie,Tr as j,Tt as Le,Ur as Re,V as ze,Vr as Be,W as Ve,Wr as He,Wt as Ue,X as We,Xr as M,Xt as Ge,Yn as Ke,Yr as qe,Yt as Je,Z as Ye,Zn as Xe,_n as Ze,_r as N,_t as Qe,a as $e,ai as P,an as et,ar as tt,at as nt,bn as rt,br as it,bt as at,c as ot,cn as st,cr as ct,dr as F,dt as lt,ei as ut,en as dt,er as ft,f as pt,fn as mt,fr as ht,g as gt,gn as _t,gr as vt,gt as yt,hn as bt,hr as xt,ii as I,in as St,ir as Ct,j as wt,jn as Tt,jr as Et,kn as Dt,kr as Ot,kt,ln as At,lr as jt,lt as Mt,m as Nt,mn as Pt,mr as Ft,ni as L,nn as It,nr as Lt,o as Rt,or as zt,pr as Bt,pt as Vt,q as Ht,r as Ut,ri as Wt,rr as Gt,rt as Kt,sn as qt,sr as Jt,st as Yt,t as Xt,ti as Zt,tn as Qt,tr as $t,tt as en,u as tn,ur as R,v as nn,vn as rn,vr as an,w as on,wn as sn,wr as cn,wt as ln,x as un,xn as dn,xr as fn,xt as pn,yn as mn,yr as hn,yt as gn,z as _n,zn as z,zr as B,zt as vn}from"../register-ts-hook-Cphn4r8s.mjs";import{$ as yn,A as bn,B as xn,D as Sn,E as Cn,G as V,H as wn,K as Tn,M as En,N as Dn,O as On,Q as kn,U as An,V as jn,X as Mn,Y as Nn,Z as Pn,d as Fn,et as In,f as Ln,h as Rn,j as zn,k as Bn,o as Vn,p as Hn,q as Un,s as Wn,v as Gn,y as Kn}from"../application-BAqZFMWP.mjs";import{g as qn,i as Jn,r as Yn}from"../service-7SCy2bhm.mjs";import{t as H}from"../multiline-EyzjEwn9.mjs";import{t as Xn}from"../package-json-C690ceex.mjs";import{t as Zn}from"../user-agent-vdHYF3QL.mjs";import{a as Qn,i as $n,n as er,o as tr,r as nr,t as rr}from"../errors-BlX4gUw5.mjs";import{t as ir}from"../service_pb-BdzjiHfC.mjs";import{a as ar,i as or,o as sr,r as cr,t as lr}from"../crashreport-BN28xp5B.mjs";import{a as ur,i as dr,n as fr}from"../kysely-type-B-BOlXH7.mjs";import*as U from"pathe";import{dirname as pr,resolve as mr}from"pathe";import{resolvePackageJSON as hr}from"pkg-types";import{arg as W,defineCommand as G,extractFields as gr,runCommand as K,runMain as _r,toCamelCase as vr}from"politty";import{withCompletionCommand as yr}from"politty/completion";import{withSkillCommand as br}from"politty/skill";import{z as q}from"zod";import{ScalarType as J,create as xr}from"@bufbuild/protobuf";import*as Y from"node:fs";import{accessSync as Sr,constants as Cr,readdirSync as wr}from"node:fs";import{timestampDate as X}from"@bufbuild/protobuf/wkt";import{pathToFileURL as Tr}from"node:url";import{generateCodeVerifier as Er}from"@badgateway/oauth2-client";import{Code as Z,ConnectError as Q}from"@connectrpc/connect";import*as Dr from"node:crypto";import{randomBytes as Or}from"node:crypto";import*as kr from"node:http";import Ar from"open";import*as jr from"rolldown";import{parseSync as Mr}from"oxc-parser";import*as Nr from"node:os";import*as $ from"node:fs/promises";import{TraceMap as Pr,generatedPositionFor as Fr,originalPositionFor as Ir}from"@jridgewell/trace-mapping";import{spawn as Lr,spawnSync as Rr}from"node:child_process";const zr=ir.methods.filter(e=>e.methodKind===`unary`);function listMethodNames(){return zr.map(e=>e.name).toSorted()}function listMethodChoices(){return zr.flatMap(e=>[e.name,`${ir.typeName}/${e.name}`]).toSorted()}function getMethodDescriptor(e){return zr.find(t=>t.name===e)}function extractMethodName(e){return e.includes(`/`)?e.split(`/`).pop()??e:e}function nestedMessage(e){if(e.fieldKind===`message`||e.fieldKind===`list`&&e.listKind===`message`||e.fieldKind===`map`&&e.mapKind===`message`)return e.message}function isWellKnownType(e){return e.typeName.startsWith(`google.protobuf.`)}const Br=new Set([`google.protobuf.Struct`,`google.protobuf.Value`,`google.protobuf.ListValue`,`google.protobuf.NullValue`,`google.protobuf.Any`,`google.protobuf.Empty`]);function isUnrepresentableWellKnownType(e){return Br.has(e.typeName)}function enumerateAllFieldCompletions(e){let t=getMethodDescriptor(e);if(!t)return[];let n=[],r=new Set;function walk(e,t){r.add(e);for(let i of e.fields){if(i.fieldKind===`list`||i.fieldKind===`map`)continue;let e=t+i.localName;if(i.fieldKind===`message`){if(isUnrepresentableWellKnownType(i.message))continue;if(!isWellKnownType(i.message)){let t=i.message;n.push({value:`${e}.`,description:`${e} (message)`}),r.has(t)||walk(t,`${e}.`);continue}}if(n.push({value:`${e}=`,description:`Set ${e}`}),i.fieldKind===`enum`)for(let t of i.enum.values)n.push({value:`${e}=${t.name}`,description:t.name});else i.fieldKind===`scalar`&&i.scalar===J.BOOL&&(n.push({value:`${e}=true`,description:`true`}),n.push({value:`${e}=false`,description:`false`}))}r.delete(e)}return walk(t.input,``),n}function resolveLeafField(e,t){let n=e;for(let e=0;e<t.length;e++){let r=n.fields.find(n=>n.localName===t[e]);if(!r)return;if(e===t.length-1)return r.fieldKind===`message`&&isUnrepresentableWellKnownType(r.message)?void 0:r;if(r.fieldKind!==`message`||isWellKnownType(r.message))return;n=r.message}}const Vr={[J.DOUBLE]:`double`,[J.FLOAT]:`float`,[J.INT64]:`int64`,[J.UINT64]:`uint64`,[J.INT32]:`int32`,[J.FIXED64]:`fixed64`,[J.FIXED32]:`fixed32`,[J.BOOL]:`bool`,[J.STRING]:`string`,[J.BYTES]:`bytes`,[J.UINT32]:`uint32`,[J.SFIXED32]:`sfixed32`,[J.SFIXED64]:`sfixed64`,[J.SINT32]:`sint32`,[J.SINT64]:`sint64`};function shortName(e){let t=e.lastIndexOf(`.`);return t<0?e:e.slice(t+1)}function scalarLabel(e){return Vr[e]??`scalar(${e})`}function enumLabel(e){return`enum ${shortName(e.typeName)}`}function enumOf(e){if(e.fieldKind===`enum`||e.fieldKind===`list`&&e.listKind===`enum`)return e.enum}function describeFieldType(e){switch(e.fieldKind){case`scalar`:return scalarLabel(e.scalar);case`enum`:return enumLabel(e.enum);case`message`:return shortName(e.message.typeName);case`list`:{let t;return t=e.listKind===`scalar`?scalarLabel(e.scalar):e.listKind===`enum`?enumLabel(e.enum):shortName(e.message.typeName),`repeated ${t}`}case`map`:{let t=scalarLabel(e.mapKey),n;return n=e.mapKind===`scalar`?scalarLabel(e.scalar):e.mapKind===`enum`?enumLabel(e.enum):shortName(e.message.typeName),`map<${t}, ${n}>`}default:return`<unknown>`}}function fieldToJson(e,t){let n={name:e.localName,protoName:e.name,type:describeFieldType(e),fieldKind:e.fieldKind,repeated:e.fieldKind===`list`};e.oneof&&(n.oneof=e.oneof.name);let r=enumOf(e);r&&(n.enumValues=r.values.map(e=>e.name));let i=nestedMessage(e);return i&&!t.has(i)?(t.add(i),n.message={typeName:i.typeName,fields:i.fields.map(e=>fieldToJson(e,t))},t.delete(i)):i&&(n.message={typeName:i.typeName,fields:[],recursive:!0}),n}function renderInspectJson(e){let t=new Set([e.input]);return{method:e.name,input:{typeName:e.input.typeName,fields:e.input.fields.map(e=>fieldToJson(e,t))},output:{typeName:e.output.typeName}}}function renderFieldText(e,t,n){let r=[],i=e.oneof?` (oneof ${e.oneof.name})`:``;r.push(`${t}${e.localName}: ${describeFieldType(e)}${i}`);let a=enumOf(e);if(a){let e=a.values.map(e=>e.name).join(`, `);r.push(`${t} values: ${e}`)}let o=nestedMessage(e);if(o&&!n.has(o)){n.add(o);for(let e of o.fields)r.push(...renderFieldText(e,`${t} `,n));n.delete(o)}else o&&r.push(`${t} …(recursive ${o.typeName})`);return r}function renderInspectText(e){let t=[];t.push(`${e.name}`),t.push(` request: ${e.input.typeName}`);let n=new Set([e.input]);for(let r of e.input.fields)t.push(...renderFieldText(r,` `,n));return t.push(` response: ${e.output.typeName}`),t.join(`
|
|
3
3
|
`)}const Hr=D({name:`inspect`,description:`Print the input message tree of an OperatorService endpoint.`,notes:"Combine with the global `--json` flag for a machine-readable descriptor. Recursive type references and `oneof` membership are annotated. Use `tailor api list` to discover endpoint names.",examples:[{cmd:`GetApplication`,desc:`Show fields of GetApplicationRequest.`},{cmd:`CreateExecutorExecutor`,desc:"Inspect a deeply nested input with `(oneof config)` annotations."}],args:q.strictObject({endpoint:W(q.string(),{positional:!0,description:`API endpoint to inspect (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').`,completion:{custom:{choices:listMethodNames()}}})}),run:e=>{let t=extractMethodName(e.endpoint),n=getMethodDescriptor(t);if(!n)throw rr({message:`unknown method: ${t}`,suggestion:"Run `tailor api list` to see available methods.",command:`api inspect`});c.jsonMode?c.out(renderInspectJson(n)):c.out(renderInspectText(n))}}),Ur=D({name:`list`,description:`List all invocable OperatorService methods.`,notes:`Only single-request (non-streaming) methods are listed, because the CLI issues a single JSON request and reads one JSON response.`,args:q.strictObject({}),run:()=>{let e=listMethodNames();if(c.jsonMode)c.out(e);else for(let t of e)c.out(t)}});function resolveNamespaceName(e,t){if(/Auth|Tenant|UserProfile/.test(e))return t.auth?.name;if(/IdP/.test(e))return t.idp?.length===1?o(t.idp[0],`idp config missing`).name:void 0;if(/TailorDB/.test(e)){let e=Object.keys(t.db??{});return e.length===1?e[0]:void 0}if(/Pipeline/.test(e)){let e=Object.keys(t.resolver??{});return e.length===1?e[0]:void 0}}function parseBodyAsObject(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t==`object`&&t&&!Array.isArray(t))return t}function setNestedPath(e,t,n){let r=e;for(let e=0;e<t.length-1;e++){let n=o(t[e],`path segment missing`),i=r[n];(typeof i!=`object`||!i||Array.isArray(i))&&(r[n]={}),r=r[n]}r[o(t[t.length-1],`path last segment missing`)]=n}function coerceFieldValue(e,t){if(e&&e.fieldKind===`scalar`&&e.scalar===J.BOOL){if(t===`true`)return!0;if(t===`false`)return!1;throw Error(`Invalid value for bool field: '${t}'. Expected 'true' or 'false'.`)}return t}function normalizeBodyFieldKeys(e,t){let n=new Map;for(let e of t)n.set(e.name,e.localName),n.set(e.jsonName,e.localName);let r=!1;for(let t of Object.keys(e)){let i=n.get(t);i&&i!==t&&(Object.hasOwn(e,i)||(e[i]=e[t]),delete e[t],r=!0)}return r}const Wr=new Set([`__proto__`,`constructor`,`prototype`]),Gr=q.string().transform((e,t)=>{let n=e.indexOf(`=`);if(n<0)return t.addIssue({code:`custom`,message:`Invalid field format: '${e}'. Expected format: 'key=value' or 'a.b.c=value'`}),q.NEVER;let r=e.slice(0,n);if(r.length===0)return t.addIssue({code:`custom`,message:`Field key cannot be empty`}),q.NEVER;let i=r.split(`.`);if(i.some(e=>e.length===0))return t.addIssue({code:`custom`,message:`Invalid field key: '${r}'. Dotted segments cannot be empty`}),q.NEVER;let a=i.find(e=>Wr.has(e));return a?(t.addIssue({code:`custom`,message:`Invalid field key: '${r}'. Segment '${a}' is not allowed.`}),q.NEVER):{path:i,value:e.slice(n+1)}}),Kr=D({name:`api`,description:`Call Tailor Platform API endpoints directly.`,notes:"Use `tailor api list` to enumerate invocable methods and `tailor api inspect <endpoint>` to print an endpoint's input message tree (combine with `--json` for machine-readable output).\n\nThe request body is inferred from the target endpoint's request schema, and commonly required fields are auto-injected so they can be omitted from `--body`:\n\n- `workspaceId` — resolved from `-w` / `TAILOR_PLATFORM_WORKSPACE_ID` / the selected profile.\n- `namespaceName` — resolved from `tailor.config.ts` based on the endpoint's service:\n - Auth / Tenant / UserProfile endpoints use `auth.name`.\n - IdP / TailorDB / Pipeline endpoints use the sole configured namespace when exactly one is defined.\n\nValues already present in `--body` are never overridden. If a value cannot be resolved (e.g. no config found), injection is silently skipped and the server-side validation error takes precedence.\n\nUse `--field key=value` (repeatable) to set request body fields without writing JSON. Dotted keys (e.g. `application.name=foo`) build nested objects. `--field` overrides matching fields in `--body` and tab-completes from the endpoint's request schema.",examples:[{cmd:`GetApplication -b '{"applicationName":"app-1"}'`,desc:`Call an endpoint; workspaceId is auto-injected.`},{cmd:`GetApplication -f applicationName=app-1`,desc:`Same as above, using --field instead of --body.`},{cmd:`list`,desc:`List all invocable OperatorService methods.`},{cmd:`inspect GetApplication`,desc:`Show the input message tree for an endpoint.`}],subCommands:{list:Ur,inspect:Hr},args:q.strictObject({...P,...qe,body:W(q.string().default(`{}`),{alias:`b`,description:`Request body as JSON.`}),field:W(Gr.array().optional(),{alias:`f`,description:"Set a body field as `key=value` (repeatable; dotted keys nest). Overrides --body.",completion:{custom:{expand:{dependsOn:[`endpoint`],enumerate:({endpoint:e})=>enumerateAllFieldCompletions(extractMethodName(e??``))}}}}),endpoint:W(q.string(),{positional:!0,description:`API endpoint to call (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').`,completion:{custom:{choices:listMethodChoices()}}})}),run:async e=>{await j({profile:e.profile});let t=extractMethodName(e.endpoint),n=getMethodDescriptor(t),r=parseBodyAsObject(e.body),i=!1;if(e.field&&e.field.length>0){if(!r)throw Error(`--field requires --body to be a JSON object (or omitted).`);for(let t of e.field){let e=n?resolveLeafField(n.input,t.path):void 0;setNestedPath(r,t.path,coerceFieldValue(e,t.value))}i=!0}if(r&&n){normalizeBodyFieldKeys(r,n.input.fields)&&(i=!0);let a=n.input.fields.map(e=>e.localName);if(a.includes(`workspaceId`)&&!Object.hasOwn(r,`workspaceId`))try{r.workspaceId=await Ne({workspaceId:e[`workspace-id`],profile:e.profile}),i=!0}catch{}if(a.includes(`namespaceName`)&&!Object.hasOwn(r,`namespaceName`))try{let{config:n}=await w(e.config),a=resolveNamespaceName(t,n);a&&(r.namespaceName=a,i=!0)}catch{}}let a=await cn({profile:e.profile,endpoint:e.endpoint,body:i&&r?JSON.stringify(r):e.body});c.out(JSON.stringify(a.data,null,2))}}),qr=D({name:`status`,description:`Show the active Tailor Platform authentication status without printing tokens.`,args:q.strictObject({profile:P.profile}),run:async({profile:e})=>{let t=await ye({profile:e});if(c.out(t),!t.authenticated)throw Error(`Not authenticated. Run 'tailor login' and try again.`)}}),Jr=D({name:`token`,description:`Print a valid Tailor Platform access token to stdout, refreshing it first if expired.`,args:q.strictObject({profile:P.profile}),run:async({profile:e})=>{let t=await Et({profile:e});c.out(t)}}),Yr=G({name:`auth`,description:`Authentication helpers for scripts and plugins.`,subCommands:{status:qr,token:Jr}}),Xr={name:W(q.string(),{alias:`n`,description:`Auth connection name`})};async function fetchOIDCDiscovery(e){let t=e.replace(/\/$/,``)+`/.well-known/openid-configuration`,n=await fetch(t).catch(e=>{throw Error(`Failed to fetch OIDC discovery from ${t}: ${Qn(e).message}`,{cause:e})});if(!n.ok)throw Error(`Failed to fetch OIDC discovery from ${t}: ${n.status}`);return n.json()}function randomState$1(){return Dr.randomBytes(32).toString(`base64url`)}const Zr=D({name:`authorize`,description:`Authorize an auth connection via OAuth2 flow.`,args:q.strictObject({...P,...Xr,scopes:q.string().optional().default(`openid,profile,email`).describe(`OAuth2 scopes to request (comma-separated)`),port:q.coerce.number().optional().default(8080).describe(`Local callback server port`),"no-browser":q.boolean().optional().default(!1).describe(`Don't open browser automatically`)}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=(await wn(async(e,r)=>{let{connections:i,nextPageToken:a}=await t.listAuthConnections({workspaceId:n,pageToken:e,pageSize:r});return[i,a]})).find(t=>t.name===e.name);if(!r)throw Error(`Auth connection "${e.name}" not found.`);if(r.config.case!==`oauth2`)throw Error(`Auth connection "${e.name}" is not an OAuth2 connection.`);let i=r.config.value,a=`http://localhost:${e.port}/callback`,o=randomState$1(),s;s=i.authUrl?i.authUrl:(await fetchOIDCDiscovery(i.providerUrl)).authorization_endpoint;let l=new URL(s);l.searchParams.set(`client_id`,i.clientId),l.searchParams.set(`redirect_uri`,a),l.searchParams.set(`response_type`,`code`),l.searchParams.set(`scope`,e.scopes.replace(/,/g,` `)),l.searchParams.set(`state`,o),l.searchParams.set(`access_type`,`offline`),await new Promise((r,i)=>{let handleCallback=async(c,l)=>{if(!c.url?.startsWith(`/callback`)){l.writeHead(404),l.end(`Not found`);return}try{let i=new URL(c.url,`http://localhost:${e.port}`),u=i.searchParams.get(`code`),d=i.searchParams.get(`state`),f=i.searchParams.get(`error`);if(f)throw Error(`Authorization failed: ${f}`);if(d!==o)throw Error(`State mismatch — possible CSRF attack.`);if(!u)throw Error(`No authorization code received.`);await t.exchangeAuthConnectionAuthorizationCode({workspaceId:n,connectionName:e.name,authorizationCode:u,redirectUri:a}),l.writeHead(200,{"Content-Type":`text/html`}),l.end(`<html><body><h1>Authorization successful</h1><p>You can close this window.</p></body></html>`),s.close(),r()}catch(e){l.writeHead(400,{"Content-Type":`text/plain`}),l.end(`Authorization failed: ${e instanceof Error?e.message:`Unknown error`}`),s.close(),i(Qn(e))}},s=kr.createServer((e,t)=>void handleCallback(e,t)),u=setTimeout(()=>{s.close(),i(Error(`Authorization timeout exceeded (5 minutes).`))},3e5);s.on(`close`,()=>{clearTimeout(u)}),s.on(`error`,t=>{clearTimeout(u);let n=t.code,r=n===`EADDRINUSE`||n===`EACCES`?`Try a different port with --port, or authorize via the Console instead:`:`Authorize via the Console instead:`;c.warn(`Could not start the local callback server on port ${e.port}${n?` (${n})`:``}.\n${r}\n tailor authconnection open`),i(t)});let announceAuthorizeUrl=async()=>{let t=l.toString();if(c.info(e[`no-browser`]?`Open this URL in your browser to authorize:\n\n${t}\n`:`Opening browser for authorization:\n\n${t}\n`),c.info(`If this flow doesn't complete, you can authorize via the Console instead:
|
|
4
4
|
tailor authconnection open`),!e[`no-browser`])try{await Ar(t)}catch{c.warn(`Failed to open browser automatically. Please open the URL above manually.`)}};s.listen(e.port,()=>void announceAuthorizeUrl())}),c.success(`Auth connection "${e.name}" authorized successfully.`)}}),Qr=D({name:`delete`,description:`Delete an auth connection entirely.`,args:q.strictObject({...P,...Xr,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]});if(!e.yes&&await A.text({message:`Enter the connection name to confirm deletion ("${e.name}"):`})!==e.name){c.info(`Auth connection deletion cancelled.`);return}try{await t.deleteAuthConnection({workspaceId:n,connectionName:e.name})}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Auth connection "${e.name}" not found.`,{cause:t}):t}c.success(`Auth connection "${e.name}" deleted.`)}});function connectionInfo(e){let t=e.config.case===`oauth2`?e.config.value:void 0;return{name:e.name,type:e.config.case??`unknown`,providerUrl:t?.providerUrl??``,issuerUrl:t?.issuerUrl??``,clientId:t?.clientId??``,authUrl:t?.authUrl??``,tokenUrl:t?.tokenUrl??``,createdAt:e.createdAt?X(e.createdAt):null}}const $r=D({name:`list`,description:`List all auth connections.`,args:q.strictObject({...P,...L()}),run:async e=>{let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]});try{let r=I(e.order),i=await V(async(e,i)=>{let{connections:a,nextPageToken:o}=await t.listAuthConnections({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e.limit});c.out(i.map(connectionInfo))}catch(e){if(e instanceof Q&&e.code===Z.NotFound){c.out([]);return}throw e}}}),ei=D({name:`open`,description:`Open the auth connections page in the Tailor Platform Console.`,args:q.strictObject({...P}),run:async e=>{let t=await Ne({workspaceId:e[`workspace-id`],profile:e.profile}),n=s(process.env.TAILOR_CONSOLE_NEXT)===!0?`/workspaces/${t}/services/auth-connections`:`/workspaces/${t}/settings/connections`,r=await Ae({profile:e.profile,...e[`workspace-id`]===void 0?{}:{allowMissingProfile:!0}}),i=new URL(n,r).toString(),a=c.jsonMode;c.info(`Opening auth connections page in Tailor Platform Console...`);let o=!0;try{await Ar(i)}catch{o=!1}if(a){c.out({consoleUrl:i,workspaceId:t,opened:o});return}o?(c.out(`Console URL: ${i}`),c.out(`Workspace ID: ${t}`)):c.warn(`Failed to open browser automatically. Please open this URL manually:\n${i}`)}}),ti=D({name:`revoke`,description:`Revoke an auth connection's tokens (keeps the connection; use 'delete' to remove it).`,notes:"Revoke invalidates the connection's active session and tokens but keeps the connection and its stored credentials, so it can be re-authorized later. Use `delete` to remove the connection entirely.",args:q.strictObject({...P,...Xr,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]});if(!e.yes&&await A.text({message:`Enter the connection name to confirm revocation ("${e.name}"):`})!==e.name){c.info(`Auth connection revocation cancelled.`);return}try{await t.revokeAuthConnection({workspaceId:n,connectionName:e.name})}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Auth connection "${e.name}" not found.`,{cause:t}):t}c.success(`Auth connection "${e.name}" revoked.`)}}),ni=G({name:`authconnection`,description:`Manage auth connections.`,subCommands:{authorize:Zr,list:$r,open:ei,revoke:ti,delete:Qr},async run(){await K($r,[])}});function orderAndLimitCrashReports(e,t){let n=e.filter(e=>e.endsWith(or)).toSorted(),r=t.order===`asc`?n:n.toReversed();return t.limit&&t.limit>0?r.slice(0,t.limit):r}function formatCrashReportFiles(e,t){return e.map(e=>({file:e,path:U.join(t,e)}))}const ri=D({name:`list`,description:`List local crash report files.`,args:q.strictObject({...L()}),run:async e=>{let t=sr(),n=c.jsonMode;if(!t.localDir){c.info(`Crash report directory not available.`),n&&c.out([]);return}let r;try{r=Y.readdirSync(t.localDir)}catch{c.info(`No crash reports found.`),n&&c.out([]);return}let i=orderAndLimitCrashReports(r,{order:e.order,limit:e.limit});if(i.length===0){c.info(`No crash reports found.`),n&&c.out([]);return}if(n){c.out(formatCrashReportFiles(i,t.localDir));return}c.info(`${i.length} crash report(s) in ${t.localDir}:`);for(let e of i)c.log(` ${e}`)}}),ii=D({name:`send`,description:`Submit a crash report to help improve the SDK.`,args:q.strictObject({file:W(q.string(),{description:`Path to the crash report file`,required:!0,completion:{type:`file`,extensions:[`log`]}})}),run:async e=>{let t;try{t=Y.readFileSync(e.file,`utf-8`)}catch{c.error(`Crash report file not found: ${e.file}`),process.exit(1)}let n=parseCrashLogFile(t);n||(c.error(`Failed to parse crash report file. The file may be corrupted.`),process.exit(1));let r=await Zn();c.info(`Sending crash report...`),await cr(n,r)?c.success(`Crash report submitted successfully. Thank you!`):(c.error(`Failed to submit crash report. The server may be unavailable.`),process.exit(1))}});function parseCrashLogFile(e){try{let t=e.replace(/\r\n/g,`
|
|
5
5
|
`),n=`\n${ar}\n`,r=t.lastIndexOf(n);if(r===-1)return;let i=t.slice(r+n.length).split(`
|
|
@@ -91,10 +91,10 @@ Error:`));let e=formatErrorWithSourcemap(x.error,m,process.cwd());e?c.log(e):c.l
|
|
|
91
91
|
No profiles found.
|
|
92
92
|
Please create a profile first using 'tailor profile create' command.
|
|
93
93
|
`),t&&c.out([]);return}let r=n.map(([e,t])=>{let n=o(t,`profile entry "${e}" is undefined`);return{name:e,user:n.user,workspaceId:n.workspace_id,permission:n.readonly===!0?`read`:`write`,...n.machine_user?{machineUser:n.machine_user,machineUserOverride:n.machine_user_override??`allow`}:{},...n.platform_url?{platformUrl:n.platform_url}:{},...n.oauth2_client_id?{oauth2ClientId:n.oauth2_client_id}:{},...n.console_url?{consoleUrl:n.console_url}:{}}});c.out(r)}}),Li=D({name:`update`,description:`Update profile properties.`,args:q.strictObject({name:W(q.string(),{positional:!0,description:`Profile name`}),user:W(q.string().optional(),{alias:`u`,description:`New user email address or machine user client ID`}),"workspace-id":W(q.string().optional(),{alias:`w`,description:`New workspace ID`}),permission:W(q.enum([`write`,`read`]).optional(),{description:`Profile permission. 'read' blocks all write commands; 'write' lifts the restriction.`}),"machine-user":W(q.string().optional(),{alias:`m`,description:`Default machine user name for application-data commands (query, workflow start, function run, machineuser token). Pass an empty string to clear.`}),"machine-user-override":W(q.enum([`allow`,`deny`]).optional(),{description:`Whether the command line or TAILOR_PLATFORM_MACHINE_USER_NAME may override the profile's machine user. 'deny' requires --machine-user; 'allow' lifts the restriction.`}),"platform-url":W(q.union([q.url(),q.literal(``)]).optional(),{description:`Platform API base URL for this profile. Pass an empty string to clear.`}),"oauth2-client-id":W(q.string().optional(),{description:`OAuth2 client ID for logging in to this profile's platform. Pass an empty string to clear.`}),"console-url":W(q.union([q.url(),q.literal(``)]).optional(),{description:`Console base URL for this profile. Pass an empty string to clear.`})}),run:async e=>{let t=await h(),n=t.profiles[e.name];if(!n)throw Error(`Profile "${e.name}" not found.`);if(!e.user&&!e[`workspace-id`]&&e.permission===void 0&&e[`machine-user`]===void 0&&e[`machine-user-override`]===void 0&&e[`platform-url`]===void 0&&e[`oauth2-client-id`]===void 0&&e[`console-url`]===void 0)throw Error(`Please provide at least one property to update.`);let r=n.user,i=e.user||r,a=n.workspace_id,o=e[`workspace-id`]||a,s=i,l=e[`machine-user`]===``?void 0:e[`machine-user`]??n.machine_user,u=e[`machine-user-override`]===`allow`?void 0:e[`machine-user-override`]??n.machine_user_override,d=e[`platform-url`]===``?void 0:e[`platform-url`]??n.platform_url,f=e[`oauth2-client-id`]===``?void 0:e[`oauth2-client-id`]??n.oauth2_client_id,p=e[`console-url`]===``?void 0:e[`console-url`]??n.console_url,m={...d?{platformUrl:d}:{},...f?{oauth2ClientId:f}:{},...p?{consoleUrl:p}:{}},g=Object.keys(m).length>0?m:void 0,_=e[`platform-url`]===``?B(n):g;if((e[`machine-user`]!==void 0||e[`machine-user-override`]!==void 0)&&u===`deny`&&!l)throw e[`machine-user-override`]===`deny`?Error(`--machine-user-override deny requires --machine-user.`):Error(`Cannot clear the machine user while machine-user-override is "deny". Also pass --machine-user-override allow.`);if(e.user!==void 0||e[`workspace-id`]!==void 0||e[`platform-url`]!==void 0){let e=await De(t,i,_);s=e.user;let n=await yn(e.accessToken,g);if(!(await wn(async(e,t)=>{let{workspaces:r,nextPageToken:i}=await n.listWorkspaces({pageToken:e,pageSize:t});return[r,i]})).find(e=>e.id===o))throw Error(`Workspace "${o}" not found.`)}n.user=s,n.workspace_id=o,e.permission===`read`?n.readonly=!0:e.permission===`write`&&delete n.readonly,e[`machine-user`]!==void 0&&(e[`machine-user`]===``?delete n.machine_user:n.machine_user=e[`machine-user`]),e[`machine-user-override`]===`deny`?n.machine_user_override=`deny`:e[`machine-user-override`]===`allow`&&delete n.machine_user_override,e[`platform-url`]!==void 0&&(e[`platform-url`]===``?delete n.platform_url:n.platform_url=e[`platform-url`]),e[`oauth2-client-id`]!==void 0&&(e[`oauth2-client-id`]===``?delete n.oauth2_client_id:n.oauth2_client_id=e[`oauth2-client-id`]),e[`console-url`]!==void 0&&(e[`console-url`]===``?delete n.console_url:n.console_url=e[`console-url`]),E(t),e.json||c.success(`Profile "${e.name}" updated successfully`);let v={name:e.name,user:s,workspaceId:o,permission:n.readonly===!0?`read`:`write`,...n.machine_user?{machineUser:n.machine_user,machineUserOverride:n.machine_user_override??`allow`}:{},...n.platform_url?{platformUrl:n.platform_url}:{},...n.oauth2_client_id?{oauth2ClientId:n.oauth2_client_id}:{},...n.console_url?{consoleUrl:n.console_url}:{}};c.out(v)}}),Ri=G({name:`profile`,description:`Manage workspace profiles (user + workspace combinations).`,subCommands:{create:Pi,delete:Fi,list:Ii,update:Li},async run(){await K(Ii,[])}}),zi={"vault-name":W(q.string(),{alias:`V`,description:`Vault name`})},Bi={...zi,name:W(q.string(),{alias:`n`,description:`Secret name`})},Vi={...Bi,value:W(q.string(),{alias:`v`,description:`Secret value`})};async function checkVaultManaged(e){let{client:t,workspaceId:n,vaultName:r}=e,i=N(n,`vault`,r),a={isManaged:!1,trn:i,existingLabels:{}},o,s;try{let{metadata:e}=await t.getMetadata({trn:i});s=e?.labels??{},o=s[hn]}catch{return a}return o?(c.warn(`Vault "${r}" is managed by defineSecretManager() in tailor.config.ts (owner: "${o}"). Changes made via CLI may conflict with the config on the next apply.`),{isManaged:!0,trn:i,existingLabels:s}):a}async function releaseVaultOwnership(e){let{client:t,trn:n}=e;await fn(t,{trn:n,remove:[hn,it,an]}),c.info(`Config ownership has been removed from this vault. Remove it from defineSecretManager() in your config to prevent the next apply from re-claiming it.`)}const Hi=D({name:`create`,description:`Create a secret in a vault.`,args:q.strictObject({...P,...Vi,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=await checkVaultManaged({client:t,workspaceId:n,vaultName:e[`vault-name`]});if(!r.isManaged||e.yes||await A.confirm({message:`Do you want to proceed?`,default:!1})){try{await t.createSecretManagerSecret({workspaceId:n,secretmanagerVaultName:e[`vault-name`],secretmanagerSecretName:e.name,secretmanagerSecretValue:e.value})}catch(t){if(t instanceof Q){if(t.code===Z.NotFound)throw Error(`Vault "${e[`vault-name`]}" not found.`,{cause:t});if(t.code===Z.AlreadyExists)throw Error(`Secret "${e.name}" already exists.`,{cause:t})}throw t}r.isManaged&&await releaseVaultOwnership({client:t,...r}),c.success(`Secret: ${e.name} created in vault: ${e[`vault-name`]}`)}}}),Ui=D({name:`delete`,description:`Delete a secret in a vault.`,args:q.strictObject({...P,...Bi,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=await checkVaultManaged({client:t,workspaceId:n,vaultName:e[`vault-name`]});if(!e.yes&&await A.text({message:`Enter the secret name to confirm deletion ("${e.name}"):`})!==e.name){c.info(`Secret deletion cancelled.`);return}try{await t.deleteSecretManagerSecret({workspaceId:n,secretmanagerVaultName:e[`vault-name`],secretmanagerSecretName:e.name})}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Secret "${e.name}" not found in vault "${e[`vault-name`]}".`,{cause:t}):t}r.isManaged&&await releaseVaultOwnership({client:t,...r}),c.success(`Secret: ${e.name} deleted from vault: ${e[`vault-name`]}`)}});function secretInfo(e){return{name:e.name,createdAt:e.createTime?X(e.createTime):null,updatedAt:e.updateTime?X(e.updateTime):null}}async function secretList(e){let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e.workspaceId}),r=I(e.order);return(await V(async(i,a)=>{let{secrets:o,nextPageToken:s}=await t.listSecretManagerSecrets({workspaceId:n,secretmanagerVaultName:e.vaultName,pageToken:i,pageSize:a,pageDirection:r});return[o,s]},{limit:e.limit})).map(secretInfo)}const Wi=D({name:`list`,description:`List all secrets in a vault.`,args:q.strictObject({...P,...zi,...L()}),run:async e=>{try{let t=await secretList({workspaceId:e[`workspace-id`],profile:e.profile,vaultName:e[`vault-name`],order:e.order,limit:e.limit});c.out(t)}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Vault "${e[`vault-name`]}" not found.`,{cause:t}):t}}}),Gi=D({name:`update`,description:`Update a secret in a vault.`,args:q.strictObject({...P,...Vi,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=await checkVaultManaged({client:t,workspaceId:n,vaultName:e[`vault-name`]});if(!r.isManaged||e.yes||await A.confirm({message:`Do you want to proceed?`,default:!1})){try{await t.updateSecretManagerSecret({workspaceId:n,secretmanagerVaultName:e[`vault-name`],secretmanagerSecretName:e.name,secretmanagerSecretValue:e.value})}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Secret "${e.name}" not found in vault "${e[`vault-name`]}".`,{cause:t}):t}r.isManaged&&await releaseVaultOwnership({client:t,...r}),c.success(`Secret: ${e.name} updated in vault: ${e[`vault-name`]}`)}}}),Ki={name:W(q.string(),{positional:!0,description:`Vault name`})},qi=D({name:`create`,description:`Create a new Secret Manager vault.`,args:q.strictObject({...P,...Ki}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]});try{await t.createSecretManagerVault({workspaceId:n,secretmanagerVaultName:e.name})}catch(t){throw t instanceof Q&&t.code===Z.AlreadyExists?Error(`Vault "${e.name}" already exists.`,{cause:t}):t}c.success(`Vault: ${e.name} created`)}}),Ji=D({name:`delete`,description:`Delete a Secret Manager vault.`,args:q.strictObject({...P,...Ki,...M}),run:async e=>{await j({profile:e.profile});let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=await checkVaultManaged({client:t,workspaceId:n,vaultName:e.name});if(!e.yes&&await A.text({message:`Enter the vault name to confirm deletion ("${e.name}"):`})!==e.name){c.info(`Vault deletion cancelled.`);return}try{await t.deleteSecretManagerVault({workspaceId:n,secretmanagerVaultName:e.name})}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Vault "${e.name}" not found.`,{cause:t}):t}r.isManaged&&c.info(`Remove this vault from defineSecretManager() in your config to prevent the next apply from re-creating it.`),c.success(`Vault: ${e.name} deleted`)}});function vaultInfo(e){return{name:e.name,createdAt:e.createTime?X(e.createTime):null,updatedAt:e.updateTime?X(e.updateTime):null}}async function vaultList(e){let{client:t,workspaceId:n}=await v({profile:e?.profile,workspaceId:e?.workspaceId}),r=I(e?.order);return(await V(async(e,i)=>{let{vaults:a,nextPageToken:o}=await t.listSecretManagerVaults({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(vaultInfo)}const Yi=D({name:`list`,description:`List all Secret Manager vaults in the workspace.`,args:q.strictObject({...P,...L()}),run:async e=>{let t=await vaultList({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});c.out(t)}}),Xi=G({name:`vault`,description:`Manage Secret Manager vaults.`,subCommands:{create:qi,delete:Ji,list:Yi},async run(){await K(Yi,[])}}),Zi=G({name:`secret`,description:`Manage Secret Manager vaults and secrets.`,subCommands:{vault:Xi,create:Hi,update:Gi,list:Wi,delete:Ui},async run(){await K(Xi,[])}}),Qi={[t.UNSPECIFIED]:`unspecified`,[t.PENDING]:`pending`,[t.VERIFYING]:`verifying`,[t.CERT_ISSUED]:`cert_issued`,[t.ACTIVE]:`active`,[t.FAILED]:`failed`},$i=D({name:`get`,description:`Get details of a custom domain.`,args:q.strictObject({...P,domain:W(q.string(),{positional:!0,description:`Custom domain name`})}),run:async e=>{let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=`Custom domain "${e.domain}" not found.`;try{let{customDomain:i}=await t.getCustomDomain({workspaceId:n,domain:e.domain});if(!i)throw Error(r);let a={domain:i.domain,status:Qi[i.status]??`unknown`,trafficCnameTarget:i.trafficCnameTarget,certificateCnameTarget:i.certificateCnameTarget,errorMessage:i.errorMessage||void 0};c.out(a)}catch(e){throw e instanceof Q&&e.code===Z.NotFound?Error(r,{cause:e}):e}}}),ea=D({name:`list`,description:`List custom domains for a static website.`,args:q.strictObject({...P,name:W(q.string(),{positional:!0,description:`Static website name`})}),run:async e=>{let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]});try{let{customDomains:r}=await t.listCustomDomains({workspaceId:n,staticWebsiteName:e.name});if(r.length===0){c.info(`No custom domains found.`),c.jsonMode&&c.out([]);return}let i=r.map(e=>({domain:e.domain,status:Qi[e.status]??`unknown`,trafficCnameTarget:e.trafficCnameTarget,certificateCnameTarget:e.certificateCnameTarget}));c.out(i)}catch(t){throw t instanceof Q&&t.code===Z.NotFound?Error(`Static website "${e.name}" not found.`,{cause:t}):t}}}),ta=G({name:`domain`,description:`Manage custom domains for static websites.`,subCommands:{list:ea,get:$i}}),na=D({name:`get`,description:`Get details of a specific static website.`,args:q.strictObject({...P,name:W(q.string(),{positional:!0,description:`Static website name`})}),run:async e=>{let{client:t,workspaceId:n}=await v({profile:e.profile,workspaceId:e[`workspace-id`]}),r=`Static website "${e.name}" not found.`;try{let{staticwebsite:i}=await t.getStaticWebsite({workspaceId:n,name:e.name});if(!i)throw Error(r);let a={workspaceId:n,name:i.name,description:i.description,url:i.url,allowedIpAddresses:e.json?i.allowedIpAddresses:i.allowedIpAddresses.join(`
|
|
94
|
-
`)};c.out(a)}catch(e){throw e instanceof Q&&e.code===Z.NotFound?Error(r,{cause:e}):e}}});async function listStaticWebsites(e){let{client:t,workspaceId:n}=await v({profile:e?.profile,workspaceId:e?.workspaceId}),r=I(e?.order);return(await V(async(e,i)=>{let{staticwebsites:a,nextPageToken:o}=await t.listStaticWebsites({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(e=>({workspaceId:n,name:e.name,description:e.description,url:e.url,allowedIpAddresses:e.allowedIpAddresses}))}const ra=D({name:`list`,description:`List all static websites in a workspace.`,args:q.strictObject({...P,...L()}),run:async e=>{let t=c.jsonMode,n=await listStaticWebsites({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({allowedIpAddresses:e,...t})=>{if(e.length===0)return{...t,allowedIpAddresses:`No allowed IP addresses`};let n=e.length,r=n===1?`1 IP address`:`${n} IP addresses`;return{...t,allowedIpAddresses:r}});c.out(r)}}),ia=G({name:`staticwebsite`,description:`Manage static websites in your workspace.`,subCommands:{deploy:ze,domain:ta,list:ra,get:na},async run(){await K(ra,[])}}),aa=new Set(Object.values(re));async function activateBaseline(e,t,n,r){let i=await $.realpath(e),a=U.dirname(i),o=U.basename(i),s=await $.mkdtemp(U.join(a,`.${o}-rebaseline-`)),l=`${s}-previous`,u=!1,d=!1;try{await $.cp(i,s,{recursive:!0});for(let e of await $.readdir(s,{withFileTypes:!0})){if(!e.isDirectory()||!fe.test(e.name))continue;let t=U.join(s,e.name);(await $.readdir(t)).some(e=>aa.has(e))&&await $.rm(t,{recursive:!0,force:!0})}let e={...t,namespace:n,version:5,createdAt:new Date().toISOString(),rebaseline:r},a=await _n(e,s,0);$t(a.filePath),await $.rename(i,l),u=!0;try{await $.rename(s,i),d=!0}catch(e){throw await $.rename(l,i),u=!1,e}try{await $.rm(l,{recursive:!0,force:!0})}catch(e){c.warn(`The previous migration directory remains at ${l}: ${e instanceof Error?e.message:String(e)}`)}u=!1}finally{Y.existsSync(s)&&await $.rm(s,{recursive:!0,force:!0}),!d&&u&&Y.existsSync(l)&&await $.rename(l,i)}}async function rebaseline(e){m(`tailordb migration`);let{config:t,plugins:n}=await w(e.configPath),r=U.dirname(t.path),i=Tt(f(t,r),e.namespace),a=nr({command:`tailor`,args:[`tailordb`,`migration`,`generate`,`--config`,t.path]});k(i.migrationsDir,i.namespace);let o=z(i.migrationsDir);if(!o)throw Error(`No migration history found for namespace "${i.namespace}". Run ${a} first.`);let s=Ke(i.migrationsDir),u=z(i.migrationsDir,0)?.rebaseline?.historyId??null,d=Se([i])[i.namespace],p=n.length>0?new mt(n):void 0,{defineApplication:h}=await import(`../application-BWOMdL3D.mjs`),g=h({config:t,pluginManager:p});for(let e of g.tailorDBServices)await e.loadTypes(),await e.processNamespacePlugins();let _=g.tailorDBServices.find(e=>e.namespace===i.namespace);if(!_)throw Error(`No TailorDB service found for namespace "${i.namespace}"`);let assertLocalTypesReady=()=>{let e=se(_.types,i.namespace),t=Jt(o,e.tables,i.namespace);if(xt(t))throw c.error(`Migration history does not reproduce the current local schema for namespace ${l.bold(i.namespace)}:`),c.log(Ft(t)),Error(`Refusing to re-baseline: the migration history must reproduce the current local schema. Run ${a} first.`)},localSourceFiles=()=>[t.path,...qn(_.config,r)];assertLocalTypesReady();let y=ve(localSourceFiles()),{client:b,workspaceId:x}=await v({profile:e.profile,workspaceId:e.workspaceId}),S=[`--config`,t.path,`--workspace-id`,x,...e.profile?[`--profile`,e.profile]:[]],C=nr({command:`tailor`,args:[`tailordb`,`migration`,`set`,`0`,`--namespace`,i.namespace,...S]}),ee=nr({command:`tailor`,args:[`deploy`,...S]}),assertConnectedWorkspaceReady=async(e,n)=>{let r=await Dt(b,N(x,`tailordb`,i.namespace)),a=r.number;if(a!==s){let e=a===null?`<unset>`:F(a);throw Error(`The connected workspace must be at the latest migration ${F(s)} before re-baselining; current checkpoint is ${e}.`)}if(r.historyIdInvalid)throw Error(`Refusing to re-baseline: the connected workspace has an invalid migration history marker.`);if(r.historyId!==e)throw Error(n===`confirmation`?`The connected workspace migration history changed while waiting for confirmation. Run the command again.`:`Refusing to re-baseline: the connected workspace does not match the local migration history.`);let o=await rt(b,x,[i],t,[mn(_)]),l=o[0];if(!l||l.remoteMigrationNumber!==s||l.hasDrift||l.checkpointMissingLocal)throw l?.hasDrift&&(c.error(`Remote schema drift detected:`),c.log(_t(o))),Error(`Refusing to re-baseline: the connected workspace remote schema must match the latest migration.`)};if(await assertConnectedWorkspaceReady(u,`initial`),c.newline(),c.warn(`This will replace the migration history for ${l.bold(i.namespace)}.`),c.log(` Latest migration: ${F(s)}`),c.log(` New history: 0000/schema.json only`),c.log(` migrate.ts and db.ts files will disappear from the working tree.`),c.log(` Committed migration files will remain in Git history. Preserve any uncommitted files before continuing.`),c.log(` Every other environment must already be at the latest migration.`),c.log(` The connected workspace checkpoint will be reset to 0000.`),c.newline(),!e.yes&&!await A.confirm({message:`Re-baseline this migration history and reset the connected workspace checkpoint?`,default:!1})){c.info(`Operation cancelled.`);return}if(k(i.migrationsDir,i.namespace),Se([i])[i.namespace]!==d)throw Error(`Migration files changed while waiting for confirmation. Run the command again.`);if(ve(localSourceFiles())!==y)throw Error(`Local TailorDB table or config files changed. Run the command again.`);assertLocalTypesReady(),await assertConnectedWorkspaceReady(u,`confirmation`);let T={historyId:Ct(),replacedHistoryId:u,replacedLatestMigration:s};await activateBaseline(i.migrationsDir,o,i.namespace,T);try{await Pe(b,x,i.namespace,0,T.historyId)}catch(e){throw Error(`The local migration history was re-baselined, but the connected workspace checkpoint could not be updated. Run ${C}, or run ${ee} with schema checks enabled after resolving the connection error.`,{cause:e})}c.success(`Re-baselined ${l.bold(i.namespace)} and reset the connected workspace checkpoint to 0000.`)}const oa=D({name:`rebaseline`,description:`Collapse the full migration history into a new 0000 baseline.`,notes:`Re-baselining removes migrations after 0000 from the working tree, records a new migration history ID, and resets the connected workspace checkpoint without changing its schema or data. Every environment must already have applied the latest migration before you run this command.`,args:q.strictObject({...O,...M,namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await rebaseline({configPath:e.config,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});async function set(e){m(`tailordb migration`);let t=ht(e.number),{config:n}=await w(e.configPath),r=U.dirname(n.path),i=f(n,r),a=Tt(i,e.namespace),o=a.namespace;k(a.migrationsDir,o),le(a.migrationsDir,t);let s=z(a.migrationsDir,0)?.rebaseline?.historyId,{client:u,workspaceId:d}=await v({profile:e.profile,workspaceId:e.workspaceId}),p=N(d,`tailordb`,o),h=await Dt(u,p),g=h.number,_=g??0,y=h.historyIdInvalid?`<invalid>`:h.historyId??`<unset>`,b=s??`<unset>`;if(c.newline(),c.warn(`This operation will change TailorDB migration state metadata.`),c.log(`Namespace: ${l.bold(o)}`),c.log(`Current migration: ${g===null?`<unset>`:l.bold(F(g))}`),c.log(`New migration: ${l.bold(F(t))}`),c.log(`Current migration history ID: ${l.bold(y)}`),c.log(`New migration history ID: ${l.bold(b)}`),c.newline(),t<_?(c.warn(`Setting migration number backwards (${F(_)} → ${F(t)}) will cause previous migrations to be re-executed on next apply.`),c.newline()):t>_&&(c.warn(`Setting migration number forwards (${F(_)} → ${F(t)}) will skip migrations ${F(_+1)} to ${F(t)}.`),c.newline()),!e.yes){if(!await A.confirm({message:`Continue with migration checkpoint and history ID update?`,default:!1})){c.info(`Operation cancelled.`);return}c.newline()}await fn(u,{trn:p,labels:{[Gt]:zt(t),...s?{[Lt]:s}:{}},remove:s?void 0:[Lt]}),c.success(`Migration checkpoint set to ${l.bold(F(t))} for namespace ${l.bold(o)}`)}const sa=D({name:`set`,description:`Set migration checkpoint to a specific number.`,notes:"The migration number must be a 4-digit value (e.g. `0001`) or a bare integer (e.g. `1`) within 0–9999, and must exist in the local migration history; `0` is always accepted as the baseline, provided the local history passes validation. A gapped history is rejected.\n\nMetadata lookup failures (authentication, permission, or network errors) are reported as errors; only a not-yet-deployed namespace is treated as having no checkpoint.",args:q.strictObject({...O,...M,number:W(q.string(),{positional:!0,description:`Migration number to set (e.g., 0001 or 1)`}),namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await set({configPath:e.config,number:e.number,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});function isStatusFailure(e){return e.status===`error`}async function collectMigrationStatuses(e){let{config:t}=await w(e.configPath),n=U.dirname(t.path),r=f(t,n);if(r.length===0)throw Error(`No TailorDB services with migrations configuration found`);let i=e.namespace?r.filter(t=>t.namespace===e.namespace):r;if(i.length===0)throw Error(`Namespace "${e.namespace}" not found or does not have migrations configured`);let a=new Map,o=new Map;for(let{namespace:e,migrationsDir:t}of i)try{let n=je(t),r=new Map,i=null;for(let e of n){if(e.type===`schema`){let t=$t(e.path);e.number===0&&(i=t.rebaseline?.historyId??null);continue}try{let t=ft(e.path);t.description&&r.set(e.number,t.description)}catch(e){if(e instanceof jt)throw e}}a.set(e,{migrationFiles:n,descriptions:r,historyId:i})}catch(t){o.set(e,t instanceof Error?t.message:String(t))}if(a.size===0)return i.map(({namespace:e})=>({status:`error`,namespace:e,error:o.get(e)??`Failed to read local migration history.`}));let{client:s,workspaceId:c}=await v({profile:e.profile,workspaceId:e.workspaceId}),l=[];for(let{namespace:e}of i){if(o.has(e)){l.push({status:`error`,namespace:e,error:o.get(e)??`Failed to read local migration history.`});continue}let t=a.get(e);if(!t){l.push({status:`error`,namespace:e,error:`Failed to read local migration history.`});continue}let{migrationFiles:n,descriptions:r,historyId:i}=t,u=N(c,`tailordb`,e),d;try{d=await Dt(s,u)}catch(t){l.push({status:`error`,namespace:e,error:t instanceof Error?t.message:String(t)});continue}let f=d.number??0;if(d.historyIdInvalid){l.push({status:`error`,namespace:e,error:`Remote migration history ID is invalid.`});continue}if((d.number!==null||d.historyId!==null)&&d.historyId!==i){l.push({status:`error`,namespace:e,error:`Remote migration history ID ${d.historyId??`<unset>`} does not match local migration history ID ${i??`<unset>`}.`});continue}let p=n.map(e=>e.number).filter((e,t,n)=>n.indexOf(e)===t).toSorted((e,t)=>e-t).filter(e=>e>f).map(e=>({number:e,label:F(e),...r.has(e)?{description:r.get(e)}:{}}));l.push({status:`ok`,namespace:e,currentMigration:f,currentMigrationLabel:F(f),pendingMigrations:p})}return l}function printMigrationStatuses(e){for(let t of e){if(c.newline(),c.info(`Namespace: ${l.bold(t.namespace)}`),isStatusFailure(t)){c.error(` Migration status error: ${t.error}`);continue}if(c.log(` Current migration: ${l.bold(t.currentMigrationLabel)}`),t.pendingMigrations.length>0){c.log(` Pending migrations:`);for(let e of t.pendingMigrations)e.description?c.log(` - ${e.label}: ${e.description}`):c.log(` - ${e.label}`)}else c.log(` Pending migrations: (none)`)}c.newline()}async function status(e){m(`tailordb migration`);let t=await collectMigrationStatuses(e);e.json?c.out(t):printMigrationStatuses(t);let n=t.filter(isStatusFailure);if(n.length>0){let e=n.map(e=>e.namespace).join(`, `);throw Error(`Migration status check failed for ${n.length} namespace${n.length===1?``:`s`}: ${e}`)}}const ca=D({name:`status`,description:`Show the current migration status for TailorDB namespaces, including applied and pending migrations.`,notes:`Every local migration file is checked for a compatible format version, and deployed migration history IDs must match the local baseline. Compatibility errors, history mismatches, and metadata lookup failures are reported per namespace and make the command exit non-zero; only a not-yet-deployed namespace is treated as having no applied migrations.`,args:q.strictObject({...O,namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (shows all namespaces if not specified)`})}),run:async e=>{await status({configPath:e.config,namespace:e.namespace,workspaceId:e[`workspace-id`],profile:e.profile,json:c.jsonMode})}});async function fetchRemoteGqlPermissions(e,t,n){return An(async(r,i)=>{let{permissions:a,nextPageToken:o}=await e.listTailorDBGQLPermissions({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]})}async function fetchRemoteTypes(e,t,n){return wn(async(r,i)=>{try{let{tailordbTypes:a,nextPageToken:o}=await e.listTailorDBTypes({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}catch(e){throw e instanceof Q&&e.code===Z.NotFound?Error(`Cannot sync: TailorDB namespace "${n}" has not been deployed yet.`,{cause:e}):e}})}async function assertMigrationsReproduceLocalTypes(e,t){let{config:n,plugins:r}=e,i=r.length>0?new mt(r):void 0,{defineApplication:a,generatePluginFilesIfNeeded:o}=await import(`../application-BWOMdL3D.mjs`),s=a({config:n,pluginManager:i}),u=s.tailorDBServices.find(e=>e.namespace===t.namespace);if(!u)throw Error(`No TailorDB service found for namespace "${t.namespace}"`);for(let e of s.tailorDBServices)await e.loadTypes(),await e.processNamespacePlugins();let d=o(i,s.tailorDBServices,n.path),f=s.executorService??(d.length>0?(await import(`../service-CWFQ8EVo.mjs`)).createExecutorService({config:{files:[]},baseDir:U.dirname(n.path)}):void 0);await f?.loadExecutors(),d.length>0&&await f?.loadPluginExecutorFiles([...d]);let p=new Set;for(let e of Object.values(f?.executors??{}))vt(e)&&e.trigger.kind===`tailordb`&&p.add(e.trigger.tableName);let m={executorUsedTables:p,namespaceGqlOperations:u.config.gqlOperations},h=z(t.migrationsDir);if(!h)return m;let g=se(u.types,t.namespace),_=Jt(h,g.tables,t.namespace);if(!xt(_))return m;throw c.error(`Migration history does not reproduce the current local schema for namespace ${l.bold(t.namespace)}:`),c.log(Ft(_)),c.newline(),c.info(`This usually means one of the following:`),c.info(` - Migration files were edited and replaying them no longer matches the table definitions — fix the migration files.`,{mode:`plain`}),c.info(` - Table definitions changed without a new migration — run 'tailor tailordb migration generate' first.`,{mode:`plain`}),c.newline(),Error(`Refusing to sync: the migration history must reproduce the current local schema before it can be applied to the remote.`)}async function sync(e){m(`tailordb migration`);let t=ht(e.number),n=await w(e.configPath),{config:r}=n,i=U.dirname(r.path),a=f(r,i),o=Tt(a,e.namespace);k(o.migrationsDir,o.namespace);let s=le(o.migrationsDir,t),u=z(o.migrationsDir,t);if(!u)throw Error(`No initial schema snapshot found in ${o.migrationsDir}. Expected 0000/schema.json.`);let d=await assertMigrationsReproduceLocalTypes(n,o),{client:p,workspaceId:h}=await v({profile:e.profile,workspaceId:e.workspaceId}),g=N(h,`tailordb`,o.namespace),_=await Ee(p,g),y=await fetchRemoteTypes(p,h,o.namespace),x=new Set(y.map(e=>e.name)),{creates:S,updates:C,deletes:T}=Ie(u,x),te=await fetchRemoteGqlPermissions(p,h,o.namespace),ne=new Set(te.map(e=>e.typeName)),re=Object.entries(u.tables).flatMap(([e,t])=>t.permissions?.gql?[{typeName:e,permission:b(t.permissions.gql)}]:[]),E=new Set(re.map(e=>e.typeName)),ie=te.filter(e=>!E.has(e.typeName));if(c.newline(),c.info(`Namespace: ${l.bold(o.namespace)}`),c.log(` Current migration: ${_===null?`<unset>`:l.bold(F(_))}`),c.log(` Target migration: ${l.bold(F(t))}`),c.log(` Tables to create: ${l.bold(String(S.length))}`),c.log(` Tables to update: ${l.bold(String(C.length))}`),c.log(` Tables to delete: ${l.bold(String(T.length))}`),c.log(` GQL permissions to set: ${l.bold(String(re.length))}`),c.log(` GQL permissions to delete: ${l.bold(String(ie.length))}`),c.newline(),S.length+C.length+T.length+re.length+ie.length===0?c.info(`No tables to apply; only the migration label will be updated.`):(c.warn(`This operation will overwrite remote TailorDB tables to match the selected snapshot.`),T.length>0&&c.warn(`Existing data in deleted tables will be lost.`),c.newline()),c.warn(`Sync never runs migrate.ts scripts; it only applies the schema snapshot and moves the migration label.`),c.newline(),_!==null&&t<_?(c.warn(`Migrations ${F(t+1)}–${F(_)} will become pending again and re-execute on the next deploy, including their migrate.ts scripts. Make sure those scripts are idempotent (safe to re-run).`),c.newline()):_!==null&&t>_&&(c.warn(`Moving the migration label forwards (${F(_)} → ${F(t)}): migrate.ts scripts for migrations ${F(_+1)}–${F(t)} will not run on the next deploy.`),c.newline()),!e.yes){if(!await A.confirm({message:`Continue and set migration label to ${F(t)}?`,default:!1})){c.info(`Operation cancelled.`);return}c.newline()}let ae=ee(u,d),manifestFor=e=>{let t=ae.get(e);if(!t)throw Error(`Internal error: no manifest generated for table "${e}". No changes were applied.`);return t},oe=S.map(e=>manifestFor(e)),se=C.map(e=>manifestFor(e));try{await Promise.all([...oe.map(e=>p.createTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbType:e})),...se.map(e=>p.updateTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbType:e}))])}catch(e){tt(e,[`The target snapshot marks a field as required, but existing remote records have no value for it.`,`Populate those records first (e.g. with a migration script applied via 'tailor deploy'), then re-run the sync.`])}await Promise.all(re.map(({typeName:e,permission:t})=>{let n={workspaceId:h,namespaceName:o.namespace,typeName:e,permission:t};return ne.has(e)?p.updateTailorDBGQLPermission(n):p.createTailorDBGQLPermission(n)})),await Promise.all(ie.map(e=>p.deleteTailorDBGQLPermission({workspaceId:h,namespaceName:o.namespace,typeName:e.typeName}))),await Promise.all(T.map(e=>p.deleteTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbTypeName:e}))),await fn(p,{trn:g,labels:{[Gt]:zt(t),...u.rebaseline?.historyId?{[Lt]:u.rebaseline.historyId}:{}},remove:u.rebaseline?.historyId?void 0:[Lt]}),c.success(`Synced namespace ${l.bold(o.namespace)} to migration ${l.bold(F(t))}.`),t<s&&(c.newline(),c.info(`Run 'tailor deploy' to apply migrations ${F(t+1)}–${F(s)} from the working tree.`))}const la=D({name:`sync`,description:`Sync remote TailorDB schema to a specific migration snapshot (recovery from --no-schema-check drift).`,args:q.strictObject({...O,...M,number:W(q.string(),{positional:!0,description:`Migration number to sync to (e.g., 0001 or 1; 0 targets the baseline snapshot)`}),namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await sync({configPath:e.config,number:e.number,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});function delay(e){return e>0?new Promise(t=>setTimeout(t,e)):Promise.resolve()}function assertSeedDataDirectory(e){let t;try{t=Y.statSync(e)}catch(t){throw t.code===`ENOENT`?Error(`Seed data directory not found: ${e}. Run 'tailor generate' before testing migrations.`,{cause:t}):t}if(!t.isDirectory())throw Error(`Seed data path is not a directory: ${e}`)}function assertAssertionScript(e){let t=U.resolve(e),n;try{n=Y.statSync(t)}catch(e){throw e.code===`ENOENT`?Error(`Migration assertion script not found: ${t}`,{cause:e}):e}if(!n.isFile())throw Error(`Migration assertion path is not a file: ${t}`)}function assertCloneTargetRegion(e,t){if(e!==t)throw Error(`Clone mode requires source and target workspaces in the same region (source: ${e}, target: ${t}).`)}function assertTargetWorkspaceDiffers(e,t){if(t?.toLowerCase()===e.toLowerCase())throw Error(`The migration test target workspace must differ from the source workspace.`)}function resolveAssertionNamespace(e,t){let n=t??(e.length===1?e[0]:void 0);if(!n)throw Error(`--assert-namespace is required when pending migrations span multiple namespaces.`);if(!e.includes(n))throw Error(`Assertion namespace "${n}" has no pending migrations.`);return n}async function createMigrationTestBaselineSnapshots(e){let t=new Map([...e.baselines].map(([e,t])=>[e,t.snapshot]));if(e.dataMode!==`clone`)return t;let n=e.inputs.filter(e=>!t.has(e.namespace)),r=await Promise.all(n.map(t=>bt(e.client,e.workspaceId,t.namespace)));return n.forEach((e,n)=>{t.set(e.namespace,o(r[n],`remote snapshot missing for "${e.namespace}"`))}),t}async function waitForCloneApplicationData(e,t){let n=t.pollInterval??1e3,i=t.timeout??3e5,a=Date.now()+i;for(;Date.now()<=a;){let i=await e.getCloneApplicationDataOperation({sourceWorkspaceId:t.sourceWorkspaceId,targetWorkspaceId:t.targetWorkspaceId,operationId:t.operationId});if(i.status===r.COMPLETED)return;if(i.status===r.FAILED)throw Error(`Application data clone failed: ${i.errorMessage||`unknown platform error`}`);if(i.status!==r.PENDING&&i.status!==r.PROCESSING)throw Error(`Application data clone returned unexpected status ${i.status}.`);await delay(n)}throw Error(`Application data clone timed out after ${Math.round(i/1e3)} seconds.`)}function loadSnapshotSeedData(e,t,n){let r={};for(let i of t){let t=n?.tables[i],a=U.join(e,`${i}.jsonl`),o;try{o=Y.readFileSync(a,`utf8`).trim()}catch(e){if(e.code===`ENOENT`){r[i]=[];continue}throw e}r[i]=o?o.split(`
|
|
94
|
+
`)};c.out(a)}catch(e){throw e instanceof Q&&e.code===Z.NotFound?Error(r,{cause:e}):e}}});async function listStaticWebsites(e){let{client:t,workspaceId:n}=await v({profile:e?.profile,workspaceId:e?.workspaceId}),r=I(e?.order);return(await V(async(e,i)=>{let{staticwebsites:a,nextPageToken:o}=await t.listStaticWebsites({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(e=>({workspaceId:n,name:e.name,description:e.description,url:e.url,allowedIpAddresses:e.allowedIpAddresses}))}const ra=D({name:`list`,description:`List all static websites in a workspace.`,args:q.strictObject({...P,...L()}),run:async e=>{let t=c.jsonMode,n=await listStaticWebsites({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({allowedIpAddresses:e,...t})=>{if(e.length===0)return{...t,allowedIpAddresses:`No allowed IP addresses`};let n=e.length,r=n===1?`1 IP address`:`${n} IP addresses`;return{...t,allowedIpAddresses:r}});c.out(r)}}),ia=G({name:`staticwebsite`,description:`Manage static websites in your workspace.`,subCommands:{deploy:ze,domain:ta,list:ra,get:na},async run(){await K(ra,[])}}),aa=new Set(Object.values(re));async function activateBaseline(e,t,n,r){let i=await $.realpath(e),a=U.dirname(i),o=U.basename(i),s=await $.mkdtemp(U.join(a,`.${o}-rebaseline-`)),l=`${s}-previous`,u=!1,d=!1;try{await $.cp(i,s,{recursive:!0});for(let e of await $.readdir(s,{withFileTypes:!0})){if(!e.isDirectory()||!fe.test(e.name))continue;let t=U.join(s,e.name);(await $.readdir(t)).some(e=>aa.has(e))&&await $.rm(t,{recursive:!0,force:!0})}let e={...t,namespace:n,version:5,createdAt:new Date().toISOString(),rebaseline:r},a=await _n(e,s,0);$t(a.filePath),await $.rename(i,l),u=!0;try{await $.rename(s,i),d=!0}catch(e){throw await $.rename(l,i),u=!1,e}try{await $.rm(l,{recursive:!0,force:!0})}catch(e){c.warn(`The previous migration directory remains at ${l}: ${e instanceof Error?e.message:String(e)}`)}u=!1}finally{Y.existsSync(s)&&await $.rm(s,{recursive:!0,force:!0}),!d&&u&&Y.existsSync(l)&&await $.rename(l,i)}}async function rebaseline(e){m(`tailordb migration`);let{config:t,plugins:n}=await w(e.configPath),r=U.dirname(t.path),i=Tt(f(t,r),e.namespace),a=nr({command:`tailor`,args:[`tailordb`,`migration`,`generate`,`--config`,t.path]});k(i.migrationsDir,i.namespace);let o=z(i.migrationsDir);if(!o)throw Error(`No migration history found for namespace "${i.namespace}". Run ${a} first.`);let s=Ke(i.migrationsDir),u=z(i.migrationsDir,0)?.rebaseline?.historyId??null,d=Se([i])[i.namespace],p=n.length>0?new mt(n):void 0,{defineApplication:h}=await import(`../application-BKlOiD1x.mjs`),g=h({config:t,pluginManager:p});for(let e of g.tailorDBServices)await e.loadTypes(),await e.processNamespacePlugins();let _=g.tailorDBServices.find(e=>e.namespace===i.namespace);if(!_)throw Error(`No TailorDB service found for namespace "${i.namespace}"`);let assertLocalTypesReady=()=>{let e=se(_.types,i.namespace),t=Jt(o,e.tables,i.namespace);if(xt(t))throw c.error(`Migration history does not reproduce the current local schema for namespace ${l.bold(i.namespace)}:`),c.log(Ft(t)),Error(`Refusing to re-baseline: the migration history must reproduce the current local schema. Run ${a} first.`)},localSourceFiles=()=>[t.path,...qn(_.config,r)];assertLocalTypesReady();let y=ve(localSourceFiles()),{client:b,workspaceId:x}=await v({profile:e.profile,workspaceId:e.workspaceId}),S=[`--config`,t.path,`--workspace-id`,x,...e.profile?[`--profile`,e.profile]:[]],C=nr({command:`tailor`,args:[`tailordb`,`migration`,`set`,`0`,`--namespace`,i.namespace,...S]}),ee=nr({command:`tailor`,args:[`deploy`,...S]}),assertConnectedWorkspaceReady=async(e,n)=>{let r=await Dt(b,N(x,`tailordb`,i.namespace)),a=r.number;if(a!==s){let e=a===null?`<unset>`:F(a);throw Error(`The connected workspace must be at the latest migration ${F(s)} before re-baselining; current checkpoint is ${e}.`)}if(r.historyIdInvalid)throw Error(`Refusing to re-baseline: the connected workspace has an invalid migration history marker.`);if(r.historyId!==e)throw Error(n===`confirmation`?`The connected workspace migration history changed while waiting for confirmation. Run the command again.`:`Refusing to re-baseline: the connected workspace does not match the local migration history.`);let o=await rt(b,x,[i],t,[mn(_)]),l=o[0];if(!l||l.remoteMigrationNumber!==s||l.hasDrift||l.checkpointMissingLocal)throw l?.hasDrift&&(c.error(`Remote schema drift detected:`),c.log(_t(o))),Error(`Refusing to re-baseline: the connected workspace remote schema must match the latest migration.`)};if(await assertConnectedWorkspaceReady(u,`initial`),c.newline(),c.warn(`This will replace the migration history for ${l.bold(i.namespace)}.`),c.log(` Latest migration: ${F(s)}`),c.log(` New history: 0000/schema.json only`),c.log(` migrate.ts and db.ts files will disappear from the working tree.`),c.log(` Committed migration files will remain in Git history. Preserve any uncommitted files before continuing.`),c.log(` Every other environment must already be at the latest migration.`),c.log(` The connected workspace checkpoint will be reset to 0000.`),c.newline(),!e.yes&&!await A.confirm({message:`Re-baseline this migration history and reset the connected workspace checkpoint?`,default:!1})){c.info(`Operation cancelled.`);return}if(k(i.migrationsDir,i.namespace),Se([i])[i.namespace]!==d)throw Error(`Migration files changed while waiting for confirmation. Run the command again.`);if(ve(localSourceFiles())!==y)throw Error(`Local TailorDB table or config files changed. Run the command again.`);assertLocalTypesReady(),await assertConnectedWorkspaceReady(u,`confirmation`);let T={historyId:Ct(),replacedHistoryId:u,replacedLatestMigration:s};await activateBaseline(i.migrationsDir,o,i.namespace,T);try{await Pe(b,x,i.namespace,0,T.historyId)}catch(e){throw Error(`The local migration history was re-baselined, but the connected workspace checkpoint could not be updated. Run ${C}, or run ${ee} with schema checks enabled after resolving the connection error.`,{cause:e})}c.success(`Re-baselined ${l.bold(i.namespace)} and reset the connected workspace checkpoint to 0000.`)}const oa=D({name:`rebaseline`,description:`Collapse the full migration history into a new 0000 baseline.`,notes:`Re-baselining removes migrations after 0000 from the working tree, records a new migration history ID, and resets the connected workspace checkpoint without changing its schema or data. Every environment must already have applied the latest migration before you run this command.`,args:q.strictObject({...O,...M,namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await rebaseline({configPath:e.config,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});async function set(e){m(`tailordb migration`);let t=ht(e.number),{config:n}=await w(e.configPath),r=U.dirname(n.path),i=f(n,r),a=Tt(i,e.namespace),o=a.namespace;k(a.migrationsDir,o),le(a.migrationsDir,t);let s=z(a.migrationsDir,0)?.rebaseline?.historyId,{client:u,workspaceId:d}=await v({profile:e.profile,workspaceId:e.workspaceId}),p=N(d,`tailordb`,o),h=await Dt(u,p),g=h.number,_=g??0,y=h.historyIdInvalid?`<invalid>`:h.historyId??`<unset>`,b=s??`<unset>`;if(c.newline(),c.warn(`This operation will change TailorDB migration state metadata.`),c.log(`Namespace: ${l.bold(o)}`),c.log(`Current migration: ${g===null?`<unset>`:l.bold(F(g))}`),c.log(`New migration: ${l.bold(F(t))}`),c.log(`Current migration history ID: ${l.bold(y)}`),c.log(`New migration history ID: ${l.bold(b)}`),c.newline(),t<_?(c.warn(`Setting migration number backwards (${F(_)} → ${F(t)}) will cause previous migrations to be re-executed on next apply.`),c.newline()):t>_&&(c.warn(`Setting migration number forwards (${F(_)} → ${F(t)}) will skip migrations ${F(_+1)} to ${F(t)}.`),c.newline()),!e.yes){if(!await A.confirm({message:`Continue with migration checkpoint and history ID update?`,default:!1})){c.info(`Operation cancelled.`);return}c.newline()}await fn(u,{trn:p,labels:{[Gt]:zt(t),...s?{[Lt]:s}:{}},remove:s?void 0:[Lt]}),c.success(`Migration checkpoint set to ${l.bold(F(t))} for namespace ${l.bold(o)}`)}const sa=D({name:`set`,description:`Set migration checkpoint to a specific number.`,notes:"The migration number must be a 4-digit value (e.g. `0001`) or a bare integer (e.g. `1`) within 0–9999, and must exist in the local migration history; `0` is always accepted as the baseline, provided the local history passes validation. A gapped history is rejected.\n\nMetadata lookup failures (authentication, permission, or network errors) are reported as errors; only a not-yet-deployed namespace is treated as having no checkpoint.",args:q.strictObject({...O,...M,number:W(q.string(),{positional:!0,description:`Migration number to set (e.g., 0001 or 1)`}),namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await set({configPath:e.config,number:e.number,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});function isStatusFailure(e){return e.status===`error`}async function collectMigrationStatuses(e){let{config:t}=await w(e.configPath),n=U.dirname(t.path),r=f(t,n);if(r.length===0)throw Error(`No TailorDB services with migrations configuration found`);let i=e.namespace?r.filter(t=>t.namespace===e.namespace):r;if(i.length===0)throw Error(`Namespace "${e.namespace}" not found or does not have migrations configured`);let a=new Map,o=new Map;for(let{namespace:e,migrationsDir:t}of i)try{let n=je(t),r=new Map,i=null;for(let e of n){if(e.type===`schema`){let t=$t(e.path);e.number===0&&(i=t.rebaseline?.historyId??null);continue}try{let t=ft(e.path);t.description&&r.set(e.number,t.description)}catch(e){if(e instanceof jt)throw e}}a.set(e,{migrationFiles:n,descriptions:r,historyId:i})}catch(t){o.set(e,t instanceof Error?t.message:String(t))}if(a.size===0)return i.map(({namespace:e})=>({status:`error`,namespace:e,error:o.get(e)??`Failed to read local migration history.`}));let{client:s,workspaceId:c}=await v({profile:e.profile,workspaceId:e.workspaceId}),l=[];for(let{namespace:e}of i){if(o.has(e)){l.push({status:`error`,namespace:e,error:o.get(e)??`Failed to read local migration history.`});continue}let t=a.get(e);if(!t){l.push({status:`error`,namespace:e,error:`Failed to read local migration history.`});continue}let{migrationFiles:n,descriptions:r,historyId:i}=t,u=N(c,`tailordb`,e),d;try{d=await Dt(s,u)}catch(t){l.push({status:`error`,namespace:e,error:t instanceof Error?t.message:String(t)});continue}let f=d.number??0;if(d.historyIdInvalid){l.push({status:`error`,namespace:e,error:`Remote migration history ID is invalid.`});continue}if((d.number!==null||d.historyId!==null)&&d.historyId!==i){l.push({status:`error`,namespace:e,error:`Remote migration history ID ${d.historyId??`<unset>`} does not match local migration history ID ${i??`<unset>`}.`});continue}let p=n.map(e=>e.number).filter((e,t,n)=>n.indexOf(e)===t).toSorted((e,t)=>e-t).filter(e=>e>f).map(e=>({number:e,label:F(e),...r.has(e)?{description:r.get(e)}:{}}));l.push({status:`ok`,namespace:e,currentMigration:f,currentMigrationLabel:F(f),pendingMigrations:p})}return l}function printMigrationStatuses(e){for(let t of e){if(c.newline(),c.info(`Namespace: ${l.bold(t.namespace)}`),isStatusFailure(t)){c.error(` Migration status error: ${t.error}`);continue}if(c.log(` Current migration: ${l.bold(t.currentMigrationLabel)}`),t.pendingMigrations.length>0){c.log(` Pending migrations:`);for(let e of t.pendingMigrations)e.description?c.log(` - ${e.label}: ${e.description}`):c.log(` - ${e.label}`)}else c.log(` Pending migrations: (none)`)}c.newline()}async function status(e){m(`tailordb migration`);let t=await collectMigrationStatuses(e);e.json?c.out(t):printMigrationStatuses(t);let n=t.filter(isStatusFailure);if(n.length>0){let e=n.map(e=>e.namespace).join(`, `);throw Error(`Migration status check failed for ${n.length} namespace${n.length===1?``:`s`}: ${e}`)}}const ca=D({name:`status`,description:`Show the current migration status for TailorDB namespaces, including applied and pending migrations.`,notes:`Every local migration file is checked for a compatible format version, and deployed migration history IDs must match the local baseline. Compatibility errors, history mismatches, and metadata lookup failures are reported per namespace and make the command exit non-zero; only a not-yet-deployed namespace is treated as having no applied migrations.`,args:q.strictObject({...O,namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (shows all namespaces if not specified)`})}),run:async e=>{await status({configPath:e.config,namespace:e.namespace,workspaceId:e[`workspace-id`],profile:e.profile,json:c.jsonMode})}});async function fetchRemoteGqlPermissions(e,t,n){return An(async(r,i)=>{let{permissions:a,nextPageToken:o}=await e.listTailorDBGQLPermissions({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]})}async function fetchRemoteTypes(e,t,n){return wn(async(r,i)=>{try{let{tailordbTypes:a,nextPageToken:o}=await e.listTailorDBTypes({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}catch(e){throw e instanceof Q&&e.code===Z.NotFound?Error(`Cannot sync: TailorDB namespace "${n}" has not been deployed yet.`,{cause:e}):e}})}async function assertMigrationsReproduceLocalTypes(e,t){let{config:n,plugins:r}=e,i=r.length>0?new mt(r):void 0,{defineApplication:a,generatePluginFilesIfNeeded:o}=await import(`../application-BKlOiD1x.mjs`),s=a({config:n,pluginManager:i}),u=s.tailorDBServices.find(e=>e.namespace===t.namespace);if(!u)throw Error(`No TailorDB service found for namespace "${t.namespace}"`);for(let e of s.tailorDBServices)await e.loadTypes(),await e.processNamespacePlugins();let d=o(i,s.tailorDBServices,n.path),f=s.executorService??(d.length>0?(await import(`../service-CWFQ8EVo.mjs`)).createExecutorService({config:{files:[]},baseDir:U.dirname(n.path)}):void 0);await f?.loadExecutors(),d.length>0&&await f?.loadPluginExecutorFiles([...d]);let p=new Set;for(let e of Object.values(f?.executors??{}))vt(e)&&e.trigger.kind===`tailordb`&&p.add(e.trigger.tableName);let m={executorUsedTables:p,namespaceGqlOperations:u.config.gqlOperations},h=z(t.migrationsDir);if(!h)return m;let g=se(u.types,t.namespace),_=Jt(h,g.tables,t.namespace);if(!xt(_))return m;throw c.error(`Migration history does not reproduce the current local schema for namespace ${l.bold(t.namespace)}:`),c.log(Ft(_)),c.newline(),c.info(`This usually means one of the following:`),c.info(` - Migration files were edited and replaying them no longer matches the table definitions — fix the migration files.`,{mode:`plain`}),c.info(` - Table definitions changed without a new migration — run 'tailor tailordb migration generate' first.`,{mode:`plain`}),c.newline(),Error(`Refusing to sync: the migration history must reproduce the current local schema before it can be applied to the remote.`)}async function sync(e){m(`tailordb migration`);let t=ht(e.number),n=await w(e.configPath),{config:r}=n,i=U.dirname(r.path),a=f(r,i),o=Tt(a,e.namespace);k(o.migrationsDir,o.namespace);let s=le(o.migrationsDir,t),u=z(o.migrationsDir,t);if(!u)throw Error(`No initial schema snapshot found in ${o.migrationsDir}. Expected 0000/schema.json.`);let d=await assertMigrationsReproduceLocalTypes(n,o),{client:p,workspaceId:h}=await v({profile:e.profile,workspaceId:e.workspaceId}),g=N(h,`tailordb`,o.namespace),_=await Ee(p,g),y=await fetchRemoteTypes(p,h,o.namespace),x=new Set(y.map(e=>e.name)),{creates:S,updates:C,deletes:T}=Ie(u,x),te=await fetchRemoteGqlPermissions(p,h,o.namespace),ne=new Set(te.map(e=>e.typeName)),re=Object.entries(u.tables).flatMap(([e,t])=>t.permissions?.gql?[{typeName:e,permission:b(t.permissions.gql)}]:[]),E=new Set(re.map(e=>e.typeName)),ie=te.filter(e=>!E.has(e.typeName));if(c.newline(),c.info(`Namespace: ${l.bold(o.namespace)}`),c.log(` Current migration: ${_===null?`<unset>`:l.bold(F(_))}`),c.log(` Target migration: ${l.bold(F(t))}`),c.log(` Tables to create: ${l.bold(String(S.length))}`),c.log(` Tables to update: ${l.bold(String(C.length))}`),c.log(` Tables to delete: ${l.bold(String(T.length))}`),c.log(` GQL permissions to set: ${l.bold(String(re.length))}`),c.log(` GQL permissions to delete: ${l.bold(String(ie.length))}`),c.newline(),S.length+C.length+T.length+re.length+ie.length===0?c.info(`No tables to apply; only the migration label will be updated.`):(c.warn(`This operation will overwrite remote TailorDB tables to match the selected snapshot.`),T.length>0&&c.warn(`Existing data in deleted tables will be lost.`),c.newline()),c.warn(`Sync never runs migrate.ts scripts; it only applies the schema snapshot and moves the migration label.`),c.newline(),_!==null&&t<_?(c.warn(`Migrations ${F(t+1)}–${F(_)} will become pending again and re-execute on the next deploy, including their migrate.ts scripts. Make sure those scripts are idempotent (safe to re-run).`),c.newline()):_!==null&&t>_&&(c.warn(`Moving the migration label forwards (${F(_)} → ${F(t)}): migrate.ts scripts for migrations ${F(_+1)}–${F(t)} will not run on the next deploy.`),c.newline()),!e.yes){if(!await A.confirm({message:`Continue and set migration label to ${F(t)}?`,default:!1})){c.info(`Operation cancelled.`);return}c.newline()}let ae=ee(u,d),manifestFor=e=>{let t=ae.get(e);if(!t)throw Error(`Internal error: no manifest generated for table "${e}". No changes were applied.`);return t},oe=S.map(e=>manifestFor(e)),se=C.map(e=>manifestFor(e));try{await Promise.all([...oe.map(e=>p.createTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbType:e})),...se.map(e=>p.updateTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbType:e}))])}catch(e){tt(e,[`The target snapshot marks a field as required, but existing remote records have no value for it.`,`Populate those records first (e.g. with a migration script applied via 'tailor deploy'), then re-run the sync.`])}await Promise.all(re.map(({typeName:e,permission:t})=>{let n={workspaceId:h,namespaceName:o.namespace,typeName:e,permission:t};return ne.has(e)?p.updateTailorDBGQLPermission(n):p.createTailorDBGQLPermission(n)})),await Promise.all(ie.map(e=>p.deleteTailorDBGQLPermission({workspaceId:h,namespaceName:o.namespace,typeName:e.typeName}))),await Promise.all(T.map(e=>p.deleteTailorDBType({workspaceId:h,namespaceName:o.namespace,tailordbTypeName:e}))),await fn(p,{trn:g,labels:{[Gt]:zt(t),...u.rebaseline?.historyId?{[Lt]:u.rebaseline.historyId}:{}},remove:u.rebaseline?.historyId?void 0:[Lt]}),c.success(`Synced namespace ${l.bold(o.namespace)} to migration ${l.bold(F(t))}.`),t<s&&(c.newline(),c.info(`Run 'tailor deploy' to apply migrations ${F(t+1)}–${F(s)} from the working tree.`))}const la=D({name:`sync`,description:`Sync remote TailorDB schema to a specific migration snapshot (recovery from --no-schema-check drift).`,args:q.strictObject({...O,...M,number:W(q.string(),{positional:!0,description:`Migration number to sync to (e.g., 0001 or 1; 0 targets the baseline snapshot)`}),namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`})}),run:async e=>{await j({profile:e.profile}),await sync({configPath:e.config,number:e.number,namespace:e.namespace,yes:e.yes,workspaceId:e[`workspace-id`],profile:e.profile})}});function delay(e){return e>0?new Promise(t=>setTimeout(t,e)):Promise.resolve()}function assertSeedDataDirectory(e){let t;try{t=Y.statSync(e)}catch(t){throw t.code===`ENOENT`?Error(`Seed data directory not found: ${e}. Run 'tailor generate' before testing migrations.`,{cause:t}):t}if(!t.isDirectory())throw Error(`Seed data path is not a directory: ${e}`)}function assertAssertionScript(e){let t=U.resolve(e),n;try{n=Y.statSync(t)}catch(e){throw e.code===`ENOENT`?Error(`Migration assertion script not found: ${t}`,{cause:e}):e}if(!n.isFile())throw Error(`Migration assertion path is not a file: ${t}`)}function assertCloneTargetRegion(e,t){if(e!==t)throw Error(`Clone mode requires source and target workspaces in the same region (source: ${e}, target: ${t}).`)}function assertTargetWorkspaceDiffers(e,t){if(t?.toLowerCase()===e.toLowerCase())throw Error(`The migration test target workspace must differ from the source workspace.`)}function resolveAssertionNamespace(e,t){let n=t??(e.length===1?e[0]:void 0);if(!n)throw Error(`--assert-namespace is required when pending migrations span multiple namespaces.`);if(!e.includes(n))throw Error(`Assertion namespace "${n}" has no pending migrations.`);return n}async function createMigrationTestBaselineSnapshots(e){let t=new Map([...e.baselines].map(([e,t])=>[e,t.snapshot]));if(e.dataMode!==`clone`)return t;let n=e.inputs.filter(e=>!t.has(e.namespace)),r=await Promise.all(n.map(t=>bt(e.client,e.workspaceId,t.namespace)));return n.forEach((e,n)=>{t.set(e.namespace,o(r[n],`remote snapshot missing for "${e.namespace}"`))}),t}async function waitForCloneApplicationData(e,t){let n=t.pollInterval??1e3,i=t.timeout??3e5,a=Date.now()+i;for(;Date.now()<=a;){let i=await e.getCloneApplicationDataOperation({sourceWorkspaceId:t.sourceWorkspaceId,targetWorkspaceId:t.targetWorkspaceId,operationId:t.operationId});if(i.status===r.COMPLETED)return;if(i.status===r.FAILED)throw Error(`Application data clone failed: ${i.errorMessage||`unknown platform error`}`);if(i.status!==r.PENDING&&i.status!==r.PROCESSING)throw Error(`Application data clone returned unexpected status ${i.status}.`);await delay(n)}throw Error(`Application data clone timed out after ${Math.round(i/1e3)} seconds.`)}function loadSnapshotSeedData(e,t,n){let r={};for(let i of t){let t=n?.tables[i],a=U.join(e,`${i}.jsonl`),o;try{o=Y.readFileSync(a,`utf8`).trim()}catch(e){if(e.code===`ENOENT`){r[i]=[];continue}throw e}r[i]=o?o.split(`
|
|
95
95
|
`).map((e,n)=>{let r;try{r=JSON.parse(e)}catch(e){throw Error(`Invalid JSON in ${a} at line ${n+1}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`Invalid seed row in ${a} at line ${n+1}: expected a JSON object`);let i=r;return t?projectSeedObject(i,t.fields,new Set([`id`])):i}):[]}return r}function projectSeedObject(e,t,n=new Set){return Object.fromEntries(Object.entries(e).flatMap(([e,r])=>{let i=t[e];return i?[[e,projectSeedValue(r,i)]]:n.has(e)?[[e,r]]:[]}))}function projectSeedValue(e,t){let n=t.fields;return n?t.array?Array.isArray(e)?e.map(e=>isJsonObject(e)?projectSeedObject(e,n):e):e:isJsonObject(e)?projectSeedObject(e,n):e:e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function sortSeedTypesForSnapshot(e){let t=Object.keys(e.tables),n=new Set(t),r=new Map,i=[];for(let[t,a]of Object.entries(e.tables)){let e=new Set;for(let r of Object.values(a.fields)){let a=r.foreignKeyType;a&&(a===t?i.push(t):n.has(a)&&e.add(a))}r.set(t,[...e])}let a=new Set,o=[],visit=e=>{if(!a.has(e)){a.add(e);for(let t of r.get(e)??[])visit(t);o.push(e)}};for(let e of t)visit(e);return{order:o,selfRefTypes:i}}function temporaryWorkspaceName(){return`migration-test-${new Date().toISOString().replace(/[-:T.Z]/g,``).slice(0,14)}-${Or(3).toString(`hex`)}`}function stateOrThrow(e){return o(e,`migration test runtime was used before preparation`)}async function assertSourceBaselineFresh(e,t,n){let r=e.loaded,i=f(r.config,U.dirname(r.config.path)),a=r.application.tailorDBServices.map(mn),o=(await rt(e.client,n,i,r.config,a)).find(e=>e.hasDrift||e.checkpointMissingLocal||e.checkpointRepair);if(o)throw Error(`Source namespace "${o.namespace}" changed after migration test preparation. Run the migration test again.`);for(let r of i){let i=t.baselines.get(r.namespace);if(!i)continue;let a=await Ee(e.client,N(n,`tailordb`,r.namespace));if(a!==i.migrationNumber)throw Error(`Source namespace "${r.namespace}" moved from migration ${i.migrationNumber} to ${a??`none`} after migration test preparation. Run the migration test again.`)}let s=a.filter(e=>!t.baselines.has(e.namespace));for(let r of s){let i=t.baselineSnapshots.get(r.namespace);if(!i)continue;let a=await bt(e.client,n,r.namespace);if(ct(i,a).changes.length>0)throw Error(`Source namespace "${r.namespace}" schema changed after migration test preparation. Run the migration test again.`)}}async function deleteExistingUserProfileConfig(e,t){let n=e.loaded.application.authService;if(!n)return;let r=n.config.name;await Mn(()=>e.client.getUserProfileConfig({workspaceId:t,namespaceName:r}))&&await e.client.deleteUserProfileConfig({workspaceId:t,namespaceName:r})}function migrationConfig(e,t){return e.config.db?.[t]?.migration}function authExecutionContext(e,t,n){let r=e.loaded.application.authService;if(!r)throw Error(`Auth configuration is required to execute migration test scripts.`);let i=n??dn(migrationConfig(e.loaded,t),r.config.machineUsers?Object.keys(r.config.machineUsers):void 0);if(!i)throw Error(`No machine user is available for namespace "${t}". Pass --machine-user or configure one in auth or db.${t}.migration.`);return{authNamespace:r.config.name,machineUserName:i}}async function prepareMigrationTest(e){let t=await pn({configPath:e.configPath}),n=U.dirname(t.config.path),r=f(t.config,n);if(r.length===0)throw Error(`No TailorDB services with migrations configuration found.`);for(let e of r)k(e.migrationsDir,e.namespace);let i;e.data===`seed`&&(i=await _e({configPath:t.config.path}),assertSeedDataDirectory(U.join(i.distPath,`data`))),e.assertionPath&&assertAssertionScript(e.assertionPath);let a=t.application.tailorDBServices.map(mn),s=await Et({profile:e.profile}),c=await ce({profile:e.profile}),l=await yn(s,c),u=await Ne({workspaceId:e.workspaceId,profile:e.profile});assertTargetWorkspaceDiffers(u,e.targetWorkspaceId);let[d,p,m]=await Promise.all([l.getWorkspace({workspaceId:u}),l.getApplication({workspaceId:u,applicationName:t.config.name}),e.data===`clone`&&e.targetWorkspaceId?l.getWorkspace({workspaceId:e.targetWorkspaceId}):Promise.resolve(void 0)]),h=o(d.workspace,`source workspace "${u}" not found`);o(p.application,`application "${t.config.name}" not found in source workspace`);let g=m?o(m.workspace,`target workspace "${e.targetWorkspaceId}" not found`):void 0,_=await rt(l,u,r,t.config,a),v=_.find(e=>e.hasDrift||e.checkpointMissingLocal);if(v)throw Error(`Source namespace "${v.namespace}" does not match its migration checkpoint. Run 'tailor tailordb migration validate' first.`);let y=_.find(e=>e.checkpointRepair);if(y)throw Error(`Source namespace "${y.namespace}" has a pending migration checkpoint repair. Run 'tailor deploy' against the source workspace first.`);let b=new Map,x=new Map,S=[];for(let e of r){let t=await Ee(l,N(u,`tailordb`,e.namespace));if(t===null)throw Error(`Source namespace "${e.namespace}" has no sdk-migration checkpoint. Deploy or set its migration checkpoint before testing.`);let n=Ke(e.migrationsDir);if(t>n)throw Error(`Source namespace "${e.namespace}" is at migration ${t}, but the local history ends at ${n}.`);let r=z(e.migrationsDir,t);if(!r)throw Error(`No migration baseline snapshot found for namespace "${e.namespace}".`);b.set(e.namespace,{migrationNumber:t,snapshot:r,historyId:r.rebaseline?.historyId??null});let i=z(e.migrationsDir,n);if(!i)throw Error(`No target migration snapshot found for namespace "${e.namespace}".`);x.set(e.namespace,i),t<n&&S.push(e.namespace)}if(S.length===0)throw Error(`No pending TailorDB migrations found in the source workspace.`);let C=await createMigrationTestBaselineSnapshots({client:l,workspaceId:u,dataMode:e.data,inputs:a,baselines:b}),ee={sourceWorkspaceId:u,sourceApplicationName:t.config.name,temporaryWorkspace:{name:temporaryWorkspaceName(),region:h.region,...h.organizationId?{organizationId:h.organizationId}:{},...h.folderId?{folderId:h.folderId}:{}},baselines:b,baselineSnapshots:C,targetSnapshots:x,pendingNamespaces:S,...g?{designatedTarget:{id:g.id,region:g.region}}:{}};return{state:{client:l,loaded:t,options:e,...i?{seedContext:i}:{}},prepared:ee}}function createMigrationTestDependencies(){let e;return{prepare:async t=>{let{state:n,prepared:r}=await prepareMigrationTest(t);return e=n,r},createWorkspace:async t=>{let n=stateOrThrow(e),r=await et(n.client,t.temporaryWorkspace);return c.info(`Created temporary workspace ${r.name} (${r.id}).`),{id:r.id,name:r.name}},deployBaseline:async({prepared:t,targetWorkspaceId:n})=>{let r=stateOrThrow(e);await deleteExistingUserProfileConfig(r,n),await dt({configPath:r.loaded.config.path,profile:r.options.profile,workspaceId:n,yes:!0},t.baselines,t.baselineSnapshots);for(let[e,i]of t.baselines)await Pe(r.client,n,e,i.migrationNumber,i.historyId??void 0)},seedData:async({prepared:t,targetWorkspaceId:n})=>{let r=stateOrThrow(e),i=o(r.seedContext,`seed context missing after migration test preparation`),a=U.join(i.distPath,`data`);assertSeedDataDirectory(a);let s=new Map(r.loaded.application.tailorDBServices.map(e=>{let n=t.baselines.get(e.namespace),r=mn(e);return[e.namespace,n?.snapshot??R({version:1,namespace:e.namespace,createdAt:new Date().toISOString(),tables:r.types})]}));for(let[e,t]of s){let{order:o,selfRefTypes:s}=sortSeedTypesForSnapshot(t),c=loadSnapshotSeedData(a,o,t),l=o.filter(e=>(c[e]?.length??0)>0);if(l.length===0)continue;let u=await Oe(e,l,U.dirname(r.loaded.config.path)),d=xe({data:c,order:o,codeByteSize:new TextEncoder().encode(u.bundledCode).length}),f=authExecutionContext(r,e,r.options.machineUser??i.machineUserName);for(let t of d){let i=await Le({client:r.client,workspaceId:n,name:`migration-test-seed-${e}.ts`,code:u.bundledCode,arg:{data:t.data,order:t.order,selfRefTypes:s,upsert:!1},invoker:{namespace:f.authNamespace,machineUserName:f.machineUserName}});if(!i.success)throw Error(i.error??`Seed execution failed for namespace "${e}".`);if(JSON.parse(i.result||`{}`).success!==!0)throw Error(`Seed execution reported failure for namespace "${e}".`)}}},cloneData:async({prepared:t,sourceWorkspaceId:n,targetWorkspaceId:r,applicationName:i})=>{let a=stateOrThrow(e);await assertSourceBaselineFresh(a,t,n),c.warn(`Clone mode copies TailorDB records only; IdP users and file blobs are not copied.`);let o;try{o=(await a.client.cloneApplicationData({sourceWorkspaceId:n,sourceApplicationName:i,targetWorkspaceId:r,targetApplicationName:i})).operationId}catch(e){throw e instanceof Q&&e.code===Z.Unimplemented?Error(`Application data clone is not enabled for this platform. Retry with '--data seed'.`,{cause:e}):e}if(!o)throw Error(`Application data clone returned no operation ID.`);await waitForCloneApplicationData(a.client,{sourceWorkspaceId:n,targetWorkspaceId:r,operationId:o})},deployMigrations:async({prepared:t,targetWorkspaceId:n})=>{let r=stateOrThrow(e);await Qt({configPath:r.loaded.config.path,profile:r.options.profile,workspaceId:n,yes:!0},t.targetSnapshots)},runAssertion:async({prepared:t,targetWorkspaceId:n,assertionPath:r,assertionNamespace:i,machineUser:a})=>{let o=stateOrThrow(e),s=resolveAssertionNamespace(t.pendingNamespaces,i),c=authExecutionContext(o,s,a),l=await sn(r,s,0,o.loaded.config.env??{},U.dirname(o.loaded.config.path)),u=await Le({client:o.client,workspaceId:n,name:`migration-test-assert-${s}.ts`,code:l.bundledCode,invoker:{namespace:c.authNamespace,machineUserName:c.machineUserName}});if(!u.success)throw Error(u.error??`Migration assertion failed for namespace "${s}".`)},deleteWorkspace:async t=>{await stateOrThrow(e).client.deleteWorkspace({workspaceId:t})}}}async function runMigrationTest(e,t=createMigrationTestDependencies()){if(e.targetWorkspaceId&&!e.yes)throw Error(`--target-workspace-id requires --yes because the target may be overwritten.`);if(e.keep&&e.targetWorkspaceId)throw Error(`--keep applies only to automatically created workspaces; a designated target is always retained.`);if(e.assertionNamespace&&!e.assertionPath)throw Error(`--assert is required when --assert-namespace is provided.`);let n=await t.prepare(e);if(assertTargetWorkspaceDiffers(n.sourceWorkspaceId,e.targetWorkspaceId),e.assertionPath&&resolveAssertionNamespace(n.pendingNamespaces,e.assertionNamespace),e.data===`clone`&&e.targetWorkspaceId){let e=o(n.designatedTarget,`designated clone target was not loaded during preparation`);assertCloneTargetRegion(n.temporaryWorkspace.region,e.region)}let r=e.targetWorkspaceId===void 0,i=r?await t.createWorkspace(n):{id:o(e.targetWorkspaceId,`designated target workspace missing`),name:void 0},a,s=!1,l=!1;try{let r={prepared:n,targetWorkspaceId:i.id};await t.deployBaseline(r);let a={...r,sourceWorkspaceId:n.sourceWorkspaceId,applicationName:n.sourceApplicationName};e.data===`clone`?await t.cloneData(a):await t.seedData(a),await t.deployMigrations(r),e.assertionPath&&await t.runAssertion({...r,assertionPath:e.assertionPath,assertionNamespace:e.assertionNamespace,machineUser:e.machineUser})}catch(e){a=e,s=!0}if(r&&e.keep)c.info(`Keeping temporary workspace ${i.name??i.id}.`);else if(r)try{await t.deleteWorkspace(i.id),l=!0}catch(e){if(!s)throw Error(`Failed to delete temporary workspace ${i.id}: ${e instanceof Error?e.message:String(e)}`,{cause:e});c.warn(`Failed to delete temporary workspace ${i.id}: ${e instanceof Error?e.message:String(e)}`)}if(s)throw a;return{success:!0,workspaceId:i.id,...i.name?{workspaceName:i.name}:{},temporary:r,deleted:l,data:e.data,pendingNamespaces:n.pendingNamespaces}}async function migrationTest(e){m(`tailordb migration`);let t=await runMigrationTest(e);if(e.json){c.out(t);return}c.success(`Pending migrations completed in workspace ${t.workspaceName??t.workspaceId}.`)}const ua=D({name:`test`,description:`Test pending migrations with seed fixtures or cloned data in a temporary workspace.`,notes:`The source workspace is read-only. Without --target-workspace-id, the command creates a workspace in the source workspace's region and deletes it after success or failure; pass --keep to retain it for inspection. A designated target is retained and requires --yes. Clone mode copies TailorDB records only; it does not copy IdP users or file blobs.`,args:q.strictObject({...O,yes:W(q.boolean().default(!1),{alias:`y`,description:`Acknowledge that a designated target workspace may be overwritten`}),data:W(q.enum([`seed`,`clone`]).default(`seed`),{description:`Data source for the migration test (seed or clone)`}),"target-workspace-id":W(q.uuid().optional(),{description:`Existing throwaway workspace to retain after the test (requires --yes)`}),keep:W(q.boolean().default(!1),{description:`Keep the automatically created workspace after the test`}),assert:W(q.string().optional(),{description:`Path to a TypeScript assertion script to run after migrations`,completion:{type:`file`,extensions:[`ts`]}}),"assert-namespace":W(q.string().optional(),{description:`TailorDB namespace exposed to the assertion script`}),"machine-user":W(q.string().optional(),{description:`Machine user for seed and assertion script execution`})}),run:async e=>{await j({profile:e.profile}),await migrationTest({configPath:e.config,workspaceId:e[`workspace-id`],profile:e.profile,data:e.data,targetWorkspaceId:e[`target-workspace-id`],keep:e.keep,assertionPath:e.assert,assertionNamespace:e[`assert-namespace`],machineUser:e[`machine-user`],yes:e.yes,json:c.jsonMode})}});function assertMigrationScriptsReady(e,t,n){let r=[],i=[],a=[],o=[];for(let t of je(e)){if(t.type!==`diff`)continue;let n=ft(t.path),s=Xe(e,t.number,`migrate`),c=Y.existsSync(s);n.requiresMigrationScript&&!n.scriptSkipped&&!c&&r.push(t.number),n.scriptSkipped&&c&&i.push(t.number),c&&Y.readFileSync(s,`utf8`).includes(`TODO(tailor-migration-review)`)&&a.push(t.number),n.hasWarnings&&!n.scriptSkipped&&!c&&o.push({migrationNumber:t.number,warnings:n.warnings})}if(r.length>0)throw Error(`Migration(s) ${r.map(F).join(`, `)} in namespace "${t}" require a migration script but have no migrate.ts. Add one with 'tailor tailordb migration script <number>', or record that no script is needed with 'tailor tailordb migration script <number> --no-script --reason "..."'.`);if(i.length>0){let e=i.map(e=>` ${_({migrationNumber:e,namespace:t,configPath:n})}`).join(`
|
|
96
96
|
`);throw Error(`Migration(s) ${i.map(F).join(`, `)} in namespace "${t}" have both a --no-script skip acknowledgment and migrate.ts. Clear the stale acknowledgment(s):
|
|
97
|
-
${e}\nOr delete migrate.ts to keep the skip.`)}if(a.length>0)throw Error(`Migration(s) ${a.map(F).join(`, `)} in namespace "${t}" contain generated normalization logic that still requires review in migrate.ts. Review each ${Me} marker, then remove the marker and its associated \`never\` annotation.`);return o}function buildValidationReports(e){let{targetNamespaces:t,migrationFileErrors:n,localResults:r,remoteResults:i,unacknowledgedWarnings:a}=e;return t.map(e=>{let t=n.get(e.namespace);if(t!==void 0)return{namespace:e.namespace,valid:!1,migrationFiles:{valid:!1,error:t}};let s=o(r.find(t=>t.namespace===e.namespace),`local schema check result missing for namespace "${e.namespace}"`),c={hasDiff:s.hasDiff,...s.diff?{diff:s.diff}:{}};if(i===void 0)return{namespace:e.namespace,valid:!1,migrationFiles:{valid:!0},localSchema:c,remoteSchema:{skipped:`check_failed`}};let l=o(i.find(t=>t.namespace===e.namespace),`remote schema check result missing for namespace "${e.namespace}"`),u=l.checkpointMissingLocal===!0,d={remoteMigrationNumber:l.remoteMigrationNumber,hasDrift:l.hasDrift,drifts:l.drifts,...l.skipped?{skipped:l.skipped}:{},...u?{checkpointMissingLocal:!0}:{},...l.rebaselinePending?{rebaselinePending:l.rebaselinePending}:{},...l.checkpointRepair?{checkpointRepair:l.checkpointRepair}:{}},f=a?.get(e.namespace),p;if(f!==void 0){let e=f.filter(e=>e.migrationNumber>l.remoteMigrationNumber);p={valid:e.length===0,missing:e}}return{namespace:e.namespace,valid:!c.hasDiff&&!d.hasDrift&&!u&&p?.valid!==!1,migrationFiles:{valid:!0},localSchema:c,remoteSchema:d,...p?{warningAcknowledgments:p}:{}}})}async function collectValidationReports(e){let{config:t,plugins:n}=await w(e.configPath),r=U.dirname(t.path),i=f(t,r);if(i.length===0)throw Error(`No TailorDB services with migrations configuration found`);let a=e.namespace?i.filter(t=>t.namespace===e.namespace):i;if(a.length===0)throw Error(`Namespace "${e.namespace}" not found or does not have migrations configured`);let o=n.length>0?new mt(n):void 0,{defineApplication:s}=await import(`../application-
|
|
97
|
+
${e}\nOr delete migrate.ts to keep the skip.`)}if(a.length>0)throw Error(`Migration(s) ${a.map(F).join(`, `)} in namespace "${t}" contain generated normalization logic that still requires review in migrate.ts. Review each ${Me} marker, then remove the marker and its associated \`never\` annotation.`);return o}function buildValidationReports(e){let{targetNamespaces:t,migrationFileErrors:n,localResults:r,remoteResults:i,unacknowledgedWarnings:a}=e;return t.map(e=>{let t=n.get(e.namespace);if(t!==void 0)return{namespace:e.namespace,valid:!1,migrationFiles:{valid:!1,error:t}};let s=o(r.find(t=>t.namespace===e.namespace),`local schema check result missing for namespace "${e.namespace}"`),c={hasDiff:s.hasDiff,...s.diff?{diff:s.diff}:{}};if(i===void 0)return{namespace:e.namespace,valid:!1,migrationFiles:{valid:!0},localSchema:c,remoteSchema:{skipped:`check_failed`}};let l=o(i.find(t=>t.namespace===e.namespace),`remote schema check result missing for namespace "${e.namespace}"`),u=l.checkpointMissingLocal===!0,d={remoteMigrationNumber:l.remoteMigrationNumber,hasDrift:l.hasDrift,drifts:l.drifts,...l.skipped?{skipped:l.skipped}:{},...u?{checkpointMissingLocal:!0}:{},...l.rebaselinePending?{rebaselinePending:l.rebaselinePending}:{},...l.checkpointRepair?{checkpointRepair:l.checkpointRepair}:{}},f=a?.get(e.namespace),p;if(f!==void 0){let e=f.filter(e=>e.migrationNumber>l.remoteMigrationNumber);p={valid:e.length===0,missing:e}}return{namespace:e.namespace,valid:!c.hasDiff&&!d.hasDrift&&!u&&p?.valid!==!1,migrationFiles:{valid:!0},localSchema:c,remoteSchema:d,...p?{warningAcknowledgments:p}:{}}})}async function collectValidationReports(e){let{config:t,plugins:n}=await w(e.configPath),r=U.dirname(t.path),i=f(t,r);if(i.length===0)throw Error(`No TailorDB services with migrations configuration found`);let a=e.namespace?i.filter(t=>t.namespace===e.namespace):i;if(a.length===0)throw Error(`Namespace "${e.namespace}" not found or does not have migrations configured`);let o=n.length>0?new mt(n):void 0,{defineApplication:s}=await import(`../application-BKlOiD1x.mjs`),c=s({config:t,pluginManager:o});for(let e of c.tailorDBServices)await e.loadTypes(),await e.processNamespacePlugins();Kn({tailorDBServices:c.tailorDBServices});for(let{namespace:e}of a)if(!c.tailorDBServices.some(t=>t.namespace===e))throw Error(`No TailorDB service found for namespace "${e}"`);let l=c.tailorDBServices.map(mn),u=new Map(l.map(e=>[e.namespace,e.types])),d=new Map,p=[],m=e.strict?new Map:void 0;for(let t of a)try{k(t.migrationsDir,t.namespace),z(t.migrationsDir);let n=assertMigrationScriptsReady(t.migrationsDir,t.namespace,e.configPath);m?.set(t.namespace,n),p.push(t)}catch(e){d.set(t.namespace,e instanceof Error?e.message:String(e))}let h={targetNamespaces:a,migrationFileErrors:d,localResults:await Pt(u,p),...m?{unacknowledgedWarnings:m}:{}};if(p.length===0)return{reports:buildValidationReports(h)};let g;try{let{client:n,workspaceId:r}=await v({profile:e.profile,workspaceId:e.workspaceId});g=await rt(n,r,p,t,l)}catch(e){return{reports:buildValidationReports(h),remoteError:e}}return{reports:buildValidationReports({...h,remoteResults:g})}}function printValidationReports(e){for(let t of e){if(c.newline(),c.info(`Namespace: ${l.bold(t.namespace)}`),!t.migrationFiles.valid){c.log(` Migration files: ${l.error(`invalid`)}`),c.log(` ${t.migrationFiles.error}`);continue}c.log(` Migration files: ${l.success(`OK`)}`);let e=t.localSchema;e?.hasDiff?e.diff?(c.log(` Local schema: ${l.error(`changes not in migration files`)}`),c.log(` ${Bt(e.diff)}`),c.log(Ft(e.diff))):c.log(` Local schema: ${l.error(`no migration snapshot found`)}`):c.log(` Local schema: ${l.success(`OK`)}`);let n=t.remoteSchema;n?.skipped===`check_failed`?c.log(` Remote schema: ${l.error(`not checked`)}`):n?.checkpointRepair?c.log(` Remote schema: ${l.success(`OK`)} (next deploy will reset the checkpoint to 0000 from ${F(n.checkpointRepair.from)})`):n?.checkpointMissingLocal?(c.log(` Remote schema: ${l.error(`remote migration ${F(n.remoteMigrationNumber)} is not in the local migration history`)}`),n.rebaselinePending&&c.log(` Fell behind before 'migration rebaseline' ran; must reach ${F(n.rebaselinePending.replacedLatestMigration)} first.`)):n?.hasDrift?(c.log(` Remote schema: ${l.error(`drift detected`)} (remote migration: ${F(n.remoteMigrationNumber)})`),c.log(T(n.drifts))):n?.skipped===`not_deployed`?c.log(` Remote schema: ${l.dim(`skipped (namespace not deployed)`)}`):n?.skipped===`no_migration_label`?c.log(` Remote schema: ${l.dim(`skipped (deployed namespace has no migration state)`)}`):n?.skipped===`no_snapshot`?c.log(` Remote schema: ${l.dim(`skipped (no local snapshot for remote migration ${F(n.remoteMigrationNumber)})`)}`):n&&c.log(` Remote schema: ${l.success(`OK`)} (remote migration: ${F(n.remoteMigrationNumber)})`);let r=t.warningAcknowledgments;if(r){if(r.valid)c.log(` Warning acknowledgments: ${l.success(`OK`)}`);else{c.log(` Warning acknowledgments: ${l.error(`missing for pending migration(s) with possible data loss`)}`);for(let e of r.missing){let t=F(e.migrationNumber);for(let n of e.warnings){let e=n.fieldName?`.${n.fieldName}`:``;c.log(` ${t}: ${n.tableName}${e}: ${n.reason}`)}}}}}c.newline()}function hasMissingCheckpoint(e){return e.remoteSchema?.checkpointMissingLocal===!0}function printResolutionHints(e,t){e.some(e=>e.localSchema?.hasDiff&&!e.localSchema.diff)&&c.info(`Run 'tailor tailordb migration generate' to create the initial snapshot.`),e.some(e=>e.localSchema?.diff)&&c.info(`Run 'tailor tailordb migration generate' to create migration files.`);let n=e.filter(hasMissingCheckpoint);n.length>0&&Ze(n.map(e=>({namespace:e.namespace,remoteMigrationNumber:e.remoteSchema.remoteMigrationNumber,...e.remoteSchema.rebaselinePending?{rebaselinePending:e.remoteSchema.rebaselinePending}:{}}))),e.some(e=>e.remoteSchema?.hasDrift)&&rn(e.map(e=>({hasDrift:e.remoteSchema?.hasDrift??!1,drifts:e.remoteSchema?.drifts??[]})));let r=e.filter(e=>e.warningAcknowledgments&&!e.warningAcknowledgments.valid);if(r.length>0){c.info(`For each migration listed, either add a data migration script with 'tailor tailordb migration script <number>' or record why none is needed:`);for(let e of r)for(let n of e.warningAcknowledgments?.missing??[])c.info(` ${_({migrationNumber:n.migrationNumber,namespace:e.namespace,configPath:t,noScript:!0})}`,{mode:`plain`})}}async function validate(e){m(`tailordb migration`);let t=await collectValidationReports(e),{reports:n}=t,r=n.filter(e=>!e.valid).length;if(e.json?c.out(n):(printValidationReports(n),r===0&&!(`remoteError`in t)?c.success(`All migration validation checks passed.`):printResolutionHints(n,e.configPath)),`remoteError`in t)throw t.remoteError;if(r>0)throw Error(`Migration validation failed for ${r} namespace(s)`)}const da=D({name:`validate`,description:`Validate the full migration history, unreviewed generated migration scripts, and schema drift (local tables vs. migration snapshot, remote schema vs. migration checkpoint) without deploying. This includes the migration and schema-drift checks used by 'deploy' and exits with a non-zero code when issues are found.`,args:q.strictObject({...O,namespace:W(q.string().optional(),{alias:`n`,description:`Target TailorDB namespace (validates all namespaces if not specified)`}),strict:W(q.boolean().default(!1),{description:`Also fail when a pending migration can drop data without an acknowledgment`})}),run:async e=>{await validate({configPath:e.config,namespace:e.namespace,workspaceId:e[`workspace-id`],profile:e.profile,json:c.jsonMode,strict:e.strict})}}),fa=G({name:`migration`,description:`Manage TailorDB schema migrations.`,subCommands:{generate:oe,rebaseline:oa,script:me,set:sa,status:ca,sync:la,test:ua,validate:da}}),pa=G({name:`tailordb`,description:`Manage TailorDB tables and data.`,notes:"The `tailordb erd` commands are provided by the @tailor-platform/sdk-plugin-tailordb-erd CLI plugin.",subCommands:{truncate:wt,migration:fa}}),ma=D({name:`upgrade`,description:`Run codemods to upgrade your project to a newer SDK version.`,args:q.strictObject({from:W(q.string(),{description:`SDK version before the upgrade (e.g., 1.33.0)`}),"dry-run":W(q.boolean().default(!1),{alias:`d`,description:`Preview changes without modifying files`}),path:W(q.string().default(`.`),{description:`Project directory to upgrade`,completion:{type:`directory`}})}),run:async e=>{let{initTelemetry:t}=await import(`../telemetry-DXHP3VVi.mjs`);await t();let{upgrade:n}=await import(`../service-CqbQXFDp.mjs`);await n({from:e.from,dryRun:e[`dry-run`],path:U.resolve(e.path)})}}),ha=D({name:`current`,description:`Show current user.`,args:q.strictObject({profile:P.profile}),run:async e=>{let t=await h(),n=e.profile||process.env.TAILOR_PLATFORM_PROFILE,r=n?t.profiles[n]:void 0;if(n&&!r)throw Error(`Profile "${n}" not found`);let i=r?B(r):void 0,a=n?r?.user??null:t.current_user,o=c.jsonMode;if(!a)throw Error(H`
|
|
98
98
|
Current user not set.
|
|
99
99
|
Please login first using 'tailor login' command to register a user.
|
|
100
100
|
`);if(!p(t,a,i))throw Error(H`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./schema-DMlLMsWA.mjs";import{t}from"./wait-point-registry-B-ESkTZX.mjs";import{$ as n,At as r,B as i,C as a,Ct as o,D as s,Dt as c,Et as l,G as u,Gt as d,I as f,It as p,Jt as m,K as h,L as g,Lt as _,M as v,Mt as y,N as b,Nt as x,O as S,Ot as C,P as w,Pt as ee,Q as te,R as ne,Rt as re,S as ie,Tt as ae,U as oe,Ut as se,V as ce,W as le,Wt as ue,X as de,Xt as fe,Y as pe,Yt as me,_ as he,_t as ge,a as _e,at as ve,b as ye,bt as be,ct as xe,d as Se,dt as Ce,en as we,et as T,f as Te,ft as Ee,g as De,gt as Oe,h as E,ht as ke,i as Ae,it as je,j as Me,jt as Ne,k as Pe,kt as Fe,l as D,lt as Ie,mt as Le,nn as Re,nt as ze,o as Be,ot as Ve,p as He,pt as Ue,qt as We,r as Ge,rn as Ke,rt as qe,s as Je,st as Ye,t as Xe,tn as Ze,tt as O,u as Qe,ut as $e,v as et,vt as tt,w as nt,wt as rt,x as it,xt as at,y as k,yt as ot,zt as st}from"./workspace_resource_pb-u9bj6p3i.mjs";import{t as A}from"./assert-WeXvmG4j.mjs";import{a as ct,i as j,n as M,o as lt,r as N,s as ut,t as dt}from"./logger-CCjs1DuH.mjs";import{$ as P,C as ft,D as pt,E as mt,F as ht,G as gt,H as _t,I as vt,J as yt,L as bt,N as xt,O as St,P as Ct,Q as wt,R as Tt,S as Et,T as Dt,U as F,V as Ot,W as kt,X as I,Y as At,Z as jt,_ as Mt,a as Nt,at as Pt,b as Ft,c as It,et as Lt,g as Rt,i as zt,it as Bt,k as Vt,l as Ht,m as Ut,n as Wt,nt as Gt,ot as Kt,q as qt,r as Jt,rt as Yt,s as Xt,st as Zt,t as Qt,tt as $t,u as en,w as tn,x as nn,y as rn,z as an}from"./application-CfevPO-k.mjs";import{_ as on,d as sn,g as cn,l as ln,t as un,v as dn,x as fn,y as pn}from"./service-7SCy2bhm.mjs";import{t as L}from"./multiline-EyzjEwn9.mjs";import{t as mn}from"./package-json-C690ceex.mjs";import{t as hn}from"./user-agent-vdHYF3QL.mjs";import{a as gn,i as _n,n as vn,o as yn,t as R}from"./errors-BlX4gUw5.mjs";import{n as bn,r as xn}from"./secret-file-C9wp_FCX.mjs";import{r as z}from"./telemetry-Bklv9kQY.mjs";import{n as Sn,t as Cn}from"./field-column-type-QMtF6lUp.mjs";import{a as wn,i as Tn,o as En,r as Dn,s as On,t as kn}from"./seed-CCc9Xk66.mjs";import*as An from"node:module";import*as B from"pathe";import{basename as jn,dirname as Mn,join as Nn,resolve as Pn}from"pathe";import{resolveTSConfig as Fn}from"pkg-types";import{arg as V,createDefineCommand as In,defineCommand as Ln,runCommand as Rn}from"politty";import{z as H}from"zod";import{create as U,createRegistry as zn,fromJson as Bn,toJson as Vn}from"@bufbuild/protobuf";import*as W from"node:fs";import{mkdirSync as Hn,readFileSync as Un,renameSync as Wn,rmSync as Gn,statSync as Kn,utimesSync as qn,writeFileSync as Jn}from"node:fs";import{parseEnv as Yn}from"node:util";import{ValueSchema as Xn,timestampDate as G}from"@bufbuild/protobuf/wkt";import{formatDistanceToNowStrict as Zn}from"date-fns";import{pathToFileURL as Qn}from"node:url";import{parseYAML as $n,stringifyYAML as er}from"confbox";import{findUpSync as tr}from"find-up-simple";import{lt as nr}from"semver";import{xdgConfig as rr}from"xdg-basedir";import{Code as K,ConnectError as q}from"@connectrpc/connect";import ir from"p-limit";import*as ar from"node:crypto";import{createHash as or,randomUUID as sr}from"node:crypto";import{ExitPromptError as cr}from"@inquirer/core";import{confirm as lr,input as ur,password as dr,select as fr}from"@inquirer/prompts";import{isCI as pr}from"std-env";import*as mr from"rolldown";import{parseSync as hr}from"oxc-parser";import*as gr from"inflection";import{tmpdir as _r}from"node:os";import{pathToString as vr,usedTypes as yr}from"@bufbuild/protobuf/reflect";import{createValidator as br}from"@bufbuild/protovalidate";import*as J from"node:fs/promises";import{mkdir as xr,readFile as Sr,rename as Cr,rm as wr,writeFile as Tr}from"node:fs/promises";import{setTimeout as Er}from"timers/promises";import{setTimeout as Dr}from"node:timers/promises";import{spawn as Or}from"node:child_process";import*as kr from"fs";import{lookup as Ar}from"mime-types";import{createPrompt as jr}from"@toiroakr/read-multiline";import{astVisitor as Mr,parse as Nr}from"pgsql-ast-parser";import{parse as Pr}from"@0no-co/graphql.web";const Fr={ms:1,s:1e3,m:6e4},Ir=/^(\d+)(ms|s|m)$/,Lr=H.string().refine(e=>Ir.test(e),{message:`Invalid duration format. Expected format: '3s', '500ms', '1m'`}).refine(e=>{let t=e.match(Ir);if(!t)return!1;let n=t[1];return n!==void 0&&parseInt(n,10)>0},{message:`Duration must be greater than 0`});function parseDuration(e){let t=A(e.match(Ir),`invalid duration format: ${e}`),n=parseInt(A(t[1],`duration digits group missing`),10),r=A(t[2],`duration unit group missing`);return n*Fr[r]}const Rr=H.coerce.number().int().positive(),zr=H.coerce.number().int().nonnegative(),Br=H.enum([`asc`,`desc`]);function toPageDirection(e){if(e!==void 0)return e===`asc`?Ke.ASC:Ke.DESC}function hasMachineUserFlag(e){return e.slice(0,e.indexOf(`--`)===-1?e.length:e.indexOf(`--`)).some(e=>e===`-m`||e.startsWith(`-m=`)||e===`--machine-user`||e.startsWith(`--machine-user=`)||e===`--machineUser`||e.startsWith(`--machineUser=`)||e===`--machineuser`||e.startsWith(`--machineuser=`))}function resolveMachineUserInputSource(e,t=process.argv.slice(2),n={}){if(e!==void 0)return n.valueIsExplicit||hasMachineUserFlag(t)?`option`:process.env.TAILOR_PLATFORM_MACHINE_USER_NAME===e?`env`:`option`}function loadEnvFiles(e,t){let n=new Set(Object.keys(process.env)),load=(e,t)=>{for(let r of[e??[]].flat()){let e=B.resolve(process.cwd(),r);if(!W.existsSync(e)){if(t)throw Error(`Environment file not found: ${e}`);continue}let i=W.readFileSync(e,`utf-8`),a=Yn(i);for(let[e,t]of Object.entries(a))n.has(e)||(process.env[e]=t)}};load(e,!0),load(t,!1)}function createCommonArgs(e={}){return{"env-file":V(H.string().optional(),{alias:`e`,description:`Path to the environment file (error if not found)`,completion:{type:`file`,matcher:[`.env.*`,`.env`]}}),"env-file-if-exists":V(H.string().optional(),{description:`Path to the environment file (ignored if not found)`,completion:{type:`file`,matcher:[`.env.*`,`.env`]},effect:(e,{args:t})=>{loadEnvFiles(t[`env-file`],t[`env-file-if-exists`])}}),verbose:V(H.boolean().default(!1),{...e.verboseAlias===void 0?{}:{alias:e.verboseAlias},description:`Enable verbose logging`,effect:e=>{M.verbose=e}}),json:V(H.boolean().default(!1),{alias:`j`,description:`Output as JSON`,effect:e=>{M.jsonMode=e}})}}const Vr=createCommonArgs(),Y={"workspace-id":V(H.string().optional(),{alias:`w`,description:`Workspace ID`,env:`TAILOR_PLATFORM_WORKSPACE_ID`,completion:{type:`none`}}),profile:V(H.string().optional(),{alias:`p`,description:`Workspace profile`,env:`TAILOR_PLATFORM_PROFILE`,completion:{type:`none`}})},Hr=`tailor.config.ts`;function formatConfigArg(e){if(!e)return;let t=B.relative(process.cwd(),e);if(t!==`tailor.config.ts`)return`--config=${t}`}const Ur={config:V(H.string().default(Hr),{alias:`c`,description:`Path to Tailor config file`,env:`TAILOR_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Wr={config:V(H.string().default(Hr),{alias:`c`,description:`Path to SDK config file. Use comma-separated paths to deploy multiple apps together.`,env:`TAILOR_PLATFORM_SDK_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Gr={...Y,...Ur},Kr={yes:V(H.boolean().default(!1),{alias:`y`,description:`Skip confirmation prompts`})},qr={"organization-id":V(H.string(),{alias:`o`,description:`Organization ID`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`,completion:{type:`none`}})},paginationArgs=(e=`desc`)=>({order:V(Br.default(e),{description:`Sort order (asc or desc)`}),limit:V(zr.optional(),{alias:`l`,description:`Maximum number of items to return (0 or omit: unlimited)`})}),Jr={order:V(Br.default(`desc`),{description:`Sort order (asc or desc)`}),limit:V(zr.default(50),{alias:`l`,description:`Maximum number of items to return (0: unlimited)`})},Yr={"folder-id":V(H.string(),{alias:`f`,description:`Folder ID`,env:`TAILOR_PLATFORM_FOLDER_ID`,completion:{type:`none`}})},X=In(),Xr=H.union([H.string(),H.number(),H.boolean()]),Zr=H.union([H.string(),H.number()]),Qr=H.union([Xr,H.strictObject({value:Zr,allowSecretReason:H.string().min(1,{message:`'allowSecretReason' must state why the value is safe to keep in 'env'.`})})]),$r=H.enum(Zt),ei=H.string().refine(e=>$r.safeParse(e.trim().toUpperCase()).success,{message:`'logLevel' must be one of: ${Zt.join(`, `)}.`}),ti=H.strictObject({id:H.uuid({message:`'id' must be a UUID.`}).optional(),name:H.string().min(1,{message:`'name' must be a non-empty string.`}),env:H.record(H.string(),Qr).optional(),cors:H.array(H.string()).optional(),allowedIpAddresses:H.array(H.string()).optional(),disableIntrospection:H.boolean().optional(),inlineSourcemap:H.boolean().optional(),logLevel:ei.optional(),db:H.unknown().optional(),resolver:H.unknown().optional(),idp:H.unknown().optional(),auth:H.unknown().optional(),executor:H.unknown().optional(),workflow:H.unknown().optional(),httpAdapter:H.unknown().optional(),staticWebsites:H.unknown().optional(),aiGateways:H.unknown().optional(),secrets:H.unknown().optional()}),ni=H.looseObject({id:H.string(),description:H.string(),importPath:H.string().optional(),pluginConfig:H.unknown().optional(),tableConfigRequired:H.union([H.boolean(),fn]).optional(),onTableLoaded:fn.optional(),onNamespaceLoaded:fn.optional(),onTailorDBReady:fn.optional(),onResolverReady:fn.optional(),onExecutorReady:fn.optional()}).refine(e=>!(e.onTableLoaded||e.onNamespaceLoaded)||!!e.importPath,{message:`importPath is required when plugin has definition-time hooks (onTableLoaded/onNamespaceLoaded)`}).transform(e=>e),ri=`tailor-platform-cli`;let ii;async function getEntryClass(){if(ii!==void 0)return ii;try{let e=await import(`@napi-rs/keyring`),t=new e.Entry(ri,`__probe__`);t.setPassword(`probe`),t.deletePassword(),ii=e.Entry}catch{M.warn(`System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.`),ii=!1}return ii}async function isKeyringAvailable(){return await getEntryClass()!==!1}async function loadKeyringTokens(e){let t=await getEntryClass();if(t)try{let n=new t(ri,e).getPassword();return n===null?void 0:JSON.parse(n)}catch{return}}async function saveKeyringTokens(e,t){let n=await getEntryClass();n&&new n(ri,e).setPassword(JSON.stringify(t))}async function deleteKeyringTokens(e){let t=await getEntryClass();if(t)try{new t(ri,e).deletePassword()}catch{}}const ai=H.object({user:H.string(),workspace_id:H.string(),readonly:H.boolean().optional(),machine_user:H.string().optional(),machine_user_override:H.enum([`allow`,`deny`]).optional(),platform_url:H.url().optional(),oauth2_client_id:H.string().optional(),console_url:H.url().optional()}),oi=H.object({access_token:H.string(),refresh_token:H.string().optional(),token_expires_at:H.string()}),si=H.object({storage:H.literal(`keyring`),token_expires_at:H.string()}),ci=H.object({storage:H.literal(`file`),token_expires_at:H.string(),access_token:H.string(),refresh_token:H.string().optional()}),li=H.discriminatedUnion(`storage`,[si,ci]),ui=si.extend({email:H.string().optional()}),di=ci.extend({email:H.string().optional()}),fi=H.discriminatedUnion(`storage`,[ui,di]),pi=H.object({version:H.literal(1),users:H.partialRecord(H.string(),oi),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()}),mi=`2.0.0`,hi=H.templateLiteral([H.number().int(),`.`,H.number().int(),`.`,H.number().int()]),gi=H.object({version:H.literal(2),min_sdk_version:hi,latest_version:H.number().int().optional(),latest_min_sdk_version:hi.optional(),users:H.partialRecord(H.string(),li),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()}),_i=H.object({version:H.literal(3),min_sdk_version:hi,latest_version:H.number().int().optional(),latest_min_sdk_version:hi.optional(),users:H.partialRecord(H.string(),fi),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()});function platformConfigPath(){if(!rr)throw Error(`User home directory not found`);return B.join(rr,`tailor-platform`,`config.yaml`)}function platformConfigFromProfile(e){let t={...e?.platform_url?{platformUrl:e.platform_url}:{},...e?.oauth2_client_id?{oauth2ClientId:e.oauth2_client_id}:{},...e?.console_url?{consoleUrl:e.console_url}:{}};return Object.keys(t).length>0?t:void 0}function platformUserKey(e,t){let n=jt(t);return n===Gt(`https://api.tailor.tech`)?e:`${n}|${e}`}function userFromPlatformUserKey(e,t){let n=`${jt(t)}|`;return e.startsWith(n)?e.slice(n.length):e}function canUseLegacyUserKey(e){try{return jt()===e}catch{return!1}}function findUserByEmail(e,t,n){let r=jt(n),i=`${r}|`,a=r===Gt(Ot);return Object.entries(e).find(([e,n])=>n?.email===t?a?!e.includes(`|`):e.startsWith(i):!1)}function findUserEntry(e,t,n,r={}){let i=platformUserKey(t,n),a=e.users[i];if(a)return{userKey:i,userEntry:a};let o=findUserByEmail(e.users,t,n);if(o?.[1])return{userKey:o[0],userEntry:o[1]};let s=jt(n);if(i!==t&&(r.allowLegacyUserKey===!1||!canUseLegacyUserKey(s)))return{userKey:i,userEntry:a};let c=e.users[t];return c?{userKey:t,userEntry:c}:{userKey:i,userEntry:a}}function resolveUserTokenKey(e,t,n,r){return findUserEntry(e,t,n,r).userKey}function resolveConfigUser(e,t,n,r){let{userKey:i,userEntry:a}=findUserEntry(e,t,n,r);return a?userFromPlatformUserKey(i,n):void 0}function hasUserTokenEntry(e,t,n,r){return findUserEntry(e,t,n,r).userEntry!==void 0}function hasUserKeyForName(e,t){return e[t]!==void 0||Object.keys(e).some(e=>e.endsWith(`|${t}`))}function hasUserEmailEntry(e,t){return Object.values(e).some(e=>e?.email===t)}function hasAnyUserTokenEntry(e,t){return hasUserKeyForName(e.users,t)||hasUserEmailEntry(e.users,t)}function hasCurrentUserEntry(e,t){return hasUserKeyForName(e,t)}function migrateV1ToV2(e){let t={};for(let[n,r]of Object.entries(e.users))r&&(t[n]={access_token:r.access_token,refresh_token:r.refresh_token,token_expires_at:r.token_expires_at,storage:`file`});return{version:2,min_sdk_version:`1.29.0`,users:t,profiles:e.profiles,current_user:e.current_user}}function inferEmailFromUserId(e){return H.email().safeParse(e).success?e:void 0}function migrateV2ToV3(e){let t={};for(let[n,r]of Object.entries(e.users)){if(!r)continue;let e=inferEmailFromUserId(n);t[n]={...r,...e?{email:e}:{}}}return{version:3,min_sdk_version:mi,users:t,profiles:e.profiles,current_user:e.current_user}}function migrateV1ToV3(e){return migrateV2ToV3(migrateV1ToV2(e))}function formatUnknownError(e){return e instanceof Error?e.message:String(e)}async function trySaveTokensInKeyring(e,t){if(!await isKeyringAvailable())return!1;try{return await saveKeyringTokens(e,t),!0}catch(e){return M.warn(`System keyring failed to store credentials. Tokens will be stored in the config file. ${formatUnknownError(e)}`),!1}}async function warnIfNewerConfigAvailable(e){if(!e.latest_min_sdk_version)return;let t=(await mn()).version??`0.0.0`;nr(t,e.latest_min_sdk_version)&&M.warn(L`
|
|
1
|
+
import{t as e}from"./schema-DMlLMsWA.mjs";import{t}from"./wait-point-registry-B-ESkTZX.mjs";import{$ as n,At as r,B as i,C as a,Ct as o,D as s,Dt as c,Et as l,G as u,Gt as d,I as f,It as p,Jt as m,K as h,L as g,Lt as _,M as v,Mt as y,N as b,Nt as x,O as S,Ot as C,P as w,Pt as ee,Q as te,R as ne,Rt as re,S as ie,Tt as ae,U as oe,Ut as se,V as ce,W as le,Wt as ue,X as de,Xt as fe,Y as pe,Yt as me,_ as he,_t as ge,a as _e,at as ve,b as ye,bt as be,ct as xe,d as Se,dt as Ce,en as we,et as T,f as Te,ft as Ee,g as De,gt as Oe,h as E,ht as ke,i as Ae,it as je,j as Me,jt as Ne,k as Pe,kt as Fe,l as D,lt as Ie,mt as Le,nn as Re,nt as ze,o as Be,ot as Ve,p as He,pt as Ue,qt as We,r as Ge,rn as Ke,rt as qe,s as Je,st as Ye,t as Xe,tn as Ze,tt as O,u as Qe,ut as $e,v as et,vt as tt,w as nt,wt as rt,x as it,xt as at,y as k,yt as ot,zt as st}from"./workspace_resource_pb-C4EY-Gns.mjs";import{t as A}from"./assert-WeXvmG4j.mjs";import{a as ct,i as j,n as M,o as lt,r as N,s as ut,t as dt}from"./logger-CCjs1DuH.mjs";import{$ as P,C as ft,D as pt,E as mt,F as ht,G as gt,H as _t,I as vt,J as yt,L as bt,N as xt,O as St,P as Ct,Q as wt,R as Tt,S as Et,T as Dt,U as F,V as Ot,W as kt,X as I,Y as At,Z as jt,_ as Mt,a as Nt,at as Pt,b as Ft,c as It,et as Lt,g as Rt,i as zt,it as Bt,k as Vt,l as Ht,m as Ut,n as Wt,nt as Gt,ot as Kt,q as qt,r as Jt,rt as Yt,s as Xt,st as Zt,t as Qt,tt as $t,u as en,w as tn,x as nn,y as rn,z as an}from"./application-BAqZFMWP.mjs";import{_ as on,d as sn,g as cn,l as ln,t as un,v as dn,x as fn,y as pn}from"./service-7SCy2bhm.mjs";import{t as L}from"./multiline-EyzjEwn9.mjs";import{t as mn}from"./package-json-C690ceex.mjs";import{t as hn}from"./user-agent-vdHYF3QL.mjs";import{a as gn,i as _n,n as vn,o as yn,t as R}from"./errors-BlX4gUw5.mjs";import{n as bn,r as xn}from"./secret-file-C9wp_FCX.mjs";import{r as z}from"./telemetry-Bklv9kQY.mjs";import{n as Sn,t as Cn}from"./field-column-type-QMtF6lUp.mjs";import{a as wn,i as Tn,o as En,r as Dn,s as On,t as kn}from"./seed-CCc9Xk66.mjs";import*as An from"node:module";import*as B from"pathe";import{basename as jn,dirname as Mn,join as Nn,resolve as Pn}from"pathe";import{resolveTSConfig as Fn}from"pkg-types";import{arg as V,createDefineCommand as In,defineCommand as Ln,runCommand as Rn}from"politty";import{z as H}from"zod";import{create as U,createRegistry as zn,fromJson as Bn,toJson as Vn}from"@bufbuild/protobuf";import*as W from"node:fs";import{mkdirSync as Hn,readFileSync as Un,renameSync as Wn,rmSync as Gn,statSync as Kn,utimesSync as qn,writeFileSync as Jn}from"node:fs";import{parseEnv as Yn}from"node:util";import{ValueSchema as Xn,timestampDate as G}from"@bufbuild/protobuf/wkt";import{formatDistanceToNowStrict as Zn}from"date-fns";import{pathToFileURL as Qn}from"node:url";import{parseYAML as $n,stringifyYAML as er}from"confbox";import{findUpSync as tr}from"find-up-simple";import{lt as nr}from"semver";import{xdgConfig as rr}from"xdg-basedir";import{Code as K,ConnectError as q}from"@connectrpc/connect";import ir from"p-limit";import*as ar from"node:crypto";import{createHash as or,randomUUID as sr}from"node:crypto";import{ExitPromptError as cr}from"@inquirer/core";import{confirm as lr,input as ur,password as dr,select as fr}from"@inquirer/prompts";import{isCI as pr}from"std-env";import*as mr from"rolldown";import{parseSync as hr}from"oxc-parser";import*as gr from"inflection";import{tmpdir as _r}from"node:os";import{pathToString as vr,usedTypes as yr}from"@bufbuild/protobuf/reflect";import{createValidator as br}from"@bufbuild/protovalidate";import*as J from"node:fs/promises";import{mkdir as xr,readFile as Sr,rename as Cr,rm as wr,writeFile as Tr}from"node:fs/promises";import{setTimeout as Er}from"timers/promises";import{setTimeout as Dr}from"node:timers/promises";import{spawn as Or}from"node:child_process";import*as kr from"fs";import{lookup as Ar}from"mime-types";import{createPrompt as jr}from"@toiroakr/read-multiline";import{astVisitor as Mr,parse as Nr}from"pgsql-ast-parser";import{parse as Pr}from"@0no-co/graphql.web";const Fr={ms:1,s:1e3,m:6e4},Ir=/^(\d+)(ms|s|m)$/,Lr=H.string().refine(e=>Ir.test(e),{message:`Invalid duration format. Expected format: '3s', '500ms', '1m'`}).refine(e=>{let t=e.match(Ir);if(!t)return!1;let n=t[1];return n!==void 0&&parseInt(n,10)>0},{message:`Duration must be greater than 0`});function parseDuration(e){let t=A(e.match(Ir),`invalid duration format: ${e}`),n=parseInt(A(t[1],`duration digits group missing`),10),r=A(t[2],`duration unit group missing`);return n*Fr[r]}const Rr=H.coerce.number().int().positive(),zr=H.coerce.number().int().nonnegative(),Br=H.enum([`asc`,`desc`]);function toPageDirection(e){if(e!==void 0)return e===`asc`?Ke.ASC:Ke.DESC}function hasMachineUserFlag(e){return e.slice(0,e.indexOf(`--`)===-1?e.length:e.indexOf(`--`)).some(e=>e===`-m`||e.startsWith(`-m=`)||e===`--machine-user`||e.startsWith(`--machine-user=`)||e===`--machineUser`||e.startsWith(`--machineUser=`)||e===`--machineuser`||e.startsWith(`--machineuser=`))}function resolveMachineUserInputSource(e,t=process.argv.slice(2),n={}){if(e!==void 0)return n.valueIsExplicit||hasMachineUserFlag(t)?`option`:process.env.TAILOR_PLATFORM_MACHINE_USER_NAME===e?`env`:`option`}function loadEnvFiles(e,t){let n=new Set(Object.keys(process.env)),load=(e,t)=>{for(let r of[e??[]].flat()){let e=B.resolve(process.cwd(),r);if(!W.existsSync(e)){if(t)throw Error(`Environment file not found: ${e}`);continue}let i=W.readFileSync(e,`utf-8`),a=Yn(i);for(let[e,t]of Object.entries(a))n.has(e)||(process.env[e]=t)}};load(e,!0),load(t,!1)}function createCommonArgs(e={}){return{"env-file":V(H.string().optional(),{alias:`e`,description:`Path to the environment file (error if not found)`,completion:{type:`file`,matcher:[`.env.*`,`.env`]}}),"env-file-if-exists":V(H.string().optional(),{description:`Path to the environment file (ignored if not found)`,completion:{type:`file`,matcher:[`.env.*`,`.env`]},effect:(e,{args:t})=>{loadEnvFiles(t[`env-file`],t[`env-file-if-exists`])}}),verbose:V(H.boolean().default(!1),{...e.verboseAlias===void 0?{}:{alias:e.verboseAlias},description:`Enable verbose logging`,effect:e=>{M.verbose=e}}),json:V(H.boolean().default(!1),{alias:`j`,description:`Output as JSON`,effect:e=>{M.jsonMode=e}})}}const Vr=createCommonArgs(),Y={"workspace-id":V(H.string().optional(),{alias:`w`,description:`Workspace ID`,env:`TAILOR_PLATFORM_WORKSPACE_ID`,completion:{type:`none`}}),profile:V(H.string().optional(),{alias:`p`,description:`Workspace profile`,env:`TAILOR_PLATFORM_PROFILE`,completion:{type:`none`}})},Hr=`tailor.config.ts`;function formatConfigArg(e){if(!e)return;let t=B.relative(process.cwd(),e);if(t!==`tailor.config.ts`)return`--config=${t}`}const Ur={config:V(H.string().default(Hr),{alias:`c`,description:`Path to Tailor config file`,env:`TAILOR_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Wr={config:V(H.string().default(Hr),{alias:`c`,description:`Path to SDK config file. Use comma-separated paths to deploy multiple apps together.`,env:`TAILOR_PLATFORM_SDK_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Gr={...Y,...Ur},Kr={yes:V(H.boolean().default(!1),{alias:`y`,description:`Skip confirmation prompts`})},qr={"organization-id":V(H.string(),{alias:`o`,description:`Organization ID`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`,completion:{type:`none`}})},paginationArgs=(e=`desc`)=>({order:V(Br.default(e),{description:`Sort order (asc or desc)`}),limit:V(zr.optional(),{alias:`l`,description:`Maximum number of items to return (0 or omit: unlimited)`})}),Jr={order:V(Br.default(`desc`),{description:`Sort order (asc or desc)`}),limit:V(zr.default(50),{alias:`l`,description:`Maximum number of items to return (0: unlimited)`})},Yr={"folder-id":V(H.string(),{alias:`f`,description:`Folder ID`,env:`TAILOR_PLATFORM_FOLDER_ID`,completion:{type:`none`}})},X=In(),Xr=H.union([H.string(),H.number(),H.boolean()]),Zr=H.union([H.string(),H.number()]),Qr=H.union([Xr,H.strictObject({value:Zr,allowSecretReason:H.string().min(1,{message:`'allowSecretReason' must state why the value is safe to keep in 'env'.`})})]),$r=H.enum(Zt),ei=H.string().refine(e=>$r.safeParse(e.trim().toUpperCase()).success,{message:`'logLevel' must be one of: ${Zt.join(`, `)}.`}),ti=H.strictObject({id:H.uuid({message:`'id' must be a UUID.`}).optional(),name:H.string().min(1,{message:`'name' must be a non-empty string.`}),env:H.record(H.string(),Qr).optional(),cors:H.array(H.string()).optional(),allowedIpAddresses:H.array(H.string()).optional(),disableIntrospection:H.boolean().optional(),inlineSourcemap:H.boolean().optional(),logLevel:ei.optional(),db:H.unknown().optional(),resolver:H.unknown().optional(),idp:H.unknown().optional(),auth:H.unknown().optional(),executor:H.unknown().optional(),workflow:H.unknown().optional(),httpAdapter:H.unknown().optional(),staticWebsites:H.unknown().optional(),aiGateways:H.unknown().optional(),secrets:H.unknown().optional()}),ni=H.looseObject({id:H.string(),description:H.string(),importPath:H.string().optional(),pluginConfig:H.unknown().optional(),tableConfigRequired:H.union([H.boolean(),fn]).optional(),onTableLoaded:fn.optional(),onNamespaceLoaded:fn.optional(),onTailorDBReady:fn.optional(),onResolverReady:fn.optional(),onExecutorReady:fn.optional()}).refine(e=>!(e.onTableLoaded||e.onNamespaceLoaded)||!!e.importPath,{message:`importPath is required when plugin has definition-time hooks (onTableLoaded/onNamespaceLoaded)`}).transform(e=>e),ri=`tailor-platform-cli`;let ii;async function getEntryClass(){if(ii!==void 0)return ii;try{let e=await import(`@napi-rs/keyring`),t=new e.Entry(ri,`__probe__`);t.setPassword(`probe`),t.deletePassword(),ii=e.Entry}catch{M.warn(`System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.`),ii=!1}return ii}async function isKeyringAvailable(){return await getEntryClass()!==!1}async function loadKeyringTokens(e){let t=await getEntryClass();if(t)try{let n=new t(ri,e).getPassword();return n===null?void 0:JSON.parse(n)}catch{return}}async function saveKeyringTokens(e,t){let n=await getEntryClass();n&&new n(ri,e).setPassword(JSON.stringify(t))}async function deleteKeyringTokens(e){let t=await getEntryClass();if(t)try{new t(ri,e).deletePassword()}catch{}}const ai=H.object({user:H.string(),workspace_id:H.string(),readonly:H.boolean().optional(),machine_user:H.string().optional(),machine_user_override:H.enum([`allow`,`deny`]).optional(),platform_url:H.url().optional(),oauth2_client_id:H.string().optional(),console_url:H.url().optional()}),oi=H.object({access_token:H.string(),refresh_token:H.string().optional(),token_expires_at:H.string()}),si=H.object({storage:H.literal(`keyring`),token_expires_at:H.string()}),ci=H.object({storage:H.literal(`file`),token_expires_at:H.string(),access_token:H.string(),refresh_token:H.string().optional()}),li=H.discriminatedUnion(`storage`,[si,ci]),ui=si.extend({email:H.string().optional()}),di=ci.extend({email:H.string().optional()}),fi=H.discriminatedUnion(`storage`,[ui,di]),pi=H.object({version:H.literal(1),users:H.partialRecord(H.string(),oi),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()}),mi=`2.0.0`,hi=H.templateLiteral([H.number().int(),`.`,H.number().int(),`.`,H.number().int()]),gi=H.object({version:H.literal(2),min_sdk_version:hi,latest_version:H.number().int().optional(),latest_min_sdk_version:hi.optional(),users:H.partialRecord(H.string(),li),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()}),_i=H.object({version:H.literal(3),min_sdk_version:hi,latest_version:H.number().int().optional(),latest_min_sdk_version:hi.optional(),users:H.partialRecord(H.string(),fi),profiles:H.partialRecord(H.string(),ai),current_user:H.string().nullable()});function platformConfigPath(){if(!rr)throw Error(`User home directory not found`);return B.join(rr,`tailor-platform`,`config.yaml`)}function platformConfigFromProfile(e){let t={...e?.platform_url?{platformUrl:e.platform_url}:{},...e?.oauth2_client_id?{oauth2ClientId:e.oauth2_client_id}:{},...e?.console_url?{consoleUrl:e.console_url}:{}};return Object.keys(t).length>0?t:void 0}function platformUserKey(e,t){let n=jt(t);return n===Gt(`https://api.tailor.tech`)?e:`${n}|${e}`}function userFromPlatformUserKey(e,t){let n=`${jt(t)}|`;return e.startsWith(n)?e.slice(n.length):e}function canUseLegacyUserKey(e){try{return jt()===e}catch{return!1}}function findUserByEmail(e,t,n){let r=jt(n),i=`${r}|`,a=r===Gt(Ot);return Object.entries(e).find(([e,n])=>n?.email===t?a?!e.includes(`|`):e.startsWith(i):!1)}function findUserEntry(e,t,n,r={}){let i=platformUserKey(t,n),a=e.users[i];if(a)return{userKey:i,userEntry:a};let o=findUserByEmail(e.users,t,n);if(o?.[1])return{userKey:o[0],userEntry:o[1]};let s=jt(n);if(i!==t&&(r.allowLegacyUserKey===!1||!canUseLegacyUserKey(s)))return{userKey:i,userEntry:a};let c=e.users[t];return c?{userKey:t,userEntry:c}:{userKey:i,userEntry:a}}function resolveUserTokenKey(e,t,n,r){return findUserEntry(e,t,n,r).userKey}function resolveConfigUser(e,t,n,r){let{userKey:i,userEntry:a}=findUserEntry(e,t,n,r);return a?userFromPlatformUserKey(i,n):void 0}function hasUserTokenEntry(e,t,n,r){return findUserEntry(e,t,n,r).userEntry!==void 0}function hasUserKeyForName(e,t){return e[t]!==void 0||Object.keys(e).some(e=>e.endsWith(`|${t}`))}function hasUserEmailEntry(e,t){return Object.values(e).some(e=>e?.email===t)}function hasAnyUserTokenEntry(e,t){return hasUserKeyForName(e.users,t)||hasUserEmailEntry(e.users,t)}function hasCurrentUserEntry(e,t){return hasUserKeyForName(e,t)}function migrateV1ToV2(e){let t={};for(let[n,r]of Object.entries(e.users))r&&(t[n]={access_token:r.access_token,refresh_token:r.refresh_token,token_expires_at:r.token_expires_at,storage:`file`});return{version:2,min_sdk_version:`1.29.0`,users:t,profiles:e.profiles,current_user:e.current_user}}function inferEmailFromUserId(e){return H.email().safeParse(e).success?e:void 0}function migrateV2ToV3(e){let t={};for(let[n,r]of Object.entries(e.users)){if(!r)continue;let e=inferEmailFromUserId(n);t[n]={...r,...e?{email:e}:{}}}return{version:3,min_sdk_version:mi,users:t,profiles:e.profiles,current_user:e.current_user}}function migrateV1ToV3(e){return migrateV2ToV3(migrateV1ToV2(e))}function formatUnknownError(e){return e instanceof Error?e.message:String(e)}async function trySaveTokensInKeyring(e,t){if(!await isKeyringAvailable())return!1;try{return await saveKeyringTokens(e,t),!0}catch(e){return M.warn(`System keyring failed to store credentials. Tokens will be stored in the config file. ${formatUnknownError(e)}`),!1}}async function warnIfNewerConfigAvailable(e){if(!e.latest_min_sdk_version)return;let t=(await mn()).version??`0.0.0`;nr(t,e.latest_min_sdk_version)&&M.warn(L`
|
|
2
2
|
A newer config version (${String(e.latest_version)}) is available.
|
|
3
3
|
Please update your SDK to >= ${e.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
|
|
4
4
|
`)}async function readPlatformConfig(){let e=platformConfigPath();if(!W.existsSync(e)){let e={version:3,min_sdk_version:mi,users:{},profiles:{},current_user:null};return writePlatformConfig(e),e}let t=$n(W.readFileSync(e,`utf-8`));bn(e);let n=typeof t==`object`&&t&&`version`in t?t.version:void 0;if(typeof n==`number`&&n>3){let e=`min_sdk_version`in t?String(t.min_sdk_version):void 0,r=e?`Please update your SDK to >= ${e}: pnpm update @tailor-platform/sdk`:`Please update your SDK: pnpm update @tailor-platform/sdk`;throw Error(L`
|
|
@@ -455,7 +455,7 @@ ${n===`throw`?` if (records.length > 1) {
|
|
|
455
455
|
}
|
|
456
456
|
lastId = rows[rows.length - 1]!.id;
|
|
457
457
|
}
|
|
458
|
-
}`}function markMigrationScriptSkipped(e){let{migrationsDir:t,migrationNumber:n,reason:r}=e,i=formatMigrationNumber(n),a=r.trim();if(!a)throw Error(`Migration script skip reason must not be empty.`);let o=getMigrationFilePath(t,n,`diff`);if(!W.existsSync(o))throw Error(`Migration ${i} not found in ${t}. Expected ${o}.`);let s=loadDiff(o);if(!s.requiresMigrationScript&&!s.hasWarnings)throw Error(`Migration ${i} does not require a migration script and has no data-loss warnings; nothing to skip.`);if(s.scriptSkipped)throw Error(`Migration ${i} already has a script skip recorded (${s.scriptSkipped.acknowledgedAt}: ${s.scriptSkipped.reason}).`);let c=getMigrationFilePath(t,n,`migrate`);if(W.existsSync(c))throw Error(`Migration script exists at ${c}. Delete migrate.ts first if this migration should run without a script.`);let l={reason:a,acknowledgedAt:new Date().toISOString()},u=JSON.parse(W.readFileSync(o,`utf-8`));return u.scriptSkipped=l,W.writeFileSync(o,JSON.stringify(u,null,2)),l}function clearMigrationScriptSkipped(e){let t=JSON.parse(W.readFileSync(e,`utf-8`));Object.hasOwn(t,`scriptSkipped`)&&(delete t.scriptSkipped,W.writeFileSync(e,JSON.stringify(t,null,2)))}async function addMigrationScriptFiles(e){let{migrationsDir:t,migrationNumber:n,withTest:r=!1}=e,i=formatMigrationNumber(n),a=getMigrationFilePath(t,n,`diff`);if(!W.existsSync(a))throw Error(`Migration ${i} not found in ${t}. Expected ${a}.`);let o=loadDiff(a),s=getMigrationFilePath(t,n,`migrate`),c=W.existsSync(s),l={};if(c&&o.scriptSkipped){if(clearMigrationScriptSkipped(a),l.clearedScriptSkip=!0,!r)return l}else if(c&&!r)throw Error(`Migration script already exists at ${s}.`);let u=getMigrationFilePath(t,n,`test`);if(r&&W.existsSync(u))throw Error(`Migration test already exists at ${u}.`);if(c&&r){let e=getMigrationFilePath(t,n,`db`);if(!W.existsSync(e))throw Error(`Generated types not found at ${e}. The test scaffold imports Database from ./db; restore db.ts before adding a test.`)}if(!c){let e=reconstructSnapshotFromMigrations(t,n-1);if(!e)throw Error(`Could not reconstruct previous schema for migration ${i}. Make sure migration 0 exists.`);await J.writeFile(s,generateMigrationScript(o)),l.migratePath=s,l.dbTypesPath=await writeDbTypesFile(e,t,n,o),clearMigrationScriptSkipped(a)}return r&&(await J.writeFile(u,generateMigrationTestScript(o)),l.testPath=u),l}async function script(e){logBetaWarning(`tailordb migration`);let t=parseMigrationNumberArg(e.number);if(t===0)throw Error(`Migration ${e.number} is the initial schema snapshot and cannot have a migration script.`);let{config:n}=await loadConfig(e.configPath),r=getNamespacesWithMigrations(n,B.dirname(n.path));if(r.length===0)throw Error(`No TailorDB services with migrations configuration found`);let i=resolveTargetNamespace(r,e.namespace),{migrationsDir:a}=A(r.find(e=>e.namespace===i),`namespace with migrations not found`);if(e.noScript){if(e.withTest)throw Error(`--with-test cannot be used together with --no-script.`);let n=e.reason?.trim();if(!n)throw Error(`--reason is required with --no-script.`);let r=markMigrationScriptSkipped({migrationsDir:a,migrationNumber:t,reason:n});M.success(`Recorded that migration ${N.bold(e.number)} in namespace ${N.bold(i)} intentionally has no migration script`),M.info(` Reason: ${r.reason}`),M.info(` Diff file: ${getMigrationFilePath(a,t,`diff`)}`);return}if(e.reason!==void 0)throw Error(`--reason can only be used together with --no-script.`);let o=await addMigrationScriptFiles({migrationsDir:a,migrationNumber:t,withTest:e.withTest});if(o.clearedScriptSkip&&(M.success(`Cleared the stale script skip record for migration ${N.bold(e.number)} in namespace ${N.bold(i)}`),!o.testPath)){M.info(` Migration script: ${getMigrationFilePath(a,t,`migrate`)}`);return}let s=[o.migratePath&&`migration script`,o.testPath&&`migration test`].filter(Boolean).join(` and `);M.success(`Added ${s} for migration ${N.bold(e.number)} in namespace ${N.bold(i)}`),o.migratePath&&(M.info(` Migration script: ${o.migratePath}`),M.info(` DB types: ${o.dbTypesPath}`)),o.testPath&&M.info(` Migration test: ${o.testPath}`),M.newline(),o.migratePath&&(M.log(`Edit the script to implement your data migration logic.`),M.log(`It will be executed by 'tailor deploy' between Pre and Post phases.`)),o.testPath&&M.log(`Fill in the test with the rows to stage and the statements to assert.`);let c=o.migratePath??o.testPath;if(!c)return;let l=getConfiguredEditorCommand();if(l){M.newline(),M.info(`Opening ${B.basename(c)} in ${l}...`);try{await openInConfiguredEditor(c)}catch{return}}}function resolveTargetNamespace(e,t){if(t){if(!e.some(e=>e.namespace===t))throw Error(`Namespace "${t}" not found or does not have migrations configured`);return t}if(e.length===1){let[t]=e;return A(t,`namespace with migrations missing`).namespace}throw Error(`Multiple TailorDB services found. Please specify namespace with --namespace flag: ${e.map(e=>e.namespace).join(`, `)}`)}const Ls=X({name:`script`,description:`Add a migration script (migrate.ts) template to an existing migration directory, or record with --no-script that a migration intentionally has none.`,notes:"When `migrate.ts` already exists, running the command clears a previously recorded `--no-script` acknowledgment.",args:H.strictObject({...Ur,number:V(H.string(),{positional:!0,description:`Migration number to add a script to (e.g., 0001 or 1)`}),namespace:V(H.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`}),"no-script":V(H.boolean().optional(),{description:`Record that this migration intentionally runs without a migration script (requires --reason)`}),reason:V(H.string().optional(),{description:`Reason why no migration script is needed (used with --no-script)`}),"with-test":V(H.boolean().optional(),{description:`Also add a migrate.test.ts unit-test scaffold; when migrate.ts already exists, only the test is added`})}),run:async e=>{await script({configPath:e.config,number:e.number,namespace:e.namespace,noScript:e[`no-script`],reason:e.reason,withTest:e[`with-test`]})}});function getUnsupportedMigrationHintLines(){return[`These changes require a manual 3-step migration process:`,` Migration 1: Add an optional temporary field with the desired structure`,` If the old field is required, make the old field optional`,` For each non-null old value, copy and convert it to the temporary field`,` and set the old field to null in the same update`,` Verify every old value is null before continuing`,` Migration 2: Remove the old field`,` Migration 3: Add the field with the original name and new structure,`,` migrate data from the temporary field, then remove it`,` Important: Reusing the name while stored old values remain can make subsequent reads fail`]}async function handleInitOption(e,t){let n=e.filter(({migrationsDir:e})=>W.existsSync(e));if(n.length===0){M.info(`No existing migration directories found.`);return}M.newline(),M.warn(`This will DELETE all existing migration files:`);for(let{namespace:e,migrationsDir:t}of n)M.log(` - ${e}: ${t}`);M.newline(),t||(await Z.confirm({message:`Are you sure you want to delete these directories and start fresh?`,default:!1})||(M.info(`Operation cancelled.`),process.exit(0)),M.newline());for(let{namespace:e,migrationsDir:t}of n)try{await J.rm(t,{recursive:!0,force:!0}),M.success(`Deleted migration directory for ${N.bold(e)}`)}catch(e){throw M.error(`Failed to delete ${t}: ${e}`),e}M.newline(),M.info(`Migration directories cleared. Generating initial snapshot...`),M.newline()}async function generate(e){logBetaWarning(`tailordb migration`);let{config:t,plugins:n}=await loadConfig(e.configPath),r=getNamespacesWithMigrations(t,B.dirname(t.path));if(r.length===0){M.warn(`No TailorDB namespaces with migrations config found.`),M.info(`Add "migration: { directory: \\"./migrations\\" }" to your db config to enable migrations.`);return}let i=[],a=[];for(let t of e.renames??[])t.includes(`.`)?i.push({raw:t,spec:parseRenameOption(t)}):a.push({raw:t,spec:parseTypeRenameOption(t)});let o=[],s=[];for(let t of e.drops??[])t.includes(`.`)?o.push({raw:t,spec:parseDropOption(t)}):s.push({raw:t,spec:parseTypeDropOption(t)});let c=(e.expandContracts??[]).map(e=>({raw:e,spec:parseExpandContractOption(e)}));if(e.init&&(i.length>0||a.length>0||o.length>0||s.length>0||c.length>0))throw Error(`--rename, --drop, and --expand-contract cannot be used together with --init.`);let l=new Set(o.map(({spec:e})=>`${e.tableName}.${e.fieldName}`)),u=i.filter(({spec:e})=>l.has(`${e.tableName}.${e.previousFieldName}`));if(u.length>0)throw Error(`--rename and --drop conflict for: ${u.map(({spec:e})=>`${e.tableName}.${e.previousFieldName}`).join(`, `)}`);let d=new Set(s.map(({spec:e})=>e.tableName)),f=a.filter(({spec:e})=>d.has(e.previousTableName));if(f.length>0)throw Error(`--rename and --drop conflict for: ${f.map(({spec:e})=>e.previousTableName).join(`, `)}`);if(e.namespace!==void 0&&!e.dataOnly)throw Error(`--namespace can only be used together with --data-only.`);if(e.dataOnly&&(e.init||i.length>0||a.length>0||o.length>0||s.length>0||c.length>0))throw Error(`--init, --rename, --drop, and --expand-contract cannot be used together with --data-only.`);let p=e.dataOnly?resolveTargetNamespace(r,e.namespace):void 0,m=p===void 0?r:r.filter(({namespace:e})=>e===p);e.init&&await handleInitOption(r,e.yes);let h;n.length>0&&(h=new PluginManager(n));let{defineApplication:g}=await import(`./application-BWOMdL3D.mjs`),_=g({config:t,pluginManager:h}),v=[];for(let{namespace:e,migrationsDir:t}of m){M.info(`Processing namespace: ${N.bold(e)}`),assertValidMigrationFiles(t,e);let n=_.tailorDBServices.find(t=>t.namespace===e);if(!n){M.warn(`No TailorDB service found for namespace "${e}"`);continue}await n.loadTypes(),await n.processNamespacePlugins();let r=n.types;v.push({namespace:e,migrationsDir:t,currentSnapshot:createSnapshotFromLocalTypes(r,e),previousSnapshot:reconstructSnapshotFromMigrations(t)})}if(p!==void 0){await generateDataOnlyMigration(v,p,e);return}let y=matchFlagsToNamespaces(i,v,renameSpecApplies,`--rename does not match a removed + added field pair`),b=matchFlagsToNamespaces(a,v,typeRenameSpecApplies,`--rename does not match a removed + added table pair`),x=matchFlagsToNamespaces(o,v,dropSpecApplies,`--drop does not match a removed field`),S=matchFlagsToNamespaces(s,v,typeDropSpecApplies,`--drop does not match a removed table`),C=new Map,w=new Set,ee=[];for(let{namespace:e,previousSnapshot:t,currentSnapshot:n}of v){if(!t)continue;let r=[];for(let i of c){let{spec:a}=i,o=t.tables[a.tableName]?.fields[a.fieldName],s=n.tables[a.tableName]?.fields[a.fieldName];if(!o||!s||o.type===s.type)continue;w.add(i);let c=getExpandContractEligibility({previous:t,current:n,tableName:a.tableName,fieldName:a.fieldName});if(!c.eligible){ee.push(`--expand-contract cannot convert ${i.raw} (namespace: ${e}): ${c.reason}`);continue}r.push(i)}C.set(e,new Set(r.map(({spec:e})=>fieldKey(e.tableName,e.fieldName))))}let te=c.filter(e=>!w.has(e));if(te.length>0)throw Error(`--expand-contract does not match a field whose type changed: ${te.map(e=>e.raw).join(`, `)}`);if(ee.length>0)throw Error(ee.join(`
|
|
458
|
+
}`}function markMigrationScriptSkipped(e){let{migrationsDir:t,migrationNumber:n,reason:r}=e,i=formatMigrationNumber(n),a=r.trim();if(!a)throw Error(`Migration script skip reason must not be empty.`);let o=getMigrationFilePath(t,n,`diff`);if(!W.existsSync(o))throw Error(`Migration ${i} not found in ${t}. Expected ${o}.`);let s=loadDiff(o);if(!s.requiresMigrationScript&&!s.hasWarnings)throw Error(`Migration ${i} does not require a migration script and has no data-loss warnings; nothing to skip.`);if(s.scriptSkipped)throw Error(`Migration ${i} already has a script skip recorded (${s.scriptSkipped.acknowledgedAt}: ${s.scriptSkipped.reason}).`);let c=getMigrationFilePath(t,n,`migrate`);if(W.existsSync(c))throw Error(`Migration script exists at ${c}. Delete migrate.ts first if this migration should run without a script.`);let l={reason:a,acknowledgedAt:new Date().toISOString()},u=JSON.parse(W.readFileSync(o,`utf-8`));return u.scriptSkipped=l,W.writeFileSync(o,JSON.stringify(u,null,2)),l}function clearMigrationScriptSkipped(e){let t=JSON.parse(W.readFileSync(e,`utf-8`));Object.hasOwn(t,`scriptSkipped`)&&(delete t.scriptSkipped,W.writeFileSync(e,JSON.stringify(t,null,2)))}async function addMigrationScriptFiles(e){let{migrationsDir:t,migrationNumber:n,withTest:r=!1}=e,i=formatMigrationNumber(n),a=getMigrationFilePath(t,n,`diff`);if(!W.existsSync(a))throw Error(`Migration ${i} not found in ${t}. Expected ${a}.`);let o=loadDiff(a),s=getMigrationFilePath(t,n,`migrate`),c=W.existsSync(s),l={};if(c&&o.scriptSkipped){if(clearMigrationScriptSkipped(a),l.clearedScriptSkip=!0,!r)return l}else if(c&&!r)throw Error(`Migration script already exists at ${s}.`);let u=getMigrationFilePath(t,n,`test`);if(r&&W.existsSync(u))throw Error(`Migration test already exists at ${u}.`);if(c&&r){let e=getMigrationFilePath(t,n,`db`);if(!W.existsSync(e))throw Error(`Generated types not found at ${e}. The test scaffold imports Database from ./db; restore db.ts before adding a test.`)}if(!c){let e=reconstructSnapshotFromMigrations(t,n-1);if(!e)throw Error(`Could not reconstruct previous schema for migration ${i}. Make sure migration 0 exists.`);await J.writeFile(s,generateMigrationScript(o)),l.migratePath=s,l.dbTypesPath=await writeDbTypesFile(e,t,n,o),clearMigrationScriptSkipped(a)}return r&&(await J.writeFile(u,generateMigrationTestScript(o)),l.testPath=u),l}async function script(e){logBetaWarning(`tailordb migration`);let t=parseMigrationNumberArg(e.number);if(t===0)throw Error(`Migration ${e.number} is the initial schema snapshot and cannot have a migration script.`);let{config:n}=await loadConfig(e.configPath),r=getNamespacesWithMigrations(n,B.dirname(n.path));if(r.length===0)throw Error(`No TailorDB services with migrations configuration found`);let i=resolveTargetNamespace(r,e.namespace),{migrationsDir:a}=A(r.find(e=>e.namespace===i),`namespace with migrations not found`);if(e.noScript){if(e.withTest)throw Error(`--with-test cannot be used together with --no-script.`);let n=e.reason?.trim();if(!n)throw Error(`--reason is required with --no-script.`);let r=markMigrationScriptSkipped({migrationsDir:a,migrationNumber:t,reason:n});M.success(`Recorded that migration ${N.bold(e.number)} in namespace ${N.bold(i)} intentionally has no migration script`),M.info(` Reason: ${r.reason}`),M.info(` Diff file: ${getMigrationFilePath(a,t,`diff`)}`);return}if(e.reason!==void 0)throw Error(`--reason can only be used together with --no-script.`);let o=await addMigrationScriptFiles({migrationsDir:a,migrationNumber:t,withTest:e.withTest});if(o.clearedScriptSkip&&(M.success(`Cleared the stale script skip record for migration ${N.bold(e.number)} in namespace ${N.bold(i)}`),!o.testPath)){M.info(` Migration script: ${getMigrationFilePath(a,t,`migrate`)}`);return}let s=[o.migratePath&&`migration script`,o.testPath&&`migration test`].filter(Boolean).join(` and `);M.success(`Added ${s} for migration ${N.bold(e.number)} in namespace ${N.bold(i)}`),o.migratePath&&(M.info(` Migration script: ${o.migratePath}`),M.info(` DB types: ${o.dbTypesPath}`)),o.testPath&&M.info(` Migration test: ${o.testPath}`),M.newline(),o.migratePath&&(M.log(`Edit the script to implement your data migration logic.`),M.log(`It will be executed by 'tailor deploy' between Pre and Post phases.`)),o.testPath&&M.log(`Fill in the test with the rows to stage and the statements to assert.`);let c=o.migratePath??o.testPath;if(!c)return;let l=getConfiguredEditorCommand();if(l){M.newline(),M.info(`Opening ${B.basename(c)} in ${l}...`);try{await openInConfiguredEditor(c)}catch{return}}}function resolveTargetNamespace(e,t){if(t){if(!e.some(e=>e.namespace===t))throw Error(`Namespace "${t}" not found or does not have migrations configured`);return t}if(e.length===1){let[t]=e;return A(t,`namespace with migrations missing`).namespace}throw Error(`Multiple TailorDB services found. Please specify namespace with --namespace flag: ${e.map(e=>e.namespace).join(`, `)}`)}const Ls=X({name:`script`,description:`Add a migration script (migrate.ts) template to an existing migration directory, or record with --no-script that a migration intentionally has none.`,notes:"When `migrate.ts` already exists, running the command clears a previously recorded `--no-script` acknowledgment.",args:H.strictObject({...Ur,number:V(H.string(),{positional:!0,description:`Migration number to add a script to (e.g., 0001 or 1)`}),namespace:V(H.string().optional(),{alias:`n`,description:`Target TailorDB namespace (required if multiple namespaces exist)`}),"no-script":V(H.boolean().optional(),{description:`Record that this migration intentionally runs without a migration script (requires --reason)`}),reason:V(H.string().optional(),{description:`Reason why no migration script is needed (used with --no-script)`}),"with-test":V(H.boolean().optional(),{description:`Also add a migrate.test.ts unit-test scaffold; when migrate.ts already exists, only the test is added`})}),run:async e=>{await script({configPath:e.config,number:e.number,namespace:e.namespace,noScript:e[`no-script`],reason:e.reason,withTest:e[`with-test`]})}});function getUnsupportedMigrationHintLines(){return[`These changes require a manual 3-step migration process:`,` Migration 1: Add an optional temporary field with the desired structure`,` If the old field is required, make the old field optional`,` For each non-null old value, copy and convert it to the temporary field`,` and set the old field to null in the same update`,` Verify every old value is null before continuing`,` Migration 2: Remove the old field`,` Migration 3: Add the field with the original name and new structure,`,` migrate data from the temporary field, then remove it`,` Important: Reusing the name while stored old values remain can make subsequent reads fail`]}async function handleInitOption(e,t){let n=e.filter(({migrationsDir:e})=>W.existsSync(e));if(n.length===0){M.info(`No existing migration directories found.`);return}M.newline(),M.warn(`This will DELETE all existing migration files:`);for(let{namespace:e,migrationsDir:t}of n)M.log(` - ${e}: ${t}`);M.newline(),t||(await Z.confirm({message:`Are you sure you want to delete these directories and start fresh?`,default:!1})||(M.info(`Operation cancelled.`),process.exit(0)),M.newline());for(let{namespace:e,migrationsDir:t}of n)try{await J.rm(t,{recursive:!0,force:!0}),M.success(`Deleted migration directory for ${N.bold(e)}`)}catch(e){throw M.error(`Failed to delete ${t}: ${e}`),e}M.newline(),M.info(`Migration directories cleared. Generating initial snapshot...`),M.newline()}async function generate(e){logBetaWarning(`tailordb migration`);let{config:t,plugins:n}=await loadConfig(e.configPath),r=getNamespacesWithMigrations(t,B.dirname(t.path));if(r.length===0){M.warn(`No TailorDB namespaces with migrations config found.`),M.info(`Add "migration: { directory: \\"./migrations\\" }" to your db config to enable migrations.`);return}let i=[],a=[];for(let t of e.renames??[])t.includes(`.`)?i.push({raw:t,spec:parseRenameOption(t)}):a.push({raw:t,spec:parseTypeRenameOption(t)});let o=[],s=[];for(let t of e.drops??[])t.includes(`.`)?o.push({raw:t,spec:parseDropOption(t)}):s.push({raw:t,spec:parseTypeDropOption(t)});let c=(e.expandContracts??[]).map(e=>({raw:e,spec:parseExpandContractOption(e)}));if(e.init&&(i.length>0||a.length>0||o.length>0||s.length>0||c.length>0))throw Error(`--rename, --drop, and --expand-contract cannot be used together with --init.`);let l=new Set(o.map(({spec:e})=>`${e.tableName}.${e.fieldName}`)),u=i.filter(({spec:e})=>l.has(`${e.tableName}.${e.previousFieldName}`));if(u.length>0)throw Error(`--rename and --drop conflict for: ${u.map(({spec:e})=>`${e.tableName}.${e.previousFieldName}`).join(`, `)}`);let d=new Set(s.map(({spec:e})=>e.tableName)),f=a.filter(({spec:e})=>d.has(e.previousTableName));if(f.length>0)throw Error(`--rename and --drop conflict for: ${f.map(({spec:e})=>e.previousTableName).join(`, `)}`);if(e.namespace!==void 0&&!e.dataOnly)throw Error(`--namespace can only be used together with --data-only.`);if(e.dataOnly&&(e.init||i.length>0||a.length>0||o.length>0||s.length>0||c.length>0))throw Error(`--init, --rename, --drop, and --expand-contract cannot be used together with --data-only.`);let p=e.dataOnly?resolveTargetNamespace(r,e.namespace):void 0,m=p===void 0?r:r.filter(({namespace:e})=>e===p);e.init&&await handleInitOption(r,e.yes);let h;n.length>0&&(h=new PluginManager(n));let{defineApplication:g}=await import(`./application-BKlOiD1x.mjs`),_=g({config:t,pluginManager:h}),v=[];for(let{namespace:e,migrationsDir:t}of m){M.info(`Processing namespace: ${N.bold(e)}`),assertValidMigrationFiles(t,e);let n=_.tailorDBServices.find(t=>t.namespace===e);if(!n){M.warn(`No TailorDB service found for namespace "${e}"`);continue}await n.loadTypes(),await n.processNamespacePlugins();let r=n.types;v.push({namespace:e,migrationsDir:t,currentSnapshot:createSnapshotFromLocalTypes(r,e),previousSnapshot:reconstructSnapshotFromMigrations(t)})}if(p!==void 0){await generateDataOnlyMigration(v,p,e);return}let y=matchFlagsToNamespaces(i,v,renameSpecApplies,`--rename does not match a removed + added field pair`),b=matchFlagsToNamespaces(a,v,typeRenameSpecApplies,`--rename does not match a removed + added table pair`),x=matchFlagsToNamespaces(o,v,dropSpecApplies,`--drop does not match a removed field`),S=matchFlagsToNamespaces(s,v,typeDropSpecApplies,`--drop does not match a removed table`),C=new Map,w=new Set,ee=[];for(let{namespace:e,previousSnapshot:t,currentSnapshot:n}of v){if(!t)continue;let r=[];for(let i of c){let{spec:a}=i,o=t.tables[a.tableName]?.fields[a.fieldName],s=n.tables[a.tableName]?.fields[a.fieldName];if(!o||!s||o.type===s.type)continue;w.add(i);let c=getExpandContractEligibility({previous:t,current:n,tableName:a.tableName,fieldName:a.fieldName});if(!c.eligible){ee.push(`--expand-contract cannot convert ${i.raw} (namespace: ${e}): ${c.reason}`);continue}r.push(i)}C.set(e,new Set(r.map(({spec:e})=>fieldKey(e.tableName,e.fieldName))))}let te=c.filter(e=>!w.has(e));if(te.length>0)throw Error(`--expand-contract does not match a field whose type changed: ${te.map(e=>e.raw).join(`, `)}`);if(ee.length>0)throw Error(ee.join(`
|
|
459
459
|
`));let ne=[];for(let t of v){let{namespace:n,previousSnapshot:r,currentSnapshot:i}=t;if(!r)continue;let a=compareSnapshots(r,i);if(!hasChanges(a)){t.diff=a;continue}let o=await resolveRenames(r,i,a,e,{fieldRenames:y.get(n)??[],typeRenames:b.get(n)??[],fieldDrops:x.get(n)??[],typeDrops:S.get(n)??[]});t.diff=o.diff,ne.push(...o.unresolved),t.expandPlans=await resolveExpandContractPlans({previousSnapshot:r,currentSnapshot:i,diff:o.diff,options:e,confirmedKeys:C.get(n)??new Set})}if(ne.length>0){let e=ne.map(({namespace:e,label:t,targets:n})=>` - ${t} → ${n.join(`, `)}? (namespace: ${e})`).join(`
|
|
460
460
|
`);throw Error(`Possible rename(s) detected:\n${e}\nRe-run with --rename "Table.oldField:newField" (field) or --rename "OldTable:NewTable" (table) to record a rename and scaffold a data copy script, or --drop "Table.field" / --drop "Table" to confirm the removal.`)}for(let{migrationsDir:t,currentSnapshot:n,previousSnapshot:r,diff:i,expandPlans:a}of v)r?await generateDiffFromSnapshot(r,A(i,`Migration diff was not resolved during preflight`),t,e,n,a??[]):await generateInitialSnapshot(n,t)}async function generateDataOnlyMigration(e,t,n){let r=e.find(e=>e.namespace===t);if(!r)throw Error(`No TailorDB service found for namespace "${t}"`);let{migrationsDir:i,previousSnapshot:a,currentSnapshot:o}=r;if(!a)throw Error(`Namespace "${t}" has no migration baseline. Run 'tailor tailordb migration generate' first to create the initial snapshot.`);let s=compareSnapshots(a,o);if(hasChanges(s))throw M.newline(),M.log(formatMigrationDiff(s)),M.newline(),Error(`Namespace "${t}" has schema changes that are not in migration files. Generate the schema migration first by running without --data-only.`);let c=getNextMigrationNumber(i),l=await generateDataOnlyMigrationFiles({diff:{...s,requiresMigrationScript:!0},migrationsDir:i,migrationNumber:c,snapshot:a,description:n.name});M.success(`Generated data-only migration ${N.bold(formatMigrationNumber(l.migrationNumber))}`),M.info(` Diff file: ${l.diffFilePath}`),M.info(` Migration script: ${l.migrateFilePath}`),M.info(` DB types: ${l.dbTypesFilePath}`),M.newline(),M.log(`This migration carries no schema changes.`),M.log(`Edit the script to implement the data transformation before running 'tailor deploy'.`),await openMigrationScriptInEditor(l.migrateFilePath)}async function openMigrationScriptInEditor(e){let t=getConfiguredEditorCommand();if(t){try{await J.access(e)}catch{return}M.newline(),M.info(`Opening ${B.basename(e)} in ${t}...`);try{await openInConfiguredEditor(e)}catch{return}}}async function resolveExpandContractPlans(e){let{previousSnapshot:t,currentSnapshot:n,diff:r,options:i,confirmedKeys:a}=e,o=new Set(a);if(!i.yes&&canPrompt())for(let e of r.changes){if(e.kind!==`field_type_modified`)continue;let r=fieldKey(e.tableName,e.fieldName);o.has(r)||canConvertField({previous:t,current:n,tableName:e.tableName,fieldName:e.fieldName})&&(M.newline(),M.info(`${e.tableName}.${e.fieldName} changes from ${e.before.type} to ${e.after.type}, which cannot be applied in one step.`),await Z.confirm({message:`Generate two migrations to convert ${e.tableName}.${e.fieldName} through a temporary field?`,default:!0})&&o.add(r))}return planExpandContract({previous:t,current:n,diff:r,confirmed:o}).plans}async function generateInitialSnapshot(e,t){let n=await generateSchemaFile(e,t,0);M.success(`Generated initial schema snapshot`),M.info(` File: ${n.filePath}`),M.info(` Tables: ${Object.keys(e.tables).length}`),M.log(`
|
|
461
461
|
This is the baseline schema. Future changes will be tracked as diffs.`)}function matchFlagsToNamespaces(e,t,n,r){let i=new Map,a=new Set;for(let{namespace:r,previousSnapshot:o,currentSnapshot:s}of t){if(!o)continue;let t=e.filter(({spec:e})=>n(e,o,s));for(let e of t)a.add(e);i.set(r,t.map(e=>e.spec))}let o=e.filter(e=>!a.has(e));if(o.length>0)throw Error(`${r}: ${o.map(e=>e.raw).join(`, `)}`);return i}function availableRenameTargets(e,t){return e.added.filter(n=>!t.has(`${e.tableName}.${n.fieldName}`)).map(e=>e.fieldName)}async function promptRenameCandidate(e,t){let n=`${e.tableName}.${e.removed.fieldName}`,[r]=t;return t.length===1&&r?await Z.confirm({message:`${n} was removed and ${r} was added with a compatible type. Was it renamed to ${r}?`,default:!0})?r:void 0:await Z.select({message:`${n} was removed. Was it renamed to one of these added fields?`,choices:[...t.map(e=>({name:`Yes, renamed to ${e}`,value:e})),{name:`No, ${e.removed.fieldName} was removed`,value:null}]})??void 0}function availableTypeRenameTargets(e,t){return e.added.filter(e=>!t.has(e.tableName)).map(e=>e.tableName)}async function promptTypeRenameCandidate(e,t){let n=e.removed.tableName,[r]=t;return t.length===1&&r?await Z.confirm({message:`${n} was removed and ${r} was added with a compatible schema. Was it renamed to ${r}?`,default:!0})?r:void 0:await Z.select({message:`${n} was removed. Was it renamed to one of these added tables?`,choices:[...t.map(e=>({name:`Yes, renamed to ${e}`,value:e})),{name:`No, ${n} was removed`,value:null}]})??void 0}async function resolveRenames(e,t,n,r,i){let a=[...i.fieldRenames],o=new Set(a.flatMap(e=>[`${e.tableName}.${e.previousFieldName}`,`${e.tableName}.${e.fieldName}`])),s=new Set(i.fieldDrops.map(e=>`${e.tableName}.${e.fieldName}`)),c=[...i.typeRenames],l=new Set(c.flatMap(e=>[e.previousTableName,e.tableName])),u=new Set(i.typeDrops.map(e=>e.tableName)),d=findTypeRenameCandidates(n).filter(e=>!u.has(e.removed.tableName)&&!l.has(e.removed.tableName)&&availableTypeRenameTargets(e,l).length>0),f=findRenameCandidates(n).filter(e=>!s.has(`${e.tableName}.${e.removed.fieldName}`)&&!o.has(`${e.tableName}.${e.removed.fieldName}`)&&availableRenameTargets(e,o).length>0),p=[];if(r.yes||!canPrompt()){for(let e of d)p.push({namespace:n.namespace,label:e.removed.tableName,targets:availableTypeRenameTargets(e,l)});for(let e of f)p.push({namespace:n.namespace,label:`${e.tableName}.${e.removed.fieldName}`,targets:availableRenameTargets(e,o)})}else{for(let e of d){let t=availableTypeRenameTargets(e,l);if(t.length===0)continue;let n=await promptTypeRenameCandidate(e,t);n&&(c.push({previousTableName:e.removed.tableName,tableName:n}),l.add(e.removed.tableName),l.add(n))}for(let e of f){let t=availableRenameTargets(e,o);if(t.length===0)continue;let n=await promptRenameCandidate(e,t);n&&(a.push({tableName:e.tableName,previousFieldName:e.removed.fieldName,fieldName:n}),o.add(`${e.tableName}.${e.removed.fieldName}`),o.add(`${e.tableName}.${n}`))}}return a.length===0&&c.length===0?{diff:n,unresolved:p}:{diff:compareSnapshots(e,t,{fieldRenames:a,typeRenames:c}),unresolved:p}}async function generateDiffFromSnapshot(e,t,n,r,i,a=[]){if(!hasChanges(t)){M.info(`No schema differences detected.`);return}M.newline(),M.log(formatMigrationDiff(t)),M.newline(),M.info(`Summary: ${formatDiffSummary(t)}`);let o=new Set(a.map(e=>fieldKey(e.tableName,e.fieldName))),s=t.breakingChanges.filter(e=>e.unsupported&&!(e.fieldName&&o.has(fieldKey(e.tableName,e.fieldName))));if(s.length>0){for(let e of s)M.newline(),M.error(`Unsupported change: ${e.tableName}.${e.fieldName}`),M.error(` ${e.reason}`);let t=s.filter(({tableName:t,fieldName:n})=>n!==void 0&&canConvertField({previous:e,current:i,tableName:t,fieldName:n}));if(t.length>0){M.newline(),M.info(`Convert these fields through a temporary field with:`);for(let{tableName:e,fieldName:n}of t)M.info(` --expand-contract "${e}.${n}"`)}if(s.some(e=>e.showThreeStepHint)){M.newline();for(let e of getUnsupportedMigrationHintLines())M.info(e)}let n=s.map(e=>` - ${e.tableName}.${e.fieldName}: ${e.reason}`).join(`
|
|
@@ -639,4 +639,4 @@ This is the baseline schema. Future changes will be tracked as diffs.`)}function
|
|
|
639
639
|
`}async function bundleQueryScript(e,t){let n=B.resolve(Xt(),`query`);W.mkdirSync(n,{recursive:!0});let r=B.join(n,`query_${e}.entry.ts`),i=e===`sql`?createSqlEntry():createGqlEntry();W.writeFileSync(r,i);let a=await St(t),o=xt({tsconfig:a}),s=await mr.build({plugins:[mt(r,t),pt(),Vt],input:r,write:!1,output:{format:`esm`,sourcemap:!1,minify:!1,codeSplitting:!1,globals:{tailordb:`tailordb`}},external:e===`sql`?[`tailordb`]:[],resolve:{conditionNames:[`node`,`import`]},tsconfig:a,treeshake:{moduleSideEffects:!1,annotations:!0,unknownGlobalSideEffects:!1},...o.options});return o.assertAllResolved(),s.output[0].code}function toErrorMessage(e){return e instanceof Error?e.message:String(e)}function mapQueryExecutionError(e){let t=toErrorMessage(e.error);if(t.includes(`machine user does not exist`))return R({code:`not_found`,message:`Machine user '${e.machineUser??`unknown`}' was not found.`,suggestion:"Run `tailor machineuser list` and use an existing name."});if(e.engine===`sql`&&t.includes(`sqlaccess error: failed to fetch schema: query returned an unexpected number of rows`))return R({code:`invalid_namespace`,message:`Failed to load TailorDB schema for namespace '${e.namespace}'.`,suggestion:`Ensure the query references TailorDB tables from a single namespace and re-apply if needed.`});if(e.engine===`sql`&&t.includes(`sqlaccess error: failed to parse:`)){let e=t.split(`sqlaccess error: failed to parse:`).at(1)?.split(`
|
|
640
640
|
`).at(0)?.trim();return R({code:`invalid_sql`,message:`SQL parse error.`,suggestion:e??`The SQL query contains unsupported syntax.`})}return e.error instanceof Error?e.error:Error(t)}function isGraphQLInputComplete(e){if(e.trim().length===0)return!1;try{return Pr(e),!0}catch{return!1}}function isSqlInputComplete(e){let t=!1,n=!1,r=!1,i=0,a=null,o=!1;for(let s=0;s<e.length;s+=1){let c=A(e[s],`character at index ${s} missing`),l=e[s+1];if(r){c===`
|
|
641
641
|
`&&(r=!1);continue}if(i>0){if(c===`/`&&l===`*`){i+=1,s+=1;continue}c===`*`&&l===`/`&&(--i,s+=1);continue}if(a!=null){e.startsWith(a,s)&&(s+=a.length-1,a=null);continue}if(t){if(c===`'`&&l===`'`){s+=1;continue}c===`'`&&(t=!1);continue}if(n){if(c===`"`&&l===`"`){s+=1;continue}c===`"`&&(n=!1);continue}if(c===`-`&&l===`-`){r=!0,s+=1;continue}if(c===`/`&&l===`*`){i=1,s+=1;continue}if(c===`'`){o=!1,t=!0;continue}if(c===`"`){o=!1,n=!0;continue}if(c===`$`){let t=e.slice(s),n=t.match(/^\$[A-Za-z_][A-Za-z0-9_]*\$/)??t.match(/^\$\$/);if(n!=null){o=!1,a=n[0],s+=n[0].length-1;continue}}if(c===`;`){o=!0;continue}/\s/.test(c)||(o=!1)}return o&&!t&&!n&&i===0&&a==null}function extractTableNamesFromSql(e){let t;try{t=Nr(e)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`SQL parse error: ${t}\nIf your table name is a reserved keyword (e.g. User), wrap it in double quotes: SELECT * FROM "User"`,{cause:e})}let n=new Set,r=Mr(e=>({tableRef:t=>(n.add(t.name),e.super().tableRef(t),t)}));for(let e of t)r.statement(e);return[...n]}function collectAliasMap(e){let t=new Map;for(let n of e)if(n.type===`table`){let e=n.name.name,r=n.name.alias??e;t.set(r,e)}return t}function extractColumnTemplate(e){try{let t=Nr(e);for(let e of t){if(e.type!==`select`||!e.columns)continue;let t=collectAliasMap(e.from??[]),n=[],r=!1;for(let i of e.columns)if(i.expr.type===`ref`&&i.expr.name===`*`){if(r=!0,i.expr.table){let e=t.get(i.expr.table.name);n.push({type:`wildcard`,tableNames:e?[e]:[]})}else n.push({type:`wildcard`,tableNames:[...new Set(t.values())]})}else{let e=i.alias?.name??(i.expr.type===`ref`?i.expr.name:null);e&&n.push({type:`explicit`,name:e})}return r?n:null}return null}catch{return null}}async function loadTypeFieldOrder(e,t){let n=new Map,r=e.db?.[t];if(!r||!(`files`in r)||r.files.length===0)return n;let i=B.dirname(e.path),a=cn(r,i);return await Promise.all(a.map(async e=>{try{let t=await import(Qn(e).href);for(let e of Object.values(t)){let t=sn.safeParse(ln(e));t.success&&n.set(t.data.name,Object.keys(t.data.fields))}}catch{}})),n}const cc=H.enum([`sql`,`gql`]),lc=H.object({workspaceId:H.string().optional(),profile:H.string().optional(),configPath:H.string().optional(),engine:cc,machineUser:H.string().optional(),machineUserSource:H.enum([`option`,`env`]).optional()}),uc=lc.extend({query:H.string()});async function getNamespaceFromSqlQuery(e,t,n,r){if(r.length===0)throw Error(`No namespaces found in configuration.`);if(r.length===1)return A(r[0],`namespace missing`);let i=extractTableNamesFromSql(t);if(i.length===0)throw Error(`Could not infer namespace from query. Detected namespaces: ${r.join(`, `)}.`);let a=await resolveTableNamespaces({workspaceId:e,namespaces:r,tableNames:i,client:n}),o=i.filter(e=>!a.has(e));if(o.length>0)throw Error(`Could not find namespace for tables in query: ${o.join(`, `)}.`);let s=new Set(a.values());if(s.size===1)return A([...s][0],`namespace from types missing`);throw Error(`Query references tables from multiple namespaces: ${[...s].join(`, `)}.`)}async function loadOptions(e){let t=parseOptions(lc,e),n=await loadMachineUserName({machineUser:t.machineUser,machineUserSource:t.machineUserSource,profile:t.profile});if(!n)throw Error(`Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.`);let r=await loadAccessToken({profile:t.profile}),i=await P(r),a=await loadWorkspaceId({workspaceId:t.workspaceId,profile:t.profile}),{config:o}=await loadConfig(e.configPath),s=extractAllNamespaces(o),{application:c}=await i.getApplication({workspaceId:a,applicationName:o.name});if(!c?.authNamespace)throw Error(`Application ${o.name} does not have an auth configuration.`);let{machineUser:l}=await i.getAuthMachineUser({workspaceId:a,authNamespace:c.authNamespace,name:n});if(!l)throw Error(`Machine user ${n} not found.`);return{engine:t.engine,client:i,workspaceId:a,config:o,application:c,machineUserResource:l,namespaces:s}}async function sqlQuery(e,t,n){let r=splitSqlStatements(n.query),i=await executeScript({client:e,workspaceId:n.workspaceId,name:`query-sql-${n.namespace}.js`,code:n.bundledCode,arg:{namespace:n.namespace,queries:r},invoker:t});if(!i.success)throw Error(i.error);return{engine:`sql`,namespace:n.namespace,query:n.query,result:parseExecutionResult(i.result)}}async function gqlQuery(e,t,n,r,i){let{access_token:a}=await kt(n.url,r.clientId,r.clientSecret),o=await executeScript({client:e,workspaceId:i.workspaceId,name:`query-gql.js`,code:i.bundledCode,arg:{endpoint:`${n.url}/query`,accessToken:a,query:i.query},invoker:t});if(!o.success)throw Error(o.error);return{engine:`gql`,query:i.query,result:parseExecutionResult(o.result)}}function parseExecutionResult(e){if(!e)return null;try{return JSON.parse(e)}catch{return e}}async function resolveQueryCommandInput(e){return e.query==null?e.file==null?e.edit?await resolveEditedQueryInput(e.engine):{mode:`repl`}:{mode:`query`,query:await J.readFile(e.file,`utf-8`)}:{mode:`query`,query:e.query}}async function resolveEditedQueryInput(e){if(!process.stdin.isTTY||!process.stdout.isTTY)throw Error(`Non-interactive terminals are not supported. Pass -q/--query or -f/--file to run a query.`);let t=getEditorCommand(),n=await J.mkdtemp(B.join(_r(),`tailor-query-`)),r=e===`sql`?`sql`:`graphql`,i=B.join(n,`query.${r}`);try{await J.writeFile(i,``,`utf-8`);try{await openInEditor(i,t)}catch(e){throw Error(`Failed to open query editor "${t}": ${e instanceof Error?e.message:String(e)}`,{cause:e})}let e=await J.readFile(i,`utf-8`);return e.trim().length===0||e===``?{mode:`abort`}:{mode:`query`,query:e}}finally{await J.rm(n,{recursive:!0,force:!0})}}async function query(e){let t=parseOptions(uc,e);return await(await prepareQueryExecutor(t))(t.query)}async function prepareQueryExecutor(e){let{client:t,workspaceId:n,config:r,application:i,machineUserResource:a,engine:o,namespaces:s}=await loadOptions(e),c=await bundleQueryScript(o,B.dirname(r.path)),l=U(C,{namespace:i.authNamespace,machineUserName:a.name});return async e=>{let u;try{switch(o){case`sql`:return u=await getNamespaceFromSqlQuery(n,e,t,s),reorderSqlColumns(await sqlQuery(t,l,{workspaceId:n,namespace:u,bundledCode:c,query:e}),r,u,e);case`gql`:return await gqlQuery(t,l,i,a,{workspaceId:n,bundledCode:c,query:e});default:throw Error(`Unsupported query engine: ${o}`)}}catch(e){throw mapQueryExecutionError({error:e,engine:o,namespace:u,machineUser:a.name})}}}function resolveReplCommand(e){let t=e.trim();return t.startsWith(`\\`)?t===`\\q`||t===`\\quit`?`quit`:t===`\\help`||t===`\\h`||t===`\\?`?`help`:t===`\\clear`||t===`\\c`?`clear`:`unknown`:null}function clearReplScreen(){process.stdout.write(`\x1Bc`)}function sanitizeHistoryScope(e){return e.replace(/[^a-zA-Z0-9._-]/g,`_`)}function getReplHistoryPath(e,t,n){if(!rr)return;let r=[t,n].filter(e=>!!e).map(sanitizeHistoryScope).join(`-`),i=e===`sql`?`sql`:`gql`,a=r?`-${r}`:``;return B.join(rr,`tailor-platform`,`query-history-${i}${a}.json`)}function createReplValidator(e){return t=>{let n=t.trim();if(n!==``&&resolveReplCommand(n)===null)return e===`sql`?isSqlInputComplete(t)?void 0:`SQL statement is incomplete (missing ';').`:isGraphQLInputComplete(t)?void 0:`GraphQL document is incomplete.`}}async function runRepl(e){if(!process.stdin.isTTY||!process.stdout.isTTY)throw Error(`Non-interactive terminals are not supported. Pass -q/--query or -f/--file to run a query.`);let t=await prepareQueryExecutor(e),n=getReplHistoryPath(e.engine,e.profile,e.workspaceId),r=createReplValidator(e.engine),{highlightSqlLine:i,highlightGraphqlLine:a,replTransform:o}=await import(`./repl-editor-BG1aDOfH.mjs`),s=e.engine===`sql`?i:a,c=jr({prefix:``,preferNewlineOnEnter:e.newlineOnEnter,validate:r,highlight:s,transform:o,theme:{submitRender:`preserve`},history:n?{filePath:n,maxEntries:100}:[],helpFooter:{items:[`submit`,`newline`],maxLines:1}});for(M.info(`Entering ${e.engine.toUpperCase()} REPL mode.`),M.info(`Type \\help for usage, \\q to quit.`);;){let[n,r]=await c(`${e.engine}> `);if(r?.kind===`cancel`){if(n.length===0)return;continue}if(r?.kind===`eof`)return;let i=n.trim();if(i===``)continue;let a=resolveReplCommand(i);if(a===`quit`)return;if(a===`help`){printReplHelp(e.engine);continue}if(a===`clear`){clearReplScreen();continue}if(a===`unknown`){M.warn(`Unknown command: ${i}`);continue}try{let n=await t(i);n.engine===`sql`?printSqlResult(n,{json:e.json}):printGqlResult(n,{json:e.json})}catch(e){if(_n(e)){M.log(e.format());continue}if(e instanceof Error){M.error(e.message);continue}M.error(String(e))}}}function printReplHelp(e){M.log(`REPL commands:`),M.log(` \\help, \\h, \\? Show this help`),M.log(` \\q, \\quit Exit REPL`),M.log(` \\clear, \\c Clear the screen`),M.log(``),M.log(`Key bindings (see footer for terminal-specific submit/newline keys):`),M.log(` Ctrl+J Insert newline (always available)`),M.log(` Ctrl+C Cancel current input`),M.log(` Ctrl+D Exit REPL (on empty input)`),M.log(` Ctrl+Z / Ctrl+Y Undo / Redo`),M.log(` Up/Down (first/last line) Navigate history`),M.log(``),M.log(`Editing aids:`),M.log(` Syntax highlighting Enabled for the current engine`),M.log(` ( [ { Auto-inserts the matching closing bracket`),M.log(` Enter after open bracket Adds one indent level and closes the block`),M.log(``),M.log(e===`sql`?`Input must end with ';' to submit.`:`Input must be a complete GraphQL document to submit.`)}async function querySql(e){let t=await query({...e,engine:`sql`});if(t.engine!==`sql`)throw Error(`Expected sql engine result but got: ${t.engine}`);return t}async function queryGql(e){let t=await query({...e,engine:`gql`});if(t.engine!==`gql`)throw Error(`Expected gql engine result but got: ${t.engine}`);return t}async function reorderSqlColumns(e,t,n,r){if(!isSQLExecutionResult(e.result)||e.result.rows.length===0)return e;let i=extractColumnTemplate(r);if(!i)return e;try{let r=buildExpectedColumnOrder(i,await loadTypeFieldOrder(t,n));if(r.length===0)return e;let a=e.result.rows.map(e=>reorderRowByTemplate(e,r));return{...e,result:{...e.result,rows:a}}}catch{return e}}const dc=[`id`];function buildExpectedColumnOrder(e,t){let n=[];for(let r of e)if(r.type===`explicit`)n.push(r.name);else for(let e of r.tableNames)n.push(...dc),n.push(...t.get(e)??[]);return n}function reorderRowByTemplate(e,t){let n={},r=new Set(Object.keys(e)),i=new Map;for(let e of r)i.set(e.toLowerCase(),e);for(let a of t){let t=i.get(a.toLowerCase());t!=null&&r.has(t)&&(n[t]=e[t],r.delete(t),i.delete(a.toLowerCase()))}for(let t of r)n[t]=e[t];return n}const fc=X({name:`query`,description:`Run SQL/GraphQL query.`,args:H.strictObject({...Gr,engine:V(cc,{description:`Query engine (sql or gql)`}),query:V(H.string().optional(),{alias:`q`,description:`Query string to execute directly; omit to start REPL mode`}),file:V(H.string().optional(),{alias:`f`,description:`Read query string from file; omit to start REPL mode`}),edit:V(H.boolean().default(!1),{description:`Open a temporary file in your editor; omit to start REPL mode`}),"machine-user":V(H.string().optional(),{alias:`m`,description:`Machine user name for query execution. Falls back to the active profile's default machine user.`,env:`TAILOR_PLATFORM_MACHINE_USER_NAME`}),"newline-on-enter":V(H.boolean().optional(),{description:`REPL: when true, Enter inserts a newline and Shift+Enter submits. Use --no-newline-on-enter to swap.`})}).superRefine((e,t)=>{e.query!=null&&e.file!=null&&t.addIssue({code:`custom`,path:[`file`],message:`Pass either -q/--query or -f/--file, not both.`}),e.edit&&e.query!=null&&t.addIssue({code:`custom`,path:[`edit`],message:`Pass only one of --edit, -q/--query, or -f/--file.`}),e.edit&&e.file!=null&&t.addIssue({code:`custom`,path:[`edit`],message:`Pass only one of --edit, -q/--query, or -f/--file.`})}),run:async e=>{let t=await resolveQueryCommandInput({query:e.query,file:e.file,edit:e.edit,engine:e.engine}),n={workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,engine:e.engine,machineUser:e[`machine-user`],machineUserSource:resolveMachineUserInputSource(e[`machine-user`])};if(t.mode===`abort`){M.info(`Editor closed without a query. Nothing was executed.`);return}if(t.mode===`repl`){let t=e[`newline-on-enter`]??ct(process.env.TAILOR_QUERY_NEWLINE_ON_ENTER)??!0;await runRepl({...n,json:e.json,newlineOnEnter:t});return}let r=t.query;if(e.engine===`sql`){printSqlResult(await querySql({...n,query:r}),{json:e.json});return}printGqlResult(await queryGql({...n,query:r}),{json:e.json})}});function isSQLExecutionResult(e){if(!e||typeof e!=`object`)return!1;let t=e;return Array.isArray(t.rows)&&typeof t.rowCount==`number`}function printSingleSqlResult(e,t={}){if(e.rows.length===0){if(t.json){M.out({results:[],rowCount:0});return}M.info(`No rows returned.`);return}if(t.json){M.out({results:e.rows,rowCount:e.rowCount});return}M.out(e.rows,{showNull:!0}),M.out(`rows: ${e.rowCount}`)}function splitSqlStatements(e){let t=Nr(e,{locationTracking:!0});return t.map((n,r)=>{let i=A(n._location,`SQL statement location missing`).start,a=t[r+1],o=a===void 0?e.length:A(a._location,`SQL statement location missing`).start;return e.substring(i,o)})}function isSQLExecutionResultArray(e){return Array.isArray(e)&&e.length>0&&e.every(isSQLExecutionResult)}function printSqlResult(e,t={}){if(isSQLExecutionResultArray(e.result)){if(t.json){M.out(e.result.map(e=>({results:e.rows,rowCount:e.rowCount})));return}let n=splitSqlStatements(e.query);for(let r=0;r<e.result.length;r++)r>0&&M.log(``),M.info(n[r]??`Statement ${r+1}`),printSingleSqlResult(A(e.result[r],`SQL result at index ${r} missing`),t);return}if(isSQLExecutionResult(e.result)){printSingleSqlResult(e.result,t);return}M.out({engine:e.engine,query:e.query,result:e.result})}function printGqlResult(e,t={}){if(t.json){M.out({result:e.result});return}M.out(JSON.stringify(e.result,null,2))}function errorToJson(e,t){if(_n(e))return{error:{code:e.code??`CLI_ERROR`,message:e.message,...e.details?{details:e.details}:{},...e.suggestion?{suggestion:e.suggestion}:{},...e.command?{help:executableHelpAction(e.command)}:{},...e.next?{next:e.next}:{},...e.context?{context:e.context}:{},...t?.includeStack&&e.stack?{stack:e.stack}:{}}};if(e instanceof q){let n=K[e.code];return{error:{code:`RPC_${typeof n==`string`?n.replaceAll(/([a-z0-9])([A-Z])/g,`$1_$2`).toUpperCase():`CODE_${e.code}`}`,message:e.message,...t?.includeStack&&e.stack?{stack:e.stack}:{}}}}if(e instanceof Error){let n=yn(e);return{error:{code:e.name===`CIPromptError`?`INTERACTIVE_PROMPT_REQUIRED`:`UNEXPECTED_ERROR`,message:e.message,...n?{suggestion:n}:{},...t?.includeStack&&e.stack?{stack:e.stack}:{}}}}return{error:{code:`UNKNOWN_ERROR`,message:String(e)}}}function serializeError(e,t){let n=errorToJson(e,t);try{return JSON.stringify(n)}catch{let e={...n.error};return delete e.context,delete e.stack,JSON.stringify({error:e})}}function executableHelpAction(e){return{command:`tailor`,args:[...e.split(/\s+/).filter(Boolean),`--help`]}}function isNativeTypeScriptRuntime(){return isBun()||isDeno()}function isBun(){return`Bun`in globalThis}function isDeno(){return`Deno`in globalThis}async function registerTsHook(e){if(isNativeTypeScriptRuntime())return;let{resolveSync:t,loadSync:n}=await import(e.href);An.registerHooks({resolve:t,load:n})}export{Ts as $,getNextMigrationNumber as $n,loadEnvFiles as $r,deployFromCLI as $t,truncate as A,getNamespacesWithMigrations as An,hasUserTokenEntry as Ar,getFunctionRegistry as At,logBetaWarning as B,no as Bn,readPlatformConfig as Br,listExecutorJobs as Bt,Ws as C,formatMigrationScriptCommand as Cn,loadOperatorWorkspaceContext as Cr,extractAllNamespaces as Ct,resumeWorkflow as D,protoGqlPermission as Dn,deleteUserTokens as Dr,ls as Dt,Vs as E,generateAllTypeManifestsFromSnapshot as En,loadConfig as Er,waitForExecution as Et,generate as F,formatSchemaDrifts as Fn,loadMachineUserName as Fr,es as Ft,remove as G,io as Gn,writePlatformConfig as Gr,getWorkflow as Gt,deployStaticWebsite as H,Za as Hn,resolveConfigUser as Hr,Qo as Ht,Rs as I,createSnapshotFromLocalTypes as In,loadPlatformClientConfig as Ir,listExecutors as It,updateOrganization as J,assertMigrationNumberExists as Jn,Vr as Jr,listWorkflowExecutions as Jt,As as K,ro as Kn,X as Kr,Xo as Kt,Ls as L,createSnapshotType as Ln,loadStoredUserTokens as Lr,getExecutorJob as Lt,loadSeedContext as M,captureFileState as Mn,loadAuthStatus as Mr,as as Mt,chunkSeedData as N,captureMigrationFileState as Nn,loadConfigPath as Nr,rs as Nt,Bs as O,fetchRemoteMigrationNumber as On,fetchLatestToken as Or,listFunctionRegistries as Ot,bundleSeedScript as P,createRemoteComparableSnapshot as Pn,loadConsoleBaseUrl as Pr,triggerExecutor as Pt,listOrganizations as Q,getMigrationFiles as Qn,Gr as Qr,deploy as Qt,Is as R,assertValidMigrationFiles as Rn,loadWorkspaceId as Rr,getExecutorWaitFailureMessage as Rt,getAppHealth as S,updateMigrationLabel as Sn,Z as Sr,loadTailorDBNamespaces as St,waitWorkflowExecution as T,compareSnapshotWithRemote as Tn,assertWritable as Tr,executeScript as Tt,show as U,eo as Un,resolveUserTokenKey as Ur,startWorkflow as Ut,Ps as V,$a as Vn,removeLegacyUserAlias as Vr,watchExecutorJob as Vt,Ms as W,to as Wn,saveUserTokens as Wr,Zo as Wt,Ds as X,getMigrationDirPath as Xn,Kr as Xr,Go as Xt,organizationTree as Y,getLatestMigrationNumber as Yn,Ur as Yr,functionExecutionStatusToString as Yt,Es as Z,getMigrationFilePath as Zn,createCommonArgs as Zr,getExecutor as Zt,getWorkspace as _,logMissingCheckpointGuidance as _n,resourceTrn as _r,us as _t,fc as a,Y as ai,createValidatedWorkspaceWithClient as an,handleOptionalToRequiredError as ar,ys as at,listApps as b,verifyRemoteSchema as bn,xi as br,resolvePluginConfig as bt,ac as c,formatTimestamp as cn,compareSnapshots as cr,deleteFolder as ct,listUsers as d,ensureConfigId as dn,formatMigrationNumber as dr,ps as dt,Wr as ei,deployMigrationTestBaseline as en,loadDiff as er,getOrganization as et,tc as f,PluginManager as fn,parseMigrationNumberArg as fr,listOAuth2Clients as ft,Xs as g,formatRemoteVerificationResults as gn,subscribesToEvents as gr,ds as gt,restoreWorkspace as h,fetchRemoteSchemaSnapshot as hn,hasChanges as hr,getMachineUserToken as ht,query as i,toPageDirection as ii,Bo as in,createMigrationHistoryId as ir,listFolders as it,zs as j,selectTargetNamespace as jn,loadAccessToken as jr,listWebhookExecutors as jt,listWorkflows as k,fetchRemoteMigrationState as kn,hasAnyUserTokenEntry as kr,ss as kt,removeUser as l,humanizeRelativeTime as ln,UnsupportedMigrationFileVersionError as lr,hs as lt,Qs as m,checkMigrationDiffs as mn,formatMigrationDiff as mr,getOAuth2Client as mt,errorToJson as n,paginationArgs as ni,Vo as nn,Qi as nr,updateFolder as nt,sc as o,createWorkspace$1 as on,sanitizeMigrationLabel as or,getFolder as ot,inviteUser as p,generateUserTypes as pn,formatDiffSummary as pr,fs as pt,ks as q,Qa as qn,Hr as qr,getWorkflowExecution as qt,serializeError as r,resolveMachineUserInputSource as ri,listWorkspaces as rn,Zi as rr,xs as rt,updateUser as s,formatKeyValueTable as sn,compareLocalTypesWithSnapshot as sr,_s as st,registerTsHook as t,Jr as ti,deployMigrationTestTarget as tn,loadSnapshot as tr,Cs as tt,rc as u,Lo as un,normalizeSchemaSnapshot as ur,createFolder as ut,Js as v,logRemoteDriftGuidance as vn,Si as vr,listMachineUsers as vt,Hs as w,bundleMigrationScript as wn,apiCall as wr,extractOwnedNamespaces as wt,Ks as x,getMigrationMachineUser as xn,writeMetadataLabels as xr,loadApplicationNamespaces as xt,deleteWorkspace as y,toTailorDBDeployInput as yn,bi as yr,generate$1 as yt,generateSchemaFile as z,reconstructSnapshotFromMigrations as zn,platformConfigFromProfile as zr,$o as zt};
|
|
642
|
-
//# sourceMappingURL=register-ts-hook-
|
|
642
|
+
//# sourceMappingURL=register-ts-hook-Cphn4r8s.mjs.map
|