@walkthru-earth/objex-utils 0.1.0 → 1.1.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/dist/index.cjs CHANGED
@@ -1,6 +1,26 @@
1
1
  'use strict';
2
2
 
3
3
  var apacheArrow = require('apache-arrow');
4
+ var YAML = require('yaml');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var YAML__default = /*#__PURE__*/_interopDefault(YAML);
9
+
10
+ // ../../src/lib/constants.ts
11
+ var STORAGE_KEYS = {
12
+ SETTINGS: "obstore-explore-settings",
13
+ CONNECTIONS: "obstore-explore-connections",
14
+ QUERY_HISTORY: "obstore-explore-query-history"
15
+ };
16
+ var WGS84_CODES = /* @__PURE__ */ new Set([4326, 4979]);
17
+ var DEFAULT_TARGET_CRS = "EPSG:4326";
18
+ var DUCKDB_INIT_TIMEOUT_MS = 3e4;
19
+ var MAX_QUERY_HISTORY_ENTRIES = 200;
20
+ var SQL_PREVIEW_LENGTH = 120;
21
+ var VIEWER_DIR_EXTENSIONS = /* @__PURE__ */ new Set(["zarr", "zr3"]);
22
+ var LAYER_HUE_MULTIPLIER = 137;
23
+ var COPY_FEEDBACK_MS = 2e3;
4
24
 
5
25
  // ../../src/lib/file-icons/index.ts
6
26
  var DEFAULT_INFO = {
@@ -1000,6 +1020,11 @@ var EXTENSIONS = {
1000
1020
  }
1001
1021
  };
1002
1022
  function getFileTypeInfo(extension, isDir = false) {
1023
+ if (isDir && extension) {
1024
+ const ext2 = extension.startsWith(".") ? extension.toLowerCase() : `.${extension.toLowerCase()}`;
1025
+ const found = EXTENSIONS[ext2];
1026
+ if (found) return found;
1027
+ }
1003
1028
  if (isDir) return FOLDER_INFO;
1004
1029
  const ext = extension.startsWith(".") ? extension.toLowerCase() : `.${extension.toLowerCase()}`;
1005
1030
  return EXTENSIONS[ext] ?? DEFAULT_INFO;
@@ -1039,6 +1064,304 @@ var QueryCancelledError = class extends Error {
1039
1064
  }
1040
1065
  };
1041
1066
 
