@tailor-platform/sdk 2.11.0 → 2.12.0
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 +22 -0
- package/dist/application-BFTkaW6X.mjs +1 -0
- package/dist/{application-CcrP-v7z.mjs → application-D3HlhR3i.mjs} +2 -2
- package/dist/{application-CcrP-v7z.mjs.map → application-D3HlhR3i.mjs.map} +1 -1
- package/dist/cli/commands/generate/seed/bundler.d.mts +2 -2
- package/dist/cli/commands/tailordb/migrate/bundler.d.mts +1 -1
- package/dist/cli/commands/workspace/user/remove.d.mts +1 -1
- package/dist/cli/commands/workspace/user/update.d.mts +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/main.mjs +41 -41
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/script-executor.d.mts +2 -2
- package/dist/completion/zsh-worker.zsh +18 -2
- package/dist/kysely-type-B-BOlXH7.mjs +43 -0
- package/dist/kysely-type-B-BOlXH7.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/{register-ts-hook-YqgUg8P7.mjs → register-ts-hook-rBH346V_.mjs} +13 -13
- package/dist/register-ts-hook-rBH346V_.mjs.map +1 -0
- package/dist/seed-CMkupmX8.mjs.map +1 -1
- package/dist/service_pb-CFVlGYdr.mjs +1 -0
- package/dist/{service_pb-BNxUPfP3.mjs → service_pb-CxHztLk1.mjs} +2 -2
- package/dist/{service_pb-BNxUPfP3.mjs.map → service_pb-CxHztLk1.mjs.map} +1 -1
- package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +10 -0
- package/dist/workflow-Cs9ISw6j.mjs.map +1 -1
- package/dist/workspace_resource_pb-u9bj6p3i.mjs +2 -0
- package/dist/workspace_resource_pb-u9bj6p3i.mjs.map +1 -0
- package/docs/cli/user.md +43 -7
- package/docs/cli-reference.md +1 -0
- package/package.json +3 -3
- package/dist/application-B4tCGHiQ.mjs +0 -1
- package/dist/kysely-type-CmvAz1Xj.mjs +0 -43
- package/dist/kysely-type-CmvAz1Xj.mjs.map +0 -1
- package/dist/register-ts-hook-YqgUg8P7.mjs.map +0 -1
- package/dist/service_pb-D-xFu9Ub.mjs +0 -1
- package/dist/workspace_resource_pb-B7S-zx4Z.mjs +0 -2
- package/dist/workspace_resource_pb-B7S-zx4Z.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./schema-6d_OHyZf.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-B7S-zx4Z.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 ft,B as pt,C as mt,D as ht,E as gt,F as _t,H as P,I as vt,J as yt,K as bt,L as xt,M as St,N as Ct,O as wt,P as Tt,Q as F,R as Et,S as Dt,T as Ot,U as kt,V as At,W as jt,X as Mt,Y as I,Z as Nt,at as Pt,b as Ft,c as It,et as Lt,g as Rt,h as zt,i as Bt,it as Vt,l as Ht,n as Ut,nt as Wt,o as Gt,ot as Kt,p as qt,q as Jt,r as Yt,rt as Xt,s as Zt,t as Qt,tt as $t,v as en,w as tn,x as nn,y as rn}from"./application-CcrP-v7z.mjs";import{_ as an,d as on,g as sn,l as cn,t as ln,v as un,x as dn,y as fn}from"./service-BzsSm2f6.mjs";import{t as L}from"./multiline-EyzjEwn9.mjs";import{t as pn}from"./package-json-C690ceex.mjs";import{t as mn}from"./user-agent-vdHYF3QL.mjs";import{a as hn,i as gn,n as _n,o as vn,t as R}from"./errors-BlX4gUw5.mjs";import{n as yn,r as bn}from"./secret-file-C9wp_FCX.mjs";import{r as z}from"./telemetry-Bklv9kQY.mjs";import{n as xn,t as Sn}from"./field-column-type-QMtF6lUp.mjs";import{a as Cn,i as wn,o as Tn,r as En,s as Dn,t as On}from"./seed-CMkupmX8.mjs";import*as kn from"node:module";import*as B from"pathe";import{basename as An,dirname as jn,join as Mn,resolve as Nn}from"pathe";import{resolveTSConfig as Pn}from"pkg-types";import{arg as V,createDefineCommand as Fn,defineCommand as In,runCommand as Ln}from"politty";import{z as H}from"zod";import{create as U,createRegistry as Rn,fromJson as zn,toJson as Bn}from"@bufbuild/protobuf";import*as W from"node:fs";import{mkdirSync as Vn,readFileSync as Hn,renameSync as Un,rmSync as Wn,statSync as Gn,utimesSync as Kn,writeFileSync as qn}from"node:fs";import{parseEnv as Jn}from"node:util";import{ValueSchema as Yn,timestampDate as G}from"@bufbuild/protobuf/wkt";import{formatDistanceToNowStrict as Xn}from"date-fns";import{pathToFileURL as Zn}from"node:url";import{parseYAML as Qn,stringifyYAML as $n}from"confbox";import{findUpSync as er}from"find-up-simple";import{lt as tr}from"semver";import{xdgConfig as nr}from"xdg-basedir";import{Code as K,ConnectError as q}from"@connectrpc/connect";import rr from"p-limit";import*as ir from"node:crypto";import{createHash as ar,randomUUID as or}from"node:crypto";import{ExitPromptError as sr}from"@inquirer/core";import{confirm as cr,input as lr,password as ur,select as dr}from"@inquirer/prompts";import{isCI as fr}from"std-env";import*as pr from"rolldown";import{parseSync as mr}from"oxc-parser";import*as hr from"inflection";import{tmpdir as gr}from"node:os";import{pathToString as _r,usedTypes as vr}from"@bufbuild/protobuf/reflect";import{createValidator as yr}from"@bufbuild/protovalidate";import*as J from"node:fs/promises";import{mkdir as br,readFile as xr,rename as Sr,rm as Cr,writeFile as wr}from"node:fs/promises";import{setTimeout as Tr}from"timers/promises";import{setTimeout as Er}from"node:timers/promises";import{spawn as Dr}from"node:child_process";import*as Or from"fs";import{lookup as kr}from"mime-types";import{createPrompt as Ar}from"@toiroakr/read-multiline";import{astVisitor as jr,parse as Mr}from"pgsql-ast-parser";import{parse as Nr}from"@0no-co/graphql.web";const Pr={ms:1,s:1e3,m:6e4},Fr=/^(\d+)(ms|s|m)$/,Ir=H.string().refine(e=>Fr.test(e),{message:`Invalid duration format. Expected format: '3s', '500ms', '1m'`}).refine(e=>{let t=e.match(Fr);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(Fr),`invalid duration format: ${e}`),n=parseInt(A(t[1],`duration digits group missing`),10),r=A(t[2],`duration unit group missing`);return n*Pr[r]}const Lr=H.coerce.number().int().positive(),Rr=H.coerce.number().int().nonnegative(),zr=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=Jn(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 Br=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`}})},Vr=`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 Hr={config:V(H.string().default(Vr),{alias:`c`,description:`Path to Tailor config file`,env:`TAILOR_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Ur={config:V(H.string().default(Vr),{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`]}})},Wr={...Y,...Hr},Gr={yes:V(H.boolean().default(!1),{alias:`y`,description:`Skip confirmation prompts`})},Kr={"organization-id":V(H.string(),{alias:`o`,description:`Organization ID`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`,completion:{type:`none`}})},paginationArgs=(e=`desc`)=>({order:V(zr.default(e),{description:`Sort order (asc or desc)`}),limit:V(Rr.optional(),{alias:`l`,description:`Maximum number of items to return (0 or omit: unlimited)`})}),qr={order:V(zr.default(`desc`),{description:`Sort order (asc or desc)`}),limit:V(Rr.default(50),{alias:`l`,description:`Maximum number of items to return (0: unlimited)`})},Jr={"folder-id":V(H.string(),{alias:`f`,description:`Folder ID`,env:`TAILOR_PLATFORM_FOLDER_ID`,completion:{type:`none`}})},X=Fn(),Yr=H.union([H.string(),H.number(),H.boolean()]),Xr=H.union([H.string(),H.number()]),Zr=H.union([Yr,H.strictObject({value:Xr,allowSecretReason:H.string().min(1,{message:`'allowSecretReason' must state why the value is safe to keep in 'env'.`})})]),Qr=H.enum(Kt),$r=H.string().refine(e=>Qr.safeParse(e.trim().toUpperCase()).success,{message:`'logLevel' must be one of: ${Kt.join(`, `)}.`}),ei=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(),Zr).optional(),cors:H.array(H.string()).optional(),allowedIpAddresses:H.array(H.string()).optional(),disableIntrospection:H.boolean().optional(),inlineSourcemap:H.boolean().optional(),logLevel:$r.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()}),ti=H.looseObject({id:H.string(),description:H.string(),importPath:H.string().optional(),pluginConfig:H.unknown().optional(),tableConfigRequired:H.union([H.boolean(),dn]).optional(),onTableLoaded:dn.optional(),onNamespaceLoaded:dn.optional(),onTailorDBReady:dn.optional(),onResolverReady:dn.optional(),onExecutorReady:dn.optional()}).refine(e=>!(e.onTableLoaded||e.onNamespaceLoaded)||!!e.importPath,{message:`importPath is required when plugin has definition-time hooks (onTableLoaded/onNamespaceLoaded)`}).transform(e=>e),ni=`tailor-platform-cli`;let ri;async function getEntryClass(){if(ri!==void 0)return ri;try{let e=await import(`@napi-rs/keyring`),t=new e.Entry(ni,`__probe__`);t.setPassword(`probe`),t.deletePassword(),ri=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.`),ri=!1}return ri}async function isKeyringAvailable(){return await getEntryClass()!==!1}async function loadKeyringTokens(e){let t=await getEntryClass();if(t)try{let n=new t(ni,e).getPassword();return n===null?void 0:JSON.parse(n)}catch{return}}async function saveKeyringTokens(e,t){let n=await getEntryClass();n&&new n(ni,e).setPassword(JSON.stringify(t))}async function deleteKeyringTokens(e){let t=await getEntryClass();if(t)try{new t(ni,e).deletePassword()}catch{}}const ii=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()}),ai=H.object({access_token:H.string(),refresh_token:H.string().optional(),token_expires_at:H.string()}),oi=H.object({storage:H.literal(`keyring`),token_expires_at:H.string()}),si=H.object({storage:H.literal(`file`),token_expires_at:H.string(),access_token:H.string(),refresh_token:H.string().optional()}),ci=H.discriminatedUnion(`storage`,[oi,si]),li=oi.extend({email:H.string().optional()}),ui=si.extend({email:H.string().optional()}),di=H.discriminatedUnion(`storage`,[li,ui]),fi=H.object({version:H.literal(1),users:H.partialRecord(H.string(),ai),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()}),pi=`2.0.0`,mi=H.templateLiteral([H.number().int(),`.`,H.number().int(),`.`,H.number().int()]),hi=H.object({version:H.literal(2),min_sdk_version:mi,latest_version:H.number().int().optional(),latest_min_sdk_version:mi.optional(),users:H.partialRecord(H.string(),ci),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()}),gi=H.object({version:H.literal(3),min_sdk_version:mi,latest_version:H.number().int().optional(),latest_min_sdk_version:mi.optional(),users:H.partialRecord(H.string(),di),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()});function platformConfigPath(){if(!nr)throw Error(`User home directory not found`);return B.join(nr,`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=Mt(t);return n===$t(`https://api.tailor.tech`)?e:`${n}|${e}`}function userFromPlatformUserKey(e,t){let n=`${Mt(t)}|`;return e.startsWith(n)?e.slice(n.length):e}function canUseLegacyUserKey(e){try{return Mt()===e}catch{return!1}}function findUserByEmail(e,t,n){let r=Mt(n),i=`${r}|`,a=r===$t(pt);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=Mt(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:pi,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 pn()).version??`0.0.0`;tr(t,e.latest_min_sdk_version)&&M.warn(L`
|
|
1
|
+
import{t as e}from"./schema-6d_OHyZf.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 ft,B as pt,C as mt,D as ht,E as gt,F as _t,H as P,I as vt,J as yt,K as bt,L as xt,M as St,N as Ct,O as wt,P as Tt,Q as F,R as Et,S as Dt,T as Ot,U as kt,V as At,W as jt,X as Mt,Y as I,Z as Nt,at as Pt,b as Ft,c as It,et as Lt,g as Rt,h as zt,i as Bt,it as Vt,l as Ht,n as Ut,nt as Wt,o as Gt,ot as Kt,p as qt,q as Jt,r as Yt,rt as Xt,s as Zt,t as Qt,tt as $t,v as en,w as tn,x as nn,y as rn}from"./application-D3HlhR3i.mjs";import{_ as an,d as on,g as sn,l as cn,t as ln,v as un,x as dn,y as fn}from"./service-BzsSm2f6.mjs";import{t as L}from"./multiline-EyzjEwn9.mjs";import{t as pn}from"./package-json-C690ceex.mjs";import{t as mn}from"./user-agent-vdHYF3QL.mjs";import{a as hn,i as gn,n as _n,o as vn,t as R}from"./errors-BlX4gUw5.mjs";import{n as yn,r as bn}from"./secret-file-C9wp_FCX.mjs";import{r as z}from"./telemetry-Bklv9kQY.mjs";import{n as xn,t as Sn}from"./field-column-type-QMtF6lUp.mjs";import{a as Cn,i as wn,o as Tn,r as En,s as Dn,t as On}from"./seed-CMkupmX8.mjs";import*as kn from"node:module";import*as B from"pathe";import{basename as An,dirname as jn,join as Mn,resolve as Nn}from"pathe";import{resolveTSConfig as Pn}from"pkg-types";import{arg as V,createDefineCommand as Fn,defineCommand as In,runCommand as Ln}from"politty";import{z as H}from"zod";import{create as U,createRegistry as Rn,fromJson as zn,toJson as Bn}from"@bufbuild/protobuf";import*as W from"node:fs";import{mkdirSync as Vn,readFileSync as Hn,renameSync as Un,rmSync as Wn,statSync as Gn,utimesSync as Kn,writeFileSync as qn}from"node:fs";import{parseEnv as Jn}from"node:util";import{ValueSchema as Yn,timestampDate as G}from"@bufbuild/protobuf/wkt";import{formatDistanceToNowStrict as Xn}from"date-fns";import{pathToFileURL as Zn}from"node:url";import{parseYAML as Qn,stringifyYAML as $n}from"confbox";import{findUpSync as er}from"find-up-simple";import{lt as tr}from"semver";import{xdgConfig as nr}from"xdg-basedir";import{Code as K,ConnectError as q}from"@connectrpc/connect";import rr from"p-limit";import*as ir from"node:crypto";import{createHash as ar,randomUUID as or}from"node:crypto";import{ExitPromptError as sr}from"@inquirer/core";import{confirm as cr,input as lr,password as ur,select as dr}from"@inquirer/prompts";import{isCI as fr}from"std-env";import*as pr from"rolldown";import{parseSync as mr}from"oxc-parser";import*as hr from"inflection";import{tmpdir as gr}from"node:os";import{pathToString as _r,usedTypes as vr}from"@bufbuild/protobuf/reflect";import{createValidator as yr}from"@bufbuild/protovalidate";import*as J from"node:fs/promises";import{mkdir as br,readFile as xr,rename as Sr,rm as Cr,writeFile as wr}from"node:fs/promises";import{setTimeout as Tr}from"timers/promises";import{setTimeout as Er}from"node:timers/promises";import{spawn as Dr}from"node:child_process";import*as Or from"fs";import{lookup as kr}from"mime-types";import{createPrompt as Ar}from"@toiroakr/read-multiline";import{astVisitor as jr,parse as Mr}from"pgsql-ast-parser";import{parse as Nr}from"@0no-co/graphql.web";const Pr={ms:1,s:1e3,m:6e4},Fr=/^(\d+)(ms|s|m)$/,Ir=H.string().refine(e=>Fr.test(e),{message:`Invalid duration format. Expected format: '3s', '500ms', '1m'`}).refine(e=>{let t=e.match(Fr);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(Fr),`invalid duration format: ${e}`),n=parseInt(A(t[1],`duration digits group missing`),10),r=A(t[2],`duration unit group missing`);return n*Pr[r]}const Lr=H.coerce.number().int().positive(),Rr=H.coerce.number().int().nonnegative(),zr=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=Jn(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 Br=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`}})},Vr=`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 Hr={config:V(H.string().default(Vr),{alias:`c`,description:`Path to Tailor config file`,env:`TAILOR_CONFIG_PATH`,completion:{type:`file`,extensions:[`ts`]}})},Ur={config:V(H.string().default(Vr),{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`]}})},Wr={...Y,...Hr},Gr={yes:V(H.boolean().default(!1),{alias:`y`,description:`Skip confirmation prompts`})},Kr={"organization-id":V(H.string(),{alias:`o`,description:`Organization ID`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`,completion:{type:`none`}})},paginationArgs=(e=`desc`)=>({order:V(zr.default(e),{description:`Sort order (asc or desc)`}),limit:V(Rr.optional(),{alias:`l`,description:`Maximum number of items to return (0 or omit: unlimited)`})}),qr={order:V(zr.default(`desc`),{description:`Sort order (asc or desc)`}),limit:V(Rr.default(50),{alias:`l`,description:`Maximum number of items to return (0: unlimited)`})},Jr={"folder-id":V(H.string(),{alias:`f`,description:`Folder ID`,env:`TAILOR_PLATFORM_FOLDER_ID`,completion:{type:`none`}})},X=Fn(),Yr=H.union([H.string(),H.number(),H.boolean()]),Xr=H.union([H.string(),H.number()]),Zr=H.union([Yr,H.strictObject({value:Xr,allowSecretReason:H.string().min(1,{message:`'allowSecretReason' must state why the value is safe to keep in 'env'.`})})]),Qr=H.enum(Kt),$r=H.string().refine(e=>Qr.safeParse(e.trim().toUpperCase()).success,{message:`'logLevel' must be one of: ${Kt.join(`, `)}.`}),ei=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(),Zr).optional(),cors:H.array(H.string()).optional(),allowedIpAddresses:H.array(H.string()).optional(),disableIntrospection:H.boolean().optional(),inlineSourcemap:H.boolean().optional(),logLevel:$r.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()}),ti=H.looseObject({id:H.string(),description:H.string(),importPath:H.string().optional(),pluginConfig:H.unknown().optional(),tableConfigRequired:H.union([H.boolean(),dn]).optional(),onTableLoaded:dn.optional(),onNamespaceLoaded:dn.optional(),onTailorDBReady:dn.optional(),onResolverReady:dn.optional(),onExecutorReady:dn.optional()}).refine(e=>!(e.onTableLoaded||e.onNamespaceLoaded)||!!e.importPath,{message:`importPath is required when plugin has definition-time hooks (onTableLoaded/onNamespaceLoaded)`}).transform(e=>e),ni=`tailor-platform-cli`;let ri;async function getEntryClass(){if(ri!==void 0)return ri;try{let e=await import(`@napi-rs/keyring`),t=new e.Entry(ni,`__probe__`);t.setPassword(`probe`),t.deletePassword(),ri=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.`),ri=!1}return ri}async function isKeyringAvailable(){return await getEntryClass()!==!1}async function loadKeyringTokens(e){let t=await getEntryClass();if(t)try{let n=new t(ni,e).getPassword();return n===null?void 0:JSON.parse(n)}catch{return}}async function saveKeyringTokens(e,t){let n=await getEntryClass();n&&new n(ni,e).setPassword(JSON.stringify(t))}async function deleteKeyringTokens(e){let t=await getEntryClass();if(t)try{new t(ni,e).deletePassword()}catch{}}const ii=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()}),ai=H.object({access_token:H.string(),refresh_token:H.string().optional(),token_expires_at:H.string()}),oi=H.object({storage:H.literal(`keyring`),token_expires_at:H.string()}),si=H.object({storage:H.literal(`file`),token_expires_at:H.string(),access_token:H.string(),refresh_token:H.string().optional()}),ci=H.discriminatedUnion(`storage`,[oi,si]),li=oi.extend({email:H.string().optional()}),ui=si.extend({email:H.string().optional()}),di=H.discriminatedUnion(`storage`,[li,ui]),fi=H.object({version:H.literal(1),users:H.partialRecord(H.string(),ai),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()}),pi=`2.0.0`,mi=H.templateLiteral([H.number().int(),`.`,H.number().int(),`.`,H.number().int()]),hi=H.object({version:H.literal(2),min_sdk_version:mi,latest_version:H.number().int().optional(),latest_min_sdk_version:mi.optional(),users:H.partialRecord(H.string(),ci),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()}),gi=H.object({version:H.literal(3),min_sdk_version:mi,latest_version:H.number().int().optional(),latest_min_sdk_version:mi.optional(),users:H.partialRecord(H.string(),di),profiles:H.partialRecord(H.string(),ii),current_user:H.string().nullable()});function platformConfigPath(){if(!nr)throw Error(`User home directory not found`);return B.join(nr,`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=Mt(t);return n===$t(`https://api.tailor.tech`)?e:`${n}|${e}`}function userFromPlatformUserKey(e,t){let n=`${Mt(t)}|`;return e.startsWith(n)?e.slice(n.length):e}function canUseLegacyUserKey(e){try{return Mt()===e}catch{return!1}}function findUserByEmail(e,t,n){let r=Mt(n),i=`${r}|`,a=r===$t(pt);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=Mt(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:pi,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 pn()).version??`0.0.0`;tr(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:pi,users:{},profiles:{},current_user:null};return writePlatformConfig(e),e}let t=Qn(W.readFileSync(e,`utf-8`));yn(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`
|
|
@@ -13,7 +13,7 @@ import{t as e}from"./schema-6d_OHyZf.mjs";import{t}from"./wait-point-registry-B-
|
|
|
13
13
|
`)}async function tryLoadWorkspaceId(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(e?.workspaceId!==void 0)return validateUUID(e.workspaceId,`--workspace-id option`);if(process.env.TAILOR_PLATFORM_WORKSPACE_ID)return validateUUID(process.env.TAILOR_PLATFORM_WORKSPACE_ID,`TAILOR_PLATFORM_WORKSPACE_ID environment variable`);if(t){let e=(await readPlatformConfig()).profiles[t]?.workspace_id;if(!e)throw Error(`Profile "${t}" not found`);return validateUUID(e,`profile "${t}"`)}}async function loadMachineUserName(e){if(e?.machineUser===``)throw R({code:`MACHINE_USER_NAME_EMPTY`,message:`Machine user name cannot be empty.`,suggestion:`Pass a non-empty machine user name, or omit the option to use the environment variable or profile default.`});let t=process.env.TAILOR_PLATFORM_MACHINE_USER_NAME||void 0,n=e?.machineUser?{source:e.machineUserSource??`option`,value:e.machineUser}:t?{source:`env`,value:t}:void 0,r=n?.value,i=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(!i)return r;let a=(await readPlatformConfig()).profiles[i];if(!a){if(r)return r;throw Error(`Profile "${i}" not found`)}if(a.machine_user&&a.machine_user_override===`deny`){if(r&&r!==a.machine_user){let e=n.source===`env`?`The machine user is being set to "${r}" via the TAILOR_PLATFORM_MACHINE_USER_NAME environment variable, which conflicts with this profile's pinned machine user "${a.machine_user}".`:`This profile fixes the machine user to "${a.machine_user}" for application-data commands.`;throw R({code:`PROFILE_MACHINE_USER_OVERRIDE_DENIED`,message:`Profile "${i}" denies overriding the machine user.`,details:e,suggestion:`Omit the machine user option, unset TAILOR_PLATFORM_MACHINE_USER_NAME, or run 'tailor profile update ${i} --machine-user-override allow'.`})}return a.machine_user}return r||a.machine_user}async function loadAccessToken(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE,n=process.env.TAILOR_PLATFORM_TOKEN??process.env.TAILOR_TOKEN;if(n&&!process.env.TAILOR_PLATFORM_TOKEN&&M.warn(`TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.`),n){let e=await loadPlatformClientConfig({profile:t,allowMissingProfile:!0});return Wt(n,e),n}let r=await readPlatformConfig(),i=t?r.profiles[t]:void 0;if(t&&!i)throw Error(`Profile "${t}" not found`);let a=i?.user??r.current_user;if(!a)throw Error(L`
|
|
14
14
|
Tailor Platform token not found.
|
|
15
15
|
Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor login' command.
|
|
16
|
-
`);return(await fetchLatestToken(r,a,i?platformConfigFromProfile(i):void 0)).accessToken}async function loadPlatformClientConfig(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(!t)return;let n;try{n=await readPlatformConfig()}catch(t){if(e?.allowMissingProfile)return;throw t}let r=n.profiles[t];if(!r){if(e?.allowMissingProfile)return;throw Error(`Profile "${t}" not found`)}return platformConfigFromProfile(r)}async function loadConsoleBaseUrl(e){let t=await loadPlatformClientConfig(e);return Jt(t)}async function resolveTokens(e,t,n=t){if(e.storage===`keyring`){let e=await loadKeyringTokens(t);if(!e)throw Error(L`
|
|
16
|
+
`);return(await fetchLatestToken(r,a,i?platformConfigFromProfile(i):void 0)).accessToken}async function loadAuthStatus(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE,n=process.env.TAILOR_PLATFORM_TOKEN??process.env.TAILOR_TOKEN;if(n&&!process.env.TAILOR_PLATFORM_TOKEN&&M.warn(`TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.`),n){let e=await readPlatformConfig().catch(()=>void 0),n=t?e?.profiles[t]:void 0,r=n?platformConfigFromProfile(n):void 0;return{authenticated:!0,identity:null,identitySource:`environment`,profile:t??null,workspaceId:process.env.TAILOR_PLATFORM_WORKSPACE_ID??n?.workspace_id??null,permission:n?.readonly===!0?`read`:`write`,platformUrl:Mt(r),tokenStatus:`environment`}}let r=await readPlatformConfig(),i=t?r.profiles[t]:void 0;if(t&&!i)throw Error(`Profile "${t}" not found`);let a=i?platformConfigFromProfile(i):void 0,o=Mt(a),s=process.env.TAILOR_PLATFORM_WORKSPACE_ID??i?.workspace_id??null,c=i?.user??r.current_user,l=i?.user?`profile`:c?`default`:`none`,u=`missing`;if(c){let{userKey:e,userEntry:t}=findUserEntry(r,c,a);if(t){let n=await resolveTokens(t,e,c).catch(()=>void 0);n&&(u=new Date(t.token_expires_at)<=new Date?n.refreshToken?`refreshable`:`expired`:`valid`)}}return{authenticated:u===`valid`||u===`refreshable`,identity:c??null,identitySource:l,profile:t??null,workspaceId:s,permission:i?.readonly===!0?`read`:`write`,platformUrl:o,tokenStatus:u}}async function loadPlatformClientConfig(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(!t)return;let n;try{n=await readPlatformConfig()}catch(t){if(e?.allowMissingProfile)return;throw t}let r=n.profiles[t];if(!r){if(e?.allowMissingProfile)return;throw Error(`Profile "${t}" not found`)}return platformConfigFromProfile(r)}async function loadConsoleBaseUrl(e){let t=await loadPlatformClientConfig(e);return Jt(t)}async function resolveTokens(e,t,n=t){if(e.storage===`keyring`){let e=await loadKeyringTokens(t);if(!e)throw Error(L`
|
|
17
17
|
Credentials not found in OS keyring for "${n}".
|
|
18
18
|
Please run 'tailor login' and try again.
|
|
19
19
|
`);return e}return{accessToken:e.access_token,refreshToken:e.refresh_token}}async function saveUserTokens(e,t,n,r,i={}){let a=platformUserKey(t,i.platformConfig),o=i.email??e.users[a]?.email;await trySaveTokensInKeyring(a,n)?e.users[a]={token_expires_at:r,storage:`keyring`,...o?{email:o}:{}}:(e.users[a]?.storage===`keyring`&&await deleteKeyringTokens(a),e.users[a]={access_token:n.accessToken,refresh_token:n.refreshToken,token_expires_at:r,storage:`file`,...o?{email:o}:{}})}async function deleteUserTokens(e,t,n,r){let{userKey:i,userEntry:a}=findUserEntry(e,t,n,r);a?.storage===`keyring`&&await deleteKeyringTokens(i),delete e.users[i]}async function loadStoredUserTokens(e,t,n,r){let{userKey:i,userEntry:a}=findUserEntry(e,t,n,r);if(a)return{userEntry:a,...await resolveTokens(a,i,t)}}function updateUserReferences(e,t,n){if(t!==n){e.current_user===t&&(e.current_user=n);for(let r of Object.values(e.profiles))r?.user===t&&(r.user=n)}}async function removeLegacyUserAlias(e,t,n,r){if(t===n)return;updateUserReferences(e,t,n);let i=platformUserKey(n,r),a=new Set([t,platformUserKey(t,r)]);for(let t of a)t!==i&&(e.users[t]?.storage===`keyring`&&await deleteKeyringTokens(t),delete e.users[t])}function shouldResolveSubjectOnRefresh(e,t){return!!(t.email||inferEmailFromUserId(e))}async function fetchLatestToken(e,t,n){let{userKey:r,userEntry:i}=findUserEntry(e,t,n);if(!i)throw Error(L`
|
|
@@ -28,7 +28,7 @@ import{t as e}from"./schema-6d_OHyZf.mjs";import{t}from"./wait-point-registry-B-
|
|
|
28
28
|
`)}let l=new Date(A(c.expiresAt,`token refresh response missing expiresAt`)).toISOString(),u=a,d=i.email??inferEmailFromUserId(t)??inferEmailFromUserId(a),f=d;if(shouldResolveSubjectOnRefresh(t,i)||shouldResolveSubjectOnRefresh(a,i))try{let e=await bt(c.accessToken,n);u=e.sub,f=e.email}catch(e){M.debug(`Failed to resolve refreshed token user info: ${String(e)}`)}return await saveUserTokens(e,u,{accessToken:c.accessToken,refreshToken:c.refreshToken??void 0},l,{platformConfig:n,email:f}),await removeLegacyUserAlias(e,t,u,n),r!==platformUserKey(u,n)&&(e.users[r]?.storage===`keyring`&&await deleteKeyringTokens(r),delete e.users[r]),d&&f&&d!==f&&M.info(`Updated local user email from "${d}" to "${f}".`),writePlatformConfig(e),Wt(c.accessToken,n),{accessToken:c.accessToken,user:u}}function loadConfigPath(e){return e||(process.env.TAILOR_CONFIG_PATH?process.env.TAILOR_CONFIG_PATH:er(`tailor.config.ts`))}const _i=/^[A-Za-z0-9+/=_.-]+$/,vi=new Map;function resolveEnvValue(e){return isAllowedSecret(e)?e.value:e}async function scanEnvForSecrets(e){let t=Object.entries(e.env??{}).filter(([,e])=>!isAllowedSecret(e)).map(([e,t])=>[e,resolveEnvValue(t)]);if(t.length===0)return[];let n=await scanWithProviderRules(t),r=new Set(n.map(e=>e.key));for(let[e,i]of t)r.has(e)||typeof i!=`string`||looksRandomlyGenerated(i)&&n.push({key:e,detector:`high-entropy`,severity:`warning`});return n}async function assertEnvHasNoSecrets(e){let t=ar(`sha256`).update(JSON.stringify([e.configPath??``,e.env??{}])).digest(`hex`),n=vi.get(t);if(n)return n;let r=reportEnvSecrets(e);return vi.set(t,r),r}async function reportEnvSecrets(e){let t=await scanEnvForSecrets(e);for(let e of t)e.severity===`warning`&&M.warn(`env.${e.key} looks like a randomly generated credential. If it is one, move it to Secret Manager; otherwise allow it with ${N.bold(`allowSecretReason`)}.`);let n=t.filter(e=>e.severity===`error`);if(n.length===0)return;let r=e.configPath?` in ${e.configPath}`:``,i=n.map(e=>{let t=e.rule?`${e.detector}: ${e.rule}`:e.detector,n=e.docsUrl?`\n ${e.docsUrl}`:``;return` - env.${e.key} (matched ${t})${n}`}).join(`
|
|
29
29
|
`),a=n[0]?.key??`KEY`;throw Error(`Secret detected in 'env'${r}:\n${i}\n'env' values are deployed as plaintext and are readable by anyone who can read the application's configuration. Define these with defineSecretManager() instead, and read them through Secret Manager at runtime.
|
|
30
30
|
If a value is genuinely safe to keep in 'env', allow it where it is defined: ${a}: { value: ..., allowSecretReason: "<why this is safe>" }`)}async function scanWithProviderRules(e){let[{lintSource:t},{rules:n}]=await Promise.all([import(`@secretlint/core`),import(`@secretlint/secretlint-rule-preset-recommend`)]),r=[],i=``;for(let[t,n]of e){let e=`${t}=${String(n)}`;r.push({key:t,start:i.length,end:i.length+e.length}),i+=`${e}\n`}let a=await t({source:{filePath:`/tailor-config-env`,content:i,contentType:`text`},options:{maskSecrets:!0,noPhysicFilePath:!0,config:{rules:n.filter(e=>e.meta.id!==`@secretlint/secretlint-rule-filter-comments`).map(e=>({id:e.meta.id,rule:e,...e.meta.id===`@secretlint/secretlint-rule-aws`?{options:{enableIDScanRule:!0}}:{}}))}}}),o=[],s=new Set;for(let e of a.messages){let t=r.find(t=>e.range[0]>=t.start&&e.range[0]<t.end);if(!t)continue;let n=e.ruleId.startsWith(`@secretlint/secretlint-rule-`)?e.ruleId.slice(28):e.ruleId,i=JSON.stringify([t.key,n,e.messageId]);s.has(i)||(s.add(i),o.push({key:t.key,detector:n,rule:e.messageId,...e.docsUrl?{docsUrl:e.docsUrl}:{},severity:`error`}))}return o}function isAllowedSecret(e){return typeof e==`object`}function looksRandomlyGenerated(e){return e.length<20||!_i.test(e)?!1:shannonEntropyPerChar(e)>=4.2}function shannonEntropyPerChar(e){let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=0;for(let r of t.values()){let t=r/e.length;n-=t*Math.log2(t)}return n}function installCliTailordbStub(){globalThis.tailordb={Client:class{constructor(e){}async connect(){}async end(){}async queryObject(){return{}}}}}async function loadConfig(e,t={}){installCliTailordbStub();let n=loadConfigPath(e);if(!n)throw Error(`Configuration file not found: tailor.config.ts not found in current or parent directories`);let r=B.resolve(process.cwd(),n);if(!W.existsSync(r))throw Error(`Configuration file not found: ${e}`);let i=Zn(r),a=t.importNonce??fn();a&&i.searchParams.set(an,a);let o=await import(i.href);if(!o||!o.default)throw Error(`Invalid Tailor config module: default export not found`);let s=ei.safeParse(o.default);if(!s.success){let e=s.error.issues.map(e=>` - ${e.path.join(`.`)||`(root)`}: ${e.message}`).join(`
|
|
31
|
-
`);throw Error(`Invalid Tailor config in ${r}:\n${e}`)}let c=o.default;await assertEnvHasNoSecrets({env:c.env,configPath:r});let l=c.env?Object.fromEntries(Object.entries(c.env).map(([e,t])=>[e,resolveEnvValue(t)])):void 0,u=[];for(let e of Object.values(o))if(Array.isArray(e)){let t=e.reduce((e,t)=>{if(!e.success)return e;let n=ti.safeParse(t);return n.success?e.items.push(n.data):e.success=!1,e},{success:!0,items:[]});t.success&&t.items.length>0&&u.push(...t.items)}return{config:{...o.default,...l?{env:l}:{},path:r},plugins:u}}async function assertWritable(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(!t)return;let n=(await readPlatformConfig()).profiles[t];if(!(!n||n.readonly!==!0))throw R({code:`PROFILE_READONLY`,message:`Profile "${t}" is read-only.`,details:`This profile blocks platform-state mutations (apply, create/update/delete, deploy, etc.). Application-data operations remain available because their permissions are governed by the machine user.`,suggestion:`Use a different profile, unset TAILOR_PLATFORM_PROFILE, or run 'tailor profile update ${t} --permission write'.`})}function hasEnvAccessToken(){return!!(process.env.TAILOR_PLATFORM_TOKEN??process.env.TAILOR_TOKEN)}async function apiCall(e){let t=await loadAccessToken({profile:e.profile}),n;try{n=await loadPlatformClientConfig({profile:e.profile})}catch(e){if(!hasEnvAccessToken())throw e}let r;r=e.endpoint.includes(`/`)?e.endpoint:`tailor.v1.OperatorService/${e.endpoint}`;let i=new URL(r,Mt(n)),a=await fetch(i.toString(),{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${t}`,"User-Agent":await mn()},body:e.body??`{}`}),o=await a.json();if(!a.ok)throw Error(`API call failed (${a.status}): ${JSON.stringify(o)}`);return{status:a.status,data:o}}function canPrompt(){return!fr&&process.stdin.isTTY===!0&&process.stdout.isTTY===!0&&!M.jsonMode}function withGuard(e,t){return async n=>{if(!canPrompt())throw new dt(t);try{return await e(n)}catch(e){throw e instanceof sr&&process.exit(130),e}}}const Z={confirm:withGuard(cr,`Interactive confirmations are not available in this environment. Use --yes to skip confirmation prompts, or provide the required options explicitly.`),text:withGuard(lr),password:withGuard(ur),select:e=>withGuard(dr)(e)};function createChangeSet(e){let t=[],n=[],r=[],i=[],a=[],isEmpty=()=>t.length===0&&n.length===0&&r.length===0&&i.length===0;return{title:e,creates:t,updates:n,deletes:r,replaces:i,unchanged:a,isEmpty,lines:()=>{if(isEmpty())return[];let itemLines=e=>t=>[` ${e} ${t.name}`,...(t.details??[]).map(e=>` ${e}`)];return[N.bold(`${e}:`),...t.flatMap(itemLines(j.create)),...r.flatMap(itemLines(j.delete)),...n.flatMap(itemLines(j.update)),...i.flatMap(itemLines(j.replace))]}}}function summarizeChangeSets(e){let t={create:0,update:0,delete:0,replace:0};for(let n of e)t.create+=n.creates.length,t.update+=n.updates.length,t.delete+=n.deletes.length,t.replace+=n.replaces.length;return t}function formatPlanSummary(e){let t=[`${e.create} to create`,`${e.update} to update`,`${e.delete} to delete`];return e.replace>0&&t.push(`${e.replace} to replace`),`Plan: ${t.join(`, `)}`}function toComparableProtoJson(e,t){return Bn(e,U(e,t))}function stableStringify$1(e){return Array.isArray(e)?`[${e.map(e=>e===void 0?`null`:stableStringify$1(e)).join(`,`)}]`:e&&typeof e==`object`?`{${Object.entries(e).filter(([e,t])=>e!==`$typeName`&&t!==void 0).toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${stableStringify$1(t)}`).join(`,`)}}`:JSON.stringify(typeof e==`bigint`?e.toString():e)}function normalizeProtoConfig(e){return e==null?e:JSON.parse(stableStringify$1(e))}function normalizeStringArray(e){return(e??[]).toSorted()}function areNormalizedEqual(e,t){return stableStringify$1(normalizeProtoConfig(e))===stableStringify$1(normalizeProtoConfig(t))}function trnPrefix(e){return`trn:v1:workspace:${e}`}function resourceTrn(e,t,n){return`${trnPrefix(e)}:${t}:${n}`}function nestedResourceTrn(e,t,n){return`${trnPrefix(e)}:${t[0]}:${t[1]}:${n[0]}:${n[1]}`}function tailorDBTypeTrn(e,t,n){return nestedResourceTrn(e,[`tailordb`,t],[`type`,n])}function resolverTrn(e,t,n){return nestedResourceTrn(e,[`pipeline`,t],[`resolver`,n])}const yi=`sdk-name`,bi=`sdk-version`,xi=`sdk-app-id`;function sdkAppIdLabelValue(e){return`app-${e}`}function hasMatchingSdkVersion(e,t){return e?.[bi]===t?.[bi]}function isOwnedByApp(e,t,n){if(!e)return!1;let r=e[xi];return r?n!==void 0&&r===sdkAppIdLabelValue(n):e[yi]===t}function prefixFor(e){return e===`jobs`?`sdk-job-depended-by-app-`:`sdk-depended-by-app-`}const Si=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function dependedByAppLabelKey(e,t=`resource`){return Si.test(e)?`${prefixFor(t)}${e}`:void 0}function recordedDependencies(e,t=`resource`){if(!e)return[];let n=prefixFor(t);return Object.entries(e).toSorted(([e],[t])=>e<t?-1:+(e>t)).flatMap(([e,t])=>{if(!e.startsWith(n))return[];let r=e.slice(n.length);return Si.test(r)?[{appId:r,reason:t}]:[]})}const Q={tailorDBType:(e,t)=>`tailordb:${e}:type:${t}`,resolver:(e,t)=>`pipeline:${e}:resolver:${t}`,idp:e=>`idp:${e}`,workflow:e=>`workflow:${e}`,workflowJobs:e=>`workflow:${e}:jobs`};function dependencyLabelWrite(e){let{existingLabels:t,dependentApps:n,runAppIds:r,pinned:i,scope:a=`resource`}=e;if(i)return{labels:{},remove:recordedDependencies(t,a).flatMap(({appId:e})=>dependedByAppLabelKey(e,a)??[])};let o=n??new Map,s=r??new Set,c={};for(let[e,t]of o){let n=dependedByAppLabelKey(e,a);if(!n)throw Error(`Application id "${e}" cannot be recorded as a dependency of this deploy. Ids are written by deploy as lowercase UUIDs; restore the generated value in the config's "id".`);c[n]=t}return{labels:c,remove:recordedDependencies(t,a).flatMap(({appId:e})=>{if(!s.has(e)||o.has(e))return[];let t=dependedByAppLabelKey(e,a);return t?[t]:[]})}}async function buildMetaRequest(e){let{trn:t,appName:n,appId:r}=e,i=await pn(),a=i.version?`v${i.version.replace(/\./g,`-`)}`:`unknown`;return{trn:t,labels:{[yi]:n,[bi]:a,...r?{[xi]:sdkAppIdLabelValue(r)}:{}},remove:r?void 0:[xi]}}function addDependencyRecords(e,t){let{key:n,dependentApps:r,runAppIds:i,pinned:a,scope:o}=t;return e.dependencies=[...e.dependencies??[],{dependentApps:r?.get(n),runAppIds:i,pinned:a,scope:o}],e}const Ci=Symbol(`metadataWriteBatch`);var MetadataWriteBatch=class{#e;#t=new Map;#n;constructor(e){this.#e=e}async enqueue(e){if(this.#n){await this.#n.catch(()=>void 0),await writeMetadataLabelsDirect(this.#e,e);return}let t=this.#t.get(e.trn)??[];t.push(e),this.#t.set(e.trn,t)}flush(){return this.#n??=this.#r(),this.#n}async#r(){let e=[...this.#t].toSorted(([e],[t])=>e<t?-1:+(e>t)),readRequest=async([e,t])=>{let n=(await I(()=>this.#e.getMetadata({trn:e})))?.metadata?.labels??{},r=t.reduce(applyMetadataLabelWrite,n);return areSameLabels(n,r)?void 0:{trn:e,labels:r}},t=[],n=0;for(;n<e.length||t.length>0;){let r=t.length===0?[]:void 0;for(;n<e.length&&t.length<100;){t.length>0&&(r=void 0);let i=e.slice(n,n+100);n+=i.length;let a=await Promise.all(i.map(async e=>{let t=await readRequest(e);return t?{entry:e,request:t}:void 0}));for(let e of a)e&&(t.push(e.entry),r?.push(e.request))}let i=t.splice(0,100),a=r??(await Promise.all(i.map(e=>readRequest(e)))).filter(e=>e!==void 0);a.length>0&&await this.#e.bulkSetMetadata({requests:a})}}};function hasMetadataLabelChange(e){return!!(Object.keys(e.labels??{}).length||e.remove?.length||e.dependencies?.length)}function applyMetadataLabelWrite(e,t){let{labels:n,remove:r,dependencies:i}=t,a=(i??[]).map(t=>dependencyLabelWrite({...t,existingLabels:e})),o={...e,...n,...Object.assign({},...a.map(e=>e.labels))};for(let e of[...r??[],...a.flatMap(e=>e.remove)])delete o[e];return o}function metadataRecoveryError(e,t){return AggregateError([e,t],`Resource apply failed: ${hn(e).message}\nQueued metadata recovery failed: ${hn(t).message}`,{cause:t})}async function withMetadataWriteBatch(e,t){let n=new MetadataWriteBatch(e),r=new Proxy(e,{get(e,t,r){return t===Ci?n:Reflect.get(e,t,r)}}),i;try{i=await t(r)}catch(e){try{await n.flush()}catch(t){throw metadataRecoveryError(e,t)}throw e}return await n.flush(),i}async function writeMetadataLabels(e,t){if(!hasMetadataLabelChange(t))return;let n=e[Ci];if(n){await n.enqueue(t);return}await writeMetadataLabelsDirect(e,t)}async function writeMetadataLabelsDirect(e,t){if(!hasMetadataLabelChange(t))return;let{trn:n}=t,r=(await I(()=>e.getMetadata({trn:n})))?.metadata?.labels??{},i=applyMetadataLabelWrite(r,t);areSameLabels(r,i)||await e.setMetadata({trn:n,labels:i})}function areSameLabels(e,t){let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>e[n]===t[n])}async function fetchExistingResourcesWithLabels(e){let{client:t,fetchPage:n,getName:r,getTrn:i}=e,a=await P(n),o={};return await Promise.all(a.map(async e=>{let n=r(e);if(!n)return;let{metadata:a}=await t.getMetadata({trn:i(n)});o[n]={resource:e,label:a?.labels[yi],allLabels:a?.labels}})),o}function trackDesiredResourceOwnership(e){let{labels:t,ownerLabel:n,appName:r,appId:i,resourceType:a,resourceName:o,conflicts:s,unmanaged:c}=e,l=isOwnedByApp(t,r,i);return l||(n?s.push({resourceType:a,resourceName:o,currentOwner:n}):c.push({resourceType:a,resourceName:o})),l}function trackRemainingResourceOwner(e){let{labels:t,ownerLabel:n,appName:r,appId:i,resourceOwners:a}=e,o=isOwnedByApp(t,r,i);return n&&!o&&a.add(n),o}async function applyStaticWebsite(e,t,n=`create-update`){let{changeSet:r,customDomainChangeSet:i}=t;n===`create-update`?(await Promise.all([...r.creates.map(async t=>{await e.createStaticWebsite(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{await e.updateStaticWebsite(t.request),await writeMetadataLabels(e,t.metaRequest)})]),await Promise.all([...i.creates.map(async t=>{await e.addCustomDomain(t.request),await writeMetadataLabels(e,t.metaRequest)}),...i.deletes.map(t=>e.removeCustomDomain(t.request))])):await Promise.all(r.deletes.map(t=>e.deleteStaticWebsite(t.request)))}function customDomainTrn(e,t,n){return`trn:v1:workspace:${e}:staticwebsite:${t}:custom_domain:${n}`}function normalizeComparableStaticWebsiteShape(e){return{description:e.description,allowedIpAddresses:e.allowedIpAddresses.toSorted()}}function normalizeComparableStaticWebsite(e){return normalizeComparableStaticWebsiteShape({description:e.description||``,allowedIpAddresses:[...e.allowedIpAddresses||[]]})}function areStaticWebsitesEqual(e,t){return areNormalizedEqual(normalizeComparableStaticWebsite(e),normalizeComparableStaticWebsite(t))}function expectedLocalStaticWebsiteNames(e){return e.expectedLocalStaticWebsiteNames??new Set(e.application.staticWebsiteServices.map(e=>e.name))}async function planStaticWebsite(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`StaticWebsites`),o=createChangeSet(`CustomDomains`),s=[],c=[],l=new Set,u=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{staticwebsites:i,nextPageToken:a}=await t.listStaticWebsites({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`staticwebsite`,e)}),d=new Set,f=i?[]:r.staticWebsiteServices;for(let e of f){let t=e,i=e.name,o=u[i],l=await buildMetaRequest({trn:resourceTrn(n,`staticwebsite`,i),appName:r.name,appId:r.id}),f=normalizeComparableStaticWebsite(t),p={workspaceId:n,staticwebsite:{name:i,description:t.description||``,allowedIpAddresses:t.allowedIpAddresses||[]}};if(o){let e=trackDesiredResourceOwnership({labels:o.allLabels,ownerLabel:o.label,appName:r.name,appId:r.id,resourceType:`StaticWebsite`,resourceName:i,conflicts:s,unmanaged:c});e&&hasMatchingSdkVersion(o.allLabels,l.labels)&&areStaticWebsitesEqual(o.resource,f)?a.unchanged.push({name:i}):a.updates.push({name:i,request:p,metaRequest:l}),e&&d.add(i),delete u[i]}else a.creates.push({name:i,request:p,metaRequest:l}),d.add(i)}Object.entries(u).forEach(([e])=>{let t=u[e],i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:l})&&a.deletes.push({name:e,request:{workspaceId:n,name:e}})});let p=new Map;for(let e of f)e.customDomains!==void 0&&d.has(e.name)&&p.set(e.name,e.customDomains);let m=new Map,h=[...d].filter(e=>!a.creates.some(t=>t.name===e));await Promise.all(h.map(async e=>{let r=await I(async()=>{let{customDomains:r}=await t.listCustomDomains({workspaceId:n,staticWebsiteName:e});return await Promise.all(r.map(async r=>{let{metadata:i}=await t.getMetadata({trn:customDomainTrn(n,e,r.domain)});return{domain:r.domain,allLabels:i?.labels}}))});r&&m.set(e,r)}));for(let e of d){let t=new Set(p.get(e)??[]),i=m.get(e)??[],a=new Set(i.map(e=>e.domain)),s=new Set(i.filter(e=>isOwnedByApp(e.allLabels,r.name,r.id)).map(e=>e.domain));for(let i of t)if(a.has(i))o.unchanged.push({name:i});else{let t=await buildMetaRequest({trn:customDomainTrn(n,e,i),appName:r.name,appId:r.id});o.creates.push({name:i,request:{workspaceId:n,staticWebsiteName:e,domain:i},metaRequest:t})}if(p.has(e))for(let e of s)t.has(e)||o.deletes.push({name:e,request:{workspaceId:n,domain:e}})}return{changeSet:a,customDomainChangeSet:o,conflicts:s,unmanaged:c,resourceOwners:l}}async function applyAIGateway(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?await Promise.all([...r.creates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`AIGateway CORS`),await e.createAIGateway(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`AIGateway CORS`),await e.updateAIGateway(t.request),await writeMetadataLabels(e,t.metaRequest)})]):await Promise.all(r.deletes.map(t=>e.deleteAIGateway(t.request)))}function normalizeComparableAIGatewayShape(e){return{authNamespace:e.authNamespace,cors:e.cors.toSorted()}}function normalizeComparableAIGateway(e){return normalizeComparableAIGatewayShape({authNamespace:e.authNamespace||``,cors:[...e.cors||[]]})}function areAIGatewaysEqual(e,t){return areNormalizedEqual(normalizeComparableAIGateway(e),normalizeComparableAIGateway(t))}async function planAIGateway(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`AIGateways`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{aigateways:i,nextPageToken:a}=await t.listAIGateways({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`aigateway`,e)}),u=i?[]:r.aiGatewayServices,d=expectedLocalStaticWebsiteNames(e);for(let e of u){let i=e,c=e.name,u=l[c],f=await buildMetaRequest({trn:resourceTrn(n,`aigateway`,c),appName:r.name,appId:r.id}),p=await Xt(t,n,i.cors?[...i.cors]:[],`AIGateway CORS`,{expectedLocalNames:d}),m=normalizeComparableAIGateway({...i,cors:p}),h={workspaceId:n,aigatewayName:c,authNamespace:i.authNamespace,cors:i.cors?[...i.cors]:[]};u?(trackDesiredResourceOwnership({labels:u.allLabels,ownerLabel:u.label,appName:r.name,appId:r.id,resourceType:`AIGateway`,resourceName:c,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(u.allLabels,f.labels)&&areAIGatewaysEqual(u.resource,m)?a.unchanged.push({name:c}):a.updates.push({name:c,request:h,metaRequest:f}),delete l[c]):a.creates.push({name:c,request:h,metaRequest:f})}return Object.entries(l).forEach(([e,t])=>{let i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:n,aigatewayName:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}async function applyApplication(e,t,n=`create-update`){if(n===`create-update`){let n=[...t.updates,...t.unchanged];await Promise.all([...t.creates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`CORS`),await e.createApplication(t.request),await writeMetadataLabels(e,t.metaRequest)}),...n.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`CORS`),await e.updateApplication(t.request),await writeMetadataLabels(e,t.metaRequest)})])}else await Promise.all(t.deletes.map(async t=>{await e.deleteApplication(t.request)}))}function sortStrings(e){return(e??[]).toSorted()}function normalizeSubgraphs(e){return[...e??[]].map(e=>({serviceType:A(e.serviceType,`subgraph missing serviceType`),serviceNamespace:e.serviceNamespace??``})).toSorted((e,t)=>e.serviceType===t.serviceType?e.serviceNamespace.localeCompare(t.serviceNamespace):e.serviceType-t.serviceType)}function normalizeHttpAdapters(e){return[...e??[]].map(e=>({name:e.name??``,pathPattern:e.pathPattern??``,methods:sortStrings(e.methods),inputScript:e.inputScript??``,outputScript:e.outputScript??``,enabled:e.enabled??!0,priority:e.priority??0})).toSorted((e,t)=>e.name.localeCompare(t.name))}function toComparableApplication(e){return{authNamespace:e.authNamespace,authIdpConfigName:e.authIdpConfigName,cors:sortStrings(e.cors),subgraphs:[...e.subgraphs],allowedIpAddresses:sortStrings(e.allowedIpAddresses),disableIntrospection:e.disableIntrospection,disabled:e.disabled,httpAdapters:[...e.httpAdapters]}}function normalizeComparableApplication(e,t,n,r,i){return toComparableApplication({authNamespace:t??``,authIdpConfigName:n??``,cors:r,subgraphs:normalizeSubgraphs(e.subgraphs.map(e=>protoSubgraph(e))),allowedIpAddresses:e.config.allowedIpAddresses??[],disableIntrospection:e.config.disableIntrospection??!1,disabled:!1,httpAdapters:normalizeHttpAdapters(i)})}function normalizeComparableExistingApplication(e){return toComparableApplication({authNamespace:e.authNamespace,authIdpConfigName:e.authIdpConfigName,cors:e.cors,subgraphs:normalizeSubgraphs(e.subgraphs),allowedIpAddresses:e.allowedIpAddresses,disableIntrospection:e.disableIntrospection,disabled:e.disabled,httpAdapters:normalizeHttpAdapters(e.httpAdapters)})}function areApplicationsEqual(e,t){return areNormalizedEqual(normalizeComparableExistingApplication(e),t)}async function planApplication(e,t){let{client:n,workspaceId:r,application:i,forRemoval:a}=e,o=[],s=[],c=new Set,l=createChangeSet(`Applications`),u=await P(async(e,t)=>{let{applications:i,nextPageToken:a}=await n.listApplications({workspaceId:r,pageToken:e,pageSize:t});return[i,a]});if(a){let e=i.id?u:u.filter(e=>e.name===i.name),t=await Promise.all(e.map(async e=>{let t=await fetchAppLabels(n,r,e.name);return trackRemainingResourceOwner({labels:t,ownerLabel:t?.[`sdk-name`],appName:i.name,appId:i.id,resourceOwners:c})?e.name:null}));for(let e of t)e&&l.deletes.push({name:e,request:{workspaceId:r,applicationName:e}});return withOwnership(l,o,s,c)}if(i.subgraphs.length===0)return withOwnership(l,o,s,c);let d,f;if(i.authService){d=i.authService.config.name;let e=i.authService.config.idProvider;e&&(f=e.name)}else if(i.config.auth){if(d=i.config.auth.name,e.externalAuthIdpConfigNames?.has(d))f=e.externalAuthIdpConfigNames.get(d);else{let e=await P(async(e,t)=>{let{idpConfigs:i,nextPageToken:a}=await n.listAuthIDPConfigs({workspaceId:r,namespaceName:A(d,`authNamespace must be set before listing IDP configs`),pageToken:e,pageSize:t});return[i,a]});if(e.length>0){let[t]=e;t&&(f=t.name)}}}let p=await buildMetaRequest({trn:resourceTrn(r,`application`,i.name),appName:i.name,appId:i.id}),m=await fetchAppLabels(n,r,i.name),h=expectedLocalStaticWebsiteNames(e),g=await Xt(n,r,i.config.cors,`CORS`,{expectedLocalNames:h}),_=buildHttpAdapters(i,t),v=normalizeComparableApplication(i,d,f,g,_),y={workspaceId:r,applicationName:i.name,authNamespace:d,authIdpConfigName:f,cors:i.config.cors,subgraphs:i.subgraphs.map(e=>protoSubgraph(e)),allowedIpAddresses:i.config.allowedIpAddresses,disableIntrospection:i.config.disableIntrospection,httpAdapters:_},b=u.find(e=>e.name===i.name);if(i.id){let e=u.filter(e=>e.name!==i.name),t=await Promise.all(e.map(async e=>isOwnedByApp(await fetchAppLabels(n,r,e.name),i.name,i.id)?e.name:null));for(let e of t)e&&l.deletes.push({name:e,request:{workspaceId:r,applicationName:e}})}if(b){let e=trackDesiredResourceOwnership({labels:m,ownerLabel:m?.[yi],appName:i.name,appId:i.id,resourceType:`Application`,resourceName:i.name,conflicts:o,unmanaged:s}),t={name:i.name,request:y,metaRequest:p};if(e&&hasMatchingSdkVersion(m,p.labels)&&areApplicationsEqual(b,v))l.unchanged.push(t);else{let e=diffHttpAdapterDisplay(b.httpAdapters,_);e.length>0&&(t.details=e),l.updates.push(t)}}else{let e=diffHttpAdapterDisplay(void 0,_);l.creates.push({name:i.name,request:y,metaRequest:p,details:e.length>0?e:void 0})}return withOwnership(l,o,s,c)}function withOwnership(e,t,n,r){return Object.assign(e,{conflicts:t,unmanaged:n,resourceOwners:r})}async function fetchAppLabels(e,t,n){return(await I(async()=>{let{metadata:r}=await e.getMetadata({trn:resourceTrn(t,`application`,n)});return r}))?.labels}function diffHttpAdapterDisplay(e,t){let n=new Map((e??[]).map(e=>[e.name??``,e])),r=new Map(t.map(e=>[e.name??``,e])),i=[];for(let[e,t]of r){let r=n.get(e);r?areNormalizedEqual(normalizeHttpAdapters([r])[0],normalizeHttpAdapters([t])[0])||i.push({name:e,symbol:j.update}):i.push({name:e,symbol:j.create})}for(let e of n.keys())r.has(e)||i.push({name:e,symbol:j.delete});return i.toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>`${e.symbol} ${e.name} (httpAdapter)`)}function buildHttpAdapters(e,t){let n=e.httpAdapterService?.adapters??[];return n.length===0?[]:n.map(e=>{let n=t?.bundledInputs.get(e.adapter.name);if(!n)throw Error(`HTTP adapter "${e.adapter.name}" was loaded but no bundled input script is available`);let r=``;if(e.hasOutput){let n=t?.bundledOutputs.get(e.adapter.name);if(!n)throw Error(`HTTP adapter "${e.adapter.name}" declares an output handler but no bundled output script is available`);r=n}return{name:e.adapter.name,pathPattern:e.adapter.pathPattern,methods:e.methods.map(e=>qt[e]),inputScript:n,outputScript:r,enabled:e.adapter.enabled,priority:e.adapter.priority}})}function protoSubgraph(e){let t;switch(e.Type){case`tailordb`:t=m.TAILORDB;break;case`pipeline`:t=m.PIPELINE;break;case`idp`:t=m.IDP;break;case`auth`:t=m.AUTH;break;default:throw Error(`Unknown subgraph type: ${e.Type}`)}return{serviceType:t,serviceNamespace:e.Name}}const wi=H.object({hash:H.string(),updateTime:H.string().optional()}),Ti=H.object({vaults:H.record(H.string(),H.record(H.string(),wi)),connections:H.record(H.string(),H.string()).optional()}),Ei=H.object({version:H.literal(2),workspaceId:H.string(),applicationKey:H.string(),state:Ti});function getSecretsStatePath(e){let t=hashValue(JSON.stringify([e.workspaceId,applicationStateKey(e)]));return B.join(Gt(),`secrets-state`,`${t}.json`)}function loadPersistedSecretsState(e){try{let t=Hn(getSecretsStatePath(e),`utf-8`),n=Ei.parse(JSON.parse(t));return n.workspaceId!==e.workspaceId||n.applicationKey!==applicationStateKey(e)?void 0:n}catch{return}}function applicationStateKey(e){if(!e.applicationId)throw Error(`Application "${e.applicationName}" has no stable id for secrets state`);return`id:${e.applicationId}`}function loadSecretsState(e){return e.applicationId?loadPersistedSecretsState(e)?.state??{vaults:{}}:{vaults:{}}}function saveSecretsState(e,t){if(!e.applicationId)return;let n=getSecretsStatePath(e),r=B.dirname(n);Vn(r,{recursive:!0});let i=`${n}.tmp-${or()}`;qn(i,JSON.stringify({version:2,workspaceId:e.workspaceId,applicationKey:applicationStateKey(e),state:t},null,2),`utf-8`),Un(i,n)}function hashValue(e){return ar(`sha256`).update(e).digest(`hex`)}function serializeUpdateTime(e){return e===void 0?void 0:`${e.seconds}.${e.nanos}`}const Di=new Map;async function withSecretsStateLock(e,t){if(!e.applicationId)return t();let n=`${getSecretsStatePath(e)}.lock`,r=Di.get(n);return r||(r=rr(1),Di.set(n,r)),r(async()=>{let e=await acquireFileLock(n),r=setInterval(()=>refreshLock(n,e),1e4);r.unref();try{return await t()}finally{clearInterval(r),releaseFileLock(n,e)}})}async function acquireFileLock(e){Vn(B.dirname(e),{recursive:!0});let t=or(),n=Date.now()+3e5;for(;;){let r=!0;try{Vn(e)}catch(e){if(e.code!==`EEXIST`)throw e;r=!1}if(r){try{qn(B.join(e,`owner.json`),JSON.stringify({pid:process.pid,token:t}))}catch(t){throw Wn(e,{recursive:!0,force:!0}),t}return t}if(!(isLockExpired(e)&&stealLock(e))){if(Date.now()>=n)throw Error(`Timed out waiting for another deploy to the same workspace and application to finish. Wait for it to complete and retry; an interrupted deploy recovers automatically within a minute.`);await new Promise(e=>setTimeout(e,100))}}}function isLockExpired(e){try{return Date.now()-Gn(e).mtimeMs>6e4}catch{return!1}}function readLockToken(e){try{return JSON.parse(Hn(B.join(e,`owner.json`),`utf-8`)).token}catch{return}}function refreshLock(e,t){if(readLockToken(e)!==t)return;let n=new Date;try{Kn(e,n,n)}catch{}}function releaseFileLock(e,t){readLockToken(e)===t&&Wn(e,{recursive:!0,force:!0})}function stealLock(e){let t=`${e}.stale-${process.pid}-${Date.now()}`;try{Un(e,t)}catch{return!1}if(isLockExpired(t))return Wn(t,{recursive:!0,force:!0}),!0;try{Un(t,e)}catch{Wn(t,{recursive:!0,force:!0})}return!1}function buildConnectionRequest(e,t,n){return{workspaceId:e,connection:{name:t,type:rt.OAUTH2,config:{case:`oauth2`,value:{providerUrl:n.providerUrl,issuerUrl:n.issuerUrl,clientId:n.clientId,clientSecret:n.clientSecret,authUrl:n.authUrl??``,tokenUrl:n.tokenUrl??``}}}}}function buildUpdateMask(e,t,n){if(e.config.case!==`oauth2`){let e=[`type`,`oauth2.provider_url`,`oauth2.issuer_url`,`oauth2.client_id`,`oauth2.auth_url`,`oauth2.token_url`];return t.clientSecret&&e.push(`oauth2.client_secret`),{paths:e}}let r=[],i=e.config.value;return i.providerUrl!==t.providerUrl&&r.push(`oauth2.provider_url`),i.issuerUrl!==t.issuerUrl&&r.push(`oauth2.issuer_url`),i.clientId!==t.clientId&&r.push(`oauth2.client_id`),i.authUrl!==(t.authUrl??``)&&r.push(`oauth2.auth_url`),i.tokenUrl!==(t.tokenUrl??``)&&r.push(`oauth2.token_url`),n&&t.clientSecret&&r.push(`oauth2.client_secret`),{paths:r}}async function planAuthConnections(e,t,n,r,i){let a={workspaceId:t,applicationId:r,applicationName:n},o=createChangeSet(`Auth connections`),s=[],c=[],l=new Set,u={};for(let e of i)for(let[t,n]of Object.entries(e.connections))u[t]=n;let d=await P(async(n,r)=>{let{connections:i,nextPageToken:a}=await e.listAuthConnections({workspaceId:t,pageToken:n,pageSize:r});return[i,a]}),f={};await Promise.all(d.map(async n=>{let{metadata:r}=await e.getMetadata({trn:resourceTrn(t,`auth_connection`,n.name)});f[n.name]={resource:n,label:r?.labels[yi],allLabels:r?.labels}}));let p=loadSecretsState(a);for(let[e,i]of Object.entries(u)){let a=f[e],l=await buildMetaRequest({trn:resourceTrn(t,`auth_connection`,e),appName:n,appId:r});if(a){let u=trackDesiredResourceOwnership({labels:a.allLabels,ownerLabel:a.label,appName:n,appId:r,resourceType:`Auth connection`,resourceName:e,conflicts:s,unmanaged:c}),d=hashValue(i.clientSecret)!==p.connections?.[e],m=buildUpdateMask(a.resource,i,d);m.paths.length>0?o.replaces.push({name:e,updateRequest:{...buildConnectionRequest(t,e,i),updateMask:m},metaRequest:l}):u?o.unchanged.push({name:e}):o.updates.push({name:e,metaRequest:l}),delete f[e]}else o.creates.push({name:e,request:buildConnectionRequest(t,e,i),metaRequest:l})}for(let[e,i]of Object.entries(f))i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceOwners:l})&&o.deletes.push({name:e,request:{workspaceId:t,connectionName:e}});return{changeSet:o,conflicts:s,unmanaged:c,resourceOwners:l,stateScope:a}}async function applyAuthConnections(e,t,n){let{changeSet:r,stateScope:i}=t;n===`create-update`?((r.creates.length>0||r.replaces.length>0)&&await withSecretsStateLock(i,async()=>{await Promise.all(r.creates.map(async t=>{await e.createAuthConnection(t.request),await writeMetadataLabels(e,t.metaRequest),M.info(`Connection "${t.name}" was created. Authorize it with:\n tailor authconnection authorize --name ${t.name}\nOr via the Console: tailor authconnection open`)}));for(let t of r.replaces)(await e.updateAuthConnection(t.updateRequest)).connection?.status===o.UNAUTHORIZED&&M.warn(`Connection "${t.name}" requires re-authorization. Authorize with:\n tailor authconnection authorize --name ${t.name}\nOr via the Console: tailor authconnection open`),await writeMetadataLabels(e,t.metaRequest);let t=r.replaces.filter(e=>e.updateRequest.updateMask?.paths?.includes(`oauth2.client_secret`));if(r.creates.length>0||t.length>0){let e=loadSecretsState(i);e.connections||={};for(let t of r.creates){let n=t.request.connection;n?.config?.case===`oauth2`&&(e.connections[t.name]=hashValue(n.config.value.clientSecret??``))}for(let n of t){let t=n.updateRequest.connection;t?.config?.case===`oauth2`&&(e.connections[n.name]=hashValue(t.config.value.clientSecret??``))}saveSecretsState(i,e)}}),await Promise.all(r.updates.map(async t=>{await writeMetadataLabels(e,t.metaRequest)}))):r.deletes.length>0&&await withSecretsStateLock(i,async()=>{await Promise.all(r.deletes.map(async t=>{await e.deleteAuthConnection(t.request)}));let t=loadSecretsState(i);if(t.connections){for(let e of r.deletes)delete t.connections[e.name];saveSecretsState(i,t)}})}const Oi=65536;function computeContentHash(e){return ir.createHash(`sha256`).update(e,`utf-8`).digest(`hex`)}const ki=`workflow--`;function resolverFunctionName(e,t){return`resolver--${e}--${t}`}function executorFunctionName(e){return`executor--${e}`}function workflowJobFunctionName(e){return`${ki}${e}`}function splitFunctionRegistryChanges(e){function partition(e){let t={workflowJob:[],resolver:[],executor:[],authHook:[],other:[]};for(let n of e)n.name.startsWith(`workflow--`)?t.workflowJob.push(n):n.name.startsWith(`resolver--`)?t.resolver.push(n):n.name.startsWith(`executor--`)?t.executor.push(n):n.name.startsWith(`auth-hook--`)?t.authHook.push(n):t.other.push(n);return t}let t=partition(e.creates),n=partition(e.updates),r=partition(e.deletes),i=partition(e.replaces),a=partition(e.unchanged);function collect(e){return{creates:t[e],updates:n[e],deletes:r[e],replaces:i[e],unchanged:a[e]}}return{workflowJobChanges:collect(`workflowJob`),resolverFunctionChanges:collect(`resolver`),executorFunctionChanges:collect(`executor`),authHookFunctionChanges:collect(`authHook`),otherChanges:collect(`other`)}}function authHookFunctionName(e,t){return`auth-hook--${e}--${t}`}function collectFunctionEntries(e,t,n){let r=[];for(let t of e.applications)for(let e of t.resolverServices)for(let t of Object.values(e.resolvers)){let i=n.resolvers.get(Bt(e.namespace,t.name));if(!i){M.warn(`Bundled code not found for resolver: ${e.namespace}/${t.name}`);continue}r.push({name:resolverFunctionName(e.namespace,t.name),scriptContent:i,contentHash:computeContentHash(i),description:`Resolver: ${e.namespace}/${t.name}`})}if(e.executorService){let t=e.executorService.executors;for(let e of Object.values(t))if(e.operation.kind===`function`||e.operation.kind===`jobFunction`){let t=n.executors.get(e.name);if(!t){M.warn(`Bundled code not found for executor: ${e.name}`);continue}r.push({name:executorFunctionName(e.name),scriptContent:t,contentHash:computeContentHash(t),description:`Executor: ${e.name}`})}}for(let e of t){let t=n.workflowJobs.get(e.name);if(!t){M.warn(`Bundled code not found for workflow job: ${e.name}`);continue}r.push({name:workflowJobFunctionName(e.name),scriptContent:t,contentHash:computeContentHash(t),description:`Workflow job: ${e.name}`})}for(let t of e.applications)if(t.authService?.config.hooks?.beforeLogin){let e=t.authService.config.name,i=authHookFunctionName(e,`before-login`),a=n.authHooks.get(i);if(!a){M.warn(`Bundled code not found for auth hook: ${i}`);continue}r.push({name:i,scriptContent:a,contentHash:computeContentHash(a),description:`Auth hook: ${e}/before-login`})}return r}function filterBundledWorkflowJobs(e,t){let n=new Set(t);return e.filter(e=>n.has(e.name))}async function planFunctionRegistry(e,t,n,r,i){let a=createChangeSet(`Function registry`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let i=await e.listFunctionRegistries({workspaceId:t,pageToken:n,pageSize:r});return[i.functions.map(e=>({name:e.name,contentHash:e.contentHash})),i.nextPageToken]},getName:e=>e.name,getTrn:e=>resourceTrn(t,`function_registry`,e)});for(let e of i){let i=l[e.name],c=await buildMetaRequest({trn:resourceTrn(t,`function_registry`,e.name),appName:n,appId:r});if(i){let t=trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceType:`Function registry`,resourceName:e.name,conflicts:o,unmanaged:s});i.resource.contentHash===e.contentHash&&t&&hasMatchingSdkVersion(i.allLabels,c.labels)?a.unchanged.push({name:e.name}):a.updates.push({name:e.name,entry:e,metaRequest:c}),delete l[e.name]}else a.creates.push({name:e.name,entry:e,metaRequest:c})}for(let[e,i]of Object.entries(l))i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceOwners:c})&&a.deletes.push({name:e,workspaceId:t});let{workflowJobChanges:u,resolverFunctionChanges:d,executorFunctionChanges:f,authHookFunctionChanges:p}=splitFunctionRegistryChanges(a);return{changeSet:a,workflowJobChanges:u,resolverFunctionChanges:d,executorFunctionChanges:f,authHookFunctionChanges:p,conflicts:o,unmanaged:s,resourceOwners:c}}async function uploadFunctionScript(e,t,n,r){let i=Buffer.from(n.scriptContent,`utf-8`),a={workspaceId:t,name:n.name,description:n.description,sizeBytes:BigInt(i.length),contentHash:n.contentHash};if(r){async function*createStream(){yield{payload:{case:`info`,value:a}};for(let e=0;e<i.length;e+=Oi)yield{payload:{case:`chunk`,value:i.subarray(e,Math.min(e+Oi,i.length))}}}await e.createFunctionRegistry(createStream())}else{async function*updateStream(){yield{payload:{case:`info`,value:a}};for(let e=0;e<i.length;e+=Oi)yield{payload:{case:`chunk`,value:i.subarray(e,Math.min(e+Oi,i.length))}}}await e.updateFunctionRegistry(updateStream())}}async function applyFunctionRegistry(e,t,n,r=`create-update`){let{changeSet:i}=n;if(r===`create-update`){let n=Pt();await Promise.all([...i.creates.map(r=>n(async()=>{await uploadFunctionScript(e,t,r.entry,!0),await writeMetadataLabels(e,r.metaRequest)})),...i.updates.map(r=>n(async()=>{await uploadFunctionScript(e,t,r.entry,!1),await writeMetadataLabels(e,r.metaRequest)}))])}else await Promise.all(i.deletes.map(t=>e.deleteFunctionRegistry({workspaceId:t.workspaceId,name:t.name})))}function createRelatedFunctionRegistryNameSets(e){return{creates:new Set(e?.creates.map(e=>e.name)??[]),updates:new Set(e?.updates.map(e=>e.name)??[]),deletes:new Set(e?.deletes.map(e=>e.name)??[]),replaces:new Set(e?.replaces.map(e=>e.name)??[])}}const Ai={create:j.create,update:j.update,delete:j.delete,replace:j.replace};function formatChangeSetEntries(e,t=[],n){function toEntry(e,r){return{action:e,symbol:Ai[e],name:r.name,labels:[...t],namespace:n?.(r)}}return[...e.creates.map(e=>toEntry(`create`,e)),...e.deletes.map(e=>toEntry(`delete`,e)),...e.updates.map(e=>toEntry(`update`,e)),...e.replaces.map(e=>toEntry(`replace`,e))]}function formatGroupedDisplayLine(e){return e.labels.length>0?`${e.symbol} ${e.name} (${e.labels.join(`, `)})`:`${e.symbol} ${e.name}`}function parseFunctionRegistryName(e){if(e.startsWith(`resolver--`)){let[,t,n]=e.split(`--`);if(t&&n)return{displayName:n,namespace:t}}if(e.startsWith(`workflow--`)||e.startsWith(`executor--`))return{displayName:e.slice(10)};if(e.startsWith(`auth-hook--`)){let[,t,n]=e.split(`--`);if(t&&n)return{displayName:n,namespace:t}}return{displayName:e}}function buildRemainingFunctionRegistryEntries(e,t=createRelatedFunctionRegistryNameSets()){return[[`create`,e.creates,t.creates],[`delete`,e.deletes,t.deletes],[`update`,e.updates,t.updates],[`replace`,e.replaces,t.replaces]].flatMap(([e,t,n])=>[...t].filter(e=>!n.has(e)).map(t=>{let{displayName:n,namespace:r}=parseFunctionRegistryName(t);return{action:e,symbol:Ai[e],name:n,labels:[`function`],namespace:r}}))}function formatChangeEntriesWithFunctionRegistry(e,t,n,r,i){let{getNamespace:a,getDisplayName:o}=i??{},s=createRelatedFunctionRegistryNameSets(n),c=createRelatedFunctionRegistryNameSets();function processItems(t,n,i,s){return t.map(t=>{let c=r(t,n),l=c.some(e=>i.has(e));if(l)for(let e of c)i.has(e)&&s.add(e);return{action:n,symbol:Ai[n],name:o?.(t)??t.name,labels:l?[e,`function`]:[e],namespace:a?.(t)}})}return[...processItems(t.creates,`create`,s.creates,c.creates),...processItems(t.deletes,`delete`,s.deletes,c.deletes),...processItems(t.updates,`update`,s.updates,c.updates),...t.replaces.map(t=>({action:`replace`,symbol:Ai.replace,name:o?.(t)??t.name,labels:[e],namespace:a?.(t)})),...buildRemainingFunctionRegistryEntries(s,c)]}function extractServiceActions(e){return[...e.creates.map(e=>({name:e.name,action:`create`})),...e.deletes.map(e=>({name:e.name,action:`delete`})),...e.updates.map(e=>({name:e.name,action:`update`})),...e.replaces.map(e=>({name:e.name,action:`replace`}))]}function buildGroupedDisplayLines(e,t,n){let r=new Map;if(n)for(let e of n)r.set(e.name,e.action);if(t.length===0&&r.size===0)return[];let i=[N.bold(`${e}:`)],a=[],o=new Map;for(let e of t){let t=e.namespace;o.has(t)||(a.push(t),o.set(t,[])),A(o.get(t),`namespace group missing`).push(e)}let s=new Set;for(let e of a){let t=A(o.get(e),`namespace group missing`);if(e){let n=r.get(e),a=n?`${Ai[n]} `:``;i.push(` ${a}${N.bold(`${e}:`)}`),s.add(e);for(let e of t)i.push(` ${formatGroupedDisplayLine(e)}`)}else for(let e of t)i.push(` ${formatGroupedDisplayLine(e)}`)}for(let[e,t]of r)s.has(e)||i.push(` ${Ai[t]} ${e}`);return i}const ji={tailorDBType:e=>`TailorDB table "${e}"`,resolver:e=>`Resolver "${e}"`,idpService:e=>`IdP service "${e}"`,workflow:e=>`Workflow "${e}"`,workflowJob:e=>`Job "${e}"`,workflowJobs:e=>`Jobs of workflow "${e}"`},Mi={tailorDBType:e=>({resource:ji.tailorDBType(e),trigger:`record`}),resolver:e=>({resource:ji.resolver(e),trigger:`resolverExecuted`}),idpService:e=>({resource:ji.idpService(e),trigger:`idpUser`}),workflow:e=>({resource:ji.workflow(e),trigger:`workflowExecution`}),workflowJob:e=>({resource:ji.workflowJob(e),trigger:`workflowJobExecution`,subscribesTo:`a workflow that runs it`})};function publishEventsConflictError(e){let{resource:t,trigger:n,subscribesTo:r=`it`}=e;return`${t} has "publishEvents: false", but executors with ${n} triggers subscribe to ${r}. Either remove "publishEvents: false" or remove the matching executor triggers.`}function subscribesToEvents(e){return!e.disabled}function assertNoPublishEventsConflict(e){let{explicit:t,subscribed:n,conflict:r}=e;if(t===!1&&n)throw Error(publishEventsConflictError(r))}function resolvePublishEvents(e){return assertNoPublishEventsConflict(e),e.explicit??e.subscribed}const{normalizeActionPermission:Ni}=Ft({"=":`eq`,"!=":`ne`,in:`in`,"not in":`nin`});function normalizeIdPActionPermission(e){return Ni(e)}function normalizeIdPPermission(e){return{create:e.create.map(e=>normalizeIdPActionPermission(e)),read:e.read.map(e=>normalizeIdPActionPermission(e)),update:e.update.map(e=>normalizeIdPActionPermission(e)),delete:e.delete.map(e=>normalizeIdPActionPermission(e)),sendPasswordResetEmail:(e.sendPasswordResetEmail??[]).map(e=>normalizeIdPActionPermission(e)),unenrollMfa:(e.unenrollMfa??[]).map(e=>normalizeIdPActionPermission(e))}}function parseIdPPermission(e){if(e)return normalizeIdPPermission(e)}function findOmittedPermitRules(e){if(!e)return[];let t=[];for(let n of Object.keys(e))e[n]?.forEach((e,r)=>{nn(e)&&t.push(`${String(n)}[${r}]`)});return t}async function resolveServiceReturnOrigins(e,t){let n=t.userAuthPolicy,r=n?.allowedReturnOrigins;if(!n||!r?.length)return;let i=await Xt(e,A(t.workspaceId,`request missing workspaceId`),r,`IdP service "${t.namespaceName??``}" allowedReturnOrigins`);if(i.length!==r.length)throw Error(`IdP service "${t.namespaceName??``}" allowedReturnOrigins: ${r.length-i.length} of ${r.length} entries could not be resolved. Check that each "<name>:url" entry refers to a deployed static website.`);n.allowedReturnOrigins=i}function idpClientVaultName(e,t){return`idp-${e}-${t}`}function idpClientSecretName(e,t){return`client-secret-${e}-${t}`}async function applyIdP(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?(await Promise.all([...r.service.creates.map(async t=>{await resolveServiceReturnOrigins(e,t.request),await e.createIdPService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await resolveServiceReturnOrigins(e,t.request),await e.updateIdPService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.unchanged.flatMap(t=>t.metaRequest?[writeMetadataLabels(e,t.metaRequest)]:[])]),await Promise.all([...r.client.creates.map(async t=>{let n=await e.createIdPClient(t.request),r=idpClientVaultName(A(t.request.namespaceName,`request missing namespaceName`),t.request.client?.name||``),i=idpClientSecretName(A(t.request.namespaceName,`request missing namespaceName`),t.request.client?.name||``);await e.createSecretManagerVault({workspaceId:t.request.workspaceId,secretmanagerVaultName:r}),await e.createSecretManagerSecret({workspaceId:t.request.workspaceId,secretmanagerVaultName:r,secretmanagerSecretName:i,secretmanagerSecretValue:n.client?.clientSecret})}),...r.client.updates.map(async t=>{let n=idpClientVaultName(t.namespaceName,t.name),r=idpClientSecretName(t.namespaceName,t.name);await I(async()=>await e.getSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:n}))||(await e.createSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:n}),await e.createSecretManagerSecret({workspaceId:t.workspaceId,secretmanagerVaultName:n,secretmanagerSecretName:r,secretmanagerSecretValue:t.clientSecret}))})])):n===`delete-resources`?await Promise.all(r.client.deletes.map(async t=>{await e.deleteIdPClient(t.request);let n=`idp-${t.request.namespaceName}-${t.request.name}`;await e.deleteSecretManagerVault({workspaceId:t.request.workspaceId,secretmanagerVaultName:n})})):await Promise.all(r.service.deletes.map(t=>e.deleteIdPService(t.request)))}async function planIdP(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1,idpUserTriggerTargets:o,dependentApps:s,runAppIds:c}=e,l=i?[]:r.idpServices,u=expectedLocalStaticWebsiteNames(e),{changeSet:d,conflicts:f,unmanaged:p,resourceOwners:m}=await planServices$3(t,n,r.name,r.id,l,o??new Set,u,{dependentApps:s,runAppIds:c});return{changeSet:{service:d,client:await planClients(t,n,l,d.deletes.map(e=>e.name),a)},conflicts:f,unmanaged:p,resourceOwners:m}}function normalizeComparableUserAuthPolicy(e){return{useNonEmailIdentifier:e?.useNonEmailIdentifier??!1,allowSelfPasswordReset:e?.allowSelfPasswordReset??!1,passwordRequireUppercase:e?.passwordRequireUppercase??!1,passwordRequireLowercase:e?.passwordRequireLowercase??!1,passwordRequireNonAlphanumeric:e?.passwordRequireNonAlphanumeric??!1,passwordRequireNumeric:e?.passwordRequireNumeric??!1,passwordMinLength:e?.passwordMinLength||6,passwordMaxLength:e?.passwordMaxLength||4096,allowedEmailDomains:(e?.allowedEmailDomains??[]).toSorted(),allowGoogleOauth:e?.allowGoogleOauth??!1,disablePasswordAuth:e?.disablePasswordAuth??!1,allowMicrosoftOauth:e?.allowMicrosoftOauth??!1,enableMfa:e?.enableMfa??!1,requireMfa:e?.requireMfa??!1,allowedReturnOrigins:(e?.allowedReturnOrigins??[]).toSorted(),mfaIssuer:e?.mfaIssuer??``}}function normalizeComparableDisableGqlOperations(e){return{create:e?.create??!1,update:e?.update??!1,delete:e?.delete??!1,read:e?.read??!1,sendPasswordResetEmail:e?.sendPasswordResetEmail??!1,requestMfaSettingsUrl:e?.requestMfaSettingsUrl??!1,unenrollMfa:e?.unenrollMfa??!1}}function normalizeComparableEmailConfig(e){return{fromName:e?.fromName??``,passwordResetSubject:e?.passwordResetSubject??``}}function normalizeComparableIdPService(e){return{authorization:e.authorization||void 0,lang:e.lang===oe.UNSPECIFIED?oe.EN:e.lang,userAuthPolicy:e.userAuthPolicy,publishEvents:e.publishEvents,disableGqlOperations:e.disableGqlOperations,emailConfig:e.emailConfig,permission:e.permission}}function normalizeComparablePermission(e){if(!e||e.create.length===0&&e.read.length===0&&e.update.length===0&&e.delete.length===0&&e.sendPasswordResetEmail.length===0&&e.unenrollMfa.length===0)return;let normalizePolicy=e=>({conditions:e.conditions.map(e=>({left:e.left?{kind:e.left.kind}:void 0,operator:e.operator,right:e.right?{kind:e.right.kind}:void 0})),permit:e.permit,description:e.description||void 0});return{create:e.create.map(normalizePolicy),read:e.read.map(normalizePolicy),update:e.update.map(normalizePolicy),delete:e.delete.map(normalizePolicy),sendPasswordResetEmail:e.sendPasswordResetEmail.map(normalizePolicy),unenrollMfa:e.unenrollMfa.map(normalizePolicy)}}function areIdPServicesEqual(e,t){return areNormalizedEqual(normalizeComparableIdPService({authorization:e.authorization,lang:e.lang,userAuthPolicy:normalizeComparableUserAuthPolicy(e.userAuthPolicy),publishEvents:e.publishUserEvents,disableGqlOperations:normalizeComparableDisableGqlOperations(e.disableGqlOperations),emailConfig:normalizeComparableEmailConfig(e.emailConfig),permission:normalizeComparablePermission(e.permission)}),t)}async function planServices$3(e,t,n,r,i,a,o,s){let c=createChangeSet(`IdP services`),l=[],u=[],d=new Set,f=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{idpServices:i,nextPageToken:a}=await e.listIdPServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`idp`,e)});for(let d of i){let i=d.name,p=f[i],m=addDependencyRecords(await buildMetaRequest({trn:resourceTrn(t,`idp`,i),appName:n,appId:r}),{key:Q.idp(i),dependentApps:s.dependentApps,runAppIds:s.runAppIds,pinned:d.publishEvents!==void 0}),h;switch(d.authorization){case`insecure`:h=`true==true`;break;case`loggedIn`:h=`user != null && size(user.id) > 0`;break;case void 0:h=void 0;break;default:h=d.authorization.cel}let g=convertLang(d.lang),_=d.userAuthPolicy,v=resolvePublishEvents({explicit:d.publishEvents,subscribed:a.has(i),conflict:Mi.idpService(i)}),y=d.emailConfig;d.permission||M.warn(`IdP service "${i}" has no permission configured.`);let b=findOmittedPermitRules(d.permission);b.length>0&&M.warn(`IdP service "${i}" has permission rule(s) ${b.join(`, `)} in object form without an explicit "permit"; they default to "deny". Set permit: true (allow) or permit: false (deny) to silence this warning.`);let x=parseIdPPermission(d.permission),S=x?protoIdPPermission(x):void 0,C=await Xt(e,t,_?.allowedReturnOrigins?[..._.allowedReturnOrigins]:[],`IdP service "${i}" allowedReturnOrigins`,{expectedLocalNames:o}),w=_&&{..._,allowedReturnOrigins:C},ee=normalizeComparableIdPService({authorization:h,lang:g,userAuthPolicy:normalizeComparableUserAuthPolicy(w),publishEvents:v,disableGqlOperations:normalizeComparableDisableGqlOperations(convertGqlOperationsToDisable(d.gqlOperations)),emailConfig:normalizeComparableEmailConfig(y),permission:S}),te={workspaceId:t,namespaceName:i,authorization:h,lang:g,userAuthPolicy:_,publishUserEvents:v,disableGqlOperations:convertGqlOperationsToDisable(d.gqlOperations),emailConfig:y,permission:S};p?(trackDesiredResourceOwnership({labels:p.allLabels,ownerLabel:p.label,appName:n,appId:r,resourceType:`IdP service`,resourceName:d.name,conflicts:l,unmanaged:u})&&hasMatchingSdkVersion(p.allLabels,m.labels)&&areIdPServicesEqual(p.resource,ee)?c.unchanged.push({name:i,metaRequest:m}):c.updates.push({name:i,request:te,metaRequest:m}),delete f[i]):c.creates.push({name:i,request:te,metaRequest:m})}return Object.entries(f).forEach(([e])=>{let i=f[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:d})&&c.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:c,conflicts:l,unmanaged:u,resourceOwners:d}}async function planClients(e,t,n,r,i=!1){let a=createChangeSet(`IdP clients`),fetchClients=n=>P(async(r,i)=>{let{clients:a,nextPageToken:o}=await e.listIdPClients({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}),o=await Promise.all(n.map(e=>fetchClients(e.name)));for(let[e,r]of n.entries()){let n=r.name,s=A(o[e],`clientsByIdp missing entry for idp index`),c=new Map;s.forEach(e=>{c.set(e.name,e.clientSecret)});for(let e of r.clients)c.has(e)?(i?a.updates.push({name:e,workspaceId:t,namespaceName:n,clientSecret:c.get(e)??``}):a.unchanged.push({name:e}),c.delete(e)):a.creates.push({name:e,request:{workspaceId:t,namespaceName:n,client:{name:e}}});c.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,namespaceName:n,name:r}})})}let s=await Promise.all(r.map(e=>fetchClients(e)));for(let[e,n]of r.entries())A(s[e],`deletedClientsByService missing entry for service index`).forEach(e=>{a.deletes.push({name:e.name,request:{workspaceId:t,namespaceName:n,name:e.name}})});return a}function convertLang(e){switch(e){case`en`:return oe.EN;case`ja`:return oe.JA;default:return oe.UNSPECIFIED}}function convertGqlOperationsToDisable(e){if(e)return{create:e.create===!1,update:e.update===!1,delete:e.delete===!1,read:e.read===!1,sendPasswordResetEmail:e.sendPasswordResetEmail===!1,requestMfaSettingsUrl:e.requestMfaSettingsUrl===!1,unenrollMfa:e.unenrollMfa===!1}}function protoIdPPermission(e){return{create:e.create.map(e=>protoIdPPolicy(e)),read:e.read.map(e=>protoIdPPolicy(e)),update:e.update.map(e=>protoIdPPolicy(e)),delete:e.delete.map(e=>protoIdPPolicy(e)),sendPasswordResetEmail:e.sendPasswordResetEmail.map(e=>protoIdPPolicy(e)),unenrollMfa:e.unenrollMfa.map(e=>protoIdPPolicy(e))}}function protoIdPPolicy(e){let t;switch(e.permit){case`allow`:t=u.ALLOW;break;case`deny`:t=u.DENY;break;default:throw Error(`Unknown permission: ${e.permit}`)}return{conditions:e.conditions.map(e=>protoIdPCondition(e)),permit:t,description:e.description}}function protoIdPCondition(e){let[t,n,r]=e,i=protoIdPOperand(t),a=protoIdPOperand(r),o;switch(n){case`eq`:o=le.EQ;break;case`ne`:o=le.NE;break;case`in`:o=le.IN;break;case`nin`:o=le.NIN;break;default:throw Error(`Unknown operator: ${n}`)}return{left:i,operator:o,right:a}}function protoIdPOperand(e){if(typeof e==`object`&&!Array.isArray(e)){if(`user`in e)return{kind:{case:`userField`,value:e.user}};if(`idpUser`in e)return{kind:{case:`idpUserField`,value:e.idpUser}};if(`newIdpUser`in e)return{kind:{case:`newIdpUserField`,value:e.newIdpUser}};if(`oldIdpUser`in e)return{kind:{case:`oldIdpUserField`,value:e.oldIdpUser}};throw Error(`Unknown operand: ${JSON.stringify(e)}`)}return{kind:{case:`value`,value:zn(Yn,e)}}}async function applyAuth(e,t,n=`create-update`){let{changeSet:r}=t;(n===`create-update-prerequisites`||n===`create-update`)&&(await(async()=>{await Promise.all([...r.service.creates.map(async t=>{await e.createAuthService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await e.updateAuthService(t.request),await writeMetadataLabels(e,t.metaRequest)})])})(),await(async()=>{await Promise.all([...r.machineUser.creates.map(t=>e.createAuthMachineUser(t.request)),...r.machineUser.updates.map(t=>e.updateAuthMachineUser(t.request))])})()),(n===`create-update-dependents`||n===`create-update`)&&await(async()=>{await applyAuthConnections(e,{changeSet:r.connection,stateScope:t.connectionStateScope},`create-update`),await Promise.all([...r.idpConfig.creates.map(async t=>(t.idpConfig.kind===`BuiltInIdP`&&(A(t.request.idpConfig,`request missing idpConfig`).config=await protoBuiltinIdPConfig(e,A(t.request.workspaceId,`request missing workspaceId`),t.idpConfig)),e.createAuthIDPConfig(t.request))),...r.idpConfig.updates.map(async t=>(t.idpConfig.kind===`BuiltInIdP`&&(A(t.request.idpConfig,`request missing idpConfig`).config=await protoBuiltinIdPConfig(e,A(t.request.workspaceId,`request missing workspaceId`),t.idpConfig)),e.updateAuthIDPConfig(t.request)))]),await Promise.all([...r.userProfileConfig.creates.map(t=>e.createUserProfileConfig(t.request)),...r.userProfileConfig.updates.map(t=>e.updateUserProfileConfig(t.request))]),await Promise.all([...r.tenantConfig.creates.map(t=>e.createTenantConfig(t.request)),...r.tenantConfig.updates.map(t=>e.updateTenantConfig(t.request))]),await Promise.all([...r.authHook.creates.map(t=>e.createAuthHook(t.request)),...r.authHook.updates.map(t=>e.updateAuthHook(t.request))]),await Promise.all([...r.oauth2Client.creates.map(async t=>{let n=A(t.request.oauth2Client,`request missing oauth2Client`);return n.redirectUris=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),e.createAuthOAuth2Client(t.request)}),...r.oauth2Client.updates.map(async t=>{let n=A(t.request.oauth2Client,`request missing oauth2Client`);return n.redirectUris=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),e.updateAuthOAuth2Client(t.request)})]);for(let t of r.oauth2Client.replaces){await e.deleteAuthOAuth2Client(t.deleteRequest);let n=A(t.createRequest.oauth2Client,`createRequest missing oauth2Client`);n.redirectUris=await Xt(e,A(t.createRequest.workspaceId,`createRequest missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),await e.createAuthOAuth2Client(t.createRequest)}await Promise.all([...r.scim.creates.map(t=>e.createAuthSCIMConfig(t.request)),...r.scim.updates.map(t=>e.updateAuthSCIMConfig(t.request))]),await Promise.all([...r.scimResource.creates.map(t=>e.createAuthSCIMResource(t.request)),...r.scimResource.updates.map(t=>e.updateAuthSCIMResource(t.request))])})(),n===`delete-resources`?(await Promise.all(r.scimResource.deletes.map(t=>e.deleteAuthSCIMResource(t.request))),await Promise.all(r.scim.deletes.map(t=>e.deleteAuthSCIMConfig(t.request))),await Promise.all(r.oauth2Client.deletes.map(t=>e.deleteAuthOAuth2Client(t.request))),await Promise.all(r.authHook.deletes.map(t=>e.deleteAuthHook(t.request))),await Promise.all(r.machineUser.deletes.map(t=>e.deleteAuthMachineUser(t.request))),await Promise.all(r.tenantConfig.deletes.map(t=>e.deleteTenantConfig(t.request))),await(async()=>{await Promise.all(r.userProfileConfig.deletes.map(t=>e.deleteUserProfileConfig(t.request)))})(),await Promise.all(r.idpConfig.deletes.map(t=>e.deleteAuthIDPConfig(t.request))),await applyAuthConnections(e,{changeSet:r.connection,stateScope:t.connectionStateScope},`delete-resources`)):n===`delete-services`&&await Promise.all(r.service.deletes.map(t=>e.deleteAuthService(t.request)))}async function planAuth(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=[];!i&&r.authService&&(await r.authService.resolveNamespaces(),o.push(r.authService));let{changeSet:s,conflicts:c,unmanaged:l,resourceOwners:u}=await planServices$2(t,n,r.name,r.id,o,a),d=s.deletes.map(e=>e.name),f=expectedLocalStaticWebsiteNames(e),[p,m,h,g,_,v,y,b,x]=await Promise.all([planIdPConfigs(t,n,o,d,a),planUserProfileConfigs(t,n,o,d,a),planTenantConfigs(t,n,o,d,a),planMachineUsers(t,n,o,d,a),planAuthHooks(t,n,o,d,a),planOAuth2Clients(t,n,o,d,f,a),planSCIMConfigs(t,n,o,d),planSCIMResources(t,n,o,d),planAuthConnections(t,n,r.name,r.id,o)]);return{changeSet:{service:s,idpConfig:p,userProfileConfig:m,tenantConfig:h,machineUser:g,authHook:_,oauth2Client:v,scim:y,scimResource:b,connection:x.changeSet},conflicts:[...c,...x.conflicts],unmanaged:[...l,...x.unmanaged],resourceOwners:new Set([...u,...x.resourceOwners]),connectionStateScope:x.stateScope}}async function planServices$2(e,t,n,r,i,a=!1){let o=createChangeSet(`Auth services`),s=[],c=[],l=new Set,u=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{authServices:i,nextPageToken:a}=await e.listAuthServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`auth`,e)});for(let e of i){let{config:i}=e,l=u[i.name],d=await buildMetaRequest({trn:resourceTrn(t,`auth`,i.name),appName:n,appId:r}),f={workspaceId:t,namespaceName:i.name,publishSessionEvents:i.publishSessionEvents};if(l){let e=trackDesiredResourceOwnership({labels:l.allLabels,ownerLabel:l.label,appName:n,appId:r,resourceType:`Auth service`,resourceName:i.name,conflicts:s,unmanaged:c});!a&&l.resource.publishSessionEvents===(i.publishSessionEvents??!1)&&e?o.unchanged.push({name:i.name}):o.updates.push({name:i.name,request:f,metaRequest:d}),delete u[i.name]}else o.creates.push({name:i.name,request:f,metaRequest:d})}return Object.entries(u).forEach(([e])=>{let i=u[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:l})&&o.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:o,conflicts:s,unmanaged:c,resourceOwners:l}}async function planIdPConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth idpConfigs`),fetchIdPConfigs=n=>P(async(r,i)=>{let{idpConfigs:a,nextPageToken:o}=await e.listAuthIDPConfigs({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]});for(let r of n){let{config:n}=r,o=await fetchIdPConfigs(n.name),s=new Map;o.forEach(e=>{s.set(e.name,e)});let c=n.idProvider;if(c){let r=protoIdPConfig(c),o=s.get(c.name);if(o){let l=await protoIdPConfigForComparison(e,t,c,r);if(!l){a.updates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}}),s.delete(c.name);continue}!i&&areAuthIdPConfigsEqual(o,l)?a.unchanged.push({name:c.name}):a.updates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}}),s.delete(c.name)}else a.creates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}})}s.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,namespaceName:n.name,name:r}})})}for(let e of r)(await fetchIdPConfigs(e)).forEach(n=>{a.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return a}async function protoIdPConfigForComparison(e,t,n,r){if(n.kind!==`BuiltInIdP`)return r;let i=await tryProtoBuiltinIdPConfig(e,t,n);return i?{name:r.name,authType:r.authType,config:i}:void 0}function normalizeComparableAuthIdPConfig(e){return toComparableProtoJson(l,e)}function areAuthIdPConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableAuthIdPConfig(e),normalizeComparableAuthIdPConfig(t))}function protoIdPConfig(e){switch(e.kind){case`IDToken`:return{name:e.name,authType:c.ID_TOKEN,config:{config:{case:`idToken`,value:{providerUrl:e.providerURL,clientId:e.clientID,issuerUrl:e.issuerURL,usernameClaim:e.usernameClaim}}}};case`SAML`:return{name:e.name,authType:c.SAML,config:{config:{case:`saml`,value:{...e.metadataURL===void 0?{rawMetadata:A(e.rawMetadata,`SAML config missing rawMetadata`)}:{metadataUrl:e.metadataURL},enableSignRequest:e.enableSignRequest,defaultRedirectUrl:e.defaultRedirectURL}}}};case`OIDC`:return{name:e.name,authType:c.OIDC,config:{config:{case:`oidc`,value:{clientIdKey:e.clientID,clientSecretKey:{vaultName:e.clientSecret.vaultName,secretKey:e.clientSecret.secretKey},providerUrl:e.providerURL,issuerUrl:e.issuerURL,usernameClaim:e.usernameClaim}}}};case`BuiltInIdP`:return{name:e.name,authType:c.OIDC,config:{}};default:throw Error(`Unexpected idp kind: ${e}`)}}async function protoBuiltinIdPConfig(e,t,n){let r=await tryProtoBuiltinIdPConfig(e,t,n);if(!r)throw Error(`Built-in IdP "${n.namespace}" not found. Please ensure that idp is configured correctly.`);return r}async function tryProtoBuiltinIdPConfig(e,t,n){let r=await I(async()=>await e.getIdPService({workspaceId:t,namespaceName:n.namespace}));if(!r)return;let i=await I(async()=>await e.getIdPClient({workspaceId:t,namespaceName:n.namespace,name:n.clientName}));if(!i)return;let a=idpClientVaultName(n.namespace,n.clientName),o=idpClientSecretName(n.namespace,n.clientName);return{config:{case:`oidc`,value:{clientIdKey:i.client?.clientId,clientSecretKey:{vaultName:a,secretKey:o},providerUrl:r.idpService?.providerUrl,usernameClaim:`name`}}}}async function planUserProfileConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth userProfileConfigs`);for(let r of n){let{config:n}=r,o=`${n.name}-user-profile-config`,s=await I(async()=>await e.getUserProfileConfig({workspaceId:t,namespaceName:n.name}));if(!s){let e=r.userProfile;e&&a.creates.push({name:o,request:{workspaceId:t,namespaceName:n.name,userProfileProviderConfig:protoUserProfileConfig(e)}});continue}let c=r.userProfile;if(c){let e=protoUserProfileConfig(c);!i&&areUserProfileConfigsEqual(s.userProfileProviderConfig??{},e)?a.unchanged.push({name:o}):a.updates.push({name:o,request:{workspaceId:t,namespaceName:n.name,userProfileProviderConfig:e}})}else a.deletes.push({name:o,request:{workspaceId:t,namespaceName:n.name}})}for(let n of r)await I(async()=>await e.getUserProfileConfig({workspaceId:t,namespaceName:n}))&&a.deletes.push({name:`${n}-user-profile-config`,request:{workspaceId:t,namespaceName:n}});return a}function protoUserProfileConfig(e){let t=e.attributes?Object.fromEntries(Object.keys(e.attributes).map(e=>[e,e])):void 0;return{provider:`TAILORDB`,providerType:st.TAILORDB,config:{config:{case:`tailordb`,value:{namespace:e.namespace,type:e.type.name,usernameField:e.usernameField,tenantIdField:void 0,attributesFields:e.attributeList,attributeMap:t}}}}}async function planTenantConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth tenantConfigs`);for(let r of n){let{config:n}=r,o=`${n.name}-tenant-config`,s=await I(async()=>await e.getTenantConfig({workspaceId:t,namespaceName:n.name}));if(!s){n.tenantProvider&&a.creates.push({name:o,request:{workspaceId:t,namespaceName:n.name,tenantProviderConfig:protoTenantConfig(n.tenantProvider)}});continue}if(n.tenantProvider){let e=protoTenantConfig(n.tenantProvider);!i&&areTenantProviderConfigsEqual(s.tenantProviderConfig,e)?a.unchanged.push({name:o}):a.updates.push({name:o,request:{workspaceId:t,namespaceName:n.name,tenantProviderConfig:e}})}else a.deletes.push({name:o,request:{workspaceId:t,namespaceName:n.name}})}for(let n of r)await I(async()=>await e.getTenantConfig({workspaceId:t,namespaceName:n}))&&a.deletes.push({name:`${n}-tenant-config`,request:{workspaceId:t,namespaceName:n}});return a}function protoTenantConfig(e){return{providerType:_.TAILORDB,config:{config:{case:`tailordb`,value:{namespace:e.namespace,type:e.type,signatureField:e.signatureField}}}}}async function planMachineUsers(e,t,n,r,i=!1){let a=createChangeSet(`Auth machineUsers`),fetchMachineUsers=n=>P(async(r,i)=>{let{machineUsers:a,nextPageToken:o}=await e.listAuthMachineUsers({workspaceId:t,authNamespace:n,pageToken:r,pageSize:i});return[a,o]});for(let e of n){let{config:n}=e,r=await fetchMachineUsers(n.name),o=new Map;r.forEach(e=>{o.set(e.name,e)});for(let e of Object.keys(n.machineUsers??{})){let r=n.machineUsers?.[e];if(!r)continue;let s={attributes:r.attributeList,attributeMap:r.attributes?protoMachineUserAttributeMap(r.attributes):void 0},c=o.get(e);c?(!i&&areMachineUsersEqual(c,s)?a.unchanged.push({name:e}):a.updates.push({name:e,request:{workspaceId:t,authNamespace:n.name,name:e,attributes:r.attributeList,attributeMap:s.attributeMap}}),o.delete(e)):a.creates.push({name:e,request:{workspaceId:t,authNamespace:n.name,name:e,attributes:r.attributeList,attributeMap:s.attributeMap}})}o.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,authNamespace:n.name,name:r}})})}for(let e of r)(await fetchMachineUsers(e)).forEach(n=>{a.deletes.push({name:n.name,request:{workspaceId:t,authNamespace:e,name:n.name}})});return a}function protoMachineUserAttributeMap(e){let t={};for(let[n,r]of Object.entries(e))t[n]=zn(Yn,r??null);return t}function normalizeComparableUserProfileConfig(e){let t=e.config?.config,n=t?.case===`tailordb`?t.value:void 0;return toComparableProtoJson(re,{providerType:e.providerType,config:n?{config:{case:`tailordb`,value:{...n,tenantIdField:n.tenantIdField||``,attributesFields:normalizeStringArray(n.attributesFields),attributeMap:normalizeProtoConfig(n.attributeMap??{})}}}:void 0})}function areUserProfileConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableUserProfileConfig(e),normalizeComparableUserProfileConfig(t))}function normalizeComparableTenantProviderConfig(e){return toComparableProtoJson(p,e??{})}function areTenantProviderConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableTenantProviderConfig(e),normalizeComparableTenantProviderConfig(t))}function normalizeComparableMachineUser(e){return normalizeProtoConfig({attributes:normalizeStringArray(e.attributes),attributeMap:normalizeProtoConfig(e.attributeMap??{})})}function areMachineUsersEqual(e,t){return areNormalizedEqual(normalizeComparableMachineUser(e),normalizeComparableMachineUser(t))}function normalizeComparableOAuth2Client(e){let t=oauth2LifetimeToSeconds(e.accessTokenLifetime),n=oauth2LifetimeToSeconds(e.refreshTokenLifetime);return normalizeProtoConfig({...e,description:e.description||void 0,redirectUris:normalizeStringArray(e.redirectUris),grantTypes:(e.grantTypes??[]).toSorted((e,t)=>e-t),accessTokenLifetime:t??86400,refreshTokenLifetime:n??604800,requireDpop:e.requireDpop??!1})}function oauth2LifetimeToSeconds(e){if(typeof e==`number`)return e;if(e?.seconds!=null)return Number(e.seconds)}function areOAuth2ClientsEqual(e,t){return areNormalizedEqual(normalizeComparableOAuth2Client(e),normalizeComparableOAuth2Client(t))}async function planOAuth2Clients(e,t,n,r,i,a=!1){let o=createChangeSet(`Auth oauth2Clients`),fetchOAuth2Clients=n=>P(async(r,i)=>{let{oauth2Clients:a,nextPageToken:o}=await e.listAuthOAuth2Clients({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]});for(let r of n){let{config:n}=r,s=await fetchOAuth2Clients(n.name),c=new Map;s.forEach(e=>{c.set(e.name,e)});for(let r of Object.keys(n.oauth2Clients??{})){let s=n.oauth2Clients?.[r];if(!s)continue;let l=protoOAuth2Client(r,s),u=await Xt(e,t,l.redirectUris??[],`OAuth2 redirect URIs`,{expectedLocalNames:i});if(c.has(r)){let e=A(c.get(r),`existingClientsMap missing entry for oauth2ClientName`);if(e.clientType!==l.clientType)o.replaces.push({name:r,deleteRequest:{workspaceId:t,namespaceName:n.name,name:r},createRequest:{workspaceId:t,namespaceName:n.name,oauth2Client:l}});else{let i={...l,redirectUris:u,accessTokenLifetime:oauth2LifetimeToSeconds(l.accessTokenLifetime),refreshTokenLifetime:oauth2LifetimeToSeconds(l.refreshTokenLifetime)},s={name:e.name,description:e.description,grantTypes:e.grantTypes,redirectUris:e.redirectUris,clientType:e.clientType,accessTokenLifetime:oauth2LifetimeToSeconds(e.accessTokenLifetime),refreshTokenLifetime:oauth2LifetimeToSeconds(e.refreshTokenLifetime),requireDpop:e.requireDpop};!a&&areOAuth2ClientsEqual(s,i)?o.unchanged.push({name:r}):o.updates.push({name:r,request:{workspaceId:t,namespaceName:n.name,oauth2Client:l}})}c.delete(r)}else o.creates.push({name:r,request:{workspaceId:t,namespaceName:n.name,oauth2Client:l}})}c.forEach((e,r)=>{o.deletes.push({name:r,request:{workspaceId:t,namespaceName:n.name,name:r}})})}for(let e of r)(await fetchOAuth2Clients(e)).forEach(n=>{o.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return o}function protoOAuth2Client(e,t){return{name:e,description:t.description,grantTypes:t.grantTypes.map(e=>{switch(e){case`authorization_code`:return r.AUTHORIZATION_CODE;case`refresh_token`:return r.REFRESH_TOKEN;default:throw Error(`Unknown OAuth2 client grant type: ${e}`)}}),redirectUris:t.redirectURIs,clientType:{confidential:Fe.CONFIDENTIAL,public:Fe.PUBLIC,browser:Fe.BROWSER}[t.clientType??`confidential`],accessTokenLifetime:t.accessTokenLifetimeSeconds,refreshTokenLifetime:t.refreshTokenLifetimeSeconds,requireDpop:t.requireDpop}}async function planSCIMConfigs(e,t,n,r){let i=createChangeSet(`Auth scimConfigs`);for(let r of n){let{config:n}=r,a=`${n.name}-scim-config`;await I(async()=>await e.getAuthSCIMConfig({workspaceId:t,namespaceName:n.name}))?n.scim?i.updates.push({name:a,request:{workspaceId:t,namespaceName:n.name,scimConfig:protoSCIMConfig(n.scim)}}):i.deletes.push({name:a,request:{workspaceId:t,namespaceName:n.name}}):n.scim&&i.creates.push({name:a,request:{workspaceId:t,namespaceName:n.name,scimConfig:protoSCIMConfig(n.scim)}})}for(let n of r)await I(async()=>await e.getAuthSCIMConfig({workspaceId:t,namespaceName:n}))&&i.deletes.push({name:`${n}-scim-config`,request:{workspaceId:t,namespaceName:n}});return i}function protoSCIMConfig(e){let t;switch(e.authorization.type){case`bearer`:t=ee.BEARER;break;case`oauth2`:t=ee.OAUTH2;break;default:throw Error(`Unknown SCIM authorization type: ${e.authorization.type}`)}return{machineUserName:e.machineUserName,authorizationType:t,authorizationConfig:{case:`bearerSecret`,value:{vaultName:e.authorization.bearerSecret?.vaultName,secretKey:e.authorization.bearerSecret?.secretKey}}}}async function planSCIMResources(e,t,n,r){let i=createChangeSet(`Auth scimResources`),fetchSCIMResources=async n=>await I(async()=>{let{scimResources:r}=await e.getAuthSCIMResources({workspaceId:t,namespaceName:n});return r})??[];for(let e of n){let{config:n}=e,r=await fetchSCIMResources(n.name),a=new Set;r.forEach(e=>{a.add(e.name)});for(let e of n.scim?.resources??[])a.has(e.name)?(i.updates.push({name:e.name,request:{workspaceId:t,namespaceName:n.name,scimResource:protoSCIMResource(e)}}),a.delete(e.name)):i.creates.push({name:e.name,request:{workspaceId:t,namespaceName:n.name,scimResource:protoSCIMResource(e)}});a.forEach(e=>{i.deletes.push({name:e,request:{workspaceId:t,namespaceName:n.name,name:e}})})}for(let e of r)(await fetchSCIMResources(e)).forEach(n=>{i.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return i}function protoSCIMResource(e){return{name:e.name,tailorDbNamespace:e.tailorDBNamespace,tailorDbType:e.tailorDBType,coreSchema:{name:e.coreSchema.name,attributes:e.coreSchema.attributes.map(e=>protoSCIMAttribute(e))},attributeMapping:e.attributeMapping.map(e=>({tailorDbField:e.tailorDBField,scimPath:e.scimPath}))}}function protoSCIMAttribute(e){let t;switch(e.type){case`string`:t=y.STRING;break;case`number`:t=y.NUMBER;break;case`boolean`:t=y.BOOLEAN;break;case`datetime`:t=y.DATETIME;break;case`complex`:t=y.COMPLEX;break;default:throw Error(`Unknown SCIM attribute type: ${e.type}`)}let n;if(e.mutability)switch(e.mutability){case`readOnly`:n=Ne.READ_ONLY;break;case`readWrite`:n=Ne.READ_WRITE;break;case`writeOnly`:n=Ne.WRITE_ONLY;break;default:throw Error(`Unknown SCIM attribute mutability: ${e.mutability}`)}let r;if(e.uniqueness)switch(e.uniqueness){case`none`:r=x.NONE;break;case`server`:r=x.SERVER;break;case`global`:r=x.GLOBAL;break;default:throw Error(`Unknown SCIM attribute uniqueness: ${e.uniqueness}`)}return{type:t,name:e.name,description:e.description,mutability:n,required:e.required,multiValued:e.multiValued,uniqueness:r,canonicalValues:e.canonicalValues??void 0,subAttributes:e.subAttributes?.map(e=>protoSCIMAttribute(e))}}function areAuthHooksEqual(e,t){return areNormalizedEqual({scriptRef:e.scriptRef??``,invoker:e.invoker?{namespace:e.invoker.namespace??``,machineUserName:e.invoker.machineUserName??``}:void 0},{scriptRef:t.scriptRef??``,invoker:t.invoker?{namespace:t.invoker.namespace??``,machineUserName:t.invoker.machineUserName??``}:void 0})}function formatAuthHookChangeEntries(e,t){return formatChangeEntriesWithFunctionRegistry(`authHook`,e,t,e=>{let[t,n]=e.name.split(`/`);return t&&n?[authHookFunctionName(t,n)]:[]},{getNamespace:e=>e.name.split(`/`)[0],getDisplayName:e=>e.name.split(`/`)[1]??e.name})}async function planAuthHooks(e,t,n,r,i=!1){let a=createChangeSet(`Auth hooks`);for(let r of n){let{config:n}=r,o=n.hooks?.beforeLogin,s=await I(async()=>{let{hook:r}=await e.getAuthHook({workspaceId:t,namespaceName:n.name,hookPoint:ae.BEFORE_LOGIN});return r});if(o){let e={workspaceId:t,namespaceName:n.name,hook:{hookPoint:ae.BEFORE_LOGIN,scriptRef:authHookFunctionName(n.name,`before-login`),invoker:{namespace:n.name,machineUserName:o.invoker}}};s?!i&&areAuthHooksEqual(s,e.hook)?a.unchanged.push({name:`${n.name}/before-login`}):a.updates.push({name:`${n.name}/before-login`,request:e}):a.creates.push({name:`${n.name}/before-login`,request:e})}else s&&a.deletes.push({name:`${n.name}/before-login`,request:{workspaceId:t,namespaceName:n.name,hookPoint:ae.BEFORE_LOGIN}})}for(let n of r)await I(async()=>await e.getAuthHook({workspaceId:t,namespaceName:n,hookPoint:ae.BEFORE_LOGIN}))&&a.deletes.push({name:`${n}/before-login`,request:{workspaceId:t,namespaceName:n,hookPoint:ae.BEFORE_LOGIN}});return a}function normalizeInvoker(e,t,n){if(e!==void 0){if(typeof e==`string`){if(!t)throw Error(`${n} uses a string invoker ("${e}"), but no Auth service is configured. Configure an Auth service before using invoker.`);return{namespace:t,machineUserName:e}}return e}}async function applyExecutor(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?await Promise.all([...r.creates.map(async t=>{await e.createExecutorExecutor(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{await e.updateExecutorExecutor(t.request),await writeMetadataLabels(e,t.metaRequest)})]):await Promise.all(r.deletes.map(t=>e.deleteExecutorExecutor(t.request)))}async function planExecutor(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`Executors`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{executors:i,nextPageToken:a}=await t.listExecutorExecutors({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`executor`,e)}),u=i?{}:await r.executorService?.loadExecutors()??{};for(let t of Object.values(u)){let i=l[t.name],c=await buildMetaRequest({trn:resourceTrn(n,`executor`,t.name),appName:r.name,appId:r.id}),u=protoExecutor(e,t);i?(trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:r.name,appId:r.id,resourceType:`Executor`,resourceName:t.name,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(i.allLabels,c.labels)&&areExecutorsEqual(i.resource,u)?a.unchanged.push({name:t.name}):a.updates.push({name:t.name,request:{workspaceId:n,executor:u},metaRequest:c}),delete l[t.name]):a.creates.push({name:t.name,request:{workspaceId:n,executor:u},metaRequest:c})}return Object.entries(l).forEach(([e])=>{let t=l[e],i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:n,name:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}function isFunctionBackedExecutor(e){return e?.targetType===T.FUNCTION||e?.targetType===T.JOB_FUNCTION}function buildPlannedExecutorsByName(e){return Object.fromEntries([...e.creates,...e.updates].map(e=>[e.name,e.request.executor]))}function formatExecutorChangeEntries(e,t,n){return formatChangeEntriesWithFunctionRegistry(`executor`,e,n,(e,n)=>{if(n===`delete`)return[executorFunctionName(e.name)];let r=t[e.name];return r&&isFunctionBackedExecutor(r)?[executorFunctionName(e.name)]:[]})}function normalizeComparableExecutor(e){let t=normalizeProtoConfig(e),n=t.targetConfig?.config?.case===`webhook`?(t.targetConfig.config.value.headers??[]).toSorted((e,t)=>(e.key??``).localeCompare(t.key??``)):void 0,r=t.triggerConfig?.config?.case===`incomingWebhook`?{...t.triggerConfig,config:{...t.triggerConfig.config,value:{...t.triggerConfig.config.value,secret:void 0}}}:t.triggerConfig?.config?.case===`event`?{...t.triggerConfig,config:{...t.triggerConfig.config,value:{...t.triggerConfig.config.value,eventType:void 0}}}:t.triggerConfig,i=normalizeProtoConfig({name:t.name,description:t.description??``,disabled:t.disabled??!1,triggerType:t.triggerType,triggerConfig:r,targetType:t.targetType,targetConfig:t.targetConfig?.config?.case===`webhook`?{...t.targetConfig,config:{...t.targetConfig.config,value:{...t.targetConfig.config.value,headers:n}}}:t.targetConfig?.config?.case===`function`?{...t.targetConfig,config:{...t.targetConfig.config,value:{...t.targetConfig.config.value,script:void 0}}}:t.targetConfig});return toComparableProtoJson(te,i)}function areExecutorsEqual(e,t){return areNormalizedEqual(normalizeComparableExecutor(e),normalizeComparableExecutor(t))}function resolveSameRunNamespace(e,t,n){if(!e?.has(t))return;let r=e.get(t);if(!r)throw Error(`${n} "${t}" is defined in multiple namespaces in this deploy run. Move the trigger to the application that owns it or use unique names.`);return r}function findTailorDBNamespace(e,t){return e.tailorDBServices.find(e=>Object.hasOwn(e.types,t))?.namespace}function findResolverNamespace(e,t){return e.resolverServices.find(e=>Object.values(e.resolvers).some(e=>e.name===t))?.namespace}function resolveNamespace(e){let{resourceLabel:t,resourceName:n,localNamespaces:r,findLocalNamespace:i,sameRunNamespaces:a}=e,o=i();if(o!==void 0)return o;let s=resolveSameRunNamespace(a,n,t);if(s!==void 0)return s;let c=a?[...new Set([...a.values()].filter(e=>e!==void 0))]:[],l=[...r,...c];throw Error(`${t} "${n}" not found in any namespace. Available namespaces: ${l.join(`, `)}`)}function resolveTailorDBNamespace(e,t,n){return resolveNamespace({resourceLabel:`TailorDB table`,resourceName:t,localNamespaces:e.tailorDBServices.map(e=>e.namespace),findLocalNamespace:()=>findTailorDBNamespace(e,t),sameRunNamespaces:n})}function resolveResolverNamespace(e,t,n){return resolveNamespace({resourceLabel:`Resolver`,resourceName:t,localNamespaces:e.resolverServices.map(e=>e.namespace),findLocalNamespace:()=>findResolverNamespace(e,t),sameRunNamespaces:n})}function collectApplicationIdpNames(e){let t=new Set(e.idpServices.map(e=>e.name));for(let n of e.subgraphs)n.Type===`idp`&&t.add(n.Name);return t}function resolveIdpNamespace(e,t,n,r){let i=collectApplicationIdpNames(e);if(n!==void 0){let e=r??i;if(!e.has(n)){let r=[...e].join(`, `);throw Error(`Executor "${t}" specifies IdP "${n}" in its idpUser trigger, but no IdP with that name is configured. Available IdPs: ${r}`)}return n}if(i.size===0)throw Error(`Executor "${t}" uses an idpUser trigger but no IdP is configured.`);if(i.size>1){let e=[...i].join(`, `);throw Error(`Executor "${t}" uses an idpUser trigger but the project defines multiple IdPs (${e}). Specify which IdP to subscribe to via the trigger's "idp" option.`)}return A([...i][0],`idp service missing`)}function protoExecutor(e,t){let{application:n}=e,r=n.name,i=n.env,a=t.trigger,o,s,c=zt(a.kind,i);function typedEventTrigger(e){return{config:{case:`event`,value:{typedConfig:e}}}}switch(a.kind){case`schedule`:o=O.SCHEDULE,s={config:{case:`schedule`,value:{timezone:a.timezone,frequency:a.cron}}};break;case`tailordb`:o=O.EVENT,s=typedEventTrigger({case:`tailordb`,value:{eventTypes:a.events,namespaceName:resolveTailorDBNamespace(n,a.tableName,e.tailorDBTypeNamespaces),typeName:a.tableName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;case`resolverExecuted`:o=O.EVENT,s=typedEventTrigger({case:`pipeline`,value:{eventTypes:[`pipeline.resolver.executed`],namespaceName:resolveResolverNamespace(n,a.resolverName,e.resolverNamespaces),resolverName:a.resolverName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;case`incomingWebhook`:o=O.INCOMING_WEBHOOK,s={config:{case:`incomingWebhook`,value:a.response?{response:{...a.response.body?{body:{expr:`(${Dt(a.response.body)})(${c})`}}:{},...a.response.statusCode==null?{}:{statusCode:a.response.statusCode}}}:{}}};break;case`idpUser`:o=O.EVENT,s=typedEventTrigger({case:`idp`,value:{eventTypes:a.events,namespaceName:resolveIdpNamespace(n,t.name,a.idp,e.idpNames)}});break;case`authAccessToken`:o=O.EVENT,s=typedEventTrigger({case:`auth`,value:{eventTypes:a.events,namespaceName:It(n)}});break;case`workflowExecution`:case`workflowJobExecution`:o=O.EVENT,s=typedEventTrigger({case:`workflow`,value:{eventTypes:a.events,workflowName:a.workflowName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;default:throw Error(`Unknown trigger: ${a}`)}let l=t.operation,u,d,f=Zt(n),p=`Executor "${t.name}"`;switch(l.kind){case`webhook`:u=T.WEBHOOK,d={config:{case:`webhook`,value:{url:{expr:`(${Dt(l.url)})(${c})`},headers:l.headers?Object.entries(l.headers).map(([e,t])=>{let n;return n=typeof t==`string`?{case:`rawValue`,value:t}:{case:`secretValue`,value:{vaultName:t.vault,secretKey:t.key}},{key:e,value:n}}):void 0,body:l.requestBody?{expr:`(${Dt(l.requestBody)})(${c})`}:void 0}}};break;case`graphql`:u=T.TAILOR_GRAPHQL,d={config:{case:`tailorGraphql`,value:{appName:l.appName??r,query:l.query,variables:l.variables?{expr:`(${Dt(l.variables)})(${c})`}:void 0,invoker:normalizeInvoker(l.invoker,f,p)}}};break;case`function`:case`jobFunction`:u=l.kind===`function`?T.FUNCTION:T.JOB_FUNCTION,d={config:{case:`function`,value:{name:`operation`,scriptRef:executorFunctionName(t.name),variables:{expr:c},invoker:normalizeInvoker(l.invoker,f,p)}}};break;case`workflow`:u=T.WORKFLOW,d={config:{case:`workflow`,value:{workflowName:l.workflowName,variables:l.args===void 0?void 0:typeof l.args==`function`?{expr:`(${Dt(l.args)})(${c})`}:{expr:JSON.stringify(l.args)},invoker:normalizeInvoker(l.invoker,f,p)}}};break;default:throw Error(`Unknown target: ${l}`)}return{name:t.name,description:t.description,disabled:t.disabled,triggerType:o,triggerConfig:s,targetType:u,targetConfig:d}}const Pi={uuid:{kind:`ScalarType`,name:`ID`},string:{kind:`ScalarType`,name:`String`},integer:{kind:`ScalarType`,name:`Int`},float:{kind:`ScalarType`,name:`Float`},decimal:{kind:`CustomScalarType`,name:`Decimal`},boolean:{kind:`ScalarType`,name:`Boolean`},date:{kind:`CustomScalarType`,name:`Date`},datetime:{kind:`CustomScalarType`,name:`DateTime`},time:{kind:`CustomScalarType`,name:`Time`}};async function applyPipeline(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?(await Promise.all([...r.service.creates.map(async t=>{await e.createPipelineService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await e.updatePipelineService(t.request),await writeMetadataLabels(e,t.metaRequest)})]),await Promise.all([...r.resolver.creates.map(async t=>{await e.createPipelineResolver(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.resolver.updates.map(async t=>{await e.updatePipelineResolver(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.resolver.unchanged.flatMap(t=>t.metaRequest?[writeMetadataLabels(e,t.metaRequest)]:[])])):n===`delete-resources`?await Promise.all(r.resolver.deletes.map(t=>e.deletePipelineResolver(t.request))):await Promise.all(r.service.deletes.map(t=>e.deletePipelineService(t.request)))}async function planPipeline(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=[];if(!i)for(let e of r.resolverServices)await e.loadResolvers(),o.push(e);let s=i?[]:Object.values(await r.executorService?.loadExecutors()??{}),{changeSet:c,conflicts:l,unmanaged:u,resourceOwners:d}=await planServices$1(t,n,r.name,r.id,o),f=c.deletes.map(e=>e.name),{changeSet:p}=await planResolvers(t,n,o,s,e.executorUsedResolvers??new Set,f,r.env,Zt(r),a,{appName:r.name,appId:r.id,dependentApps:e.dependentApps,runAppIds:e.runAppIds});return{changeSet:{service:c,resolver:p},conflicts:l,unmanaged:u,resourceOwners:d}}async function planServices$1(e,t,n,r,i){let a=createChangeSet(`Pipeline services`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{pipelineServices:i,nextPageToken:a}=await e.listPipelineServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`pipeline`,e)});for(let e of i){let i=l[e.namespace],c=await buildMetaRequest({trn:resourceTrn(t,`pipeline`,e.namespace),appName:n,appId:r});i?(trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceType:`Pipeline service`,resourceName:e.namespace,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(i.allLabels,c.labels)?a.unchanged.push({name:e.namespace}):a.updates.push({name:e.namespace,request:{workspaceId:t,namespaceName:e.namespace},metaRequest:c}),delete l[e.namespace]):a.creates.push({name:e.namespace,request:{workspaceId:t,namespaceName:e.namespace},metaRequest:c})}return Object.entries(l).forEach(([e])=>{let i=l[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}async function planResolvers(e,t,n,r,i,a,o,s,c=!1,l={}){let u=createChangeSet(`Pipeline resolvers`),{appName:d,appId:f,dependentApps:p,runAppIds:m}=l,resolverMetaRequest=async(e,n)=>addDependencyRecords(await buildMetaRequest({trn:resolverTrn(t,e,n.name),appName:d??``,appId:f}),{key:Q.resolver(e,n.name),dependentApps:p,runAppIds:m,pinned:n.publishEvents!==void 0}),fetchResolvers=n=>P(async(r,i)=>{let{pipelineResolvers:a,nextPageToken:o}=await e.listPipelineResolvers({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}),h=new Set(i);for(let e of r)subscribesToEvents(e)&&e.trigger.kind===`resolverExecuted`&&h.add(e.trigger.resolverName);for(let e of n)for(let t of Object.values(e.resolvers))assertNoPublishEventsConflict({explicit:t.publishEvents,subscribed:h.has(t.name),conflict:Mi.resolver(t.name)});for(let r of n){let n=await fetchResolvers(r.namespace),i=new Map(n.map(e=>[e.name,e]));for(let n of Object.values(r.resolvers)){let a=processResolver(r.namespace,n,h,o,s),l=i.get(n.name),d=await resolverMetaRequest(r.namespace,n);if(l){let{pipelineResolver:o}=await e.getPipelineResolver({workspaceId:t,namespaceName:r.namespace,resolverName:n.name});!c&&o&&areResolversEqual(o,a)?u.unchanged.push({name:n.name,metaRequest:d}):u.updates.push({name:n.name,request:{workspaceId:t,namespaceName:r.namespace,pipelineResolver:a},metaRequest:d}),i.delete(n.name)}else u.creates.push({name:n.name,request:{workspaceId:t,namespaceName:r.namespace,pipelineResolver:a},metaRequest:d})}i.forEach((e,n)=>{u.deletes.push({name:n,request:{workspaceId:t,namespaceName:r.namespace,resolverName:n}})})}for(let e of a)(await fetchResolvers(e)).forEach(n=>{u.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,resolverName:n.name}})});return{changeSet:u}}function formatResolverChangeEntries(e,t){return formatChangeEntriesWithFunctionRegistry(`resolver`,e,t,e=>{let t=e.request.namespaceName;return t?[resolverFunctionName(t,e.name)]:[]},{getNamespace:e=>e.request.namespaceName})}function normalizeComparableResolver(e){return toComparableProtoJson(f,e)}function areResolversEqual(e,t){return areNormalizedEqual(normalizeComparableResolver(e),normalizeComparableResolver(t))}function processResolver(e,t,n,r,i){let a=[{name:`body`,operationName:`body`,description:`${t.name} function body`,operationType:g.FUNCTION,operationSourceRef:resolverFunctionName(e,t.name),operationHook:{expr:Rt(r)},postScript:`args.body`,invoker:normalizeInvoker(t.invoker,i,`Resolver "${t.name}"`)}],o=hr.camelize(t.name),s=t.input?protoFields(t.input,`${o}Input`,!0):[],c=A(protoFields({"":t.output},`${o}Output`,!1)[0],`resolver output field missing`),l=t.description||`${t.name} resolver`,u=t.output.metadata.description,d=u?`${l}\n\nReturns:\n${u}`:l,f=resolvePublishEvents({explicit:t.publishEvents,subscribed:n.has(t.name),conflict:Mi.resolver(t.name)});return{authorization:`true==true`,description:d,inputs:s,name:t.name,operationType:t.operation,response:c,pipelines:a,publishExecutionEvents:f}}function protoFields(e,t,n){return Object.entries(e).map(([e,r])=>{let i,a=n&&r.metadata.hooks?.create!==void 0?!1:r.metadata.required??!0;if(r.type===`nested`){let o=r.metadata.typeName??`${t}${hr.camelize(e)}`;i={kind:`UserDefined`,name:o,description:r.metadata.description??``,required:a,fields:protoFields(r.fields,o,n)}}else i=r.type===`enum`?{kind:`EnumType`,name:r.metadata.typeName??`${t}${hr.camelize(e)}`,required:a,allowedValues:r.metadata.allowedValues}:{...Pi[r.type],required:a};return{name:e,description:r.metadata.description,array:r.metadata.array??!1,required:a,type:i}})}function vaultCreateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.name}}function secretCreateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.vaultName,secretmanagerSecretName:e.secretName,secretmanagerSecretValue:e.value}}function secretUpdateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.vaultName,secretmanagerSecretName:e.secretName,secretmanagerSecretValue:e.value}}async function planSecretManager(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=i?[]:r.secrets,s=createChangeSet(`Secret Manager vaults`),c=createChangeSet(`Secret Manager secrets`),l=[],u=[],d=new Set,f=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{vaults:i,nextPageToken:a}=await t.listSecretManagerVaults({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`vault`,e)}),p={workspaceId:n,applicationId:r.id,applicationName:r.name},m=loadSecretsState(p),h=[];await Promise.all(o.map(async e=>{let i=e.vaultName,o=f[i];if(o){let e=await buildMetaRequest({trn:resourceTrn(n,`vault`,i),appName:r.name,appId:r.id});trackDesiredResourceOwnership({labels:o.allLabels,ownerLabel:o.label,appName:r.name,appId:r.id,resourceType:`Secret Manager vault`,resourceName:i,conflicts:l,unmanaged:u})&&hasMatchingSdkVersion(o.allLabels,e.labels)?s.unchanged.push({name:i}):s.updates.push({name:i,workspaceId:n}),delete f[i]}else s.creates.push({name:i,workspaceId:n});let d=new Map;if(o){let e=await P(async(e,r)=>{let{secrets:a,nextPageToken:o}=await t.listSecretManagerSecrets({workspaceId:n,secretmanagerVaultName:i,pageToken:e,pageSize:r});return[a,o]});for(let t of e)d.set(t.name,serializeUpdateTime(t.updateTime))}let p=new Set(d.keys());for(let t of e.secrets){if(t.value==null){p.delete(t.name),h.push(`${i}/${t.name}`);continue}if(p.has(t.name)){let e=m.vaults[i]?.[t.name],r=d.get(t.name),o=e!==void 0&&e.hash===hashValue(t.value)&&e.updateTime!==void 0&&e.updateTime===r;(a||!o)&&c.updates.push({name:`${i}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:i,value:t.value}),p.delete(t.name)}else c.creates.push({name:`${i}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:i,value:t.value})}for(let e of p)c.deletes.push({name:`${i}/${e}`,secretName:e,workspaceId:n,vaultName:i})}));for(let[e,i]of Object.entries(f))if(i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:r.name,appId:r.id,resourceOwners:d})){let r=await P(async(r,i)=>{let{secrets:a,nextPageToken:o}=await t.listSecretManagerSecrets({workspaceId:n,secretmanagerVaultName:e,pageToken:r,pageSize:i});return[a,o]});for(let t of r)c.deletes.push({name:`${e}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:e});s.deletes.push({name:e,workspaceId:n})}return{vaultChangeSet:s,secretChangeSet:c,skippedSecrets:h,conflicts:l,unmanaged:u,resourceOwners:d,stateScope:p}}async function applySecretManager(e,t,n=`create-update`,r){let{vaultChangeSet:i,secretChangeSet:a,stateScope:o}=t;if(n===`create-update`){await Promise.all(i.creates.map(async t=>{await e.createSecretManagerVault(vaultCreateRequest(t)),r&&await writeMetadataLabels(e,await buildMetaRequest({trn:resourceTrn(t.workspaceId,`vault`,t.name),appName:r.name,appId:r.id}))})),r&&await Promise.all(i.updates.map(async t=>{await writeMetadataLabels(e,await buildMetaRequest({trn:resourceTrn(t.workspaceId,`vault`,t.name),appName:r.name,appId:r.id}))}));let t=[...a.creates,...a.updates];t.length>0&&await withSecretsStateLock(o,async()=>{let n=new Map;if(await Promise.all(a.creates.map(async t=>{let r=await e.createSecretManagerSecret(secretCreateRequest(t));n.set(t.name,serializeUpdateTime(r.secret?.updateTime))})),await Promise.all(a.updates.map(async t=>{let r=await e.updateSecretManagerSecret(secretUpdateRequest(t));n.set(t.name,serializeUpdateTime(r.secret?.updateTime))})),r){let e=loadSecretsState(o);for(let r of t){Object.hasOwn(e.vaults,r.vaultName)||(e.vaults[r.vaultName]={});let t=n.get(r.name);A(e.vaults[r.vaultName],`vault state entry missing`)[r.secretName]={hash:hashValue(r.value),...t===void 0?{}:{updateTime:t}}}saveSecretsState(o,e)}})}else(a.deletes.length>0||i.deletes.length>0)&&await withSecretsStateLock(o,async()=>{await Promise.all(a.deletes.map(t=>e.deleteSecretManagerSecret({workspaceId:t.workspaceId,secretmanagerVaultName:t.vaultName,secretmanagerSecretName:t.secretName}))),await Promise.all(i.deletes.map(t=>e.deleteSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:t.name})));let t=loadSecretsState(o);for(let e of a.deletes)Object.hasOwn(t.vaults,e.vaultName)&&(delete A(t.vaults[e.vaultName],`vault state entry missing`)[e.secretName],Object.keys(A(t.vaults[e.vaultName],`vault state entry missing`)).length===0&&delete t.vaults[e.vaultName]);for(let e of i.deletes)delete t.vaults[e.name];saveSecretsState(o,t)})}function hasChanges(e){return e.changes.length>0}function formatMigrationDiff(e){if(e.changes.length===0)return`No schema differences detected.`;let t=[],n=new Map;for(let t of e.changes){let e=n.get(t.tableName)??[];e.push(t),n.set(t.tableName,e)}for(let[r,i]of n){t.push(`${e.namespace}.${r}:`);for(let e of i)t.push(formatDiffChange(e))}return t.join(`
|
|
31
|
+
`);throw Error(`Invalid Tailor config in ${r}:\n${e}`)}let c=o.default;await assertEnvHasNoSecrets({env:c.env,configPath:r});let l=c.env?Object.fromEntries(Object.entries(c.env).map(([e,t])=>[e,resolveEnvValue(t)])):void 0,u=[];for(let e of Object.values(o))if(Array.isArray(e)){let t=e.reduce((e,t)=>{if(!e.success)return e;let n=ti.safeParse(t);return n.success?e.items.push(n.data):e.success=!1,e},{success:!0,items:[]});t.success&&t.items.length>0&&u.push(...t.items)}return{config:{...o.default,...l?{env:l}:{},path:r},plugins:u}}async function assertWritable(e){let t=e?.profile||process.env.TAILOR_PLATFORM_PROFILE;if(!t)return;let n=(await readPlatformConfig()).profiles[t];if(!(!n||n.readonly!==!0))throw R({code:`PROFILE_READONLY`,message:`Profile "${t}" is read-only.`,details:`This profile blocks platform-state mutations (apply, create/update/delete, deploy, etc.). Application-data operations remain available because their permissions are governed by the machine user.`,suggestion:`Use a different profile, unset TAILOR_PLATFORM_PROFILE, or run 'tailor profile update ${t} --permission write'.`})}function hasEnvAccessToken(){return!!(process.env.TAILOR_PLATFORM_TOKEN??process.env.TAILOR_TOKEN)}async function apiCall(e){let t=await loadAccessToken({profile:e.profile}),n;try{n=await loadPlatformClientConfig({profile:e.profile})}catch(e){if(!hasEnvAccessToken())throw e}let r;r=e.endpoint.includes(`/`)?e.endpoint:`tailor.v1.OperatorService/${e.endpoint}`;let i=new URL(r,Mt(n)),a=await fetch(i.toString(),{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${t}`,"User-Agent":await mn()},body:e.body??`{}`}),o=await a.json();if(!a.ok)throw Error(`API call failed (${a.status}): ${JSON.stringify(o)}`);return{status:a.status,data:o}}async function loadOperatorWorkspaceContext(e){let t=await loadAccessToken({profile:e.profile});return{client:await F(t),workspaceId:await loadWorkspaceId({profile:e.profile,workspaceId:e.workspaceId})}}function canPrompt(){return!fr&&process.stdin.isTTY===!0&&process.stdout.isTTY===!0&&!M.jsonMode}function withGuard(e,t){return async n=>{if(!canPrompt())throw new dt(t);try{return await e(n)}catch(e){throw e instanceof sr&&process.exit(130),e}}}const Z={confirm:withGuard(cr,`Interactive confirmations are not available in this environment. Use --yes to skip confirmation prompts, or provide the required options explicitly.`),text:withGuard(lr),password:withGuard(ur),select:e=>withGuard(dr)(e)};function createChangeSet(e){let t=[],n=[],r=[],i=[],a=[],isEmpty=()=>t.length===0&&n.length===0&&r.length===0&&i.length===0;return{title:e,creates:t,updates:n,deletes:r,replaces:i,unchanged:a,isEmpty,lines:()=>{if(isEmpty())return[];let itemLines=e=>t=>[` ${e} ${t.name}`,...(t.details??[]).map(e=>` ${e}`)];return[N.bold(`${e}:`),...t.flatMap(itemLines(j.create)),...r.flatMap(itemLines(j.delete)),...n.flatMap(itemLines(j.update)),...i.flatMap(itemLines(j.replace))]}}}function summarizeChangeSets(e){let t={create:0,update:0,delete:0,replace:0};for(let n of e)t.create+=n.creates.length,t.update+=n.updates.length,t.delete+=n.deletes.length,t.replace+=n.replaces.length;return t}function formatPlanSummary(e){let t=[`${e.create} to create`,`${e.update} to update`,`${e.delete} to delete`];return e.replace>0&&t.push(`${e.replace} to replace`),`Plan: ${t.join(`, `)}`}function toComparableProtoJson(e,t){return Bn(e,U(e,t))}function stableStringify$1(e){return Array.isArray(e)?`[${e.map(e=>e===void 0?`null`:stableStringify$1(e)).join(`,`)}]`:e&&typeof e==`object`?`{${Object.entries(e).filter(([e,t])=>e!==`$typeName`&&t!==void 0).toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${stableStringify$1(t)}`).join(`,`)}}`:JSON.stringify(typeof e==`bigint`?e.toString():e)}function normalizeProtoConfig(e){return e==null?e:JSON.parse(stableStringify$1(e))}function normalizeStringArray(e){return(e??[]).toSorted()}function areNormalizedEqual(e,t){return stableStringify$1(normalizeProtoConfig(e))===stableStringify$1(normalizeProtoConfig(t))}function trnPrefix(e){return`trn:v1:workspace:${e}`}function resourceTrn(e,t,n){return`${trnPrefix(e)}:${t}:${n}`}function nestedResourceTrn(e,t,n){return`${trnPrefix(e)}:${t[0]}:${t[1]}:${n[0]}:${n[1]}`}function tailorDBTypeTrn(e,t,n){return nestedResourceTrn(e,[`tailordb`,t],[`type`,n])}function resolverTrn(e,t,n){return nestedResourceTrn(e,[`pipeline`,t],[`resolver`,n])}const yi=`sdk-name`,bi=`sdk-version`,xi=`sdk-app-id`;function sdkAppIdLabelValue(e){return`app-${e}`}function hasMatchingSdkVersion(e,t){return e?.[bi]===t?.[bi]}function isOwnedByApp(e,t,n){if(!e)return!1;let r=e[xi];return r?n!==void 0&&r===sdkAppIdLabelValue(n):e[yi]===t}function prefixFor(e){return e===`jobs`?`sdk-job-depended-by-app-`:`sdk-depended-by-app-`}const Si=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function dependedByAppLabelKey(e,t=`resource`){return Si.test(e)?`${prefixFor(t)}${e}`:void 0}function recordedDependencies(e,t=`resource`){if(!e)return[];let n=prefixFor(t);return Object.entries(e).toSorted(([e],[t])=>e<t?-1:+(e>t)).flatMap(([e,t])=>{if(!e.startsWith(n))return[];let r=e.slice(n.length);return Si.test(r)?[{appId:r,reason:t}]:[]})}const Q={tailorDBType:(e,t)=>`tailordb:${e}:type:${t}`,resolver:(e,t)=>`pipeline:${e}:resolver:${t}`,idp:e=>`idp:${e}`,workflow:e=>`workflow:${e}`,workflowJobs:e=>`workflow:${e}:jobs`};function dependencyLabelWrite(e){let{existingLabels:t,dependentApps:n,runAppIds:r,pinned:i,scope:a=`resource`}=e;if(i)return{labels:{},remove:recordedDependencies(t,a).flatMap(({appId:e})=>dependedByAppLabelKey(e,a)??[])};let o=n??new Map,s=r??new Set,c={};for(let[e,t]of o){let n=dependedByAppLabelKey(e,a);if(!n)throw Error(`Application id "${e}" cannot be recorded as a dependency of this deploy. Ids are written by deploy as lowercase UUIDs; restore the generated value in the config's "id".`);c[n]=t}return{labels:c,remove:recordedDependencies(t,a).flatMap(({appId:e})=>{if(!s.has(e)||o.has(e))return[];let t=dependedByAppLabelKey(e,a);return t?[t]:[]})}}async function buildMetaRequest(e){let{trn:t,appName:n,appId:r}=e,i=await pn(),a=i.version?`v${i.version.replace(/\./g,`-`)}`:`unknown`;return{trn:t,labels:{[yi]:n,[bi]:a,...r?{[xi]:sdkAppIdLabelValue(r)}:{}},remove:r?void 0:[xi]}}function addDependencyRecords(e,t){let{key:n,dependentApps:r,runAppIds:i,pinned:a,scope:o}=t;return e.dependencies=[...e.dependencies??[],{dependentApps:r?.get(n),runAppIds:i,pinned:a,scope:o}],e}const Ci=Symbol(`metadataWriteBatch`);var MetadataWriteBatch=class{#e;#t=new Map;#n;constructor(e){this.#e=e}async enqueue(e){if(this.#n){await this.#n.catch(()=>void 0),await writeMetadataLabelsDirect(this.#e,e);return}let t=this.#t.get(e.trn)??[];t.push(e),this.#t.set(e.trn,t)}flush(){return this.#n??=this.#r(),this.#n}async#r(){let e=[...this.#t].toSorted(([e],[t])=>e<t?-1:+(e>t)),readRequest=async([e,t])=>{let n=(await I(()=>this.#e.getMetadata({trn:e})))?.metadata?.labels??{},r=t.reduce(applyMetadataLabelWrite,n);return areSameLabels(n,r)?void 0:{trn:e,labels:r}},t=[],n=0;for(;n<e.length||t.length>0;){let r=t.length===0?[]:void 0;for(;n<e.length&&t.length<100;){t.length>0&&(r=void 0);let i=e.slice(n,n+100);n+=i.length;let a=await Promise.all(i.map(async e=>{let t=await readRequest(e);return t?{entry:e,request:t}:void 0}));for(let e of a)e&&(t.push(e.entry),r?.push(e.request))}let i=t.splice(0,100),a=r??(await Promise.all(i.map(e=>readRequest(e)))).filter(e=>e!==void 0);a.length>0&&await this.#e.bulkSetMetadata({requests:a})}}};function hasMetadataLabelChange(e){return!!(Object.keys(e.labels??{}).length||e.remove?.length||e.dependencies?.length)}function applyMetadataLabelWrite(e,t){let{labels:n,remove:r,dependencies:i}=t,a=(i??[]).map(t=>dependencyLabelWrite({...t,existingLabels:e})),o={...e,...n,...Object.assign({},...a.map(e=>e.labels))};for(let e of[...r??[],...a.flatMap(e=>e.remove)])delete o[e];return o}function metadataRecoveryError(e,t){return AggregateError([e,t],`Resource apply failed: ${hn(e).message}\nQueued metadata recovery failed: ${hn(t).message}`,{cause:t})}async function withMetadataWriteBatch(e,t){let n=new MetadataWriteBatch(e),r=new Proxy(e,{get(e,t,r){return t===Ci?n:Reflect.get(e,t,r)}}),i;try{i=await t(r)}catch(e){try{await n.flush()}catch(t){throw metadataRecoveryError(e,t)}throw e}return await n.flush(),i}async function writeMetadataLabels(e,t){if(!hasMetadataLabelChange(t))return;let n=e[Ci];if(n){await n.enqueue(t);return}await writeMetadataLabelsDirect(e,t)}async function writeMetadataLabelsDirect(e,t){if(!hasMetadataLabelChange(t))return;let{trn:n}=t,r=(await I(()=>e.getMetadata({trn:n})))?.metadata?.labels??{},i=applyMetadataLabelWrite(r,t);areSameLabels(r,i)||await e.setMetadata({trn:n,labels:i})}function areSameLabels(e,t){let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>e[n]===t[n])}async function fetchExistingResourcesWithLabels(e){let{client:t,fetchPage:n,getName:r,getTrn:i}=e,a=await P(n),o={};return await Promise.all(a.map(async e=>{let n=r(e);if(!n)return;let{metadata:a}=await t.getMetadata({trn:i(n)});o[n]={resource:e,label:a?.labels[yi],allLabels:a?.labels}})),o}function trackDesiredResourceOwnership(e){let{labels:t,ownerLabel:n,appName:r,appId:i,resourceType:a,resourceName:o,conflicts:s,unmanaged:c}=e,l=isOwnedByApp(t,r,i);return l||(n?s.push({resourceType:a,resourceName:o,currentOwner:n}):c.push({resourceType:a,resourceName:o})),l}function trackRemainingResourceOwner(e){let{labels:t,ownerLabel:n,appName:r,appId:i,resourceOwners:a}=e,o=isOwnedByApp(t,r,i);return n&&!o&&a.add(n),o}async function applyStaticWebsite(e,t,n=`create-update`){let{changeSet:r,customDomainChangeSet:i}=t;n===`create-update`?(await Promise.all([...r.creates.map(async t=>{await e.createStaticWebsite(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{await e.updateStaticWebsite(t.request),await writeMetadataLabels(e,t.metaRequest)})]),await Promise.all([...i.creates.map(async t=>{await e.addCustomDomain(t.request),await writeMetadataLabels(e,t.metaRequest)}),...i.deletes.map(t=>e.removeCustomDomain(t.request))])):await Promise.all(r.deletes.map(t=>e.deleteStaticWebsite(t.request)))}function customDomainTrn(e,t,n){return`trn:v1:workspace:${e}:staticwebsite:${t}:custom_domain:${n}`}function normalizeComparableStaticWebsiteShape(e){return{description:e.description,allowedIpAddresses:e.allowedIpAddresses.toSorted()}}function normalizeComparableStaticWebsite(e){return normalizeComparableStaticWebsiteShape({description:e.description||``,allowedIpAddresses:[...e.allowedIpAddresses||[]]})}function areStaticWebsitesEqual(e,t){return areNormalizedEqual(normalizeComparableStaticWebsite(e),normalizeComparableStaticWebsite(t))}function expectedLocalStaticWebsiteNames(e){return e.expectedLocalStaticWebsiteNames??new Set(e.application.staticWebsiteServices.map(e=>e.name))}async function planStaticWebsite(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`StaticWebsites`),o=createChangeSet(`CustomDomains`),s=[],c=[],l=new Set,u=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{staticwebsites:i,nextPageToken:a}=await t.listStaticWebsites({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`staticwebsite`,e)}),d=new Set,f=i?[]:r.staticWebsiteServices;for(let e of f){let t=e,i=e.name,o=u[i],l=await buildMetaRequest({trn:resourceTrn(n,`staticwebsite`,i),appName:r.name,appId:r.id}),f=normalizeComparableStaticWebsite(t),p={workspaceId:n,staticwebsite:{name:i,description:t.description||``,allowedIpAddresses:t.allowedIpAddresses||[]}};if(o){let e=trackDesiredResourceOwnership({labels:o.allLabels,ownerLabel:o.label,appName:r.name,appId:r.id,resourceType:`StaticWebsite`,resourceName:i,conflicts:s,unmanaged:c});e&&hasMatchingSdkVersion(o.allLabels,l.labels)&&areStaticWebsitesEqual(o.resource,f)?a.unchanged.push({name:i}):a.updates.push({name:i,request:p,metaRequest:l}),e&&d.add(i),delete u[i]}else a.creates.push({name:i,request:p,metaRequest:l}),d.add(i)}Object.entries(u).forEach(([e])=>{let t=u[e],i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:l})&&a.deletes.push({name:e,request:{workspaceId:n,name:e}})});let p=new Map;for(let e of f)e.customDomains!==void 0&&d.has(e.name)&&p.set(e.name,e.customDomains);let m=new Map,h=[...d].filter(e=>!a.creates.some(t=>t.name===e));await Promise.all(h.map(async e=>{let r=await I(async()=>{let{customDomains:r}=await t.listCustomDomains({workspaceId:n,staticWebsiteName:e});return await Promise.all(r.map(async r=>{let{metadata:i}=await t.getMetadata({trn:customDomainTrn(n,e,r.domain)});return{domain:r.domain,allLabels:i?.labels}}))});r&&m.set(e,r)}));for(let e of d){let t=new Set(p.get(e)??[]),i=m.get(e)??[],a=new Set(i.map(e=>e.domain)),s=new Set(i.filter(e=>isOwnedByApp(e.allLabels,r.name,r.id)).map(e=>e.domain));for(let i of t)if(a.has(i))o.unchanged.push({name:i});else{let t=await buildMetaRequest({trn:customDomainTrn(n,e,i),appName:r.name,appId:r.id});o.creates.push({name:i,request:{workspaceId:n,staticWebsiteName:e,domain:i},metaRequest:t})}if(p.has(e))for(let e of s)t.has(e)||o.deletes.push({name:e,request:{workspaceId:n,domain:e}})}return{changeSet:a,customDomainChangeSet:o,conflicts:s,unmanaged:c,resourceOwners:l}}async function applyAIGateway(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?await Promise.all([...r.creates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`AIGateway CORS`),await e.createAIGateway(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`AIGateway CORS`),await e.updateAIGateway(t.request),await writeMetadataLabels(e,t.metaRequest)})]):await Promise.all(r.deletes.map(t=>e.deleteAIGateway(t.request)))}function normalizeComparableAIGatewayShape(e){return{authNamespace:e.authNamespace,cors:e.cors.toSorted()}}function normalizeComparableAIGateway(e){return normalizeComparableAIGatewayShape({authNamespace:e.authNamespace||``,cors:[...e.cors||[]]})}function areAIGatewaysEqual(e,t){return areNormalizedEqual(normalizeComparableAIGateway(e),normalizeComparableAIGateway(t))}async function planAIGateway(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`AIGateways`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{aigateways:i,nextPageToken:a}=await t.listAIGateways({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`aigateway`,e)}),u=i?[]:r.aiGatewayServices,d=expectedLocalStaticWebsiteNames(e);for(let e of u){let i=e,c=e.name,u=l[c],f=await buildMetaRequest({trn:resourceTrn(n,`aigateway`,c),appName:r.name,appId:r.id}),p=await Xt(t,n,i.cors?[...i.cors]:[],`AIGateway CORS`,{expectedLocalNames:d}),m=normalizeComparableAIGateway({...i,cors:p}),h={workspaceId:n,aigatewayName:c,authNamespace:i.authNamespace,cors:i.cors?[...i.cors]:[]};u?(trackDesiredResourceOwnership({labels:u.allLabels,ownerLabel:u.label,appName:r.name,appId:r.id,resourceType:`AIGateway`,resourceName:c,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(u.allLabels,f.labels)&&areAIGatewaysEqual(u.resource,m)?a.unchanged.push({name:c}):a.updates.push({name:c,request:h,metaRequest:f}),delete l[c]):a.creates.push({name:c,request:h,metaRequest:f})}return Object.entries(l).forEach(([e,t])=>{let i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:n,aigatewayName:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}async function applyApplication(e,t,n=`create-update`){if(n===`create-update`){let n=[...t.updates,...t.unchanged];await Promise.all([...t.creates.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`CORS`),await e.createApplication(t.request),await writeMetadataLabels(e,t.metaRequest)}),...n.map(async t=>{t.request.cors=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),t.request.cors,`CORS`),await e.updateApplication(t.request),await writeMetadataLabels(e,t.metaRequest)})])}else await Promise.all(t.deletes.map(async t=>{await e.deleteApplication(t.request)}))}function sortStrings(e){return(e??[]).toSorted()}function normalizeSubgraphs(e){return[...e??[]].map(e=>({serviceType:A(e.serviceType,`subgraph missing serviceType`),serviceNamespace:e.serviceNamespace??``})).toSorted((e,t)=>e.serviceType===t.serviceType?e.serviceNamespace.localeCompare(t.serviceNamespace):e.serviceType-t.serviceType)}function normalizeHttpAdapters(e){return[...e??[]].map(e=>({name:e.name??``,pathPattern:e.pathPattern??``,methods:sortStrings(e.methods),inputScript:e.inputScript??``,outputScript:e.outputScript??``,enabled:e.enabled??!0,priority:e.priority??0})).toSorted((e,t)=>e.name.localeCompare(t.name))}function toComparableApplication(e){return{authNamespace:e.authNamespace,authIdpConfigName:e.authIdpConfigName,cors:sortStrings(e.cors),subgraphs:[...e.subgraphs],allowedIpAddresses:sortStrings(e.allowedIpAddresses),disableIntrospection:e.disableIntrospection,disabled:e.disabled,httpAdapters:[...e.httpAdapters]}}function normalizeComparableApplication(e,t,n,r,i){return toComparableApplication({authNamespace:t??``,authIdpConfigName:n??``,cors:r,subgraphs:normalizeSubgraphs(e.subgraphs.map(e=>protoSubgraph(e))),allowedIpAddresses:e.config.allowedIpAddresses??[],disableIntrospection:e.config.disableIntrospection??!1,disabled:!1,httpAdapters:normalizeHttpAdapters(i)})}function normalizeComparableExistingApplication(e){return toComparableApplication({authNamespace:e.authNamespace,authIdpConfigName:e.authIdpConfigName,cors:e.cors,subgraphs:normalizeSubgraphs(e.subgraphs),allowedIpAddresses:e.allowedIpAddresses,disableIntrospection:e.disableIntrospection,disabled:e.disabled,httpAdapters:normalizeHttpAdapters(e.httpAdapters)})}function areApplicationsEqual(e,t){return areNormalizedEqual(normalizeComparableExistingApplication(e),t)}async function planApplication(e,t){let{client:n,workspaceId:r,application:i,forRemoval:a}=e,o=[],s=[],c=new Set,l=createChangeSet(`Applications`),u=await P(async(e,t)=>{let{applications:i,nextPageToken:a}=await n.listApplications({workspaceId:r,pageToken:e,pageSize:t});return[i,a]});if(a){let e=i.id?u:u.filter(e=>e.name===i.name),t=await Promise.all(e.map(async e=>{let t=await fetchAppLabels(n,r,e.name);return trackRemainingResourceOwner({labels:t,ownerLabel:t?.[`sdk-name`],appName:i.name,appId:i.id,resourceOwners:c})?e.name:null}));for(let e of t)e&&l.deletes.push({name:e,request:{workspaceId:r,applicationName:e}});return withOwnership(l,o,s,c)}if(i.subgraphs.length===0)return withOwnership(l,o,s,c);let d,f;if(i.authService){d=i.authService.config.name;let e=i.authService.config.idProvider;e&&(f=e.name)}else if(i.config.auth){if(d=i.config.auth.name,e.externalAuthIdpConfigNames?.has(d))f=e.externalAuthIdpConfigNames.get(d);else{let e=await P(async(e,t)=>{let{idpConfigs:i,nextPageToken:a}=await n.listAuthIDPConfigs({workspaceId:r,namespaceName:A(d,`authNamespace must be set before listing IDP configs`),pageToken:e,pageSize:t});return[i,a]});if(e.length>0){let[t]=e;t&&(f=t.name)}}}let p=await buildMetaRequest({trn:resourceTrn(r,`application`,i.name),appName:i.name,appId:i.id}),m=await fetchAppLabels(n,r,i.name),h=expectedLocalStaticWebsiteNames(e),g=await Xt(n,r,i.config.cors,`CORS`,{expectedLocalNames:h}),_=buildHttpAdapters(i,t),v=normalizeComparableApplication(i,d,f,g,_),y={workspaceId:r,applicationName:i.name,authNamespace:d,authIdpConfigName:f,cors:i.config.cors,subgraphs:i.subgraphs.map(e=>protoSubgraph(e)),allowedIpAddresses:i.config.allowedIpAddresses,disableIntrospection:i.config.disableIntrospection,httpAdapters:_},b=u.find(e=>e.name===i.name);if(i.id){let e=u.filter(e=>e.name!==i.name),t=await Promise.all(e.map(async e=>isOwnedByApp(await fetchAppLabels(n,r,e.name),i.name,i.id)?e.name:null));for(let e of t)e&&l.deletes.push({name:e,request:{workspaceId:r,applicationName:e}})}if(b){let e=trackDesiredResourceOwnership({labels:m,ownerLabel:m?.[yi],appName:i.name,appId:i.id,resourceType:`Application`,resourceName:i.name,conflicts:o,unmanaged:s}),t={name:i.name,request:y,metaRequest:p};if(e&&hasMatchingSdkVersion(m,p.labels)&&areApplicationsEqual(b,v))l.unchanged.push(t);else{let e=diffHttpAdapterDisplay(b.httpAdapters,_);e.length>0&&(t.details=e),l.updates.push(t)}}else{let e=diffHttpAdapterDisplay(void 0,_);l.creates.push({name:i.name,request:y,metaRequest:p,details:e.length>0?e:void 0})}return withOwnership(l,o,s,c)}function withOwnership(e,t,n,r){return Object.assign(e,{conflicts:t,unmanaged:n,resourceOwners:r})}async function fetchAppLabels(e,t,n){return(await I(async()=>{let{metadata:r}=await e.getMetadata({trn:resourceTrn(t,`application`,n)});return r}))?.labels}function diffHttpAdapterDisplay(e,t){let n=new Map((e??[]).map(e=>[e.name??``,e])),r=new Map(t.map(e=>[e.name??``,e])),i=[];for(let[e,t]of r){let r=n.get(e);r?areNormalizedEqual(normalizeHttpAdapters([r])[0],normalizeHttpAdapters([t])[0])||i.push({name:e,symbol:j.update}):i.push({name:e,symbol:j.create})}for(let e of n.keys())r.has(e)||i.push({name:e,symbol:j.delete});return i.toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>`${e.symbol} ${e.name} (httpAdapter)`)}function buildHttpAdapters(e,t){let n=e.httpAdapterService?.adapters??[];return n.length===0?[]:n.map(e=>{let n=t?.bundledInputs.get(e.adapter.name);if(!n)throw Error(`HTTP adapter "${e.adapter.name}" was loaded but no bundled input script is available`);let r=``;if(e.hasOutput){let n=t?.bundledOutputs.get(e.adapter.name);if(!n)throw Error(`HTTP adapter "${e.adapter.name}" declares an output handler but no bundled output script is available`);r=n}return{name:e.adapter.name,pathPattern:e.adapter.pathPattern,methods:e.methods.map(e=>qt[e]),inputScript:n,outputScript:r,enabled:e.adapter.enabled,priority:e.adapter.priority}})}function protoSubgraph(e){let t;switch(e.Type){case`tailordb`:t=m.TAILORDB;break;case`pipeline`:t=m.PIPELINE;break;case`idp`:t=m.IDP;break;case`auth`:t=m.AUTH;break;default:throw Error(`Unknown subgraph type: ${e.Type}`)}return{serviceType:t,serviceNamespace:e.Name}}const wi=H.object({hash:H.string(),updateTime:H.string().optional()}),Ti=H.object({vaults:H.record(H.string(),H.record(H.string(),wi)),connections:H.record(H.string(),H.string()).optional()}),Ei=H.object({version:H.literal(2),workspaceId:H.string(),applicationKey:H.string(),state:Ti});function getSecretsStatePath(e){let t=hashValue(JSON.stringify([e.workspaceId,applicationStateKey(e)]));return B.join(Gt(),`secrets-state`,`${t}.json`)}function loadPersistedSecretsState(e){try{let t=Hn(getSecretsStatePath(e),`utf-8`),n=Ei.parse(JSON.parse(t));return n.workspaceId!==e.workspaceId||n.applicationKey!==applicationStateKey(e)?void 0:n}catch{return}}function applicationStateKey(e){if(!e.applicationId)throw Error(`Application "${e.applicationName}" has no stable id for secrets state`);return`id:${e.applicationId}`}function loadSecretsState(e){return e.applicationId?loadPersistedSecretsState(e)?.state??{vaults:{}}:{vaults:{}}}function saveSecretsState(e,t){if(!e.applicationId)return;let n=getSecretsStatePath(e),r=B.dirname(n);Vn(r,{recursive:!0});let i=`${n}.tmp-${or()}`;qn(i,JSON.stringify({version:2,workspaceId:e.workspaceId,applicationKey:applicationStateKey(e),state:t},null,2),`utf-8`),Un(i,n)}function hashValue(e){return ar(`sha256`).update(e).digest(`hex`)}function serializeUpdateTime(e){return e===void 0?void 0:`${e.seconds}.${e.nanos}`}const Di=new Map;async function withSecretsStateLock(e,t){if(!e.applicationId)return t();let n=`${getSecretsStatePath(e)}.lock`,r=Di.get(n);return r||(r=rr(1),Di.set(n,r)),r(async()=>{let e=await acquireFileLock(n),r=setInterval(()=>refreshLock(n,e),1e4);r.unref();try{return await t()}finally{clearInterval(r),releaseFileLock(n,e)}})}async function acquireFileLock(e){Vn(B.dirname(e),{recursive:!0});let t=or(),n=Date.now()+3e5;for(;;){let r=!0;try{Vn(e)}catch(e){if(e.code!==`EEXIST`)throw e;r=!1}if(r){try{qn(B.join(e,`owner.json`),JSON.stringify({pid:process.pid,token:t}))}catch(t){throw Wn(e,{recursive:!0,force:!0}),t}return t}if(!(isLockExpired(e)&&stealLock(e))){if(Date.now()>=n)throw Error(`Timed out waiting for another deploy to the same workspace and application to finish. Wait for it to complete and retry; an interrupted deploy recovers automatically within a minute.`);await new Promise(e=>setTimeout(e,100))}}}function isLockExpired(e){try{return Date.now()-Gn(e).mtimeMs>6e4}catch{return!1}}function readLockToken(e){try{return JSON.parse(Hn(B.join(e,`owner.json`),`utf-8`)).token}catch{return}}function refreshLock(e,t){if(readLockToken(e)!==t)return;let n=new Date;try{Kn(e,n,n)}catch{}}function releaseFileLock(e,t){readLockToken(e)===t&&Wn(e,{recursive:!0,force:!0})}function stealLock(e){let t=`${e}.stale-${process.pid}-${Date.now()}`;try{Un(e,t)}catch{return!1}if(isLockExpired(t))return Wn(t,{recursive:!0,force:!0}),!0;try{Un(t,e)}catch{Wn(t,{recursive:!0,force:!0})}return!1}function buildConnectionRequest(e,t,n){return{workspaceId:e,connection:{name:t,type:rt.OAUTH2,config:{case:`oauth2`,value:{providerUrl:n.providerUrl,issuerUrl:n.issuerUrl,clientId:n.clientId,clientSecret:n.clientSecret,authUrl:n.authUrl??``,tokenUrl:n.tokenUrl??``}}}}}function buildUpdateMask(e,t,n){if(e.config.case!==`oauth2`){let e=[`type`,`oauth2.provider_url`,`oauth2.issuer_url`,`oauth2.client_id`,`oauth2.auth_url`,`oauth2.token_url`];return t.clientSecret&&e.push(`oauth2.client_secret`),{paths:e}}let r=[],i=e.config.value;return i.providerUrl!==t.providerUrl&&r.push(`oauth2.provider_url`),i.issuerUrl!==t.issuerUrl&&r.push(`oauth2.issuer_url`),i.clientId!==t.clientId&&r.push(`oauth2.client_id`),i.authUrl!==(t.authUrl??``)&&r.push(`oauth2.auth_url`),i.tokenUrl!==(t.tokenUrl??``)&&r.push(`oauth2.token_url`),n&&t.clientSecret&&r.push(`oauth2.client_secret`),{paths:r}}async function planAuthConnections(e,t,n,r,i){let a={workspaceId:t,applicationId:r,applicationName:n},o=createChangeSet(`Auth connections`),s=[],c=[],l=new Set,u={};for(let e of i)for(let[t,n]of Object.entries(e.connections))u[t]=n;let d=await P(async(n,r)=>{let{connections:i,nextPageToken:a}=await e.listAuthConnections({workspaceId:t,pageToken:n,pageSize:r});return[i,a]}),f={};await Promise.all(d.map(async n=>{let{metadata:r}=await e.getMetadata({trn:resourceTrn(t,`auth_connection`,n.name)});f[n.name]={resource:n,label:r?.labels[yi],allLabels:r?.labels}}));let p=loadSecretsState(a);for(let[e,i]of Object.entries(u)){let a=f[e],l=await buildMetaRequest({trn:resourceTrn(t,`auth_connection`,e),appName:n,appId:r});if(a){let u=trackDesiredResourceOwnership({labels:a.allLabels,ownerLabel:a.label,appName:n,appId:r,resourceType:`Auth connection`,resourceName:e,conflicts:s,unmanaged:c}),d=hashValue(i.clientSecret)!==p.connections?.[e],m=buildUpdateMask(a.resource,i,d);m.paths.length>0?o.replaces.push({name:e,updateRequest:{...buildConnectionRequest(t,e,i),updateMask:m},metaRequest:l}):u?o.unchanged.push({name:e}):o.updates.push({name:e,metaRequest:l}),delete f[e]}else o.creates.push({name:e,request:buildConnectionRequest(t,e,i),metaRequest:l})}for(let[e,i]of Object.entries(f))i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceOwners:l})&&o.deletes.push({name:e,request:{workspaceId:t,connectionName:e}});return{changeSet:o,conflicts:s,unmanaged:c,resourceOwners:l,stateScope:a}}async function applyAuthConnections(e,t,n){let{changeSet:r,stateScope:i}=t;n===`create-update`?((r.creates.length>0||r.replaces.length>0)&&await withSecretsStateLock(i,async()=>{await Promise.all(r.creates.map(async t=>{await e.createAuthConnection(t.request),await writeMetadataLabels(e,t.metaRequest),M.info(`Connection "${t.name}" was created. Authorize it with:\n tailor authconnection authorize --name ${t.name}\nOr via the Console: tailor authconnection open`)}));for(let t of r.replaces)(await e.updateAuthConnection(t.updateRequest)).connection?.status===o.UNAUTHORIZED&&M.warn(`Connection "${t.name}" requires re-authorization. Authorize with:\n tailor authconnection authorize --name ${t.name}\nOr via the Console: tailor authconnection open`),await writeMetadataLabels(e,t.metaRequest);let t=r.replaces.filter(e=>e.updateRequest.updateMask?.paths?.includes(`oauth2.client_secret`));if(r.creates.length>0||t.length>0){let e=loadSecretsState(i);e.connections||={};for(let t of r.creates){let n=t.request.connection;n?.config?.case===`oauth2`&&(e.connections[t.name]=hashValue(n.config.value.clientSecret??``))}for(let n of t){let t=n.updateRequest.connection;t?.config?.case===`oauth2`&&(e.connections[n.name]=hashValue(t.config.value.clientSecret??``))}saveSecretsState(i,e)}}),await Promise.all(r.updates.map(async t=>{await writeMetadataLabels(e,t.metaRequest)}))):r.deletes.length>0&&await withSecretsStateLock(i,async()=>{await Promise.all(r.deletes.map(async t=>{await e.deleteAuthConnection(t.request)}));let t=loadSecretsState(i);if(t.connections){for(let e of r.deletes)delete t.connections[e.name];saveSecretsState(i,t)}})}const Oi=65536;function computeContentHash(e){return ir.createHash(`sha256`).update(e,`utf-8`).digest(`hex`)}const ki=`workflow--`;function resolverFunctionName(e,t){return`resolver--${e}--${t}`}function executorFunctionName(e){return`executor--${e}`}function workflowJobFunctionName(e){return`${ki}${e}`}function splitFunctionRegistryChanges(e){function partition(e){let t={workflowJob:[],resolver:[],executor:[],authHook:[],other:[]};for(let n of e)n.name.startsWith(`workflow--`)?t.workflowJob.push(n):n.name.startsWith(`resolver--`)?t.resolver.push(n):n.name.startsWith(`executor--`)?t.executor.push(n):n.name.startsWith(`auth-hook--`)?t.authHook.push(n):t.other.push(n);return t}let t=partition(e.creates),n=partition(e.updates),r=partition(e.deletes),i=partition(e.replaces),a=partition(e.unchanged);function collect(e){return{creates:t[e],updates:n[e],deletes:r[e],replaces:i[e],unchanged:a[e]}}return{workflowJobChanges:collect(`workflowJob`),resolverFunctionChanges:collect(`resolver`),executorFunctionChanges:collect(`executor`),authHookFunctionChanges:collect(`authHook`),otherChanges:collect(`other`)}}function authHookFunctionName(e,t){return`auth-hook--${e}--${t}`}function collectFunctionEntries(e,t,n){let r=[];for(let t of e.applications)for(let e of t.resolverServices)for(let t of Object.values(e.resolvers)){let i=n.resolvers.get(Bt(e.namespace,t.name));if(!i){M.warn(`Bundled code not found for resolver: ${e.namespace}/${t.name}`);continue}r.push({name:resolverFunctionName(e.namespace,t.name),scriptContent:i,contentHash:computeContentHash(i),description:`Resolver: ${e.namespace}/${t.name}`})}if(e.executorService){let t=e.executorService.executors;for(let e of Object.values(t))if(e.operation.kind===`function`||e.operation.kind===`jobFunction`){let t=n.executors.get(e.name);if(!t){M.warn(`Bundled code not found for executor: ${e.name}`);continue}r.push({name:executorFunctionName(e.name),scriptContent:t,contentHash:computeContentHash(t),description:`Executor: ${e.name}`})}}for(let e of t){let t=n.workflowJobs.get(e.name);if(!t){M.warn(`Bundled code not found for workflow job: ${e.name}`);continue}r.push({name:workflowJobFunctionName(e.name),scriptContent:t,contentHash:computeContentHash(t),description:`Workflow job: ${e.name}`})}for(let t of e.applications)if(t.authService?.config.hooks?.beforeLogin){let e=t.authService.config.name,i=authHookFunctionName(e,`before-login`),a=n.authHooks.get(i);if(!a){M.warn(`Bundled code not found for auth hook: ${i}`);continue}r.push({name:i,scriptContent:a,contentHash:computeContentHash(a),description:`Auth hook: ${e}/before-login`})}return r}function filterBundledWorkflowJobs(e,t){let n=new Set(t);return e.filter(e=>n.has(e.name))}async function planFunctionRegistry(e,t,n,r,i){let a=createChangeSet(`Function registry`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let i=await e.listFunctionRegistries({workspaceId:t,pageToken:n,pageSize:r});return[i.functions.map(e=>({name:e.name,contentHash:e.contentHash})),i.nextPageToken]},getName:e=>e.name,getTrn:e=>resourceTrn(t,`function_registry`,e)});for(let e of i){let i=l[e.name],c=await buildMetaRequest({trn:resourceTrn(t,`function_registry`,e.name),appName:n,appId:r});if(i){let t=trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceType:`Function registry`,resourceName:e.name,conflicts:o,unmanaged:s});i.resource.contentHash===e.contentHash&&t&&hasMatchingSdkVersion(i.allLabels,c.labels)?a.unchanged.push({name:e.name}):a.updates.push({name:e.name,entry:e,metaRequest:c}),delete l[e.name]}else a.creates.push({name:e.name,entry:e,metaRequest:c})}for(let[e,i]of Object.entries(l))i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceOwners:c})&&a.deletes.push({name:e,workspaceId:t});let{workflowJobChanges:u,resolverFunctionChanges:d,executorFunctionChanges:f,authHookFunctionChanges:p}=splitFunctionRegistryChanges(a);return{changeSet:a,workflowJobChanges:u,resolverFunctionChanges:d,executorFunctionChanges:f,authHookFunctionChanges:p,conflicts:o,unmanaged:s,resourceOwners:c}}async function uploadFunctionScript(e,t,n,r){let i=Buffer.from(n.scriptContent,`utf-8`),a={workspaceId:t,name:n.name,description:n.description,sizeBytes:BigInt(i.length),contentHash:n.contentHash};if(r){async function*createStream(){yield{payload:{case:`info`,value:a}};for(let e=0;e<i.length;e+=Oi)yield{payload:{case:`chunk`,value:i.subarray(e,Math.min(e+Oi,i.length))}}}await e.createFunctionRegistry(createStream())}else{async function*updateStream(){yield{payload:{case:`info`,value:a}};for(let e=0;e<i.length;e+=Oi)yield{payload:{case:`chunk`,value:i.subarray(e,Math.min(e+Oi,i.length))}}}await e.updateFunctionRegistry(updateStream())}}async function applyFunctionRegistry(e,t,n,r=`create-update`){let{changeSet:i}=n;if(r===`create-update`){let n=Pt();await Promise.all([...i.creates.map(r=>n(async()=>{await uploadFunctionScript(e,t,r.entry,!0),await writeMetadataLabels(e,r.metaRequest)})),...i.updates.map(r=>n(async()=>{await uploadFunctionScript(e,t,r.entry,!1),await writeMetadataLabels(e,r.metaRequest)}))])}else await Promise.all(i.deletes.map(t=>e.deleteFunctionRegistry({workspaceId:t.workspaceId,name:t.name})))}function createRelatedFunctionRegistryNameSets(e){return{creates:new Set(e?.creates.map(e=>e.name)??[]),updates:new Set(e?.updates.map(e=>e.name)??[]),deletes:new Set(e?.deletes.map(e=>e.name)??[]),replaces:new Set(e?.replaces.map(e=>e.name)??[])}}const Ai={create:j.create,update:j.update,delete:j.delete,replace:j.replace};function formatChangeSetEntries(e,t=[],n){function toEntry(e,r){return{action:e,symbol:Ai[e],name:r.name,labels:[...t],namespace:n?.(r)}}return[...e.creates.map(e=>toEntry(`create`,e)),...e.deletes.map(e=>toEntry(`delete`,e)),...e.updates.map(e=>toEntry(`update`,e)),...e.replaces.map(e=>toEntry(`replace`,e))]}function formatGroupedDisplayLine(e){return e.labels.length>0?`${e.symbol} ${e.name} (${e.labels.join(`, `)})`:`${e.symbol} ${e.name}`}function parseFunctionRegistryName(e){if(e.startsWith(`resolver--`)){let[,t,n]=e.split(`--`);if(t&&n)return{displayName:n,namespace:t}}if(e.startsWith(`workflow--`)||e.startsWith(`executor--`))return{displayName:e.slice(10)};if(e.startsWith(`auth-hook--`)){let[,t,n]=e.split(`--`);if(t&&n)return{displayName:n,namespace:t}}return{displayName:e}}function buildRemainingFunctionRegistryEntries(e,t=createRelatedFunctionRegistryNameSets()){return[[`create`,e.creates,t.creates],[`delete`,e.deletes,t.deletes],[`update`,e.updates,t.updates],[`replace`,e.replaces,t.replaces]].flatMap(([e,t,n])=>[...t].filter(e=>!n.has(e)).map(t=>{let{displayName:n,namespace:r}=parseFunctionRegistryName(t);return{action:e,symbol:Ai[e],name:n,labels:[`function`],namespace:r}}))}function formatChangeEntriesWithFunctionRegistry(e,t,n,r,i){let{getNamespace:a,getDisplayName:o}=i??{},s=createRelatedFunctionRegistryNameSets(n),c=createRelatedFunctionRegistryNameSets();function processItems(t,n,i,s){return t.map(t=>{let c=r(t,n),l=c.some(e=>i.has(e));if(l)for(let e of c)i.has(e)&&s.add(e);return{action:n,symbol:Ai[n],name:o?.(t)??t.name,labels:l?[e,`function`]:[e],namespace:a?.(t)}})}return[...processItems(t.creates,`create`,s.creates,c.creates),...processItems(t.deletes,`delete`,s.deletes,c.deletes),...processItems(t.updates,`update`,s.updates,c.updates),...t.replaces.map(t=>({action:`replace`,symbol:Ai.replace,name:o?.(t)??t.name,labels:[e],namespace:a?.(t)})),...buildRemainingFunctionRegistryEntries(s,c)]}function extractServiceActions(e){return[...e.creates.map(e=>({name:e.name,action:`create`})),...e.deletes.map(e=>({name:e.name,action:`delete`})),...e.updates.map(e=>({name:e.name,action:`update`})),...e.replaces.map(e=>({name:e.name,action:`replace`}))]}function buildGroupedDisplayLines(e,t,n){let r=new Map;if(n)for(let e of n)r.set(e.name,e.action);if(t.length===0&&r.size===0)return[];let i=[N.bold(`${e}:`)],a=[],o=new Map;for(let e of t){let t=e.namespace;o.has(t)||(a.push(t),o.set(t,[])),A(o.get(t),`namespace group missing`).push(e)}let s=new Set;for(let e of a){let t=A(o.get(e),`namespace group missing`);if(e){let n=r.get(e),a=n?`${Ai[n]} `:``;i.push(` ${a}${N.bold(`${e}:`)}`),s.add(e);for(let e of t)i.push(` ${formatGroupedDisplayLine(e)}`)}else for(let e of t)i.push(` ${formatGroupedDisplayLine(e)}`)}for(let[e,t]of r)s.has(e)||i.push(` ${Ai[t]} ${e}`);return i}const ji={tailorDBType:e=>`TailorDB table "${e}"`,resolver:e=>`Resolver "${e}"`,idpService:e=>`IdP service "${e}"`,workflow:e=>`Workflow "${e}"`,workflowJob:e=>`Job "${e}"`,workflowJobs:e=>`Jobs of workflow "${e}"`},Mi={tailorDBType:e=>({resource:ji.tailorDBType(e),trigger:`record`}),resolver:e=>({resource:ji.resolver(e),trigger:`resolverExecuted`}),idpService:e=>({resource:ji.idpService(e),trigger:`idpUser`}),workflow:e=>({resource:ji.workflow(e),trigger:`workflowExecution`}),workflowJob:e=>({resource:ji.workflowJob(e),trigger:`workflowJobExecution`,subscribesTo:`a workflow that runs it`})};function publishEventsConflictError(e){let{resource:t,trigger:n,subscribesTo:r=`it`}=e;return`${t} has "publishEvents: false", but executors with ${n} triggers subscribe to ${r}. Either remove "publishEvents: false" or remove the matching executor triggers.`}function subscribesToEvents(e){return!e.disabled}function assertNoPublishEventsConflict(e){let{explicit:t,subscribed:n,conflict:r}=e;if(t===!1&&n)throw Error(publishEventsConflictError(r))}function resolvePublishEvents(e){return assertNoPublishEventsConflict(e),e.explicit??e.subscribed}const{normalizeActionPermission:Ni}=Ft({"=":`eq`,"!=":`ne`,in:`in`,"not in":`nin`});function normalizeIdPActionPermission(e){return Ni(e)}function normalizeIdPPermission(e){return{create:e.create.map(e=>normalizeIdPActionPermission(e)),read:e.read.map(e=>normalizeIdPActionPermission(e)),update:e.update.map(e=>normalizeIdPActionPermission(e)),delete:e.delete.map(e=>normalizeIdPActionPermission(e)),sendPasswordResetEmail:(e.sendPasswordResetEmail??[]).map(e=>normalizeIdPActionPermission(e)),unenrollMfa:(e.unenrollMfa??[]).map(e=>normalizeIdPActionPermission(e))}}function parseIdPPermission(e){if(e)return normalizeIdPPermission(e)}function findOmittedPermitRules(e){if(!e)return[];let t=[];for(let n of Object.keys(e))e[n]?.forEach((e,r)=>{nn(e)&&t.push(`${String(n)}[${r}]`)});return t}async function resolveServiceReturnOrigins(e,t){let n=t.userAuthPolicy,r=n?.allowedReturnOrigins;if(!n||!r?.length)return;let i=await Xt(e,A(t.workspaceId,`request missing workspaceId`),r,`IdP service "${t.namespaceName??``}" allowedReturnOrigins`);if(i.length!==r.length)throw Error(`IdP service "${t.namespaceName??``}" allowedReturnOrigins: ${r.length-i.length} of ${r.length} entries could not be resolved. Check that each "<name>:url" entry refers to a deployed static website.`);n.allowedReturnOrigins=i}function idpClientVaultName(e,t){return`idp-${e}-${t}`}function idpClientSecretName(e,t){return`client-secret-${e}-${t}`}async function applyIdP(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?(await Promise.all([...r.service.creates.map(async t=>{await resolveServiceReturnOrigins(e,t.request),await e.createIdPService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await resolveServiceReturnOrigins(e,t.request),await e.updateIdPService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.unchanged.flatMap(t=>t.metaRequest?[writeMetadataLabels(e,t.metaRequest)]:[])]),await Promise.all([...r.client.creates.map(async t=>{let n=await e.createIdPClient(t.request),r=idpClientVaultName(A(t.request.namespaceName,`request missing namespaceName`),t.request.client?.name||``),i=idpClientSecretName(A(t.request.namespaceName,`request missing namespaceName`),t.request.client?.name||``);await e.createSecretManagerVault({workspaceId:t.request.workspaceId,secretmanagerVaultName:r}),await e.createSecretManagerSecret({workspaceId:t.request.workspaceId,secretmanagerVaultName:r,secretmanagerSecretName:i,secretmanagerSecretValue:n.client?.clientSecret})}),...r.client.updates.map(async t=>{let n=idpClientVaultName(t.namespaceName,t.name),r=idpClientSecretName(t.namespaceName,t.name);await I(async()=>await e.getSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:n}))||(await e.createSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:n}),await e.createSecretManagerSecret({workspaceId:t.workspaceId,secretmanagerVaultName:n,secretmanagerSecretName:r,secretmanagerSecretValue:t.clientSecret}))})])):n===`delete-resources`?await Promise.all(r.client.deletes.map(async t=>{await e.deleteIdPClient(t.request);let n=`idp-${t.request.namespaceName}-${t.request.name}`;await e.deleteSecretManagerVault({workspaceId:t.request.workspaceId,secretmanagerVaultName:n})})):await Promise.all(r.service.deletes.map(t=>e.deleteIdPService(t.request)))}async function planIdP(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1,idpUserTriggerTargets:o,dependentApps:s,runAppIds:c}=e,l=i?[]:r.idpServices,u=expectedLocalStaticWebsiteNames(e),{changeSet:d,conflicts:f,unmanaged:p,resourceOwners:m}=await planServices$3(t,n,r.name,r.id,l,o??new Set,u,{dependentApps:s,runAppIds:c});return{changeSet:{service:d,client:await planClients(t,n,l,d.deletes.map(e=>e.name),a)},conflicts:f,unmanaged:p,resourceOwners:m}}function normalizeComparableUserAuthPolicy(e){return{useNonEmailIdentifier:e?.useNonEmailIdentifier??!1,allowSelfPasswordReset:e?.allowSelfPasswordReset??!1,passwordRequireUppercase:e?.passwordRequireUppercase??!1,passwordRequireLowercase:e?.passwordRequireLowercase??!1,passwordRequireNonAlphanumeric:e?.passwordRequireNonAlphanumeric??!1,passwordRequireNumeric:e?.passwordRequireNumeric??!1,passwordMinLength:e?.passwordMinLength||6,passwordMaxLength:e?.passwordMaxLength||4096,allowedEmailDomains:(e?.allowedEmailDomains??[]).toSorted(),allowGoogleOauth:e?.allowGoogleOauth??!1,disablePasswordAuth:e?.disablePasswordAuth??!1,allowMicrosoftOauth:e?.allowMicrosoftOauth??!1,enableMfa:e?.enableMfa??!1,requireMfa:e?.requireMfa??!1,allowedReturnOrigins:(e?.allowedReturnOrigins??[]).toSorted(),mfaIssuer:e?.mfaIssuer??``}}function normalizeComparableDisableGqlOperations(e){return{create:e?.create??!1,update:e?.update??!1,delete:e?.delete??!1,read:e?.read??!1,sendPasswordResetEmail:e?.sendPasswordResetEmail??!1,requestMfaSettingsUrl:e?.requestMfaSettingsUrl??!1,unenrollMfa:e?.unenrollMfa??!1}}function normalizeComparableEmailConfig(e){return{fromName:e?.fromName??``,passwordResetSubject:e?.passwordResetSubject??``}}function normalizeComparableIdPService(e){return{authorization:e.authorization||void 0,lang:e.lang===oe.UNSPECIFIED?oe.EN:e.lang,userAuthPolicy:e.userAuthPolicy,publishEvents:e.publishEvents,disableGqlOperations:e.disableGqlOperations,emailConfig:e.emailConfig,permission:e.permission}}function normalizeComparablePermission(e){if(!e||e.create.length===0&&e.read.length===0&&e.update.length===0&&e.delete.length===0&&e.sendPasswordResetEmail.length===0&&e.unenrollMfa.length===0)return;let normalizePolicy=e=>({conditions:e.conditions.map(e=>({left:e.left?{kind:e.left.kind}:void 0,operator:e.operator,right:e.right?{kind:e.right.kind}:void 0})),permit:e.permit,description:e.description||void 0});return{create:e.create.map(normalizePolicy),read:e.read.map(normalizePolicy),update:e.update.map(normalizePolicy),delete:e.delete.map(normalizePolicy),sendPasswordResetEmail:e.sendPasswordResetEmail.map(normalizePolicy),unenrollMfa:e.unenrollMfa.map(normalizePolicy)}}function areIdPServicesEqual(e,t){return areNormalizedEqual(normalizeComparableIdPService({authorization:e.authorization,lang:e.lang,userAuthPolicy:normalizeComparableUserAuthPolicy(e.userAuthPolicy),publishEvents:e.publishUserEvents,disableGqlOperations:normalizeComparableDisableGqlOperations(e.disableGqlOperations),emailConfig:normalizeComparableEmailConfig(e.emailConfig),permission:normalizeComparablePermission(e.permission)}),t)}async function planServices$3(e,t,n,r,i,a,o,s){let c=createChangeSet(`IdP services`),l=[],u=[],d=new Set,f=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{idpServices:i,nextPageToken:a}=await e.listIdPServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`idp`,e)});for(let d of i){let i=d.name,p=f[i],m=addDependencyRecords(await buildMetaRequest({trn:resourceTrn(t,`idp`,i),appName:n,appId:r}),{key:Q.idp(i),dependentApps:s.dependentApps,runAppIds:s.runAppIds,pinned:d.publishEvents!==void 0}),h;switch(d.authorization){case`insecure`:h=`true==true`;break;case`loggedIn`:h=`user != null && size(user.id) > 0`;break;case void 0:h=void 0;break;default:h=d.authorization.cel}let g=convertLang(d.lang),_=d.userAuthPolicy,v=resolvePublishEvents({explicit:d.publishEvents,subscribed:a.has(i),conflict:Mi.idpService(i)}),y=d.emailConfig;d.permission||M.warn(`IdP service "${i}" has no permission configured.`);let b=findOmittedPermitRules(d.permission);b.length>0&&M.warn(`IdP service "${i}" has permission rule(s) ${b.join(`, `)} in object form without an explicit "permit"; they default to "deny". Set permit: true (allow) or permit: false (deny) to silence this warning.`);let x=parseIdPPermission(d.permission),S=x?protoIdPPermission(x):void 0,C=await Xt(e,t,_?.allowedReturnOrigins?[..._.allowedReturnOrigins]:[],`IdP service "${i}" allowedReturnOrigins`,{expectedLocalNames:o}),w=_&&{..._,allowedReturnOrigins:C},ee=normalizeComparableIdPService({authorization:h,lang:g,userAuthPolicy:normalizeComparableUserAuthPolicy(w),publishEvents:v,disableGqlOperations:normalizeComparableDisableGqlOperations(convertGqlOperationsToDisable(d.gqlOperations)),emailConfig:normalizeComparableEmailConfig(y),permission:S}),te={workspaceId:t,namespaceName:i,authorization:h,lang:g,userAuthPolicy:_,publishUserEvents:v,disableGqlOperations:convertGqlOperationsToDisable(d.gqlOperations),emailConfig:y,permission:S};p?(trackDesiredResourceOwnership({labels:p.allLabels,ownerLabel:p.label,appName:n,appId:r,resourceType:`IdP service`,resourceName:d.name,conflicts:l,unmanaged:u})&&hasMatchingSdkVersion(p.allLabels,m.labels)&&areIdPServicesEqual(p.resource,ee)?c.unchanged.push({name:i,metaRequest:m}):c.updates.push({name:i,request:te,metaRequest:m}),delete f[i]):c.creates.push({name:i,request:te,metaRequest:m})}return Object.entries(f).forEach(([e])=>{let i=f[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:d})&&c.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:c,conflicts:l,unmanaged:u,resourceOwners:d}}async function planClients(e,t,n,r,i=!1){let a=createChangeSet(`IdP clients`),fetchClients=n=>P(async(r,i)=>{let{clients:a,nextPageToken:o}=await e.listIdPClients({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}),o=await Promise.all(n.map(e=>fetchClients(e.name)));for(let[e,r]of n.entries()){let n=r.name,s=A(o[e],`clientsByIdp missing entry for idp index`),c=new Map;s.forEach(e=>{c.set(e.name,e.clientSecret)});for(let e of r.clients)c.has(e)?(i?a.updates.push({name:e,workspaceId:t,namespaceName:n,clientSecret:c.get(e)??``}):a.unchanged.push({name:e}),c.delete(e)):a.creates.push({name:e,request:{workspaceId:t,namespaceName:n,client:{name:e}}});c.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,namespaceName:n,name:r}})})}let s=await Promise.all(r.map(e=>fetchClients(e)));for(let[e,n]of r.entries())A(s[e],`deletedClientsByService missing entry for service index`).forEach(e=>{a.deletes.push({name:e.name,request:{workspaceId:t,namespaceName:n,name:e.name}})});return a}function convertLang(e){switch(e){case`en`:return oe.EN;case`ja`:return oe.JA;default:return oe.UNSPECIFIED}}function convertGqlOperationsToDisable(e){if(e)return{create:e.create===!1,update:e.update===!1,delete:e.delete===!1,read:e.read===!1,sendPasswordResetEmail:e.sendPasswordResetEmail===!1,requestMfaSettingsUrl:e.requestMfaSettingsUrl===!1,unenrollMfa:e.unenrollMfa===!1}}function protoIdPPermission(e){return{create:e.create.map(e=>protoIdPPolicy(e)),read:e.read.map(e=>protoIdPPolicy(e)),update:e.update.map(e=>protoIdPPolicy(e)),delete:e.delete.map(e=>protoIdPPolicy(e)),sendPasswordResetEmail:e.sendPasswordResetEmail.map(e=>protoIdPPolicy(e)),unenrollMfa:e.unenrollMfa.map(e=>protoIdPPolicy(e))}}function protoIdPPolicy(e){let t;switch(e.permit){case`allow`:t=u.ALLOW;break;case`deny`:t=u.DENY;break;default:throw Error(`Unknown permission: ${e.permit}`)}return{conditions:e.conditions.map(e=>protoIdPCondition(e)),permit:t,description:e.description}}function protoIdPCondition(e){let[t,n,r]=e,i=protoIdPOperand(t),a=protoIdPOperand(r),o;switch(n){case`eq`:o=le.EQ;break;case`ne`:o=le.NE;break;case`in`:o=le.IN;break;case`nin`:o=le.NIN;break;default:throw Error(`Unknown operator: ${n}`)}return{left:i,operator:o,right:a}}function protoIdPOperand(e){if(typeof e==`object`&&!Array.isArray(e)){if(`user`in e)return{kind:{case:`userField`,value:e.user}};if(`idpUser`in e)return{kind:{case:`idpUserField`,value:e.idpUser}};if(`newIdpUser`in e)return{kind:{case:`newIdpUserField`,value:e.newIdpUser}};if(`oldIdpUser`in e)return{kind:{case:`oldIdpUserField`,value:e.oldIdpUser}};throw Error(`Unknown operand: ${JSON.stringify(e)}`)}return{kind:{case:`value`,value:zn(Yn,e)}}}async function applyAuth(e,t,n=`create-update`){let{changeSet:r}=t;(n===`create-update-prerequisites`||n===`create-update`)&&(await(async()=>{await Promise.all([...r.service.creates.map(async t=>{await e.createAuthService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await e.updateAuthService(t.request),await writeMetadataLabels(e,t.metaRequest)})])})(),await(async()=>{await Promise.all([...r.machineUser.creates.map(t=>e.createAuthMachineUser(t.request)),...r.machineUser.updates.map(t=>e.updateAuthMachineUser(t.request))])})()),(n===`create-update-dependents`||n===`create-update`)&&await(async()=>{await applyAuthConnections(e,{changeSet:r.connection,stateScope:t.connectionStateScope},`create-update`),await Promise.all([...r.idpConfig.creates.map(async t=>(t.idpConfig.kind===`BuiltInIdP`&&(A(t.request.idpConfig,`request missing idpConfig`).config=await protoBuiltinIdPConfig(e,A(t.request.workspaceId,`request missing workspaceId`),t.idpConfig)),e.createAuthIDPConfig(t.request))),...r.idpConfig.updates.map(async t=>(t.idpConfig.kind===`BuiltInIdP`&&(A(t.request.idpConfig,`request missing idpConfig`).config=await protoBuiltinIdPConfig(e,A(t.request.workspaceId,`request missing workspaceId`),t.idpConfig)),e.updateAuthIDPConfig(t.request)))]),await Promise.all([...r.userProfileConfig.creates.map(t=>e.createUserProfileConfig(t.request)),...r.userProfileConfig.updates.map(t=>e.updateUserProfileConfig(t.request))]),await Promise.all([...r.tenantConfig.creates.map(t=>e.createTenantConfig(t.request)),...r.tenantConfig.updates.map(t=>e.updateTenantConfig(t.request))]),await Promise.all([...r.authHook.creates.map(t=>e.createAuthHook(t.request)),...r.authHook.updates.map(t=>e.updateAuthHook(t.request))]),await Promise.all([...r.oauth2Client.creates.map(async t=>{let n=A(t.request.oauth2Client,`request missing oauth2Client`);return n.redirectUris=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),e.createAuthOAuth2Client(t.request)}),...r.oauth2Client.updates.map(async t=>{let n=A(t.request.oauth2Client,`request missing oauth2Client`);return n.redirectUris=await Xt(e,A(t.request.workspaceId,`request missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),e.updateAuthOAuth2Client(t.request)})]);for(let t of r.oauth2Client.replaces){await e.deleteAuthOAuth2Client(t.deleteRequest);let n=A(t.createRequest.oauth2Client,`createRequest missing oauth2Client`);n.redirectUris=await Xt(e,A(t.createRequest.workspaceId,`createRequest missing workspaceId`),n.redirectUris,`OAuth2 redirect URIs`),await e.createAuthOAuth2Client(t.createRequest)}await Promise.all([...r.scim.creates.map(t=>e.createAuthSCIMConfig(t.request)),...r.scim.updates.map(t=>e.updateAuthSCIMConfig(t.request))]),await Promise.all([...r.scimResource.creates.map(t=>e.createAuthSCIMResource(t.request)),...r.scimResource.updates.map(t=>e.updateAuthSCIMResource(t.request))])})(),n===`delete-resources`?(await Promise.all(r.scimResource.deletes.map(t=>e.deleteAuthSCIMResource(t.request))),await Promise.all(r.scim.deletes.map(t=>e.deleteAuthSCIMConfig(t.request))),await Promise.all(r.oauth2Client.deletes.map(t=>e.deleteAuthOAuth2Client(t.request))),await Promise.all(r.authHook.deletes.map(t=>e.deleteAuthHook(t.request))),await Promise.all(r.machineUser.deletes.map(t=>e.deleteAuthMachineUser(t.request))),await Promise.all(r.tenantConfig.deletes.map(t=>e.deleteTenantConfig(t.request))),await(async()=>{await Promise.all(r.userProfileConfig.deletes.map(t=>e.deleteUserProfileConfig(t.request)))})(),await Promise.all(r.idpConfig.deletes.map(t=>e.deleteAuthIDPConfig(t.request))),await applyAuthConnections(e,{changeSet:r.connection,stateScope:t.connectionStateScope},`delete-resources`)):n===`delete-services`&&await Promise.all(r.service.deletes.map(t=>e.deleteAuthService(t.request)))}async function planAuth(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=[];!i&&r.authService&&(await r.authService.resolveNamespaces(),o.push(r.authService));let{changeSet:s,conflicts:c,unmanaged:l,resourceOwners:u}=await planServices$2(t,n,r.name,r.id,o,a),d=s.deletes.map(e=>e.name),f=expectedLocalStaticWebsiteNames(e),[p,m,h,g,_,v,y,b,x]=await Promise.all([planIdPConfigs(t,n,o,d,a),planUserProfileConfigs(t,n,o,d,a),planTenantConfigs(t,n,o,d,a),planMachineUsers(t,n,o,d,a),planAuthHooks(t,n,o,d,a),planOAuth2Clients(t,n,o,d,f,a),planSCIMConfigs(t,n,o,d),planSCIMResources(t,n,o,d),planAuthConnections(t,n,r.name,r.id,o)]);return{changeSet:{service:s,idpConfig:p,userProfileConfig:m,tenantConfig:h,machineUser:g,authHook:_,oauth2Client:v,scim:y,scimResource:b,connection:x.changeSet},conflicts:[...c,...x.conflicts],unmanaged:[...l,...x.unmanaged],resourceOwners:new Set([...u,...x.resourceOwners]),connectionStateScope:x.stateScope}}async function planServices$2(e,t,n,r,i,a=!1){let o=createChangeSet(`Auth services`),s=[],c=[],l=new Set,u=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{authServices:i,nextPageToken:a}=await e.listAuthServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`auth`,e)});for(let e of i){let{config:i}=e,l=u[i.name],d=await buildMetaRequest({trn:resourceTrn(t,`auth`,i.name),appName:n,appId:r}),f={workspaceId:t,namespaceName:i.name,publishSessionEvents:i.publishSessionEvents};if(l){let e=trackDesiredResourceOwnership({labels:l.allLabels,ownerLabel:l.label,appName:n,appId:r,resourceType:`Auth service`,resourceName:i.name,conflicts:s,unmanaged:c});!a&&l.resource.publishSessionEvents===(i.publishSessionEvents??!1)&&e?o.unchanged.push({name:i.name}):o.updates.push({name:i.name,request:f,metaRequest:d}),delete u[i.name]}else o.creates.push({name:i.name,request:f,metaRequest:d})}return Object.entries(u).forEach(([e])=>{let i=u[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:l})&&o.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:o,conflicts:s,unmanaged:c,resourceOwners:l}}async function planIdPConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth idpConfigs`),fetchIdPConfigs=n=>P(async(r,i)=>{let{idpConfigs:a,nextPageToken:o}=await e.listAuthIDPConfigs({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]});for(let r of n){let{config:n}=r,o=await fetchIdPConfigs(n.name),s=new Map;o.forEach(e=>{s.set(e.name,e)});let c=n.idProvider;if(c){let r=protoIdPConfig(c),o=s.get(c.name);if(o){let l=await protoIdPConfigForComparison(e,t,c,r);if(!l){a.updates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}}),s.delete(c.name);continue}!i&&areAuthIdPConfigsEqual(o,l)?a.unchanged.push({name:c.name}):a.updates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}}),s.delete(c.name)}else a.creates.push({name:c.name,idpConfig:c,request:{workspaceId:t,namespaceName:n.name,idpConfig:r}})}s.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,namespaceName:n.name,name:r}})})}for(let e of r)(await fetchIdPConfigs(e)).forEach(n=>{a.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return a}async function protoIdPConfigForComparison(e,t,n,r){if(n.kind!==`BuiltInIdP`)return r;let i=await tryProtoBuiltinIdPConfig(e,t,n);return i?{name:r.name,authType:r.authType,config:i}:void 0}function normalizeComparableAuthIdPConfig(e){return toComparableProtoJson(l,e)}function areAuthIdPConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableAuthIdPConfig(e),normalizeComparableAuthIdPConfig(t))}function protoIdPConfig(e){switch(e.kind){case`IDToken`:return{name:e.name,authType:c.ID_TOKEN,config:{config:{case:`idToken`,value:{providerUrl:e.providerURL,clientId:e.clientID,issuerUrl:e.issuerURL,usernameClaim:e.usernameClaim}}}};case`SAML`:return{name:e.name,authType:c.SAML,config:{config:{case:`saml`,value:{...e.metadataURL===void 0?{rawMetadata:A(e.rawMetadata,`SAML config missing rawMetadata`)}:{metadataUrl:e.metadataURL},enableSignRequest:e.enableSignRequest,defaultRedirectUrl:e.defaultRedirectURL}}}};case`OIDC`:return{name:e.name,authType:c.OIDC,config:{config:{case:`oidc`,value:{clientIdKey:e.clientID,clientSecretKey:{vaultName:e.clientSecret.vaultName,secretKey:e.clientSecret.secretKey},providerUrl:e.providerURL,issuerUrl:e.issuerURL,usernameClaim:e.usernameClaim}}}};case`BuiltInIdP`:return{name:e.name,authType:c.OIDC,config:{}};default:throw Error(`Unexpected idp kind: ${e}`)}}async function protoBuiltinIdPConfig(e,t,n){let r=await tryProtoBuiltinIdPConfig(e,t,n);if(!r)throw Error(`Built-in IdP "${n.namespace}" not found. Please ensure that idp is configured correctly.`);return r}async function tryProtoBuiltinIdPConfig(e,t,n){let r=await I(async()=>await e.getIdPService({workspaceId:t,namespaceName:n.namespace}));if(!r)return;let i=await I(async()=>await e.getIdPClient({workspaceId:t,namespaceName:n.namespace,name:n.clientName}));if(!i)return;let a=idpClientVaultName(n.namespace,n.clientName),o=idpClientSecretName(n.namespace,n.clientName);return{config:{case:`oidc`,value:{clientIdKey:i.client?.clientId,clientSecretKey:{vaultName:a,secretKey:o},providerUrl:r.idpService?.providerUrl,usernameClaim:`name`}}}}async function planUserProfileConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth userProfileConfigs`);for(let r of n){let{config:n}=r,o=`${n.name}-user-profile-config`,s=await I(async()=>await e.getUserProfileConfig({workspaceId:t,namespaceName:n.name}));if(!s){let e=r.userProfile;e&&a.creates.push({name:o,request:{workspaceId:t,namespaceName:n.name,userProfileProviderConfig:protoUserProfileConfig(e)}});continue}let c=r.userProfile;if(c){let e=protoUserProfileConfig(c);!i&&areUserProfileConfigsEqual(s.userProfileProviderConfig??{},e)?a.unchanged.push({name:o}):a.updates.push({name:o,request:{workspaceId:t,namespaceName:n.name,userProfileProviderConfig:e}})}else a.deletes.push({name:o,request:{workspaceId:t,namespaceName:n.name}})}for(let n of r)await I(async()=>await e.getUserProfileConfig({workspaceId:t,namespaceName:n}))&&a.deletes.push({name:`${n}-user-profile-config`,request:{workspaceId:t,namespaceName:n}});return a}function protoUserProfileConfig(e){let t=e.attributes?Object.fromEntries(Object.keys(e.attributes).map(e=>[e,e])):void 0;return{providerType:st.TAILORDB,config:{config:{case:`tailordb`,value:{namespace:e.namespace,type:e.type.name,usernameField:e.usernameField,tenantIdField:void 0,attributesFields:e.attributeList,attributeMap:t}}}}}async function planTenantConfigs(e,t,n,r,i=!1){let a=createChangeSet(`Auth tenantConfigs`);for(let r of n){let{config:n}=r,o=`${n.name}-tenant-config`,s=await I(async()=>await e.getTenantConfig({workspaceId:t,namespaceName:n.name}));if(!s){n.tenantProvider&&a.creates.push({name:o,request:{workspaceId:t,namespaceName:n.name,tenantProviderConfig:protoTenantConfig(n.tenantProvider)}});continue}if(n.tenantProvider){let e=protoTenantConfig(n.tenantProvider);!i&&areTenantProviderConfigsEqual(s.tenantProviderConfig,e)?a.unchanged.push({name:o}):a.updates.push({name:o,request:{workspaceId:t,namespaceName:n.name,tenantProviderConfig:e}})}else a.deletes.push({name:o,request:{workspaceId:t,namespaceName:n.name}})}for(let n of r)await I(async()=>await e.getTenantConfig({workspaceId:t,namespaceName:n}))&&a.deletes.push({name:`${n}-tenant-config`,request:{workspaceId:t,namespaceName:n}});return a}function protoTenantConfig(e){return{providerType:_.TAILORDB,config:{config:{case:`tailordb`,value:{namespace:e.namespace,type:e.type,signatureField:e.signatureField}}}}}async function planMachineUsers(e,t,n,r,i=!1){let a=createChangeSet(`Auth machineUsers`),fetchMachineUsers=n=>P(async(r,i)=>{let{machineUsers:a,nextPageToken:o}=await e.listAuthMachineUsers({workspaceId:t,authNamespace:n,pageToken:r,pageSize:i});return[a,o]});for(let e of n){let{config:n}=e,r=await fetchMachineUsers(n.name),o=new Map;r.forEach(e=>{o.set(e.name,e)});for(let e of Object.keys(n.machineUsers??{})){let r=n.machineUsers?.[e];if(!r)continue;let s={attributes:r.attributeList,attributeMap:r.attributes?protoMachineUserAttributeMap(r.attributes):void 0},c=o.get(e);c?(!i&&areMachineUsersEqual(c,s)?a.unchanged.push({name:e}):a.updates.push({name:e,request:{workspaceId:t,authNamespace:n.name,name:e,attributes:r.attributeList,attributeMap:s.attributeMap}}),o.delete(e)):a.creates.push({name:e,request:{workspaceId:t,authNamespace:n.name,name:e,attributes:r.attributeList,attributeMap:s.attributeMap}})}o.forEach((e,r)=>{a.deletes.push({name:r,request:{workspaceId:t,authNamespace:n.name,name:r}})})}for(let e of r)(await fetchMachineUsers(e)).forEach(n=>{a.deletes.push({name:n.name,request:{workspaceId:t,authNamespace:e,name:n.name}})});return a}function protoMachineUserAttributeMap(e){let t={};for(let[n,r]of Object.entries(e))t[n]=zn(Yn,r??null);return t}function normalizeComparableUserProfileConfig(e){let t=e.config?.config,n=t?.case===`tailordb`?t.value:void 0;return toComparableProtoJson(re,{providerType:e.providerType,config:n?{config:{case:`tailordb`,value:{...n,tenantIdField:n.tenantIdField||``,attributesFields:normalizeStringArray(n.attributesFields),attributeMap:normalizeProtoConfig(n.attributeMap??{})}}}:void 0})}function areUserProfileConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableUserProfileConfig(e),normalizeComparableUserProfileConfig(t))}function normalizeComparableTenantProviderConfig(e){return toComparableProtoJson(p,e??{})}function areTenantProviderConfigsEqual(e,t){return areNormalizedEqual(normalizeComparableTenantProviderConfig(e),normalizeComparableTenantProviderConfig(t))}function normalizeComparableMachineUser(e){return normalizeProtoConfig({attributes:normalizeStringArray(e.attributes),attributeMap:normalizeProtoConfig(e.attributeMap??{})})}function areMachineUsersEqual(e,t){return areNormalizedEqual(normalizeComparableMachineUser(e),normalizeComparableMachineUser(t))}function normalizeComparableOAuth2Client(e){let t=oauth2LifetimeToSeconds(e.accessTokenLifetime),n=oauth2LifetimeToSeconds(e.refreshTokenLifetime);return normalizeProtoConfig({...e,description:e.description||void 0,redirectUris:normalizeStringArray(e.redirectUris),grantTypes:(e.grantTypes??[]).toSorted((e,t)=>e-t),accessTokenLifetime:t??86400,refreshTokenLifetime:n??604800,requireDpop:e.requireDpop??!1})}function oauth2LifetimeToSeconds(e){if(typeof e==`number`)return e;if(e?.seconds!=null)return Number(e.seconds)}function areOAuth2ClientsEqual(e,t){return areNormalizedEqual(normalizeComparableOAuth2Client(e),normalizeComparableOAuth2Client(t))}async function planOAuth2Clients(e,t,n,r,i,a=!1){let o=createChangeSet(`Auth oauth2Clients`),fetchOAuth2Clients=n=>P(async(r,i)=>{let{oauth2Clients:a,nextPageToken:o}=await e.listAuthOAuth2Clients({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]});for(let r of n){let{config:n}=r,s=await fetchOAuth2Clients(n.name),c=new Map;s.forEach(e=>{c.set(e.name,e)});for(let r of Object.keys(n.oauth2Clients??{})){let s=n.oauth2Clients?.[r];if(!s)continue;let l=protoOAuth2Client(r,s),u=await Xt(e,t,l.redirectUris??[],`OAuth2 redirect URIs`,{expectedLocalNames:i});if(c.has(r)){let e=A(c.get(r),`existingClientsMap missing entry for oauth2ClientName`);if(e.clientType!==l.clientType)o.replaces.push({name:r,deleteRequest:{workspaceId:t,namespaceName:n.name,name:r},createRequest:{workspaceId:t,namespaceName:n.name,oauth2Client:l}});else{let i={...l,redirectUris:u,accessTokenLifetime:oauth2LifetimeToSeconds(l.accessTokenLifetime),refreshTokenLifetime:oauth2LifetimeToSeconds(l.refreshTokenLifetime)},s={name:e.name,description:e.description,grantTypes:e.grantTypes,redirectUris:e.redirectUris,clientType:e.clientType,accessTokenLifetime:oauth2LifetimeToSeconds(e.accessTokenLifetime),refreshTokenLifetime:oauth2LifetimeToSeconds(e.refreshTokenLifetime),requireDpop:e.requireDpop};!a&&areOAuth2ClientsEqual(s,i)?o.unchanged.push({name:r}):o.updates.push({name:r,request:{workspaceId:t,namespaceName:n.name,oauth2Client:l}})}c.delete(r)}else o.creates.push({name:r,request:{workspaceId:t,namespaceName:n.name,oauth2Client:l}})}c.forEach((e,r)=>{o.deletes.push({name:r,request:{workspaceId:t,namespaceName:n.name,name:r}})})}for(let e of r)(await fetchOAuth2Clients(e)).forEach(n=>{o.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return o}function protoOAuth2Client(e,t){return{name:e,description:t.description,grantTypes:t.grantTypes.map(e=>{switch(e){case`authorization_code`:return r.AUTHORIZATION_CODE;case`refresh_token`:return r.REFRESH_TOKEN;default:throw Error(`Unknown OAuth2 client grant type: ${e}`)}}),redirectUris:t.redirectURIs,clientType:{confidential:Fe.CONFIDENTIAL,public:Fe.PUBLIC,browser:Fe.BROWSER}[t.clientType??`confidential`],accessTokenLifetime:t.accessTokenLifetimeSeconds,refreshTokenLifetime:t.refreshTokenLifetimeSeconds,requireDpop:t.requireDpop}}async function planSCIMConfigs(e,t,n,r){let i=createChangeSet(`Auth scimConfigs`);for(let r of n){let{config:n}=r,a=`${n.name}-scim-config`;await I(async()=>await e.getAuthSCIMConfig({workspaceId:t,namespaceName:n.name}))?n.scim?i.updates.push({name:a,request:{workspaceId:t,namespaceName:n.name,scimConfig:protoSCIMConfig(n.scim)}}):i.deletes.push({name:a,request:{workspaceId:t,namespaceName:n.name}}):n.scim&&i.creates.push({name:a,request:{workspaceId:t,namespaceName:n.name,scimConfig:protoSCIMConfig(n.scim)}})}for(let n of r)await I(async()=>await e.getAuthSCIMConfig({workspaceId:t,namespaceName:n}))&&i.deletes.push({name:`${n}-scim-config`,request:{workspaceId:t,namespaceName:n}});return i}function protoSCIMConfig(e){let t;switch(e.authorization.type){case`bearer`:t=ee.BEARER;break;case`oauth2`:t=ee.OAUTH2;break;default:throw Error(`Unknown SCIM authorization type: ${e.authorization.type}`)}return{machineUserName:e.machineUserName,authorizationType:t,authorizationConfig:{case:`bearerSecret`,value:{vaultName:e.authorization.bearerSecret?.vaultName,secretKey:e.authorization.bearerSecret?.secretKey}}}}async function planSCIMResources(e,t,n,r){let i=createChangeSet(`Auth scimResources`),fetchSCIMResources=async n=>await I(async()=>{let{scimResources:r}=await e.getAuthSCIMResources({workspaceId:t,namespaceName:n});return r})??[];for(let e of n){let{config:n}=e,r=await fetchSCIMResources(n.name),a=new Set;r.forEach(e=>{a.add(e.name)});for(let e of n.scim?.resources??[])a.has(e.name)?(i.updates.push({name:e.name,request:{workspaceId:t,namespaceName:n.name,scimResource:protoSCIMResource(e)}}),a.delete(e.name)):i.creates.push({name:e.name,request:{workspaceId:t,namespaceName:n.name,scimResource:protoSCIMResource(e)}});a.forEach(e=>{i.deletes.push({name:e,request:{workspaceId:t,namespaceName:n.name,name:e}})})}for(let e of r)(await fetchSCIMResources(e)).forEach(n=>{i.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,name:n.name}})});return i}function protoSCIMResource(e){return{name:e.name,tailorDbNamespace:e.tailorDBNamespace,tailorDbType:e.tailorDBType,coreSchema:{name:e.coreSchema.name,attributes:e.coreSchema.attributes.map(e=>protoSCIMAttribute(e))},attributeMapping:e.attributeMapping.map(e=>({tailorDbField:e.tailorDBField,scimPath:e.scimPath}))}}function protoSCIMAttribute(e){let t;switch(e.type){case`string`:t=y.STRING;break;case`number`:t=y.NUMBER;break;case`boolean`:t=y.BOOLEAN;break;case`datetime`:t=y.DATETIME;break;case`complex`:t=y.COMPLEX;break;default:throw Error(`Unknown SCIM attribute type: ${e.type}`)}let n;if(e.mutability)switch(e.mutability){case`readOnly`:n=Ne.READ_ONLY;break;case`readWrite`:n=Ne.READ_WRITE;break;case`writeOnly`:n=Ne.WRITE_ONLY;break;default:throw Error(`Unknown SCIM attribute mutability: ${e.mutability}`)}let r;if(e.uniqueness)switch(e.uniqueness){case`none`:r=x.NONE;break;case`server`:r=x.SERVER;break;case`global`:r=x.GLOBAL;break;default:throw Error(`Unknown SCIM attribute uniqueness: ${e.uniqueness}`)}return{type:t,name:e.name,description:e.description,mutability:n,required:e.required,multiValued:e.multiValued,uniqueness:r,canonicalValues:e.canonicalValues??void 0,subAttributes:e.subAttributes?.map(e=>protoSCIMAttribute(e))}}function areAuthHooksEqual(e,t){return areNormalizedEqual({scriptRef:e.scriptRef??``,invoker:e.invoker?{namespace:e.invoker.namespace??``,machineUserName:e.invoker.machineUserName??``}:void 0},{scriptRef:t.scriptRef??``,invoker:t.invoker?{namespace:t.invoker.namespace??``,machineUserName:t.invoker.machineUserName??``}:void 0})}function formatAuthHookChangeEntries(e,t){return formatChangeEntriesWithFunctionRegistry(`authHook`,e,t,e=>{let[t,n]=e.name.split(`/`);return t&&n?[authHookFunctionName(t,n)]:[]},{getNamespace:e=>e.name.split(`/`)[0],getDisplayName:e=>e.name.split(`/`)[1]??e.name})}async function planAuthHooks(e,t,n,r,i=!1){let a=createChangeSet(`Auth hooks`);for(let r of n){let{config:n}=r,o=n.hooks?.beforeLogin,s=await I(async()=>{let{hook:r}=await e.getAuthHook({workspaceId:t,namespaceName:n.name,hookPoint:ae.BEFORE_LOGIN});return r});if(o){let e={workspaceId:t,namespaceName:n.name,hook:{hookPoint:ae.BEFORE_LOGIN,scriptRef:authHookFunctionName(n.name,`before-login`),invoker:{namespace:n.name,machineUserName:o.invoker}}};s?!i&&areAuthHooksEqual(s,e.hook)?a.unchanged.push({name:`${n.name}/before-login`}):a.updates.push({name:`${n.name}/before-login`,request:e}):a.creates.push({name:`${n.name}/before-login`,request:e})}else s&&a.deletes.push({name:`${n.name}/before-login`,request:{workspaceId:t,namespaceName:n.name,hookPoint:ae.BEFORE_LOGIN}})}for(let n of r)await I(async()=>await e.getAuthHook({workspaceId:t,namespaceName:n,hookPoint:ae.BEFORE_LOGIN}))&&a.deletes.push({name:`${n}/before-login`,request:{workspaceId:t,namespaceName:n,hookPoint:ae.BEFORE_LOGIN}});return a}function normalizeInvoker(e,t,n){if(e!==void 0){if(typeof e==`string`){if(!t)throw Error(`${n} uses a string invoker ("${e}"), but no Auth service is configured. Configure an Auth service before using invoker.`);return{namespace:t,machineUserName:e}}return e}}async function applyExecutor(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?await Promise.all([...r.creates.map(async t=>{await e.createExecutorExecutor(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.updates.map(async t=>{await e.updateExecutorExecutor(t.request),await writeMetadataLabels(e,t.metaRequest)})]):await Promise.all(r.deletes.map(t=>e.deleteExecutorExecutor(t.request)))}async function planExecutor(e){let{client:t,workspaceId:n,application:r,forRemoval:i}=e,a=createChangeSet(`Executors`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{executors:i,nextPageToken:a}=await t.listExecutorExecutors({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`executor`,e)}),u=i?{}:await r.executorService?.loadExecutors()??{};for(let t of Object.values(u)){let i=l[t.name],c=await buildMetaRequest({trn:resourceTrn(n,`executor`,t.name),appName:r.name,appId:r.id}),u=protoExecutor(e,t);i?(trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:r.name,appId:r.id,resourceType:`Executor`,resourceName:t.name,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(i.allLabels,c.labels)&&areExecutorsEqual(i.resource,u)?a.unchanged.push({name:t.name}):a.updates.push({name:t.name,request:{workspaceId:n,executor:u},metaRequest:c}),delete l[t.name]):a.creates.push({name:t.name,request:{workspaceId:n,executor:u},metaRequest:c})}return Object.entries(l).forEach(([e])=>{let t=l[e],i=t?.label;trackRemainingResourceOwner({labels:t?.allLabels,ownerLabel:i,appName:r.name,appId:r.id,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:n,name:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}function isFunctionBackedExecutor(e){return e?.targetType===T.FUNCTION||e?.targetType===T.JOB_FUNCTION}function buildPlannedExecutorsByName(e){return Object.fromEntries([...e.creates,...e.updates].map(e=>[e.name,e.request.executor]))}function formatExecutorChangeEntries(e,t,n){return formatChangeEntriesWithFunctionRegistry(`executor`,e,n,(e,n)=>{if(n===`delete`)return[executorFunctionName(e.name)];let r=t[e.name];return r&&isFunctionBackedExecutor(r)?[executorFunctionName(e.name)]:[]})}function normalizeComparableExecutor(e){let t=normalizeProtoConfig(e),n=t.targetConfig?.config?.case===`webhook`?(t.targetConfig.config.value.headers??[]).toSorted((e,t)=>(e.key??``).localeCompare(t.key??``)):void 0,r=t.triggerConfig?.config?.case===`incomingWebhook`?{...t.triggerConfig,config:{...t.triggerConfig.config,value:{...t.triggerConfig.config.value,secret:void 0}}}:t.triggerConfig?.config?.case===`event`?{...t.triggerConfig,config:{...t.triggerConfig.config,value:{...t.triggerConfig.config.value,eventType:void 0}}}:t.triggerConfig,i=normalizeProtoConfig({name:t.name,description:t.description??``,disabled:t.disabled??!1,triggerType:t.triggerType,triggerConfig:r,targetType:t.targetType,targetConfig:t.targetConfig?.config?.case===`webhook`?{...t.targetConfig,config:{...t.targetConfig.config,value:{...t.targetConfig.config.value,headers:n}}}:t.targetConfig?.config?.case===`function`?{...t.targetConfig,config:{...t.targetConfig.config,value:{...t.targetConfig.config.value,script:void 0}}}:t.targetConfig});return toComparableProtoJson(te,i)}function areExecutorsEqual(e,t){return areNormalizedEqual(normalizeComparableExecutor(e),normalizeComparableExecutor(t))}function resolveSameRunNamespace(e,t,n){if(!e?.has(t))return;let r=e.get(t);if(!r)throw Error(`${n} "${t}" is defined in multiple namespaces in this deploy run. Move the trigger to the application that owns it or use unique names.`);return r}function findTailorDBNamespace(e,t){return e.tailorDBServices.find(e=>Object.hasOwn(e.types,t))?.namespace}function findResolverNamespace(e,t){return e.resolverServices.find(e=>Object.values(e.resolvers).some(e=>e.name===t))?.namespace}function resolveNamespace(e){let{resourceLabel:t,resourceName:n,localNamespaces:r,findLocalNamespace:i,sameRunNamespaces:a}=e,o=i();if(o!==void 0)return o;let s=resolveSameRunNamespace(a,n,t);if(s!==void 0)return s;let c=a?[...new Set([...a.values()].filter(e=>e!==void 0))]:[],l=[...r,...c];throw Error(`${t} "${n}" not found in any namespace. Available namespaces: ${l.join(`, `)}`)}function resolveTailorDBNamespace(e,t,n){return resolveNamespace({resourceLabel:`TailorDB table`,resourceName:t,localNamespaces:e.tailorDBServices.map(e=>e.namespace),findLocalNamespace:()=>findTailorDBNamespace(e,t),sameRunNamespaces:n})}function resolveResolverNamespace(e,t,n){return resolveNamespace({resourceLabel:`Resolver`,resourceName:t,localNamespaces:e.resolverServices.map(e=>e.namespace),findLocalNamespace:()=>findResolverNamespace(e,t),sameRunNamespaces:n})}function collectApplicationIdpNames(e){let t=new Set(e.idpServices.map(e=>e.name));for(let n of e.subgraphs)n.Type===`idp`&&t.add(n.Name);return t}function resolveIdpNamespace(e,t,n,r){let i=collectApplicationIdpNames(e);if(n!==void 0){let e=r??i;if(!e.has(n)){let r=[...e].join(`, `);throw Error(`Executor "${t}" specifies IdP "${n}" in its idpUser trigger, but no IdP with that name is configured. Available IdPs: ${r}`)}return n}if(i.size===0)throw Error(`Executor "${t}" uses an idpUser trigger but no IdP is configured.`);if(i.size>1){let e=[...i].join(`, `);throw Error(`Executor "${t}" uses an idpUser trigger but the project defines multiple IdPs (${e}). Specify which IdP to subscribe to via the trigger's "idp" option.`)}return A([...i][0],`idp service missing`)}function protoExecutor(e,t){let{application:n}=e,r=n.name,i=n.env,a=t.trigger,o,s,c=zt(a.kind,i);function typedEventTrigger(e){return{config:{case:`event`,value:{typedConfig:e}}}}switch(a.kind){case`schedule`:o=O.SCHEDULE,s={config:{case:`schedule`,value:{timezone:a.timezone,frequency:a.cron}}};break;case`tailordb`:o=O.EVENT,s=typedEventTrigger({case:`tailordb`,value:{eventTypes:a.events,namespaceName:resolveTailorDBNamespace(n,a.tableName,e.tailorDBTypeNamespaces),typeName:a.tableName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;case`resolverExecuted`:o=O.EVENT,s=typedEventTrigger({case:`pipeline`,value:{eventTypes:[`pipeline.resolver.executed`],namespaceName:resolveResolverNamespace(n,a.resolverName,e.resolverNamespaces),resolverName:a.resolverName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;case`incomingWebhook`:o=O.INCOMING_WEBHOOK,s={config:{case:`incomingWebhook`,value:a.response?{response:{...a.response.body?{body:{expr:`(${Dt(a.response.body)})(${c})`}}:{},...a.response.statusCode==null?{}:{statusCode:a.response.statusCode}}}:{}}};break;case`idpUser`:o=O.EVENT,s=typedEventTrigger({case:`idp`,value:{eventTypes:a.events,namespaceName:resolveIdpNamespace(n,t.name,a.idp,e.idpNames)}});break;case`authAccessToken`:o=O.EVENT,s=typedEventTrigger({case:`auth`,value:{eventTypes:a.events,namespaceName:It(n)}});break;case`workflowExecution`:case`workflowJobExecution`:o=O.EVENT,s=typedEventTrigger({case:`workflow`,value:{eventTypes:a.events,workflowName:a.workflowName,...a.condition?{condition:{expr:`(${Dt(a.condition)})(${c})`}}:{}}});break;default:throw Error(`Unknown trigger: ${a}`)}let l=t.operation,u,d,f=Zt(n),p=`Executor "${t.name}"`;switch(l.kind){case`webhook`:u=T.WEBHOOK,d={config:{case:`webhook`,value:{url:{expr:`(${Dt(l.url)})(${c})`},headers:l.headers?Object.entries(l.headers).map(([e,t])=>{let n;return n=typeof t==`string`?{case:`rawValue`,value:t}:{case:`secretValue`,value:{vaultName:t.vault,secretKey:t.key}},{key:e,value:n}}):void 0,body:l.requestBody?{expr:`(${Dt(l.requestBody)})(${c})`}:void 0}}};break;case`graphql`:u=T.TAILOR_GRAPHQL,d={config:{case:`tailorGraphql`,value:{appName:l.appName??r,query:l.query,variables:l.variables?{expr:`(${Dt(l.variables)})(${c})`}:void 0,invoker:normalizeInvoker(l.invoker,f,p)}}};break;case`function`:case`jobFunction`:u=l.kind===`function`?T.FUNCTION:T.JOB_FUNCTION,d={config:{case:`function`,value:{name:`operation`,scriptRef:executorFunctionName(t.name),variables:{expr:c},invoker:normalizeInvoker(l.invoker,f,p)}}};break;case`workflow`:u=T.WORKFLOW,d={config:{case:`workflow`,value:{workflowName:l.workflowName,variables:l.args===void 0?void 0:typeof l.args==`function`?{expr:`(${Dt(l.args)})(${c})`}:{expr:JSON.stringify(l.args)},invoker:normalizeInvoker(l.invoker,f,p)}}};break;default:throw Error(`Unknown target: ${l}`)}return{name:t.name,description:t.description,disabled:t.disabled,triggerType:o,triggerConfig:s,targetType:u,targetConfig:d}}const Pi={uuid:{kind:`ScalarType`,name:`ID`},string:{kind:`ScalarType`,name:`String`},integer:{kind:`ScalarType`,name:`Int`},float:{kind:`ScalarType`,name:`Float`},decimal:{kind:`CustomScalarType`,name:`Decimal`},boolean:{kind:`ScalarType`,name:`Boolean`},date:{kind:`CustomScalarType`,name:`Date`},datetime:{kind:`CustomScalarType`,name:`DateTime`},time:{kind:`CustomScalarType`,name:`Time`}};async function applyPipeline(e,t,n=`create-update`){let{changeSet:r}=t;n===`create-update`?(await Promise.all([...r.service.creates.map(async t=>{await e.createPipelineService(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.service.updates.map(async t=>{await e.updatePipelineService(t.request),await writeMetadataLabels(e,t.metaRequest)})]),await Promise.all([...r.resolver.creates.map(async t=>{await e.createPipelineResolver(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.resolver.updates.map(async t=>{await e.updatePipelineResolver(t.request),await writeMetadataLabels(e,t.metaRequest)}),...r.resolver.unchanged.flatMap(t=>t.metaRequest?[writeMetadataLabels(e,t.metaRequest)]:[])])):n===`delete-resources`?await Promise.all(r.resolver.deletes.map(t=>e.deletePipelineResolver(t.request))):await Promise.all(r.service.deletes.map(t=>e.deletePipelineService(t.request)))}async function planPipeline(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=[];if(!i)for(let e of r.resolverServices)await e.loadResolvers(),o.push(e);let s=i?[]:Object.values(await r.executorService?.loadExecutors()??{}),{changeSet:c,conflicts:l,unmanaged:u,resourceOwners:d}=await planServices$1(t,n,r.name,r.id,o),f=c.deletes.map(e=>e.name),{changeSet:p}=await planResolvers(t,n,o,s,e.executorUsedResolvers??new Set,f,r.env,Zt(r),a,{appName:r.name,appId:r.id,dependentApps:e.dependentApps,runAppIds:e.runAppIds});return{changeSet:{service:c,resolver:p},conflicts:l,unmanaged:u,resourceOwners:d}}async function planServices$1(e,t,n,r,i){let a=createChangeSet(`Pipeline services`),o=[],s=[],c=new Set,l=await fetchExistingResourcesWithLabels({client:e,fetchPage:async(n,r)=>{let{pipelineServices:i,nextPageToken:a}=await e.listPipelineServices({workspaceId:t,pageToken:n,pageSize:r});return[i,a]},getName:e=>e.namespace?.name,getTrn:e=>resourceTrn(t,`pipeline`,e)});for(let e of i){let i=l[e.namespace],c=await buildMetaRequest({trn:resourceTrn(t,`pipeline`,e.namespace),appName:n,appId:r});i?(trackDesiredResourceOwnership({labels:i.allLabels,ownerLabel:i.label,appName:n,appId:r,resourceType:`Pipeline service`,resourceName:e.namespace,conflicts:o,unmanaged:s})&&hasMatchingSdkVersion(i.allLabels,c.labels)?a.unchanged.push({name:e.namespace}):a.updates.push({name:e.namespace,request:{workspaceId:t,namespaceName:e.namespace},metaRequest:c}),delete l[e.namespace]):a.creates.push({name:e.namespace,request:{workspaceId:t,namespaceName:e.namespace},metaRequest:c})}return Object.entries(l).forEach(([e])=>{let i=l[e];trackRemainingResourceOwner({labels:i?.allLabels,ownerLabel:i?.label,appName:n,appId:r,resourceOwners:c})&&a.deletes.push({name:e,request:{workspaceId:t,namespaceName:e}})}),{changeSet:a,conflicts:o,unmanaged:s,resourceOwners:c}}async function planResolvers(e,t,n,r,i,a,o,s,c=!1,l={}){let u=createChangeSet(`Pipeline resolvers`),{appName:d,appId:f,dependentApps:p,runAppIds:m}=l,resolverMetaRequest=async(e,n)=>addDependencyRecords(await buildMetaRequest({trn:resolverTrn(t,e,n.name),appName:d??``,appId:f}),{key:Q.resolver(e,n.name),dependentApps:p,runAppIds:m,pinned:n.publishEvents!==void 0}),fetchResolvers=n=>P(async(r,i)=>{let{pipelineResolvers:a,nextPageToken:o}=await e.listPipelineResolvers({workspaceId:t,namespaceName:n,pageToken:r,pageSize:i});return[a,o]}),h=new Set(i);for(let e of r)subscribesToEvents(e)&&e.trigger.kind===`resolverExecuted`&&h.add(e.trigger.resolverName);for(let e of n)for(let t of Object.values(e.resolvers))assertNoPublishEventsConflict({explicit:t.publishEvents,subscribed:h.has(t.name),conflict:Mi.resolver(t.name)});for(let r of n){let n=await fetchResolvers(r.namespace),i=new Map(n.map(e=>[e.name,e]));for(let n of Object.values(r.resolvers)){let a=processResolver(r.namespace,n,h,o,s),l=i.get(n.name),d=await resolverMetaRequest(r.namespace,n);if(l){let{pipelineResolver:o}=await e.getPipelineResolver({workspaceId:t,namespaceName:r.namespace,resolverName:n.name});!c&&o&&areResolversEqual(o,a)?u.unchanged.push({name:n.name,metaRequest:d}):u.updates.push({name:n.name,request:{workspaceId:t,namespaceName:r.namespace,pipelineResolver:a},metaRequest:d}),i.delete(n.name)}else u.creates.push({name:n.name,request:{workspaceId:t,namespaceName:r.namespace,pipelineResolver:a},metaRequest:d})}i.forEach((e,n)=>{u.deletes.push({name:n,request:{workspaceId:t,namespaceName:r.namespace,resolverName:n}})})}for(let e of a)(await fetchResolvers(e)).forEach(n=>{u.deletes.push({name:n.name,request:{workspaceId:t,namespaceName:e,resolverName:n.name}})});return{changeSet:u}}function formatResolverChangeEntries(e,t){return formatChangeEntriesWithFunctionRegistry(`resolver`,e,t,e=>{let t=e.request.namespaceName;return t?[resolverFunctionName(t,e.name)]:[]},{getNamespace:e=>e.request.namespaceName})}function normalizeComparableResolver(e){return toComparableProtoJson(f,e)}function areResolversEqual(e,t){return areNormalizedEqual(normalizeComparableResolver(e),normalizeComparableResolver(t))}function processResolver(e,t,n,r,i){let a=[{name:`body`,operationName:`body`,description:`${t.name} function body`,operationType:g.FUNCTION,operationSourceRef:resolverFunctionName(e,t.name),operationHook:{expr:Rt(r)},postScript:`args.body`,invoker:normalizeInvoker(t.invoker,i,`Resolver "${t.name}"`)}],o=hr.camelize(t.name),s=t.input?protoFields(t.input,`${o}Input`,!0):[],c=A(protoFields({"":t.output},`${o}Output`,!1)[0],`resolver output field missing`),l=t.description||`${t.name} resolver`,u=t.output.metadata.description,d=u?`${l}\n\nReturns:\n${u}`:l,f=resolvePublishEvents({explicit:t.publishEvents,subscribed:n.has(t.name),conflict:Mi.resolver(t.name)});return{authorization:`true==true`,description:d,inputs:s,name:t.name,operationType:t.operation,response:c,pipelines:a,publishExecutionEvents:f}}function protoFields(e,t,n){return Object.entries(e).map(([e,r])=>{let i,a=n&&r.metadata.hooks?.create!==void 0?!1:r.metadata.required??!0;if(r.type===`nested`){let o=r.metadata.typeName??`${t}${hr.camelize(e)}`;i={kind:`UserDefined`,name:o,description:r.metadata.description??``,required:a,fields:protoFields(r.fields,o,n)}}else i=r.type===`enum`?{kind:`EnumType`,name:r.metadata.typeName??`${t}${hr.camelize(e)}`,required:a,allowedValues:r.metadata.allowedValues}:{...Pi[r.type],required:a};return{name:e,description:r.metadata.description,array:r.metadata.array??!1,required:a,type:i}})}function vaultCreateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.name}}function secretCreateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.vaultName,secretmanagerSecretName:e.secretName,secretmanagerSecretValue:e.value}}function secretUpdateRequest(e){return{workspaceId:e.workspaceId,secretmanagerVaultName:e.vaultName,secretmanagerSecretName:e.secretName,secretmanagerSecretValue:e.value}}async function planSecretManager(e){let{client:t,workspaceId:n,application:r,forRemoval:i,forceApplyAll:a=!1}=e,o=i?[]:r.secrets,s=createChangeSet(`Secret Manager vaults`),c=createChangeSet(`Secret Manager secrets`),l=[],u=[],d=new Set,f=await fetchExistingResourcesWithLabels({client:t,fetchPage:async(e,r)=>{let{vaults:i,nextPageToken:a}=await t.listSecretManagerVaults({workspaceId:n,pageToken:e,pageSize:r});return[i,a]},getName:e=>e.name,getTrn:e=>resourceTrn(n,`vault`,e)}),p={workspaceId:n,applicationId:r.id,applicationName:r.name},m=loadSecretsState(p),h=[];await Promise.all(o.map(async e=>{let i=e.vaultName,o=f[i];if(o){let e=await buildMetaRequest({trn:resourceTrn(n,`vault`,i),appName:r.name,appId:r.id});trackDesiredResourceOwnership({labels:o.allLabels,ownerLabel:o.label,appName:r.name,appId:r.id,resourceType:`Secret Manager vault`,resourceName:i,conflicts:l,unmanaged:u})&&hasMatchingSdkVersion(o.allLabels,e.labels)?s.unchanged.push({name:i}):s.updates.push({name:i,workspaceId:n}),delete f[i]}else s.creates.push({name:i,workspaceId:n});let d=new Map;if(o){let e=await P(async(e,r)=>{let{secrets:a,nextPageToken:o}=await t.listSecretManagerSecrets({workspaceId:n,secretmanagerVaultName:i,pageToken:e,pageSize:r});return[a,o]});for(let t of e)d.set(t.name,serializeUpdateTime(t.updateTime))}let p=new Set(d.keys());for(let t of e.secrets){if(t.value==null){p.delete(t.name),h.push(`${i}/${t.name}`);continue}if(p.has(t.name)){let e=m.vaults[i]?.[t.name],r=d.get(t.name),o=e!==void 0&&e.hash===hashValue(t.value)&&e.updateTime!==void 0&&e.updateTime===r;(a||!o)&&c.updates.push({name:`${i}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:i,value:t.value}),p.delete(t.name)}else c.creates.push({name:`${i}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:i,value:t.value})}for(let e of p)c.deletes.push({name:`${i}/${e}`,secretName:e,workspaceId:n,vaultName:i})}));for(let[e,i]of Object.entries(f))if(i&&trackRemainingResourceOwner({labels:i.allLabels,ownerLabel:i.label,appName:r.name,appId:r.id,resourceOwners:d})){let r=await P(async(r,i)=>{let{secrets:a,nextPageToken:o}=await t.listSecretManagerSecrets({workspaceId:n,secretmanagerVaultName:e,pageToken:r,pageSize:i});return[a,o]});for(let t of r)c.deletes.push({name:`${e}/${t.name}`,secretName:t.name,workspaceId:n,vaultName:e});s.deletes.push({name:e,workspaceId:n})}return{vaultChangeSet:s,secretChangeSet:c,skippedSecrets:h,conflicts:l,unmanaged:u,resourceOwners:d,stateScope:p}}async function applySecretManager(e,t,n=`create-update`,r){let{vaultChangeSet:i,secretChangeSet:a,stateScope:o}=t;if(n===`create-update`){await Promise.all(i.creates.map(async t=>{await e.createSecretManagerVault(vaultCreateRequest(t)),r&&await writeMetadataLabels(e,await buildMetaRequest({trn:resourceTrn(t.workspaceId,`vault`,t.name),appName:r.name,appId:r.id}))})),r&&await Promise.all(i.updates.map(async t=>{await writeMetadataLabels(e,await buildMetaRequest({trn:resourceTrn(t.workspaceId,`vault`,t.name),appName:r.name,appId:r.id}))}));let t=[...a.creates,...a.updates];t.length>0&&await withSecretsStateLock(o,async()=>{let n=new Map;if(await Promise.all(a.creates.map(async t=>{let r=await e.createSecretManagerSecret(secretCreateRequest(t));n.set(t.name,serializeUpdateTime(r.secret?.updateTime))})),await Promise.all(a.updates.map(async t=>{let r=await e.updateSecretManagerSecret(secretUpdateRequest(t));n.set(t.name,serializeUpdateTime(r.secret?.updateTime))})),r){let e=loadSecretsState(o);for(let r of t){Object.hasOwn(e.vaults,r.vaultName)||(e.vaults[r.vaultName]={});let t=n.get(r.name);A(e.vaults[r.vaultName],`vault state entry missing`)[r.secretName]={hash:hashValue(r.value),...t===void 0?{}:{updateTime:t}}}saveSecretsState(o,e)}})}else(a.deletes.length>0||i.deletes.length>0)&&await withSecretsStateLock(o,async()=>{await Promise.all(a.deletes.map(t=>e.deleteSecretManagerSecret({workspaceId:t.workspaceId,secretmanagerVaultName:t.vaultName,secretmanagerSecretName:t.secretName}))),await Promise.all(i.deletes.map(t=>e.deleteSecretManagerVault({workspaceId:t.workspaceId,secretmanagerVaultName:t.name})));let t=loadSecretsState(o);for(let e of a.deletes)Object.hasOwn(t.vaults,e.vaultName)&&(delete A(t.vaults[e.vaultName],`vault state entry missing`)[e.secretName],Object.keys(A(t.vaults[e.vaultName],`vault state entry missing`)).length===0&&delete t.vaults[e.vaultName]);for(let e of i.deletes)delete t.vaults[e.name];saveSecretsState(o,t)})}function hasChanges(e){return e.changes.length>0}function formatMigrationDiff(e){if(e.changes.length===0)return`No schema differences detected.`;let t=[],n=new Map;for(let t of e.changes){let e=n.get(t.tableName)??[];e.push(t),n.set(t.tableName,e)}for(let[r,i]of n){t.push(`${e.namespace}.${r}:`);for(let e of i)t.push(formatDiffChange(e))}return t.join(`
|
|
32
32
|
`)}function formatDiffChange(e){switch(e.kind){case`table_added`:return` + [Table] ${e.tableName} (new table)`;case`table_removed`:return` - [Table] ${e.tableName} (removed)`;case`table_renamed`:return` ~ [Table] ${e.previousTableName} → ${e.tableName} (renamed)`;case`table_modified`:return` ~ [Table] ${e.tableName}: ${e.reason}`;case`table_settings_modified`:return` ~ [Table Settings] ${e.tableName}: ${e.reason??`settings changed`}`;case`field_added`:{let t=formatFieldType(e.after);return` + ${e.fieldName}: ${t}`}case`field_removed`:return` - ${e.fieldName}: ${e.before.type}`;case`field_modified`:case`field_type_modified`:return` ~ ${e.fieldName}: ${formatFieldModification(e.before,e.after)}`;case`field_renamed`:return` ~ ${e.previousFieldName} → ${e.fieldName}: ${formatFieldType(e.after)} (renamed)`;case`index_added`:return` + [Index] ${e.indexName}`;case`index_removed`:return` - [Index] ${e.indexName}`;case`index_modified`:return` ~ [Index] ${e.indexName}: ${e.reason??`modified`}`;case`file_added`:return` + [File] ${e.fieldName}`;case`file_removed`:return` - [File] ${e.fieldName}`;case`file_modified`:return` ~ [File] ${e.fieldName}: ${e.reason??`modified`}`;case`relationship_added`:return` + [Relationship${e.relationshipType?` (${e.relationshipType})`:``}] ${e.relationshipName}`;case`relationship_removed`:return` - [Relationship${e.relationshipType?` (${e.relationshipType})`:``}] ${e.relationshipName}`;case`relationship_modified`:return` ~ [Relationship${e.relationshipType?` (${e.relationshipType})`:``}] ${e.relationshipName}: ${e.reason??`modified`}`;case`permission_modified`:return` ~ [Permission] ${e.reason??`modified`}`;case`table_scripts_modified`:return` ~ [Table Scripts] ${e.tableName}: ${e.reason??`table-level hooks/validate changed`}`;default:{let t=e;return` ? ${t.tableName}.${t.fieldName??``}`}}}function formatFieldType(e){let t=e.type;return e.array&&(t+=`[]`),e.required?t+=` (required)`:t+=` (optional)`,t}function formatFieldModification(e,t){let n=[];e.type!==t.type&&n.push(`type: ${e.type} → ${t.type}`),e.required!==t.required&&n.push(`required: ${e.required} → ${t.required}`),!!e.array!=!!t.array&&n.push(`array: ${e.array??!1} → ${t.array??!1}`),!!e.index!=!!t.index&&n.push(`index: ${e.index??!1} → ${t.index??!1}`),!!e.unique!=!!t.unique&&n.push(`unique: ${e.unique??!1} → ${t.unique??!1}`),!!e.vector!=!!t.vector&&n.push(`vector: ${e.vector??!1} → ${t.vector??!1}`);let r=e.allowedValues??[],i=t.allowedValues??[],a=new Set(i.map(e=>e.value));if(r.length!==i.length||r.some(e=>!a.has(e.value))){let e=r.map(e=>e.value).join(`, `),t=i.map(e=>e.value).join(`, `);n.push(`allowedValues: [${e}] → [${t}]`)}let o=e.hooks,s=t.hooks;((o?.create?.expr??``)!==(s?.create?.expr??``)||(o?.update?.expr??``)!==(s?.update?.expr??``))&&n.push(`hooks modified`);let c=e.validate??[],l=t.validate??[];return c.length!==l.length&&n.push(`validations: ${c.length} → ${l.length}`),!!e.serial!=!!t.serial&&n.push(`serial: ${e.serial?`enabled`:`disabled`} → ${t.serial?`enabled`:`disabled`}`),n.join(`, `)}function formatBreakingChanges(e){if(e.length===0)return``;let t=[`Breaking changes detected:`,``];for(let n of e){let e=n.fieldName?`${n.tableName}.${n.fieldName}`:n.tableName;t.push(` - ${e}: ${n.reason}`)}return t.join(`
|
|
33
33
|
`)}function formatWarnings(e){if(e.length===0)return``;let t=[`Warning: data loss possible:`,``];for(let n of e){let e=n.fieldName?`${n.tableName}.${n.fieldName}`:n.tableName;t.push(` - ${e}: ${n.reason}`)}return t.join(`
|
|
34
34
|
`)}const Fi={table_added:`table(s) added`,table_removed:`table(s) removed`,table_renamed:`table(s) renamed`,table_modified:`table(s) modified`,table_settings_modified:`table setting(s) modified`,field_added:`field(s) added`,field_removed:`field(s) removed`,field_modified:`field(s) modified`,field_renamed:`field(s) renamed`,field_type_modified:`field type(s) modified`,index_added:`index(es) added`,index_removed:`index(es) removed`,index_modified:`index(es) modified`,file_added:`file field(s) added`,file_removed:`file field(s) removed`,file_modified:`file field(s) modified`,relationship_added:`relationship(s) added`,relationship_removed:`relationship(s) removed`,relationship_modified:`relationship(s) modified`,permission_modified:`permission(s) modified`,table_scripts_modified:`table script(s) modified`};function formatDiffSummary(e){let t={};for(let n of e.changes)t[n.kind]=(t[n.kind]??0)+1;let n=Object.keys(t).map(e=>`${t[e]} ${Fi[e]}`);return n.length>0?n.join(`, `):`No changes`}function formatMigrationNumber(e){return e.toString().padStart(4,`0`)}function parseMigrationNumberArg(e){if(/^\d{4}$/.test(e))return parseInt(e,10);if(/^(0|[1-9]\d*)$/.test(e)){let t=parseInt(e,10);if(t>9999)throw Error(`Migration number ${e} is out of range. Expected 0-9999.`);return t}throw Error(`Invalid migration number format: ${e}. Expected 4-digit format (e.g., 0001) or integer 0-9999 (e.g., 1).`)}const Ii=[`array`,`index`,`unique`,`foreignKey`,`vector`,`optionalOnCreate`];function isSnapshotFieldRefOperand(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const Li=new Set([`boolean:string`,`decimal:float`,`decimal:string`,`enum:string`,`float:decimal`,`float:string`,`integer:decimal`,`integer:float`,`integer:string`,`uuid:string`]);function supportsInPlaceFieldTypeChange(e,t){return e.type===t.type||e.array||t.array||e.type===`nested`||t.type===`nested`||e.serial||t.serial||e.vector||t.vector||e.foreignKey||t.foreignKey||!Li.has(`${e.type}:${t.type}`)?!1:!(e.unique??!1)||t.type!==`decimal`||e.type!==`float`}function getExpandContractFieldChangeEligibility(e,t){return e.type===t.type?{eligible:!1,reason:`the field type did not change`}:supportsInPlaceFieldTypeChange(e,t)?{eligible:!1,reason:`the ${e.type} to ${t.type} change is already supported in place`}:e.unique||t.unique?{eligible:!1,reason:`the field is unique`}:e.array||t.array?{eligible:!1,reason:`the field is an array`}:e.type===`nested`||t.type===`nested`?{eligible:!1,reason:`the field is nested`}:e.serial||t.serial?{eligible:!1,reason:`the field uses a serial sequence`}:e.vector||t.vector?{eligible:!1,reason:`the field is a vector`}:e.foreignKey||t.foreignKey?{eligible:!1,reason:`the field is a foreign key`}:{eligible:!0}}const Ri=new Set([`index`,`unique`,`vector`]);function isRenameCompatible(e,t){if(e.type!==t.type)return!1;for(let n of Ii)if(!Ri.has(n)&&(e[n]??!1)!==(t[n]??!1))return!1;if((e.foreignKeyType??``)!==(t.foreignKeyType??``)||(e.foreignKeyField??``)!==(t.foreignKeyField??``)||e.serial||t.serial)return!1;if(e.type===`enum`){let n=new Set((t.allowedValues??[]).map(e=>e.value));if((e.allowedValues??[]).some(e=>!n.has(e.value)))return!1}let n=e.fields??{},r=t.fields??{},i=Object.keys(n),a=Object.keys(r);if(i.length!==a.length)return!1;for(let e of i){let t=n[e],i=r[e];if(!t||!i||t.required!==i.required||!isRenameCompatible(t,i))return!1}return!0}function findRenameCandidates(e){let t=new Map,n=new Map;for(let r of e.changes)if(r.kind===`field_removed`){let e=t.get(r.tableName)??[];e.push(r),t.set(r.tableName,e)}else if(r.kind===`field_added`){let e=n.get(r.tableName)??[];e.push(r),n.set(r.tableName,e)}let r=[];for(let[e,i]of t){let t=n.get(e);if(t)for(let n of i){let i=t.filter(e=>isRenameCompatible(n.before,e.after));i.length>0&&r.push({tableName:e,removed:n,added:i})}}return r}function renameSpecApplies(e,t,n){let r=t.tables[e.tableName]?.fields,i=n.tables[e.tableName]?.fields;return!!(r?.[e.previousFieldName]&&!i?.[e.previousFieldName]&&i?.[e.fieldName]&&!r[e.fieldName])}function assertValidFieldRenames(e,t,n){let r=new Set;for(let i of n){let{tableName:n,previousFieldName:a,fieldName:o}=i,s=`${n}.${a}:${o}`;for(let e of[`${n}.${a}`,`${n}.${o}`]){if(r.has(e))throw Error(`Field "${e}" appears in more than one rename.`);r.add(e)}let c=e.tables[n],l=t.tables[n];if(!c||!l)throw Error(`Cannot rename ${s}: table "${n}" must exist in both the previous and the current schema.`);let u=c.fields[a];if(!u)throw Error(`Cannot rename ${s}: field "${a}" does not exist in the previous schema.`);if(l.fields[a])throw Error(`Cannot rename ${s}: field "${a}" still exists in the current schema.`);let d=l.fields[o];if(!d)throw Error(`Cannot rename ${s}: field "${o}" does not exist in the current schema.`);if(c.fields[o])throw Error(`Cannot rename ${s}: field "${o}" already exists in the previous schema.`);if(!isRenameCompatible(u,d))throw Error(`Cannot rename ${s}: the fields are not rename-compatible (the field type, array-ness, and foreign key target must match, enum values must not be removed, nested member names, requiredness, and types must match recursively, and serial fields cannot be renamed).`)}}const zi=/^([^.:\s]+)\.([^.:\s]+):([^.:\s]+)$/;function parseRenameOption(e){let[,t,n,r]=e.match(zi)??[];if(!t||!n||!r)throw Error(`Invalid --rename value "${e}". Expected format: "Table.oldField:newField".`);if(n===r)throw Error(`Invalid --rename value "${e}": old and new field names are identical.`);return{tableName:t,previousFieldName:n,fieldName:r}}const Bi=/^([^.:\s]+)\.([^.:\s]+)$/;function parseDropOption(e){let[,t,n]=e.match(Bi)??[];if(!t||!n)throw Error(`Invalid --drop value "${e}". Expected format: "Table.field".`);return{tableName:t,fieldName:n}}function dropSpecApplies(e,t,n){let r=t.tables[e.tableName]?.fields,i=n.tables[e.tableName]?.fields;return!!(r?.[e.fieldName]&&!i?.[e.fieldName])}function parseExpandContractOption(e){let[,t,n]=e.match(Bi)??[];if(!t||!n)throw Error(`Invalid --expand-contract value "${e}". Expected format: "Table.field".`);return{tableName:t,fieldName:n}}function retargetSelfReferences(e,t,n){let r=e.fields?Object.fromEntries(Object.entries(e.fields).map(([e,r])=>[e,retargetSelfReferences(r,t,n)])):void 0;return{...e,...e.foreignKeyType===t&&{foreignKeyType:n},...r&&{fields:r}}}function stableStringify(e){return Array.isArray(e)?`[${e.map(stableStringify).join(`,`)}]`:typeof e==`object`&&e?`{${Object.entries(e).filter(([,e])=>e!==void 0).toSorted(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${stableStringify(t)}`).join(`,`)}}`:JSON.stringify(e)}function isTypeRenameFieldCompatible(e,t){if(!isRenameCompatible(e,t)||e.required!==t.required||(e.unique??!1)!==(t.unique??!1)||(e.scale??null)!==(t.scale??null))return!1;for(let[n,r]of Object.entries(e.fields??{})){let e=t.fields?.[n];if(!e||!isTypeRenameFieldCompatible(r,e))return!1}return!0}function isTypeRenameCompatible(e,t){if(Object.keys(e.files??{}).length>0||Object.keys(t.files??{}).length>0)return!1;let n=Object.keys(e.fields),r=Object.keys(t.fields);if(n.length!==r.length)return!1;for(let r of n){let n=e.fields[r],i=t.fields[r];if(!n||!i||n.foreignKeyType===e.name&&n.required||!isTypeRenameFieldCompatible(retargetSelfReferences(n,e.name,t.name),i))return!1}return stableStringify(e.indexes??{})===stableStringify(t.indexes??{})}function findTypeRenameCandidates(e){let t=e.changes.filter(e=>e.kind===`table_removed`),n=e.changes.filter(e=>e.kind===`table_added`),r=[];for(let e of t){let t=n.filter(t=>isTypeRenameCompatible(e.before,t.after));t.length>0&&r.push({removed:e,added:t})}return r}function typeRenameSpecApplies(e,t,n){return!!(t.tables[e.previousTableName]&&!n.tables[e.previousTableName]&&n.tables[e.tableName]&&!t.tables[e.tableName])}function assertValidTypeRenames(e,t,n){let r=new Set;for(let i of n){let{previousTableName:n,tableName:a}=i,o=`${n}:${a}`;for(let e of[n,a]){if(r.has(e))throw Error(`Table "${e}" appears in more than one rename.`);r.add(e)}let s=e.tables[n];if(!s)throw Error(`Cannot rename ${o}: table "${n}" does not exist in the previous schema.`);if(t.tables[n])throw Error(`Cannot rename ${o}: table "${n}" still exists in the current schema.`);let c=t.tables[a];if(!c)throw Error(`Cannot rename ${o}: table "${a}" does not exist in the current schema.`);if(e.tables[a])throw Error(`Cannot rename ${o}: table "${a}" already exists in the previous schema.`);if(!isTypeRenameCompatible(s,c))throw Error(`Cannot rename ${o}: the tables are not rename-compatible (every field must keep its name, type, array-ness, required/unique constraints, foreign key target, and scale, enum values must not be removed, indexes must match, self-referential foreign keys must be optional, and tables with serial or file fields cannot be renamed).`)}}function isBreakingForeignKeyRetarget(e,t,n){return!!(e.foreignKeyType&&t.foreignKeyType&&e.foreignKeyType!==t.foreignKeyType&&(n?.get(e.foreignKeyType)!==t.foreignKeyType||(e.foreignKeyField??``)!==(t.foreignKeyField??``)))}const Vi=/^([^.:\s]+):([^.:\s]+)$/;function parseTypeRenameOption(e){let[,t,n]=e.match(Vi)??[];if(!t||!n)throw Error(`Invalid --rename value "${e}". Expected format: "Table.oldField:newField" or "OldTable:NewTable".`);if(t===n)throw Error(`Invalid --rename value "${e}": old and new table names are identical.`);return{previousTableName:t,tableName:n}}const Hi=/^([^.:\s]+)$/;function parseTypeDropOption(e){let[,t]=e.match(Hi)??[];if(!t)throw Error(`Invalid --drop value "${e}". Expected format: "Table.field" or "Table".`);return{tableName:t}}function typeDropSpecApplies(e,t,n){return!!(t.tables[e.tableName]&&!n.tables[e.tableName])}var UnsupportedMigrationFileVersionError=class extends Error{};function assertSupportedMigrationFileVersion(e,t){if(typeof t!=`object`||!t||!(`version`in t))return;let n=t.version;if(typeof n!=`number`||Number.isInteger(n)&&n>=1&&n<=5)return;let r;throw r=n>5?`Upgrade to an SDK that supports migration file format version ${n}.`:n<1?`Re-baseline with an SDK that still supports this migration history, then upgrade the SDK.`:`Restore the migration file from version control or regenerate it.`,new UnsupportedMigrationFileVersionError(`Unsupported migration file format version ${n} at ${e}. This SDK supports migration file format versions 1-5. ${r}`)}const Ui=new Map([[`type_added`,`table_added`],[`type_removed`,`table_removed`],[`type_renamed`,`table_renamed`],[`type_modified`,`table_modified`],[`type_settings_modified`,`table_settings_modified`],[`type_scripts_modified`,`table_scripts_modified`]]);function normalizeLegacyChangeKinds(e){if(typeof e!=`object`||!e||!(`changes`in e))return e;let t=e.changes;if(!Array.isArray(t))return e;let n=t.map(e=>{if(typeof e!=`object`||!e||!(`kind`in e))return e;let t=e.kind;if(typeof t!=`string`)return e;let n=Ui.get(t);return n===void 0?e:{...e,kind:n}});return{...e,changes:n}}const Wi=new Map([[`typeName`,`tableName`],[`previousTypeName`,`previousTableName`]]);function renameLegacyEntryFields(e){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=e,n={},r=!1;for(let[e,i]of Object.entries(t)){let a=Wi.get(e);a!==void 0&&!(a in t)?(n[a]=i,r=!0):n[e]=i}return r?n:e}const Gi=[`changes`,`breakingChanges`,`warnings`];function normalizeLegacyTablesKey(e){if(typeof e!=`object`||!e)return e;let t=e;if(!(`types`in t)||`tables`in t)return e;let{types:n,...r}=t;return{...r,tables:n}}function normalizeLegacyFieldNames(e){if(typeof e!=`object`||!e)return e;let t=e,n={...t};for(let e of Gi){let r=t[e];Array.isArray(r)&&(n[e]=r.map(renameLegacyEntryFields))}return n}function createSnapshotRecord(){return Object.create(null)}function copySnapshotRecord(e){let t=createSnapshotRecord();for(let[n,r]of Object.entries(e??{}))t[n]=r;return t}function normalizeSnapshotField(e){let t=e.fields?Object.fromEntries(Object.entries(e.fields).map(([e,t])=>[e,normalizeSnapshotField(t)])):void 0;return{...e,...e.type===`decimal`&&e.scale===void 0&&{scale:6},...t&&{fields:t}}}function normalizeSnapshotType(e){let t=e.pluralForm||hr.pluralize(e.name),n=createSnapshotRecord();for(let[t,r]of Object.entries(e.fields))n[t]=normalizeSnapshotField(r);return{...e,pluralForm:t,fields:n}}function normalizeSchemaSnapshot(e){let t=createSnapshotRecord();for(let[n,r]of Object.entries(e.tables))t[n]=normalizeSnapshotType(r);return{...e,tables:t}}const Ki=`Field removed (existing data will no longer be accessible through the schema)`,qi=`Table removed (all records in this table will be deleted during post-migration cleanup)`;function deriveWarningsFromChanges(e){let t=[];for(let n of e.changes)n.kind===`field_removed`?t.push({tableName:n.tableName,fieldName:n.fieldName,reason:Ki}):n.kind===`table_removed`&&t.push({tableName:n.tableName,reason:qi});return t}function areFieldsDifferent(e,t){if(e.type!==t.type||e.required!==t.required)return!0;for(let n of Ii)if((e[n]??!1)!==(t[n]??!1))return!0;if(e.foreignKeyType!==t.foreignKeyType||e.foreignKeyField!==t.foreignKeyField||(e.description??``)!==(t.description??``))return!0;let n=e.allowedValues??[],r=t.allowedValues??[];if(n.length!==r.length)return!0;let i=new Map(r.map(e=>[e.value,e.description]));for(let e of n)if(!i.has(e.value)||(e.description??``)!==(i.get(e.value)??``))return!0;let a=e.hooks,o=t.hooks;if(!!a!=!!o||a&&o&&((a.create?.expr??``)!==(o.create?.expr??``)||(a.update?.expr??``)!==(o.update?.expr??``)))return!0;let s=e.validate??[],c=t.validate??[];if(s.length!==c.length)return!0;for(let e=0;e<s.length;e++){let t=A(s[e],`oldValidate missing index ${e}`),n=A(c[e],`newValidate missing index ${e}`);if((t.script?.expr??``)!==(n.script?.expr??``)||t.errorMessage!==n.errorMessage)return!0}let l=e.serial,u=t.serial;if(!!l!=!!u||l&&u&&(l.start!==u.start||l.maxValue!==u.maxValue||(l.format??``)!==(u.format??``))||e.scale!==t.scale||e.default!==t.default&&(typeof e.default!=typeof t.default||JSON.stringify(e.default)!==JSON.stringify(t.default)))return!0;let d=e.fields??{},f=t.fields??{},p=Object.keys(d),m=Object.keys(f);if(p.length!==m.length)return!0;for(let e of p){let t=d[e],n=f[e];if(!n||areFieldsDifferent(A(t,`field "${e}" missing from oldFields`),n))return!0}return!1}function getBreakingFieldChanges(e,t,n,r,i){let a=[];if(!n&&r&&r.required&&a.push({tableName:e,fieldName:t,reason:`Required field added`}),n&&r&&n.type!==r.type){let i=supportsInPlaceFieldTypeChange(n,r);a.push({tableName:e,fieldName:t,reason:`Field type changed from ${n.type} to ${r.type}`,...!i&&{unsupported:!0,showThreeStepHint:!0}})}if(n&&r&&!n.required&&r.required&&a.push({tableName:e,fieldName:t,reason:`Field changed from optional to required`}),n&&r&&(n.array??!1)!==(r.array??!1)){let[r,i]=n.array?[`array`,`single value`]:[`single value`,`array`];a.push({tableName:e,fieldName:t,reason:`Field changed from ${r} to ${i}`,unsupported:!0,showThreeStepHint:!0})}if(n&&r&&isBreakingForeignKeyRetarget(n,r,i)&&a.push({tableName:e,fieldName:t,reason:`Foreign key target type changed from ${n.foreignKeyType} to ${r.foreignKeyType}`}),n&&r&&!(n.unique??!1)&&(r.unique??!1)&&a.push({tableName:e,fieldName:t,reason:`Unique constraint added to field`}),n?.type===`decimal`&&r?.type===`decimal`&&n.scale!==r.scale&&a.push({tableName:e,fieldName:t,reason:`Decimal scale changed from ${n.scale} to ${r.scale}`}),n&&r&&n.type===`enum`&&r.type===`enum`){let i=n.allowedValues??[],o=r.allowedValues??[],s=i.map(e=>e.value),c=new Set(o.map(e=>e.value)),l=s.filter(e=>!c.has(e));l.length>0&&a.push({tableName:e,fieldName:t,reason:`Enum values removed: ${l.join(`, `)}`})}return a}function addChange(e,t,n,r){if(e.changes.push(t),!t.fieldName)return;let i=getBreakingFieldChanges(t.tableName,t.fieldName,n,r,e.typeRenameTargets);if(i.length>0){e.breakingChanges.push(...i);return}t.kind===`field_removed`&&e.warnings.push({tableName:t.tableName,fieldName:t.fieldName,reason:Ki})}function compareTypeFields(e,t,n,r,i=[]){let a=new Set(Object.keys(n.fields)),o=new Set(Object.keys(r.fields)),s=new Set(i.map(e=>e.previousFieldName)),c=new Set(i.map(e=>e.fieldName));for(let a of i){let i=A(n.fields[a.previousFieldName],`renamed field "${a.previousFieldName}" missing from prevType`),o=A(r.fields[a.fieldName],`renamed field "${a.fieldName}" missing from currType`);e.changes.push({kind:`field_renamed`,tableName:t,fieldName:a.fieldName,previousFieldName:a.previousFieldName,before:i,after:o}),e.breakingChanges.push({tableName:t,fieldName:a.fieldName,reason:`Field renamed from ${a.previousFieldName} to ${a.fieldName} (existing values must be copied by the migration script)`})}for(let n of o)if(!c.has(n)&&!a.has(n)){let i=A(r.fields[n],`field "${n}" missing from currType`);addChange(e,{kind:`field_added`,tableName:t,fieldName:n,after:i},void 0,i)}for(let r of a)if(!s.has(r)&&!o.has(r)){let i=A(n.fields[r],`field "${r}" missing from prevType`);addChange(e,{kind:`field_removed`,tableName:t,fieldName:r,before:i},i,void 0)}for(let i of o){if(!a.has(i))continue;let o=A(n.fields[i],`field "${i}" missing from prevType`),s=A(r.fields[i],`field "${i}" missing from currType`);areFieldsDifferent(o,s)&&addChange(e,{kind:o.type===s.type?`field_modified`:`field_type_modified`,tableName:t,fieldName:i,before:o,after:s},o,s)}}function isBreakingIndexChange(e,t,n,r){return!r||!(r.unique??!1)?null:!n||!(n.unique??!1)?{tableName:e,reason:`Unique constraint added to index "${t}"`}:JSON.stringify(n.fields.toSorted())===JSON.stringify(r.fields.toSorted())?null:{tableName:e,reason:`Unique index fields changed on index "${t}"`}}function compareIndexes(e,t,n,r){let i=new Set(Object.keys(n||{})),a=new Set(Object.keys(r||{}));for(let[n,a]of Object.entries(r??{}))if(!i.has(n)){e.changes.push({kind:`index_added`,tableName:t,indexName:n,after:a});let r=isBreakingIndexChange(t,n,void 0,a);r&&e.breakingChanges.push(r)}for(let[r,i]of Object.entries(n??{}))a.has(r)||e.changes.push({kind:`index_removed`,tableName:t,indexName:r,before:i});for(let[a,o]of Object.entries(r??{}))if(i.has(a)){let r=A(A(n,`oldIndexes is undefined when oldKeys has entry`)[a],`index "${a}" missing from oldIndexes`),i=JSON.stringify(r.fields.toSorted()),s=JSON.stringify(o.fields.toSorted());if(i!==s||(r.unique??!1)!==(o.unique??!1)){let n=[];i!==s&&n.push(`fields changed`),(r.unique??!1)!==(o.unique??!1)&&n.push(`unique constraint changed`),e.changes.push({kind:`index_modified`,tableName:t,indexName:a,reason:n.join(`, `),before:r,after:o});let c=isBreakingIndexChange(t,a,r,o);c&&e.breakingChanges.push(c)}}}function compareFiles(e,t,n,r){let i=new Set(Object.keys(n||{})),a=new Set(Object.keys(r||{}));for(let[n,a]of Object.entries(r??{}))i.has(n)||e.changes.push({kind:`file_added`,tableName:t,fieldName:n,after:a});for(let[r,i]of Object.entries(n??{}))a.has(r)||e.changes.push({kind:`file_removed`,tableName:t,fieldName:r,before:i});for(let[a,o]of Object.entries(r??{}))if(i.has(a)){let r=A(A(n,`oldFiles is undefined when oldKeys has entry`)[a],`file "${a}" missing from oldFiles`);r!==o&&e.changes.push({kind:`file_modified`,tableName:t,fieldName:a,reason:`description changed`,before:r,after:o})}}function compareRelationships(e,t,n,r,i){let a=new Set(Object.keys(r||{})),o=new Set(Object.keys(i||{}));for(let[r,o]of Object.entries(i??{}))a.has(r)||e.changes.push({kind:`relationship_added`,tableName:t,relationshipName:r,relationshipType:n,after:o});for(let[i,a]of Object.entries(r??{}))o.has(i)||e.changes.push({kind:`relationship_removed`,tableName:t,relationshipName:i,relationshipType:n,before:a});for(let[o,s]of Object.entries(i??{}))if(a.has(o)){let i=A(A(r,`oldRelationships is undefined when oldKeys has entry`)[o],`relationship "${o}" missing from oldRelationships`),a=[];i.targetType!==s.targetType&&a.push(`targetType changed`),i.targetField!==s.targetField&&a.push(`targetField changed`),i.sourceField!==s.sourceField&&a.push(`sourceField changed`),i.isArray!==s.isArray&&a.push(`isArray changed`),i.description!==s.description&&a.push(`description changed`),a.length>0&&e.changes.push({kind:`relationship_modified`,tableName:t,relationshipName:o,relationshipType:n,reason:a.join(`, `),before:i,after:s})}}function comparePermissions(e,t,n,r,i,a){let o=comparableRecordPermission(n),s=comparableRecordPermission(r),c=JSON.stringify(o??null)!==JSON.stringify(s??null),l=comparableGqlPermission(i),u=comparableGqlPermission(a),d=JSON.stringify(l??null)!==JSON.stringify(u??null);if(c||d){let n=[];c&&n.push(`record permission`),d&&n.push(`GQL permission`),e.changes.push({kind:`permission_modified`,tableName:t,reason:`${n.join(` and `)} changed`,before:{recordPermission:o,gqlPermission:l},after:{recordPermission:s,gqlPermission:u}})}}const Ji={all:0,create:1,read:2,update:3,delete:4,aggregate:5,bulkUpsert:6};function sortByJson(e){return e.map(e=>[JSON.stringify(e),e]).toSorted(([e],[t])=>e<t?-1:+(e>t)).map(([,e])=>e)}function comparableGqlPermission(e){let t=e?.map(e=>({...e,conditions:sortByJson(e.conditions),actions:e.actions.toSorted((e,t)=>Ji[e]-Ji[t])}));return t&&t.length>0?sortByJson(t):void 0}function comparableRecordPermission(e){if(e&&Object.values(e).some(e=>e.length>0))return{create:sortByJson(e.create.map(canonicalActionPermission)),read:sortByJson(e.read.map(canonicalActionPermission)),update:sortByJson(e.update.map(canonicalActionPermission)),delete:sortByJson(e.delete.map(canonicalActionPermission))}}function canonicalActionPermission(e){return{...e,conditions:sortByJson(e.conditions)}}function normalizeComparableGqlOperations(e){if(e)return{create:e.create??!0,update:e.update??!0,delete:e.delete??!0,read:e.read??!0}}function normalizeComparableSettings(e){let t={};e?.aggregation===!0&&(t.aggregation=!0),e?.bulkUpsert===!0&&(t.bulkUpsert=!0),e?.publishEvents===!0&&(t.publishEvents=!0);let n=normalizeComparableGqlOperations(e?.gqlOperations);return n&&(t.gqlOperations=n),Object.keys(t).length>0?t:void 0}function typeSettingsState(e,t,n){return{...e?{description:e}:{},pluralForm:t,...n&&{settings:n}}}function comparableTypeSettings(e){return typeSettingsState(e.description,hr.camelize(e.pluralForm,!0),normalizeComparableSettings(e.settings))}function snapshotTypeSettingsState(e){return typeSettingsState(e.description,e.pluralForm,e.settings??{})}function compareTypeSettings(e,t,n,r){let i=comparableTypeSettings(n),a=comparableTypeSettings(r);JSON.stringify(i)!==JSON.stringify(a)&&e.changes.push({kind:`table_settings_modified`,tableName:t,reason:`settings changed`,before:snapshotTypeSettingsState(n),after:snapshotTypeSettingsState(r)})}function typeScriptsState(e){return{...e.typeHookExpr&&{typeHookExpr:e.typeHookExpr},...e.typeValidateExpr!==void 0&&{typeValidateExpr:e.typeValidateExpr}}}function compareTypeScripts(e,t,n,r){let i=typeScriptsState(n),a=typeScriptsState(r);JSON.stringify(i)!==JSON.stringify(a)&&e.changes.push({kind:`table_scripts_modified`,tableName:t,reason:`table-level scripts changed`,before:i,after:a})}function buildExpandBaseSnapshot(e,t){let n=copySnapshotRecord(e.tables);for(let e of t){let t=n[e.tableName],r=t?.fields[e.fieldName];if(!t||!r)continue;let i=copySnapshotRecord(t.fields);i[e.fieldName]={...r,required:!1},n[e.tableName]={...t,fields:i}}return normalizeSchemaSnapshot({...e,tables:n})}function buildExpandDiff(e,t,n){return{...compareSnapshots(buildExpandBaseSnapshot(e,n),t),requiresMigrationScript:!0}}function buildIntermediateSnapshot(e,t){let n=copySnapshotRecord(e.tables);for(let e of t){let t=n[e.tableName];if(!t)continue;let r=copySnapshotRecord(t.fields),{hooks:i,validate:a,...o}=e.after;r[e.tempFieldName]={...o,required:!1,unique:!1},delete r[e.fieldName],n[e.tableName]={...t,fields:r}}return normalizeSchemaSnapshot({...e,tables:n})}function compareSnapshots(e,t,n){let r=n?.fieldRenames??[];assertValidFieldRenames(e,t,r);let i=new Map;for(let e of r){let t=i.get(e.tableName)??[];t.push(e),i.set(e.tableName,t)}let a=n?.typeRenames??[];assertValidTypeRenames(e,t,a);let o=new Map(a.map(e=>[e.previousTableName,e.tableName])),s=new Set(a.map(e=>e.tableName)),c={changes:[],breakingChanges:[],warnings:[],typeRenameTargets:o},l=new Set(Object.keys(e.tables)),u=new Set(Object.keys(t.tables));for(let n of a){let r=A(e.tables[n.previousTableName],`renamed table "${n.previousTableName}" missing from previous snapshot`),i=A(t.tables[n.tableName],`renamed table "${n.tableName}" missing from current snapshot`);c.changes.push({kind:`table_renamed`,tableName:n.tableName,previousTableName:n.previousTableName,before:r,after:i}),c.breakingChanges.push({tableName:n.tableName,reason:`Table renamed from ${n.previousTableName} to ${n.tableName} (existing records must be copied by the migration script)`}),c.breakingChanges.push({tableName:n.tableName,reason:`GraphQL API names derived from ${n.previousTableName}/${r.pluralForm} change to ${n.tableName}/${i.pluralForm} — breaking for API clients`})}for(let[e,n]of Object.entries(t.tables))s.has(e)||l.has(e)||c.changes.push({kind:`table_added`,tableName:e,after:n});for(let[t,n]of Object.entries(e.tables))o.has(t)||u.has(t)||(c.changes.push({kind:`table_removed`,tableName:t,before:n}),c.warnings.push({tableName:t,reason:qi}));for(let n of u){if(!l.has(n))continue;let r=A(e.tables[n],`table "${n}" missing from previous snapshot`),a=A(t.tables[n],`table "${n}" missing from current snapshot`);compareTypeSettings(c,n,r,a),compareTypeScripts(c,n,r,a),compareTypeFields(c,n,r,a,i.get(n)),compareIndexes(c,n,r.indexes,a.indexes),compareFiles(c,n,r.files,a.files),compareRelationships(c,n,`forward`,r.forwardRelationships,a.forwardRelationships),compareRelationships(c,n,`backward`,r.backwardRelationships,a.backwardRelationships),comparePermissions(c,n,r.permissions?.record,a.permissions?.record,r.permissions?.gql,a.permissions?.gql)}return{version:5,namespace:t.namespace,createdAt:new Date().toISOString(),changes:c.changes,hasBreakingChanges:c.breakingChanges.length>0,breakingChanges:c.breakingChanges,hasWarnings:c.warnings.length>0,warnings:c.warnings,requiresMigrationScript:c.breakingChanges.length>0}}function compareLocalTypesWithSnapshot(e,t,n){let r={version:5,namespace:n,createdAt:new Date().toISOString(),tables:t};return compareSnapshots(normalizeSchemaSnapshot(e),normalizeSchemaSnapshot(r))}const Yi=`sdk-migration`,Xi=`sdk-migration-history`,Zi=/^[a-z][a-z0-9_-]{0,62}$/;function sanitizeMigrationLabel(e){return(`m`+formatMigrationNumber(e)).slice(0,63)}function parseMigrationLabelNumber(e){if(!e.startsWith(`m`))return null;let t=e.slice(1);if(!/^\d+$/.test(t))return null;let n=parseInt(t,10);return n>9999?null:n}function parseMigrationHistoryId(e){return Zi.test(e)?e:null}function createMigrationHistoryId(){return`h${or().replaceAll(`-`,``)}`}function handleOptionalToRequiredError(e,t){if(e instanceof q&&e.code===K.FailedPrecondition&&e.message.includes(`cannot be updated from non-required to required when records exist`)){M.error(`Schema change failed: Cannot change field from optional to required when records exist.`),M.newline();for(let e of t)M.info(e)}throw e}function snapshotRecordSchema(e){return H.custom(e=>typeof e==`object`&&!!e&&!Array.isArray(e),{message:`Expected record`}).transform((t,n)=>{let r=Object.create(null);for(let i of Object.keys(t)){let a=e.safeParse(t[i]);if(!a.success){for(let e of a.error.issues)n.addIssue({...e,path:[i,...e.path]});continue}r[i]=a.data}return r})}const Qi=H.looseObject({expr:H.string()}),$i=H.looseObject({script:H.looseObject({expr:H.string()}).optional(),errorMessage:H.string()}),ea=H.looseObject({start:H.number(),maxValue:H.number().optional(),format:H.string().optional()}),ta=H.looseObject({value:H.string(),description:H.string().optional()}),na=H.looseObject({type:H.string(),required:H.boolean().default(!0),array:H.boolean().optional(),index:H.boolean().optional(),unique:H.boolean().optional(),allowedValues:H.array(ta).optional(),foreignKey:H.boolean().optional(),foreignKeyType:H.string().optional(),foreignKeyField:H.string().optional(),description:H.string().optional(),vector:H.boolean().optional(),hooks:H.looseObject({create:Qi.optional(),update:Qi.optional()}).optional(),validate:H.array($i).optional(),serial:ea.optional(),scale:H.number().optional(),default:H.unknown().optional(),fields:H.lazy(()=>snapshotRecordSchema(na)).optional()}),ra=H.looseObject({fields:H.array(H.string()),unique:H.boolean().optional()}),ia=H.looseObject({targetType:H.string(),targetField:H.string(),sourceField:H.string(),isArray:H.boolean(),description:H.string()}),aa=[`user`,`record`,`newRecord`,`oldRecord`],oa=H.unknown().refine(e=>{if(typeof e!=`object`||!e||Array.isArray(e))return!0;let t=Object.keys(e);return aa.filter(e=>t.includes(e)).length<2},`Ambiguous field-ref operand: contains more than one of user/record/newRecord/oldRecord`),sa=H.unknown().refine(e=>{if(typeof e!=`object`||!e||Array.isArray(e))return!0;let t=Object.keys(e);return aa.filter(e=>t.includes(e)).length<2},`Ambiguous field-ref operand: contains more than one of user/record/newRecord/oldRecord`).refine(e=>{if(typeof e!=`object`||!e||Array.isArray(e))return!0;let t=Object.keys(e);return![`record`,`newRecord`,`oldRecord`].some(e=>t.includes(e))},`GQL permissions only support { user } field references`),ca=H.string(),la=H.tuple([oa,ca,oa]).rest(H.unknown()),ua=H.tuple([sa,ca,sa]).rest(H.unknown()),da=H.looseObject({conditions:H.array(la),description:H.string().optional(),permit:H.enum([`allow`,`deny`])}),fa=H.looseObject({create:H.array(da).default([]),read:H.array(da).default([]),update:H.array(da).default([]),delete:H.array(da).default([])}),pa=H.string(),ma=H.looseObject({conditions:H.array(ua),actions:H.array(pa),permit:H.enum([`allow`,`deny`]),description:H.string().optional()}),ha=H.array(ma),ga=H.looseObject({name:H.string(),pluralForm:H.string().optional(),description:H.string().optional(),fields:snapshotRecordSchema(na),settings:H.looseObject({aggregation:H.boolean().optional(),bulkUpsert:H.boolean().optional(),gqlOperations:H.looseObject({create:H.boolean().optional(),update:H.boolean().optional(),delete:H.boolean().optional(),read:H.boolean().optional()}).optional(),publishEvents:H.boolean().optional()}).optional(),indexes:snapshotRecordSchema(ra).optional(),files:snapshotRecordSchema(H.string()).optional(),forwardRelationships:snapshotRecordSchema(ia).optional(),backwardRelationships:snapshotRecordSchema(ia).optional(),permissions:H.looseObject({record:fa.optional(),gql:ha.optional()}).optional()}),_a=H.looseObject({historyId:H.string().regex(Zi),replacedHistoryId:H.string().regex(Zi).nullable(),replacedLatestMigration:H.number().int().min(0).max(9999)}),va=H.looseObject({version:H.number(),namespace:H.string(),createdAt:H.string(),tables:snapshotRecordSchema(ga),rebaseline:_a.optional()}),ya=H.looseObject({indexes:snapshotRecordSchema(ra).optional(),files:snapshotRecordSchema(H.string()).optional()}),ba=H.looseObject({description:H.string().optional(),pluralForm:H.string(),settings:H.looseObject({aggregation:H.boolean().optional(),bulkUpsert:H.boolean().optional(),gqlOperations:H.looseObject({create:H.boolean().optional(),update:H.boolean().optional(),delete:H.boolean().optional(),read:H.boolean().optional()}).optional(),publishEvents:H.boolean().optional()}).optional()}),xa=H.looseObject({recordPermission:fa.optional(),gqlPermission:ha.optional()}),Sa=H.looseObject({kind:H.literal(`table_added`),tableName:H.string(),reason:H.string().optional(),after:ga}),Ca=H.looseObject({kind:H.literal(`table_removed`),tableName:H.string(),reason:H.string().optional(),before:ga}),wa=H.looseObject({kind:H.literal(`table_renamed`),tableName:H.string(),reason:H.string().optional(),previousTableName:H.string(),before:ga,after:ga}),Ta=H.looseObject({kind:H.literal(`table_modified`),tableName:H.string(),reason:H.string().optional(),before:ya.optional(),after:ya.optional()}),Ea=H.looseObject({kind:H.literal(`table_settings_modified`),tableName:H.string(),reason:H.string().optional(),before:ba,after:ba}),Da=H.looseObject({kind:H.literal(`field_added`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),after:na}),Oa=H.looseObject({kind:H.literal(`field_removed`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),before:na}),ka=H.looseObject({kind:H.literal(`field_modified`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),before:na,after:na}),Aa=H.looseObject({kind:H.literal(`field_renamed`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),previousFieldName:H.string(),before:na,after:na}),ja=H.looseObject({kind:H.literal(`field_type_modified`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),before:na,after:na}),Ma=H.looseObject({kind:H.literal(`index_added`),tableName:H.string(),reason:H.string().optional(),indexName:H.string(),after:ra}),Na=H.looseObject({kind:H.literal(`index_removed`),tableName:H.string(),reason:H.string().optional(),indexName:H.string(),before:ra}),Pa=H.looseObject({kind:H.literal(`index_modified`),tableName:H.string(),reason:H.string().optional(),indexName:H.string(),before:ra,after:ra}),Fa=H.looseObject({kind:H.literal(`file_added`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),after:H.string()}),Ia=H.looseObject({kind:H.literal(`file_removed`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),before:H.string()}),La=H.looseObject({kind:H.literal(`file_modified`),tableName:H.string(),reason:H.string().optional(),fieldName:H.string(),before:H.string(),after:H.string()}),Ra=H.looseObject({kind:H.literal(`relationship_added`),tableName:H.string(),reason:H.string().optional(),relationshipName:H.string(),relationshipType:H.enum([`forward`,`backward`]).optional(),after:ia}),za=H.looseObject({kind:H.literal(`relationship_removed`),tableName:H.string(),reason:H.string().optional(),relationshipName:H.string(),relationshipType:H.enum([`forward`,`backward`]).optional(),before:ia}),Ba=H.looseObject({kind:H.literal(`relationship_modified`),tableName:H.string(),reason:H.string().optional(),relationshipName:H.string(),relationshipType:H.enum([`forward`,`backward`]).optional(),before:ia,after:ia}),Va=H.looseObject({kind:H.literal(`permission_modified`),tableName:H.string(),reason:H.string().optional(),before:xa.optional(),after:xa.optional()}),Ha=H.looseObject({typeHookExpr:H.looseObject({create:H.string().optional(),update:H.string().optional()}).optional(),typeValidateExpr:H.string().optional()}),Ua=H.looseObject({kind:H.literal(`table_scripts_modified`),tableName:H.string(),reason:H.string().optional(),before:Ha,after:Ha}),Wa=H.discriminatedUnion(`kind`,[Sa,Ca,wa,Ta,Ea,Da,Oa,ka,Aa,ja,Ma,Na,Pa,Fa,Ia,La,Ra,za,Ba,Va,Ua]),Ga=H.looseObject({tableName:H.string(),fieldName:H.string().optional(),reason:H.string(),unsupported:H.boolean().optional(),showThreeStepHint:H.boolean().optional()}),Ka=H.looseObject({tableName:H.string(),fieldName:H.string().optional(),reason:H.string()}),qa=H.looseObject({reason:H.string().trim().min(1),acknowledgedAt:H.string()}),Ja=H.looseObject({version:H.number(),namespace:H.string(),createdAt:H.string(),description:H.string().optional(),changes:H.array(Wa),hasBreakingChanges:H.boolean(),breakingChanges:H.array(Ga),hasWarnings:H.boolean().optional(),warnings:H.array(Ka).optional(),requiresMigrationScript:H.boolean(),scriptSkipped:qa.optional()}),Ya=0,Xa=`schema.json`,Za=`diff.json`,Qa=`migrate.ts`,$a=`migrate.test.ts`,eo=`db.ts`,to=/^\d{4}$/;function isValidMigrationNumber(e){return to.test(e)}const no={schema:Xa,diff:Za,migrate:Qa,test:$a,db:eo};function getMigrationDirPath(e,t){let n=formatMigrationNumber(t);return B.join(e,n)}function getMigrationFilePath(e,t,n){let r=getMigrationDirPath(e,t);return B.join(r,no[n])}function loadSnapshot(e){let t=W.readFileSync(e,`utf-8`),n;try{n=JSON.parse(t)}catch(t){throw Error(`Invalid schema snapshot at ${e}: ${String(t)}`,{cause:t})}assertSupportedMigrationFileVersion(e,n);let r=va.safeParse(normalizeLegacyTablesKey(n));if(!r.success)throw Error(`Invalid schema snapshot at ${e}: ${H.prettifyError(r.error)}`,{cause:r.error});let i=r.data;return normalizeSchemaSnapshot(i)}function loadDiff(e){let t=W.readFileSync(e,`utf-8`),n;try{n=JSON.parse(t)}catch(t){throw Error(`Invalid migration diff at ${e}: ${String(t)}`,{cause:t})}assertSupportedMigrationFileVersion(e,n);let r=Ja.safeParse(normalizeLegacyFieldNames(normalizeLegacyChangeKinds(n)));if(!r.success)throw Error(`Invalid migration diff at ${e}: ${H.prettifyError(r.error)}`,{cause:r.error});let i=r.data,a=i.warnings??deriveWarningsFromChanges(i);return{...i,warnings:a,hasWarnings:a.length>0}}function getMigrationFiles(e){if(!W.existsSync(e))return[];let t=W.readdirSync(e,{withFileTypes:!0}),n=[];for(let r of t){if(!r.isDirectory()||!isValidMigrationNumber(r.name))continue;let t=parseInt(r.name,10),i=B.join(e,r.name),a=B.join(i,Xa);W.existsSync(a)&&n.push({number:t,type:`schema`,path:a});let o=B.join(i,Za);W.existsSync(o)&&n.push({number:t,type:`diff`,path:o})}return n.toSorted((e,t)=>e.number-t.number)}function getNextMigrationNumber(e){let t=getMigrationFiles(e);return t.length===0?0:Math.max(...t.map(e=>e.number))+1}function getLatestMigrationNumber(e){return latestMigrationNumber(getMigrationFiles(e))}function latestMigrationNumber(e){return e.length===0?0:Math.max(...e.map(e=>e.number))}function assertMigrationNumberExists(e,t){let n=getMigrationFiles(e);if(t!==0&&!n.some(e=>e.number===t))throw Error(`Migration ${formatMigrationNumber(t)} does not exist in working tree (latest is ${formatMigrationNumber(latestMigrationNumber(n))}).`);return latestMigrationNumber(n)}function applyDiffToSnapshot(e,t){let n=copySnapshotRecord(e.tables);for(let e of t.changes)switch(e.kind){case`table_added`:n[e.tableName]=e.after;break;case`table_removed`:delete n[e.tableName];break;case`table_modified`:{let t=n[e.tableName];if(t&&e.after){let r=e.after;n[e.tableName]={...t,...r.indexes!==void 0&&{indexes:r.indexes},...r.files!==void 0&&{files:r.files}}}break}case`table_settings_modified`:{let t=n[e.tableName];t&&(n[e.tableName]={...t,description:e.after.description,pluralForm:e.after.pluralForm,settings:e.after.settings??{}});break}case`table_scripts_modified`:{let t=n[e.tableName];if(t){let{typeHookExpr:r,typeValidateExpr:i,...a}=t;n[e.tableName]={...a,...e.after.typeHookExpr&&{typeHookExpr:e.after.typeHookExpr},...e.after.typeValidateExpr!==void 0&&{typeValidateExpr:e.after.typeValidateExpr}}}break}case`field_added`:case`field_modified`:case`field_type_modified`:{let t=n[e.tableName];if(t){let r=copySnapshotRecord(t.fields);r[e.fieldName]=e.after,n[e.tableName]={...t,fields:r}}break}case`field_removed`:{let t=n[e.tableName];if(t){let r=copySnapshotRecord(t.fields);delete r[e.fieldName],n[e.tableName]={...t,fields:r}}break}case`field_renamed`:{let t=n[e.tableName];if(t){let r=copySnapshotRecord(t.fields);delete r[e.previousFieldName],r[e.fieldName]=e.after,n[e.tableName]={...t,fields:r}}break}case`table_renamed`:delete n[e.previousTableName],n[e.tableName]=e.after;break;case`index_added`:case`index_modified`:{let t=n[e.tableName];if(t){let r=copySnapshotRecord(t.indexes);r[e.indexName]=e.after,n[e.tableName]={...t,indexes:r}}break}case`index_removed`:{let t=n[e.tableName];if(t&&t.indexes){let r=copySnapshotRecord(t.indexes);delete r[e.indexName],n[e.tableName]={...t,indexes:Object.keys(r).length>0?r:void 0}}break}case`file_added`:case`file_modified`:{let t=n[e.tableName];if(t){let r=copySnapshotRecord(t.files);r[e.fieldName]=e.after,n[e.tableName]={...t,files:r}}break}case`file_removed`:{let t=n[e.tableName];if(t&&t.files){let r=copySnapshotRecord(t.files);delete r[e.fieldName],n[e.tableName]={...t,files:Object.keys(r).length>0?r:void 0}}break}case`relationship_added`:case`relationship_modified`:{let t=n[e.tableName];if(t){let r=e.after;if((e.relationshipType??(t.forwardRelationships?.[e.relationshipName]?`forward`:t.backwardRelationships?.[e.relationshipName]?`backward`:`forward`))===`forward`){let i=copySnapshotRecord(t.forwardRelationships);i[e.relationshipName]=r,n[e.tableName]={...t,forwardRelationships:i}}else{let i=copySnapshotRecord(t.backwardRelationships);i[e.relationshipName]=r,n[e.tableName]={...t,backwardRelationships:i}}}break}case`relationship_removed`:{let t=n[e.tableName];if(t){let r=e.relationshipType??(t.forwardRelationships?.[e.relationshipName]?`forward`:t.backwardRelationships?.[e.relationshipName]?`backward`:null);if(r===`forward`&&t.forwardRelationships?.[e.relationshipName]){let r=copySnapshotRecord(t.forwardRelationships);delete r[e.relationshipName],n[e.tableName]={...t,forwardRelationships:Object.keys(r).length>0?r:void 0}}else if(r===`backward`&&t.backwardRelationships?.[e.relationshipName]){let r=copySnapshotRecord(t.backwardRelationships);delete r[e.relationshipName],n[e.tableName]={...t,backwardRelationships:Object.keys(r).length>0?r:void 0}}}break}case`permission_modified`:{let t=n[e.tableName];if(t&&e.after){let r=e.after;n[e.tableName]={...t,permissions:{record:r.recordPermission,gql:r.gqlPermission}}}break}}return normalizeSchemaSnapshot({...e,tables:n,createdAt:t.createdAt})}function reconstructSnapshotFromMigrations(e,t){let n=getMigrationFiles(e);if(n.length===0)return null;let r=n.find(e=>e.type===`schema`&&e.number===0);if(!r)throw Error(`No initial schema file found in ${e}. Expected ${formatMigrationNumber(0)}/schema.json`);let i=loadSnapshot(r.path);for(let e of n)if(e.type===`diff`&&e.number>r.number){if(t!==void 0&&e.number>t)continue;let n=loadDiff(e.path);i=applyDiffToSnapshot(i,n)}return i}function validateMigrationFiles(e){let t=[];if(!W.existsSync(e))return t;let n=getMigrationFiles(e);if(n.length===0)return t;let r=[],i=[];for(let e of n)e.type===`schema`?r.push(e.number):i.push(e.number);r.includes(0)||t.push({type:`missing_schema`,message:`Initial schema snapshot (${formatMigrationNumber(0)}/schema.json) is missing`,migrationNumber:0});for(let e of r)e!==0&&t.push({type:`invalid_schema_number`,message:`Schema file found at migration ${formatMigrationNumber(e)}, but schema should only exist at ${formatMigrationNumber(0)}`,migrationNumber:e});let a=[...new Set([...r,...i])].toSorted((e,t)=>e-t);if(a.length===0)return t;for(let e of r)e!==0&&i.includes(e)&&t.push({type:`duplicate`,message:`Migration ${formatMigrationNumber(e)} has both schema and diff files`,migrationNumber:e});let o=Math.max(...a);for(let e=0;e<=o;e++)a.includes(e)||t.push({type:`gap`,message:`Migration ${formatMigrationNumber(e)} is missing (gap in sequence)`,migrationNumber:e});for(let e of a)e>0&&!i.includes(e)&&t.push({type:`missing_diff`,message:`Migration ${formatMigrationNumber(e)} is missing diff file`,migrationNumber:e});return t}function assertValidMigrationFiles(e,t){let n=validateMigrationFiles(e);if(n.length>0){let e=n.map(e=>` - ${e.message}`).join(`
|
|
@@ -127,13 +127,13 @@ export {};
|
|
|
127
127
|
another file cannot have one injected automatically. 'tailor deploy' can add it for you.`))}const Ao=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function findDefineConfigCalls(e,t){if(!e||typeof e!=`object`)return;let n=e;if(n.type===`CallExpression`){let e=n;if(e.callee.type===`Identifier`&&e.callee.name===`defineConfig`){let n=e.arguments[0],r=n&&n.type===`ObjectExpression`?n:null;t.push({callExpr:e,configObj:r})}}for(let e of Object.keys(n)){let r=n[e];if(Array.isArray(r))for(let e of r)findDefineConfigCalls(e,t);else r&&typeof r==`object`&&findDefineConfigCalls(r,t)}}function findIdProperty(e){for(let t of e.properties)if(t.type===`Property`&&(t.key.type===`Identifier`?t.key.name:t.key.type===`Literal`?t.key.value:null)===`id`)return t;return null}async function ensureConfigId(e){let t=await W.promises.readFile(e,`utf-8`),{program:n}=mr(e,t),r=[];if(findDefineConfigCalls(n,r),r.length===0)return null;if(r.length>1)throw Error(`Multiple defineConfig() calls found in ${e}. Only one is supported.`);let{configObj:i}=A(r[0],`defineConfig call site missing`);if(!i)throw Error(`defineConfig() argument must be an inline object literal in ${e} so the SDK can manage the 'id' field.`);let a=findIdProperty(i);if(a){let t=a.value;if(t.type!==`Literal`)throw Error(`'id' field in ${e} must be a string literal. To use this config for a separate app, delete it.`);let n=t.value;if(typeof n!=`string`||n===``)throw Error(`'id' field in ${e} must be a non-empty string literal. To use this config for a separate app, delete it.`);if(!Ao.test(n))throw Error(`'id' field in ${e} must be a UUID. To use this config for a separate app, delete it.`);return{id:n,injected:!1}}let o=crypto.randomUUID(),s=insertIdProperty(t,i,o);return await W.promises.writeFile(e,s,`utf-8`),M.info(`Generated app id and wrote to ${e}: ${o}`),{id:o,injected:!0}}async function readConfigId(e){let t=await W.promises.readFile(e,`utf-8`),{program:n}=mr(e,t),r=[];if(findDefineConfigCalls(n,r),r.length===0)return null;if(r.length>1)throw Error(`Multiple defineConfig() calls found in ${e}. Only one is supported.`);let{configObj:i}=A(r[0],`defineConfig call site missing`);if(!i)throw Error(`defineConfig() argument must be an inline object literal in ${e} so the SDK can manage the 'id' field.`);let a=findIdProperty(i);if(!a||a.value.type!==`Literal`)return{id:null};let o=a.value.value;return{id:typeof o==`string`&&o!==``?o:null}}async function assertConfigIdInCI(e){let t=await readConfigId(e);if(t!==null){if(!t.id)throw Error(`tailor.config.ts is missing an 'id'. CI does not auto-generate one (each run would be treated as a separate app and break resource ownership). Run 'tailor deploy' locally and commit the injected id.`);if(!Ao.test(t.id))throw Error(`'id' in ${e} must be a UUID. To use this config for a separate app, delete it.`)}}async function ensureConfigIdForDeploy(e){let{configPath:t,dryRun:n,buildOnly:r}=e;if(r)return;let i=ct(process.env.TAILOR_CI_ALLOW_ID_INJECTION)===!0,a=fr&&!i;if(n){a&&await assertConfigIdInCI(t);return}if(a){await assertConfigIdInCI(t);return}await ensureConfigId(t)}const jo=`// SDK-managed app id — do not edit, except when copying this config to a separate app.`;function insertIdProperty(e,t,n){let r=`id: ${JSON.stringify(n)}`;if(t.properties.length>0){let n=A(t.properties[0],`first property missing`),i=e.lastIndexOf(`
|
|
128
128
|
`,n.start-1)+1,a=e.slice(i,n.start);if(!/^[\t ]*$/.test(a))return e.slice(0,n.start)+`${r}, `+e.slice(n.start);let o=`${jo}\n${a}${r},\n${a}`;return e.slice(0,n.start)+o+e.slice(n.start)}let i=t.start+1,a=e.lastIndexOf(`
|
|
129
129
|
`,t.start)+1,o=e.slice(a).match(/^[\t ]*/)?.[0]??``,s=`${o} `,c=`\n${s}${jo}\n${s}${r},\n${o}`;return e.slice(0,i)+c+e.slice(i)}function parseDeployConfigPaths(e){let t=e??process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH;if(t===void 0)return[void 0];let n=t.split(`,`).map(e=>e.trim());if(n.some(e=>e.length===0))throw Error(`--config must contain one or more non-empty config paths.`);return n}async function buildDeploymentTarget(e){let{configPath:t,loadedConfig:n,dryRun:r,buildOnly:i,noCache:a,packageVersion:o,cacheDir:s}=e,{config:c,plugins:l}=n??await loadDeployConfig({configPath:t,dryRun:r,buildOnly:i}),u=B.dirname(c.path),d=er(`pnpm-lock.yaml`,{cwd:u})??er(`package-lock.json`,{cwd:u})??er(`yarn.lock`,{cwd:u})??er(`bun.lock`,{cwd:u}),f=createCacheManager({enabled:!a,cacheDir:s,sdkVersion:o,lockfileHash:d?_t(d):void 0}),p;l.length>0&&(p=new PluginManager(l)),await z(`build.generateUserTypes`,()=>generateUserTypes({config:c,configPath:c.path}));let m,h,g,_;try{let e=await z(`build.loadApplication`,()=>Yt({config:c,pluginManager:p,bundleCache:f.bundleCache}));m=e.application,h=e.workflowBuildResult,g=e.httpAdapterBuildResult,_=e.bundledScripts}finally{f.finalize()}return{config:c,application:m,workflowBuildResult:h,httpAdapterBuildResult:g,bundledScripts:_}}async function loadDeployConfig(e){let{configPath:t,dryRun:n,buildOnly:r}=e;return z(`build.loadConfig`,async()=>{let e=loadConfigPath(t);if(e){let t=B.resolve(process.cwd(),e);W.existsSync(t)&&await ensureConfigIdForDeploy({configPath:t,dryRun:n,buildOnly:r})}let i=await loadConfig(t);return r||warnMissingAppId(i.config.id),i})}async function buildDeploymentTargets(e){let{configPaths:t,loadedConfigs:n,buildTarget:r=buildDeploymentTarget,...i}=e;return Promise.all(t.map((e,t)=>r({...i,configPath:e,loadedConfig:n?.[t]})))}function addPossiblyAmbiguousNamespace(e,t,n){if(e.has(t)){e.get(t)!==n&&e.set(t,void 0);return}e.set(t,n)}function collectVisibleResources(e){let{application:t,applications:n,visibleKeysOf:r,resourcesOf:i,createResult:a,addResource:o}=e,s=r(t),c=a();for(let e of n)for(let t of i(e))s.has(t.visibilityKey)&&o(c,t.resourceKey,t.visibilityKey);return c}function collectApplicationTailorDBNamespaces(e){return new Set([...e.tailorDBServices.map(e=>e.namespace),...e.externalTailorDBNamespaces])}function*tailorDBTypeResources(e){for(let t of e.tailorDBServices)for(let e of Object.keys(t.types))yield{visibilityKey:t.namespace,resourceKey:e}}function collectVisibleTailorDBTypeNamespaces(e,t){return collectVisibleResources({application:e,applications:t,visibleKeysOf:collectApplicationTailorDBNamespaces,resourcesOf:tailorDBTypeResources,createResult:()=>new Map,addResource:addPossiblyAmbiguousNamespace})}function collectApplicationResolverNamespaces(e){return new Set(e.subgraphs.filter(e=>e.Type===`pipeline`).map(e=>e.Name))}function*idpNameResources(e){for(let t of collectApplicationIdpNames(e))yield{visibilityKey:t,resourceKey:t}}function collectVisibleIdpNames(e,t){return collectVisibleResources({application:e,applications:t,visibleKeysOf:collectApplicationIdpNames,resourcesOf:idpNameResources,createResult:()=>new Set,addResource:(e,t)=>{e.add(t)}})}function*resolverResources(e){for(let t of e.resolverServices)for(let e of Object.values(t.resolvers))yield{visibilityKey:t.namespace,resourceKey:e.name}}function collectVisibleResolverNamespaces(e,t){return collectVisibleResources({application:e,applications:t,visibleKeysOf:collectApplicationResolverNamespaces,resourcesOf:resolverResources,createResult:()=>new Map,addResource:addPossiblyAmbiguousNamespace})}function subscribedIdpName(e,t){if(t.idp!=null)return t.idp;let n=collectApplicationIdpNames(e);if(n.size!==1)return;let[r]=n;return r}function missingOwnerMessage(e,t,n){let r=`Executor "${e}" subscribes to ${t.resource}, which no config in this deploy declares.`,i=t.externalHint(n);return i?`${r} This config declares ${i}, so add the config that owns it to --config.`:t.trigger.kind===`workflowExecution`||t.trigger.kind===`workflowJobExecution`?`${r} A workflow has no "external" declaration, unlike a TailorDB namespace or resolver, so nothing in this config points at the one that owns it. Check the name, or add the config that declares the workflow to --config.`:`${r} This config declares nothing external that could hold it, so check the name.`}function collectEventSubscriptions(e){let t=[],n=e.map(e=>e.application);for(let r of e){let i=r.application.executorService?.executors??{},a=collectSubscriberVisibility(r,n);for(let n of Object.values(i)){let i=eventSourceLookup(n,r,a);if(!i)continue;let o={subscriber:r,executorName:n.name,resource:i.resource,disabled:!subscribesToEvents(n),trigger:i.trigger};if(i.declaredBy(r)){t.push({...o,owner:r,pinned:i.pinned(r),key:i.keyIn(r)});continue}let s=e.filter(e=>e.config.path!==r.config.path&&i.declaredBy(e)),c=i.narrowOwners(s);if(c===`ambiguous`)continue;let[l]=c;if(!l)throw Error(missingOwnerMessage(n.name,i,r));t.push({...o,owner:l,pinned:i.pinned(l),key:i.keyIn(l)})}}return t}function subscribedResourceKeys(e,t){return new Set(publishingSubscriptions(ownedSubscriptions(e,t)).flatMap(e=>e.key??[]))}function ownedSubscriptions(e,t){return e.filter(e=>e.owner.config.path===t.config.path)}function publishingSubscriptions(e){return e.filter(e=>!e.disabled)}function subscribedTailorDBTables(e){return new Set(publishingSubscriptions(e).flatMap(e=>e.trigger.kind===`tailordb`?[e.trigger.tableName]:[]))}function subscribedResolvers(e){return new Set(publishingSubscriptions(e).flatMap(e=>e.trigger.kind===`resolverExecuted`?[e.trigger.resolverName]:[]))}function subscribedIdps(e){return new Set(publishingSubscriptions(e).flatMap(e=>e.trigger.kind===`idpUser`?[subscribedIdpName(e.subscriber.application,e.trigger)??[]].flat():[]))}function subscribedWorkflows(e){let t={workflowNames:new Set},n={workflowNames:new Set};for(let{trigger:r}of publishingSubscriptions(e))r.kind===`workflowExecution`?t.workflowNames.add(r.workflowName):r.kind===`workflowJobExecution`&&n.workflowNames.add(r.workflowName);return{execution:t,jobExecution:n}}function collectDependentApps(e){let t=new Map;for(let{subscriber:n,owner:r,pinned:i,key:a}of publishingSubscriptions(e)){if(n.config.path===r.config.path||i||a===void 0)continue;let e=n.application.id;if(e===void 0)continue;let o=t.get(a)??new Map;o.set(e,`publish-events`),t.set(a,o)}return t}function collectWorkflowJobPublishEvents(e){let t=new Map;for(let n of e.application.workflowService?.jobs??[])n.publishEvents!==void 0&&t.set(n.name,n.publishEvents);return t}function collectSubscriberVisibility(e,t){return{tailorDBTypes:collectVisibleTailorDBTypeNamespaces(e.application,t),resolvers:collectVisibleResolverNamespaces(e.application,t),idps:collectVisibleIdpNames(e.application,t)}}function externalTailorDBNamespaces(e){return e.application.externalTailorDBNamespaces}function externalSubgraphNames(e,t,n){return e.application.subgraphs.filter(e=>e.Type===t&&!n.has(e.Name)).map(e=>e.Name)}function externalResolverNamespaces(e){return externalSubgraphNames(e,`pipeline`,new Set(e.application.resolverServices.map(e=>e.namespace)))}function externalIdpNames(e){return externalSubgraphNames(e,`idp`,new Set(e.application.idpServices.map(e=>e.name)))}function describeExternal(e,t){if(t.length!==0)return`external ${t.length===1?e:`${e}s`} ${t.map(e=>`"${e}"`).join(`, `)}`}function declaresTailorDBType(e,t){return e.application.tailorDBServices.some(e=>e.types[t])||void 0}function declaresResolver(e,t){return e.application.resolverServices.some(e=>Object.values(e.resolvers).some(e=>e.name===t))||void 0}function declaresIdp(e,t){return e.application.idpServices.some(e=>e.name===t)||void 0}function declaresWorkflow(e,t){return Object.values(e.application.workflowService?.workflows??{}).some(e=>e.name===t)||void 0}function pinsTailorDBType(e,t){for(let n of e.application.tailorDBServices){let e=n.types[t];if(e)return e.settings.publishEvents!==void 0}return!1}function pinsResolverIn(e,t,n){return e.application.resolverServices.some(e=>e.namespace===t&&Object.values(e.resolvers).some(e=>e.name===n&&e.publishEvents!==void 0))}function pinsIdp(e,t){return e.application.idpServices.some(e=>e.name===t&&e.publishEvents!==void 0)}function pinsWorkflow(e,t){return Object.values(e.application.workflowService?.workflows??{}).some(e=>e.name===t&&e.publishEvents!==void 0)}function pinsEveryJobOfWorkflow(e,t){let n=Object.values(e.application.workflowService?.workflows??{}).find(e=>e.name===t);if(n===void 0)return!1;let r=e.workflowBuildResult?.mainJobDeps[n.mainJob.name]??[],i=collectWorkflowJobPublishEvents(e);return r.length>0&&r.every(e=>i.has(e))}function tailorDBTypeNamespaceIn(e,t){return e.application.tailorDBServices.find(e=>e.types[t])?.namespace}function narrowByVisibleNamespace(e){let{candidates:t,visible:n,resourceKey:r,declaresIn:i}=e;if(!n.has(r))return[];let a=n.get(r);return a===void 0?`ambiguous`:t.filter(e=>i(e,a))}function declaresTailorDBTypeIn(e,t,n){return e.application.tailorDBServices.some(e=>e.namespace===t&&!!e.types[n])}function declaresResolverIn(e,t,n){return e.application.resolverServices.some(e=>e.namespace===t&&Object.values(e.resolvers).some(e=>e.name===n))}function eventSourceLookup(e,t,n){let{trigger:r}=e;switch(r.kind){case`tailordb`:return{resource:Mi.tailorDBType(r.tableName).resource,trigger:r,declaredBy:e=>declaresTailorDBType(e,r.tableName),pinned:e=>pinsTailorDBType(e,r.tableName),keyIn:e=>{let t=tailorDBTypeNamespaceIn(e,r.tableName);return t&&Q.tailorDBType(t,r.tableName)},narrowOwners:e=>narrowByVisibleNamespace({candidates:e,visible:n.tailorDBTypes,resourceKey:r.tableName,declaresIn:(e,t)=>declaresTailorDBTypeIn(e,t,r.tableName)}),externalHint:e=>describeExternal(`TailorDB namespace`,externalTailorDBNamespaces(e))};case`resolverExecuted`:{let e=findResolverNamespace(t.application,r.resolverName)??n.resolvers.get(r.resolverName);return{resource:Mi.resolver(r.resolverName).resource,trigger:r,declaredBy:e=>declaresResolver(e,r.resolverName),pinned:t=>e!==void 0&&pinsResolverIn(t,e,r.resolverName),keyIn:()=>e&&Q.resolver(e,r.resolverName),narrowOwners:e=>narrowByVisibleNamespace({candidates:e,visible:n.resolvers,resourceKey:r.resolverName,declaresIn:(e,t)=>declaresResolverIn(e,t,r.resolverName)}),externalHint:e=>describeExternal(`resolver namespace`,externalResolverNamespaces(e))}}case`idpUser`:{let e=subscribedIdpName(t.application,r);return e===void 0?void 0:{resource:Mi.idpService(e).resource,trigger:r,declaredBy:t=>declaresIdp(t,e),pinned:t=>pinsIdp(t,e),keyIn:()=>Q.idp(e),narrowOwners:t=>n.idps.has(e)?t.filter(t=>declaresIdp(t,e)):[],externalHint:t=>describeExternal(`IdP`,externalIdpNames(t).filter(t=>t===e))}}case`workflowExecution`:case`workflowJobExecution`:return{resource:r.kind===`workflowExecution`?ji.workflow(r.workflowName):ji.workflowJobs(r.workflowName),trigger:r,declaredBy:e=>declaresWorkflow(e,r.workflowName),pinned:e=>r.kind===`workflowExecution`?pinsWorkflow(e,r.workflowName):pinsEveryJobOfWorkflow(e,r.workflowName),keyIn:()=>r.kind===`workflowExecution`?Q.workflow(r.workflowName):Q.workflowJobs(r.workflowName),narrowOwners:e=>e.filter(e=>declaresWorkflow(e,r.workflowName)),externalHint:()=>void 0};default:return}}function assertRecordableDependencies(e,t){for(let{subscriber:n,owner:r,executorName:i,resource:a,pinned:o}of publishingSubscriptions(e)){if(n.config.path===r.config.path||o||!t)continue;let e=n.application.id;if(e!==void 0&&dependedByAppLabelKey(e)!==void 0)continue;let s=e===void 0?`${n.config.path} resolves without an "id" — a config that re-exports defineConfig() from another file never gets one`:`${n.config.path} resolves to the id "${e}", which is not the lowercase UUID deploy writes`,c=e===void 0?`Call defineConfig() inline in ${n.config.path} so deploy can manage its "id".`:`Restore the generated value in ${n.config.path}'s "id".`;throw Error(`Executor "${i}" in ${n.config.path} subscribes to ${a} in ${r.config.path}, which would enable event publishing on it for this deploy only. ${s} — so deploy cannot record which config the dependency belongs to, and deploying ${r.config.path} alone later would turn publishing back off without asking.\n\n${c}`)}}function computeRenamedAppDeletions(e){let{conflicts:t,resourceOwners:n,protectedAppNames:r}=e;return[...new Set(t.map(e=>e.currentOwner))].filter(e=>!n.has(e)&&!r.has(e))}function assertUniqueGlobalResourceNames(e){for(let t of Mo){let n=new Set;for(let r of e)for(let e of t.namesOf(r)){if(n.has(e))throw Error(`Duplicate ${t.resourceLabel} name "${e}" across config files. ${t.resourceLabel} names must be unique across all configs in a single deploy.`);n.add(e)}}}function ownershipTrackedPlans(e){return Object.values(e)}function collectOwnerConflicts(e){return ownershipTrackedPlans(e).flatMap(e=>e.conflicts)}function collectUnmanagedResources(e){return ownershipTrackedPlans(e).flatMap(e=>e.unmanaged)}function collectResourceOwners(e){return new Set(ownershipTrackedPlans(e).flatMap(e=>[...e.resourceOwners]))}function collectImportantResourceDeletions(e){let t=[];for(let n of e.tailorDB.changeSet.type.deletes)t.push({resourceType:`TailorDB table`,resourceName:n.name});for(let n of e.staticWebsite.changeSet.deletes)t.push({resourceType:`StaticWebsite`,resourceName:n.name});for(let n of e.aiGateway.changeSet.deletes)t.push({resourceType:`AIGateway`,resourceName:n.name});for(let n of e.auth.changeSet.oauth2Client.deletes)t.push({resourceType:`OAuth2 client`,resourceName:n.name});for(let n of e.auth.changeSet.oauth2Client.replaces)t.push({resourceType:`OAuth2 client (client type change)`,resourceName:n.name});for(let n of e.auth.changeSet.connection.deletes)t.push({resourceType:`Auth connection`,resourceName:n.name});for(let n of e.secretManager.vaultChangeSet.deletes)t.push({resourceType:`Secret Manager vault`,resourceName:n.name});for(let n of e.secretManager.secretChangeSet.deletes)t.push({resourceType:`Secret Manager secret`,resourceName:n.name});return t}function readResourceField(e,t){let n=e;for(let e of[`request`,`deleteRequest`,`createRequest`]){let r=n[e];if(r&&typeof r==`object`&&t in r){let e=r[t];return e==null?void 0:String(e)}}let r=n[t];return r==null?void 0:String(r)}function managedResourceName(e,t){return e.getName?e.getName(t):t.name}function managedResourceKey(e,t){let n=e.namespaceFields?.map(e=>readResourceField(t,e)).find(e=>e!==void 0),r=managedResourceName(e,t);return n===void 0?`${e.resourceType}:${r}`:`${e.resourceType}:${n}:${r}`}function managedNamespaceOwnerKey(e,t){if(!e.namespaceOwnerResourceType)return;let n=e.namespaceFields?.map(e=>readResourceField(t,e)).find(e=>e!==void 0);return n===void 0?void 0:`${e.namespaceOwnerResourceType}:${n}`}function addManagedResourceClaims(e,t,n){e.add(managedResourceKey(t,n));let r=managedNamespaceOwnerKey(t,n);r&&e.add(r)}function isManagedResourceClaimed(e,t,n){if(e.has(managedResourceKey(t,n)))return!0;let r=managedNamespaceOwnerKey(t,n);return r?e.has(r):!1}function retainDeletesNotClaimed(e,t){let n=0;for(let r of e.changeSet.deletes){if(isManagedResourceClaimed(t,e,r)){M.debug(`Skipping delete of ${managedResourceKey(e,r)}: still managed by another config in this deploy.`);continue}e.changeSet.deletes[n]=r,n+=1}e.changeSet.deletes.length=n}function workflowJobFunctionItems(e){let t=new Set;for(let n of e){let e=n.usedJobNames;if(Array.isArray(e))for(let n of e)typeof n==`string`&&t.add(n)}return[...t].map(e=>({name:e}))}function workflowJobFunctionResourceGroup(e){return{changeSet:{creates:workflowJobFunctionItems(e.workflow.changeSet.creates),updates:workflowJobFunctionItems(e.workflow.changeSet.updates),replaces:workflowJobFunctionItems(e.workflow.changeSet.replaces),unchanged:[...e.workflow.unchangedWorkflowJobNames].map(e=>({name:e})),deletes:e.workflow.jobFunctionDeletes},resourceType:`workflow_job_function`,getName:e=>`jobFunctionName`in e?e.jobFunctionName:e.name}}const $=[`namespaceName`,`authNamespace`,`vaultName`,`staticWebsiteName`],Mo=[{resourceLabel:`Application`,resourceType:`application`,namesOf:e=>[e.application.name],changeSetOf:e=>e.app},{resourceLabel:`Executor`,resourceType:`executor`,namesOf:e=>Object.values(e.application.executorService?.executors??{}).map(e=>e.name),changeSetOf:e=>e.executor.changeSet},{resourceLabel:`Workflow job`,resourceType:`workflow_job_function`,namesOf:e=>e.bundledScripts.workflowJobs.keys(),changeSetOf:e=>workflowJobFunctionResourceGroup(e).changeSet,getName:e=>`jobFunctionName`in e?e.jobFunctionName:e.name},{resourceLabel:`Workflow`,resourceType:`workflow`,namesOf:e=>Object.values(e.application.workflowService?.workflows??{}).map(e=>e.name),changeSetOf:e=>e.workflow.changeSet},{resourceLabel:`Workflow execution policy`,resourceType:`workflow_job_function_execution_policy`,namesOf:e=>Object.values(e.config.workflow?.executionPolicies??{}).map(e=>e.name),changeSetOf:e=>e.workflowExecutionPolicy.changeSet},{resourceLabel:`Auth connection`,resourceType:`auth.connection`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`,namesOf:e=>Object.keys(e.application.authService?.connections??{}),changeSetOf:e=>e.auth.changeSet.connection},{resourceLabel:`StaticWebsite`,resourceType:`staticwebsite`,namesOf:e=>e.application.staticWebsiteServices.map(e=>e.name),changeSetOf:e=>e.staticWebsite.changeSet},{resourceLabel:`TailorDB namespace`,resourceType:`tailordb.service`,namesOf:e=>e.application.tailorDBServices.map(e=>e.namespace),changeSetOf:e=>e.tailorDB.changeSet.service},{resourceLabel:`Auth namespace`,resourceType:`auth.service`,namesOf:e=>{let t=e.application.authService?.config.name;return t===void 0?[]:[t]},changeSetOf:e=>e.auth.changeSet.service},{resourceLabel:`IdP namespace`,resourceType:`idp.service`,namesOf:e=>e.application.idpServices.map(e=>e.name),changeSetOf:e=>e.idp.changeSet.service},{resourceLabel:`Resolver namespace`,resourceType:`pipeline.service`,namesOf:e=>e.application.resolverServices.map(e=>e.namespace),changeSetOf:e=>e.pipeline.changeSet.service},{resourceLabel:`AIGateway`,resourceType:`aigateway`,namesOf:e=>e.application.aiGatewayServices.map(e=>e.name),changeSetOf:e=>e.aiGateway.changeSet},{resourceLabel:`Secret Manager vault`,resourceType:`secret.vault`,namesOf:e=>e.application.secrets.map(e=>e.vaultName),changeSetOf:e=>e.secretManager.vaultChangeSet}];function managedResourceGroupFromDefinition(e,t){let{changeSetOf:n,namesOf:r,resourceLabel:i,...a}=e;return{...a,changeSet:n(t)}}function managedResourceGroups(e){return[{changeSet:e.functionRegistry.changeSet,resourceType:`function_registry`},...Mo.map(t=>managedResourceGroupFromDefinition(t,e)),{changeSet:e.tailorDB.changeSet.type,resourceType:`tailordb.type`,namespaceFields:$,namespaceOwnerResourceType:`tailordb.service`},{changeSet:e.tailorDB.changeSet.gqlPermission,resourceType:`tailordb.gql_permission`,namespaceFields:$,namespaceOwnerResourceType:`tailordb.service`},{changeSet:e.staticWebsite.customDomainChangeSet,resourceType:`staticwebsite.custom_domain`,namespaceFields:$,namespaceOwnerResourceType:`staticwebsite`},{changeSet:e.idp.changeSet.client,resourceType:`idp.client`,namespaceFields:$,namespaceOwnerResourceType:`idp.service`},{changeSet:e.auth.changeSet.idpConfig,resourceType:`auth.idp_config`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.userProfileConfig,resourceType:`auth.user_profile_config`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.tenantConfig,resourceType:`auth.tenant_config`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.machineUser,resourceType:`auth.machine_user`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.oauth2Client,resourceType:`auth.oauth2_client`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.authHook,resourceType:`auth.hook`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.scim,resourceType:`auth.scim`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.auth.changeSet.scimResource,resourceType:`auth.scim_resource`,namespaceFields:$,namespaceOwnerResourceType:`auth.service`},{changeSet:e.pipeline.changeSet.resolver,resourceType:`pipeline.resolver`,namespaceFields:$,namespaceOwnerResourceType:`pipeline.service`},{changeSet:e.secretManager.secretChangeSet,resourceType:`secret.secret`,namespaceFields:$,namespaceOwnerResourceType:`secret.vault`}]}function dropCrossDeploymentManagedDeletes(e){let t=e.map(e=>managedResourceGroups(deploymentPlanResults(e))),n=t.map(e=>e.reduce((e,t)=>{for(let n of[...t.changeSet.creates,...t.changeSet.updates,...t.changeSet.replaces,...t.changeSet.unchanged])addManagedResourceClaims(e,t,n);return e},new Set));t.forEach((e,t)=>{let r=new Set;n.forEach((e,n)=>{if(n!==t)for(let t of e)r.add(t)});for(let t of e)retainDeletesNotClaimed(t,r)})}function collectDeploymentResourceOwners(e){let t=new Set;for(let n of e)for(let e of collectResourceOwners(deploymentPlanResults(n)))t.add(e);return t}function ownershipFilters(e){let t=new Map;for(let n of e)if(t.set(`${yi}\0${n.name}`,{[yi]:n.name}),n.id){let e=sdkAppIdLabelValue(n.id);t.set(`${xi}\0${e}`,{[xi]:e})}return[...t.values()]}async function createMetadataLookupClient(e){let{client:t,workspaceId:n,applications:r}=e,i=await Promise.all(ownershipFilters(r).map(e=>P(async(r,i)=>{let{results:a,nextPageToken:o}=await t.listMetadata({workspaceId:n,labels:e,pageToken:r,pageSize:i});return[a,o]}))),a=new Map;for(let e of i.flat())e.metadata&&a.set(e.trn,e.metadata);let o=new Map,getMetadata=(e,n)=>{let r=a.get(e.trn??``);if(r)return Promise.resolve(U(ne,{metadata:r}));let i=e.trn??``,s=o.get(i);return s||(s=t.getMetadata(e,n),o.set(i,s)),s};return new Proxy(t,{get(e,t,n){return t===`getMetadata`?getMetadata:Reflect.get(e,t,n)}})}function buildPlanReport(e){let t=formatExecutorChangeEntries(e.executor.changeSet,buildPlannedExecutorsByName(e.executor.changeSet),e.functionRegistry.executorFunctionChanges),n=formatResolverChangeEntries(e.pipeline.changeSet.resolver,e.functionRegistry.resolverFunctionChanges),r=formatWorkflowChangeEntries(e.workflow.changeSet,e.functionRegistry.workflowJobChanges),i=formatChangeSetEntries(e.workflowExecutionPolicy.changeSet,[`executionPolicy`]),a=formatAuthHookChangeEntries(e.auth.changeSet.authHook,e.functionRegistry.authHookFunctionChanges),o=formatTailorDBResourceChangeEntries(e.tailorDB.changeSet.type,e.tailorDB.changeSet.gqlPermission),s=e.tailorDB.context.checkpointRepairs.map(e=>({action:`update`,symbol:Ai.update,name:`migration checkpoint ${formatMigrationNumber(e.from)} → ${formatMigrationNumber(e.to)}`,labels:[`migrationCheckpoint`],namespace:e.namespace})),c=[...o,...s],l=[...n],namespaceOf=e=>{if(`request`in e&&e.request&&typeof e.request==`object`&&`namespaceName`in e.request)return e.request.namespaceName;if(`namespaceName`in e)return e.namespaceName},authNamespaceOf=e=>`request`in e&&e.request&&typeof e.request==`object`&&`authNamespace`in e.request?e.request.authNamespace:void 0,u=[...formatChangeSetEntries(e.idp.changeSet.client,[`client`],namespaceOf)],d=[...formatChangeSetEntries(e.auth.changeSet.idpConfig,[`idpConfig`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.userProfileConfig,[`userProfileConfig`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.tenantConfig,[`tenantConfig`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.machineUser,[`machineUser`],authNamespaceOf),...a,...formatChangeSetEntries(e.auth.changeSet.oauth2Client,[`oauth2Client`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.scim,[`scimConfig`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.scimResource,[`scimResource`],namespaceOf),...formatChangeSetEntries(e.auth.changeSet.connection,[`connection`],namespaceOf)],{otherChanges:f}=splitFunctionRegistryChanges(e.functionRegistry.changeSet),p=extractServiceActions(e.tailorDB.changeSet.service),m=extractServiceActions(e.pipeline.changeSet.service),h=extractServiceActions(e.idp.changeSet.service),g=extractServiceActions(e.auth.changeSet.service),_=[...c,...l,...t,...r,...i,...u,...d],v=summarizePlanResults(e,_,[...p,...m,...h,...g]),y=[...e.functionRegistry.unmanaged,...e.tailorDB.unmanaged,...e.staticWebsite.unmanaged,...e.aiGateway.unmanaged,...e.idp.unmanaged,...e.auth.unmanaged,...e.pipeline.unmanaged,...e.executor.unmanaged,...e.workflow.unmanaged,...e.secretManager.unmanaged],b=[...e.functionRegistry.conflicts,...e.tailorDB.conflicts,...e.staticWebsite.conflicts,...e.aiGateway.conflicts,...e.idp.conflicts,...e.auth.conflicts,...e.pipeline.conflicts,...e.executor.conflicts,...e.workflow.conflicts,...e.secretManager.conflicts],x=[..._,...p.map(({action:e,name:t})=>({action:e,name:t,labels:[`tailorDB`],namespace:void 0})),...m.map(({action:e,name:t})=>({action:e,name:t,labels:[`pipeline`],namespace:void 0})),...h.map(({action:e,name:t})=>({action:e,name:t,labels:[`idp`],namespace:void 0})),...g.map(({action:e,name:t})=>({action:e,name:t,labels:[`auth`],namespace:void 0})),...formatChangeSetEntries(f),...formatChangeSetEntries(e.staticWebsite.changeSet,[`staticWebsite`]),...formatChangeSetEntries(e.staticWebsite.customDomainChangeSet,[`customDomain`]),...formatChangeSetEntries(e.aiGateway.changeSet,[`aiGateway`]),...formatChangeSetEntries(e.app,[`application`]),...formatChangeSetEntries(e.secretManager.vaultChangeSet,[`vault`]),...formatChangeSetEntries(e.secretManager.secretChangeSet,[`secret`])].map(({action:e,name:t,labels:n,namespace:r})=>({action:e,name:t,labels:n,namespace:r})),S=[...y.map(({resourceType:e,resourceName:t})=>({type:`unmanaged`,resourceType:e,name:t})),...e.secretManager.skippedSecrets.map(e=>({type:`skippedSecret`,resourceType:`secret`,name:e}))],C=b.map(({resourceType:e,resourceName:t,currentOwner:n})=>({resourceType:e,name:t,currentOwner:n})),w=[...buildGroupedDisplayLines(e.functionRegistry.changeSet.title,formatChangeSetEntries(f)),...e.staticWebsite.changeSet.lines(),...e.staticWebsite.customDomainChangeSet.lines(),...e.aiGateway.changeSet.lines(),...e.app.lines(),...buildGroupedDisplayLines(`TailorDB`,c,p),...buildGroupedDisplayLines(`Resolver`,l,m),...buildGroupedDisplayLines(`Executor`,t),...buildGroupedDisplayLines(`Workflow`,r),...buildGroupedDisplayLines(`IdP`,u,h),...buildGroupedDisplayLines(`Auth`,d,g),...e.secretManager.vaultChangeSet.lines(),...e.secretManager.secretChangeSet.lines()];if(y.length>0){w.push(N.bold(`Unmanaged resources (not in config):`));for(let{resourceType:e,resourceName:t}of y)w.push(` ${N.warning(`⚠`)} ${N.bold(e)} "${t}"`)}if(e.secretManager.skippedSecrets.length>0){w.push(N.bold(`Secret Manager secrets (skipped - no value provided):`));for(let t of e.secretManager.skippedSecrets)w.push(` ${N.dim(`○`)} ${t}`)}if(b.length>0){w.push(N.bold(`Owner conflicts (will require confirmation on apply):`));for(let{resourceType:e,resourceName:t,currentOwner:n}of b)w.push(` ${N.warning(`!`)} ${N.bold(e)} "${t}" — owned by "${n}"`)}return w.push(formatPlanSummary(v)),{summary:v,json:{summary:v,changes:x,warnings:S,conflicts:C},lines:w}}function printPlanResults(e,t){let n=buildPlanReport(e);if(M.jsonMode&&t?.dryRun)return M.out(n.json),n.summary;let r=n.lines.join(`
|
|
130
|
-
`);return t?.dryRun?M.out(r):M.log(r),n.summary}function summarizePlanResults(e,t,n){let r={create:0,update:0,delete:0,replace:0};for(let e of t)r[e.action]+=1;for(let e of n)r[e.action]+=1;let{otherChanges:i}=splitFunctionRegistryChanges(e.functionRegistry.changeSet),a=summarizeChangeSets([i,e.staticWebsite.changeSet,e.staticWebsite.customDomainChangeSet,e.aiGateway.changeSet,e.app,e.secretManager.vaultChangeSet,e.secretManager.secretChangeSet]);return r.create+=a.create,r.update+=a.update,r.delete+=a.delete,r.replace+=a.replace,r}function sumPlanSummaries(e){return e.reduce((e,t)=>({create:e.create+t.create,update:e.update+t.update,delete:e.delete+t.delete,replace:e.replace+t.replace}),{create:0,update:0,delete:0,replace:0})}function printDeploymentPlans(e,t){if(M.jsonMode&&t?.dryRun){let t=e.map(e=>buildPlanReport(deploymentPlanResults(e))),n=sumPlanSummaries(t.map(e=>e.summary));return M.out({summary:n,changes:t.flatMap(e=>e.json.changes),warnings:t.flatMap(e=>e.json.warnings),conflicts:t.flatMap(e=>e.json.conflicts)}),n}return sumPlanSummaries(e.map(e=>printPlanResults(deploymentPlanResults(e),t)))}const No=new Map;function validatorFor(e){let t=No.get(e.typeName);if(t)return t;let n=yr({registry:Rn(e,...vr(e))});return No.set(e.typeName,n),n}function validateItems(e){let{schema:t,kind:n,action:r,items:i,requestKey:a,violations:o}=e;if(i.length===0)return;let s=validatorFor(t);for(let e of i){let i=e[a],c=U(t,i),l=s.validate(t,c);if(l.kind===`invalid`)for(let t of l.violations)o.push({kind:n,name:e.name,action:r,fieldPath:t.field.length>0?_r(t.field):`(message)`,message:t.message});else l.kind===`error`&&M.warn(`Could not validate ${n} "${e.name}" (${r}): ${l.error.message}`)}}async function validatePlan(e){let{tailorDB:t,staticWebsite:n,aiGateway:r,idp:o,auth:c,pipeline:l,app:u,executor:f,workflow:p,workflowExecutionPolicy:m,secretManager:h}=e,g=[];function creates(e,t,n){validateItems({schema:e,kind:t,action:`create`,items:n,requestKey:`request`,violations:g})}function updates(e,t,n){validateItems({schema:e,kind:t,action:`update`,items:n,requestKey:`request`,violations:g})}function replaces(e,t,n){validateItems({schema:e,kind:t,action:`replace`,items:n,requestKey:`createRequest`,violations:g})}function inPlaceReplaces(e,t,n){validateItems({schema:e,kind:t,action:`replace`,items:n,requestKey:`updateRequest`,violations:g})}creates(Se,`TailorDB service`,t.changeSet.service.creates),creates(Te,`TailorDB table`,t.changeSet.type.creates),updates(He,`TailorDB table`,t.changeSet.type.updates),creates(a,`StaticWebsite`,n.changeSet.creates),updates(nt,`StaticWebsite`,n.changeSet.updates),creates(ie,`StaticWebsite custom domain`,n.customDomainChangeSet.creates),creates(me,`AIGateway`,r.changeSet.creates.map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),updates(fe,`AIGateway`,r.changeSet.updates.map(e=>({name:e.name,request:{...e.request,cors:void 0}})));let substituteIdpReturnOrigins=e=>{let t=e.request,n=t.userAuthPolicy?.allowedReturnOrigins;if(!Array.isArray(n)||n.length===0)return e;let r=n.map(e=>typeof e==`string`&&/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url$/.test(e)?`https://placeholder.invalid`:e);return{...e,request:{...t,userAuthPolicy:{...t.userAuthPolicy,allowedReturnOrigins:r}}}};creates(i,`IdP service`,o.changeSet.service.creates.map(substituteIdpReturnOrigins)),updates(ce,`IdP service`,o.changeSet.service.updates.map(substituteIdpReturnOrigins));let _=[...o.changeSet.client.creates.map(e=>({clientName:e.request.client?.name??``,namespaceName:e.request.namespaceName??``,workspaceId:e.request.workspaceId??``})),...o.changeSet.client.updates.map(e=>({clientName:e.name,namespaceName:e.namespaceName,workspaceId:e.workspaceId}))];creates(S,`IdP client secret`,_.map(e=>({name:e.clientName,request:{workspaceId:e.workspaceId,secretmanagerVaultName:idpClientVaultName(e.namespaceName,e.clientName)}}))),creates(s,`IdP client secret`,_.map(e=>({name:e.clientName,request:{workspaceId:e.workspaceId,secretmanagerVaultName:idpClientVaultName(e.namespaceName,e.clientName),secretmanagerSecretName:idpClientSecretName(e.namespaceName,e.clientName)}}))),creates(Ie,`Auth service`,c.changeSet.service.creates),updates(ot,`Auth service`,c.changeSet.service.updates),creates(je,`Auth IDP config`,c.changeSet.idpConfig.creates),updates(Le,`Auth IDP config`,c.changeSet.idpConfig.updates),creates(Ce,`Auth user profile config`,c.changeSet.userProfileConfig.creates),updates(at,`Auth user profile config`,c.changeSet.userProfileConfig.updates),creates($e,`Auth tenant config`,c.changeSet.tenantConfig.creates),updates(be,`Auth tenant config`,c.changeSet.tenantConfig.updates),creates(ve,`Auth machine user`,c.changeSet.machineUser.creates),updates(ke,`Auth machine user`,c.changeSet.machineUser.updates),creates(qe,`Auth hook`,c.changeSet.authHook.creates),updates(Ue,`Auth hook`,c.changeSet.authHook.updates),creates(Ye,`Auth SCIM config`,c.changeSet.scim.creates),updates(ge,`Auth SCIM config`,c.changeSet.scim.updates),creates(xe,`Auth SCIM resource`,c.changeSet.scimResource.creates),updates(tt,`Auth SCIM resource`,c.changeSet.scimResource.updates),creates(Ve,`OAuth2 client`,c.changeSet.oauth2Client.creates),updates(Oe,`OAuth2 client`,c.changeSet.oauth2Client.updates),replaces(Ve,`OAuth2 client`,c.changeSet.oauth2Client.replaces),creates(v,`Pipeline service`,l.changeSet.service.creates),updates(w,`Pipeline service`,l.changeSet.service.updates),creates(Me,`Resolver`,l.changeSet.resolver.creates),updates(b,`Resolver`,l.changeSet.resolver.updates),creates(pe,`Executor`,f.changeSet.creates),updates(de,`Executor`,f.changeSet.updates),creates(_e,`Workflow`,p.changeSet.creates.map(e=>({name:e.name,request:buildWorkflowValidationShape(e.workspaceId,e.workflow)}))),updates(Je,`Workflow`,p.changeSet.updates.map(e=>({name:e.name,request:buildWorkflowValidationShape(e.workspaceId,e.workflow)})));let y=p.changeSet.creates[0]?.workspaceId??p.changeSet.updates[0]?.workspaceId??``;if(y){let e=new Set;for(let t of[...p.changeSet.creates,...p.changeSet.updates])for(let n of t.usedJobNames)e.add(n);for(let t of p.unchangedWorkflowJobNames)e.add(t);creates(Ae,`Workflow job function`,[...e].map(e=>({name:e,request:{workspaceId:y,jobFunctionName:e,scriptRef:e}})))}if(creates(Ge,`Workflow execution policy`,[...m.changeSet.creates,...m.changeSet.replaces].map(e=>({name:e.name,request:{workspaceId:e.workspaceId,executionPolicyName:e.policy.name,executionPolicyKey:toPlatformExecutionPolicyKey(e.policy),...e.policy.concurrencyPolicy&&{concurrencyPolicy:{maxConcurrentExecutions:e.policy.concurrencyPolicy.maxConcurrentExecutions}}}}))),updates(Be,`Workflow execution policy`,m.changeSet.updates.map(e=>({name:e.name,request:{workspaceId:e.workspaceId,executionPolicyName:e.policy.name,...e.policy.concurrencyPolicy&&{concurrencyPolicy:{maxConcurrentExecutions:e.policy.concurrencyPolicy.maxConcurrentExecutions}}}}))),creates(S,`Secret Manager vault`,h.vaultChangeSet.creates.map(e=>({name:e.name,request:vaultCreateRequest(e)}))),creates(s,`Secret Manager secret`,h.secretChangeSet.creates.map(e=>({name:e.name,request:secretCreateRequest(e)}))),updates(Pe,`Secret Manager secret`,h.secretChangeSet.updates.map(e=>({name:e.name,request:secretUpdateRequest(e)}))),creates(se,`Application`,u.creates.map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),updates(d,`Application`,[...u.updates,...u.unchanged].map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),creates(ze,`Auth connection`,c.changeSet.connection.creates),inPlaceReplaces(Ee,`Auth connection`,c.changeSet.connection.replaces),g.length===0)return;let x=new Set(g.map(e=>`${e.kind}:${e.name}`));M.error(`Pre-flight validation found ${g.length} violation(s) across ${x.size} resource(s):`);for(let e of g)M.log(` ${N.resourceType(e.kind)} ${N.resourceName(e.name)} (${e.action}) — ${N.bold(e.fieldPath)}: ${e.message}`);throw Error(`${g.length} validation error(s) found in ${x.size} resource(s)`)}const Po=H.string().min(1,`Profile must not be empty`),Fo=H.string().min(3,`Name must be at least 3 characters`).max(63,`Name must be at most 63 characters`).regex(/^[a-z0-9-]+$/,`Name can only contain lowercase letters, numbers, and hyphens`).refine(e=>!e.startsWith(`-`)&&!e.endsWith(`-`),`Name cannot start or end with a hyphen`);function validateWorkspaceName(e){let t=Fo.safeParse(e);return t.success?!0:A(t.error.issues[0],`Zod returned no issues`).message}function formatTimestamp(e){if(!e)return null;let t=G(e);return Number.isNaN(t.getTime())?null:t}function formatTable(e,t){return lt(e,t)}function formatKeyValueTable(e){return formatTable(e,{singleLine:!0})}function humanizeRelativeTime(e){if(e===null)return`N/A`;let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.getTime())?typeof e==`string`?e:`N/A`:Xn(t,{addSuffix:!0})}const workspaceInfo=(e,t)=>{let n={id:e.id,name:e.name,region:e.region,...e.organizationId?{organizationId:e.organizationId}:{},...e.folderId?{folderId:e.folderId}:{},createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)};return t?{...n,folderName:t}:n},workspaceDetails=(e,t)=>({...workspaceInfo(e,t),deleteProtection:e.deleteProtection,organizationId:e.organizationId,folderId:e.folderId});async function resolveWorkspaceFolderName(e,t){if(!(!t.organizationId||!t.folderId))try{return(await e.getOrganizationFolder({organizationId:t.organizationId,folderId:t.folderId})).folder?.name||void 0}catch(e){if(e instanceof q&&(e.code===K.NotFound||e.code===K.PermissionDenied))return;M.warn(`Failed to resolve workspace folder name: ${e}`);return}}function createWorkspaceFolderNameResolver(e){let t=new Map;return n=>{if(!n.organizationId||!n.folderId)return Promise.resolve(void 0);let r=`${n.organizationId}/${n.folderId}`,i=t.get(r);if(i)return i;let a=resolveWorkspaceFolderName(e,n);return t.set(r,a),a}}async function workspaceInfoWithFolderName(e,t){let n=await resolveWorkspaceFolderName(e,t);return workspaceInfo(t,n)}async function workspaceDetailsWithFolderName(e,t){let n=await resolveWorkspaceFolderName(e,t);return workspaceDetails(t,n)}async function workspaceInfosWithFolderNames(e,t){let n=createWorkspaceFolderNameResolver(e),r=rr(5);return Promise.all(t.map(e=>r(async()=>workspaceInfo(e,await n(e)))))}function workspaceDisplayName(e){return e.folderName?`${e.folderName}/${e.name}`:e.name}function createWorkspaceNameTransformer(e,t){return(n,r)=>{let i=r,a=i[e],o=i[t];return typeof a==`string`&&typeof o==`string`?workspaceDisplayName({name:a,folderName:o}):String(n??``)}}const Io=createWorkspaceNameTransformer(`name`,`folderName`),Lo=H.object({name:Fo,region:H.string(),deleteProtection:H.boolean().optional(),organizationId:H.uuid().optional(),folderId:H.uuid().optional(),profile:Po.optional()}),validateRegion=async(e,t)=>{let n=await t.listAvailableWorkspaceRegions({});if(!n.regions.includes(e))throw Error(`Region must be one of: ${n.regions.join(`, `)}.`)};function profilePlatformSettings(e){let t=e?.oauth2ClientId||process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID,n=e?.consoleUrl??process.env.TAILOR_PLATFORM_CONSOLE_URL;return{...ft(e)?{}:{platform_url:Mt(e)},...t?{oauth2_client_id:yt(e)}:{},...n?{console_url:$t(n)}:{}}}async function createWorkspace$1(e){let t=validateCreateWorkspaceOptions(e),n=await loadAccessToken({profile:t.profile}),r=await loadPlatformClientConfig({profile:t.profile}),i=await F(n,r);return await validateRegion(t.region,i),createValidatedWorkspaceWithClient(i,t)}async function createValidatedWorkspaceWithClient(e,t){let n=await e.createWorkspace({workspaceName:t.name,workspaceRegion:t.region,deleteProtection:t.deleteProtection??!1,organizationId:t.organizationId,folderId:t.folderId});return workspaceInfoWithFolderName(e,A(n.workspace,`createWorkspace response missing workspace`))}function validateCreateWorkspaceOptions(e){let t=Lo.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);return t.data}const Ro=X({name:`create`,description:`Create a new Tailor Platform workspace.`,args:H.strictObject({name:V(H.string(),{alias:`n`,description:`Workspace name`}),region:V(H.string(),{alias:`r`,description:`Workspace region (us-west, asia-northeast)`}),"delete-protection":V(H.boolean().default(!1),{alias:`d`,description:`Enable delete protection`}),"organization-id":V(H.string().optional(),{alias:`o`,description:`Organization ID to workspace associate with`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`}),"folder-id":V(H.string().optional(),{alias:`f`,description:`Folder ID to workspace associate with`,env:`TAILOR_PLATFORM_FOLDER_ID`}),"profile-name":V(H.string().optional(),{alias:`p`,description:`Profile name to create`}),profile:V(Po.optional(),{description:`Workspace profile used for authentication and Platform selection`,env:`TAILOR_PLATFORM_PROFILE`}),"profile-user":V(H.string().optional(),{description:`User email address or machine user client ID for the profile (defaults to current user)`}),permission:V(H.enum([`write`,`read`]).default(`write`),{description:`Profile permission (requires --profile-name). 'read' blocks all write commands while the profile is active.`})}),run:async e=>{await assertWritable({profile:e.profile});let t=e[`profile-name`],n;if(t){let r=await readPlatformConfig();if(r.profiles[t])throw Error(`Profile "${t}" already exists.`);let i=e.profile,a=i?r.profiles[i]:void 0,o=a?platformConfigFromProfile(a):void 0,s=e[`profile-user`]||a?.user||r.current_user;if(!s)throw Error(`Current user not found. Please login or specify --profile-user to create a profile.`);let c=resolveConfigUser(r,s,o);if(!c)throw Error(`User "${s}" not found.\nPlease verify your user name and login using 'tailor login' command.`);n={name:t,user:c,platformSettings:profilePlatformSettings(o)}}let r=await createWorkspace$1({name:e.name,region:e.region,deleteProtection:e[`delete-protection`],organizationId:e[`organization-id`],folderId:e[`folder-id`],profile:e.profile}),i;if(n){let t=await readPlatformConfig(),a=n.platformSettings;t.profiles[n.name]={user:n.user,workspace_id:r.id,...e.permission===`read`?{readonly:!0}:{},...a},writePlatformConfig(t),i={name:n.name,user:n.user,workspaceId:r.id,permission:e.permission,...a.platform_url?{platformUrl:a.platform_url}:{},...a.oauth2_client_id?{oauth2ClientId:a.oauth2_client_id}:{},...a.console_url?{consoleUrl:a.console_url}:{}},e.json||M.success(`Profile "${n.name}" created successfully.`)}if(e.json||M.success(`Workspace "${workspaceDisplayName(r)}" created successfully.`),e.json&&i){M.out({...r,profile:i});return}M.out(r,{display:{name:Io,folderName:null}}),i&&(M.out(`Profile:`),M.out(i))}});async function listWorkspaces(e){let t=Po.optional().parse(e?.profile),n=await loadAccessToken({profile:t}),r=await loadPlatformClientConfig({profile:t});return listWorkspacesWithClient(await F(n,r),e)}async function listWorkspacesWithClient(e,t){let n=toPageDirection(t?.order);return workspaceInfosWithFolderNames(e,await jt(async(t,r)=>{let{workspaces:i,nextPageToken:a}=await e.listWorkspaces({pageToken:t,pageSize:r,pageDirection:n});return[i,a]},{limit:t?.limit}))}const zo=X({name:`list`,description:`List all Tailor Platform workspaces.`,args:H.strictObject({...paginationArgs(),profile:V(Po.optional(),{description:`Workspace profile used for authentication and Platform selection`,env:`TAILOR_PLATFORM_PROFILE`})}),run:async e=>{let t=await listWorkspaces({order:e.order,limit:e.limit,profile:e.profile});M.out(t,{display:{name:Io,folderName:null,organizationId:null,folderId:null,updatedAt:null}})}}),Bo=H.object({version:H.literal(1),platformUrl:H.url(),applicationId:H.string().min(1).optional(),workspaceId:H.uuid()});function defaultConfigPath(){return Nn(process.cwd(),`tailor.config.ts`)}function contextPath(e){return Mn(jn(e),Gt(),`${An(e)}.context.json`)}async function loadWorkspaceContext(e,t=defaultConfigPath(),n){let r;try{r=await xr(contextPath(t),`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let i;try{i=JSON.parse(r)}catch{return}let a=Bo.safeParse(i);if(!(!a.success||a.data.platformUrl!==e||n!==void 0&&a.data.applicationId!==n))return a.data}async function saveWorkspaceContext(e,t=defaultConfigPath(),n){let r=Bo.parse({...e,...n===void 0?{}:{applicationId:n}}),i=Mn(jn(t),Gt()),a=contextPath(t),o=`${JSON.stringify(r,null,2)}\n`;try{if(await xr(a,`utf8`)===o)return}catch{}let s=`${a}.${process.pid}.${or()}.tmp`;await br(i,{recursive:!0});try{await wr(s,o,{mode:384}),await Sr(s,a)}catch(e){throw await Cr(s,{force:!0}).catch(()=>void 0),e}}function suggestedWorkspaceName(){let e=An(process.cwd()).toLowerCase().replaceAll(/[^a-z0-9-]+/g,`-`).replaceAll(/^-+|-+$/g,``).slice(0,63).replace(/-+$/,``);return validateWorkspaceName(e)===!0?e:`my-workspace`}function executableAction(e){return{command:`tailor`,args:e}}function deployArgs(e){return e.deployArgs??[`deploy`]}function workspaceCommandArgs(e){return e.workspaceCommandArgs??[]}function createDeployArgs(e,t,n){return[...deployArgs(e),`--create-workspace`,`--workspace-name`,t,`--workspace-region`,n,...e.organizationId?[`--organization-id`,e.organizationId]:[],...e.folderId?[`--folder-id`,e.folderId]:[]]}function selectDeployArgs(e){return[...deployArgs(e),`--workspace-id`,`<workspace-id>`]}function workspaceLabel(e){let t=e.organizationId??`personal`;return`${workspaceDisplayName(e)} (${e.region}, org: ${t}, id: ${e.id})`}function workspaceMatchesRequestedIdentity(e,t){return t.workspaceName===e.name&&t.workspaceRegion===e.region&&t.organizationId===e.organizationId&&t.folderId===e.folderId}function workspaceIdentity(e){let{id:t,name:n,region:r,organizationId:i,folderId:a}=e;return{id:t,name:n,region:r,organizationId:i,folderId:a}}function projectContextTargets(e){if(e)return[...new Map(e.map(e=>[e.configPath,e])).values()]}async function loadProjectContexts(e,t){let n=projectContextTargets(t);if(!n||n.length===0){let t=await loadWorkspaceContext(e);return t?[t]:[]}return(await Promise.all(n.map(({configPath:t,applicationId:n})=>loadWorkspaceContext(e,t,n)))).filter(e=>e!==void 0)}async function persistWorkspaceContext(e,t){let n=projectContextTargets(t);if(!n||n.length===0){await saveWorkspaceContext(e);return}let r=(await Promise.allSettled(n.map(({configPath:t,applicationId:n})=>saveWorkspaceContext(e,t,n)))).filter(e=>e.status===`rejected`);if(r.length>0)throw Error(r.map(({reason:e})=>e instanceof Error?e.message:String(e)).join(`; `))}async function rememberWorkspaceContext(e,t,n=`error-on-partial`){if(!t.dryRun)try{await persistWorkspaceContext(e,t.contextTargets)}catch(r){if((projectContextTargets(t.contextTargets)?.length??0)>1&&n===`error-on-partial`)throw R({code:`WORKSPACE_CONTEXT_SAVE_FAILED`,message:`The workspace selection could not be saved for every configuration file.`,details:r instanceof Error?r.message:String(r),suggestion:`Fix project state permissions, then rerun deploy with the workspace ID.`,next:executableAction([...deployArgs(t),`--workspace-id`,e.workspaceId]),context:{workspaceId:e.workspaceId,configPaths:t.contextTargets?.map(({configPath:e})=>e)}});M.warn(`Could not save the project workspace selection (${r instanceof Error?r.message:String(r)}). Continue with --workspace-id ${e.workspaceId} on later runs.`)}}async function useWorkspace(e,t,n,r,i=`error-on-partial`){return await rememberWorkspaceContext({version:1,platformUrl:t,workspaceId:n.id},r,i),M.info(`Using workspace: ${workspaceLabel(n)}`),{client:e,workspaceId:n.id}}function useRememberedWorkspace(e,t){return M.warn(`Using saved workspace selection: ${workspaceLabel(t)}`),{client:e,workspaceId:t.id}}const Vo=`create-new-workspace`;async function chooseWorkspace(e,t,n,r){let i=await Z.select({message:`Select a workspace`,choices:[...n.map(e=>({name:workspaceLabel(e),value:e.id})),{name:`Create new workspace`,value:Vo}]});if(i===Vo)return createWorkspaceForDeploy(e,t,r);let a=n.find(({id:e})=>e===i);if(!a)throw Error(`Selected workspace was not found`);return useWorkspace(e,t,a,r)}function invalidCreateOptionsError(e,t,n,r){return R({code:`WORKSPACE_CREATE_OPTIONS_INVALID`,message:`Workspace creation options are invalid.`,details:r,suggestion:`Correct the workspace creation options and rerun deploy.`,next:executableAction(createDeployArgs(e,t,n))})}async function createWorkspace(e,t,n,r,i){let a=n.workspaceName,o=n.workspaceRegion,s=canPrompt();if(s)a??=await Z.text({message:`Workspace name`,default:suggestedWorkspaceName(),validate:validateWorkspaceName}),o??=await Z.select({message:`Workspace region`,choices:r.map(e=>({name:e,value:e}))});else{let e=[...a===void 0?[`--workspace-name`]:[],...o===void 0?[`--workspace-region`]:[]];if(e.length>0)throw R({code:`WORKSPACE_CREATE_OPTIONS_REQUIRED`,message:`Workspace creation requires a name and region in non-interactive mode.`,suggestion:`Provide every workspace creation option and rerun deploy.`,next:executableAction(createDeployArgs(n,a??`<name>`,o??`<region>`)),context:{missingOptions:e}})}if(!a||!o)throw Error(`Workspace creation options were not resolved`);let c=i;if(!c){try{c=validateCreateWorkspaceOptions({name:a,region:o,organizationId:n.organizationId,folderId:n.folderId})}catch(e){throw invalidCreateOptionsError(n,a,o,e instanceof Error?e.message:String(e))}if(!r.includes(o))throw invalidCreateOptionsError(n,a,o,`Region must be one of: ${r.join(`, `)}.`)}if(s){let e=[n.organizationId?`organization: ${n.organizationId}`:void 0,n.folderId?`folder: ${n.folderId}`:void 0].filter(e=>e!==void 0);if(!await Z.confirm({message:`Create workspace "${a}" in ${o}${e.length>0?` (${e.join(`, `)})`:``}?`,default:!0}))throw R({code:`WORKSPACE_CREATION_CANCELLED`,message:`Workspace creation was cancelled.`})}let l;try{l=await createValidatedWorkspaceWithClient(e,c)}catch(e){throw e instanceof q&&![K.Canceled,K.Unknown,K.DeadlineExceeded,K.Aborted,K.Internal,K.Unavailable,K.DataLoss].includes(e.code)?e:R({code:`WORKSPACE_CREATION_FAILED`,message:`Workspace creation did not complete successfully.`,details:e instanceof Error?e.message:String(e),suggestion:`The outcome may be uncertain. List workspaces before retrying creation to avoid duplicates.`,next:executableAction([`workspace`,`list`,...workspaceCommandArgs(n),`--json`])})}return await rememberWorkspaceContext({version:1,platformUrl:t,workspaceId:l.id},n),M.success(`Created workspace: ${workspaceLabel(l)}`),M.info(`Reuse this workspace with: tailor deploy --workspace-id ${l.id}`),M.info(`Or set TAILOR_PLATFORM_WORKSPACE_ID=${l.id}.`),{client:e,workspaceId:l.id}}async function createWorkspaceForDeploy(e,t,n,r,i){let a=r??(await e.listAvailableWorkspaceRegions({})).regions;if(n.dryRun)throw R({code:`WORKSPACE_CREATION_DISABLED_IN_DRY_RUN`,message:`Dry-run cannot create the workspace required to build a deployment plan.`,suggestion:`Create a workspace explicitly, then rerun the same dry-run with its workspace ID.`,context:{availableRegions:a}});return createWorkspace(e,t,n,a,i)}async function resolveDeployWorkspace(e={}){let t=[e.workspaceName===void 0?void 0:`--workspace-name`,e.workspaceRegion===void 0?void 0:`--workspace-region`].filter(e=>e!==void 0);if(!e.createWorkspace&&t.length>0)throw R({code:`WORKSPACE_CREATE_FLAG_REQUIRED`,message:`Workspace creation options require --create-workspace.`,suggestion:`Add --create-workspace or remove the workspace creation options.`,next:executableAction(createDeployArgs(e,e.workspaceName??`<name>`,e.workspaceRegion??`<region>`)),context:{options:t}});if(e.createWorkspace&&e.workspaceName!==void 0){let t=validateWorkspaceName(e.workspaceName);if(t!==!0)throw invalidCreateOptionsError(e,e.workspaceName,e.workspaceRegion??`<region>`,t)}if(e.createWorkspace&&e.workspaceRegion===``)throw invalidCreateOptionsError(e,e.workspaceName??`<name>`,e.workspaceRegion,`Region must not be empty.`);let n=await tryLoadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),r=await loadAccessToken({profile:e.profile}),i=await loadPlatformClientConfig({profile:e.profile,allowMissingProfile:n!==void 0}),a=Mt(i),o=await F(r,i);if(n){let t;try{t=await o.getWorkspace({workspaceId:n})}catch(e){throw e instanceof q&&e.code===K.NotFound?R({code:`WORKSPACE_NOT_FOUND`,message:`Workspace "${n}" was not found.`}):e}if(!t.workspace)throw R({code:`WORKSPACE_NOT_FOUND`,message:`Workspace "${n}" was not found.`});return useWorkspace(o,a,workspaceInfo(t.workspace),e,`warn`)}let s;if(e.createWorkspace&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0)try{s=validateCreateWorkspaceOptions({name:e.workspaceName,region:e.workspaceRegion,organizationId:e.organizationId,folderId:e.folderId})}catch(t){throw invalidCreateOptionsError(e,e.workspaceName,e.workspaceRegion,t instanceof Error?t.message:String(t))}let[c,l]=await Promise.all([loadProjectContexts(a,e.contextTargets),listWorkspacesWithClient(o)]),u=canPrompt(),d=new Set(c.map(({workspaceId:e})=>e)),f=d.size===1?l.find(({id:e})=>d.has(e)):void 0;if(f&&(!e.createWorkspace||workspaceMatchesRequestedIdentity(f,e))){let t=projectContextTargets(e.contextTargets)?.length??1;return c.length===t?useRememberedWorkspace(o,f):useWorkspace(o,a,f,e)}let p=l.length===1?l[0]:void 0,m=p!==void 0&&s!==void 0&&workspaceMatchesRequestedIdentity(p,e),h;if(s&&!m&&(h=await o.listAvailableWorkspaceRegions({}),!h.regions.includes(s.region)))throw invalidCreateOptionsError(e,s.name,s.region,`Region must be one of: ${h.regions.join(`, `)}.`);if(l.length===0&&(u||e.createWorkspace||c.length===0)){let t=h?.regions??(await o.listAvailableWorkspaceRegions({})).regions;if(e.dryRun||u||e.createWorkspace)return createWorkspaceForDeploy(o,a,e,t,s);throw R({code:`WORKSPACE_NOT_FOUND`,message:`No workspaces are available for this account.`,suggestion:`Create one during deploy by providing the workspace name and one of the available regions.`,next:executableAction(createDeployArgs(e,`<name>`,`<region>`)),context:{availableRegions:t}})}if(d.size>1){let t=e.createWorkspace===!0&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0&&l.length===0;if(!u&&!t)throw R({code:`WORKSPACE_CONTEXT_CONFLICT`,message:`The deployed configuration files are linked to different workspaces.`,suggestion:`Choose one workspace explicitly for the combined deployment.`,next:executableAction(selectDeployArgs(e)),context:{savedWorkspaceIds:[...d]}});if(l.length>0&&!e.createWorkspace)return chooseWorkspace(o,a,l,e)}if(!f&&c.length>0){let t=e.createWorkspace===!0&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0&&l.length<=1;if(!u&&!t)throw R({code:`WORKSPACE_CONTEXT_STALE`,message:`The saved project workspace is no longer available.`,suggestion:`Choose an available workspace explicitly before deploying.`,next:executableAction(selectDeployArgs(e)),context:{savedWorkspaceIds:[...d],workspaces:l.map(workspaceIdentity)}});if(l.length>0&&u&&!e.createWorkspace)return chooseWorkspace(o,a,l,e)}if(l.length===1){let[t]=l;if(!t)throw Error(`Workspace discovery returned an invalid result`);if(e.createWorkspace&&!workspaceMatchesRequestedIdentity(t,e))throw R({code:`WORKSPACE_CREATE_CONFLICT`,message:`The existing workspace does not match the requested workspace.`,suggestion:`Use the existing workspace, or run the explicit workspace create command to create another one.`,next:executableAction([`workspace`,`create`,...workspaceCommandArgs(e),...e.workspaceCommandJson?[`--json`]:[],`--name`,e.workspaceName??`<name>`,`--region`,e.workspaceRegion??`<region>`,...e.organizationId?[`--organization-id`,e.organizationId]:[],...e.folderId?[`--folder-id`,e.folderId]:[]]),context:{existingWorkspace:workspaceIdentity(t)}});return u&&!e.createWorkspace?chooseWorkspace(o,a,l,e):useWorkspace(o,a,t,e)}if(l.length>1){if(!u)throw R({code:`WORKSPACE_SELECTION_REQUIRED`,message:`Multiple workspaces are available.`,suggestion:`Choose one explicitly for non-interactive deployment.`,next:executableAction(selectDeployArgs(e)),context:{workspaces:l.map(workspaceIdentity)}});return chooseWorkspace(o,a,l,e)}throw Error(`Workspace discovery returned an invalid result`)}function collectExpectedLocalStaticWebsiteNames(e){let t=new Set;for(let n of e)for(let e of n.application.staticWebsiteServices)t.add(e.name);return t}async function shouldForceApplyAll(e,t,n,r){let i=(await buildMetaRequest({trn:resourceTrn(t,`application`,n.name),appName:n.name,appId:n.id})).labels,a=new Set;n.subgraphs.length>0&&a.add(resourceTrn(t,`application`,n.name)),n.staticWebsiteServices.forEach(e=>{a.add(resourceTrn(t,`staticwebsite`,e.name))}),n.aiGatewayServices.forEach(e=>{a.add(resourceTrn(t,`aigateway`,e.name))}),n.resolverServices.forEach(e=>{a.add(resourceTrn(t,`pipeline`,e.namespace))}),n.idpServices.forEach(e=>{a.add(resourceTrn(t,`idp`,e.name))}),n.authService&&a.add(resourceTrn(t,`auth`,n.authService.config.name)),Object.values(n.executorService?.executors??{}).forEach(e=>{a.add(resourceTrn(t,`executor`,e.name))}),Object.values(n.workflowService?.workflows??{}).forEach(e=>{a.add(resourceTrn(t,`workflow`,e.name))}),n.tailorDBServices.forEach(e=>{a.add(resourceTrn(t,`tailordb`,e.namespace))}),n.secrets.forEach(e=>{a.add(resourceTrn(t,`vault`,e.vaultName))}),r.forEach(e=>{a.add(resourceTrn(t,`function_registry`,e.name))});let o=await Promise.allSettled([...a].map(t=>I(async()=>{let{metadata:n}=await e.getMetadata({trn:t});return n})));if(o.some(e=>e.status===`fulfilled`&&e.value?.labels[`sdk-name`]===n.name&&!hasMatchingSdkVersion(e.value.labels,i)))return!0;let s=o.find(e=>e.status===`rejected`);if(s)throw s.reason;return!1}function recoveryEnvironmentArgs(e,t){return[...t?.envFile?[`--env-file`,B.resolve(process.cwd(),t.envFile)]:[],...t?.envFileIfExists?[`--env-file-if-exists`,B.resolve(process.cwd(),t.envFileIfExists)]:[],...e?.profile?[`--profile`,e.profile]:[]]}function recoveryOutputArgs(e){return[...e?.verbose?[`--verbose`]:[],...e?.json||M.jsonMode?[`--json`]:[]]}function retryDeployArgs(e,t,n){return[`deploy`,`--config`,t.join(`,`),...recoveryEnvironmentArgs(e,n),...e?.dryRun?[`--dry-run`]:[],...e?.yes?[`--yes`]:[],...e?.noSchemaCheck?[`--no-schema-check`]:[],...e?.noValidate?[`--no-validate`]:[],...e?.noCache?[`--no-cache`]:[],...e?.cleanCache?[`--clean-cache`]:[],...recoveryOutputArgs(n)]}function workspaceRecoveryArgs(e,t){return[...recoveryEnvironmentArgs(e,t),...t?.verbose?[`--verbose`]:[]]}function collectPlannedExternalTailorDBServices(e,t){let n=new Set(e.application.externalTailorDBNamespaces);return n.size===0?[]:t.flatMap(e=>e.application.tailorDBServices.filter(e=>n.has(e.namespace)))}function collectExternalAuthIdpConfigNames(e){let t=new Map;for(let n of e){let e=n.application.authService;if(!e)continue;let{name:r}=e.config,i=e.config.idProvider?.name;if(t.has(r)&&t.get(r)!==i)throw Error(`Auth namespace "${r}" is defined by multiple config files with different IdP configs. Auth namespace names must be unique across all configs in a single deploy.`);t.set(r,i)}return t}function collectDeployRunPlanInputs(e,t){let n=collectEventSubscriptions(e);return assertRecordableDependencies(n,t),{eventSubscriptions:n,runAppIds:new Set(e.map(e=>e.application.id).filter(e=>e!==void 0)),expectedLocalStaticWebsiteNames:collectExpectedLocalStaticWebsiteNames(e),externalAuthIdpConfigNames:collectExternalAuthIdpConfigNames(e)}}async function planDeploymentTarget(e){let{target:t,targets:n,runInputs:r,client:i,workspaceId:a,noSchemaCheck:o,migrationTestBaselines:s,migrationTestSnapshots:c}=e,{config:l,application:u,workflowBuildResult:d,httpAdapterBuildResult:f,bundledScripts:p}=t,m=ownedSubscriptions(r.eventSubscriptions,t),h=u.tailorDBServices.map(e=>{let t=c?.get(e.namespace);return t?{...e,types:t.tables,typeSourceInfo:{}}:e});await z(`plan.validateTailorDBTypeNames`,()=>rn({client:i,workspaceId:a,tailorDBServices:h,externalTailorDBNamespaces:u.externalTailorDBNamespaces,plannedExternalTailorDBServices:collectPlannedExternalTailorDBServices(t,n)}));let g=u.workflowService,_=collectFunctionEntries(u,filterBundledWorkflowJobs(g?.jobs??[],d?.usedJobNames??[]),p),v=await z(`plan.detectSdkVersionChange`,()=>shouldForceApplyAll(i,a,u,_));return z(`plan`,async()=>{let e=n.map(e=>e.application),p=collectVisibleTailorDBTypeNamespaces(u,e),h=collectVisibleResolverNamespaces(u,e),y=collectVisibleIdpNames(u,e),b={client:i,workspaceId:a,application:u,forRemoval:!1,config:l,noSchemaCheck:o,migrationTestBaselines:s,migrationTestSnapshots:c,forceApplyAll:v,...r,idpUserTriggerTargets:subscribedIdps(m),executorUsedTailorDBTables:subscribedTailorDBTables(m),executorUsedResolvers:subscribedResolvers(m),dependentApps:collectDependentApps(m),tailorDBTypeNamespaces:p,resolverNamespaces:h,idpNames:y},x=await z(`plan.functionRegistry`,()=>planFunctionRegistry(i,a,u.name,u.id,_)),S=new Set(x.changeSet.unchanged.filter(e=>e.name.startsWith(ki)).map(e=>e.name.slice(10))),[C,w,ee,te,ne,re,ie,ae,oe,se,ce]=await Promise.all([z(`plan.tailorDB`,()=>planTailorDB(b)),z(`plan.staticWebsite`,()=>planStaticWebsite(b)),z(`plan.aiGateway`,()=>planAIGateway(b)),z(`plan.idp`,()=>planIdP(b)),z(`plan.auth`,()=>planAuth(b)),z(`plan.pipeline`,()=>planPipeline(b)),z(`plan.application`,()=>planApplication(b,f)),z(`plan.executor`,()=>planExecutor(b)),z(`plan.workflow`,()=>planWorkflow(i,a,u.name,u.id,g?.workflows??{},d?.mainJobDeps??{},S,{...subscribedWorkflows(m),jobPublishEvents:collectWorkflowJobPublishEvents(t),dependentApps:b.dependentApps,runAppIds:b.runAppIds})),z(`plan.workflowExecutionPolicy`,()=>planWorkflowJobFunctionExecutionPolicy(i,a,u.name,u.id,l.workflow?.executionPolicies??{})),z(`plan.secretManager`,()=>planSecretManager(b))]);return{application:u,functionRegistry:x,tailorDB:C,staticWebsite:w,aiGateway:ee,idp:te,auth:ne,pipeline:re,app:ie,executor:ae,workflow:oe,workflowExecutionPolicy:se,secretManager:ce}})}async function planDeploymentTargets(e){let{targets:t,planTarget:n=planDeploymentTarget,...r}=e;return Promise.all(t.map(e=>n({...r,target:e,targets:t})))}async function confirmDeploymentPlans(e){let{deployments:t,yes:n,dryRun:r=!1,missingDependentApps:i=[]}=e;r||await confirmMigrationCheckpointRepairs(t.flatMap(e=>e.tailorDB.context.checkpointRepairs),n),await confirmMissingDependentApps(i,n);let a=new Set(t.map(e=>e.application.name)),o=collectDeploymentResourceOwners(t),s=new Set,c=[];for(let e of t){let t=deploymentPlanResults(e),r=collectOwnerConflicts(t);await confirmOwnerConflict(r,e.application.name,n,e.application.id),await confirmUnmanagedResources(collectUnmanagedResources(t),e.application.name,n),c.push(...collectImportantResourceDeletions(t));let i=computeRenamedAppDeletions({conflicts:r,resourceOwners:o,protectedAppNames:a});for(let t of i)s.has(t)||(s.add(t),e.app.deletes.push({name:t,request:{workspaceId:e.tailorDB.context.workspaceId,applicationName:t}}))}await confirmImportantResourceDeletion(c,n)}async function validateDeploymentPlans(e){for(let t of e)await validatePlan(deploymentPlanResults(t))}function adjustApplicationForMigrationTest(e,t){if(!t?.migrationTestSnapshots)return e;let n=t.migrationTestBaselines!==void 0,r=n&&e.authService?{...e.authService,userProfile:void 0}:e.authService,i={...e,executorService:n?void 0:e.executorService,authService:r,staticWebsiteServices:e.staticWebsiteServices.map(e=>({...e,customDomains:void 0})),get applications(){return[i]}};return i}async function deployInternal(e,n,r){return z(`deploy`,async i=>{i.setAttribute(`deploy.dry_run`,e?.dryRun??!1),un(),t();let a=parseDeployConfigPaths(e?.configPath),o=e?.dryRun??!1,s=e?.buildOnly??ct(process.env.TAILOR_DEPLOY_BUILD_ONLY)===!0,c=s?[]:await z(`config.preflight`,()=>Promise.all(a.map(e=>loadDeployConfig({configPath:e,dryRun:o,buildOnly:s})))),l=c.map(({config:e})=>e.path),u=c.map(({config:e})=>({configPath:e.path,applicationId:e.id??`name:${e.name}`})),d=s?void 0:await resolveDeployWorkspace({workspaceId:e?.workspaceId,profile:e?.profile,createWorkspace:e?.createWorkspace,workspaceName:e?.workspaceName,workspaceRegion:e?.workspaceRegion,organizationId:e?.organizationId,folderId:e?.folderId,dryRun:o,contextTargets:u,deployArgs:retryDeployArgs(e,l,n),workspaceCommandArgs:workspaceRecoveryArgs(e,n),workspaceCommandJson:n?.json||M.jsonMode}),f=await z(`build`,async()=>{let t=e?.noCache??!1,n=await pn(),r=B.resolve(Gt(),`cache`);return e?.cleanCache&&(W.rmSync(r,{recursive:!0,force:!0}),M.info(`Bundle cache cleaned`)),await buildDeploymentTargets({configPaths:a,loadedConfigs:c,dryRun:o,buildOnly:s,noCache:t,packageVersion:n.version??`unknown`,cacheDir:r})});if(s)return{bundledScripts:mergeBundledScripts(f)};if(assertUniqueGlobalResourceNames(f),!d)throw Error(`Workspace was not resolved`);let{client:p,workspaceId:m}=d;i.setAttribute(`app.name`,f.map(e=>e.application.name).join(`,`)),i.setAttribute(`workspace.id`,m);let h=f.map(e=>({...e,application:adjustApplicationForMigrationTest(e.application,r)})),g=await z(`plan.metadataLookup`,()=>createMetadataLookupClient({client:p,workspaceId:m,applications:h.map(({application:e})=>e)})),_=collectDeployRunPlanInputs(h,!e?.dryRun),v=await planDeploymentTargets({targets:h,runInputs:_,client:g,workspaceId:m,noSchemaCheck:e?.noSchemaCheck,migrationTestBaselines:r?.migrationTestBaselines,migrationTestSnapshots:r?.migrationTestSnapshots}),y=e?.yes??!1;dropCrossDeploymentManagedDeletes(v);let b=(await Promise.all(h.map(e=>fetchMissingDependentApps({client:g,workspaceId:m,application:e.application,runAppIds:_.runAppIds??new Set,subscribedKeys:subscribedResourceKeys(_.eventSubscriptions,e),jobsByWorkflow:e.workflowBuildResult?.mainJobDeps??{}})))).flat();await z(`confirm`,async()=>{await confirmDeploymentPlans({deployments:v,yes:y,dryRun:o,missingDependentApps:b})});let x=printDeploymentPlans(v,{dryRun:e?.dryRun});if(e?.noValidate?M.warn(`Client-side validation skipped (--no-validate).`):await validateDeploymentPlans(v),o){M.info(`Dry run enabled. No changes applied.`);return}await applyDeploymentPlans(p,m,v),r?.suppressResultOutput||(M.jsonMode?M.out({summary:x,status:`applied`}):M.success(`Successfully applied changes.`))})}function deploy(e){return deployInternal(e)}function deployMigrationTestBaseline(e,t,n){return deployInternal(e,void 0,{migrationTestBaselines:t,migrationTestSnapshots:n,suppressResultOutput:!0})}function deployMigrationTestTarget(e,t){return deployInternal(e,void 0,{migrationTestSnapshots:t,suppressResultOutput:!0})}function deployFromCLI(e,t){return deployInternal(e,t)}function colorizeExecutorJobStatus(e){switch(e){case`PENDING`:return N.dim(e);case`RUNNING`:return N.info(e);case`SUCCESS`:return N.success(e);case`FAILED`:return N.error(e);case`CANCELED`:return N.warning(e);default:return e}}function isExecutorJobTerminalStatus(e){return isExecutorJobSuccessStatus(e)||isExecutorJobFailureStatus(e)}function isExecutorJobSuccessStatus(e){return e===n.SUCCESS}function isExecutorJobFailureStatus(e){return e===n.FAILED||e===n.CANCELED}function isExecutorJobTransientStatus(e){return e===n.UNSPECIFIED||e===n.PENDING||e===n.RUNNING}function classifyExecutorJobStatus(e){return isExecutorJobSuccessStatus(e)?`success`:isExecutorJobTerminalStatus(e)?`failure`:(isExecutorJobTransientStatus(e),`transient`)}function parseExecutorJobStatus(e){switch(e.toUpperCase()){case`PENDING`:return n.PENDING;case`RUNNING`:return n.RUNNING;case`SUCCESS`:return n.SUCCESS;case`FAILED`:return n.FAILED;case`CANCELED`:return n.CANCELED;default:throw Error(`Invalid status: ${e}. Valid values: PENDING, RUNNING, SUCCESS, FAILED, CANCELED`)}}function colorizeFunctionExecutionStatus(e){switch(e){case`RUNNING`:return N.info(e);case`SUCCESS`:return N.success(e);case`FAILED`:return N.error(e);default:return e}}function isFunctionExecutionTerminalStatus(e){return e===h.SUCCESS||e===h.FAILED||e===h.CANCELED}function executorTargetTypeToString(e){switch(e){case T.WEBHOOK:return`WEBHOOK`;case T.TAILOR_GRAPHQL:return`GRAPHQL`;case T.FUNCTION:return`FUNCTION`;case T.JOB_FUNCTION:return`JOB_FUNCTION`;case T.WORKFLOW:return`WORKFLOW`;default:return`UNSPECIFIED`}}function executorTriggerTypeToString(e){switch(e){case O.SCHEDULE:return`SCHEDULE`;case O.EVENT:return`EVENT`;case O.INCOMING_WEBHOOK:return`INCOMING_WEBHOOK`;default:return`UNSPECIFIED`}}function executorJobStatusToString(e){switch(e){case n.PENDING:return`PENDING`;case n.RUNNING:return`RUNNING`;case n.SUCCESS:return`SUCCESS`;case n.FAILED:return`FAILED`;case n.CANCELED:return`CANCELED`;default:return`UNSPECIFIED`}}function toExecutorJobListInfo(e){return{id:e.id,executorName:e.executorName,status:executorJobStatusToString(e.status),createdAt:e.createdAt?G(e.createdAt).toISOString():`N/A`}}function toExecutorJobInfo(e){return{id:e.id,executorName:e.executorName,status:executorJobStatusToString(e.status),scheduledAt:e.scheduledAt?G(e.scheduledAt).toISOString():`N/A`,createdAt:e.createdAt?G(e.createdAt).toISOString():`N/A`,updatedAt:e.updatedAt?G(e.updatedAt).toISOString():`N/A`}}function toExecutorJobAttemptInfo(e){return{id:e.id,jobId:e.jobId,status:executorJobStatusToString(e.status),error:e.error||``,startedAt:e.startedAt?G(e.startedAt).toISOString():`N/A`,finishedAt:e.finishedAt?G(e.finishedAt).toISOString():`N/A`,operationReference:e.operationReference||``}}function formatSubjectEvent(e,t){let n=t.map(e=>e.split(`.`).at(-1)??e).join(`, `);return n?`event: ${e} ${n}`:`event: ${e}`}function formatTypedEventTrigger(e){let t=e.typedConfig;if(t.case===void 0)return null;switch(t.case){case`tailordb`:return formatSubjectEvent(t.value.typeName,t.value.eventTypes);case`pipeline`:return formatSubjectEvent(t.value.resolverName,t.value.eventTypes);case`idp`:return formatSubjectEvent(`idp user`,t.value.eventTypes);case`auth`:return formatSubjectEvent(`auth access_token`,t.value.eventTypes);default:return null}}function formatTriggerType(e){let t=e.triggerConfig?.config;if(!t||t.case===void 0)return executorTriggerTypeToString(e.triggerType);switch(t.case){case`schedule`:return`schedule: ${t.value.frequency} (${t.value.timezone})`;case`event`:return formatTypedEventTrigger(t.value)||(t.value.eventType?formatEventTrigger(t.value.eventType,t.value.condition?.expr):executorTriggerTypeToString(e.triggerType));case`incomingWebhook`:return`webhook`;default:return executorTriggerTypeToString(e.triggerType)}}function formatEventTrigger(e,t){let n=e.split(`.`);if(n.length<3)return`event: ${e}`;let[r,i,a]=n;if(t){let e=t.match(/args\.typeName\s*===?\s*["']([^"']+)["']/);if(e)return`event: ${e[1]} ${a}`;let n=t.match(/args\.resolverName\s*===?\s*["']([^"']+)["']/);if(n)return`event: ${n[1]} ${a}`}return`event: ${r} ${i} ${a}`}function formatTriggerConfig(e){let t=e.triggerConfig?.config;if(!t||t.case===void 0)return{};switch(t.case){case`schedule`:return{timezone:t.value.timezone,frequency:t.value.frequency};case`event`:return formatEventTriggerConfig(t.value);case`incomingWebhook`:return{secret:t.value.secret?`***`:``};default:return{}}}function formatEventTriggerConfig(e){let t=e.typedConfig;if(t.case===void 0)return{eventType:e.eventType,condition:e.condition?.expr||``};if(t.case===`workflow`)return{kind:t.case,eventTypes:t.value.eventTypes,condition:t.value.condition?.expr||``,...t.value.workflowName&&{workflowName:t.value.workflowName}};let n={kind:t.case,eventTypes:t.value.eventTypes,namespaceName:t.value.namespaceName,condition:t.value.condition?.expr||``};switch(t.case){case`tailordb`:return{...n,typeName:t.value.typeName};case`pipeline`:return{...n,resolverName:t.value.resolverName};default:return n}}function formatTargetConfig(e){let t=e.targetConfig?.config;if(!t||t.case===void 0)return{};switch(t.case){case`webhook`:return{url:t.value.url?.expr||``,headers:t.value.headers.length};case`tailorGraphql`:return{appName:t.value.appName,query:t.value.query};case`function`:return{name:t.value.name};case`workflow`:return{workflowName:t.value.workflowName};default:return{}}}function toExecutorListInfo(e){return{name:e.name,triggerType:formatTriggerType(e),targetType:executorTargetTypeToString(e.targetType),disabled:e.disabled}}function toExecutorInfo(e){return{name:e.name,description:e.description,triggerType:formatTriggerType(e),targetType:executorTargetTypeToString(e.targetType),disabled:e.disabled,triggerConfig:formatTriggerConfig(e),targetConfig:formatTargetConfig(e)}}const Ho={name:V(H.string(),{positional:!0,description:`Executor name`})};async function resolveExecutor(e,t,n){let{executor:r}=await e.getExecutorExecutor({workspaceId:t,name:n});if(!r)throw Error(`Executor '${n}' not found.`);return r}async function getExecutor(e){let t=e.executor.name,n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile});try{return toExecutorInfo(await resolveExecutor(r,i,t))}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Executor '${t}' not found.`,{cause:e}):e}}const Uo=X({name:`get`,description:`Get executor details`,args:H.strictObject({...Y,...Ho}),run:async e=>{let t=await getExecutor({executor:{name:e.name},workspaceId:e[`workspace-id`],profile:e.profile});M.out(t,{display:{triggerConfig:null,targetConfig:null}})}});function functionExecutionStatusToString(e){switch(e){case h.RUNNING:return`RUNNING`;case h.SUCCESS:return`SUCCESS`;case h.FAILED:return`FAILED`;case h.SUSPEND:return`SUSPEND`;case h.CANCELING:return`CANCELING`;case h.CANCELED:return`CANCELED`;default:return`UNSPECIFIED`}}function formatWaitError(e){return e instanceof Error?e.message:String(e)}function isRetryableWaitError(e){return e instanceof q?e.code===K.Aborted||e.code===K.ResourceExhausted||e.code===K.Unavailable:!1}const Wo=H.enum([`success`,`suspended`,`terminal`]),Go={name:V(H.string(),{positional:!0,description:`Workflow name`})},Ko={interval:V(Ir.default(`3s`),{alias:`i`,description:`Polling interval when waiting (e.g., '3s', '500ms', '1m')`}),timeout:V(Ir.default(`10m`),{alias:`t`,description:`Maximum time to wait (e.g., '30s', '10m')`}),until:V(Wo.default(`terminal`),{alias:`u`,description:`Wait target (success, suspended, terminal)`}),logs:V(H.boolean().default(!1),{alias:`l`,description:`Display job execution logs after completion`})},qo={wait:V(H.boolean().default(!1),{alias:`W`,description:`Wait for execution to complete`}),...Ko};function isWorkflowExecutionSuccessStatus(e){return e===D.SUCCESS}function isWorkflowJobExecutionSuspendedStatus(e){return e===Qe.SUSPEND||e===Qe.WAITING}function isWorkflowExecutionSuspendedStatus(e){return e===D.PENDING_RESUME||e===D.WAITING}function isWorkflowExecutionFailureStatus(e){return e===D.FAILED}function isWorkflowExecutionTransientStatus(e){return e===D.UNSPECIFIED||e===D.PENDING||e===D.RUNNING||e===D.PENDING_RETRY}function isWorkflowExecutionTerminalStatus(e){return isWorkflowExecutionSuccessStatus(e)||isWorkflowExecutionFailureStatus(e)||isWorkflowExecutionSuspendedStatus(e)}function classifyWorkflowExecutionStatus(e){return isWorkflowExecutionTerminalStatus(e.status)?isWorkflowExecutionSuccessStatus(e.status)?{statusClass:`success`,status:e.status}:isWorkflowExecutionFailureStatus(e.status)?{statusClass:`failure`,status:e.status}:{statusClass:`suspended`,status:e.status}:e.jobExecutions.some(e=>isWorkflowJobExecutionSuspendedStatus(e.status))?{statusClass:`suspended`,status:e.status}:(isWorkflowExecutionTransientStatus(e.status),{statusClass:`transient`,status:e.status})}function hasReachedWorkflowWaitTarget(e,t){switch(t){case`success`:return e.statusClass===`success`;case`suspended`:return e.statusClass===`suspended`;case`terminal`:return e.statusClass===`success`||e.statusClass===`failure`||e.statusClass===`suspended`}}function workflowExecutionStatusToString(e){switch(e){case D.PENDING:return`PENDING`;case D.PENDING_RESUME:return`PENDING_RESUME`;case D.RUNNING:return`RUNNING`;case D.SUCCESS:return`SUCCESS`;case D.FAILED:return`FAILED`;case D.PENDING_RETRY:return`PENDING_RETRY`;case D.WAITING:return`WAITING`;default:return`UNSPECIFIED`}}function workflowJobExecutionStatusToString(e){switch(e){case Qe.RUNNING:return`RUNNING`;case Qe.SUSPEND:return`SUSPEND`;case Qe.SUCCESS:return`SUCCESS`;case Qe.FAILED:return`FAILED`;case Qe.WAITING:return`WAITING`;default:return`UNSPECIFIED`}}function toWorkflowListInfo(e){return{name:e.name,mainJob:e.mainJobFunctionName,jobFunctions:Object.keys(e.jobFunctions).length,updatedAt:e.updatedAt?G(e.updatedAt):null}}function toWorkflowInfo(e){let t={};for(let[n,r]of Object.entries(e.jobFunctions))t[n]=r.toString();return{name:e.name,id:e.id,mainJob:e.mainJobFunctionName,jobFunctions:t,createdAt:e.createdAt?G(e.createdAt):null,updatedAt:e.updatedAt?G(e.updatedAt):null}}function toWorkflowJobExecutionInfo(e){return{id:e.id,stackedJobName:e.stackedJobName,status:workflowJobExecutionStatusToString(e.status),executionId:e.executionId,startedAt:e.startedAt?G(e.startedAt):null,finishedAt:e.finishedAt?G(e.finishedAt):null}}function toWorkflowExecutionInfo(e){return{id:e.id,workflowName:e.workflowName,status:workflowExecutionStatusToString(e.status),jobExecutions:e.jobExecutions.length,startedAt:e.startedAt?G(e.startedAt):null,finishedAt:e.finishedAt?G(e.finishedAt):null}}function formatTime$1(e){return e.toLocaleTimeString(`en-US`,{hour12:!1})}function colorizeStatus(e){let t=D[e];switch(e){case D.PENDING:case D.UNSPECIFIED:return N.dim(t);case D.PENDING_RESUME:case D.PENDING_RETRY:case D.WAITING:return N.warning(t);case D.RUNNING:return N.info(t);case D.SUCCESS:return N.success(t);case D.FAILED:return N.error(t);default:return t}}function getActiveJobs(e){return e.jobExecutions.filter(e=>e.status===Qe.RUNNING||e.status===Qe.SUSPEND||e.status===Qe.WAITING).map(e=>e.stackedJobName).join(`, `)}function createWorkflowWaitResult(e){let t=Date.now()-e.startedAt;if(e.execution){let n=classifyWorkflowExecutionStatus(e.execution);return{...toWorkflowExecutionInfo(e.execution),statusClass:n.statusClass,elapsedMs:t,attempts:e.attempts,timedOut:e.timedOut,lastError:e.lastError}}return{id:e.executionId,workflowName:``,status:`UNKNOWN`,statusClass:`unknown`,jobExecutions:0,startedAt:null,finishedAt:null,elapsedMs:t,attempts:e.attempts,timedOut:e.timedOut,lastError:e.lastError}}async function waitForWorkflowExecution(e){let t=e.interval??3e3,n=e.until??`terminal`,r=Date.now(),i=e.showProgress?spinner({indent:2}).start(`Waiting for workflow to complete...`):null,a=0,o,s=null,c,l;try{for(;;){let u=Date.now()-r,d=e.timeout===void 0?void 0:e.timeout-u;if(d!==void 0&&d<=0)return i?.fail(`Workflow wait timed out.`),createWorkflowWaitResult({executionId:e.executionId,execution:o,startedAt:r,attempts:a,timedOut:!0,lastError:s});try{a+=1;let{execution:t}=await e.client.getWorkflowExecution({workspaceId:e.workspaceId,executionId:e.executionId});if(!t)throw i?.fail(`Execution '${e.executionId}' not found.`),Error(`Execution '${e.executionId}' not found.`);o=t,s=null;let u=classifyWorkflowExecutionStatus(t),d=colorizeStatus(t.status);if(t.status!==c&&(e.showProgress&&(i?.stop(),M.info(`Status: ${d}`,{mode:`stream`,indent:2}),i?.start(`Waiting for workflow to complete...`)),c=t.status),e.trackJobs){let n=getActiveJobs(t);n&&n!==l&&(e.showProgress&&(i?.stop(),M.info(`Job | ${n}: ${d}`,{mode:`stream`,indent:2}),i?.start(`Waiting for workflow to complete...`)),l=n)}if(i&&(i.text=`Waiting for workflow to complete... (${formatTime$1(new Date)})`),hasReachedWorkflowWaitTarget(u,n)||u.statusClass===`failure`||n===`suspended`&&u.statusClass===`success`)return t.status===D.SUCCESS?i?.succeed(`Completed: ${d}`):isWorkflowExecutionFailureStatus(t.status)?i?.fail(`Completed: ${d}`):isWorkflowExecutionSuspendedStatus(t.status)?i?.warn(`Completed: ${d}`):i?.succeed(`Completed: ${d}`),createWorkflowWaitResult({executionId:e.executionId,execution:t,startedAt:r,attempts:a,timedOut:!1,lastError:s})}catch(t){if(!isRetryableWaitError(t))throw t;s=formatWaitError(t),e.showProgress&&i&&(i.text=`Retrying workflow status poll... (${formatTime$1(new Date)})`)}let f=Date.now()-r,p=e.timeout===void 0?void 0:e.timeout-f;if(p!==void 0&&p<=0)return i?.fail(`Workflow wait timed out.`),createWorkflowWaitResult({executionId:e.executionId,execution:o,startedAt:r,attempts:a,timedOut:!0,lastError:s});await Er(p===void 0?t:Math.min(t,p))}}finally{i?.stop()}}async function waitForWorkflowExecutionById(e){let t=await loadAccessToken({profile:e.profile});return await waitForWorkflowExecution({client:await F(t),workspaceId:await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),executionId:e.executionId,interval:e.interval,timeout:e.timeout,until:e.until,showProgress:e.showProgress,trackJobs:e.trackJobs})}function getWorkflowWaitFailureMessage(e,t){if(e.timedOut)return`Timed out waiting for workflow execution '${e.id}' to reach ${t}. Last status: ${e.status}.`;if(e.status===`FAILED`)return`Workflow execution '${e.id}' failed.`;if(t===`success`&&e.statusClass!==`success`)return`Workflow execution '${e.id}' reached ${e.status} before success.`;if(t===`suspended`&&e.statusClass!==`suspended`)return`Workflow execution '${e.id}' reached ${e.status} before suspension.`}function parseStatus(e){switch(e.toUpperCase()){case`PENDING`:return D.PENDING;case`PENDING_RESUME`:return D.PENDING_RESUME;case`RUNNING`:return D.RUNNING;case`SUCCESS`:return D.SUCCESS;case`FAILED`:return D.FAILED;case`PENDING_RETRY`:return D.PENDING_RETRY;case`WAITING`:return D.WAITING;case`UNSPECIFIED`:return D.UNSPECIFIED;default:throw Error(`Invalid status: ${e}. Valid values: UNSPECIFIED, PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED, PENDING_RETRY, WAITING`)}}async function listWorkflowExecutions(e){let t=e?.workflow?.name,n=await loadAccessToken({profile:e?.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e?.workspaceId,profile:e?.profile}),a=[];if(e?.status){let t=parseStatus(e.status);a.push(U(Re,{condition:U(we,{field:`status`,operator:Ze.EQ,value:{kind:{case:`numberValue`,value:t}}})}))}let o=a.length>0?U(Re,{and:a}):void 0,s=toPageDirection(e?.order??`desc`);return(await jt(async(e,n)=>{let{executions:a,nextPageToken:c}=await r.listWorkflowExecutions({workspaceId:i,workflowName:t??``,pageToken:e,pageSize:n,pageDirection:s,filter:o});return[a,c]},{limit:e?.limit})).map(toWorkflowExecutionInfo)}async function getWorkflowExecution(e){let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile});async function fetchFunctionExecution(e){try{let t=U(Re,{condition:U(we,{field:`id`,operator:Ze.EQ,value:{kind:{case:`stringValue`,value:e}}})});return(await n.listFunctionExecutions({workspaceId:r,filter:t,pageSize:1})).executions[0]}catch{return}}async function fetchExecutionWithLogs(e,t){let{execution:i}=await n.getWorkflowExecution({workspaceId:r,executionId:e});if(!i)throw Error(`Execution '${e}' not found.`);let a=toWorkflowExecutionInfo(i);return t&&i.jobExecutions.length>0&&(a.jobDetails=await Promise.all(i.jobExecutions.map(async e=>{let t=toWorkflowJobExecutionInfo(e);if(e.executionId){let n=await fetchFunctionExecution(e.executionId);if(n)return{...t,logs:n.logs||void 0,result:n.result||void 0}}return t}))),a}async function waitForCompletion(){let t=e.interval??3e3,i=await waitForWorkflowExecution({client:n,workspaceId:r,executionId:e.executionId,interval:t,timeout:e.timeout,until:e.until??`terminal`});return{...await fetchExecutionWithLogs(e.executionId,e.logs??!1),statusClass:i.statusClass,elapsedMs:i.elapsedMs,attempts:i.attempts,timedOut:i.timedOut,lastError:i.lastError}}return{execution:await fetchExecutionWithLogs(e.executionId,e.logs??!1),wait:waitForCompletion}}function printExecutionWithLogs(e){let formatDate=e=>e?e.toISOString():`N/A`,t=[[`id`,e.id],[`workflowName`,e.workflowName],[`status`,e.status],[`jobExecutions`,e.jobExecutions.toString()],[`startedAt`,formatDate(e.startedAt)],[`finishedAt`,formatDate(e.finishedAt)]];if(M.out(formatKeyValueTable(t)),e.jobDetails&&e.jobDetails.length>0){M.log(N.bold(`
|
|
130
|
+
`);return t?.dryRun?M.out(r):M.log(r),n.summary}function summarizePlanResults(e,t,n){let r={create:0,update:0,delete:0,replace:0};for(let e of t)r[e.action]+=1;for(let e of n)r[e.action]+=1;let{otherChanges:i}=splitFunctionRegistryChanges(e.functionRegistry.changeSet),a=summarizeChangeSets([i,e.staticWebsite.changeSet,e.staticWebsite.customDomainChangeSet,e.aiGateway.changeSet,e.app,e.secretManager.vaultChangeSet,e.secretManager.secretChangeSet]);return r.create+=a.create,r.update+=a.update,r.delete+=a.delete,r.replace+=a.replace,r}function sumPlanSummaries(e){return e.reduce((e,t)=>({create:e.create+t.create,update:e.update+t.update,delete:e.delete+t.delete,replace:e.replace+t.replace}),{create:0,update:0,delete:0,replace:0})}function printDeploymentPlans(e,t){if(M.jsonMode&&t?.dryRun){let t=e.map(e=>buildPlanReport(deploymentPlanResults(e))),n=sumPlanSummaries(t.map(e=>e.summary));return M.out({summary:n,changes:t.flatMap(e=>e.json.changes),warnings:t.flatMap(e=>e.json.warnings),conflicts:t.flatMap(e=>e.json.conflicts)}),n}return sumPlanSummaries(e.map(e=>printPlanResults(deploymentPlanResults(e),t)))}const No=new Map;function validatorFor(e){let t=No.get(e.typeName);if(t)return t;let n=yr({registry:Rn(e,...vr(e))});return No.set(e.typeName,n),n}function validateItems(e){let{schema:t,kind:n,action:r,items:i,requestKey:a,violations:o}=e;if(i.length===0)return;let s=validatorFor(t);for(let e of i){let i=e[a],c=U(t,i),l=s.validate(t,c);if(l.kind===`invalid`)for(let t of l.violations)o.push({kind:n,name:e.name,action:r,fieldPath:t.field.length>0?_r(t.field):`(message)`,message:t.message});else l.kind===`error`&&M.warn(`Could not validate ${n} "${e.name}" (${r}): ${l.error.message}`)}}async function validatePlan(e){let{tailorDB:t,staticWebsite:n,aiGateway:r,idp:o,auth:c,pipeline:l,app:u,executor:f,workflow:p,workflowExecutionPolicy:m,secretManager:h}=e,g=[];function creates(e,t,n){validateItems({schema:e,kind:t,action:`create`,items:n,requestKey:`request`,violations:g})}function updates(e,t,n){validateItems({schema:e,kind:t,action:`update`,items:n,requestKey:`request`,violations:g})}function replaces(e,t,n){validateItems({schema:e,kind:t,action:`replace`,items:n,requestKey:`createRequest`,violations:g})}function inPlaceReplaces(e,t,n){validateItems({schema:e,kind:t,action:`replace`,items:n,requestKey:`updateRequest`,violations:g})}creates(Se,`TailorDB service`,t.changeSet.service.creates),creates(Te,`TailorDB table`,t.changeSet.type.creates),updates(He,`TailorDB table`,t.changeSet.type.updates),creates(a,`StaticWebsite`,n.changeSet.creates),updates(nt,`StaticWebsite`,n.changeSet.updates),creates(ie,`StaticWebsite custom domain`,n.customDomainChangeSet.creates),creates(me,`AIGateway`,r.changeSet.creates.map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),updates(fe,`AIGateway`,r.changeSet.updates.map(e=>({name:e.name,request:{...e.request,cors:void 0}})));let substituteIdpReturnOrigins=e=>{let t=e.request,n=t.userAuthPolicy?.allowedReturnOrigins;if(!Array.isArray(n)||n.length===0)return e;let r=n.map(e=>typeof e==`string`&&/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url$/.test(e)?`https://placeholder.invalid`:e);return{...e,request:{...t,userAuthPolicy:{...t.userAuthPolicy,allowedReturnOrigins:r}}}};creates(i,`IdP service`,o.changeSet.service.creates.map(substituteIdpReturnOrigins)),updates(ce,`IdP service`,o.changeSet.service.updates.map(substituteIdpReturnOrigins));let _=[...o.changeSet.client.creates.map(e=>({clientName:e.request.client?.name??``,namespaceName:e.request.namespaceName??``,workspaceId:e.request.workspaceId??``})),...o.changeSet.client.updates.map(e=>({clientName:e.name,namespaceName:e.namespaceName,workspaceId:e.workspaceId}))];creates(S,`IdP client secret`,_.map(e=>({name:e.clientName,request:{workspaceId:e.workspaceId,secretmanagerVaultName:idpClientVaultName(e.namespaceName,e.clientName)}}))),creates(s,`IdP client secret`,_.map(e=>({name:e.clientName,request:{workspaceId:e.workspaceId,secretmanagerVaultName:idpClientVaultName(e.namespaceName,e.clientName),secretmanagerSecretName:idpClientSecretName(e.namespaceName,e.clientName)}}))),creates(Ie,`Auth service`,c.changeSet.service.creates),updates(ot,`Auth service`,c.changeSet.service.updates),creates(je,`Auth IDP config`,c.changeSet.idpConfig.creates),updates(Le,`Auth IDP config`,c.changeSet.idpConfig.updates),creates(Ce,`Auth user profile config`,c.changeSet.userProfileConfig.creates),updates(at,`Auth user profile config`,c.changeSet.userProfileConfig.updates),creates($e,`Auth tenant config`,c.changeSet.tenantConfig.creates),updates(be,`Auth tenant config`,c.changeSet.tenantConfig.updates),creates(ve,`Auth machine user`,c.changeSet.machineUser.creates),updates(ke,`Auth machine user`,c.changeSet.machineUser.updates),creates(qe,`Auth hook`,c.changeSet.authHook.creates),updates(Ue,`Auth hook`,c.changeSet.authHook.updates),creates(Ye,`Auth SCIM config`,c.changeSet.scim.creates),updates(ge,`Auth SCIM config`,c.changeSet.scim.updates),creates(xe,`Auth SCIM resource`,c.changeSet.scimResource.creates),updates(tt,`Auth SCIM resource`,c.changeSet.scimResource.updates),creates(Ve,`OAuth2 client`,c.changeSet.oauth2Client.creates),updates(Oe,`OAuth2 client`,c.changeSet.oauth2Client.updates),replaces(Ve,`OAuth2 client`,c.changeSet.oauth2Client.replaces),creates(v,`Pipeline service`,l.changeSet.service.creates),updates(w,`Pipeline service`,l.changeSet.service.updates),creates(Me,`Resolver`,l.changeSet.resolver.creates),updates(b,`Resolver`,l.changeSet.resolver.updates),creates(pe,`Executor`,f.changeSet.creates),updates(de,`Executor`,f.changeSet.updates),creates(_e,`Workflow`,p.changeSet.creates.map(e=>({name:e.name,request:buildWorkflowValidationShape(e.workspaceId,e.workflow)}))),updates(Je,`Workflow`,p.changeSet.updates.map(e=>({name:e.name,request:buildWorkflowValidationShape(e.workspaceId,e.workflow)})));let y=p.changeSet.creates[0]?.workspaceId??p.changeSet.updates[0]?.workspaceId??``;if(y){let e=new Set;for(let t of[...p.changeSet.creates,...p.changeSet.updates])for(let n of t.usedJobNames)e.add(n);for(let t of p.unchangedWorkflowJobNames)e.add(t);creates(Ae,`Workflow job function`,[...e].map(e=>({name:e,request:{workspaceId:y,jobFunctionName:e,scriptRef:e}})))}if(creates(Ge,`Workflow execution policy`,[...m.changeSet.creates,...m.changeSet.replaces].map(e=>({name:e.name,request:{workspaceId:e.workspaceId,executionPolicyName:e.policy.name,executionPolicyKey:toPlatformExecutionPolicyKey(e.policy),...e.policy.concurrencyPolicy&&{concurrencyPolicy:{maxConcurrentExecutions:e.policy.concurrencyPolicy.maxConcurrentExecutions}}}}))),updates(Be,`Workflow execution policy`,m.changeSet.updates.map(e=>({name:e.name,request:{workspaceId:e.workspaceId,executionPolicyName:e.policy.name,...e.policy.concurrencyPolicy&&{concurrencyPolicy:{maxConcurrentExecutions:e.policy.concurrencyPolicy.maxConcurrentExecutions}}}}))),creates(S,`Secret Manager vault`,h.vaultChangeSet.creates.map(e=>({name:e.name,request:vaultCreateRequest(e)}))),creates(s,`Secret Manager secret`,h.secretChangeSet.creates.map(e=>({name:e.name,request:secretCreateRequest(e)}))),updates(Pe,`Secret Manager secret`,h.secretChangeSet.updates.map(e=>({name:e.name,request:secretUpdateRequest(e)}))),creates(se,`Application`,u.creates.map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),updates(d,`Application`,[...u.updates,...u.unchanged].map(e=>({name:e.name,request:{...e.request,cors:void 0}}))),creates(ze,`Auth connection`,c.changeSet.connection.creates),inPlaceReplaces(Ee,`Auth connection`,c.changeSet.connection.replaces),g.length===0)return;let x=new Set(g.map(e=>`${e.kind}:${e.name}`));M.error(`Pre-flight validation found ${g.length} violation(s) across ${x.size} resource(s):`);for(let e of g)M.log(` ${N.resourceType(e.kind)} ${N.resourceName(e.name)} (${e.action}) — ${N.bold(e.fieldPath)}: ${e.message}`);throw Error(`${g.length} validation error(s) found in ${x.size} resource(s)`)}function formatIssues(e){return e.map(e=>e.message).join(`; `)||`Invalid options`}function parseOptions(e,t){let n=e.safeParse(t);if(!n.success)throw Error(formatIssues(n.error.issues));return n.data}const Po=H.string().min(1,`Profile must not be empty`),Fo=H.string().min(3,`Name must be at least 3 characters`).max(63,`Name must be at most 63 characters`).regex(/^[a-z0-9-]+$/,`Name can only contain lowercase letters, numbers, and hyphens`).refine(e=>!e.startsWith(`-`)&&!e.endsWith(`-`),`Name cannot start or end with a hyphen`);function validateWorkspaceName(e){let t=Fo.safeParse(e);return t.success?!0:formatIssues(t.error.issues)}function formatTimestamp(e){if(!e)return null;let t=G(e);return Number.isNaN(t.getTime())?null:t}function formatTable(e,t){return lt(e,t)}function formatKeyValueTable(e){return formatTable(e,{singleLine:!0})}function humanizeRelativeTime(e){if(e===null)return`N/A`;let t=e instanceof Date?e:new Date(e);return Number.isNaN(t.getTime())?typeof e==`string`?e:`N/A`:Xn(t,{addSuffix:!0})}const workspaceInfo=(e,t)=>{let n={id:e.id,name:e.name,region:e.region,...e.organizationId?{organizationId:e.organizationId}:{},...e.folderId?{folderId:e.folderId}:{},createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)};return t?{...n,folderName:t}:n},workspaceDetails=(e,t)=>({...workspaceInfo(e,t),deleteProtection:e.deleteProtection,organizationId:e.organizationId,folderId:e.folderId});async function resolveWorkspaceFolderName(e,t){if(!(!t.organizationId||!t.folderId))try{return(await e.getOrganizationFolder({organizationId:t.organizationId,folderId:t.folderId})).folder?.name||void 0}catch(e){if(e instanceof q&&(e.code===K.NotFound||e.code===K.PermissionDenied))return;M.warn(`Failed to resolve workspace folder name: ${e}`);return}}function createWorkspaceFolderNameResolver(e){let t=new Map;return n=>{if(!n.organizationId||!n.folderId)return Promise.resolve(void 0);let r=`${n.organizationId}/${n.folderId}`,i=t.get(r);if(i)return i;let a=resolveWorkspaceFolderName(e,n);return t.set(r,a),a}}async function workspaceInfoWithFolderName(e,t){let n=await resolveWorkspaceFolderName(e,t);return workspaceInfo(t,n)}async function workspaceDetailsWithFolderName(e,t){let n=await resolveWorkspaceFolderName(e,t);return workspaceDetails(t,n)}async function workspaceInfosWithFolderNames(e,t){let n=createWorkspaceFolderNameResolver(e),r=rr(5);return Promise.all(t.map(e=>r(async()=>workspaceInfo(e,await n(e)))))}function workspaceDisplayName(e){return e.folderName?`${e.folderName}/${e.name}`:e.name}function createWorkspaceNameTransformer(e,t){return(n,r)=>{let i=r,a=i[e],o=i[t];return typeof a==`string`&&typeof o==`string`?workspaceDisplayName({name:a,folderName:o}):String(n??``)}}const Io=createWorkspaceNameTransformer(`name`,`folderName`),Lo=H.object({name:Fo,region:H.string(),deleteProtection:H.boolean().optional(),organizationId:H.uuid().optional(),folderId:H.uuid().optional(),profile:Po.optional()}),validateRegion=async(e,t)=>{let n=await t.listAvailableWorkspaceRegions({});if(!n.regions.includes(e))throw Error(`Region must be one of: ${n.regions.join(`, `)}.`)};function profilePlatformSettings(e){let t=e?.oauth2ClientId||process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID,n=e?.consoleUrl??process.env.TAILOR_PLATFORM_CONSOLE_URL;return{...ft(e)?{}:{platform_url:Mt(e)},...t?{oauth2_client_id:yt(e)}:{},...n?{console_url:$t(n)}:{}}}async function createWorkspace$1(e){let t=validateCreateWorkspaceOptions(e),n=await loadAccessToken({profile:t.profile}),r=await loadPlatformClientConfig({profile:t.profile}),i=await F(n,r);return await validateRegion(t.region,i),createValidatedWorkspaceWithClient(i,t)}async function createValidatedWorkspaceWithClient(e,t){let n=await e.createWorkspace({workspaceName:t.name,workspaceRegion:t.region,deleteProtection:t.deleteProtection??!1,organizationId:t.organizationId,folderId:t.folderId});return workspaceInfoWithFolderName(e,A(n.workspace,`createWorkspace response missing workspace`))}function validateCreateWorkspaceOptions(e){return parseOptions(Lo,e)}const Ro=X({name:`create`,description:`Create a new Tailor Platform workspace.`,args:H.strictObject({name:V(H.string(),{alias:`n`,description:`Workspace name`}),region:V(H.string(),{alias:`r`,description:`Workspace region (us-west, asia-northeast)`}),"delete-protection":V(H.boolean().default(!1),{alias:`d`,description:`Enable delete protection`}),"organization-id":V(H.string().optional(),{alias:`o`,description:`Organization ID to workspace associate with`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`}),"folder-id":V(H.string().optional(),{alias:`f`,description:`Folder ID to workspace associate with`,env:`TAILOR_PLATFORM_FOLDER_ID`}),"profile-name":V(H.string().optional(),{alias:`p`,description:`Profile name to create`}),profile:V(Po.optional(),{description:`Workspace profile used for authentication and Platform selection`,env:`TAILOR_PLATFORM_PROFILE`}),"profile-user":V(H.string().optional(),{description:`User email address or machine user client ID for the profile (defaults to current user)`}),permission:V(H.enum([`write`,`read`]).default(`write`),{description:`Profile permission (requires --profile-name). 'read' blocks all write commands while the profile is active.`})}),run:async e=>{await assertWritable({profile:e.profile});let t=e[`profile-name`],n;if(t){let r=await readPlatformConfig();if(r.profiles[t])throw Error(`Profile "${t}" already exists.`);let i=e.profile,a=i?r.profiles[i]:void 0,o=a?platformConfigFromProfile(a):void 0,s=e[`profile-user`]||a?.user||r.current_user;if(!s)throw Error(`Current user not found. Please login or specify --profile-user to create a profile.`);let c=resolveConfigUser(r,s,o);if(!c)throw Error(`User "${s}" not found.\nPlease verify your user name and login using 'tailor login' command.`);n={name:t,user:c,platformSettings:profilePlatformSettings(o)}}let r=await createWorkspace$1({name:e.name,region:e.region,deleteProtection:e[`delete-protection`],organizationId:e[`organization-id`],folderId:e[`folder-id`],profile:e.profile}),i;if(n){let t=await readPlatformConfig(),a=n.platformSettings;t.profiles[n.name]={user:n.user,workspace_id:r.id,...e.permission===`read`?{readonly:!0}:{},...a},writePlatformConfig(t),i={name:n.name,user:n.user,workspaceId:r.id,permission:e.permission,...a.platform_url?{platformUrl:a.platform_url}:{},...a.oauth2_client_id?{oauth2ClientId:a.oauth2_client_id}:{},...a.console_url?{consoleUrl:a.console_url}:{}},e.json||M.success(`Profile "${n.name}" created successfully.`)}if(e.json||M.success(`Workspace "${workspaceDisplayName(r)}" created successfully.`),e.json&&i){M.out({...r,profile:i});return}M.out(r,{display:{name:Io,folderName:null}}),i&&(M.out(`Profile:`),M.out(i))}});async function listWorkspaces(e){let t=Po.optional().parse(e?.profile),n=await loadAccessToken({profile:t}),r=await loadPlatformClientConfig({profile:t});return listWorkspacesWithClient(await F(n,r),e)}async function listWorkspacesWithClient(e,t){let n=toPageDirection(t?.order);return workspaceInfosWithFolderNames(e,await jt(async(t,r)=>{let{workspaces:i,nextPageToken:a}=await e.listWorkspaces({pageToken:t,pageSize:r,pageDirection:n});return[i,a]},{limit:t?.limit}))}const zo=X({name:`list`,description:`List all Tailor Platform workspaces.`,args:H.strictObject({...paginationArgs(),profile:V(Po.optional(),{description:`Workspace profile used for authentication and Platform selection`,env:`TAILOR_PLATFORM_PROFILE`})}),run:async e=>{let t=await listWorkspaces({order:e.order,limit:e.limit,profile:e.profile});M.out(t,{display:{name:Io,folderName:null,organizationId:null,folderId:null,updatedAt:null}})}}),Bo=H.object({version:H.literal(1),platformUrl:H.url(),applicationId:H.string().min(1).optional(),workspaceId:H.uuid()});function defaultConfigPath(){return Nn(process.cwd(),`tailor.config.ts`)}function contextPath(e){return Mn(jn(e),Gt(),`${An(e)}.context.json`)}async function loadWorkspaceContext(e,t=defaultConfigPath(),n){let r;try{r=await xr(contextPath(t),`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let i;try{i=JSON.parse(r)}catch{return}let a=Bo.safeParse(i);if(!(!a.success||a.data.platformUrl!==e||n!==void 0&&a.data.applicationId!==n))return a.data}async function saveWorkspaceContext(e,t=defaultConfigPath(),n){let r=Bo.parse({...e,...n===void 0?{}:{applicationId:n}}),i=Mn(jn(t),Gt()),a=contextPath(t),o=`${JSON.stringify(r,null,2)}\n`;try{if(await xr(a,`utf8`)===o)return}catch{}let s=`${a}.${process.pid}.${or()}.tmp`;await br(i,{recursive:!0});try{await wr(s,o,{mode:384}),await Sr(s,a)}catch(e){throw await Cr(s,{force:!0}).catch(()=>void 0),e}}function suggestedWorkspaceName(){let e=An(process.cwd()).toLowerCase().replaceAll(/[^a-z0-9-]+/g,`-`).replaceAll(/^-+|-+$/g,``).slice(0,63).replace(/-+$/,``);return validateWorkspaceName(e)===!0?e:`my-workspace`}function executableAction(e){return{command:`tailor`,args:e}}function deployArgs(e){return e.deployArgs??[`deploy`]}function workspaceCommandArgs(e){return e.workspaceCommandArgs??[]}function createDeployArgs(e,t,n){return[...deployArgs(e),`--create-workspace`,`--workspace-name`,t,`--workspace-region`,n,...e.organizationId?[`--organization-id`,e.organizationId]:[],...e.folderId?[`--folder-id`,e.folderId]:[]]}function selectDeployArgs(e){return[...deployArgs(e),`--workspace-id`,`<workspace-id>`]}function workspaceLabel(e){let t=e.organizationId??`personal`;return`${workspaceDisplayName(e)} (${e.region}, org: ${t}, id: ${e.id})`}function workspaceMatchesRequestedIdentity(e,t){return t.workspaceName===e.name&&t.workspaceRegion===e.region&&t.organizationId===e.organizationId&&t.folderId===e.folderId}function workspaceIdentity(e){let{id:t,name:n,region:r,organizationId:i,folderId:a}=e;return{id:t,name:n,region:r,organizationId:i,folderId:a}}function projectContextTargets(e){if(e)return[...new Map(e.map(e=>[e.configPath,e])).values()]}async function loadProjectContexts(e,t){let n=projectContextTargets(t);if(!n||n.length===0){let t=await loadWorkspaceContext(e);return t?[t]:[]}return(await Promise.all(n.map(({configPath:t,applicationId:n})=>loadWorkspaceContext(e,t,n)))).filter(e=>e!==void 0)}async function persistWorkspaceContext(e,t){let n=projectContextTargets(t);if(!n||n.length===0){await saveWorkspaceContext(e);return}let r=(await Promise.allSettled(n.map(({configPath:t,applicationId:n})=>saveWorkspaceContext(e,t,n)))).filter(e=>e.status===`rejected`);if(r.length>0)throw Error(r.map(({reason:e})=>e instanceof Error?e.message:String(e)).join(`; `))}async function rememberWorkspaceContext(e,t,n=`error-on-partial`){if(!t.dryRun)try{await persistWorkspaceContext(e,t.contextTargets)}catch(r){if((projectContextTargets(t.contextTargets)?.length??0)>1&&n===`error-on-partial`)throw R({code:`WORKSPACE_CONTEXT_SAVE_FAILED`,message:`The workspace selection could not be saved for every configuration file.`,details:r instanceof Error?r.message:String(r),suggestion:`Fix project state permissions, then rerun deploy with the workspace ID.`,next:executableAction([...deployArgs(t),`--workspace-id`,e.workspaceId]),context:{workspaceId:e.workspaceId,configPaths:t.contextTargets?.map(({configPath:e})=>e)}});M.warn(`Could not save the project workspace selection (${r instanceof Error?r.message:String(r)}). Continue with --workspace-id ${e.workspaceId} on later runs.`)}}async function useWorkspace(e,t,n,r,i=`error-on-partial`){return await rememberWorkspaceContext({version:1,platformUrl:t,workspaceId:n.id},r,i),M.info(`Using workspace: ${workspaceLabel(n)}`),{client:e,workspaceId:n.id}}function useRememberedWorkspace(e,t){return M.warn(`Using saved workspace selection: ${workspaceLabel(t)}`),{client:e,workspaceId:t.id}}const Vo=`create-new-workspace`;async function chooseWorkspace(e,t,n,r){let i=await Z.select({message:`Select a workspace`,choices:[...n.map(e=>({name:workspaceLabel(e),value:e.id})),{name:`Create new workspace`,value:Vo}]});if(i===Vo)return createWorkspaceForDeploy(e,t,r);let a=n.find(({id:e})=>e===i);if(!a)throw Error(`Selected workspace was not found`);return useWorkspace(e,t,a,r)}function invalidCreateOptionsError(e,t,n,r){return R({code:`WORKSPACE_CREATE_OPTIONS_INVALID`,message:`Workspace creation options are invalid.`,details:r,suggestion:`Correct the workspace creation options and rerun deploy.`,next:executableAction(createDeployArgs(e,t,n))})}async function createWorkspace(e,t,n,r,i){let a=n.workspaceName,o=n.workspaceRegion,s=canPrompt();if(s)a??=await Z.text({message:`Workspace name`,default:suggestedWorkspaceName(),validate:validateWorkspaceName}),o??=await Z.select({message:`Workspace region`,choices:r.map(e=>({name:e,value:e}))});else{let e=[...a===void 0?[`--workspace-name`]:[],...o===void 0?[`--workspace-region`]:[]];if(e.length>0)throw R({code:`WORKSPACE_CREATE_OPTIONS_REQUIRED`,message:`Workspace creation requires a name and region in non-interactive mode.`,suggestion:`Provide every workspace creation option and rerun deploy.`,next:executableAction(createDeployArgs(n,a??`<name>`,o??`<region>`)),context:{missingOptions:e}})}if(!a||!o)throw Error(`Workspace creation options were not resolved`);let c=i;if(!c){try{c=validateCreateWorkspaceOptions({name:a,region:o,organizationId:n.organizationId,folderId:n.folderId})}catch(e){throw invalidCreateOptionsError(n,a,o,e instanceof Error?e.message:String(e))}if(!r.includes(o))throw invalidCreateOptionsError(n,a,o,`Region must be one of: ${r.join(`, `)}.`)}if(s){let e=[n.organizationId?`organization: ${n.organizationId}`:void 0,n.folderId?`folder: ${n.folderId}`:void 0].filter(e=>e!==void 0);if(!await Z.confirm({message:`Create workspace "${a}" in ${o}${e.length>0?` (${e.join(`, `)})`:``}?`,default:!0}))throw R({code:`WORKSPACE_CREATION_CANCELLED`,message:`Workspace creation was cancelled.`})}let l;try{l=await createValidatedWorkspaceWithClient(e,c)}catch(e){throw e instanceof q&&![K.Canceled,K.Unknown,K.DeadlineExceeded,K.Aborted,K.Internal,K.Unavailable,K.DataLoss].includes(e.code)?e:R({code:`WORKSPACE_CREATION_FAILED`,message:`Workspace creation did not complete successfully.`,details:e instanceof Error?e.message:String(e),suggestion:`The outcome may be uncertain. List workspaces before retrying creation to avoid duplicates.`,next:executableAction([`workspace`,`list`,...workspaceCommandArgs(n),`--json`])})}return await rememberWorkspaceContext({version:1,platformUrl:t,workspaceId:l.id},n),M.success(`Created workspace: ${workspaceLabel(l)}`),M.info(`Reuse this workspace with: tailor deploy --workspace-id ${l.id}`),M.info(`Or set TAILOR_PLATFORM_WORKSPACE_ID=${l.id}.`),{client:e,workspaceId:l.id}}async function createWorkspaceForDeploy(e,t,n,r,i){let a=r??(await e.listAvailableWorkspaceRegions({})).regions;if(n.dryRun)throw R({code:`WORKSPACE_CREATION_DISABLED_IN_DRY_RUN`,message:`Dry-run cannot create the workspace required to build a deployment plan.`,suggestion:`Create a workspace explicitly, then rerun the same dry-run with its workspace ID.`,context:{availableRegions:a}});return createWorkspace(e,t,n,a,i)}async function resolveDeployWorkspace(e={}){let t=[e.workspaceName===void 0?void 0:`--workspace-name`,e.workspaceRegion===void 0?void 0:`--workspace-region`].filter(e=>e!==void 0);if(!e.createWorkspace&&t.length>0)throw R({code:`WORKSPACE_CREATE_FLAG_REQUIRED`,message:`Workspace creation options require --create-workspace.`,suggestion:`Add --create-workspace or remove the workspace creation options.`,next:executableAction(createDeployArgs(e,e.workspaceName??`<name>`,e.workspaceRegion??`<region>`)),context:{options:t}});if(e.createWorkspace&&e.workspaceName!==void 0){let t=validateWorkspaceName(e.workspaceName);if(t!==!0)throw invalidCreateOptionsError(e,e.workspaceName,e.workspaceRegion??`<region>`,t)}if(e.createWorkspace&&e.workspaceRegion===``)throw invalidCreateOptionsError(e,e.workspaceName??`<name>`,e.workspaceRegion,`Region must not be empty.`);let n=await tryLoadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),r=await loadAccessToken({profile:e.profile}),i=await loadPlatformClientConfig({profile:e.profile,allowMissingProfile:n!==void 0}),a=Mt(i),o=await F(r,i);if(n){let t;try{t=await o.getWorkspace({workspaceId:n})}catch(e){throw e instanceof q&&e.code===K.NotFound?R({code:`WORKSPACE_NOT_FOUND`,message:`Workspace "${n}" was not found.`}):e}if(!t.workspace)throw R({code:`WORKSPACE_NOT_FOUND`,message:`Workspace "${n}" was not found.`});return useWorkspace(o,a,workspaceInfo(t.workspace),e,`warn`)}let s;if(e.createWorkspace&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0)try{s=validateCreateWorkspaceOptions({name:e.workspaceName,region:e.workspaceRegion,organizationId:e.organizationId,folderId:e.folderId})}catch(t){throw invalidCreateOptionsError(e,e.workspaceName,e.workspaceRegion,t instanceof Error?t.message:String(t))}let[c,l]=await Promise.all([loadProjectContexts(a,e.contextTargets),listWorkspacesWithClient(o)]),u=canPrompt(),d=new Set(c.map(({workspaceId:e})=>e)),f=d.size===1?l.find(({id:e})=>d.has(e)):void 0;if(f&&(!e.createWorkspace||workspaceMatchesRequestedIdentity(f,e))){let t=projectContextTargets(e.contextTargets)?.length??1;return c.length===t?useRememberedWorkspace(o,f):useWorkspace(o,a,f,e)}let p=l.length===1?l[0]:void 0,m=p!==void 0&&s!==void 0&&workspaceMatchesRequestedIdentity(p,e),h;if(s&&!m&&(h=await o.listAvailableWorkspaceRegions({}),!h.regions.includes(s.region)))throw invalidCreateOptionsError(e,s.name,s.region,`Region must be one of: ${h.regions.join(`, `)}.`);if(l.length===0&&(u||e.createWorkspace||c.length===0)){let t=h?.regions??(await o.listAvailableWorkspaceRegions({})).regions;if(e.dryRun||u||e.createWorkspace)return createWorkspaceForDeploy(o,a,e,t,s);throw R({code:`WORKSPACE_NOT_FOUND`,message:`No workspaces are available for this account.`,suggestion:`Create one during deploy by providing the workspace name and one of the available regions.`,next:executableAction(createDeployArgs(e,`<name>`,`<region>`)),context:{availableRegions:t}})}if(d.size>1){let t=e.createWorkspace===!0&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0&&l.length===0;if(!u&&!t)throw R({code:`WORKSPACE_CONTEXT_CONFLICT`,message:`The deployed configuration files are linked to different workspaces.`,suggestion:`Choose one workspace explicitly for the combined deployment.`,next:executableAction(selectDeployArgs(e)),context:{savedWorkspaceIds:[...d]}});if(l.length>0&&!e.createWorkspace)return chooseWorkspace(o,a,l,e)}if(!f&&c.length>0){let t=e.createWorkspace===!0&&e.workspaceName!==void 0&&e.workspaceRegion!==void 0&&l.length<=1;if(!u&&!t)throw R({code:`WORKSPACE_CONTEXT_STALE`,message:`The saved project workspace is no longer available.`,suggestion:`Choose an available workspace explicitly before deploying.`,next:executableAction(selectDeployArgs(e)),context:{savedWorkspaceIds:[...d],workspaces:l.map(workspaceIdentity)}});if(l.length>0&&u&&!e.createWorkspace)return chooseWorkspace(o,a,l,e)}if(l.length===1){let[t]=l;if(!t)throw Error(`Workspace discovery returned an invalid result`);if(e.createWorkspace&&!workspaceMatchesRequestedIdentity(t,e))throw R({code:`WORKSPACE_CREATE_CONFLICT`,message:`The existing workspace does not match the requested workspace.`,suggestion:`Use the existing workspace, or run the explicit workspace create command to create another one.`,next:executableAction([`workspace`,`create`,...workspaceCommandArgs(e),...e.workspaceCommandJson?[`--json`]:[],`--name`,e.workspaceName??`<name>`,`--region`,e.workspaceRegion??`<region>`,...e.organizationId?[`--organization-id`,e.organizationId]:[],...e.folderId?[`--folder-id`,e.folderId]:[]]),context:{existingWorkspace:workspaceIdentity(t)}});return u&&!e.createWorkspace?chooseWorkspace(o,a,l,e):useWorkspace(o,a,t,e)}if(l.length>1){if(!u)throw R({code:`WORKSPACE_SELECTION_REQUIRED`,message:`Multiple workspaces are available.`,suggestion:`Choose one explicitly for non-interactive deployment.`,next:executableAction(selectDeployArgs(e)),context:{workspaces:l.map(workspaceIdentity)}});return chooseWorkspace(o,a,l,e)}throw Error(`Workspace discovery returned an invalid result`)}function collectExpectedLocalStaticWebsiteNames(e){let t=new Set;for(let n of e)for(let e of n.application.staticWebsiteServices)t.add(e.name);return t}async function shouldForceApplyAll(e,t,n,r){let i=(await buildMetaRequest({trn:resourceTrn(t,`application`,n.name),appName:n.name,appId:n.id})).labels,a=new Set;n.subgraphs.length>0&&a.add(resourceTrn(t,`application`,n.name)),n.staticWebsiteServices.forEach(e=>{a.add(resourceTrn(t,`staticwebsite`,e.name))}),n.aiGatewayServices.forEach(e=>{a.add(resourceTrn(t,`aigateway`,e.name))}),n.resolverServices.forEach(e=>{a.add(resourceTrn(t,`pipeline`,e.namespace))}),n.idpServices.forEach(e=>{a.add(resourceTrn(t,`idp`,e.name))}),n.authService&&a.add(resourceTrn(t,`auth`,n.authService.config.name)),Object.values(n.executorService?.executors??{}).forEach(e=>{a.add(resourceTrn(t,`executor`,e.name))}),Object.values(n.workflowService?.workflows??{}).forEach(e=>{a.add(resourceTrn(t,`workflow`,e.name))}),n.tailorDBServices.forEach(e=>{a.add(resourceTrn(t,`tailordb`,e.namespace))}),n.secrets.forEach(e=>{a.add(resourceTrn(t,`vault`,e.vaultName))}),r.forEach(e=>{a.add(resourceTrn(t,`function_registry`,e.name))});let o=await Promise.allSettled([...a].map(t=>I(async()=>{let{metadata:n}=await e.getMetadata({trn:t});return n})));if(o.some(e=>e.status===`fulfilled`&&e.value?.labels[`sdk-name`]===n.name&&!hasMatchingSdkVersion(e.value.labels,i)))return!0;let s=o.find(e=>e.status===`rejected`);if(s)throw s.reason;return!1}function recoveryEnvironmentArgs(e,t){return[...t?.envFile?[`--env-file`,B.resolve(process.cwd(),t.envFile)]:[],...t?.envFileIfExists?[`--env-file-if-exists`,B.resolve(process.cwd(),t.envFileIfExists)]:[],...e?.profile?[`--profile`,e.profile]:[]]}function recoveryOutputArgs(e){return[...e?.verbose?[`--verbose`]:[],...e?.json||M.jsonMode?[`--json`]:[]]}function retryDeployArgs(e,t,n){return[`deploy`,`--config`,t.join(`,`),...recoveryEnvironmentArgs(e,n),...e?.dryRun?[`--dry-run`]:[],...e?.yes?[`--yes`]:[],...e?.noSchemaCheck?[`--no-schema-check`]:[],...e?.noValidate?[`--no-validate`]:[],...e?.noCache?[`--no-cache`]:[],...e?.cleanCache?[`--clean-cache`]:[],...recoveryOutputArgs(n)]}function workspaceRecoveryArgs(e,t){return[...recoveryEnvironmentArgs(e,t),...t?.verbose?[`--verbose`]:[]]}function collectPlannedExternalTailorDBServices(e,t){let n=new Set(e.application.externalTailorDBNamespaces);return n.size===0?[]:t.flatMap(e=>e.application.tailorDBServices.filter(e=>n.has(e.namespace)))}function collectExternalAuthIdpConfigNames(e){let t=new Map;for(let n of e){let e=n.application.authService;if(!e)continue;let{name:r}=e.config,i=e.config.idProvider?.name;if(t.has(r)&&t.get(r)!==i)throw Error(`Auth namespace "${r}" is defined by multiple config files with different IdP configs. Auth namespace names must be unique across all configs in a single deploy.`);t.set(r,i)}return t}function collectDeployRunPlanInputs(e,t){let n=collectEventSubscriptions(e);return assertRecordableDependencies(n,t),{eventSubscriptions:n,runAppIds:new Set(e.map(e=>e.application.id).filter(e=>e!==void 0)),expectedLocalStaticWebsiteNames:collectExpectedLocalStaticWebsiteNames(e),externalAuthIdpConfigNames:collectExternalAuthIdpConfigNames(e)}}async function planDeploymentTarget(e){let{target:t,targets:n,runInputs:r,client:i,workspaceId:a,noSchemaCheck:o,migrationTestBaselines:s,migrationTestSnapshots:c}=e,{config:l,application:u,workflowBuildResult:d,httpAdapterBuildResult:f,bundledScripts:p}=t,m=ownedSubscriptions(r.eventSubscriptions,t),h=u.tailorDBServices.map(e=>{let t=c?.get(e.namespace);return t?{...e,types:t.tables,typeSourceInfo:{}}:e});await z(`plan.validateTailorDBTypeNames`,()=>rn({client:i,workspaceId:a,tailorDBServices:h,externalTailorDBNamespaces:u.externalTailorDBNamespaces,plannedExternalTailorDBServices:collectPlannedExternalTailorDBServices(t,n)}));let g=u.workflowService,_=collectFunctionEntries(u,filterBundledWorkflowJobs(g?.jobs??[],d?.usedJobNames??[]),p),v=await z(`plan.detectSdkVersionChange`,()=>shouldForceApplyAll(i,a,u,_));return z(`plan`,async()=>{let e=n.map(e=>e.application),p=collectVisibleTailorDBTypeNamespaces(u,e),h=collectVisibleResolverNamespaces(u,e),y=collectVisibleIdpNames(u,e),b={client:i,workspaceId:a,application:u,forRemoval:!1,config:l,noSchemaCheck:o,migrationTestBaselines:s,migrationTestSnapshots:c,forceApplyAll:v,...r,idpUserTriggerTargets:subscribedIdps(m),executorUsedTailorDBTables:subscribedTailorDBTables(m),executorUsedResolvers:subscribedResolvers(m),dependentApps:collectDependentApps(m),tailorDBTypeNamespaces:p,resolverNamespaces:h,idpNames:y},x=await z(`plan.functionRegistry`,()=>planFunctionRegistry(i,a,u.name,u.id,_)),S=new Set(x.changeSet.unchanged.filter(e=>e.name.startsWith(ki)).map(e=>e.name.slice(10))),[C,w,ee,te,ne,re,ie,ae,oe,se,ce]=await Promise.all([z(`plan.tailorDB`,()=>planTailorDB(b)),z(`plan.staticWebsite`,()=>planStaticWebsite(b)),z(`plan.aiGateway`,()=>planAIGateway(b)),z(`plan.idp`,()=>planIdP(b)),z(`plan.auth`,()=>planAuth(b)),z(`plan.pipeline`,()=>planPipeline(b)),z(`plan.application`,()=>planApplication(b,f)),z(`plan.executor`,()=>planExecutor(b)),z(`plan.workflow`,()=>planWorkflow(i,a,u.name,u.id,g?.workflows??{},d?.mainJobDeps??{},S,{...subscribedWorkflows(m),jobPublishEvents:collectWorkflowJobPublishEvents(t),dependentApps:b.dependentApps,runAppIds:b.runAppIds})),z(`plan.workflowExecutionPolicy`,()=>planWorkflowJobFunctionExecutionPolicy(i,a,u.name,u.id,l.workflow?.executionPolicies??{})),z(`plan.secretManager`,()=>planSecretManager(b))]);return{application:u,functionRegistry:x,tailorDB:C,staticWebsite:w,aiGateway:ee,idp:te,auth:ne,pipeline:re,app:ie,executor:ae,workflow:oe,workflowExecutionPolicy:se,secretManager:ce}})}async function planDeploymentTargets(e){let{targets:t,planTarget:n=planDeploymentTarget,...r}=e;return Promise.all(t.map(e=>n({...r,target:e,targets:t})))}async function confirmDeploymentPlans(e){let{deployments:t,yes:n,dryRun:r=!1,missingDependentApps:i=[]}=e;r||await confirmMigrationCheckpointRepairs(t.flatMap(e=>e.tailorDB.context.checkpointRepairs),n),await confirmMissingDependentApps(i,n);let a=new Set(t.map(e=>e.application.name)),o=collectDeploymentResourceOwners(t),s=new Set,c=[];for(let e of t){let t=deploymentPlanResults(e),r=collectOwnerConflicts(t);await confirmOwnerConflict(r,e.application.name,n,e.application.id),await confirmUnmanagedResources(collectUnmanagedResources(t),e.application.name,n),c.push(...collectImportantResourceDeletions(t));let i=computeRenamedAppDeletions({conflicts:r,resourceOwners:o,protectedAppNames:a});for(let t of i)s.has(t)||(s.add(t),e.app.deletes.push({name:t,request:{workspaceId:e.tailorDB.context.workspaceId,applicationName:t}}))}await confirmImportantResourceDeletion(c,n)}async function validateDeploymentPlans(e){for(let t of e)await validatePlan(deploymentPlanResults(t))}function adjustApplicationForMigrationTest(e,t){if(!t?.migrationTestSnapshots)return e;let n=t.migrationTestBaselines!==void 0,r=n&&e.authService?{...e.authService,userProfile:void 0}:e.authService,i={...e,executorService:n?void 0:e.executorService,authService:r,staticWebsiteServices:e.staticWebsiteServices.map(e=>({...e,customDomains:void 0})),get applications(){return[i]}};return i}async function deployInternal(e,n,r){return z(`deploy`,async i=>{i.setAttribute(`deploy.dry_run`,e?.dryRun??!1),un(),t();let a=parseDeployConfigPaths(e?.configPath),o=e?.dryRun??!1,s=e?.buildOnly??ct(process.env.TAILOR_DEPLOY_BUILD_ONLY)===!0,c=s?[]:await z(`config.preflight`,()=>Promise.all(a.map(e=>loadDeployConfig({configPath:e,dryRun:o,buildOnly:s})))),l=c.map(({config:e})=>e.path),u=c.map(({config:e})=>({configPath:e.path,applicationId:e.id??`name:${e.name}`})),d=s?void 0:await resolveDeployWorkspace({workspaceId:e?.workspaceId,profile:e?.profile,createWorkspace:e?.createWorkspace,workspaceName:e?.workspaceName,workspaceRegion:e?.workspaceRegion,organizationId:e?.organizationId,folderId:e?.folderId,dryRun:o,contextTargets:u,deployArgs:retryDeployArgs(e,l,n),workspaceCommandArgs:workspaceRecoveryArgs(e,n),workspaceCommandJson:n?.json||M.jsonMode}),f=await z(`build`,async()=>{let t=e?.noCache??!1,n=await pn(),r=B.resolve(Gt(),`cache`);return e?.cleanCache&&(W.rmSync(r,{recursive:!0,force:!0}),M.info(`Bundle cache cleaned`)),await buildDeploymentTargets({configPaths:a,loadedConfigs:c,dryRun:o,buildOnly:s,noCache:t,packageVersion:n.version??`unknown`,cacheDir:r})});if(s)return{bundledScripts:mergeBundledScripts(f)};if(assertUniqueGlobalResourceNames(f),!d)throw Error(`Workspace was not resolved`);let{client:p,workspaceId:m}=d;i.setAttribute(`app.name`,f.map(e=>e.application.name).join(`,`)),i.setAttribute(`workspace.id`,m);let h=f.map(e=>({...e,application:adjustApplicationForMigrationTest(e.application,r)})),g=await z(`plan.metadataLookup`,()=>createMetadataLookupClient({client:p,workspaceId:m,applications:h.map(({application:e})=>e)})),_=collectDeployRunPlanInputs(h,!e?.dryRun),v=await planDeploymentTargets({targets:h,runInputs:_,client:g,workspaceId:m,noSchemaCheck:e?.noSchemaCheck,migrationTestBaselines:r?.migrationTestBaselines,migrationTestSnapshots:r?.migrationTestSnapshots}),y=e?.yes??!1;dropCrossDeploymentManagedDeletes(v);let b=(await Promise.all(h.map(e=>fetchMissingDependentApps({client:g,workspaceId:m,application:e.application,runAppIds:_.runAppIds??new Set,subscribedKeys:subscribedResourceKeys(_.eventSubscriptions,e),jobsByWorkflow:e.workflowBuildResult?.mainJobDeps??{}})))).flat();await z(`confirm`,async()=>{await confirmDeploymentPlans({deployments:v,yes:y,dryRun:o,missingDependentApps:b})});let x=printDeploymentPlans(v,{dryRun:e?.dryRun});if(e?.noValidate?M.warn(`Client-side validation skipped (--no-validate).`):await validateDeploymentPlans(v),o){M.info(`Dry run enabled. No changes applied.`);return}await applyDeploymentPlans(p,m,v),r?.suppressResultOutput||(M.jsonMode?M.out({summary:x,status:`applied`}):M.success(`Successfully applied changes.`))})}function deploy(e){return deployInternal(e)}function deployMigrationTestBaseline(e,t,n){return deployInternal(e,void 0,{migrationTestBaselines:t,migrationTestSnapshots:n,suppressResultOutput:!0})}function deployMigrationTestTarget(e,t){return deployInternal(e,void 0,{migrationTestSnapshots:t,suppressResultOutput:!0})}function deployFromCLI(e,t){return deployInternal(e,t)}function colorizeExecutorJobStatus(e){switch(e){case`PENDING`:return N.dim(e);case`RUNNING`:return N.info(e);case`SUCCESS`:return N.success(e);case`FAILED`:return N.error(e);case`CANCELED`:return N.warning(e);default:return e}}function isExecutorJobTerminalStatus(e){return isExecutorJobSuccessStatus(e)||isExecutorJobFailureStatus(e)}function isExecutorJobSuccessStatus(e){return e===n.SUCCESS}function isExecutorJobFailureStatus(e){return e===n.FAILED||e===n.CANCELED}function isExecutorJobTransientStatus(e){return e===n.UNSPECIFIED||e===n.PENDING||e===n.RUNNING}function classifyExecutorJobStatus(e){return isExecutorJobSuccessStatus(e)?`success`:isExecutorJobTerminalStatus(e)?`failure`:(isExecutorJobTransientStatus(e),`transient`)}function parseExecutorJobStatus(e){switch(e.toUpperCase()){case`PENDING`:return n.PENDING;case`RUNNING`:return n.RUNNING;case`SUCCESS`:return n.SUCCESS;case`FAILED`:return n.FAILED;case`CANCELED`:return n.CANCELED;default:throw Error(`Invalid status: ${e}. Valid values: PENDING, RUNNING, SUCCESS, FAILED, CANCELED`)}}function colorizeFunctionExecutionStatus(e){switch(e){case`RUNNING`:return N.info(e);case`SUCCESS`:return N.success(e);case`FAILED`:return N.error(e);default:return e}}function isFunctionExecutionTerminalStatus(e){return e===h.SUCCESS||e===h.FAILED||e===h.CANCELED}function executorTargetTypeToString(e){switch(e){case T.WEBHOOK:return`WEBHOOK`;case T.TAILOR_GRAPHQL:return`GRAPHQL`;case T.FUNCTION:return`FUNCTION`;case T.JOB_FUNCTION:return`JOB_FUNCTION`;case T.WORKFLOW:return`WORKFLOW`;default:return`UNSPECIFIED`}}function executorTriggerTypeToString(e){switch(e){case O.SCHEDULE:return`SCHEDULE`;case O.EVENT:return`EVENT`;case O.INCOMING_WEBHOOK:return`INCOMING_WEBHOOK`;default:return`UNSPECIFIED`}}function executorJobStatusToString(e){switch(e){case n.PENDING:return`PENDING`;case n.RUNNING:return`RUNNING`;case n.SUCCESS:return`SUCCESS`;case n.FAILED:return`FAILED`;case n.CANCELED:return`CANCELED`;default:return`UNSPECIFIED`}}function toExecutorJobListInfo(e){return{id:e.id,executorName:e.executorName,status:executorJobStatusToString(e.status),createdAt:e.createdAt?G(e.createdAt).toISOString():`N/A`}}function toExecutorJobInfo(e){return{id:e.id,executorName:e.executorName,status:executorJobStatusToString(e.status),scheduledAt:e.scheduledAt?G(e.scheduledAt).toISOString():`N/A`,createdAt:e.createdAt?G(e.createdAt).toISOString():`N/A`,updatedAt:e.updatedAt?G(e.updatedAt).toISOString():`N/A`}}function toExecutorJobAttemptInfo(e){return{id:e.id,jobId:e.jobId,status:executorJobStatusToString(e.status),error:e.error||``,startedAt:e.startedAt?G(e.startedAt).toISOString():`N/A`,finishedAt:e.finishedAt?G(e.finishedAt).toISOString():`N/A`,operationReference:e.operationReference||``}}function formatSubjectEvent(e,t){let n=t.map(e=>e.split(`.`).at(-1)??e).join(`, `);return n?`event: ${e} ${n}`:`event: ${e}`}function formatTypedEventTrigger(e){let t=e.typedConfig;if(t.case===void 0)return null;switch(t.case){case`tailordb`:return formatSubjectEvent(t.value.typeName,t.value.eventTypes);case`pipeline`:return formatSubjectEvent(t.value.resolverName,t.value.eventTypes);case`idp`:return formatSubjectEvent(`idp user`,t.value.eventTypes);case`auth`:return formatSubjectEvent(`auth access_token`,t.value.eventTypes);default:return null}}function formatTriggerType(e){let t=e.triggerConfig?.config;if(!t||t.case===void 0)return executorTriggerTypeToString(e.triggerType);switch(t.case){case`schedule`:return`schedule: ${t.value.frequency} (${t.value.timezone})`;case`event`:{let n=formatTypedEventTrigger(t.value);if(n)return n;let r=readLegacyEventTriggerConfig(t.value);return r.eventType?formatEventTrigger(r.eventType,r.condition):executorTriggerTypeToString(e.triggerType)}case`incomingWebhook`:return`webhook`;default:return executorTriggerTypeToString(e.triggerType)}}function readLegacyEventTriggerConfig(e){return{eventType:e.eventType,condition:e.condition?.expr}}function formatEventTrigger(e,t){let n=e.split(`.`);if(n.length<3)return`event: ${e}`;let[r,i,a]=n;if(t){let e=t.match(/args\.typeName\s*===?\s*["']([^"']+)["']/);if(e)return`event: ${e[1]} ${a}`;let n=t.match(/args\.resolverName\s*===?\s*["']([^"']+)["']/);if(n)return`event: ${n[1]} ${a}`}return`event: ${r} ${i} ${a}`}function formatTriggerConfig(e){let t=e.triggerConfig?.config;if(!t||t.case===void 0)return{};switch(t.case){case`schedule`:return{timezone:t.value.timezone,frequency:t.value.frequency};case`event`:return formatEventTriggerConfig(t.value);case`incomingWebhook`:return{secret:t.value.secret?`***`:``};default:return{}}}function formatEventTriggerConfig(e){let t=e.typedConfig;if(t.case===void 0){let t=readLegacyEventTriggerConfig(e);return{eventType:t.eventType,condition:t.condition||``}}if(t.case===`workflow`)return{kind:t.case,eventTypes:t.value.eventTypes,condition:t.value.condition?.expr||``,...t.value.workflowName&&{workflowName:t.value.workflowName}};let n={kind:t.case,eventTypes:t.value.eventTypes,namespaceName:t.value.namespaceName,condition:t.value.condition?.expr||``};switch(t.case){case`tailordb`:return{...n,typeName:t.value.typeName};case`pipeline`:return{...n,resolverName:t.value.resolverName};default:return n}}function formatTargetConfig(e){let t=e.targetConfig?.config;if(!t||t.case===void 0)return{};switch(t.case){case`webhook`:return{url:t.value.url?.expr||``,headers:t.value.headers.length};case`tailorGraphql`:return{appName:t.value.appName,query:t.value.query};case`function`:return{name:t.value.name};case`workflow`:return{workflowName:t.value.workflowName};default:return{}}}function toExecutorListInfo(e){return{name:e.name,triggerType:formatTriggerType(e),targetType:executorTargetTypeToString(e.targetType),disabled:e.disabled}}function toExecutorInfo(e){return{name:e.name,description:e.description,triggerType:formatTriggerType(e),targetType:executorTargetTypeToString(e.targetType),disabled:e.disabled,triggerConfig:formatTriggerConfig(e),targetConfig:formatTargetConfig(e)}}const Ho={name:V(H.string(),{positional:!0,description:`Executor name`})};async function resolveExecutor(e,t,n){let{executor:r}=await e.getExecutorExecutor({workspaceId:t,name:n});if(!r)throw Error(`Executor '${n}' not found.`);return r}async function getExecutor(e){let t=e.executor.name,{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});try{return toExecutorInfo(await resolveExecutor(n,r,t))}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Executor '${t}' not found.`,{cause:e}):e}}const Uo=X({name:`get`,description:`Get executor details`,args:H.strictObject({...Y,...Ho}),run:async e=>{let t=await getExecutor({executor:{name:e.name},workspaceId:e[`workspace-id`],profile:e.profile});M.out(t,{display:{triggerConfig:null,targetConfig:null}})}});function functionExecutionStatusToString(e){switch(e){case h.RUNNING:return`RUNNING`;case h.SUCCESS:return`SUCCESS`;case h.FAILED:return`FAILED`;case h.SUSPEND:return`SUSPEND`;case h.CANCELING:return`CANCELING`;case h.CANCELED:return`CANCELED`;default:return`UNSPECIFIED`}}function formatWaitError(e){return e instanceof Error?e.message:String(e)}function isRetryableWaitError(e){return e instanceof q?e.code===K.Aborted||e.code===K.ResourceExhausted||e.code===K.Unavailable:!1}const Wo=H.enum([`success`,`suspended`,`terminal`]),Go={name:V(H.string(),{positional:!0,description:`Workflow name`})},Ko={interval:V(Ir.default(`3s`),{alias:`i`,description:`Polling interval when waiting (e.g., '3s', '500ms', '1m')`}),timeout:V(Ir.default(`10m`),{alias:`t`,description:`Maximum time to wait (e.g., '30s', '10m')`}),until:V(Wo.default(`terminal`),{alias:`u`,description:`Wait target (success, suspended, terminal)`}),logs:V(H.boolean().default(!1),{alias:`l`,description:`Display job execution logs after completion`})},qo={wait:V(H.boolean().default(!1),{alias:`W`,description:`Wait for execution to complete`}),...Ko};function isWorkflowExecutionSuccessStatus(e){return e===D.SUCCESS}function isWorkflowJobExecutionSuspendedStatus(e){return e===Qe.SUSPEND||e===Qe.WAITING}function isWorkflowExecutionSuspendedStatus(e){return e===D.PENDING_RESUME||e===D.WAITING}function isWorkflowExecutionFailureStatus(e){return e===D.FAILED}function isWorkflowExecutionTransientStatus(e){return e===D.UNSPECIFIED||e===D.PENDING||e===D.RUNNING||e===D.PENDING_RETRY}function isWorkflowExecutionTerminalStatus(e){return isWorkflowExecutionSuccessStatus(e)||isWorkflowExecutionFailureStatus(e)||isWorkflowExecutionSuspendedStatus(e)}function classifyWorkflowExecutionStatus(e){return isWorkflowExecutionTerminalStatus(e.status)?isWorkflowExecutionSuccessStatus(e.status)?{statusClass:`success`,status:e.status}:isWorkflowExecutionFailureStatus(e.status)?{statusClass:`failure`,status:e.status}:{statusClass:`suspended`,status:e.status}:e.jobExecutions.some(e=>isWorkflowJobExecutionSuspendedStatus(e.status))?{statusClass:`suspended`,status:e.status}:(isWorkflowExecutionTransientStatus(e.status),{statusClass:`transient`,status:e.status})}function hasReachedWorkflowWaitTarget(e,t){switch(t){case`success`:return e.statusClass===`success`;case`suspended`:return e.statusClass===`suspended`;case`terminal`:return e.statusClass===`success`||e.statusClass===`failure`||e.statusClass===`suspended`}}function workflowExecutionStatusToString(e){switch(e){case D.PENDING:return`PENDING`;case D.PENDING_RESUME:return`PENDING_RESUME`;case D.RUNNING:return`RUNNING`;case D.SUCCESS:return`SUCCESS`;case D.FAILED:return`FAILED`;case D.PENDING_RETRY:return`PENDING_RETRY`;case D.WAITING:return`WAITING`;default:return`UNSPECIFIED`}}function workflowJobExecutionStatusToString(e){switch(e){case Qe.RUNNING:return`RUNNING`;case Qe.SUSPEND:return`SUSPEND`;case Qe.SUCCESS:return`SUCCESS`;case Qe.FAILED:return`FAILED`;case Qe.WAITING:return`WAITING`;default:return`UNSPECIFIED`}}function toWorkflowListInfo(e){return{name:e.name,mainJob:e.mainJobFunctionName,jobFunctions:Object.keys(e.jobFunctions).length,updatedAt:e.updatedAt?G(e.updatedAt):null}}function toWorkflowInfo(e){let t={};for(let[n,r]of Object.entries(e.jobFunctions))t[n]=r.toString();return{name:e.name,id:e.id,mainJob:e.mainJobFunctionName,jobFunctions:t,createdAt:e.createdAt?G(e.createdAt):null,updatedAt:e.updatedAt?G(e.updatedAt):null}}function toWorkflowJobExecutionInfo(e){return{id:e.id,stackedJobName:e.stackedJobName,status:workflowJobExecutionStatusToString(e.status),executionId:e.executionId,startedAt:e.startedAt?G(e.startedAt):null,finishedAt:e.finishedAt?G(e.finishedAt):null}}function toWorkflowExecutionInfo(e){return{id:e.id,workflowName:e.workflowName,status:workflowExecutionStatusToString(e.status),jobExecutions:e.jobExecutions.length,startedAt:e.startedAt?G(e.startedAt):null,finishedAt:e.finishedAt?G(e.finishedAt):null}}function formatTime$1(e){return e.toLocaleTimeString(`en-US`,{hour12:!1})}function colorizeStatus(e){let t=D[e];switch(e){case D.PENDING:case D.UNSPECIFIED:return N.dim(t);case D.PENDING_RESUME:case D.PENDING_RETRY:case D.WAITING:return N.warning(t);case D.RUNNING:return N.info(t);case D.SUCCESS:return N.success(t);case D.FAILED:return N.error(t);default:return t}}function getActiveJobs(e){return e.jobExecutions.filter(e=>e.status===Qe.RUNNING||e.status===Qe.SUSPEND||e.status===Qe.WAITING).map(e=>e.stackedJobName).join(`, `)}function createWorkflowWaitResult(e){let t=Date.now()-e.startedAt;if(e.execution){let n=classifyWorkflowExecutionStatus(e.execution);return{...toWorkflowExecutionInfo(e.execution),statusClass:n.statusClass,elapsedMs:t,attempts:e.attempts,timedOut:e.timedOut,lastError:e.lastError}}return{id:e.executionId,workflowName:``,status:`UNKNOWN`,statusClass:`unknown`,jobExecutions:0,startedAt:null,finishedAt:null,elapsedMs:t,attempts:e.attempts,timedOut:e.timedOut,lastError:e.lastError}}async function waitForWorkflowExecution(e){let t=e.interval??3e3,n=e.until??`terminal`,r=Date.now(),i=e.showProgress?spinner({indent:2}).start(`Waiting for workflow to complete...`):null,a=0,o,s=null,c,l;try{for(;;){let u=Date.now()-r,d=e.timeout===void 0?void 0:e.timeout-u;if(d!==void 0&&d<=0)return i?.fail(`Workflow wait timed out.`),createWorkflowWaitResult({executionId:e.executionId,execution:o,startedAt:r,attempts:a,timedOut:!0,lastError:s});try{a+=1;let{execution:t}=await e.client.getWorkflowExecution({workspaceId:e.workspaceId,executionId:e.executionId});if(!t)throw i?.fail(`Execution '${e.executionId}' not found.`),Error(`Execution '${e.executionId}' not found.`);o=t,s=null;let u=classifyWorkflowExecutionStatus(t),d=colorizeStatus(t.status);if(t.status!==c&&(e.showProgress&&(i?.stop(),M.info(`Status: ${d}`,{mode:`stream`,indent:2}),i?.start(`Waiting for workflow to complete...`)),c=t.status),e.trackJobs){let n=getActiveJobs(t);n&&n!==l&&(e.showProgress&&(i?.stop(),M.info(`Job | ${n}: ${d}`,{mode:`stream`,indent:2}),i?.start(`Waiting for workflow to complete...`)),l=n)}if(i&&(i.text=`Waiting for workflow to complete... (${formatTime$1(new Date)})`),hasReachedWorkflowWaitTarget(u,n)||u.statusClass===`failure`||n===`suspended`&&u.statusClass===`success`)return t.status===D.SUCCESS?i?.succeed(`Completed: ${d}`):isWorkflowExecutionFailureStatus(t.status)?i?.fail(`Completed: ${d}`):isWorkflowExecutionSuspendedStatus(t.status)?i?.warn(`Completed: ${d}`):i?.succeed(`Completed: ${d}`),createWorkflowWaitResult({executionId:e.executionId,execution:t,startedAt:r,attempts:a,timedOut:!1,lastError:s})}catch(t){if(!isRetryableWaitError(t))throw t;s=formatWaitError(t),e.showProgress&&i&&(i.text=`Retrying workflow status poll... (${formatTime$1(new Date)})`)}let f=Date.now()-r,p=e.timeout===void 0?void 0:e.timeout-f;if(p!==void 0&&p<=0)return i?.fail(`Workflow wait timed out.`),createWorkflowWaitResult({executionId:e.executionId,execution:o,startedAt:r,attempts:a,timedOut:!0,lastError:s});await Er(p===void 0?t:Math.min(t,p))}}finally{i?.stop()}}async function waitForWorkflowExecutionById(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});return await waitForWorkflowExecution({client:t,workspaceId:n,executionId:e.executionId,interval:e.interval,timeout:e.timeout,until:e.until,showProgress:e.showProgress,trackJobs:e.trackJobs})}function getWorkflowWaitFailureMessage(e,t){if(e.timedOut)return`Timed out waiting for workflow execution '${e.id}' to reach ${t}. Last status: ${e.status}.`;if(e.status===`FAILED`)return`Workflow execution '${e.id}' failed.`;if(t===`success`&&e.statusClass!==`success`)return`Workflow execution '${e.id}' reached ${e.status} before success.`;if(t===`suspended`&&e.statusClass!==`suspended`)return`Workflow execution '${e.id}' reached ${e.status} before suspension.`}function parseStatus(e){switch(e.toUpperCase()){case`PENDING`:return D.PENDING;case`PENDING_RESUME`:return D.PENDING_RESUME;case`RUNNING`:return D.RUNNING;case`SUCCESS`:return D.SUCCESS;case`FAILED`:return D.FAILED;case`PENDING_RETRY`:return D.PENDING_RETRY;case`WAITING`:return D.WAITING;case`UNSPECIFIED`:return D.UNSPECIFIED;default:throw Error(`Invalid status: ${e}. Valid values: UNSPECIFIED, PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED, PENDING_RETRY, WAITING`)}}async function listWorkflowExecutions(e){let t=e?.workflow?.name,{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),i=[];if(e?.status){let t=parseStatus(e.status);i.push(U(Re,{condition:U(we,{field:`status`,operator:Ze.EQ,value:{kind:{case:`numberValue`,value:t}}})}))}let a=i.length>0?U(Re,{and:i}):void 0,o=toPageDirection(e?.order??`desc`);return(await jt(async(e,i)=>{let{executions:s,nextPageToken:c}=await n.listWorkflowExecutions({workspaceId:r,workflowName:t??``,pageToken:e,pageSize:i,pageDirection:o,filter:a});return[s,c]},{limit:e?.limit})).map(toWorkflowExecutionInfo)}async function getWorkflowExecution(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});async function fetchFunctionExecution(e){try{let r=U(Re,{condition:U(we,{field:`id`,operator:Ze.EQ,value:{kind:{case:`stringValue`,value:e}}})});return(await t.listFunctionExecutions({workspaceId:n,filter:r,pageSize:1})).executions[0]}catch{return}}async function fetchExecutionWithLogs(e,r){let{execution:i}=await t.getWorkflowExecution({workspaceId:n,executionId:e});if(!i)throw Error(`Execution '${e}' not found.`);let a=toWorkflowExecutionInfo(i);return r&&i.jobExecutions.length>0&&(a.jobDetails=await Promise.all(i.jobExecutions.map(async e=>{let t=toWorkflowJobExecutionInfo(e);if(e.executionId){let n=await fetchFunctionExecution(e.executionId);if(n)return{...t,logs:n.logs||void 0,result:n.result||void 0}}return t}))),a}async function waitForCompletion(){let r=e.interval??3e3,i=await waitForWorkflowExecution({client:t,workspaceId:n,executionId:e.executionId,interval:r,timeout:e.timeout,until:e.until??`terminal`});return{...await fetchExecutionWithLogs(e.executionId,e.logs??!1),statusClass:i.statusClass,elapsedMs:i.elapsedMs,attempts:i.attempts,timedOut:i.timedOut,lastError:i.lastError}}return{execution:await fetchExecutionWithLogs(e.executionId,e.logs??!1),wait:waitForCompletion}}function printExecutionWithLogs(e){let formatDate=e=>e?e.toISOString():`N/A`,t=[[`id`,e.id],[`workflowName`,e.workflowName],[`status`,e.status],[`jobExecutions`,e.jobExecutions.toString()],[`startedAt`,formatDate(e.startedAt)],[`finishedAt`,formatDate(e.finishedAt)]];if(M.out(formatKeyValueTable(t)),e.jobDetails&&e.jobDetails.length>0){M.log(N.bold(`
|
|
131
131
|
Job Executions:`));for(let t of e.jobDetails){if(M.log(N.info(`\n--- ${t.stackedJobName} ---`)),M.log(` Status: ${t.status}`),M.log(` Started: ${formatDate(t.startedAt)}`),M.log(` Finished: ${formatDate(t.finishedAt)}`),t.logs){M.log(N.warning(`
|
|
132
132
|
Logs:`));let e=t.logs.split(`
|
|
133
133
|
`);for(let t of e)M.log(` ${t}`)}if(t.result){M.log(N.success(`
|
|
134
134
|
Result:`));try{let e=JSON.parse(t.result);M.log(` ${JSON.stringify(e,null,2).split(`
|
|
135
135
|
`).join(`
|
|
136
|
-
`)}`)}catch{M.log(` ${t.result}`)}}}}}const Jo=X({name:`executions`,description:`List or get workflow executions.`,args:H.strictObject({...Y,...qr,"execution-id":V(H.string().optional(),{positional:!0,description:`Execution ID (if provided, shows details)`}),"workflow-name":V(H.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/,`Must be 3-63 lowercase alphanumeric characters or hyphens, starting and ending with alphanumeric`).optional(),{alias:`n`,description:`Filter by workflow name (list mode only)`}),status:V(H.string().optional(),{alias:`s`,description:`Filter by status (list mode only)`}),...qo,logs:V(H.boolean().default(!1),{description:`Display job execution logs (detail mode only)`})}),run:async e=>{let t=M.jsonMode||e.json;if(e.executionId){let n=parseDuration(e.interval);if(t||M.info(`Execution ID: ${e.executionId}`,{mode:`stream`}),e.wait){let r=await waitForWorkflowExecutionById({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:n,timeout:parseDuration(e.timeout),until:e.until,showProgress:!t,trackJobs:!0});if(e.logs&&!t){let{execution:t}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(t)}else if(e.logs){let{execution:t}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0}),n={...r,jobDetails:t.jobDetails};M.out(n)}else M.out(r);let i=getWorkflowWaitFailureMessage(r,e.until);if(i)throw Error(i);return}let{execution:r}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:n,logs:e.logs});e.logs&&!t?printExecutionWithLogs(r):M.out(r)}else{let t=await listWorkflowExecutions({workspaceId:e[`workspace-id`],profile:e.profile,workflow:e[`workflow-name`]===void 0?void 0:{name:e[`workflow-name`]},status:e.status,order:e.order,limit:e.limit});M.out(t)}}});async function resolveWorkflow(e,t,n){let{workflow:r}=await e.getWorkflowByName({workspaceId:t,workflowName:n});if(!r)throw Error(`Workflow '${n}' not found.`);return r}async function getWorkflow(e){let t=e.workflow.name,n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile});try{return toWorkflowInfo(await resolveWorkflow(r,i,t))}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workflow '${t}' not found.`,{cause:e}):e}}const Yo=X({name:`get`,description:`Get workflow details.`,args:H.strictObject({...Y,...Go}),run:async e=>{let t=await getWorkflow({workflow:{name:e.name},workspaceId:e[`workspace-id`],profile:e.profile});M.out(t)}});async function startWorkflowCore(e){let{client:t,workspaceId:n,workflowName:r}=e;try{let i=await resolveWorkflow(t,n,r),a=U(C,e.invoker),o=e.arg===void 0?void 0:typeof e.arg==`string`?e.arg:JSON.stringify(e.arg),{executionId:s}=await t.testStartWorkflow({workspaceId:n,workflowId:i.id,authInvoker:a,arg:o});return{executionId:s,wait:r=>waitForWorkflowExecution({client:t,workspaceId:n,executionId:s,interval:e.interval??3e3,timeout:r?.timeout,until:r?.until,showProgress:r?.showProgress,trackJobs:!0})}}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workflow '${r}' not found.`,{cause:e}):e}}async function resolveApplicationAuthNamespace(e){let{config:t}=await loadConfig(e.configPath),{application:n}=await e.client.getApplication({workspaceId:e.workspaceId,applicationName:t.name}),r=n?.authNamespace||t.auth?.name;if(!r)throw Error(`Application ${t.name} does not have an auth configuration.`);return r}async function startWorkflowByName(e){let t=await loadMachineUserName({machineUser:e.machineUser,machineUserSource:e.machineUserSource,profile:e.profile});if(!t)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 n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),a=await resolveApplicationAuthNamespace({client:r,workspaceId:i,configPath:e.configPath});return await startWorkflowCore({client:r,workspaceId:i,workflowName:e.name,invoker:{namespace:a,machineUserName:t},arg:e.arg,interval:e.interval})}async function startWorkflow(e){let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),i=await resolveApplicationAuthNamespace({client:n,workspaceId:r,configPath:e.configPath});return await startWorkflowCore({client:n,workspaceId:r,workflowName:e.workflow.name,invoker:{namespace:i,machineUserName:e.invoker},arg:e.arg,interval:e.interval})}const Xo=X({name:`start`,description:`Start a workflow execution.`,args:H.strictObject({...Wr,...Go,"machine-user":V(H.string().optional(),{alias:`m`,description:`Machine user name. Falls back to the active profile's default machine user.`,env:`TAILOR_PLATFORM_MACHINE_USER_NAME`}),arg:V(H.string().optional(),{alias:`a`,description:`Workflow argument (JSON string)`}),...qo}),run:async e=>{let{executionId:t,wait:n}=await startWorkflowByName({name:e.name,machineUser:e[`machine-user`],machineUserSource:resolveMachineUserInputSource(e[`machine-user`]),arg:e.arg,workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,interval:parseDuration(e.interval)}),r=M.jsonMode;if(M.info(`Execution ID: ${t}`,{mode:`stream`}),e.wait){let i=await n({showProgress:!r,timeout:parseDuration(e.timeout),until:e.until});if(e.logs&&!r){let{execution:n}=await getWorkflowExecution({executionId:t,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(n)}else if(e.logs){let{execution:n}=await getWorkflowExecution({executionId:t,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});M.out({...i,jobDetails:n.jobDetails})}else M.out(i);let a=getWorkflowWaitFailureMessage(i,e.until);if(a)throw Error(a)}else M.out({executionId:t})}});function formatTime(e){return e.toLocaleTimeString(`en-US`,{hour12:!1})}function createUnknownExecutorJob(e,t){return{id:t,executorName:e,status:`UNKNOWN`,scheduledAt:`N/A`,createdAt:`N/A`,updatedAt:`N/A`}}async function listExecutorJobs(e){let t=e.executor.name,n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),a=[];if(e.status){let t=parseExecutorJobStatus(e.status);a.push(U(Re,{condition:U(we,{field:`status`,operator:Ze.EQ,value:{kind:{case:`numberValue`,value:t}}})}))}let o=a.length>0?U(Re,{and:a}):void 0,s=toPageDirection(e.order??`desc`);try{return(await jt(async(e,n)=>{let{jobs:a,nextPageToken:c}=await r.listExecutorJobs({workspaceId:i,executorName:t,pageToken:e,pageSize:n,pageDirection:s,filter:o});return[a,c]},{limit:e.limit})).map(toExecutorJobListInfo)}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Executor '${t}' not found.`,{cause:e}):e}}async function getExecutorJob(e){let t=e.executor.name,n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile});try{let{job:n}=await r.getExecutorJob({workspaceId:i,executorName:t,jobId:e.jobId});if(!n)throw Error(`Job '${e.jobId}' not found.`);let a=toExecutorJobInfo(n);if(e.attempts){let t=await At(async(t,n)=>{let{attempts:a,nextPageToken:o}=await r.listExecutorJobAttempts({workspaceId:i,jobId:e.jobId,pageToken:t,pageSize:n,pageDirection:Ke.DESC});return[a,o]});return{...a,attempts:t.map(toExecutorJobAttemptInfo)}}return a}catch(n){throw n instanceof q&&n.code===K.NotFound?Error(`Job '${e.jobId}' not found for executor '${t}'.`,{cause:n}):n}}async function watchExecutorJob(e){let t=e.executor.name,r=await loadAccessToken({profile:e.profile}),i=await F(r),a=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),o=e.interval??3e3,s=e.timeout,c=e.showProgress??!M.jsonMode,l=Date.now(),u=c?spinner().start(`Waiting for executor job to complete...`):null,d=0,f=null,remainingTimeout=()=>{if(s!==void 0)return s-(Date.now()-l)},withWaitMetadata=(e,t)=>({...e,elapsedMs:Date.now()-l,attempts:d,timedOut:t,lastError:f}),timeoutResult=(n,r)=>withWaitMetadata({job:r?toExecutorJobInfo(r):createUnknownExecutorJob(t,e.jobId),targetType:n},!0);try{let{executor:r}=await i.getExecutorExecutor({workspaceId:a,name:t});if(!r)throw Error(`Executor '${t}' not found.`);let s=r.targetType,l=executorTargetTypeToString(s),p;for(;;){let n=remainingTimeout();if(n!==void 0&&n<=0)return u?.fail(`Executor job wait timed out.`),timeoutResult(l,p);try{if(d+=1,p=(await i.getExecutorJob({workspaceId:a,executorName:t,jobId:e.jobId})).job,!p)throw Error(`Job '${e.jobId}' not found.`);if(f=null,classifyExecutorJobStatus(p.status)!==`transient`)break}catch(e){if(!isRetryableWaitError(e))throw e;f=formatWaitError(e),u&&(u.text=`Retrying executor job poll... (${formatTime(new Date)})`)}let r=remainingTimeout();if(r!==void 0&&r<=0)return u?.fail(`Executor job wait timed out.`),timeoutResult(l,p);u&&(u.text=`Waiting for executor job... (${formatTime(new Date)})`),await Tr(r===void 0?o:Math.min(o,r))}let m=toExecutorJobInfo(p),g=colorizeExecutorJobStatus(m.status);p.status===n.SUCCESS?u?.succeed(`Executor job completed: ${g}`):u?.fail(`Executor job completed: ${g}`);let _=(await At(async(t,n)=>{let{attempts:r,nextPageToken:o}=await i.listExecutorJobAttempts({workspaceId:a,jobId:e.jobId,pageToken:t,pageSize:n,pageDirection:Ke.DESC});return[r,o]})).map(toExecutorJobAttemptInfo),v={...m,attempts:_},y=_[0]?.operationReference;if(y)switch(s){case T.WORKFLOW:u?.stop();try{let t=remainingTimeout();if(t!==void 0&&t<=0)return withWaitMetadata({job:v,targetType:l,workflowExecutionId:y},!0);let n=await waitForWorkflowExecution({client:i,workspaceId:a,executionId:y,interval:o,timeout:t,showProgress:c,trackJobs:!0});d+=n.attempts,f=n.lastError;let r;if(e.logs)try{let{execution:t}=await getWorkflowExecution({executionId:y,workspaceId:e.workspaceId,profile:e.profile,logs:!0});t.jobDetails&&(r=t.jobDetails.filter(e=>e.logs||e.result).map(e=>({jobName:e.stackedJobName||e.id,logs:e.logs,result:e.result})))}catch(e){M.warn(`Could not fetch workflow execution logs: ${e instanceof Error?e.message:e}`)}return withWaitMetadata({job:v,targetType:l,workflowExecutionId:y,workflowStatus:n.status,workflowJobLogs:r},n.timedOut)}catch(e){return M.warn(`Could not track workflow execution: ${e instanceof Error?e.message:e}`),withWaitMetadata({job:v,targetType:l,workflowExecutionId:y},!1)}case T.FUNCTION:case T.JOB_FUNCTION:u?.start(`Waiting for function execution ${y}...`);try{let t;for(;;){let n=remainingTimeout();if(n!==void 0&&n<=0)return u?.fail(`Function execution wait timed out.`),withWaitMetadata({job:v,targetType:l,functionExecutionId:y,functionStatus:t},!0);try{d+=1;let{execution:n}=await i.getFunctionExecution({workspaceId:a,executionId:y});if(!n)throw Error(`Function execution '${y}' not found.`);if(f=null,t=functionExecutionStatusToString(n.status),isFunctionExecutionTerminalStatus(n.status)){let r=colorizeFunctionExecutionStatus(t);return n.status===h.SUCCESS?u?.succeed(`Function execution completed: ${r}`):u?.fail(`Function execution completed: ${r}`),withWaitMetadata({job:v,targetType:l,functionExecutionId:y,functionStatus:t,functionLogs:e.logs&&n.logs||void 0},!1)}}catch(e){if(!isRetryableWaitError(e))throw e;f=formatWaitError(e),u&&(u.text=`Retrying function execution poll... (${formatTime(new Date)})`)}let r=remainingTimeout();if(r!==void 0&&r<=0)return u?.fail(`Function execution wait timed out.`),withWaitMetadata({job:v,targetType:l,functionExecutionId:y,functionStatus:t},!0);u&&(u.text=`Waiting for function execution... (${formatTime(new Date)})`),await Tr(r===void 0?o:Math.min(o,r))}}catch(e){return u?.warn(`Could not track function execution: ${e instanceof Error?e.message:e}`),withWaitMetadata({job:v,targetType:l,functionExecutionId:y},!1)}}return withWaitMetadata({job:v,targetType:l},!1)}finally{u?.stop()}}function getExecutorWaitFailureMessage(e){if(e.timedOut)return`Timed out waiting for executor job '${e.job.id}'. Last status: ${e.job.status}.`;if(e.job.status===`FAILED`||e.job.status===`CANCELED`)return`Executor job '${e.job.id}' completed with status ${e.job.status}.`;if(e.workflowStatus===`FAILED`)return`Workflow execution '${e.workflowExecutionId}' failed.`;if(e.functionStatus===`FAILED`)return`Function execution '${e.functionExecutionId}' failed.`;if(e.functionStatus===`CANCELED`)return`Function execution '${e.functionExecutionId}' was canceled.`}function printJobWithAttempts(e){let t=[[`id`,e.id],[`executorName`,e.executorName],[`status`,e.status],[`scheduledAt`,e.scheduledAt],[`createdAt`,e.createdAt],[`updatedAt`,e.updatedAt]];if(M.log(formatKeyValueTable(t)),e.attempts&&e.attempts.length>0){M.log(N.bold(`
|
|
136
|
+
`)}`)}catch{M.log(` ${t.result}`)}}}}}const Jo=X({name:`executions`,description:`List or get workflow executions.`,args:H.strictObject({...Y,...qr,"execution-id":V(H.string().optional(),{positional:!0,description:`Execution ID (if provided, shows details)`}),"workflow-name":V(H.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/,`Must be 3-63 lowercase alphanumeric characters or hyphens, starting and ending with alphanumeric`).optional(),{alias:`n`,description:`Filter by workflow name (list mode only)`}),status:V(H.string().optional(),{alias:`s`,description:`Filter by status (list mode only)`}),...qo,logs:V(H.boolean().default(!1),{description:`Display job execution logs (detail mode only)`})}),run:async e=>{let t=M.jsonMode||e.json;if(e.executionId){let n=parseDuration(e.interval);if(t||M.info(`Execution ID: ${e.executionId}`,{mode:`stream`}),e.wait){let r=await waitForWorkflowExecutionById({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:n,timeout:parseDuration(e.timeout),until:e.until,showProgress:!t,trackJobs:!0});if(e.logs&&!t){let{execution:t}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(t)}else if(e.logs){let{execution:t}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0}),n={...r,jobDetails:t.jobDetails};M.out(n)}else M.out(r);let i=getWorkflowWaitFailureMessage(r,e.until);if(i)throw Error(i);return}let{execution:r}=await getWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:n,logs:e.logs});e.logs&&!t?printExecutionWithLogs(r):M.out(r)}else{let t=await listWorkflowExecutions({workspaceId:e[`workspace-id`],profile:e.profile,workflow:e[`workflow-name`]===void 0?void 0:{name:e[`workflow-name`]},status:e.status,order:e.order,limit:e.limit});M.out(t)}}});async function resolveWorkflow(e,t,n){let{workflow:r}=await e.getWorkflowByName({workspaceId:t,workflowName:n});if(!r)throw Error(`Workflow '${n}' not found.`);return r}async function getWorkflow(e){let t=e.workflow.name,{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});try{return toWorkflowInfo(await resolveWorkflow(n,r,t))}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workflow '${t}' not found.`,{cause:e}):e}}const Yo=X({name:`get`,description:`Get workflow details.`,args:H.strictObject({...Y,...Go}),run:async e=>{let t=await getWorkflow({workflow:{name:e.name},workspaceId:e[`workspace-id`],profile:e.profile});M.out(t)}});async function startWorkflowCore(e){let{client:t,workspaceId:n,workflowName:r}=e;try{let i=await resolveWorkflow(t,n,r),a=U(C,e.invoker),o=e.arg===void 0?void 0:typeof e.arg==`string`?e.arg:JSON.stringify(e.arg),{executionId:s}=await t.startWorkflow({workspaceId:n,workflowId:i.id,authInvoker:a,arg:o});return{executionId:s,wait:r=>waitForWorkflowExecution({client:t,workspaceId:n,executionId:s,interval:e.interval??3e3,timeout:r?.timeout,until:r?.until,showProgress:r?.showProgress,trackJobs:!0})}}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workflow '${r}' not found.`,{cause:e}):e}}async function resolveApplicationAuthNamespace(e){let{config:t}=await loadConfig(e.configPath),{application:n}=await e.client.getApplication({workspaceId:e.workspaceId,applicationName:t.name}),r=n?.authNamespace||t.auth?.name;if(!r)throw Error(`Application ${t.name} does not have an auth configuration.`);return r}async function startWorkflowByName(e){let t=await loadMachineUserName({machineUser:e.machineUser,machineUserSource:e.machineUserSource,profile:e.profile});if(!t)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{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),i=await resolveApplicationAuthNamespace({client:n,workspaceId:r,configPath:e.configPath});return await startWorkflowCore({client:n,workspaceId:r,workflowName:e.name,invoker:{namespace:i,machineUserName:t},arg:e.arg,interval:e.interval})}async function startWorkflow(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),r=await resolveApplicationAuthNamespace({client:t,workspaceId:n,configPath:e.configPath});return await startWorkflowCore({client:t,workspaceId:n,workflowName:e.workflow.name,invoker:{namespace:r,machineUserName:e.invoker},arg:e.arg,interval:e.interval})}const Xo=X({name:`start`,description:`Start a workflow execution.`,args:H.strictObject({...Wr,...Go,"machine-user":V(H.string().optional(),{alias:`m`,description:`Machine user name. Falls back to the active profile's default machine user.`,env:`TAILOR_PLATFORM_MACHINE_USER_NAME`}),arg:V(H.string().optional(),{alias:`a`,description:`Workflow argument (JSON string)`}),...qo}),run:async e=>{let{executionId:t,wait:n}=await startWorkflowByName({name:e.name,machineUser:e[`machine-user`],machineUserSource:resolveMachineUserInputSource(e[`machine-user`]),arg:e.arg,workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,interval:parseDuration(e.interval)}),r=M.jsonMode;if(M.info(`Execution ID: ${t}`,{mode:`stream`}),e.wait){let i=await n({showProgress:!r,timeout:parseDuration(e.timeout),until:e.until});if(e.logs&&!r){let{execution:n}=await getWorkflowExecution({executionId:t,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(n)}else if(e.logs){let{execution:n}=await getWorkflowExecution({executionId:t,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});M.out({...i,jobDetails:n.jobDetails})}else M.out(i);let a=getWorkflowWaitFailureMessage(i,e.until);if(a)throw Error(a)}else M.out({executionId:t})}});function formatTime(e){return e.toLocaleTimeString(`en-US`,{hour12:!1})}function createUnknownExecutorJob(e,t){return{id:t,executorName:e,status:`UNKNOWN`,scheduledAt:`N/A`,createdAt:`N/A`,updatedAt:`N/A`}}async function listExecutorJobs(e){let t=e.executor.name,{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),i=[];if(e.status){let t=parseExecutorJobStatus(e.status);i.push(U(Re,{condition:U(we,{field:`status`,operator:Ze.EQ,value:{kind:{case:`numberValue`,value:t}}})}))}let a=i.length>0?U(Re,{and:i}):void 0,o=toPageDirection(e.order??`desc`);try{return(await jt(async(e,i)=>{let{jobs:s,nextPageToken:c}=await n.listExecutorJobs({workspaceId:r,executorName:t,pageToken:e,pageSize:i,pageDirection:o,filter:a});return[s,c]},{limit:e.limit})).map(toExecutorJobListInfo)}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Executor '${t}' not found.`,{cause:e}):e}}async function getExecutorJob(e){let t=e.executor.name,{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});try{let{job:i}=await n.getExecutorJob({workspaceId:r,executorName:t,jobId:e.jobId});if(!i)throw Error(`Job '${e.jobId}' not found.`);let a=toExecutorJobInfo(i);if(e.attempts){let t=await At(async(t,i)=>{let{attempts:a,nextPageToken:o}=await n.listExecutorJobAttempts({workspaceId:r,jobId:e.jobId,pageToken:t,pageSize:i,pageDirection:Ke.DESC});return[a,o]});return{...a,attempts:t.map(toExecutorJobAttemptInfo)}}return a}catch(n){throw n instanceof q&&n.code===K.NotFound?Error(`Job '${e.jobId}' not found for executor '${t}'.`,{cause:n}):n}}async function watchExecutorJob(e){let t=e.executor.name,{client:r,workspaceId:i}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),a=e.interval??3e3,o=e.timeout,s=e.showProgress??!M.jsonMode,c=Date.now(),l=s?spinner().start(`Waiting for executor job to complete...`):null,u=0,d=null,remainingTimeout=()=>{if(o!==void 0)return o-(Date.now()-c)},withWaitMetadata=(e,t)=>({...e,elapsedMs:Date.now()-c,attempts:u,timedOut:t,lastError:d}),timeoutResult=(n,r)=>withWaitMetadata({job:r?toExecutorJobInfo(r):createUnknownExecutorJob(t,e.jobId),targetType:n},!0);try{let{executor:o}=await r.getExecutorExecutor({workspaceId:i,name:t});if(!o)throw Error(`Executor '${t}' not found.`);let c=o.targetType,f=executorTargetTypeToString(c),p;for(;;){let n=remainingTimeout();if(n!==void 0&&n<=0)return l?.fail(`Executor job wait timed out.`),timeoutResult(f,p);try{if(u+=1,p=(await r.getExecutorJob({workspaceId:i,executorName:t,jobId:e.jobId})).job,!p)throw Error(`Job '${e.jobId}' not found.`);if(d=null,classifyExecutorJobStatus(p.status)!==`transient`)break}catch(e){if(!isRetryableWaitError(e))throw e;d=formatWaitError(e),l&&(l.text=`Retrying executor job poll... (${formatTime(new Date)})`)}let o=remainingTimeout();if(o!==void 0&&o<=0)return l?.fail(`Executor job wait timed out.`),timeoutResult(f,p);l&&(l.text=`Waiting for executor job... (${formatTime(new Date)})`),await Tr(o===void 0?a:Math.min(a,o))}let m=toExecutorJobInfo(p),g=colorizeExecutorJobStatus(m.status);p.status===n.SUCCESS?l?.succeed(`Executor job completed: ${g}`):l?.fail(`Executor job completed: ${g}`);let _=(await At(async(t,n)=>{let{attempts:a,nextPageToken:o}=await r.listExecutorJobAttempts({workspaceId:i,jobId:e.jobId,pageToken:t,pageSize:n,pageDirection:Ke.DESC});return[a,o]})).map(toExecutorJobAttemptInfo),v={...m,attempts:_},y=_[0]?.operationReference;if(y)switch(c){case T.WORKFLOW:l?.stop();try{let t=remainingTimeout();if(t!==void 0&&t<=0)return withWaitMetadata({job:v,targetType:f,workflowExecutionId:y},!0);let n=await waitForWorkflowExecution({client:r,workspaceId:i,executionId:y,interval:a,timeout:t,showProgress:s,trackJobs:!0});u+=n.attempts,d=n.lastError;let o;if(e.logs)try{let{execution:t}=await getWorkflowExecution({executionId:y,workspaceId:e.workspaceId,profile:e.profile,logs:!0});t.jobDetails&&(o=t.jobDetails.filter(e=>e.logs||e.result).map(e=>({jobName:e.stackedJobName||e.id,logs:e.logs,result:e.result})))}catch(e){M.warn(`Could not fetch workflow execution logs: ${e instanceof Error?e.message:e}`)}return withWaitMetadata({job:v,targetType:f,workflowExecutionId:y,workflowStatus:n.status,workflowJobLogs:o},n.timedOut)}catch(e){return M.warn(`Could not track workflow execution: ${e instanceof Error?e.message:e}`),withWaitMetadata({job:v,targetType:f,workflowExecutionId:y},!1)}case T.FUNCTION:case T.JOB_FUNCTION:l?.start(`Waiting for function execution ${y}...`);try{let t;for(;;){let n=remainingTimeout();if(n!==void 0&&n<=0)return l?.fail(`Function execution wait timed out.`),withWaitMetadata({job:v,targetType:f,functionExecutionId:y,functionStatus:t},!0);try{u+=1;let{execution:n}=await r.getFunctionExecution({workspaceId:i,executionId:y});if(!n)throw Error(`Function execution '${y}' not found.`);if(d=null,t=functionExecutionStatusToString(n.status),isFunctionExecutionTerminalStatus(n.status)){let r=colorizeFunctionExecutionStatus(t);return n.status===h.SUCCESS?l?.succeed(`Function execution completed: ${r}`):l?.fail(`Function execution completed: ${r}`),withWaitMetadata({job:v,targetType:f,functionExecutionId:y,functionStatus:t,functionLogs:e.logs&&n.logs||void 0},!1)}}catch(e){if(!isRetryableWaitError(e))throw e;d=formatWaitError(e),l&&(l.text=`Retrying function execution poll... (${formatTime(new Date)})`)}let o=remainingTimeout();if(o!==void 0&&o<=0)return l?.fail(`Function execution wait timed out.`),withWaitMetadata({job:v,targetType:f,functionExecutionId:y,functionStatus:t},!0);l&&(l.text=`Waiting for function execution... (${formatTime(new Date)})`),await Tr(o===void 0?a:Math.min(a,o))}}catch(e){return l?.warn(`Could not track function execution: ${e instanceof Error?e.message:e}`),withWaitMetadata({job:v,targetType:f,functionExecutionId:y},!1)}}return withWaitMetadata({job:v,targetType:f},!1)}finally{l?.stop()}}function getExecutorWaitFailureMessage(e){if(e.timedOut)return`Timed out waiting for executor job '${e.job.id}'. Last status: ${e.job.status}.`;if(e.job.status===`FAILED`||e.job.status===`CANCELED`)return`Executor job '${e.job.id}' completed with status ${e.job.status}.`;if(e.workflowStatus===`FAILED`)return`Workflow execution '${e.workflowExecutionId}' failed.`;if(e.functionStatus===`FAILED`)return`Function execution '${e.functionExecutionId}' failed.`;if(e.functionStatus===`CANCELED`)return`Function execution '${e.functionExecutionId}' was canceled.`}function printJobWithAttempts(e){let t=[[`id`,e.id],[`executorName`,e.executorName],[`status`,e.status],[`scheduledAt`,e.scheduledAt],[`createdAt`,e.createdAt],[`updatedAt`,e.updatedAt]];if(M.log(formatKeyValueTable(t)),e.attempts&&e.attempts.length>0){M.log(N.bold(`
|
|
137
137
|
Attempts:`));for(let t of e.attempts)if(M.log(N.info(`\n--- Attempt ${t.id} ---`)),M.log(` Status: ${t.status}`),M.log(` Started: ${t.startedAt}`),M.log(` Finished: ${t.finishedAt}`),t.error){M.log(N.error(`
|
|
138
138
|
Error:`));let e=t.error.split(`
|
|
139
139
|
`);for(let t of e)M.log(` ${t}`)}}}const Zo=X({name:`jobs`,description:`List or get executor jobs.`,examples:[{cmd:`my-executor`,desc:`List jobs for an executor (default: 50 jobs)`},{cmd:`my-executor --limit 10`,desc:`Limit the number of jobs`},{cmd:`my-executor -s RUNNING`,desc:`Filter by status`},{cmd:`my-executor <job-id>`,desc:`Get job details`},{cmd:`my-executor <job-id> --attempts`,desc:`Get job details with attempts`},{cmd:`my-executor <job-id> -W`,desc:`Wait for job to complete`},{cmd:`my-executor <job-id> -W -l`,desc:`Wait for job with logs`}],args:H.strictObject({...Y,"executor-name":V(H.string(),{positional:!0,description:`Executor name`}),"job-id":V(H.string().optional(),{positional:!0,description:`Job ID (if provided, shows job details)`}),status:V(H.string().optional(),{alias:`s`,description:`Filter by status (PENDING, RUNNING, SUCCESS, FAILED, CANCELED) (list mode only)`}),attempts:V(H.boolean().default(!1),{description:`Show job attempts (only with job ID) (detail mode only)`}),wait:V(H.boolean().default(!1),{alias:`W`,description:`Wait for job completion and downstream execution (workflow/function) if applicable (detail mode only)`}),interval:V(Ir.default(`3s`),{alias:`i`,description:`Polling interval when using --wait (e.g., '3s', '500ms', '1m')`}),timeout:V(Ir.default(`5m`),{alias:`t`,description:`Maximum time to wait when using --wait (e.g., '30s', '5m')`}),...qr,limit:V(Rr.default(50),{description:`Maximum number of jobs to list (0: unlimited, default: 50) (list mode only)`}),logs:V(H.boolean().default(!1),{alias:`l`,description:`Display function execution logs after completion (requires --wait)`})}),run:async e=>{let t=M.jsonMode||e.json;if(e.jobId){if(e.wait){let n=await watchExecutorJob({executor:{name:e.executorName},jobId:e.jobId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval),timeout:parseDuration(e.timeout),logs:e.logs,showProgress:!t});if(t)M.out(n);else{if(M.log(N.bold(`Target Type: ${n.targetType}\n`)),printJobWithAttempts(n.job),n.workflowExecutionId&&(M.log(N.bold(`
|
|
@@ -141,20 +141,20 @@ Workflow Execution:`)),M.log(` ID: ${n.workflowExecutionId}`),n.workflowStatus&
|
|
|
141
141
|
`))M.log(` ${t}`)}if(e.result){M.log(N.dim(` Result:`));try{let t=JSON.parse(e.result),n=JSON.stringify(t,null,2);for(let e of n.split(`
|
|
142
142
|
`))M.log(` ${e}`)}catch{M.log(` ${e.result}`)}}}if(n.functionExecutionId&&(M.log(N.bold(`
|
|
143
143
|
Function Execution:`)),M.log(` ID: ${n.functionExecutionId}`),n.functionStatus&&M.log(` Status: ${n.functionStatus}`),n.functionLogs)){M.log(N.dim(` Logs:`));for(let e of n.functionLogs.split(`
|
|
144
|
-
`))M.log(` ${e}`)}}let r=getExecutorWaitFailureMessage(n);if(r)throw Error(r);return}let n=await getExecutorJob({executor:{name:e.executorName},jobId:e.jobId,attempts:e.attempts,workspaceId:e[`workspace-id`],profile:e.profile});e.attempts&&!t?printJobWithAttempts(n):M.out(n)}else{e.wait&&M.warn(`--wait flag is ignored in list mode. Specify a job ID to wait.`);let t=await listExecutorJobs({executor:{name:e.executorName},status:e.status,order:e.order,limit:e.limit,workspaceId:e[`workspace-id`],profile:e.profile});M.out(t)}}});async function listExecutors(e){let
|
|
144
|
+
`))M.log(` ${e}`)}}let r=getExecutorWaitFailureMessage(n);if(r)throw Error(r);return}let n=await getExecutorJob({executor:{name:e.executorName},jobId:e.jobId,attempts:e.attempts,workspaceId:e[`workspace-id`],profile:e.profile});e.attempts&&!t?printJobWithAttempts(n):M.out(n)}else{e.wait&&M.warn(`--wait flag is ignored in list mode. Specify a job ID to wait.`);let t=await listExecutorJobs({executor:{name:e.executorName},status:e.status,order:e.order,limit:e.limit,workspaceId:e[`workspace-id`],profile:e.profile});M.out(t)}}});async function listExecutors(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),r=toPageDirection(e?.order);return(await jt(async(e,i)=>{let{executors:a,nextPageToken:o}=await t.listExecutorExecutors({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(e=>toExecutorListInfo(e))}const Qo=X({name:`list`,description:`List all executors`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listExecutors({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});if(n.length===0){M.info(`No executors found.`),t&&M.out([]);return}M.out(n,{display:{disabled:e=>e?N.warning(`true`):N.dim(`false`)}}),t||n.some(e=>e.triggerType===`webhook`)&&M.info(`To see webhook URLs, run: tailor executor webhook list`)}}),$o=H.string().transform(e=>{try{return JSON.parse(e)}catch{throw Error(`Invalid JSON data: ${e}. Please provide a valid JSON string.`)}}).refine(e=>typeof e==`object`&&!!e&&!Array.isArray(e),{message:`JSON data must be an object, not an array or primitive value`}),es=H.string().superRefine((e,t)=>{e.includes(`:`)||t.addIssue({code:`custom`,message:`Invalid header format: '${e}'. Expected format: 'Key: Value'`})}).transform(e=>{let t=e.indexOf(`:`);return{key:e.slice(0,t).trim(),value:e.slice(t+1).trim()}}).refine(e=>e.key.length>0,{message:`Header name cannot be empty`});async function triggerExecutorByName(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});try{return{jobId:(await t.triggerExecutor({workspaceId:n,executorName:e.executorName,payload:e.payload})).jobId}}catch(t){throw t instanceof q&&t.code===K.NotFound?Error(`Executor '${e.executorName}' not found.`,{cause:t}):t instanceof q&&t.code===K.InvalidArgument?Error(`Invalid argument: ${t.message}`,{cause:t}):t}}async function triggerExecutor(e){if(e.executor.trigger.kind!==`incomingWebhook`&&e.payload!==void 0)throw Error(`Executor '${e.executor.name}' has '${e.executor.trigger.kind}' trigger type. The payload is only available for 'incomingWebhook' trigger type.`);return await triggerExecutorByName({executorName:e.executor.name,payload:e.payload,workspaceId:e.workspaceId,profile:e.profile})}const ts=X({name:`trigger`,description:`Trigger an executor manually.`,notes:"Only executors with `INCOMING_WEBHOOK` or `SCHEDULE` trigger types can be triggered manually.\nExecutors with `EVENT` trigger types (such as `recordCreated`, `recordUpdated`, `recordDeleted`) cannot be triggered manually.\n\nThe `--data` and `--header` options are only available for `INCOMING_WEBHOOK` trigger type.\n\n**Downstream Execution Tracking**\n\nWhen using `--wait`, the CLI tracks not only the executor job but also any downstream executions:\n\n- **Workflow targets**: Waits for the workflow execution to complete (SUCCESS, FAILED, or PENDING_RESUME). Shows real-time status changes and currently running job names during execution (same output as `workflow start --wait`).\n- **Function targets**: Waits for the function execution to complete\n- **Webhook/GraphQL targets**: Only waits for the executor job itself\n\nThe `--logs` option displays logs from the downstream execution when available.",examples:[{cmd:`my-executor`,desc:`Trigger an executor`},{cmd:`my-executor -d '{"message": "hello"}'`,desc:`Trigger with data`},{cmd:`my-executor -d '{"message": "hello"}' -H "X-Custom: value" -H "X-Another: value2"`,desc:`Trigger with data and headers`},{cmd:`my-executor -W`,desc:`Trigger and wait for completion`},{cmd:`my-executor -W -l`,desc:`Trigger, wait, and show logs`}],args:H.strictObject({...Y,"executor-name":V(H.string(),{positional:!0,description:`Executor name`}),data:V($o.optional(),{alias:`d`,description:`Request body (JSON string)`}),header:V(es.array().optional(),{alias:`H`,overrideBuiltinAlias:!0,description:`Request header (format: 'Key: Value', can be specified multiple times)`}),wait:V(H.boolean().default(!1),{alias:`W`,description:`Wait for job completion and downstream execution (workflow/function) if applicable`}),interval:V(Ir.default(`3s`),{alias:`i`,description:`Polling interval when using --wait (e.g., '3s', '500ms', '1m')`}),timeout:V(Ir.default(`5m`),{alias:`t`,description:`Maximum time to wait when using --wait (e.g., '30s', '5m')`}),logs:V(H.boolean().default(!1),{alias:`l`,description:`Display function execution logs after completion (requires --wait)`})}),run:async e=>{let t=M.jsonMode||e.json;await assertWritable({profile:e.profile});let{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e[`workspace-id`]}),{executor:i}=await n.getExecutorExecutor({workspaceId:r,name:e.executorName});if(!i)throw Error(`Executor '${e.executorName}' not found.`);if(i.triggerType===O.EVENT)throw Error(`Executor '${e.executorName}' has '${executorTriggerTypeToString(i.triggerType)}' trigger type and cannot be triggered manually. Only executors with 'INCOMING_WEBHOOK' or 'SCHEDULE' triggers can be triggered manually.`);if(i.triggerType===O.SCHEDULE&&(e.data||e.header))throw Error(`Executor '${e.executorName}' has 'SCHEDULE' trigger type. The --data and --header options are only available for 'INCOMING_WEBHOOK' trigger type.`);let a,o=e.data,s={};if(e.header)for(let t of e.header)s[t.key]=t.value;(o!==void 0||Object.keys(s).length>0)&&(a={body:o??{},headers:s});let c=await triggerExecutorByName({executorName:e.executorName,payload:a,workspaceId:e[`workspace-id`],profile:e.profile});if(!c.jobId){M.success(`Executor '${e.executorName}' triggered successfully.`),e.wait&&M.warn(`Cannot watch: job ID not available. The API may need to be updated.`);return}if(M.success(`Executor '${e.executorName}' triggered successfully. Job ID: ${c.jobId}`),e.wait){let n=await watchExecutorJob({executor:{name:e.executorName},jobId:c.jobId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval),timeout:parseDuration(e.timeout),logs:e.logs,showProgress:!t});if(t)M.out(n);else{if(M.log(N.bold(`\nTarget Type: ${n.targetType}`)),M.log(`Job Status: ${n.job.status}`),n.workflowExecutionId&&(M.log(N.bold(`
|
|
145
145
|
Workflow Execution:`)),M.log(` ID: ${n.workflowExecutionId}`),n.workflowStatus&&M.log(` Status: ${n.workflowStatus}`),n.workflowJobLogs&&n.workflowJobLogs.length>0))for(let e of n.workflowJobLogs){if(M.log(N.bold(`\n Job: ${e.jobName}`)),e.logs){M.log(N.dim(` Logs:`));for(let t of e.logs.split(`
|
|
146
146
|
`))M.log(` ${t}`)}if(e.result){M.log(N.dim(` Result:`));try{let t=JSON.parse(e.result),n=JSON.stringify(t,null,2);for(let e of n.split(`
|
|
147
147
|
`))M.log(` ${e}`)}catch{M.log(` ${e.result}`)}}}if(n.functionExecutionId&&(M.log(N.bold(`
|
|
148
148
|
Function Execution:`)),M.log(` ID: ${n.functionExecutionId}`),n.functionStatus&&M.log(` Status: ${n.functionStatus}`),n.functionLogs)){M.log(N.dim(` Logs:`));for(let e of n.functionLogs.split(`
|
|
149
|
-
`))M.log(` ${e}`)}}let r=getExecutorWaitFailureMessage(n);if(r)throw Error(r)}}});async function listWebhookExecutors(e){let t=await loadAccessToken({profile:e?.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e?.workspaceId,profile:e?.profile}),i=toPageDirection(e?.order);return(await jt(async(e,t)=>{let{webhooks:a,nextPageToken:o}=await n.listExecutorIncomingWebhooks({workspaceId:r,pageToken:e,pageSize:t,pageDirection:i});return[a,o]},{limit:e?.limit})).map(e=>({name:e.executorName,webhookUrl:e.url,disabled:e.disabled}))}const ns=X({name:`list`,description:`List executors with incoming webhook triggers`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listWebhookExecutors({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});if(n.length===0){M.info(`No webhook executors found.`),t&&M.out([]);return}M.out(n,{display:{disabled:e=>e?N.warning(`true`):N.dim(`false`)}}),t||M.info(`To test a webhook, run: tailor executor trigger <name> -d '{"key":"value"}'`)}}),rs=In({name:`webhook`,description:`Manage executor webhooks`,subCommands:{list:ns},async run(){await Ln(ns,[])}}),functionRegistryInfo=e=>({name:e.name,description:e.description,sizeBytes:e.sizeBytes.toString(),contentHash:e.contentHash,createdAt:formatTimestamp(e.createdAt),updatedAt:formatTimestamp(e.updatedAt)}),is=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),name:H.string().min(1,{message:`name is required`})});async function loadOptions$12(e){let t=is.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),name:t.data.name}}async function getFunctionRegistry(e){let{client:t,workspaceId:n,name:r}=await loadOptions$12(e),i=`Function registry "${r}" not found.`;try{let e=await t.getFunctionRegistry({workspaceId:n,name:r});if(!e.function)throw Error(i);return functionRegistryInfo(e.function)}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(i,{cause:e}):e}}const as=X({name:`get`,description:`Get a function registry by name`,args:H.strictObject({...Y,name:V(H.string(),{description:`Function name`,alias:`n`})}),run:async e=>{let t=await getFunctionRegistry({workspaceId:e[`workspace-id`],profile:e.profile,name:e.name}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}}),os=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:H.enum([`asc`,`desc`]).optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$11(e){let t=os.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),order:t.data.order,limit:t.data.limit}}async function listFunctionRegistries(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$11(e),a=toPageDirection(r);return(await jt(async(e,r)=>{try{let{functions:i,nextPageToken:o}=await t.listFunctionRegistries({workspaceId:n,pageToken:e,pageSize:r,sortBy:`updated_at`,pageDirection:a});return[i,o]}catch(e){if(e instanceof q&&e.code===K.NotFound)return[[],``];throw e}},{limit:i})).map(functionRegistryInfo)}const ss=X({name:`list`,description:`List function registries in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listFunctionRegistries({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({createdAt:e,updatedAt:t,...n})=>({...n,createdAt:humanizeRelativeTime(e),updatedAt:humanizeRelativeTime(t)}));M.out(r)}});async function waitForExecution(e,t,n,r=1e3){for(;;){let{execution:i}=await e.getFunctionExecution({workspaceId:t,executionId:n});if(!i)throw Error(`Execution '${n}' not found.`);if(i.status===h.SUCCESS||i.status===h.FAILED||i.status===h.CANCELED)return{status:i.status,logs:i.logs,result:i.result};await new Promise(e=>setTimeout(e,r))}}async function executeScript(e){let{client:t,workspaceId:n,name:r,code:i,arg:a,invoker:o,pollInterval:s}=e,c=await t.testExecScript({workspaceId:n,name:r,code:i,arg:JSON.stringify(a===void 0?{}:a),invoker:o}),l=c.executionId,u=await waitForExecution(t,n,l,s);return u.status===h.SUCCESS?{success:!0,logs:u.logs,result:u.result}:{success:!1,logs:u.logs,result:u.result||c.result,error:u.result||c.result||(u.status===h.CANCELED?`Script execution was canceled`:`Script execution failed with unknown error`)}}function extractAllNamespaces(e){let t=new Set;if(e.db)for(let n of Object.keys(e.db))t.add(n);return Array.from(t)}function extractOwnedNamespaces(e){let t=new Set;if(e.db)for(let[n,r]of Object.entries(e.db))`external`in r||t.add(n);return Array.from(t)}async function loadApplicationNamespaces(e={}){let{config:t,plugins:n}=await loadConfig(e.configPath);await generateUserTypes({config:t,configPath:t.path});let r=n.length>0?new PluginManager(n):void 0,i=Qt({config:t,pluginManager:r}),a=typeof e.namespaces==`function`?e.namespaces(t,n):e.namespaces,o=a?new Set(a):void 0,s=o?i.tailorDBServices.filter(e=>o.has(e.namespace)):i.tailorDBServices;if(o&&s.length!==o.size){let e=new Set(s.map(e=>e.namespace)),t=[...o].filter(t=>!e.has(t)).join(`, `),n=i.tailorDBServices.map(e=>e.namespace).join(`, `);throw Error(`TailorDB namespace "${t}" not found in local config.db.`+(n?` Available owned namespaces: ${n}`:``))}let c=[];for(let e of s)await e.loadTypes(),await e.processNamespacePlugins(),c.push({namespace:e.namespace,tables:{...e.types},sourceInfo:new Map(Object.entries(e.typeSourceInfo)),pluginAttachments:e.pluginAttachments});return{config:t,plugins:n,application:i,namespaces:c}}async function loadTailorDBNamespaces(e={}){let{config:t,plugins:n,namespaces:r}=await loadApplicationNamespaces(e);return{config:t,plugins:n,namespaces:r}}function resolvePluginConfig(e,t){return e.find(e=>e.id===t)?.pluginConfig}function getAuthInput(e){let t=e.authService;if(!t)return;let n=t.config,r=t.userProfile;return{name:n.name,userProfile:r?{tableName:r.type.name,namespace:r.namespace,usernameField:r.usernameField}:void 0,machineUsers:n.machineUsers,oauth2Clients:n.oauth2Clients,idProvider:n.idProvider}}function createGenerationManager(e){let{application:t,config:n,pluginManager:r}=e,i=B.join(Gt(),`generated`);W.mkdirSync(i,{recursive:!0});let a={tailordb:{},resolver:{},executor:{}},o=r?.getPluginsWithGenerationHooks()??[];function buildTailorDBData(){return Object.entries(a.tailordb).map(([e,t])=>({namespace:e,tables:t.types,sourceInfo:new Map(Object.entries(t.sourceInfo)),pluginAttachments:t.pluginAttachments}))}function buildResolverData(){return Object.entries(a.resolver).map(([e,t])=>({namespace:e,resolvers:t}))}async function runPluginPhaseHook(e,r){if(!e[r])return;let o=B.join(i,e.id),s=getAuthInput(t),c=buildTailorDBData(),l;switch(r){case`onTailorDBReady`:l=await A(e.onTailorDBReady,`plugin.onTailorDBReady hook missing`)({tailordb:c,auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig});break;case`onResolverReady`:l=await A(e.onResolverReady,`plugin.onResolverReady hook missing`)({tailordb:c,resolvers:buildResolverData(),auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig});break;case`onExecutorReady`:l=await A(e.onExecutorReady,`plugin.onExecutorReady hook missing`)({tailordb:c,resolvers:buildResolverData(),executors:{...a.executor},auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig})}await writeGeneratedFiles(e.id,l)}async function runPluginHook(e){let t=o.filter(t=>t[e]!=null);if(t.length===0)return;let n=(await Promise.allSettled(t.map(async t=>{try{await runPluginPhaseHook(t,e)}catch(n){throw M.error(`Error processing plugin ${N.bold(t.id)} (${e})`),M.error(String(n)),n}}))).filter(e=>e.status===`rejected`);if(n.length>0)throw AggregateError(n.map(e=>e.reason))}async function writeGeneratedFiles(e,t){await Promise.all(t.files.map(async t=>(W.mkdirSync(B.dirname(t.path),{recursive:!0}),new Promise((n,r)=>{if(t.skipIfExists&&W.existsSync(t.path)){let r=B.relative(process.cwd(),t.path);return M.debug(`${e} | skip existing: ${r}`),n()}W.writeFile(t.path,t.content,i=>{if(i){let e=B.relative(process.cwd(),t.path);M.error(`Error writing file ${N.bold(e)}`),M.error(String(i)),r(i)}else{let i=B.relative(process.cwd(),t.path);M.log(`${e} | generate: ${N.success(i)}`),t.executable?W.chmod(t.path,493,e=>{if(e){let n=B.relative(process.cwd(),t.path);M.error(`Error setting executable permission on ${N.bold(n)}`),M.error(String(e)),r(e)}else n()}):n()}})}))))}return{application:t,baseDir:i,services:a,async generate(){M.newline(),M.log(`Generation for application: ${N.highlight(t.config.name)}`);let e=t;await z(`generate.loadTailorDBTypes`,async t=>{t.setAttribute(`generate.namespace_count`,e.tailorDBServices.length);for(let t of e.tailorDBServices){let e=t.namespace;await z(`generate.loadTypes.${e}`,async()=>{try{await t.loadTypes(),await t.processNamespacePlugins(),a.tailordb[e]={types:t.types,sourceInfo:t.typeSourceInfo,pluginAttachments:t.pluginAttachments}}catch(t){throw M.error(`Error loading tables for TailorDB service ${N.bold(e)}`),M.error(String(t)),t}})}try{en({tailorDBServices:e.tailorDBServices})}catch(e){throw M.error(`Error validating TailorDB table names`),M.error(String(e)),e}});let{pluginExecutorFiles:i,executorService:s}=await z(`generate.pluginFiles`,async()=>{let t=Ut(r,e.tailorDBServices,n.path);return{pluginExecutorFiles:t,executorService:e.executorService??(t.length>0?ln({config:{files:[]},baseDir:B.dirname(n.path)}):void 0)}});if(e.authService){let t=e.authService;await z(`generate.resolveAuthNamespaces`,async()=>t.resolveNamespaces())}(e.tailorDBServices.length>0||i.length>0)&&M.newline(),o.some(e=>e.onTailorDBReady!=null)&&(await z(`generate.onTailorDBReady`,async()=>{await runPluginHook(`onTailorDBReady`)}),M.newline()),await z(`generate.loadResolvers`,async()=>{for(let t of e.resolverServices){let e=t.namespace;await z(`generate.loadResolvers.${e}`,async()=>{try{await t.loadResolvers();let n={};a.resolver[e]=n,Object.entries(t.resolvers).forEach(([e,t])=>{n[t.name]=t})}catch(t){throw M.error(`Error loading resolvers for Resolver service ${N.bold(e)}`),M.error(String(t)),t}})}}),o.some(e=>e.onResolverReady!=null)&&(await z(`generate.onResolversReady`,async()=>{await runPluginHook(`onResolverReady`)}),M.newline()),await z(`generate.loadExecutors`,async()=>{s&&(await s.loadExecutors(),i.length>0&&await s.loadPluginExecutorFiles([...i]));let e=s?.executors??{};Object.entries(e).forEach(([e,t])=>{a.executor[e]=t})}),o.some(e=>e.onExecutorReady!=null)&&(await z(`generate.onExecutorsReady`,async()=>{await runPluginHook(`onExecutorReady`)}),M.newline())}}}async function generate$1(e){return z(`generate`,async t=>{let{config:n,plugins:r}=await z(`generate.loadConfig`,async()=>loadConfig(e?.configPath));await z(`generate.generateUserTypes`,async()=>generateUserTypes({config:n,configPath:n.path}));let i;r.length>0&&(i=new PluginManager(r));let a=Qt({config:n,pluginManager:i});t.setAttribute(`app.name`,a.config.name),await createGenerationManager({application:a,config:n,pluginManager:i}).generate()})}function machineUserInfo(e){return{name:e.name,clientId:e.clientId,clientSecret:e.clientSecret,createdAt:e.createdAt?G(e.createdAt):null,updatedAt:e.updatedAt?G(e.updatedAt):null,attributes:Object.fromEntries(Object.entries(e.attributeMap).map(([e,t])=>[e,Bn(Yn,t)]))}}async function listMachineUsers(e){let t=await loadAccessToken({profile:e?.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e?.workspaceId,profile:e?.profile}),{config:i}=await loadConfig(e?.configPath),{application:a}=await n.getApplication({workspaceId:r,applicationName:i.name});if(!a?.authNamespace)throw Error(`Application ${i.name} does not have an auth configuration.`);let o=toPageDirection(e?.order);return(await jt(async(e,t)=>{let{machineUsers:i,nextPageToken:s}=await n.listAuthMachineUsers({workspaceId:r,pageToken:e,pageSize:t,authNamespace:a.authNamespace,pageDirection:o});return[i,s]},{limit:e?.limit})).map(machineUserInfo)}const cs=X({name:`list`,description:`List all machine users in the application.`,args:H.strictObject({...Wr,...paginationArgs()}),run:async e=>{let t=await listMachineUsers({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,order:e.order,limit:e.limit});M.out(t,{display:{createdAt:null,updatedAt:null}})}});async function getMachineUserTokenInternal(e){let t=await loadMachineUserName({machineUser:e.name,machineUserSource:e.nameSource,profile:e.profile});if(!t)throw Error(`Machine user is required. Provide the NAME positional argument, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.`);let n=await loadAccessToken({profile:e.profile}),r=await F(n),i=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),{config:a}=await loadConfig(e.configPath),{application:o}=await r.getApplication({workspaceId:i,applicationName:a.name});if(!o?.authNamespace)throw Error(`Application ${a.name} does not have an auth configuration.`);let{machineUser:s}=await r.getAuthMachineUser({workspaceId:i,authNamespace:o.authNamespace,name:t});if(!s)throw Error(`Machine user ${t} not found.`);let c=await kt(o.url,s.clientId,s.clientSecret),l=new Date;return l.setSeconds(l.getSeconds()+c.expires_in),{accessToken:c.access_token,tokenType:c.token_type,expiresAt:l.toISOString()}}async function getMachineUserToken(e){return await getMachineUserTokenInternal(e)}const ls=X({name:`token`,description:`Get an access token for a machine user.`,args:H.strictObject({...Wr,name:V(H.string().optional(),{positional:!0,description:`Machine user name. Falls back to TAILOR_PLATFORM_MACHINE_USER_NAME, then the active profile's default machine user.`})}),run:async e=>{let t=await getMachineUserTokenInternal({name:e.name,nameSource:resolveMachineUserInputSource(e.name,process.argv.slice(2),{valueIsExplicit:e.name!==void 0}),workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config}),n={access_token:t.accessToken,token_type:t.tokenType,expires_at:t.expiresAt};M.out(n)}}),grantTypeToString=e=>{switch(e){case r.AUTHORIZATION_CODE:return`authorization_code`;case r.REFRESH_TOKEN:return`refresh_token`;default:return`unknown`}};function toOAuth2ClientInfo(e){return{name:e.name,description:e.description,clientId:e.clientId,grantTypes:e.grantTypes.map(grantTypeToString),redirectUris:e.redirectUris,createdAt:e.createdAt?G(e.createdAt):null}}function toOAuth2ClientCredentials(e){return{name:e.name,description:e.description,clientId:e.clientId,clientSecret:e.clientSecret,grantTypes:e.grantTypes.map(grantTypeToString),redirectUris:e.redirectUris,createdAt:e.createdAt?G(e.createdAt):null}}async function getOAuth2Client(e){let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),{config:i}=await loadConfig(e.configPath),{application:a}=await n.getApplication({workspaceId:r,applicationName:i.name});if(!a?.authNamespace)throw Error(`Application ${i.name} does not have an auth configuration.`);try{let{oauth2Client:t}=await n.getAuthOAuth2Client({workspaceId:r,namespaceName:a.authNamespace,name:e.name});return toOAuth2ClientCredentials(A(t,`oauth2Client missing in response`))}catch(t){throw t instanceof q&&t.code===K.NotFound?Error(`OAuth2 client '${e.name}' not found.`,{cause:t}):t}}const us=X({name:`get`,description:`Get OAuth2 client credentials (including client secret).`,args:H.strictObject({...Wr,name:V(H.string(),{positional:!0,description:`OAuth2 client name`})}),run:async e=>{let t=await getOAuth2Client({name:e.name,workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config});M.out(t)}});async function listOAuth2Clients(e){let t=await loadAccessToken({profile:e?.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e?.workspaceId,profile:e?.profile}),{config:i}=await loadConfig(e?.configPath),{application:a}=await n.getApplication({workspaceId:r,applicationName:i.name});if(!a?.authNamespace)throw Error(`Application ${i.name} does not have an auth configuration.`);let o=toPageDirection(e?.order);return(await jt(async(e,t)=>{let{oauth2Clients:i,nextPageToken:s}=await n.listAuthOAuth2Clients({workspaceId:r,pageToken:e,pageSize:t,namespaceName:a.authNamespace,pageDirection:o});return[i,s]},{limit:e?.limit})).map(toOAuth2ClientInfo)}const ds=X({name:`list`,description:`List all OAuth2 clients in the application.`,args:H.strictObject({...Wr,...paginationArgs()}),run:async e=>{let t=await listOAuth2Clients({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,order:e.order,limit:e.limit});M.out(t)}}),userOrganizationInfo=e=>({organizationId:e.organizationId,organizationName:e.organizationName,rootFolderId:e.rootFolderId,rootFolderName:e.rootFolderName,displayName:e.displayName}),organizationInfo=e=>({id:e.id,name:e.name,createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)}),folderListInfo=e=>({id:e.id,name:e.name,organizationId:e.organizationId,parentFolderId:e.parentFolderId,hasChildren:e.hasChildren,createdAt:formatTimestamp(e.createTime)}),folderInfo=e=>({...folderListInfo(e),updatedAt:formatTimestamp(e.updateTime)}),fs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),parentFolderId:H.string().optional(),name:H.string().min(1,`Name must not be empty`)});async function createFolder(e){let t=fs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken(),r=await(await F(n)).createOrganizationFolder({organizationId:t.data.organizationId,parentFolderId:t.data.parentFolderId??``,folderName:t.data.name});if(!r.folder)throw Error(`Failed to create folder.`);return folderInfo(r.folder)}const ps=X({name:`create`,description:`Create a new folder in an organization.`,args:H.strictObject({...Kr,"parent-folder-id":V(H.string().optional(),{description:`Parent folder ID`}),name:V(H.string(),{alias:`n`,description:`Folder name`})}),run:async e=>{await assertWritable();let t=await createFolder({organizationId:e[`organization-id`],parentFolderId:e[`parent-folder-id`],name:e.name});e.json||M.success(`Folder "${t.name}" created successfully.`),M.out(t)}}),ms=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`})});async function deleteFolder(e){let t=ms.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken();await(await F(n)).deleteOrganizationFolder({organizationId:t.data.organizationId,folderId:t.data.folderId})}const hs=X({name:`delete`,description:`Delete a folder from an organization.`,args:H.strictObject({...Kr,...Jr,...Gr}),run:async e=>{await assertWritable();let t=await loadAccessToken(),n=await F(t),r;try{r=await n.getOrganizationFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]})}catch(t){throw t instanceof q&&t.code===K.NotFound?Error(`Folder "${e[`folder-id`]}" not found.`,{cause:t}):t}if(!r.folder)throw Error(`Folder "${e[`folder-id`]}" not found.`);let i=r.folder.name;if(!e.yes&&!await Z.confirm({message:`Are you sure you want to delete folder "${i}"?`})){M.info(`Folder deletion cancelled.`);return}await n.deleteOrganizationFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]}),M.success(`Folder "${i}" deleted successfully.`)}}),gs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`})});async function getFolder(e){let t=gs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken(),r=await(await F(n)).getOrganizationFolder({organizationId:t.data.organizationId,folderId:t.data.folderId});if(!r.folder)throw Error(`Folder "${t.data.folderId}" not found.`);return folderInfo(r.folder)}const _s=X({name:`get`,description:`Show detailed information about a folder.`,args:H.strictObject({...Kr,...Jr}),run:async e=>{let t=await getFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}}),vs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),parentFolderId:H.string().optional(),order:zr.optional(),limit:H.number().int().nonnegative().optional()});async function listFolders(e){let t=vs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let{organizationId:n,parentFolderId:r,order:i,limit:a}=t.data,o=await loadAccessToken(),s=await F(o),c=toPageDirection(i);return(await jt(async(e,t)=>{let i=await s.listOrganizationFolders({organizationId:n,...r?{parentFolderId:r}:{},pageToken:e,pageSize:t,pageDirection:c});return[i.folders,i.nextPageToken]},{limit:a})).map(folderListInfo)}const ys=X({name:`list`,description:`List folders in an organization.`,args:H.strictObject({...Kr,"parent-folder-id":V(H.string().optional(),{description:`Parent folder ID to list children of`}),...paginationArgs()}),run:async e=>{let t=await listFolders({organizationId:e[`organization-id`],parentFolderId:e[`parent-folder-id`],order:e.order,limit:e.limit});M.out(t,{display:{updatedAt:null}})}}),bs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`}),name:H.string().min(1,`Name must not be empty`)});async function updateFolder(e){let t=bs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken(),r=await(await F(n)).updateOrganizationFolder({organizationId:t.data.organizationId,folderId:t.data.folderId,folderName:t.data.name});if(!r.folder)throw Error(`Failed to update folder "${t.data.folderId}".`);return folderInfo(r.folder)}const xs=X({name:`update`,description:`Update a folder's name.`,args:H.strictObject({...Kr,...Jr,name:V(H.string(),{alias:`n`,description:`New folder name`})}),run:async e=>{await assertWritable();let t=await updateFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`],name:e.name});e.json||M.success(`Folder "${t.name}" updated successfully.`),M.out(t)}}),Ss=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`})});async function getOrganization(e){let t=Ss.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken(),r=await(await F(n)).getOrganization({organizationId:t.data.organizationId});if(!r.organization)throw Error(`Organization "${t.data.organizationId}" not found.`);return organizationInfo(r.organization)}const Cs=X({name:`get`,description:`Show detailed information about an organization.`,args:H.strictObject({...Kr}),run:async e=>{let t=await getOrganization({organizationId:e[`organization-id`]}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}});async function listOrganizations(e){let t=e?.limit,n=await loadAccessToken(),{userOrganizations:r}=await(await F(n)).listUserOrganizations({}),i=r.map(userOrganizationInfo);return t===void 0?i:i.slice(0,t)}const ws=X({name:`list`,description:`List organizations you belong to.`,args:H.strictObject({limit:V(Lr.optional(),{alias:`l`,description:`Maximum number of organizations to list`})}),run:async e=>{let t=await listOrganizations({limit:e.limit});M.out(t)}});async function fetchChildFolders(e,t,n,r,i){if(i!==void 0&&r>=i)return[];let a=await At(async(r,i)=>{let a=await e.listOrganizationFolders({organizationId:t,parentFolderId:n,pageToken:r,pageSize:i});return[a.folders,a.nextPageToken]}),o=[];for(let n of a){let a=n.hasChildren?await fetchChildFolders(e,t,n.id,r+1,i):[];o.push({name:n.name,children:a})}return o}async function buildFolderTreeJson(e,t,n,r,i){if(i!==void 0&&r>=i)return[];let a=await At(async(r,i)=>{let a=await e.listOrganizationFolders({organizationId:t,parentFolderId:n,pageToken:r,pageSize:i});return[a.folders,a.nextPageToken]}),o=[];for(let n of a){let a=n.hasChildren?await buildFolderTreeJson(e,t,n.id,r+1,i):[];o.push({id:n.id,name:n.name,children:a})}return o}function renderTree(e,t){let n=``;for(let[r,i]of e.entries()){let a=r===e.length-1,o=a?`└── `:`├── `,s=a?` `:`│ `;n+=`${t}${o}${i.name}\n`,i.children.length>0&&(n+=renderTree(i.children,t+s))}return n}async function buildOrgTree(e,t,n){let r=await fetchChildFolders(e,t.organizationId,t.rootFolderId,0,n),i=`${t.organizationName}\n`;return i+=renderTree(r,``),i}async function organizationTree(e){let t=await loadAccessToken(),n=await F(t),r;if(e?.organizationId){if(r=(await listOrganizations()).filter(t=>t.organizationId===e.organizationId),r.length===0)throw Error(`Organization "${e.organizationId}" not found.`)}else r=await listOrganizations();let i=e?.depth,a=[];for(let e of r){let t=await buildFolderTreeJson(n,e.organizationId,e.rootFolderId,0,i);a.push({organizationId:e.organizationId,organizationName:e.organizationName,folders:t})}return a}const Ts=X({name:`tree`,description:`Display organization folder hierarchy as a tree.`,args:H.strictObject({"organization-id":V(H.string().optional(),{alias:`o`,description:`Organization ID (show all if omitted)`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`}),depth:V(Lr.optional(),{alias:`d`,description:`Maximum folder depth to display`})}),run:async e=>{let t=await loadAccessToken(),n=await F(t),r;if(e[`organization-id`]){if(r=(await listOrganizations()).filter(t=>t.organizationId===e[`organization-id`]),r.length===0)throw Error(`Organization "${e[`organization-id`]}" not found.`)}else r=await listOrganizations();if(e.json){let t=[];for(let i of r){let r=await buildFolderTreeJson(n,i.organizationId,i.rootFolderId,0,e.depth);t.push({organizationId:i.organizationId,organizationName:i.organizationName,folders:r})}M.out(t);return}let i=[];for(let t of r)i.push(await buildOrgTree(n,t,e.depth));M.log(i.join(`
|
|
150
|
-
`))}}),Es=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),name:H.string().min(1,`Name must not be empty`)});async function updateOrganization(e){let t=Es
|
|
149
|
+
`))M.log(` ${e}`)}}let r=getExecutorWaitFailureMessage(n);if(r)throw Error(r)}}});async function listWebhookExecutors(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),r=toPageDirection(e?.order);return(await jt(async(e,i)=>{let{webhooks:a,nextPageToken:o}=await t.listExecutorIncomingWebhooks({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(e=>({name:e.executorName,webhookUrl:e.url,disabled:e.disabled}))}const ns=X({name:`list`,description:`List executors with incoming webhook triggers`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listWebhookExecutors({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});if(n.length===0){M.info(`No webhook executors found.`),t&&M.out([]);return}M.out(n,{display:{disabled:e=>e?N.warning(`true`):N.dim(`false`)}}),t||M.info(`To test a webhook, run: tailor executor trigger <name> -d '{"key":"value"}'`)}}),rs=In({name:`webhook`,description:`Manage executor webhooks`,subCommands:{list:ns},async run(){await Ln(ns,[])}}),functionRegistryInfo=e=>({name:e.name,description:e.description,sizeBytes:e.sizeBytes.toString(),contentHash:e.contentHash,createdAt:formatTimestamp(e.createdAt),updatedAt:formatTimestamp(e.updatedAt)}),is=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),name:H.string().min(1,{message:`name is required`})});async function loadOptions$12(e){let t=parseOptions(is,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,name:t.name}}async function getFunctionRegistry(e){let{client:t,workspaceId:n,name:r}=await loadOptions$12(e),i=`Function registry "${r}" not found.`;try{let e=await t.getFunctionRegistry({workspaceId:n,name:r});if(!e.function)throw Error(i);return functionRegistryInfo(e.function)}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(i,{cause:e}):e}}const as=X({name:`get`,description:`Get a function registry by name`,args:H.strictObject({...Y,name:V(H.string(),{description:`Function name`,alias:`n`})}),run:async e=>{let t=await getFunctionRegistry({workspaceId:e[`workspace-id`],profile:e.profile,name:e.name}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}}),os=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:H.enum([`asc`,`desc`]).optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$11(e){let t=parseOptions(os,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,order:t.order,limit:t.limit}}async function listFunctionRegistries(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$11(e),a=toPageDirection(r);return(await jt(async(e,r)=>{try{let{functions:i,nextPageToken:o}=await t.listFunctionRegistries({workspaceId:n,pageToken:e,pageSize:r,sortBy:`updated_at`,pageDirection:a});return[i,o]}catch(e){if(e instanceof q&&e.code===K.NotFound)return[[],``];throw e}},{limit:i})).map(functionRegistryInfo)}const ss=X({name:`list`,description:`List function registries in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listFunctionRegistries({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({createdAt:e,updatedAt:t,...n})=>({...n,createdAt:humanizeRelativeTime(e),updatedAt:humanizeRelativeTime(t)}));M.out(r)}});async function waitForExecution(e,t,n,r=1e3){for(;;){let{execution:i}=await e.getFunctionExecution({workspaceId:t,executionId:n});if(!i)throw Error(`Execution '${n}' not found.`);if(i.status===h.SUCCESS||i.status===h.FAILED||i.status===h.CANCELED)return{status:i.status,logs:i.logs,result:i.result};await new Promise(e=>setTimeout(e,r))}}async function executeScript(e){let{client:t,workspaceId:n,name:r,code:i,arg:a,invoker:o,pollInterval:s}=e,c=await t.execScript({workspaceId:n,name:r,code:i,arg:JSON.stringify(a===void 0?{}:a),invoker:o}),l=c.executionId,u=await waitForExecution(t,n,l,s);return u.status===h.SUCCESS?{success:!0,logs:u.logs,result:u.result}:{success:!1,logs:u.logs,result:u.result||c.result,error:u.result||c.result||(u.status===h.CANCELED?`Script execution was canceled`:`Script execution failed with unknown error`)}}function extractAllNamespaces(e){let t=new Set;if(e.db)for(let n of Object.keys(e.db))t.add(n);return Array.from(t)}function extractOwnedNamespaces(e){let t=new Set;if(e.db)for(let[n,r]of Object.entries(e.db))`external`in r||t.add(n);return Array.from(t)}async function loadApplicationNamespaces(e={}){let{config:t,plugins:n}=await loadConfig(e.configPath);await generateUserTypes({config:t,configPath:t.path});let r=n.length>0?new PluginManager(n):void 0,i=Qt({config:t,pluginManager:r}),a=typeof e.namespaces==`function`?e.namespaces(t,n):e.namespaces,o=a?new Set(a):void 0,s=o?i.tailorDBServices.filter(e=>o.has(e.namespace)):i.tailorDBServices;if(o&&s.length!==o.size){let e=new Set(s.map(e=>e.namespace)),t=[...o].filter(t=>!e.has(t)).join(`, `),n=i.tailorDBServices.map(e=>e.namespace).join(`, `);throw Error(`TailorDB namespace "${t}" not found in local config.db.`+(n?` Available owned namespaces: ${n}`:``))}let c=[];for(let e of s)await e.loadTypes(),await e.processNamespacePlugins(),c.push({namespace:e.namespace,tables:{...e.types},sourceInfo:new Map(Object.entries(e.typeSourceInfo)),pluginAttachments:e.pluginAttachments});return{config:t,plugins:n,application:i,namespaces:c}}async function loadTailorDBNamespaces(e={}){let{config:t,plugins:n,namespaces:r}=await loadApplicationNamespaces(e);return{config:t,plugins:n,namespaces:r}}function resolvePluginConfig(e,t){return e.find(e=>e.id===t)?.pluginConfig}function getAuthInput(e){let t=e.authService;if(!t)return;let n=t.config,r=t.userProfile;return{name:n.name,userProfile:r?{tableName:r.type.name,namespace:r.namespace,usernameField:r.usernameField}:void 0,machineUsers:n.machineUsers,oauth2Clients:n.oauth2Clients,idProvider:n.idProvider}}function createGenerationManager(e){let{application:t,config:n,pluginManager:r}=e,i=B.join(Gt(),`generated`);W.mkdirSync(i,{recursive:!0});let a={tailordb:{},resolver:{},executor:{}},o=r?.getPluginsWithGenerationHooks()??[];function buildTailorDBData(){return Object.entries(a.tailordb).map(([e,t])=>({namespace:e,tables:t.types,sourceInfo:new Map(Object.entries(t.sourceInfo)),pluginAttachments:t.pluginAttachments}))}function buildResolverData(){return Object.entries(a.resolver).map(([e,t])=>({namespace:e,resolvers:t}))}async function runPluginPhaseHook(e,r){if(!e[r])return;let o=B.join(i,e.id),s=getAuthInput(t),c=buildTailorDBData(),l;switch(r){case`onTailorDBReady`:l=await A(e.onTailorDBReady,`plugin.onTailorDBReady hook missing`)({tailordb:c,auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig});break;case`onResolverReady`:l=await A(e.onResolverReady,`plugin.onResolverReady hook missing`)({tailordb:c,resolvers:buildResolverData(),auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig});break;case`onExecutorReady`:l=await A(e.onExecutorReady,`plugin.onExecutorReady hook missing`)({tailordb:c,resolvers:buildResolverData(),executors:{...a.executor},auth:s,baseDir:o,configPath:n.path,pluginConfig:e.pluginConfig})}await writeGeneratedFiles(e.id,l)}async function runPluginHook(e){let t=o.filter(t=>t[e]!=null);if(t.length===0)return;let n=(await Promise.allSettled(t.map(async t=>{try{await runPluginPhaseHook(t,e)}catch(n){throw M.error(`Error processing plugin ${N.bold(t.id)} (${e})`),M.error(String(n)),n}}))).filter(e=>e.status===`rejected`);if(n.length>0)throw AggregateError(n.map(e=>e.reason))}async function writeGeneratedFiles(e,t){await Promise.all(t.files.map(async t=>(W.mkdirSync(B.dirname(t.path),{recursive:!0}),new Promise((n,r)=>{if(t.skipIfExists&&W.existsSync(t.path)){let r=B.relative(process.cwd(),t.path);return M.debug(`${e} | skip existing: ${r}`),n()}W.writeFile(t.path,t.content,i=>{if(i){let e=B.relative(process.cwd(),t.path);M.error(`Error writing file ${N.bold(e)}`),M.error(String(i)),r(i)}else{let i=B.relative(process.cwd(),t.path);M.log(`${e} | generate: ${N.success(i)}`),t.executable?W.chmod(t.path,493,e=>{if(e){let n=B.relative(process.cwd(),t.path);M.error(`Error setting executable permission on ${N.bold(n)}`),M.error(String(e)),r(e)}else n()}):n()}})}))))}return{application:t,baseDir:i,services:a,async generate(){M.newline(),M.log(`Generation for application: ${N.highlight(t.config.name)}`);let e=t;await z(`generate.loadTailorDBTypes`,async t=>{t.setAttribute(`generate.namespace_count`,e.tailorDBServices.length);for(let t of e.tailorDBServices){let e=t.namespace;await z(`generate.loadTypes.${e}`,async()=>{try{await t.loadTypes(),await t.processNamespacePlugins(),a.tailordb[e]={types:t.types,sourceInfo:t.typeSourceInfo,pluginAttachments:t.pluginAttachments}}catch(t){throw M.error(`Error loading tables for TailorDB service ${N.bold(e)}`),M.error(String(t)),t}})}try{en({tailorDBServices:e.tailorDBServices})}catch(e){throw M.error(`Error validating TailorDB table names`),M.error(String(e)),e}});let{pluginExecutorFiles:i,executorService:s}=await z(`generate.pluginFiles`,async()=>{let t=Ut(r,e.tailorDBServices,n.path);return{pluginExecutorFiles:t,executorService:e.executorService??(t.length>0?ln({config:{files:[]},baseDir:B.dirname(n.path)}):void 0)}});if(e.authService){let t=e.authService;await z(`generate.resolveAuthNamespaces`,async()=>t.resolveNamespaces())}(e.tailorDBServices.length>0||i.length>0)&&M.newline(),o.some(e=>e.onTailorDBReady!=null)&&(await z(`generate.onTailorDBReady`,async()=>{await runPluginHook(`onTailorDBReady`)}),M.newline()),await z(`generate.loadResolvers`,async()=>{for(let t of e.resolverServices){let e=t.namespace;await z(`generate.loadResolvers.${e}`,async()=>{try{await t.loadResolvers();let n={};a.resolver[e]=n,Object.entries(t.resolvers).forEach(([e,t])=>{n[t.name]=t})}catch(t){throw M.error(`Error loading resolvers for Resolver service ${N.bold(e)}`),M.error(String(t)),t}})}}),o.some(e=>e.onResolverReady!=null)&&(await z(`generate.onResolversReady`,async()=>{await runPluginHook(`onResolverReady`)}),M.newline()),await z(`generate.loadExecutors`,async()=>{s&&(await s.loadExecutors(),i.length>0&&await s.loadPluginExecutorFiles([...i]));let e=s?.executors??{};Object.entries(e).forEach(([e,t])=>{a.executor[e]=t})}),o.some(e=>e.onExecutorReady!=null)&&(await z(`generate.onExecutorsReady`,async()=>{await runPluginHook(`onExecutorReady`)}),M.newline())}}}async function generate$1(e){return z(`generate`,async t=>{let{config:n,plugins:r}=await z(`generate.loadConfig`,async()=>loadConfig(e?.configPath));await z(`generate.generateUserTypes`,async()=>generateUserTypes({config:n,configPath:n.path}));let i;r.length>0&&(i=new PluginManager(r));let a=Qt({config:n,pluginManager:i});t.setAttribute(`app.name`,a.config.name),await createGenerationManager({application:a,config:n,pluginManager:i}).generate()})}function machineUserInfo(e){return{name:e.name,clientId:e.clientId,clientSecret:e.clientSecret,createdAt:e.createdAt?G(e.createdAt):null,updatedAt:e.updatedAt?G(e.updatedAt):null,attributes:Object.fromEntries(Object.entries(e.attributeMap).map(([e,t])=>[e,Bn(Yn,t)]))}}async function listMachineUsers(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),{config:r}=await loadConfig(e?.configPath),{application:i}=await t.getApplication({workspaceId:n,applicationName:r.name});if(!i?.authNamespace)throw Error(`Application ${r.name} does not have an auth configuration.`);let a=toPageDirection(e?.order);return(await jt(async(e,r)=>{let{machineUsers:o,nextPageToken:s}=await t.listAuthMachineUsers({workspaceId:n,pageToken:e,pageSize:r,authNamespace:i.authNamespace,pageDirection:a});return[o,s]},{limit:e?.limit})).map(machineUserInfo)}const cs=X({name:`list`,description:`List all machine users in the application.`,args:H.strictObject({...Wr,...paginationArgs()}),run:async e=>{let t=await listMachineUsers({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,order:e.order,limit:e.limit});M.out(t,{display:{createdAt:null,updatedAt:null}})}});async function getMachineUserTokenInternal(e){let t=await loadMachineUserName({machineUser:e.name,machineUserSource:e.nameSource,profile:e.profile});if(!t)throw Error(`Machine user is required. Provide the NAME positional argument, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.`);let{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),{config:i}=await loadConfig(e.configPath),{application:a}=await n.getApplication({workspaceId:r,applicationName:i.name});if(!a?.authNamespace)throw Error(`Application ${i.name} does not have an auth configuration.`);let{machineUser:o}=await n.getAuthMachineUser({workspaceId:r,authNamespace:a.authNamespace,name:t});if(!o)throw Error(`Machine user ${t} not found.`);let s=await kt(a.url,o.clientId,o.clientSecret),c=new Date;return c.setSeconds(c.getSeconds()+s.expires_in),{accessToken:s.access_token,tokenType:s.token_type,expiresAt:c.toISOString()}}async function getMachineUserToken(e){return await getMachineUserTokenInternal(e)}const ls=X({name:`token`,description:`Get an access token for a machine user.`,args:H.strictObject({...Wr,name:V(H.string().optional(),{positional:!0,description:`Machine user name. Falls back to TAILOR_PLATFORM_MACHINE_USER_NAME, then the active profile's default machine user.`})}),run:async e=>{let t=await getMachineUserTokenInternal({name:e.name,nameSource:resolveMachineUserInputSource(e.name,process.argv.slice(2),{valueIsExplicit:e.name!==void 0}),workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config}),n={access_token:t.accessToken,token_type:t.tokenType,expires_at:t.expiresAt};M.out(n)}}),grantTypeToString=e=>{switch(e){case r.AUTHORIZATION_CODE:return`authorization_code`;case r.REFRESH_TOKEN:return`refresh_token`;default:return`unknown`}};function toOAuth2ClientInfo(e){return{name:e.name,description:e.description,clientId:e.clientId,grantTypes:e.grantTypes.map(grantTypeToString),redirectUris:e.redirectUris,createdAt:e.createdAt?G(e.createdAt):null}}function toOAuth2ClientCredentials(e){return{name:e.name,description:e.description,clientId:e.clientId,clientSecret:e.clientSecret,grantTypes:e.grantTypes.map(grantTypeToString),redirectUris:e.redirectUris,createdAt:e.createdAt?G(e.createdAt):null}}async function getOAuth2Client(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),{config:r}=await loadConfig(e.configPath),{application:i}=await t.getApplication({workspaceId:n,applicationName:r.name});if(!i?.authNamespace)throw Error(`Application ${r.name} does not have an auth configuration.`);try{let{oauth2Client:r}=await t.getAuthOAuth2Client({workspaceId:n,namespaceName:i.authNamespace,name:e.name});return toOAuth2ClientCredentials(A(r,`oauth2Client missing in response`))}catch(t){throw t instanceof q&&t.code===K.NotFound?Error(`OAuth2 client '${e.name}' not found.`,{cause:t}):t}}const us=X({name:`get`,description:`Get OAuth2 client credentials (including client secret).`,args:H.strictObject({...Wr,name:V(H.string(),{positional:!0,description:`OAuth2 client name`})}),run:async e=>{let t=await getOAuth2Client({name:e.name,workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config});M.out(t)}});async function listOAuth2Clients(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),{config:r}=await loadConfig(e?.configPath),{application:i}=await t.getApplication({workspaceId:n,applicationName:r.name});if(!i?.authNamespace)throw Error(`Application ${r.name} does not have an auth configuration.`);let a=toPageDirection(e?.order);return(await jt(async(e,r)=>{let{oauth2Clients:o,nextPageToken:s}=await t.listAuthOAuth2Clients({workspaceId:n,pageToken:e,pageSize:r,namespaceName:i.authNamespace,pageDirection:a});return[o,s]},{limit:e?.limit})).map(toOAuth2ClientInfo)}const ds=X({name:`list`,description:`List all OAuth2 clients in the application.`,args:H.strictObject({...Wr,...paginationArgs()}),run:async e=>{let t=await listOAuth2Clients({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,order:e.order,limit:e.limit});M.out(t)}}),userOrganizationInfo=e=>({organizationId:e.organizationId,organizationName:e.organizationName,rootFolderId:e.rootFolderId,rootFolderName:e.rootFolderName,displayName:e.displayName}),organizationInfo=e=>({id:e.id,name:e.name,createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)}),folderListInfo=e=>({id:e.id,name:e.name,organizationId:e.organizationId,parentFolderId:e.parentFolderId,hasChildren:e.hasChildren,createdAt:formatTimestamp(e.createTime)}),folderInfo=e=>({...folderListInfo(e),updatedAt:formatTimestamp(e.updateTime)}),fs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),parentFolderId:H.string().optional(),name:H.string().min(1,`Name must not be empty`)});async function createFolder(e){let t=parseOptions(fs,e),n=await loadAccessToken(),r=await(await F(n)).createOrganizationFolder({organizationId:t.organizationId,parentFolderId:t.parentFolderId??``,folderName:t.name});if(!r.folder)throw Error(`Failed to create folder.`);return folderInfo(r.folder)}const ps=X({name:`create`,description:`Create a new folder in an organization.`,args:H.strictObject({...Kr,"parent-folder-id":V(H.string().optional(),{description:`Parent folder ID`}),name:V(H.string(),{alias:`n`,description:`Folder name`})}),run:async e=>{await assertWritable();let t=await createFolder({organizationId:e[`organization-id`],parentFolderId:e[`parent-folder-id`],name:e.name});e.json||M.success(`Folder "${t.name}" created successfully.`),M.out(t)}}),ms=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`})});async function deleteFolder(e){let t=parseOptions(ms,e),n=await loadAccessToken();await(await F(n)).deleteOrganizationFolder({organizationId:t.organizationId,folderId:t.folderId})}const hs=X({name:`delete`,description:`Delete a folder from an organization.`,args:H.strictObject({...Kr,...Jr,...Gr}),run:async e=>{await assertWritable();let t=await loadAccessToken(),n=await F(t),r;try{r=await n.getOrganizationFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]})}catch(t){throw t instanceof q&&t.code===K.NotFound?Error(`Folder "${e[`folder-id`]}" not found.`,{cause:t}):t}if(!r.folder)throw Error(`Folder "${e[`folder-id`]}" not found.`);let i=r.folder.name;if(!e.yes&&!await Z.confirm({message:`Are you sure you want to delete folder "${i}"?`})){M.info(`Folder deletion cancelled.`);return}await n.deleteOrganizationFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]}),M.success(`Folder "${i}" deleted successfully.`)}}),gs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`})});async function getFolder(e){let t=parseOptions(gs,e),n=await loadAccessToken(),r=await(await F(n)).getOrganizationFolder({organizationId:t.organizationId,folderId:t.folderId});if(!r.folder)throw Error(`Folder "${t.folderId}" not found.`);return folderInfo(r.folder)}const _s=X({name:`get`,description:`Show detailed information about a folder.`,args:H.strictObject({...Kr,...Jr}),run:async e=>{let t=await getFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`]}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}}),vs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),parentFolderId:H.string().optional(),order:zr.optional(),limit:H.number().int().nonnegative().optional()});async function listFolders(e){let{organizationId:t,parentFolderId:n,order:r,limit:i}=parseOptions(vs,e),a=await loadAccessToken(),o=await F(a),s=toPageDirection(r);return(await jt(async(e,r)=>{let i=await o.listOrganizationFolders({organizationId:t,...n?{parentFolderId:n}:{},pageToken:e,pageSize:r,pageDirection:s});return[i.folders,i.nextPageToken]},{limit:i})).map(folderListInfo)}const ys=X({name:`list`,description:`List folders in an organization.`,args:H.strictObject({...Kr,"parent-folder-id":V(H.string().optional(),{description:`Parent folder ID to list children of`}),...paginationArgs()}),run:async e=>{let t=await listFolders({organizationId:e[`organization-id`],parentFolderId:e[`parent-folder-id`],order:e.order,limit:e.limit});M.out(t,{display:{updatedAt:null}})}}),bs=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),folderId:H.uuid({message:`folder-id must be a valid UUID`}),name:H.string().min(1,`Name must not be empty`)});async function updateFolder(e){let t=parseOptions(bs,e),n=await loadAccessToken(),r=await(await F(n)).updateOrganizationFolder({organizationId:t.organizationId,folderId:t.folderId,folderName:t.name});if(!r.folder)throw Error(`Failed to update folder "${t.folderId}".`);return folderInfo(r.folder)}const xs=X({name:`update`,description:`Update a folder's name.`,args:H.strictObject({...Kr,...Jr,name:V(H.string(),{alias:`n`,description:`New folder name`})}),run:async e=>{await assertWritable();let t=await updateFolder({organizationId:e[`organization-id`],folderId:e[`folder-id`],name:e.name});e.json||M.success(`Folder "${t.name}" updated successfully.`),M.out(t)}}),Ss=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`})});async function getOrganization(e){let t=parseOptions(Ss,e),n=await loadAccessToken(),r=await(await F(n)).getOrganization({organizationId:t.organizationId});if(!r.organization)throw Error(`Organization "${t.organizationId}" not found.`);return organizationInfo(r.organization)}const Cs=X({name:`get`,description:`Show detailed information about an organization.`,args:H.strictObject({...Kr}),run:async e=>{let t=await getOrganization({organizationId:e[`organization-id`]}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n)}});async function listOrganizations(e){let t=e?.limit,n=await loadAccessToken(),{userOrganizations:r}=await(await F(n)).listUserOrganizations({}),i=r.map(userOrganizationInfo);return t===void 0?i:i.slice(0,t)}const ws=X({name:`list`,description:`List organizations you belong to.`,args:H.strictObject({limit:V(Lr.optional(),{alias:`l`,description:`Maximum number of organizations to list`})}),run:async e=>{let t=await listOrganizations({limit:e.limit});M.out(t)}});async function fetchChildFolders(e,t,n,r,i){if(i!==void 0&&r>=i)return[];let a=await At(async(r,i)=>{let a=await e.listOrganizationFolders({organizationId:t,parentFolderId:n,pageToken:r,pageSize:i});return[a.folders,a.nextPageToken]}),o=[];for(let n of a){let a=n.hasChildren?await fetchChildFolders(e,t,n.id,r+1,i):[];o.push({name:n.name,children:a})}return o}async function buildFolderTreeJson(e,t,n,r,i){if(i!==void 0&&r>=i)return[];let a=await At(async(r,i)=>{let a=await e.listOrganizationFolders({organizationId:t,parentFolderId:n,pageToken:r,pageSize:i});return[a.folders,a.nextPageToken]}),o=[];for(let n of a){let a=n.hasChildren?await buildFolderTreeJson(e,t,n.id,r+1,i):[];o.push({id:n.id,name:n.name,children:a})}return o}function renderTree(e,t){let n=``;for(let[r,i]of e.entries()){let a=r===e.length-1,o=a?`└── `:`├── `,s=a?` `:`│ `;n+=`${t}${o}${i.name}\n`,i.children.length>0&&(n+=renderTree(i.children,t+s))}return n}async function buildOrgTree(e,t,n){let r=await fetchChildFolders(e,t.organizationId,t.rootFolderId,0,n),i=`${t.organizationName}\n`;return i+=renderTree(r,``),i}async function organizationTree(e){let t=await loadAccessToken(),n=await F(t),r;if(e?.organizationId){if(r=(await listOrganizations()).filter(t=>t.organizationId===e.organizationId),r.length===0)throw Error(`Organization "${e.organizationId}" not found.`)}else r=await listOrganizations();let i=e?.depth,a=[];for(let e of r){let t=await buildFolderTreeJson(n,e.organizationId,e.rootFolderId,0,i);a.push({organizationId:e.organizationId,organizationName:e.organizationName,folders:t})}return a}const Ts=X({name:`tree`,description:`Display organization folder hierarchy as a tree.`,args:H.strictObject({"organization-id":V(H.string().optional(),{alias:`o`,description:`Organization ID (show all if omitted)`,env:`TAILOR_PLATFORM_ORGANIZATION_ID`}),depth:V(Lr.optional(),{alias:`d`,description:`Maximum folder depth to display`})}),run:async e=>{let t=await loadAccessToken(),n=await F(t),r;if(e[`organization-id`]){if(r=(await listOrganizations()).filter(t=>t.organizationId===e[`organization-id`]),r.length===0)throw Error(`Organization "${e[`organization-id`]}" not found.`)}else r=await listOrganizations();if(e.json){let t=[];for(let i of r){let r=await buildFolderTreeJson(n,i.organizationId,i.rootFolderId,0,e.depth);t.push({organizationId:i.organizationId,organizationName:i.organizationName,folders:r})}M.out(t);return}let i=[];for(let t of r)i.push(await buildOrgTree(n,t,e.depth));M.log(i.join(`
|
|
150
|
+
`))}}),Es=H.object({organizationId:H.uuid({message:`organization-id must be a valid UUID`}),name:H.string().min(1,`Name must not be empty`)});async function updateOrganization(e){let t=parseOptions(Es,e),n=await loadAccessToken(),r=await(await F(n)).updateOrganization({organizationId:t.organizationId,organizationName:t.name});if(!r.organization)throw Error(`Failed to update organization "${t.organizationId}".`);return organizationInfo(r.organization)}const Ds=X({name:`update`,description:`Update an organization's name.`,args:H.strictObject({...Kr,name:V(H.string(),{alias:`n`,description:`New organization name`})}),run:async e=>{await assertWritable();let t=await updateOrganization({organizationId:e[`organization-id`],name:e.name});e.json||M.success(`Organization "${t.name}" updated successfully.`),M.out(t)}});async function loadOptions$10(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),{config:r}=await loadConfig(e?.configPath),i=Qt({config:r});return warnMissingAppId(i.id),{client:t,workspaceId:n,application:i,config:r}}async function execRemove(e,t,n,r,i){let a={client:e,workspaceId:t,application:n,forRemoval:!0,config:r},o={tailorDB:await planTailorDB(a),staticWebsite:await planStaticWebsite(a),aiGateway:await planAIGateway(a),idp:await planIdP(a),auth:await planAuth(a),pipeline:await planPipeline(a),app:await planApplication(a),executor:await planExecutor(a),workflow:await planWorkflow(e,t,n.name,n.id,{},{}),workflowExecutionPolicy:await planWorkflowJobFunctionExecutionPolicy(e,t,n.name,n.id,{}),functionRegistry:await planFunctionRegistry(e,t,n.name,n.id,[]),secretManager:await planSecretManager(a)},s=Object.values(o).some(e=>`resourceOwners`in e&&e.resourceOwners.has(n.name)),c=[...o.functionRegistry.changeSet.lines(),...o.staticWebsite.changeSet.lines(),...o.aiGateway.changeSet.lines(),...o.app.lines(),...o.tailorDB.changeSet.service.lines(),...o.tailorDB.changeSet.type.lines(),...o.tailorDB.changeSet.gqlPermission.lines(),...o.pipeline.changeSet.service.lines(),...o.pipeline.changeSet.resolver.lines(),...o.executor.changeSet.lines(),...o.workflow.changeSet.lines(),...o.workflowExecutionPolicy.changeSet.lines(),...o.idp.changeSet.service.lines(),...o.idp.changeSet.client.lines(),...o.auth.changeSet.service.lines(),...o.auth.changeSet.idpConfig.lines(),...o.auth.changeSet.userProfileConfig.lines(),...o.auth.changeSet.tenantConfig.lines(),...o.auth.changeSet.machineUser.lines(),...o.auth.changeSet.oauth2Client.lines(),...o.auth.changeSet.authHook.lines(),...o.auth.changeSet.scim.lines(),...o.auth.changeSet.scimResource.lines(),...o.auth.changeSet.connection.lines(),...o.secretManager.vaultChangeSet.lines(),...o.secretManager.secretChangeSet.lines()];return c.length>0&&M.log(c.join(`
|
|
151
151
|
`)),o.tailorDB.changeSet.service.deletes.length===0&&o.staticWebsite.changeSet.deletes.length===0&&o.aiGateway.changeSet.deletes.length===0&&o.idp.changeSet.service.deletes.length===0&&o.auth.changeSet.service.deletes.length===0&&o.pipeline.changeSet.service.deletes.length===0&&o.app.deletes.length===0&&o.executor.changeSet.deletes.length===0&&o.workflow.changeSet.deletes.length===0&&o.workflowExecutionPolicy.changeSet.deletes.length===0&&o.functionRegistry.changeSet.deletes.length===0&&o.secretManager.vaultChangeSet.deletes.length===0&&o.secretManager.secretChangeSet.deletes.length===0?{leftBehind:s}:(i&&await i(),await applyWorkflow(e,o.workflow,`delete`),await applyWorkflowJobFunctionExecutionPolicy(e,o.workflowExecutionPolicy,`delete`),await applyExecutor(e,o.executor,`delete`),await applyStaticWebsite(e,o.staticWebsite,`delete`),await applyAIGateway(e,o.aiGateway,`delete`),await applyApplication(e,o.app,`delete`),await applyPipeline(e,o.pipeline,`delete-resources`),await applyPipeline(e,o.pipeline,`delete-services`),await applyAuth(e,o.auth,`delete-resources`),await applyAuth(e,o.auth,`delete-services`),await applyIdP(e,o.idp,`delete-resources`),await applyIdP(e,o.idp,`delete-services`),await applyTailorDB(e,o.tailorDB,`delete-resources`),await applyTailorDB(e,o.tailorDB,`delete-services`),await applyFunctionRegistry(e,t,o.functionRegistry,`delete`),await applySecretManager(e,o.secretManager,`delete`),{leftBehind:s})}async function remove(e){let{client:t,workspaceId:n,application:r,config:i}=await loadOptions$10(e);await execRemove(t,n,r,i)}const Os=X({name:`remove`,description:`Remove all resources managed by the application from the workspace.`,args:H.strictObject({...Wr,...Gr}),run:async e=>{await assertWritable({profile:e.profile});let{client:t,workspaceId:n,application:r,config:i}=await loadOptions$10({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config});M.info(`Planning removal of resources managed by "${r.name}"...`),M.newline();let{leftBehind:a}=await execRemove(t,n,r,i,async()=>{if(e.yes)M.success(`Removing all resources (--yes flag specified)...`);else if(!await Z.confirm({message:`Are you sure you want to remove all resources?`,default:!1}))throw Error(L`
|
|
152
152
|
Remove cancelled. No resources were deleted.
|
|
153
153
|
To override, run again and confirm, or use --yes flag.
|
|
154
154
|
`)});if(a){M.warn(L`
|
|
155
155
|
Resources tagged with "${r.name}" were left in place: they carry an application id this config does not match.
|
|
156
156
|
Put that id in your config, or run deploy to take them over first, then remove again.
|
|
157
|
-
`);return}M.success(`Successfully removed all resources managed by "${r.name}".`)}});function applicationInfo(e){return{name:e.name,domain:e.domain,url:e.url,auth:e.authNamespace,cors:e.cors,allowedIpAddresses:e.allowedIpAddresses,disableIntrospection:e.disableIntrospection,createdAt:e.createTime?G(e.createTime):null,updatedAt:e.updateTime?G(e.updateTime):null}}async function fetchAIGateways(e,t,n){return(await Promise.all(n.map(async n=>{try{let{aigateway:r}=await e.getAIGateway({workspaceId:t,aigatewayName:n});return r?{name:r.name,url:r.url}:void 0}catch(e){if(e instanceof q&&e.code===K.NotFound)return;throw e}}))).filter(e=>e!==void 0)}async function show(e){let
|
|
157
|
+
`);return}M.success(`Successfully removed all resources managed by "${r.name}".`)}});function applicationInfo(e){return{name:e.name,domain:e.domain,url:e.url,auth:e.authNamespace,cors:e.cors,allowedIpAddresses:e.allowedIpAddresses,disableIntrospection:e.disableIntrospection,createdAt:e.createTime?G(e.createTime):null,updatedAt:e.updateTime?G(e.updateTime):null}}async function fetchAIGateways(e,t,n){return(await Promise.all(n.map(async n=>{try{let{aigateway:r}=await e.getAIGateway({workspaceId:t,aigatewayName:n});return r?{name:r.name,url:r.url}:void 0}catch(e){if(e instanceof q&&e.code===K.NotFound)return;throw e}}))).filter(e=>e!==void 0)}async function show(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),{config:r}=await loadConfig(e?.configPath),i=r.aiGateways?.length?[...new Set(r.aiGateways.map(e=>e.name))]:[],[a,o,s]=await Promise.all([t.getWorkspace({workspaceId:n}),t.getApplication({workspaceId:n,applicationName:r.name}),fetchAIGateways(t,n,i)]),{name:c,...l}=applicationInfo(A(o.application,`application "${r.name}" not found in workspace`)),u=a.workspace,d=u?await resolveWorkspaceFolderName(t,u):``;return{name:c,workspaceId:n,workspaceName:u?.name??``,...d?{workspaceFolderName:d}:{},workspaceRegion:u?.region??``,...l,aiGateways:s}}const ks=createWorkspaceNameTransformer(`workspaceName`,`workspaceFolderName`),As=X({name:`show`,description:`Show information about the deployed application.`,args:H.strictObject({...Wr}),run:async e=>{let t=await show({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config});M.out(t,{display:{workspaceName:ks,workspaceFolderName:null}})}});function createProgress(e,t){let n=0;return{update:()=>{n+=1;let r=Math.round(n/t*100);process.stderr.write(`\r${e} ${n}/${t} (${r}%)`)},finish:()=>{process.stderr.write(`
|
|
158
158
|
`)}}}async function withTimeout(e,t,n){let r=new AbortController;try{return await Promise.race([e,Er(t,void 0,{signal:r.signal}).then(()=>{throw Error(n)})])}finally{r.abort()}}const js=new Set([`.DS_Store`,`thumbs.db`,`desktop.ini`]);function shouldIgnoreFile(e){let t=B.basename(e).toLowerCase();return js.has(t)}async function deployStaticWebsite(e,t,n,r,i=!0){let{deploymentId:a}=await e.createDeployment({workspaceId:t,name:n});if(!a)throw Error(`createDeployment returned empty deploymentId`);let o=await uploadDirectory(e,t,a,r,i),{url:s}=await e.publishDeployment({workspaceId:t,deploymentId:a});if(!s)throw Error(`publishDeployment returned empty url`);return{url:s,skippedFiles:o}}async function uploadDirectory(e,t,n,r,i){let a=await collectFiles(r);if(a.length===0)return M.warn(`No files found under ${r}`),[];let o=rr(5),s=a.length,c=i?createProgress(`Uploading files`,s):void 0,l=[];return await Promise.all(a.map(i=>o(async()=>{await uploadSingleFile(e,t,n,r,i,l),c&&c.update()}))),c&&c.finish(),l}async function collectFiles(e,t=``){let n=B.join(e,t),r=await Or.promises.readdir(n,{withFileTypes:!0}),i=[];for(let n of r){let r=B.join(t,n.name);if(n.isDirectory()){let t=await collectFiles(e,r);i.push(...t)}else n.isFile()&&!n.isSymbolicLink()&&!shouldIgnoreFile(r)&&i.push(r)}return i}async function uploadSingleFile(e,t,n,r,i,a){let o=B.join(r,i),s=kr(i);if(!s){a.push(`${i} (unsupported content type; no MIME mapping found)`);return}let c=s,l=Or.createReadStream(o,{highWaterMark:65536});async function*requestStream(){yield{payload:{case:`initialMetadata`,value:{workspaceId:t,deploymentId:n,filePath:i,contentType:c}}};for await(let e of l)yield{payload:{case:`chunkData`,value:e}}}async function uploadWithLogging(){try{await e.uploadFile(requestStream())}catch(e){if(e instanceof q&&e.code===K.InvalidArgument){a.push(`${i} (server rejected file as invalid: ${e.message})`);return}throw e}}await withTimeout(uploadWithLogging(),12e4,`Upload timed out for "${i}"`)}function logSkippedFiles(e){if(e.length!==0){M.warn(`Deployment completed, but some files failed to upload. These files may have unsupported content types or other validation issues. Please review the list below:`);for(let t of e)M.log(` - ${t}`)}}const Ms=X({name:`deploy`,description:`Deploy a static website from a local build directory.`,args:H.strictObject({...Y,name:V(H.string(),{alias:`n`,description:`Static website name`}),dir:V(H.string(),{alias:`d`,description:`Path to the static website files`,completion:{type:`directory`}})}),run:async e=>{await assertWritable({profile:e.profile}),M.info(`Deploying static website "${e.name}" from directory: ${e.dir}`);let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=e.name,i=B.resolve(process.cwd(),e.dir),a=await loadWorkspaceId({workspaceId:e[`workspace-id`],profile:e.profile});if(!Or.existsSync(i)||!Or.statSync(i).isDirectory())throw Error(`Directory not found or not a directory: ${i}`);let{url:o,skippedFiles:s}=await withTimeout(deployStaticWebsite(n,a,r,i,!e.json),6e5,`Deployment timed out after 10 minutes.`);e.json?M.out({name:r,workspaceId:a,url:o,skippedFiles:s}):(M.success(`Static website "${r}" deployed successfully. URL: ${o}`),logSkippedFiles(s))}});function logBetaWarning(e){M.warn(`The '${e}' command is a beta feature and may introduce breaking changes in future releases.`),M.newline()}function normalizeEditorCommand(e){let t=e?.trim();return t&&t.length>0?t:void 0}function getConfiguredEditorCommand(){return normalizeEditorCommand(process.env.VISUAL)??normalizeEditorCommand(process.env.EDITOR)}function getEditorCommand(){return getConfiguredEditorCommand()??`editor`}function parseEditorCommand(e){let[t,...n]=e.trim().split(/\s+/);if(!t)throw Error(`Editor command is empty.`);return{command:t,args:n}}async function openInEditor(e,t=getEditorCommand()){let{command:n,args:r}=parseEditorCommand(t);return await new Promise((t,i)=>{let a=Dr(n,[...r,e],{stdio:`inherit`,detached:!1});a.once(`error`,e=>i(e)),a.once(`close`,e=>{if(e==null||e===0){t();return}i(Error(`Editor exited with code ${e}.`))})}),!0}async function openInConfiguredEditor(e){let t=getConfiguredEditorCommand();return t?await openInEditor(e,t):!1}function fieldKey(e,t){return`${e}.${t}`}function buildTempFieldName(e,t){let n=`${e}Migrate`;for(let e=1;e<=t.size+1;e++){let r=e===1?n:`${n}${e}`;if(r.length>63)break;if(!t.has(r))return r}throw Error(`Cannot derive a temporary field name for "${e}": every candidate is taken or exceeds 63 characters.`)}function canConvertField(e){return getExpandContractEligibility(e).eligible}function getExpandContractEligibility(e){let{previous:t,current:n,tableName:r,fieldName:i}=e,a=t.tables[r]?.fields[i],o=n.tables[r]?.fields[i];if(!a||!o)return{eligible:!1,reason:`the field does not exist in both schemas`};let s=getExpandContractFieldChangeEligibility(a,o);return s.eligible?isFieldReferenced(t.tables[r],i)||isFieldReferenced(n.tables[r],i)?{eligible:!1,reason:`another schema feature references the field`}:{eligible:!0}:s}function typeMemberNames(e){return e?[...Object.keys(e.fields),...Object.keys(e.files??{}),...Object.keys(e.forwardRelationships??{}),...Object.keys(e.backwardRelationships??{})]:[]}function staticPropertyName(e,t){if(!t&&e.type===`Identifier`)return e.name;if(e.type===`Literal`&&typeof e.value==`string`)return e.value;if(e.type===`TemplateLiteral`&&e.expressions.length===0)return e.quasis[0]?.value.cooked??void 0}const Ns=new Set([`input`,`newRecord`,`oldRecord`,`invoker`,`now`]);function walkScriptAst(e,t,n=[]){if(!e)return;t(e,n);let r=[...n,e],i=e;for(let[e,n]of Object.entries(i))if(e!==`type`&&e!==`parent`){if(Array.isArray(n))for(let e of n)e&&typeof e==`object`&&`type`in e&&walkScriptAst(e,t,r);else n&&typeof n==`object`&&`type`in n&&walkScriptAst(n,t,r)}}function unwrapFunction(e){return e.type===`ParenthesizedExpression`?unwrapFunction(e.expression):e}function collectIssueBindings(e){let t=new Set([`__issues`]);walkScriptAst(e,e=>{if(e.type!==`CallExpression`)return;let n=unwrapFunction(e.callee);if(n.type!==`ArrowFunctionExpression`&&n.type!==`FunctionExpression`||e.arguments[1]?.type!==`Identifier`||e.arguments[1].name!==`__issues`)return;let r=n.params[1];r?.type===`Identifier`&&t.add(r.name)});let n;do{let r=t.size;walkScriptAst(e,e=>{e.type===`VariableDeclarator`&&e.id.type===`Identifier`&&e.init?.type===`Identifier`&&t.has(e.init.name)&&t.add(e.id.name)}),n=t.size>r}while(n);return t}function isWrapperArgumentProperty(e,t){if(e.type!==`Property`)return!1;let n=staticPropertyName(e.key,e.computed);if(!n||!Ns.has(n))return!1;let r=t.at(-1),i=t.at(-2);return r?.type!==`ObjectExpression`||i?.type!==`CallExpression`?!1:i.arguments[0]===r&&[`ArrowFunctionExpression`,`FunctionExpression`].includes(unwrapFunction(i.callee).type)}function isWrapperParameterProperty(e,t){if(e.type!==`Property`)return!1;let n=staticPropertyName(e.key,e.computed);if(!n||!Ns.has(n))return!1;let r=t.at(-1);if(r?.type!==`ObjectPattern`)return!1;for(let e=t.length-2;e>=0;e--){let i=t[e];if(i&&(i.type===`ArrowFunctionExpression`||i.type===`FunctionExpression`)&&i.params[0]===r)return t.slice(0,e).some(e=>e.type===`CallExpression`&&unwrapFunction(e.callee)===i&&e.arguments[0]?.type===`ObjectExpression`&&e.arguments[0].properties.some(e=>e.type===`Property`&&staticPropertyName(e.key,e.computed)===n))}return!1}function isIssueMessage(e,t,n){let r=t.at(-1);return r?.type===`CallExpression`&&r.callee.type===`Identifier`&&n.has(r.callee.name)&&r.arguments.findIndex(t=>t===e)>0}function scriptReferencesField(e,t){try{let{program:n,errors:r}=mr(`expand-contract-reference.js`,e,{sourceType:`module`});if(r.length>0)return!0;let i=collectIssueBindings(n),a=!1;return walkScriptAst(n,(e,n)=>{a||(e.type===`MemberExpression`&&(staticPropertyName(e.property,e.computed)===t||e.computed&&staticPropertyName(e.property,!0)===void 0)||e.type===`Property`&&(staticPropertyName(e.key,e.computed)===t||e.computed&&staticPropertyName(e.key,!0)===void 0)&&(e.computed||!isWrapperArgumentProperty(e,n)&&!isWrapperParameterProperty(e,n))||e.type===`CallExpression`&&e.callee.type===`Identifier`&&i.has(e.callee.name)&&e.arguments[0]!==void 0&&e.arguments[0].type!==`SpreadElement`&&staticPropertyName(e.arguments[0],!0)===t||(e.type===`Literal`||e.type===`TemplateLiteral`)&&staticPropertyName(e,!0)===t&&!isIssueMessage(e,n,i))&&(a=!0)}),a}catch{return!0}}function permissionsReferenceField(e,t){return e?[...e.record?Object.values(e.record).flatMap(e=>e):[],...e.gql??[]].some(e=>e.conditions.some(e=>{let[n,,r]=e;return[n,r].some(e=>isSnapshotFieldRefOperand(e)&&(`record`in e&&e.record===t||`newRecord`in e&&e.newRecord===t||`oldRecord`in e&&e.oldRecord===t))})):!1}function isFieldReferenced(e,t){return e?Object.values(e.indexes??{}).some(e=>e.fields.includes(t))||[...Object.values(e.forwardRelationships??{}),...Object.values(e.backwardRelationships??{})].some(e=>e.sourceField===t||e.targetField===t)||permissionsReferenceField(e.permissions,t)?!0:[e.typeHookExpr?.create,e.typeHookExpr?.update,e.typeValidateExpr].filter(e=>e!==void 0).some(e=>scriptReferencesField(e,t)):!1}function planExpandContract(e){let{previous:t,current:n,diff:r,confirmed:i}=e,a=[],o=new Set;for(let e of r.changes){if(e.kind!==`field_type_modified`)continue;let r=fieldKey(e.tableName,e.fieldName);if(!i.has(r)||!canConvertField({previous:t,current:n,tableName:e.tableName,fieldName:e.fieldName}))continue;let s=new Set([...typeMemberNames(t.tables[e.tableName]),...typeMemberNames(n.tables[e.tableName]),...a.filter(t=>t.tableName===e.tableName).map(e=>e.tempFieldName)]);a.push({tableName:e.tableName,fieldName:e.fieldName,tempFieldName:buildTempFieldName(e.fieldName,s),before:e.before,after:e.after}),o.add(r)}return{plans:a,blocked:r.breakingChanges.filter(e=>e.unsupported&&!(e.fieldName&&o.has(fieldKey(e.tableName,e.fieldName))))}}function extractBreakingChangeFields(e){let t=new Map,n=new Map,r=new Map,i=new Map,a=new Map;for(let o of e.changes)if(o.kind===`field_modified`||o.kind===`field_type_modified`){let{before:e,after:n}=o;if(!e.required&&n.required&&(t.has(o.tableName)||t.set(o.tableName,new Set),A(t.get(o.tableName),`optionalToRequired entry missing`).add(o.fieldName)),e.type===`enum`&&n.type===`enum`&&e.allowedValues&&n.allowedValues){let t=e.allowedValues.map(e=>e.value),i=n.allowedValues.map(e=>e.value),a=new Set(t),s=new Set(i);(t.some(e=>!s.has(e))||i.some(e=>!a.has(e)))&&(r.has(o.tableName)||r.set(o.tableName,new Map),A(r.get(o.tableName),`enumValueChanges entry missing`).set(o.fieldName,{beforeValues:t,afterValues:i}))}}else if(o.kind===`field_added`){let{after:e}=o;e.required&&(n.has(o.tableName)||n.set(o.tableName,new Map),A(n.get(o.tableName),`addedRequiredFields entry missing`).set(o.fieldName,e))}else o.kind===`field_renamed`?(i.has(o.tableName)||i.set(o.tableName,new Map),A(i.get(o.tableName),`renamedFields entry missing`).set(o.fieldName,o.after)):o.kind===`table_renamed`&&a.set(o.tableName,o.after);return{optionalToRequired:t,addedRequiredFields:n,enumValueChanges:r,renamedFields:i,clearedFields:new Map,renamedTypes:a}}function generateDbTypesFromSnapshot(e,t,n=[]){let r=t?extractBreakingChangeFields(t):{optionalToRequired:new Map,addedRequiredFields:new Map,enumValueChanges:new Map,renamedFields:new Map,clearedFields:new Map,renamedTypes:new Map};for(let e of n){let t=r.renamedFields.get(e.tableName)??new Map;t.set(e.tempFieldName,{...e.after,required:!1,unique:!1}),r.renamedFields.set(e.tableName,t);let n=r.clearedFields.get(e.tableName)??new Set;n.add(e.fieldName),r.clearedFields.set(e.tableName,n)}let i=[...Object.values(e.tables),...r.renamedTypes.values()];if(i.length===0)return generateEmptyDbTypes(e.namespace);let a=new Set,o=!1,s=[];for(let e of i){let t=generateTableType(e,r);t.usedTimestamp&&a.add(`Timestamp`),o||=t.usedArrayColumnType,s.push(t.typeDef)}let c=[`type ColumnType`,`type Transaction as KyselyTransaction`];o&&c.push(`type ArrayColumnType`);let l=[];return a.has(`Timestamp`)&&l.push(`type Timestamp = ColumnType<Date, Date | string, Date | string>;`),l.push(`type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
|
|
159
159
|
? ColumnType<S, I | undefined, U>
|
|
160
160
|
: ColumnType<T, T | undefined, T>;`),a.has(`Serial`)&&l.push(`type Serial<T = string | number> = ColumnType<T, never, never>;`),[`/**`,` * Auto-generated Kysely types for migration script.`,` * These types reflect the database schema state at this migration point.`,` *`,` * DO NOT EDIT - This file is auto-generated by the migration system.`,` */`,``,`import { ${c.join(`, `)} } from "@tailor-platform/sdk/kysely";`,`import type { Env } from "@tailor-platform/sdk";`,``,...l,``,`export interface Database {`,...s,`}`,``,`export type Transaction = KyselyTransaction<Database>;`,``,"/** Context passed as the second argument to the migration's `main` function. */",`export type MigrationContext = {`,` env: keyof Env extends never ? Record<string, string | number | boolean> : Env;`,`};`].join(`
|
|
@@ -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 Fs=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({...Hr,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-B4tCGHiQ.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 Fs=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({...Hr,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-BFTkaW6X.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(`
|
|
@@ -574,7 +574,7 @@ This is the baseline schema. Future changes will be tracked as diffs.`)}function
|
|
|
574
574
|
errors,
|
|
575
575
|
};
|
|
576
576
|
}
|
|
577
|
-
`}async function bundleSeedScript(e,t,n=process.cwd()){let r=B.resolve(Gt(),`seed`);W.mkdirSync(r,{recursive:!0});let i=B.join(r,`seed_${e}.entry.ts`),a=generateSeedScriptContent(e);W.writeFileSync(i,a);let o;try{o=await Pn(n)}catch{o=void 0}let s=St({tsconfig:o}),c=await pr.build({plugins:[Ot(i,n),gt(),wt],input:i,write:!1,output:{format:`esm`,sourcemap:!1,minify:!1,codeSplitting:!1,globals:{tailordb:`tailordb`}},external:[`tailordb`],resolve:{conditionNames:[`node`,`import`]},tsconfig:o,treeshake:{moduleSideEffects:!1,annotations:!0,unknownGlobalSideEffects:!1},...s.options});return s.assertAllResolved(),{namespace:e,bundledCode:c.output[0].code,typesIncluded:t}}function chunkSeedData(e){let{data:t,order:n,codeByteSize:r,maxMessageSize:i=3670016}=e,a=i-r-1024;if(a<=0)throw Error(`Code size (${r} bytes) exceeds the message size limit (${i} bytes). No space left for seed data.`);let o=n.filter(e=>(t[e]?.length??0)>0);if(o.length===0)return[];if(byteSize(JSON.stringify({data:t,order:n}))<=a)return[{data:t,order:n,index:0,total:1}];let s=[],c={},l=[];for(let e of o){let n=A(t[e],`seed data missing for type: ${e}`);if(l.length>0){let t={...c,[e]:n},r=[...l,e];byteSize(JSON.stringify({data:t,order:r}))>a&&(s.push({data:c,order:l,index:s.length}),c={},l=[])}if(byteSize(JSON.stringify({data:{[e]:n},order:[e]}))<=a){c[e]=n,l.push(e);continue}l.length>0&&(s.push({data:c,order:l,index:s.length}),c={},l=[]);let r=[];for(let t of n){if(byteSize(JSON.stringify({data:{[e]:[t]},order:[e]}))>a){let n=byteSize(JSON.stringify(t));throw Error(`A single record in table "${e}" (${n} bytes) exceeds the message size budget (${a} bytes). Consider increasing maxMessageSize or reducing the record size.`)}let n=[...r,t],i={...c,[e]:n},o=l.includes(e)?l:[...l,e];byteSize(JSON.stringify({data:i,order:o}))>a&&r.length>0?(c[e]=r,l.includes(e)||l.push(e),s.push({data:c,order:l,index:s.length}),c={},l=[],r=[t]):r=n}r.length>0&&(c[e]=r,l.includes(e)||l.push(e))}l.length>0&&s.push({data:c,order:l,index:s.length});let u=s.length;return s.map(e=>({...e,total:u}))}function byteSize(e){return new TextEncoder().encode(e).length}function processSeedTypeInfo(e,t){let n=new Set,r=[];for(let[t,i]of Object.entries(e.fields)){let a=i.relation?.targetType??i.config.foreignKeyType;a&&(a===e.name?r.push(t):n.add(a))}return{name:e.name,namespace:t,dependencies:Array.from(n),selfRefFields:r,dataFile:`data/${e.name}.jsonl`}}function buildSeedNamespaceConfigs(e){return e.map(e=>{let t=[],n={},r=[],i={};for(let[a,o]of Object.entries(e.tables)){let s=processSeedTypeInfo(o,e.namespace);t.push(s.name),n[s.name]=s.dependencies,s.selfRefFields.length>0&&r.push(s.name);let c=A(e.sourceInfo.get(a),`source info missing for table: ${a}`),l=En(o,c);i[s.name]=Object.entries(o.fields).filter(([e,t])=>t.config.required!==!1&&!l.optionalFields.includes(e)&&!l.omitFields.includes(e)).map(([e])=>e)}return{namespace:e.namespace,types:t,dependencies:n,selfRefTypes:r,requiredFields:i}})}async function loadSeedContext(e={}){let{config:t,plugins:n,application:r,namespaces:i}=await loadApplicationNamespaces({configPath:e.configPath});en({tailorDBServices:r.tailorDBServices});let a=resolvePluginConfig(n,On);if(!a)throw Error(`seedPlugin is not configured in ${t.path}. Add seedPlugin({ distPath: "./seed" }) from "@tailor-platform/sdk/plugin/seed" to definePlugins().`);if(typeof a.distPath!=`string`||a.distPath===``)throw Error(`seedPlugin in ${t.path} has no distPath option. Pass seedPlugin({ distPath: "./seed" }) so seed data has a location.`);await r.authService?.resolveNamespaces();let o=getAuthInput(r),s=o?Dn(o):void 0,c=s?{idpNamespace:s.idpNamespace,seedScriptCode:Cn(s.idpNamespace),listScriptCode:wn(s.idpNamespace),truncateScriptCode:Tn(s.idpNamespace)}:null;return{config:t,distPath:B.resolve(a.distPath),machineUserName:a.machineUserName,namespaces:buildSeedNamespaceConfigs(i),idpUser:c}}async function resolveTableNamespaces(e){let t=new Map;for(let n of e.tableNames){let e=n.toLowerCase(),r=t.get(e);if(r){r.push(n);continue}t.set(e,[n])}let n=new Set(e.tableNames),r=new Map;for(let i of e.namespaces){if(n.size===0)break;try{let{tailordbTypes:a}=await e.client.listTailorDBTypes({workspaceId:e.workspaceId,namespaceName:i});for(let e of a){let a=t.get(e.name.toLowerCase());if(a)for(let e of a)r.has(e)||(r.set(e,i),n.delete(e))}}catch{continue}}return r}async function truncateSingleType(e,t){await t.truncateTailorDBType({workspaceId:e.workspaceId,namespaceName:e.namespaceName,tailordbTypeName:e.tableName}),M.success(`Truncated table "${e.tableName}" in namespace "${e.namespaceName}"`)}async function truncateNamespace(e,t,n){await n.truncateTailorDBTypes({workspaceId:e,namespaceName:t}),M.success(`Truncated all tables in namespace "${t}"`)}async function truncate(e){return await $truncate({...e,yes:!0})}async function $truncate(e={}){let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile}),i=e.tables&&e.tables.length>0,a=!!e.namespace,o=!!e.all,s=[o,a,i].filter(Boolean).length;if(s===0)throw Error(`Please specify one of: --all, --namespace <name>, or table names`);if(s>1)throw Error(`Options --all, --namespace, and table names are mutually exclusive. Please specify only one.`);let{config:c}=await loadConfig(e.configPath),l=extractOwnedNamespaces(c);if(o){if(l.length===0){M.warn(`No namespaces found in config file.`);return}if(!e.yes){let e=l.join(`, `);if(!await Z.confirm({message:`This will truncate ALL tables in the following owned namespaces (external namespaces are excluded): ${e}. Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}}for(let e of l)await truncateNamespace(r,e,n);M.success(`Truncated all tables in all owned namespaces`);return}if(a){let t=A(e.namespace,`namespace option missing`);if(!l.includes(t)){let e=c.db?.[t];throw e&&`external`in e?Error(`Namespace "${t}" is declared as external in this app's config and cannot be truncated from here. Run truncate from the app that owns it.`):Error(`Namespace "${t}" not found in config. Available owned namespaces (external namespaces are excluded): ${l.join(`, `)}`)}if(!e.yes&&!await Z.confirm({message:`This will truncate ALL tables in namespace "${t}". Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}await truncateNamespace(r,t,n);return}if(i){let t=A(e.tables,`tables option missing`),i=await resolveTableNamespaces({workspaceId:r,namespaces:l,tableNames:t,client:n}),a=t.filter(e=>!i.has(e));if(a.length>0)throw Error(`The following tables were not found in any namespace: ${a.join(`, `)}`);if(!e.yes){let e=t.join(`, `);if(!await Z.confirm({message:`This will truncate the following tables: ${e}. Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}}for(let e of t){let t=i.get(e);t&&await truncateSingleType({workspaceId:r,namespaceName:t,tableName:e},n)}}}const Ls=X({name:`truncate`,description:`Truncate (delete all records from) TailorDB tables.`,args:H.strictObject({...Wr,...Gr,tables:V(H.string().array().optional(),{positional:!0,description:`Table names to truncate`}),all:V(H.boolean().default(!1),{alias:`a`,description:`Truncate all tables in all owned namespaces (excludes external namespaces)`}),namespace:V(H.string().optional(),{alias:`n`,description:`Truncate all tables in specified namespace`})}),run:async e=>{await assertWritable({profile:e.profile});let t=e.tables&&e.tables.length>0?e.tables:void 0;await $truncate({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,all:e.all,namespace:e.namespace,tables:t,yes:e.yes})}});async function listWorkflows(e){let t=await loadAccessToken({profile:e?.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e?.workspaceId,profile:e?.profile}),i=toPageDirection(e?.order);return(await jt(async(e,t)=>{let{workflows:a,nextPageToken:o}=await n.listWorkflows({workspaceId:r,pageToken:e,pageSize:t,pageDirection:i});return[a,o]},{limit:e?.limit})).map(toWorkflowListInfo)}const Rs=X({name:`list`,description:`List all workflows in the workspace.`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listWorkflows({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});n.length===0&&(M.info(`No workflows found.`),!t)||M.out(n)}});async function resumeWorkflow(e){let t=await loadAccessToken({profile:e.profile}),n=await F(t),r=await loadWorkspaceId({workspaceId:e.workspaceId,profile:e.profile});try{let{executionId:t}=await n.testResumeWorkflow({workspaceId:r,executionId:e.executionId});return{executionId:t,wait:i=>waitForWorkflowExecution({client:n,workspaceId:r,executionId:t,interval:e.interval??3e3,timeout:i?.timeout,until:i?.until,showProgress:i?.showProgress})}}catch(t){if(t instanceof q){if(t.code===K.NotFound)throw Error(`Execution '${e.executionId}' not found.`,{cause:t});if(t.code===K.FailedPrecondition)throw Error(`Execution '${e.executionId}' is not in a resumable state.`,{cause:t})}throw t}}const zs=X({name:`resume`,description:`Resume a failed or pending workflow execution.`,args:H.strictObject({...Y,"execution-id":V(H.string(),{positional:!0,description:`Failed execution ID`}),...qo}),run:async e=>{let t=M.jsonMode||e.json,{executionId:n,wait:r}=await resumeWorkflow({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval)});if(t||M.info(`Execution ID: ${n}`,{mode:`stream`}),e.wait){let i=await r({showProgress:!t,timeout:parseDuration(e.timeout),until:e.until});if(e.logs&&!t){let{execution:t}=await getWorkflowExecution({executionId:n,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(t)}else if(e.logs){let{execution:t}=await getWorkflowExecution({executionId:n,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});M.out({...i,jobDetails:t.jobDetails})}else M.out(i);let a=getWorkflowWaitFailureMessage(i,e.until);if(a)throw Error(a)}else M.out({executionId:n})}});async function waitWorkflowExecution(e){return await waitForWorkflowExecutionById({...e,showProgress:e.showProgress??!M.jsonMode,trackJobs:e.trackJobs??!0})}async function addWorkflowLogsToWaitResult(e,t){let{execution:n}=await getWorkflowExecution({executionId:t.executionId,workspaceId:t.workspaceId,profile:t.profile,logs:!0});return{...e,jobDetails:n.jobDetails}}const Bs=X({name:`wait`,description:`Wait for a workflow execution.`,examples:[{cmd:`execution-id --until success --timeout 10m --json`,desc:`Wait for workflow success`},{cmd:`execution-id --until suspended --timeout 6m --logs --json`,desc:`Wait for a workflow wait point`},{cmd:`execution-id --until terminal`,desc:`Wait for success, failure, or suspension`}],args:H.strictObject({...Y,"execution-id":V(H.string(),{positional:!0,description:`Execution ID`}),...Ko}),run:async e=>{let t=M.jsonMode||e.json,n=await waitWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval),timeout:parseDuration(e.timeout),until:e.until,showProgress:!t}),r=e.logs?await addWorkflowLogsToWaitResult(n,{executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile}):n;!t&&r.jobDetails?printExecutionWithLogs({id:r.id,workflowName:r.workflowName,status:r.status,jobExecutions:r.jobExecutions,startedAt:r.startedAt,finishedAt:r.finishedAt,jobDetails:r.jobDetails}):M.out(r);let i=getWorkflowWaitFailureMessage(n,e.until);if(i)throw Error(i)}}),statusToString=e=>{switch(e){case ue.OK:return`ok`;case ue.COMPOSITION_ERROR:return`composition_error`;default:return`unknown`}},attemptStatusToString=e=>{switch(e){case We.SUCCEEDED:return`success`;case We.FAILED:return`failure`;default:return`unknown`}},appInfo=e=>({name:e.name,domain:e.domain,authNamespace:e.authNamespace,createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)}),appHealthInfo=(e,t)=>{let n=t.lastSchemaUpdateAttempt;return{name:e,status:statusToString(t.status),currentServingSchemaUpdatedAt:formatTimestamp(t.currentServingSchemaUpdateTime),lastAttemptStatus:n?attemptStatusToString(n.status):`N/A`,lastAttemptAt:formatTimestamp(n?.attemptTime),lastAttemptError:n?.error??``}},Vs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),name:H.string().min(1,{message:`name is required`})});async function loadOptions$9(e){let t=Vs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),name:t.data.name}}async function getAppHealth(e){let{client:t,workspaceId:n,name:r}=await loadOptions$9(e),i=await t.getApplicationSchemaHealth({workspaceId:n,applicationName:r});return appHealthInfo(r,i)}const Hs=X({name:`health`,description:`Check application schema health`,args:H.strictObject({...Y,name:V(H.string(),{description:`Application name`,alias:`n`})}),run:async e=>{let t=await getAppHealth({workspaceId:e[`workspace-id`],profile:e.profile,name:e.name}),n=e.json?t:{...t,currentServingSchemaUpdatedAt:humanizeRelativeTime(t.currentServingSchemaUpdatedAt),lastAttemptAt:humanizeRelativeTime(t.lastAttemptAt)};M.out(n)}}),Us=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:zr.optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$8(e){let t=Us.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),order:t.data.order,limit:t.data.limit}}async function listApps(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$8(e),a=toPageDirection(r);return(await jt(async(e,r)=>{let{applications:i,nextPageToken:o}=await t.listApplications({workspaceId:n,pageToken:e,pageSize:r,pageDirection:a});return[i,o]},{limit:i})).map(appInfo)}const Ws=X({name:`list`,description:`List applications in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listApps({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({updatedAt:e,createdAt:t,...n})=>({...n,createdAt:humanizeRelativeTime(t)}));M.out(r)}}),Gs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`})});async function loadOptions$7(e){let t=Gs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken();return{client:await F(n),workspaceId:t.data.workspaceId}}async function deleteWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$7(e);await t.deleteWorkspace({workspaceId:n})}const Ks=X({name:`delete`,description:`Delete a Tailor Platform workspace.`,args:H.strictObject({"workspace-id":V(H.string(),{alias:`w`,description:`Workspace ID`}),...Gr}),run:async e=>{await assertWritable();let{client:t,workspaceId:n}=await loadOptions$7({workspaceId:e[`workspace-id`]}),r;try{r=await t.getWorkspace({workspaceId:n})}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workspace "${n}" not found.`,{cause:e}):e}let i=r.workspace,a=i?.name??n,o=workspaceDisplayName({name:a,folderName:i?await resolveWorkspaceFolderName(t,i):``});if(!e.yes){let e=await Z.text({message:`Enter the workspace name to confirm deletion (${o}):`});if(e!==a&&e!==o){M.info(`Workspace deletion cancelled.`);return}}await t.deleteWorkspace({workspaceId:n});let s=await readPlatformConfig(),c=Object.entries(s.profiles).filter(([,e])=>e?.workspace_id===n);if(c.length>0){for(let[e]of c)delete s.profiles[e];writePlatformConfig(s)}c.length>0?M.success(`Workspace "${o}" and ${c.length} associated profile(s) deleted successfully.`):M.success(`Workspace "${o}" deleted successfully.`)}}),qs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional()});async function loadOptions$6(e){let t=qs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile})}}async function getWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$6(e),r=await t.getWorkspace({workspaceId:n});if(!r.workspace)throw Error(`Workspace "${n}" not found.`);return workspaceDetailsWithFolderName(t,r.workspace)}const Js=X({name:`get`,description:`Show detailed information about a workspace`,args:H.strictObject({...Y}),run:async e=>{let t=await getWorkspace({workspaceId:e[`workspace-id`],profile:e.profile}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n,{display:{name:Io,folderName:null}})}}),Ys=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`})});async function loadOptions$5(e){let t=Ys.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken();return{client:await F(n),workspaceId:t.data.workspaceId}}async function restoreWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$5(e);await t.restoreWorkspace({workspaceId:n})}const Xs=X({name:`restore`,description:`Restore a deleted workspace`,args:H.strictObject({"workspace-id":V(H.string(),{alias:`w`,description:`Workspace ID`}),...Gr}),run:async e=>{await assertWritable();let{client:t,workspaceId:n}=await loadOptions$5({workspaceId:e[`workspace-id`]});if(!e.yes&&await Z.text({message:`Are you sure you want to restore workspace "${n}"? (yes/no):`})!==`yes`){M.info(`Workspace restoration cancelled.`);return}await t.restoreWorkspace({workspaceId:n}),M.success(`Workspace "${n}" restored successfully.`)}}),roleToString=e=>{switch(e){case Xe.ADMIN:return`admin`;case Xe.EDITOR:return`editor`;case Xe.VIEWER:return`viewer`;default:return`unknown`}},stringToRole=e=>{switch(e.toLowerCase()){case`admin`:return Xe.ADMIN;case`editor`:return Xe.EDITOR;case`viewer`:return Xe.VIEWER;default:throw Error(`Invalid role: ${e}. Valid roles: admin, editor, viewer`)}},userInfo=e=>({userId:e.platformUser?.userId??``,email:e.platformUser?.email??``,role:roleToString(e.role)}),Zs=[`admin`,`editor`,`viewer`],Qs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.email({message:`email must be a valid email address`}),role:H.enum(Zs,{message:`role must be one of: ${Zs.join(`, `)}`})});async function loadOptions$4(e){let t=Qs.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),email:t.data.email,role:stringToRole(t.data.role)}}async function inviteUser(e){let{client:t,workspaceId:n,email:r,role:i}=await loadOptions$4(e);await t.inviteWorkspacePlatformUser({workspaceId:n,email:r,role:i})}const $s=X({name:`invite`,description:`Invite a user to a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to invite`}),role:V(H.enum(Zs),{description:`Role to assign (${Zs.join(`, `)})`,alias:`r`})}),run:async e=>{await assertWritable({profile:e.profile}),await inviteUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email,role:e.role}),M.success(`User "${e.email}" invited successfully with role "${e.role}".`)}}),ec=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:zr.optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$3(e){let t=ec.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),order:t.data.order,limit:t.data.limit}}async function listUsers(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$3(e),a=toPageDirection(r);return(await jt(async(e,r)=>{let{workspacePlatformUsers:i,nextPageToken:o}=await t.listWorkspacePlatformUsers({workspaceId:n,pageToken:e,pageSize:r,pageDirection:a});return[i,o]},{limit:i})).map(userInfo)}const tc=X({name:`list`,description:`List users in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=await listUsers({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});M.out(t)}}),nc=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.string().email({message:`email must be a valid email address`})});async function loadOptions$2(e){let t=nc.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),email:t.data.email}}async function removeUser(e){let{client:t,workspaceId:n,email:r}=await loadOptions$2(e);await t.removeWorkspacePlatformUser({workspaceId:n,email:r})}const rc=X({name:`remove`,description:`Remove a user from a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to remove`}),...Gr}),run:async e=>{if(await assertWritable({profile:e.profile}),!e.yes&&await Z.text({message:`Are you sure you want to remove user "${e.email}" from the workspace? (yes/no):`})!==`yes`){M.info(`User removal cancelled.`);return}await removeUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email}),M.success(`User "${e.email}" removed from workspace.`)}}),ic=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.string().email({message:`email must be a valid email address`}),role:H.enum(Zs,{message:`role must be one of: ${Zs.join(`, `)}`})});async function loadOptions$1(e){let t=ic.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`Zod returned no issues`).message);let n=await loadAccessToken({profile:t.data.profile});return{client:await F(n),workspaceId:await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.profile}),email:t.data.email,role:stringToRole(t.data.role)}}async function updateUser(e){let{client:t,workspaceId:n,email:r,role:i}=await loadOptions$1(e);await t.updateWorkspacePlatformUser({workspaceId:n,email:r,role:i})}const ac=X({name:`update`,description:`Update a user's role in a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to update`}),role:V(H.enum(Zs),{description:`New role to assign (${Zs.join(`, `)})`,alias:`r`})}),run:async e=>{await assertWritable({profile:e.profile}),await updateUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email,role:e.role}),M.success(`User "${e.email}" updated to role "${e.role}".`)}});function createSqlEntry(){return L`
|
|
577
|
+
`}async function bundleSeedScript(e,t,n=process.cwd()){let r=B.resolve(Gt(),`seed`);W.mkdirSync(r,{recursive:!0});let i=B.join(r,`seed_${e}.entry.ts`),a=generateSeedScriptContent(e);W.writeFileSync(i,a);let o;try{o=await Pn(n)}catch{o=void 0}let s=St({tsconfig:o}),c=await pr.build({plugins:[Ot(i,n),gt(),wt],input:i,write:!1,output:{format:`esm`,sourcemap:!1,minify:!1,codeSplitting:!1,globals:{tailordb:`tailordb`}},external:[`tailordb`],resolve:{conditionNames:[`node`,`import`]},tsconfig:o,treeshake:{moduleSideEffects:!1,annotations:!0,unknownGlobalSideEffects:!1},...s.options});return s.assertAllResolved(),{namespace:e,bundledCode:c.output[0].code,typesIncluded:t}}function chunkSeedData(e){let{data:t,order:n,codeByteSize:r,maxMessageSize:i=3670016}=e,a=i-r-1024;if(a<=0)throw Error(`Code size (${r} bytes) exceeds the message size limit (${i} bytes). No space left for seed data.`);let o=n.filter(e=>(t[e]?.length??0)>0);if(o.length===0)return[];if(byteSize(JSON.stringify({data:t,order:n}))<=a)return[{data:t,order:n,index:0,total:1}];let s=[],c={},l=[];for(let e of o){let n=A(t[e],`seed data missing for type: ${e}`);if(l.length>0){let t={...c,[e]:n},r=[...l,e];byteSize(JSON.stringify({data:t,order:r}))>a&&(s.push({data:c,order:l,index:s.length}),c={},l=[])}if(byteSize(JSON.stringify({data:{[e]:n},order:[e]}))<=a){c[e]=n,l.push(e);continue}l.length>0&&(s.push({data:c,order:l,index:s.length}),c={},l=[]);let r=[];for(let t of n){if(byteSize(JSON.stringify({data:{[e]:[t]},order:[e]}))>a){let n=byteSize(JSON.stringify(t));throw Error(`A single record in table "${e}" (${n} bytes) exceeds the message size budget (${a} bytes). Consider increasing maxMessageSize or reducing the record size.`)}let n=[...r,t],i={...c,[e]:n},o=l.includes(e)?l:[...l,e];byteSize(JSON.stringify({data:i,order:o}))>a&&r.length>0?(c[e]=r,l.includes(e)||l.push(e),s.push({data:c,order:l,index:s.length}),c={},l=[],r=[t]):r=n}r.length>0&&(c[e]=r,l.includes(e)||l.push(e))}l.length>0&&s.push({data:c,order:l,index:s.length});let u=s.length;return s.map(e=>({...e,total:u}))}function byteSize(e){return new TextEncoder().encode(e).length}function processSeedTypeInfo(e,t){let n=new Set,r=[];for(let[t,i]of Object.entries(e.fields)){let a=i.relation?.targetType??i.config.foreignKeyType;a&&(a===e.name?r.push(t):n.add(a))}return{name:e.name,namespace:t,dependencies:Array.from(n),selfRefFields:r,dataFile:`data/${e.name}.jsonl`}}function buildSeedNamespaceConfigs(e){return e.map(e=>{let t=[],n={},r=[],i={};for(let[a,o]of Object.entries(e.tables)){let s=processSeedTypeInfo(o,e.namespace);t.push(s.name),n[s.name]=s.dependencies,s.selfRefFields.length>0&&r.push(s.name);let c=A(e.sourceInfo.get(a),`source info missing for table: ${a}`),l=En(o,c);i[s.name]=Object.entries(o.fields).filter(([e,t])=>t.config.required!==!1&&!l.optionalFields.includes(e)&&!l.omitFields.includes(e)).map(([e])=>e)}return{namespace:e.namespace,types:t,dependencies:n,selfRefTypes:r,requiredFields:i}})}async function loadSeedContext(e={}){let{config:t,plugins:n,application:r,namespaces:i}=await loadApplicationNamespaces({configPath:e.configPath});en({tailorDBServices:r.tailorDBServices});let a=resolvePluginConfig(n,On);if(!a)throw Error(`seedPlugin is not configured in ${t.path}. Add seedPlugin({ distPath: "./seed" }) from "@tailor-platform/sdk/plugin/seed" to definePlugins().`);if(typeof a.distPath!=`string`||a.distPath===``)throw Error(`seedPlugin in ${t.path} has no distPath option. Pass seedPlugin({ distPath: "./seed" }) so seed data has a location.`);await r.authService?.resolveNamespaces();let o=getAuthInput(r),s=o?Dn(o):void 0,c=s?{idpNamespace:s.idpNamespace,seedScriptCode:Cn(s.idpNamespace),listScriptCode:wn(s.idpNamespace),truncateScriptCode:Tn(s.idpNamespace)}:null;return{config:t,distPath:B.resolve(a.distPath),machineUserName:a.machineUserName,namespaces:buildSeedNamespaceConfigs(i),idpUser:c}}async function resolveTableNamespaces(e){let t=new Map;for(let n of e.tableNames){let e=n.toLowerCase(),r=t.get(e);if(r){r.push(n);continue}t.set(e,[n])}let n=new Set(e.tableNames),r=new Map;for(let i of e.namespaces){if(n.size===0)break;try{let{tailordbTypes:a}=await e.client.listTailorDBTypes({workspaceId:e.workspaceId,namespaceName:i});for(let e of a){let a=t.get(e.name.toLowerCase());if(a)for(let e of a)r.has(e)||(r.set(e,i),n.delete(e))}}catch{continue}}return r}async function truncateSingleType(e,t){await t.truncateTailorDBType({workspaceId:e.workspaceId,namespaceName:e.namespaceName,tailordbTypeName:e.tableName}),M.success(`Truncated table "${e.tableName}" in namespace "${e.namespaceName}"`)}async function truncateNamespace(e,t,n){await n.truncateTailorDBTypes({workspaceId:e,namespaceName:t}),M.success(`Truncated all tables in namespace "${t}"`)}async function truncate(e){return await $truncate({...e,yes:!0})}async function $truncate(e={}){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId}),r=e.tables&&e.tables.length>0,i=!!e.namespace,a=!!e.all,o=[a,i,r].filter(Boolean).length;if(o===0)throw Error(`Please specify one of: --all, --namespace <name>, or table names`);if(o>1)throw Error(`Options --all, --namespace, and table names are mutually exclusive. Please specify only one.`);let{config:s}=await loadConfig(e.configPath),c=extractOwnedNamespaces(s);if(a){if(c.length===0){M.warn(`No namespaces found in config file.`);return}if(!e.yes){let e=c.join(`, `);if(!await Z.confirm({message:`This will truncate ALL tables in the following owned namespaces (external namespaces are excluded): ${e}. Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}}for(let e of c)await truncateNamespace(n,e,t);M.success(`Truncated all tables in all owned namespaces`);return}if(i){let r=A(e.namespace,`namespace option missing`);if(!c.includes(r)){let e=s.db?.[r];throw e&&`external`in e?Error(`Namespace "${r}" is declared as external in this app's config and cannot be truncated from here. Run truncate from the app that owns it.`):Error(`Namespace "${r}" not found in config. Available owned namespaces (external namespaces are excluded): ${c.join(`, `)}`)}if(!e.yes&&!await Z.confirm({message:`This will truncate ALL tables in namespace "${r}". Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}await truncateNamespace(n,r,t);return}if(r){let r=A(e.tables,`tables option missing`),i=await resolveTableNamespaces({workspaceId:n,namespaces:c,tableNames:r,client:t}),a=r.filter(e=>!i.has(e));if(a.length>0)throw Error(`The following tables were not found in any namespace: ${a.join(`, `)}`);if(!e.yes){let e=r.join(`, `);if(!await Z.confirm({message:`This will truncate the following tables: ${e}. Continue?`,default:!1})){M.info(`Truncate cancelled.`);return}}for(let e of r){let r=i.get(e);r&&await truncateSingleType({workspaceId:n,namespaceName:r,tableName:e},t)}}}const Ls=X({name:`truncate`,description:`Truncate (delete all records from) TailorDB tables.`,args:H.strictObject({...Wr,...Gr,tables:V(H.string().array().optional(),{positional:!0,description:`Table names to truncate`}),all:V(H.boolean().default(!1),{alias:`a`,description:`Truncate all tables in all owned namespaces (excludes external namespaces)`}),namespace:V(H.string().optional(),{alias:`n`,description:`Truncate all tables in specified namespace`})}),run:async e=>{await assertWritable({profile:e.profile});let t=e.tables&&e.tables.length>0?e.tables:void 0;await $truncate({workspaceId:e[`workspace-id`],profile:e.profile,configPath:e.config,all:e.all,namespace:e.namespace,tables:t,yes:e.yes})}});async function listWorkflows(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e?.profile,workspaceId:e?.workspaceId}),r=toPageDirection(e?.order);return(await jt(async(e,i)=>{let{workflows:a,nextPageToken:o}=await t.listWorkflows({workspaceId:n,pageToken:e,pageSize:i,pageDirection:r});return[a,o]},{limit:e?.limit})).map(toWorkflowListInfo)}const Rs=X({name:`list`,description:`List all workflows in the workspace.`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listWorkflows({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});n.length===0&&(M.info(`No workflows found.`),!t)||M.out(n)}});async function resumeWorkflow(e){let{client:t,workspaceId:n}=await loadOperatorWorkspaceContext({profile:e.profile,workspaceId:e.workspaceId});try{let{executionId:r}=await t.resumeWorkflowExecution({workspaceId:n,executionId:e.executionId});return{executionId:r,wait:i=>waitForWorkflowExecution({client:t,workspaceId:n,executionId:r,interval:e.interval??3e3,timeout:i?.timeout,until:i?.until,showProgress:i?.showProgress})}}catch(t){if(t instanceof q){if(t.code===K.NotFound)throw Error(`Execution '${e.executionId}' not found.`,{cause:t});if(t.code===K.FailedPrecondition)throw Error(`Execution '${e.executionId}' is not in a resumable state.`,{cause:t})}throw t}}const zs=X({name:`resume`,description:`Resume a failed or pending workflow execution.`,args:H.strictObject({...Y,"execution-id":V(H.string(),{positional:!0,description:`Failed execution ID`}),...qo}),run:async e=>{let t=M.jsonMode||e.json,{executionId:n,wait:r}=await resumeWorkflow({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval)});if(t||M.info(`Execution ID: ${n}`,{mode:`stream`}),e.wait){let i=await r({showProgress:!t,timeout:parseDuration(e.timeout),until:e.until});if(e.logs&&!t){let{execution:t}=await getWorkflowExecution({executionId:n,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});printExecutionWithLogs(t)}else if(e.logs){let{execution:t}=await getWorkflowExecution({executionId:n,workspaceId:e[`workspace-id`],profile:e.profile,logs:!0});M.out({...i,jobDetails:t.jobDetails})}else M.out(i);let a=getWorkflowWaitFailureMessage(i,e.until);if(a)throw Error(a)}else M.out({executionId:n})}});async function waitWorkflowExecution(e){return await waitForWorkflowExecutionById({...e,showProgress:e.showProgress??!M.jsonMode,trackJobs:e.trackJobs??!0})}async function addWorkflowLogsToWaitResult(e,t){let{execution:n}=await getWorkflowExecution({executionId:t.executionId,workspaceId:t.workspaceId,profile:t.profile,logs:!0});return{...e,jobDetails:n.jobDetails}}const Bs=X({name:`wait`,description:`Wait for a workflow execution.`,examples:[{cmd:`execution-id --until success --timeout 10m --json`,desc:`Wait for workflow success`},{cmd:`execution-id --until suspended --timeout 6m --logs --json`,desc:`Wait for a workflow wait point`},{cmd:`execution-id --until terminal`,desc:`Wait for success, failure, or suspension`}],args:H.strictObject({...Y,"execution-id":V(H.string(),{positional:!0,description:`Execution ID`}),...Ko}),run:async e=>{let t=M.jsonMode||e.json,n=await waitWorkflowExecution({executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile,interval:parseDuration(e.interval),timeout:parseDuration(e.timeout),until:e.until,showProgress:!t}),r=e.logs?await addWorkflowLogsToWaitResult(n,{executionId:e.executionId,workspaceId:e[`workspace-id`],profile:e.profile}):n;!t&&r.jobDetails?printExecutionWithLogs({id:r.id,workflowName:r.workflowName,status:r.status,jobExecutions:r.jobExecutions,startedAt:r.startedAt,finishedAt:r.finishedAt,jobDetails:r.jobDetails}):M.out(r);let i=getWorkflowWaitFailureMessage(n,e.until);if(i)throw Error(i)}}),statusToString=e=>{switch(e){case ue.OK:return`ok`;case ue.COMPOSITION_ERROR:return`composition_error`;default:return`unknown`}},attemptStatusToString=e=>{switch(e){case We.SUCCEEDED:return`success`;case We.FAILED:return`failure`;default:return`unknown`}},appInfo=e=>({name:e.name,domain:e.domain,authNamespace:e.authNamespace,createdAt:formatTimestamp(e.createTime),updatedAt:formatTimestamp(e.updateTime)}),appHealthInfo=(e,t)=>{let n=t.lastSchemaUpdateAttempt;return{name:e,status:statusToString(t.status),currentServingSchemaUpdatedAt:formatTimestamp(t.currentServingSchemaUpdateTime),lastAttemptStatus:n?attemptStatusToString(n.status):`N/A`,lastAttemptAt:formatTimestamp(n?.attemptTime),lastAttemptError:n?.error??``}},Vs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),name:H.string().min(1,{message:`name is required`})});async function loadOptions$9(e){let t=parseOptions(Vs,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,name:t.name}}async function getAppHealth(e){let{client:t,workspaceId:n,name:r}=await loadOptions$9(e),i=await t.getApplicationSchemaHealth({workspaceId:n,applicationName:r});return appHealthInfo(r,i)}const Hs=X({name:`health`,description:`Check application schema health`,args:H.strictObject({...Y,name:V(H.string(),{description:`Application name`,alias:`n`})}),run:async e=>{let t=await getAppHealth({workspaceId:e[`workspace-id`],profile:e.profile,name:e.name}),n=e.json?t:{...t,currentServingSchemaUpdatedAt:humanizeRelativeTime(t.currentServingSchemaUpdatedAt),lastAttemptAt:humanizeRelativeTime(t.lastAttemptAt)};M.out(n)}}),Us=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:zr.optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$8(e){let t=parseOptions(Us,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,order:t.order,limit:t.limit}}async function listApps(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$8(e),a=toPageDirection(r);return(await jt(async(e,r)=>{let{applications:i,nextPageToken:o}=await t.listApplications({workspaceId:n,pageToken:e,pageSize:r,pageDirection:a});return[i,o]},{limit:i})).map(appInfo)}const Ws=X({name:`list`,description:`List applications in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=M.jsonMode,n=await listApps({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit}),r=t?n:n.map(({updatedAt:e,createdAt:t,...n})=>({...n,createdAt:humanizeRelativeTime(t)}));M.out(r)}}),Gs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`})});async function loadOptions$7(e){let t=parseOptions(Gs,e),n=await loadAccessToken();return{client:await F(n),workspaceId:t.workspaceId}}async function deleteWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$7(e);await t.deleteWorkspace({workspaceId:n})}const Ks=X({name:`delete`,description:`Delete a Tailor Platform workspace.`,args:H.strictObject({"workspace-id":V(H.string(),{alias:`w`,description:`Workspace ID`}),...Gr}),run:async e=>{await assertWritable();let{client:t,workspaceId:n}=await loadOptions$7({workspaceId:e[`workspace-id`]}),r;try{r=await t.getWorkspace({workspaceId:n})}catch(e){throw e instanceof q&&e.code===K.NotFound?Error(`Workspace "${n}" not found.`,{cause:e}):e}let i=r.workspace,a=i?.name??n,o=workspaceDisplayName({name:a,folderName:i?await resolveWorkspaceFolderName(t,i):``});if(!e.yes){let e=await Z.text({message:`Enter the workspace name to confirm deletion (${o}):`});if(e!==a&&e!==o){M.info(`Workspace deletion cancelled.`);return}}await t.deleteWorkspace({workspaceId:n});let s=await readPlatformConfig(),c=Object.entries(s.profiles).filter(([,e])=>e?.workspace_id===n);if(c.length>0){for(let[e]of c)delete s.profiles[e];writePlatformConfig(s)}c.length>0?M.success(`Workspace "${o}" and ${c.length} associated profile(s) deleted successfully.`):M.success(`Workspace "${o}" deleted successfully.`)}}),qs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional()});async function loadOptions$6(e){let t=parseOptions(qs,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r}}async function getWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$6(e),r=await t.getWorkspace({workspaceId:n});if(!r.workspace)throw Error(`Workspace "${n}" not found.`);return workspaceDetailsWithFolderName(t,r.workspace)}const Js=X({name:`get`,description:`Show detailed information about a workspace`,args:H.strictObject({...Y}),run:async e=>{let t=await getWorkspace({workspaceId:e[`workspace-id`],profile:e.profile}),n=e.json?t:{...t,createdAt:humanizeRelativeTime(t.createdAt),updatedAt:humanizeRelativeTime(t.updatedAt)};M.out(n,{display:{name:Io,folderName:null}})}}),Ys=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`})});async function loadOptions$5(e){let t=parseOptions(Ys,e),n=await loadAccessToken();return{client:await F(n),workspaceId:t.workspaceId}}async function restoreWorkspace(e){let{client:t,workspaceId:n}=await loadOptions$5(e);await t.restoreWorkspace({workspaceId:n})}const Xs=X({name:`restore`,description:`Restore a deleted workspace`,args:H.strictObject({"workspace-id":V(H.string(),{alias:`w`,description:`Workspace ID`}),...Gr}),run:async e=>{await assertWritable();let{client:t,workspaceId:n}=await loadOptions$5({workspaceId:e[`workspace-id`]});if(!e.yes&&await Z.text({message:`Are you sure you want to restore workspace "${n}"? (yes/no):`})!==`yes`){M.info(`Workspace restoration cancelled.`);return}await t.restoreWorkspace({workspaceId:n}),M.success(`Workspace "${n}" restored successfully.`)}}),roleToString=e=>{switch(e){case Xe.ADMIN:return`admin`;case Xe.EDITOR:return`editor`;case Xe.VIEWER:return`viewer`;default:return`unknown`}},stringToRole=e=>{switch(e.toLowerCase()){case`admin`:return Xe.ADMIN;case`editor`:return Xe.EDITOR;case`viewer`:return Xe.VIEWER;default:throw Error(`Invalid role: ${e}. Valid roles: admin, editor, viewer`)}},userInfo=e=>({userId:e.platformUser?.userId??``,email:e.platformUser?.email??``,role:roleToString(e.role)}),Zs=[`admin`,`editor`,`viewer`],Qs=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.email({message:`email must be a valid email address`}),role:H.enum(Zs,{message:`role must be one of: ${Zs.join(`, `)}`})});async function loadOptions$4(e){let t=parseOptions(Qs,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,email:t.email,role:stringToRole(t.role)}}async function inviteUser(e){let{client:t,workspaceId:n,email:r,role:i}=await loadOptions$4(e);await t.inviteWorkspacePlatformUser({workspaceId:n,email:r,role:i})}const $s=X({name:`invite`,description:`Invite a user to a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to invite`}),role:V(H.enum(Zs),{description:`Role to assign (${Zs.join(`, `)})`,alias:`r`})}),run:async e=>{await assertWritable({profile:e.profile}),await inviteUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email,role:e.role}),M.success(`User "${e.email}" invited successfully with role "${e.role}".`)}}),ec=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),order:zr.optional(),limit:H.coerce.number().int().nonnegative().optional()});async function loadOptions$3(e){let t=parseOptions(ec,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,order:t.order,limit:t.limit}}async function listUsers(e){let{client:t,workspaceId:n,order:r,limit:i}=await loadOptions$3(e),a=toPageDirection(r);return(await jt(async(e,r)=>{let{workspacePlatformUsers:i,nextPageToken:o}=await t.listWorkspacePlatformUsers({workspaceId:n,pageToken:e,pageSize:r,pageDirection:a});return[i,o]},{limit:i})).map(userInfo)}const tc=X({name:`list`,description:`List users in a workspace`,args:H.strictObject({...Y,...paginationArgs()}),run:async e=>{let t=await listUsers({workspaceId:e[`workspace-id`],profile:e.profile,order:e.order,limit:e.limit});M.out(t)}}),nc=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.email({message:`email must be a valid email address`})});async function loadOptions$2(e){let t=parseOptions(nc,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,email:t.email}}async function removeUser(e){let{client:t,workspaceId:n,email:r}=await loadOptions$2(e);await t.removeWorkspacePlatformUser({workspaceId:n,email:r})}const rc=X({name:`remove`,description:`Remove a user from a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to remove`}),...Gr}),run:async e=>{if(await assertWritable({profile:e.profile}),!e.yes&&await Z.text({message:`Are you sure you want to remove user "${e.email}" from the workspace? (yes/no):`})!==`yes`){M.info(`User removal cancelled.`);return}await removeUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email}),M.success(`User "${e.email}" removed from workspace.`)}}),ic=H.object({workspaceId:H.uuid({message:`workspace-id must be a valid UUID`}).optional(),profile:H.string().optional(),email:H.email({message:`email must be a valid email address`}),role:H.enum(Zs,{message:`role must be one of: ${Zs.join(`, `)}`})});async function loadOptions$1(e){let t=parseOptions(ic,e),{client:n,workspaceId:r}=await loadOperatorWorkspaceContext({profile:t.profile,workspaceId:t.workspaceId});return{client:n,workspaceId:r,email:t.email,role:stringToRole(t.role)}}async function updateUser(e){let{client:t,workspaceId:n,email:r,role:i}=await loadOptions$1(e);await t.updateWorkspacePlatformUser({workspaceId:n,email:r,role:i})}const ac=X({name:`update`,description:`Update a user's role in a workspace`,args:H.strictObject({...Y,email:V(H.email(),{description:`Email address of the user to update`}),role:V(H.enum(Zs),{description:`New role to assign (${Zs.join(`, `)})`,alias:`r`})}),run:async e=>{await assertWritable({profile:e.profile}),await updateUser({workspaceId:e[`workspace-id`],profile:e.profile,email:e.email,role:e.role}),M.success(`User "${e.email}" updated to role "${e.role}".`)}});function createSqlEntry(){return L`
|
|
578
578
|
import { Kysely, sql, TailordbDialect } from "@tailor-platform/sdk/kysely";
|
|
579
579
|
|
|
580
580
|
type QueryInput = {
|
|
@@ -638,5 +638,5 @@ This is the baseline schema. Future changes will be tracked as diffs.`)}function
|
|
|
638
638
|
}
|
|
639
639
|
`}async function bundleQueryScript(e,t){let n=B.resolve(Gt(),`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 ht(t),o=St({tsconfig:a}),s=await pr.build({plugins:[Ot(r,t),gt(),wt],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 Nr(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
|
-
`&&(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=Mr(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=jr(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=Mr(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=sn(r,i);return await Promise.all(a.map(async e=>{try{let t=await import(Zn(e).href);for(let e of Object.values(t)){let t=on.safeParse(cn(e));t.success&&n.set(t.data.name,Object.keys(t.data.fields))}}catch{}})),n}const oc=H.enum([`sql`,`gql`]),sc=H.object({workspaceId:H.string().optional(),profile:H.string().optional(),configPath:H.string().optional(),engine:oc,machineUser:H.string().optional(),machineUserSource:H.enum([`option`,`env`]).optional()}),cc=sc.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=sc.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`validation error missing issues`).message);let n=await loadMachineUserName({machineUser:t.data.machineUser,machineUserSource:t.data.machineUserSource,profile:t.data.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.data.profile}),i=await F(r),a=await loadWorkspaceId({workspaceId:t.data.workspaceId,profile:t.data.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.data.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(gr(),`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=cc.safeParse(e);if(!t.success)throw Error(A(t.error.issues[0],`validation error missing issues`).message);return await(await prepareQueryExecutor(t.data))(t.data.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(!nr)return;let r=[t,n].filter(e=>!!e).map(sanitizeHistoryScope).join(`-`),i=e===`sql`?`sql`:`gql`,a=r?`-${r}`:``;return B.join(nr,`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=Ar({prefix:``,preferNewlineOnEnter:e.newlineOnEnter,validate:r,highlight:s,transform:o,clearAfterSubmit:!1,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(gn(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 lc=[`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(...lc),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 uc=X({name:`query`,description:`Run SQL/GraphQL query.`,args:H.strictObject({...Wr,engine:V(oc,{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=Mr(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(gn(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=vn(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);kn.registerHooks({resolve:t,load:n})}export{Cs as $,Xi as $n,toPageDirection as $r,deployFromCLI as $t,truncate as A,captureMigrationFileState as An,loadMachineUserName as Ar,getFunctionRegistry as At,logBetaWarning as B,Qa as Bn,writePlatformConfig as Br,listExecutorJobs as Bt,Hs as C,generateAllTypeManifestsFromSnapshot as Cn,deleteUserTokens as Cr,extractAllNamespaces as Ct,resumeWorkflow as D,getNamespacesWithMigrations as Dn,loadAccessToken as Dr,ss as Dt,zs as E,fetchRemoteMigrationState as En,hasUserTokenEntry as Er,waitForExecution as Et,generate as F,assertValidMigrationFiles as Fn,readPlatformConfig as Fr,Qo as Ft,remove as G,assertMigrationNumberExists as Gn,Gr,getWorkflow as Gt,deployStaticWebsite as H,no as Hn,Vr as Hr,Xo as Ht,Is as I,reconstructSnapshotFromMigrations as In,removeLegacyUserAlias as Ir,listExecutors as It,updateOrganization as J,getMigrationFilePath as Jn,loadEnvFiles as Jr,listWorkflowExecutions as Jt,Os as K,getLatestMigrationNumber as Kn,createCommonArgs as Kr,Jo as Kt,Fs as L,eo as Ln,resolveConfigUser as Lr,getExecutorJob as Lt,loadSeedContext as M,formatSchemaDrifts as Mn,loadStoredUserTokens as Mr,rs as Mt,chunkSeedData as N,createSnapshotFromLocalTypes as Nn,loadWorkspaceId as Nr,ts as Nt,Rs as O,selectTargetNamespace as On,loadConfigPath as Or,listFunctionRegistries as Ot,bundleSeedScript as P,createSnapshotType as Pn,platformConfigFromProfile as Pr,triggerExecutor as Pt,listOrganizations as Q,loadSnapshot as Qn,resolveMachineUserInputSource as Qr,deploy as Qt,Ps as R,Za as Rn,resolveUserTokenKey as Rr,getExecutorWaitFailureMessage as Rt,getAppHealth as S,compareSnapshotWithRemote as Sn,loadConfig as Sr,loadTailorDBNamespaces as St,waitWorkflowExecution as T,fetchRemoteMigrationNumber as Tn,hasAnyUserTokenEntry as Tr,executeScript as Tt,show as U,to as Un,Br as Ur,startWorkflow as Ut,Ms as V,$a as Vn,X as Vr,watchExecutorJob as Vt,As as W,Xa as Wn,Hr as Wr,Yo as Wt,Ts as X,getNextMigrationNumber as Xn,qr as Xr,Uo as Xt,organizationTree as Y,getMigrationFiles as Yn,Ur as Yr,functionExecutionStatusToString as Yt,ws as Z,loadDiff as Zn,paginationArgs as Zr,getExecutor as Zt,getWorkspace as _,verifyRemoteSchema as _n,bi as _r,cs as _t,uc as a,createValidatedWorkspaceWithClient as an,compareSnapshots as ar,_s as at,listApps as b,formatMigrationScriptCommand as bn,apiCall as br,resolvePluginConfig as bt,rc as c,Fo as cn,formatMigrationNumber as cr,deleteFolder as ct,listUsers as d,generateUserTypes as dn,formatMigrationDiff as dr,ds as dt,Y as ei,deployMigrationTestBaseline as en,Yi as er,getOrganization as et,$s as f,checkMigrationDiffs as fn,hasChanges as fr,listOAuth2Clients as ft,Js as g,toTailorDBDeployInput as gn,yi as gr,ls as gt,restoreWorkspace as h,logRemoteDriftGuidance as hn,xi as hr,getMachineUserToken as ht,query as i,Ro as in,compareLocalTypesWithSnapshot as ir,listFolders as it,Ls as j,createRemoteComparableSnapshot as jn,loadPlatformClientConfig as jr,listWebhookExecutors as jt,listWorkflows as k,captureFileState as kn,loadConsoleBaseUrl as kr,as as kt,removeUser as l,ensureConfigId as ln,parseMigrationNumberArg as lr,ps as lt,Xs as m,formatRemoteVerificationResults as mn,resourceTrn as mr,getOAuth2Client as mt,errorToJson as n,zo as nn,handleOptionalToRequiredError as nr,updateFolder as nt,ac as o,createWorkspace$1 as on,UnsupportedMigrationFileVersionError as or,getFolder as ot,inviteUser as p,fetchRemoteSchemaSnapshot as pn,subscribesToEvents as pr,us as pt,Ds as q,getMigrationDirPath as qn,Wr as qr,getWorkflowExecution as qt,serializeError as r,listWorkspaces as rn,sanitizeMigrationLabel as rr,ys as rt,updateUser as s,formatKeyValueTable as sn,normalizeSchemaSnapshot as sr,hs as st,registerTsHook as t,deployMigrationTestTarget as tn,createMigrationHistoryId as tr,xs as tt,tc as u,PluginManager as un,formatDiffSummary as ur,createFolder as ut,Ks as v,getMigrationMachineUser as vn,writeMetadataLabels as vr,listMachineUsers as vt,Bs as w,protoGqlPermission as wn,fetchLatestToken as wr,extractOwnedNamespaces as wt,Ws as x,bundleMigrationScript as xn,assertWritable as xr,loadApplicationNamespaces as xt,deleteWorkspace as y,updateMigrationLabel as yn,Z as yr,generate$1 as yt,generateSchemaFile as z,Ya as zn,saveUserTokens as zr,Zo as zt};
|
|
642
|
-
//# sourceMappingURL=register-ts-hook-
|
|
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=Mr(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=jr(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=Mr(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=sn(r,i);return await Promise.all(a.map(async e=>{try{let t=await import(Zn(e).href);for(let e of Object.values(t)){let t=on.safeParse(cn(e));t.success&&n.set(t.data.name,Object.keys(t.data.fields))}}catch{}})),n}const oc=H.enum([`sql`,`gql`]),sc=H.object({workspaceId:H.string().optional(),profile:H.string().optional(),configPath:H.string().optional(),engine:oc,machineUser:H.string().optional(),machineUserSource:H.enum([`option`,`env`]).optional()}),cc=sc.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(sc,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 F(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(gr(),`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(cc,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(!nr)return;let r=[t,n].filter(e=>!!e).map(sanitizeHistoryScope).join(`-`),i=e===`sql`?`sql`:`gql`,a=r?`-${r}`:``;return B.join(nr,`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=Ar({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(gn(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 lc=[`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(...lc),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 uc=X({name:`query`,description:`Run SQL/GraphQL query.`,args:H.strictObject({...Wr,engine:V(oc,{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=Mr(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(gn(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=vn(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);kn.registerHooks({resolve:t,load:n})}export{Cs as $,loadDiff as $n,Ur as $r,deployFromCLI as $t,truncate as A,selectTargetNamespace as An,loadAccessToken as Ar,getFunctionRegistry as At,logBetaWarning as B,Za as Bn,removeLegacyUserAlias as Br,listExecutorJobs as Bt,Hs as C,bundleMigrationScript as Cn,apiCall as Cr,extractAllNamespaces as Ct,resumeWorkflow as D,fetchRemoteMigrationNumber as Dn,fetchLatestToken as Dr,ss as Dt,zs as E,protoGqlPermission as En,deleteUserTokens as Er,waitForExecution as Et,generate as F,createSnapshotFromLocalTypes as Fn,loadPlatformClientConfig as Fr,Qo as Ft,remove as G,to as Gn,X as Gr,getWorkflow as Gt,deployStaticWebsite as H,Qa as Hn,resolveUserTokenKey as Hr,Xo as Ht,Is as I,createSnapshotType as In,loadStoredUserTokens as Ir,listExecutors as It,updateOrganization as J,getLatestMigrationNumber as Jn,Hr as Jr,listWorkflowExecutions as Jt,Os as K,Xa as Kn,Vr as Kr,Jo as Kt,Fs as L,assertValidMigrationFiles as Ln,loadWorkspaceId as Lr,getExecutorJob as Lt,loadSeedContext as M,captureMigrationFileState as Mn,loadConfigPath as Mr,rs as Mt,chunkSeedData as N,createRemoteComparableSnapshot as Nn,loadConsoleBaseUrl as Nr,ts as Nt,Rs as O,fetchRemoteMigrationState as On,hasAnyUserTokenEntry as Or,listFunctionRegistries as Ot,bundleSeedScript as P,formatSchemaDrifts as Pn,loadMachineUserName as Pr,triggerExecutor as Pt,listOrganizations as Q,getNextMigrationNumber as Qn,loadEnvFiles as Qr,deploy as Qt,Ps as R,reconstructSnapshotFromMigrations as Rn,platformConfigFromProfile as Rr,getExecutorWaitFailureMessage as Rt,getAppHealth as S,formatMigrationScriptCommand as Sn,loadOperatorWorkspaceContext as Sr,loadTailorDBNamespaces as St,waitWorkflowExecution as T,generateAllTypeManifestsFromSnapshot as Tn,loadConfig as Tr,executeScript as Tt,show as U,$a as Un,saveUserTokens as Ur,startWorkflow as Ut,Ms as V,Ya as Vn,resolveConfigUser as Vr,watchExecutorJob as Vt,As as W,no as Wn,writePlatformConfig as Wr,Yo as Wt,Ts as X,getMigrationFilePath as Xn,createCommonArgs as Xr,Uo as Xt,organizationTree as Y,getMigrationDirPath as Yn,Gr as Yr,functionExecutionStatusToString as Yt,ws as Z,getMigrationFiles as Zn,Wr as Zr,getExecutor as Zt,getWorkspace as _,logRemoteDriftGuidance as _n,xi as _r,cs as _t,uc as a,createValidatedWorkspaceWithClient as an,sanitizeMigrationLabel as ar,_s as at,listApps as b,getMigrationMachineUser as bn,writeMetadataLabels as br,resolvePluginConfig as bt,rc as c,formatTimestamp as cn,UnsupportedMigrationFileVersionError as cr,deleteFolder as ct,listUsers as d,ensureConfigId as dn,parseMigrationNumberArg as dr,ds as dt,qr as ei,deployMigrationTestBaseline as en,loadSnapshot as er,getOrganization as et,$s as f,PluginManager as fn,formatDiffSummary as fr,listOAuth2Clients as ft,Js as g,formatRemoteVerificationResults as gn,resourceTrn as gr,ls as gt,restoreWorkspace as h,fetchRemoteSchemaSnapshot as hn,subscribesToEvents as hr,getMachineUserToken as ht,query as i,Y as ii,Ro as in,handleOptionalToRequiredError as ir,listFolders as it,Ls as j,captureFileState as jn,loadAuthStatus as jr,listWebhookExecutors as jt,listWorkflows as k,getNamespacesWithMigrations as kn,hasUserTokenEntry as kr,as as kt,removeUser as l,humanizeRelativeTime as ln,normalizeSchemaSnapshot as lr,ps as lt,Xs as m,checkMigrationDiffs as mn,hasChanges as mr,getOAuth2Client as mt,errorToJson as n,resolveMachineUserInputSource as ni,zo as nn,Yi as nr,updateFolder as nt,ac as o,createWorkspace$1 as on,compareLocalTypesWithSnapshot as or,getFolder as ot,inviteUser as p,generateUserTypes as pn,formatMigrationDiff as pr,us as pt,Ds as q,assertMigrationNumberExists as qn,Br as qr,getWorkflowExecution as qt,serializeError as r,toPageDirection as ri,listWorkspaces as rn,createMigrationHistoryId as rr,ys as rt,updateUser as s,formatKeyValueTable as sn,compareSnapshots as sr,hs as st,registerTsHook as t,paginationArgs as ti,deployMigrationTestTarget as tn,Xi as tr,xs as tt,tc as u,Fo as un,formatMigrationNumber as ur,createFolder as ut,Ks as v,toTailorDBDeployInput as vn,yi as vr,listMachineUsers as vt,Bs as w,compareSnapshotWithRemote as wn,assertWritable as wr,extractOwnedNamespaces as wt,Ws as x,updateMigrationLabel as xn,Z as xr,loadApplicationNamespaces as xt,deleteWorkspace as y,verifyRemoteSchema as yn,bi as yr,generate$1 as yt,generateSchemaFile as z,eo as zn,readPlatformConfig as zr,Zo as zt};
|
|
642
|
+
//# sourceMappingURL=register-ts-hook-rBH346V_.mjs.map
|