dengdeyan's picture
support splat files
aa00da8
/**
* AWS Configuration for Cognito-based S3 access
*
* This module handles AWS credentials through Cognito Identity Provider.
* No AWS credentials are stored in code or exposed to the client.
*
* Environment Variables Required:
* - VITE_AWS_REGION: AWS region (e.g., "us-east-2")
* - VITE_AWS_COGNITO_IDENTITY_POOL_ID: Cognito Identity Pool ID (e.g., "us-east-2:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
* - VITE_S3_BUCKET: Default S3 bucket name (e.g., "ddy-first-bucket")
*/
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity";
import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity";
export const AWS_REGION = import.meta.env.VITE_AWS_REGION || "us-east-2";
// Cognito pool ID is safe to embed in client code (not a secret)
export const COGNITO_IDENTITY_POOL_ID = import.meta.env.VITE_AWS_COGNITO_IDENTITY_POOL_ID || "us-east-2:1387102d-5a87-4742-8a69-1baa70f37984";
export const DEFAULT_BUCKET = import.meta.env.VITE_S3_BUCKET || "ddy-first-bucket";
/**
* Initialize S3 client with Cognito credentials
* Uses unauthenticated Cognito Identity pool for public S3 access
*/
export function getS3Client() {
const credentialsProvider = fromCognitoIdentityPool({
client: new CognitoIdentityClient({ region: AWS_REGION }),
identityPoolId: COGNITO_IDENTITY_POOL_ID,
});
return new S3Client({
region: AWS_REGION,
credentials: credentialsProvider,
});
}
/**
* Get S3 object as text (for JSON tilesets, metadata, etc.)
*/
export async function getS3ObjectAsText(bucket, key) {
const s3Client = getS3Client();
if (!s3Client) {
throw new Error("S3 client not initialized");
}
try {
const command = new GetObjectCommand({
Bucket: bucket,
Key: key,
});
const response = await s3Client.send(command);
const text = await response.Body.transformToString();
return text;
} catch (error) {
console.error(`Failed to fetch S3 object s3://${bucket}/${key}:`, error);
throw error;
}
}
/**
* Get S3 object as JSON
*/
export async function getS3ObjectAsJson(bucket, key) {
const text = await getS3ObjectAsText(bucket, key);
return JSON.parse(text);
}
/**
* Build a direct S3 URL for tile assets
* Note: This URL requires proper CORS configuration on S3 bucket
* or the bucket must be public with proper authentication
*/
export function buildS3Url(bucket, key) {
return `https://${bucket}.s3.${AWS_REGION}.amazonaws.com/${key}`;
}
/**
* Rewrite URLs in a tileset JSON to use proper S3 paths
* Handles both relative and absolute URLs
*/
export function rewriteTilesetUrls(tilesetJson, bucket, basePath) {
const rewrite = (obj) => {
if (!obj || typeof obj !== "object") return;
if (Array.isArray(obj)) {
obj.forEach(rewrite);
return;
}
Object.keys(obj).forEach((key) => {
const value = obj[key];
// Rewrite uri/url fields to point to S3
if ((key === "uri" || key === "url") && typeof value === "string") {
// Skip external URLs
if (value.startsWith("http://") || value.startsWith("https://")) {
return;
}
// Skip data URLs
if (value.startsWith("data:")) {
return;
}
// Build S3 URL for relative paths
const relativePath = value.startsWith("/") ? value.slice(1) : value;
const s3Key = basePath
? `${basePath}/${relativePath}`.replace(/\/+/g, "/")
: relativePath;
obj[key] = buildS3Url(bucket, s3Key);
}
// Recursively rewrite nested objects
if (typeof value === "object") {
rewrite(value);
}
});
};
rewrite(tilesetJson);
return tilesetJson;
}
/**
* Load a tileset JSON file from S3 and rewrite its URLs
*/
export async function loadTilesetFromS3(bucket, tilesetPath, basePath) {
try {
const tilesetJson = await getS3ObjectAsJson(bucket, tilesetPath);
return rewriteTilesetUrls(tilesetJson, bucket, basePath);
} catch (error) {
console.error(`Failed to load tileset from S3:`, error);
throw error;
}
}
/**
* Get default S3 bucket name
*/
export function getDefaultBucket() {
return DEFAULT_BUCKET;
}
/**
* Get AWS region
*/
export function getAwsRegion() {
return AWS_REGION;
}
/**
* Validate AWS configuration
*/
export function validateAwsConfig() {
return !!(AWS_REGION && COGNITO_IDENTITY_POOL_ID && DEFAULT_BUCKET);
}