UNPKG

@getcronit/pylon-dev

Version:

CLI for creating a Pylon

226 lines (191 loc) 30.2 kB
import{program as Y}from"commander";import K from"consola";import Ue from"dotenv";import B from"pm2";var se="2.0.0-canary-20251114081320.eebcc06b20e2b45fd9717fa0911912f568b21784";import{PostHog as ve}from"posthog-node";import Se from"conf";import{readFileSync as Pe}from"fs";import{randomUUID as re}from"crypto";var Fe={distinctId:{type:"string",default:re()}},xe=new Se({projectName:"pylon",schema:Fe}),O=xe.get("distinctId"),N=re(),C=new ve("phc_KN4qCOcCdkXp6sHLIuMWGRfzZWuNht69oqv5Kw5rGxj",{host:"https://eu.i.posthog.com",disabled:process.env.PYLON_DISABLE_TELEMETRY==="true"}),Ne=()=>{let o;try{o=JSON.parse(Pe("./package.json","utf8"))}catch{o={}}let s=o.dependencies||{},t=o.devDependencies||{},e=o.peerDependencies||{};return{dependencies:s,devDependencies:t,peerDependencies:e}},E=Ne(),V=async()=>{try{let s=(await import(`${process.cwd()}/.pylon/config.js`)).config,t=JSON.parse(JSON.stringify(s));return Object.keys(t).length===0?!1:t}catch{return!1}};import $e from"path";import{context as Ee}from"esbuild";import Ae from"esbuild-plugin-tsc";import $ from"path";import ue from"fs/promises";import U from"path";import Ce from"fs/promises";import oe from"fs/promises";async function F(o,s){try{if(await oe.readFile(o,"utf8")===s)return!1}catch(t){if(t.code!=="ENOENT")throw t}return await oe.writeFile(o,s,"utf8"),!0}var ae=({getBuildDefs:o,outputDir:s})=>({name:"inject-code",setup(t){t.onLoad({filter:/src[\/\\]index\.ts$/,namespace:"file"},async e=>{if(U.relative(process.cwd(),e.path)!==U.join("src","index.ts"))return;let{typeDefs:i,resolvers:a}=o(),n=ce(a),c=await Ce.readFile(e.path,"utf-8"),l=U.join(process.cwd(),s,"schema.graphql");await F(l,i);let p=U.join(process.cwd(),s,"resolvers.js");return await F(p,`export const resolvers = ${n}`),{loader:"ts",contents:`import {executeConfig} from "@getcronit/pylon" const __internalPylonConfig = await import(".pylon/config.js") await executeConfig(__internalPylonConfig.config) `+c+` import {handler as __internalPylonHandler} from "@getcronit/pylon" app.use(__internalPylonHandler({ typeDefs: ${JSON.stringify(i)}, graphql, resolvers: ${n}, })) await executeConfig(__internalPylonConfig.config, { pluginsStrategy: "last" }) `}})}});function ce(o){return`{${Object.entries(o).map(([t,e])=>{if(e!==void 0)return typeof e=="string"?`${t}:${e}`:typeof e=="function"?`${t}:${e.toString()}`:typeof e=="object"&&!Array.isArray(e)?`${t}:${ce(e)}`:`${t}:${JSON.stringify(e)}`}).join(",")}}`}import De from"path";import le from"fs/promises";import A from"consola";var pe=({dir:o,onBuild:s})=>({name:"notify",async setup(t){let e=async()=>{let a=De.join(o,"schema.graphql");try{await le.access(a)}catch{return null}return await le.readFile(a,"utf-8")},r=await e(),i=Date.now();t.onStart(async()=>{i=Date.now(),A.start("[Pylon]: Building...")}),t.onEnd(async a=>{if(a.errors.length>0){for(let u of a.errors)A.error(`[Pylon]: ${u.text} ${u.location?`at ${u.location.file}:${u.location.line}:${u.location.column}`:""} ${u.detail?u.detail:""}`);throw new Error("Failed to build Pylon")}if(a.warnings.length>0)for(let u of a.warnings)A.warn(u);let n=Date.now()-i,c=Object.keys(a.metafile.inputs).length,l=Object.values(a.metafile.outputs).reduce((u,g)=>u+g.bytes,0),p=await e();A.success(`[Pylon]: Built in ${n}ms`);let f=p!==r;f&&(A.info("[Pylon]: Schema updated"),r=p),s&&await s({totalFiles:c,totalSize:l,schemaChanged:f,duration:n})})}});import ke from"esbuild";import{readFileSync as Ie}from"fs";import{dirname as je,resolve as Oe}from"path";import D from"typescript";async function fe(o,s=".pylon/config.js"){let t=Oe(o),e=Ie(t,"utf8"),r=D.createSourceFile(t,e,D.ScriptTarget.ESNext,!0),i="",a=[];D.forEachChild(r,c=>{if(D.isImportDeclaration(c)){let l=c.getFullText(r).trim();a.push(l)}if(D.isVariableStatement(c)&&c.declarationList.declarations.length>0){let l=c.declarationList.declarations[0];D.isIdentifier(l.name)&&l.name.text==="config"&&l.initializer&&(i=`export const config = ${l.initializer.getText(r)}`)}}),i||(i="export const config = {}");let n=[...a,i].join(` `);await ke.build({stdin:{contents:n,resolveDir:je(t),sourcefile:t,loader:"ts"},bundle:!0,format:"esm",outfile:s,packages:"external"})}var M=class{sfiFilePath;outputDir;constructor(s,t="./.pylon"){this.sfiFilePath=s,this.outputDir=t}async initBuildPlugins(s){let t=$.join(process.cwd(),this.outputDir,"config.js");await fe(this.sfiFilePath,t);let e;try{e=(await import(t)).config}catch(a){console.error("Error loading config",a)}let r=[],i=e?.plugins||[];for(let a of i)if(a.build){let n=a.build({onBuild:s.onBuild});r.push(n)}return r}async build(s){let t=$.join(process.cwd(),this.sfiFilePath),e=$.join(process.cwd(),this.outputDir);await ue.mkdir(e,{recursive:!0});let r={name:"write-on-end",setup(n){n.onEnd(async c=>{await Promise.all(c.outputFiles.map(async l=>{await ue.mkdir($.dirname(l.path),{recursive:!0}),await F(l.path,l.text)}))})}},i=await Ee({write:!1,platform:"node",logLevel:"silent",metafile:!0,entryPoints:[t],outdir:e,bundle:!0,format:"esm",sourcemap:"inline",packages:"external",plugins:[pe({dir:e,onBuild:async n=>{await s.onBuild?.(n)}}),ae({getBuildDefs:s.getBuildDefs,outputDir:this.outputDir}),Ae({tsconfigPath:$.join(process.cwd(),"tsconfig.json")}),r]});s.skipInitialBuild||await i.rebuild();let a=await this.initBuildPlugins({onBuild:()=>{s.onBuild?.({totalFiles:0,totalSize:0,schemaChanged:!1,duration:0})}});if(!s.skipInitialBuild)for(let n of a)await(await n).rebuild();return{watch:async()=>{for(let n of a)await(await n).watch();return await i.watch()},rebuild:async()=>{for(let n of a)await(await n).rebuild();await i.rebuild()},dispose:async()=>{for(let n of a)await(await n).dispose();await i.dispose()},cancel:async()=>{for(let n of a)await(await n).cancel();await i.cancel()}}}};import v from"typescript";import S from"typescript";import d from"typescript";var me=o=>o.flags&d.TypeFlags.Object&&o.getProperties().length===0&&o.getCallSignatures().length===0,x=(o,s)=>{let t=o.typeToTypeNode(s,void 0,void 0),e=!!(t&&(t.kind===d.SyntaxKind.ArrayType||t.kind===d.SyntaxKind.TupleType));return!e&&s.getSymbol()?.getName()==="Array"?!0:e};var b=o=>o.flags&d.TypeFlags.String||o.flags&d.TypeFlags.Number||o.flags&d.TypeFlags.Boolean||o.flags&d.TypeFlags.StringLiteral||o.flags&d.TypeFlags.NumberLiteral||o.flags&d.TypeFlags.BooleanLiteral,q=o=>o.getCallSignatures().length>0,k=o=>b(o)?!1:!!(o.types?.length>1&&o.types.every(e=>e.flags&d.TypeFlags.StringLiteral||e.flags&d.TypeFlags.NumberLiteral||e.flags&d.TypeFlags.BooleanLiteral)),R=o=>o.getSymbol()?.getName()==="Promise",_=o=>{if(o.objectFlags&d.ObjectFlags.Reference){let e=o.typeArguments;if(e&&e.length>0)return e[0]}},de=o=>{if(!o.isUnion())return{type:o,wasOptional:!1};let t=o.types.filter(e=>!(e.flags&d.TypeFlags.Undefined||e.flags&d.TypeFlags.Null)).length!==o.types.length;return{type:o.getNonNullableType(),wasOptional:t}};function ye(o,s){let t=s;if(t.isUnion()){let i=t.types.filter(c=>!(c.flags&d.TypeFlags.Object&&c.objectFlags&d.ObjectFlags.Reference&&c.typeArguments?.length)),a=t.types.filter(c=>c.flags&d.TypeFlags.Object&&c.objectFlags&d.ObjectFlags.Reference&&c.typeArguments?.length).map(c=>c.typeArguments[0]),n=i.filter(c=>!a.some(l=>l===c));t=o.getUnionType(n)}let e=[];if(x(o,t)||b(t)||k(t))return e;let r=[];r=t.resolvedProperties||t.getProperties()||[];for(let i of r)(i.valueDeclaration&&!(d.getCombinedModifierFlags(i.valueDeclaration)&d.ModifierFlags.Private)&&!i.getName().startsWith("#"))!==!1&&e.push(i);return e}var I=o=>o.replace(/[^0-9a-zA-Z_]/g,"_"),Q=o=>!!o.getSymbol()?.getDeclarations()?.some(s=>s.getSourceFile().fileName.includes("@repeaterjs"));import w from"typescript";var z=class{checker;schema;typesNameMap=new Map;inputsNameMap=new Map;unions=[];enums=[];constructor(s,t){this.checker=s,this.schema=t}getTypeDefinition=(s,t={isInputType:!1})=>{let{type:e,wasOptional:r}=de(s);if(e.flags&w.TypeFlags.Void||e.flags&w.TypeFlags.Undefined||e.flags&w.TypeFlags.Null)return{name:"Void",isList:!1,isRequired:!1};if(Q(e)){let l=this.checker.getTypeArguments(e)[0];if(l)return this.getTypeDefinition(l,t)}if(R(e)){let l=_(e);if(l)return this.getTypeDefinition(l,t)}let i=t.isRequired!==void 0?t.isRequired:!r;if(me(e))return{name:"Object",isList:!1,isRequired:i};let a=t.isInputType?this.inputsNameMap:this.typesNameMap;if(a.has(e))return{name:a.get(e),isList:!1,isRequired:i};let n=e.aliasSymbol?.escapedName?.toString()||e.symbol?.escapedName.toString();(n==="__type"||n==="__object")&&(t.propertyName?n=t.propertyName.charAt(0).toUpperCase()+t.propertyName.slice(1):n=void 0),n&&(n=I(n));let c=l=>Array.from(a.values()).includes(l);if(n&&!this.schema.scalars.includes(n)){t.isInputType&&(n=`${n}Input`);let l=1,p=n;for(;c(n);)n=`${p}_${l}`,l++}if(n&&this.schema.scalars.includes(n))return{name:n,isList:!1,isRequired:i};if(x(this.checker,e)){let l=this.checker.getIndexTypeOfType(e,w.IndexKind.Number);if(l){let p=this.getTypeDefinition(l,t);return{name:p.name,isList:!0,isRequired:p.isRequired,isListRequired:i}}}else if(k(e)){let l=this.checker.typeToTypeNode(e,void 0,void 0),f=e.types.map(u=>{if(u.isLiteral()){let g=u.value?.toString();if(!g)throw new Error("Enum member name is undefined");return I(g)}throw new Error("Invalid type for enum member")});f.length>0&&(n=n||l.typeName?.symbol?.escapedName,n||(n=f.join("_").toUpperCase(),n=t.isInputType?`${n}Input`:n),this.enums.push({name:n,values:f,rawType:e}))}else if(b(e)){let l=this.checker.typeToString(e);return e.flags&w.TypeFlags.StringLiteral?l="String":e.flags&w.TypeFlags.NumberLiteral?l="Number":e.flags&w.TypeFlags.BooleanLiteral?l="Boolean":e.flags&w.TypeFlags.String?l="String":e.flags&w.TypeFlags.Number?l="Number":e.flags&w.TypeFlags.Boolean&&(l="Boolean"),{name:I(l),isList:!1,isRequired:i}}else if(e.isIntersection()){let p=e.types.map(f=>this.getTypeDefinition(f,t).name);n=I(n||p.join("And"))}else if(e.isUnion()){let l=e.types,p=e.types.length===l.length,f=l.some(m=>{let h=x(this.checker,m)?this.checker.getIndexTypeOfType(m,w.IndexKind.Number):m;return h?b(h)||k(h):!0}),u=[...new Set(l.map(m=>this.getTypeDefinition(m,{...t,isRequired:p})))],g=u.filter(m=>m.isList);for(let m of g){let h=u.findIndex(T=>T.name===m.name&&!T.isList);h>-1&&u.splice(h,1)}let y=u.map(m=>m.name);if(n=I(n||y.join("Or")),n){let m=1,h=n;for(;c(n);)n=`${h}_${m}`,m++}if(u.length>1&&!t.isInputType&&!f)this.unions.push({name:n,types:y,rawType:e});else{let m=u[0];if(!m)throw new Error("Cannot get type definition");let h=u.some(T=>T.isList&&T.name===m.name);return{name:m.name,isList:h,isRequired:i}}}else if(q(e)){let p=e.getCallSignatures()[0]?.getReturnType();if(p&&R(p)){let f=_(p);f&&(p=f)}if(p)return this.getTypeDefinition(p,t)}return n||(n="Any"),a.set(e,n),{name:n,isList:!1,isRequired:i}};getUnions(){return this.unions}getEnums(){return this.enums}typeDefinitionToGraphQLType=s=>{let t=s.name,{isList:e,isRequired:r,isListRequired:i}=s;return r&&(t=`${t}!`),e&&(t=`[${t}]`,i&&(t=`${t}!`)),t}};import Z from"consola";var H=class{schema;checker;program;sfiFile;typeDefinitionBuilder;constructor(s,t,e){this.schema={types:[],inputs:[],interfaces:[],unions:[],enums:[],scalars:["ID","Int","Float","Number","Any","Void","Object","File","Date","JSON","String","Boolean"]},this.checker=s,this.sfiFile=t,this.program=e,this.typeDefinitionBuilder=new z(s,this.schema)}parse(s){let t=this.makeReferenceSchema(s);for(let[e,r]of t.types){let i;s.Query===e?i="Query":s.Mutation===e?i="Mutation":s.Subscription===e&&(i="Subscription"),this.processSchemaReference(e,r,i,"types")}for(let[e,r]of t.inputs)this.processSchemaReference(e,r,void 0,"inputs");this.extractForbiddenFieldNamesFromSchema(),this.schema.unions=this.typeDefinitionBuilder.getUnions().map(e=>({...e,description:this.getTypeDocumentation(e.rawType)})),this.schema.enums=this.typeDefinitionBuilder.getEnums().map(e=>({...e,description:this.getTypeDocumentation(e.rawType)})),this.schema.types=this.schema.types.filter(e=>!this.schema.enums.find(r=>r.name===e.name)),this.schema.inputs=this.schema.inputs.filter(e=>!this.schema.enums.find(r=>r.name===e.name)),this.schema.unions.forEach(e=>{let r=this.checkIfInterfaceIsPossibleForUnion(e,this.schema.types);r&&(this.schema.interfaces.push(r),this.schema.unions=this.schema.unions.filter(i=>i.name!==e.name),this.schema.types.map(i=>{if(e.types.includes(i.name))return i.implements||(i.implements=[]),i.implements.push(r.name),i}))});for(let[e,r]of t.classImplementsMap){this.schema.types.map(i=>{let a=this.schema.types.find(n=>n.rawType===e);return a&&(a.implements=Array.from(new Set([...a.implements||[],...r.map(n=>this.checker.typeToString(n))]))),i});for(let i of r){let a=this.schema.types.find(n=>n.rawType===i);a&&(this.schema.interfaces.push({name:this.checker.typeToString(i),description:this.getTypeDocumentation(i),fields:a.fields}),this.schema.types=this.schema.types.filter(n=>n.rawType!==i))}}this.schema.types=this.schema.types.map(e=>((e.implements||this.schema.unions.find(r=>r.types.includes(e.name)))&&(e.fields=e.fields.filter(r=>r.type.name!=="Void")),e)),this.schema.unions=this.schema.unions.map(e=>({...e,__resolveType:this.getResolveTypeForUnionOrInterface(e,this.schema.types)})),this.schema.interfaces=this.schema.interfaces.map(e=>({...e,__resolveType:this.getResolveTypeForUnionOrInterface(e,this.schema.types)}))}checkIfInterfaceIsPossibleForUnion(s,t){let e=s.types.map(a=>{let n=t.find(c=>c.name===a);if(!n)throw new Error(`Type ${a} not found`);return n}),i=e[0].fields.filter(a=>e.every(n=>n.fields.some(c=>JSON.stringify(c)===JSON.stringify(a))));return i.length>0?{name:s.name,description:s.description,fields:i}:null}getResolveTypeForUnionOrInterface(s,t){let e="types"in s?t.filter(n=>s.types.includes(n.name)):t.filter(n=>n.implements?.includes(s.name));e.sort((n,c)=>c.fields.length-n.fields.length);let r=new Map;e.forEach(n=>{let c=n.fields.map(l=>l.name).sort().join(", ");if(r.has(c)){let l=r.get(c);Z.warn(`Warning: Union types "${n.name}" and "${l?.name}" have the same fields: [${c}]. Consider differentiating these types by adding unique fields or using different type names. This may cause ambiguity in type resolution.`)}else r.set(c,n)});let a=`function resolveType(node) { if (node && typeof node === 'object') { ${e.map(n=>`if (${n.fields.map(p=>`"${p.name}" in node`).join(" && ")}) {return '${n.name}'};`).join(" ")} } }`;return new Function("return "+a)()}toString(){let{typeDefinitionToGraphQLType:s}=this.typeDefinitionBuilder,t=r=>r?`""" ${r} """ `:"",e="";for(let r of this.schema.inputs){e+=t(r.description),e+=`input ${r.name} { `,r.fields.length===0&&(e+=` _ : String `);for(let i of r.fields)e+=`${t(i.type.description)}`,e+=` ${i.name}: ${s(i.type)} `;e+=`} `}for(let r of this.schema.types)if(r.fields.length!==0){e+=t(r.description),e+=`type ${r.name}`,r.implements&&(e+=` implements ${r.implements.join(" & ")}`),e+=` { `;for(let i of r.fields){let a="";i.args.length>0&&(a=`(${i.args.map(n=>`${t(n.type.description)}${n.name}: ${s(n.type)}`).join(", ")})`),e+=`${t(i.type.description)}`,e+=`${i.name}${a}: ${s(i.type)} `}e+=`} `}for(let r of this.schema.unions)e+=t(r.description),e+=`union ${r.name} = ${r.types.join(" | ")} `;for(let r of this.schema.interfaces){e+=t(r.description),e+=`interface ${r.name} { `;for(let i of r.fields)e+=`${t(i.type.description)}`,e+=`${i.name}: ${s(i.type)} `;e+=`} `}for(let r of this.schema.scalars)e+=`scalar ${r} `;for(let r of this.schema.enums){e+=t(r.description),e+=`enum ${r.name} { `;for(let i of r.values)e+=` ${i} `;e+=`} `}return e}getSchema(){return this.schema}getResolvers(){let s={};for(let t of this.schema.unions)s[t.name]={__resolveType:t.__resolveType};for(let t of this.schema.interfaces)s[t.name]={__resolveType:t.__resolveType};return s}processSchemaReference(s,t,e,r="types"){let{getTypeDefinition:i}=this.typeDefinitionBuilder,a=r==="inputs",n=i(s,{isInputType:a}),c=e||n.name,l=this.schema[r].find(p=>p.name===c);if(!l){if(this.schema.scalars.includes(c))return;this.schema[r].push({name:c,description:this.getTypeDocumentation(s),fields:[],rawType:x(this.checker,s)&&(s.getNumberIndexType()||s.getStringIndexType())||s}),l=this.schema[r][this.schema[r].length-1]}for(let[p,f]of Object.entries(t)){let u=f.returnType,g=i(u,{isInputType:a,propertyName:p});if(r==="types"){let y={name:p,type:{...g,description:this.getSymbolDocumentation(f.symbol)},args:[]};if(f.args)for(let[m,h]of Object.entries(f.args)){let T=h,P=i(T.type,{isInputType:!0,propertyName:m,isRequired:h.isRequired});this.schema.scalars.includes(this.checker.typeToString(T.type))&&(P.name=this.checker.typeToString(T.type)),y.args.push({name:m,type:{...P,description:T.documentation}})}l.fields.push(y)}else if(r==="inputs"){let y={name:p,type:{...g,description:this.getTypeDocumentation(u)}};l.fields.find(m=>m.name===y.name)||l.fields.push(y)}}}getSymbolDocumentation(s){let t="";t+=S.displayPartsToString(s.getDocumentationComment(this.checker));let e=s.getJsDocTags(this.checker).map(r=>`@${r.name} ${S.displayPartsToString(r.text)}`).join(` `);return e&&(t+=` `+e),t}getTypeDocumentation=s=>{let t=s.getSymbol();return t?this.getSymbolDocumentation(t):""};extractForbiddenFieldNamesFromSchema(){let s=/^[_A-Za-z][_0-9A-Za-z]*$/,t=e=>s.test(e)?e.startsWith("__"):!0;for(let e of this.schema.types)e.fields=e.fields.filter(r=>!t(r.name));for(let e of this.schema.inputs)e.fields=e.fields.filter(r=>!t(r.name))}makeReferenceSchema(s){let t={types:new Map,inputs:new Map,classImplementsMap:new Map},e=(i,a={},n="types",c=[])=>{if(t[n].has(i))return;if(Q(i)){let p=this.checker.getTypeArguments(i)[0];e(p,a,n,[...c,"REPEATER_ITEM"]);return}if(this.checker.typeToString(i)!=="[]"&&!this.schema.scalars.includes(this.checker.typeToString(i))&&!b(i)){if(R(i)){if(n==="inputs")return;let p=_(i);p&&e(p,a,n,[...c,"PROMISE"]);return}if(i.isClass()){let p=i.getBaseTypes();p&&p.forEach(f=>{t.classImplementsMap.has(f)||t.classImplementsMap.set(f,[]),t.classImplementsMap.get(f).push(i)})}if(i.isUnion())if(k(i))t[n].has(i)||t[n].set(i,{}),e(i,a,n,[...c,"ENUM"]);else if(n==="types")i.types.forEach(p=>{p.flags&S.TypeFlags.Null||p.flags&S.TypeFlags.Undefined||b(p)||e(p,a,n,[...c,p.symbol?.getName()||`N/A ${this.checker.typeToString(p)}`])});else{let p=i.getNonNullableType();p.isUnion()&&!b(p)&&(Z.warn(`Warning: Union types in input fields are not supported yet. Defaulting to the first type (${this.checker.typeToString(p)}) at path: ${c.join(" > ")}`),p=p.types[0]),e(p,a,n,[...c,"NON_NULLABLE"])}else if(q(i)){if(n==="inputs")return;if(!a.parentType)throw new Error("Cannot have a function without a parent type");let p=i.getCallSignatures()[0],f=p?.getParameters()||[],u=p?.getReturnType(),g=t[n].get(a.parentType)[a.propetyName];f.forEach(y=>{let m=this.checker.getTypeOfSymbolAtLocation(y,this.sfiFile);if(this.checker.isTupleType(m))m.target.labeledElementDeclarations.forEach((P,Qe)=>{let ie=this.checker.getTypeAtLocation(P),ne=P.name.text,Te=this.checker.getSymbolAtLocation(P),be=this.getSymbolDocumentation(Te||y);g.args[ne]={type:ie,isRequired:P.initializer===void 0?void 0:!1,documentation:be},e(ie,{parentType:i},"inputs",[...c,ne])});else if(y.valueDeclaration&&S.isParameter(y.valueDeclaration)&&y.valueDeclaration.dotDotDotToken)Z.warn(`Warning: Rest parameters without explicit names are not supported. Skipping rest parameter at path: ${c.join(" > ")}. Unsupported: \`function example(...args: any[]) { }\`. Supported: \`function example(...namedArgs: [first: string, second: number]) { }\`. Please provide named rest parameters to ensure proper type resolution.`);else{let h=y.valueDeclaration;g.args&&(g.args[y.escapedName]={type:m,isRequired:h.initializer===void 0?void 0:!1,documentation:this.getSymbolDocumentation(y)},e(m,{parentType:i},"inputs",[...c,y.escapedName]))}}),u&&e(u,a,n,[...c,"RETURN_TYPE"])}else if(x(this.checker,i)){let p=this.checker.getIndexTypeOfType(i,S.IndexKind.Number);p&&!b(p)&&(t[n].has(i)||t[n].set(i,{}),e(p,a,n,[...c,"ITEM_TYPE"]))}else if(!b(i)){let p=ye(this.checker,i);t[n].has(i)||t[n].set(i,{}),p.forEach(f=>{let u=this.checker.getTypeOfSymbolAtLocation(f,this.sfiFile);t[n].get(i)[f.escapedName]||(t[n].get(i)[f.escapedName]={symbol:f,returnType:u,args:{}}),e(u,{propetyName:f.escapedName,parentType:i},n,[...c,f.escapedName])})}}};s.Query&&e(s.Query),s.Mutation&&e(s.Mutation),s.Subscription&&e(s.Subscription);let r=this.program.getSourceFiles();for(let i of r)S.forEachChild(i,a=>{if(S.isClassDeclaration(a)){let n=a.heritageClauses?.flatMap(c=>c.types.map(l=>l))||[];if(n.length>0)for(let c of n)t.types.has(this.checker.getTypeAtLocation(c))&&(t.classImplementsMap.set(this.checker.getTypeAtLocation(a),[this.checker.getTypeAtLocation(c)]),e(this.checker.getTypeAtLocation(a)))}});return t}};import j from"path";var G=class{program;checker;sfiFile;sfi;sfiFilePath;constructor(s){this.sfiFilePath=s;let t=this.loadTsConfigOptions(),e=v.sys.readDirectory(j.dirname(this.sfiFilePath),[".ts"],[".d.ts"]).concat([j.join(j.dirname(this.sfiFilePath),"..","pylon.d.ts")]);this.program=v.createProgram(e,t),this.checker=this.program.getTypeChecker(),this.loadSfi()}loadSfi(){let t=this.program.getSourceFiles().find(a=>j.resolve(a.fileName)===this.sfiFilePath);if(!t)throw new Error("Could not find index.ts (pylon entrypoint)");this.sfiFile=t;let e=this.checker.getSymbolAtLocation(t),i=this.checker.getExportsOfModule(e).find(a=>a.escapedName==="graphql");if(!i)throw new Error("Could not find graphql export");this.sfi=i}loadTsConfigOptions(){let s={target:v.ScriptTarget.ESNext,module:v.ModuleKind.CommonJS,strict:!0,esModuleInterop:!0,skipLibCheck:!1,forceConsistentCasingInFileNames:!0,noImplicitAny:!0,experimentalDecorators:!0},t=v.findConfigFile(j.dirname(this.sfiFilePath),v.sys.fileExists,"tsconfig.json");if(!t)return console.log("Could not find tsconfig.json"),s;let e=v.readConfigFile(t,v.sys.readFile);return e.error?(console.log("Could not read tsconfig.json",e.error),s):v.parseJsonConfigFileContent(e.config,v.sys,j.dirname(t)).options}build(){let s=this.checker.getTypeOfSymbolAtLocation(this.sfi,this.sfiFile),t=s.getProperty("Query"),e=s.getProperty("Mutation"),r=s.getProperty("Subscription"),i=t?this.checker.getTypeOfSymbolAtLocation(t,this.sfiFile):void 0,a=e?this.checker.getTypeOfSymbolAtLocation(e,this.sfiFile):void 0,n=r?this.checker.getTypeOfSymbolAtLocation(r,this.sfiFile):void 0,c=new H(this.checker,this.sfiFile,this.program);return c.parse({Query:i,Mutation:a,Subscription:n}),{typeDefs:c.toString(),schema:c.getSchema(),resolvers:c.getResolvers()}}};var X=async o=>await new M(o.sfiFilePath,o.outputFilePath).build({getBuildDefs:()=>{let e=new G($e.join(process.cwd(),o.sfiFilePath)).build();return{typeDefs:e.typeDefs,resolvers:e.resolvers}},onBuild:o.onBuild,skipInitialBuild:o.skipInitialBuild});import W from"path";import J from"fs/promises";import{generateClient as Re}from"@gqty/cli";import _e from"esbuild";import{buildSchema as Le}from"graphql";var he=W.join(process.cwd(),".pylon/schema.graphql"),L=W.join(process.cwd(),".pylon/client/index.ts"),ee=async({schemaChanged:o})=>{try{await J.access(he)}catch{throw new Error("Schema not found. Please run `pylon build` or `pylon dev` first.")}if(!o)try{await J.access(L);return}catch{}let s=await J.readFile(he,"utf-8"),t=Le(s);await J.mkdir(W.dirname(L),{recursive:!0}),await F(L,Be),await Re(t,{endpoint:"will-be-overwritten",frameworks:["react"],destination:L,react:!0,scalarTypes:{Number:"number",Object:"Record<string, unknown>"}}),await _e.build({entryPoints:[L],bundle:!0,outfile:W.join(process.cwd(),".pylon/client/index.js"),packages:"external",format:"esm",platform:"node"})},Be=`/** * GQty: You can safely modify this file based on your needs. */ import {createReactClient} from '@gqty/react' import { Cache, createClient, defaultResponseHandler, type QueryFetcher } from 'gqty' import { generatedSchema, scalarsEnumsHash, type GeneratedSchema } from './schema.generated' const queryFetcher: QueryFetcher = async function ( {query, variables, operationName}, fetchOptions ) { const headers = new Headers({}); let fetchToUse: typeof fetch | typeof app.request = fetch try { // 1. Try importing Pylon \u2014 if this works, we're on the server const moduleNameToPreventBundling = '@getcronit/pylon' const { app, getContext } = await import(moduleNameToPreventBundling) fetchToUse = app.request // 2. Get headers from the original server request and forward them const context = getContext() for (const [key, value] of context.req.raw.headers.entries()) { headers.append(key, value) } } catch { // 3. Pylon not available \u2014 fallback to default fetch (runs in browser) // No additional headers are needed; browser sends cookies automatically } const formData = buildGraphQLMultipartForm(query, variables); const response = await fetchToUse('/graphql', { method: 'POST', headers, body: formData, mode: 'cors', ...fetchOptions }) return await defaultResponseHandler(response) } function buildGraphQLMultipartForm(query, variables) { const form = new FormData(); const operations = { query, variables: structuredClone(variables) }; const map = {}; const files = []; let fileIndex = 0; // Helper to find all files in variables function recurse(value, path = []) { if (value instanceof File || value instanceof Blob) { map[fileIndex] = [\`variables.\${path.join(".")}\`]; set(operations.variables, path, null); files.push({ index: fileIndex, file: value }); fileIndex++; } else if (Array.isArray(value)) { value.forEach((item, i) => recurse(item, [...path, i])); } else if (value && typeof value === "object") { Object.entries(value).forEach(([key, val]) => recurse(val, [...path, key]) ); } } recurse(variables); form.append("operations", JSON.stringify(operations)); form.append("map", JSON.stringify(map)); files.forEach(({ index, file }) => { form.append(index, file); }); return form; } // Utility to set a value at a path inside an object function set(obj, path, value) { let curr = obj; for (let i = 0; i < path.length - 1; i++) { curr = curr[path[i]]; } curr[path[path.length - 1]] = value; } export const cache = new Cache( undefined, /** * Default option is immediate cache expiry but keep it for 5 minutes, * allowing soft refetches in background. */ { maxAge: Infinity, staleWhileRevalidate: 5 * 60 * 1000, normalization: true } ) export const client = createClient<GeneratedSchema>({ schema: generatedSchema, scalars: scalarsEnumsHash, cache, fetchOptions: { fetcher: queryFetcher } }) export const pageClient = () => { const client = createClient<GeneratedSchema>({ schema: generatedSchema, scalars: scalarsEnumsHash, cache: new Cache( undefined, { maxAge: Infinity, staleWhileRevalidate: 5 * 60 * 1000, normalization: true } ), fetchOptions: { fetcher: queryFetcher } }) const react = createReactClient(client) return {useQuery: react.useQuery, useHydrateCache: react.useHydrateCache} } // Core functions export const {resolve, subscribe, schema} = client // Legacy functions export const {query, mutation, mutate, subscription, resolved, refetch, track} = client export const { graphql, useQuery, usePaginatedQuery, useTransactionQuery, useLazyQuery, useRefetch, useMutation, useMetaState, prepareReactRender, useHydrateCache, prepareQuery } = createReactClient<GeneratedSchema>(client, { defaults: { // Enable Suspense, you can override this option for each hook. suspense: false } }) export * from './schema.generated'`;var ge=`pylon-dev-${N}`;Ue.config();Y.name("pylon-dev").description("Pylon Development CLI").version(se);Y.command("build").description("Build the Pylon Schema").action(async()=>{let o=await X({sfiFilePath:"./src/index.ts",outputFilePath:"./.pylon",onBuild:async({totalFiles:s,totalSize:t,duration:e,schemaChanged:r})=>{C.capture({distinctId:O,event:"build completed",properties:{duration:e,totalFiles:s,totalSize:t,schemaChanged:r,dependencies:E,isDevelopment:!1,$session_id:N}}),await ee({schemaChanged:r})}});await o.rebuild(),await o.dispose()});Y.command("dev").description("Start the Pylon Development Server").option("-c, --command <command>","Command to run the server","bun run .pylon/index.js").action(async o=>{await new Promise(async(s,t)=>{try{await Me();let e=await X({sfiFilePath:"./src/index.ts",outputFilePath:"./.pylon",onBuild:async({schemaChanged:r,totalFiles:i,totalSize:a,duration:n})=>{await ee({schemaChanged:r}),C.capture({distinctId:O,event:"build completed",properties:{duration:n,totalFiles:i,totalSize:a,schemaChanged:r,dependencies:E,pylonConfig:await V(),isDevelopment:!0,$session_id:N}})},skipInitialBuild:!0});await e.watch(),await qe(o.command),K.box(`Pylon is up and running! Press \`Ctrl + C\` to stop the server. Encounter any issues? Report them here: https://github.com/getcronit/pylon/issues We value your feedback\u2014help us make Pylon even better!`),process.on("SIGINT",async()=>{await e.cancel(),await te(),s()}),process.on("SIGTERM",async()=>{await e.cancel(),await te(),s()}),C.capture({distinctId:O,event:"dev server started",properties:{command:o.command,dependencies:E,pylonConfig:await V(),$session_id:N}})}catch(e){await te(),t(e)}})});var Me=()=>new Promise((o,s)=>{B.connect(t=>{t?s(t):o()})}),qe=o=>new Promise((s,t)=>{B.launchBus((e,r)=>{e&&t(e),r.on("log:out",i=>{K.log(i.data.trim())}),r.on("log:err",i=>{K.error(i.data)})}),B.start({name:ge,script:o,exec_mode:"fork",instances:1,autorestart:!0,watch:["./.pylon"],restart_delay:5e3,watch_delay:1e3,ignore_watch:["node_modules"],env:{...process.env,NODE_ENV:"development"}},function(e,r){e?t(e):s()})}),te=async()=>{try{await new Promise((o,s)=>{B.delete(ge,function(t){t?s(t):o()})})}catch{}finally{B.disconnect()}};try{await Y.parseAsync(process.argv)}catch(o){K.error(o),C.captureException(o,O,{$session_id:N,dependencies:E})}finally{await C.shutdown()} //# sourceMappingURL=index.js.map