dbxlite-ui 0.3.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/assets/bigquery-parse.worker-t8ggxXCo.js +1 -0
- package/assets/assets/{main-_S84z-Oh.js → main-BAj1_oUZ.js} +21703 -27581
- package/assets/assets/oauth-callback-D-QMdUuo.js +1 -0
- package/assets/assets/oauth-constants-deHgNN8Q.js +1 -0
- package/assets/assets/snowflake-parse.worker-D5M-j54J.js +1 -0
- package/assets/assets/worker-CFHnLDOA.js +5 -0
- package/assets/index.html +29 -2
- package/assets/oauth-callback.html +2 -2
- package/dist/cli.js +22 -0
- package/package.json +1 -1
- package/assets/assets/oauth-callback-BSauVj6P.js +0 -1
- package/assets/assets/oauth-constants-m7PlKcMR.js +0 -1
- package/assets/assets/worker-D76K9Q9Q.js +0 -5
- package/assets/duckdb/duckdb-browser-coi.pthread.worker.js +0 -14
- package/assets/duckdb/duckdb-browser-coi.worker.js +0 -14
- package/assets/duckdb/duckdb-browser-mvp.worker.js +0 -14
- package/assets/duckdb/duckdb-coi.wasm +0 -0
- package/assets/duckdb/duckdb-mvp.wasm +0 -0
- package/assets/screenshots/excel-query-any-sheet.png +0 -0
- package/assets/screenshots/explorer-multi-themes.png +0 -0
- package/assets/screenshots/export-status.png +0 -0
- package/assets/screenshots/main-interface-dark.png +0 -0
- package/assets/screenshots/query-remote-files.png +0 -0
- package/assets/screenshots/server-settings.png +0 -0
- package/assets/screenshots/share-links.png +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as l,a as h,b as f}from"./oauth-constants-deHgNN8Q.js";const y="bigquery_oauth_response",g="bigquery_oauth_error",n=new URLSearchParams(window.location.search),r=n.get("code"),o=n.get("state"),d=n.get("error"),_=n.get("error_description"),p=document.getElementById("spinner"),a=document.getElementById("status"),c=(e,t)=>{a&&(a.textContent=e,t&&(a.className=t)),p&&t&&(p.style.display="none")},u=e=>{try{localStorage.setItem(h,e)}catch{}try{localStorage.setItem(y,JSON.stringify({type:"oauth_code",code:JSON.parse(e).code,state:JSON.parse(e).state,timestamp:Date.now()}))}catch{}},E=e=>{try{localStorage.setItem(f,e)}catch{}try{localStorage.setItem(g,e)}catch{}},w=typeof window.opener<"u"&&window.opener!==null,S=()=>{for(const e of[h,f,y,g])try{localStorage.removeItem(e)}catch{}};window.addEventListener("unload",S);if(d){const e=_||d;c(`Authentication failed: ${e}`,"error");let t=!1;if(w)try{window.opener.postMessage({type:"oauth_error",error:e,state:o},window.location.origin),t=!0}catch{}if(!t&&(E(e),typeof BroadcastChannel<"u"))try{const s=new BroadcastChannel(l);s.postMessage({type:"oauth_error",error:e,state:o}),setTimeout(()=>s.close(),1e3)}catch{}setTimeout(()=>window.close(),3e3)}else if(r&&o){c("Authentication successful. Closing…","success");const e=JSON.stringify({code:r,state:o,timestamp:Date.now()});let t=!1;if(w)try{window.opener.postMessage({type:"oauth_code",code:r,state:o},window.location.origin),t=!0}catch{}if(t)setTimeout(()=>window.close(),250);else{if(u(e),typeof BroadcastChannel<"u")try{const i=new BroadcastChannel(l);i.postMessage({type:"oauth_code",code:r,state:o}),setTimeout(()=>i.close(),1e3)}catch{}let s=0;const m=setInterval(()=>{s++,u(e),s>=6&&(clearInterval(m),window.close())},500)}}else c("Missing authorization code. Please try again.","error"),setTimeout(()=>window.close(),3e3);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const i of n.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function t(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerPolicy&&(n.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?n.credentials="include":r.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(r){if(r.ep)return;r.ep=!0;const n=t(r);fetch(r.href,n)}})();const a=65535,d=new TextDecoder;class c{constructor(e){this.reader=e}peekFieldId(){return this.reader.peekUint16(!0)}consumeFieldId(){this.reader.consume(2)}checkFieldId(e){return this.peekFieldId()===e?(this.consumeFieldId(),!0):!1}expectFieldId(e){const t=this.peekFieldId();if(t!==e)throw new Error(`Expected field ID ${e}, got ${t} at offset ${this.reader.getOffset()}`);this.consumeFieldId()}expectObjectEnd(){this.expectFieldId(a)}throwUnsupported(e="Unsupported"){throw new Error(`${e} at offset ${this.reader.getOffset()}`)}readUint8(){return this.reader.readUint8()}readUint16(){return this.reader.readUint16(!0)}readUint32(){return this.reader.readUint32(!0)}readFloat64(){return this.reader.readFloat64(!0)}readBool(){return this.reader.readUint8()!==0}readVarInt(){let e=0,t=0,s;do s=this.reader.readUint8(),e|=(s&127)<<t,t+=7;while(s>=128);return e}readSignedVarInt(){const e=this.readVarInt();return e>>>1^-(e&1)}readVarInt64(){let e=0n,t=0n,s;do s=this.reader.readUint8(),e|=BigInt(s&127)<<t,t+=7n;while(s>=128);return e}readNullable(e){return this.readUint8()!==0?e(this):null}readData(){const e=this.readVarInt();return this.reader.readBytes(e)}readString(){const e=this.readVarInt(),t=this.reader.readBytes(e);return d.decode(t)}readList(e){const t=this.readVarInt(),s=[];for(let r=0;r<t;r++)s.push(e(this,r));return s}readPair(e,t){const s=e(this),r=t(this);return this.expectObjectEnd(),[s,r]}readProperty(e,t){return this.expectFieldId(e),t(this)}readPropertyWithDefault(e,t,s){return this.checkFieldId(e)?t(this):s}hasMore(){return this.reader.hasMore()}getOffset(){return this.reader.getOffset()}}const u="snowflake_oauth_response",l="snowflake_oauth_error",h="snowflake-auto-connect",f="snowflake_oauth",p="/oauth-callback.html";export{c as B,p as S,u as a,l as b,f as c,h as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function T(t,e){if(t==null)return null;const r=e.type.toUpperCase();switch(r){case"FIXED":return f(t,e.scale??0);case"NUMBER":case"DECIMAL":case"NUMERIC":return f(t,e.scale??0);case"INT":case"INTEGER":case"BIGINT":case"SMALLINT":case"TINYINT":case"BYTEINT":return typeof t=="string"?parseInt(t,10):t;case"FLOAT":case"FLOAT4":case"FLOAT8":case"DOUBLE":case"DOUBLE PRECISION":case"REAL":return typeof t=="string"?parseFloat(t):t;case"BOOLEAN":return t===!0||t==="true"||t===1;case"DATE":if(typeof t=="string"&&/^-?\d+$/.test(t)){const n=parseInt(t,10);return new Date(n*864e5)}return t;case"TIME":return t;case"DATETIME":case"TIMESTAMP":case"TIMESTAMP_LTZ":case"TIMESTAMP_NTZ":case"TIMESTAMP_TZ":return p(t,r);case"VARIANT":case"OBJECT":case"ARRAY":if(typeof t=="string")try{return JSON.parse(t)}catch{return t}return t;case"BINARY":return t;default:return t}}function f(t,e){return t==null?null:e>0?typeof t=="string"?t:String(t):typeof t=="string"?parseInt(t,10):t}function p(t,e){if(typeof t!="string")return t instanceof Date?t:new Date(t);let r=t;if(e==="TIMESTAMP_TZ"){const s=t.indexOf(" ");s!==-1&&(r=t.slice(0,s))}if(!/^-?\d+(\.\d+)?$/.test(r))return new Date(t);const n=parseFloat(r);return Number.isFinite(n)?new Date(n*1e3):new Date(t)}function I(t,e){if(!t||t.length===0)return[];if(!e||e.length===0)return[];const r=new Array(t.length);for(let n=0;n<t.length;n++){const s=t[n],o={};for(let c=0;c<e.length;c++){const i=e[c];o[i.name]=T(s[c],i)}r[n]=o}return r}self.onmessage=t=>{const e=t.data;if(e&&e.type==="parseRows"){const r=I(e.data,e.rowType),n={id:e.id,rows:r};self.postMessage(n)}};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
function O(r){return Number.isNaN(r)||!Number.isFinite(r)?null:r}function z(r,f=!0){if(r.length===0)return 0n;let e=0n;for(let a=r.length-1;a>=0;a--)e=e<<32n|BigInt(r[a]>>>0);if(f){const a=r.length*32,s=1n<<BigInt(a-1);if(e>=s){const u=1n<<BigInt(a);e=e-u}}return e>BigInt(Number.MAX_SAFE_INTEGER)||e<BigInt(Number.MIN_SAFE_INTEGER)?e.toString():e}function W(r){return r>BigInt(Number.MAX_SAFE_INTEGER)||r<BigInt(Number.MIN_SAFE_INTEGER)?r.toString():Number(r)}function L(r){return r>BigInt(Number.MAX_SAFE_INTEGER)?r.toString():Number(r)}let M=null,d=null,S=null,H=[],k=null;const G=2,b=new Map,R=new Set;function P(){const r=globalThis;typeof r.gc=="function"&&r.gc()}setInterval(()=>{P()},15e3);function q(r,f,e,a,s){if(r==null)return r;if(typeof r=="object"&&r!==null&&!Array.isArray(r)&&e){let t=!1;for(const i of e.values())if(i.toLowerCase().includes("dictionary")){t=!0;break}if(t)try{const i=JSON.stringify(r);return JSON.parse(i)}catch{}}if(typeof r=="bigint")return r>Number.MAX_SAFE_INTEGER||r<Number.MIN_SAFE_INTEGER?r.toString():Number(r);if(r instanceof Date)return r.toISOString();if(typeof r!="object")return r;if(r.constructor?.name?.includes("Decimal")){const t=r.toString();try{const i=BigInt(t);if(i>BigInt(Number.MAX_SAFE_INTEGER)||i<BigInt(Number.MIN_SAFE_INTEGER))return t}catch{}return Number(t)}const p=Array.isArray(r),E=p?[]:{},h=[];if(p)for(let t=r.length-1;t>=0;t--)h.push([r[t],E,t,void 0]);else{const t=Object.keys(r);for(let i=t.length-1;i>=0;i--){const l=t[i];h.push([r[l],E,l,l])}}for(;h.length>0;){const[t,i,l,m]=h.pop();if(t==null){i[l]=t;continue}if(typeof t=="bigint"){t>Number.MAX_SAFE_INTEGER||t<Number.MIN_SAFE_INTEGER?i[l]=t.toString():i[l]=Number(t);continue}if(t instanceof Date){i[l]=t.toISOString();continue}if(typeof t!="object"){i[l]=t;continue}if(m&&e?.has(m)&&e.get(m).toLowerCase().includes("dictionary")){const o=String(t);if(o&&!o.startsWith("[object ")){i[l]=o;continue}}const A=t.constructor?.name;if(A?.includes("Decimal")){const n=t.toString();if(m&&f?.has(m)){const o=f.get(m);if(o>0){const y=Number(n),w=Math.pow(10,o);i[l]=y/w;continue}}try{const o=BigInt(n);o>BigInt(Number.MAX_SAFE_INTEGER)||o<BigInt(Number.MIN_SAFE_INTEGER)?i[l]=n:i[l]=Number(n)}catch{i[l]=Number(n)}continue}if(t instanceof Uint8Array){const n=Array.from(t).map(o=>o.toString(16).padStart(2,"0")).join("");i[l]=`0x${n}`;continue}if(t instanceof Uint32Array){const n=z(t);typeof n=="bigint"?i[l]=Number(n):i[l]=n;continue}if(t instanceof BigInt64Array){t.length===1?i[l]=W(t[0]):i[l]=Array.from(t).map(n=>W(n));continue}if(t instanceof BigUint64Array){t.length===1?i[l]=L(t[0]):i[l]=Array.from(t).map(n=>L(n));continue}if(t instanceof Float32Array){if(t.length===1){const n=O(t[0]);n===null&&(t[0],void 0),i[l]=n}else i[l]=Array.from(t).map(n=>O(n));continue}if(t instanceof Float64Array){if(t.length===1){const n=O(t[0]);n===null&&(t[0],void 0),i[l]=n}else i[l]=Array.from(t).map(n=>O(n));continue}if(m&&e?.get(m)?.toLowerCase().includes("interval")){let n=0,o=0,y=0;const w=a?.get(m);if(w&&s!==void 0){const g=s*4;if(g+3<w.length){n=w[g],o=w[g+1];const N=w[g+2]>>>0,_=w[g+3];y=N+_*4294967296}}else if(A==="Int32Array"){const g=t;g.length>=2&&(n=g[0]*12+g[1])}const c=[];if(n!==0){const g=Math.floor(Math.abs(n)/12),N=Math.abs(n)%12,_=n<0?"-":"";g!==0&&c.push(`${_}${g}y`),N!==0&&c.push(`${n<0&&g===0?"-":""}${N}mo`)}if(o!==0){const g=o<0?"-":"";c.push(`${g}${Math.abs(o)}d`)}if(y!==0){const g=Math.abs(y),N=y<0?"-":"",_=Math.floor(g/36e11),$=Math.floor(g%36e11/6e10),C=g%6e10,B=Math.floor(C/1e9),I=C%1e9;if(_!==0&&c.push(`${N}${_}h`),$!==0&&c.push(`${$}m`),B!==0||I!==0)if(I===0)c.push(`${B}s`);else if(I%1e6===0){const v=I/1e6;c.push(`${B}.${v.toString().padStart(3,"0")}s`)}else if(I%1e3===0){const v=I/1e3;c.push(`${B}.${v.toString().padStart(6,"0")}s`)}else c.push(`${B}.${I.toString().padStart(9,"0")}s`)}i[l]=c.length>0?c.join(" "):"0";continue}if(Array.isArray(t)){const n=[];i[l]=n;for(let o=t.length-1;o>=0;o--)h.push([t[o],n,o,m]);continue}if(typeof t.toJSON=="function"){const n=t.toJSON();h.push([n,i,l,m]);continue}if(t instanceof Map){const n={};i[l]=n;const o=Array.from(t.entries());for(let y=o.length-1;y>=0;y--){const[w,c]=o[y];h.push([c,n,String(w),String(w)])}continue}const D={};i[l]=D;const T=Object.keys(t);for(let n=T.length-1;n>=0;n--){const o=T[n];h.push([t[o],D,o,o])}}return E}async function U(){try{S&&await S.close(),d&&await d.terminate()}catch{}d=null,S=null}function x(r){return{mvp:{mainModule:`${r}/duckdb-mvp.wasm`,mainWorker:`${r}/duckdb-browser-mvp.worker.js`},eh:{mainModule:`${r}/duckdb-eh.wasm`,mainWorker:`${r}/duckdb-browser-eh.worker.js`},coi:{mainModule:`${r}/duckdb-coi.wasm`,mainWorker:`${r}/duckdb-browser-coi.worker.js`,pthreadWorker:`${r}/duckdb-browser-coi.pthread.worker.js`}}}async function X(r){for(const f of r)try{const e=f.eh?.mainModule||f.mvp?.mainModule;if(e&&(await fetch(e,{method:"HEAD"})).ok)return f}catch{}return null}self.addEventListener("message",async r=>{const f=r.data;try{if(f.type==="init"){const e=f.baseUrls||[];if(H=e,!M){const t=await import("./duckdb-browser-BX0LtQQW.js");M=t,k=t.DuckDBDataProtocol}const a=new M.ConsoleLogger(M.LogLevel.WARNING),s=e.map(t=>x(t));let u=await X(s);u||(u=M.getJsDelivrBundles());const p=u.eh||await M.selectBundle(u),E=new Worker(p.mainWorker);d=new M.AsyncDuckDB(a,E),await d.instantiate(p.mainModule,p.pthreadWorker);let h=!1;await d.open({path:":memory:",accessMode:M.DuckDBAccessMode.READ_WRITE}),S=await d.connect();try{await S.query("SET memory_limit=-1"),await S.query("SET threads=1"),await S.query("SET preserve_insertion_order=false");const t=Intl.DateTimeFormat().resolvedOptions().timeZone;t&&await S.query(`SET TimeZone='${t}'`)}catch(t){console.warn("[DuckDB] Config failed (non-critical):",t)}self.postMessage({type:"inited",opfsPersistence:h})}else if(f.type==="run"){const{id:e,sql:a}=f;b.set(e,0);try{if(S&&typeof S.queryArrowIPC=="function"){const s=await S.queryArrowIPC(a);for await(const u of s){for(;(b.get(e)||0)>=G;)await new Promise(p=>setTimeout(p,10));try{self.postMessage({type:"arrow",id:e,buffer:u},[u])}catch{self.postMessage({type:"arrow",id:e,buffer:u})}b.set(e,(b.get(e)||0)+1)}}else{const s=await S.query(a),u=new Map;if(s.schema?.fields){for(const p of s.schema.fields)if(p.type?.toString()?.includes("Interval")){const E=s.getChild(p.name);E?.data?.[0]?.values instanceof Int32Array&&u.set(p.name,E.data[0].values)}}if(s.toArrow){const p=s.toArrow();self.postMessage({type:"arrow",id:e,buffer:p},[p])}else{let p,E;if(s.schema&&s.schema.fields){p=new Map,E=new Map;const o=s.schema.fields.map(c=>{let g="UNKNOWN";return c.type&&typeof c.type.toString=="function"&&(g=c.type.toString()),E.set(c.name,g),c.type&&c.type.constructor?.name?.includes("Decimal")&&c.type.scale!==void 0&&p.set(c.name,c.type.scale),{name:c.name,type:g,nullable:c.nullable}}),y=JSON.stringify(o),w=new TextEncoder().encode(y).buffer;self.postMessage({type:"json-schema",id:e,buffer:w},[w])}const h=s.toArray?s.toArray():s,t=5*1024*1024,i=500,l=5e5;let m=[],A=0,F=0,D=0,T=0,n=0;for(let o=0;o<h.length&&!R.has(e);o++)try{const y=q(h[o],p,E,u,o),c=JSON.stringify(y).length;if(F+=c,c>T&&(T=c),c>l&&D++,m.length>0&&(A+c>t||m.length>=i)){const g=JSON.stringify(m),N=new TextEncoder().encode(g).buffer;for(self.postMessage({type:"json",id:e,buffer:N},[N]),n++,b.set(e,(b.get(e)||0)+1);(b.get(e)||0)>=G&&!R.has(e);)await new Promise(_=>setTimeout(_,10));m=[],A=0}m.push(y),A+=c}catch(y){const w=h[o],c=w&&typeof w=="object"?Object.keys(w):[];console.error(`[DuckDB Worker] Row ${o} failed to serialize:`,{error:String(y),errorName:y.name,rowKeys:c.slice(0,10)}),m.push({__error:`Row ${o} failed: ${y.name}`}),A+=100}if(m.length>0&&!R.has(e)){const o=JSON.stringify(m),y=new TextEncoder().encode(o).buffer;self.postMessage({type:"json",id:e,buffer:y},[y]),n++,b.set(e,(b.get(e)||0)+1)}self.postMessage({type:"query-stats",id:e,stats:{totalRows:h.length,totalBytes:F,largeRowCount:D,maxRowSize:T,chunkCount:n,avgRowSize:h.length>0?Math.round(F/h.length):0}})}}}catch(s){const u=String(s);u.includes("database has been invalidated")||u.includes("FATAL Error")?(await U(),self.postMessage({type:"error",id:e,error:"Database encountered a fatal error and has been reset. Please reload the page to reinitialize."})):u.includes("Out of Memory")||u.includes("Allocation failure")?self.postMessage({type:"error",id:e,error:`Out of Memory: The query or file is too large to process in the browser. Try:
|
|
2
|
+
1. Querying smaller subsets using LIMIT or WHERE clauses
|
|
3
|
+
2. Using SELECT with specific columns instead of SELECT *
|
|
4
|
+
3. Processing smaller files
|
|
5
|
+
4. Using COUNT(*) with LIMIT for large tables`}):self.postMessage({type:"error",id:e,error:u})}finally{self.postMessage({type:"done",id:e}),b.delete(e),R.delete(e),P()}}else if(f.type==="ack"){const{id:e}=f,a=b.get(e)||0;b.set(e,Math.max(0,a-1))}else if(f.type==="cancel"){const{id:e}=f;R.add(e),self.postMessage({type:"cancelled",id:e})}else if(f.type==="register_file"){const{id:e,fileName:a,fileBuffer:s}=f;try{if(!d)throw new Error("Database not initialized");await d.registerFileBuffer(a,new Uint8Array(s)),self.postMessage({type:"file_registered",id:e})}catch(u){self.postMessage({type:"error",id:e,error:String(u)})}}else if(f.type==="copy_file_to_buffer"){const{id:e,fileName:a}=f;try{if(!d)throw new Error("Database not initialized");const s=await d.copyFileToBuffer(a);self.postMessage({type:"file_buffer",id:e,buffer:s},[s.buffer])}catch(s){self.postMessage({type:"error",id:e,error:String(s)})}}else if(f.type==="register_file_handle"){const{id:e,fileName:a,file:s}=f;try{if(!d)throw new Error("Database not initialized");if(!k)throw new Error("DuckDBDataProtocol not loaded");await d.registerFileHandle(a,s,k.BROWSER_FILEREADER,!0),self.postMessage({type:"file_registered",id:e})}catch(u){self.postMessage({type:"error",id:e,error:String(u)})}}else if(f.type==="drop_file"){const{id:e,fileName:a}=f;try{if(!d)throw new Error("Database not initialized");await d.dropFile(a),self.postMessage({type:"file_dropped",id:e})}catch(s){self.postMessage({type:"error",id:e,error:String(s)})}}else if(f.type==="opfs_register_output"){const{id:e,fileName:a}=f;try{if(!d)throw new Error("Database not initialized");if(!k)throw new Error("DuckDBDataProtocol not loaded");const u=await(await navigator.storage.getDirectory()).getFileHandle(a,{create:!0});await d.registerFileHandle(a,u,k.BROWSER_FSACCESS,!0),self.postMessage({type:"opfs_output_registered",id:e})}catch(s){self.postMessage({type:"error",id:e,error:String(s)})}}else if(f.type==="opfs_release_output"){const{id:e,fileName:a}=f;try{if(!d)throw new Error("Database not initialized");await d.dropFile(a),self.postMessage({type:"opfs_output_released",id:e})}catch(s){self.postMessage({type:"error",id:e,error:String(s)})}}else if(f.type==="opfs_probe"){const{id:e}=f,a=`__opfs_probe_${Date.now()}.parquet`,s=async()=>{try{await(await navigator.storage.getDirectory()).removeEntry(a)}catch{}};try{if(!d||!S||!k)throw new Error("Database not initialized");const u=await navigator.storage.getDirectory(),p=await u.getFileHandle(a,{create:!0});await d.registerFileHandle(a,p,k.BROWSER_FSACCESS,!0),await S.query(`COPY (SELECT 1 AS a) TO '${a}' (FORMAT PARQUET)`),await d.dropFile(a);const h=(await(await u.getFileHandle(a)).getFile()).size>0;await s(),self.postMessage({type:"opfs_probe_result",id:e,ok:h})}catch{await s(),self.postMessage({type:"opfs_probe_result",id:e,ok:!1})}}}catch(e){self.postMessage({type:"error",error:String(e)})}});
|
package/assets/index.html
CHANGED
|
@@ -7,6 +7,33 @@
|
|
|
7
7
|
<meta name="description" content="Lightweight browser-native SQL utility powered by DuckDB. No install, just query. Run SQL queries entirely in your browser with zero setup.">
|
|
8
8
|
<meta name="keywords" content="sql, duckdb, browser, database, query, data analysis, wasm, browser-native, no install">
|
|
9
9
|
|
|
10
|
+
<!--
|
|
11
|
+
Content Security Policy. Always-on baseline; HTTP-header CSP from
|
|
12
|
+
cli.js / vercel.json takes precedence when present and adds
|
|
13
|
+
frame-ancestors (which is meta-incompatible).
|
|
14
|
+
- 'wasm-unsafe-eval' is required by DuckDB-WASM
|
|
15
|
+
- connect-src https: is required for DuckDB httpfs (queries against
|
|
16
|
+
arbitrary remote CSV/Parquet URLs); known endpoints listed
|
|
17
|
+
explicitly for documentation even though https: subsumes them
|
|
18
|
+
- http://localhost:4213 is the DuckDB CLI's `-ui` server (server
|
|
19
|
+
mode). Without it the mode-detection probe to /info is blocked,
|
|
20
|
+
including under the vite dev server, so server mode never detects.
|
|
21
|
+
- blob: for DuckDB worker module URLs
|
|
22
|
+
-->
|
|
23
|
+
<meta http-equiv="Content-Security-Policy" content="
|
|
24
|
+
default-src 'self';
|
|
25
|
+
script-src 'self' 'wasm-unsafe-eval';
|
|
26
|
+
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
|
|
27
|
+
font-src 'self' data: https://fonts.gstatic.com;
|
|
28
|
+
img-src 'self' data: blob:;
|
|
29
|
+
connect-src 'self' https: http://localhost:4213 blob: data:;
|
|
30
|
+
worker-src 'self' blob:;
|
|
31
|
+
object-src 'none';
|
|
32
|
+
base-uri 'self';
|
|
33
|
+
form-action 'self';
|
|
34
|
+
">
|
|
35
|
+
<meta name="referrer" content="no-referrer">
|
|
36
|
+
|
|
10
37
|
<!-- Google Fonts for editor font options -->
|
|
11
38
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
12
39
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
@@ -14,8 +41,8 @@
|
|
|
14
41
|
|
|
15
42
|
<!-- Favicon - database icon in gradient rounded square -->
|
|
16
43
|
<link rel="icon" type="image/svg+xml" href="./logo/favicon.svg">
|
|
17
|
-
<script type="module" crossorigin src="./assets/main-
|
|
18
|
-
<link rel="modulepreload" crossorigin href="./assets/oauth-constants-
|
|
44
|
+
<script type="module" crossorigin src="./assets/main-BAj1_oUZ.js"></script>
|
|
45
|
+
<link rel="modulepreload" crossorigin href="./assets/oauth-constants-deHgNN8Q.js">
|
|
19
46
|
<link rel="modulepreload" crossorigin href="./assets/react-vendor-B2Ij4Vfr.js">
|
|
20
47
|
<link rel="modulepreload" crossorigin href="./assets/monaco-editor-CbzSR0rd.js">
|
|
21
48
|
<link rel="stylesheet" crossorigin href="./assets/monaco-editor-DvqauXKu.css">
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
color: #ff6b6b;
|
|
46
46
|
}
|
|
47
47
|
</style>
|
|
48
|
-
<script type="module" crossorigin src="./assets/oauth-callback-
|
|
49
|
-
<link rel="modulepreload" crossorigin href="./assets/oauth-constants-
|
|
48
|
+
<script type="module" crossorigin src="./assets/oauth-callback-D-QMdUuo.js"></script>
|
|
49
|
+
<link rel="modulepreload" crossorigin href="./assets/oauth-constants-deHgNN8Q.js">
|
|
50
50
|
</head>
|
|
51
51
|
<body>
|
|
52
52
|
<div class="box">
|
package/dist/cli.js
CHANGED
|
@@ -228,6 +228,28 @@ const server = createServer((req, res) => {
|
|
|
228
228
|
'Content-Type': contentType,
|
|
229
229
|
'Content-Length': content.length,
|
|
230
230
|
'Cache-Control': 'no-cache',
|
|
231
|
+
// Security headers - mirror the production posture (sql.dbxlite.com)
|
|
232
|
+
// so the npm-distributed build doesn't have a weaker baseline than
|
|
233
|
+
// the hosted version. CSP also lives in index.html as a meta tag;
|
|
234
|
+
// the HTTP header here adds frame-ancestors (which meta CSP can't
|
|
235
|
+
// express) and ensures any non-HTML asset (JS, WASM) is served with
|
|
236
|
+
// a CSP too.
|
|
237
|
+
'Content-Security-Policy':
|
|
238
|
+
"default-src 'self'; " +
|
|
239
|
+
"script-src 'self' 'wasm-unsafe-eval'; " +
|
|
240
|
+
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
|
|
241
|
+
"font-src 'self' data: https://fonts.gstatic.com; " +
|
|
242
|
+
"img-src 'self' data: blob:; " +
|
|
243
|
+
"connect-src 'self' https: http://localhost:4213 blob: data:; " +
|
|
244
|
+
"worker-src 'self' blob:; " +
|
|
245
|
+
"object-src 'none'; " +
|
|
246
|
+
"base-uri 'self'; " +
|
|
247
|
+
"form-action 'self'; " +
|
|
248
|
+
"frame-ancestors 'none';",
|
|
249
|
+
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
250
|
+
'Cross-Origin-Embedder-Policy': 'credentialless',
|
|
251
|
+
'Referrer-Policy': 'no-referrer',
|
|
252
|
+
'X-Content-Type-Options': 'nosniff',
|
|
231
253
|
});
|
|
232
254
|
res.end(content);
|
|
233
255
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as l,b as h,c as u}from"./oauth-constants-m7PlKcMR.js";const y="bigquery_oauth_response",_="bigquery_oauth_error",n=new URLSearchParams(window.location.search),s=n.get("code"),o=n.get("state"),d=n.get("error"),g=n.get("error_description"),p=document.getElementById("spinner"),r=document.getElementById("status"),a=(e,t)=>{r&&(r.textContent=e,t&&(r.className=t)),p&&t&&(p.style.display="none")},c=e=>{try{localStorage.setItem(h,e)}catch{}try{localStorage.setItem(y,JSON.stringify({type:"oauth_code",code:JSON.parse(e).code,state:JSON.parse(e).state,timestamp:Date.now()}))}catch{}},m=e=>{try{localStorage.setItem(u,e)}catch{}try{localStorage.setItem(_,e)}catch{}};s&&o&&c(JSON.stringify({code:s,state:o,timestamp:Date.now()}));if(d){const e=g||d;if(a(`Authentication failed: ${e}`,"error"),m(e),typeof BroadcastChannel<"u")try{const t=new BroadcastChannel(l);t.postMessage({type:"oauth_error",error:e,state:o}),setTimeout(()=>t.close(),1e3)}catch{}if(window.opener)try{window.opener.postMessage({type:"oauth_error",error:e,state:o},window.location.origin)}catch{}setTimeout(()=>window.close(),3e3)}else if(s&&o){a("Authentication successful. Closing…","success");const e=JSON.stringify({code:s,state:o,timestamp:Date.now()});if(c(e),typeof BroadcastChannel<"u")try{const i=new BroadcastChannel(l);i.postMessage({type:"oauth_code",code:s,state:o}),setTimeout(()=>i.close(),1e3)}catch{}if(window.opener)try{window.opener.postMessage({type:"oauth_code",code:s,state:o},window.location.origin)}catch{}let t=0;const w=setInterval(()=>{t++,c(e),t>=6&&(clearInterval(w),window.close())},500)}else a("Missing authorization code. Please try again.","error"),setTimeout(()=>window.close(),3e3);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))s(e);new MutationObserver(e=>{for(const t of e)if(t.type==="childList")for(const r of t.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&s(r)}).observe(document,{childList:!0,subtree:!0});function n(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?t.credentials="include":e.crossOrigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function s(e){if(e.ep)return;e.ep=!0;const t=n(e);fetch(e.href,t)}})();const i="snowflake_oauth_response",u="snowflake_oauth_error",a="snowflake-auto-connect",f="snowflake_oauth";export{a as S,f as a,i as b,u as c};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
function R(n){return Number.isNaN(n)||!Number.isFinite(n)?null:n}function P(n,u=!0){if(n.length===0)return 0n;let t=0n;for(let g=n.length-1;g>=0;g--)t=t<<32n|BigInt(n[g]>>>0);if(u){const g=n.length*32,c=1n<<BigInt(g-1);if(t>=c){const f=1n<<BigInt(g);t=t-f}}return t>BigInt(Number.MAX_SAFE_INTEGER)||t<BigInt(Number.MIN_SAFE_INTEGER)?t.toString():t}function C(n){return n>BigInt(Number.MAX_SAFE_INTEGER)||n<BigInt(Number.MIN_SAFE_INTEGER)?n.toString():Number(n)}function G(n){return n>BigInt(Number.MAX_SAFE_INTEGER)?n.toString():Number(n)}let _=null,w=null,b=null,q=[],F=null;const W=2,S=new Map;function L(){const n=globalThis;typeof n.gc=="function"&&n.gc()}setInterval(()=>{L()},15e3);function x(n,u,t,g,c){if(n==null)return n;if(typeof n=="object"&&n!==null&&!Array.isArray(n)&&t){let e=!1;for(const o of t.values())if(o.toLowerCase().includes("dictionary")){e=!0;break}if(e)try{const o=JSON.stringify(n);return JSON.parse(o)}catch{}}if(typeof n=="bigint")return n>Number.MAX_SAFE_INTEGER||n<Number.MIN_SAFE_INTEGER?n.toString():Number(n);if(n instanceof Date)return n.toISOString();if(typeof n!="object")return n;if(n.constructor?.name?.includes("Decimal")){const e=n.toString();try{const o=BigInt(e);if(o>BigInt(Number.MAX_SAFE_INTEGER)||o<BigInt(Number.MIN_SAFE_INTEGER))return e}catch{}return Number(e)}const m=Array.isArray(n),N=m?[]:{},d=[];if(m)for(let e=n.length-1;e>=0;e--)d.push([n[e],N,e,void 0]);else{const e=Object.keys(n);for(let o=e.length-1;o>=0;o--){const a=e[o];d.push([n[a],N,a,a])}}for(;d.length>0;){const[e,o,a,p]=d.pop();if(e==null){o[a]=e;continue}if(typeof e=="bigint"){e>Number.MAX_SAFE_INTEGER||e<Number.MIN_SAFE_INTEGER?o[a]=e.toString():o[a]=Number(e);continue}if(e instanceof Date){o[a]=e.toISOString();continue}if(typeof e!="object"){o[a]=e;continue}if(p&&t?.has(p)&&t.get(p).toLowerCase().includes("dictionary")){const s=String(e);if(s&&!s.startsWith("[object ")){o[a]=s;continue}}const A=e.constructor?.name;if(A?.includes("Decimal")){const r=e.toString();if(p&&u?.has(p)){const s=u.get(p);if(s>0){const y=Number(r),h=Math.pow(10,s);o[a]=y/h;continue}}try{const s=BigInt(r);s>BigInt(Number.MAX_SAFE_INTEGER)||s<BigInt(Number.MIN_SAFE_INTEGER)?o[a]=r:o[a]=Number(r)}catch{o[a]=Number(r)}continue}if(e instanceof Uint8Array){const r=Array.from(e).map(s=>s.toString(16).padStart(2,"0")).join("");o[a]=`0x${r}`;continue}if(e instanceof Uint32Array){const r=P(e);typeof r=="bigint"?o[a]=Number(r):o[a]=r;continue}if(e instanceof BigInt64Array){e.length===1?o[a]=C(e[0]):o[a]=Array.from(e).map(r=>C(r));continue}if(e instanceof BigUint64Array){e.length===1?o[a]=G(e[0]):o[a]=Array.from(e).map(r=>G(r));continue}if(e instanceof Float32Array){if(e.length===1){const r=R(e[0]);r===null&&(e[0],void 0),o[a]=r}else o[a]=Array.from(e).map(r=>R(r));continue}if(e instanceof Float64Array){if(e.length===1){const r=R(e[0]);r===null&&(e[0],void 0),o[a]=r}else o[a]=Array.from(e).map(r=>R(r));continue}if(p&&t?.get(p)?.toLowerCase().includes("interval")){let r=0,s=0,y=0;const h=g?.get(p);if(h&&c!==void 0){const l=c*4;if(l+3<h.length){r=h[l],s=h[l+1];const E=h[l+2]>>>0,M=h[l+3];y=E+M*4294967296}}else if(A==="Int32Array"){const l=e;l.length>=2&&(r=l[0]*12+l[1])}const i=[];if(r!==0){const l=Math.floor(Math.abs(r)/12),E=Math.abs(r)%12,M=r<0?"-":"";l!==0&&i.push(`${M}${l}y`),E!==0&&i.push(`${r<0&&l===0?"-":""}${E}mo`)}if(s!==0){const l=s<0?"-":"";i.push(`${l}${Math.abs(s)}d`)}if(y!==0){const l=Math.abs(y),E=y<0?"-":"",M=Math.floor(l/36e11),O=Math.floor(l%36e11/6e10),v=l%6e10,B=Math.floor(v/1e9),I=v%1e9;if(M!==0&&i.push(`${E}${M}h`),O!==0&&i.push(`${O}m`),B!==0||I!==0)if(I===0)i.push(`${B}s`);else if(I%1e6===0){const $=I/1e6;i.push(`${B}.${$.toString().padStart(3,"0")}s`)}else if(I%1e3===0){const $=I/1e3;i.push(`${B}.${$.toString().padStart(6,"0")}s`)}else i.push(`${B}.${I.toString().padStart(9,"0")}s`)}o[a]=i.length>0?i.join(" "):"0";continue}if(Array.isArray(e)){const r=[];o[a]=r;for(let s=e.length-1;s>=0;s--)d.push([e[s],r,s,p]);continue}if(typeof e.toJSON=="function"){const r=e.toJSON();d.push([r,o,a,p]);continue}if(e instanceof Map){const r={};o[a]=r;const s=Array.from(e.entries());for(let y=s.length-1;y>=0;y--){const[h,i]=s[y];d.push([i,r,String(h),String(h)])}continue}const T={};o[a]=T;const k=Object.keys(e);for(let r=k.length-1;r>=0;r--){const s=k[r];d.push([e[s],T,s,s])}}return N}async function U(){try{b&&await b.close(),w&&await w.terminate()}catch{}w=null,b=null}function X(n){return{mvp:{mainModule:`${n}/duckdb-mvp.wasm`,mainWorker:`${n}/duckdb-browser-mvp.worker.js`},eh:{mainModule:`${n}/duckdb-eh.wasm`,mainWorker:`${n}/duckdb-browser-eh.worker.js`},coi:{mainModule:`${n}/duckdb-coi.wasm`,mainWorker:`${n}/duckdb-browser-coi.worker.js`,pthreadWorker:`${n}/duckdb-browser-coi.pthread.worker.js`}}}async function z(n){for(const u of n)try{const t=u.eh?.mainModule||u.mvp?.mainModule;if(t&&(await fetch(t,{method:"HEAD"})).ok)return u}catch{}return null}self.addEventListener("message",async n=>{const u=n.data;try{if(u.type==="init"){const t=u.baseUrls||[];if(q=t,!_){const e=await import("./duckdb-browser-BX0LtQQW.js");_=e,F=e.DuckDBDataProtocol}const g=new _.ConsoleLogger,c=t.map(e=>X(e));let f=await z(c);f||(f=_.getJsDelivrBundles());const m=f.eh||await _.selectBundle(f),N=new Worker(m.mainWorker);w=new _.AsyncDuckDB(g,N),await w.instantiate(m.mainModule,m.pthreadWorker);let d=!1;await w.open({path:":memory:",accessMode:_.DuckDBAccessMode.READ_WRITE}),b=await w.connect();try{await b.query("SET memory_limit=-1"),await b.query("SET threads=1"),await b.query("SET preserve_insertion_order=false");const e=Intl.DateTimeFormat().resolvedOptions().timeZone;e&&await b.query(`SET TimeZone='${e}'`)}catch(e){console.warn("[DuckDB] Config failed (non-critical):",e)}self.postMessage({type:"inited",opfsPersistence:d})}else if(u.type==="run"){const{id:t,sql:g}=u;S.set(t,0);try{if(b&&typeof b.queryArrowIPC=="function"){const c=await b.queryArrowIPC(g);for await(const f of c){for(;(S.get(t)||0)>=W;)await new Promise(m=>setTimeout(m,10));try{self.postMessage({type:"arrow",id:t,buffer:f},[f])}catch{self.postMessage({type:"arrow",id:t,buffer:f})}S.set(t,(S.get(t)||0)+1)}}else{const c=await b.query(g),f=new Map;if(c.schema?.fields){for(const m of c.schema.fields)if(m.type?.toString()?.includes("Interval")){const N=c.getChild(m.name);N?.data?.[0]?.values instanceof Int32Array&&f.set(m.name,N.data[0].values)}}if(c.toArrow){const m=c.toArrow();self.postMessage({type:"arrow",id:t,buffer:m},[m])}else{let m,N;if(c.schema&&c.schema.fields){m=new Map,N=new Map;const s=c.schema.fields.map(i=>{let l="UNKNOWN";return i.type&&typeof i.type.toString=="function"&&(l=i.type.toString()),N.set(i.name,l),i.type&&i.type.constructor?.name?.includes("Decimal")&&i.type.scale!==void 0&&m.set(i.name,i.type.scale),{name:i.name,type:l,nullable:i.nullable}}),y=JSON.stringify(s),h=new TextEncoder().encode(y).buffer;self.postMessage({type:"json-schema",id:t,buffer:h},[h])}const d=c.toArray?c.toArray():c,e=5*1024*1024,o=500,a=5e5;let p=[],A=0,D=0,T=0,k=0,r=0;for(let s=0;s<d.length;s++)try{const y=x(d[s],m,N,f,s),i=JSON.stringify(y).length;if(D+=i,i>k&&(k=i),i>a&&T++,p.length>0&&(A+i>e||p.length>=o)){const l=JSON.stringify(p),E=new TextEncoder().encode(l).buffer;for(self.postMessage({type:"json",id:t,buffer:E},[E]),r++,S.set(t,(S.get(t)||0)+1);(S.get(t)||0)>=W;)await new Promise(M=>setTimeout(M,10));p=[],A=0}p.push(y),A+=i}catch(y){const h=d[s],i=h&&typeof h=="object"?Object.keys(h):[];console.error(`[DuckDB Worker] Row ${s} failed to serialize:`,{error:String(y),errorName:y.name,rowKeys:i.slice(0,10)}),p.push({__error:`Row ${s} failed: ${y.name}`}),A+=100}if(p.length>0){const s=JSON.stringify(p),y=new TextEncoder().encode(s).buffer;self.postMessage({type:"json",id:t,buffer:y},[y]),r++,S.set(t,(S.get(t)||0)+1)}self.postMessage({type:"query-stats",id:t,stats:{totalRows:d.length,totalBytes:D,largeRowCount:T,maxRowSize:k,chunkCount:r,avgRowSize:d.length>0?Math.round(D/d.length):0}})}}}catch(c){const f=String(c);f.includes("database has been invalidated")||f.includes("FATAL Error")?(await U(),self.postMessage({type:"error",id:t,error:"Database encountered a fatal error and has been reset. Please reload the page to reinitialize."})):f.includes("Out of Memory")||f.includes("Allocation failure")?self.postMessage({type:"error",id:t,error:`Out of Memory: The query or file is too large to process in the browser. Try:
|
|
2
|
-
1. Querying smaller subsets using LIMIT or WHERE clauses
|
|
3
|
-
2. Using SELECT with specific columns instead of SELECT *
|
|
4
|
-
3. Processing smaller files
|
|
5
|
-
4. Using COUNT(*) with LIMIT for large tables`}):self.postMessage({type:"error",id:t,error:f})}finally{self.postMessage({type:"done",id:t}),S.delete(t),L()}}else if(u.type==="ack"){const{id:t}=u,g=S.get(t)||0;S.set(t,Math.max(0,g-1))}else if(u.type==="cancel"){const{id:t}=u;self.postMessage({type:"cancelled",id:t})}else if(u.type==="register_file"){const{id:t,fileName:g,fileBuffer:c}=u;try{if(!w)throw new Error("Database not initialized");await w.registerFileBuffer(g,new Uint8Array(c)),self.postMessage({type:"file_registered",id:t})}catch(f){self.postMessage({type:"error",id:t,error:String(f)})}}else if(u.type==="copy_file_to_buffer"){const{id:t,fileName:g}=u;try{if(!w)throw new Error("Database not initialized");const c=await w.copyFileToBuffer(g);self.postMessage({type:"file_buffer",id:t,buffer:c},[c.buffer])}catch(c){self.postMessage({type:"error",id:t,error:String(c)})}}else if(u.type==="register_file_handle"){const{id:t,fileName:g,file:c}=u;try{if(!w)throw new Error("Database not initialized");if(!F)throw new Error("DuckDBDataProtocol not loaded");await w.registerFileHandle(g,c,F.BROWSER_FILEREADER,!0),self.postMessage({type:"file_registered",id:t})}catch(f){self.postMessage({type:"error",id:t,error:String(f)})}}}catch(t){self.postMessage({type:"error",error:String(t)})}});
|