Files
workinf_Blender_Wasm/web/protocol/editor-resource-path.ts
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

23 lines
1.6 KiB
TypeScript

import { normalizeProjectAssetPath } from './asset-path';
export const EDITOR_RESOURCE_MAX_BYTES = 256 * 1024 * 1024;
export const SHADER_BUNDLE_MAX_FILES = 256;
export interface ShaderResourceSelection { batchId: string; relativePath: string }
export function isEditorResourcePath(value: unknown): value is string {
if (typeof value !== 'string') return false;
const parts = value.split('/'), bytes = new TextEncoder();
if (parts[0] !== 'cache' || !/^[0-9a-f-]{36}$/.test(parts[1] ?? '') || parts.length < 3 || parts.length > 16 || bytes.encode('/browser/' + value).length > 1023) return false;
if (parts.some(part => !part || part === '.' || part === '..' || /[\\\u0000-\u001f\u007f]/.test(part) || bytes.encode(part).length > 200)) return false;
try { if (normalizeProjectAssetPath(value) !== value) return false; } catch { return false; }
return parts[2] === 'shader' || parts[2] === 'model' ? parts.length > 3 : parts.length === 3 && /^[A-Za-z0-9._-]{1,200}\.(?:abc|usd|usda|usdc|usdz|btx|osl|oso)$/i.test(parts[2]);
}
export function modelResourcePath(batchId: string, relativePath: string): string {
const path = `cache/${batchId}/model/${relativePath}`;
if (!isEditorResourcePath(path)) throw new Error('请选择不含路径跳转的模型相对路径');
return path;
}
export function shaderResourcePath(selection: ShaderResourceSelection): string {
const path = `cache/${selection.batchId}/shader/${selection.relativePath}`;
if (!isEditorResourcePath(path)) throw new Error('Choose a bounded shader-relative path without traversal or renamed characters'); return path;
}