1067
+ // ../../src/lib/storage/providers.ts
1068
+ var PROVIDERS = {
1069
+ s3: {
1070
+ label: "AWS S3",
1071
+ description: "Amazon S3 or any S3-compatible service",
1072
+ authMethod: "sigv4",
1073
+ needsRegion: true,
1074
+ needsEndpoint: false,
1075
+ defaultRegion: "us-east-1",
1076
+ endpointTemplate: null,
1077
+ regions: [
1078
+ { code: "us-east-1", label: "US East (N. Virginia)" },
1079
+ { code: "us-east-2", label: "US East (Ohio)" },
1080
+ { code: "us-west-1", label: "US West (N. California)" },
1081
+ { code: "us-west-2", label: "US West (Oregon)" },
1082
+ { code: "eu-west-1", label: "EU (Ireland)" },
1083
+ { code: "eu-west-2", label: "EU (London)" },
1084
+ { code: "eu-west-3", label: "EU (Paris)" },
1085
+ { code: "eu-central-1", label: "EU (Frankfurt)" },
1086
+ { code: "eu-central-2", label: "EU (Zurich)" },
1087
+ { code: "eu-north-1", label: "EU (Stockholm)" },
1088
+ { code: "eu-south-1", label: "EU (Milan)" },
1089
+ { code: "eu-south-2", label: "EU (Spain)" },
1090
+ { code: "ap-northeast-1", label: "Asia Pacific (Tokyo)" },
1091
+ { code: "ap-northeast-2", label: "Asia Pacific (Seoul)" },
1092
+ { code: "ap-northeast-3", label: "Asia Pacific (Osaka)" },
1093
+ { code: "ap-southeast-1", label: "Asia Pacific (Singapore)" },
1094
+ { code: "ap-southeast-2", label: "Asia Pacific (Sydney)" },
1095
+ { code: "ap-southeast-3", label: "Asia Pacific (Jakarta)" },
1096
+ { code: "ap-south-1", label: "Asia Pacific (Mumbai)" },
1097
+ { code: "ap-south-2", label: "Asia Pacific (Hyderabad)" },
1098
+ { code: "ap-east-1", label: "Asia Pacific (Hong Kong)" },
1099
+ { code: "sa-east-1", label: "South America (S\xE3o Paulo)" },
1100
+ { code: "ca-central-1", label: "Canada (Central)" },
1101
+ { code: "ca-west-1", label: "Canada (Calgary)" },
1102
+ { code: "me-south-1", label: "Middle East (Bahrain)" },
1103
+ { code: "me-central-1", label: "Middle East (UAE)" },
1104
+ { code: "af-south-1", label: "Africa (Cape Town)" },
1105
+ { code: "il-central-1", label: "Israel (Tel Aviv)" }
1106
+ ],
1107
+ endpointPlaceholder: "Leave empty for AWS, or enter custom S3 endpoint",
1108
+ schemes: ["s3", "s3a", "s3n", "aws"]
1109
+ },
1110
+ gcs: {
1111
+ label: "Google Cloud",
1112
+ description: "Google Cloud Storage",
1113
+ authMethod: "sigv4",
1114
+ needsRegion: false,
1115
+ needsEndpoint: false,
1116
+ defaultRegion: "auto",
1117
+ endpointTemplate: "https://storage.googleapis.com",
1118
+ regions: [],
1119
+ endpointPlaceholder: "https://storage.googleapis.com",
1120
+ schemes: ["gs", "gcs"]
1121
+ },
1122
+ r2: {
1123
+ label: "Cloudflare R2",
1124
+ description: "Cloudflare R2 Storage",
1125
+ authMethod: "sigv4",
1126
+ needsRegion: false,
1127
+ needsEndpoint: true,
1128
+ defaultRegion: "auto",
1129
+ endpointTemplate: null,
1130
+ regions: [],
1131
+ endpointPlaceholder: "https://<account-id>.r2.cloudflarestorage.com",
1132
+ schemes: ["r2"]
1133
+ },
1134
+ azure: {
1135
+ label: "Azure",
1136
+ description: "Azure Blob Storage",
1137
+ authMethod: "sas-token",
1138
+ needsRegion: false,
1139
+ needsEndpoint: true,
1140
+ defaultRegion: "",
1141
+ endpointTemplate: null,
1142
+ regions: [],
1143
+ bucketLabel: "Container",
1144
+ endpointPlaceholder: "https://<account>.blob.core.windows.net",
1145
+ schemes: ["azure", "az", "abfs", "abfss", "wasbs", "adl"]
1146
+ },
1147
+ minio: {
1148
+ label: "MinIO",
1149
+ description: "Self-hosted MinIO or S3-compatible",
1150
+ authMethod: "sigv4",
1151
+ needsRegion: false,
1152
+ needsEndpoint: true,
1153
+ defaultRegion: "us-east-1",
1154
+ endpointTemplate: null,
1155
+ regions: [],
1156
+ endpointPlaceholder: "https://minio.example.com or http://localhost:9000",
1157
+ schemes: []
1158
+ },
1159
+ storj: {
1160
+ label: "Storj",
1161
+ description: "Storj Decentralized Cloud",
1162
+ authMethod: "sigv4",
1163
+ needsRegion: false,
1164
+ needsEndpoint: false,
1165
+ defaultRegion: "us1",
1166
+ endpointTemplate: "https://gateway.storjshare.io",
1167
+ regions: [
1168
+ { code: "us1", label: "US1" },
1169
+ { code: "eu1", label: "EU1" },
1170
+ { code: "ap1", label: "AP1" }
1171
+ ],
1172
+ endpointPlaceholder: "https://gateway.storjshare.io",
1173
+ schemes: ["storj", "sj"]
1174
+ },
1175
+ b2: {
1176
+ label: "Backblaze B2",
1177
+ description: "Backblaze B2 Cloud Storage",
1178
+ authMethod: "sigv4",
1179
+ needsRegion: true,
1180
+ needsEndpoint: false,
1181
+ defaultRegion: "us-west-004",
1182
+ endpointTemplate: "https://s3.{region}.backblazeb2.com",
1183
+ regions: [
1184
+ { code: "us-west-000", label: "US West (Sacramento)" },
1185
+ { code: "us-west-001", label: "US West (Stockton)" },
1186
+ { code: "us-west-002", label: "US West (Phoenix)" },
1187
+ { code: "us-west-004", label: "US West" },
1188
+ { code: "us-east-005", label: "US East (Reston)" },
1189
+ { code: "eu-central-003", label: "EU Central (Amsterdam)" },
1190
+ { code: "ca-central-001", label: "Canada (Toronto)" }
1191
+ ],
1192
+ endpointPlaceholder: "https://s3.us-west-004.backblazeb2.com",
1193
+ schemes: []
1194
+ },
1195
+ digitalocean: {
1196
+ label: "DigitalOcean",
1197
+ description: "DigitalOcean Spaces",
1198
+ authMethod: "sigv4",
1199
+ needsRegion: true,
1200
+ needsEndpoint: false,
1201
+ defaultRegion: "nyc3",
1202
+ endpointTemplate: "https://{region}.digitaloceanspaces.com",
1203
+ regions: [
1204
+ { code: "nyc3", label: "New York 3" },
1205
+ { code: "sfo3", label: "San Francisco 3" },
1206
+ { code: "ams3", label: "Amsterdam 3" },
1207
+ { code: "sgp1", label: "Singapore 1" },
1208
+ { code: "lon1", label: "London 1" },
1209
+ { code: "fra1", label: "Frankfurt 1" },
1210
+ { code: "tor1", label: "Toronto 1" },
1211
+ { code: "blr1", label: "Bangalore 1" },
1212
+ { code: "syd1", label: "Sydney 1" }
1213
+ ],
1214
+ endpointPlaceholder: "https://nyc3.digitaloceanspaces.com",
1215
+ schemes: []
1216
+ },
1217
+ wasabi: {
1218
+ label: "Wasabi",
1219
+ description: "Wasabi Hot Cloud Storage",
1220
+ authMethod: "sigv4",
1221
+ needsRegion: true,
1222
+ needsEndpoint: false,
1223
+ defaultRegion: "us-east-1",
1224
+ endpointTemplate: "https://s3.{region}.wasabisys.com",
1225
+ regions: [
1226
+ { code: "us-east-1", label: "US East 1 (Virginia)" },
1227
+ { code: "us-east-2", label: "US East 2 (Virginia)" },
1228
+ { code: "us-central-1", label: "US Central 1 (Texas)" },
1229
+ { code: "us-west-1", label: "US West 1 (Oregon)" },
1230
+ { code: "eu-central-1", label: "EU Central 1 (Amsterdam)" },
1231
+ { code: "eu-central-2", label: "EU Central 2 (Frankfurt)" },
1232
+ { code: "eu-west-1", label: "EU West 1 (London)" },
1233
+ { code: "eu-west-2", label: "EU West 2 (Paris)" },
1234
+ { code: "ap-northeast-1", label: "AP Northeast 1 (Tokyo)" },
1235
+ { code: "ap-northeast-2", label: "AP Northeast 2 (Osaka)" },
1236
+ { code: "ap-southeast-1", label: "AP Southeast 1 (Singapore)" },
1237
+ { code: "ap-southeast-2", label: "AP Southeast 2 (Sydney)" },
1238
+ { code: "ca-central-1", label: "Canada (Toronto)" }
1239
+ ],
1240
+ endpointPlaceholder: "https://s3.us-east-1.wasabisys.com",
1241
+ schemes: []
1242
+ },
1243
+ contabo: {
1244
+ label: "Contabo",
1245
+ description: "Contabo Object Storage",
1246
+ authMethod: "sigv4",
1247
+ needsRegion: true,
1248
+ needsEndpoint: false,
1249
+ defaultRegion: "eu2",
1250
+ endpointTemplate: "https://{region}.contabostorage.com",
1251
+ regions: [
1252
+ { code: "eu2", label: "European Union" },
1253
+ { code: "usc1", label: "US Central" },
1254
+ { code: "sin1", label: "Singapore" }
1255
+ ],
1256
+ endpointPlaceholder: "https://eu2.contabostorage.com",
1257
+ schemes: []
1258
+ },
1259
+ hetzner: {
1260
+ label: "Hetzner",
1261
+ description: "Hetzner Object Storage",
1262
+ authMethod: "sigv4",
1263
+ needsRegion: true,
1264
+ needsEndpoint: false,
1265
+ defaultRegion: "fsn1",
1266
+ endpointTemplate: "https://{region}.your-objectstorage.com",
1267
+ regions: [
1268
+ { code: "fsn1", label: "Falkenstein, DE" },
1269
+ { code: "nbg1", label: "Nuremberg, DE" },
1270
+ { code: "hel1", label: "Helsinki, FI" }
1271
+ ],
1272
+ endpointPlaceholder: "https://fsn1.your-objectstorage.com",
1273
+ schemes: []
1274
+ },
1275
+ linode: {
1276
+ label: "Linode / Akamai",
1277
+ description: "Akamai / Linode Object Storage",
1278
+ authMethod: "sigv4",
1279
+ needsRegion: true,
1280
+ needsEndpoint: false,
1281
+ defaultRegion: "us-east-1",
1282
+ endpointTemplate: "https://{region}.linodeobjects.com",
1283
+ regions: [
1284
+ { code: "us-east-1", label: "Newark, NJ" },
1285
+ { code: "us-southeast-1", label: "Atlanta, GA" },
1286
+ { code: "us-ord-1", label: "Chicago, IL" },
1287
+ { code: "us-iad-1", label: "Washington, DC" },
1288
+ { code: "us-lax-1", label: "Los Angeles, CA" },
1289
+ { code: "us-sea-1", label: "Seattle, WA" },
1290
+ { code: "us-mia-1", label: "Miami, FL" },
1291
+ { code: "eu-central-1", label: "Frankfurt, DE" },
1292
+ { code: "nl-ams-1", label: "Amsterdam, NL" },
1293
+ { code: "gb-lon-1", label: "London, UK" },
1294
+ { code: "fr-par-1", label: "Paris, FR" },
1295
+ { code: "ap-south-1", label: "Singapore" },
1296
+ { code: "jp-osa-1", label: "Osaka, JP" },
1297
+ { code: "au-mel-1", label: "Melbourne, AU" },
1298
+ { code: "br-gru-1", label: "S\xE3o Paulo, BR" },
1299
+ { code: "in-maa-1", label: "Chennai, IN" },
1300
+ { code: "id-cgk-1", label: "Jakarta, ID" },
1301
+ { code: "it-mil-1", label: "Milan, IT" },
1302
+ { code: "se-sto-1", label: "Stockholm, SE" }
1303
+ ],
1304
+ endpointPlaceholder: "https://us-east-1.linodeobjects.com",
1305
+ schemes: []
1306
+ },
1307
+ ovhcloud: {
1308
+ label: "OVHcloud",
1309
+ description: "OVHcloud Object Storage",
1310
+ authMethod: "sigv4",
1311
+ needsRegion: true,
1312
+ needsEndpoint: false,
1313
+ defaultRegion: "gra",
1314
+ endpointTemplate: "https://s3.{region}.io.cloud.ovh.net",
1315
+ regions: [
1316
+ { code: "gra", label: "Gravelines, FR" },
1317
+ { code: "sbg", label: "Strasbourg, FR" },
1318
+ { code: "bhs", label: "Beauharnois, CA" },
1319
+ { code: "de", label: "Frankfurt, DE" },
1320
+ { code: "uk", label: "London, UK" },
1321
+ { code: "waw", label: "Warsaw, PL" }
1322
+ ],
1323
+ endpointPlaceholder: "https://s3.gra.io.cloud.ovh.net",
1324
+ schemes: []
1325
+ }
1326
+ };
1327
+ var PROVIDER_IDS = [
1328
+ "s3",
1329
+ "gcs",
1330
+ "r2",
1331
+ "azure",
1332
+ "b2",
1333
+ "digitalocean",
1334
+ "wasabi",
1335
+ "storj",
1336
+ "hetzner",
1337
+ "contabo",
1338
+ "linode",
1339
+ "ovhcloud",
1340
+ "minio"
1341
+ ];
1342
+ function getProvider(id) {
1343
+ return PROVIDERS[id] ?? PROVIDERS.s3;
1344
+ }
1345
+ function buildEndpointFromTemplate(id, region) {
1346
+ const def = PROVIDERS[id];
1347
+ if (!def?.endpointTemplate) return "";
1348
+ return def.endpointTemplate.replace("{region}", region);
1349
+ }
1350
+ function buildProviderBaseUrl(provider, endpoint, bucket, region) {
1351
+ if (endpoint) {
1352
+ return `${endpoint.replace(/\/$/, "")}/${bucket}`;
1353
+ }
1354
+ const def = PROVIDERS[provider];
1355
+ if (def?.endpointTemplate) {
1356
+ const resolved = def.endpointTemplate.replace("{region}", region || def.defaultRegion);
1357
+ return `${resolved}/${bucket}`;
1358
+ }
1359
+ return `https://s3.${region || "us-east-1"}.amazonaws.com/${bucket}`;
1360
+ }
1361
+ function isGcsProvider(provider, endpoint) {
1362
+ return provider === "gcs" || !!endpoint && /storage\.googleapis\.com/i.test(endpoint);
1363
+ }
1364
+
1042
1365
  // ../../src/lib/storage/url-adapter.ts
