- Added new CORS origins for local development and specific IP addresses in `settings.py`. - Refactored API URL retrieval logic in `loadSiteDefinition.ts` and `fileAccess.ts` to auto-detect based on the current origin. - Enhanced error handling in API calls and improved logging for better debugging. - Updated `renderTemplate` function to support additional block types and improved rendering logic for various components in `templateEngine.tsx`.
143 lines
3.6 KiB
TypeScript
143 lines
3.6 KiB
TypeScript
/**
|
|
* File Access Utility
|
|
* Phase 5: Sites Renderer & Publishing
|
|
*
|
|
* Integrates with Phase 3's SiteBuilderFileService for file access.
|
|
* Provides utilities to access site assets (images, documents, media).
|
|
*/
|
|
|
|
const SITES_DATA_PATH = import.meta.env.SITES_DATA_PATH || '/sites';
|
|
|
|
/**
|
|
* Get API base URL - auto-detect based on current origin
|
|
*/
|
|
function getApiBaseUrl(): string {
|
|
const envUrl = import.meta.env.VITE_API_URL;
|
|
if (envUrl) {
|
|
return envUrl.endsWith('/api') ? envUrl : `${envUrl}/api`;
|
|
}
|
|
|
|
if (typeof window !== 'undefined') {
|
|
const origin = window.location.origin;
|
|
if (/^\d+\.\d+\.\d+\.\d+/.test(origin) || origin.includes('localhost') || origin.includes('127.0.0.1')) {
|
|
if (origin.includes(':8024')) {
|
|
return origin.replace(':8024', ':8011') + '/api';
|
|
}
|
|
return origin.split(':')[0] + ':8011/api';
|
|
}
|
|
}
|
|
|
|
return 'https://api.igny8.com/api';
|
|
}
|
|
|
|
const API_URL = getApiBaseUrl();
|
|
|
|
/**
|
|
* Get file URL for a site asset.
|
|
*
|
|
* @param siteId - Site ID
|
|
* @param version - Site version (optional, defaults to 'latest')
|
|
* @param filePath - Relative path to file from assets directory
|
|
* @returns Full URL to the asset
|
|
*/
|
|
export function getSiteAssetUrl(
|
|
siteId: string | number,
|
|
filePath: string,
|
|
version: string | number = 'latest'
|
|
): string {
|
|
// Try filesystem first (for deployed sites)
|
|
const fsPath = `${SITES_DATA_PATH}/clients/${siteId}/v${version}/assets/${filePath}`;
|
|
|
|
// In browser, we need to use API endpoint
|
|
// The backend will serve files from the filesystem
|
|
return `${API_URL}/v1/site-builder/assets/${siteId}/${version}/${filePath}`;
|
|
}
|
|
|
|
/**
|
|
* Get image URL for a site.
|
|
*/
|
|
export function getSiteImageUrl(
|
|
siteId: string | number,
|
|
imagePath: string,
|
|
version: string | number = 'latest'
|
|
): string {
|
|
return getSiteAssetUrl(siteId, `images/${imagePath}`, version);
|
|
}
|
|
|
|
/**
|
|
* Get document URL for a site.
|
|
*/
|
|
export function getSiteDocumentUrl(
|
|
siteId: string | number,
|
|
documentPath: string,
|
|
version: string | number = 'latest'
|
|
): string {
|
|
return getSiteAssetUrl(siteId, `documents/${documentPath}`, version);
|
|
}
|
|
|
|
/**
|
|
* Get media URL for a site.
|
|
*/
|
|
export function getSiteMediaUrl(
|
|
siteId: string | number,
|
|
mediaPath: string,
|
|
version: string | number = 'latest'
|
|
): string {
|
|
return getSiteAssetUrl(siteId, `media/${mediaPath}`, version);
|
|
}
|
|
|
|
/**
|
|
* Check if a file exists.
|
|
*
|
|
* @param siteId - Site ID
|
|
* @param filePath - Relative path to file
|
|
* @param version - Site version
|
|
* @returns Promise that resolves to true if file exists
|
|
*/
|
|
export async function fileExists(
|
|
siteId: string | number,
|
|
filePath: string,
|
|
version: string | number = 'latest'
|
|
): Promise<boolean> {
|
|
try {
|
|
const url = getSiteAssetUrl(siteId, filePath, version);
|
|
const response = await fetch(url, { method: 'HEAD' });
|
|
return response.ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load file content as text.
|
|
*/
|
|
export async function loadFileAsText(
|
|
siteId: string | number,
|
|
filePath: string,
|
|
version: string | number = 'latest'
|
|
): Promise<string> {
|
|
const url = getSiteAssetUrl(siteId, filePath, version);
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to load file: ${filePath}`);
|
|
}
|
|
return response.text();
|
|
}
|
|
|
|
/**
|
|
* Load file content as blob.
|
|
*/
|
|
export async function loadFileAsBlob(
|
|
siteId: string | number,
|
|
filePath: string,
|
|
version: string | number = 'latest'
|
|
): Promise<Blob> {
|
|
const url = getSiteAssetUrl(siteId, filePath, version);
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to load file: ${filePath}`);
|
|
}
|
|
return response.blob();
|
|
}
|
|
|