typebulb 0.4.5 → 0.4.6

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.
Files changed (2) hide show
  1. package/dist/index.js +12 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import*as w from"fs/promises";import{readFileSync as it,existsSync as Ie}from"fs";import*as y from"path";import{pathToFileURL as at}from"url";import{execFile as ct}from"child_process";import{promisify as lt}from"util";import{EventEmitter as ie}from"events";var Ce={code:{path:"code.tsx",language:"typescript"},css:{path:"styles.css",language:"css"},html:{path:"index.html",language:"html"},config:{path:"config.json",language:"json"},notes:{path:"notes.md",language:"markdown"},data:{path:"data.txt",language:"text"},infer:{path:"infer.md",language:"markdown"},insight:{path:"insight.json",language:"json"},server:{path:"server.ts",language:"typescript"}};function W(n){try{let e=n.split(`
3
- `),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let s=De(r);if(!s)return null;let o=new Map;for(;t<e.length;){let c=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(c){let d=c[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let f=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!f){t++;continue}let a=f[1];t++;let l=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${a}\\s*$`));)l.push(e[t]),t++;t++,o.set(d,l.join(`
4
- `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function De(n){let e={};for(let t of n){let r=t.indexOf(":");if(r===-1)continue;let s=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=Be(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function Be(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function J(n){let e=t=>n.files.get(Ce[t].path)||"";return{name:n.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function Ne(n){try{return JSON.parse(n),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(n)||/^---\s*$/m.test(n)||/^\w[\w\s]*:[ \t]/m.test(n))}function le(n){let e=n.trim();return e?Ne(e)?[e]:n.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function z(n){if(!n.trim())return{};try{return JSON.parse(n)}catch{return{}}}import{transform as pe}from"sucrase";function je(n,e){try{let{code:t}=pe(n,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function de(n,e={}){return je(n,e)}function ue(n){try{let{code:e}=pe(n,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var $="https://esm.sh",C="https://cdn.jsdelivr.net/npm/",K="https://data.jsdelivr.com/v1/package/npm/";function fe(n){let e=(n||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class n{constructor(e,t,r){let s=typeof e=="string"?n.parse(e):e;this.name=s.name,this.version=k(t??s.version),this.subpath=k(r??s.subpath)}static parse(e){let t=fe(e||"");if(!t.length)return new n({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=me(t[1]??""),c=k(t.slice(2).join("/"));return new n({name:`${s}/${o}`,version:i,subpath:c})}else{let[s,o]=me(t[0]),i=k(t.slice(1).join("/"));return new n({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL($).host,s=new URL(C).host;if(t.host===r){let o=fe(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return n.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return n.parse(i)}return}catch{return}}static versionFromUrl(e){return n.fromUrl(e)?.version}format(){let e=this.version?`${this.name}@${this.version}`:this.name;return this.subpath?`${e}/${this.subpath}`:e}root(){return this.name}static rootOf(e){return n.parse(e).name}withVersion(e){return new n({name:this.name,version:k(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},k=n=>n&&n.length?n:void 0,me=n=>{let e=n.indexOf("@");return e<0?[n,void 0]:[n.slice(0,e),k(n.slice(e+1))]};async function v(n){try{return await n()}catch{return}}var D=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=$,this.jsDelivrBase=C,this.jsDelivrMeta=K,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new g(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:r="es2022",bundle:s=!1,external:o}=t,i=new URLSearchParams({target:r});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),s=await v(()=>this.http.head(r));return s?.ok?s.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let r=await v(()=>this.http.head(t)),s=this.parseVersionFromUrl(r?.url||t);if(s)return s}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let r=await v(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,s),r}parseVersionFromUrl(e){let t=g.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:a,peerDependencies:l,peerDependenciesMeta:u}=r;return{name:e,version:t,dependencies:a,peerDependencies:l,peerDependenciesMeta:u}}let s=this.packageJson(new g(`${e}@${t}`)),o=await v(()=>this.http.getJson(s));if(!o)return;let i=a=>a&&Object.keys(a).length?a:void 0,c=i(o.dependencies),d=i(o.peerDependencies),f=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,c,d,f),{name:e,version:t,dependencies:c,peerDependencies:d,peerDependenciesMeta:f}}};var he=n=>n.startsWith("@types/"),B=n=>Object.keys(n?.peerDependencies||{}).filter(e=>!he(e)),Y=n=>Object.keys(n?.dependencies||{}).filter(e=>!he(e)),Fe=n=>B(n).filter(e=>!n?.peerDependenciesMeta?.[e]?.optional),N=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(o=>[o.name,o])),s=[];for(let o of e)for(let i of Fe(o.meta))!r.has(i)&&!s.some(c=>c.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let c=await t(o),d=await this.cdn.fetchPackageMeta(o,c);r.set(o,{name:o,version:c,meta:d})}catch(c){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,c)}return{allRoots:[...r.values()],autoAddedPeers:s.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>B(o.meta))),r=new Map;for(let o of e)for(let i of Y(o.meta))r.set(i,(r.get(i)||0)+1);let s=new Set([...r.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:B(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var j=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await v(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let s=await v(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let c=await v(()=>this.cdn.fetchVersionsIndex(e));if(c?.versions?.length){let d=this.selectVersionFromIndex(c.versions,t,c.distTags);if(d&&this.semver.isExactVersion(d))return await this.cache.setPinnedExact(e,t,d),d}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let r=new g(e),s=r.root(),o=t[s],i=o?await v(()=>this.cache.getPinnedExact(s,o))??await v(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as Ue,parse as Le}from"es-module-lexer";var T=class n{constructor(e,t,r,s){this.version=e,this.cdn=t,this.peer=r,this.cache=s}extractImportsSync(e){let t=new Set;for(let r of n.importPatterns){r.lastIndex=0;for(let s of e.matchAll(r))g.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=s=>{g.isBare(s)&&t.add(s)};try{await Ue;let[s]=Le(e);s.forEach(o=>r(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t){let r=await this.extractImports(e),s=[...new Set(r.map(g.rootOf))],o=await Promise.all(s.map(async a=>({name:a,version:await this.resolveVersion(a,t)}))),{allRoots:i,flags:c,autoAddedPeers:d}=await this.peer.resolve(o,a=>this.resolveVersion(a,t)),f=this.buildEntries([...r,...d.map(a=>a.name)],i,c,t);return{importMap:{imports:Object.fromEntries(f)},prefetchUrls:f.map(([,a])=>a)}}async resolveVersion(e,t){let r=t[e],s=await this.version.resolveExactForRoot(e,r);if(!s){let o=r?`${e}@${r}`:e,i=await v(()=>this.cdn.pinEsmUrl(o));if(!i)throw new Error(`Cannot resolve version for ${e} - network may be unavailable.`);s=g.versionFromUrl(i),s&&r&&await v(()=>this.cache.setPinnedExact(e,r,s))}if(!s)throw new Error(`Cannot resolve version for ${e}`);return s}buildEntries(e,t,r,s){let o=new Map(t.map(p=>[p.name,p])),i=p=>{let m=o.get(g.rootOf(p));return new g(p).withPreferredVersion(m.version,s[m.name]).format()},c=new Set([...r.entries()].filter(([,p])=>p.isPeerRoot||p.isSharedDep).map(([p])=>p)),d=new Set(e.filter(p=>p!==g.rootOf(p)).map(g.rootOf)),f=[],a=new Set,l=new Set(e.filter(p=>p===g.rootOf(p))),u=new Set;for(let p of e){let m=g.rootOf(p),P=o.get(m),{isPeerRoot:x,hasPeers:R,isSharedDep:A}=r.get(m),H=d.has(m),I=p!==m,Me=!(x||A)&&(H||!R),G=this.singletonDepsOf(P,c),ce=I&&l.has(m);ce&&u.add(m);let $e=ce?[...G,m]:G.length?G:void 0;f.push([p,this.cdn.buildEsmUrl(i(p),{bundle:Me,external:$e})]),a.add(p)}let h=new Set([...c,...u]);for(let p of h)o.has(p)&&(a.has(p)||f.push([p,this.cdn.buildEsmUrl(i(p),{})]),f.push([`${p}/`,`${this.cdn.esmHost}/${i(p)}/`]));return f}singletonDepsOf(e,t){return[...new Set([...B(e.meta),...Y(e.meta)])].filter(r=>t.has(r))}};T.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as ge,satisfies as Ve,maxSatisfying as X,major as He,prerelease as We,rsort as Je,valid as qe}from"semver";var q=class{cmp(e,t){return e===t?0:ge(e,t)?1:ge(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Ve(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=X(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Je(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(s){let c=X(e,r,{includePrerelease:!1});if(c)return c}return X(e,r,{includePrerelease:!0})??void 0}majorOf(e){return He(e)}isPrerelease(e){return We(e)!==null}isExactVersion(e){return qe(e)!==null}},Z=new q;function ye(n,e){let t=new D(n,e),r=new N(t),s=new j(n,t,Z);return{packageService:new T(s,t,r,n),versionResolver:s,cdnClient:t,peerResolver:r}}var Q=class{pins=new Map;indexes=new Map;negatives=new Set;meta=new Map;async getPinnedExact(e,t){return this.pins.get(`${e}@${t}`)}async setPinnedExact(e,t,r){this.pins.set(`${e}@${t}`,r)}async getIndex(e){return this.indexes.get(e)}async setIndex(e,t,r){this.indexes.set(e,{versions:t,distTags:r,updatedAt:Date.now()})}async invalidateVersionsCache(e){this.indexes.delete(e)}async isNegative(e){return this.negatives.has(e)}async recordNegative(e){this.negatives.add(e)}async clearNegative(e){this.negatives.delete(e)}async getMeta(e,t){return this.meta.get(`${e}@${t}`)}async setMeta(e,t,r,s,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()})}},Ge={async getJson(n){try{let e=await fetch(n,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(n){try{let e=await fetch(n,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}},ze=new Q,{packageService:we,versionResolver:rr,cdnClient:sr,peerResolver:nr}=ye(ze,Ge);var ve=`
2
+ import*as w from"fs/promises";import{readFileSync as it,existsSync as Ae}from"fs";import*as y from"path";import{pathToFileURL as at}from"url";import{execFile as ct}from"child_process";import{promisify as lt}from"util";import{EventEmitter as ie}from"events";var Ce={code:{path:"code.tsx",language:"typescript"},css:{path:"styles.css",language:"css"},html:{path:"index.html",language:"html"},config:{path:"config.json",language:"json"},notes:{path:"notes.md",language:"markdown"},data:{path:"data.txt",language:"text"},infer:{path:"infer.md",language:"markdown"},insight:{path:"insight.json",language:"json"},server:{path:"server.ts",language:"typescript"}};function W(n){try{let e=n.split(`
3
+ `),t=0;if(e[t]?.trim()!=="---")return null;t++;let r=[];for(;t<e.length&&e[t]?.trim()!=="---";)r.push(e[t]),t++;if(e[t]?.trim()!=="---")return null;t++;let s=Be(r);if(!s)return null;let o=new Map;for(;t<e.length;){let c=e[t]?.trim()?.match(/^\*\*(.+)\*\*$/);if(c){let d=c[1].trim();for(t++;t<e.length&&e[t]?.trim()==="";)t++;let f=e[t]?.match(/^(`{3,})(\w*)\s*$/);if(!f){t++;continue}let a=f[1];t++;let l=[];for(;t<e.length&&!e[t]?.match(new RegExp(`^${a}\\s*$`));)l.push(e[t]),t++;t++,o.set(d,l.join(`
4
+ `))}else t++}return{frontmatter:s,files:o}}catch{return null}}function Be(n){let e={};for(let t of n){let r=t.indexOf(":");if(r===-1)continue;let s=t.slice(0,r).trim(),o=t.slice(r+1).trim();switch(s){case"format":e.format=o;break;case"name":e.name=De(o);break}}return!e.format?.startsWith("typebulb")||!e.name?null:e}function De(n){return n.startsWith('"')&&n.endsWith('"')?n.slice(1,-1).replace(/\\"/g,'"'):n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n}function J(n){let e=t=>n.files.get(Ce[t].path)||"";return{name:n.frontmatter.name,code:e("code"),css:e("css"),html:e("html"),config:e("config"),notes:e("notes"),data:e("data"),infer:e("infer"),insight:e("insight"),server:e("server")}}function Ne(n){try{return JSON.parse(n),!0}catch{}return!!(/^\s*<[\s\S]*>/.test(n)||/^---\s*$/m.test(n)||/^\w[\w\s]*:[ \t]/m.test(n))}function le(n){let e=n.trim();return e?Ne(e)?[e]:n.split(/\n\n\n+/).map(t=>t.trim()).filter(Boolean):[]}function z(n){if(!n.trim())return{};try{return JSON.parse(n)}catch{return{}}}import{transform as pe}from"sucrase";function je(n,e){try{let{code:t}=pe(n,{transforms:["typescript","jsx"],jsxRuntime:"automatic",jsxImportSource:e.jsxImportSource||"react",production:!0});return{code:t}}catch(t){return{code:"",error:String(t)}}}function de(n,e={}){return je(n,e)}function ue(n){try{let{code:e}=pe(n,{transforms:["typescript"]});return{code:e}}catch(e){return{code:"",error:String(e)}}}var $="https://esm.sh",C="https://cdn.jsdelivr.net/npm/",K="https://data.jsdelivr.com/v1/package/npm/";function fe(n){let e=(n||"").replace(/^\/+/,"").replace(/\/+$/,"");return e?e.split("/"):[]}var g=class n{constructor(e,t,r){let s=typeof e=="string"?n.parse(e):e;this.name=s.name,this.version=T(t??s.version),this.subpath=T(r??s.subpath)}static parse(e){let t=fe(e||"");if(!t.length)return new n({name:""});if(t[0].startsWith("@")){let s=t[0],[o,i]=me(t[1]??""),c=T(t.slice(2).join("/"));return new n({name:`${s}/${o}`,version:i,subpath:c})}else{let[s,o]=me(t[0]),i=T(t.slice(1).join("/"));return new n({name:s,version:o,subpath:i})}}static fromUrl(e){try{let t=new URL(e),r=new URL($).host,s=new URL(C).host;if(t.host===r){let o=fe(t.pathname.replace(/^\/v\d+\//,"/"));if(!o.length)return;let i=o[0].startsWith("@")?`${o[0]}/${o[1]??""}`:o[0];return n.parse(i)}if(t.host===s){let o=t.pathname.split("/npm/")[1];if(!o)return;let i=o.split("/")[0]||"";return n.parse(i)}return}catch{return}}static versionFromUrl(e){return n.fromUrl(e)?.version}format(){let e=this.version?`${this.name}@${this.version}`:this.name;return this.subpath?`${e}/${this.subpath}`:e}root(){return this.name}static rootOf(e){return n.parse(e).name}withVersion(e){return new n({name:this.name,version:T(e),subpath:this.subpath})}withPreferredVersion(e,t){let r=e||t;return r?this.withVersion(r):this}static isBare(e){if(!e||e.startsWith(".")||e.startsWith("/"))return!1;let t=e.toLowerCase();return!t.startsWith("http://")&&!t.startsWith("https://")}},T=n=>n&&n.length?n:void 0,me=n=>{let e=n.indexOf("@");return e<0?[n,void 0]:[n.slice(0,e),T(n.slice(e+1))]};async function v(n){try{return await n()}catch{return}}var B=class{constructor(e,t){this.cache=e,this.http=t,this.esmHost=$,this.jsDelivrBase=C,this.jsDelivrMeta=K,this.pinMs=1e4,this.versionsIndexMs=1440*60*1e3,this.metaTtlMs=10080*60*1e3,this.pinCache=new Map}normalizeRelative(e){let t=e||"";return t.startsWith("./")?t.slice(2):t.replace(/^\/+/,"")}ensureLeadingDotSlash(e){return e.startsWith("./")?e:`./${e}`}baseDir(e){let t=typeof e=="string"?new g(e):e;return`${this.jsDelivrBase}${t.name}${t.version?`@${t.version}`:""}/`}file(e,t){return new URL(this.normalizeRelative(t),this.baseDir(e)).toString()}packageJson(e){return this.file(e,"package.json")}buildEsmUrl(e,t={}){let{target:r="es2022",bundle:s=!1,external:o}=t,i=new URLSearchParams({target:r});return s&&i.append("bundle",""),o?.length&&i.append("external",o.join(",")),`${this.esmHost}/${e}?${i.toString()}`}async pinEsmUrl(e,t="es2022"){let r=this.buildEsmUrl(e,{target:t}),s=await v(()=>this.http.head(r));return s?.ok?s.url||r:void 0}async resolveExactVersion(e){let t=Date.now(),r=this.pinCache.get(e);if(r&&t-r.ts<this.pinMs)return r.value;let s=await this.tryResolveFromUrls([this.buildEsmUrl(e),`${this.esmHost}/${e}`]);return this.pinCache.set(e,{value:s,ts:t}),s}async tryResolveFromUrls(e){for(let t of e){let r=await v(()=>this.http.head(t)),s=this.parseVersionFromUrl(r?.url||t);if(s)return s}}async fetchVersionsIndex(e){if(await this.cache.isNegative(e))return;let t=await this.cache.getIndex(e);if(t&&Date.now()-t.updatedAt<this.versionsIndexMs)return{versions:t.versions,distTags:t.distTags};let r=await v(()=>this.http.getJson(`${this.jsDelivrMeta}${encodeURIComponent(e)}`));if(!r?.versions?.length){await this.cache.recordNegative(e);return}await this.cache.clearNegative(e);let s=r.distTags&&Object.keys(r.distTags).length?r.distTags:void 0;return await this.cache.setIndex(e,r.versions,s),r}parseVersionFromUrl(e){let t=g.fromUrl(e)?.version;return t&&/\d+\.\d+\.\d+/.test(t)?t:void 0}async fetchPackageMeta(e,t){let r=await this.cache.getMeta(e,t);if(r&&Date.now()-r.updatedAt<this.metaTtlMs){let{dependencies:a,peerDependencies:l,peerDependenciesMeta:u}=r;return{name:e,version:t,dependencies:a,peerDependencies:l,peerDependenciesMeta:u}}let s=this.packageJson(new g(`${e}@${t}`)),o=await v(()=>this.http.getJson(s));if(!o)return;let i=a=>a&&Object.keys(a).length?a:void 0,c=i(o.dependencies),d=i(o.peerDependencies),f=i(o.peerDependenciesMeta);return await this.cache.setMeta(e,t,c,d,f),{name:e,version:t,dependencies:c,peerDependencies:d,peerDependenciesMeta:f}}};var he=n=>n.startsWith("@types/"),D=n=>Object.keys(n?.peerDependencies||{}).filter(e=>!he(e)),Y=n=>Object.keys(n?.dependencies||{}).filter(e=>!he(e)),Ue=n=>D(n).filter(e=>!n?.peerDependenciesMeta?.[e]?.optional),N=class{constructor(e){this.cdn=e}async resolve(e,t){let r=await this.fetchMeta(e),{allRoots:s,autoAddedPeers:o}=await this.expandWithPeers(r,t),i=this.computeFlags(s);return{allRoots:s,flags:i,autoAddedPeers:o}}async fetchMeta(e){return Promise.all(e.map(async({name:t,version:r})=>({name:t,version:r,meta:await this.cdn.fetchPackageMeta(t,r)})))}async expandWithPeers(e,t){let r=new Map(e.map(o=>[o.name,o])),s=[];for(let o of e)for(let i of Ue(o.meta))!r.has(i)&&!s.some(c=>c.name===i)&&s.push({name:i,requiredBy:o.name});for(let{name:o,requiredBy:i}of s)try{let c=await t(o),d=await this.cdn.fetchPackageMeta(o,c);r.set(o,{name:o,version:c,meta:d})}catch(c){console.warn(`[typebulb] Failed to resolve peer "${o}" for "${i}":`,c)}return{allRoots:[...r.values()],autoAddedPeers:s.filter(o=>r.has(o.name))}}computeFlags(e){let t=new Set(e.flatMap(o=>D(o.meta))),r=new Map;for(let o of e)for(let i of Y(o.meta))r.set(i,(r.get(i)||0)+1);let s=new Set([...r.entries()].filter(([,o])=>o>=2).map(([o])=>o));return new Map(e.map(o=>[o.name,{isPeerRoot:t.has(o.name),hasPeers:D(o.meta).length>0,isSharedDep:s.has(o.name)}]))}};var j=class{constructor(e,t,r){this.cache=e,this.cdn=t,this.semver=r}selectVersionFromIndex(e,t,r){return this.semver.selectBestVersion(e,{range:t,distTags:r})}async learnExactVersion(e){let t=await v(()=>this.cdn.fetchVersionsIndex(e));if(t?.versions?.length){let r=this.semver.selectBestVersion(t.versions,{distTags:t.distTags});if(r)return r}return this.cdn.resolveExactVersion(e)}async resolveExactForRoot(e,t){if(!t)return this.learnExactVersion(e);let r=await this.cache.getPinnedExact(e,t);if(r){if(this.semver.isExactVersion(r))return r;console.warn("[versionResolver] Rejecting invalid cached version for",e,":",r)}let s=await v(()=>this.cdn.fetchVersionsIndex(e));if(s?.versions?.length){let i=this.selectVersionFromIndex(s.versions,t,s.distTags);if(i){if(this.semver.isExactVersion(i))return await this.cache.setPinnedExact(e,t,i),i}else{console.warn("[versionResolver] Invalidating stale versions cache for",e,"- range",t,"not satisfied"),await this.cache.invalidateVersionsCache(e);let c=await v(()=>this.cdn.fetchVersionsIndex(e));if(c?.versions?.length){let d=this.selectVersionFromIndex(c.versions,t,c.distTags);if(d&&this.semver.isExactVersion(d))return await this.cache.setPinnedExact(e,t,d),d}}}let o=await this.cdn.resolveExactVersion(`${e}@${t}`);if(o&&this.semver.isExactVersion(o))return await this.cache.setPinnedExact(e,t,o),o}async effectivePackage(e,t){let r=new g(e),s=r.root(),o=t[s],i=o?await v(()=>this.cache.getPinnedExact(s,o))??await v(()=>this.resolveExactForRoot(s,o)):void 0;return{effectivePackage:i?r.withVersion(i).format():e,root:s,range:o,pinned:i}}};import{init as Fe,parse as Le}from"es-module-lexer";var k=class n{constructor(e,t,r,s){this.version=e,this.cdn=t,this.peer=r,this.cache=s}extractImportsSync(e){let t=new Set;for(let r of n.importPatterns){r.lastIndex=0;for(let s of e.matchAll(r))g.isBare(s[1])&&t.add(s[1])}return Array.from(t)}async extractImports(e){let t=new Set,r=s=>{g.isBare(s)&&t.add(s)};try{await Fe;let[s]=Le(e);s.forEach(o=>r(e.slice(o.s,o.e).trim()))}catch{return this.extractImportsSync(e)}return Array.from(t)}async buildImportMap(e,t){let r=await this.extractImports(e),s=[...new Set(r.map(g.rootOf))],o=await Promise.all(s.map(async a=>({name:a,version:await this.resolveVersion(a,t)}))),{allRoots:i,flags:c,autoAddedPeers:d}=await this.peer.resolve(o,a=>this.resolveVersion(a,t)),f=this.buildEntries([...r,...d.map(a=>a.name)],i,c,t);return{importMap:{imports:Object.fromEntries(f)},prefetchUrls:f.map(([,a])=>a)}}async resolveVersion(e,t){let r=t[e],s=await this.version.resolveExactForRoot(e,r);if(!s){let o=r?`${e}@${r}`:e,i=await v(()=>this.cdn.pinEsmUrl(o));if(!i)throw new Error(`Cannot resolve version for ${e} - network may be unavailable.`);s=g.versionFromUrl(i),s&&r&&await v(()=>this.cache.setPinnedExact(e,r,s))}if(!s)throw new Error(`Cannot resolve version for ${e}`);return s}buildEntries(e,t,r,s){let o=new Map(t.map(p=>[p.name,p])),i=p=>{let m=o.get(g.rootOf(p));return new g(p).withPreferredVersion(m.version,s[m.name]).format()},c=new Set([...r.entries()].filter(([,p])=>p.isPeerRoot||p.isSharedDep).map(([p])=>p)),d=new Set(e.filter(p=>p!==g.rootOf(p)).map(g.rootOf)),f=[],a=new Set,l=new Set(e.filter(p=>p===g.rootOf(p))),u=new Set;for(let p of e){let m=g.rootOf(p),P=o.get(m),{isPeerRoot:x,hasPeers:R,isSharedDep:I}=r.get(m),H=d.has(m),A=p!==m,Me=!(x||I)&&(H||!R),G=this.singletonDepsOf(P,c),ce=A&&l.has(m);ce&&u.add(m);let $e=ce?[...G,m]:G.length?G:void 0;f.push([p,this.cdn.buildEsmUrl(i(p),{bundle:Me,external:$e})]),a.add(p)}let h=new Set([...c,...u]);for(let p of h)o.has(p)&&(a.has(p)||f.push([p,this.cdn.buildEsmUrl(i(p),{})]),f.push([`${p}/`,`${this.cdn.esmHost}/${i(p)}/`]));return f}singletonDepsOf(e,t){return[...new Set([...D(e.meta),...Y(e.meta)])].filter(r=>t.has(r))}};k.importPatterns=[/\bimport\s+(?:[^'";]*?from\s*)?['"]([^'"]+)['"]/g,/\bexport\s+[^'";]*?from\s*['"]([^'"]+)['"]/g];import{gt as ge,satisfies as Ve,maxSatisfying as X,major as He,prerelease as We,rsort as Je,valid as qe}from"semver";var q=class{cmp(e,t){return e===t?0:ge(e,t)?1:ge(t,e)?-1:0}satisfies(e,t){return!e||!e.trim()?!0:!!Ve(t,e,{includePrerelease:!0})}pickMaxSatisfying(e,t){if(!e?.length)return;let r=X(e,t,{includePrerelease:!0});return r===null?void 0:r}pickLatest(e){return e?.length?Je(e)[0]:void 0}selectBestVersion(e,t){if(!e?.length)return;let r=t?.range?.trim()||"*",s=t?.preferStable??!0,o=t?.distTags?.latest;if(o&&e.includes(o)&&this.satisfies(r,o))return o;if(s){let c=X(e,r,{includePrerelease:!1});if(c)return c}return X(e,r,{includePrerelease:!0})??void 0}majorOf(e){return He(e)}isPrerelease(e){return We(e)!==null}isExactVersion(e){return qe(e)!==null}},Z=new q;function ye(n,e){let t=new B(n,e),r=new N(t),s=new j(n,t,Z);return{packageService:new k(s,t,r,n),versionResolver:s,cdnClient:t,peerResolver:r}}var Q=class{pins=new Map;indexes=new Map;negatives=new Set;meta=new Map;async getPinnedExact(e,t){return this.pins.get(`${e}@${t}`)}async setPinnedExact(e,t,r){this.pins.set(`${e}@${t}`,r)}async getIndex(e){return this.indexes.get(e)}async setIndex(e,t,r){this.indexes.set(e,{versions:t,distTags:r,updatedAt:Date.now()})}async invalidateVersionsCache(e){this.indexes.delete(e)}async isNegative(e){return this.negatives.has(e)}async recordNegative(e){this.negatives.add(e)}async clearNegative(e){this.negatives.delete(e)}async getMeta(e,t){return this.meta.get(`${e}@${t}`)}async setMeta(e,t,r,s,o){this.meta.set(`${e}@${t}`,{dependencies:r,peerDependencies:s,peerDependenciesMeta:o,updatedAt:Date.now()})}},Ge={async getJson(n){try{let e=await fetch(n,{redirect:"follow"});return e.ok?await e.json():void 0}catch{return}},async head(n){try{let e=await fetch(n,{method:"HEAD",redirect:"follow"});return{ok:e.ok,url:e.url}}catch{return}}},ze=new Q,{packageService:we,versionResolver:rr,cdnClient:sr,peerResolver:nr}=ye(ze,Ge);var ve=`
5
5
  (() => {
6
6
  // JSON parser (handles jsonish - unquoted keys)
7
7
  const parseJson = (str) => {
@@ -184,19 +184,19 @@ ${a(t)}
184
184
  </body>
185
185
  </html>`}function Ke(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}import{Hono as Xe}from"hono";import{serve as Ze}from"@hono/node-server";import{streamSSE as Qe}from"hono/streaming";import*as M from"fs/promises";import*as _ from"path";var b=class extends Error{constructor(e,t="unknown",r=!1){super(e),this.code=t,this.retryable=r}},S=class{getPath(e,t){return this.path}parseStreamChunk(e){return this.checkAndThrowError(e),this.parseProviderStreamChunk(e)}isReasoningEnabled(e){return e?.reasoning!==void 0&&e.reasoning>0}extractSystemMessages(e,t=`
186
186
 
187
- `){let r=e.filter(s=>s.role==="system").map(s=>s.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return r&&(o.code=s.error.code),o}return s.message?{message:s.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",s=!!e.retryable;throw new b(t,r,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new b(t)}}extractErrorMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);return t.error?.message||t.message||e}catch{return e}return typeof e=="object"&&e!==null?e.message||JSON.stringify(e):`${this.providerName} returned an error`}};var F=class extends S{constructor(){super(...arguments),this.providerName="Anthropic",this.defaultBaseUrl="https://api.anthropic.com",this.path="/v1/messages"}buildHeaders(e){return{"x-api-key":e,"anthropic-version":"2023-06-01","Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),c={model:t,max_tokens:this.getMaxTokens(t),messages:i,stream:s};if(r?.webSearch!==!1&&(c.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(c.system=o),this.isReasoningEnabled(r)){let d=r.reasoning;if(this.isModernModel(t)){let f={0:"low",1:"low",2:"medium",3:"high"};c.thinking={type:"adaptive"},c.output_config={effort:f[d]}}else{let f={0:0,1:2048,2:4096,3:8192};c.thinking={type:"enabled",budget_tokens:f[d]}}}return c}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),r=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
187
+ `){let r=e.filter(s=>s.role==="system").map(s=>s.content);return{system:r.length?r.join(t):void 0,conversationMessages:e.filter(s=>s.role!=="system")}}parseJsonError(e,t,r=!1){if(!e)return{message:`HTTP ${t}`};try{let s=JSON.parse(e);if(s.error&&typeof s.error=="object"){let o={message:s.error.message||`HTTP ${t}`,type:s.error.type};return r&&(o.code=s.error.code),o}return s.message?{message:s.message}:{message:e}}catch{return{message:e}}}checkAndThrowError(e){if("type"in e&&e.type==="error"&&"message"in e){let t=e.message,r=e.code||"unknown",s=!!e.retryable;throw new b(t,r,s)}if("error"in e&&e.error){let t=this.extractErrorMessage(e.error);throw new b(t)}}extractErrorMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);return t.error?.message||t.message||e}catch{return e}return typeof e=="object"&&e!==null?e.message||JSON.stringify(e):`${this.providerName} returned an error`}};var U=class extends S{constructor(){super(...arguments),this.providerName="Anthropic",this.defaultBaseUrl="https://api.anthropic.com",this.path="/v1/messages"}buildHeaders(e){return{"x-api-key":e,"anthropic-version":"2023-06-01","Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e),c={model:t,max_tokens:this.getMaxTokens(t),messages:i,stream:s};if(r?.webSearch!==!1&&(c.tools=[{type:"web_search_20250305",name:"web_search"}]),o&&(c.system=o),this.isReasoningEnabled(r)){let d=r.reasoning;if(this.isModernModel(t)){let f={0:"low",1:"low",2:"medium",3:"high"};c.thinking={type:"adaptive"},c.output_config={effort:f[d]}}else{let f={0:0,1:2048,2:4096,3:8192};c.thinking={type:"enabled",budget_tokens:f[d]}}}return c}parseError(e,t){return this.parseJsonError(e,t)}parseNonStreamingResponse(e){if(!this.isAnthropicResponse(e))return{text:""};let t=e.content.filter(s=>s.type==="text").map(s=>s.text).join(""),r=e.content.filter(s=>s.type==="thinking").map(s=>s.thinking).join(`
188
188
 
189
- `);return{text:t,reasoning:r||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var U=class extends S{constructor(){super(...arguments),this.providerName="OpenAI",this.defaultBaseUrl="https://api.openai.com",this.path="/v1/responses",this.effortMap={0:"minimal",1:"low",2:"medium",3:"high"}}buildHeaders(e){return{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return r?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",r;if(e.output&&Array.isArray(e.output))for(let s of e.output)s.type==="reasoning"&&s.summary&&(r=s.summary.map(o=>o.text).join(`
189
+ `);return{text:t,reasoning:r||void 0}}parseProviderStreamChunk(e){if(!("type"in e))return null;switch(e.type){case"content_block_delta":return e.delta.type==="text_delta"?{text:e.delta.text||""}:e.delta.type==="thinking_delta"?{reasoning:e.delta.thinking||""}:null;case"message_start":case"content_block_start":case"content_block_stop":case"message_delta":case"message_stop":case"ping":return null;default:return null}}isAnthropicResponse(e){return"content"in e&&Array.isArray(e.content)&&"type"in e&&e.type==="message"}isModernModel(e){let t=e.match(/^claude-\w+-(\d+)-(\d+)/);return!!t&&(+t[1]>4||+t[1]==4&&+t[2]>=6)}getMaxTokens(e){return this.isModernModel(e)?64e3:32e3}};var F=class extends S{constructor(){super(...arguments),this.providerName="OpenAI",this.defaultBaseUrl="https://api.openai.com",this.path="/v1/responses",this.effortMap={0:"minimal",1:"low",2:"medium",3:"high"}}buildHeaders(e){return{Authorization:`Bearer ${e}`,"Content-Type":"application/json",Accept:"application/json"}}buildPayload(e,t,r,s){let o=this.convertMessagesToInput(e),i={model:t,input:o,stream:s};return r?.webSearch!==!1&&(i.tools=[{type:"web_search"}]),this.isReasoningEnabled(r)&&(i.reasoning={effort:this.effortMap[r.reasoning],summary:"auto"}),i}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.isResponsesApiResponse(e))return{text:""};let t=e.output_text||"",r;if(e.output&&Array.isArray(e.output))for(let s of e.output)s.type==="reasoning"&&s.summary&&(r=s.summary.map(o=>o.text).join(`
190
190
  `)),!t&&s.type==="message"&&s.content&&(t=s.content.filter(o=>o.type==="output_text").map(o=>o.text).join(""));return{text:t,reasoning:r}}parseProviderStreamChunk(e){if(!this.isResponsesApiEvent(e))return null;switch(e.type){case"error":return null;case"response.failed":{let s=e.response?.error,o=s?.message||"Response failed",i=s?.code==="insufficient_quota"||s?.code==="rate_limit_exceeded";throw new b(o,i?"rate_limit":"unknown",i)}case"response.output_text.delta":return{text:e.delta};case"response.reasoning_summary_text.delta":return{reasoning:e.delta};case"response.created":case"response.in_progress":case"response.output_item.added":case"response.output_item.done":case"response.content_part.added":case"response.content_part.done":case"response.output_text.done":case"response.output_text.annotation.added":case"response.reasoning_summary_text.done":case"response.completed":case"response.web_search_call.in_progress":case"response.web_search_call.searching":case"response.web_search_call.completed":return null;default:return null}}convertMessagesToInput(e){return e.map(t=>t.role==="system"?`System: ${t.content}`:t.role==="user"?`User: ${t.content}`:t.role==="assistant"?`Assistant: ${t.content}`:t.content).join(`
191
191
 
192
192
  `)}isResponsesApiEvent(e){return"type"in e&&typeof e.type=="string"}isResponsesApiResponse(e){return"object"in e&&e.object==="response"}};var L=class extends S{constructor(){super(...arguments),this.providerName="Gemini",this.defaultBaseUrl="https://generativelanguage.googleapis.com",this.path="/v1beta/models"}getPath(e,t){return`/v1beta/models/${e}:${t?"streamGenerateContent":"generateContent"}${t?"?alt=sse":""}`}buildHeaders(e){return{"Content-Type":"application/json","x-goog-api-key":e}}buildPayload(e,t,r,s){let{system:o,conversationMessages:i}=this.extractSystemMessages(e,`
193
193
  `),d={contents:i.map(f=>({role:f.role==="assistant"?"model":"user",parts:[{text:f.content}]}))};return r?.webSearch!==!1&&(d.tools=[{google_search:{}}]),o&&(d.systemInstruction={role:"system",parts:[{text:o}]}),this.isReasoningEnabled(r)&&(d.generationConfig={temperature:.7+r.reasoning*.1}),d}parseError(e,t){if(!e)return{message:`HTTP ${t}`};try{let r=JSON.parse(e),s=Array.isArray(r)?r[0]?.error:r?.error;return s&&typeof s=="object"?{message:(s.message||`HTTP ${t}`).split(`
194
- `)[0],type:s.status,code:s.code?.toString()}:r.message?{message:r.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",r=e.candidates?.[0]?.finishReason,s="complete";return r==="MAX_TOKENS"?s="interrupted":(r==="SAFETY"||r==="RECITATION")&&(s="failed"),{text:t,status:s}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let s=t;r=s.message||s.status||"Gemini returned an error"}else r="Gemini returned an error";throw new b(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new b(`Prompt blocked: ${t}`)}}};var V=class extends S{constructor(){super(...arguments),this.providerName="OpenRouter",this.defaultBaseUrl="https://openrouter.ai/api",this.path="/api/v1/chat/completions",this.effortMap={0:"low",1:"low",2:"medium",3:"high"}}buildHeaders(e,t){let r={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(r["HTTP-Referer"]=t,r.Referer=t,r.Origin=t),r}buildPayload(e,t,r,s){let o={model:t,messages:e,stream:s};return r?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning]}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],r=t?.message?.content??t?.text??"",s=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:s}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let r=t.delta||t.message;if(!r)return null;let s=r.content||void 0,o=r.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var Ye=new Map([["openai",new U],["openrouter",new V],["anthropic",new F],["gemini",new L]]);function E(n){let e=Ye.get(n);if(!e)throw new Error(`Unsupported protocol: ${n}`);return e}async function ee(n,e){let t=E(n.protocol),r=t.getPath(e.model,e.stream),s=new URL(r,n.baseUrl).toString(),o=t.buildHeaders(n.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function te(n,e){let t=E(e),r=await n.text().catch(()=>""),{message:s}=t.parseError(r,n.status),o=n.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}function xe(n){let e=n.indexOf(`\r
194
+ `)[0],type:s.status,code:s.code?.toString()}:r.message?{message:r.message}:{message:e}}catch{return{message:e}}}parseNonStreamingResponse(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return{text:"",status:"failed",error:"Invalid response format"};let t=this.extractText(e)||"",r=e.candidates?.[0]?.finishReason,s="complete";return r==="MAX_TOKENS"?s="interrupted":(r==="SAFETY"||r==="RECITATION")&&(s="failed"),{text:t,status:s}}parseProviderStreamChunk(e){if(this.checkGeminiError(e),!this.isGeminiResponse(e))return null;let t=this.extractText(e);return t?{text:t}:null}isGeminiResponse(e){return typeof e=="object"&&e!==null&&"candidates"in e&&Array.isArray(e.candidates)}extractText(e){let t=e.candidates?.[0];if(t?.content?.parts)return t.content.parts.map(r=>r.text).filter(Boolean).join("")}checkGeminiError(e){if(typeof e=="object"&&e!==null&&"error"in e){let t=e.error,r;if(typeof t=="string")r=t;else if(typeof t=="object"&&t!==null){let s=t;r=s.message||s.status||"Gemini returned an error"}else r="Gemini returned an error";throw new b(r)}if(this.isGeminiResponse(e)&&e.promptFeedback?.blockReason){let t=e.promptFeedback.blockReason;throw new b(`Prompt blocked: ${t}`)}}};var V=class extends S{constructor(){super(...arguments),this.providerName="OpenRouter",this.defaultBaseUrl="https://openrouter.ai/api",this.path="/api/v1/chat/completions",this.effortMap={0:"low",1:"low",2:"medium",3:"high"}}buildHeaders(e,t){let r={Authorization:`Bearer ${e}`,"x-api-key":e,"Content-Type":"application/json",Accept:"application/json","X-Title":"Typebulb"};return t&&(r["HTTP-Referer"]=t,r.Referer=t,r.Origin=t),r}buildPayload(e,t,r,s){let o={model:t,messages:e,stream:s};return r?.webSearch===!0&&(o.plugins=[{id:"web"}]),this.isReasoningEnabled(r)&&(o.reasoning={effort:this.effortMap[r.reasoning]}),o}parseError(e,t){return this.parseJsonError(e,t,!0)}parseNonStreamingResponse(e){if(!this.hasChoices(e))return{text:""};let t=e.choices[0],r=t?.message?.content??t?.text??"",s=t?.message?.reasoning??e.reasoning;return{text:r,reasoning:s}}parseProviderStreamChunk(e){if(!this.hasChoices(e))return null;let t=e.choices[0];if(!t)return null;let r=t.delta||t.message;if(!r)return null;let s=r.content||void 0,o=r.reasoning||void 0;return!s&&!o?null:{text:s,reasoning:o}}hasChoices(e){return typeof e=="object"&&e!==null&&"choices"in e&&Array.isArray(e.choices)}};var Ye=new Map([["openai",new F],["openrouter",new V],["anthropic",new U],["gemini",new L]]);function E(n){let e=Ye.get(n);if(!e)throw new Error(`Unsupported protocol: ${n}`);return e}async function ee(n,e){let t=E(n.protocol),r=t.getPath(e.model,e.stream),s=new URL(r,n.baseUrl).toString(),o=t.buildHeaders(n.apiKey,e.origin),i=t.buildPayload(e.messages,e.model,{reasoning:e.reasoning,webSearch:e.webSearch},e.stream);return e.modifyPayload?.(i),fetch(s,{method:"POST",headers:o,body:JSON.stringify(i),signal:e.signal})}async function te(n,e){let t=E(e),r=await n.text().catch(()=>""),{message:s}=t.parseError(r,n.status),o=n.status,i="unknown";return o===429?i="rate_limit":o===413&&(i="context_exceeded"),{code:i,message:s,retryable:o===429}}function xe(n){let e=n.indexOf(`\r
195
195
  \r
196
196
  `),t=n.indexOf(`
197
197
 
198
198
  `);return e!==-1&&(t===-1||e<t)?{pos:e,len:4}:t!==-1?{pos:t,len:2}:{pos:-1,len:0}}function re(n){let t=n.split(/\r?\n/).filter(s=>s.startsWith("data:"));if(!t.length)return null;let r=t.map(s=>s.replace(/^data:\s?/,"")).join(`
199
- `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Se(n,e,t){let r=new TextDecoder,s="",o=!1,i=t?new Promise((c,d)=>{t.aborted&&d(new Error("Aborted")),t.addEventListener("abort",()=>d(new Error("Aborted")),{once:!0})}):null;for(;;){let c=i?await Promise.race([n.read(),i]):await n.read(),{done:d,value:f}=c;if(d){if(s.trim()){let u=re(s);u!==null&&u!=="done"&&e(u)}break}o=!0,s+=r.decode(f,{stream:!0});let{pos:a,len:l}=xe(s);for(;a!==-1;){let u=s.slice(0,a);s=s.slice(a+l);let h=re(u);if(h==="done"){s="";break}h!==null&&e(h),{pos:a,len:l}=xe(s)}}return{receivedAnyData:o}}async function se(n,e){let t=e??(n.headers.get("X-Provider-Protocol")||"openai"),r=E(t);if(!n.body)throw new Error("Response body is missing");let s=n.body.getReader(),o="";return await Se(s,i=>{let c=r.parseStreamChunk(i);c?.text&&(o+=c.text)}),o}async function _e(n){let{getHtml:e,basePath:t,port:r,reloadEmitter:s,getServerExports:o}=n,i=new Xe;i.use("*",async(a,l)=>{await l(),a.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),a.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),i.get("/",a=>a.html(e())),i.post("/__fs/read",async a=>{try{let{path:l}=await a.req.json(),u=Ee(l,t),h=await M.readFile(u,"utf-8");return a.json({content:h})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},400)}}),i.post("/__fs/write",async a=>{try{let{path:l,content:u}=await a.req.json(),h=Ee(l,t);return await M.mkdir(_.dirname(h),{recursive:!0}),await M.writeFile(h,u,"utf-8"),a.json({success:!0})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},400)}});let c={log:console.log};i.post("/__api/:name",async a=>{try{let l=o?.(),u=a.req.param("name"),h=l?.[u]??c[u];if(!h||typeof h!="function")return a.json({error:`API function '${u}' not found`},404);let{args:p}=await a.req.json(),m=await h(...p||[]);return a.json({result:m})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},500)}}),i.post("/__ai",async a=>{try{let{messages:l,system:u,reasoning:h,provider:p,model:m,webSearch:P}=await a.req.json();if(!l||!Array.isArray(l)||l.length===0)return a.json({message:"messages array is required",code:"unknown",retryable:!1},400);let x=et(p,m);if(typeof x=="string")return a.json({message:x,code:"unknown",retryable:!1},400);let R=[...u?[{role:"system",content:u}]:[],...l.map(I=>({role:I.role,content:I.content}))],A=await ee(x,{model:x.model,messages:R,stream:!0,reasoning:h??0,webSearch:P??!0});if(!A.ok){let I=await te(A,x.protocol);return a.json(I,A.status)}let H=await se(A,x.protocol);return H||console.warn("[tb.ai] Empty response from provider"),a.json({text:H})}catch(l){if(l instanceof b)return a.json({message:l.message,code:l.code,retryable:l.retryable},500);let u=l instanceof Error?l.message:"Unknown error";return a.json({message:u,code:"unknown",retryable:!1},500)}}),i.get("/__models",async a=>{try{let l=await st();return a.json(l)}catch{return a.json([],200)}});let d=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"];i.get("/proxy/*",async a=>{let l=a.req.path.slice(7),u=l.lastIndexOf("https://");if(u===-1)return a.text("Invalid proxy URL",400);let h=l.slice(u),p;try{p=new URL(h)}catch{return a.text("Invalid URL",400)}if(p.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(p.hostname))return a.text("Host not allowed",403);try{let m=await fetch(h,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!m.ok)return a.text(`Upstream ${m.status}`,m.status);let P=new Headers,x=m.headers.get("Content-Type");x&&P.set("Content-Type",x);let R=m.headers.get("Cache-Control");return R&&P.set("Cache-Control",R),P.set("Access-Control-Allow-Origin","*"),P.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(m.body,{status:m.status,headers:P})}catch(m){return a.text(`Proxy fetch failed: ${m instanceof Error?m.message:m}`,502)}}),s&&i.get("/__reload",a=>Qe(a,async l=>{let u=()=>{l.writeSSE({event:"reload",data:""})};for(s.on("reload",u),l.onAbort(()=>{s.removeListener("reload",u)});;)await l.sleep(3e4)}));let f=Ze({fetch:i.fetch,port:r});return{port:r,close:()=>f.close()}}var Re={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function et(n,e){let t=n??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 s;try{s=E(t)}catch{return`Unknown provider '${t}'.`}let o=Re[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}var tt="https://api.typebulb.com/api/models",rt=1440*60*1e3,O=null;async function st(){if(!O||Date.now()-O.fetchedAt>rt){let n=await fetch(tt);if(!n.ok)return O?Pe(O.models):[];O={models:await n.json(),fetchedAt:Date.now()}}return Pe(O.models)}function Pe(n){let e=new Set(Object.entries(Re).filter(([,t])=>!!process.env[t]).map(([t])=>t));return n.filter(t=>e.has(t.provider))}function Ee(n,e){let t=_.resolve(e,n),r=_.normalize(e);if(!_.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function ne(n){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(n,()=>{let s=r.address(),o=typeof s=="object"&&s?s.port:n;r.close(()=>t(o))}),r.on("error",()=>{t(ne(n+1))})})}import nt from"open";async function Ae(n){await nt(n)}import ot from"chokidar";function oe(n){let{bulbPath:e,emitter:t}=n,r=ot.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var pt=lt(ct),dt="0.1.3";function ut(n){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};for(let t=0;t<n.length;t++){let r=n[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 s=n[++t],o=parseInt(s,10);isNaN(o)&&(console.error(`Invalid port: ${s}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function ft(){console.log(`
199
+ `).trim();if(!r)return null;if(r==="[DONE]")return"done";try{return JSON.parse(r)}catch{return null}}async function Se(n,e,t){let r=new TextDecoder,s="",o=!1,i=t?new Promise((c,d)=>{t.aborted&&d(new Error("Aborted")),t.addEventListener("abort",()=>d(new Error("Aborted")),{once:!0})}):null;for(;;){let c=i?await Promise.race([n.read(),i]):await n.read(),{done:d,value:f}=c;if(d){if(s.trim()){let u=re(s);u!==null&&u!=="done"&&e(u)}break}o=!0,s+=r.decode(f,{stream:!0});let{pos:a,len:l}=xe(s);for(;a!==-1;){let u=s.slice(0,a);s=s.slice(a+l);let h=re(u);if(h==="done"){s="";break}h!==null&&e(h),{pos:a,len:l}=xe(s)}}return{receivedAnyData:o}}async function se(n,e){let t=e??(n.headers.get("X-Provider-Protocol")||"openai"),r=E(t);if(!n.body)throw new Error("Response body is missing");let s=n.body.getReader(),o="";return await Se(s,i=>{let c=r.parseStreamChunk(i);c?.text&&(o+=c.text)}),o}async function _e(n){let{getHtml:e,basePath:t,port:r,reloadEmitter:s,getServerExports:o}=n,i=new Xe;i.use("*",async(a,l)=>{await l(),a.res.headers.set("Cross-Origin-Opener-Policy","same-origin"),a.res.headers.set("Cross-Origin-Embedder-Policy","credentialless")}),i.get("/",a=>a.html(e())),i.post("/__fs/read",async a=>{try{let{path:l}=await a.req.json(),u=Ee(l,t),h=await M.readFile(u,"utf-8");return a.json({content:h})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},400)}}),i.post("/__fs/write",async a=>{try{let{path:l,content:u}=await a.req.json(),h=Ee(l,t);return await M.mkdir(_.dirname(h),{recursive:!0}),await M.writeFile(h,u,"utf-8"),a.json({success:!0})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},400)}});let c={log:console.log};i.post("/__api/:name",async a=>{try{let l=o?.(),u=a.req.param("name"),h=l?.[u]??c[u];if(!h||typeof h!="function")return a.json({error:`API function '${u}' not found`},404);let{args:p}=await a.req.json(),m=await h(...p||[]);return a.json({result:m})}catch(l){let u=l instanceof Error?l.message:"Unknown error";return a.json({error:u},500)}}),i.post("/__ai",async a=>{try{let{messages:l,system:u,reasoning:h,provider:p,model:m,webSearch:P}=await a.req.json();if(!l||!Array.isArray(l)||l.length===0)return a.json({message:"messages array is required",code:"unknown",retryable:!1},400);let x=et(p,m);if(typeof x=="string")return a.json({message:x,code:"unknown",retryable:!1},400);let R=[...u?[{role:"system",content:u}]:[],...l.map(A=>({role:A.role,content:A.content}))],I=await ee(x,{model:x.model,messages:R,stream:!0,reasoning:h??0,webSearch:P??!0});if(!I.ok){let A=await te(I,x.protocol);return a.json(A,I.status)}let H=await se(I,x.protocol);return H||console.warn("[tb.ai] Empty response from provider"),a.json({text:H})}catch(l){if(l instanceof b)return a.json({message:l.message,code:l.code,retryable:l.retryable},500);let u=l instanceof Error?l.message:"Unknown error";return a.json({message:u,code:"unknown",retryable:!1},500)}}),i.get("/__models",async a=>{try{let l=await st();return a.json(l)}catch{return a.json([],200)}});let d=["esm.sh","unpkg.com","cdn.jsdelivr.net","cdnjs.cloudflare.com"];i.get("/proxy/*",async a=>{let l=a.req.path.slice(7),u=l.lastIndexOf("https://");if(u===-1)return a.text("Invalid proxy URL",400);let h=l.slice(u),p;try{p=new URL(h)}catch{return a.text("Invalid URL",400)}if(p.protocol!=="https:")return a.text("HTTPS only",400);if(!d.includes(p.hostname))return a.text("Host not allowed",403);try{let m=await fetch(h,{headers:{Accept:a.req.header("Accept")||"*/*"},redirect:"follow"});if(!m.ok)return a.text(`Upstream ${m.status}`,m.status);let P=new Headers,x=m.headers.get("Content-Type");x&&P.set("Content-Type",x);let R=m.headers.get("Cache-Control");return R&&P.set("Cache-Control",R),P.set("Access-Control-Allow-Origin","*"),P.set("Cross-Origin-Resource-Policy","cross-origin"),new Response(m.body,{status:m.status,headers:P})}catch(m){return a.text(`Proxy fetch failed: ${m instanceof Error?m.message:m}`,502)}}),s&&i.get("/__reload",a=>Qe(a,async l=>{let u=()=>{l.writeSSE({event:"reload",data:""})};for(s.on("reload",u),l.onAbort(()=>{s.removeListener("reload",u)});;)await l.sleep(3e4)}));let f=Ze({fetch:i.fetch,port:r});return{port:r,close:()=>f.close()}}var Re={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",gemini:"GOOGLE_API_KEY",openrouter:"OPENROUTER_API_KEY"};function et(n,e){let t=n??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 s;try{s=E(t)}catch{return`Unknown provider '${t}'.`}let o=Re[t],i=process.env[o];return i?{apiKey:i,baseUrl:s.defaultBaseUrl,protocol:t,model:r,isFreeModel:!1}:`No API key for '${t}'. Set ${o} in your .env file.`}var tt="https://api.typebulb.com/api/models",rt=1440*60*1e3,O=null;async function st(){if(!O||Date.now()-O.fetchedAt>rt){let n=await fetch(tt);if(!n.ok)return O?Pe(O.models):[];O={models:await n.json(),fetchedAt:Date.now()}}return Pe(O.models)}function Pe(n){let e=new Set(Object.entries(Re).filter(([,t])=>!!process.env[t]).map(([t])=>t));return n.filter(t=>e.has(t.provider))}function Ee(n,e){let t=_.resolve(e,n),r=_.normalize(e);if(!_.normalize(t).startsWith(r))throw new Error("Path traversal detected - access denied");return t}async function ne(n){let e=await import("net");return new Promise(t=>{let r=e.createServer();r.listen(n,()=>{let s=r.address(),o=typeof s=="object"&&s?s.port:n;r.close(()=>t(o))}),r.on("error",()=>{t(ne(n+1))})})}import nt from"open";async function Ie(n){await nt(n)}import ot from"chokidar";function oe(n){let{bulbPath:e,emitter:t}=n,r=ot.watch(e,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}});return r.on("change",()=>{t.emit("reload")}),()=>r.close()}var pt=lt(ct),dt="0.4.6";function ut(n){let e={file:"",port:3e3,watch:!0,open:!0,server:!1,help:!1,version:!1};for(let t=0;t<n.length;t++){let r=n[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 s=n[++t],o=parseInt(s,10);isNaN(o)&&(console.error(`Invalid port: ${s}`),process.exit(1)),e.port=o}else r.startsWith("-")||(e.file=r)}return e}function ft(){console.log(`
200
200
  typebulb - Local bulb runner for Typebulb
201
201
 
202
202
  Usage:
@@ -243,11 +243,11 @@ Examples:
243
243
  typebulb my-editor.bulb.md
244
244
  typebulb --no-watch --port 8080 my-editor.bulb.md
245
245
  typebulb .
246
- `)}async function mt(n){let t=(await w.readdir(n)).find(r=>r.endsWith(".bulb.md"));return t?y.join(n,t):null}function Te(){ae([".env",".env.local"],process.cwd(),!0)}function ae(n,e,t=!1){for(let r of n){let s=y.resolve(e,r);try{let o=it(s,"utf-8");for(let i of o.split(`
247
- `)){let c=i.trim();if(!c||c.startsWith("#"))continue;let d=c.indexOf("=");if(d===-1)continue;let f=c.slice(0,d).trim(),a=c.slice(d+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),process.env[f]??=a}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}function ht(n){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(n);){let s=r[1];if(s.startsWith("node:"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}async function gt(n,e){let t=n.filter(s=>!Ie(y.join(e,"node_modules",s)));if(t.length===0)return;let r=y.join(e,"package.json");Ie(r)||await w.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await pt("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function Oe(n,e){let t=ue(n);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=y.join(e,".typebulb");await w.mkdir(r,{recursive:!0});let s=ht(t.code);s.length>0&&await gt(s,r);let o=y.join(r,"server.mjs");return await w.writeFile(o,t.code,"utf-8"),await import(`${at(o).href}?t=${Date.now()}`)}async function ke(n,e){let t=await w.readFile(n,"utf-8"),r=W(t);if(!r)throw new Error("Invalid .bulb.md file format");let s=J(r),o=z(s.config),i=le(s.data),c=de(s.code,{jsxImportSource:o.jsxImportSource});c.error&&console.error("Compilation error:",c.error);let{importMap:d}=await we.buildImportMap(c.code,o.dependencies??{}),f=be({name:s.name,code:c.code,css:s.css,html:s.html,data:i,insight:s.insight,importMap:d,watch:e}),a=y.dirname(n);o.env?.length&&ae(o.env,a);let l=null;return s.server&&(l=await Oe(s.server,a)),{html:f,bulb:s,serverExports:l}}async function yt(n,e){Te();let t=async()=>{let r=await w.readFile(n,"utf-8"),s=W(r);if(!s)throw new Error("Invalid .bulb.md file format");let o=J(s),i=z(o.config),c=y.dirname(n);i.env?.length&&ae(i.env,c),await Oe(o.server,c)};if(console.log(`Running ${y.basename(n)}...`),await t(),e){console.log(`Watching for changes...
248
- `);let r=new ie;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(s){console.error("Error:",s)}}),oe({bulbPath:n,emitter:r})}}async function wt(){let n=ut(process.argv.slice(2));n.version&&(console.log(`typebulb ${dt}`),process.exit(0)),n.help&&(ft(),process.exit(0));let e;if(!n.file||n.file==="."){let p=await mt(process.cwd());p||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=p}else e=y.resolve(n.file);try{await w.access(e)}catch{console.error(`File not found: ${e}`),process.exit(1)}e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let t=await w.readFile(e,"utf-8"),r=W(t);if(r){let p=J(r);if(p.server&&(!p.code||n.server)){await yt(e,n.watch);return}}let s=process.cwd(),o=n.watch?new ie:void 0;Te(),console.log(`Loading ${y.basename(e)}...`);let{html:i,bulb:c,serverExports:d}=await ke(e,n.watch),f=await ne(n.port),a=await _e({getHtml:()=>i,basePath:s,port:f,reloadEmitter:o,getServerExports:()=>d}),l=`http://localhost:${f}`;console.log(`
246
+ `)}async function mt(n){let t=(await w.readdir(n)).find(r=>r.endsWith(".bulb.md"));return t?y.join(n,t):null}function ke(){ae([".env",".env.local"],process.cwd(),!0)}function ae(n,e,t=!1){for(let r of n){let s=y.resolve(e,r);try{let o=it(s,"utf-8");for(let i of o.split(`
247
+ `)){let c=i.trim();if(!c||c.startsWith("#"))continue;let d=c.indexOf("=");if(d===-1)continue;let f=c.slice(0,d).trim(),a=c.slice(d+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),process.env[f]??=a}}catch{t||console.warn(` Warning: env file not found: ${r}`)}}}function ht(n){let e=new Set,t=/\bimport\s+(?:[\s\S]*?\s+from\s+)?['"]([^./][^'"]*)['"]/g,r;for(;r=t.exec(n);){let s=r[1];if(s.startsWith("node:"))continue;let o=s.startsWith("@")?s.split("/").slice(0,2).join("/"):s.split("/")[0];e.add(o)}return[...e]}async function gt(n,e){let t=n.filter(s=>!Ae(y.join(e,"node_modules",s)));if(t.length===0)return;let r=y.join(e,"package.json");Ae(r)||await w.writeFile(r,JSON.stringify({name:"typebulb-server",private:!0})),console.log(` Installing: ${t.join(", ")}`),await pt("npm",["install","--no-audit","--no-fund",...t],{cwd:e,shell:!0})}async function Oe(n,e){let t=ue(n);if(t.error)throw new Error(`Server compilation error: ${t.error}`);let r=y.join(e,".typebulb");await w.mkdir(r,{recursive:!0});let s=ht(t.code);s.length>0&&await gt(s,r);let o=y.join(r,"server.mjs");return await w.writeFile(o,t.code,"utf-8"),await import(`${at(o).href}?t=${Date.now()}`)}async function Te(n,e){let t=await w.readFile(n,"utf-8"),r=W(t);if(!r)throw new Error("Invalid .bulb.md file format");let s=J(r),o=z(s.config),i=le(s.data),c=de(s.code,{jsxImportSource:o.jsxImportSource});c.error&&console.error("Compilation error:",c.error);let{importMap:d}=await we.buildImportMap(c.code,o.dependencies??{}),f=be({name:s.name,code:c.code,css:s.css,html:s.html,data:i,insight:s.insight,importMap:d,watch:e}),a=y.dirname(n);o.env?.length&&ae(o.env,a);let l=null;return s.server&&(l=await Oe(s.server,a)),{html:f,bulb:s,serverExports:l}}async function yt(n,e){ke();let t=async()=>{let r=await w.readFile(n,"utf-8"),s=W(r);if(!s)throw new Error("Invalid .bulb.md file format");let o=J(s),i=z(o.config),c=y.dirname(n);i.env?.length&&ae(i.env,c),await Oe(o.server,c)};if(console.log(`Running ${y.basename(n)}...`),await t(),e){console.log(`Watching for changes...
248
+ `);let r=new ie;r.on("reload",async()=>{try{console.log("Re-running..."),await t()}catch(s){console.error("Error:",s)}}),oe({bulbPath:n,emitter:r})}}async function wt(){let n=ut(process.argv.slice(2));n.version&&(console.log(`typebulb ${dt}`),process.exit(0)),n.help&&(ft(),process.exit(0));let e;if(!n.file||n.file==="."){let p=await mt(process.cwd());p||(console.error("No .bulb.md file found in current directory"),process.exit(1)),e=p}else e=y.resolve(n.file);try{await w.access(e)}catch{console.error(`File not found: ${e}`),process.exit(1)}e.endsWith(".bulb.md")||(console.error("File must have .bulb.md extension"),process.exit(1));let t=await w.readFile(e,"utf-8"),r=W(t);if(r){let p=J(r);if(p.server&&(!p.code||n.server)){await yt(e,n.watch);return}}let s=process.cwd(),o=n.watch?new ie:void 0;ke(),console.log(`Loading ${y.basename(e)}...`);let{html:i,bulb:c,serverExports:d}=await Te(e,n.watch),f=await ne(n.port),a=await _e({getHtml:()=>i,basePath:s,port:f,reloadEmitter:o,getServerExports:()=>d}),l=`http://localhost:${f}`;console.log(`
249
249
  ${c.name}`),console.log(` ${l}
250
250
  `),n.watch&&console.log(` Watching for changes...
251
- `);let u;if(n.watch&&o){let p=new ie;p.on("reload",async()=>{try{console.log("Recompiling...");let m=await ke(e,!0);i=m.html,d=m.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
252
- `)}catch(m){console.error("Compile error:",m)}}),u=oe({bulbPath:e,emitter:p})}n.open&&await Ae(l);let h=async()=>{console.log(`
251
+ `);let u;if(n.watch&&o){let p=new ie;p.on("reload",async()=>{try{console.log("Recompiling...");let m=await Te(e,!0);i=m.html,d=m.serverExports,o.emit("reload"),console.log(`Done. Browser reloading...
252
+ `)}catch(m){console.error("Compile error:",m)}}),u=oe({bulbPath:e,emitter:p})}n.open&&await Ie(l);let h=async()=>{console.log(`
253
253
  Shutting down...`),a.close(),u?.();let p=y.join(y.dirname(e),".typebulb","server.mjs");await w.rm(p,{force:!0}).catch(()=>{}),process.exit(0)};process.on("SIGINT",h),process.on("SIGTERM",h)}wt().catch(n=>{console.error("Error:",n.message),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typebulb",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "Local bulb runner CLI for Typebulb",
5
5
  "license": "MIT",
6
6
  "engines": { "node": ">=18" },