1043
1366
  var UrlAdapter = class {
1044
1367
  supportsWrite = false;
@@ -1084,6 +1407,38 @@ var UrlAdapter = class {
1084
1407
  }
1085
1408
  };
1086
1409
 
1410
+ // ../../src/lib/utils/cloud-url.ts
1411
+ var AWS_REGION_RE = /^(us|eu|ap|sa|ca|me|af|il)-(north|south|east|west|central|northeast|southeast|northwest|southwest)-\d+/;
1412
+ function getNativeScheme(provider) {
1413
+ const def = PROVIDERS[provider];
1414
+ if (def?.schemes.length) return def.schemes[0];
1415
+ return "s3";
1416
+ }
1417
+ function safeDecodeURIComponent(s) {
1418
+ try {
1419
+ return decodeURIComponent(s);
1420
+ } catch {
1421
+ return s;
1422
+ }
1423
+ }
1424
+ function resolveCloudUrl(url) {
1425
+ const s3Match = url.match(/^s3[an]?:\/\/([^/]+)\/?(.*)$/);
1426
+ if (s3Match) {
1427
+ const [, bucket, key] = s3Match;
1428
+ const regionMatch = bucket.match(AWS_REGION_RE);
1429
+ const region = regionMatch ? regionMatch[0] : "us-east-1";
1430
+ const base = buildProviderBaseUrl("s3", "", bucket, region);
1431
+ return key ? `${base}/${key}` : base;
1432
+ }
1433
+ const gcsMatch = url.match(/^gcs?:\/\/([^/]+)\/?(.*)$/);
1434
+ if (gcsMatch) {
1435
+ const [, bucket, key] = gcsMatch;
1436
+ const base = buildProviderBaseUrl("gcs", "", bucket, "");
1437
+ return key ? `${base}/${key}` : base;
1438
+ }
1439
+ return url;
1440
+ }
1441
+
1087
1442
  // ../../src/lib/utils/column-types.ts
