twenty-sdk 0.8.0 → 0.9.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/dist/cli/commands/dev-once.d.ts +7 -0
- package/dist/cli/commands/exec.d.ts +2 -2
- package/dist/cli/operations/dev-once.d.ts +13 -0
- package/dist/cli/operations/execute.d.ts +2 -2
- package/dist/cli/operations/index.d.ts +2 -0
- package/dist/cli/operations/server-start.d.ts +1 -0
- package/dist/cli/utilities/build/manifest/manifest-extract-config.d.ts +1 -1
- package/dist/cli/utilities/build/manifest/utils/add-missing-field-option-ids.d.ts +2 -0
- package/dist/cli/utilities/build/manifest/utils/from-role-config-to-role-manifest.d.ts +3 -0
- package/dist/cli/utilities/config/config-service.d.ts +3 -1
- package/dist/cli/utilities/config/get-config-path.d.ts +1 -1
- package/dist/cli/utilities/server/docker-container.d.ts +5 -3
- package/dist/cli.cjs +46 -44
- package/dist/cli.mjs +2035 -2089
- package/dist/{frontComponentHostCommunicationApi-op3Q7sYg.mjs → frontComponentHostCommunicationApi-Bz03t3FY.mjs} +66 -74
- package/dist/{frontComponentHostCommunicationApi-DvdpnfNz.js → frontComponentHostCommunicationApi-DyOxvANW.js} +3 -3
- package/dist/{get-function-input-schema-BZ7_XyUh-xI83N7kX.mjs → get-function-input-schema-BZ7_XyUh-CtECetlr.mjs} +1 -1
- package/dist/{get-function-input-schema-BZ7_XyUh-Bf_NiyDR.js → get-function-input-schema-BZ7_XyUh-D2ypJxjI.js} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +9 -9
- package/dist/operations.cjs +1 -1
- package/dist/operations.mjs +14 -13
- package/dist/sdk/application/application-config.d.ts +1 -1
- package/dist/sdk/common/types/define-entity.type.d.ts +5 -2
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/logic-functions/define-post-install-logic-function.d.ts +2 -5
- package/dist/sdk/logic-functions/define-post-install-logic-function.js.map +1 -1
- package/dist/sdk/logic-functions/define-pre-install-logic-function.d.ts +2 -5
- package/dist/sdk/logic-functions/define-pre-install-logic-function.js.map +1 -1
- package/dist/sdk/logic-functions/install-payload-type.d.ts +5 -0
- package/dist/sdk/logic-functions/post-install-logic-function-config.d.ts +4 -0
- package/dist/sdk/logic-functions/pre-install-logic-function-config.d.ts +5 -0
- package/dist/sdk/roles/define-role.d.ts +2 -2
- package/dist/sdk/roles/define-role.js.map +1 -1
- package/dist/sdk/roles/role-config.d.ts +7 -0
- package/dist/ui/index.cjs +413 -398
- package/dist/ui/index.mjs +2164 -2134
- package/dist/uninstall-CXlUxs8p.js +189 -0
- package/dist/{uninstall-9yB-e13_.mjs → uninstall-CrGYRb-Z.mjs} +993 -663
- package/package.json +2 -2
- package/dist/sdk/logic-functions/install-logic-function-payload-type.d.ts +0 -4
- package/dist/uninstall-BCUbP_Bn.js +0 -178
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "twenty-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"main": "dist/index.cjs",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/sdk/index.d.ts",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"react": "^19.0.0",
|
|
71
71
|
"react-dom": "^19.0.0",
|
|
72
72
|
"tinyglobby": "^0.2.15",
|
|
73
|
-
"twenty-client-sdk": "0.
|
|
73
|
+
"twenty-client-sdk": "0.9.0",
|
|
74
74
|
"typescript": "^5.9.2",
|
|
75
75
|
"uuid": "^13.0.0",
|
|
76
76
|
"vite": "^7.0.0",
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use strict";const st=require("fs"),Pe=require("child_process"),I=require("path"),it=require("crypto"),y=require("node:fs/promises"),l=require("./frontComponentHostCommunicationApi-DvdpnfNz.js"),at=require("esbuild"),de=require("./get-front-component-build-plugins-Ce_mghCA.js"),x=require("node:child_process"),pe=require("node:path"),rt=require("node:http"),ot=require("node:crypto"),ct=require("axios"),lt=require("chalk"),ut=require("node:fs"),dt=require("os"),pt=require("graphql-sse"),re=require("graphql"),ft=require("typescript"),ht=require("fs/promises"),mt=require("module"),gt=require("uuid");require("@sniptt/guards");require("react");const xe=require("tinyglobby"),Y=e=>e&&e.__esModule?e:{default:e};function z(e){if(e&&e.__esModule)return e;const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const le=z(st),f=z(I),De=Y(it),fe=z(at),_e=Y(pe),yt=Y(rt),Oe=Y(ot),O=Y(ct),X=Y(lt),he=z(dt),q=z(ft),It=z(ht),ne=async e=>{try{return await y.access(e),!0}catch{return!1}},vt=e=>ut.existsSync(e),P=e=>y.mkdir(e,{recursive:!0}),At=async e=>{await y.mkdir(pe.dirname(e),{recursive:!0});try{await y.access(e)}catch{await y.writeFile(e,"")}},Ue=async e=>{let t;try{t=await y.readdir(e)}catch(n){if(n instanceof Error&&"code"in n&&n.code==="ENOENT"){await y.mkdir(e,{recursive:!0});return}throw n}await Promise.all(t.map(n=>y.rm(pe.join(e,n),{recursive:!0,force:!0})))},je=(e,t)=>y.cp(e,t,{recursive:!0}),Q=e=>y.rm(e,{recursive:!0,force:!0}),wt=async e=>{const t=await y.readFile(e,"utf-8");return JSON.parse(t)},Tt=async(e,t)=>{await y.writeFile(e,JSON.stringify(t,null,2)+`
|
|
2
|
-
`)},Ft="twenty-client-sdk",Me=async({result:e,appPath:t,fileFolder:n,lastChecksums:s,onFileBuilt:i})=>{const a=Object.keys(e.metafile?.outputs??{}).filter(r=>r.endsWith(".mjs"));for(const r of a){const o=f.default.resolve(r),u=f.default.relative(t,o),c=e.metafile?.outputs?.[r]?.entryPoint||"",d=f.default.relative(t,c),h=await y.readFile(o),m=De.default.createHash("md5").update(h).digest("hex");if(s.get(u)===m)continue;s.set(u,m);const S=e.metafile?.outputs?.[r]?.imports?.some(R=>R.external===!0&&R.path.startsWith(Ft))??!1;i&&await i({fileFolder:n,builtPath:u,sourcePath:d,checksum:m,usesSdkClient:S})}},Ce=async({appPath:e,sourcePaths:t,fileFolder:n,buildOptions:s,onFileBuilt:i})=>{if(t.length===0)return;const a={};for(const o of t){const u=o.replace(/\.tsx?$/,"");a[u]=f.default.join(e,o)}const r=await fe.build({...s,entryPoints:a});await Me({result:r,appPath:e,fileFolder:n,lastChecksums:new Map,onFileBuilt:i})},Et=async(e,t,n)=>{const s=new Set(n),i=t.filter(a=>!s.has(a));for(const a of i){const r=a.replace(/\.tsx?$/,".mjs"),o=f.default.join(e,r),u=`${o}.map`;await Q(o),await Q(u)}},$e=["twenty-client-sdk/core","twenty-client-sdk/metadata"],bt=/^(.+)\((\d+),(\d+)\): error TS\d+: (.+)$/,Be=e=>{const t=e.match(bt);if(!t)return null;const[,n,s,i,a]=t;return{text:a,file:n,line:Number(s),column:Number(i)-1}},Nt=e=>{const t=[];for(const n of e.split(`
|
|
3
|
-
`)){const s=Be(n);s&&t.push(s)}return t},me=e=>{const t=_e.default.join(e,"tsconfig.json"),n=_e.default.join(e,"node_modules",".bin","tsc");return new Promise(s=>{x.execFile(n,["--noEmit","--pretty","false","-p",t],{cwd:e},(i,a,r)=>{s(Nt(r||a))})})},_t=e=>e.map(t=>({text:t.text,location:{file:t.file,line:t.line,column:t.column,lineText:"",length:0,namespace:"",suggestion:""}})),He=(e,t)=>({name:"typecheck",setup:n=>{n.onStart(async()=>{if(t())return;const s=await me(e);return{errors:_t(s)}})}}),qe=["twenty-client-sdk/core","twenty-client-sdk/metadata","path","fs","crypto","stream","util","os","url","http","https","events","buffer","querystring","assert","zlib","net","tls","child_process","worker_threads"];class Ve{constructor(t){this.esBuildContext=null,this.isRestarting=!1,this.lastChecksums=new Map,this.buildCompletePromise=Promise.resolve(),this.resolveBuildComplete=null,this.appPath=t.appPath,this.sourcePaths=t.sourcePaths,this.watchMode=t.watch??!0,this.onFileBuilt=t.handleFileBuilt,this.onBuildError=t.handleBuildError,this.config=t.config}shouldRestart(t){const n=this.sourcePaths.sort().join(","),s=[...t].sort().join(",");return n!==s}async start(){this.sourcePaths.length>0&&await this.createContext()}async close(){await this.esBuildContext?.dispose(),this.esBuildContext=null}async restart(t){if(!this.isRestarting){this.isRestarting=!0;try{await this.close();const n=f.default.join(this.appPath,l.E);await Et(n,this.sourcePaths,t),this.sourcePaths=t,this.lastChecksums.clear(),this.sourcePaths.length>0&&await this.createContext()}finally{this.isRestarting=!1}}}async createContext(){const t=f.default.join(this.appPath,l.E),n={};for(const a of this.sourcePaths){const r=a.replace(/\.tsx?$/,"");n[r]=f.default.join(this.appPath,a)}const s=this,i=[...this.config.extraPlugins??[],{name:"build-notifications",setup:a=>{a.onEnd(async r=>{try{if(r.errors.length>0){r.errors[0].text.includes("Could not resolve")||await this.onBuildError?.(r.errors.map(o=>({error:o.text,location:o.location})));return}await Me({result:r,appPath:this.appPath,fileFolder:this.config.fileFolder,lastChecksums:s.lastChecksums,onFileBuilt:s.onFileBuilt})}finally{s.resolveBuildComplete?.()}})}}];this.esBuildContext=await fe.context({entryPoints:n,bundle:!0,splitting:!1,format:"esm",platform:this.config.platform,outdir:t,outExtension:{".js":".mjs"},external:this.config.externalModules,tsconfig:f.default.join(this.appPath,"tsconfig.json"),jsx:this.config.jsx,sourcemap:!0,metafile:!0,logLevel:"silent",minify:this.config.minify,banner:this.config.banner,plugins:i}),this.buildCompletePromise=new Promise(a=>{this.resolveBuildComplete=a}),await this.esBuildContext.rebuild(),await this.buildCompletePromise,this.watchMode&&await this.esBuildContext.watch()}}const Ot=e=>new Ve({...e,config:{externalModules:qe,fileFolder:l.B.BuiltLogicFunction,platform:"node",extraPlugins:[He(e.appPath,e.shouldSkipTypecheck)],banner:l.T}}),Ct=e=>new Ve({...e,config:{externalModules:$e,fileFolder:l.B.BuiltFrontComponent,jsx:"automatic",extraPlugins:[He(e.appPath,e.shouldSkipTypecheck),...de.getFrontComponentBuildPlugins()]}}),kt=()=>({bundle:!0,splitting:!1,format:"esm",outExtension:{".js":".mjs"},external:$e,jsx:"automatic",sourcemap:!0,metafile:!0,logLevel:"silent",plugins:[...de.getFrontComponentBuildPlugins()]}),St=async e=>{const t=I.join(e.appPath,l.E);await P(t),await Ue(t);const n=new Map,s=r=>{n.set(r.builtPath,{checksum:r.checksum,builtPath:r.builtPath,sourcePath:r.sourcePath,fileFolder:r.fileFolder,usesSdkClient:r.usesSdkClient})},{logicFunctions:i,frontComponents:a}=e.filePaths;return await Ce({appPath:e.appPath,sourcePaths:i,fileFolder:l.B.BuiltLogicFunction,buildOptions:{bundle:!0,splitting:!1,format:"esm",platform:"node",outdir:I.join(e.appPath,l.E),outExtension:{".js":".mjs"},external:qe,tsconfig:I.join(e.appPath,"tsconfig.json"),sourcemap:!0,metafile:!0,logLevel:"silent",banner:l.T},onFileBuilt:s}),await Ce({appPath:e.appPath,sourcePaths:a,fileFolder:l.B.BuiltFrontComponent,buildOptions:{...kt(),outdir:I.join(e.appPath,l.E),tsconfig:I.join(e.appPath,"tsconfig.json"),jsx:"automatic",sourcemap:!0,metafile:!0,logLevel:"silent",plugins:[...de.getFrontComponentBuildPlugins()]},onFileBuilt:s}),await ke({appPath:e.appPath,fileFolder:l.B.PublicAsset,filePaths:e.filePaths.publicAssets,collectFileBuilt:s}),await ke({appPath:e.appPath,fileFolder:l.B.Dependencies,filePaths:["package.json","yarn.lock"].filter(r=>vt(I.join(e.appPath,r))),collectFileBuilt:s}),{builtFileInfos:n}},ke=async({appPath:e,fileFolder:t,filePaths:n,collectFileBuilt:s})=>{for(const i of n){const a=I.join(e,i);if(!await ne(a))continue;const r=I.join(l.E,i),o=I.join(e,r);await P(I.dirname(o)),await je(a,o);const u=await y.readFile(o),c=De.default.createHash("md5").update(u).digest("hex");s({fileFolder:t,builtPath:r,sourcePath:i,checksum:c})}};var Z=(e=>(e.DefineApplication="defineApplication",e.DefineField="defineField",e.DefineLogicFunction="defineLogicFunction",e.DefinePreInstallLogicFunction="definePreInstallLogicFunction",e.DefinePostInstallLogicFunction="definePostInstallLogicFunction",e.DefineObject="defineObject",e.DefineRole="defineRole",e.DefineSkill="defineSkill",e.DefineAgent="defineAgent",e.DefineFrontComponent="defineFrontComponent",e.DefineView="defineView",e.DefineNavigationMenuItem="defineNavigationMenuItem",e.DefinePageLayout="definePageLayout",e))(Z||{}),T=(e=>(e.Application="application",e.Fields="fields",e.LogicFunctions="logicFunctions",e.Objects="objects",e.Roles="roles",e.Skills="skills",e.Agents="agents",e.FrontComponents="frontComponents",e.PublicAssets="publicAssets",e.Views="views",e.NavigationMenuItems="navigationMenuItems",e.PageLayouts="pageLayouts",e))(T||{});const Rt={defineApplication:"application",defineField:"fields",defineLogicFunction:"logicFunctions",definePreInstallLogicFunction:"logicFunctions",definePostInstallLogicFunction:"logicFunctions",defineObject:"objects",defineRole:"roles",defineSkill:"skills",defineAgent:"agents",defineFrontComponent:"frontComponents",defineView:"views",defineNavigationMenuItem:"navigationMenuItems",definePageLayout:"pageLayouts"},Lt=e=>{if(!q.isCallExpression(e))return;const t=e.expression;if(q.isIdentifier(t)&&Object.values(Z).includes(t.text))return t.text},Pt=e=>{const t=q.createSourceFile("temp.ts",e,q.ScriptTarget.Latest,!0),n=[];q.forEachChild(t,s=>{n.push(s)});for(const s of n)if(q.isExportAssignment(s)){if(s.isExportEquals||!s.expression)return;const i=Lt(s.expression);if(i)return i}},xt=[[/\bfavoriteRecordIds\.length\b/g,"arrayLength(favoriteRecordIds)"],[/\bselectedRecords\.length\b/g,"arrayLength(selectedRecords)"]],Dt=e=>xt.reduce((t,[n,s])=>t.replace(n,s),e.replace(/!==/g,"!=").replace(/===/g,"==").replace(/&&/g,"and").replace(/\|\|/g,"or").replace(/!(?!=)/g,"not ").replace(/,(\s*\))/g,"$1")),Ut=/(conditionalAvailabilityExpression\s*:\s*)(?!['"`])((?:[^,}()]|\([^()]*\))+)/g,jt=e=>e.replace(Ut,(t,n,s)=>n+JSON.stringify(Dt(s.trim()))),Mt={name:"conditional-availability-transform",setup:e=>{e.onLoad({filter:/\.tsx?$/},async t=>{const n=await It.readFile(t.path,"utf8");if(!n.includes("conditionalAvailabilityExpression"))return null;const s=jt(n);return s===n?null:{contents:s,loader:t.path.endsWith(".tsx")?"tsx":"ts"}})}},$t=["twenty-sdk/ui","twenty-client-sdk/core","twenty-client-sdk/metadata"],Bt={name:"manifest-mock",setup:e=>{const t=new RegExp(`^(${$t.map(n=>n.replace("/","\\/")).join("|")})$`);e.onResolve({filter:t},({path:n})=>({path:n,namespace:"manifest-mock"})),e.onLoad({filter:/.*/,namespace:"manifest-mock"},()=>({contents:"module.exports = new Proxy({}, { get: () => () => {} });",loader:"js"}))}},b=async({filePath:e,appPath:t})=>{const n=await Ht({filePath:e,appPath:t});return qt(n,e)},Ht=async({filePath:e,appPath:t})=>{const n=f.default.join(t,"tsconfig.json"),s=await ne(n),i=mt.createRequire(f.default.join(t,"package.json"));let a,r;try{a=f.default.dirname(i.resolve("react/package.json")),r=f.default.dirname(i.resolve("react-dom/package.json"))}catch{}const u=(await fe.build({entryPoints:[e],bundle:!0,write:!1,format:"cjs",platform:"node",target:"node18",jsx:"automatic",tsconfig:s?n:void 0,alias:{...a&&{react:a},...r&&{"react-dom":r}},plugins:[Mt,Bt],logLevel:"silent"})).outputFiles[0].text,c=await y.mkdtemp(f.default.join(he.default.tmpdir(),"twenty-manifest-")),d=f.default.join(c,"module.cjs");try{return await y.writeFile(d,u),i(d)}finally{await Q(c)}},qt=(e,t)=>{if(l.o(e.default)&&l.uI(e.default))return e.default;throw new Error(`Config file ${t} must export a config object default export`)},Vt="142046f0-4d80-48b5-ad56-26ad410e895c",_=({objectConfig:e,fieldName:t})=>{const n=`${e.universalIdentifier}-${t}`;return gt.v5(n,Vt)},Yt=e=>{const t={name:"id",label:"Id",description:"Id",icon:"Icon123",isNullable:!1,defaultValue:"uuid",type:l.R.UUID,universalIdentifier:_({objectConfig:e,fieldName:"id"})},n={name:"name",label:"Name",description:"Name",icon:"IconAbc",isNullable:!0,defaultValue:null,type:l.R.TEXT,universalIdentifier:_({objectConfig:e,fieldName:"name"})},s={name:"createdAt",label:"Creation date",description:"Creation date",icon:"IconCalendar",isNullable:!1,defaultValue:"now",type:l.R.DATE_TIME,universalIdentifier:_({objectConfig:e,fieldName:"createdAt"})},i={name:"updatedAt",label:"Last update",description:"Last time the record was changed",icon:"IconCalendarClock",isNullable:!1,defaultValue:"now",type:l.R.DATE_TIME,universalIdentifier:_({objectConfig:e,fieldName:"updatedAt"})},a={name:"deletedAt",label:"Deleted at",description:"Deletion date",icon:"IconCalendarClock",isNullable:!0,defaultValue:null,type:l.R.DATE_TIME,universalIdentifier:_({objectConfig:e,fieldName:"deletedAt"})},r={name:"createdBy",label:"Created by",description:"The creator of the record",icon:"IconCreativeCommonsSa",isNullable:!1,defaultValue:{name:"''",source:"'MANUAL'"},type:l.R.ACTOR,universalIdentifier:_({objectConfig:e,fieldName:"createdBy"})},o={name:"updatedBy",label:"Updated by",description:"The workspace member who last updated the record",icon:"IconUserCircle",isNullable:!1,defaultValue:{name:"''",source:"'MANUAL'"},type:l.R.ACTOR,universalIdentifier:_({objectConfig:e,fieldName:"updatedBy"})},u={name:"position",label:"Position",description:"Position",icon:"IconHierarchy2",isNullable:!1,defaultValue:0,type:l.R.POSITION,universalIdentifier:_({objectConfig:e,fieldName:"position"})},c={name:"searchVector",label:"Search vector",icon:"IconSearch",description:"Search vector",isNullable:!0,defaultValue:null,type:l.R.TS_VECTOR,universalIdentifier:_({objectConfig:e,fieldName:"searchVector"})};return[t,n,s,i,a,r,o,u,c]},J={targetFieldName:e=>`target${l.so(e.nameSingular)}`,targetLabel:e=>l.so(e.nameSingular),icon:"IconBuildingSkyscraper",isNullable:!0},zt=[{...J,fieldName:"timelineActivities",label:"Timeline Activities",targetIcon:"IconTimelineEvent",targetFieldType:l.R.MORPH_RELATION,standardObjectKey:"timelineActivity",morphId:l.y.timelineActivity.morphIds.targetMorphId.morphId},{...J,fieldName:"favorites",label:"Favorites",icon:"IconBuildingSkyscraper",targetIcon:"IconHeart",targetFieldType:l.R.RELATION,standardObjectKey:"favorite"},{...J,fieldName:"attachments",label:"Attachments",icon:"IconBuildingSkyscraper",targetIcon:"IconFileImport",targetFieldType:l.R.MORPH_RELATION,standardObjectKey:"attachment",morphId:l.y.attachment.morphIds.targetMorphId.morphId},{...J,fieldName:"noteTargets",label:"Note Targets",icon:"IconBuildingSkyscraper",targetIcon:"IconCheckbox",targetFieldType:l.R.MORPH_RELATION,standardObjectKey:"noteTarget",morphId:l.y.noteTarget.morphIds.targetMorphId.morphId},{...J,fieldName:"taskTargets",label:"Task Targets",icon:"IconBuildingSkyscraper",targetIcon:"IconCheckbox",targetFieldType:l.R.MORPH_RELATION,standardObjectKey:"taskTarget",morphId:l.y.taskTarget.morphIds.targetMorphId.morphId}],Wt=({config:e,forwardFieldUniversalIdentifier:t,objectConfig:n,universalIdentifier:s})=>{const i=l.y[e.standardObjectKey],a={name:e.targetFieldName(n),label:e.targetLabel(n),description:`${e.targetLabel(n)} ${n.labelSingular}`,icon:e.targetIcon,isNullable:!0,universalSettings:{relationType:l.z.MANY_TO_ONE,onDelete:l.Z.SET_NULL,joinColumnName:`target${l.so(n.nameSingular)}Id`},universalIdentifier:s,objectUniversalIdentifier:i.universalIdentifier,relationTargetFieldMetadataUniversalIdentifier:t,relationTargetObjectMetadataUniversalIdentifier:n.universalIdentifier};return e.targetFieldType===l.R.MORPH_RELATION?{...a,type:e.targetFieldType,morphId:e.morphId}:{...a,type:e.targetFieldType}},Jt=e=>{const t=[],n=[];for(const s of zt){const i=l.y[s.standardObjectKey],a=_({objectConfig:e,fieldName:s.fieldName}),r=_({objectConfig:e,fieldName:`${s.fieldName}Inverse`}),o={name:s.fieldName,label:s.label,description:`${e.labelPlural} tied to the ${s.targetLabel(e)}`,icon:s.icon,isNullable:s.isNullable,type:l.R.RELATION,universalSettings:{relationType:l.z.ONE_TO_MANY},universalIdentifier:a,relationTargetFieldMetadataUniversalIdentifier:r,relationTargetObjectMetadataUniversalIdentifier:i.universalIdentifier},u=Wt({config:s,objectConfig:e,universalIdentifier:r,forwardFieldUniversalIdentifier:a});t.push(o),n.push(u)}return{objectFields:t,fields:n}},Gt=e=>{const t=Yt(e),{objectFields:n,fields:s}=Jt(e),i=(e.fields??[]).map(r=>r.name),a=[...e.fields];for(const r of t)i.includes(r.name)||a.push(r);for(const r of n)i.includes(r.name)||a.push(r);return{objectFields:a,fields:s}},Kt={type:"object",properties:{}},Xt=async e=>{const{getFunctionInputSchema:t}=await Promise.resolve().then(()=>require("./get-function-input-schema-BZ7_XyUh-Bf_NiyDR.js")),n=t(e)[0];return n?.type==="object"&&l.o(n.properties)?{type:"object",properties:n.properties}:Kt},Qt=async e=>await xe.glob(["**/*.ts","**/*.tsx"],{cwd:e,absolute:!0,ignore:["**/node_modules/**","**/*.d.ts","**/dist/**","**/.twenty/**"],onlyFiles:!0}),Zt=async e=>await xe.glob([`${l._}/**/*`],{cwd:e,onlyFiles:!0}),Ye=async e=>{const t=await Qt(e),n=[];let s;const i=[],a=[],r=[],o=[],u=[],c=[],d=[],h=[],m=[],A=[],F=[],S=[],R=[],ie=[],ae=[],ye=[],Ie=[],ve=[],Ae=[],we=[],Te=[],Fe=[],Ee=[],be=[],Ne=[];for(const g of t){const $=await y.readFile(g,"utf-8"),E=I.relative(e,g),K=Pt($);if(!K)continue;switch(Rt[K]){case T.Application:{const p=await b({appPath:e,filePath:g});s={...p.config,yarnLockChecksum:null,packageJsonChecksum:null},n.push(...p.errors),ie.push(E);break}case T.Objects:{const p=await b({appPath:e,filePath:g}),{objectFields:L,fields:B}=Gt(p.config),D=p.config.labelIdentifierFieldMetadataUniversalIdentifier??L.find(W=>W.name==="name")?.universalIdentifier;if(!D){n.push(`No label identifier field found for object ${p.config.nameSingular}. Please add a field with name "name" to your object.`);break}const H={...p.config,fields:L,labelIdentifierFieldMetadataUniversalIdentifier:D};i.push(H),a.push(...B),n.push(...p.errors),ae.push(E);break}case T.Fields:{const p=await b({appPath:e,filePath:g});a.push(p.config),n.push(...p.errors),ye.push(E);break}case T.Roles:{const p=await b({appPath:e,filePath:g});r.push(p.config),n.push(...p.errors),Ie.push(E);break}case T.Skills:{const p=await b({appPath:e,filePath:g});o.push(p.config),n.push(...p.errors),ve.push(E);break}case T.Agents:{const p=await b({appPath:e,filePath:g});u.push(p.config),n.push(...p.errors),Ae.push(E);break}case T.LogicFunctions:{const p=await b({appPath:e,filePath:g});n.push(...p.errors);const{handler:L,...B}=p.config,D=I.relative(e,g),H=B.toolInputSchema??await Xt($),W={...B,toolInputSchema:H,handlerName:"default.config.handler",sourceHandlerPath:D,builtHandlerPath:D.replace(/\.tsx?$/,".mjs"),builtHandlerChecksum:"[default-checksum]"};c.push(W),we.push(E),K===Z.DefinePreInstallLogicFunction&&S.push(p.config.universalIdentifier),K===Z.DefinePostInstallLogicFunction&&R.push(p.config.universalIdentifier);break}case T.FrontComponents:{const p=await b({appPath:e,filePath:g});n.push(...p.errors);const{component:L,command:B,...D}=p.config,H=I.relative(e,g),W={...D,componentName:L.name,sourceComponentPath:H,builtComponentPath:H.replace(/\.tsx?$/,".mjs"),builtComponentChecksum:"",isHeadless:D.isHeadless??!1,command:B};d.push(W),Te.push(E);break}case T.Views:{const p=await b({appPath:e,filePath:g}),L={...p.config};m.push(L),n.push(...p.errors),Ee.push(E);break}case T.NavigationMenuItems:{const p=await b({appPath:e,filePath:g});A.push(p.config),n.push(...p.errors),be.push(E);break}case T.PageLayouts:{const p=await b({appPath:e,filePath:g}),L={...p.config};F.push(L),n.push(...p.errors),Ne.push(E);break}case T.PublicAssets:break;default:l.yt()}}const tt=await Zt(e);for(const g of tt)h.push({filePath:g,fileName:I.basename(g),fileType:I.extname(g).replace(/^\./,""),checksum:null}),Fe.push(I.relative(e,g));s||n.push("Cannot build application, please export default defineApplication() to define an application"),S.length>1&&n.push("Only one pre install logic function is allowed per application"),R.length>1&&n.push("Only one post install logic function is allowed per application"),s&&S.length>=1&&(s={...s,preInstallLogicFunctionUniversalIdentifier:S[0]}),s&&R.length>=1&&(s={...s,postInstallLogicFunctionUniversalIdentifier:R[0]});const C=(g,$)=>g.universalIdentifier.localeCompare($.universalIdentifier),nt=(g,$)=>g.filePath.localeCompare($.filePath);return{manifest:s?{application:s,objects:i.sort(C),fields:a.sort(C),roles:r.sort(C),skills:o.sort(C),agents:u.sort(C),logicFunctions:c.sort(C),frontComponents:d.sort(C),publicAssets:h.sort(nt),views:m.sort(C),navigationMenuItems:A.sort(C),pageLayouts:F.sort(C)}:null,filePaths:{application:ie,objects:ae,fields:ye,roles:Ie,skills:ve,agents:Ae,logicFunctions:we,frontComponents:Te,publicAssets:Fe,views:Ee,navigationMenuItems:be,pageLayouts:Ne},errors:n}},en=[l.R.RELATION,l.R.MORPH_RELATION],oe=[l.z.MANY_TO_ONE,l.z.ONE_TO_MANY],tn=e=>{const t=new Set,n=new Set;for(const s of e)t.has(s)?n.add(s):t.add(s);return Array.from(n)},ze=e=>{const t=[];if(!e)return[];for(const[n,s]of Object.entries(e))n==="universalIdentifier"&&typeof s=="string"&&t.push(s),typeof s=="object"&&t.push(...ze(s));return t},nn=e=>{const t=[];for(const n of e){if(!en.includes(n.type))continue;const s=n.universalSettings;if(!s?.relationType){t.push(`Relation field "${n.name}" is missing relationType. ${n.type} fields must declare a relationType (${oe.join(" or ")}) in universalSettings.`);continue}if(!oe.includes(s.relationType)){t.push(`Relation field "${n.name}" has invalid relationType "${s.relationType}". Expected ${oe.join(" or ")}.`);continue}s.relationType===l.z.MANY_TO_ONE&&!s.joinColumnName&&t.push(`MANY_TO_ONE relation field "${n.name}" is missing joinColumnName. MANY_TO_ONE relations must declare a joinColumnName in universalSettings.`)}return t},sn=e=>{const t=[],n=[],s=tn(ze(e));s.length>0&&t.push(`Duplicate universal identifiers: ${s.join(", ")}`),l.da(e.objects)||n.push("No object defined"),l.da(e.logicFunctions)||n.push("No logic function defined"),l.da(e.frontComponents)||n.push("No front component defined");const i=[...e.fields,...e.objects.flatMap(a=>a.fields)];return t.push(...nn(i)),{errors:t,warnings:n,isValid:t.length===0}},We=async e=>{const t=await Ye(e);if(t.errors.length>0||!t.manifest)return{success:!1,errors:t.errors.length>0?t.errors:["Failed to build manifest."]};const n=sn(t.manifest);return n.isValid?{success:!0,manifest:t.manifest,filePaths:t.filePaths,warnings:n.warnings}:{success:!1,errors:n.errors}},Je=({manifest:e,builtFileInfos:t})=>{let n=structuredClone(e);for(const[s,{fileFolder:i,checksum:a}]of t.entries()){const r=I.relative(l.E,s);if(i===l.B.BuiltLogicFunction){const o=n.logicFunctions,u=o.findIndex(c=>c.builtHandlerPath===r);if(u===-1)continue;n={...n,logicFunctions:o.map((c,d)=>d===u?{...c,builtHandlerChecksum:a}:c)}}if(i===l.B.PublicAsset){const o=n.publicAssets,u=o.findIndex(c=>c.filePath===r);if(u===-1)continue;n={...n,publicAssets:o.map((c,d)=>d===u?{...c,checksum:a}:c)};continue}if(i===l.B.BuiltFrontComponent){const o=n.frontComponents,u=o.findIndex(d=>d.builtComponentPath===r)??-1;if(u===-1)continue;const c=t.get(s);n={...n,frontComponents:o.map((d,h)=>h===u?{...d,builtComponentChecksum:a,usesSdkClient:c?.usesSdkClient??!1}:d)}}i===l.B.Dependencies&&(r==="package.json"&&(n.application.packageJsonChecksum=a),r==="yarn.lock"&&(n.application.yarnLockChecksum=a))}return n},Ge=async(e,t)=>{const n=f.default.join(e,l.E);await P(n);const s=f.default.join(n,"manifest.json");return await Tt(s,t),s},k=async(e,t)=>{try{return await e()}catch(n){return{success:!1,error:{code:t,message:n instanceof Error?n.message:"Unexpected error"}}}},U={AUTH_FAILED:"AUTH_FAILED",NO_REMOTES:"NO_REMOTES",REMOTE_NOT_FOUND:"REMOTE_NOT_FOUND",OAUTH_NOT_SUPPORTED:"OAUTH_NOT_SUPPORTED"},w={MANIFEST_NOT_FOUND:"MANIFEST_NOT_FOUND",MANIFEST_BUILD_FAILED:"MANIFEST_BUILD_FAILED",BUILD_FAILED:"BUILD_FAILED",PUBLISH_FAILED:"PUBLISH_FAILED",INSTALL_FAILED:"INSTALL_FAILED",UNINSTALL_FAILED:"UNINSTALL_FAILED",SYNC_FAILED:"SYNC_FAILED",TYPECHECK_FAILED:"TYPECHECK_FAILED",DEPLOY_FAILED:"DEPLOY_FAILED"},V={DOCKER_NOT_RUNNING:"DOCKER_NOT_RUNNING",CONTAINER_START_FAILED:"CONTAINER_START_FAILED",HEALTH_TIMEOUT:"HEALTH_TIMEOUT"},G={FETCH_FUNCTIONS_FAILED:"FETCH_FUNCTIONS_FAILED",FUNCTION_NOT_FOUND:"FUNCTION_NOT_FOUND",EXECUTION_FAILED:"EXECUTION_FAILED"},an=async e=>{const{appPath:t,onProgress:n}=e;n?.("Building manifest...");const s=await We(t);if(!s.success)return{success:!1,error:{code:w.MANIFEST_BUILD_FAILED,message:s.errors.join(`
|
|
4
|
-
`)}};const{manifest:i,filePaths:a}=s;for(const h of s.warnings)n?.(`⚠ ${h}`);n?.("Building application files...");const r=await St({appPath:t,filePaths:a});n?.("Running typecheck...");const o=await me(t);if(o.length>0){const h=o.map(m=>`${m.file}(${m.line},${m.column+1}): ${m.text}`);return{success:!1,error:{code:w.TYPECHECK_FAILED,message:`Typecheck failed:
|
|
5
|
-
${h.join(`
|
|
6
|
-
`)}`}}}const u=Je({manifest:i,builtFileInfos:r.builtFileInfos});await Ge(t,u);const c=f.default.join(t,".twenty","output"),d={outputDir:c,fileCount:r.builtFileInfos.size};if(e.tarball){n?.("Packing tarball...");const m=Pe.execSync("npm pack --pack-destination .",{cwd:c,encoding:"utf-8"}).trim().split(`
|
|
7
|
-
`).pop();d.tarballPath=f.default.join(c,m)}return{success:!0,data:d}},Ke=e=>k(()=>an(e),w.BUILD_FAILED),rn=f.join(he.tmpdir(),".twenty-sdk-test"),on=()=>process.env.NODE_ENV==="test"?f.join(rn,"config.json"):f.join(he.homedir(),".twenty","config.json"),ce=1,N="local",te=class te{constructor(){this.configPath=on()}static setActiveRemote(t){this.activeRemote=t??N}static getActiveRemote(){return this.activeRemote}getActiveRemoteName(){return te.getActiveRemote()}async readRawConfig(){await At(this.configPath);const t=await y.readFile(this.configPath,"utf8"),n=JSON.parse(t||"{}");return this.migrateConfigIfNeeded(n)}async migrateConfigIfNeeded(t){if(t.version===ce)return t;const n="profiles"in t,s="apiUrl"in t&&!("remotes"in t);if(!n&&!s)return t;const i={version:ce},a=d=>typeof d=="string"?d:void 0,r=d=>({apiUrl:a(d.apiUrl)??"",apiKey:a(d.apiKey),accessToken:a(d.accessToken)??a(d.applicationAccessToken),refreshToken:a(d.refreshToken)??a(d.applicationRefreshToken),oauthClientId:a(d.oauthClientId)}),o=t.profiles??{};i.remotes={};for(const[d,h]of Object.entries(o)){const m=d==="default"?N:d;i.remotes[m]=r(h)}const u=t.remotes??{};for(const[d,h]of Object.entries(u)){const m=d==="default"?N:d;i.remotes[m]=h}s&&!i.remotes[N]&&(i.remotes[N]=r(t));const c=t.defaultWorkspace;return c&&(i.defaultRemote=c==="default"?N:c),await P(f.dirname(this.configPath)),await y.writeFile(this.configPath,JSON.stringify(i,null,2)),i}async getConfig(){return process.env.TWENTY_TOKEN&&process.env.TWENTY_API_URL?{apiUrl:process.env.TWENTY_API_URL,accessToken:process.env.TWENTY_TOKEN}:this.getConfigForRemote(this.getActiveRemoteName())}async getConfigForRemote(t){const n=this.getDefaultConfig();try{const i=(await this.readRawConfig()).remotes?.[t];return i?{apiUrl:i.apiUrl??n.apiUrl,apiKey:i.apiKey,accessToken:i.accessToken,refreshToken:i.refreshToken,oauthClientId:i.oauthClientId}:n}catch{return n}}async setConfig(t){const n=await this.readRawConfig(),s=this.getActiveRemoteName();n.version=ce,n.remotes||(n.remotes={});const i=n.remotes[s]||{apiUrl:""};n.remotes[s]={...i,...t},await P(f.dirname(this.configPath)),await y.writeFile(this.configPath,JSON.stringify(n,null,2))}async clearConfig(){const t=await this.readRawConfig(),n=this.getActiveRemoteName();t.remotes||(t.remotes={}),t.remotes[n]&&delete t.remotes[n],await P(f.dirname(this.configPath)),await y.writeFile(this.configPath,JSON.stringify(t,null,2))}getDefaultConfig(){return{apiUrl:"http://localhost:2020"}}async getRemotes(){try{const t=await this.readRawConfig(),n=new Set;return n.add(N),t.remotes&&Object.keys(t.remotes).forEach(s=>n.add(s)),Array.from(n).sort()}catch{return[N]}}async getDefaultRemote(){try{return(await this.readRawConfig()).defaultRemote??N}catch{return N}}async setDefaultRemote(t){const n=await this.readRawConfig();n.defaultRemote=t,await P(f.dirname(this.configPath)),await y.writeFile(this.configPath,JSON.stringify(n,null,2))}};te.activeRemote=N;let v=te;class cn{constructor(t){const{disableInterceptors:n=!1,serverUrl:s,token:i,skipAuth:a=!1}=t||{};this.configService=new v,this.tokenOverride=i,this.serverUrlOverride=s,this.client=O.default.create(),this.client.interceptors.request.use(async r=>{const o=await this.configService.getConfig();if(r.baseURL=this.serverUrlOverride??o.apiUrl,!r.headers.Authorization&&!a){const u=await this.resolveAuthToken();u&&(r.headers.Authorization=`Bearer ${u}`)}return r}),!n&&this.client.interceptors.response.use(r=>r,async r=>{throw r.response?.status===401?console.error(X.default.red("Authentication failed. Run `yarn twenty remote add` to authenticate.")):r.response?.status===403?console.error(X.default.red("Access denied. Check your API key and workspace permissions.")):r.code==="ECONNREFUSED"&&console.error(X.default.red("Cannot connect to Twenty server. Is it running?")),r})}async validateAuth(){try{const n=await this.client.post("/metadata",{query:`
|
|
8
|
-
query CurrentWorkspace {
|
|
9
|
-
currentWorkspace {
|
|
10
|
-
id
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
`},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return{authValid:n.status===200&&!n.data.errors,serverUp:n.status===200}}catch(t){return O.default.isAxiosError(t)&&t.response?{authValid:!1,serverUp:!0}:{authValid:!1,serverUp:!1}}}async refreshToken(){const t=await this.configService.getConfig();if(!t.refreshToken||!t.oauthClientId)return null;try{const n=await O.default.post(`${t.apiUrl}/oauth/token`,{grant_type:"refresh_token",refresh_token:t.refreshToken,client_id:t.oauthClientId}),{access_token:s,refresh_token:i}=n.data;return await this.configService.setConfig({accessToken:s,...i?{refreshToken:i}:{}}),s}catch{return null}}async resolveAuthToken(){if(this.tokenOverride)return this.tokenOverride;const t=process.env.TWENTY_TOKEN;if(t)return t;const n=await this.configService.getConfig(),s=n.accessToken;if(s&&this.isTokenExpired(s)){const i=await this.refreshToken();if(i)return i}return s??n.apiKey}isTokenExpired(t){try{return JSON.parse(Buffer.from(t.split(".")[1],"base64").toString()).exp*1e3<Date.now()+30*1e3}catch{return!1}}}class ln{constructor(t){this.client=t}async syncMarketplaceCatalog(){try{const n=await this.client.post("/metadata",{query:`
|
|
14
|
-
mutation SyncMarketplaceCatalog {
|
|
15
|
-
syncMarketplaceCatalog
|
|
16
|
-
}
|
|
17
|
-
`},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return n.data.errors?{success:!1,error:n.data.errors[0]}:{success:!0,data:n.data.data.syncMarketplaceCatalog}}catch(t){return{success:!1,error:t}}}async findApplicationRegistrationByUniversalIdentifier(t){try{const s=await this.client.post("/metadata",{query:`
|
|
18
|
-
query FindApplicationRegistrationByUniversalIdentifier($universalIdentifier: String!) {
|
|
19
|
-
findApplicationRegistrationByUniversalIdentifier(universalIdentifier: $universalIdentifier) {
|
|
20
|
-
id
|
|
21
|
-
universalIdentifier
|
|
22
|
-
name
|
|
23
|
-
oAuthClientId
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
`,variables:{universalIdentifier:t}},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return s.data.errors?{success:!1,error:s.data.errors[0]}:{success:!0,data:s.data.data.findApplicationRegistrationByUniversalIdentifier}}catch(n){return{success:!1,error:n}}}async createApplicationRegistration(t){try{const s=await this.client.post("/metadata",{query:`
|
|
27
|
-
mutation CreateApplicationRegistration($input: CreateApplicationRegistrationInput!) {
|
|
28
|
-
createApplicationRegistration(input: $input) {
|
|
29
|
-
applicationRegistration {
|
|
30
|
-
id
|
|
31
|
-
universalIdentifier
|
|
32
|
-
oAuthClientId
|
|
33
|
-
}
|
|
34
|
-
clientSecret
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
`,variables:{input:t}},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return s.data.errors?{success:!1,error:s.data.errors[0]}:{success:!0,data:s.data.data.createApplicationRegistration}}catch(n){return{success:!1,error:n}}}async createDevelopmentApplication(t){try{const s=await this.client.post("/metadata",{query:`
|
|
38
|
-
mutation CreateDevelopmentApplication($universalIdentifier: String!, $name: String!) {
|
|
39
|
-
createDevelopmentApplication(universalIdentifier: $universalIdentifier, name: $name) {
|
|
40
|
-
id
|
|
41
|
-
universalIdentifier
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
`,variables:t},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return s.data.errors?{success:!1,error:s.data.errors[0]}:{success:!0,data:s.data.data.createDevelopmentApplication}}catch(n){return{success:!1,error:n}}}async syncApplication(t){try{const n=`
|
|
45
|
-
mutation SyncApplication($manifest: JSON!) {
|
|
46
|
-
syncApplication(manifest: $manifest) {
|
|
47
|
-
applicationUniversalIdentifier
|
|
48
|
-
actions
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
`,s={manifest:t},i=await this.client.post("/metadata",{query:n,variables:s},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return i.data.errors?{success:!1,error:i.data.errors[0]}:{success:!0,data:i.data.data.syncApplication,message:`Successfully synced application: ${t.application.displayName}`}}catch(n){if(O.default.isAxiosError(n)&&n.response){const s=n.response.data?.errors;return Array.isArray(s)&&s.length>0?{success:!1,error:s[0]?.message||n.message}:{success:!1,error:n.response.data?.message||`HTTP ${n.response.status}: ${n.message}`}}return{success:!1,error:n instanceof Error?n.message:n}}}async uninstallApplication(t){try{const n=`
|
|
52
|
-
mutation UninstallApplication($universalIdentifier: String!) {
|
|
53
|
-
uninstallApplication(universalIdentifier: $universalIdentifier)
|
|
54
|
-
}
|
|
55
|
-
`,s={universalIdentifier:t},i=await this.client.post("/metadata",{query:n,variables:s},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return i.data.errors?{success:!1,error:i.data.errors[0]?.message||"Failed to delete application"}:{success:!0,data:i.data.data.uninstallApplication,message:"Successfully uninstalled application"}}catch(n){if(O.default.isAxiosError(n)&&n.response)return{success:!1,error:n.response.data?.errors?.[0]?.message||n.message};throw n}}}const un={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".csv":"text/csv",".json":"application/json",".xml":"application/xml",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".mp3":"audio/mpeg",".mp4":"video/mp4",".avi":"video/x-msvideo",".mov":"video/quicktime",".js":"application/javascript",".ts":"application/typescript",".jsx":"application/javascript",".tsx":"application/typescript",".html":"text/html",".css":"text/css"},dn=e=>{const t=f.extname(e).toLowerCase();return un[t]||"application/octet-stream"};class pn{constructor(t){this.client=t}async uploadAppTarball({tarballBuffer:t,universalIdentifier:n}){try{const i=JSON.stringify({query:`
|
|
56
|
-
mutation UploadAppTarball($file: Upload!, $universalIdentifier: String) {
|
|
57
|
-
uploadAppTarball(file: $file, universalIdentifier: $universalIdentifier) {
|
|
58
|
-
id
|
|
59
|
-
universalIdentifier
|
|
60
|
-
name
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
`,variables:{file:null,universalIdentifier:n??null}}),a=JSON.stringify({0:["variables.file"]}),r=new FormData;r.append("operations",i),r.append("map",a),r.append("0",new Blob([new Uint8Array(t)],{type:"application/gzip"}),"app.tar.gz");const o=await this.client.post("/metadata",r);return o.data.errors?{success:!1,error:o.data.errors[0]?.message||"Failed to upload tarball"}:{success:!0,data:o.data.data.uploadAppTarball}}catch(s){return O.default.isAxiosError(s)&&s.response?{success:!1,error:s.response.data?.errors?.[0]?.message||s.message}:{success:!1,error:s}}}async installTarballApp({universalIdentifier:t}){try{const s=await this.client.post("/metadata",{query:`
|
|
64
|
-
mutation InstallMarketplaceApp($universalIdentifier: String!) {
|
|
65
|
-
installMarketplaceApp(universalIdentifier: $universalIdentifier)
|
|
66
|
-
}
|
|
67
|
-
`,variables:{universalIdentifier:t}},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return s.data.errors?{success:!1,error:s.data.errors[0]?.message||"Failed to install application"}:{success:!0,data:s.data.data.installMarketplaceApp}}catch(n){return O.default.isAxiosError(n)&&n.response?{success:!1,error:n.response.data?.errors?.[0]?.message||n.message}:{success:!1,error:n}}}async uploadFile({filePath:t,builtHandlerPath:n,fileFolder:s,applicationUniversalIdentifier:i}){try{const a=f.resolve(t);if(!le.existsSync(a))return{success:!1,error:`File not found: ${a}`};const r=f.basename(a),o=le.readFileSync(a),u=dn(r),c=`
|
|
68
|
-
mutation UploadApplicationFile($file: Upload!, $applicationUniversalIdentifier: String!, $fileFolder: FileFolder!, $filePath: String!) {
|
|
69
|
-
uploadApplicationFile(file: $file, applicationUniversalIdentifier: $applicationUniversalIdentifier, fileFolder: $fileFolder, filePath: $filePath)
|
|
70
|
-
{ path }
|
|
71
|
-
}
|
|
72
|
-
`,d=l.ta(s),h=JSON.stringify({query:c,variables:{file:null,applicationUniversalIdentifier:i,filePath:n,fileFolder:d}}),m=JSON.stringify({0:["variables.file"]}),A=new FormData;A.append("operations",h),A.append("map",m),A.append("0",new Blob([new Uint8Array(o)],{type:u}),r);const F=await this.client.post("/metadata",A);return F.data.errors?{success:!1,error:F.data.errors[0]?.message||"Failed to upload file"}:{success:!0,data:F.data.data.uploadApplicationFile,message:`Successfully uploaded ${r}`}}catch(a){return O.default.isAxiosError(a)&&a.response?{success:!1,error:a.response.data?.errors?.[0]?.message||a.message}:{success:!1,error:a}}}}class fn{constructor(t){this.apiClient=t}async findLogicFunctions(){try{const n=await this.apiClient.client.post("/metadata",{query:`
|
|
73
|
-
query FindManyLogicFunctions {
|
|
74
|
-
findManyLogicFunctions {
|
|
75
|
-
id
|
|
76
|
-
name
|
|
77
|
-
universalIdentifier
|
|
78
|
-
applicationId
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
`},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return n.data.errors?{success:!1,error:n.data.errors[0]?.message||"Failed to fetch functions"}:{success:!0,data:n.data.data.findManyLogicFunctions}}catch(t){return{success:!1,error:t}}}async executeLogicFunction({functionId:t,payload:n}){try{const s=`
|
|
82
|
-
mutation ExecuteOneLogicFunction($input: ExecuteOneLogicFunctionInput!) {
|
|
83
|
-
executeOneLogicFunction(input: $input) {
|
|
84
|
-
data
|
|
85
|
-
logs
|
|
86
|
-
duration
|
|
87
|
-
status
|
|
88
|
-
error
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
`,i={input:{id:t,payload:n}},a=await this.apiClient.client.post("/metadata",{query:s,variables:i},{headers:{"Content-Type":"application/json",Accept:"*/*"}});return a.data.errors?{success:!1,error:a.data.errors[0]?.message||"Failed to execute logic function"}:{success:!0,data:a.data.data.executeOneLogicFunction}}catch(s){return{success:!1,error:s}}}async subscribeToLogs({applicationUniversalIdentifier:t,functionUniversalIdentifier:n,functionName:s}){const i=await this.apiClient.configService.getConfig(),a=this.apiClient.serverUrlOverride??i.apiUrl,r=pt.createClient({url:a+"/metadata",headers:async()=>{const c=await this.apiClient.resolveAuthToken();return{Authorization:c?`Bearer ${c}`:"","Content-Type":"application/json",Accept:"text/event-stream"}}}),o=`
|
|
92
|
-
subscription SubscribeToLogs($input: LogicFunctionLogsInput!) {
|
|
93
|
-
logicFunctionLogs(input: $input) {
|
|
94
|
-
logs
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
`,u={input:{applicationUniversalIdentifier:t,universalIdentifier:n,name:s}};r.subscribe({query:o,variables:u},{next:({data:c})=>console.log(c?.logicFunctionLogs.logs),error:c=>console.error(c),complete:()=>console.log("Completed")})}}class hn{constructor(t){this.client=t}async getSchema(t){return this.introspectEndpoint("/graphql",t)}async getMetadataSchema(t){return this.introspectEndpoint("/metadata",t)}async introspectEndpoint(t,n){try{const s=re.getIntrospectionQuery(),i={"Content-Type":"application/json",Accept:"*/*"};n?.authToken&&(i.Authorization=`Bearer ${n.authToken}`);const a=await this.client.post(t,{query:s},{headers:i});if(a.data.errors)return{success:!1,error:`GraphQL introspection errors: ${JSON.stringify(a.data.errors)}`};const r=re.buildClientSchema(a.data.data);return{success:!0,data:re.printSchema(r),message:`Successfully loaded schema from ${t}`}}catch(s){if(O.default.isAxiosError(s)&&s.response)return{success:!1,error:s.response.data?.errors?.[0]?.message||`Failed to load schema from ${t}`};throw s}}}class M{constructor(t){this.apiClient=new cn(t),this.applicationApi=new ln(this.apiClient.client),this.schemaApi=new hn(this.apiClient.client),this.logicFunctionApi=new fn(this.apiClient),this.fileApi=new pn(this.apiClient.client)}validateAuth(){return this.apiClient.validateAuth()}refreshToken(){return this.apiClient.refreshToken()}findApplicationRegistrationByUniversalIdentifier(...t){return this.applicationApi.findApplicationRegistrationByUniversalIdentifier(...t)}createApplicationRegistration(...t){return this.applicationApi.createApplicationRegistration(...t)}createDevelopmentApplication(...t){return this.applicationApi.createDevelopmentApplication(...t)}syncApplication(t){return this.applicationApi.syncApplication(t)}uninstallApplication(t){return this.applicationApi.uninstallApplication(t)}syncMarketplaceCatalog(){return this.applicationApi.syncMarketplaceCatalog()}getSchema(t){return this.schemaApi.getSchema(t)}getMetadataSchema(t){return this.schemaApi.getMetadataSchema(t)}findLogicFunctions(...t){return this.logicFunctionApi.findLogicFunctions(...t)}executeLogicFunction(...t){return this.logicFunctionApi.executeLogicFunction(...t)}subscribeToLogs(...t){return this.logicFunctionApi.subscribeToLogs(...t)}uploadAppTarball(...t){return this.fileApi.uploadAppTarball(...t)}installTarballApp(...t){return this.fileApi.installTarballApp(...t)}uploadFile(...t){return this.fileApi.uploadFile(...t)}}const mn=async e=>{const{tarballPath:t,onProgress:n}=e;e.remote&&v.setActiveRemote(e.remote),n?.(`Uploading ${t}...`);const s=le.default.readFileSync(t),a=await new M({serverUrl:e.serverUrl,token:e.token}).uploadAppTarball({tarballBuffer:s});return a.success?{success:!0,data:{universalIdentifier:a.data.universalIdentifier}}:{success:!1,error:{code:w.DEPLOY_FAILED,message:`Upload failed: ${a.error}`}}},gn=e=>k(()=>mn(e),w.DEPLOY_FAILED),yn=[2020,3e3],ge=async e=>{const t=new AbortController,n=setTimeout(()=>t.abort(),2e3);try{return(await(await fetch(`http://localhost:${e}/healthz`,{signal:t.signal})).json()).status==="ok"}catch{return!1}finally{clearTimeout(n)}},Xe=async e=>{const t=e?[e]:yn;for(const n of t)if(await ge(n))return`http://localhost:${n}`;return null},se=async e=>{const t=f.default.join(e,l.E);await P(t);const n=f.default.join(t,"manifest.json");if(!await ne(n)){const{manifest:s}=await Ye(e);return s}return await wt(n)},In=(e,t)=>t.logicFunctions.some(n=>n.universalIdentifier===e.universalIdentifier),Se=e=>"preInstall"in e?"pre install":"postInstall"in e?"post install":"functionUniversalIdentifier"in e?e.functionUniversalIdentifier:"functionName"in e?e.functionName:"unknown",vn=async e=>{e.remote&&v.setActiveRemote(e.remote);const t=new M,n=await se(e.appPath);if(!n)return{success:!1,error:{code:w.MANIFEST_NOT_FOUND,message:"Manifest not found. Run `build` or `dev` first."}};const s=await t.findLogicFunctions();if(!s.success){const o=s.error instanceof Error?s.error.message:String(s.error??"Failed to fetch functions");return{success:!1,error:{code:G.FETCH_FUNCTIONS_FAILED,message:o}}}const i=s.data.filter(o=>o.universalIdentifier&&In(o,n)),a=i.find(o=>"preInstall"in e&&e.preInstall?o.universalIdentifier===n.application.preInstallLogicFunctionUniversalIdentifier:"postInstall"in e&&e.postInstall?o.universalIdentifier===n.application.postInstallLogicFunctionUniversalIdentifier:"functionUniversalIdentifier"in e?o.universalIdentifier===e.functionUniversalIdentifier:"functionName"in e?o.name===e.functionName:!1);if(!a)return{success:!1,error:{code:G.FUNCTION_NOT_FOUND,message:`Function "${Se(e)}" not found in application.`,details:{identifier:Se(e),availableFunctions:i.map(o=>({name:o.name,universalIdentifier:o.universalIdentifier}))}}};const r=await t.executeLogicFunction({functionId:a.id,payload:e.payload??{}});if(!r.success){const o=r.error instanceof Error?r.error.message:String(r.error??"Execution failed");return{success:!1,error:{code:G.EXECUTION_FAILED,message:o}}}return{success:!0,data:{functionName:a.name,...r.data}}},An=e=>k(()=>vn(e),G.EXECUTION_FAILED),wn=async e=>{e.remote&&v.setActiveRemote(e.remote);const t=new M,n=await se(e.appPath);if(!n)return{success:!1,error:{code:w.MANIFEST_NOT_FOUND,message:"Manifest not found. Run `build` or `dev` first."}};const s=await t.installTarballApp({universalIdentifier:n.application.universalIdentifier});if(!s.success){const i=s.error instanceof Error?s.error.message:String(s.error??"Unknown error");return{success:!1,error:{code:w.INSTALL_FAILED,message:i}}}return{success:!0,data:void 0}},Tn=e=>k(()=>wn(e),w.INSTALL_FAILED),Fn=async e=>{const{appPath:t,onProgress:n}=e,s=await Ke({appPath:t,onProgress:n});if(!s.success)return s;n?.("Publishing to npm...");const i=e.npmTag?` --tag ${e.npmTag}`:"";try{Pe.execSync(`npm publish${i}`,{cwd:s.data.outputDir,stdio:"inherit"})}catch{return{success:!1,error:{code:w.PUBLISH_FAILED,message:"npm publish failed"}}}return{success:!0,data:{target:"npm"}}},En=e=>k(()=>Fn(e),w.PUBLISH_FAILED),bn=async e=>{const{apiKey:t,apiUrl:n,remote:s}=e;s&&v.setActiveRemote(s);const i=new v;return await i.setConfig({apiUrl:n,apiKey:t,accessToken:void 0,refreshToken:void 0,oauthClientId:void 0}),(await new M().validateAuth()).authValid?{success:!0,data:void 0}:(await i.clearConfig(),{success:!1,error:{code:U.AUTH_FAILED,message:"Authentication failed. Please check your credentials."}})},Nn=e=>k(()=>bn(e),U.AUTH_FAILED),_n=`<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 96 96">
|
|
98
|
-
<rect width="96" height="96" rx="11.3" fill="#000"/>
|
|
99
|
-
<path fill="#fff" d="M19.25 35.75c0-5.25 4.26-9.5 9.5-9.5h18.29c.27 0 .51.16.63.4.11.25.06.54-.12.75l-4.01 4.35c-.7.76-1.68 1.2-2.71 1.2H28.8c-1.57 0-2.85 1.27-2.85 2.85v7.18c0 .93-.75 1.67-1.68 1.67h-3.34c-.93 0-1.67-.75-1.67-1.67v-7.23z"/>
|
|
100
|
-
<path fill="#fff" d="M76.15 60.25c0 5.25-4.26 9.5-9.5 9.5h-7.77c-5.25 0-9.5-4.25-9.5-9.5V46.65c0-.93.35-1.82.98-2.5l4.53-4.92c.19-.2.49-.27.75-.17.26.11.44.36.44.64v20.52c0 1.57 1.28 2.85 2.85 2.85h7.68c1.57 0 2.85-1.28 2.85-2.85V35.8c0-1.57-1.28-2.85-2.85-2.85h-8.93c-1.02 0-2 .43-2.7 1.18L28.35 63.06h16c.92 0 1.67.75 1.67 1.68v3.34c0 .93-.75 1.67-1.67 1.67H22.79c-1.95 0-3.55-1.59-3.55-3.54v-1.77c0-.89.33-1.75.94-2.4l29.86-32.43c1.98-2.15 4.75-3.36 7.67-3.36h8.93c5.25 0 9.5 4.25 9.5 9.5v24.5z"/>
|
|
101
|
-
</svg>`,Qe=({title:e,message:t,isSuccess:n})=>`<!DOCTYPE html>
|
|
102
|
-
<html lang="en">
|
|
103
|
-
<head>
|
|
104
|
-
<meta charset="utf-8">
|
|
105
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
106
|
-
<title>${e} — Twenty</title>
|
|
107
|
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
108
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
109
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
|
|
110
|
-
<style>
|
|
111
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
112
|
-
body {
|
|
113
|
-
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
114
|
-
background: #fafafa;
|
|
115
|
-
display: flex;
|
|
116
|
-
align-items: center;
|
|
117
|
-
justify-content: center;
|
|
118
|
-
min-height: 100dvh;
|
|
119
|
-
color: #333;
|
|
120
|
-
}
|
|
121
|
-
.card {
|
|
122
|
-
background: #fff;
|
|
123
|
-
border-radius: 8px;
|
|
124
|
-
box-shadow: 2px 4px 16px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04);
|
|
125
|
-
padding: 32px;
|
|
126
|
-
width: 400px;
|
|
127
|
-
max-width: calc(100vw - 32px);
|
|
128
|
-
display: flex;
|
|
129
|
-
flex-direction: column;
|
|
130
|
-
align-items: center;
|
|
131
|
-
gap: 16px;
|
|
132
|
-
}
|
|
133
|
-
.logo { margin-bottom: 4px; }
|
|
134
|
-
.icon {
|
|
135
|
-
width: 48px;
|
|
136
|
-
height: 48px;
|
|
137
|
-
border-radius: 50%;
|
|
138
|
-
display: flex;
|
|
139
|
-
align-items: center;
|
|
140
|
-
justify-content: center;
|
|
141
|
-
}
|
|
142
|
-
.icon-success { background: #f0faf0; }
|
|
143
|
-
.icon-error { background: #fef0f0; }
|
|
144
|
-
.icon svg { width: 24px; height: 24px; }
|
|
145
|
-
h2 {
|
|
146
|
-
font-size: 1.23rem;
|
|
147
|
-
font-weight: 600;
|
|
148
|
-
color: #333;
|
|
149
|
-
}
|
|
150
|
-
p {
|
|
151
|
-
font-size: 0.92rem;
|
|
152
|
-
color: #666;
|
|
153
|
-
text-align: center;
|
|
154
|
-
line-height: 1.5;
|
|
155
|
-
}
|
|
156
|
-
</style>
|
|
157
|
-
</head>
|
|
158
|
-
<body>
|
|
159
|
-
<div class="card">
|
|
160
|
-
<div class="logo">${_n}</div>
|
|
161
|
-
<div class="icon ${n?"icon-success":"icon-error"}">
|
|
162
|
-
${n?'<svg viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>':'<svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>'}
|
|
163
|
-
</div>
|
|
164
|
-
<h2>${e}</h2>
|
|
165
|
-
<p>${t}</p>
|
|
166
|
-
</div>
|
|
167
|
-
</body>
|
|
168
|
-
</html>`,On=Qe({title:"Authentication successful",message:"You can close this window and return to the terminal.",isSuccess:!0}),Cn=e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),kn=e=>Qe({title:"Authentication failed",message:`${Cn(e)}<br>Please return to the terminal and try again.`,isSuccess:!1}),Sn=e=>{const t=e?.timeoutMs??12e4;return new Promise((n,s)=>{let i,a;const r=new Promise(u=>{i=u}),o=yt.default.createServer((u,c)=>{const d=new URL(u.url??"/","http://127.0.0.1");if(d.pathname!=="/callback"){c.writeHead(404),c.end("Not found");return}const h=d.searchParams.get("code"),m=d.searchParams.get("error"),A={"Content-Type":"text/html",Connection:"close"};if(h)c.writeHead(200,A),c.end(On),i({success:!0,code:h});else{const F=m??d.searchParams.get("error_description")??"Unknown error";c.writeHead(200,A),c.end(kn(F)),i({success:!1,error:F})}});o.listen(0,"127.0.0.1",()=>{const u=o.address();if(!u||typeof u=="string"){s(new Error("Failed to start callback server"));return}const c=u.port;n({port:c,callbackUrl:`http://127.0.0.1:${c}/callback`,waitForCallback:()=>(a=setTimeout(()=>{i({success:!1,error:`Timed out waiting for authorization (${t/1e3}s)`})},t),r.finally(()=>{clearTimeout(a)})),close:()=>{clearTimeout(a),o.closeAllConnections(),o.close()}})}),o.on("error",s)})},Rn=e=>{try{new URL(e)}catch{return Promise.resolve(!1)}const[t,n]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];return new Promise(s=>{x.execFile(t,n,i=>{s(!i)})})},Ln=()=>{const e=Oe.default.randomBytes(32).toString("base64url"),t=Oe.default.createHash("sha256").update(e).digest("base64url");return{codeVerifier:e,codeChallenge:t}},Pn=async e=>{const{apiUrl:t,remote:n,timeoutMs:s}=e;n&&v.setActiveRemote(n);const i=new v,a=`${t}/.well-known/oauth-authorization-server`;let r;try{r=(await O.default.get(a)).data}catch{return{success:!1,error:{code:U.OAUTH_NOT_SUPPORTED,message:`Could not reach the OAuth discovery endpoint at ${a}. Ensure the server is running. Use --api-key instead.`}}}if(!r.cli_client_id)return{success:!1,error:{code:U.OAUTH_NOT_SUPPORTED,message:"Server does not expose a CLI client ID. Ensure the server is up to date. Use --api-key instead."}};const o=r.cli_client_id,{codeVerifier:u,codeChallenge:c}=Ln(),d=await Sn({timeoutMs:s});try{const h=new URL(r.authorization_endpoint);h.searchParams.set("clientId",o),h.searchParams.set("codeChallenge",c),h.searchParams.set("redirectUrl",d.callbackUrl),await Rn(h.toString())||console.log(`
|
|
169
|
-
Open this URL in your browser to authenticate:
|
|
170
|
-
${h.toString()}
|
|
171
|
-
`);const A=await d.waitForCallback();if(!A.success)return{success:!1,error:{code:U.AUTH_FAILED,message:A.error}};const F=await O.default.post(r.token_endpoint,{grant_type:"authorization_code",code:A.code,code_verifier:u,redirect_uri:d.callbackUrl,client_id:o}),{access_token:S,refresh_token:R}=F.data;return await i.setConfig({apiUrl:t,accessToken:S,refreshToken:R,oauthClientId:o}),(await new M({serverUrl:t,token:S}).validateAuth()).authValid?{success:!0,data:void 0}:(await i.clearConfig(),{success:!1,error:{code:U.AUTH_FAILED,message:"OAuth tokens received but authentication validation failed."}})}finally{d.close()}},xn=e=>k(()=>Pn(e),U.AUTH_FAILED),j="twenty-app-dev",Dn="twentycrm/twenty-app-dev:latest",ee=2020,Ze=()=>{try{return x.execSync(`docker inspect -f '{{.State.Running}}' ${j}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).trim()==="true"}catch{return!1}},ue=()=>{try{const t=x.execSync(`docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' ${j}`,{encoding:"utf-8",stdio:["pipe","pipe","ignore"]}).match(/^NODE_PORT=(\d+)$/m);return t?parseInt(t[1],10):ee}catch{return ee}},et=()=>{try{return x.execSync(`docker inspect ${j}`,{stdio:["pipe","pipe","ignore"]}),!0}catch{return!1}},Un=()=>{try{return x.execSync("docker info",{stdio:"ignore"}),!0}catch{return!1}},jn=2e3,Mn=180*1e3,Re="==> START ",$n="==> DONE",Le=async e=>{const t=Date.now(),n=u=>process.stdout.write(X.default.gray(u)),s=x.spawn("docker",["logs","-f","--since","1s",j],{stdio:["ignore","pipe","pipe"]});s.on("error",()=>{});let i=!1;const a=u=>{const c=u.trim(),d=c.indexOf(Re),h=c.indexOf($n);if(d!==-1){i&&n(`Done
|
|
172
|
-
`);const m=c.slice(d+Re.length);n(`==> ${m}... `),i=!0}else h!==-1&&i&&(n(`Done
|
|
173
|
-
`),i=!1)};let r="";const o=u=>{r+=u.toString();const c=r.split(`
|
|
174
|
-
`);r=c.pop()??"",c.forEach(a)};s.stdout?.on("data",o),s.stderr?.on("data",o);try{for(;Date.now()-t<Mn;){if(await ge(e))return i&&n(`Done
|
|
175
|
-
`),!0;await new Promise(u=>setTimeout(u,jn))}return i&&n(`Failed
|
|
176
|
-
`),!1}finally{s.kill()}},Bn=async(e={})=>{const{onProgress:t}=e,n=await Xe(e.port);if(n){const o=new v;v.setActiveRemote("local"),await o.setConfig({apiUrl:n});const u=new URL(n).port;return t?.(`Twenty server detected on ${n}`),{success:!0,data:{port:parseInt(u,10),url:n}}}if(!Un())return{success:!1,error:{code:V.DOCKER_NOT_RUNNING,message:"Docker is not running. Please start Docker and try again."}};if(Ze()){const o=ue();if(t?.("Container is running, waiting for it to become healthy..."),!await Le(o))return{success:!1,error:{code:V.HEALTH_TIMEOUT,message:`Twenty server did not become healthy in time.
|
|
177
|
-
Check: 'yarn twenty server logs'`}};const c=`http://localhost:${o}`,d=new v;return v.setActiveRemote("local"),await d.setConfig({apiUrl:c}),t?.(`Server running on ${c}`),{success:!0,data:{port:o,url:c}}}let s=e.port??ee;if(et()){const o=ue();o!==s&&t?.(`Existing container uses port ${o}. Run 'yarn twenty server reset' first to change ports.`),s=o,t?.("Starting existing container..."),x.execSync(`docker start ${j}`,{stdio:"ignore"})}else if(t?.("Starting Twenty container..."),x.spawnSync("docker",["run","-d","--name",j,"-p",`${s}:${s}`,"-e",`NODE_PORT=${s}`,"-e",`SERVER_URL=http://localhost:${s}`,"-v","twenty-app-dev-data:/data/postgres","-v","twenty-app-dev-storage:/app/packages/twenty-server/.local-storage",Dn],{stdio:"inherit"}).status!==0)return{success:!1,error:{code:V.CONTAINER_START_FAILED,message:"Failed to start Twenty container."}};if(t?.("Waiting for Twenty to be ready..."),!await Le(s))return{success:!1,error:{code:V.HEALTH_TIMEOUT,message:`Twenty server did not become healthy in time.
|
|
178
|
-
Check: 'yarn twenty server logs'`}};const a=`http://localhost:${s}`,r=new v;return v.setActiveRemote("local"),await r.setConfig({apiUrl:a}),t?.(`Server running on ${a}`),{success:!0,data:{port:s,url:a}}},Hn=e=>k(()=>Bn(e),V.CONTAINER_START_FAILED),qn=async e=>{e.remote&&v.setActiveRemote(e.remote);const t=new M,n=await se(e.appPath);if(!n)return{success:!1,error:{code:w.MANIFEST_NOT_FOUND,message:"Manifest not found. Run `build` or `dev` first."}};const s=await t.uninstallApplication(n.application.universalIdentifier);if(!s.success){const i=s.error instanceof Error?s.error.message:String(s.error??"Unknown error");return{success:!1,error:{code:w.UNINSTALL_FAILED,message:i}}}return{success:!0,data:void 0}},Vn=e=>k(()=>qn(e),w.UNINSTALL_FAILED);exports.APP_ERROR_CODES=w;exports.AUTH_ERROR_CODES=U;exports.ApiService=M;exports.CONTAINER_NAME=j;exports.ConfigService=v;exports.DEFAULT_PORT=ee;exports.FUNCTION_ERROR_CODES=G;exports.SERVER_ERROR_CODES=V;exports.appBuild=Ke;exports.appDeploy=gn;exports.appInstall=Tn;exports.appPublish=En;exports.appUninstall=Vn;exports.authLogin=Nn;exports.authLoginOAuth=xn;exports.buildAndValidateManifest=We;exports.checkServerHealth=ge;exports.containerExists=et;exports.copy=je;exports.createFrontComponentsWatcher=Ct;exports.createLogicFunctionsWatcher=Ot;exports.detectLocalServer=Xe;exports.emptyDir=Ue;exports.ensureDir=P;exports.functionExecute=An;exports.getContainerPort=ue;exports.isContainerRunning=Ze;exports.manifestUpdateChecksums=Je;exports.parseTscOutputLine=Be;exports.pathExists=ne;exports.readManifestFromFile=se;exports.remove=Q;exports.runSafe=k;exports.runTypecheck=me;exports.serverStart=Hn;exports.writeManifestToOutput=Ge;
|