@walkthru-earth/objex-utils 1.2.1 → 1.3.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/README.md +8 -0
- package/dist/index.cjs +228 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +137 -2
- package/dist/index.d.ts +137 -2
- package/dist/index.js +223 -26
- package/dist/index.js.map +1 -1
- package/docs/README.md +1 -0
- package/docs/parquet-metadata.md +9 -1
- package/docs/stac-geoparquet.md +198 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,6 +29,13 @@ import {
|
|
|
29
29
|
extractEpsgFromGeoMeta,
|
|
30
30
|
extractBounds,
|
|
31
31
|
|
|
32
|
+
// stac-geoparquet (detection + row → STAC Item)
|
|
33
|
+
isStacGeoparquetSchema,
|
|
34
|
+
stacRowToItem,
|
|
35
|
+
flattenStacBbox,
|
|
36
|
+
pickStacPrimaryAsset,
|
|
37
|
+
resolveStacAssetHref,
|
|
38
|
+
|
|
32
39
|
// Storage URLs
|
|
33
40
|
parseStorageUrl,
|
|
34
41
|
resolveCloudUrl,
|
|
@@ -67,6 +74,7 @@ Full per-module developer reference lives in [`docs/`](./docs/README.md). Each p
|
|
|
67
74
|
| [`docs/geometry.md`](./docs/geometry.md) | WKB parser, GeoArrow builder, geometry-column detection |
|
|
68
75
|
| [`docs/cog.md`](./docs/cog.md) | Cloud-Optimized GeoTIFF pipeline helpers, band configs, color ramps |
|
|
69
76
|
| [`docs/parquet-metadata.md`](./docs/parquet-metadata.md) | `readParquetMetadata` + CRS / bounds / geometry-type extractors |
|
|
77
|
+
| [`docs/stac-geoparquet.md`](./docs/stac-geoparquet.md) | stac-geoparquet detection + row → STAC Item transforms |
|
|
70
78
|
| [`docs/storage.md`](./docs/storage.md) | URL parsing, provider registry, `StorageAdapter`, `UrlAdapter` |
|
|
71
79
|
| [`docs/query-engine.md`](./docs/query-engine.md) | `QueryEngine` interface + handle / result types |
|
|
72
80
|
| [`docs/file-types.md`](./docs/file-types.md) | File-type registry: `getFileTypeInfo`, `getViewerKind`, `getDuckDbReadFn`, … |
|
package/dist/index.cjs
CHANGED
|
@@ -2477,6 +2477,15 @@ async function readParquetMetadata(url) {
|
|
|
2477
2477
|
name: col.name,
|
|
2478
2478
|
type: mapParquetType(col)
|
|
2479
2479
|
}));
|
|
2480
|
+
const topLevelColumns = [];
|
|
2481
|
+
const root = metadata.schema[0];
|
|
2482
|
+
const rootChildren = root?.num_children ?? 0;
|
|
2483
|
+
let cursor = 1;
|
|
2484
|
+
for (let i = 0; i < rootChildren && cursor < metadata.schema.length; i++) {
|
|
2485
|
+
const el = metadata.schema[cursor];
|
|
2486
|
+
if (el?.name) topLevelColumns.push(el.name);
|
|
2487
|
+
cursor += countSubtree(metadata.schema, cursor);
|
|
2488
|
+
}
|
|
2480
2489
|
let geo = null;
|
|
2481
2490
|
let legacyGeoParquet = false;
|
|
2482
2491
|
const geoKv = metadata.key_value_metadata?.find((kv) => kv.key === "geo");
|
|
@@ -2518,7 +2527,26 @@ async function readParquetMetadata(url) {
|
|
|
2518
2527
|
compression = [...codecs].join(", ");
|
|
2519
2528
|
}
|
|
2520
2529
|
}
|
|
2521
|
-
return {
|
|
2530
|
+
return {
|
|
2531
|
+
rowCount,
|
|
2532
|
+
schema,
|
|
2533
|
+
topLevelColumns,
|
|
2534
|
+
geo,
|
|
2535
|
+
legacyGeoParquet,
|
|
2536
|
+
createdBy,
|
|
2537
|
+
numRowGroups,
|
|
2538
|
+
compression
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
function countSubtree(schema, start) {
|
|
2542
|
+
const el = schema[start];
|
|
2543
|
+
if (!el) return 0;
|
|
2544
|
+
const n = el.num_children ?? 0;
|
|
2545
|
+
let cursor = start + 1;
|
|
2546
|
+
for (let i = 0; i < n; i++) {
|
|
2547
|
+
cursor += countSubtree(schema, cursor);
|
|
2548
|
+
}
|
|
2549
|
+
return cursor - start;
|
|
2522
2550
|
}
|
|
2523
2551
|
function extractEpsgFromGeoMeta(geo) {
|
|
2524
2552
|
const primaryCol = geo.columns[geo.primaryColumn];
|
|
@@ -2557,6 +2585,144 @@ function extractBounds(geo) {
|
|
|
2557
2585
|
return [primaryCol.bbox[0], primaryCol.bbox[1], primaryCol.bbox[2], primaryCol.bbox[3]];
|
|
2558
2586
|
}
|
|
2559
2587
|
|
|
2588
|
+
// ../../src/lib/utils/stac-geoparquet.ts
|
|
2589
|
+
var STAC_GEOPARQUET_REQUIRED_COLUMNS = [
|
|
2590
|
+
"stac_version",
|
|
2591
|
+
"type",
|
|
2592
|
+
"geometry",
|
|
2593
|
+
"assets"
|
|
2594
|
+
];
|
|
2595
|
+
function isStacGeoparquetSchema(schema) {
|
|
2596
|
+
if (!Array.isArray(schema) || schema.length === 0) return false;
|
|
2597
|
+
const names = new Set(schema.map((c) => c.name));
|
|
2598
|
+
return STAC_GEOPARQUET_REQUIRED_COLUMNS.every((c) => names.has(c));
|
|
2599
|
+
}
|
|
2600
|
+
function flattenStacBbox(bbox) {
|
|
2601
|
+
if (!bbox) return null;
|
|
2602
|
+
if (Array.isArray(bbox)) {
|
|
2603
|
+
if (bbox.length < 4) return null;
|
|
2604
|
+
const [minX, minY, maxX, maxY] = bbox;
|
|
2605
|
+
if (![minX, minY, maxX, maxY].every((v) => Number.isFinite(v))) return null;
|
|
2606
|
+
return [minX, minY, maxX, maxY];
|
|
2607
|
+
}
|
|
2608
|
+
if (typeof bbox === "object") {
|
|
2609
|
+
const { xmin, ymin, xmax, ymax } = bbox;
|
|
2610
|
+
if (![xmin, ymin, xmax, ymax].every((v) => Number.isFinite(v))) return null;
|
|
2611
|
+
return [xmin, ymin, xmax, ymax];
|
|
2612
|
+
}
|
|
2613
|
+
return null;
|
|
2614
|
+
}
|
|
2615
|
+
function resolveStacAssetHref(href, baseUrl) {
|
|
2616
|
+
if (!href) return href;
|
|
2617
|
+
if (/^[a-z][a-z0-9+\-.]*:\/\//i.test(href)) return href;
|
|
2618
|
+
try {
|
|
2619
|
+
return new URL(href, baseUrl).toString();
|
|
2620
|
+
} catch {
|
|
2621
|
+
return href;
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
function pickStacPrimaryAsset(assets, preferredKeys) {
|
|
2625
|
+
if (!assets || typeof assets !== "object") return null;
|
|
2626
|
+
const entries = Object.entries(assets).filter(
|
|
2627
|
+
([, a]) => a && typeof a === "object" && typeof a.href === "string"
|
|
2628
|
+
);
|
|
2629
|
+
if (entries.length === 0) return null;
|
|
2630
|
+
if (preferredKeys) {
|
|
2631
|
+
for (const key of preferredKeys) {
|
|
2632
|
+
const match = entries.find(([k]) => k === key);
|
|
2633
|
+
if (match) return { key: match[0], asset: match[1] };
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
const data = entries.find(([k]) => k === "data");
|
|
2637
|
+
if (data) return { key: data[0], asset: data[1] };
|
|
2638
|
+
const byRole = entries.find(([, a]) => Array.isArray(a.roles) && a.roles.includes("data"));
|
|
2639
|
+
if (byRole) return { key: byRole[0], asset: byRole[1] };
|
|
2640
|
+
return { key: entries[0][0], asset: entries[0][1] };
|
|
2641
|
+
}
|
|
2642
|
+
function normalizeAssetsField(value, baseUrl) {
|
|
2643
|
+
if (!value || typeof value !== "object") return void 0;
|
|
2644
|
+
const out = {};
|
|
2645
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
2646
|
+
if (!raw || typeof raw !== "object") continue;
|
|
2647
|
+
const asset = raw;
|
|
2648
|
+
if (typeof asset.href !== "string" || !asset.href) continue;
|
|
2649
|
+
out[key] = {
|
|
2650
|
+
...asset,
|
|
2651
|
+
href: resolveStacAssetHref(asset.href, baseUrl)
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
2655
|
+
}
|
|
2656
|
+
function normalizeLinksField(value, baseUrl) {
|
|
2657
|
+
if (!Array.isArray(value)) return void 0;
|
|
2658
|
+
const links = [];
|
|
2659
|
+
for (const raw of value) {
|
|
2660
|
+
if (!raw || typeof raw !== "object") continue;
|
|
2661
|
+
const link = raw;
|
|
2662
|
+
if (typeof link.href !== "string" || typeof link.rel !== "string") continue;
|
|
2663
|
+
links.push({ ...link, href: resolveStacAssetHref(link.href, baseUrl) });
|
|
2664
|
+
}
|
|
2665
|
+
return links.length > 0 ? links : void 0;
|
|
2666
|
+
}
|
|
2667
|
+
function stacRowToItem(row, baseUrl, opts = {}) {
|
|
2668
|
+
const { wkbParser, wkbColumn = "geom_wkb", geometryColumn = "geometry" } = opts;
|
|
2669
|
+
let geometry = row[geometryColumn];
|
|
2670
|
+
if (!geometry) {
|
|
2671
|
+
const wkb = row[wkbColumn];
|
|
2672
|
+
if (wkb && wkbParser) {
|
|
2673
|
+
const bytes = wkb instanceof Uint8Array ? wkb : toUint8Array(wkb);
|
|
2674
|
+
if (bytes) {
|
|
2675
|
+
try {
|
|
2676
|
+
geometry = wkbParser(bytes) ?? void 0;
|
|
2677
|
+
} catch {
|
|
2678
|
+
geometry = void 0;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
const bbox = flattenStacBbox(row.bbox) ?? void 0;
|
|
2684
|
+
const assets = normalizeAssetsField(row.assets, baseUrl);
|
|
2685
|
+
const links = normalizeLinksField(row.links, baseUrl);
|
|
2686
|
+
const properties = {};
|
|
2687
|
+
for (const [key, value] of Object.entries(row)) {
|
|
2688
|
+
if (value === null || value === void 0) continue;
|
|
2689
|
+
if (key.startsWith("proj:") || key.startsWith("raster:") || key.startsWith("eo:")) {
|
|
2690
|
+
properties[key] = value;
|
|
2691
|
+
}
|
|
2692
|
+
if (key === "datetime") {
|
|
2693
|
+
properties.datetime = value instanceof Date ? value.toISOString() : String(value);
|
|
2694
|
+
}
|
|
2695
|
+
if (key === "bands") {
|
|
2696
|
+
properties.bands = value;
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
const item = {
|
|
2700
|
+
type: "Feature",
|
|
2701
|
+
stac_version: typeof row.stac_version === "string" ? row.stac_version : "1.0.0",
|
|
2702
|
+
id: typeof row.id === "string" ? row.id : String(row.id ?? ""),
|
|
2703
|
+
properties
|
|
2704
|
+
};
|
|
2705
|
+
if (typeof row.collection === "string") item.collection = row.collection;
|
|
2706
|
+
if (Array.isArray(row.stac_extensions)) {
|
|
2707
|
+
item.stac_extensions = row.stac_extensions;
|
|
2708
|
+
}
|
|
2709
|
+
if (bbox) item.bbox = bbox;
|
|
2710
|
+
if (geometry) item.geometry = geometry;
|
|
2711
|
+
if (assets) item.assets = assets;
|
|
2712
|
+
if (links) item.links = links;
|
|
2713
|
+
return item;
|
|
2714
|
+
}
|
|
2715
|
+
function toUint8Array(value) {
|
|
2716
|
+
if (value instanceof Uint8Array) return value;
|
|
2717
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
2718
|
+
if (ArrayBuffer.isView(value)) {
|
|
2719
|
+
const view = value;
|
|
2720
|
+
return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
2721
|
+
}
|
|
2722
|
+
if (Array.isArray(value)) return new Uint8Array(value);
|
|
2723
|
+
return null;
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2560
2726
|
// ../../src/lib/utils/storage-url.ts
|
|
2561
2727
|
function buildSchemeMap() {
|
|
2562
2728
|
const map = {};
|
|
@@ -2570,6 +2736,32 @@ function buildSchemeMap() {
|
|
|
2570
2736
|
return map;
|
|
2571
2737
|
}
|
|
2572
2738
|
var SCHEME_MAP = buildSchemeMap();
|
|
2739
|
+
var AWS_VHOST_RE = /^(.+)\.s3[.-]([a-z0-9-]+)\.amazonaws\.com$/;
|
|
2740
|
+
var AWS_PATH_RE = /^s3[.-]([a-z0-9-]+)\.amazonaws\.com$/;
|
|
2741
|
+
var AWS_GLOBAL_HOST = "s3.amazonaws.com";
|
|
2742
|
+
var R2_RE = /^([a-z0-9]+)\.r2\.cloudflarestorage\.com$/;
|
|
2743
|
+
var GCS_GLOBAL_HOST = "storage.googleapis.com";
|
|
2744
|
+
var GCS_VHOST_RE = /^(.+)\.storage\.googleapis\.com$/;
|
|
2745
|
+
var DO_VHOST_RE = /^(.+)\.([a-z0-9-]+)\.digitaloceanspaces\.com$/;
|
|
2746
|
+
var DO_PATH_RE = /^([a-z0-9-]+)\.digitaloceanspaces\.com$/;
|
|
2747
|
+
var WASABI_RE = /^s3\.([a-z0-9-]+)\.wasabisys\.com$/;
|
|
2748
|
+
var B2_S3_RE = /^(.+)\.s3\.([a-z0-9-]+)\.backblazeb2\.com$/;
|
|
2749
|
+
var B2_NATIVE_RE = /^f[a-z0-9]+\.backblazeb2\.com$/;
|
|
2750
|
+
var OSS_RE = /^(.+)\.(oss-[a-z0-9-]+)\.aliyuncs\.com$/;
|
|
2751
|
+
var COS_RE = /^(.+)\.cos\.([a-z0-9-]+)\.myqcloud\.com$/;
|
|
2752
|
+
var YANDEX_HOST = "storage.yandexcloud.net";
|
|
2753
|
+
var CONTABO_RE = /^([a-z0-9]+)\.contabostorage\.com$/;
|
|
2754
|
+
var HETZNER_RE = /^([a-z0-9]+)\.your-objectstorage\.com$/;
|
|
2755
|
+
var LINODE_VHOST_RE = /^(.+)\.([a-z0-9-]+)\.linodeobjects\.com$/;
|
|
2756
|
+
var LINODE_PATH_RE = /^([a-z0-9-]+)\.linodeobjects\.com$/;
|
|
2757
|
+
var OVH_RE = /^s3\.([a-z0-9-]+)\.io\.cloud\.ovh\.(?:net|us)$/;
|
|
2758
|
+
var AZURE_BLOB_RE = /^([a-z0-9]+)\.blob\.core\.windows\.net$/;
|
|
2759
|
+
var STORJ_GATEWAY_RE = /^gateway\.(?:([a-z0-9]+)\.)?storjshare\.io$/;
|
|
2760
|
+
var STORJ_LINK_RE = /^link\.(?:([a-z0-9]+)\.)?storjshare\.io$/;
|
|
2761
|
+
function isMinioLikeHost(host) {
|
|
2762
|
+
return host.includes("minio") || host === "localhost" || host === "127.0.0.1" || host.startsWith("192.168.") || host.startsWith("10.");
|
|
2763
|
+
}
|
|
2764
|
+
var STAC_API_PATH_RE = /\/(collections|items|catalogs|search)(\/|\?|$)/i;
|
|
2573
2765
|
function defaultResult(defaults) {
|
|
2574
2766
|
return {
|
|
2575
2767
|
bucket: "",
|
|
@@ -2610,7 +2802,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2610
2802
|
const url = new URL(trimmed);
|
|
2611
2803
|
const host = url.hostname;
|
|
2612
2804
|
const pathParts = url.pathname.replace(/^\//, "").split("/").filter(Boolean);
|
|
2613
|
-
const awsVhost = host.match(
|
|
2805
|
+
const awsVhost = host.match(AWS_VHOST_RE);
|
|
2614
2806
|
if (awsVhost) {
|
|
2615
2807
|
return {
|
|
2616
2808
|
bucket: awsVhost[1],
|
|
@@ -2620,7 +2812,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2620
2812
|
prefix: pathParts.join("/")
|
|
2621
2813
|
};
|
|
2622
2814
|
}
|
|
2623
|
-
const awsPath = host.match(
|
|
2815
|
+
const awsPath = host.match(AWS_PATH_RE);
|
|
2624
2816
|
if (awsPath && pathParts.length > 0) {
|
|
2625
2817
|
return {
|
|
2626
2818
|
bucket: pathParts[0],
|
|
@@ -2630,7 +2822,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2630
2822
|
prefix: pathParts.slice(1).join("/")
|
|
2631
2823
|
};
|
|
2632
2824
|
}
|
|
2633
|
-
if (host ===
|
|
2825
|
+
if (host === AWS_GLOBAL_HOST && pathParts.length > 0) {
|
|
2634
2826
|
return {
|
|
2635
2827
|
bucket: pathParts[0],
|
|
2636
2828
|
region: defaults.region || "us-east-1",
|
|
@@ -2639,7 +2831,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2639
2831
|
prefix: pathParts.slice(1).join("/")
|
|
2640
2832
|
};
|
|
2641
2833
|
}
|
|
2642
|
-
const r2Match = host.match(
|
|
2834
|
+
const r2Match = host.match(R2_RE);
|
|
2643
2835
|
if (r2Match && pathParts.length > 0) {
|
|
2644
2836
|
return {
|
|
2645
2837
|
bucket: pathParts[0],
|
|
@@ -2649,7 +2841,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2649
2841
|
prefix: pathParts.slice(1).join("/")
|
|
2650
2842
|
};
|
|
2651
2843
|
}
|
|
2652
|
-
if (host ===
|
|
2844
|
+
if (host === GCS_GLOBAL_HOST && pathParts.length > 0) {
|
|
2653
2845
|
return {
|
|
2654
2846
|
bucket: pathParts[0],
|
|
2655
2847
|
region: defaults.region || "us",
|
|
@@ -2658,7 +2850,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2658
2850
|
prefix: pathParts.slice(1).join("/")
|
|
2659
2851
|
};
|
|
2660
2852
|
}
|
|
2661
|
-
const gcsVhost = host.match(
|
|
2853
|
+
const gcsVhost = host.match(GCS_VHOST_RE);
|
|
2662
2854
|
if (gcsVhost) {
|
|
2663
2855
|
return {
|
|
2664
2856
|
bucket: gcsVhost[1],
|
|
@@ -2668,7 +2860,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2668
2860
|
prefix: pathParts.join("/")
|
|
2669
2861
|
};
|
|
2670
2862
|
}
|
|
2671
|
-
const doVhost = host.match(
|
|
2863
|
+
const doVhost = host.match(DO_VHOST_RE);
|
|
2672
2864
|
if (doVhost) {
|
|
2673
2865
|
return {
|
|
2674
2866
|
bucket: doVhost[1],
|
|
@@ -2678,7 +2870,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2678
2870
|
prefix: pathParts.join("/")
|
|
2679
2871
|
};
|
|
2680
2872
|
}
|
|
2681
|
-
const doPath = host.match(
|
|
2873
|
+
const doPath = host.match(DO_PATH_RE);
|
|
2682
2874
|
if (doPath && pathParts.length > 0) {
|
|
2683
2875
|
return {
|
|
2684
2876
|
bucket: pathParts[0],
|
|
@@ -2688,7 +2880,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2688
2880
|
prefix: pathParts.slice(1).join("/")
|
|
2689
2881
|
};
|
|
2690
2882
|
}
|
|
2691
|
-
const wasabiMatch = host.match(
|
|
2883
|
+
const wasabiMatch = host.match(WASABI_RE);
|
|
2692
2884
|
if (wasabiMatch && pathParts.length > 0) {
|
|
2693
2885
|
return {
|
|
2694
2886
|
bucket: pathParts[0],
|
|
@@ -2698,7 +2890,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2698
2890
|
prefix: pathParts.slice(1).join("/")
|
|
2699
2891
|
};
|
|
2700
2892
|
}
|
|
2701
|
-
const b2S3 = host.match(
|
|
2893
|
+
const b2S3 = host.match(B2_S3_RE);
|
|
2702
2894
|
if (b2S3) {
|
|
2703
2895
|
return {
|
|
2704
2896
|
bucket: b2S3[1],
|
|
@@ -2708,7 +2900,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2708
2900
|
prefix: pathParts.join("/")
|
|
2709
2901
|
};
|
|
2710
2902
|
}
|
|
2711
|
-
const b2Native = host.match(
|
|
2903
|
+
const b2Native = host.match(B2_NATIVE_RE);
|
|
2712
2904
|
if (b2Native && pathParts[0] === "file" && pathParts.length > 1) {
|
|
2713
2905
|
return {
|
|
2714
2906
|
bucket: pathParts[1],
|
|
@@ -2718,7 +2910,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2718
2910
|
prefix: pathParts.slice(2).join("/")
|
|
2719
2911
|
};
|
|
2720
2912
|
}
|
|
2721
|
-
const ossMatch = host.match(
|
|
2913
|
+
const ossMatch = host.match(OSS_RE);
|
|
2722
2914
|
if (ossMatch) {
|
|
2723
2915
|
return {
|
|
2724
2916
|
bucket: ossMatch[1],
|
|
@@ -2728,7 +2920,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2728
2920
|
prefix: pathParts.join("/")
|
|
2729
2921
|
};
|
|
2730
2922
|
}
|
|
2731
|
-
const cosMatch = host.match(
|
|
2923
|
+
const cosMatch = host.match(COS_RE);
|
|
2732
2924
|
if (cosMatch) {
|
|
2733
2925
|
return {
|
|
2734
2926
|
bucket: cosMatch[1],
|
|
@@ -2738,7 +2930,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2738
2930
|
prefix: pathParts.join("/")
|
|
2739
2931
|
};
|
|
2740
2932
|
}
|
|
2741
|
-
if (host ===
|
|
2933
|
+
if (host === YANDEX_HOST && pathParts.length > 0) {
|
|
2742
2934
|
return {
|
|
2743
2935
|
bucket: pathParts[0],
|
|
2744
2936
|
region: defaults.region || "ru-central1",
|
|
@@ -2747,7 +2939,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2747
2939
|
prefix: pathParts.slice(1).join("/")
|
|
2748
2940
|
};
|
|
2749
2941
|
}
|
|
2750
|
-
const contaboMatch = host.match(
|
|
2942
|
+
const contaboMatch = host.match(CONTABO_RE);
|
|
2751
2943
|
if (contaboMatch && pathParts.length > 0) {
|
|
2752
2944
|
return {
|
|
2753
2945
|
bucket: pathParts[0],
|
|
@@ -2757,7 +2949,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2757
2949
|
prefix: pathParts.slice(1).join("/")
|
|
2758
2950
|
};
|
|
2759
2951
|
}
|
|
2760
|
-
const hetznerMatch = host.match(
|
|
2952
|
+
const hetznerMatch = host.match(HETZNER_RE);
|
|
2761
2953
|
if (hetznerMatch && pathParts.length > 0) {
|
|
2762
2954
|
return {
|
|
2763
2955
|
bucket: pathParts[0],
|
|
@@ -2767,7 +2959,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2767
2959
|
prefix: pathParts.slice(1).join("/")
|
|
2768
2960
|
};
|
|
2769
2961
|
}
|
|
2770
|
-
const linodeVhost = host.match(
|
|
2962
|
+
const linodeVhost = host.match(LINODE_VHOST_RE);
|
|
2771
2963
|
if (linodeVhost) {
|
|
2772
2964
|
return {
|
|
2773
2965
|
bucket: linodeVhost[1],
|
|
@@ -2777,7 +2969,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2777
2969
|
prefix: pathParts.join("/")
|
|
2778
2970
|
};
|
|
2779
2971
|
}
|
|
2780
|
-
const linodePath = host.match(
|
|
2972
|
+
const linodePath = host.match(LINODE_PATH_RE);
|
|
2781
2973
|
if (linodePath && pathParts.length > 0) {
|
|
2782
2974
|
return {
|
|
2783
2975
|
bucket: pathParts[0],
|
|
@@ -2787,7 +2979,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2787
2979
|
prefix: pathParts.slice(1).join("/")
|
|
2788
2980
|
};
|
|
2789
2981
|
}
|
|
2790
|
-
const ovhMatch = host.match(
|
|
2982
|
+
const ovhMatch = host.match(OVH_RE);
|
|
2791
2983
|
if (ovhMatch && pathParts.length > 0) {
|
|
2792
2984
|
return {
|
|
2793
2985
|
bucket: pathParts[0],
|
|
@@ -2797,8 +2989,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2797
2989
|
prefix: pathParts.slice(1).join("/")
|
|
2798
2990
|
};
|
|
2799
2991
|
}
|
|
2800
|
-
|
|
2801
|
-
if (isMinioLike && pathParts.length > 0) {
|
|
2992
|
+
if (isMinioLikeHost(host) && pathParts.length > 0) {
|
|
2802
2993
|
return {
|
|
2803
2994
|
bucket: pathParts[0],
|
|
2804
2995
|
region: defaults.region || "us-east-1",
|
|
@@ -2807,7 +2998,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2807
2998
|
prefix: pathParts.slice(1).join("/")
|
|
2808
2999
|
};
|
|
2809
3000
|
}
|
|
2810
|
-
const azureBlob = host.match(
|
|
3001
|
+
const azureBlob = host.match(AZURE_BLOB_RE);
|
|
2811
3002
|
if (azureBlob && pathParts.length > 0) {
|
|
2812
3003
|
return {
|
|
2813
3004
|
bucket: pathParts[0],
|
|
@@ -2817,7 +3008,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2817
3008
|
prefix: pathParts.slice(1).join("/")
|
|
2818
3009
|
};
|
|
2819
3010
|
}
|
|
2820
|
-
const storjGateway = host.match(
|
|
3011
|
+
const storjGateway = host.match(STORJ_GATEWAY_RE);
|
|
2821
3012
|
if (storjGateway && pathParts.length > 0) {
|
|
2822
3013
|
return {
|
|
2823
3014
|
bucket: pathParts[0],
|
|
@@ -2827,7 +3018,7 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2827
3018
|
prefix: pathParts.slice(1).join("/")
|
|
2828
3019
|
};
|
|
2829
3020
|
}
|
|
2830
|
-
const storjLink = host.match(
|
|
3021
|
+
const storjLink = host.match(STORJ_LINK_RE);
|
|
2831
3022
|
if (storjLink && pathParts.length >= 3 && (pathParts[0] === "raw" || pathParts[0] === "s")) {
|
|
2832
3023
|
return {
|
|
2833
3024
|
bucket: pathParts[2],
|
|
@@ -2837,6 +3028,12 @@ function parseStorageUrl(input, defaults = {}) {
|
|
|
2837
3028
|
prefix: pathParts.slice(3).join("/")
|
|
2838
3029
|
};
|
|
2839
3030
|
}
|
|
3031
|
+
if (STAC_API_PATH_RE.test(url.pathname)) {
|
|
3032
|
+
return {
|
|
3033
|
+
...defaultResult(defaults),
|
|
3034
|
+
endpoint: `${url.protocol}//${url.host}`
|
|
3035
|
+
};
|
|
3036
|
+
}
|
|
2840
3037
|
if (pathParts.length > 0) {
|
|
2841
3038
|
const endpoint = `${url.protocol}//${url.host}`;
|
|
2842
3039
|
return {
|
|
@@ -3146,6 +3343,7 @@ exports.PROVIDER_IDS = PROVIDER_IDS;
|
|
|
3146
3343
|
exports.QueryCancelledError = QueryCancelledError;
|
|
3147
3344
|
exports.SF_LABELS = SF_LABELS;
|
|
3148
3345
|
exports.SQL_PREVIEW_LENGTH = SQL_PREVIEW_LENGTH;
|
|
3346
|
+
exports.STAC_GEOPARQUET_REQUIRED_COLUMNS = STAC_GEOPARQUET_REQUIRED_COLUMNS;
|
|
3149
3347
|
exports.STORAGE_KEYS = STORAGE_KEYS;
|
|
3150
3348
|
exports.UrlAdapter = UrlAdapter;
|
|
3151
3349
|
exports.VIEWER_DIR_EXTENSIONS = VIEWER_DIR_EXTENSIONS;
|
|
@@ -3166,6 +3364,7 @@ exports.extractEpsgFromGeoMeta = extractEpsgFromGeoMeta;
|
|
|
3166
3364
|
exports.extractGeometryTypes = extractGeometryTypes;
|
|
3167
3365
|
exports.findGeoColumn = findGeoColumn;
|
|
3168
3366
|
exports.findGeoColumnFromRows = findGeoColumnFromRows;
|
|
3367
|
+
exports.flattenStacBbox = flattenStacBbox;
|
|
3169
3368
|
exports.formatDate = formatDate;
|
|
3170
3369
|
exports.formatFileSize = formatFileSize;
|
|
3171
3370
|
exports.formatValue = formatValue;
|
|
@@ -3184,6 +3383,7 @@ exports.isCloudNativeFormat = isCloudNativeFormat;
|
|
|
3184
3383
|
exports.isGcsProvider = isGcsProvider;
|
|
3185
3384
|
exports.isPubliclyStreamable = isPubliclyStreamable;
|
|
3186
3385
|
exports.isQueryable = isQueryable;
|
|
3386
|
+
exports.isStacGeoparquetSchema = isStacGeoparquetSchema;
|
|
3187
3387
|
exports.jsonReplacerBigInt = jsonReplacerBigInt;
|
|
3188
3388
|
exports.loadFromStorage = loadFromStorage;
|
|
3189
3389
|
exports.looksLikeUrl = looksLikeUrl;
|
|
@@ -3193,14 +3393,17 @@ exports.parseMarkdownDocument = parseMarkdownDocument;
|
|
|
3193
3393
|
exports.parseStorageUrl = parseStorageUrl;
|
|
3194
3394
|
exports.parseWKB = parseWKB;
|
|
3195
3395
|
exports.persistToStorage = persistToStorage;
|
|
3396
|
+
exports.pickStacPrimaryAsset = pickStacPrimaryAsset;
|
|
3196
3397
|
exports.readParquetMetadata = readParquetMetadata;
|
|
3197
3398
|
exports.resolveCloudUrl = resolveCloudUrl;
|
|
3198
3399
|
exports.resolveProviderEndpoint = resolveProviderEndpoint;
|
|
3400
|
+
exports.resolveStacAssetHref = resolveStacAssetHref;
|
|
3199
3401
|
exports.safeClamp = safeClamp;
|
|
3200
3402
|
exports.safeDecodeURIComponent = safeDecodeURIComponent;
|
|
3201
3403
|
exports.serializeToCsv = serializeToCsv;
|
|
3202
3404
|
exports.serializeToJson = serializeToJson;
|
|
3203
3405
|
exports.sortFileEntries = sortFileEntries;
|
|
3406
|
+
exports.stacRowToItem = stacRowToItem;
|
|
3204
3407
|
exports.toBinary = toBinary;
|
|
3205
3408
|
exports.toggleSortField = toggleSortField;
|
|
3206
3409
|
exports.typeBadgeClass = typeBadgeClass;
|