| |
| |
| |
| |
| |
| |
|
|
| import { VirtualFile } from '@/lib/vfs/types'; |
|
|
| export interface DeploymentServing { |
| |
| servedAtRoot: boolean; |
| |
| baseUrl: string; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function resolveDeploymentServing( |
| deployment: { slug?: string; customDomain?: string }, |
| deploymentId: string, |
| opts: { staticProxyEnabled: boolean; appUrl: string } |
| ): DeploymentServing { |
| const servedViaSubdomain = opts.staticProxyEnabled && !!deployment.slug; |
| const servedAtRoot = !!deployment.customDomain || servedViaSubdomain; |
| const instanceDomain = opts.appUrl.replace(/^https?:\/\//, ''); |
| const baseUrl = deployment.customDomain |
| ? `https://${deployment.customDomain}` |
| : servedViaSubdomain |
| ? `https://${deployment.slug}.${instanceDomain}` |
| : `${opts.appUrl}/deployments/${deploymentId}`; |
| return { servedAtRoot, baseUrl }; |
| } |
|
|
| |
| |
| |
| export function replaceAssetPathsWithDeploymentPrefix( |
| content: string, |
| blobUrlToPath: Map<string, string>, |
| allFiles: VirtualFile[], |
| deploymentId: string, |
| servedAtRoot?: boolean |
| ): string { |
| let result = content; |
|
|
| |
| |
| const pathPrefix = servedAtRoot ? '' : `/deployments/${deploymentId}`; |
|
|
| |
| for (const [blobUrl, filePath] of blobUrlToPath) { |
| const absolutePath = `${pathPrefix}${filePath}`; |
| result = result.replace(new RegExp(escapeRegex(blobUrl), 'g'), absolutePath); |
| } |
|
|
| |
| const isAlreadyPrefixed = (path: string) => |
| pathPrefix && path.startsWith(pathPrefix); |
|
|
| |
| |
| result = result.replace( |
| /href=(["'])(\/[^"']*\.html?)\1/g, |
| (match, quote, filePath) => { |
| if (isAlreadyPrefixed(filePath)) { |
| return match; |
| } |
| return `href=${quote}${pathPrefix}${filePath}${quote}`; |
| } |
| ); |
|
|
| |
| const assetDirPattern = /(?:href|src)=(["'])(\/(?:styles|scripts|assets|images|fonts|js|css)\/[^"']+)\1/g; |
| result = result.replace(assetDirPattern, (match, quote, filePath) => { |
| if (isAlreadyPrefixed(filePath)) { |
| return match; |
| } |
| return match.replace(filePath, `${pathPrefix}${filePath}`); |
| }); |
|
|
| |
| const rootAssetPattern = /(?:href|src)=(["'])(\/[^"'\/]+\.(?:js|css|json|xml|ico|png|jpg|jpeg|gif|svg|webp|woff|woff2|ttf|eot))\1/g; |
| result = result.replace(rootAssetPattern, (match, quote, filePath) => { |
| if (isAlreadyPrefixed(filePath)) { |
| return match; |
| } |
| return match.replace(filePath, `${pathPrefix}${filePath}`); |
| }); |
|
|
| |
| result = result.replace( |
| /url\(['"]?(\/(?:styles|scripts|assets|images|fonts|js|css)\/[^'")]+)['"]?\)/g, |
| (match, filePath) => { |
| if (isAlreadyPrefixed(filePath)) { |
| return match; |
| } |
| return match.replace(filePath, `${pathPrefix}${filePath}`); |
| } |
| ); |
|
|
| |
| result = result.replace( |
| /href=(["'])([^"':/][^"']*\.html?)\1/g, |
| (match, quote, filePath) => { |
| |
| if (filePath.startsWith('/') || filePath.includes('://')) { |
| return match; |
| } |
| return `href=${quote}${pathPrefix}/${filePath}${quote}`; |
| } |
| ); |
|
|
| |
| if (pathPrefix) { |
| result = result.replace( |
| /href=(["'])\/\1/g, |
| (match, quote) => `href=${quote}${pathPrefix}/${quote}` |
| ); |
| } |
|
|
| return result; |
| } |
|
|
| |
| |
| |
| function escapeRegex(str: string): string { |
| return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); |
| } |
|
|