1088
1443
  var NUMBER_TYPES = [
1089
1444
  "TINYINT",
@@ -1200,6 +1555,12 @@ function typeLabel(category) {
1200
1555
  return TYPE_LABELS[category];
1201
1556
  }
1202
1557
 
1558
+ // ../../src/lib/utils/error.ts
1559
+ function handleLoadError(err) {
1560
+ if (err instanceof DOMException && err.name === "AbortError") return null;
1561
+ return err instanceof Error ? err.message : String(err);
1562
+ }
1563
+
1203
1564
  // ../../src/lib/utils/format.ts
1204
1565
  function formatFileSize(bytes) {
1205
1566
  if (bytes < 0) return "0 B";
@@ -1235,6 +1596,81 @@ function getFileExtension(filename) {
1235
1596
  if (lastDot <= 0) return "";
1236
1597
  return filename.slice(lastDot).toLowerCase();
1237
1598
  }
1599
+ function jsonReplacerBigInt(_key, value) {
1600
+ return typeof value === "bigint" ? value.toString() : value;
1601
+ }
1602
+ function formatValue(value) {
1603
+ if (value === null || value === void 0) return "NULL";
1604
+ if (value instanceof Date) return value.toISOString();
1605
+ if (typeof value === "bigint") return value.toString();
1606
+ if (typeof value === "object") return JSON.stringify(value, jsonReplacerBigInt);
1607
+ return String(value);
1608
+ }
1609
+
1610
+ // ../../src/lib/utils/export.ts
1611
+ function formatCellValue(value) {
1612
+ if (value === null || value === void 0) return "";
1613
+ if (value instanceof Date) return value.toISOString();
1614
+ if (typeof value === "bigint") return value.toString();
1615
+ if (typeof value === "object") return JSON.stringify(value, jsonReplacerBigInt);
1616
+ return String(value);
1617
+ }
1618
+ function escapeCsvField(value) {
1619
+ if (value.includes(",") || value.includes('"') || value.includes("\n") || value.includes("\r")) {
1620
+ return `"${value.replace(/"/g, '""')}"`;
1621
+ }
1622
+ return value;
1623
+ }
1624
+ function serializeToCsv(columns, rows) {
1625
+ const header = columns.map(escapeCsvField).join(",");
1626
+ const body = rows.map((row) => columns.map((col) => escapeCsvField(formatCellValue(row[col]))).join(",")).join("\n");
1627
+ return `${header}
1628
+ ${body}`;
1629
+ }
1630
+ function serializeToJson(columns, rows) {
1631
+ const data = rows.map((row) => {
1632
+ const obj = {};
1633
+ for (const col of columns) {
1634
+ const val = row[col];
1635
+ if (val instanceof Date) {
1636
+ obj[col] = val.toISOString();
1637
+ } else {
1638
+ obj[col] = val ?? null;
1639
+ }
1640
+ }
1641
+ return obj;
1642
+ });
1643
+ return JSON.stringify(data, jsonReplacerBigInt, 2);
1644
+ }
1645
+
1646
+ // ../../src/lib/utils/file-sort.ts
1647
+ function sortFileEntries(entries, config) {
1648
+ const sorted = [...entries];
1649
+ const dir = config.direction === "asc" ? 1 : -1;
1650
+ sorted.sort((a, b) => {
1651
+ if (a.is_dir && !b.is_dir) return -1;
1652
+ if (!a.is_dir && b.is_dir) return 1;
1653
+ switch (config.field) {
1654
+ case "name":
1655
+ return dir * a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
1656
+ case "size":
1657
+ return dir * (a.size - b.size);
1658
+ case "modified":
1659
+ return dir * (a.modified - b.modified);
1660
+ case "extension":
1661
+ return dir * a.extension.localeCompare(b.extension, void 0, { sensitivity: "base" });
1662
+ default:
1663
+ return 0;
1664
+ }
1665
+ });
1666
+ return sorted;
1667
+ }
1668
+ function toggleSortField(current, field) {
1669
+ if (current.field === field) {
1670
+ return { field, direction: current.direction === "asc" ? "desc" : "asc" };
1671
+ }
1672
+ return { field, direction: "asc" };
1673
+ }
1238
1674
  function normalizeGeomType(raw) {
1239
1675
  const s = raw.toUpperCase().replace(/\s+/g, "");
1240
1676
  if (s === "POINT") return "point";
@@ -1836,8 +2272,78 @@ function generateHexDump(data, bytesPerRow = 16) {
1836
2272
  return rows;
1837
2273
  }
1838
2274
 
2275
+ // ../../src/lib/utils/local-storage.ts
2276
+ function loadFromStorage(key, defaultValue) {
2277
+ if (typeof window === "undefined") return defaultValue;
2278
+ try {
2279
+ const raw = localStorage.getItem(key);
2280
+ if (raw) return JSON.parse(raw);
2281
+ } catch {
2282
+ }
2283
+ return defaultValue;
2284
+ }
2285
+ function persistToStorage(key, value) {
2286
+ if (typeof window === "undefined") return;
2287
+ try {
2288
+ localStorage.setItem(key, JSON.stringify(value));
2289
+ } catch {
2290
+ }
2291
+ }
2292
+ function parseMarkdownDocument(markdown) {
2293
+ let frontmatter = {};
2294
+ let content = markdown;
2295
+ const fmMatch = markdown.match(/^---\n([\s\S]*?)\n---\n/);
2296
+ if (fmMatch) {
2297
+ try {
2298
+ frontmatter = YAML__default.default.parse(fmMatch[1]) || {};
2299
+ } catch {
2300
+ }
2301
+ content = markdown.slice(fmMatch[0].length);
2302
+ }
2303
+ const sqlBlocks = [];
2304
+ const lines = content.split("\n");
2305
+ let i = 0;
2306
+ while (i < lines.length) {
2307
+ const line = lines[i];
2308
+ const match = line.match(/^```sql\s+(\w[\w-]*)\s*$/);
2309
+ if (match) {
2310
+ const name = match[1];
2311
+ const startLine = i;
2312
+ const sqlLines = [];
2313
+ i++;
2314
+ while (i < lines.length && lines[i] !== "```") {
2315
+ sqlLines.push(lines[i]);
2316
+ i++;
2317
+ }
2318
+ sqlBlocks.push({
2319
+ name,
2320
+ sql: sqlLines.join("\n"),
2321
+ startLine,
2322
+ endLine: i
2323
+ });
2324
+ }
2325
+ i++;
2326
+ }
2327
+ return { frontmatter, content, sqlBlocks };
2328
+ }
2329
+ function interpolateTemplates(text, queryResults) {
2330
+ return text.replace(/\{(\w+)\.rows\[(\d+)\]\.(\w+)\}/g, (match, queryName, rowIdx, colName) => {
2331
+ const rows = queryResults.get(queryName);
2332
+ if (!rows) return match;
2333
+ const row = rows[parseInt(rowIdx, 10)];
2334
+ if (!row) return match;
2335
+ const value = row[colName];
2336
+ return value !== void 0 ? String(value) : match;
2337
+ });
2338
+ }
2339
+ function markSqlBlocks(content) {
2340
+ return content.replace(
2341
+ /```sql\s+(\w[\w-]*)\s*\n([\s\S]*?)```/g,
2342
+ (_, name) => `<div data-sql-block="${name}"></div>`
2343
+ );
2344
+ }
2345
+
1839
2346
  // ../../src/lib/utils/parquet-metadata.ts
1840
- var WGS84_CODES = /* @__PURE__ */ new Set([4326, 4979]);
1841
2347
  function mapParquetType(col) {
1842
2348
  const lt = col.logical_type;
1843
2349
  if (lt) {
@@ -1978,24 +2484,18 @@ function extractBounds(geo) {
1978
2484
  }
1979
2485
 
1980
2486
  // ../../src/lib/utils/storage-url.ts
1981
- var SCHEME_MAP = {
1982
- "s3://": { provider: "s3", strip: 5 },
1983
- "s3a://": { provider: "s3", strip: 6 },
1984
- "s3n://": { provider: "s3", strip: 6 },
1985
- "aws://": { provider: "s3", strip: 6 },
1986
- "r2://": { provider: "r2", strip: 5 },
1987
- "gs://": { provider: "gcs", strip: 5 },
1988
- "gcs://": { provider: "gcs", strip: 6 },
1989
- "azure://": { provider: "azure", strip: 8 },
1990
- "az://": { provider: "azure", strip: 5 },
1991
- "abfs://": { provider: "azure", strip: 7 },
1992
- "abfss://": { provider: "azure", strip: 8 },
1993
- "wasbs://": { provider: "azure", strip: 8 },
1994
- "adl://": { provider: "azure", strip: 6 },
1995
- "storj://": { provider: "storj", strip: 8 },
1996
- "sj://": { provider: "storj", strip: 5 },
1997
- "swift://": { provider: "unknown", strip: 8 }
1998
- };
2487
+ function buildSchemeMap() {
2488
+ const map = {};
2489
+ for (const [id, def] of Object.entries(PROVIDERS)) {
2490
+ for (const scheme of def.schemes) {
2491
+ const key = `${scheme}://`;
2492
+ map[key] = { provider: id, strip: key.length };
2493
+ }
2494
+ }
2495
+ map["swift://"] = { provider: "unknown", strip: 8 };
2496
+ return map;
2497
+ }
2498
+ var SCHEME_MAP = buildSchemeMap();
1999
2499
  function defaultResult(defaults) {
2000
2500
  return {
2001
2501
  bucket: "",
@@ -2100,7 +2600,7 @@ function parseStorageUrl(input, defaults = {}) {
2100
2600
  bucket: doVhost[1],
2101
2601
  region: doVhost[2],
2102
2602
  endpoint: `${url.protocol}//${doVhost[2]}.digitaloceanspaces.com`,
2103
- provider: "s3",
2603
+ provider: "digitalocean",
2104
2604
  prefix: pathParts.join("/")
2105
2605
  };
2106
2606
  }
@@ -2110,7 +2610,7 @@ function parseStorageUrl(input, defaults = {}) {
2110
2610
  bucket: pathParts[0],
2111
2611
  region: doPath[1],
2112
2612
  endpoint: `${url.protocol}//${url.host}`,
2113
- provider: "s3",
2613
+ provider: "digitalocean",
2114
2614
  prefix: pathParts.slice(1).join("/")
2115
2615
  };
2116
2616
  }
@@ -2120,7 +2620,7 @@ function parseStorageUrl(input, defaults = {}) {
2120
2620
  bucket: pathParts[0],
2121
2621
  region: wasabiMatch[1],
2122
2622
  endpoint: `${url.protocol}//${url.host}`,
2123
- provider: "s3",
2623
+ provider: "wasabi",
2124
2624
  prefix: pathParts.slice(1).join("/")
2125
2625
  };
2126
2626
  }
@@ -2130,7 +2630,7 @@ function parseStorageUrl(input, defaults = {}) {
2130
2630
  bucket: b2S3[1],
2131
2631
  region: b2S3[2],
2132
2632
  endpoint: `${url.protocol}//s3.${b2S3[2]}.backblazeb2.com`,
2133
- provider: "s3",
2633
+ provider: "b2",
2134
2634
  prefix: pathParts.join("/")
2135
2635
  };
2136
2636
  }
@@ -2140,7 +2640,7 @@ function parseStorageUrl(input, defaults = {}) {
2140
2640
  bucket: pathParts[1],
2141
2641
  region: defaults.region || "us-west-000",
2142
2642
  endpoint: `${url.protocol}//${url.host}`,
2143
- provider: "s3",
2643
+ provider: "b2",
2144
2644
  prefix: pathParts.slice(2).join("/")
2145
2645
  };
2146
2646
  }
@@ -2173,6 +2673,56 @@ function parseStorageUrl(input, defaults = {}) {
2173
2673
  prefix: pathParts.slice(1).join("/")
2174
2674
  };
2175
2675
  }
