typebulb 0.5.0 → 0.5.1
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/index.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -367,9 +367,9 @@ ${u(t)}
|
|
|
367
367
|
`),t=s.indexOf(`
|
|
368
368
|
|
|
369
369
|
`);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function rt(s){let t=s.split(/\r?\n/).filter(n=>n.startsWith("data:"));if(!t.length)return null;let r=t.map(n=>n.replace(/^data:\s?/,"")).join(`
|
|
370
|
-
`).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Vt(s,e,t){let r=new TextDecoder,n="",i=!1,o=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=o?await Promise.race([s.read(),o]):await s.read(),{done:c,value:d}=a;if(c){if(n.trim()){let h=rt(n);h!==null&&h!=="done"&&e(h)}break}i=!0,n+=r.decode(d,{stream:!0});let{pos:u,len:f}=Wt(n);for(;u!==-1;){let h=n.slice(0,u);n=n.slice(u+f);let p=rt(h);if(p==="done"){n="";break}p!==null&&e(p),{pos:u,len:f}=Wt(n)}}return{receivedAnyData:i}}async function nt(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=V(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await Vt(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as st from"fs/promises";import*as Pe from"path";var Oe=class{async get(e){let t=k(e),r=Pe.join(ye,t+".bin"),n=Pe.join(ye,t+".json");try{let[i,o]=await Promise.all([st.readFile(r),st.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await v();let r=k(e),n=Pe.join(ye,r+".bin"),i=Pe.join(ye,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([P(n,t.body),P(i,JSON.stringify(o))])}};async function Gt(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i}=s,o=new $r;o.use("*",async(p,l)=>{await l(),p.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),p.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),o.get("/",p=>p.html(e())),o.post("/__fs/read",async p=>{try{let{path:l}=await p.req.json(),m=Ht(l,t),w=await ee.readFile(m,"utf-8");return p.json({content:w})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},400)}}),o.post("/__fs/write",async p=>{try{let{path:l,content:m}=await p.req.json(),w=Ht(l,t);return await ee.mkdir(J.dirname(w),{recursive:!0}),await ee.writeFile(w,m,"utf-8"),p.json({success:!0})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},400)}});let a={log:console.log};o.post("/__api/:name",async p=>{try{let l=i?.(),m=p.req.param("name"),w=l?.[m]??a[m];if(!w||typeof w!="function")return p.json({error:`API function '${m}' not found`},404);let{args:y}=await p.req.json(),A=await w(...y||[]);return p.json({result:A})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},500)}}),o.post("/__ai",async p=>{try{let{messages:l,system:m,reasoning:w,provider:y,model:A,webSearch:$}=await p.req.json();if(!l||!Array.isArray(l)||l.length===0)return p.json({message:"messages array is required",code:"unknown",retryable:!1},400);let _=Lr(y,A);if(typeof _=="string")return p.json({message:_,code:"unknown",retryable:!1},400);let re=[...m?[{role:"system",content:m}]:[],...l.map(O=>({role:O.role,content:O.content}))],U=await et(_,{model:_.model,messages:re,stream:!0,reasoning:w??0,webSearch:$??!0});if(!U.ok){let O=await tt(U,_.protocol);return p.json(O,U.status)}let Se=await nt(U,_.protocol);return Se||console.warn("[tb.ai] Empty response from provider"),p.json({text:Se})}catch(l){if(l instanceof S)return p.json({message:l.message,code:l.code,retryable:l.retryable},500);let m=l instanceof Error?l.message:"Unknown error";return p.json({message:m,code:"unknown",retryable:!1},500)}}),o.get("/__models",async p=>{try{let l=await Jr();return p.json(l)}catch{return p.json([],200)}});let c=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],d=new Oe;o.get("/proxy/*",async p=>{let l=new URL(p.req.url),w=(l.pathname+l.search).slice(7),y=w.lastIndexOf("https://");return y===-1?p.text("Invalid proxy URL",400):u(p,w.slice(y))});async function u(p,l){let m;try{m=new URL(l)}catch{return p.text("Invalid URL",400)}if(m.protocol!=="https:")return p.text("HTTPS only",400);if(!c.includes(m.hostname))return p.text("Host not allowed",403);let w=await d.get(l);if(w)return new Response(w.body,{status:200,headers:it(w.contentType,w.cacheControl)});try{let y=await fetch(l,{headers:{Accept:p.req.header("Accept")||"*/*"},redirect:"follow"});if(!y.ok)return p.text(`Upstream ${y.status}`,y.status);let A=y.headers.get("Content-Type")||void 0,$=y.headers.get("Cache-Control")||void 0;if(y.body){let[_,re]=y.body.tee();return(async()=>{try{let U=await new Response(re).arrayBuffer();await d.set(l,{body:Buffer.from(U),contentType:A,cacheControl:$})}catch{}})(),new Response(_,{status:y.status,headers:it(A,$)})}return new Response(null,{status:y.status,headers:it(A,$)})}catch(y){return p.text(`Proxy fetch failed: ${y instanceof Error?y.message:y}`,502)}}n&&o.get("/__reload",p=>Br(p,async l=>{let m=()=>{l.writeSSE({event:"reload",data:""})};for(n.on("reload",m),l.onAbort(()=>{n.removeListener("reload",m)});;)await l.sleep(3e4)}));let f=/^\/(v\d
|
|
370
|
+
`).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Vt(s,e,t){let r=new TextDecoder,n="",i=!1,o=t?new Promise((a,c)=>{t.aborted&&c(new Error("Aborted")),t.addEventListener("abort",()=>c(new Error("Aborted")),{once:!0})}):null;for(;;){let a=o?await Promise.race([s.read(),o]):await s.read(),{done:c,value:d}=a;if(c){if(n.trim()){let h=rt(n);h!==null&&h!=="done"&&e(h)}break}i=!0,n+=r.decode(d,{stream:!0});let{pos:u,len:f}=Wt(n);for(;u!==-1;){let h=n.slice(0,u);n=n.slice(u+f);let p=rt(h);if(p==="done"){n="";break}p!==null&&e(p),{pos:u,len:f}=Wt(n)}}return{receivedAnyData:i}}async function nt(s,e){let t=e??(s.headers.get("X-Provider-Protocol")||"openai"),r=V(t);if(!s.body)throw new Error("Response body is missing");let n=s.body.getReader(),i="";return await Vt(n,o=>{let a=r.parseStreamChunk(o);a?.text&&(i+=a.text)}),i}import*as st from"fs/promises";import*as Pe from"path";var Oe=class{async get(e){let t=k(e),r=Pe.join(ye,t+".bin"),n=Pe.join(ye,t+".json");try{let[i,o]=await Promise.all([st.readFile(r),st.readFile(n,"utf8")]),a=JSON.parse(o);return{body:i,contentType:a.contentType,cacheControl:a.cacheControl}}catch{return}}async set(e,t){await v();let r=k(e),n=Pe.join(ye,r+".bin"),i=Pe.join(ye,r+".json"),o={url:e,contentType:t.contentType,cacheControl:t.cacheControl};await Promise.all([P(n,t.body),P(i,JSON.stringify(o))])}};async function Gt(s){let{getHtml:e,basePath:t,port:r,reloadEmitter:n,getServerExports:i}=s,o=new $r;o.use("*",async(p,l)=>{await l(),p.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),p.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),o.get("/",p=>p.html(e())),o.post("/__fs/read",async p=>{try{let{path:l}=await p.req.json(),m=Ht(l,t),w=await ee.readFile(m,"utf-8");return p.json({content:w})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},400)}}),o.post("/__fs/write",async p=>{try{let{path:l,content:m}=await p.req.json(),w=Ht(l,t);return await ee.mkdir(J.dirname(w),{recursive:!0}),await ee.writeFile(w,m,"utf-8"),p.json({success:!0})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},400)}});let a={log:console.log};o.post("/__api/:name",async p=>{try{let l=i?.(),m=p.req.param("name"),w=l?.[m]??a[m];if(!w||typeof w!="function")return p.json({error:`API function '${m}' not found`},404);let{args:y}=await p.req.json(),A=await w(...y||[]);return p.json({result:A})}catch(l){let m=l instanceof Error?l.message:"Unknown error";return p.json({error:m},500)}}),o.post("/__ai",async p=>{try{let{messages:l,system:m,reasoning:w,provider:y,model:A,webSearch:$}=await p.req.json();if(!l||!Array.isArray(l)||l.length===0)return p.json({message:"messages array is required",code:"unknown",retryable:!1},400);let _=Lr(y,A);if(typeof _=="string")return p.json({message:_,code:"unknown",retryable:!1},400);let re=[...m?[{role:"system",content:m}]:[],...l.map(O=>({role:O.role,content:O.content}))],U=await et(_,{model:_.model,messages:re,stream:!0,reasoning:w??0,webSearch:$??!0});if(!U.ok){let O=await tt(U,_.protocol);return p.json(O,U.status)}let Se=await nt(U,_.protocol);return Se||console.warn("[tb.ai] Empty response from provider"),p.json({text:Se})}catch(l){if(l instanceof S)return p.json({message:l.message,code:l.code,retryable:l.retryable},500);let m=l instanceof Error?l.message:"Unknown error";return p.json({message:m,code:"unknown",retryable:!1},500)}}),o.get("/__models",async p=>{try{let l=await Jr();return p.json(l)}catch{return p.json([],200)}});let c=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"],d=new Oe;o.get("/proxy/*",async p=>{let l=new URL(p.req.url),w=(l.pathname+l.search).slice(7),y=w.lastIndexOf("https://");return y===-1?p.text("Invalid proxy URL",400):u(p,w.slice(y))});async function u(p,l){let m;try{m=new URL(l)}catch{return p.text("Invalid URL",400)}if(m.protocol!=="https:")return p.text("HTTPS only",400);if(!c.includes(m.hostname))return p.text("Host not allowed",403);let w=await d.get(l);if(w)return new Response(w.body,{status:200,headers:it(w.contentType,w.cacheControl)});try{let y=await fetch(l,{headers:{Accept:p.req.header("Accept")||"*/*"},redirect:"follow"});if(!y.ok)return p.text(`Upstream ${y.status}`,y.status);let A=y.headers.get("Content-Type")||void 0,$=y.headers.get("Cache-Control")||void 0;if(y.body){let[_,re]=y.body.tee();return(async()=>{try{let U=await new Response(re).arrayBuffer();await d.set(l,{body:Buffer.from(U),contentType:A,cacheControl:$})}catch{}})(),new Response(_,{status:y.status,headers:it(A,$)})}return new Response(null,{status:y.status,headers:it(A,$)})}catch(y){return p.text(`Proxy fetch failed: ${y instanceof Error?y.message:y}`,502)}}n&&o.get("/__reload",p=>Br(p,async l=>{let m=()=>{l.writeSSE({event:"reload",data:""})};for(n.on("reload",m),l.onAbort(()=>{n.removeListener("reload",m)});;)await l.sleep(3e4)}));let f=/^\/(v\d+\/|stable\/|node\/|gh\/|@[^/]+\/[^@/]+@|[^@/]+@)/;o.notFound(async p=>{if(p.req.method!=="GET")return p.text("Not Found",404);let l=new URL(p.req.url);return f.test(l.pathname)?u(p,"https://esm.sh"+l.pathname+l.search):p.text("Not Found",404)});let h=Ur({fetch:o.fetch,port:r});return{port:r,close:()=>h.close()}}var qt={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function Lr(s,e){let t=s??process.env.TB_AI_PROVIDER,r=e??process.env.TB_AI_MODEL;if(!t)return"No provider specified. Set TB_AI_PROVIDER in your .env file or pass provider in the tb.ai() call.";if(!r)return"No model specified. Set TB_AI_MODEL in your .env file or pass model in the tb.ai() call.";let n;try{n=V(t)}catch{return`Unknown provider '${t}'.`}let i=qt[t],o=process.env[i];return o?{apiKey:o,baseUrl:n.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${i} in your .env file.`}var Wr="https://api.typebulb.com/api/models",Vr=1440*60*1e3,Z=null;async function Jr(){if(!Z||Date.now()-Z.fetchedAt>Vr){let s=await fetch(Wr);if(!s.ok)return Z?Jt(Z.models):[];Z={models:await s.json(),fetchedAt:Date.now()}}return Jt(Z.models)}function Jt(s){let e=new Set(Object.entries(qt).filter(([,t])=>!!process.env[t]).map(([t])=>t));return s.filter(t=>e.has(t.provider))}function it(s,e){let t=new Headers;return s&&t.set("Content-Type",s),e&&t.set("Cache-Control",e),t.set("Access-Control-Allow-Origin","*"),t.set("Cross-Origin-Resource-Policy","cross-origin"),t}function Ht(s,e){let t=J.resolve(e,s),r=J.normalize(e);if(!J.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function ot(s){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(s,()=>{let n=r.address(),i=typeof n=="object"&&n?n.port:s;r.close(()=>t(i))}),r.on("error",()=>{t(ot(s+1))})})}import Hr from"open";async function zt(s){await Hr(s)}import Gr from"chokidar";function at(s){let{bulbPath:e,emitter:t}=s,r=Gr.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}import*as D from"fs/promises";import*as H from"path";import*as te from"path";var qr=te.join(_e,"pkg"),zr=te.join(_e,"files"),Kr=te.join(_e,"negative.json"),je=class{pkgMem=new Map;fileMem=new Map;negativeCache=new L(new X(Kr));async getCachedDts(e){if(this.pkgMem.has(e))return this.pkgMem.get(e);await v();let t=await W(Kt(e));return this.pkgMem.set(e,t),t}async setCachedDts(e,t,r){let n={content:t,url:r};this.pkgMem.set(e,n),await Fe(async()=>{await v(),await P(Kt(e),JSON.stringify(n))})}async getCachedFile(e){if(this.fileMem.has(e))return this.fileMem.get(e);await v();let t=await Ce(Yt(e));return this.fileMem.set(e,t),t}async setCachedFile(e,t){this.fileMem.set(e,t),await Fe(async()=>{await v(),await P(Yt(e),t)})}isNegative(e){return this.negativeCache.isNegative(e)}async recordNegative(e){await Fe(async()=>{await v(),await this.negativeCache.recordNegative(e)})}clearNegative(e){return Fe(()=>this.negativeCache.clearNegative(e))}};async function Fe(s){try{await s()}catch{}}function Kt(s){return te.join(qr,k(s)+".json")}function Yt(s){return te.join(zr,k(s)+".txt")}var ct;function Yr(){return ct||(ct=Ye({cache:new je,cdnClient:Ut,packageService:Me,versionResolver:$t})),ct}var Xt="file:///node_modules/";async function Qt(s){let e=Ie(s.emitKey,"typecheck");await v(),await D.rm(e,{recursive:!0,force:!0}),await D.mkdir(e,{recursive:!0});let t=en(s.jsxImportSource,s.dependencies),r=await Yr().resolve(s.code,s.dependencies,t),n=new Set;for(let a of r)for(let c of a.files){let d=lt(c.path);if(!d||n.has(d))continue;n.add(d);let u=H.join(e,"node_modules",d);await D.mkdir(H.dirname(u),{recursive:!0}),await D.writeFile(u,c.content,"utf8")}let i={};for(let a of r)for(let c of a.shims){let d=lt(c.path);d&&(i[c.module]=[`./node_modules/${d}`])}for(let a of r){let c=lt(a.mainPath);c&&(i[a.pkg]=[`./node_modules/${c}`])}let o=Xr(s.jsxImportSource,i);return await D.writeFile(H.join(e,"tsconfig.json"),JSON.stringify(o,null,2)+`
|
|
371
371
|
`,"utf8"),await D.writeFile(H.join(e,"code.tsx"),s.code,"utf8"),await D.writeFile(H.join(e,"tb.d.ts"),Ge,"utf8"),{dir:e}}function Xr(s,e){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"bundler",lib:Qr([...Je,...He]),jsx:"react-jsx",jsxImportSource:s??"react",strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0,baseUrl:".",paths:e},include:["code.tsx","tb.d.ts"]}}function Qr(s){return s.filter(e=>!e.since).map(e=>Zr(e.name))}function Zr(s){return s.split(".").map(e=>/^es\d+$/i.test(e)?e.toUpperCase():e==="dom"?"DOM":e==="esnext"?"ESNext":e.charAt(0).toUpperCase()+e.slice(1)).join(".")}function en(s,e){let t=s??("react"in e?"react":void 0);return t?[`${t}/jsx-runtime`,`${t}/jsx-dev-runtime`]:[]}function lt(s){if(!s.startsWith(Xt))return;let e=s.slice(Xt.length),t=e.indexOf("/");if(!(t<0))return e.slice(t+1)}import*as R from"fs/promises";import*as G from"path";import{existsSync as an}from"fs";import*as Ne from"fs/promises";import*as dt from"path";import{existsSync as Zt}from"fs";import{execFile as tn}from"child_process";import{promisify as rn}from"util";var nn=rn(tn);async function $e(s,e){let t=s.filter(n=>!sn(n,e));if(t.length===0)return;await Ne.mkdir(e,{recursive:!0});let r=dt.join(e,"package.json");Zt(r)||await Ne.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await nn("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}function sn(s,e){return Zt(dt.join(e,"node_modules",on(s)))}function on(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t<0)return s;let r=s.indexOf("@",t+1);return r<0?s:s.slice(0,r)}let e=s.indexOf("@");return e<0?s:s.slice(0,e)}var cn="^22";async function er(s){let e=Ie(s.emitKey,"typecheck-server");await v(),await R.rm(e,{recursive:!0,force:!0}),await R.mkdir(e,{recursive:!0});let t=G.join(s.bulbDir,".typebulb");await $e([`@types/node@${cn}`],t);let r=G.join(t,"node_modules"),n=G.join(e,"node_modules");return await dn(r,n),await R.writeFile(G.join(e,"server.ts"),s.server,"utf8"),await R.writeFile(G.join(e,"tb.d.ts"),qe,"utf8"),await R.writeFile(G.join(e,"tsconfig.json"),JSON.stringify(ln(),null,2)+`
|
|
372
|
-
`,"utf8"),{dir:e}}function ln(){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"node",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0},include:["server.ts","tb.d.ts"]}}async function dn(s,e){if(!an(s)){await R.mkdir(e,{recursive:!0});return}await R.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await R.symlink(s,e,t)}var Io=hn(mn),gn="0.5.
|
|
372
|
+
`,"utf8"),{dir:e}}function ln(){return{compilerOptions:{target:"es2023",module:"esnext",moduleResolution:"node",lib:["ES2023"],types:["node"],strict:!0,noEmit:!0,skipLibCheck:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,forceConsistentCasingInFileNames:!0},include:["server.ts","tb.d.ts"]}}async function dn(s,e){if(!an(s)){await R.mkdir(e,{recursive:!0});return}await R.rm(e,{recursive:!0,force:!0});let t=process.platform==="win32"?"junction":"dir";await R.symlink(s,e,t)}var Io=hn(mn),gn="0.5.1";function yn(s){let e={subcommand:"run",file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};s[0]==="check"&&(e.subcommand="check",s=s.slice(1));for(let t=0;t<s.length;t++){let r=s[t];if(r==="--help"||r==="-h")e.help=!0;else if(r==="--version"||r==="-V")e.version=!0;else if(r==="--no-watch")e.watch=!1;else if(r==="--no-open")e.open=!1;else if(r==="--server")e.server=!0;else if(r==="--port"||r==="-p"){let n=s[++t],i=parseInt(n,10);isNaN(i)&&(console.error(`Invalid port: ${n}`),process.exit(1)),e.port=i}else r.startsWith("-")||(e.file=r)}return e}function wn(){console.log(`
|
|
373
373
|
typebulb - Local bulb runner for Typebulb
|
|
374
374
|
|
|
375
375
|
Usage:
|