dbxlite-ui 0.3.1 → 0.3.3

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/index.html CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  <!-- Favicon - database icon in gradient rounded square -->
16
16
  <link rel="icon" type="image/svg+xml" href="./logo/favicon.svg">
17
- <script type="module" crossorigin src="./assets/main-D7VyIWiO.js"></script>
17
+ <script type="module" crossorigin src="./assets/main-CyH5V7SF.js"></script>
18
18
  <link rel="modulepreload" crossorigin href="./assets/oauth-constants-m7PlKcMR.js">
19
19
  <link rel="modulepreload" crossorigin href="./assets/react-vendor-B2Ij4Vfr.js">
20
20
  <link rel="modulepreload" crossorigin href="./assets/monaco-editor-CbzSR0rd.js">
package/dist/cli.js CHANGED
@@ -160,12 +160,43 @@ function findAssetsDir() {
160
160
  const ASSETS_DIR = findAssetsDir();
161
161
  console.log(`Assets directory: ${ASSETS_DIR}`);
162
162
 
163
+ // SPA-route prefixes that map to actual on-disk asset folders. Any path
164
+ // outside these prefixes that doesn't resolve to a file falls back to
165
+ // index.html so the React router can handle it (mirrors the Vercel rewrite).
166
+ const ASSET_PREFIXES = ['/assets/', '/duckdb/', '/sql-templates/', '/logo/', '/screenshots/'];
167
+ const ASSET_FILES = ['/robots.txt', '/sitemap.xml', '/favicon.ico'];
168
+ // API prefixes never fall back to index.html — they're CORS-proxy paths
169
+ // (Snowflake, BigQuery) that exist in the Vercel deployment but not here.
170
+ // Returning index.html for these breaks the connector with "Unexpected
171
+ // token '<'" when it tries to JSON.parse the HTML response.
172
+ const API_PREFIXES = ['/api/'];
173
+
174
+ function isAssetPath(urlPath) {
175
+ return ASSET_PREFIXES.some(p => urlPath.startsWith(p)) || ASSET_FILES.includes(urlPath);
176
+ }
177
+
178
+ function isApiPath(urlPath) {
179
+ return API_PREFIXES.some(p => urlPath.startsWith(p));
180
+ }
181
+
163
182
  // Create asset server
164
183
  const server = createServer((req, res) => {
165
184
  let urlPath = req.url.split('?')[0];
166
185
  if (urlPath === '/') urlPath = '/index.html';
167
186
 
168
- const filePath = join(ASSETS_DIR, urlPath);
187
+ // Cloud API proxy paths (Snowflake / BigQuery CORS proxies) only exist in
188
+ // the Vercel deployment. Locally we 501 with a JSON body so the connector
189
+ // can show a clear error instead of choking on HTML.
190
+ if (isApiPath(urlPath)) {
191
+ res.writeHead(501, { 'Content-Type': 'application/json' });
192
+ res.end(JSON.stringify({
193
+ error: 'cloud_proxy_unavailable',
194
+ message: `${urlPath} requires the dbxlite-cloud proxy. Use sql.dbxlite.com for Snowflake/BigQuery, or run dbxlite locally only for DuckDB.`,
195
+ }));
196
+ return;
197
+ }
198
+
199
+ let filePath = join(ASSETS_DIR, urlPath);
169
200
 
170
201
  // Security: prevent directory traversal
171
202
  if (!filePath.startsWith(ASSETS_DIR)) {
@@ -175,10 +206,18 @@ const server = createServer((req, res) => {
175
206
  }
176
207
 
177
208
  try {
178
- if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
179
- res.writeHead(404, { 'Content-Type': 'text/plain', 'Content-Length': 9 });
180
- res.end('Not found');
181
- return;
209
+ const missing = !existsSync(filePath) || statSync(filePath).isDirectory();
210
+ if (missing) {
211
+ // SPA fallback: non-asset routes (e.g. /examples, /screenshots-page)
212
+ // serve index.html so the React router can handle them. True asset
213
+ // misses (under /assets/, /duckdb/, etc.) still 404.
214
+ if (!isAssetPath(urlPath) && urlPath !== '/index.html') {
215
+ filePath = join(ASSETS_DIR, 'index.html');
216
+ } else {
217
+ res.writeHead(404, { 'Content-Type': 'text/plain', 'Content-Length': 9 });
218
+ res.end('Not found');
219
+ return;
220
+ }
182
221
  }
183
222
 
184
223
  const content = readFileSync(filePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbxlite-ui",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Local UI for DuckDB - replaces duckdb -ui with dbxlite",
5
5
  "homepage": "https://github.com/hfmsio/dbxlite",
6
6
  "bugs": "https://github.com/hfmsio/dbxlite/issues",