2676
+ const contaboMatch = host.match(/^([a-z0-9]+)\.contabostorage\.com$/);
2677
+ if (contaboMatch && pathParts.length > 0) {
2678
+ return {
2679
+ bucket: pathParts[0],
2680
+ region: contaboMatch[1],
2681
+ endpoint: `${url.protocol}//${url.host}`,
2682
+ provider: "contabo",
2683
+ prefix: pathParts.slice(1).join("/")
2684
+ };
2685
+ }
2686
+ const hetznerMatch = host.match(/^([a-z0-9]+)\.your-objectstorage\.com$/);
2687
+ if (hetznerMatch && pathParts.length > 0) {
2688
+ return {
2689
+ bucket: pathParts[0],
2690
+ region: hetznerMatch[1],
2691
+ endpoint: `${url.protocol}//${url.host}`,
2692
+ provider: "hetzner",
2693
+ prefix: pathParts.slice(1).join("/")
2694
+ };
2695
+ }
2696
+ const linodeVhost = host.match(/^(.+)\.([a-z0-9-]+)\.linodeobjects\.com$/);
2697
+ if (linodeVhost) {
2698
+ return {
2699
+ bucket: linodeVhost[1],
2700
+ region: linodeVhost[2],
2701
+ endpoint: `${url.protocol}//${linodeVhost[2]}.linodeobjects.com`,
2702
+ provider: "linode",
2703
+ prefix: pathParts.join("/")
2704
+ };
2705
+ }
2706
+ const linodePath = host.match(/^([a-z0-9-]+)\.linodeobjects\.com$/);
2707
+ if (linodePath && pathParts.length > 0) {
2708
+ return {
2709
+ bucket: pathParts[0],
2710
+ region: linodePath[1],
2711
+ endpoint: `${url.protocol}//${url.host}`,
2712
+ provider: "linode",
2713
+ prefix: pathParts.slice(1).join("/")
2714
+ };
2715
+ }
2716
+ const ovhMatch = host.match(/^s3\.([a-z0-9-]+)\.io\.cloud\.ovh\.(?:net|us)$/);
2717
+ if (ovhMatch && pathParts.length > 0) {
2718
+ return {
2719
+ bucket: pathParts[0],
2720
+ region: ovhMatch[1],
2721
+ endpoint: `${url.protocol}//${url.host}`,
2722
+ provider: "ovhcloud",
2723
+ prefix: pathParts.slice(1).join("/")
2724
+ };
2725
+ }
2176
2726
  const isMinioLike = host.includes("minio") || host === "localhost" || host === "127.0.0.1" || host.startsWith("192.168.") || host.startsWith("10.");
