@voobase/cli 0.1.1-nonprod.2032 → 0.1.1-nonprod.2037
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/dist-bundle/index.mjs +5 -5
- package/package.json +6 -6
package/dist-bundle/index.mjs
CHANGED
|
@@ -2193,7 +2193,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2193
2193
|
`}function buildPageRenderShellExampleSource(){return buildPageRenderShellSource()}function buildPageRenderArticleListTemplateSource(){return["<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," </head>",' <body class="min-h-screen bg-[linear-gradient(180deg,#f7f4ed_0%,#efebe3_100%)] text-slate-900">',' <div data-shell-slot="header"></div>',' <main class="mx-auto w-[min(1120px,calc(100%-32px))] px-0 py-6 pb-14">',' <section class="grid gap-4 rounded-[24px] border border-stone-300 bg-stone-50 px-7 py-7 shadow-[0_12px_32px_rgba(15,23,42,0.06)]">',' <div class="w-fit rounded-full bg-amber-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-amber-700">PAGE RENDER SAMPLE</div>',' <h1 class="m-0 text-[clamp(28px,4vw,44px)] font-extrabold leading-[1.1] tracking-tight text-slate-900">\u5185\u5BB9\u5217\u8868\u9875\u6A21\u677F</h1>',' <p class="m-0 text-base leading-7 text-slate-600">\u8FD9\u4E2A\u9875\u9762\u7531\u5E73\u53F0\u5728\u8BF7\u6C42\u65F6\u6309 CMS collection \u6E32\u67D3\u3002\u5217\u8868\u5361\u7247\u3001\u5206\u9875\u548C\u8BE6\u60C5\u8DF3\u8F6C\u90FD\u7531 `page-render` \u914D\u7F6E\u9A71\u52A8\u3002</p>'," </section>",' <form class="mt-6 grid grid-cols-[repeat(auto-fit,minmax(180px,1fr))] gap-3" method="get" action="">',' <input type="search" name="keyword" placeholder="\u6309\u5173\u952E\u5B57\u641C\u7D22" class="min-h-12 rounded-2xl border border-slate-300 bg-white/95 px-4 text-base text-slate-900 placeholder:text-slate-500">',' <input type="text" name="category" placeholder="\u6309\u5206\u7C7B slug \u8FC7\u6EE4" class="min-h-12 rounded-2xl border border-slate-300 bg-white/95 px-4 text-base text-slate-900 placeholder:text-slate-500">',' <button type="submit" class="min-h-12 rounded-2xl border border-slate-800 bg-slate-800 px-4 text-base font-bold text-slate-50">\u5237\u65B0\u5217\u8868</button>'," </form>",' <div data-render-list="article-list-main" class="mt-5 grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-[18px]">',' <article data-render-template="article-card" class="grid min-h-full gap-3.5 rounded-[22px] border border-slate-200 bg-white p-[18px] shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <img data-field="cover" alt="cover" class="aspect-[16/10] w-full rounded-2xl bg-stone-200 object-cover">',' <h2 data-field="title" class="m-0 text-[22px] font-bold leading-[1.3] text-slate-900">\u6587\u7AE0\u6807\u9898</h2>',' <p data-field="summary" class="m-0 text-base leading-7 text-slate-600">\u6587\u7AE0\u6458\u8981</p>',' <a data-field="link" class="inline-flex w-fit items-center gap-2 text-sm font-bold text-amber-700" href="#">\u67E5\u770B\u8BE6\u60C5</a>'," </article>"," </div>",' <nav data-render-pagination="article-list-main" class="mt-6 flex flex-wrap gap-2.5 [&>a]:inline-flex [&>a]:h-10 [&>a]:min-w-10 [&>a]:items-center [&>a]:justify-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-300 [&>a]:bg-white [&>a]:px-3 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900 [&>a.is-active]:border-slate-800 [&>a.is-active]:bg-slate-800 [&>a.is-active]:text-white"></nav>'," </main>",' <div data-shell-slot="footer"></div>',' <header data-shell-template="site-header" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-b border-slate-900/8 py-5">',' <strong class="text-[15px] font-bold text-slate-900">Page Render Sample</strong>',' <nav class="flex flex-wrap gap-3 [&>a]:inline-flex [&>a]:min-h-9 [&>a]:items-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-900/10 [&>a]:bg-white/80 [&>a]:px-3.5 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900">',' <a href="./app">App Home</a>',' <a href="./articles">Articles</a>',' <a href="./cms">CMS Page</a>'," </nav>"," </header>",' <footer data-shell-template="site-footer" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-t border-slate-900/8 py-5 text-sm text-slate-600">',' <span class="text-slate-600">On-demand rendered from CMS delivery data</span>',' <span class="text-slate-600">Progressive enhancement assets loaded from current app build</span>'," </footer>"," </body>","</html>",""].join(`
|
|
2194
2194
|
`)}function buildPageRenderArticleDetailTemplateSource(){return["<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," </head>",' <body class="min-h-screen bg-[radial-gradient(circle_at_top_left,rgba(15,118,110,0.12),transparent_30%),linear-gradient(180deg,#fdfaf3_0%,#f3efe7_100%)] text-slate-900">',' <div data-shell-slot="header"></div>',' <main class="mx-auto grid w-[min(1120px,calc(100%-32px))] gap-6 py-6 pb-14">',' <article data-render-detail="article-main" class="rounded-[24px] border border-stone-300 bg-stone-50 px-7 py-7 shadow-[0_12px_32px_rgba(15,23,42,0.06)]">',' <h1 data-field="title" class="mb-4 text-[clamp(30px,4vw,48px)] font-extrabold leading-[1.08] tracking-tight text-slate-900">\u6587\u7AE0\u6807\u9898</h1>',' <div data-field="body" class="article-content text-[15px] leading-8 text-slate-700"><p>\u8FD9\u91CC\u5C06\u7531\u5E73\u53F0\u6309 CMS \u8BE6\u60C5\u5185\u5BB9\u6E32\u67D3\u5BCC\u6587\u672C\u6B63\u6587\u3002</p></div>'," </article>",' <section class="rounded-[24px] border border-stone-300 bg-white px-6 py-6 shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <div class="mb-3 w-fit rounded-full bg-teal-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-teal-700">RELATED</div>',' <h2 class="m-0 text-2xl font-extrabold tracking-tight text-slate-900">\u63A8\u8350\u9605\u8BFB</h2>',' <p class="mb-5 mt-3 text-base leading-7 text-slate-600">\u8BE6\u60C5\u9875\u53EF\u4EE5\u540C\u65F6\u6302\u63A5\u5185\u5BB9\u8BE6\u60C5\u548C\u63A8\u8350\u5217\u8868\uFF0C\u4E0D\u9700\u8981\u5355\u72EC\u8D77\u5E94\u7528\u8FD0\u884C\u65F6\u3002</p>',' <div data-render-list="related-articles" class="grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-4">',' <article data-render-template="related-card" class="grid min-h-full gap-2.5 rounded-[18px] border border-slate-200 bg-slate-50 p-[18px]">',' <h3 data-field="title" class="m-0 text-xl font-bold leading-[1.35] text-slate-900">\u63A8\u8350\u5185\u5BB9\u6807\u9898</h3>',' <p data-field="summary" class="m-0 text-sm leading-7 text-slate-600">\u63A8\u8350\u5185\u5BB9\u6458\u8981</p>',' <a data-field="link" class="inline-flex w-fit items-center gap-2 text-sm font-bold text-teal-700" href="#">\u7EE7\u7EED\u9605\u8BFB</a>'," </article>"," </div>"," </section>",' <section class="rounded-[24px] border border-stone-300 bg-white px-6 py-6 shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <div class="mb-3 w-fit rounded-full bg-fuchsia-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-fuchsia-700">REACT ISLAND</div>',' <h2 class="m-0 text-2xl font-extrabold tracking-tight text-slate-900">\u6D3B\u52A8\u62A5\u540D\u8868\u5355</h2>',' <p class="mb-5 mt-3 text-base leading-7 text-slate-600">\u6B63\u6587\u548C\u63A8\u8350\u5185\u5BB9\u4ECD\u7531 HTML + CMS \u6E32\u67D3\uFF0C\u4E0B\u9762\u7684\u5B8C\u6574\u8868\u5355\u5219\u5728\u9875\u9762\u52A0\u8F7D\u540E\u7531\u5F53\u524D app bundle \u6302\u8F7D\uFF0C\u590D\u7528\u5DF2\u6709 shadcn/Data Form \u7EC4\u4EF6\u4F53\u7CFB\u3002</p>',' <div data-platform-react-island="event-signup-form"></div>'," </section>"," </main>",' <div data-shell-slot="footer"></div>',' <header data-shell-template="site-header" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-b border-slate-900/8 py-5">',' <strong class="text-[15px] font-bold text-slate-900">Page Render Sample</strong>',' <nav class="flex flex-wrap gap-3 [&>a]:inline-flex [&>a]:min-h-9 [&>a]:items-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-900/10 [&>a]:bg-white/80 [&>a]:px-3.5 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900">',' <a href="./app">App Home</a>',' <a href="./articles">Articles</a>',' <a href="./cms">CMS Page</a>'," </nav>"," </header>",' <footer data-shell-template="site-footer" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-t border-slate-900/8 py-5 text-sm text-slate-600">',' <span class="text-slate-600">Detail template with progressive enhancement assets</span>',' <span class="text-slate-600">Rendered on demand from CMS delivery data</span>'," </footer>"," </body>","</html>",""].join(`
|
|
2195
2195
|
`)}function buildPageRenderPostBuildScriptSource(){return['import { cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";','import { join, relative, resolve } from "node:path";',"","const appRoot = process.cwd();",'const sourceDir = resolve(appRoot, "page-render");','const registryPath = resolve(sourceDir, "registry.json");','const distDir = resolve(appRoot, "dist");','const distPageRenderDir = resolve(distDir, "page-render");',"","async function main() {"," if (!(await pathExists(registryPath))) {",' process.stdout.write("[page-render-postbuild] skipped: page-render/registry.json not found\\n");'," return;"," }"," if (!(await pathExists(distDir))) {",' throw new Error("dist directory not found; run vite build before page-render postbuild");'," }",""," await validateJsonFile(registryPath);"," const assetsManifest = await collectAssetsManifest(distDir);",""," await rm(distPageRenderDir, { recursive: true, force: true });"," await mkdir(distPageRenderDir, { recursive: true });"," await cp(sourceDir, distPageRenderDir, { recursive: true });"," await writeFile(",' join(distPageRenderDir, "assets-manifest.json"),',' JSON.stringify(assetsManifest, null, 2) + "\\n",',' "utf8"'," );","",' process.stdout.write("[page-render-postbuild] emitted dist/page-render assets manifest\\n");',"}","","async function collectAssetsManifest(distRoot) {",' const viteManifestPath = join(distRoot, ".vite", "manifest.json");',' const fallbackEntryHtmlPath = join(distRoot, "index.html");'," const css = [];"," const js = [];"," if (await pathExists(viteManifestPath)) {"," const manifest = await readJsonFile(viteManifestPath);"," const entryAssets = collectEntryAssetsFromViteManifest(manifest);"," css.push(...entryAssets.css);"," js.push(...entryAssets.js);"," } else if (await pathExists(fallbackEntryHtmlPath)) {"," const fallbackAssets = await collectAssetsFromHtmlEntry(fallbackEntryHtmlPath);"," css.push(...fallbackAssets.css);"," js.push(...fallbackAssets.js);"," }"," return {"," version: 1,",' mode: "progressive-enhancement",'," css: uniqueStable(css),"," js: uniqueStable(js)"," };","}","","function collectEntryAssetsFromViteManifest(manifest) {",' const entryKey = typeof manifest["index.html"] === "object" && manifest["index.html"] ? "index.html" : findFirstManifestEntryKey(manifest);'," if (!entryKey) {"," return { css: [], js: [] };"," }"," const css = [];"," const js = [];"," const visited = new Set();"," walkManifestEntry(manifest, entryKey, visited, { css, js }, true);"," return { css, js };","}","","function findFirstManifestEntryKey(manifest) {"," for (const [key, value] of Object.entries(manifest)) {",' if (value && typeof value === "object" && value.isEntry && typeof value.file === "string") {'," return key;"," }"," }"," return undefined;","}","","function walkManifestEntry(manifest, entryKey, visited, assets, includeJs) {"," if (visited.has(entryKey)) {"," return;"," }"," visited.add(entryKey);"," const entry = manifest[entryKey];",' if (!entry || typeof entry !== "object") {'," return;"," }",' if (includeJs && typeof entry.file === "string" && entry.file.endsWith(".js")) {'," assets.js.push(stripLeadingSlash(entry.file));"," }"," if (Array.isArray(entry.css)) {"," for (const cssFile of entry.css) {",' if (typeof cssFile === "string" && cssFile.endsWith(".css")) {'," assets.css.push(stripLeadingSlash(cssFile));"," }"," }"," }"," if (Array.isArray(entry.imports)) {"," for (const importKey of entry.imports) {",' if (typeof importKey === "string") {'," walkManifestEntry(manifest, importKey, visited, assets, false);"," }"," }"," }","}","","async function collectAssetsFromHtmlEntry(entryHtmlPath) {",' const html = await readFile(entryHtmlPath, "utf8");',` const css = Array.from(html.matchAll(/<link[^>]+rel=["']stylesheet["'][^>]+href=["']([^"']+)["']/gu)).map((match) => stripLeadingSlash(resolveAssetPath(match[1]))).filter(Boolean);`,` const js = Array.from(html.matchAll(/<script[^>]+type=["']module["'][^>]+src=["']([^"']+)["'][^>]*><\\/script>/gu)).map((match) => stripLeadingSlash(resolveAssetPath(match[1]))).filter(Boolean);`," return { css, js };","}","","function resolveAssetPath(value) {",' if (typeof value !== "string") {',' return "";'," }"," const trimmed = value.trim();",' if (!trimmed || /^https?:\\/\\//.test(trimmed) || trimmed.startsWith("data:")) {',' return "";'," }",' return trimmed.replace(/^\\.\\//, "");',"}","","function stripLeadingSlash(value) {",' return String(value).replace(/^\\/+/, "");',"}","","function uniqueStable(values) {"," const seen = new Set();"," return values.filter((value) => {"," if (!value || seen.has(value)) {"," return false;"," }"," seen.add(value);"," return true;"," });","}","","async function readJsonFile(filePath) {",' const raw = await readFile(filePath, "utf8");'," try {"," return JSON.parse(raw);"," } catch (error) {"," throw new Error(`invalid json file: ${relative(appRoot, filePath)} ${error instanceof Error ? error.message : String(error)}`);"," }","}","","async function validateJsonFile(filePath) {",' const raw = await readFile(filePath, "utf8");'," try {"," JSON.parse(raw);"," } catch (error) {"," throw new Error("," `invalid page-render json: ${relative(appRoot, filePath)} ${error instanceof Error ? error.message : String(error)}`"," );"," }","}","","async function pathExists(targetPath) {"," const target = await stat(targetPath).catch(() => null);"," return Boolean(target);","}","","main().catch((error) => {"," const message = error instanceof Error ? error.stack || error.message : String(error);"," process.stderr.write(`${message}\\n`);"," process.exit(1);","});",""].join(`
|
|
2196
|
-
`)}function buildFrontendAppViteTemplateFiles(){let templatePackageName=DEFAULT_TEMPLATE_PACKAGE_NAME;return[{path:"app.yaml",content:buildAppYamlSource2(templatePackageName)},{path:"package.json",content:buildPackageJsonSource2(templatePackageName)},{path:"package-lock.json",content:buildPackageLockSource2(templatePackageName)},{path:"pnpm-workspace.yaml",content:buildPnpmWorkspaceSource()},{path:"README.md",content:buildReadmeSource2()},{path:".env.example",content:buildEnvExampleSource2(templatePackageName)},{path:"scripts/page-render-postbuild.mjs",content:buildPageRenderPostBuildScriptSource()},{path:"tsconfig.json",content:buildTsconfigSource2()},{path:"vite.config.ts",content:buildViteConfigSource2()},{path:"index.html",content:buildIndexHtmlSource2()},{path:"page-render/README.md",content:buildPageRenderReadmeSource()},{path:"page-render/registry.json",content:buildPageRenderRegistrySource()},{path:"page-render/registry.json.example",content:buildPageRenderRegistryExampleSource()},{path:"page-render/pages/article-list.page-render.json",content:buildPageRenderListConfigSource()},{path:"page-render/pages/article-list.page-render.json.example",content:buildPageRenderListExampleSource()},{path:"page-render/pages/article-detail.page-render.json",content:buildPageRenderDetailConfigSource()},{path:"page-render/pages/article-detail.page-render.json.example",content:buildPageRenderDetailExampleSource()},{path:"page-render/shells/default.shell.json",content:buildPageRenderShellSource()},{path:"page-render/shells/default.shell.json.example",content:buildPageRenderShellExampleSource()},{path:"public/site/article-list.html",content:buildPageRenderArticleListTemplateSource()},{path:"public/site/article-detail.html",content:buildPageRenderArticleDetailTemplateSource()},{path:"public/shared/shells/.gitkeep",content:""},{path:"public/shared/styles/.gitkeep",content:""},{path:"public/shared/scripts/.gitkeep",content:""},{path:"src/main.tsx",content:buildMainSource()},{path:"src/page-render/react-islands.tsx",content:buildReactIslandsSource()},...buildWebSharedPageFiles("src",{buildRouterAppSource,buildHomePageSource:()=>buildFrontendShowcaseHomePageSource(),buildFormPageSource,buildEventSignupFormSource,buildProtectedPageSource,buildCmsPageSource}),{path:"public/auth/index.html",content:buildAuthIndexHtmlSource()},{path:"public/__app/auth-ui.config.json",content:buildAuthUiConfigJsonSource()},{path:"public/__app/auth-ui.override.css",content:buildGeneratedAppAuthUiOverrideCssModuleSource()},{path:"src/styles/index.css",content:buildStylesSource()},{path:"src/styles/cms-content.css",content:buildCmsContentStylesSource()},{path:"src/vite-env.d.ts",content:buildViteEnvSource()},...buildWebSharedDataFormUiFiles("src"),{path:"resources/data-forms/README.md",content:buildDataFormsReadmeSource2()},{path:"resources/data-forms/0001_event_signup.yaml.example",content:buildDataFormExampleSource2()},...buildWebSharedPlatformFiles("src",{buildPlatformConfigSource,buildPlatformClientSource,buildPlatformErrorsSource,buildCapabilitiesIndexSource,buildCapabilitySource})]}function assembleFrontendAppViteTemplate(){let files=buildFrontendAppViteTemplateFiles(),manifest=buildPlatformBlocksManifestFromTemplateFiles("frontend-app-vite",files);return[...files,{path:".platform/platform-blocks.lock.json",content:stringifyPlatformBlocksLockfile(buildPlatformBlocksLockfile(manifest))}]}function getPlatformBlocksManifest(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return buildPlatformBlocksManifestFromTemplateFiles(templateKey,files)}import{mkdtempSync,writeFileSync}from"node:fs";import{basename as basename2,extname as extname2,join,resolve as resolve3}from"node:path";import{tmpdir}from"node:os";import{readFileSync as readFileSync4}from"node:fs";import{basename,extname,resolve as resolve2}from"node:path";function inferAssetMimeType(fileName){switch(extname(fileName).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";default:throw new Error(`\u5F53\u524D\u4EC5\u652F\u6301\u5E38\u89C1\u56FE\u7247\u4E0E\u89C6\u9891\u6269\u5C55\u540D\uFF0C\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u7C7B\u578B: ${fileName}`)}}async function uploadTenantAssetBinary(sdk,input){let filePath=resolve2(input.filePath),fileName=basename(filePath);return sdk.createTenantAssetBinary({fileName,mimeType:inferAssetMimeType(fileName),content:new Uint8Array(readFileSync4(filePath)),...input.title?.trim()?{title:input.title.trim()}:{},...input.folderId?.trim()?{folderId:input.folderId.trim()}:{}})}import{spawn as nodeSpawn}from"node:child_process";import{readdir,readFile}from"node:fs/promises";import path from"node:path";import crossSpawn from"cross-spawn";import{zipSync}from"fflate";function spawnCrossPlatform(command,args,options={}){return crossSpawn(command,[...args],{...options,shell:!1})}async function terminateProcessTree(pid,options={}){if((options.platform??process.platform)==="win32"){let spawnImpl=options.spawnImpl??nodeSpawn;await new Promise((resolve19,reject)=>{let child;try{child=spawnImpl("taskkill.exe",["/PID",String(pid),"/T","/F"],{shell:!1,stdio:"ignore",windowsHide:!0})}catch(error){reject(error instanceof Error?error:new Error(String(error)));return}child.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.once("exit",(code2,signal)=>{if(signal){reject(new Error(`taskkill.exe was terminated by ${signal}`));return}if(code2!==0){reject(new Error(`taskkill.exe exited with status ${code2??"unknown"}`));return}resolve19()})});return}let killImpl=options.killImpl??process.kill.bind(process);try{killImpl(-pid,"SIGTERM")}catch(error){if(error.code==="ESRCH")return;throw error}}async function openExternal(target,options={}){let normalizedTarget=target.trim();if(!normalizedTarget)return{opened:!1,error:"Cannot open an empty target."};let platform=options.platform??process.platform,spawnImpl=options.spawnImpl??nodeSpawn,launcher=platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",normalizedTarget]}:platform==="darwin"?{command:"open",args:[normalizedTarget]}:{command:"xdg-open",args:[normalizedTarget]};return await new Promise(resolve19=>{let child;try{child=spawnImpl(launcher.command,launcher.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(error){resolve19({opened:!1,error:toErrorMessage(error)});return}child.once("error",error=>{resolve19({opened:!1,error:toErrorMessage(error)})}),child.once("spawn",()=>{child.unref(),resolve19({opened:!0})})})}async function createZipBuffer(directory){let archive=Object.create(null);return await addDirectoryToArchive(path.resolve(directory),"",archive),zipSync(archive,{level:6})}async function addDirectoryToArchive(directory,relativeDirectory,archive){let entries=await readdir(directory,{withFileTypes:!0});entries.sort((left,right)=>compareCodeUnits(left.name,right.name));for(let entry of entries){let absolutePath=path.join(directory,entry.name),relativePath=relativeDirectory?`${relativeDirectory}/${entry.name}`:entry.name;if(entry.isDirectory()){await addDirectoryToArchive(absolutePath,relativePath,archive);continue}if(entry.isSymbolicLink())throw new Error(`Cannot add symbolic link to portable ZIP archive: ${relativePath}`);if(!entry.isFile())throw new Error(`Cannot add unsupported filesystem entry to ZIP archive: ${relativePath}`);if(relativePath==="__proto__")throw new Error("Cannot add reserved root ZIP entry name: __proto__");archive[relativePath]=[await readFile(absolutePath),{mtime:new Date(1980,0,1,0,0,0)}]}}function compareCodeUnits(left,right){return left<right?-1:left>right?1:0}function toErrorMessage(error){return error instanceof Error?error.message:String(error)}async function runAssetCommand(args,deps){if(hasHelpFlag(args)||args.rest.length===0){printAssetHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runAssetUpload(args,deps);return}if(subcommand==="list"){await runAssetList(args,deps);return}if(subcommand==="folder"){await runAssetFolder(args,deps);return}if(subcommand==="get"){await runAssetGet(args,deps);return}if(subcommand==="move"){await runAssetMove(args,deps);return}if(subcommand==="update"){await runAssetUpdate(args,deps);return}if(subcommand==="analyze"){await runAssetAnalyze(args,deps);return}if(subcommand==="open"){await runAssetOpen(args,deps);return}if(subcommand==="download"){await runAssetDownload(args,deps);return}if(subcommand==="tag"){await runAssetTag(args,deps);return}throw new Error("`platform asset` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`move`\u3001`update`\u3001`analyze`\u3001`open`\u3001`download`\u3001`folder`\u3001`tag`\u3002")}function printAssetHelp(){process.stdout.write(["platform asset <command>","","Commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>] [--json]"," platform asset list [--q <keyword>] [--media-type image|video] [--mime-type <mime>] [--folder-id <folder-id>] [--tag-ids <id,id>] [--has-ocr true|false] [--has-person true|false] [--is-svg true|false] [--scene <scene>] [--objects <name,name>] [--safety-flags <flag,flag>] [--orientation landscape|portrait|square] [--page <n>] [--limit <n>] [--json]"," platform asset folder list [--json]"," platform asset folder create <name> [--parent-folder-id <folder-id>] [--json]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id>] [--root] [--json]"," platform asset get <asset-id> [--json]"," platform asset move <asset-id> [--folder-id <folder-id> | --root] [--json]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--summary <text>] [--caption <text>] [--scene <scene>] [--objects <name,name>] [--ocr <text>] [--colors <hex,hex>] [--safety-flags <flag,flag>] [--tags <label,label>] [--json]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>] [--json]"," platform asset tag add <asset-id> <label> [--json]"," platform asset tag remove <asset-id> <label> [--json]","","Notes:"," - \u7B2C\u4E00\u9636\u6BB5\u4EE5 tenant/workspace \u4E3A\u4E3B\uFF0C\u4E0D\u8981\u6C42 app/consumer \u4E0A\u4E0B\u6587"," - `list` \u652F\u6301\u7CBE\u786E\u68C0\u7D22 + \u7ED3\u6784\u5316\u8FC7\u6EE4\uFF1B\u4E0D\u5355\u72EC\u63D0\u4F9B `search` \u5B50\u547D\u4EE4"," - `update` \u4E00\u6B21\u547D\u4EE4\u53EF patch \u591A\u4E2A\u5143\u6570\u636E\u5B57\u6BB5\uFF1B\u4E0D\u66FF\u6362\u539F\u59CB\u6587\u4EF6"," - `analyze` \u4E0D\u8C03\u7528\u89C6\u89C9\u6A21\u578B\u3001\u4E0D\u4E0A\u4F20\u56FE\u7247\uFF1B\u4EC5\u6839\u636E\u5143\u6570\u636E\u7ED9\u51FA\u300C\u4E0B\u8F7D\u54EA\u4E00\u7248 + \u5982\u4F55 update\u300D\u7684\u5EFA\u8BAE\uFF1B`--json` \u8F93\u51FA\u540C\u4E0A\u7ED3\u6784\u4FBF\u4E8E\u811A\u672C\u89E3\u6790"," - `analyze` \u53EF\u7528\u4E8E\u7ED9\u4EBA\u5DE5\u6216\u52A9\u624B\u751F\u6210\u5206\u6790\u64CD\u4F5C\u63D0\u793A\uFF0C\u4E0D\u76F4\u63A5\u8BFB\u53D6\u50CF\u7D20\u5185\u5BB9"," - `open` \u4F1A\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6\uFF1B\u672A\u6307\u5B9A `--output` \u65F6\u4F1A\u5199\u5165\u4E34\u65F6\u76EE\u5F55\u5E76\u5C1D\u8BD5\u6253\u5F00"," - `download --variant` \u7528\u4E8E\u660E\u786E\u4E0B\u8F7D\u6307\u5B9A\u53D8\u4F53\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6253\u5F00",""].join(`
|
|
2196
|
+
`)}function buildFrontendAppViteTemplateFiles(){let templatePackageName=DEFAULT_TEMPLATE_PACKAGE_NAME;return[{path:"app.yaml",content:buildAppYamlSource2(templatePackageName)},{path:"package.json",content:buildPackageJsonSource2(templatePackageName)},{path:"package-lock.json",content:buildPackageLockSource2(templatePackageName)},{path:"pnpm-workspace.yaml",content:buildPnpmWorkspaceSource()},{path:"README.md",content:buildReadmeSource2()},{path:".env.example",content:buildEnvExampleSource2(templatePackageName)},{path:"scripts/page-render-postbuild.mjs",content:buildPageRenderPostBuildScriptSource()},{path:"tsconfig.json",content:buildTsconfigSource2()},{path:"vite.config.ts",content:buildViteConfigSource2()},{path:"index.html",content:buildIndexHtmlSource2()},{path:"page-render/README.md",content:buildPageRenderReadmeSource()},{path:"page-render/registry.json",content:buildPageRenderRegistrySource()},{path:"page-render/registry.json.example",content:buildPageRenderRegistryExampleSource()},{path:"page-render/pages/article-list.page-render.json",content:buildPageRenderListConfigSource()},{path:"page-render/pages/article-list.page-render.json.example",content:buildPageRenderListExampleSource()},{path:"page-render/pages/article-detail.page-render.json",content:buildPageRenderDetailConfigSource()},{path:"page-render/pages/article-detail.page-render.json.example",content:buildPageRenderDetailExampleSource()},{path:"page-render/shells/default.shell.json",content:buildPageRenderShellSource()},{path:"page-render/shells/default.shell.json.example",content:buildPageRenderShellExampleSource()},{path:"public/site/article-list.html",content:buildPageRenderArticleListTemplateSource()},{path:"public/site/article-detail.html",content:buildPageRenderArticleDetailTemplateSource()},{path:"public/shared/shells/.gitkeep",content:""},{path:"public/shared/styles/.gitkeep",content:""},{path:"public/shared/scripts/.gitkeep",content:""},{path:"src/main.tsx",content:buildMainSource()},{path:"src/page-render/react-islands.tsx",content:buildReactIslandsSource()},...buildWebSharedPageFiles("src",{buildRouterAppSource,buildHomePageSource:()=>buildFrontendShowcaseHomePageSource(),buildFormPageSource,buildEventSignupFormSource,buildProtectedPageSource,buildCmsPageSource}),{path:"public/auth/index.html",content:buildAuthIndexHtmlSource()},{path:"public/__app/auth-ui.config.json",content:buildAuthUiConfigJsonSource()},{path:"public/__app/auth-ui.override.css",content:buildGeneratedAppAuthUiOverrideCssModuleSource()},{path:"src/styles/index.css",content:buildStylesSource()},{path:"src/styles/cms-content.css",content:buildCmsContentStylesSource()},{path:"src/vite-env.d.ts",content:buildViteEnvSource()},...buildWebSharedDataFormUiFiles("src"),{path:"resources/data-forms/README.md",content:buildDataFormsReadmeSource2()},{path:"resources/data-forms/0001_event_signup.yaml.example",content:buildDataFormExampleSource2()},...buildWebSharedPlatformFiles("src",{buildPlatformConfigSource,buildPlatformClientSource,buildPlatformErrorsSource,buildCapabilitiesIndexSource,buildCapabilitySource})]}function assembleFrontendAppViteTemplate(){let files=buildFrontendAppViteTemplateFiles(),manifest=buildPlatformBlocksManifestFromTemplateFiles("frontend-app-vite",files);return[...files,{path:".platform/platform-blocks.lock.json",content:stringifyPlatformBlocksLockfile(buildPlatformBlocksLockfile(manifest))}]}function getPlatformBlocksManifest(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return buildPlatformBlocksManifestFromTemplateFiles(templateKey,files)}import{mkdtempSync,writeFileSync}from"node:fs";import{basename as basename2,extname as extname2,join,resolve as resolve3}from"node:path";import{tmpdir}from"node:os";import{readFileSync as readFileSync4}from"node:fs";import{basename,extname,resolve as resolve2}from"node:path";function inferAssetMimeType(fileName){switch(extname(fileName).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";case".svg":return"image/svg+xml";case".avif":return"image/avif";case".bmp":return"image/bmp";case".ico":return"image/x-icon";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";default:throw new Error(`\u5F53\u524D\u4EC5\u652F\u6301\u5E38\u89C1\u56FE\u7247\u4E0E\u89C6\u9891\u6269\u5C55\u540D\uFF0C\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u7C7B\u578B: ${fileName}`)}}async function uploadTenantAssetBinary(sdk,input){let filePath=resolve2(input.filePath),fileName=basename(filePath);return sdk.createTenantAssetBinary({fileName,mimeType:inferAssetMimeType(fileName),content:new Uint8Array(readFileSync4(filePath)),...input.title?.trim()?{title:input.title.trim()}:{},...input.folderId?.trim()?{folderId:input.folderId.trim()}:{}})}import{spawn as nodeSpawn}from"node:child_process";import{readdir,readFile}from"node:fs/promises";import path from"node:path";import crossSpawn from"cross-spawn";import{zipSync}from"fflate";function spawnCrossPlatform(command,args,options={}){return crossSpawn(command,[...args],{...options,shell:!1})}async function terminateProcessTree(pid,options={}){if((options.platform??process.platform)==="win32"){let spawnImpl=options.spawnImpl??nodeSpawn;await new Promise((resolve19,reject)=>{let child;try{child=spawnImpl("taskkill.exe",["/PID",String(pid),"/T","/F"],{shell:!1,stdio:"ignore",windowsHide:!0})}catch(error){reject(error instanceof Error?error:new Error(String(error)));return}child.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.once("exit",(code2,signal)=>{if(signal){reject(new Error(`taskkill.exe was terminated by ${signal}`));return}if(code2!==0){reject(new Error(`taskkill.exe exited with status ${code2??"unknown"}`));return}resolve19()})});return}let killImpl=options.killImpl??process.kill.bind(process);try{killImpl(-pid,"SIGTERM")}catch(error){if(error.code==="ESRCH")return;throw error}}async function openExternal(target,options={}){let normalizedTarget=target.trim();if(!normalizedTarget)return{opened:!1,error:"Cannot open an empty target."};let platform=options.platform??process.platform,spawnImpl=options.spawnImpl??nodeSpawn,launcher=platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",normalizedTarget]}:platform==="darwin"?{command:"open",args:[normalizedTarget]}:{command:"xdg-open",args:[normalizedTarget]};return await new Promise(resolve19=>{let child;try{child=spawnImpl(launcher.command,launcher.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(error){resolve19({opened:!1,error:toErrorMessage(error)});return}child.once("error",error=>{resolve19({opened:!1,error:toErrorMessage(error)})}),child.once("spawn",()=>{child.unref(),resolve19({opened:!0})})})}async function createZipBuffer(directory){let archive=Object.create(null);return await addDirectoryToArchive(path.resolve(directory),"",archive),zipSync(archive,{level:6})}async function addDirectoryToArchive(directory,relativeDirectory,archive){let entries=await readdir(directory,{withFileTypes:!0});entries.sort((left,right)=>compareCodeUnits(left.name,right.name));for(let entry of entries){let absolutePath=path.join(directory,entry.name),relativePath=relativeDirectory?`${relativeDirectory}/${entry.name}`:entry.name;if(entry.isDirectory()){await addDirectoryToArchive(absolutePath,relativePath,archive);continue}if(entry.isSymbolicLink())throw new Error(`Cannot add symbolic link to portable ZIP archive: ${relativePath}`);if(!entry.isFile())throw new Error(`Cannot add unsupported filesystem entry to ZIP archive: ${relativePath}`);if(relativePath==="__proto__")throw new Error("Cannot add reserved root ZIP entry name: __proto__");archive[relativePath]=[await readFile(absolutePath),{mtime:new Date(1980,0,1,0,0,0)}]}}function compareCodeUnits(left,right){return left<right?-1:left>right?1:0}function toErrorMessage(error){return error instanceof Error?error.message:String(error)}async function runAssetCommand(args,deps){if(hasHelpFlag(args)||args.rest.length===0){printAssetHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runAssetUpload(args,deps);return}if(subcommand==="list"){await runAssetList(args,deps);return}if(subcommand==="folder"){await runAssetFolder(args,deps);return}if(subcommand==="get"){await runAssetGet(args,deps);return}if(subcommand==="move"){await runAssetMove(args,deps);return}if(subcommand==="update"){await runAssetUpdate(args,deps);return}if(subcommand==="analyze"){await runAssetAnalyze(args,deps);return}if(subcommand==="open"){await runAssetOpen(args,deps);return}if(subcommand==="download"){await runAssetDownload(args,deps);return}if(subcommand==="tag"){await runAssetTag(args,deps);return}throw new Error("`platform asset` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`move`\u3001`update`\u3001`analyze`\u3001`open`\u3001`download`\u3001`folder`\u3001`tag`\u3002")}function printAssetHelp(){process.stdout.write(["platform asset <command>","","Commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>] [--json]"," platform asset list [--q <keyword>] [--media-type image|video] [--mime-type <mime>] [--folder-id <folder-id>] [--tag-ids <id,id>] [--has-ocr true|false] [--has-person true|false] [--is-svg true|false] [--scene <scene>] [--objects <name,name>] [--safety-flags <flag,flag>] [--orientation landscape|portrait|square] [--page <n>] [--limit <n>] [--json]"," platform asset folder list [--json]"," platform asset folder create <name> [--parent-folder-id <folder-id>] [--json]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id>] [--root] [--json]"," platform asset get <asset-id> [--json]"," platform asset move <asset-id> [--folder-id <folder-id> | --root] [--json]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--summary <text>] [--caption <text>] [--scene <scene>] [--objects <name,name>] [--ocr <text>] [--colors <hex,hex>] [--safety-flags <flag,flag>] [--tags <label,label>] [--json]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>] [--json]"," platform asset tag add <asset-id> <label> [--json]"," platform asset tag remove <asset-id> <label> [--json]","","Notes:"," - \u7B2C\u4E00\u9636\u6BB5\u4EE5 tenant/workspace \u4E3A\u4E3B\uFF0C\u4E0D\u8981\u6C42 app/consumer \u4E0A\u4E0B\u6587"," - `list` \u652F\u6301\u7CBE\u786E\u68C0\u7D22 + \u7ED3\u6784\u5316\u8FC7\u6EE4\uFF1B\u4E0D\u5355\u72EC\u63D0\u4F9B `search` \u5B50\u547D\u4EE4"," - `update` \u4E00\u6B21\u547D\u4EE4\u53EF patch \u591A\u4E2A\u5143\u6570\u636E\u5B57\u6BB5\uFF1B\u4E0D\u66FF\u6362\u539F\u59CB\u6587\u4EF6"," - `analyze` \u4E0D\u8C03\u7528\u89C6\u89C9\u6A21\u578B\u3001\u4E0D\u4E0A\u4F20\u56FE\u7247\uFF1B\u4EC5\u6839\u636E\u5143\u6570\u636E\u7ED9\u51FA\u300C\u4E0B\u8F7D\u54EA\u4E00\u7248 + \u5982\u4F55 update\u300D\u7684\u5EFA\u8BAE\uFF1B`--json` \u8F93\u51FA\u540C\u4E0A\u7ED3\u6784\u4FBF\u4E8E\u811A\u672C\u89E3\u6790"," - `analyze` \u53EF\u7528\u4E8E\u7ED9\u4EBA\u5DE5\u6216\u52A9\u624B\u751F\u6210\u5206\u6790\u64CD\u4F5C\u63D0\u793A\uFF0C\u4E0D\u76F4\u63A5\u8BFB\u53D6\u50CF\u7D20\u5185\u5BB9"," - `open` \u4F1A\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6\uFF1B\u672A\u6307\u5B9A `--output` \u65F6\u4F1A\u5199\u5165\u4E34\u65F6\u76EE\u5F55\u5E76\u5C1D\u8BD5\u6253\u5F00"," - `download --variant` \u7528\u4E8E\u660E\u786E\u4E0B\u8F7D\u6307\u5B9A\u53D8\u4F53\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6253\u5F00",""].join(`
|
|
2197
2197
|
`))}async function runAssetList(args,deps){let response=await deps.sdk.listTenantAssets({...readStringOption(args,"q")?{q:readStringOption(args,"q")}:{},...readMediaTypeOption(args)?{media_type:readMediaTypeOption(args)}:{},...readStringOption(args,"mime-type")?{mime_type:readStringOption(args,"mime-type")}:{},...readStringOption(args,"folder-id")?{folder_id:readStringOption(args,"folder-id")}:{},...readCsvOption(args,"tag-ids").length>0?{tag_ids:readCsvOption(args,"tag-ids")}:{},...readBooleanOption(args,"has-ocr")!==void 0?{has_ocr:readBooleanOption(args,"has-ocr")}:{},...readBooleanOption(args,"has-person")!==void 0?{has_person:readBooleanOption(args,"has-person")}:{},...readBooleanOption(args,"is-svg")!==void 0?{is_svg:readBooleanOption(args,"is-svg")}:{},...readStringOption(args,"scene")?{scene:readStringOption(args,"scene")}:{},...readCsvOption(args,"objects").length>0?{objects:readCsvOption(args,"objects")}:{},...readCsvOption(args,"safety-flags").length>0?{safety_flags:readCsvOption(args,"safety-flags")}:{},...readOrientationOption(args)?{orientation:readOrientationOption(args)}:{},...readNumberOption(args,"page")!==void 0?{page:readNumberOption(args,"page")}:{},...readNumberOption(args,"limit")!==void 0?{limit:readNumberOption(args,"limit")}:{}}).catch(error=>{throw formatAssetError(error,"list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2198
2198
|
`);return}process.stdout.write([`tenant/workspace: ${response.tenant_id}/${response.workspace_id}`,`assets: ${response.items.length}`,`page: ${response.page}/${Math.max(1,Math.ceil(response.total/Math.max(1,response.page_size)))}`,`page_size: ${response.page_size}`,`total: ${response.total}`,...response.items.map(item=>[item.asset.asset_id,item.asset.title,`mime=${item.asset.mime_type}`,`folder=${item.folder?.path??"/"}`,item.tags.length>0?`tags=${item.tags.map(tag=>tag.label).join(",")}`:"tags=-"].join(" ")),""].join(`
|
|
2199
2199
|
`))}async function runAssetFolder(args,deps){let action=args.rest[1];if(action==="list"){let response=await deps.sdk.listTenantAssetFolders().catch(error=>{throw formatAssetError(error,"folder list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
|
|
@@ -2407,10 +2407,10 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
|
|
|
2407
2407
|
`,"utf8")}function assertDirectory(pathValue,label){let stats=statSync4(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace(workspaceDir){assertDirectory(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES.filter(file=>!existsSync15(join11(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function buildMergeSummary(args,payload){let sourcePreprocessExecutionMode=payload.importSummary.source_preprocess_execution_mode||payload.importManifest.execution_mode||"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D merge \u6765\u6E90\u4E8E dry-run \u9884\u5904\u7406\u4EA7\u7269\uFF1Bsrc/imported-upstream/ \u4E2D\u4ECD\u53EF\u80FD\u5305\u542B\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"merge-imported-upstream",version:1,mode:"merge-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,import_summary:payload.importSummaryPath,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,upstream_clean_source_dir:payload.upstreamCleanSourceDir,merged_target_dir:payload.mergedTargetDir,merge_required:payload.mergeRequired,merged_paths:payload.mergedPaths,skipped_paths:payload.skippedPaths,preserved_workspace_files:payload.importSummary.preserved_workspace_files??[],warnings,next_steps:[`\u5728 ${payload.layout.imported_upstream_root}/ \u4E2D\u5BA1\u67E5\u4E0A\u6E38\u9875\u9762\u3001components\u3001styles\u3001lib\u3001imports`,payload.layout.template_key==="backend-app-node"?"\u4ECE src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC":"\u4ECE src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC","\u9010\u6B65\u628A\u9700\u8981\u7684\u5E73\u53F0\u80FD\u529B\u63A5\u5165\u5230\u6A21\u677F\u4E3B\u5BFC\u7684\u8FD0\u884C\u5165\u53E3\u4E2D","\u5B8C\u6210\u63A5\u7EBF\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}async function runAppImportMergeCli(argv){let args=parseArgs(argv);if(args.help){printAppImportMergeUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve9(args.workspaceDir);validateWorkspace(workspaceDir);let designImportRoot=join11(workspaceDir,".design-import"),importSummaryPath=join11(designImportRoot,"import-summary.json"),importManifestPath=join11(designImportRoot,"reports","import-manifest.json"),upstreamCleanSourceDir=join11(designImportRoot,"upstream-clean-source");assertDirectory(designImportRoot,".design-import"),assertDirectory(upstreamCleanSourceDir,"upstream-clean-source");let importSummary=readJson(importSummaryPath),importManifest=existsSync15(importManifestPath)?readJson(importManifestPath):{},layout=resolveAppImportLayout(workspaceDir),mergedTargetDir=join11(workspaceDir,...layout.imported_upstream_root.split("/")),upstreamSrcDir=join11(upstreamCleanSourceDir,"src"),upstreamPublicDir=join11(upstreamCleanSourceDir,"public"),mergedPublicTargetDir=join11(workspaceDir,"public","imported-upstream"),mergeRequired=!0,upstreamSrcExists=!!statSync4(upstreamSrcDir,{throwIfNoEntry:!1})?.isDirectory(),upstreamPublicExists=!!statSync4(upstreamPublicDir,{throwIfNoEntry:!1})?.isDirectory();importSummary.source_detected_type==="frontend-app"&&assertDirectory(upstreamSrcDir,"upstream clean-source/src");let mergedPaths=[],skippedPaths=[];if(args.dryRun||(rmSync3(mergedTargetDir,{recursive:!0,force:!0}),rmSync3(mergedPublicTargetDir,{recursive:!0,force:!0}),mkdirSync8(mergedTargetDir,{recursive:!0})),importSummary.source_detected_type==="frontend-app"&&upstreamSrcExists)for(let name of FRONTEND_MERGEABLE_SOURCE_DIRS){let sourcePath=join11(upstreamSrcDir,name),sourceStats=statSync4(sourcePath,{throwIfNoEntry:!1});if(!sourceStats||!sourceStats.isDirectory()){skippedPaths.push(`src/${name}`);continue}let targetPath=join11(mergedTargetDir,name);mergedPaths.push({source:`src/${name}`,target:`${layout.imported_upstream_root}/${name}`}),args.dryRun||cpSync(sourcePath,targetPath,{recursive:!0})}else importSummary.source_detected_type==="frontend-app"?skippedPaths.push("src/: upstream clean-source does not contain mergeable frontend source"):skippedPaths.push("src/: static-site upstream does not require frontend source merge");upstreamPublicExists?(mergedPaths.push({source:"public",target:"public/imported-upstream"}),args.dryRun||(mkdirSync8(join11(workspaceDir,"public"),{recursive:!0}),cpSync(upstreamPublicDir,mergedPublicTargetDir,{recursive:!0}))):skippedPaths.push("public");let summary=buildMergeSummary(args,{workspaceDir,importSummaryPath,importSummary,importManifest,layout,upstreamCleanSourceDir,mergedTargetDir,mergeRequired,mergedPaths,skippedPaths});if(args.dryRun||writeJson(join11(designImportRoot,"merge-summary.json"),summary),args.json){process.stdout.write(`${JSON.stringify(summary,null,2)}
|
|
2408
2408
|
`);return}process.stdout.write(["third-party design merge stage completed",`execution_mode: ${summary.execution_mode}`,`workspace_dir: ${summary.workspace_dir}`,`merged_target_dir: ${summary.merged_target_dir}`,`merged_paths: ${summary.merged_paths.length}`,`skipped_paths: ${summary.skipped_paths.length}`,`warnings: ${summary.warnings.length}`].join(`
|
|
2409
2409
|
`)+`
|
|
2410
|
-
`)}import{createHash as createHash5}from"node:crypto";import{
|
|
2410
|
+
`)}import{createHash as createHash5}from"node:crypto";import{copyFileSync,existsSync as existsSync16,lstatSync,mkdtempSync as mkdtempSync3,mkdirSync as mkdirSync9,readFileSync as readFileSync16,readdirSync as readdirSync5,rmSync as rmSync4,statSync as statSync5,unlinkSync as unlinkSync2,writeFileSync as writeFileSync10}from"node:fs";import{spawn}from"node:child_process";import{basename as basename4,dirname as dirname10,extname as extname3,join as join12,relative as relative3,resolve as resolve10}from"node:path";import{tmpdir as tmpdir2}from"node:os";var DEFAULT_INCLUDE_EXTENSIONS=new Set([".html",".css",".js",".jsx",".ts",".tsx",".vue",".svelte"]),DEFAULT_SKIP_DIRS=new Set([".git","node_modules","dist","build",".next",".nuxt","coverage",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]),IMAGE_HOST_HINTS=["unsplash.com","images.unsplash.com","googleusercontent.com","lh3.googleusercontent.com"],IMAGE_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".avif",".bmp",".ico"]),VIDEO_EXTENSIONS=new Set([".mp4",".webm",".mov",".m4v",".avi",".mkv"]),HTTPS_FORCE_HOST_SUFFIXES=["21epub.com"],URL_PATTERN=/https?:\/\/[^\s"'`)>\]]+/giu,LOCAL_ASSET_REF_PATTERN=/["'`](\.{1,2}\/[^"'`]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))["'`]/giu,CSS_URL_PATTERN=/url\((['"]?)(\.{1,2}\/[^)'"]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\1\)/giu,IMPORT_LOCAL_ASSET_PATTERN=/^(\s*)import\s+([A-Za-z_$][\w$]*)\s+from\s+(["'])(\.{1,2}\/[^"'`\n]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\3;?(\s*)$/gmu,LOCAL_IMAGE_UPLOAD_MAX_WIDTH=2048,PREFLIGHT_LOCAL_ASSET_WARN_BYTES=5*1024*1024,CACHE_VERSION=1,REMOTE_IMAGE_CONCURRENCY=3;function logProgress(message){process.stderr.write(`[app import preprocess] ${message}
|
|
2411
2411
|
`)}async function runWithConcurrency(items,concurrency,worker){let limit=Math.max(1,concurrency),results=new Array(items.length),nextIndex=0;async function consume(){for(;;){let currentIndex=nextIndex;if(nextIndex+=1,currentIndex>=items.length)return;results[currentIndex]=await worker(items[currentIndex],currentIndex)}}let runners=Array.from({length:Math.min(limit,items.length)},()=>consume());return await Promise.all(runners),results}function printAppImportPreprocessUsage(){process.stdout.write(["platform app import preprocess","","\u7528\u6CD5\uFF1A"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run] [--json]"," platform app import preprocess --dir <third-party-source-dir> --folder-id <asset-folder-id>","","\u4F5C\u7528\uFF1A"," \u626B\u63CF\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u505A\u7D20\u6750\u4E0A\u4F20\u56DE\u5199\u3001clean-source \u751F\u6210\u3001path-base \u57FA\u7840\u4FEE\u6B63\u4E0E\u9884\u5904\u7406\u62A5\u544A\u8F93\u51FA\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u7B49\u4EF7\u4E8E\u5728\u5F53\u524D\u76EE\u5F55\u6267\u884C\u9884\u5904\u7406\uFF1B\u82E5\u672A\u4F20 `--dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002"," - \u9ED8\u8BA4\u4F1A\u590D\u7528 `.design-preprocess/cache/` \u4E2D\u5DF2\u6210\u529F\u4E0A\u4F20\u7684\u7D20\u6750\u6620\u5C04\uFF1B\u82E5\u9700\u5FFD\u7565\u7F13\u5B58\u91CD\u8DD1\uFF0C\u53EF\u663E\u5F0F\u4F20 `--reset-cache`\u3002",""].join(`
|
|
2412
2412
|
`))}function parseArgs2(argv){let result={dir:"",include:new Set(DEFAULT_INCLUDE_EXTENSIONS),folderId:"",type:"auto",dryRun:!1,resume:!0,resetCache:!1,localReport:"",json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--resume"){result.resume=!0;continue}if(arg==="--reset-cache"){result.resetCache=!0;continue}if(arg==="--dir"){result.dir=argv[index+1]??"",index+=1;continue}if(arg==="--include"){let raw=argv[index+1]??"";index+=1,result.include=normalizeInclude(raw);continue}if(arg==="--folder-id"){result.folderId=argv[index+1]??"",index+=1;continue}if(arg==="--type"){result.type=argv[index+1]??result.type,index+=1;continue}if(arg==="--local-report"){result.localReport=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function normalizeInclude(raw){let values=raw.split(",").map(item=>item.trim().toLowerCase()).filter(Boolean).map(item=>item.startsWith(".")?item:`.${item}`);return values.length>0?new Set(values):new Set(DEFAULT_INCLUDE_EXTENSIONS)}function buildRemoteCacheKey(url){return`remote:${url}`}function buildLocalCacheKey(contentHash){return`local:${contentHash}`}function defaultAssetCache(sourceDir){return{version:CACHE_VERSION,source_dir:sourceDir,entries:{}}}function defaultLockState(){return{version:CACHE_VERSION,active_run_id:null,started_at:null,phase:null,in_progress_keys:[],last_interrupted_at:null}}function readJsonIfExists2(filePath,fallbackValue){if(!existsSync16(filePath))return fallbackValue;try{return JSON.parse(readFileSync16(filePath,"utf8"))}catch{return fallbackValue}}function loadAssetCache(cacheFile,sourceDir){let loaded=readJsonIfExists2(cacheFile,defaultAssetCache(sourceDir));return{version:CACHE_VERSION,source_dir:loaded.source_dir||sourceDir,entries:loaded.entries&&typeof loaded.entries=="object"?loaded.entries:{}}}function persistAssetCache(cacheFile,payload){ensureDir(dirname10(cacheFile)),writeJson2(cacheFile,payload)}function loadLockState(lockFile){let loaded=readJsonIfExists2(lockFile,defaultLockState());return{version:CACHE_VERSION,active_run_id:loaded.active_run_id??null,started_at:loaded.started_at??null,phase:loaded.phase??null,in_progress_keys:Array.isArray(loaded.in_progress_keys)?loaded.in_progress_keys:[],last_interrupted_at:loaded.last_interrupted_at??null}}function persistLockState(lockFile,payload){ensureDir(dirname10(lockFile)),writeJson2(lockFile,payload)}function beginLockRun(lockFile,previousLock){let interruptedItems=previousLock.active_run_id?previousLock.in_progress_keys.length:0,next={version:CACHE_VERSION,active_run_id:`preprocess-${Date.now()}`,started_at:new Date().toISOString(),phase:"scan",in_progress_keys:[],last_interrupted_at:previousLock.active_run_id?new Date().toISOString():previousLock.last_interrupted_at};return persistLockState(lockFile,next),{lock:next,interruptedItems}}function updateLockState(lockFile,currentLock,patch){let next={...currentLock,...patch};return persistLockState(lockFile,next),next}function completeLockRun(lockFile,currentLock){let next={...currentLock,active_run_id:null,phase:"completed",in_progress_keys:[]};return persistLockState(lockFile,next),next}function cacheEntryReusable(entry){return!!(entry&&typeof entry.final_url=="string"&&entry.final_url.trim()&&entry.asset_id&&entry.status!=="failed")}function updateCacheEntry(cache,cacheKey,patch){cache.entries[cacheKey]={...cache.entries[cacheKey]??{},...patch,updated_at:new Date().toISOString()}}function walkFiles(rootDir,includeExtensions){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname3(entry.name).toLowerCase();includeExtensions.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function walkAssetFiles(rootDir){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname3(entry.name).toLowerCase();IMAGE_EXTENSIONS.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function normalizeMatchedUrl(rawUrl){return rawUrl.replace(/[),.;]+$/u,"").replace(/^("?|"?|'?|'?)+/iu,"").replace(/("?|"?|'?|'?)+$/iu,"").replace(/&/giu,"&")}function findLineNumber(text2,offset){let line=1;for(let index=0;index<offset;index+=1)text2.charCodeAt(index)===10&&(line+=1);return line}function inferExtensionFromUrl(url){try{let parsed=new URL(url);return extname3(parsed.pathname).toLowerCase()}catch{return extname3(url).toLowerCase()}}function classifyUrl(url,surroundingText){let lowerUrl=url.toLowerCase(),extension=inferExtensionFromUrl(lowerUrl),lowerContext=surroundingText.toLowerCase(),nonImageContext=lowerContext.includes("<script")||lowerContext.includes("script src")||lowerContext.includes('rel="stylesheet"')||lowerContext.includes("rel='stylesheet'")||lowerContext.includes("xmlns="),nonImageUrl=lowerUrl.includes("cdn.tailwindcss.com")||lowerUrl.includes("fonts.googleapis.com")||lowerUrl.includes("fonts.gstatic.com")||lowerUrl.includes("w3.org/2000/svg");return lowerContext.includes("poster")?"poster":VIDEO_EXTENSIONS.has(extension)?"video":nonImageContext||nonImageUrl||extension===".js"||extension===".mjs"||extension===".css"?"unknown_remote":IMAGE_EXTENSIONS.has(extension)||IMAGE_HOST_HINTS.some(item=>lowerUrl.includes(item))||lowerContext.includes("<img")||lowerContext.includes("background-image")||lowerContext.includes("url(")?"image":"unknown_remote"}function computeRewriteSupported(kind){return kind==="image"}function compactContext(value){return value.replace(/\s+/gu," ").trim().slice(0,200)}function kindPriority(kind){switch(kind){case"video":return 4;case"poster":return 3;case"image":return 2;default:return 1}}function collectRemoteCandidates(rootDir,files){let byUrl=new Map;for(let filePath of files){let raw=readFileSync16(filePath,"utf8");for(let match2 of raw.matchAll(URL_PATTERN)){let matched=match2[0],offset=match2.index??0,url=normalizeMatchedUrl(matched),line=findLineNumber(raw,offset),surroundingText=raw.slice(Math.max(0,offset-80),Math.min(raw.length,offset+url.length+80)),kind=classifyUrl(url,surroundingText),occurrence={file:relative3(rootDir,filePath),line,kind,context:compactContext(surroundingText)},existing=byUrl.get(url);if(existing){existing.occurrences.push(occurrence),kindPriority(kind)>kindPriority(existing.kind)&&(existing.kind=kind,existing.rewrite_supported=computeRewriteSupported(kind));continue}byUrl.set(url,{url,kind,rewrite_supported:computeRewriteSupported(kind),occurrences:[occurrence],notes:kind==="video"?["\u5F53\u524D\u7B2C\u4E00\u7248\u4EC5\u626B\u63CF\uFF0C\u4E0D\u81EA\u52A8\u56DE\u5199\u89C6\u9891\u3002"]:[]})}}return[...byUrl.values()].sort((left,right)=>left.url.localeCompare(right.url))}function buildReport(rootDir,files,candidates,reportDir=join12(rootDir,".third-party-design-reports")){let byKind=candidates.reduce((accumulator,item)=>(accumulator[item.kind]=(accumulator[item.kind]??0)+1,accumulator),{}),pendingManualItems=candidates.filter(item=>item.rewrite_supported!==!0);return{tool:"assetize-project-urls",version:1,mode:"scan",project_dir:rootDir,scanned_files:files.map(file=>relative3(rootDir,file)),summary:{scanned_file_count:files.length,unique_remote_candidates:candidates.length,image_count:byKind.image??0,video_count:byKind.video??0,poster_count:byKind.poster??0,unknown_remote_count:byKind.unknown_remote??0},remote_candidates:candidates,pending_videos:candidates.filter(item=>item.kind==="video"),pending_manual_items:pendingManualItems,report_dir:reportDir}}function hashFileContent(filePath){let content=readFileSync16(filePath);return createHash5("sha256").update(content).digest("hex")}function collectReferencedLocalAssetPaths(sourceFilePath,sourceText){let found=new Set;for(let match2 of sourceText.matchAll(LOCAL_ASSET_REF_PATTERN))found.add(resolve10(dirname10(sourceFilePath),match2[1]));for(let match2 of sourceText.matchAll(CSS_URL_PATTERN))found.add(resolve10(dirname10(sourceFilePath),match2[2]));return found}function collectLocalAssetCandidates(rootDir,sourceFiles,assetFiles){let assetPathSet=new Set(assetFiles.map(filePath=>resolve10(filePath))),byHash=new Map,referencedAssets=new Map;for(let sourceFilePath of sourceFiles){let raw=readFileSync16(sourceFilePath,"utf8"),refs=collectReferencedLocalAssetPaths(sourceFilePath,raw);for(let absoluteRef of refs){if(!assetPathSet.has(absoluteRef))continue;let existing=referencedAssets.get(absoluteRef);if(existing){existing.referenced_by.push(relative3(rootDir,sourceFilePath));continue}referencedAssets.set(absoluteRef,{absolute_path:absoluteRef,relative_path:relative3(rootDir,absoluteRef),referenced_by:[relative3(rootDir,sourceFilePath)]})}}for(let asset of referencedAssets.values()){let stats=statSync5(asset.absolute_path),contentHash=hashFileContent(asset.absolute_path),existing=byHash.get(contentHash);if(existing){existing.source_paths.push(asset.relative_path),existing.referenced_by.push(...asset.referenced_by);continue}byHash.set(contentHash,{hash:contentHash,path:asset.relative_path,source_paths:[asset.relative_path],file_name:basename4(asset.absolute_path),size_bytes:stats.size,kind:"local_image",upload_supported:!0,referenced_by:[...asset.referenced_by]})}return[...byHash.values()].sort((left,right)=>left.path.localeCompare(right.path))}function detectProjectType(rootDir,requestedType="auto"){return requestedType==="static-site"||requestedType==="frontend-app"?requestedType:existsSync16(join12(rootDir,"package.json"))?"frontend-app":"static-site"}function collectPathBaseViolations(rootDir,files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let filePath of files){let relativePath=relative3(rootDir,filePath);if(!textFilePattern.test(relativePath))continue;let lines=readFileSync16(filePath,"utf8").split(/\r?\n/u);for(let index=0;index<lines.length;index+=1){let line=lines[index];for(let pattern of patterns)pattern.regex.lastIndex=0,pattern.regex.test(line)&&violations.push({file:relativePath,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function toPosixPath(value){return value.replace(/\\/gu,"/")}function ensureDotRelativePath(value){return value===""||value==="."?"./":value.startsWith("./")||value.startsWith("../")?value:`./${value}`}function resolveRootRelativePathForFile(rootDir,filePath,rootRelativePath){let normalizedTarget=rootRelativePath.replace(/^\/+/u,""),targetPath=join12(rootDir,normalizedTarget),relativePath=relative3(dirname10(filePath),targetPath);return ensureDotRelativePath(toPosixPath(relativePath))}function rewritePathBaseRefsInContent(rootDir,filePath,content){let changed=!1,rewrites=[],patterns=[{regex:/\b(src|href)\s*=\s*(["'])\/(?!\/)([^"'`]+)\2/gu,buildReplacement(attrName,quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"attribute",attr:attrName,from:`/${rawPath}`,to:nextPath}),`${attrName}=${quote}${nextPath}${quote}`}},{regex:/\bfetch\(\s*(["'])\/(?!\/)([^"'`]+)\1/gu,buildReplacement(quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"fetch",from:`/${rawPath}`,to:nextPath}),`fetch(${quote}${nextPath}${quote}`}}],next=content;return next=next.replace(patterns[0].regex,(fullMatch,attrName,quote,rawPath)=>(changed=!0,patterns[0].buildReplacement(attrName,quote,rawPath))),next=next.replace(patterns[1].regex,(fullMatch,quote,rawPath)=>(changed=!0,patterns[1].buildReplacement(quote,rawPath))),{changed,content:next,rewrites}}async function runPathBaseRewrite(args,report,files){let rewrittenFiles=[],rewriteEntries=[],warnings=[];for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),rewritten=rewritePathBaseRefsInContent(report.project_dir,absolutePath,before);rewritten.changed&&(args.dryRun||writeFileSync10(absolutePath,rewritten.content,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)),rewriteEntries.push({file:relative3(report.project_dir,absolutePath),rewrites:rewritten.rewrites}))}return rewriteEntries.length>0&&warnings.push(`\u5DF2\u4FEE\u6B63 root-relative \u9759\u6001\u8D44\u6E90\u5F15\u7528: ${rewriteEntries.length} \u4E2A\u6587\u4EF6`),{rewritten_files:rewrittenFiles,rewrite_entries:rewriteEntries,warnings}}function collectSourcePackageBytes(rootDir){let total=0;function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){visit(fullPath);continue}entry.isFile()&&(total+=statSync5(fullPath).size)}}return visit(rootDir),total}function collectPreflightWarnings(rootDir,localAssetCandidates){let warnings=[];existsSync16(join12(rootDir,"pnpm-workspace.yaml"))&&warnings.push({kind:"workspace_like",file:"pnpm-workspace.yaml",message:"\u68C0\u6D4B\u5230 pnpm-workspace.yaml\uFF1B\u540E\u7EED\u6A21\u677F\u627F\u63A5\u6216\u4E91\u7AEF\u6784\u5EFA\u524D\u901A\u5E38\u9700\u8981\u5904\u7406 workspace-like \u7ED3\u6784\u3002"});for(let asset of localAssetCandidates)asset.size_bytes>=PREFLIGHT_LOCAL_ASSET_WARN_BYTES&&warnings.push({kind:"large_local_asset",file:asset.path,size_bytes:asset.size_bytes,message:"\u68C0\u6D4B\u5230\u5927\u4F53\u79EF\u672C\u5730\u56FE\u7247\uFF1B\u5EFA\u8BAE\u5728\u9884\u5904\u7406\u9636\u6BB5\u5B8C\u6210\u4E0A\u4F20\u3001\u56DE\u5199\u4E0E\u6E05\u7406\u3002"});return warnings}function inferExtensionFromMimeType2(mimeType){switch((mimeType||"").toLowerCase()){case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"image/avif":return".avif";case"image/jpeg":case"image/jpg":return".jpg";default:return".jpg"}}function sanitizeFileStem(value){return value.toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,80)}function sanitizeFileName(value){let trimmed=value.trim(),extension=extname3(trimmed).toLowerCase(),stem=trimmed.slice(0,Math.max(0,trimmed.length-extension.length));return`${sanitizeFileStem(stem)||"remote-image"}${extension||".jpg"}`}function inferRemoteFileName(url,mimeType){let extension=inferExtensionFromUrl(url),fallbackExtension=inferExtensionFromMimeType2(mimeType);if(extension)try{let segment=new URL(url).pathname.split("/").filter(Boolean).at(-1);if(segment)return sanitizeFileName(decodeURIComponent(segment))}catch{}try{let parsed=new URL(url),rawSegment=parsed.pathname.split("/").filter(Boolean).at(-1)||parsed.hostname,sanitizedBase=sanitizeFileStem(decodeURIComponent(rawSegment).replace(/\.[a-z0-9]+$/iu,"").trim());if(sanitizedBase)return`${sanitizedBase}${fallbackExtension}`}catch{}switch((mimeType||"").toLowerCase()){case"image/png":return"remote-image.png";case"image/webp":return"remote-image.webp";case"image/gif":return"remote-image.gif";case"image/svg+xml":return"remote-image.svg";case"image/avif":return"remote-image.avif";default:return"remote-image.jpg"}}async function downloadRemoteImage(url,deps={}){let fetchImpl=deps.fetchImpl??fetch,runCurl=deps.runCurl??runCurlProcess;try{return await downloadRemoteImageViaFetch(url,fetchImpl)}catch(error){if(!shouldRetryRemoteDownloadWithCurl(error))throw error;try{return await downloadRemoteImageViaCurl(url,runCurl)}catch(curlError){let fetchMessage=error instanceof Error?error.message:String(error),curlMessage=curlError instanceof Error?curlError.message:String(curlError),unavailable=curlError&&typeof curlError=="object"&&curlError.code==="ENOENT";throw new Error(`${fetchMessage}
|
|
2413
|
-
${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:error})}}}async function downloadRemoteImageViaFetch(url,fetchImpl=fetch){let response=await fetchImpl(url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let mimeType=String(response.headers.get("content-type")??"").split(";")[0].trim().toLowerCase();if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=Buffer.from(await response.arrayBuffer());if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}function shouldRetryRemoteDownloadWithCurl(error){let message=error instanceof Error?error.message:String(error);return/fetch failed|timed?out|econnreset|socket|network|tls|und_err/iu.test(message)}function extractLastContentType(headerText){let matches=[...headerText.matchAll(/^content-type:\s*([^\r\n;]+)/gimu)];return matches.length>0?String(matches[matches.length-1][1]).trim().toLowerCase():""}async function runCurlProcess(executable,args){await new Promise((resolvePromise,reject)=>{let child=spawn(executable,args,{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`curl \u4E0B\u8F7D\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})})}async function downloadRemoteImageViaCurl(url,runCurl=runCurlProcess){let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-remote-")),outputPath=join12(tempRoot,"remote.bin"),headerPath=join12(tempRoot,"headers.txt");try{let injectedResult=await runCurl("curl",["-L","--fail","--silent","--show-error","-D",headerPath,"-o",outputPath,url]),headerText=typeof injectedResult?.headers=="string"?injectedResult.headers:existsSync16(headerPath)?readFileSync16(headerPath,"utf8"):"",mimeType=extractLastContentType(headerText);if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=injectedResult?.content?Buffer.from(injectedResult.content):readFileSync16(outputPath);if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function shouldRetryWithCompression(error){if(error&&typeof error=="object"&&"status"in error&&Number(error.status)===413)return!0;let message=error instanceof Error?error.message:String(error);return/\b413\b/u.test(message)}function buildCompressedFilePath(tempRoot,sourcePath){let safeStem=sanitizeFileStem(basename4(sourcePath,extname3(sourcePath)))||"compressed-image";return join12(tempRoot,`${safeStem}-${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}.jpg`)}function resolveImageCompressionRetry(platform){return platform==="darwin"?{mode:"sips"}:platform==="win32"?{mode:"manual",code:"image_compression_unsupported_on_windows"}:{mode:"manual",code:"image_compression_unavailable"}}async function runSipsCompressor({sourcePath,outputPath}){return await new Promise((resolvePromise,reject)=>{let child=spawn("sips",["-s","format","jpeg","--resampleWidth",String(LOCAL_IMAGE_UPLOAD_MAX_WIDTH),sourcePath,"--out",outputPath],{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`sips \u538B\u7F29\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})}),outputPath}function shouldForceHttps(hostname){let lower=hostname.toLowerCase();return lower==="localhost"||lower==="127.0.0.1"||lower==="::1"?!1:HTTPS_FORCE_HOST_SUFFIXES.some(suffix=>lower===suffix||lower.endsWith(`.${suffix}`))}function normalizeUploadedAssetUrl(rawUrl){try{let parsed=new URL(rawUrl);return parsed.protocol==="http:"&&shouldForceHttps(parsed.hostname)?(parsed.protocol="https:",parsed.toString()):rawUrl}catch{return rawUrl}}function replaceUrlInContent(content,originalUrl,finalUrl){return content.split(originalUrl).join(finalUrl)}function normalizeLocalAssetReportPath(args,reportDir){return args.localReport?resolve10(args.localReport):join12(reportDir,"local-asset-report.json")}function loadLocalUploadMappings(reportPath){if(!existsSync16(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync16(reportPath,"utf8"));if(!Array.isArray(payload.uploaded_local_assets))throw new Error(`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u683C\u5F0F\u65E0\u6548\uFF0C\u7F3A\u5C11 uploaded_local_assets: ${reportPath}`);let bySourcePath=new Map;for(let item of payload.uploaded_local_assets){if(!item||typeof item.final_url!="string"||!item.final_url.trim()||item.status!=="uploaded"&&item.status!=="uploaded_after_compress"&&item.status!=="reused_from_cache")continue;let allSourcePaths=Array.isArray(item.source_paths)&&item.source_paths.length>0?item.source_paths:[item.source_path];for(let sourcePath of allSourcePaths)typeof sourcePath=="string"&&sourcePath.trim()&&bySourcePath.set(sourcePath,item.final_url)}return{reportPath,bySourcePath}}function rewriteImportedLocalAssets(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(IMPORT_LOCAL_ASSET_PATTERN,(fullMatch,leading,identifier,quote,rawRef,trailing)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,`${leading}const ${identifier} = ${quote}${finalUrl}${quote};${trailing}`):fullMatch});return{changed,content:next}}function rewriteLiteralLocalAssetRefs(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(LOCAL_ASSET_REF_PATTERN,(fullMatch,rawRef)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,fullMatch.replace(rawRef,finalUrl)):fullMatch});return{changed,content:next}}async function runRewriteLocal(args,report,files,cacheContext){let warnings=[];if(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0)return{rewritten_files:[],deleted_clean_source_assets:[],warnings};let localReportPath=normalizeLocalAssetReportPath(args,report.report_dir),loaded=loadLocalUploadMappings(localReportPath),relativePathToUrl=loaded.bySourcePath;if(relativePathToUrl.size===0){let message=report.local_asset_candidates.length===0?`\u5F53\u524D\u6E90\u7801\u5305\u672A\u68C0\u6D4B\u5230\u9700\u8981\u56DE\u5199\u7684\u672C\u5730\u7D20\u6750: ${loaded.reportPath}`:`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u91CC\u6CA1\u6709\u53EF\u56DE\u5199\u7684\u6210\u529F\u4E0A\u4F20\u8BB0\u5F55: ${loaded.reportPath}`;return args.dryRun?{rewritten_files:[],deleted_clean_source_assets:[],warnings:[`dry-run \u6A21\u5F0F\u4E0B\u672A\u751F\u6210\u672C\u5730\u7D20\u6750\u56DE\u5199\u6620\u5C04: ${loaded.reportPath}`]}:{rewritten_files:[],deleted_clean_source_assets:[],warnings:[message]}}let rewrittenFiles=[],deletedLocalAssets=[],hashBySourcePath=new Map;for(let asset of report.local_asset_candidates)for(let sourcePath of asset.source_paths)hashBySourcePath.set(sourcePath,asset.hash);for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),after=before;after=rewriteImportedLocalAssets(report.project_dir,absolutePath,after,relativePathToUrl).content,after=rewriteLiteralLocalAssetRefs(report.project_dir,absolutePath,after,relativePathToUrl).content,after!==before&&(args.dryRun||writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_local_refs"});for(let sourcePath of[...relativePathToUrl.keys()]){let contentHash=hashBySourcePath.get(sourcePath);if(!contentHash)continue;let cacheKey=buildLocalCacheKey(contentHash),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}for(let sourcePath of[...relativePathToUrl.keys()].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,sourcePath);if(!existsSync16(absolutePath))continue;let contentHash=hashBySourcePath.get(sourcePath),cacheKey=contentHash?buildLocalCacheKey(contentHash):null;if(cacheContext?.enabled&&cacheKey){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"cleanup_local_assets",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]});let cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaning"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}args.dryRun||unlinkSync2(absolutePath),deletedLocalAssets.push(sourcePath),cacheContext?.enabled&&cacheKey&&(cacheContext.cache.entries[cacheKey]&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaned"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}return warnings.push(`\u5DF2\u57FA\u4E8E\u4E0A\u4F20\u62A5\u544A\u56DE\u5199\u672C\u5730\u56FE\u7247\u5F15\u7528: ${loaded.reportPath}`),{rewritten_files:rewrittenFiles,deleted_clean_source_assets:deletedLocalAssets,warnings}}function copyWorkspaceForPreprocess(sourceDir,cleanSourceDir){rmSync4(cleanSourceDir,{recursive:!0,force:!0}),ensureDir(cleanSourceDir);let entries=readdirSync5(sourceDir,{withFileTypes:!0});for(let entry of entries)DEFAULT_SKIP_DIRS.has(entry.name)||cpSync2(join12(sourceDir,entry.name),join12(cleanSourceDir,entry.name),{recursive:!0})}function buildPreflightPayload(report,sourceDir,cleanSourceDir,options){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,detected_type:options.detectedType,upstream_source_package_bytes:options.upstreamSourcePackageBytes,clean_source_package_bytes_before_rewrite:options.cleanSourcePackageBytesBeforeRewrite,summary:report.summary,path_base_violations_detected:options.pathBaseViolationsDetected,path_base_rewrites:options.pathBaseRewrites,path_base_violations_remaining:options.pathBaseViolationsRemaining,preflight_warnings:options.preflightWarnings,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,pending_videos:report.pending_videos,pending_manual_items:report.pending_manual_items}}function buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets}}function countAppliedRemoteUploads(rewriteResult){return rewriteResult.uploaded_assets.filter(item=>item.status==="uploaded").length}function countAppliedLocalUploads(localUploadResult){return localUploadResult.uploaded_local_assets.filter(item=>item.status==="uploaded"||item.status==="uploaded_after_compress").length}function buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult){return{remote_upload_candidates:rewriteResult.uploaded_assets.length,local_upload_candidates:localUploadResult.uploaded_local_assets.length,path_base_rewrite_candidates:pathBaseRewriteResult.rewritten_files.length,local_cleanup_candidates:localRewriteResult.deleted_clean_source_assets.length,file_rewrite_candidates:rewriteResult.rewritten_files.length+localRewriteResult.rewritten_files.length+pathBaseRewriteResult.rewritten_files.length,pending_video_candidates:report.pending_videos.length}}function buildWarningsPayload(report,importManifest,reportsDir,cacheContext){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:importManifest.source_dir,clean_source_dir:importManifest.clean_source_dir,warnings:importManifest.warnings,pending_manual_items:report.pending_manual_items,pending_videos:report.pending_videos,cache_warnings:cacheContext?.warnings??[],recovery_actions:{resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0},report_files:{preflight_report:join12(reportsDir,"preflight-report.json"),asset_inventory:join12(reportsDir,"asset-inventory.json"),import_manifest:join12(reportsDir,"import-manifest.json"),pending_videos:join12(reportsDir,"pending-videos.json")}}}function buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext){return{tool:report.tool,version:report.version,generated_at:new Date().toISOString(),mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,cache_dir:cacheContext?.cacheDir??null,cache_enabled:cacheContext?.enabled??!1,resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0,clean_source_package_bytes:collectSourcePackageBytes(cleanSourceDir),summary:report.summary,planned_actions:buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult),asset_mappings:{remote:rewriteResult.uploaded_assets,local:localUploadResult.uploaded_local_assets},rewritten_files:[...rewriteResult.rewritten_files,...localRewriteResult.rewritten_files,...pathBaseRewriteResult.rewritten_files],deleted_clean_source_assets:localRewriteResult.deleted_clean_source_assets,path_base_rewrites:pathBaseRewriteResult.rewrite_entries,pending_videos:report.pending_videos,warnings:[...rewriteResult.warnings,...localUploadResult.warnings,...localRewriteResult.warnings,...pathBaseRewriteResult.warnings]}}async function runRewrite(args,report,cacheContext,deps){let imageCandidates=report.remote_candidates.filter(item=>item.kind==="image"&&item.rewrite_supported===!0),warnings=[],uploads=[],replacements=new Map;if(args.dryRun)return{uploaded_assets:imageCandidates.map(item=>({original_url:item.url,final_url:item.url,status:"dry-run"})),rewritten_files:[],warnings};let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-project-"));try{let total=imageCandidates.length,uploadResults=await runWithConcurrency(imageCandidates,REMOTE_IMAGE_CONCURRENCY,async(candidate,index)=>{let itemLabel=`remote image ${index+1}/${total}`,cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached))return logProgress(`${itemLabel} reused from cache: ${candidate.url}`),cacheContext.stats.remote_reused+=1,{candidate,finalUrl:cached.final_url,assetId:cached.asset_id??null,status:"reused_from_cache"};try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_remote",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploading",original_ref:candidate.url}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let downloadStart=Date.now();logProgress(`${itemLabel} downloading: ${candidate.url}`);let downloaded=await downloadRemoteImage(candidate.url,{fetchImpl:deps.fetchImpl,runCurl:deps.runCurl}),downloadMs=Date.now()-downloadStart,tempFilePath=join12(tempRoot,`${index+1}-${downloaded.fileName}`);writeFileSync10(tempFilePath,downloaded.content),logProgress(`${itemLabel} downloaded in ${downloadMs}ms, uploading asset`);let uploadStart=Date.now(),uploaded=await deps.uploadAsset({filePath:tempFilePath,title:downloaded.fileName,folderId:args.folderId||void 0}),uploadMs=Date.now()-uploadStart,finalUrl=normalizeUploadedAssetUrl(uploaded.original_url);return logProgress(`${itemLabel} uploaded in ${uploadMs}ms`),finalUrl!==uploaded.original_url&&warnings.push(`\u5DF2\u5C06\u7D20\u6750 URL \u534F\u8BAE\u89C4\u8303\u5316\u4E3A HTTPS: ${uploaded.original_url} -> ${finalUrl}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploaded",original_ref:candidate.url,final_url:finalUrl,asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,content_digest:`sha256:${createHash5("sha256").update(downloaded.content).digest("hex")}`}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)})),{candidate,finalUrl,assetId:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}}catch(error){let message=error instanceof Error?error.message:String(error);return logProgress(`${itemLabel} failed: ${message}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"failed",original_ref:candidate.url,last_error:message}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),{candidate,error:message,status:"fallback"}}});for(let result of uploadResults){if(result.error){warnings.push(`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${result.candidate.url} (${result.error})`),uploads.push({original_url:result.candidate.url,final_url:result.candidate.url,status:"fallback"});continue}replacements.set(result.candidate.url,result.finalUrl),uploads.push({original_url:result.candidate.url,final_url:result.finalUrl,asset_id:result.assetId??null,status:result.status})}let targetFiles=new Set(imageCandidates.flatMap(candidate=>candidate.occurrences.map(occurrence=>occurrence.file))),rewrittenFiles=[];for(let relativePath of[...targetFiles].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,relativePath),before=readFileSync16(absolutePath,"utf8"),after=before;for(let[originalUrl,finalUrl]of replacements)after=replaceUrlInContent(after,originalUrl,finalUrl);after!==before&&(writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relativePath))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_remote_refs"});for(let candidate of imageCandidates){let cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}return{uploaded_assets:uploads,rewritten_files:rewrittenFiles,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}async function runUploadLocal(args,report,cacheContext,deps){let warnings=[],uploads=[],tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-local-"));try{if(args.dryRun)return{uploaded_local_assets:report.local_asset_candidates.map(item=>({source_path:item.path,title:item.file_name,status:"dry-run"})),warnings};for(let asset of report.local_asset_candidates){let absolutePath=join12(report.project_dir,asset.path),cacheKey=buildLocalCacheKey(asset.hash),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached)){uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:cached.title??asset.file_name,final_url:cached.final_url,asset_id:cached.asset_id??null,status:"reused_from_cache"}),cacheContext.stats.local_reused+=1;continue}try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_local",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploading",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let uploaded=await deps.uploadAsset({filePath:absolutePath,title:asset.file_name,folderId:args.folderId||void 0});uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}catch(error){if(shouldRetryWithCompression(error)){let hostPlatform=deps.platform??process.platform,retry=resolveImageCompressionRetry(hostPlatform);if(retry.mode==="manual")warnings.push(`[${retry.code}] \u672C\u5730\u56FE\u7247\u8D85\u8FC7\u4E0A\u4F20\u9650\u5236\uFF08HTTP 413\uFF09\uFF0C${hostPlatform==="win32"?"Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u538B\u7F29":"\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u81EA\u52A8\u538B\u7F29"}: ${asset.path}\u3002\u8BF7\u5C06\u56FE\u7247\u5BBD\u5EA6\u538B\u7F29\u81F3\u4E0D\u8D85\u8FC7 ${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}px \u5E76\u51CF\u5C0F\u6587\u4EF6\u4F53\u79EF\uFF0C\u7136\u540E\u6267\u884C\uFF1Aplatform app import preprocess --dir "${report.project_dir}" --reset-cache`);else try{let outputPath=buildCompressedFilePath(tempRoot,absolutePath),compressedPath=await(deps.runCompressor??runSipsCompressor)({sourcePath:absolutePath,outputPath}),uploaded=await deps.uploadAsset({filePath:compressedPath,title:basename4(compressedPath),folderId:args.folderId||void 0});warnings.push(`\u672C\u5730\u56FE\u7247\u8FC7\u5927\uFF0C\u5DF2\u81EA\u52A8\u538B\u7F29\u540E\u4E0A\u4F20: ${asset.path}`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded_after_compress"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}));continue}catch(compressionError){warnings.push(`\u672C\u5730\u56FE\u7247\u538B\u7F29\u91CD\u8BD5\u5931\u8D25: ${asset.path} (${compressionError instanceof Error?compressionError.message:String(compressionError)})`)}}warnings.push(`\u672C\u5730\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${asset.path} (${error instanceof Error?error.message:String(error)})`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,status:"failed"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"failed",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,last_error:error instanceof Error?error.message:String(error)}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}}return{uploaded_local_assets:uploads,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function renderMarkdown(report){let lines=[];if(lines.push("# Scan Report",""),lines.push(`- Project: \`${report.project_dir}\``),lines.push(`- Mode: \`${report.mode}\``),lines.push(`- Scanned files: ${report.summary.scanned_file_count}`),lines.push(`- Unique remote candidates: ${report.summary.unique_remote_candidates}`),lines.push(`- Images: ${report.summary.image_count}`),lines.push(`- Videos: ${report.summary.video_count}`),lines.push(`- Posters: ${report.summary.poster_count}`),lines.push(`- Unknown remote: ${report.summary.unknown_remote_count}`),lines.push(`- Local images: ${report.summary.local_asset_count??0}`,""),report.remote_candidates.length===0&&(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0))return lines.push("No candidates found.",""),lines.join(`
|
|
2413
|
+
${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:error})}}}async function downloadRemoteImageViaFetch(url,fetchImpl=fetch){let response=await fetchImpl(url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let mimeType=String(response.headers.get("content-type")??"").split(";")[0].trim().toLowerCase();if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=Buffer.from(await response.arrayBuffer());if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}function shouldRetryRemoteDownloadWithCurl(error){let message=error instanceof Error?error.message:String(error);return/fetch failed|timed?out|econnreset|socket|network|tls|und_err/iu.test(message)}function extractLastContentType(headerText){let matches=[...headerText.matchAll(/^content-type:\s*([^\r\n;]+)/gimu)];return matches.length>0?String(matches[matches.length-1][1]).trim().toLowerCase():""}async function runCurlProcess(executable,args){await new Promise((resolvePromise,reject)=>{let child=spawn(executable,args,{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`curl \u4E0B\u8F7D\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})})}async function downloadRemoteImageViaCurl(url,runCurl=runCurlProcess){let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-remote-")),outputPath=join12(tempRoot,"remote.bin"),headerPath=join12(tempRoot,"headers.txt");try{let injectedResult=await runCurl("curl",["-L","--fail","--silent","--show-error","-D",headerPath,"-o",outputPath,url]),headerText=typeof injectedResult?.headers=="string"?injectedResult.headers:existsSync16(headerPath)?readFileSync16(headerPath,"utf8"):"",mimeType=extractLastContentType(headerText);if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=injectedResult?.content?Buffer.from(injectedResult.content):readFileSync16(outputPath);if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function shouldRetryWithCompression(error){if(error&&typeof error=="object"&&"status"in error&&Number(error.status)===413)return!0;let message=error instanceof Error?error.message:String(error);return/\b413\b/u.test(message)}function buildCompressedFilePath(tempRoot,sourcePath){let safeStem=sanitizeFileStem(basename4(sourcePath,extname3(sourcePath)))||"compressed-image";return join12(tempRoot,`${safeStem}-${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}.jpg`)}function resolveImageCompressionRetry(platform){return platform==="darwin"?{mode:"sips"}:platform==="win32"?{mode:"manual",code:"image_compression_unsupported_on_windows"}:{mode:"manual",code:"image_compression_unavailable"}}async function runSipsCompressor({sourcePath,outputPath}){return await new Promise((resolvePromise,reject)=>{let child=spawn("sips",["-s","format","jpeg","--resampleWidth",String(LOCAL_IMAGE_UPLOAD_MAX_WIDTH),sourcePath,"--out",outputPath],{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`sips \u538B\u7F29\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})}),outputPath}function shouldForceHttps(hostname){let lower=hostname.toLowerCase();return lower==="localhost"||lower==="127.0.0.1"||lower==="::1"?!1:HTTPS_FORCE_HOST_SUFFIXES.some(suffix=>lower===suffix||lower.endsWith(`.${suffix}`))}function normalizeUploadedAssetUrl(rawUrl){try{let parsed=new URL(rawUrl);return parsed.protocol==="http:"&&shouldForceHttps(parsed.hostname)?(parsed.protocol="https:",parsed.toString()):rawUrl}catch{return rawUrl}}function replaceUrlInContent(content,originalUrl,finalUrl){return content.split(originalUrl).join(finalUrl)}function normalizeLocalAssetReportPath(args,reportDir){return args.localReport?resolve10(args.localReport):join12(reportDir,"local-asset-report.json")}function loadLocalUploadMappings(reportPath){if(!existsSync16(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync16(reportPath,"utf8"));if(!Array.isArray(payload.uploaded_local_assets))throw new Error(`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u683C\u5F0F\u65E0\u6548\uFF0C\u7F3A\u5C11 uploaded_local_assets: ${reportPath}`);let bySourcePath=new Map;for(let item of payload.uploaded_local_assets){if(!item||typeof item.final_url!="string"||!item.final_url.trim()||item.status!=="uploaded"&&item.status!=="uploaded_after_compress"&&item.status!=="reused_from_cache")continue;let allSourcePaths=Array.isArray(item.source_paths)&&item.source_paths.length>0?item.source_paths:[item.source_path];for(let sourcePath of allSourcePaths)typeof sourcePath=="string"&&sourcePath.trim()&&bySourcePath.set(sourcePath,item.final_url)}return{reportPath,bySourcePath}}function rewriteImportedLocalAssets(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(IMPORT_LOCAL_ASSET_PATTERN,(fullMatch,leading,identifier,quote,rawRef,trailing)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,`${leading}const ${identifier} = ${quote}${finalUrl}${quote};${trailing}`):fullMatch});return{changed,content:next}}function rewriteLiteralLocalAssetRefs(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(LOCAL_ASSET_REF_PATTERN,(fullMatch,rawRef)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,fullMatch.replace(rawRef,finalUrl)):fullMatch});return{changed,content:next}}async function runRewriteLocal(args,report,files,cacheContext){let warnings=[];if(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0)return{rewritten_files:[],deleted_clean_source_assets:[],warnings};let localReportPath=normalizeLocalAssetReportPath(args,report.report_dir),loaded=loadLocalUploadMappings(localReportPath),relativePathToUrl=loaded.bySourcePath;if(relativePathToUrl.size===0){let message=report.local_asset_candidates.length===0?`\u5F53\u524D\u6E90\u7801\u5305\u672A\u68C0\u6D4B\u5230\u9700\u8981\u56DE\u5199\u7684\u672C\u5730\u7D20\u6750: ${loaded.reportPath}`:`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u91CC\u6CA1\u6709\u53EF\u56DE\u5199\u7684\u6210\u529F\u4E0A\u4F20\u8BB0\u5F55: ${loaded.reportPath}`;return args.dryRun?{rewritten_files:[],deleted_clean_source_assets:[],warnings:[`dry-run \u6A21\u5F0F\u4E0B\u672A\u751F\u6210\u672C\u5730\u7D20\u6750\u56DE\u5199\u6620\u5C04: ${loaded.reportPath}`]}:{rewritten_files:[],deleted_clean_source_assets:[],warnings:[message]}}let rewrittenFiles=[],deletedLocalAssets=[],hashBySourcePath=new Map;for(let asset of report.local_asset_candidates)for(let sourcePath of asset.source_paths)hashBySourcePath.set(sourcePath,asset.hash);for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),after=before;after=rewriteImportedLocalAssets(report.project_dir,absolutePath,after,relativePathToUrl).content,after=rewriteLiteralLocalAssetRefs(report.project_dir,absolutePath,after,relativePathToUrl).content,after!==before&&(args.dryRun||writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_local_refs"});for(let sourcePath of[...relativePathToUrl.keys()]){let contentHash=hashBySourcePath.get(sourcePath);if(!contentHash)continue;let cacheKey=buildLocalCacheKey(contentHash),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}for(let sourcePath of[...relativePathToUrl.keys()].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,sourcePath);if(!existsSync16(absolutePath))continue;let contentHash=hashBySourcePath.get(sourcePath),cacheKey=contentHash?buildLocalCacheKey(contentHash):null;if(cacheContext?.enabled&&cacheKey){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"cleanup_local_assets",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]});let cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaning"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}args.dryRun||unlinkSync2(absolutePath),deletedLocalAssets.push(sourcePath),cacheContext?.enabled&&cacheKey&&(cacheContext.cache.entries[cacheKey]&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaned"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}return warnings.push(`\u5DF2\u57FA\u4E8E\u4E0A\u4F20\u62A5\u544A\u56DE\u5199\u672C\u5730\u56FE\u7247\u5F15\u7528: ${loaded.reportPath}`),{rewritten_files:rewrittenFiles,deleted_clean_source_assets:deletedLocalAssets,warnings}}function copyWorkspaceForPreprocess(sourceDir,cleanSourceDir){rmSync4(cleanSourceDir,{recursive:!0,force:!0}),ensureDir(cleanSourceDir);let entries=readdirSync5(sourceDir,{withFileTypes:!0});for(let entry of entries)DEFAULT_SKIP_DIRS.has(entry.name)||copyWorkspaceEntry(join12(sourceDir,entry.name),join12(cleanSourceDir,entry.name))}function copyWorkspaceEntry(sourcePath,targetPath){let sourceStats=lstatSync(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`\u9884\u5904\u7406\u590D\u5236\u6E90\u4E0D\u5B58\u5728: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`\u9884\u5904\u7406\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5\uFF0C\u8BF7\u5148\u8F6C\u6362\u4E3A\u666E\u901A\u6587\u4EF6\u6216\u76EE\u5F55: ${sourcePath}`);if(sourceStats.isDirectory()){ensureDir(targetPath);for(let entry of readdirSync5(sourcePath,{withFileTypes:!0}))copyWorkspaceEntry(join12(sourcePath,entry.name),join12(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir(dirname10(targetPath)),copyFileSync(sourcePath,targetPath);return}throw new Error(`\u9884\u5904\u7406\u4E0D\u652F\u6301\u590D\u5236\u6B64\u6587\u4EF6\u7C7B\u578B: ${sourcePath}`)}function buildPreflightPayload(report,sourceDir,cleanSourceDir,options){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,detected_type:options.detectedType,upstream_source_package_bytes:options.upstreamSourcePackageBytes,clean_source_package_bytes_before_rewrite:options.cleanSourcePackageBytesBeforeRewrite,summary:report.summary,path_base_violations_detected:options.pathBaseViolationsDetected,path_base_rewrites:options.pathBaseRewrites,path_base_violations_remaining:options.pathBaseViolationsRemaining,preflight_warnings:options.preflightWarnings,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,pending_videos:report.pending_videos,pending_manual_items:report.pending_manual_items}}function buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets}}function countAppliedRemoteUploads(rewriteResult){return rewriteResult.uploaded_assets.filter(item=>item.status==="uploaded").length}function countAppliedLocalUploads(localUploadResult){return localUploadResult.uploaded_local_assets.filter(item=>item.status==="uploaded"||item.status==="uploaded_after_compress").length}function buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult){return{remote_upload_candidates:rewriteResult.uploaded_assets.length,local_upload_candidates:localUploadResult.uploaded_local_assets.length,path_base_rewrite_candidates:pathBaseRewriteResult.rewritten_files.length,local_cleanup_candidates:localRewriteResult.deleted_clean_source_assets.length,file_rewrite_candidates:rewriteResult.rewritten_files.length+localRewriteResult.rewritten_files.length+pathBaseRewriteResult.rewritten_files.length,pending_video_candidates:report.pending_videos.length}}function buildWarningsPayload(report,importManifest,reportsDir,cacheContext){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:importManifest.source_dir,clean_source_dir:importManifest.clean_source_dir,warnings:importManifest.warnings,pending_manual_items:report.pending_manual_items,pending_videos:report.pending_videos,cache_warnings:cacheContext?.warnings??[],recovery_actions:{resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0},report_files:{preflight_report:join12(reportsDir,"preflight-report.json"),asset_inventory:join12(reportsDir,"asset-inventory.json"),import_manifest:join12(reportsDir,"import-manifest.json"),pending_videos:join12(reportsDir,"pending-videos.json")}}}function buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext){return{tool:report.tool,version:report.version,generated_at:new Date().toISOString(),mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,cache_dir:cacheContext?.cacheDir??null,cache_enabled:cacheContext?.enabled??!1,resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0,clean_source_package_bytes:collectSourcePackageBytes(cleanSourceDir),summary:report.summary,planned_actions:buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult),asset_mappings:{remote:rewriteResult.uploaded_assets,local:localUploadResult.uploaded_local_assets},rewritten_files:[...rewriteResult.rewritten_files,...localRewriteResult.rewritten_files,...pathBaseRewriteResult.rewritten_files],deleted_clean_source_assets:localRewriteResult.deleted_clean_source_assets,path_base_rewrites:pathBaseRewriteResult.rewrite_entries,pending_videos:report.pending_videos,warnings:[...rewriteResult.warnings,...localUploadResult.warnings,...localRewriteResult.warnings,...pathBaseRewriteResult.warnings]}}async function runRewrite(args,report,cacheContext,deps){let imageCandidates=report.remote_candidates.filter(item=>item.kind==="image"&&item.rewrite_supported===!0),warnings=[],uploads=[],replacements=new Map;if(args.dryRun)return{uploaded_assets:imageCandidates.map(item=>({original_url:item.url,final_url:item.url,status:"dry-run"})),rewritten_files:[],warnings};let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-project-"));try{let total=imageCandidates.length,uploadResults=await runWithConcurrency(imageCandidates,REMOTE_IMAGE_CONCURRENCY,async(candidate,index)=>{let itemLabel=`remote image ${index+1}/${total}`,cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached))return logProgress(`${itemLabel} reused from cache: ${candidate.url}`),cacheContext.stats.remote_reused+=1,{candidate,finalUrl:cached.final_url,assetId:cached.asset_id??null,status:"reused_from_cache"};try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_remote",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploading",original_ref:candidate.url}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let downloadStart=Date.now();logProgress(`${itemLabel} downloading: ${candidate.url}`);let downloaded=await downloadRemoteImage(candidate.url,{fetchImpl:deps.fetchImpl,runCurl:deps.runCurl}),downloadMs=Date.now()-downloadStart,tempFilePath=join12(tempRoot,`${index+1}-${downloaded.fileName}`);writeFileSync10(tempFilePath,downloaded.content),logProgress(`${itemLabel} downloaded in ${downloadMs}ms, uploading asset`);let uploadStart=Date.now(),uploaded=await deps.uploadAsset({filePath:tempFilePath,title:downloaded.fileName,folderId:args.folderId||void 0}),uploadMs=Date.now()-uploadStart,finalUrl=normalizeUploadedAssetUrl(uploaded.original_url);return logProgress(`${itemLabel} uploaded in ${uploadMs}ms`),finalUrl!==uploaded.original_url&&warnings.push(`\u5DF2\u5C06\u7D20\u6750 URL \u534F\u8BAE\u89C4\u8303\u5316\u4E3A HTTPS: ${uploaded.original_url} -> ${finalUrl}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploaded",original_ref:candidate.url,final_url:finalUrl,asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,content_digest:`sha256:${createHash5("sha256").update(downloaded.content).digest("hex")}`}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)})),{candidate,finalUrl,assetId:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}}catch(error){let message=error instanceof Error?error.message:String(error);return logProgress(`${itemLabel} failed: ${message}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"failed",original_ref:candidate.url,last_error:message}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),{candidate,error:message,status:"fallback"}}});for(let result of uploadResults){if(result.error){warnings.push(`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${result.candidate.url} (${result.error})`),uploads.push({original_url:result.candidate.url,final_url:result.candidate.url,status:"fallback"});continue}replacements.set(result.candidate.url,result.finalUrl),uploads.push({original_url:result.candidate.url,final_url:result.finalUrl,asset_id:result.assetId??null,status:result.status})}let targetFiles=new Set(imageCandidates.flatMap(candidate=>candidate.occurrences.map(occurrence=>occurrence.file))),rewrittenFiles=[];for(let relativePath of[...targetFiles].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,relativePath),before=readFileSync16(absolutePath,"utf8"),after=before;for(let[originalUrl,finalUrl]of replacements)after=replaceUrlInContent(after,originalUrl,finalUrl);after!==before&&(writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relativePath))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_remote_refs"});for(let candidate of imageCandidates){let cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}return{uploaded_assets:uploads,rewritten_files:rewrittenFiles,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}async function runUploadLocal(args,report,cacheContext,deps){let warnings=[],uploads=[],tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-local-"));try{if(args.dryRun)return{uploaded_local_assets:report.local_asset_candidates.map(item=>({source_path:item.path,title:item.file_name,status:"dry-run"})),warnings};for(let asset of report.local_asset_candidates){let absolutePath=join12(report.project_dir,asset.path),cacheKey=buildLocalCacheKey(asset.hash),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached)){uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:cached.title??asset.file_name,final_url:cached.final_url,asset_id:cached.asset_id??null,status:"reused_from_cache"}),cacheContext.stats.local_reused+=1;continue}try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_local",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploading",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let uploaded=await deps.uploadAsset({filePath:absolutePath,title:asset.file_name,folderId:args.folderId||void 0});uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}catch(error){if(shouldRetryWithCompression(error)){let hostPlatform=deps.platform??process.platform,retry=resolveImageCompressionRetry(hostPlatform);if(retry.mode==="manual")warnings.push(`[${retry.code}] \u672C\u5730\u56FE\u7247\u8D85\u8FC7\u4E0A\u4F20\u9650\u5236\uFF08HTTP 413\uFF09\uFF0C${hostPlatform==="win32"?"Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u538B\u7F29":"\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u81EA\u52A8\u538B\u7F29"}: ${asset.path}\u3002\u8BF7\u5C06\u56FE\u7247\u5BBD\u5EA6\u538B\u7F29\u81F3\u4E0D\u8D85\u8FC7 ${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}px \u5E76\u51CF\u5C0F\u6587\u4EF6\u4F53\u79EF\uFF0C\u7136\u540E\u6267\u884C\uFF1Aplatform app import preprocess --dir "${report.project_dir}" --reset-cache`);else try{let outputPath=buildCompressedFilePath(tempRoot,absolutePath),compressedPath=await(deps.runCompressor??runSipsCompressor)({sourcePath:absolutePath,outputPath}),uploaded=await deps.uploadAsset({filePath:compressedPath,title:basename4(compressedPath),folderId:args.folderId||void 0});warnings.push(`\u672C\u5730\u56FE\u7247\u8FC7\u5927\uFF0C\u5DF2\u81EA\u52A8\u538B\u7F29\u540E\u4E0A\u4F20: ${asset.path}`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded_after_compress"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}));continue}catch(compressionError){warnings.push(`\u672C\u5730\u56FE\u7247\u538B\u7F29\u91CD\u8BD5\u5931\u8D25: ${asset.path} (${compressionError instanceof Error?compressionError.message:String(compressionError)})`)}}warnings.push(`\u672C\u5730\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${asset.path} (${error instanceof Error?error.message:String(error)})`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,status:"failed"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"failed",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,last_error:error instanceof Error?error.message:String(error)}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}}return{uploaded_local_assets:uploads,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function renderMarkdown(report){let lines=[];if(lines.push("# Scan Report",""),lines.push(`- Project: \`${report.project_dir}\``),lines.push(`- Mode: \`${report.mode}\``),lines.push(`- Scanned files: ${report.summary.scanned_file_count}`),lines.push(`- Unique remote candidates: ${report.summary.unique_remote_candidates}`),lines.push(`- Images: ${report.summary.image_count}`),lines.push(`- Videos: ${report.summary.video_count}`),lines.push(`- Posters: ${report.summary.poster_count}`),lines.push(`- Unknown remote: ${report.summary.unknown_remote_count}`),lines.push(`- Local images: ${report.summary.local_asset_count??0}`,""),report.remote_candidates.length===0&&(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0))return lines.push("No candidates found.",""),lines.join(`
|
|
2414
2414
|
`);if(report.remote_candidates.length>0){lines.push("## Remote Candidates","","| Kind | Rewrite | URL | Refs |","|---|---|---|---:|");for(let item of report.remote_candidates)lines.push(`| ${item.kind} | ${item.rewrite_supported?"yes":"no"} | ${escapeMdCell(item.url)} | ${item.occurrences.length} |`);lines.push("")}if(report.pending_videos.length>0){lines.push("## Pending Videos","");for(let item of report.pending_videos)lines.push(`- ${item.url}`);lines.push("")}if(Array.isArray(report.local_asset_candidates)&&report.local_asset_candidates.length>0){lines.push("## Local Images","","| File | Dedupe Refs | Size (bytes) | Upload |","|---|---:|---:|---|");for(let item of report.local_asset_candidates)lines.push(`| ${escapeMdCell(item.path)} | ${item.source_paths.length} | ${item.size_bytes} | ${item.upload_supported?"yes":"no"} |`);lines.push("")}if(report.remote_candidates.length>0){lines.push("## Occurrences","");for(let item of report.remote_candidates){lines.push(`### ${item.url}`,"",`- kind: \`${item.kind}\``,`- rewrite_supported: \`${item.rewrite_supported}\``),Array.isArray(item.notes)&&item.notes.length>0&&lines.push(`- notes: ${item.notes.join(" / ")}`);for(let occurrence of item.occurrences)lines.push(`- ${occurrence.file}:${occurrence.line} (${occurrence.kind})`);lines.push("")}}return lines.join(`
|
|
2415
2415
|
`)}function escapeMdCell(value){return value.replace(/\|/gu,"\\|")}function ensureDir(dirPath){mkdirSync9(dirPath,{recursive:!0})}function writeJson2(filePath,payload){writeFileSync10(filePath,`${JSON.stringify(payload,null,2)}
|
|
2416
2416
|
`,"utf8")}async function runPreprocess(args,sourceDir,deps){let preprocessRoot=join12(sourceDir,".design-preprocess"),cleanSourceDir=join12(preprocessRoot,"clean-source"),reportsDir=join12(preprocessRoot,"reports"),cacheDir=join12(preprocessRoot,"cache"),cacheFile=join12(cacheDir,"assets.json"),lockFile=join12(cacheDir,"locks.json");args.resetCache&&!args.dryRun&&rmSync4(cacheDir,{recursive:!0,force:!0}),rmSync4(cleanSourceDir,{recursive:!0,force:!0}),rmSync4(reportsDir,{recursive:!0,force:!0}),ensureDir(reportsDir),ensureDir(cacheDir),copyWorkspaceForPreprocess(sourceDir,cleanSourceDir);let cache=loadAssetCache(cacheFile,sourceDir),previousLock=loadLockState(lockFile),lockRun=args.dryRun?{lock:defaultLockState(),interruptedItems:0}:beginLockRun(lockFile,previousLock),lock=lockRun.lock,cacheContext={enabled:!args.dryRun&&args.resume!==!1,cacheDir,cacheFile,cache,lockFile,lock,warnings:[],stats:{resumed_from_cache:!1,remote_reused:0,local_reused:0,interrupted_items_count:lockRun.interruptedItems}};cacheContext.stats.interrupted_items_count>0&&(cacheContext.stats.resumed_from_cache=!0,cacheContext.warnings.push(`\u68C0\u6D4B\u5230\u4E0A\u6B21\u9884\u5904\u7406\u53EF\u80FD\u4E2D\u65AD\uFF1B\u5C06\u5C1D\u8BD5\u4ECE\u672C\u5730 cache \u6062\u590D\uFF08\u4E2D\u65AD\u9879: ${cacheContext.stats.interrupted_items_count}\uFF09\u3002`));let files=walkFiles(cleanSourceDir,args.include),assetFiles=walkAssetFiles(cleanSourceDir),candidates=collectRemoteCandidates(cleanSourceDir,files),localAssetCandidates=collectLocalAssetCandidates(cleanSourceDir,files,assetFiles),report=buildReport(cleanSourceDir,files,candidates,reportsDir);report.execution_mode=args.dryRun?"dry-run":"apply",report.local_asset_candidates=localAssetCandidates,report.summary.local_asset_count=localAssetCandidates.length;let detectedType=detectProjectType(sourceDir,args.type),upstreamSourcePackageBytes=collectSourcePackageBytes(sourceDir),cleanSourcePackageBytesBeforeRewrite=collectSourcePackageBytes(cleanSourceDir),pathBaseViolationsDetected=collectPathBaseViolations(cleanSourceDir,files),preflightWarnings=collectPreflightWarnings(cleanSourceDir,localAssetCandidates);cacheContext.enabled&&(lock=updateLockState(lockFile,lock,{phase:"rewrite_path_base"}),cacheContext.lock=lock);let pathBaseRewriteResult=await runPathBaseRewrite(args,report,files),pathBaseViolationsRemaining=collectPathBaseViolations(cleanSourceDir,files);writeJson2(join12(reportsDir,"preflight-report.json"),buildPreflightPayload(report,sourceDir,cleanSourceDir,{detectedType,upstreamSourcePackageBytes,cleanSourcePackageBytesBeforeRewrite,pathBaseViolationsDetected,pathBaseRewrites:pathBaseRewriteResult.rewrite_entries,pathBaseViolationsRemaining,preflightWarnings})),writeFileSync10(join12(reportsDir,"preflight-report.md"),`${renderMarkdown(report)}
|
|
@@ -2419,9 +2419,9 @@ ${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:erro
|
|
|
2419
2419
|
`,"utf8"),cacheContext.enabled&&(cacheContext.lock=completeLockRun(lockFile,cacheContext.lock)),{preprocess_root:preprocessRoot,clean_source_dir:cleanSourceDir,reports_dir:reportsDir,cache_dir:cacheDir,report,pathBaseRewriteResult,rewriteResult,localUploadResult,localRewriteResult,importManifest:importManifestWithCache,cacheContext}}async function runAppImportPreprocess(argv,deps={}){let args=parseArgs2(argv);if(args.help)throw new Error("\u5E2E\u52A9\u8BF7\u6C42\u5E94\u7531 runAppImportPreprocessCli \u5904\u7406\u3002");let rootDir=resolve10(args.dir||process.env.PLATFORM_INVOCATION_CWD||process.env.INIT_CWD||process.cwd()),stats=statSync5(rootDir,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${rootDir}`);let uploadAsset=deps.uploadAsset??(async()=>{throw new Error("app import preprocess \u7F3A\u5C11\u8FDB\u7A0B\u5185\u7D20\u6750\u4E0A\u4F20\u4F9D\u8D56\u3002")}),result=await runPreprocess(args,rootDir,{...deps,uploadAsset,platform:deps.platform??process.platform}),warnings=result.importManifest.warnings;return{tool:"assetize-project-urls",version:1,mode:"preprocess",execution_mode:args.dryRun?"dry-run":"apply",source_dir:rootDir,clean_source_dir:result.clean_source_dir,reports_dir:result.reports_dir,cache_dir:result.cache_dir,summary:result.report.summary,planned_actions:result.importManifest.planned_actions,path_base_rewritten_files:result.pathBaseRewriteResult.rewritten_files.length,uploaded_assets:countAppliedRemoteUploads(result.rewriteResult),uploaded_local_assets:countAppliedLocalUploads(result.localUploadResult),resumed_from_cache:result.importManifest.resumed_from_cache,reused_uploaded_assets:result.importManifest.reused_uploaded_assets_count,reused_uploaded_local_assets:result.importManifest.reused_uploaded_local_assets_count,interrupted_items_count:result.importManifest.interrupted_items_count,rewritten_files:args.dryRun?0:result.importManifest.rewritten_files.length,deleted_clean_source_assets:args.dryRun?0:result.importManifest.deleted_clean_source_assets.length,warnings,report_files:{preflight_report:join12(result.reports_dir,"preflight-report.json"),asset_inventory:join12(result.reports_dir,"asset-inventory.json"),import_manifest:join12(result.reports_dir,"import-manifest.json"),warnings:join12(result.reports_dir,"warnings.json"),pending_videos:join12(result.reports_dir,"pending-videos.json")}}}async function runAppImportPreprocessCli(argv,deps={}){let args=parseArgs2(argv);if(args.help){printAppImportPreprocessUsage();return}let output=await runAppImportPreprocess(argv,deps);if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
|
|
2420
2420
|
`);return}process.stdout.write(["third-party design preprocess completed",`mode: ${output.mode}`,`execution_mode: ${output.execution_mode}`,`source_dir: ${output.source_dir}`,`clean_source_dir: ${output.clean_source_dir}`,`cache_dir: ${output.cache_dir}`,`scanned_files: ${output.summary.scanned_file_count}`,`unique_remote_candidates: ${output.summary.unique_remote_candidates}`,`local_images: ${output.summary.local_asset_count}`,`planned_remote_upload_candidates: ${output.planned_actions.remote_upload_candidates}`,`planned_local_upload_candidates: ${output.planned_actions.local_upload_candidates}`,`planned_file_rewrite_candidates: ${output.planned_actions.file_rewrite_candidates}`,`planned_local_cleanup_candidates: ${output.planned_actions.local_cleanup_candidates}`,`path_base_rewritten_files: ${output.path_base_rewritten_files}`,`uploaded_assets: ${output.uploaded_assets}`,`uploaded_local_assets: ${output.uploaded_local_assets}`,`resumed_from_cache: ${output.resumed_from_cache}`,`reused_uploaded_assets: ${output.reused_uploaded_assets}`,`reused_uploaded_local_assets: ${output.reused_uploaded_local_assets}`,`interrupted_items_count: ${output.interrupted_items_count}`,`rewritten_files: ${output.rewritten_files}`,`deleted_clean_source_assets: ${output.deleted_clean_source_assets}`,`warnings: ${output.warnings.length}`,`preflight_report: ${output.report_files.preflight_report}`,`import_manifest: ${output.report_files.import_manifest}`].join(`
|
|
2421
2421
|
`)+`
|
|
2422
|
-
`)}import{cpSync as
|
|
2422
|
+
`)}import{cpSync as cpSync2,existsSync as existsSync17,mkdirSync as mkdirSync10,readFileSync as readFileSync17,readdirSync as readdirSync6,rmSync as rmSync5,statSync as statSync6,writeFileSync as writeFileSync11}from"node:fs";import{basename as basename5,dirname as dirname11,join as join13,resolve as resolve11}from"node:path";var WORKSPACE_REQUIRED_FILES=["app.yaml","package.json"],REPORT_FILE_NAMES=["import-manifest.json","preflight-report.json","asset-inventory.json","warnings.json","pending-videos.json"],TOP_LEVEL_IMPORT_CANDIDATES=["src","public","_videos","guidelines","index.html","README.md","ATTRIBUTIONS.md"],SKIP_DIRS=new Set([".git","node_modules","dist","build",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]);function printAppImportStageUsage(){process.stdout.write(["platform app import stage","","\u7528\u6CD5\uFF1A"," platform app import stage [--workspace-dir <template-workspace-dir>] --preprocess <source-dir|.design-preprocess|reports|import-manifest.json> [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06\u9884\u5904\u7406\u4EA7\u7269\u4EE5\u975E\u7834\u574F\u65B9\u5F0F stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A `.design-import/`\uFF0C\u4E0D\u76F4\u63A5\u8986\u76D6\u6A21\u677F\u5165\u53E3\u4E0E\u8FD0\u884C\u5951\u7EA6\u6587\u4EF6\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",""].join(`
|
|
2423
2423
|
`))}function parseArgs3(argv){let result={workspaceDir:"",preprocess:"",dryRun:!1,json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}if(arg==="--preprocess"){result.preprocess=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function ensureDir2(dirPath){mkdirSync10(dirPath,{recursive:!0})}function writeJson3(filePath,payload){writeFileSync11(filePath,`${JSON.stringify(payload,null,2)}
|
|
2424
|
-
`,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync17(filePath,"utf8"))}function assertDirectory2(pathValue,label){let stats=statSync6(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function resolveManifestPath(inputPath){let absolute=resolve11(inputPath),stats=statSync6(absolute,{throwIfNoEntry:!1});if(!stats)throw new Error(`\u672A\u627E\u5230\u9884\u5904\u7406\u8F93\u5165: ${absolute}`);if(stats.isFile()){if(basename5(absolute)!=="import-manifest.json")throw new Error(`\u9884\u5904\u7406\u8F93\u5165\u6587\u4EF6\u5FC5\u987B\u662F import-manifest.json: ${absolute}`);return absolute}let candidates=[join13(absolute,"reports","import-manifest.json"),join13(absolute,"import-manifest.json"),join13(absolute,".design-preprocess","reports","import-manifest.json")];for(let candidate of candidates)if(existsSync17(candidate))return candidate;throw new Error(`\u65E0\u6CD5\u4ECE\u9884\u5904\u7406\u8F93\u5165\u89E3\u6790 import-manifest.json: ${absolute}`)}function validateWorkspace2(workspaceDir){assertDirectory2(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=WORKSPACE_REQUIRED_FILES.filter(file=>!existsSync17(join13(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function topLevelEntries(rootDir){return readdirSync6(rootDir,{withFileTypes:!0}).filter(entry=>!SKIP_DIRS.has(entry.name)).map(entry=>({name:entry.name,kind:entry.isDirectory()?"dir":entry.isFile()?"file":"other"})).sort((left,right)=>left.name.localeCompare(right.name))}function collectImportCandidates(cleanSourceDir,layout,sourceDetectedType){return topLevelEntries(cleanSourceDir).filter(entry=>TOP_LEVEL_IMPORT_CANDIDATES.includes(entry.name)).map(entry=>({path:entry.name,kind:entry.kind,suggested_target:entry.name==="src"?sourceDetectedType==="frontend-app"?`workspace/${layout.imported_upstream_root}/ (\u6309 pages/components/styles/lib/imports \u53D7\u63A7\u5E76\u5165)`:`workspace/.design-import/upstream-clean-source/${entry.name}`:entry.name==="_videos"?"workspace/public/imported-upstream/_videos/ \u6216\u6A21\u677F\u9759\u6001\u8D44\u6E90\u76EE\u5F55":entry.name==="public"?"workspace/public/imported-upstream/ (\u9700\u4EBA\u5DE5\u5BA1\u67E5\u51B2\u7A81)":`workspace/.design-import/upstream-clean-source/${entry.name}`}))}function collectPreservedWorkspaceFiles(workspaceDir,layout){return layout.preserved_workspace_files.filter(file=>existsSync17(join13(workspaceDir,file)))}function buildImportSummary(args,payload){let sourcePreprocessExecutionMode=payload.importManifest.execution_mode??"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1Bstaged clean source \u4ECD\u53EF\u80FD\u5305\u542B\u672A\u771F\u5B9E\u56DE\u5199\u6216\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"import-clean-source",version:1,mode:"import-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,preprocess_manifest:payload.manifestPath,source_dir:payload.importManifest.source_dir,clean_source_dir:payload.importManifest.clean_source_dir,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,imported_upstream_root:payload.layout.imported_upstream_root,staged_clean_source_dir:payload.stagedCleanSourceDir,staged_reports_dir:payload.stagedReportsDir,source_detected_type:payload.preflightReport.detected_type??"unknown",clean_source_package_bytes:payload.importManifest.clean_source_package_bytes??null,upstream_source_package_bytes:payload.preflightReport.upstream_source_package_bytes??null,import_candidates:collectImportCandidates(payload.importManifest.clean_source_dir,payload.layout,payload.preflightReport.detected_type??"unknown"),preserved_workspace_files:collectPreservedWorkspaceFiles(payload.workspaceDir,payload.layout),pending_videos_count:Array.isArray(payload.importManifest.pending_videos)?payload.importManifest.pending_videos.length:0,pending_manual_items_count:Array.isArray(payload.warningsReport.pending_manual_items)?payload.warningsReport.pending_manual_items.length:0,warnings,next_steps:["\u5148\u5728 .design-import/upstream-clean-source \u4E2D\u5BA1\u67E5\u4E0A\u6E38 clean source",`\u518D\u6309 import_candidates \u9009\u62E9\u6027\u5408\u5E76\u5230\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 ${payload.layout.frontend_root}/public \u7B49\u76EE\u5F55`,"\u4FDD\u7559\u6A21\u677F\u4E3B\u5BFC\u6587\u4EF6\uFF08app.yaml / package.json / vite.config.ts / \u8FD0\u884C\u5165\u53E3 / platform \u5C42\uFF09\u4E0D\u88AB\u8986\u76D6","\u5B8C\u6210\u9875\u9762\u5408\u5E76\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}function stageReports(sourceReportsDir,stagedReportsDir,dryRun){let copied=[];for(let fileName of REPORT_FILE_NAMES){let sourcePath=join13(sourceReportsDir,fileName);existsSync17(sourcePath)&&(copied.push(fileName),dryRun||
|
|
2424
|
+
`,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync17(filePath,"utf8"))}function assertDirectory2(pathValue,label){let stats=statSync6(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function resolveManifestPath(inputPath){let absolute=resolve11(inputPath),stats=statSync6(absolute,{throwIfNoEntry:!1});if(!stats)throw new Error(`\u672A\u627E\u5230\u9884\u5904\u7406\u8F93\u5165: ${absolute}`);if(stats.isFile()){if(basename5(absolute)!=="import-manifest.json")throw new Error(`\u9884\u5904\u7406\u8F93\u5165\u6587\u4EF6\u5FC5\u987B\u662F import-manifest.json: ${absolute}`);return absolute}let candidates=[join13(absolute,"reports","import-manifest.json"),join13(absolute,"import-manifest.json"),join13(absolute,".design-preprocess","reports","import-manifest.json")];for(let candidate of candidates)if(existsSync17(candidate))return candidate;throw new Error(`\u65E0\u6CD5\u4ECE\u9884\u5904\u7406\u8F93\u5165\u89E3\u6790 import-manifest.json: ${absolute}`)}function validateWorkspace2(workspaceDir){assertDirectory2(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=WORKSPACE_REQUIRED_FILES.filter(file=>!existsSync17(join13(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function topLevelEntries(rootDir){return readdirSync6(rootDir,{withFileTypes:!0}).filter(entry=>!SKIP_DIRS.has(entry.name)).map(entry=>({name:entry.name,kind:entry.isDirectory()?"dir":entry.isFile()?"file":"other"})).sort((left,right)=>left.name.localeCompare(right.name))}function collectImportCandidates(cleanSourceDir,layout,sourceDetectedType){return topLevelEntries(cleanSourceDir).filter(entry=>TOP_LEVEL_IMPORT_CANDIDATES.includes(entry.name)).map(entry=>({path:entry.name,kind:entry.kind,suggested_target:entry.name==="src"?sourceDetectedType==="frontend-app"?`workspace/${layout.imported_upstream_root}/ (\u6309 pages/components/styles/lib/imports \u53D7\u63A7\u5E76\u5165)`:`workspace/.design-import/upstream-clean-source/${entry.name}`:entry.name==="_videos"?"workspace/public/imported-upstream/_videos/ \u6216\u6A21\u677F\u9759\u6001\u8D44\u6E90\u76EE\u5F55":entry.name==="public"?"workspace/public/imported-upstream/ (\u9700\u4EBA\u5DE5\u5BA1\u67E5\u51B2\u7A81)":`workspace/.design-import/upstream-clean-source/${entry.name}`}))}function collectPreservedWorkspaceFiles(workspaceDir,layout){return layout.preserved_workspace_files.filter(file=>existsSync17(join13(workspaceDir,file)))}function buildImportSummary(args,payload){let sourcePreprocessExecutionMode=payload.importManifest.execution_mode??"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1Bstaged clean source \u4ECD\u53EF\u80FD\u5305\u542B\u672A\u771F\u5B9E\u56DE\u5199\u6216\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"import-clean-source",version:1,mode:"import-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,preprocess_manifest:payload.manifestPath,source_dir:payload.importManifest.source_dir,clean_source_dir:payload.importManifest.clean_source_dir,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,imported_upstream_root:payload.layout.imported_upstream_root,staged_clean_source_dir:payload.stagedCleanSourceDir,staged_reports_dir:payload.stagedReportsDir,source_detected_type:payload.preflightReport.detected_type??"unknown",clean_source_package_bytes:payload.importManifest.clean_source_package_bytes??null,upstream_source_package_bytes:payload.preflightReport.upstream_source_package_bytes??null,import_candidates:collectImportCandidates(payload.importManifest.clean_source_dir,payload.layout,payload.preflightReport.detected_type??"unknown"),preserved_workspace_files:collectPreservedWorkspaceFiles(payload.workspaceDir,payload.layout),pending_videos_count:Array.isArray(payload.importManifest.pending_videos)?payload.importManifest.pending_videos.length:0,pending_manual_items_count:Array.isArray(payload.warningsReport.pending_manual_items)?payload.warningsReport.pending_manual_items.length:0,warnings,next_steps:["\u5148\u5728 .design-import/upstream-clean-source \u4E2D\u5BA1\u67E5\u4E0A\u6E38 clean source",`\u518D\u6309 import_candidates \u9009\u62E9\u6027\u5408\u5E76\u5230\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 ${payload.layout.frontend_root}/public \u7B49\u76EE\u5F55`,"\u4FDD\u7559\u6A21\u677F\u4E3B\u5BFC\u6587\u4EF6\uFF08app.yaml / package.json / vite.config.ts / \u8FD0\u884C\u5165\u53E3 / platform \u5C42\uFF09\u4E0D\u88AB\u8986\u76D6","\u5B8C\u6210\u9875\u9762\u5408\u5E76\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}function stageReports(sourceReportsDir,stagedReportsDir,dryRun){let copied=[];for(let fileName of REPORT_FILE_NAMES){let sourcePath=join13(sourceReportsDir,fileName);existsSync17(sourcePath)&&(copied.push(fileName),dryRun||cpSync2(sourcePath,join13(stagedReportsDir,fileName)))}return copied}async function runAppImportStageCli(argv){let args=parseArgs3(argv);if(args.help){printAppImportStageUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");if(!args.preprocess)throw new Error("\u7F3A\u5C11 `--preprocess <source-dir|.design-preprocess|reports|import-manifest.json>`\u3002");let workspaceDir=resolve11(args.workspaceDir);validateWorkspace2(workspaceDir);let manifestPath=resolveManifestPath(args.preprocess),reportsDir=resolve11(dirname11(manifestPath)),importManifest=readJson2(manifestPath),preflightReport=readJson2(join13(reportsDir,"preflight-report.json")),warningsReport=readJson2(join13(reportsDir,"warnings.json")),cleanSourceDir=resolve11(importManifest.clean_source_dir);assertDirectory2(cleanSourceDir,"clean-source");let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join13(workspaceDir,".design-import"),stagedCleanSourceDir=join13(designImportRoot,"upstream-clean-source"),stagedReportsDir=join13(designImportRoot,"reports");args.dryRun||(rmSync5(designImportRoot,{recursive:!0,force:!0}),ensureDir2(stagedReportsDir),cpSync2(cleanSourceDir,stagedCleanSourceDir,{recursive:!0}));let copiedReports=stageReports(reportsDir,stagedReportsDir,args.dryRun),summary=buildImportSummary(args,{workspaceDir,manifestPath,importManifest,preflightReport,warningsReport,layout,stagedCleanSourceDir,stagedReportsDir});args.dryRun||writeJson3(join13(designImportRoot,"import-summary.json"),summary);let output={...summary,copied_report_files:copiedReports};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
|
|
2425
2425
|
`);return}process.stdout.write(["third-party design import stage completed",`execution_mode: ${output.execution_mode}`,`workspace_dir: ${output.workspace_dir}`,`source_detected_type: ${output.source_detected_type}`,`staged_clean_source_dir: ${output.staged_clean_source_dir}`,`staged_reports_dir: ${output.staged_reports_dir}`,`import_candidates: ${output.import_candidates.length}`,`preserved_workspace_files: ${output.preserved_workspace_files.length}`,`pending_videos_count: ${output.pending_videos_count}`,`pending_manual_items_count: ${output.pending_manual_items_count}`].join(`
|
|
2426
2426
|
`)+`
|
|
2427
2427
|
`)}import{existsSync as existsSync18,readFileSync as readFileSync18,statSync as statSync7}from"node:fs";import{join as join14,resolve as resolve12}from"node:path";var REQUIRED_WORKSPACE_FILES2=["app.yaml","package.json"];function printAppImportVerifyUsage(){process.stdout.write(["platform app import verify","","\u7528\u6CD5\uFF1A"," platform app import verify [--workspace-dir <template-workspace-dir>] [--json]","","\u4F5C\u7528\uFF1A"," \u6821\u9A8C\u6A21\u677F\u5DE5\u4F5C\u533A\u662F\u5426\u5DF2\u5177\u5907 preprocess / stage / merge \u7684\u57FA\u7840\u4EA7\u7269\uFF0C\u5E76\u8F93\u51FA\u4E0B\u4E00\u6B65\u5EFA\u8BAE\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002"," - verify \u53EA\u505A\u72B6\u6001\u6821\u9A8C\uFF0C\u4E0D\u4F1A\u6267\u884C\u7D20\u6750\u4E0A\u4F20\u3001\u6587\u4EF6\u642C\u8FD0\u6216\u6A21\u677F\u63A5\u7EBF\u3002",""].join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voobase/cli",
|
|
3
|
-
"version": "0.1.1-nonprod.
|
|
3
|
+
"version": "0.1.1-nonprod.2037",
|
|
4
4
|
"private": false,
|
|
5
5
|
"platformDistributionProfile": {
|
|
6
6
|
"name": "nonprod",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"bundleDependencies": [],
|
|
54
54
|
"platformDistributionBuild": {
|
|
55
55
|
"channel": "nonprod",
|
|
56
|
-
"version": "0.1.1-nonprod.
|
|
57
|
-
"sequence":
|
|
58
|
-
"gitSha": "
|
|
59
|
-
"fullGitSha": "
|
|
60
|
-
"buildId": "0.1.1-nonprod.
|
|
56
|
+
"version": "0.1.1-nonprod.2037",
|
|
57
|
+
"sequence": 2037,
|
|
58
|
+
"gitSha": "5efe76a",
|
|
59
|
+
"fullGitSha": "5efe76afccc2a22d0c8d49705a424bb4c1d2fe46",
|
|
60
|
+
"buildId": "0.1.1-nonprod.2037+5efe76a"
|
|
61
61
|
}
|
|
62
62
|
}
|