2177
2727
  if (isMinioLike && pathParts.length > 0) {
2178
2728
  return {
@@ -2509,12 +3059,26 @@ function isWKT(value) {
2509
3059
  return WKT_TYPES.some((t) => s.startsWith(t) || s.startsWith(`MULTI${t}`));
2510
3060
  }
2511
3061
 
3062
+ exports.COPY_FEEDBACK_MS = COPY_FEEDBACK_MS;
3063
+ exports.DEFAULT_TARGET_CRS = DEFAULT_TARGET_CRS;
3064
+ exports.DUCKDB_INIT_TIMEOUT_MS = DUCKDB_INIT_TIMEOUT_MS;
3065
+ exports.LAYER_HUE_MULTIPLIER = LAYER_HUE_MULTIPLIER;
3066
+ exports.MAX_QUERY_HISTORY_ENTRIES = MAX_QUERY_HISTORY_ENTRIES;
3067
+ exports.PROVIDERS = PROVIDERS;
3068
+ exports.PROVIDER_IDS = PROVIDER_IDS;
2512
3069
  exports.QueryCancelledError = QueryCancelledError;
3070
+ exports.SQL_PREVIEW_LENGTH = SQL_PREVIEW_LENGTH;
3071
+ exports.STORAGE_KEYS = STORAGE_KEYS;
2513
3072
  exports.UrlAdapter = UrlAdapter;
3073
+ exports.VIEWER_DIR_EXTENSIONS = VIEWER_DIR_EXTENSIONS;
3074
+ exports.WGS84_CODES = WGS84_CODES;
2514
3075
  exports.buildDuckDbSource = buildDuckDbSource;
3076
+ exports.buildEndpointFromTemplate = buildEndpointFromTemplate;
2515
3077
  exports.buildGeoArrowTables = buildGeoArrowTables;
3078
+ exports.buildProviderBaseUrl = buildProviderBaseUrl;
2516
3079
  exports.classifyType = classifyType;
2517
3080
  exports.describeParseResult = describeParseResult;
3081
+ exports.escapeCsvField = escapeCsvField;
2518
3082
  exports.extractBounds = extractBounds;
2519
3083
  exports.extractEpsgFromGeoMeta = extractEpsgFromGeoMeta;
2520
3084
  exports.extractGeometryTypes = extractGeometryTypes;
@@ -2522,20 +3086,37 @@ exports.findGeoColumn = findGeoColumn;
2522
3086
  exports.findGeoColumnFromRows = findGeoColumnFromRows;
2523
3087
  exports.formatDate = formatDate;
2524
3088
  exports.formatFileSize = formatFileSize;
3089
+ exports.formatValue = formatValue;
2525
3090
  exports.generateHexDump = generateHexDump;
2526
3091
  exports.getDuckDbReadFn = getDuckDbReadFn;
2527
3092
  exports.getFileExtension = getFileExtension;
2528
3093
  exports.getFileTypeInfo = getFileTypeInfo;
2529
3094
  exports.getMimeType = getMimeType;
3095
+ exports.getNativeScheme = getNativeScheme;
3096
+ exports.getProvider = getProvider;
2530
3097
  exports.getViewerKind = getViewerKind;
3098
+ exports.handleLoadError = handleLoadError;
3099
+ exports.interpolateTemplates = interpolateTemplates;
2531
3100
  exports.isCloudNativeFormat = isCloudNativeFormat;
3101
+ exports.isGcsProvider = isGcsProvider;
2532
3102
  exports.isQueryable = isQueryable;
3103
+ exports.jsonReplacerBigInt = jsonReplacerBigInt;
3104
+ exports.loadFromStorage = loadFromStorage;
2533
3105
  exports.looksLikeUrl = looksLikeUrl;
3106
+ exports.markSqlBlocks = markSqlBlocks;
2534
3107
  exports.normalizeGeomType = normalizeGeomType;
3108
+ exports.parseMarkdownDocument = parseMarkdownDocument;
2535
3109
  exports.parseStorageUrl = parseStorageUrl;
2536
3110
  exports.parseWKB = parseWKB;
3111
+ exports.persistToStorage = persistToStorage;
2537
3112
  exports.readParquetMetadata = readParquetMetadata;
3113
+ exports.resolveCloudUrl = resolveCloudUrl;
3114
+ exports.safeDecodeURIComponent = safeDecodeURIComponent;
3115
+ exports.serializeToCsv = serializeToCsv;
3116
+ exports.serializeToJson = serializeToJson;
3117
+ exports.sortFileEntries = sortFileEntries;
2538
3118
  exports.toBinary = toBinary;
3119
+ exports.toggleSortField = toggleSortField;
2539
3120
  exports.typeBadgeClass = typeBadgeClass;
2540
3121
  exports.typeColor = typeColor;
2541
3122
  exports.typeLabel = typeLabel;