@voobase/cli 0.1.1-nonprod.2038 → 0.1.1-nonprod.2050
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 +72 -61
- package/package.json +9 -6
- package/runtime-sdk/dist/auth/client.d.ts +14 -0
- package/runtime-sdk/dist/auth/client.js +28 -0
- package/runtime-sdk/dist/blob/client.d.ts +39 -0
- package/runtime-sdk/dist/blob/client.js +148 -0
- package/runtime-sdk/dist/blob/client.test.d.ts +1 -0
- package/runtime-sdk/dist/blob/client.test.js +494 -0
- package/runtime-sdk/dist/browser/app.d.ts +142 -0
- package/runtime-sdk/dist/browser/app.js +256 -0
- package/runtime-sdk/dist/browser/app.test.d.ts +1 -0
- package/runtime-sdk/dist/browser/app.test.js +81 -0
- package/runtime-sdk/dist/browser/errors.d.ts +39 -0
- package/runtime-sdk/dist/browser/errors.js +265 -0
- package/runtime-sdk/dist/browser/errors.test.d.ts +1 -0
- package/runtime-sdk/dist/browser/errors.test.js +41 -0
- package/runtime-sdk/dist/browser.d.ts +5 -0
- package/runtime-sdk/dist/browser.js +5 -0
- package/runtime-sdk/dist/client.d.ts +16 -0
- package/runtime-sdk/dist/client.js +22 -0
- package/runtime-sdk/dist/cms/client.d.ts +39 -0
- package/runtime-sdk/dist/cms/client.js +56 -0
- package/runtime-sdk/dist/cms/client.test.d.ts +1 -0
- package/runtime-sdk/dist/cms/client.test.js +56 -0
- package/runtime-sdk/dist/cms/media.d.ts +10 -0
- package/runtime-sdk/dist/cms/media.js +113 -0
- package/runtime-sdk/dist/cms/media.test.d.ts +1 -0
- package/runtime-sdk/dist/cms/media.test.js +76 -0
- package/runtime-sdk/dist/cms/taxonomy.d.ts +8 -0
- package/runtime-sdk/dist/cms/taxonomy.js +77 -0
- package/runtime-sdk/dist/cms/taxonomy.test.d.ts +1 -0
- package/runtime-sdk/dist/cms/taxonomy.test.js +65 -0
- package/runtime-sdk/dist/data-form/client.d.ts +19 -0
- package/runtime-sdk/dist/data-form/client.js +118 -0
- package/runtime-sdk/dist/data-form/client.test.d.ts +1 -0
- package/runtime-sdk/dist/data-form/client.test.js +210 -0
- package/runtime-sdk/dist/data-form/contracts.d.ts +10 -0
- package/runtime-sdk/dist/data-form/contracts.js +33 -0
- package/runtime-sdk/dist/data-form/index.d.ts +3 -0
- package/runtime-sdk/dist/data-form/index.js +2 -0
- package/runtime-sdk/dist/data-form/types.d.ts +110 -0
- package/runtime-sdk/dist/data-form/types.js +1 -0
- package/runtime-sdk/dist/http.d.ts +27 -0
- package/runtime-sdk/dist/http.js +126 -0
- package/runtime-sdk/dist/index.d.ts +19 -0
- package/runtime-sdk/dist/index.js +14 -0
- package/runtime-sdk/dist/notification/client.d.ts +16 -0
- package/runtime-sdk/dist/notification/client.js +39 -0
- package/runtime-sdk/dist/notification/index.d.ts +1 -0
- package/runtime-sdk/dist/notification/index.js +1 -0
- package/runtime-sdk/dist/react/context.d.ts +18 -0
- package/runtime-sdk/dist/react/context.js +28 -0
- package/runtime-sdk/dist/react/hooks.d.ts +90 -0
- package/runtime-sdk/dist/react/hooks.js +172 -0
- package/runtime-sdk/dist/react.d.ts +2 -0
- package/runtime-sdk/dist/react.js +2 -0
- package/runtime-sdk/dist/session/browser.d.ts +25 -0
- package/runtime-sdk/dist/session/browser.js +60 -0
- package/runtime-sdk/dist/types/auth.d.ts +38 -0
- package/runtime-sdk/dist/types/auth.js +1 -0
- package/runtime-sdk/dist/types/cms.d.ts +93 -0
- package/runtime-sdk/dist/types/cms.js +1 -0
- package/runtime-sdk/dist/types/notification.d.ts +37 -0
- package/runtime-sdk/dist/types/notification.js +1 -0
- package/runtime-sdk/dist/types/object-storage.d.ts +58 -0
- package/runtime-sdk/dist/types/object-storage.js +1 -0
- package/runtime-sdk/dist/types/workflow.d.ts +52 -0
- package/runtime-sdk/dist/types/workflow.js +1 -0
- package/runtime-sdk/dist/workflow/client.d.ts +30 -0
- package/runtime-sdk/dist/workflow/client.js +45 -0
- package/scaffold-assets-manifest.json +429 -0
- package/template-blocks/assets.ts +95 -0
- package/template-blocks/contract/capabilities.ts +33 -0
- package/template-blocks/contract/facade-contract.ts +59 -0
- package/template-blocks/contract/index.ts +4 -0
- package/template-blocks/contract/path-builders.ts +76 -0
- package/template-blocks/contract/route-path-patterns-source.ts +222 -0
- package/template-blocks/contract/route-path-patterns.ts +210 -0
- package/template-blocks/contract/runtime-config.ts +256 -0
- package/template-blocks/dev-support/index.ts +2 -0
- package/template-blocks/dev-support/node/auth-shell.ts +31 -0
- package/template-blocks/dev-support/node/index.ts +3 -0
- package/template-blocks/dev-support/node/proxy.ts +133 -0
- package/template-blocks/dev-support/node/runtime-config.ts +163 -0
- package/template-blocks/dev-support/vite/auth-shell.ts +23 -0
- package/template-blocks/dev-support/vite/index.ts +3 -0
- package/template-blocks/dev-support/vite/proxy.ts +451 -0
- package/template-blocks/dev-support/vite/runtime-config.ts +107 -0
- package/template-blocks/legacy/app-core.ts +153 -0
- package/template-blocks/legacy/index.ts +10 -0
- package/template-blocks/legacy/lifecycle.ts +38 -0
- package/template-blocks/legacy/metadata.ts +59 -0
- package/template-blocks/legacy/pages.ts +156 -0
- package/template-blocks/legacy/react-lock.ts +1599 -0
- package/template-blocks/legacy/react.ts +823 -0
- package/template-blocks/legacy/tailwind.ts +1138 -0
- package/template-blocks/legacy/wrappers/auth.ts +105 -0
- package/template-blocks/legacy/wrappers/proxy.ts +250 -0
- package/template-blocks/legacy/wrappers/runtime.ts +535 -0
- package/template-blocks/protocol/auth-routes.ts +82 -0
- package/template-blocks/protocol/cms-routes.ts +81 -0
- package/template-blocks/protocol/index.ts +4 -0
- package/template-blocks/protocol/public-app-routes.ts +48 -0
- package/template-blocks/protocol/route-map.ts +75 -0
- package/template-blocks/routing.ts +62 -0
- package/template-blocks/server/html-injection.ts +45 -0
- package/template-blocks/server/proxy-routing.ts +65 -0
- package/template-blocks/server/request-context.ts +103 -0
- package/template-blocks/server/route-strip.ts +47 -0
package/dist-bundle/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));var require_punycode=__commonJS({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js"(exports,module){"use strict";var regexPunycode=/^xn--/,regexNonASCII=/[^\0-\x7F]/,regexSeparators=/[\x2E\u3002\uFF0E\uFF61]/g,errors={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},baseMinusTMin=35,floor=Math.floor,stringFromCharCode=String.fromCharCode;function error(type){throw new RangeError(errors[type])}function map(array,callback){let result=[],length=array.length;for(;length--;)result[length]=callback(array[length]);return result}function mapDomain(domain,callback){let parts=domain.split("@"),result="";parts.length>1&&(result=parts[0]+"@",domain=parts[1]),domain=domain.replace(regexSeparators,".");let labels=domain.split("."),encoded=map(labels,callback).join(".");return result+encoded}function ucs2decode(string){let output=[],counter=0,length=string.length;for(;counter<length;){let value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){let extra=string.charCodeAt(counter++);(extra&64512)==56320?output.push(((value&1023)<<10)+(extra&1023)+65536):(output.push(value),counter--)}else output.push(value)}return output}var ucs2encode=codePoints=>String.fromCodePoint(...codePoints),basicToDigit=function(codePoint){return codePoint>=48&&codePoint<58?26+(codePoint-48):codePoint>=65&&codePoint<91?codePoint-65:codePoint>=97&&codePoint<123?codePoint-97:36},digitToBasic=function(digit,flag){return digit+22+75*(digit<26)-((flag!=0)<<5)},adapt=function(delta,numPoints,firstTime){let k=0;for(delta=firstTime?floor(delta/700):delta>>1,delta+=floor(delta/numPoints);delta>baseMinusTMin*26>>1;k+=36)delta=floor(delta/baseMinusTMin);return floor(k+(baseMinusTMin+1)*delta/(delta+38))},decode2=function(input){let output=[],inputLength=input.length,i=0,n=128,bias=72,basic=input.lastIndexOf("-");basic<0&&(basic=0);for(let j=0;j<basic;++j)input.charCodeAt(j)>=128&&error("not-basic"),output.push(input.charCodeAt(j));for(let index=basic>0?basic+1:0;index<inputLength;){let oldi=i;for(let w=1,k=36;;k+=36){index>=inputLength&&error("invalid-input");let digit=basicToDigit(input.charCodeAt(index++));digit>=36&&error("invalid-input"),digit>floor((2147483647-i)/w)&&error("overflow"),i+=digit*w;let t=k<=bias?1:k>=bias+26?26:k-bias;if(digit<t)break;let baseMinusT=36-t;w>floor(2147483647/baseMinusT)&&error("overflow"),w*=baseMinusT}let out=output.length+1;bias=adapt(i-oldi,out,oldi==0),floor(i/out)>2147483647-n&&error("overflow"),n+=floor(i/out),i%=out,output.splice(i++,0,n)}return String.fromCodePoint(...output)},encode2=function(input){let output=[];input=ucs2decode(input);let inputLength=input.length,n=128,delta=0,bias=72;for(let currentValue of input)currentValue<128&&output.push(stringFromCharCode(currentValue));let basicLength=output.length,handledCPCount=basicLength;for(basicLength&&output.push("-");handledCPCount<inputLength;){let m=2147483647;for(let currentValue of input)currentValue>=n&¤tValue<m&&(m=currentValue);let handledCPCountPlusOne=handledCPCount+1;m-n>floor((2147483647-delta)/handledCPCountPlusOne)&&error("overflow"),delta+=(m-n)*handledCPCountPlusOne,n=m;for(let currentValue of input)if(currentValue<n&&++delta>2147483647&&error("overflow"),currentValue===n){let q=delta;for(let k=36;;k+=36){let t=k<=bias?1:k>=bias+26?26:k-bias;if(q<t)break;let qMinusT=q-t,baseMinusT=36-t;output.push(stringFromCharCode(digitToBasic(t+qMinusT%baseMinusT,0))),q=floor(qMinusT/baseMinusT)}output.push(stringFromCharCode(digitToBasic(q,0))),bias=adapt(delta,handledCPCountPlusOne,handledCPCount===basicLength),delta=0,++handledCPCount}++delta,++n}return output.join("")},toUnicode=function(input){return mapDomain(input,function(string){return regexPunycode.test(string)?decode2(string.slice(4).toLowerCase()):string})},toASCII=function(input){return mapDomain(input,function(string){return regexNonASCII.test(string)?"xn--"+encode2(string):string})},punycode2={version:"2.3.1",ucs2:{decode:ucs2decode,encode:ucs2encode},decode:decode2,encode:encode2,toASCII,toUnicode};module.exports=punycode2}});import{spawn as spawn5}from"node:child_process";import{existsSync as existsSync24,readFileSync as readFileSync26}from"node:fs";import{resolve as resolve18}from"node:path";import process7 from"node:process";async function batchUpdateTenantCmsItems(args){let collection=args.payload.collection.trim(),itemIds=Array.from(new Set(args.payload.item_ids.map(itemId=>itemId.trim()).filter(Boolean))),tagAdds=dedupeTags(args.payload.changes.tags.add),discover=await args.sdk.discoverTenantCmsCollection(collection),schemaSpec=discover.active_schema??discover.draft_schema;if(!schemaSpec)throw new Error(`Collection \`${collection}\` \u5F53\u524D\u6CA1\u6709\u53EF\u7528 schema\u3002`);let succeeded=[],failed=[];for(let itemId of itemIds){let title=itemId;try{let item=await args.sdk.getTenantCmsItem({collection,id:itemId});title=resolveCmsItemTitle(item);let currentStatus=item.system.publish_status??"draft",targetStatus=args.payload.changes.publish_status.mode==="set"?args.payload.changes.publish_status.value:void 0,hasCategoryChange=args.payload.changes.category.mode!=="keep",hasTagChange=tagAdds.length>0,hasMetadataChange=hasCategoryChange||hasTagChange,effectiveStatus=currentStatus;if(hasMetadataChange){currentStatus==="archived"&&targetStatus&&targetStatus!=="archived"&&(await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus}),effectiveStatus=targetStatus);let payload=buildCmsItemWritePayloadFromDelivery({item,schemaSpec,publishStatus:targetStatus&&targetStatus!=="archived"?targetStatus:effectiveStatus,categoryChange:args.payload.changes.category,tagsToAdd:tagAdds});await args.sdk.configureTenantCmsItem({...payload,item_id:itemId}),targetStatus==="archived"&&effectiveStatus!=="archived"?await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:"archived"}):targetStatus&&targetStatus!=="archived"&&(effectiveStatus=targetStatus)}else targetStatus&&targetStatus!==effectiveStatus&&await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus});succeeded.push({item_id:itemId,title})}catch(error){failed.push({item_id:itemId,title,message:error instanceof Error?error.message:"\u6279\u91CF\u66F4\u65B0\u5931\u8D25"})}}return{total:itemIds.length,succeeded,failed}}function buildCmsItemWritePayloadFromDelivery(args){let nextTags=dedupeTags([...args.item.system.tags??[],...args.tagsToAdd]);return{collection:args.item.collection,system:{publish_status:args.publishStatus,...args.item.system.slug?{slug:args.item.system.slug}:{},featured:args.item.system.featured??!1,tags:nextTags,category_id:resolveNextCategoryId(args.item,args.categoryChange),...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:normalizeCmsContentForWrite(args.item.content,args.schemaSpec.fields)}}function resolveNextCategoryId(item,categoryChange){return categoryChange.mode==="clear"?null:categoryChange.mode==="set"?categoryChange.category_id?.trim()||null:item.system.category_id??null}function resolveCmsItemTitle(item){let title=item.content.title,name=item.content.name;return typeof title=="string"&&title.trim()?title.trim():typeof name=="string"&&name.trim()?name.trim():item.system.slug??item.system.id??"Untitled item"}function dedupeTags(values){let seen=new Set,next=[];for(let value of values){let normalized=value.trim();if(!normalized)continue;let lowered=normalized.toLowerCase();seen.has(lowered)||(seen.add(lowered),next.push(normalized))}return next}function normalizeCmsContentForWrite(content,fields){let normalized={};for(let field of fields)normalized[field.name]=normalizeFieldValueForPayload(field,content[field.name]);return normalized}function normalizeFieldValueForPayload(field,value){switch(field.type){case"date":if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}return value??null;case"number":if(typeof value=="string"){let parsed=Number.parseFloat(value.trim());return Number.isFinite(parsed)?field.ui?.number_kind==="integer"?Math.trunc(parsed):parsed:0}return value;case"bool":return!!value;case"multi_select":return normalizeStringArrayValue(value);case"image":case"file":return normalizeAssetValue(value);case"images":case"files":return normalizeAssetArrayValue(value);case"relation":return normalizeRelationId(value);case"relations":return normalizeRelationArrayValue(value);default:return typeof value=="string"?value:value??""}}function normalizeRelationId(value){if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}if(value&&typeof value=="object"&&!Array.isArray(value)&&"id"in value){let id=value.id;return typeof id=="string"&&id.trim().length>0?id.trim():null}return null}function normalizeAssetValue(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:null}function normalizeStringArrayValue(value){return Array.isArray(value)?value.map(item=>String(item)):typeof value=="string"?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function normalizeAssetArrayValue(value){return Array.isArray(value)?value.filter(item=>!!item&&typeof item=="object"&&!Array.isArray(item)):[]}function normalizeRelationArrayValue(value){return Array.isArray(value)?value.map(item=>normalizeRelationId(item)).filter(item=>!!item):[]}import{createHash}from"node:crypto";import{URL as URL2}from"node:url";var IMAGE_URL_ATTRS=["src","data-src","data-original","data-original-src","data-lazy-src"],IMAGE_SRCSET_ATTRS=["srcset","data-srcset"];function trimToUndefined(value){let normalized=value?.trim();return normalized||void 0}function normalizeUrl(value,baseUrl){let trimmed=trimToUndefined(value);if(trimmed)try{return baseUrl?new URL2(trimmed,baseUrl).toString():new URL2(trimmed).toString()}catch{return}}function isPlatformHostedAssetUrl(value){try{let parsed=new URL2(value);return/^\/assets\/[^/]+\/(original|variants\/[^/]+)$/.test(parsed.pathname)||parsed.pathname.startsWith("/api/tenant/assets/")}catch{return!1}}function inferMimeTypeFromUrl(value){if(!value)return;let pathname=(()=>{try{return new URL2(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg";if(pathname.endsWith(".avif"))return"image/avif"}function computeChecksum(content){return`sha256:${createHash("sha256").update(content).digest("hex")}`}function inferRemoteImageFileName(url,mimeType){let lastSegment=(()=>{try{return new URL2(url).pathname}catch{return url}})().split("/").filter(Boolean).at(-1);return lastSegment&&/\.[a-z0-9]{2,6}$/i.test(lastSegment)?decodeURIComponent(lastSegment):`remote-image.${(()=>{switch(mimeType){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":default:return"jpg"}})()}`}function buildTenantAssetReference(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function replaceImageAttributeUrls(html,replacementsByUrl,attribute2){let pattern=new RegExp(`(<img\\b[^>]*?\\s${attribute2}\\s*=\\s*)(["'])(.*?)\\2`,"gi");return html.replace(pattern,(fullMatch,prefix,quote,rawUrl)=>{let replacement=replacementsByUrl.get(rawUrl);return!replacement||replacement.finalUrl===rawUrl?fullMatch:`${prefix}${quote}${replacement.finalUrl}${quote}`})}function stripImageAttributes(html,attributes){let nextHtml=html;for(let attribute2 of attributes){let pattern=new RegExp(`\\s${attribute2}\\s*=\\s*(["']).*?\\1`,"gi");nextHtml=nextHtml.replace(pattern,"")}return nextHtml}async function fetchRemoteImageBinary(args){let response=await(args.fetchImpl??fetch)(args.url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u56FE\u7247\u62C9\u53D6\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let normalizedMimeType=String(response.headers.get("content-type")??"").split(";")[0]?.trim().toLowerCase()||inferMimeTypeFromUrl(args.url);if(!normalizedMimeType||!normalizedMimeType.startsWith("image/"))throw new Error("\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u53D7\u652F\u6301\u7684\u56FE\u7247\u7C7B\u578B");let content=new Uint8Array(await response.arrayBuffer()),maxBytes=args.maxBytes??20*1024*1024;if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");if(content.byteLength>maxBytes)throw new Error(`\u8FDC\u7A0B\u56FE\u7247\u8D85\u8FC7\u5927\u5C0F\u9650\u5236\uFF08${content.byteLength} bytes\uFF09`);return{content,mimeType:normalizedMimeType}}async function ingestRemoteImageCandidates(args){let uniqueCandidates=new Map;for(let candidate of args.candidates)uniqueCandidates.has(candidate.url)||uniqueCandidates.set(candidate.url,candidate);let resultsByUrl=new Map,resultsByChecksum=new Map,warnings=[];for(let candidate of uniqueCandidates.values())try{let{content,mimeType}=await fetchRemoteImageBinary({url:candidate.url,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),checksum3=computeChecksum(content),existingByChecksum=resultsByChecksum.get(checksum3);if(existingByChecksum){let reused={...existingByChecksum,originalUrl:candidate.url,status:"reused"};resultsByUrl.set(candidate.url,reused);continue}let fileName=inferRemoteImageFileName(candidate.url,mimeType),uploadedAsset=await args.sdk.createTenantAssetBinary({fileName,mimeType,content,title:candidate.title,...args.folderId?{folderId:args.folderId}:{}}),uploaded={originalUrl:candidate.url,finalUrl:uploadedAsset.original_url,asset:uploadedAsset,assetReference:buildTenantAssetReference(uploadedAsset),mimeType,checksum:checksum3,status:"uploaded"};resultsByUrl.set(candidate.url,uploaded),resultsByChecksum.set(checksum3,uploaded)}catch(error){let message=error instanceof Error?error.message:"\u5916\u94FE\u56FE\u7247\u8D44\u4EA7\u5316\u5931\u8D25";warnings.push(`\u56FE\u7247 \`${candidate.url}\` \u8D44\u4EA7\u5316\u5931\u8D25\uFF0C\u5DF2\u56DE\u9000\u539F\u94FE\u63A5\uFF1A${message}`),resultsByUrl.set(candidate.url,{originalUrl:candidate.url,finalUrl:candidate.url,mimeType:inferMimeTypeFromUrl(candidate.url),status:"fallback",warning:message})}return{resultsByUrl,warnings}}function collectExternalImageCandidatesFromHtml(args){let candidates=new Map;return args.html.replace(/<img\b[^>]*>/gi,tag=>{for(let attribute2 of IMAGE_URL_ATTRS){let rawUrl=tag.match(new RegExp(`(?:^|\\s)${attribute2}\\s*=\\s*(["'])(.*?)\\1`,"i"))?.[2],normalizedUrl=normalizeUrl(rawUrl,args.baseUrl);!normalizedUrl||normalizedUrl.startsWith("data:")||isPlatformHostedAssetUrl(normalizedUrl)||candidates.has(normalizedUrl)||candidates.set(normalizedUrl,{url:normalizedUrl,title:args.title,source:"body"})}return""}),[...candidates.values()]}async function assetizeExternalImagesInHtml(args){let bodyCandidates=collectExternalImageCandidatesFromHtml({html:args.html,baseUrl:args.baseUrl,title:args.bodyTitle}),normalizedCoverUrl=normalizeUrl(args.coverUrl,args.baseUrl),coverCandidate=normalizedCoverUrl&&!normalizedCoverUrl.startsWith("data:")&&!isPlatformHostedAssetUrl(normalizedCoverUrl)?{url:normalizedCoverUrl,title:args.coverTitle??args.bodyTitle,source:"cover"}:null,candidates=coverCandidate?[coverCandidate,...bodyCandidates]:bodyCandidates,{resultsByUrl,warnings}=await ingestRemoteImageCandidates({sdk:args.sdk,candidates,folderId:args.folderId,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),html=args.html;for(let attribute2 of IMAGE_URL_ATTRS)html=replaceImageAttributeUrls(html,resultsByUrl,attribute2);html=stripImageAttributes(html,IMAGE_SRCSET_ATTRS);let replacements=[...resultsByUrl.values()].map(result=>({originalUrl:result.originalUrl,finalUrl:result.finalUrl,...result.asset?.asset.asset_id?{assetId:result.asset.asset.asset_id}:{},status:result.status}));if(!normalizedCoverUrl)return{html,cover:{mode:"none"},replacements,warnings};let coverResult=resultsByUrl.get(normalizedCoverUrl);return coverResult?.assetReference?{html,cover:{mode:"asset",value:coverResult.assetReference},replacements,warnings}:{html,cover:{mode:"remote",value:{title:args.coverTitle??args.bodyTitle??"Remote cover",...coverResult?.mimeType||args.coverMimeType?{mime_type:coverResult?.mimeType??args.coverMimeType}:{},original_url:normalizedCoverUrl}},replacements,warnings}}var PlatformApiError=class extends Error{status;code;detail;requestId;capability;category;remediation;constructor(message,status,code2,detail,requestId,capability,category,remediation){super(message),this.status=status,this.code=code2,this.detail=detail,this.requestId=requestId,this.capability=capability,this.category=category,this.remediation=remediation,this.name="PlatformApiError"}},BasePlatformSdk=class{options;fetchImpl;constructor(options){this.options=options,this.fetchImpl=options.fetchImpl??fetch}async request(path2,init={}){return this.requestUrl(new URL(path2,this.options.baseUrl),init)}async requestBinary(path2,init={}){return this.requestBinaryUrl(new URL(path2,this.options.baseUrl),init)}async requestVoid(path2,init={}){return this.requestVoidUrl(new URL(path2,this.options.baseUrl),init)}async requestUrl(url,init={}){let response=await this.fetchResponse(url,init),payload=await parseJsonResponse(response);if(!response.ok){let errorPayload=payload,error=errorPayload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??errorPayload.detail,errorPayload.request_id,error?.capability,error?.category,error?.remediation)}return payload}async requestBinaryUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}return new Uint8Array(await response.arrayBuffer())}async requestVoidUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}}async fetchResponse(url,init={}){let headers=new Headers(init.headers);!headers.has("Content-Type")&&init.body&&headers.set("Content-Type","application/json");let extraHeaders=await this.options.getHeaders?.();return extraHeaders&&new Headers(extraHeaders).forEach((value,key)=>{headers.set(key,value)}),this.fetchImpl(url,{...init,headers})}};async function parseJsonResponse(response){let text2=await response.text();if(text2.trim().length===0)return{};try{return JSON.parse(text2)}catch{if(response.ok)return{};throw new PlatformApiError(`Request failed with non-JSON response: ${response.status}`,response.status,"non_json_response",{content_type:response.headers.get("content-type")??void 0,body_preview:text2.replace(/\s+/g," ").slice(0,240)})}}var PlatformSdk=class extends BasePlatformSdk{notification;constructor(options){super(options),this.notification=new NotificationSdkNamespace(this)}async listNotificationInbox(filters={}){let url=new URL("/api/tenant/notification/inbox",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"inbox_type",filters.inbox_type),setOptionalSearchParam(url,"status",filters.status),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async updateNotificationInboxItemStatus(itemId,payload){return(await this.request(`/api/tenant/notification/inbox/${encodeURIComponent(itemId)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async batchUpdateNotificationInboxItemsStatus(payload){return this.request("/api/tenant/notification/inbox:batch",{method:"PATCH",body:JSON.stringify(payload)})}async listNotificationDeliveries(filters={}){let url=new URL("/api/tenant/notification/deliveries",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async announcePlatformNotification(payload){return(await this.request("/api/admin/notification/announcements/platform",{method:"POST",body:JSON.stringify(payload)})).item}async announceAppNotification(appId,payload){return(await this.request(`/api/tenant/notification/apps/${encodeURIComponent(appId)}/announcements`,{method:"POST",body:JSON.stringify(payload)})).item}async getAppNotificationConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/config`)}async listAppNotificationAnnouncements(appId,options={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,this.options.baseUrl);return typeof options.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async createAppNotificationAnnouncement(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,{method:"POST",body:JSON.stringify(payload)})}async archiveAppNotificationAnnouncement(appId,announcementId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements/${encodeURIComponent(announcementId)}:archive`,{method:"POST"})}async publishEndUserNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/publish`,{method:"POST",body:JSON.stringify(payload)})}async createEndUserNotificationReminder(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/reminders`,{method:"POST",body:JSON.stringify(payload)})}async projectEndUserTaskNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/task-projections`,{method:"POST",body:JSON.stringify(payload)})}async listEndUserNotificationInbox(appId,query){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/inbox`,this.options.baseUrl);return url.searchParams.set("end_user_id",query.end_user_id),setOptionalSearchParam(url,"status",query.status),setOptionalSearchParam(url,"inbox_type",query.inbox_type),typeof query.limit=="number"&&Number.isFinite(query.limit)&&url.searchParams.set("limit",String(query.limit)),this.request(`${url.pathname}${url.search}`)}async getEndUserNotificationUnreadCount(appId,endUserId){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/unread-count`,this.options.baseUrl);return url.searchParams.set("end_user_id",endUserId),this.request(`${url.pathname}${url.search}`)}async createWorkflowDefinition(payload){return(await this.request("/api/workflow/definitions",{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowTemplates(){return(await this.request("/api/workflow/templates")).items}async listWorkflowDefinitions(filters={}){let url=new URL("/api/workflow/definitions",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async listWorkflowBindings(filters={}){let url=new URL("/api/workflow/bindings",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"definition_key",filters.definition_key),(await this.request(`${url.pathname}${url.search}`)).items}async updateWorkflowDefinitionMetadata(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async saveWorkflowRoleBindings(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/role-bindings`,{method:"POST",body:JSON.stringify(payload)})).items}async getWorkflowBindingOverride(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/binding-override`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).item}async saveWorkflowBindingOverride(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/binding-override`,{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowRoleBindings(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/role-bindings`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).items}async startWorkflow(payload){return(await this.request("/api/workflow/instances/start",{method:"POST",body:JSON.stringify(payload)})).item}async performWorkflowAction(instanceId,payload){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}/actions`,{method:"POST",body:JSON.stringify(payload)})).item}async getWorkflowInstance(instanceId){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}`)).item}async listWorkflowTasks(filters={}){let url=new URL("/api/workflow/tasks",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async getWhoAmI(){return this.request("/api/auth/whoami")}async getResolvedPermissions(){return this.request("/api/auth/permissions")}async switchTenantContext(payload){return this.request("/api/auth/context/switch-tenant",{method:"POST",body:JSON.stringify(payload)})}async listTenantWorkspaces(){return this.request("/api/auth/workspaces")}async ensurePersonalWorkspace(){return this.request("/api/auth/workspaces/ensure-personal",{method:"POST"})}async getAdminOverview(){return this.request("/api/admin/overview")}async listAdminWorkbenchEntries(){return this.request("/api/admin/workbench-entries")}async getAdminWorkbenchEntryDetail(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}`)}async updateAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"PUT",body:JSON.stringify(payload)})}async resetAdminWorkbenchEntryVisibility(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"DELETE"})}async previewAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility:preview`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAsset(payload){return this.request("/api/tenant/assets",{method:"POST",body:JSON.stringify(payload)})}async createTenantAssetBinary(args){let headers=new Headers({"Content-Type":args.mimeType,"X-Asset-File-Name":encodeURIComponent(args.fileName)});return args.title?.trim()&&headers.set("X-Asset-Title",encodeURIComponent(args.title.trim())),args.folderId?.trim()&&headers.set("X-Asset-Folder-Id",encodeURIComponent(args.folderId.trim())),this.request("/api/tenant/assets/upload",{method:"POST",headers,body:Buffer.from(args.content)})}async listTenantAssets(filters={}){let url=new URL("/api/tenant/assets",this.options.baseUrl);return setOptionalSearchParam(url,"q",filters.q),setOptionalSearchParam(url,"media_type",filters.media_type),setOptionalSearchParam(url,"mime_type",filters.mime_type),setOptionalSearchParam(url,"folder_id",filters.folder_id),setOptionalSearchParam(url,"tag_ids",filters.tag_ids?.join(",")),setOptionalSearchParam(url,"scene",filters.scene),setOptionalSearchParam(url,"objects",filters.objects?.join(",")),setOptionalSearchParam(url,"safety_flags",filters.safety_flags?.join(",")),setOptionalSearchParam(url,"orientation",filters.orientation),setOptionalBooleanSearchParam(url,"has_ocr",filters.has_ocr),setOptionalBooleanSearchParam(url,"has_person",filters.has_person),setOptionalBooleanSearchParam(url,"is_svg",filters.is_svg),typeof filters.page=="number"&&Number.isFinite(filters.page)&&url.searchParams.set("page",String(filters.page)),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`)}async deleteTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`,{method:"DELETE"})}async batchUpdateTenantAssets(payload){return this.request("/api/tenant/assets/batch",{method:"POST",body:JSON.stringify(payload)})}async listTenantAssetFolders(){return this.request("/api/tenant/assets/folders")}async createTenantAssetFolder(payload){return this.request("/api/tenant/assets/folders",{method:"POST",body:JSON.stringify(payload)})}async updateTenantAssetFolderMetadata(folderId,payload){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAssetFolder(folderId){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"DELETE"})}async moveTenantAssetFolder(folderId,direction){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}/move-${direction}`,{method:"POST"})}async updateTenantAssetFolder(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/folder`,{method:"PATCH",body:JSON.stringify(payload)})}async updateTenantAssetMetadata(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/metadata`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAssetTags(options){let url=new URL("/api/tenant/assets/tags",this.options.baseUrl);return options?.assetId&&url.searchParams.set("asset_id",options.assetId),this.request(`${url.pathname}${url.search}`)}async addTenantAssetTag(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,{method:"POST",body:JSON.stringify(payload)})}async removeTenantAssetTag(assetId,label){let url=new URL(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,this.options.baseUrl);return url.searchParams.set("label",label),this.request(`${url.pathname}${url.search}`,{method:"DELETE"})}async downloadTenantAssetOriginal(assetId){return this.requestBinary(`/api/tenant/assets/${encodeURIComponent(assetId)}/original`)}async downloadTenantAssetVariant(assetId,variantKind){return this.requestBinary(`/assets/${encodeURIComponent(assetId)}/variants/${encodeURIComponent(variantKind)}`)}async createTenantBlobUploadSession(payload){return this.request("/api/tenant/blobs/upload-sessions",{method:"POST",body:JSON.stringify(payload)})}async uploadTenantBlobBinary(uploadSessionId,payload){let url=resolveRelativeOrAbsoluteUrl(payload.upload_url??`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/content`,this.options.baseUrl),headers=new Headers(payload.headers);headers.set("Content-Type",payload.content_type?.trim()||"application/octet-stream"),await this.requestVoidUrl(url,{method:"PUT",headers,body:Buffer.from(payload.content)})}async completeTenantBlobUpload(uploadSessionId,payload={}){return this.request(`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/complete`,{method:"POST",body:JSON.stringify(payload)})}async createTenantBlobBinary(args){let contentType=args.contentType?.trim()||"application/octet-stream",session=await this.createTenantBlobUploadSession({original_filename:args.fileName,content_type:contentType,size_bytes:args.content.byteLength,...args.appId?.trim()?{app_id:args.appId.trim()}:{},...args.clientRequestId?.trim()?{client_request_id:args.clientRequestId.trim()}:{}});return await this.uploadTenantBlobBinary(session.upload_session_id,{content:args.content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}),this.completeTenantBlobUpload(session.upload_session_id,{size_bytes:args.content.byteLength,...args.sha256?.trim()?{sha256:args.sha256.trim()}:{}})}async listTenantBlobs(filters={}){let url=new URL("/api/tenant/blobs",this.options.baseUrl);return setOptionalSearchParam(url,"cursor",filters.cursor),setOptionalSearchParam(url,"app_id",filters.app_id??void 0),setOptionalSearchParam(url,"q",filters.q??void 0),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantBlob(blobId){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}`)}async issueTenantBlobDownloadUrl(blobId,payload={}){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}/download-url`,{method:"POST",body:JSON.stringify(payload)})}async getTenantOverview(){return this.request("/api/tenant/overview")}async getTenantEffectiveState(){return this.request("/api/tenant/effective-state")}async getTenantWorkbenchNavigation(){return this.request("/api/tenant/workbench/navigation")}async createTenantApp(payload){return this.request("/api/tenant/apps",{method:"POST",body:JSON.stringify(payload)})}async updateTenantApp(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listAppTemplates(){return this.request("/api/tenant/app-templates")}async createAppTemplate(payload){return this.request("/api/tenant/app-templates",{method:"POST",body:JSON.stringify(payload)})}async getAppTemplate(templateId){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`)}async openAppTemplatePreview(templateId){return this.requestVoid(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/preview`)}async updateAppTemplateSettings(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteAppTemplate(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"DELETE",body:JSON.stringify(payload)})}async createAppTemplateInitializationTask(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/initialization-tasks`,{method:"POST",body:JSON.stringify(payload)})}async getAppTemplateInitializationTask(taskId){return this.request(`/api/tenant/app-template-initialization-tasks/${encodeURIComponent(taskId)}`)}async createAppMarketSubmission(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/market-submissions`,{method:"POST",body:JSON.stringify(payload)})}async cancelAppMarketSubmission(submissionId){return this.request(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/cancel`,{method:"POST"})}async listTenantAppMarketSubmissions(options){let url=new URL("/api/tenant/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async listAppMarketListings(options){let url=new URL("/api/tenant/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async listAdminAppMarketListings(options){let url=new URL("/api/admin/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async getAppMarketListing(listingId){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}`)}async openAppMarketSubmissionPreview(submissionId){return this.requestVoid(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/preview`)}async createAppMarketInstall(listingId,payload){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}/installs`,{method:"POST",body:JSON.stringify(payload)})}async listAdminAppMarketSubmissions(options){let url=new URL("/api/admin/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async approveAppMarketSubmission(submissionId){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/approve`,{method:"POST"})}async rejectAppMarketSubmission(submissionId,payload={}){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/reject`,{method:"POST",body:JSON.stringify(payload)})}async unlistAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/unlist`,{method:"POST",body:JSON.stringify(payload)})}async publishAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/publish`,{method:"POST",body:JSON.stringify(payload)})}async listAdminLightAppLibraries(options){let url=new URL("/api/admin/light-app-library/libraries",this.options.baseUrl);return options?.visibility&&url.searchParams.set("visibility",options.visibility),this.request(`${url.pathname}${url.search}`)}async setAdminLightAppLibraryVisibility(libraryId,payload){return this.request(`/api/admin/light-app-library/libraries/${encodeURIComponent(libraryId)}/visibility`,{method:"POST",body:JSON.stringify(payload)})}async listLightAppLibraryEntries(options){let url=new URL("/api/tenant/light-app-library/entries",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.status&&url.searchParams.set("status",options.status),options?.template_key&&url.searchParams.set("template_key",options.template_key),options?.tag&&url.searchParams.set("tag",options.tag),options?.visibility&&url.searchParams.set("visibility",options.visibility),typeof options?.include_public=="boolean"&&url.searchParams.set("include_public",String(options.include_public)),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntries(query){let url=new URL("/api/tenant/light-app-library/entries/search",this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async getLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`)}async createLightAppLibraryEntry(payload){return this.request("/api/tenant/light-app-library/entries",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppLibraryEntry(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async submitLightAppLibraryEntrySnapshot(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/snapshots`,{method:"POST",body:JSON.stringify(payload)})}async publishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/publish`,{method:"POST"})}async unpublishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/unpublish`,{method:"POST"})}async archiveLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/archive`,{method:"POST"})}async deleteLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async getLightAppLibraryEntrySource(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source`)}async readLightAppLibraryEntrySourceFile(entryId,path2){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/files`,this.options.baseUrl);return url.searchParams.set("path",path2),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntrySource(entryId,query){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/search`,this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async listLightAppPrototypeEntries(options){let url=new URL("/api/tenant/prototypes",this.options.baseUrl);return options?.q&&url.searchParams.set("q",options.q),options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async getLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`)}async createLightAppPrototypeEntry(payload){return this.request("/api/tenant/prototypes",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppPrototypeEntry(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async copyLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/copy`,{method:"POST"})}async deleteLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async saveLightAppPrototypeCurrentVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/current-version`,{method:"PUT",body:JSON.stringify(payload)})}async submitLightAppPrototypeVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions`,{method:"POST",body:JSON.stringify(payload)})}async getLightAppPrototypeVersion(entryId,versionId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions/${encodeURIComponent(versionId)}`)}async deleteTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"DELETE"})}async getTenantAppDeletePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/delete-preview`,{method:"POST"})}async getTenantAppDeleteJob(jobId){return this.request(`/api/tenant/app-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppUndeployPreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy-preview`,{method:"POST"})}async undeployTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy`,{method:"POST"})}async getTenantAppUndeployJob(jobId){return this.request(`/api/tenant/app-undeploy-jobs/${encodeURIComponent(jobId)}`)}async createBuild(payload){return this.request("/api/builds",{method:"POST",body:JSON.stringify(payload)})}async listBuilds(appId,options){let url=new URL("/api/builds",this.options.baseUrl);return url.searchParams.set("app_id",appId),typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getBuildPrecheck(appId,args){let url=new URL("/api/builds/precheck",this.options.baseUrl);return url.searchParams.set("app_id",appId),url.searchParams.set("source_version_id",args.source_version_id),args.build_config?.dockerfile_path&&url.searchParams.set("dockerfile_path",args.build_config.dockerfile_path),args.build_config?.context_subdir&&url.searchParams.set("context_subdir",args.build_config.context_subdir),args.build_config?.target&&url.searchParams.set("target",args.build_config.target),this.request(`${url.pathname}${url.search}`)}async getBuild(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}`)}async listBuildEvents(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}/events`)}async createLocalBuildSession(payload){return this.request("/api/builds/local-sessions",{method:"POST",body:JSON.stringify(payload)})}async completeLocalBuildSession(buildId,payload){return this.request(`/api/builds/${encodeURIComponent(buildId)}/local-complete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceWorkspace(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/source-workspace`,this.options.baseUrl);return options?.sourceVersionId&&url.searchParams.set("source_version_id",options.sourceVersionId),this.request(`${url.pathname}${url.search}`)}async getTenantAppDevWorkspace(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace`)}async pushTenantAppDevWorkspace(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/push`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)})}async createTenantAppDevWorkspacePreview(appId,payload={}){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDevWorkspacePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`)}async listTenantAppSourceVersions(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`)}async updateTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async getTenantAppEndUserAuthConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/config`)}async getTenantAppEndUserAuthDiscovery(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/discovery`)}async getTenantAppEndUserAuthInspect(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/inspect`)}async configureTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/configure`,{method:"POST",body:JSON.stringify(payload)})}async bindTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/bind`,{method:"POST",body:JSON.stringify(payload)})}async listTenantAppEndUsers(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users`)}async listTenantAppEndUserRoles(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`)}async createTenantAppEndUserRole(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppEndUserRole(appId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`)}async updateTenantAppEndUserRole(appId,roleKey,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAppUserRoles(appId,appUserId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`)}async assignTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles:assign`,{method:"POST",body:JSON.stringify(payload)})}async replaceTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`,{method:"PUT",body:JSON.stringify(payload)})}async removeTenantAppUserRole(appId,appUserId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles/${encodeURIComponent(roleKey)}`,{method:"DELETE"})}async discoverTenantCmsCollection(collection){let url=new URL("/api/tenant/cms/discover",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsCollections(){return this.request("/api/tenant/cms/collections")}async inspectTenantCmsSchema(collection){let url=new URL("/api/tenant/cms/inspect/schema",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsItems(args){let url=new URL("/api/tenant/cms/items",this.options.baseUrl);return url.searchParams.set("collection",args.collection),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"status",args.status),setOptionalSearchParam(url,"q",args.query),this.request(`${url.pathname}${url.search}`)}async getTenantCmsItem(args){let url=new URL(`/api/tenant/cms/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("collection",args.collection),this.request(`${url.pathname}${url.search}`)}async configureTenantCmsCollection(spec){return this.request("/api/tenant/cms/configure/collection",{method:"POST",body:JSON.stringify(spec)})}async configureTenantCmsItem(payload){return this.request("/api/tenant/cms/configure/item",{method:"POST",body:JSON.stringify(payload)})}async configureTenantCmsCategory(payload){return this.request("/api/tenant/cms/configure/category",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsSchema(payload){return this.request("/api/tenant/cms/apply/schema",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsCollectionStatus(payload){return this.request("/api/tenant/cms/apply/collection-status",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsPublish(payload){return this.request("/api/tenant/cms/apply/publish",{method:"POST",body:JSON.stringify(payload)})}async listPublicCmsItems(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items`,this.options.baseUrl);url.searchParams.set("tenant_id",args.tenantId),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"sort_field",args.sortField),setOptionalSearchParam(url,"sort_direction",args.sortDirection);for(let tag of args.tags??[])url.searchParams.append("tag",tag);return this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemBySlug(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/by-slug/${encodeURIComponent(args.slug)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemById(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listPublicCmsCategories(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/categories`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listTenantAppDeploymentTimeline(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/deployments`,this.options.baseUrl);return typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAppPublishSettings(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`)}async updateTenantAppPublishSettings(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`,{method:"PATCH",body:JSON.stringify(payload)})}async setTenantAppCurrentPublishedVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings/current-version`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppPreview(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/previews`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersionFromTemplate(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions:from-template`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppReleaseDeletePreview(appId,releaseId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete-preview`,{method:"POST"})}async deleteTenantAppRelease(appId,releaseId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceVersionDeletePreview(appId,sourceVersionId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete-preview`,{method:"POST"})}async deleteTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantVersionDeleteJob(jobId){return this.request(`/api/tenant/version-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppBuildDeletePreview(appId,buildId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete-preview`,{method:"POST"})}async deleteTenantAppBuild(appId,buildId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDbInstance(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbRuntimeBindings(appId,env="preview",purpose){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/runtime-bindings`,this.options.baseUrl);return url.searchParams.set("env",env),purpose&&url.searchParams.set("purpose",purpose),this.requestUrl(url)}async resolveDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/resolve",{method:"POST",body:JSON.stringify(payload)})}async revokeDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/revoke",{method:"POST",body:JSON.stringify(payload)})}async listTenantAppDbTables(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableSchema(appId,tableName,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/schema`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableRows(appId,tableName,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.page=="number"&&url.searchParams.set("page",String(args.page)),typeof args.page_size=="number"&&url.searchParams.set("page_size",String(args.page_size)),typeof args.sort_by=="string"&&args.sort_by.trim().length>0&&url.searchParams.set("sort_by",args.sort_by),args.sort_order==="desc"&&url.searchParams.set("sort_order","desc"),typeof args.filter_column=="string"&&args.filter_column.trim().length>0&&url.searchParams.set("filter_column",args.filter_column),typeof args.filter_value=="string"&&args.filter_value.length>0&&url.searchParams.set("filter_value",args.filter_value),typeof args.search_query=="string"&&args.search_query.trim().length>0&&url.searchParams.set("search_query",args.search_query),this.requestUrl(url)}async listTenantAppDbMigrationRuns(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/migrations`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async listTenantAppDbChangeAudits(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/audits`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.table_name=="string"&&args.table_name.trim().length>0&&url.searchParams.set("table_name",args.table_name),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async insertTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"POST",body:JSON.stringify(payload)})}async updateTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"DELETE",body:JSON.stringify(payload)})}async queryTenantAppDb(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/query`,{method:"POST",body:JSON.stringify(payload)})}async createWorkspace(payload){return this.request("/api/admin/workspaces",{method:"POST",body:JSON.stringify(payload)})}async deleteWorkspace(workspaceId,payload){return this.request(`/api/admin/workspaces/${encodeURIComponent(workspaceId)}`,{method:"DELETE",...payload?{body:JSON.stringify(payload)}:{}})}async createApproval(payload){return this.request("/api/admin/resource-approvals",{method:"POST",body:JSON.stringify(payload)})}async listApprovals(filters){let url=new URL("/api/admin/resource-approvals",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.status&&url.searchParams.set("status",filters.status),filters?.operation&&url.searchParams.set("operation",filters.operation),this.requestUrl(url)}async decideApproval(approvalId,payload){return this.request(`/api/admin/resource-approvals/${approvalId}/decision`,{method:"POST",body:JSON.stringify(payload)})}async listResourceLocks(filters){let url=new URL("/api/admin/resource-locks",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.env&&url.searchParams.set("env",filters.env),this.requestUrl(url)}async diffResources(payload){return this.request("/api/resources/diff",{method:"POST",body:JSON.stringify(payload)})}async applyResources(payload){return this.request("/api/resources/apply",{method:"POST",body:JSON.stringify(payload)})}async rollbackResources(payload){return this.request("/api/resources/rollback",{method:"POST",body:JSON.stringify(payload)})}async deployRelease(payload){return this.request("/api/releases/deploy",{method:"POST",body:JSON.stringify(payload)})}async rollbackRelease(payload){return this.request("/api/releases/rollback",{method:"POST",body:JSON.stringify(payload)})}async queryLogs(payload){return this.request("/api/logs/query",{method:"POST",body:JSON.stringify(payload)})}};function setOptionalSearchParam(url,key,value){typeof value=="string"&&value.trim().length>0&&url.searchParams.set(key,value)}function setOptionalBooleanSearchParam(url,key,value){typeof value=="boolean"&&url.searchParams.set(key,value?"true":"false")}function resolveRelativeOrAbsoluteUrl(pathOrUrl,baseUrl){return new URL(pathOrUrl,baseUrl)}function createPlatformSdk(options){return new PlatformSdk(options)}var NotificationSdkNamespace=class{sdk;endUser;constructor(sdk){this.sdk=sdk,this.endUser=new EndUserNotificationNamespace(sdk)}},EndUserNotificationNamespace=class{sdk;constructor(sdk){this.sdk=sdk}forApp(appId){return new EndUserNotificationAppClient(this.sdk,appId)}},EndUserNotificationAppClient=class{sdk;appId;announcements;constructor(sdk,appId){this.sdk=sdk,this.appId=appId,this.announcements=new EndUserNotificationAppAnnouncementsClient(sdk,appId)}listUsers(){return this.sdk.listTenantAppEndUsers(this.appId)}forUser(endUserId){return new EndUserNotificationUserClient(this.sdk,this.appId,endUserId)}listInbox(endUserId,query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:endUserId,...query})}getUnreadCount(endUserId){return this.sdk.getEndUserNotificationUnreadCount(this.appId,endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,input.end_user_id),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,input.end_user_id)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,input.end_user_id)})}},EndUserNotificationAppAnnouncementsClient=class{sdk;appId;constructor(sdk,appId){this.sdk=sdk,this.appId=appId}getConfig(){return this.sdk.getAppNotificationConfig(this.appId)}list(limit){return this.sdk.listAppNotificationAnnouncements(this.appId,{limit})}create(input){return this.sdk.createAppNotificationAnnouncement(this.appId,input)}archive(announcementId){return this.sdk.archiveAppNotificationAnnouncement(this.appId,announcementId)}},EndUserNotificationUserClient=class{sdk;appId;endUserId;constructor(sdk,appId,endUserId){this.sdk=sdk,this.appId=appId,this.endUserId=endUserId}buildRecipientRef(){return buildDirectEndUserRecipientRef(this.appId,this.endUserId)}listInbox(query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:this.endUserId,...query})}getUnreadCount(){return this.sdk.getEndUserNotificationUnreadCount(this.appId,this.endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:this.buildRecipientRef(),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,this.endUserId),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:this.buildRecipientRef(),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,this.endUserId)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:this.buildRecipientRef(),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,this.endUserId)})}};function buildDirectEndUserRecipientRef(appId,endUserId){return{app_id:appId,end_user_id:endUserId,recipient_type:"direct_user"}}function buildNotificationIdempotencyKey(prefix,appId,endUserId){return`${prefix}:${appId}:${endUserId}:${Date.now()}`}var AUTH_PAGE_HTML=String.raw`<!doctype html>
|
|
2
|
+
var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));var require_punycode=__commonJS({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js"(exports,module){"use strict";var regexPunycode=/^xn--/,regexNonASCII=/[^\0-\x7F]/,regexSeparators=/[\x2E\u3002\uFF0E\uFF61]/g,errors={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},baseMinusTMin=35,floor=Math.floor,stringFromCharCode=String.fromCharCode;function error(type){throw new RangeError(errors[type])}function map(array,callback){let result=[],length=array.length;for(;length--;)result[length]=callback(array[length]);return result}function mapDomain(domain,callback){let parts=domain.split("@"),result="";parts.length>1&&(result=parts[0]+"@",domain=parts[1]),domain=domain.replace(regexSeparators,".");let labels=domain.split("."),encoded=map(labels,callback).join(".");return result+encoded}function ucs2decode(string){let output=[],counter=0,length=string.length;for(;counter<length;){let value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){let extra=string.charCodeAt(counter++);(extra&64512)==56320?output.push(((value&1023)<<10)+(extra&1023)+65536):(output.push(value),counter--)}else output.push(value)}return output}var ucs2encode=codePoints=>String.fromCodePoint(...codePoints),basicToDigit=function(codePoint){return codePoint>=48&&codePoint<58?26+(codePoint-48):codePoint>=65&&codePoint<91?codePoint-65:codePoint>=97&&codePoint<123?codePoint-97:36},digitToBasic=function(digit,flag){return digit+22+75*(digit<26)-((flag!=0)<<5)},adapt=function(delta,numPoints,firstTime){let k=0;for(delta=firstTime?floor(delta/700):delta>>1,delta+=floor(delta/numPoints);delta>baseMinusTMin*26>>1;k+=36)delta=floor(delta/baseMinusTMin);return floor(k+(baseMinusTMin+1)*delta/(delta+38))},decode2=function(input){let output=[],inputLength=input.length,i=0,n=128,bias=72,basic=input.lastIndexOf("-");basic<0&&(basic=0);for(let j=0;j<basic;++j)input.charCodeAt(j)>=128&&error("not-basic"),output.push(input.charCodeAt(j));for(let index=basic>0?basic+1:0;index<inputLength;){let oldi=i;for(let w=1,k=36;;k+=36){index>=inputLength&&error("invalid-input");let digit=basicToDigit(input.charCodeAt(index++));digit>=36&&error("invalid-input"),digit>floor((2147483647-i)/w)&&error("overflow"),i+=digit*w;let t=k<=bias?1:k>=bias+26?26:k-bias;if(digit<t)break;let baseMinusT=36-t;w>floor(2147483647/baseMinusT)&&error("overflow"),w*=baseMinusT}let out=output.length+1;bias=adapt(i-oldi,out,oldi==0),floor(i/out)>2147483647-n&&error("overflow"),n+=floor(i/out),i%=out,output.splice(i++,0,n)}return String.fromCodePoint(...output)},encode2=function(input){let output=[];input=ucs2decode(input);let inputLength=input.length,n=128,delta=0,bias=72;for(let currentValue of input)currentValue<128&&output.push(stringFromCharCode(currentValue));let basicLength=output.length,handledCPCount=basicLength;for(basicLength&&output.push("-");handledCPCount<inputLength;){let m=2147483647;for(let currentValue of input)currentValue>=n&¤tValue<m&&(m=currentValue);let handledCPCountPlusOne=handledCPCount+1;m-n>floor((2147483647-delta)/handledCPCountPlusOne)&&error("overflow"),delta+=(m-n)*handledCPCountPlusOne,n=m;for(let currentValue of input)if(currentValue<n&&++delta>2147483647&&error("overflow"),currentValue===n){let q=delta;for(let k=36;;k+=36){let t=k<=bias?1:k>=bias+26?26:k-bias;if(q<t)break;let qMinusT=q-t,baseMinusT=36-t;output.push(stringFromCharCode(digitToBasic(t+qMinusT%baseMinusT,0))),q=floor(qMinusT/baseMinusT)}output.push(stringFromCharCode(digitToBasic(q,0))),bias=adapt(delta,handledCPCountPlusOne,handledCPCount===basicLength),delta=0,++handledCPCount}++delta,++n}return output.join("")},toUnicode=function(input){return mapDomain(input,function(string){return regexPunycode.test(string)?decode2(string.slice(4).toLowerCase()):string})},toASCII=function(input){return mapDomain(input,function(string){return regexNonASCII.test(string)?"xn--"+encode2(string):string})},punycode2={version:"2.3.1",ucs2:{decode:ucs2decode,encode:ucs2encode},decode:decode2,encode:encode2,toASCII,toUnicode};module.exports=punycode2}});import{existsSync as existsSync25,readFileSync as readFileSync27}from"node:fs";import{resolve as resolve18}from"node:path";import process7 from"node:process";async function batchUpdateTenantCmsItems(args){let collection=args.payload.collection.trim(),itemIds=Array.from(new Set(args.payload.item_ids.map(itemId=>itemId.trim()).filter(Boolean))),tagAdds=dedupeTags(args.payload.changes.tags.add),discover=await args.sdk.discoverTenantCmsCollection(collection),schemaSpec=discover.active_schema??discover.draft_schema;if(!schemaSpec)throw new Error(`Collection \`${collection}\` \u5F53\u524D\u6CA1\u6709\u53EF\u7528 schema\u3002`);let succeeded=[],failed=[];for(let itemId of itemIds){let title=itemId;try{let item=await args.sdk.getTenantCmsItem({collection,id:itemId});title=resolveCmsItemTitle(item);let currentStatus=item.system.publish_status??"draft",targetStatus=args.payload.changes.publish_status.mode==="set"?args.payload.changes.publish_status.value:void 0,hasCategoryChange=args.payload.changes.category.mode!=="keep",hasTagChange=tagAdds.length>0,hasMetadataChange=hasCategoryChange||hasTagChange,effectiveStatus=currentStatus;if(hasMetadataChange){currentStatus==="archived"&&targetStatus&&targetStatus!=="archived"&&(await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus}),effectiveStatus=targetStatus);let payload=buildCmsItemWritePayloadFromDelivery({item,schemaSpec,publishStatus:targetStatus&&targetStatus!=="archived"?targetStatus:effectiveStatus,categoryChange:args.payload.changes.category,tagsToAdd:tagAdds});await args.sdk.configureTenantCmsItem({...payload,item_id:itemId}),targetStatus==="archived"&&effectiveStatus!=="archived"?await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:"archived"}):targetStatus&&targetStatus!=="archived"&&(effectiveStatus=targetStatus)}else targetStatus&&targetStatus!==effectiveStatus&&await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus});succeeded.push({item_id:itemId,title})}catch(error){failed.push({item_id:itemId,title,message:error instanceof Error?error.message:"\u6279\u91CF\u66F4\u65B0\u5931\u8D25"})}}return{total:itemIds.length,succeeded,failed}}function buildCmsItemWritePayloadFromDelivery(args){let nextTags=dedupeTags([...args.item.system.tags??[],...args.tagsToAdd]);return{collection:args.item.collection,system:{publish_status:args.publishStatus,...args.item.system.slug?{slug:args.item.system.slug}:{},featured:args.item.system.featured??!1,tags:nextTags,category_id:resolveNextCategoryId(args.item,args.categoryChange),...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:normalizeCmsContentForWrite(args.item.content,args.schemaSpec.fields)}}function resolveNextCategoryId(item,categoryChange){return categoryChange.mode==="clear"?null:categoryChange.mode==="set"?categoryChange.category_id?.trim()||null:item.system.category_id??null}function resolveCmsItemTitle(item){let title=item.content.title,name=item.content.name;return typeof title=="string"&&title.trim()?title.trim():typeof name=="string"&&name.trim()?name.trim():item.system.slug??item.system.id??"Untitled item"}function dedupeTags(values){let seen=new Set,next=[];for(let value of values){let normalized=value.trim();if(!normalized)continue;let lowered=normalized.toLowerCase();seen.has(lowered)||(seen.add(lowered),next.push(normalized))}return next}function normalizeCmsContentForWrite(content,fields){let normalized={};for(let field of fields)normalized[field.name]=normalizeFieldValueForPayload(field,content[field.name]);return normalized}function normalizeFieldValueForPayload(field,value){switch(field.type){case"date":if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}return value??null;case"number":if(typeof value=="string"){let parsed=Number.parseFloat(value.trim());return Number.isFinite(parsed)?field.ui?.number_kind==="integer"?Math.trunc(parsed):parsed:0}return value;case"bool":return!!value;case"multi_select":return normalizeStringArrayValue(value);case"image":case"file":return normalizeAssetValue(value);case"images":case"files":return normalizeAssetArrayValue(value);case"relation":return normalizeRelationId(value);case"relations":return normalizeRelationArrayValue(value);default:return typeof value=="string"?value:value??""}}function normalizeRelationId(value){if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}if(value&&typeof value=="object"&&!Array.isArray(value)&&"id"in value){let id=value.id;return typeof id=="string"&&id.trim().length>0?id.trim():null}return null}function normalizeAssetValue(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:null}function normalizeStringArrayValue(value){return Array.isArray(value)?value.map(item=>String(item)):typeof value=="string"?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function normalizeAssetArrayValue(value){return Array.isArray(value)?value.filter(item=>!!item&&typeof item=="object"&&!Array.isArray(item)):[]}function normalizeRelationArrayValue(value){return Array.isArray(value)?value.map(item=>normalizeRelationId(item)).filter(item=>!!item):[]}import{createHash}from"node:crypto";import{URL as URL2}from"node:url";var IMAGE_URL_ATTRS=["src","data-src","data-original","data-original-src","data-lazy-src"],IMAGE_SRCSET_ATTRS=["srcset","data-srcset"];function trimToUndefined(value){let normalized=value?.trim();return normalized||void 0}function normalizeUrl(value,baseUrl){let trimmed=trimToUndefined(value);if(trimmed)try{return baseUrl?new URL2(trimmed,baseUrl).toString():new URL2(trimmed).toString()}catch{return}}function isPlatformHostedAssetUrl(value){try{let parsed=new URL2(value);return/^\/assets\/[^/]+\/(original|variants\/[^/]+)$/.test(parsed.pathname)||parsed.pathname.startsWith("/api/tenant/assets/")}catch{return!1}}function inferMimeTypeFromUrl(value){if(!value)return;let pathname=(()=>{try{return new URL2(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg";if(pathname.endsWith(".avif"))return"image/avif"}function computeChecksum(content){return`sha256:${createHash("sha256").update(content).digest("hex")}`}function inferRemoteImageFileName(url,mimeType){let lastSegment=(()=>{try{return new URL2(url).pathname}catch{return url}})().split("/").filter(Boolean).at(-1);return lastSegment&&/\.[a-z0-9]{2,6}$/i.test(lastSegment)?decodeURIComponent(lastSegment):`remote-image.${(()=>{switch(mimeType){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":default:return"jpg"}})()}`}function buildTenantAssetReference(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function replaceImageAttributeUrls(html,replacementsByUrl,attribute2){let pattern=new RegExp(`(<img\\b[^>]*?\\s${attribute2}\\s*=\\s*)(["'])(.*?)\\2`,"gi");return html.replace(pattern,(fullMatch,prefix,quote,rawUrl)=>{let replacement=replacementsByUrl.get(rawUrl);return!replacement||replacement.finalUrl===rawUrl?fullMatch:`${prefix}${quote}${replacement.finalUrl}${quote}`})}function stripImageAttributes(html,attributes){let nextHtml=html;for(let attribute2 of attributes){let pattern=new RegExp(`\\s${attribute2}\\s*=\\s*(["']).*?\\1`,"gi");nextHtml=nextHtml.replace(pattern,"")}return nextHtml}async function fetchRemoteImageBinary(args){let response=await(args.fetchImpl??fetch)(args.url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u56FE\u7247\u62C9\u53D6\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let normalizedMimeType=String(response.headers.get("content-type")??"").split(";")[0]?.trim().toLowerCase()||inferMimeTypeFromUrl(args.url);if(!normalizedMimeType||!normalizedMimeType.startsWith("image/"))throw new Error("\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u53D7\u652F\u6301\u7684\u56FE\u7247\u7C7B\u578B");let content=new Uint8Array(await response.arrayBuffer()),maxBytes=args.maxBytes??20*1024*1024;if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");if(content.byteLength>maxBytes)throw new Error(`\u8FDC\u7A0B\u56FE\u7247\u8D85\u8FC7\u5927\u5C0F\u9650\u5236\uFF08${content.byteLength} bytes\uFF09`);return{content,mimeType:normalizedMimeType}}async function ingestRemoteImageCandidates(args){let uniqueCandidates=new Map;for(let candidate of args.candidates)uniqueCandidates.has(candidate.url)||uniqueCandidates.set(candidate.url,candidate);let resultsByUrl=new Map,resultsByChecksum=new Map,warnings=[];for(let candidate of uniqueCandidates.values())try{let{content,mimeType}=await fetchRemoteImageBinary({url:candidate.url,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),checksum3=computeChecksum(content),existingByChecksum=resultsByChecksum.get(checksum3);if(existingByChecksum){let reused={...existingByChecksum,originalUrl:candidate.url,status:"reused"};resultsByUrl.set(candidate.url,reused);continue}let fileName=inferRemoteImageFileName(candidate.url,mimeType),uploadedAsset=await args.sdk.createTenantAssetBinary({fileName,mimeType,content,title:candidate.title,...args.folderId?{folderId:args.folderId}:{}}),uploaded={originalUrl:candidate.url,finalUrl:uploadedAsset.original_url,asset:uploadedAsset,assetReference:buildTenantAssetReference(uploadedAsset),mimeType,checksum:checksum3,status:"uploaded"};resultsByUrl.set(candidate.url,uploaded),resultsByChecksum.set(checksum3,uploaded)}catch(error){let message=error instanceof Error?error.message:"\u5916\u94FE\u56FE\u7247\u8D44\u4EA7\u5316\u5931\u8D25";warnings.push(`\u56FE\u7247 \`${candidate.url}\` \u8D44\u4EA7\u5316\u5931\u8D25\uFF0C\u5DF2\u56DE\u9000\u539F\u94FE\u63A5\uFF1A${message}`),resultsByUrl.set(candidate.url,{originalUrl:candidate.url,finalUrl:candidate.url,mimeType:inferMimeTypeFromUrl(candidate.url),status:"fallback",warning:message})}return{resultsByUrl,warnings}}function collectExternalImageCandidatesFromHtml(args){let candidates=new Map;return args.html.replace(/<img\b[^>]*>/gi,tag=>{for(let attribute2 of IMAGE_URL_ATTRS){let rawUrl=tag.match(new RegExp(`(?:^|\\s)${attribute2}\\s*=\\s*(["'])(.*?)\\1`,"i"))?.[2],normalizedUrl=normalizeUrl(rawUrl,args.baseUrl);!normalizedUrl||normalizedUrl.startsWith("data:")||isPlatformHostedAssetUrl(normalizedUrl)||candidates.has(normalizedUrl)||candidates.set(normalizedUrl,{url:normalizedUrl,title:args.title,source:"body"})}return""}),[...candidates.values()]}async function assetizeExternalImagesInHtml(args){let bodyCandidates=collectExternalImageCandidatesFromHtml({html:args.html,baseUrl:args.baseUrl,title:args.bodyTitle}),normalizedCoverUrl=normalizeUrl(args.coverUrl,args.baseUrl),coverCandidate=normalizedCoverUrl&&!normalizedCoverUrl.startsWith("data:")&&!isPlatformHostedAssetUrl(normalizedCoverUrl)?{url:normalizedCoverUrl,title:args.coverTitle??args.bodyTitle,source:"cover"}:null,candidates=coverCandidate?[coverCandidate,...bodyCandidates]:bodyCandidates,{resultsByUrl,warnings}=await ingestRemoteImageCandidates({sdk:args.sdk,candidates,folderId:args.folderId,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),html=args.html;for(let attribute2 of IMAGE_URL_ATTRS)html=replaceImageAttributeUrls(html,resultsByUrl,attribute2);html=stripImageAttributes(html,IMAGE_SRCSET_ATTRS);let replacements=[...resultsByUrl.values()].map(result=>({originalUrl:result.originalUrl,finalUrl:result.finalUrl,...result.asset?.asset.asset_id?{assetId:result.asset.asset.asset_id}:{},status:result.status}));if(!normalizedCoverUrl)return{html,cover:{mode:"none"},replacements,warnings};let coverResult=resultsByUrl.get(normalizedCoverUrl);return coverResult?.assetReference?{html,cover:{mode:"asset",value:coverResult.assetReference},replacements,warnings}:{html,cover:{mode:"remote",value:{title:args.coverTitle??args.bodyTitle??"Remote cover",...coverResult?.mimeType||args.coverMimeType?{mime_type:coverResult?.mimeType??args.coverMimeType}:{},original_url:normalizedCoverUrl}},replacements,warnings}}var PlatformApiError=class extends Error{status;code;detail;requestId;capability;category;remediation;constructor(message,status,code2,detail,requestId,capability,category,remediation){super(message),this.status=status,this.code=code2,this.detail=detail,this.requestId=requestId,this.capability=capability,this.category=category,this.remediation=remediation,this.name="PlatformApiError"}},BasePlatformSdk=class{options;fetchImpl;constructor(options){this.options=options,this.fetchImpl=options.fetchImpl??fetch}async request(path3,init={}){return this.requestUrl(new URL(path3,this.options.baseUrl),init)}async requestBinary(path3,init={}){return this.requestBinaryUrl(new URL(path3,this.options.baseUrl),init)}async requestVoid(path3,init={}){return this.requestVoidUrl(new URL(path3,this.options.baseUrl),init)}async requestUrl(url,init={}){let response=await this.fetchResponse(url,init),payload=await parseJsonResponse(response);if(!response.ok){let errorPayload=payload,error=errorPayload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??errorPayload.detail,errorPayload.request_id,error?.capability,error?.category,error?.remediation)}return payload}async requestBinaryUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}return new Uint8Array(await response.arrayBuffer())}async requestVoidUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}}async fetchResponse(url,init={}){let headers=new Headers(init.headers);!headers.has("Content-Type")&&init.body&&headers.set("Content-Type","application/json");let extraHeaders=await this.options.getHeaders?.();return extraHeaders&&new Headers(extraHeaders).forEach((value,key)=>{headers.set(key,value)}),this.fetchImpl(url,{...init,headers})}};async function parseJsonResponse(response){let text2=await response.text();if(text2.trim().length===0)return{};try{return JSON.parse(text2)}catch{if(response.ok)return{};throw new PlatformApiError(`Request failed with non-JSON response: ${response.status}`,response.status,"non_json_response",{content_type:response.headers.get("content-type")??void 0,body_preview:text2.replace(/\s+/g," ").slice(0,240)})}}var PlatformSdk=class extends BasePlatformSdk{notification;constructor(options){super(options),this.notification=new NotificationSdkNamespace(this)}async listNotificationInbox(filters={}){let url=new URL("/api/tenant/notification/inbox",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"inbox_type",filters.inbox_type),setOptionalSearchParam(url,"status",filters.status),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async updateNotificationInboxItemStatus(itemId,payload){return(await this.request(`/api/tenant/notification/inbox/${encodeURIComponent(itemId)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async batchUpdateNotificationInboxItemsStatus(payload){return this.request("/api/tenant/notification/inbox:batch",{method:"PATCH",body:JSON.stringify(payload)})}async listNotificationDeliveries(filters={}){let url=new URL("/api/tenant/notification/deliveries",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async announcePlatformNotification(payload){return(await this.request("/api/admin/notification/announcements/platform",{method:"POST",body:JSON.stringify(payload)})).item}async announceAppNotification(appId,payload){return(await this.request(`/api/tenant/notification/apps/${encodeURIComponent(appId)}/announcements`,{method:"POST",body:JSON.stringify(payload)})).item}async getAppNotificationConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/config`)}async listAppNotificationAnnouncements(appId,options={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,this.options.baseUrl);return typeof options.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async createAppNotificationAnnouncement(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,{method:"POST",body:JSON.stringify(payload)})}async archiveAppNotificationAnnouncement(appId,announcementId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements/${encodeURIComponent(announcementId)}:archive`,{method:"POST"})}async publishEndUserNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/publish`,{method:"POST",body:JSON.stringify(payload)})}async createEndUserNotificationReminder(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/reminders`,{method:"POST",body:JSON.stringify(payload)})}async projectEndUserTaskNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/task-projections`,{method:"POST",body:JSON.stringify(payload)})}async listEndUserNotificationInbox(appId,query){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/inbox`,this.options.baseUrl);return url.searchParams.set("end_user_id",query.end_user_id),setOptionalSearchParam(url,"status",query.status),setOptionalSearchParam(url,"inbox_type",query.inbox_type),typeof query.limit=="number"&&Number.isFinite(query.limit)&&url.searchParams.set("limit",String(query.limit)),this.request(`${url.pathname}${url.search}`)}async getEndUserNotificationUnreadCount(appId,endUserId){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/unread-count`,this.options.baseUrl);return url.searchParams.set("end_user_id",endUserId),this.request(`${url.pathname}${url.search}`)}async createWorkflowDefinition(payload){return(await this.request("/api/workflow/definitions",{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowTemplates(){return(await this.request("/api/workflow/templates")).items}async listWorkflowDefinitions(filters={}){let url=new URL("/api/workflow/definitions",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async listWorkflowBindings(filters={}){let url=new URL("/api/workflow/bindings",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"definition_key",filters.definition_key),(await this.request(`${url.pathname}${url.search}`)).items}async updateWorkflowDefinitionMetadata(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async saveWorkflowRoleBindings(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/role-bindings`,{method:"POST",body:JSON.stringify(payload)})).items}async getWorkflowBindingOverride(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/binding-override`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).item}async saveWorkflowBindingOverride(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/binding-override`,{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowRoleBindings(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/role-bindings`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).items}async startWorkflow(payload){return(await this.request("/api/workflow/instances/start",{method:"POST",body:JSON.stringify(payload)})).item}async performWorkflowAction(instanceId,payload){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}/actions`,{method:"POST",body:JSON.stringify(payload)})).item}async getWorkflowInstance(instanceId){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}`)).item}async listWorkflowTasks(filters={}){let url=new URL("/api/workflow/tasks",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async getWhoAmI(){return this.request("/api/auth/whoami")}async getResolvedPermissions(){return this.request("/api/auth/permissions")}async switchTenantContext(payload){return this.request("/api/auth/context/switch-tenant",{method:"POST",body:JSON.stringify(payload)})}async listTenantWorkspaces(){return this.request("/api/auth/workspaces")}async ensurePersonalWorkspace(){return this.request("/api/auth/workspaces/ensure-personal",{method:"POST"})}async getAdminOverview(){return this.request("/api/admin/overview")}async listAdminWorkbenchEntries(){return this.request("/api/admin/workbench-entries")}async getAdminWorkbenchEntryDetail(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}`)}async updateAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"PUT",body:JSON.stringify(payload)})}async resetAdminWorkbenchEntryVisibility(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"DELETE"})}async previewAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility:preview`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAsset(payload){return this.request("/api/tenant/assets",{method:"POST",body:JSON.stringify(payload)})}async createTenantAssetBinary(args){let headers=new Headers({"Content-Type":args.mimeType,"X-Asset-File-Name":encodeURIComponent(args.fileName)});return args.title?.trim()&&headers.set("X-Asset-Title",encodeURIComponent(args.title.trim())),args.folderId?.trim()&&headers.set("X-Asset-Folder-Id",encodeURIComponent(args.folderId.trim())),this.request("/api/tenant/assets/upload",{method:"POST",headers,body:Buffer.from(args.content)})}async listTenantAssets(filters={}){let url=new URL("/api/tenant/assets",this.options.baseUrl);return setOptionalSearchParam(url,"q",filters.q),setOptionalSearchParam(url,"media_type",filters.media_type),setOptionalSearchParam(url,"mime_type",filters.mime_type),setOptionalSearchParam(url,"folder_id",filters.folder_id),setOptionalSearchParam(url,"tag_ids",filters.tag_ids?.join(",")),setOptionalSearchParam(url,"scene",filters.scene),setOptionalSearchParam(url,"objects",filters.objects?.join(",")),setOptionalSearchParam(url,"safety_flags",filters.safety_flags?.join(",")),setOptionalSearchParam(url,"orientation",filters.orientation),setOptionalBooleanSearchParam(url,"has_ocr",filters.has_ocr),setOptionalBooleanSearchParam(url,"has_person",filters.has_person),setOptionalBooleanSearchParam(url,"is_svg",filters.is_svg),typeof filters.page=="number"&&Number.isFinite(filters.page)&&url.searchParams.set("page",String(filters.page)),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`)}async deleteTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`,{method:"DELETE"})}async batchUpdateTenantAssets(payload){return this.request("/api/tenant/assets/batch",{method:"POST",body:JSON.stringify(payload)})}async listTenantAssetFolders(){return this.request("/api/tenant/assets/folders")}async createTenantAssetFolder(payload){return this.request("/api/tenant/assets/folders",{method:"POST",body:JSON.stringify(payload)})}async updateTenantAssetFolderMetadata(folderId,payload){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAssetFolder(folderId){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"DELETE"})}async moveTenantAssetFolder(folderId,direction){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}/move-${direction}`,{method:"POST"})}async updateTenantAssetFolder(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/folder`,{method:"PATCH",body:JSON.stringify(payload)})}async updateTenantAssetMetadata(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/metadata`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAssetTags(options){let url=new URL("/api/tenant/assets/tags",this.options.baseUrl);return options?.assetId&&url.searchParams.set("asset_id",options.assetId),this.request(`${url.pathname}${url.search}`)}async addTenantAssetTag(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,{method:"POST",body:JSON.stringify(payload)})}async removeTenantAssetTag(assetId,label){let url=new URL(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,this.options.baseUrl);return url.searchParams.set("label",label),this.request(`${url.pathname}${url.search}`,{method:"DELETE"})}async downloadTenantAssetOriginal(assetId){return this.requestBinary(`/api/tenant/assets/${encodeURIComponent(assetId)}/original`)}async downloadTenantAssetVariant(assetId,variantKind){return this.requestBinary(`/assets/${encodeURIComponent(assetId)}/variants/${encodeURIComponent(variantKind)}`)}async createTenantBlobUploadSession(payload){return this.request("/api/tenant/blobs/upload-sessions",{method:"POST",body:JSON.stringify(payload)})}async uploadTenantBlobBinary(uploadSessionId,payload){let url=resolveRelativeOrAbsoluteUrl(payload.upload_url??`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/content`,this.options.baseUrl),headers=new Headers(payload.headers);headers.set("Content-Type",payload.content_type?.trim()||"application/octet-stream"),await this.requestVoidUrl(url,{method:"PUT",headers,body:Buffer.from(payload.content)})}async completeTenantBlobUpload(uploadSessionId,payload={}){return this.request(`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/complete`,{method:"POST",body:JSON.stringify(payload)})}async createTenantBlobBinary(args){let contentType=args.contentType?.trim()||"application/octet-stream",session=await this.createTenantBlobUploadSession({original_filename:args.fileName,content_type:contentType,size_bytes:args.content.byteLength,...args.appId?.trim()?{app_id:args.appId.trim()}:{},...args.clientRequestId?.trim()?{client_request_id:args.clientRequestId.trim()}:{}});return await this.uploadTenantBlobBinary(session.upload_session_id,{content:args.content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}),this.completeTenantBlobUpload(session.upload_session_id,{size_bytes:args.content.byteLength,...args.sha256?.trim()?{sha256:args.sha256.trim()}:{}})}async listTenantBlobs(filters={}){let url=new URL("/api/tenant/blobs",this.options.baseUrl);return setOptionalSearchParam(url,"cursor",filters.cursor),setOptionalSearchParam(url,"app_id",filters.app_id??void 0),setOptionalSearchParam(url,"q",filters.q??void 0),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantBlob(blobId){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}`)}async issueTenantBlobDownloadUrl(blobId,payload={}){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}/download-url`,{method:"POST",body:JSON.stringify(payload)})}async getTenantOverview(){return this.request("/api/tenant/overview")}async getTenantEffectiveState(){return this.request("/api/tenant/effective-state")}async getTenantWorkbenchNavigation(){return this.request("/api/tenant/workbench/navigation")}async createTenantApp(payload){return this.request("/api/tenant/apps",{method:"POST",body:JSON.stringify(payload)})}async updateTenantApp(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listAppTemplates(){return this.request("/api/tenant/app-templates")}async createAppTemplate(payload){return this.request("/api/tenant/app-templates",{method:"POST",body:JSON.stringify(payload)})}async getAppTemplate(templateId){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`)}async openAppTemplatePreview(templateId){return this.requestVoid(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/preview`)}async updateAppTemplateSettings(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteAppTemplate(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"DELETE",body:JSON.stringify(payload)})}async createAppTemplateInitializationTask(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/initialization-tasks`,{method:"POST",body:JSON.stringify(payload)})}async getAppTemplateInitializationTask(taskId){return this.request(`/api/tenant/app-template-initialization-tasks/${encodeURIComponent(taskId)}`)}async createAppMarketSubmission(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/market-submissions`,{method:"POST",body:JSON.stringify(payload)})}async cancelAppMarketSubmission(submissionId){return this.request(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/cancel`,{method:"POST"})}async listTenantAppMarketSubmissions(options){let url=new URL("/api/tenant/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async listAppMarketListings(options){let url=new URL("/api/tenant/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async listAdminAppMarketListings(options){let url=new URL("/api/admin/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async getAppMarketListing(listingId){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}`)}async openAppMarketSubmissionPreview(submissionId){return this.requestVoid(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/preview`)}async createAppMarketInstall(listingId,payload){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}/installs`,{method:"POST",body:JSON.stringify(payload)})}async listAdminAppMarketSubmissions(options){let url=new URL("/api/admin/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async approveAppMarketSubmission(submissionId){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/approve`,{method:"POST"})}async rejectAppMarketSubmission(submissionId,payload={}){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/reject`,{method:"POST",body:JSON.stringify(payload)})}async unlistAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/unlist`,{method:"POST",body:JSON.stringify(payload)})}async publishAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/publish`,{method:"POST",body:JSON.stringify(payload)})}async listAdminLightAppLibraries(options){let url=new URL("/api/admin/light-app-library/libraries",this.options.baseUrl);return options?.visibility&&url.searchParams.set("visibility",options.visibility),this.request(`${url.pathname}${url.search}`)}async setAdminLightAppLibraryVisibility(libraryId,payload){return this.request(`/api/admin/light-app-library/libraries/${encodeURIComponent(libraryId)}/visibility`,{method:"POST",body:JSON.stringify(payload)})}async listLightAppLibraryEntries(options){let url=new URL("/api/tenant/light-app-library/entries",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.status&&url.searchParams.set("status",options.status),options?.template_key&&url.searchParams.set("template_key",options.template_key),options?.tag&&url.searchParams.set("tag",options.tag),options?.visibility&&url.searchParams.set("visibility",options.visibility),typeof options?.include_public=="boolean"&&url.searchParams.set("include_public",String(options.include_public)),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntries(query){let url=new URL("/api/tenant/light-app-library/entries/search",this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async getLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`)}async createLightAppLibraryEntry(payload){return this.request("/api/tenant/light-app-library/entries",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppLibraryEntry(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async submitLightAppLibraryEntrySnapshot(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/snapshots`,{method:"POST",body:JSON.stringify(payload)})}async publishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/publish`,{method:"POST"})}async unpublishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/unpublish`,{method:"POST"})}async archiveLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/archive`,{method:"POST"})}async deleteLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async getLightAppLibraryEntrySource(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source`)}async readLightAppLibraryEntrySourceFile(entryId,path3){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/files`,this.options.baseUrl);return url.searchParams.set("path",path3),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntrySource(entryId,query){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/search`,this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async listLightAppPrototypeEntries(options){let url=new URL("/api/tenant/prototypes",this.options.baseUrl);return options?.q&&url.searchParams.set("q",options.q),options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async getLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`)}async createLightAppPrototypeEntry(payload){return this.request("/api/tenant/prototypes",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppPrototypeEntry(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async copyLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/copy`,{method:"POST"})}async deleteLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async saveLightAppPrototypeCurrentVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/current-version`,{method:"PUT",body:JSON.stringify(payload)})}async submitLightAppPrototypeVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions`,{method:"POST",body:JSON.stringify(payload)})}async getLightAppPrototypeVersion(entryId,versionId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions/${encodeURIComponent(versionId)}`)}async deleteTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"DELETE"})}async getTenantAppDeletePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/delete-preview`,{method:"POST"})}async getTenantAppDeleteJob(jobId){return this.request(`/api/tenant/app-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppUndeployPreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy-preview`,{method:"POST"})}async undeployTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy`,{method:"POST"})}async getTenantAppUndeployJob(jobId){return this.request(`/api/tenant/app-undeploy-jobs/${encodeURIComponent(jobId)}`)}async createBuild(payload){return this.request("/api/builds",{method:"POST",body:JSON.stringify(payload)})}async listBuilds(appId,options){let url=new URL("/api/builds",this.options.baseUrl);return url.searchParams.set("app_id",appId),typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getBuildPrecheck(appId,args){let url=new URL("/api/builds/precheck",this.options.baseUrl);return url.searchParams.set("app_id",appId),url.searchParams.set("source_version_id",args.source_version_id),args.build_config?.dockerfile_path&&url.searchParams.set("dockerfile_path",args.build_config.dockerfile_path),args.build_config?.context_subdir&&url.searchParams.set("context_subdir",args.build_config.context_subdir),args.build_config?.target&&url.searchParams.set("target",args.build_config.target),this.request(`${url.pathname}${url.search}`)}async getBuild(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}`)}async listBuildEvents(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}/events`)}async createLocalBuildSession(payload){return this.request("/api/builds/local-sessions",{method:"POST",body:JSON.stringify(payload)})}async completeLocalBuildSession(buildId,payload){return this.request(`/api/builds/${encodeURIComponent(buildId)}/local-complete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceWorkspace(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/source-workspace`,this.options.baseUrl);return options?.sourceVersionId&&url.searchParams.set("source_version_id",options.sourceVersionId),this.request(`${url.pathname}${url.search}`)}async getTenantAppDevWorkspace(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace`)}async pushTenantAppDevWorkspace(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/push`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)})}async createTenantAppDevWorkspacePreview(appId,payload={}){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDevWorkspacePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`)}async listTenantAppSourceVersions(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`)}async updateTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async getTenantAppEndUserAuthConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/config`)}async getTenantAppEndUserAuthDiscovery(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/discovery`)}async getTenantAppEndUserAuthInspect(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/inspect`)}async configureTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/configure`,{method:"POST",body:JSON.stringify(payload)})}async bindTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/bind`,{method:"POST",body:JSON.stringify(payload)})}async listTenantAppEndUsers(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users`)}async listTenantAppEndUserRoles(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`)}async createTenantAppEndUserRole(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppEndUserRole(appId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`)}async updateTenantAppEndUserRole(appId,roleKey,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAppUserRoles(appId,appUserId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`)}async assignTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles:assign`,{method:"POST",body:JSON.stringify(payload)})}async replaceTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`,{method:"PUT",body:JSON.stringify(payload)})}async removeTenantAppUserRole(appId,appUserId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles/${encodeURIComponent(roleKey)}`,{method:"DELETE"})}async discoverTenantCmsCollection(collection){let url=new URL("/api/tenant/cms/discover",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsCollections(){return this.request("/api/tenant/cms/collections")}async inspectTenantCmsSchema(collection){let url=new URL("/api/tenant/cms/inspect/schema",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsItems(args){let url=new URL("/api/tenant/cms/items",this.options.baseUrl);return url.searchParams.set("collection",args.collection),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"status",args.status),setOptionalSearchParam(url,"q",args.query),this.request(`${url.pathname}${url.search}`)}async getTenantCmsItem(args){let url=new URL(`/api/tenant/cms/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("collection",args.collection),this.request(`${url.pathname}${url.search}`)}async configureTenantCmsCollection(spec){return this.request("/api/tenant/cms/configure/collection",{method:"POST",body:JSON.stringify(spec)})}async configureTenantCmsItem(payload){return this.request("/api/tenant/cms/configure/item",{method:"POST",body:JSON.stringify(payload)})}async configureTenantCmsCategory(payload){return this.request("/api/tenant/cms/configure/category",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsSchema(payload){return this.request("/api/tenant/cms/apply/schema",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsCollectionStatus(payload){return this.request("/api/tenant/cms/apply/collection-status",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsPublish(payload){return this.request("/api/tenant/cms/apply/publish",{method:"POST",body:JSON.stringify(payload)})}async listPublicCmsItems(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items`,this.options.baseUrl);url.searchParams.set("tenant_id",args.tenantId),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"sort_field",args.sortField),setOptionalSearchParam(url,"sort_direction",args.sortDirection);for(let tag of args.tags??[])url.searchParams.append("tag",tag);return this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemBySlug(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/by-slug/${encodeURIComponent(args.slug)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemById(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listPublicCmsCategories(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/categories`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listTenantAppDeploymentTimeline(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/deployments`,this.options.baseUrl);return typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAppPublishSettings(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`)}async updateTenantAppPublishSettings(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`,{method:"PATCH",body:JSON.stringify(payload)})}async setTenantAppCurrentPublishedVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings/current-version`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppPreview(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/previews`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersionFromTemplate(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions:from-template`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppReleaseDeletePreview(appId,releaseId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete-preview`,{method:"POST"})}async deleteTenantAppRelease(appId,releaseId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceVersionDeletePreview(appId,sourceVersionId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete-preview`,{method:"POST"})}async deleteTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantVersionDeleteJob(jobId){return this.request(`/api/tenant/version-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppBuildDeletePreview(appId,buildId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete-preview`,{method:"POST"})}async deleteTenantAppBuild(appId,buildId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDbInstance(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbRuntimeBindings(appId,env="preview",purpose){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/runtime-bindings`,this.options.baseUrl);return url.searchParams.set("env",env),purpose&&url.searchParams.set("purpose",purpose),this.requestUrl(url)}async resolveDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/resolve",{method:"POST",body:JSON.stringify(payload)})}async revokeDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/revoke",{method:"POST",body:JSON.stringify(payload)})}async listTenantAppDbTables(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableSchema(appId,tableName,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/schema`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableRows(appId,tableName,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.page=="number"&&url.searchParams.set("page",String(args.page)),typeof args.page_size=="number"&&url.searchParams.set("page_size",String(args.page_size)),typeof args.sort_by=="string"&&args.sort_by.trim().length>0&&url.searchParams.set("sort_by",args.sort_by),args.sort_order==="desc"&&url.searchParams.set("sort_order","desc"),typeof args.filter_column=="string"&&args.filter_column.trim().length>0&&url.searchParams.set("filter_column",args.filter_column),typeof args.filter_value=="string"&&args.filter_value.length>0&&url.searchParams.set("filter_value",args.filter_value),typeof args.search_query=="string"&&args.search_query.trim().length>0&&url.searchParams.set("search_query",args.search_query),this.requestUrl(url)}async listTenantAppDbMigrationRuns(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/migrations`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async listTenantAppDbChangeAudits(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/audits`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.table_name=="string"&&args.table_name.trim().length>0&&url.searchParams.set("table_name",args.table_name),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async insertTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"POST",body:JSON.stringify(payload)})}async updateTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"DELETE",body:JSON.stringify(payload)})}async queryTenantAppDb(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/query`,{method:"POST",body:JSON.stringify(payload)})}async createWorkspace(payload){return this.request("/api/admin/workspaces",{method:"POST",body:JSON.stringify(payload)})}async deleteWorkspace(workspaceId,payload){return this.request(`/api/admin/workspaces/${encodeURIComponent(workspaceId)}`,{method:"DELETE",...payload?{body:JSON.stringify(payload)}:{}})}async createApproval(payload){return this.request("/api/admin/resource-approvals",{method:"POST",body:JSON.stringify(payload)})}async listApprovals(filters){let url=new URL("/api/admin/resource-approvals",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.status&&url.searchParams.set("status",filters.status),filters?.operation&&url.searchParams.set("operation",filters.operation),this.requestUrl(url)}async decideApproval(approvalId,payload){return this.request(`/api/admin/resource-approvals/${approvalId}/decision`,{method:"POST",body:JSON.stringify(payload)})}async listResourceLocks(filters){let url=new URL("/api/admin/resource-locks",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.env&&url.searchParams.set("env",filters.env),this.requestUrl(url)}async diffResources(payload){return this.request("/api/resources/diff",{method:"POST",body:JSON.stringify(payload)})}async applyResources(payload){return this.request("/api/resources/apply",{method:"POST",body:JSON.stringify(payload)})}async rollbackResources(payload){return this.request("/api/resources/rollback",{method:"POST",body:JSON.stringify(payload)})}async deployRelease(payload){return this.request("/api/releases/deploy",{method:"POST",body:JSON.stringify(payload)})}async rollbackRelease(payload){return this.request("/api/releases/rollback",{method:"POST",body:JSON.stringify(payload)})}async queryLogs(payload){return this.request("/api/logs/query",{method:"POST",body:JSON.stringify(payload)})}};function setOptionalSearchParam(url,key,value){typeof value=="string"&&value.trim().length>0&&url.searchParams.set(key,value)}function setOptionalBooleanSearchParam(url,key,value){typeof value=="boolean"&&url.searchParams.set(key,value?"true":"false")}function resolveRelativeOrAbsoluteUrl(pathOrUrl,baseUrl){return new URL(pathOrUrl,baseUrl)}function createPlatformSdk(options){return new PlatformSdk(options)}var NotificationSdkNamespace=class{sdk;endUser;constructor(sdk){this.sdk=sdk,this.endUser=new EndUserNotificationNamespace(sdk)}},EndUserNotificationNamespace=class{sdk;constructor(sdk){this.sdk=sdk}forApp(appId){return new EndUserNotificationAppClient(this.sdk,appId)}},EndUserNotificationAppClient=class{sdk;appId;announcements;constructor(sdk,appId){this.sdk=sdk,this.appId=appId,this.announcements=new EndUserNotificationAppAnnouncementsClient(sdk,appId)}listUsers(){return this.sdk.listTenantAppEndUsers(this.appId)}forUser(endUserId){return new EndUserNotificationUserClient(this.sdk,this.appId,endUserId)}listInbox(endUserId,query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:endUserId,...query})}getUnreadCount(endUserId){return this.sdk.getEndUserNotificationUnreadCount(this.appId,endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,input.end_user_id),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,input.end_user_id)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,input.end_user_id)})}},EndUserNotificationAppAnnouncementsClient=class{sdk;appId;constructor(sdk,appId){this.sdk=sdk,this.appId=appId}getConfig(){return this.sdk.getAppNotificationConfig(this.appId)}list(limit){return this.sdk.listAppNotificationAnnouncements(this.appId,{limit})}create(input){return this.sdk.createAppNotificationAnnouncement(this.appId,input)}archive(announcementId){return this.sdk.archiveAppNotificationAnnouncement(this.appId,announcementId)}},EndUserNotificationUserClient=class{sdk;appId;endUserId;constructor(sdk,appId,endUserId){this.sdk=sdk,this.appId=appId,this.endUserId=endUserId}buildRecipientRef(){return buildDirectEndUserRecipientRef(this.appId,this.endUserId)}listInbox(query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:this.endUserId,...query})}getUnreadCount(){return this.sdk.getEndUserNotificationUnreadCount(this.appId,this.endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:this.buildRecipientRef(),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,this.endUserId),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:this.buildRecipientRef(),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,this.endUserId)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:this.buildRecipientRef(),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,this.endUserId)})}};function buildDirectEndUserRecipientRef(appId,endUserId){return{app_id:appId,end_user_id:endUserId,recipient_type:"direct_user"}}function buildNotificationIdempotencyKey(prefix,appId,endUserId){return`${prefix}:${appId}:${endUserId}:${Date.now()}`}var AUTH_PAGE_HTML=String.raw`<!doctype html>
|
|
3
3
|
<html lang="zh-CN">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
@@ -2121,7 +2121,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2121
2121
|
}
|
|
2122
2122
|
return "/";
|
|
2123
2123
|
}
|
|
2124
|
-
`}import{existsSync,readdirSync,readFileSync
|
|
2124
|
+
`}import{existsSync,lstatSync,readdirSync,readFileSync}from"node:fs";import{createRequire}from"node:module";import{dirname,resolve,posix as pathPosix2}from"node:path";import{fileURLToPath}from"node:url";function resolveRuntimeSdkDistDirForTest({workspaceCandidates,exists,isDirectory,resolvePackageEntrypoint}){let workspaceDir=workspaceCandidates.find(candidate=>exists(candidate)&&isDirectory(candidate));if(workspaceDir)return workspaceDir;try{let runtimeSdkEntrypoint=resolvePackageEntrypoint(),packagedDir=dirname(runtimeSdkEntrypoint);if(exists(packagedDir)&&isDirectory(packagedDir))return packagedDir}catch{}throw new Error(`Missing runtime-sdk dist directory for template vendor scaffold. Checked ${workspaceCandidates.map(candidate=>resolve(candidate)).join(", ")} and package entrypoint @platform/runtime-sdk.`)}function resolveRuntimeSdkDistDir(){let require2=createRequire(import.meta.url),workspaceCandidates=[new URL("../runtime-sdk/dist/",import.meta.url),new URL("../../../../runtime-sdk/dist/",import.meta.url),new URL("../../../../../runtime-sdk/dist/",import.meta.url)].map(candidate=>fileURLToPath(candidate));return resolveRuntimeSdkDistDirForTest({workspaceCandidates,exists:existsSync,isDirectory:path3=>{let stats=lstatSync(path3);return stats.isDirectory()&&!stats.isSymbolicLink()},resolvePackageEntrypoint:()=>require2.resolve("@platform/runtime-sdk")})}function collectRuntimeSdkDistFiles(dirPath,relativeDir=""){let directoryStats=lstatSync(dirPath);if(!directoryStats.isDirectory()||directoryStats.isSymbolicLink())throw new Error(`Refusing non-directory runtime-sdk vendor root: ${dirPath}`);let entries=readdirSync(dirPath,{withFileTypes:!0}).sort((a,b)=>a.name.localeCompare(b.name)),files=[];for(let entry of entries){let nextRelativePath=relativeDir?`${relativeDir}/${entry.name}`:entry.name,entryPath=resolve(dirPath,entry.name);if(entry.isDirectory()){files.push(...collectRuntimeSdkDistFiles(entryPath,nextRelativePath));continue}if(!entry.isFile()||entry.isSymbolicLink())throw new Error(`Refusing non-regular runtime-sdk vendor entry: ${entryPath}`);entry.name.includes(".test.")||/\.(?:js|d\.ts)$/u.test(entry.name)&&files.push({path:nextRelativePath,content:readFileSync(entryPath,"utf8")})}return files}function buildVendorRoot(prefix){let normalizedPrefix=prefix.replace(/^\/+|\/+$/gu,""),prefixDir=normalizedPrefix.includes("/")?pathPosix2.dirname(normalizedPrefix):normalizedPrefix;return prefixDir==="."?"vendor/runtime-sdk":`${prefixDir}/vendor/runtime-sdk`}function buildRuntimeSdkVendorFiles(prefix){let vendorRoot=buildVendorRoot(prefix);return collectRuntimeSdkDistFiles(resolveRuntimeSdkDistDir()).map(file=>({path:`${vendorRoot}/${file.path}`,content:file.content}))}function buildPrefixedPath3(prefix,relativePath){return`${prefix.replace(/\/+$/u,"")}/${relativePath}`}function readTemplateBlockSource(relativePath){let fileUrl=[new URL(`../template-blocks/${relativePath}`,import.meta.url),new URL(`../../template-blocks/${relativePath}`,import.meta.url),new URL(`../../../src/template-blocks/${relativePath}`,import.meta.url)].find(candidate=>existsSync2(candidate));if(!fileUrl)throw new Error(`Missing template block source for ${relativePath}`);return readFileSync2(fileUrl,"utf8")}function scaffoldTemplateBlock(relativePath,outputPath){return relativePath==="contract/route-path-patterns.ts"?{path:outputPath,content:buildRoutePathPatternsSource()}:{path:outputPath,content:readTemplateBlockSource(relativePath)}}function buildWebSharedPlatformFiles(prefix,builders){let platformPrefix=buildPrefixedPath3(prefix,"platform");return[...buildRuntimeSdkVendorFiles(prefix),scaffoldTemplateBlock("contract/capabilities.ts",`${platformPrefix}/contract/capabilities.ts`),scaffoldTemplateBlock("contract/runtime-config.ts",`${platformPrefix}/contract/runtime-config.ts`),scaffoldTemplateBlock("contract/path-builders.ts",`${platformPrefix}/contract/path-builders.ts`),scaffoldTemplateBlock("protocol/auth-routes.ts",`${platformPrefix}/protocol/auth-routes.ts`),scaffoldTemplateBlock("protocol/public-app-routes.ts",`${platformPrefix}/protocol/public-app-routes.ts`),scaffoldTemplateBlock("protocol/cms-routes.ts",`${platformPrefix}/protocol/cms-routes.ts`),scaffoldTemplateBlock("protocol/route-map.ts",`${platformPrefix}/protocol/route-map.ts`),scaffoldTemplateBlock("dev-support/vite/runtime-config.ts",`${platformPrefix}/dev/vite/runtime-config.ts`),scaffoldTemplateBlock("dev-support/vite/auth-shell.ts",`${platformPrefix}/dev/vite/auth-shell.ts`),scaffoldTemplateBlock("dev-support/vite/proxy.ts",`${platformPrefix}/dev/vite/proxy.ts`),{path:`${platformPrefix}/config.ts`,content:builders.buildPlatformConfigSource()},{path:`${platformPrefix}/client.ts`,content:builders.buildPlatformClientSource(prefix)},{path:`${platformPrefix}/errors.ts`,content:builders.buildPlatformErrorsSource()},{path:`${platformPrefix}/capabilities/index.ts`,content:builders.buildCapabilitiesIndexSource()},{path:`${platformPrefix}/capabilities/auth.ts`,content:builders.buildCapabilitySource("auth",prefix)},{path:`${platformPrefix}/capabilities/workflow.ts`,content:builders.buildCapabilitySource("workflow",prefix)},{path:`${platformPrefix}/capabilities/cms.ts`,content:builders.buildCapabilitySource("cms",prefix)},{path:`${platformPrefix}/capabilities/blob.ts`,content:builders.buildCapabilitySource("blob",prefix)},{path:`${platformPrefix}/capabilities/data-form.ts`,content:builders.buildCapabilitySource("data-form",prefix)}]}import{posix as pathPosix3}from"node:path";function buildPlatformConfigSource(){return['import { getRuntimeConfig, type PlatformRuntimeConfig } from "./contract/runtime-config";',"","export type FrontendPlatformConfig = PlatformRuntimeConfig;","","export function getPlatformConfig(): FrontendPlatformConfig {"," return getRuntimeConfig();","}",""].join(`
|
|
2125
2125
|
`)}function buildVendorRuntimeImport2(prefix,fromRelativeDir,runtimeSdkPath){let normalizedPrefix=prefix.replace(/^\/+|\/+$/gu,""),vendorBase=normalizedPrefix.includes("/")?pathPosix3.join(pathPosix3.dirname(normalizedPrefix),"vendor/runtime-sdk"):pathPosix3.join(normalizedPrefix,"vendor/runtime-sdk"),fromDir=pathPosix3.join(normalizedPrefix,fromRelativeDir),relativePath=pathPosix3.relative(fromDir,pathPosix3.join(vendorBase,runtimeSdkPath));return relativePath.startsWith(".")?relativePath:`./${relativePath}`}function buildPlatformClientSource(prefix="src"){return[`import { createBrowserRuntimeApp } from "${buildVendorRuntimeImport2(prefix,"platform","browser.js")}";`,'import { buildPlatformAbsoluteUrl as buildPlatformAbsoluteUrlFromContract, buildPlatformAuthPath as buildPlatformAuthPathFromContract, buildPlatformPath as buildPlatformPathFromContract } from "./contract/path-builders";','import { getPlatformConfig } from "./config";','import { PlatformRuntimeUnavailableError } from "./errors";',"","let runtimeApp: ReturnType<typeof createBrowserRuntimeApp> | null = null;","",'export function buildPlatformPath(path = "/") {'," return buildPlatformPathFromContract(getPlatformConfig(), path);","}","",'export function buildPlatformAbsoluteUrl(path = "/") {'," return buildPlatformAbsoluteUrlFromContract(getPlatformConfig(), path);","}","","export function buildPlatformAuthPath() {"," return buildPlatformAuthPathFromContract(getPlatformConfig());","}","","export function getPlatformRuntimeContext() {"," return getPlatformConfig();","}","","export { getPlatformConfig };","","export function hasPlatformRuntimeBinding() {"," return Boolean(getPlatformRuntimeContext().appId);","}","","export function getPlatformRuntimeApp() {"," if (runtimeApp) {"," return runtimeApp;"," }"," const config = getPlatformRuntimeContext();"," if (!config.appId) {",' throw new PlatformRuntimeUnavailableError("platform appId is not available in current location context");'," }"," runtimeApp = createBrowserRuntimeApp({",' baseUrl: buildPlatformAbsoluteUrl("/"),'," appId: config.appId,"," env: config.env || undefined,"," authPath: buildPlatformAuthPath(),"," sessionOptions: { authPath: buildPlatformAuthPath() },"," });"," return runtimeApp;","}","","export function tryGetPlatformRuntimeApp() {"," return hasPlatformRuntimeBinding() ? getPlatformRuntimeApp() : null;","}",""].join(`
|
|
2126
2126
|
`)}function buildPlatformErrorsSource(){return["export class PlatformRuntimeUnavailableError extends Error {",' constructor(message = "platform runtime is not available in current location context") {'," super(message);",' this.name = "PlatformRuntimeUnavailableError";'," }","}","",'export function getPlatformCapabilityErrorMessage(error: unknown, fallback = "\u5E73\u53F0\u80FD\u529B\u6682\u4E0D\u53EF\u7528\u3002") {'," if (error instanceof PlatformRuntimeUnavailableError) {"," return error.message;"," }"," if (error instanceof Error && error.message.trim()) {"," return error.message;"," }"," return fallback;","}",""].join(`
|
|
2127
2127
|
`)}function buildCapabilitySource(kind,prefix="src"){return kind==="auth"?[`import { createBrowserSessionStore } from "${buildVendorRuntimeImport2(prefix,"platform/capabilities","browser.js")}";`,'import { buildPlatformAbsoluteUrl, buildPlatformAuthPath, buildPlatformPath, getPlatformRuntimeApp, getPlatformRuntimeContext, hasPlatformRuntimeBinding } from "../client";',"","type AuthUiConfig = {"," auth_enabled: boolean;"," sign_in_methods: Array<{ method: string; label: string }>;"," default_method?: string;","};","","type StartEmailMagicLinkResult =",' | { next_action: "wait_for_verification"; masked_target: string; magic_link_url?: string }',' | { next_action: "registration_blocked"; message: string };',"","function buildSameOriginAuthEndpoint(path: string) {",' const normalizedPath = path.startsWith("/") ? path : `/${path}`;'," return buildPlatformAbsoluteUrl(`/api/auth${normalizedPath}`);","}","","async function requestPublicAuth<T>(path: string, init?: RequestInit): Promise<T> {"," const response = await fetch(buildSameOriginAuthEndpoint(path), {",' credentials: "include",'," ...init,"," headers: {",' "Content-Type": "application/json",'," ...(init?.headers ?? {}),"," },"," });"," if (!response.ok) {"," let message = `Request failed: ${response.status}`;"," try {"," const payload = (await response.json()) as { error?: { message?: string } };"," if (payload.error?.message) {"," message = payload.error.message;"," }"," } catch {}"," throw new Error(message);"," }"," return (await response.json()) as T;","}","","export async function getCurrentEndUser() {"," return getPlatformRuntimeApp().getCurrentEndUser();","}","","export async function getCurrentEndUserRoles() {"," return getPlatformRuntimeApp().getCurrentEndUserRoles();","}","","function getSessionStore() {"," return createBrowserSessionStore({ authPath: buildPlatformAuthPath() });","}","","export function saveEndUserSessionToken(token: string) {"," getSessionStore().writeToken(token);","}","","export function clearEndUserSessionToken() {"," getSessionStore().clearToken();","}","","export function hasEndUserSessionToken() {"," return Boolean(getSessionStore().readToken());","}","","export function readEndUserSessionToken() {"," return getSessionStore().readToken();","}","","export async function getEndUserSessionState() {"," try {"," const endUser = await getCurrentEndUser();"," const access = getPlatformRuntimeApp().resolveAccess(endUser);",' return { signedIn: access.kind === "ready", endUser, access };'," } catch {"," return { signedIn: false, endUser: null, access: null };"," }","}","","export async function getAuthUiConfig() {",' return requestPublicAuth<AuthUiConfig>("/ui-config", { method: "GET" });',"}","","export async function startEmailMagicLinkSignIn(args: { email: string; redirectUri?: string }) {",' return requestPublicAuth<StartEmailMagicLinkResult>("/sign-in/email_magic_link/start", {',' method: "POST",'," body: JSON.stringify({"," email: args.email,"," redirect_uri: args.redirectUri,"," }),"," });","}","","export async function signInWithPassword(args: { email: string; password: string }) {",' const result = await requestPublicAuth<{ session_token: string }>("/sign-in/admin_provisioned_password/start", {',' method: "POST",'," body: JSON.stringify(args),"," });"," if (result.session_token) {"," saveEndUserSessionToken(result.session_token);"," }"," return result;","}","","export async function completeEmailMagicLinkSignIn(token: string) {",' const url = new URL(buildSameOriginAuthEndpoint("/callback/email_magic_link"));',' url.searchParams.set("token", token);'," const response = await fetch(url.toString(), {",' method: "GET",',' credentials: "include",'," });"," if (!response.ok) {"," let message = `Request failed: ${response.status}`;"," try {"," const payload = (await response.json()) as { error?: { message?: string } };"," if (payload.error?.message) {"," message = payload.error.message;"," }"," } catch {}"," throw new Error(message);"," }"," const result = (await response.json()) as { session_token?: string };"," if (result.session_token) {"," saveEndUserSessionToken(result.session_token);"," }"," return result;","}","",'export function buildSignInHref(returnTo = "/app") {'," return getPlatformRuntimeApp().buildSignInUrl(returnTo);","}","","async function requestSameOriginSignOut(sessionToken: string) {",' const response = await fetch(buildSameOriginAuthEndpoint("/sign-out"), {',' method: "POST",',' credentials: "include",'," headers: {",' "Content-Type": "application/json",'," },"," body: JSON.stringify({ session_token: sessionToken })"," });"," if (response.ok) {"," return;"," }"," let message = `Request failed: ${response.status}`;"," try {"," const payload = (await response.json()) as { error?: { message?: string } };"," if (payload.error?.message) {"," message = payload.error.message;"," }"," } catch {}"," throw new Error(message);","}","","export async function signOutEndUser() {"," const sessionToken = readEndUserSessionToken();"," if (sessionToken) {"," try {"," await requestSameOriginSignOut(sessionToken);"," } finally {"," clearEndUserSessionToken();"," }"," return;"," }"," if (!hasPlatformRuntimeBinding()) {"," clearEndUserSessionToken();"," return;"," }"," await getPlatformRuntimeApp().signOut();","}","","export async function ensureEndUserAuthenticated(args: { returnTo?: string; redirectToSignIn?: boolean } = {}) {"," return getPlatformRuntimeApp().ensureAuthenticated(args);","}","","export function getAuthCapabilityState() {"," return {"," ready: hasPlatformRuntimeBinding(),"," mode: getPlatformRuntimeContext().mode,"," };","}",""].join(`
|
|
@@ -2139,14 +2139,14 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2139
2139
|
`)}function buildProtectedPageSource(){return['import React from "react";','import { ensureEndUserAuthenticated, getAuthCapabilityState, getCurrentEndUserRoles, signOutEndUser } from "../platform/capabilities/auth";','import { buildPlatformPath } from "../platform/client";','import { getPlatformCapabilityErrorMessage } from "../platform/errors";',"",'type AuthState = "loading" | "ready" | "error";',"","export function ProtectedPage() {"," const authCapability = getAuthCapabilityState();",' const [authState, setAuthState] = React.useState<AuthState>("loading");'," const [authError, setAuthError] = React.useState<string | null>(null);"," const [currentEndUser, setCurrentEndUser] = React.useState<Awaited<ReturnType<typeof ensureEndUserAuthenticated>> | null>(null);"," const [currentRoles, setCurrentRoles] = React.useState<Awaited<ReturnType<typeof getCurrentEndUserRoles>>>([]);",""," React.useEffect(() => {"," let cancelled = false;"," async function loadProtectedState() {",' setAuthState("loading");'," setAuthError(null);"," try {",' const endUser = await ensureEndUserAuthenticated({ returnTo: "/protected", redirectToSignIn: true });'," if (!endUser || cancelled) {"," return;"," }"," const roles = await getCurrentEndUserRoles();"," if (cancelled) {"," return;"," }"," setCurrentEndUser(endUser);"," setCurrentRoles(roles);",' setAuthState("ready");'," } catch (error) {"," if (cancelled) {"," return;"," }",' setAuthState("error");',' setAuthError(getPlatformCapabilityErrorMessage(error, "\u4FDD\u62A4\u9875\u767B\u5F55\u6001\u8BFB\u53D6\u5931\u8D25\u3002"));'," }"," }"," void loadProtectedState();"," return () => {"," cancelled = true;"," };"," }, []);",""," const handleSignOut = React.useCallback(async () => {"," try {"," await signOutEndUser();"," } finally {",' window.location.assign(buildPlatformPath("/app"));'," }"," }, []);",""," return (",' <main className="min-h-screen bg-slate-950 text-slate-50">',' <section className="mx-auto flex min-h-screen max-w-4xl flex-col justify-center gap-8 px-6 py-16">',' <a href={buildPlatformPath("/app")} className="text-sm text-slate-400 underline-offset-4 hover:text-slate-200 hover:underline">\u8FD4\u56DE\u9996\u9875</a>',' <div className="space-y-4">',' <div className="inline-flex w-fit rounded-full border border-sky-400/30 bg-sky-400/10 px-3 py-1 text-xs font-medium tracking-wide text-sky-200">\u4FDD\u62A4\u9875</div>',' <h1 className="text-4xl font-semibold tracking-tight sm:text-5xl">\u9700\u767B\u5F55\u9875\u9762\u9AA8\u67B6</h1>',' <p className="max-w-2xl text-sm leading-7 text-slate-300 sm:text-base">'," \u8FD9\u662F\u4E00\u4E2A\u767B\u5F55\u540E\u624D\u80FD\u8BBF\u95EE\u7684\u9875\u9762\u793A\u4F8B\u3002\u5F53\u524D\u4F1A\u81EA\u52A8\u663E\u793A\u5F53\u524D\u7528\u6237\u548C\u89D2\u8272\uFF0C\u540E\u7EED\u53EF\u4EE5\u76F4\u63A5\u66FF\u6362\u6210\u4F60\u7684\u6B63\u5F0F\u4E1A\u52A1\u9875\u9762\u3002"," </p>"," </div>",' <div className="rounded-3xl border border-white/10 bg-slate-900/70 p-6">',' <div className="flex flex-wrap items-center gap-3">',' <button type="button" className="rounded-full bg-white px-4 py-2 text-sm font-medium text-slate-950 transition hover:bg-slate-200 disabled:cursor-not-allowed disabled:bg-slate-700 disabled:text-slate-300" disabled={authState === "loading"} onClick={() => void handleSignOut()}>\u9000\u51FA\u767B\u5F55</button>',' <span className={`rounded-full border px-2.5 py-1 text-[11px] font-medium ${authCapability.ready ? "border-emerald-400/30 bg-emerald-400/10 text-emerald-200" : "border-amber-400/30 bg-amber-400/10 text-amber-100"}`}>{authCapability.ready ? "\u5E73\u53F0\u4E0A\u4E0B\u6587\u53EF\u7528" : "\u5F53\u524D\u4E3A standalone / \u672A\u7ED1\u5B9A"}</span>'," </div>",' <div className="mt-5 rounded-2xl border border-white/10 bg-black/20 p-4">',' {authError ? <p className="text-sm text-rose-300">{authError}</p> : null}',' {!authError && authState === "loading" ? <p className="text-sm text-slate-400">\u6B63\u5728\u6821\u9A8C\u767B\u5F55\u6001\u5E76\u52A0\u8F7D\u5F53\u524D\u7528\u6237\u4FE1\u606F...</p> : null}',' {!authError && authState === "ready" ? (',' <div className="space-y-3 text-sm text-slate-200">',' <div><div className="text-xs text-slate-500">\u7528\u6237 ID</div><div className="mt-1 break-all font-mono text-[13px]">{currentEndUser?.app_user?.app_user_id || currentEndUser?.identity?.identity_id || "\u672A\u767B\u5F55 / \u672A\u8FD4\u56DE"}</div></div>',' <div><div className="text-xs text-slate-500">\u663E\u793A\u540D\u79F0</div><div className="mt-1">{currentEndUser?.app_user?.display_name || currentEndUser?.identity?.email || currentEndUser?.identity?.phone || "\u672A\u767B\u5F55 / \u672A\u8FD4\u56DE"}</div></div>',' <div><div className="text-xs text-slate-500">\u89D2\u8272\u5217\u8868</div><div className="mt-2 flex flex-wrap gap-2">{currentRoles.length > 0 ? currentRoles.map((role: Awaited<ReturnType<typeof getCurrentEndUserRoles>>[number]) => <span key={role.role_key} className="rounded-full border border-sky-400/30 bg-sky-400/10 px-2.5 py-1 text-xs text-sky-100">{role.display_name || role.role_key}</span>) : <span className="text-sm text-slate-400">\u6682\u65E0\u89D2\u8272\u6216\u5F53\u524D\u672A\u767B\u5F55\u3002</span>}</div></div>'," </div>"," ) : null}"," </div>"," </div>"," </section>"," </main>"," );","}",""].join(`
|
|
2140
2140
|
`)}function buildCmsPageSource(){return['import React from "react";','import { getCmsCapabilityState, getCurrentAppCmsCollectionMeta, listCurrentAppCmsCollections, listCurrentAppCmsItems, resolveCmsItemCategoryName, resolveCmsItemTagLabels, resolveCurrentAppCmsTenantId } from "../platform/capabilities/cms";','import { buildPlatformPath, getPlatformConfig, getPlatformRuntimeApp } from "../platform/client";','import { getPlatformCapabilityErrorMessage } from "../platform/errors";',"",'type CmsState = "idle" | "loading" | "ready" | "error";','type CmsCollection = Awaited<ReturnType<typeof listCurrentAppCmsCollections>>["items"][number];',"type CmsCollectionMeta = Awaited<ReturnType<typeof getCurrentAppCmsCollectionMeta>>;",'type CmsItem = Awaited<ReturnType<typeof listCurrentAppCmsItems>>["items"][number];',"","function pickCmsTitle(item: CmsItem): string {",' if (typeof item.presentation?.title === "string" && item.presentation.title.trim()) {'," return item.presentation.title.trim();"," }"," const contentTitle = item.content?.title;",' if (typeof contentTitle === "string" && contentTitle.trim()) {'," return contentTitle.trim();"," }",' return item.system.slug || item.system.id || "\u672A\u547D\u540D\u5185\u5BB9";',"}","","function pickCmsSummary(item: CmsItem): string | null {",' if (typeof item.presentation?.summary === "string" && item.presentation.summary.trim()) {'," return item.presentation.summary.trim();"," }"," return null;","}","","function pickCmsCoverImageUrl(item: CmsItem): string | null {"," return getPlatformRuntimeApp().resolveCmsCoverImageUrl(item);","}","","function isSampleMode(cmsCapabilityReady: boolean, cmsTenantId: string, cmsCollections: CmsCollection[]): boolean {"," return !cmsCapabilityReady || !cmsTenantId.trim() || cmsCollections.length === 0;","}","","export function CmsPage() {"," const config = getPlatformConfig();"," const cmsCapability = getCmsCapabilityState();",' const [cmsState, setCmsState] = React.useState<CmsState>("idle");'," const [cmsError, setCmsError] = React.useState<string | null>(null);",' const [cmsTenantId, setCmsTenantId] = React.useState(config.tenantId || "");'," const [cmsCollections, setCmsCollections] = React.useState<CmsCollection[]>([]);"," const [cmsItems, setCmsItems] = React.useState<CmsItem[]>([]);"," const [cmsPrimaryCollection, setCmsPrimaryCollection] = React.useState<string | null>(null);"," const [cmsCollectionMeta, setCmsCollectionMeta] = React.useState<CmsCollectionMeta | null>(null);"," const [selectedItemId, setSelectedItemId] = React.useState<string | null>(null);",""," const loadCmsExample = React.useCallback(async () => {",' const tenantId = ((cmsTenantId || "").trim() || (await resolveCurrentAppCmsTenantId()).trim());'," if (!tenantId) {",' setCmsTenantId("");',' setCmsState("error");',' setCmsError("\u5F53\u524D\u672A\u62FF\u5230\u53EF\u7528 tenantId\uFF0C\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D CMS \u793A\u4F8B\u3002");'," return;"," }"," setCmsTenantId(tenantId);",' setCmsState("loading");'," setCmsError(null);"," try {"," const collectionsResult = await listCurrentAppCmsCollections();"," const collections = collectionsResult.items;"," setCmsCollections(collections);"," const firstCollection = collections[0]?.collection ?? null;"," setCmsPrimaryCollection(firstCollection);"," if (!firstCollection) {"," setCmsItems([]);"," setSelectedItemId(null);",' setCmsState("ready");'," return;"," }"," const [metaResult, itemsResult] = await Promise.all(["," getCurrentAppCmsCollectionMeta({ collection: firstCollection }),"," listCurrentAppCmsItems({ collection: firstCollection, page: 1, pageSize: 20 })"," ]);"," setCmsCollectionMeta(metaResult);"," setCmsItems(itemsResult.items);"," setSelectedItemId(itemsResult.items[0]?.system.id || itemsResult.items[0]?.system.slug || null);",' setCmsState("ready");'," } catch (error) {",' setCmsError(getPlatformCapabilityErrorMessage(error, "CMS \u793A\u4F8B\u8BF7\u6C42\u5931\u8D25\u3002"));',' setCmsState("error");'," }"," }, [cmsTenantId]);",""," React.useEffect(() => {"," if (!cmsCapability.ready) {"," return;"," }"," void loadCmsExample();"," }, [cmsCapability.ready, loadCmsExample]);",""," const selectedCollectionMeta = React.useMemo(() => cmsCollectionMeta, [cmsCollectionMeta]);"," const selectedItem = React.useMemo(() => cmsItems.find((item) => (item.system.id || item.system.slug) === selectedItemId) ?? cmsItems[0] ?? null, [cmsItems, selectedItemId]);"," const sampleMode = isSampleMode(cmsCapability.ready, cmsTenantId, cmsCollections);",""," const handleCollectionChange = React.useCallback(async (collectionName: string) => {",' const tenantId = ((cmsTenantId || "").trim() || (await resolveCurrentAppCmsTenantId()).trim());'," if (!tenantId) {",' setCmsTenantId("");',' setCmsError("\u5F53\u524D\u672A\u62FF\u5230\u53EF\u7528 tenantId\uFF0C\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D CMS \u793A\u4F8B\u3002");',' setCmsState("error");'," return;"," }"," setCmsTenantId(tenantId);",' setCmsState("loading");'," setCmsError(null);"," setCmsPrimaryCollection(collectionName);"," try {"," const [metaResult, itemsResult] = await Promise.all(["," getCurrentAppCmsCollectionMeta({ collection: collectionName }),"," listCurrentAppCmsItems({ collection: collectionName, page: 1, pageSize: 20 })"," ]);"," setCmsCollectionMeta(metaResult);"," setCmsItems(itemsResult.items);"," setSelectedItemId(itemsResult.items[0]?.system.id || itemsResult.items[0]?.system.slug || null);",' setCmsState("ready");'," } catch (error) {",' setCmsError(getPlatformCapabilityErrorMessage(error, "CMS \u5185\u5BB9\u52A0\u8F7D\u5931\u8D25\u3002"));',' setCmsState("error");'," }"," }, [cmsTenantId]);",""," return (",' <main className="min-h-screen bg-slate-950 text-slate-50">',' <section className="mx-auto flex min-h-screen max-w-6xl flex-col justify-center gap-8 px-6 py-16">',' <a href={buildPlatformPath("/app")} className="text-sm text-slate-400 underline-offset-4 hover:text-slate-200 hover:underline">\u8FD4\u56DE\u9996\u9875</a>',' <div className="space-y-4">',' <div className="flex flex-wrap items-center gap-3"><div className="inline-flex w-fit rounded-full border border-emerald-400/30 bg-emerald-400/10 px-3 py-1 text-xs font-medium tracking-wide text-emerald-200">CMS \u9875</div><span className={`rounded-full border px-3 py-1 text-xs font-medium ${sampleMode ? "border-amber-400/20 bg-amber-400/10 text-amber-100" : "border-emerald-400/20 bg-emerald-400/10 text-emerald-100"}`}>{sampleMode ? "\u5F53\u524D\u4E3A\u793A\u4F8B\u6A21\u5F0F" : "\u5F53\u524D\u4E3A\u771F\u5B9E\u8D44\u6E90\u6A21\u5F0F"}</span></div>',' <h1 className="text-4xl font-semibold tracking-tight sm:text-5xl">\u5185\u5BB9\u4E2D\u5FC3\u793A\u4F8B</h1>',' <p className="max-w-3xl text-sm leading-7 text-slate-300 sm:text-base">\u8FD9\u4E2A\u9875\u9762\u5C55\u793A\u5F53\u524D\u5E94\u7528\u53EF\u8BBF\u95EE\u7684\u5185\u5BB9\u5217\u8868\u4E0E\u8BE6\u60C5\u3002\u4F60\u53EF\u4EE5\u5728\u6B64\u57FA\u7840\u4E0A\u7EE7\u7EED\u505A\u5185\u5BB9\u5B98\u7F51\u3001\u5E2E\u52A9\u4E2D\u5FC3\u3001\u6D3B\u52A8\u9875\u6216\u8D44\u8BAF\u9875\u3002</p>'," </div>",' {sampleMode ? <div className="rounded-3xl border border-amber-400/20 bg-amber-400/10 p-5 text-sm leading-7 text-amber-50"><div className="font-medium">\u5F53\u524D\u5148\u5C55\u793A CMS \u9875\u9762\u9AA8\u67B6</div><div className="mt-2 text-amber-100/90">\u5982\u679C\u5F53\u524D app \u5C1A\u672A\u7ED1\u5B9A\u5185\u5BB9\u670D\u52A1\u3001\u672A\u6CE8\u5165 tenantId\uFF0C\u6216\u5F53\u524D\u79DF\u6237\u4E0B\u8FD8\u6CA1\u6709\u5185\u5BB9\u96C6\u5408\uFF0C\u8FD9\u4E00\u9875\u4F1A\u5148\u4FDD\u7559\u793A\u4F8B\u5E03\u5C40\uFF0C\u65B9\u4FBF\u5148\u8C03\u6574\u5BFC\u822A\u3001\u5361\u7247\u3001\u8BE6\u60C5\u533A\u548C\u6837\u5F0F\u3002\u63A5\u901A\u771F\u5B9E\u5185\u5BB9\u540E\uFF0C\u65E0\u9700\u91CD\u5199\u9875\u9762\u7ED3\u6784\u3002</div></div> : <div className="rounded-3xl border border-emerald-400/20 bg-emerald-400/10 p-5 text-sm leading-7 text-emerald-50"><div className="font-medium">\u5F53\u524D\u5DF2\u63A5\u5165\u771F\u5B9E CMS \u5185\u5BB9</div><div className="mt-2 text-emerald-100/90">\u9875\u9762\u6B63\u5728\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u7ED1\u5B9A\u7684\u5185\u5BB9\u96C6\u5408\u3001\u5217\u8868\u548C\u8BE6\u60C5\uFF0C\u53EF\u76F4\u63A5\u7EE7\u7EED\u6309\u771F\u5B9E\u6570\u636E\u7ED3\u6784\u6269\u5C55\u5C55\u793A\u3002</div></div>}',' <div className="rounded-3xl border border-white/10 bg-slate-900/70 p-6">',' <div className="flex items-start justify-between gap-4">',' <div className="space-y-1"><div className="text-sm font-semibold text-white">\u5F53\u524D\u5185\u5BB9\u6E90</div><p className="text-sm leading-6 text-slate-400">\u9875\u9762\u4F1A\u81EA\u52A8\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u7ED1\u5B9A\u7684\u5185\u5BB9\uFF0C\u4E0D\u518D\u63D0\u4F9B\u624B\u5DE5\u5207\u6362\u79DF\u6237\u5165\u53E3\uFF0C\u907F\u514D\u8BEF\u8BFB\u5230\u5176\u4ED6\u5185\u5BB9\u8303\u56F4\u3002</p></div>',' <span className={`rounded-full border px-2.5 py-1 text-[11px] font-medium ${cmsCapability.ready ? "border-emerald-400/30 bg-emerald-400/10 text-emerald-200" : "border-amber-400/30 bg-amber-400/10 text-amber-100"}`}>{cmsCapability.ready ? "\u5185\u5BB9\u670D\u52A1\u53EF\u7528" : "\u5F53\u524D\u672A\u8FDE\u63A5\u5185\u5BB9\u670D\u52A1"}</span>'," </div>",' <div className="mt-5 flex flex-col gap-3 sm:flex-row">',' <div className="min-w-0 flex-1 rounded-2xl border border-white/10 bg-black/20 px-4 py-2.5 text-sm text-slate-200">{cmsTenantId || "\u5F53\u524D\u5E94\u7528\u6682\u672A\u6CE8\u5165\u5185\u5BB9\u79DF\u6237"}</div>',' <div className="rounded-full border border-white/10 px-4 py-2 text-sm text-slate-300">{cmsState === "loading" ? "\u5185\u5BB9\u52A0\u8F7D\u4E2D..." : "\u5DF2\u81EA\u52A8\u52A0\u8F7D"}</div>'," </div>",' {cmsError ? <p className="mt-4 text-sm text-rose-300">{cmsError}</p> : null}',' <div className="mt-5 flex flex-wrap gap-2">{cmsCollections.length > 0 ? cmsCollections.map((collection) => <button key={collection.collection} type="button" onClick={() => void handleCollectionChange(collection.collection)} className={`rounded-full border px-3 py-1.5 text-xs font-medium transition ${cmsPrimaryCollection === collection.collection ? "border-emerald-400/30 bg-emerald-400/10 text-emerald-100" : "border-white/10 bg-white/5 text-slate-300 hover:border-white/20 hover:text-white"}`}>{collection.label}<span className="ml-2 text-[11px] text-slate-400">{collection.published_item_count}</span></button>) : sampleMode ? <span className="rounded-full border border-dashed border-white/10 px-3 py-1.5 text-xs text-slate-400">\u5F85\u63A5\u5165\u771F\u5B9E\u5185\u5BB9\u96C6\u5408\u540E\u663E\u793A</span> : null}</div>',' <div className="mt-5 grid gap-4 xl:grid-cols-[320px_minmax(0,1fr)]">',' <div className="rounded-2xl border border-white/10 bg-black/20 p-4"><div className="flex items-center justify-between gap-3"><div className="text-xs uppercase tracking-[0.2em] text-slate-500">\u5185\u5BB9\u5217\u8868</div>{selectedCollectionMeta ? <div className="text-xs text-slate-400">{selectedCollectionMeta.collection}</div> : null}</div><div className="mt-3 space-y-2">{cmsItems.length > 0 ? cmsItems.map((item) => { const itemKey = item.system.id || item.system.slug || pickCmsTitle(item); const categoryName = resolveCmsItemCategoryName(item, selectedCollectionMeta ?? undefined); const tagLabels = resolveCmsItemTagLabels(item); const coverImageUrl = pickCmsCoverImageUrl(item); return <button key={itemKey} type="button" onClick={() => setSelectedItemId(itemKey)} className={`block w-full rounded-2xl border px-3 py-3 text-left text-sm transition ${selectedItemId === itemKey || (!selectedItemId && selectedItem === item) ? "border-emerald-400/30 bg-emerald-400/10 text-emerald-100" : "border-white/10 bg-white/5 text-slate-200 hover:border-white/20"}`}>{coverImageUrl ? <img src={coverImageUrl} alt={pickCmsTitle(item)} className="mb-3 h-32 w-full rounded-xl object-cover" loading="lazy" /> : null}<div className="font-medium text-white">{pickCmsTitle(item)}</div>{pickCmsSummary(item) ? <div className="mt-1 line-clamp-2 text-xs leading-5 text-slate-400">{pickCmsSummary(item)}</div> : null}<div className="mt-2 flex flex-wrap gap-2 text-[11px] text-slate-400"><span>\u5206\u7C7B\uFF1A{categoryName}</span>{tagLabels.slice(0, 3).map((tag: string) => <span key={tag}>#{tag}</span>)}</div></button>; }) : sampleMode ? <div className="space-y-2"><div className="rounded-2xl border border-dashed border-white/10 px-3 py-4 text-sm text-slate-400">\u5F53\u524D\u5148\u5C55\u793A\u5217\u8868\u9AA8\u67B6\u3002\u63A5\u5165\u771F\u5B9E CMS \u540E\uFF0C\u8FD9\u91CC\u4F1A\u81EA\u52A8\u5207\u6362\u4E3A\u5185\u5BB9\u6761\u76EE\u3002</div><div className="rounded-2xl border border-white/10 bg-white/5 px-3 py-3 text-sm text-slate-300"><div className="font-medium text-white">\u793A\u4F8B\u5361\u7247\u7ED3\u6784</div><div className="mt-1 text-xs leading-5 text-slate-400">\u6807\u9898\u3001\u6458\u8981\u3001\u5206\u7C7B\u3001\u5C01\u9762\u56FE\u548C\u6807\u7B7E\u5EFA\u8BAE\u4FDD\u7559\u4E3A\u5361\u7247\u7684\u9ED8\u8BA4\u4FE1\u606F\u5C42\u7EA7\u3002</div></div></div> : <div className="rounded-2xl border border-dashed border-white/10 px-3 py-4 text-sm text-slate-400">\u5F53\u524D\u79DF\u6237\u4E0B\u6682\u65E0\u53EF\u5C55\u793A\u5185\u5BB9\u3002</div>}</div></div>',' <div className="rounded-2xl border border-white/10 bg-black/20 p-4"><div className="flex items-center justify-between gap-3"><div className="text-xs uppercase tracking-[0.2em] text-slate-500">\u5185\u5BB9\u8BE6\u60C5</div>{selectedItem?.system.slug ? <div className="text-xs text-slate-400">slug: {selectedItem?.system.slug}</div> : null}</div>{selectedItem ? <article className="mt-4 space-y-4"><div>{pickCmsCoverImageUrl(selectedItem) ? <img src={pickCmsCoverImageUrl(selectedItem) || undefined} alt={pickCmsTitle(selectedItem)} className="mb-4 h-64 w-full rounded-2xl object-cover" /> : null}<h2 className="text-2xl font-semibold text-white">{pickCmsTitle(selectedItem)}</h2>{pickCmsSummary(selectedItem) ? <p className="mt-2 text-sm leading-6 text-slate-300">{pickCmsSummary(selectedItem)}</p> : null}</div><div className="flex flex-wrap gap-2 text-xs text-slate-300"><span className="rounded-full border border-white/10 bg-white/5 px-2.5 py-1">\u5206\u7C7B\uFF1A{resolveCmsItemCategoryName(selectedItem, selectedCollectionMeta ?? undefined)}</span>{resolveCmsItemTagLabels(selectedItem).length > 0 ? resolveCmsItemTagLabels(selectedItem).map((tag: string) => <span key={tag} className="rounded-full border border-sky-400/20 bg-sky-400/10 px-2.5 py-1 text-sky-100">#{tag}</span>) : <span className="rounded-full border border-white/10 bg-white/5 px-2.5 py-1 text-slate-400">\u65E0\u6807\u7B7E</span>}</div>{selectedItem.system.rendered_html ? <div className="cms-content rounded-2xl bg-white px-4 py-4 text-sm" dangerouslySetInnerHTML={{ __html: selectedItem.system.rendered_html }} /> : <div className="rounded-2xl border border-dashed border-white/10 px-4 py-5 text-sm text-slate-400">\u5F53\u524D\u5185\u5BB9\u6CA1\u6709 `rendered_html`\uFF0C\u53EF\u4EE5\u7EE7\u7EED\u5C55\u793A\u7ED3\u6784\u5316\u5B57\u6BB5\u3002</div>}<div className="grid gap-3 md:grid-cols-2"><div className="rounded-2xl border border-white/10 bg-white/5 p-4 text-sm text-slate-300"><div className="text-xs uppercase tracking-[0.2em] text-slate-500">\u53D1\u5E03\u72B6\u6001</div><div className="mt-2">{selectedItem.system.publish_status || "-"}</div></div><div className="rounded-2xl border border-white/10 bg-white/5 p-4 text-sm text-slate-300"><div className="text-xs uppercase tracking-[0.2em] text-slate-500">\u5185\u5BB9 ID</div><div className="mt-2 break-all font-mono text-[13px]">{selectedItem.system.id || "-"}</div></div></div></article> : sampleMode ? <div className="mt-4 rounded-2xl border border-dashed border-white/10 px-4 py-6 text-sm text-slate-400">\u5F53\u524D\u5148\u5C55\u793A\u8BE6\u60C5\u9AA8\u67B6\u3002\u63A5\u5165\u771F\u5B9E\u5185\u5BB9\u540E\uFF0C\u8FD9\u91CC\u4F1A\u81EA\u52A8\u6E32\u67D3\u6B63\u6587\u3001\u5C01\u9762\u56FE\u3001\u6807\u7B7E\u548C\u53D1\u5E03\u4FE1\u606F\u3002</div> : <div className="mt-4 rounded-2xl border border-dashed border-white/10 px-3 py-6 text-sm text-slate-400">\u5F53\u524D\u6CA1\u6709\u9009\u4E2D\u7684\u5185\u5BB9\u6761\u76EE\u3002</div>}</div>'," </div>"," </div>"," </section>"," </main>"," );","}",""].join(`
|
|
2141
2141
|
`)}function buildStylesSource(){return['@import "tailwindcss";','@source "../../public/**/*.html";',"","@theme inline {"," --color-background: var(--background);"," --color-foreground: var(--foreground);"," --color-border: var(--border);"," --color-input: var(--input);"," --color-ring: var(--ring);"," --color-muted: var(--muted);"," --color-muted-foreground: var(--muted-foreground);"," --color-accent: var(--accent);"," --color-accent-foreground: var(--accent-foreground);"," --color-primary: var(--primary);"," --color-primary-foreground: var(--primary-foreground);"," --color-popover: var(--popover);"," --color-popover-foreground: var(--popover-foreground);","}","",":root {",' font-family: Inter, "PingFang SC", "Hiragino Sans GB", sans-serif;'," color-scheme: dark;"," --background: #0f172a;"," --foreground: #e5eefb;"," --border: #334155;"," --input: #475569;"," --ring: #38bdf8;"," --muted: #162033;"," --muted-foreground: #94a3b8;"," --accent: #1e293b;"," --accent-foreground: #f8fafc;"," --primary: #f8fafc;"," --primary-foreground: #0f172a;"," --popover: rgba(15, 23, 42, 0.98);"," --popover-foreground: #e5eefb;","}","","html {"," background: var(--background);"," color: var(--foreground);","}","","body {"," margin: 0;"," background: var(--background);"," color: var(--foreground);","}","","code {",' font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;',"}",""].join(`
|
|
2142
|
-
`)}function buildCmsContentStylesSource(){return buildWebBackendLiteCmsContentPresetCssSource()}import{createHash as createHash2}from"node:crypto";var BACKEND_PLATFORM_OWNED_FILES=new Set(["src/server/app.ts","src/server/routes/seo-pages.ts"]),PLATFORM_BLOCKS_RELEASES={"frontend-app-vite":"2026.07.19.1","backend-app-node":"2026.07.19.1"};function isManagedPlatformFilePath(templateKey,filePath){return templateKey==="frontend-app-vite"?filePath.startsWith("src/platform/"):filePath.startsWith("src/web/platform/")||filePath.startsWith("src/server/platform/")||BACKEND_PLATFORM_OWNED_FILES.has(filePath)}function getPlatformBlocksRelease(templateKey){return PLATFORM_BLOCKS_RELEASES[templateKey]}function buildPlatformBlocksManifestFromTemplateFiles(templateKey,files){let managedFiles=files.filter(file=>isManagedPlatformFilePath(templateKey,file.path)).map(file=>({path:file.path,block_id:buildManagedPlatformBlockId(file.path),policy:"replace",content_sha256:checksum(file.content)})).sort((left,right)=>left.path.localeCompare(right.path));return{schema_version:1,template_key:templateKey,platform_blocks_release:getPlatformBlocksRelease(templateKey),platform_blocks_revision:buildPlatformBlocksRevision(managedFiles),managed_files:managedFiles}}function buildManagedPlatformBlockId(path2){return path2.replace(/\.[^/.]+$/u,"").replace(/[^a-zA-Z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").toLowerCase()}function buildPlatformBlocksRevision(files){return`platform-blocks@${createHash2("sha256").update(JSON.stringify(files)).digest("hex").slice(0,16)}`}function checksum(content){return`sha256-${createHash2("sha256").update(content).digest("hex")}`}function readTemplateBlockSource2(relativePath){let fileUrl=[new URL(`../template-blocks/${relativePath}`,import.meta.url),new URL(`../../src/template-blocks/${relativePath}`,import.meta.url)].find(candidate=>existsSync3(candidate));if(!fileUrl)throw new Error(`Missing template block source for ${relativePath}`);return readFileSync3(fileUrl,"utf8")}function scaffoldTemplateBlock2(relativePath,outputPath){return{path:outputPath,content:readTemplateBlockSource2(relativePath)}}function buildAppYamlSource(templatePackageName){return[`name: ${templatePackageName}`,"version: 0.1.0","entry:"," command: npm run dev"," port: 3000"," health_check: /healthz",""].join(`
|
|
2143
|
-
`)}function buildPackageJsonManifest(templatePackageName){return{name:templatePackageName,version:"0.1.0",private:!0,type:"module",scripts:{dev:"node ./scripts/dev.mjs","dev:web":"vite --config vite.config.ts","dev:server":"tsx watch src/server/entry.ts",build:"npm run build:web && npm run build:server","build:web":"vite build","build:server":"tsc -p tsconfig.server.json",preview:"vite preview",start:"node dist/server/entry.js"},dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",tsx:"4.19.4",typescript:"5.8.2",vite:"6.3.5"}}}function buildPackageJsonSource(templatePackageName){return JSON.stringify(buildPackageJsonManifest(templatePackageName),null,2)+`
|
|
2144
|
-
`}function buildPackageLockSource(templatePackageName){let
|
|
2142
|
+
`)}function buildCmsContentStylesSource(){return buildWebBackendLiteCmsContentPresetCssSource()}import{createHash as createHash2}from"node:crypto";var BACKEND_PLATFORM_OWNED_FILES=new Set(["src/server/app.ts","src/server/routes/seo-pages.ts"]),PLATFORM_BLOCKS_RELEASES={"frontend-app-vite":"2026.07.19.1","backend-app-node":"2026.07.19.1"};function isManagedPlatformFilePath(templateKey,filePath){return templateKey==="frontend-app-vite"?filePath.startsWith("src/platform/"):filePath.startsWith("src/web/platform/")||filePath.startsWith("src/server/platform/")||BACKEND_PLATFORM_OWNED_FILES.has(filePath)}function getPlatformBlocksRelease(templateKey){return PLATFORM_BLOCKS_RELEASES[templateKey]}function buildPlatformBlocksManifestFromTemplateFiles(templateKey,files){let managedFiles=files.filter(file=>isManagedPlatformFilePath(templateKey,file.path)).map(file=>({path:file.path,block_id:buildManagedPlatformBlockId(file.path),policy:"replace",content_sha256:checksum(file.content)})).sort((left,right)=>left.path.localeCompare(right.path));return{schema_version:1,template_key:templateKey,platform_blocks_release:getPlatformBlocksRelease(templateKey),platform_blocks_revision:buildPlatformBlocksRevision(managedFiles),managed_files:managedFiles}}function buildManagedPlatformBlockId(path3){return path3.replace(/\.[^/.]+$/u,"").replace(/[^a-zA-Z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").toLowerCase()}function buildPlatformBlocksRevision(files){return`platform-blocks@${createHash2("sha256").update(JSON.stringify(files)).digest("hex").slice(0,16)}`}function checksum(content){return`sha256-${createHash2("sha256").update(content).digest("hex")}`}var FRONTEND_APP_VITE_PACKAGE_LOCK={name:"voobase-light-app",version:"0.1.0",lockfileVersion:3,requires:!0,packages:{"":{name:"voobase-light-app",version:"0.1.0",dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",typescript:"5.8.2",vite:"6.3.5"},engines:{node:">=20.0.0"}},"node_modules/@babel/code-frame":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",integrity:"sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",dev:!0,license:"MIT",dependencies:{"@babel/helper-validator-identifier":"^7.29.7","js-tokens":"^4.0.0",picocolors:"^1.1.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/compat-data":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",integrity:"sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/core":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",integrity:"sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/generator":"^7.29.7","@babel/helper-compilation-targets":"^7.29.7","@babel/helper-module-transforms":"^7.29.7","@babel/helpers":"^7.29.7","@babel/parser":"^7.29.7","@babel/template":"^7.29.7","@babel/traverse":"^7.29.7","@babel/types":"^7.29.7","@jridgewell/remapping":"^2.3.5","convert-source-map":"^2.0.0",debug:"^4.1.0",gensync:"^1.0.0-beta.2",json5:"^2.2.3",semver:"^6.3.1"},engines:{node:">=6.9.0"},funding:{type:"opencollective",url:"https://opencollective.com/babel"}},"node_modules/@babel/generator":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",integrity:"sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.29.7","@babel/types":"^7.29.7","@jridgewell/gen-mapping":"^0.3.12","@jridgewell/trace-mapping":"^0.3.28",jsesc:"^3.0.2"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-compilation-targets":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",integrity:"sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",dev:!0,license:"MIT",dependencies:{"@babel/compat-data":"^7.29.7","@babel/helper-validator-option":"^7.29.7",browserslist:"^4.24.0","lru-cache":"^5.1.1",semver:"^6.3.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-globals":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",integrity:"sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-module-imports":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",integrity:"sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",dev:!0,license:"MIT",dependencies:{"@babel/traverse":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-module-transforms":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",integrity:"sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",dev:!0,license:"MIT",dependencies:{"@babel/helper-module-imports":"^7.29.7","@babel/helper-validator-identifier":"^7.29.7","@babel/traverse":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0"}},"node_modules/@babel/helper-plugin-utils":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",integrity:"sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-string-parser":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",integrity:"sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-validator-identifier":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",integrity:"sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-validator-option":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",integrity:"sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helpers":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",integrity:"sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",dev:!0,license:"MIT",dependencies:{"@babel/template":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/parser":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",integrity:"sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.29.7"},bin:{parser:"bin/babel-parser.js"},engines:{node:">=6.0.0"}},"node_modules/@babel/plugin-transform-react-jsx-self":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",integrity:"sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",dev:!0,license:"MIT",dependencies:{"@babel/helper-plugin-utils":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0-0"}},"node_modules/@babel/plugin-transform-react-jsx-source":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",integrity:"sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",dev:!0,license:"MIT",dependencies:{"@babel/helper-plugin-utils":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0-0"}},"node_modules/@babel/template":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",integrity:"sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/parser":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/traverse":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",integrity:"sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/generator":"^7.29.7","@babel/helper-globals":"^7.29.7","@babel/parser":"^7.29.7","@babel/template":"^7.29.7","@babel/types":"^7.29.7",debug:"^4.3.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/types":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",integrity:"sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",dev:!0,license:"MIT",dependencies:{"@babel/helper-string-parser":"^7.29.7","@babel/helper-validator-identifier":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@date-fns/tz":{version:"1.5.0",resolved:"https://registry.npmjs.org/@date-fns/tz/-/tz-1.5.0.tgz",integrity:"sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==",license:"MIT"},"node_modules/@esbuild/aix-ppc64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",integrity:"sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["aix"],engines:{node:">=18"}},"node_modules/@esbuild/android-arm":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",integrity:"sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/android-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",integrity:"sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/android-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",integrity:"sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/darwin-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",integrity:"sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">=18"}},"node_modules/@esbuild/darwin-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",integrity:"sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">=18"}},"node_modules/@esbuild/freebsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",integrity:"sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">=18"}},"node_modules/@esbuild/freebsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",integrity:"sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">=18"}},"node_modules/@esbuild/linux-arm":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",integrity:"sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",integrity:"sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-ia32":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",integrity:"sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-loong64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",integrity:"sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-mips64el":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",integrity:"sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",cpu:["mips64el"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-ppc64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",integrity:"sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-riscv64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",integrity:"sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-s390x":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",integrity:"sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",cpu:["s390x"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",integrity:"sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/netbsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",integrity:"sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["netbsd"],engines:{node:">=18"}},"node_modules/@esbuild/netbsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",integrity:"sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["netbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openbsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",integrity:"sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openbsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",integrity:"sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openharmony-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",integrity:"sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openharmony"],engines:{node:">=18"}},"node_modules/@esbuild/sunos-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",integrity:"sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["sunos"],engines:{node:">=18"}},"node_modules/@esbuild/win32-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",integrity:"sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@esbuild/win32-ia32":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",integrity:"sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@esbuild/win32-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",integrity:"sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@floating-ui/core":{version:"1.8.0",resolved:"https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz",integrity:"sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==",license:"MIT",dependencies:{"@floating-ui/utils":"^0.2.12"}},"node_modules/@floating-ui/dom":{version:"1.8.0",resolved:"https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz",integrity:"sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==",license:"MIT",dependencies:{"@floating-ui/core":"^1.8.0","@floating-ui/utils":"^0.2.12"}},"node_modules/@floating-ui/react-dom":{version:"2.1.9",resolved:"https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz",integrity:"sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==",license:"MIT",dependencies:{"@floating-ui/dom":"^1.8.0"},peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}},"node_modules/@floating-ui/utils":{version:"0.2.12",resolved:"https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz",integrity:"sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",license:"MIT"},"node_modules/@jridgewell/gen-mapping":{version:"0.3.13",resolved:"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",integrity:"sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",dev:!0,license:"MIT",dependencies:{"@jridgewell/sourcemap-codec":"^1.5.0","@jridgewell/trace-mapping":"^0.3.24"}},"node_modules/@jridgewell/remapping":{version:"2.3.5",resolved:"https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",integrity:"sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",dev:!0,license:"MIT",dependencies:{"@jridgewell/gen-mapping":"^0.3.5","@jridgewell/trace-mapping":"^0.3.24"}},"node_modules/@jridgewell/resolve-uri":{version:"3.1.2",resolved:"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",integrity:"sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",dev:!0,license:"MIT",engines:{node:">=6.0.0"}},"node_modules/@jridgewell/sourcemap-codec":{version:"1.5.5",resolved:"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",integrity:"sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",dev:!0,license:"MIT"},"node_modules/@jridgewell/trace-mapping":{version:"0.3.31",resolved:"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",integrity:"sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",dev:!0,license:"MIT",dependencies:{"@jridgewell/resolve-uri":"^3.1.0","@jridgewell/sourcemap-codec":"^1.4.14"}},"node_modules/@radix-ui/number":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz",integrity:"sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig==",license:"MIT"},"node_modules/@radix-ui/primitive":{version:"1.1.6",resolved:"https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.6.tgz",integrity:"sha512-w9hl+724uYEgCGR3bhuRepjBtrNB/6gkhCnAf58Ke+SLbHPPQqVZZB59z60roB+5H+nh3nWTcdJhQdFMEydWmw==",license:"MIT"},"node_modules/@radix-ui/react-arrow":{version:"1.1.12",resolved:"https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.12.tgz",integrity:"sha512-ltXCE0glRomMZ9+u10d9o1Go+edqa1aLxufH59JRNNM3Yz1uvaeNWSaS1HeVh1X64agtdBG5JA1W1I6ySqWiwA==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-checkbox":{version:"1.3.8",resolved:"https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.8.tgz",integrity:"sha512-wfN60IGuxynWK7rP4Ks2p7u9G7gqirzkAiFptuzVbsR1ot2/K+PavNUAtxiKxyRfLOvSbVfvvm9m3rFqLEXz7A==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-controllable-state":"1.2.4","@radix-ui/react-use-size":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-collection":{version:"1.1.12",resolved:"https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.12.tgz",integrity:"sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-compose-refs":{version:"1.1.3",resolved:"https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz",integrity:"sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-context":{version:"1.2.0",resolved:"https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.0.tgz",integrity:"sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-direction":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz",integrity:"sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-dismissable-layer":{version:"1.1.16",resolved:"https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.16.tgz",integrity:"sha512-t45h68IjFx0ccBnPJqk0X6ecv69LkCFWd6DNCFQX56mUnVEXZbNOLCH/u9fHlAjFZ1RrFdl8/m4zev7B7NyhXQ==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-effect-event":"0.0.3"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-focus-guards":{version:"1.1.4",resolved:"https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz",integrity:"sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-focus-scope":{version:"1.1.13",resolved:"https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.13.tgz",integrity:"sha512-dE04aPEuP9rvKKT0d0KjSOtTEYNg6bmCYFsoSJpfC+y91Hic28ZfDCGgv6aJ+2Kw/LBXYipMZpyqVj/OD3Z8Gg==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-id":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz",integrity:"sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-popover":{version:"1.1.20",resolved:"https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.20.tgz",integrity:"sha512-/PYqbsyuDkNj+IxMcRx71qNt6GelnuNulMwdCV7AtFEhUyK6XkbwreEN6CCLydMeTiDozBV4uv5aF5d12dDH7w==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-dismissable-layer":"1.1.16","@radix-ui/react-focus-guards":"1.1.4","@radix-ui/react-focus-scope":"1.1.13","@radix-ui/react-id":"1.1.2","@radix-ui/react-popper":"1.3.4","@radix-ui/react-portal":"1.1.14","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0","@radix-ui/react-use-controllable-state":"1.2.4","aria-hidden":"^1.2.4","react-remove-scroll":"^2.7.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-popper":{version:"1.3.4",resolved:"https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.4.tgz",integrity:"sha512-PXnCa3XgTQk0FegMctxgqJXtFLZe4IFJdbUkB7jKSCKEpb6utEO4S9Vog/pkyCfEPdzM331gvE4xpztmBAfMng==",license:"MIT",dependencies:{"@floating-ui/react-dom":"^2.0.0","@radix-ui/react-arrow":"1.1.12","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-layout-effect":"1.1.2","@radix-ui/react-use-rect":"1.1.2","@radix-ui/react-use-size":"1.1.2","@radix-ui/rect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-portal":{version:"1.1.14",resolved:"https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.14.tgz",integrity:"sha512-REwjAGPMa3J9oyDE4cuWkZbwnCbbyky66NurquQklXMSDn67cl6oGFx2gO7KZhPtFNbNw9xTWNrti3VIhgluYw==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-presence":{version:"1.1.8",resolved:"https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.8.tgz",integrity:"sha512-0hhyrQdXMaATgq4ammLG9+iPqsXxzZkgTSIxdrJHdfLnXO4Uo5L7BoO3/Xf0AEaettadGZWGGJMw6ujzQvIpGA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-primitive":{version:"2.1.7",resolved:"https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz",integrity:"sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==",license:"MIT",dependencies:{"@radix-ui/react-slot":"1.3.0"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-select":{version:"2.3.4",resolved:"https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.4.tgz",integrity:"sha512-E2JxqAvaTUEhWtBptWo02g8FnLYPymv9ahEvW/cZQPPV4ySeyo0M8n3sXccsLUAIfMbexnfXt91qF7UjTbTMMg==",license:"MIT",dependencies:{"@radix-ui/number":"1.1.2","@radix-ui/primitive":"1.1.6","@radix-ui/react-collection":"1.1.12","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-direction":"1.1.2","@radix-ui/react-dismissable-layer":"1.1.16","@radix-ui/react-focus-guards":"1.1.4","@radix-ui/react-focus-scope":"1.1.13","@radix-ui/react-id":"1.1.2","@radix-ui/react-popper":"1.3.4","@radix-ui/react-portal":"1.1.14","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-controllable-state":"1.2.4","@radix-ui/react-use-layout-effect":"1.1.2","@radix-ui/react-use-previous":"1.1.2","@radix-ui/react-visually-hidden":"1.2.8","aria-hidden":"^1.2.4","react-remove-scroll":"^2.7.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-slot":{version:"1.3.0",resolved:"https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz",integrity:"sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-callback-ref":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz",integrity:"sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-controllable-state":{version:"1.2.4",resolved:"https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.4.tgz",integrity:"sha512-cx2DixxmSfjCcEoRvDvy1NLd6SWK94XFcEEOZUcharUlXbmahFQGKCfwdKZL2ub34iIwOPOEFVF80xb+yfLYiA==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-use-effect-event":"0.0.3","@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-effect-event":{version:"0.0.3",resolved:"https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz",integrity:"sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-layout-effect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz",integrity:"sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-previous":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.2.tgz",integrity:"sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-rect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz",integrity:"sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==",license:"MIT",dependencies:{"@radix-ui/rect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-size":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz",integrity:"sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-visually-hidden":{version:"1.2.8",resolved:"https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.8.tgz",integrity:"sha512-FjsQEpkNBJJYiPSat6jh2LGKLPX2jAoDVS3AZSBNX3cOUoEGhw/f+z2FCY8Cf1NkoYIbytJ1f4mlWPQpR+MjVg==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/rect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz",integrity:"sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==",license:"MIT"},"node_modules/@rollup/rollup-android-arm-eabi":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",integrity:"sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["android"]},"node_modules/@rollup/rollup-android-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",integrity:"sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"]},"node_modules/@rollup/rollup-darwin-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",integrity:"sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"]},"node_modules/@rollup/rollup-darwin-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",integrity:"sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"]},"node_modules/@rollup/rollup-freebsd-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",integrity:"sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"]},"node_modules/@rollup/rollup-freebsd-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",integrity:"sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"]},"node_modules/@rollup/rollup-linux-arm-gnueabihf":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",integrity:"sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm-musleabihf":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",integrity:"sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",integrity:"sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",integrity:"sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-loong64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",integrity:"sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-loong64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",integrity:"sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-ppc64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",integrity:"sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-ppc64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",integrity:"sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-riscv64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",integrity:"sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-riscv64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",integrity:"sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-s390x-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",integrity:"sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",cpu:["s390x"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-x64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",integrity:"sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-x64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",integrity:"sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-openbsd-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",integrity:"sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"]},"node_modules/@rollup/rollup-openharmony-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",integrity:"sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openharmony"]},"node_modules/@rollup/rollup-win32-arm64-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",integrity:"sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-ia32-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",integrity:"sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-x64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",integrity:"sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-x64-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",integrity:"sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@tabby_ai/hijri-converter":{version:"1.0.5",resolved:"https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz",integrity:"sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==",license:"MIT",engines:{node:">=16.0.0"}},"node_modules/@tailwindcss/node":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",integrity:"sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==",dev:!0,license:"MIT",dependencies:{"@jridgewell/remapping":"^2.3.5","enhanced-resolve":"^5.19.0",jiti:"^2.6.1",lightningcss:"1.32.0","magic-string":"^0.30.21","source-map-js":"^1.2.1",tailwindcss:"4.2.2"}},"node_modules/@tailwindcss/oxide":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz",integrity:"sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==",dev:!0,license:"MIT",engines:{node:">= 20"},optionalDependencies:{"@tailwindcss/oxide-android-arm64":"4.2.2","@tailwindcss/oxide-darwin-arm64":"4.2.2","@tailwindcss/oxide-darwin-x64":"4.2.2","@tailwindcss/oxide-freebsd-x64":"4.2.2","@tailwindcss/oxide-linux-arm-gnueabihf":"4.2.2","@tailwindcss/oxide-linux-arm64-gnu":"4.2.2","@tailwindcss/oxide-linux-arm64-musl":"4.2.2","@tailwindcss/oxide-linux-x64-gnu":"4.2.2","@tailwindcss/oxide-linux-x64-musl":"4.2.2","@tailwindcss/oxide-wasm32-wasi":"4.2.2","@tailwindcss/oxide-win32-arm64-msvc":"4.2.2","@tailwindcss/oxide-win32-x64-msvc":"4.2.2"}},"node_modules/@tailwindcss/oxide-android-arm64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz",integrity:"sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-darwin-arm64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz",integrity:"sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-darwin-x64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz",integrity:"sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-freebsd-x64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz",integrity:"sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz",integrity:"sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm64-gnu":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz",integrity:"sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm64-musl":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz",integrity:"sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-x64-gnu":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz",integrity:"sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-x64-musl":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz",integrity:"sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-wasm32-wasi":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz",integrity:"sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==",bundleDependencies:["@napi-rs/wasm-runtime","@emnapi/core","@emnapi/runtime","@tybys/wasm-util","@emnapi/wasi-threads","tslib"],cpu:["wasm32"],dev:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/core":"^1.8.1","@emnapi/runtime":"^1.8.1","@emnapi/wasi-threads":"^1.1.0","@napi-rs/wasm-runtime":"^1.1.1","@tybys/wasm-util":"^0.10.1",tslib:"^2.8.1"},engines:{node:">=14.0.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core":{version:"1.8.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/wasi-threads":"1.1.0",tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime":{version:"1.8.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads":{version:"1.1.0",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime":{version:"1.1.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/core":"^1.7.1","@emnapi/runtime":"^1.7.1","@tybys/wasm-util":"^0.10.1"},funding:{type:"github",url:"https://github.com/sponsors/Brooooooklyn"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util":{version:"0.10.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib":{version:"2.8.1",dev:!0,inBundle:!0,license:"0BSD",optional:!0},"node_modules/@tailwindcss/oxide-win32-arm64-msvc":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz",integrity:"sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-win32-x64-msvc":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz",integrity:"sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">= 20"}},"node_modules/@tailwindcss/vite":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz",integrity:"sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==",dev:!0,license:"MIT",dependencies:{"@tailwindcss/node":"4.2.2","@tailwindcss/oxide":"4.2.2",tailwindcss:"4.2.2"},peerDependencies:{vite:"^5.2.0 || ^6 || ^7 || ^8"}},"node_modules/@types/babel__core":{version:"7.20.5",resolved:"https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",integrity:"sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.20.7","@babel/types":"^7.20.7","@types/babel__generator":"*","@types/babel__template":"*","@types/babel__traverse":"*"}},"node_modules/@types/babel__generator":{version:"7.27.0",resolved:"https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",integrity:"sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.0.0"}},"node_modules/@types/babel__template":{version:"7.4.4",resolved:"https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",integrity:"sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.1.0","@babel/types":"^7.0.0"}},"node_modules/@types/babel__traverse":{version:"7.28.0",resolved:"https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",integrity:"sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.28.2"}},"node_modules/@types/estree":{version:"1.0.9",resolved:"https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",integrity:"sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",dev:!0,license:"MIT"},"node_modules/@types/node":{version:"22.15.17",resolved:"https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",integrity:"sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",dev:!0,license:"MIT",dependencies:{"undici-types":"~6.21.0"}},"node_modules/@types/react":{version:"19.2.2",resolved:"https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",integrity:"sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",devOptional:!0,license:"MIT",dependencies:{csstype:"^3.0.2"}},"node_modules/@types/react-dom":{version:"19.2.2",resolved:"https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz",integrity:"sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",devOptional:!0,license:"MIT",peerDependencies:{"@types/react":"^19.2.0"}},"node_modules/@vitejs/plugin-react":{version:"4.3.4",resolved:"https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",integrity:"sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",dev:!0,license:"MIT",dependencies:{"@babel/core":"^7.26.0","@babel/plugin-transform-react-jsx-self":"^7.25.9","@babel/plugin-transform-react-jsx-source":"^7.25.9","@types/babel__core":"^7.20.5","react-refresh":"^0.14.2"},engines:{node:"^14.18.0 || >=16.0.0"},peerDependencies:{vite:"^4.2.0 || ^5.0.0 || ^6.0.0"}},"node_modules/aria-hidden":{version:"1.2.6",resolved:"https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",integrity:"sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",license:"MIT",dependencies:{tslib:"^2.0.0"},engines:{node:">=10"}},"node_modules/baseline-browser-mapping":{version:"2.11.0",resolved:"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.0.tgz",integrity:"sha512-oCu2wfipvX3AePSgmOuKkIywOu+8n9psz7hXYmk56ghpu3+7KzNIBopaOs4c9BrtdnTtW30unG9GTfHo7EwERQ==",dev:!0,license:"Apache-2.0",bin:{"baseline-browser-mapping":"dist/cli.cjs"},engines:{node:">=6.0.0"}},"node_modules/browserslist":{version:"4.28.6",resolved:"https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz",integrity:"sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/browserslist"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{"baseline-browser-mapping":"^2.10.42","caniuse-lite":"^1.0.30001803","electron-to-chromium":"^1.5.389","node-releases":"^2.0.51","update-browserslist-db":"^1.2.3"},bin:{browserslist:"cli.js"},engines:{node:"^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"}},"node_modules/caniuse-lite":{version:"1.0.30001806",resolved:"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",integrity:"sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/caniuse-lite"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"CC-BY-4.0"},"node_modules/convert-source-map":{version:"2.0.0",resolved:"https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",integrity:"sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",dev:!0,license:"MIT"},"node_modules/csstype":{version:"3.2.3",resolved:"https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",integrity:"sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",devOptional:!0,license:"MIT"},"node_modules/date-fns":{version:"4.4.0",resolved:"https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz",integrity:"sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==",license:"MIT",funding:{type:"github",url:"https://github.com/sponsors/kossnocorp"}},"node_modules/date-fns-jalali":{version:"4.1.0-0",resolved:"https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",integrity:"sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==",license:"MIT"},"node_modules/debug":{version:"4.4.3",resolved:"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",integrity:"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",dev:!0,license:"MIT",dependencies:{ms:"^2.1.3"},engines:{node:">=6.0"},peerDependenciesMeta:{"supports-color":{optional:!0}}},"node_modules/detect-libc":{version:"2.1.2",resolved:"https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",integrity:"sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",dev:!0,license:"Apache-2.0",engines:{node:">=8"}},"node_modules/detect-node-es":{version:"1.1.0",resolved:"https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",integrity:"sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",license:"MIT"},"node_modules/electron-to-chromium":{version:"1.5.394",resolved:"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.394.tgz",integrity:"sha512-Wmt2Gm0o8JWBuGgmc4XZ0u9s1RaCRqhxP47phplmfg04+qypTUurpeJGP45A7Fhv7jdrrVH44PLlR9qXo37cVQ==",dev:!0,license:"ISC"},"node_modules/enhanced-resolve":{version:"5.24.3",resolved:"https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz",integrity:"sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==",dev:!0,license:"MIT",dependencies:{"graceful-fs":"^4.2.4",tapable:"^2.3.3"},engines:{node:">=10.13.0"}},"node_modules/esbuild":{version:"0.25.12",resolved:"https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",integrity:"sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",dev:!0,hasInstallScript:!0,license:"MIT",bin:{esbuild:"bin/esbuild"},engines:{node:">=18"},optionalDependencies:{"@esbuild/aix-ppc64":"0.25.12","@esbuild/android-arm":"0.25.12","@esbuild/android-arm64":"0.25.12","@esbuild/android-x64":"0.25.12","@esbuild/darwin-arm64":"0.25.12","@esbuild/darwin-x64":"0.25.12","@esbuild/freebsd-arm64":"0.25.12","@esbuild/freebsd-x64":"0.25.12","@esbuild/linux-arm":"0.25.12","@esbuild/linux-arm64":"0.25.12","@esbuild/linux-ia32":"0.25.12","@esbuild/linux-loong64":"0.25.12","@esbuild/linux-mips64el":"0.25.12","@esbuild/linux-ppc64":"0.25.12","@esbuild/linux-riscv64":"0.25.12","@esbuild/linux-s390x":"0.25.12","@esbuild/linux-x64":"0.25.12","@esbuild/netbsd-arm64":"0.25.12","@esbuild/netbsd-x64":"0.25.12","@esbuild/openbsd-arm64":"0.25.12","@esbuild/openbsd-x64":"0.25.12","@esbuild/openharmony-arm64":"0.25.12","@esbuild/sunos-x64":"0.25.12","@esbuild/win32-arm64":"0.25.12","@esbuild/win32-ia32":"0.25.12","@esbuild/win32-x64":"0.25.12"}},"node_modules/escalade":{version:"3.2.0",resolved:"https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",integrity:"sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",dev:!0,license:"MIT",engines:{node:">=6"}},"node_modules/fdir":{version:"6.5.0",resolved:"https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",integrity:"sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",dev:!0,license:"MIT",engines:{node:">=12.0.0"},peerDependencies:{picomatch:"^3 || ^4"},peerDependenciesMeta:{picomatch:{optional:!0}}},"node_modules/fsevents":{version:"2.3.3",resolved:"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",integrity:"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",dev:!0,hasInstallScript:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:"^8.16.0 || ^10.6.0 || >=11.0.0"}},"node_modules/gensync":{version:"1.0.0-beta.2",resolved:"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",integrity:"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/get-nonce":{version:"1.0.1",resolved:"https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",integrity:"sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",license:"MIT",engines:{node:">=6"}},"node_modules/graceful-fs":{version:"4.2.11",resolved:"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",integrity:"sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",dev:!0,license:"ISC"},"node_modules/jiti":{version:"2.7.0",resolved:"https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",integrity:"sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",dev:!0,license:"MIT",bin:{jiti:"lib/jiti-cli.mjs"}},"node_modules/js-tokens":{version:"4.0.0",resolved:"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",integrity:"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",license:"MIT"},"node_modules/jsesc":{version:"3.1.0",resolved:"https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",integrity:"sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",dev:!0,license:"MIT",bin:{jsesc:"bin/jsesc"},engines:{node:">=6"}},"node_modules/json5":{version:"2.2.3",resolved:"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",integrity:"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",dev:!0,license:"MIT",bin:{json5:"lib/cli.js"},engines:{node:">=6"}},"node_modules/lightningcss":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",integrity:"sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",dev:!0,license:"MPL-2.0",dependencies:{"detect-libc":"^2.0.3"},engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"},optionalDependencies:{"lightningcss-android-arm64":"1.32.0","lightningcss-darwin-arm64":"1.32.0","lightningcss-darwin-x64":"1.32.0","lightningcss-freebsd-x64":"1.32.0","lightningcss-linux-arm-gnueabihf":"1.32.0","lightningcss-linux-arm64-gnu":"1.32.0","lightningcss-linux-arm64-musl":"1.32.0","lightningcss-linux-x64-gnu":"1.32.0","lightningcss-linux-x64-musl":"1.32.0","lightningcss-win32-arm64-msvc":"1.32.0","lightningcss-win32-x64-msvc":"1.32.0"}},"node_modules/lightningcss-android-arm64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",integrity:"sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["android"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-darwin-arm64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",integrity:"sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["darwin"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-darwin-x64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",integrity:"sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["darwin"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-freebsd-x64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",integrity:"sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["freebsd"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm-gnueabihf":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",integrity:"sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",cpu:["arm"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm64-gnu":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",integrity:"sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm64-musl":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",integrity:"sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-x64-gnu":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",integrity:"sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-x64-musl":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",integrity:"sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-win32-arm64-msvc":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",integrity:"sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["win32"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-win32-x64-msvc":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",integrity:"sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["win32"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/loose-envify":{version:"1.4.0",resolved:"https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",integrity:"sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",license:"MIT",dependencies:{"js-tokens":"^3.0.0 || ^4.0.0"},bin:{"loose-envify":"cli.js"}},"node_modules/lru-cache":{version:"5.1.1",resolved:"https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",integrity:"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",dev:!0,license:"ISC",dependencies:{yallist:"^3.0.2"}},"node_modules/lucide-react":{version:"0.577.0",resolved:"https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz",integrity:"sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==",license:"ISC",peerDependencies:{react:"^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"}},"node_modules/magic-string":{version:"0.30.21",resolved:"https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",integrity:"sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",dev:!0,license:"MIT",dependencies:{"@jridgewell/sourcemap-codec":"^1.5.5"}},"node_modules/ms":{version:"2.1.3",resolved:"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",integrity:"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",dev:!0,license:"MIT"},"node_modules/nanoid":{version:"3.3.16",resolved:"https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",integrity:"sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",dev:!0,funding:[{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",bin:{nanoid:"bin/nanoid.cjs"},engines:{node:"^10 || ^12 || ^13.7 || ^14 || >=15.0.1"}},"node_modules/node-releases":{version:"2.0.51",resolved:"https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",integrity:"sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",dev:!0,license:"MIT",engines:{node:">=18"}},"node_modules/picocolors":{version:"1.1.1",resolved:"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",integrity:"sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",dev:!0,license:"ISC"},"node_modules/picomatch":{version:"4.0.5",resolved:"https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",integrity:"sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",dev:!0,license:"MIT",engines:{node:">=12"},funding:{url:"https://github.com/sponsors/jonschlinkert"}},"node_modules/postcss":{version:"8.5.21",resolved:"https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz",integrity:"sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/postcss/"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/postcss"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{nanoid:"^3.3.16",picocolors:"^1.1.1","source-map-js":"^1.2.1"},engines:{node:"^10 || ^12 || >=14"}},"node_modules/react":{version:"18.3.1",resolved:"https://registry.npmjs.org/react/-/react-18.3.1.tgz",integrity:"sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",license:"MIT",dependencies:{"loose-envify":"^1.1.0"},engines:{node:">=0.10.0"}},"node_modules/react-day-picker":{version:"9.14.0",resolved:"https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz",integrity:"sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==",license:"MIT",dependencies:{"@date-fns/tz":"^1.4.1","@tabby_ai/hijri-converter":"1.0.5","date-fns":"^4.1.0","date-fns-jalali":"4.1.0-0"},engines:{node:">=18"},funding:{type:"individual",url:"https://github.com/sponsors/gpbl"},peerDependencies:{react:">=16.8.0"}},"node_modules/react-dom":{version:"18.3.1",resolved:"https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",integrity:"sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",license:"MIT",dependencies:{"loose-envify":"^1.1.0",scheduler:"^0.23.2"},peerDependencies:{react:"^18.3.1"}},"node_modules/react-refresh":{version:"0.14.2",resolved:"https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",integrity:"sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",dev:!0,license:"MIT",engines:{node:">=0.10.0"}},"node_modules/react-remove-scroll":{version:"2.7.2",resolved:"https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",integrity:"sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",license:"MIT",dependencies:{"react-remove-scroll-bar":"^2.3.7","react-style-singleton":"^2.2.3",tslib:"^2.1.0","use-callback-ref":"^1.3.3","use-sidecar":"^1.1.3"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/react-remove-scroll-bar":{version:"2.3.8",resolved:"https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",integrity:"sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",license:"MIT",dependencies:{"react-style-singleton":"^2.2.2",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/react-style-singleton":{version:"2.2.3",resolved:"https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",integrity:"sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",license:"MIT",dependencies:{"get-nonce":"^1.0.0",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/rollup":{version:"4.62.2",resolved:"https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",integrity:"sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",dev:!0,license:"MIT",dependencies:{"@types/estree":"1.0.9"},bin:{rollup:"dist/bin/rollup"},engines:{node:">=18.0.0",npm:">=8.0.0"},optionalDependencies:{"@rollup/rollup-android-arm-eabi":"4.62.2","@rollup/rollup-android-arm64":"4.62.2","@rollup/rollup-darwin-arm64":"4.62.2","@rollup/rollup-darwin-x64":"4.62.2","@rollup/rollup-freebsd-arm64":"4.62.2","@rollup/rollup-freebsd-x64":"4.62.2","@rollup/rollup-linux-arm-gnueabihf":"4.62.2","@rollup/rollup-linux-arm-musleabihf":"4.62.2","@rollup/rollup-linux-arm64-gnu":"4.62.2","@rollup/rollup-linux-arm64-musl":"4.62.2","@rollup/rollup-linux-loong64-gnu":"4.62.2","@rollup/rollup-linux-loong64-musl":"4.62.2","@rollup/rollup-linux-ppc64-gnu":"4.62.2","@rollup/rollup-linux-ppc64-musl":"4.62.2","@rollup/rollup-linux-riscv64-gnu":"4.62.2","@rollup/rollup-linux-riscv64-musl":"4.62.2","@rollup/rollup-linux-s390x-gnu":"4.62.2","@rollup/rollup-linux-x64-gnu":"4.62.2","@rollup/rollup-linux-x64-musl":"4.62.2","@rollup/rollup-openbsd-x64":"4.62.2","@rollup/rollup-openharmony-arm64":"4.62.2","@rollup/rollup-win32-arm64-msvc":"4.62.2","@rollup/rollup-win32-ia32-msvc":"4.62.2","@rollup/rollup-win32-x64-gnu":"4.62.2","@rollup/rollup-win32-x64-msvc":"4.62.2",fsevents:"~2.3.2"}},"node_modules/scheduler":{version:"0.23.2",resolved:"https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",integrity:"sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",license:"MIT",dependencies:{"loose-envify":"^1.1.0"}},"node_modules/semver":{version:"6.3.1",resolved:"https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",integrity:"sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",dev:!0,license:"ISC",bin:{semver:"bin/semver.js"}},"node_modules/source-map-js":{version:"1.2.1",resolved:"https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",integrity:"sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",dev:!0,license:"BSD-3-Clause",engines:{node:">=0.10.0"}},"node_modules/tailwindcss":{version:"4.2.2",resolved:"https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",integrity:"sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",dev:!0,license:"MIT"},"node_modules/tapable":{version:"2.3.3",resolved:"https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",integrity:"sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",dev:!0,license:"MIT",engines:{node:">=6"},funding:{type:"opencollective",url:"https://opencollective.com/webpack"}},"node_modules/tinyglobby":{version:"0.2.17",resolved:"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",integrity:"sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",dev:!0,license:"MIT",dependencies:{fdir:"^6.5.0",picomatch:"^4.0.4"},engines:{node:">=12.0.0"},funding:{url:"https://github.com/sponsors/SuperchupuDev"}},"node_modules/tslib":{version:"2.8.1",resolved:"https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",integrity:"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",license:"0BSD"},"node_modules/typescript":{version:"5.8.2",resolved:"https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",integrity:"sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",dev:!0,license:"Apache-2.0",bin:{tsc:"bin/tsc",tsserver:"bin/tsserver"},engines:{node:">=14.17"}},"node_modules/undici-types":{version:"6.21.0",resolved:"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",integrity:"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",dev:!0,license:"MIT"},"node_modules/update-browserslist-db":{version:"1.2.3",resolved:"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",integrity:"sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/browserslist"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{escalade:"^3.2.0",picocolors:"^1.1.1"},bin:{"update-browserslist-db":"cli.js"},peerDependencies:{browserslist:">= 4.21.0"}},"node_modules/use-callback-ref":{version:"1.3.3",resolved:"https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",integrity:"sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",license:"MIT",dependencies:{tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/use-sidecar":{version:"1.1.3",resolved:"https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",integrity:"sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",license:"MIT",dependencies:{"detect-node-es":"^1.1.0",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/vite":{version:"6.3.5",resolved:"https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",integrity:"sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",dev:!0,license:"MIT",dependencies:{esbuild:"^0.25.0",fdir:"^6.4.4",picomatch:"^4.0.2",postcss:"^8.5.3",rollup:"^4.34.9",tinyglobby:"^0.2.13"},bin:{vite:"bin/vite.js"},engines:{node:"^18.0.0 || ^20.0.0 || >=22.0.0"},funding:{url:"https://github.com/vitejs/vite?sponsor=1"},optionalDependencies:{fsevents:"~2.3.3"},peerDependencies:{"@types/node":"^18.0.0 || ^20.0.0 || >=22.0.0",jiti:">=1.21.0",less:"*",lightningcss:"^1.21.0",sass:"*","sass-embedded":"*",stylus:"*",sugarss:"*",terser:"^5.16.0",tsx:"^4.8.1",yaml:"^2.4.2"},peerDependenciesMeta:{"@types/node":{optional:!0},jiti:{optional:!0},less:{optional:!0},lightningcss:{optional:!0},sass:{optional:!0},"sass-embedded":{optional:!0},stylus:{optional:!0},sugarss:{optional:!0},terser:{optional:!0},tsx:{optional:!0},yaml:{optional:!0}}},"node_modules/yallist":{version:"3.1.1",resolved:"https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",integrity:"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",dev:!0,license:"ISC"}}},BACKEND_APP_NODE_PACKAGE_LOCK={name:"voobase-light-app",version:"0.1.0",lockfileVersion:3,requires:!0,packages:{"":{name:"voobase-light-app",version:"0.1.0",dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",tsx:"4.19.4",typescript:"5.8.2",vite:"6.3.5"},engines:{node:">=20.0.0"}},"node_modules/@babel/code-frame":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",integrity:"sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",dev:!0,license:"MIT",dependencies:{"@babel/helper-validator-identifier":"^7.29.7","js-tokens":"^4.0.0",picocolors:"^1.1.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/compat-data":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",integrity:"sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/core":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",integrity:"sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/generator":"^7.29.7","@babel/helper-compilation-targets":"^7.29.7","@babel/helper-module-transforms":"^7.29.7","@babel/helpers":"^7.29.7","@babel/parser":"^7.29.7","@babel/template":"^7.29.7","@babel/traverse":"^7.29.7","@babel/types":"^7.29.7","@jridgewell/remapping":"^2.3.5","convert-source-map":"^2.0.0",debug:"^4.1.0",gensync:"^1.0.0-beta.2",json5:"^2.2.3",semver:"^6.3.1"},engines:{node:">=6.9.0"},funding:{type:"opencollective",url:"https://opencollective.com/babel"}},"node_modules/@babel/generator":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",integrity:"sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.29.7","@babel/types":"^7.29.7","@jridgewell/gen-mapping":"^0.3.12","@jridgewell/trace-mapping":"^0.3.28",jsesc:"^3.0.2"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-compilation-targets":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",integrity:"sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",dev:!0,license:"MIT",dependencies:{"@babel/compat-data":"^7.29.7","@babel/helper-validator-option":"^7.29.7",browserslist:"^4.24.0","lru-cache":"^5.1.1",semver:"^6.3.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-globals":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",integrity:"sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-module-imports":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",integrity:"sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",dev:!0,license:"MIT",dependencies:{"@babel/traverse":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/helper-module-transforms":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",integrity:"sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",dev:!0,license:"MIT",dependencies:{"@babel/helper-module-imports":"^7.29.7","@babel/helper-validator-identifier":"^7.29.7","@babel/traverse":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0"}},"node_modules/@babel/helper-plugin-utils":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",integrity:"sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-string-parser":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",integrity:"sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-validator-identifier":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",integrity:"sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helper-validator-option":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",integrity:"sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/@babel/helpers":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",integrity:"sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",dev:!0,license:"MIT",dependencies:{"@babel/template":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/parser":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",integrity:"sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.29.7"},bin:{parser:"bin/babel-parser.js"},engines:{node:">=6.0.0"}},"node_modules/@babel/plugin-transform-react-jsx-self":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",integrity:"sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",dev:!0,license:"MIT",dependencies:{"@babel/helper-plugin-utils":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0-0"}},"node_modules/@babel/plugin-transform-react-jsx-source":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",integrity:"sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",dev:!0,license:"MIT",dependencies:{"@babel/helper-plugin-utils":"^7.29.7"},engines:{node:">=6.9.0"},peerDependencies:{"@babel/core":"^7.0.0-0"}},"node_modules/@babel/template":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",integrity:"sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/parser":"^7.29.7","@babel/types":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@babel/traverse":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",integrity:"sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",dev:!0,license:"MIT",dependencies:{"@babel/code-frame":"^7.29.7","@babel/generator":"^7.29.7","@babel/helper-globals":"^7.29.7","@babel/parser":"^7.29.7","@babel/template":"^7.29.7","@babel/types":"^7.29.7",debug:"^4.3.1"},engines:{node:">=6.9.0"}},"node_modules/@babel/types":{version:"7.29.7",resolved:"https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",integrity:"sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",dev:!0,license:"MIT",dependencies:{"@babel/helper-string-parser":"^7.29.7","@babel/helper-validator-identifier":"^7.29.7"},engines:{node:">=6.9.0"}},"node_modules/@date-fns/tz":{version:"1.5.0",resolved:"https://registry.npmjs.org/@date-fns/tz/-/tz-1.5.0.tgz",integrity:"sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==",license:"MIT"},"node_modules/@esbuild/aix-ppc64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",integrity:"sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["aix"],engines:{node:">=18"}},"node_modules/@esbuild/android-arm":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",integrity:"sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/android-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",integrity:"sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/android-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",integrity:"sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">=18"}},"node_modules/@esbuild/darwin-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",integrity:"sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">=18"}},"node_modules/@esbuild/darwin-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",integrity:"sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">=18"}},"node_modules/@esbuild/freebsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",integrity:"sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">=18"}},"node_modules/@esbuild/freebsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",integrity:"sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">=18"}},"node_modules/@esbuild/linux-arm":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",integrity:"sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",integrity:"sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-ia32":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",integrity:"sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-loong64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",integrity:"sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-mips64el":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",integrity:"sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",cpu:["mips64el"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-ppc64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",integrity:"sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-riscv64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",integrity:"sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-s390x":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",integrity:"sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",cpu:["s390x"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/linux-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",integrity:"sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">=18"}},"node_modules/@esbuild/netbsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",integrity:"sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["netbsd"],engines:{node:">=18"}},"node_modules/@esbuild/netbsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",integrity:"sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["netbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openbsd-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",integrity:"sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openbsd-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",integrity:"sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"],engines:{node:">=18"}},"node_modules/@esbuild/openharmony-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",integrity:"sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openharmony"],engines:{node:">=18"}},"node_modules/@esbuild/sunos-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",integrity:"sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["sunos"],engines:{node:">=18"}},"node_modules/@esbuild/win32-arm64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",integrity:"sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@esbuild/win32-ia32":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",integrity:"sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@esbuild/win32-x64":{version:"0.25.12",resolved:"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",integrity:"sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">=18"}},"node_modules/@floating-ui/core":{version:"1.8.0",resolved:"https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz",integrity:"sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==",license:"MIT",dependencies:{"@floating-ui/utils":"^0.2.12"}},"node_modules/@floating-ui/dom":{version:"1.8.0",resolved:"https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz",integrity:"sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==",license:"MIT",dependencies:{"@floating-ui/core":"^1.8.0","@floating-ui/utils":"^0.2.12"}},"node_modules/@floating-ui/react-dom":{version:"2.1.9",resolved:"https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz",integrity:"sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==",license:"MIT",dependencies:{"@floating-ui/dom":"^1.8.0"},peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}},"node_modules/@floating-ui/utils":{version:"0.2.12",resolved:"https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz",integrity:"sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",license:"MIT"},"node_modules/@jridgewell/gen-mapping":{version:"0.3.13",resolved:"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",integrity:"sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",dev:!0,license:"MIT",dependencies:{"@jridgewell/sourcemap-codec":"^1.5.0","@jridgewell/trace-mapping":"^0.3.24"}},"node_modules/@jridgewell/remapping":{version:"2.3.5",resolved:"https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",integrity:"sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",dev:!0,license:"MIT",dependencies:{"@jridgewell/gen-mapping":"^0.3.5","@jridgewell/trace-mapping":"^0.3.24"}},"node_modules/@jridgewell/resolve-uri":{version:"3.1.2",resolved:"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",integrity:"sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",dev:!0,license:"MIT",engines:{node:">=6.0.0"}},"node_modules/@jridgewell/sourcemap-codec":{version:"1.5.5",resolved:"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",integrity:"sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",dev:!0,license:"MIT"},"node_modules/@jridgewell/trace-mapping":{version:"0.3.31",resolved:"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",integrity:"sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",dev:!0,license:"MIT",dependencies:{"@jridgewell/resolve-uri":"^3.1.0","@jridgewell/sourcemap-codec":"^1.4.14"}},"node_modules/@radix-ui/number":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz",integrity:"sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig==",license:"MIT"},"node_modules/@radix-ui/primitive":{version:"1.1.6",resolved:"https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.6.tgz",integrity:"sha512-w9hl+724uYEgCGR3bhuRepjBtrNB/6gkhCnAf58Ke+SLbHPPQqVZZB59z60roB+5H+nh3nWTcdJhQdFMEydWmw==",license:"MIT"},"node_modules/@radix-ui/react-arrow":{version:"1.1.12",resolved:"https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.12.tgz",integrity:"sha512-ltXCE0glRomMZ9+u10d9o1Go+edqa1aLxufH59JRNNM3Yz1uvaeNWSaS1HeVh1X64agtdBG5JA1W1I6ySqWiwA==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-checkbox":{version:"1.3.8",resolved:"https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.8.tgz",integrity:"sha512-wfN60IGuxynWK7rP4Ks2p7u9G7gqirzkAiFptuzVbsR1ot2/K+PavNUAtxiKxyRfLOvSbVfvvm9m3rFqLEXz7A==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-controllable-state":"1.2.4","@radix-ui/react-use-size":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-collection":{version:"1.1.12",resolved:"https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.12.tgz",integrity:"sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-compose-refs":{version:"1.1.3",resolved:"https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz",integrity:"sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-context":{version:"1.2.0",resolved:"https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.0.tgz",integrity:"sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-direction":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz",integrity:"sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-dismissable-layer":{version:"1.1.16",resolved:"https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.16.tgz",integrity:"sha512-t45h68IjFx0ccBnPJqk0X6ecv69LkCFWd6DNCFQX56mUnVEXZbNOLCH/u9fHlAjFZ1RrFdl8/m4zev7B7NyhXQ==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-effect-event":"0.0.3"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-focus-guards":{version:"1.1.4",resolved:"https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz",integrity:"sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-focus-scope":{version:"1.1.13",resolved:"https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.13.tgz",integrity:"sha512-dE04aPEuP9rvKKT0d0KjSOtTEYNg6bmCYFsoSJpfC+y91Hic28ZfDCGgv6aJ+2Kw/LBXYipMZpyqVj/OD3Z8Gg==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-id":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz",integrity:"sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-popover":{version:"1.1.20",resolved:"https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.20.tgz",integrity:"sha512-/PYqbsyuDkNj+IxMcRx71qNt6GelnuNulMwdCV7AtFEhUyK6XkbwreEN6CCLydMeTiDozBV4uv5aF5d12dDH7w==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-dismissable-layer":"1.1.16","@radix-ui/react-focus-guards":"1.1.4","@radix-ui/react-focus-scope":"1.1.13","@radix-ui/react-id":"1.1.2","@radix-ui/react-popper":"1.3.4","@radix-ui/react-portal":"1.1.14","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0","@radix-ui/react-use-controllable-state":"1.2.4","aria-hidden":"^1.2.4","react-remove-scroll":"^2.7.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-popper":{version:"1.3.4",resolved:"https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.4.tgz",integrity:"sha512-PXnCa3XgTQk0FegMctxgqJXtFLZe4IFJdbUkB7jKSCKEpb6utEO4S9Vog/pkyCfEPdzM331gvE4xpztmBAfMng==",license:"MIT",dependencies:{"@floating-ui/react-dom":"^2.0.0","@radix-ui/react-arrow":"1.1.12","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-layout-effect":"1.1.2","@radix-ui/react-use-rect":"1.1.2","@radix-ui/react-use-size":"1.1.2","@radix-ui/rect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-portal":{version:"1.1.14",resolved:"https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.14.tgz",integrity:"sha512-REwjAGPMa3J9oyDE4cuWkZbwnCbbyky66NurquQklXMSDn67cl6oGFx2gO7KZhPtFNbNw9xTWNrti3VIhgluYw==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7","@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-presence":{version:"1.1.8",resolved:"https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.8.tgz",integrity:"sha512-0hhyrQdXMaATgq4ammLG9+iPqsXxzZkgTSIxdrJHdfLnXO4Uo5L7BoO3/Xf0AEaettadGZWGGJMw6ujzQvIpGA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-primitive":{version:"2.1.7",resolved:"https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz",integrity:"sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==",license:"MIT",dependencies:{"@radix-ui/react-slot":"1.3.0"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-select":{version:"2.3.4",resolved:"https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.4.tgz",integrity:"sha512-E2JxqAvaTUEhWtBptWo02g8FnLYPymv9ahEvW/cZQPPV4ySeyo0M8n3sXccsLUAIfMbexnfXt91qF7UjTbTMMg==",license:"MIT",dependencies:{"@radix-ui/number":"1.1.2","@radix-ui/primitive":"1.1.6","@radix-ui/react-collection":"1.1.12","@radix-ui/react-compose-refs":"1.1.3","@radix-ui/react-context":"1.2.0","@radix-ui/react-direction":"1.1.2","@radix-ui/react-dismissable-layer":"1.1.16","@radix-ui/react-focus-guards":"1.1.4","@radix-ui/react-focus-scope":"1.1.13","@radix-ui/react-id":"1.1.2","@radix-ui/react-popper":"1.3.4","@radix-ui/react-portal":"1.1.14","@radix-ui/react-presence":"1.1.8","@radix-ui/react-primitive":"2.1.7","@radix-ui/react-slot":"1.3.0","@radix-ui/react-use-callback-ref":"1.1.2","@radix-ui/react-use-controllable-state":"1.2.4","@radix-ui/react-use-layout-effect":"1.1.2","@radix-ui/react-use-previous":"1.1.2","@radix-ui/react-visually-hidden":"1.2.8","aria-hidden":"^1.2.4","react-remove-scroll":"^2.7.2"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/react-slot":{version:"1.3.0",resolved:"https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz",integrity:"sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==",license:"MIT",dependencies:{"@radix-ui/react-compose-refs":"1.1.3"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-callback-ref":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz",integrity:"sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-controllable-state":{version:"1.2.4",resolved:"https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.4.tgz",integrity:"sha512-cx2DixxmSfjCcEoRvDvy1NLd6SWK94XFcEEOZUcharUlXbmahFQGKCfwdKZL2ub34iIwOPOEFVF80xb+yfLYiA==",license:"MIT",dependencies:{"@radix-ui/primitive":"1.1.6","@radix-ui/react-use-effect-event":"0.0.3","@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-effect-event":{version:"0.0.3",resolved:"https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz",integrity:"sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-layout-effect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz",integrity:"sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-previous":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.2.tgz",integrity:"sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw==",license:"MIT",peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-rect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz",integrity:"sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==",license:"MIT",dependencies:{"@radix-ui/rect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-use-size":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz",integrity:"sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==",license:"MIT",dependencies:{"@radix-ui/react-use-layout-effect":"1.1.2"},peerDependencies:{"@types/react":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/@radix-ui/react-visually-hidden":{version:"1.2.8",resolved:"https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.8.tgz",integrity:"sha512-FjsQEpkNBJJYiPSat6jh2LGKLPX2jAoDVS3AZSBNX3cOUoEGhw/f+z2FCY8Cf1NkoYIbytJ1f4mlWPQpR+MjVg==",license:"MIT",dependencies:{"@radix-ui/react-primitive":"2.1.7"},peerDependencies:{"@types/react":"*","@types/react-dom":"*",react:"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc","react-dom":"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0},"@types/react-dom":{optional:!0}}},"node_modules/@radix-ui/rect":{version:"1.1.2",resolved:"https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz",integrity:"sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==",license:"MIT"},"node_modules/@rollup/rollup-android-arm-eabi":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",integrity:"sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["android"]},"node_modules/@rollup/rollup-android-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",integrity:"sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"]},"node_modules/@rollup/rollup-darwin-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",integrity:"sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"]},"node_modules/@rollup/rollup-darwin-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",integrity:"sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"]},"node_modules/@rollup/rollup-freebsd-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",integrity:"sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"]},"node_modules/@rollup/rollup-freebsd-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",integrity:"sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"]},"node_modules/@rollup/rollup-linux-arm-gnueabihf":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",integrity:"sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm-musleabihf":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",integrity:"sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",integrity:"sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-arm64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",integrity:"sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-loong64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",integrity:"sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-loong64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",integrity:"sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",cpu:["loong64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-ppc64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",integrity:"sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-ppc64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",integrity:"sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",cpu:["ppc64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-riscv64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",integrity:"sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-riscv64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",integrity:"sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",cpu:["riscv64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-s390x-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",integrity:"sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",cpu:["s390x"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-x64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",integrity:"sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-linux-x64-musl":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",integrity:"sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"]},"node_modules/@rollup/rollup-openbsd-x64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",integrity:"sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["openbsd"]},"node_modules/@rollup/rollup-openharmony-arm64":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",integrity:"sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["openharmony"]},"node_modules/@rollup/rollup-win32-arm64-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",integrity:"sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-ia32-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",integrity:"sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",cpu:["ia32"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-x64-gnu":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",integrity:"sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@rollup/rollup-win32-x64-msvc":{version:"4.62.2",resolved:"https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",integrity:"sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"]},"node_modules/@tabby_ai/hijri-converter":{version:"1.0.5",resolved:"https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz",integrity:"sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==",license:"MIT",engines:{node:">=16.0.0"}},"node_modules/@tailwindcss/node":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",integrity:"sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==",dev:!0,license:"MIT",dependencies:{"@jridgewell/remapping":"^2.3.5","enhanced-resolve":"^5.19.0",jiti:"^2.6.1",lightningcss:"1.32.0","magic-string":"^0.30.21","source-map-js":"^1.2.1",tailwindcss:"4.2.2"}},"node_modules/@tailwindcss/oxide":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz",integrity:"sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==",dev:!0,license:"MIT",engines:{node:">= 20"},optionalDependencies:{"@tailwindcss/oxide-android-arm64":"4.2.2","@tailwindcss/oxide-darwin-arm64":"4.2.2","@tailwindcss/oxide-darwin-x64":"4.2.2","@tailwindcss/oxide-freebsd-x64":"4.2.2","@tailwindcss/oxide-linux-arm-gnueabihf":"4.2.2","@tailwindcss/oxide-linux-arm64-gnu":"4.2.2","@tailwindcss/oxide-linux-arm64-musl":"4.2.2","@tailwindcss/oxide-linux-x64-gnu":"4.2.2","@tailwindcss/oxide-linux-x64-musl":"4.2.2","@tailwindcss/oxide-wasm32-wasi":"4.2.2","@tailwindcss/oxide-win32-arm64-msvc":"4.2.2","@tailwindcss/oxide-win32-x64-msvc":"4.2.2"}},"node_modules/@tailwindcss/oxide-android-arm64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz",integrity:"sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["android"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-darwin-arm64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz",integrity:"sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-darwin-x64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz",integrity:"sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-freebsd-x64":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz",integrity:"sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["freebsd"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz",integrity:"sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==",cpu:["arm"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm64-gnu":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz",integrity:"sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-arm64-musl":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz",integrity:"sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-x64-gnu":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz",integrity:"sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-linux-x64-musl":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz",integrity:"sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["linux"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-wasm32-wasi":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz",integrity:"sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==",bundleDependencies:["@napi-rs/wasm-runtime","@emnapi/core","@emnapi/runtime","@tybys/wasm-util","@emnapi/wasi-threads","tslib"],cpu:["wasm32"],dev:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/core":"^1.8.1","@emnapi/runtime":"^1.8.1","@emnapi/wasi-threads":"^1.1.0","@napi-rs/wasm-runtime":"^1.1.1","@tybys/wasm-util":"^0.10.1",tslib:"^2.8.1"},engines:{node:">=14.0.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core":{version:"1.8.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/wasi-threads":"1.1.0",tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime":{version:"1.8.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads":{version:"1.1.0",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime":{version:"1.1.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{"@emnapi/core":"^1.7.1","@emnapi/runtime":"^1.7.1","@tybys/wasm-util":"^0.10.1"},funding:{type:"github",url:"https://github.com/sponsors/Brooooooklyn"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util":{version:"0.10.1",dev:!0,inBundle:!0,license:"MIT",optional:!0,dependencies:{tslib:"^2.4.0"}},"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib":{version:"2.8.1",dev:!0,inBundle:!0,license:"0BSD",optional:!0},"node_modules/@tailwindcss/oxide-win32-arm64-msvc":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz",integrity:"sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==",cpu:["arm64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">= 20"}},"node_modules/@tailwindcss/oxide-win32-x64-msvc":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz",integrity:"sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==",cpu:["x64"],dev:!0,license:"MIT",optional:!0,os:["win32"],engines:{node:">= 20"}},"node_modules/@tailwindcss/vite":{version:"4.2.2",resolved:"https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz",integrity:"sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==",dev:!0,license:"MIT",dependencies:{"@tailwindcss/node":"4.2.2","@tailwindcss/oxide":"4.2.2",tailwindcss:"4.2.2"},peerDependencies:{vite:"^5.2.0 || ^6 || ^7 || ^8"}},"node_modules/@types/babel__core":{version:"7.20.5",resolved:"https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",integrity:"sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.20.7","@babel/types":"^7.20.7","@types/babel__generator":"*","@types/babel__template":"*","@types/babel__traverse":"*"}},"node_modules/@types/babel__generator":{version:"7.27.0",resolved:"https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",integrity:"sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.0.0"}},"node_modules/@types/babel__template":{version:"7.4.4",resolved:"https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",integrity:"sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",dev:!0,license:"MIT",dependencies:{"@babel/parser":"^7.1.0","@babel/types":"^7.0.0"}},"node_modules/@types/babel__traverse":{version:"7.28.0",resolved:"https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",integrity:"sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",dev:!0,license:"MIT",dependencies:{"@babel/types":"^7.28.2"}},"node_modules/@types/estree":{version:"1.0.9",resolved:"https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",integrity:"sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",dev:!0,license:"MIT"},"node_modules/@types/node":{version:"22.15.17",resolved:"https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",integrity:"sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",dev:!0,license:"MIT",dependencies:{"undici-types":"~6.21.0"}},"node_modules/@types/react":{version:"19.2.2",resolved:"https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",integrity:"sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",devOptional:!0,license:"MIT",dependencies:{csstype:"^3.0.2"}},"node_modules/@types/react-dom":{version:"19.2.2",resolved:"https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz",integrity:"sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",devOptional:!0,license:"MIT",peerDependencies:{"@types/react":"^19.2.0"}},"node_modules/@vitejs/plugin-react":{version:"4.3.4",resolved:"https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",integrity:"sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",dev:!0,license:"MIT",dependencies:{"@babel/core":"^7.26.0","@babel/plugin-transform-react-jsx-self":"^7.25.9","@babel/plugin-transform-react-jsx-source":"^7.25.9","@types/babel__core":"^7.20.5","react-refresh":"^0.14.2"},engines:{node:"^14.18.0 || >=16.0.0"},peerDependencies:{vite:"^4.2.0 || ^5.0.0 || ^6.0.0"}},"node_modules/aria-hidden":{version:"1.2.6",resolved:"https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",integrity:"sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",license:"MIT",dependencies:{tslib:"^2.0.0"},engines:{node:">=10"}},"node_modules/baseline-browser-mapping":{version:"2.11.0",resolved:"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.0.tgz",integrity:"sha512-oCu2wfipvX3AePSgmOuKkIywOu+8n9psz7hXYmk56ghpu3+7KzNIBopaOs4c9BrtdnTtW30unG9GTfHo7EwERQ==",dev:!0,license:"Apache-2.0",bin:{"baseline-browser-mapping":"dist/cli.cjs"},engines:{node:">=6.0.0"}},"node_modules/browserslist":{version:"4.28.6",resolved:"https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz",integrity:"sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/browserslist"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{"baseline-browser-mapping":"^2.10.42","caniuse-lite":"^1.0.30001803","electron-to-chromium":"^1.5.389","node-releases":"^2.0.51","update-browserslist-db":"^1.2.3"},bin:{browserslist:"cli.js"},engines:{node:"^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"}},"node_modules/caniuse-lite":{version:"1.0.30001806",resolved:"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",integrity:"sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/caniuse-lite"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"CC-BY-4.0"},"node_modules/convert-source-map":{version:"2.0.0",resolved:"https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",integrity:"sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",dev:!0,license:"MIT"},"node_modules/csstype":{version:"3.2.3",resolved:"https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",integrity:"sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",devOptional:!0,license:"MIT"},"node_modules/date-fns":{version:"4.4.0",resolved:"https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz",integrity:"sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==",license:"MIT",funding:{type:"github",url:"https://github.com/sponsors/kossnocorp"}},"node_modules/date-fns-jalali":{version:"4.1.0-0",resolved:"https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",integrity:"sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==",license:"MIT"},"node_modules/debug":{version:"4.4.3",resolved:"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",integrity:"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",dev:!0,license:"MIT",dependencies:{ms:"^2.1.3"},engines:{node:">=6.0"},peerDependenciesMeta:{"supports-color":{optional:!0}}},"node_modules/detect-libc":{version:"2.1.2",resolved:"https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",integrity:"sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",dev:!0,license:"Apache-2.0",engines:{node:">=8"}},"node_modules/detect-node-es":{version:"1.1.0",resolved:"https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",integrity:"sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",license:"MIT"},"node_modules/electron-to-chromium":{version:"1.5.394",resolved:"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.394.tgz",integrity:"sha512-Wmt2Gm0o8JWBuGgmc4XZ0u9s1RaCRqhxP47phplmfg04+qypTUurpeJGP45A7Fhv7jdrrVH44PLlR9qXo37cVQ==",dev:!0,license:"ISC"},"node_modules/enhanced-resolve":{version:"5.24.3",resolved:"https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz",integrity:"sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==",dev:!0,license:"MIT",dependencies:{"graceful-fs":"^4.2.4",tapable:"^2.3.3"},engines:{node:">=10.13.0"}},"node_modules/esbuild":{version:"0.25.12",resolved:"https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",integrity:"sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",dev:!0,hasInstallScript:!0,license:"MIT",bin:{esbuild:"bin/esbuild"},engines:{node:">=18"},optionalDependencies:{"@esbuild/aix-ppc64":"0.25.12","@esbuild/android-arm":"0.25.12","@esbuild/android-arm64":"0.25.12","@esbuild/android-x64":"0.25.12","@esbuild/darwin-arm64":"0.25.12","@esbuild/darwin-x64":"0.25.12","@esbuild/freebsd-arm64":"0.25.12","@esbuild/freebsd-x64":"0.25.12","@esbuild/linux-arm":"0.25.12","@esbuild/linux-arm64":"0.25.12","@esbuild/linux-ia32":"0.25.12","@esbuild/linux-loong64":"0.25.12","@esbuild/linux-mips64el":"0.25.12","@esbuild/linux-ppc64":"0.25.12","@esbuild/linux-riscv64":"0.25.12","@esbuild/linux-s390x":"0.25.12","@esbuild/linux-x64":"0.25.12","@esbuild/netbsd-arm64":"0.25.12","@esbuild/netbsd-x64":"0.25.12","@esbuild/openbsd-arm64":"0.25.12","@esbuild/openbsd-x64":"0.25.12","@esbuild/openharmony-arm64":"0.25.12","@esbuild/sunos-x64":"0.25.12","@esbuild/win32-arm64":"0.25.12","@esbuild/win32-ia32":"0.25.12","@esbuild/win32-x64":"0.25.12"}},"node_modules/escalade":{version:"3.2.0",resolved:"https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",integrity:"sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",dev:!0,license:"MIT",engines:{node:">=6"}},"node_modules/fdir":{version:"6.5.0",resolved:"https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",integrity:"sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",dev:!0,license:"MIT",engines:{node:">=12.0.0"},peerDependencies:{picomatch:"^3 || ^4"},peerDependenciesMeta:{picomatch:{optional:!0}}},"node_modules/fsevents":{version:"2.3.3",resolved:"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",integrity:"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",dev:!0,hasInstallScript:!0,license:"MIT",optional:!0,os:["darwin"],engines:{node:"^8.16.0 || ^10.6.0 || >=11.0.0"}},"node_modules/gensync":{version:"1.0.0-beta.2",resolved:"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",integrity:"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",dev:!0,license:"MIT",engines:{node:">=6.9.0"}},"node_modules/get-nonce":{version:"1.0.1",resolved:"https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",integrity:"sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",license:"MIT",engines:{node:">=6"}},"node_modules/get-tsconfig":{version:"4.14.0",resolved:"https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz",integrity:"sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==",dev:!0,license:"MIT",dependencies:{"resolve-pkg-maps":"^1.0.0"},funding:{url:"https://github.com/privatenumber/get-tsconfig?sponsor=1"}},"node_modules/graceful-fs":{version:"4.2.11",resolved:"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",integrity:"sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",dev:!0,license:"ISC"},"node_modules/jiti":{version:"2.7.0",resolved:"https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",integrity:"sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",dev:!0,license:"MIT",bin:{jiti:"lib/jiti-cli.mjs"}},"node_modules/js-tokens":{version:"4.0.0",resolved:"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",integrity:"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",license:"MIT"},"node_modules/jsesc":{version:"3.1.0",resolved:"https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",integrity:"sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",dev:!0,license:"MIT",bin:{jsesc:"bin/jsesc"},engines:{node:">=6"}},"node_modules/json5":{version:"2.2.3",resolved:"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",integrity:"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",dev:!0,license:"MIT",bin:{json5:"lib/cli.js"},engines:{node:">=6"}},"node_modules/lightningcss":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",integrity:"sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",dev:!0,license:"MPL-2.0",dependencies:{"detect-libc":"^2.0.3"},engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"},optionalDependencies:{"lightningcss-android-arm64":"1.32.0","lightningcss-darwin-arm64":"1.32.0","lightningcss-darwin-x64":"1.32.0","lightningcss-freebsd-x64":"1.32.0","lightningcss-linux-arm-gnueabihf":"1.32.0","lightningcss-linux-arm64-gnu":"1.32.0","lightningcss-linux-arm64-musl":"1.32.0","lightningcss-linux-x64-gnu":"1.32.0","lightningcss-linux-x64-musl":"1.32.0","lightningcss-win32-arm64-msvc":"1.32.0","lightningcss-win32-x64-msvc":"1.32.0"}},"node_modules/lightningcss-android-arm64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",integrity:"sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["android"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-darwin-arm64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",integrity:"sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["darwin"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-darwin-x64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",integrity:"sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["darwin"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-freebsd-x64":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",integrity:"sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["freebsd"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm-gnueabihf":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",integrity:"sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",cpu:["arm"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm64-gnu":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",integrity:"sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-arm64-musl":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",integrity:"sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-x64-gnu":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",integrity:"sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-linux-x64-musl":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",integrity:"sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["linux"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-win32-arm64-msvc":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",integrity:"sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",cpu:["arm64"],dev:!0,license:"MPL-2.0",optional:!0,os:["win32"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/lightningcss-win32-x64-msvc":{version:"1.32.0",resolved:"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",integrity:"sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",cpu:["x64"],dev:!0,license:"MPL-2.0",optional:!0,os:["win32"],engines:{node:">= 12.0.0"},funding:{type:"opencollective",url:"https://opencollective.com/parcel"}},"node_modules/loose-envify":{version:"1.4.0",resolved:"https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",integrity:"sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",license:"MIT",dependencies:{"js-tokens":"^3.0.0 || ^4.0.0"},bin:{"loose-envify":"cli.js"}},"node_modules/lru-cache":{version:"5.1.1",resolved:"https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",integrity:"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",dev:!0,license:"ISC",dependencies:{yallist:"^3.0.2"}},"node_modules/lucide-react":{version:"0.577.0",resolved:"https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz",integrity:"sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==",license:"ISC",peerDependencies:{react:"^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"}},"node_modules/magic-string":{version:"0.30.21",resolved:"https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",integrity:"sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",dev:!0,license:"MIT",dependencies:{"@jridgewell/sourcemap-codec":"^1.5.5"}},"node_modules/ms":{version:"2.1.3",resolved:"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",integrity:"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",dev:!0,license:"MIT"},"node_modules/nanoid":{version:"3.3.16",resolved:"https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",integrity:"sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",dev:!0,funding:[{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",bin:{nanoid:"bin/nanoid.cjs"},engines:{node:"^10 || ^12 || ^13.7 || ^14 || >=15.0.1"}},"node_modules/node-releases":{version:"2.0.51",resolved:"https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",integrity:"sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",dev:!0,license:"MIT",engines:{node:">=18"}},"node_modules/picocolors":{version:"1.1.1",resolved:"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",integrity:"sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",dev:!0,license:"ISC"},"node_modules/picomatch":{version:"4.0.5",resolved:"https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",integrity:"sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",dev:!0,license:"MIT",engines:{node:">=12"},funding:{url:"https://github.com/sponsors/jonschlinkert"}},"node_modules/postcss":{version:"8.5.21",resolved:"https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz",integrity:"sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/postcss/"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/postcss"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{nanoid:"^3.3.16",picocolors:"^1.1.1","source-map-js":"^1.2.1"},engines:{node:"^10 || ^12 || >=14"}},"node_modules/react":{version:"18.3.1",resolved:"https://registry.npmjs.org/react/-/react-18.3.1.tgz",integrity:"sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",license:"MIT",dependencies:{"loose-envify":"^1.1.0"},engines:{node:">=0.10.0"}},"node_modules/react-day-picker":{version:"9.14.0",resolved:"https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz",integrity:"sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==",license:"MIT",dependencies:{"@date-fns/tz":"^1.4.1","@tabby_ai/hijri-converter":"1.0.5","date-fns":"^4.1.0","date-fns-jalali":"4.1.0-0"},engines:{node:">=18"},funding:{type:"individual",url:"https://github.com/sponsors/gpbl"},peerDependencies:{react:">=16.8.0"}},"node_modules/react-dom":{version:"18.3.1",resolved:"https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",integrity:"sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",license:"MIT",dependencies:{"loose-envify":"^1.1.0",scheduler:"^0.23.2"},peerDependencies:{react:"^18.3.1"}},"node_modules/react-refresh":{version:"0.14.2",resolved:"https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",integrity:"sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",dev:!0,license:"MIT",engines:{node:">=0.10.0"}},"node_modules/react-remove-scroll":{version:"2.7.2",resolved:"https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",integrity:"sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",license:"MIT",dependencies:{"react-remove-scroll-bar":"^2.3.7","react-style-singleton":"^2.2.3",tslib:"^2.1.0","use-callback-ref":"^1.3.3","use-sidecar":"^1.1.3"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/react-remove-scroll-bar":{version:"2.3.8",resolved:"https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",integrity:"sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",license:"MIT",dependencies:{"react-style-singleton":"^2.2.2",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/react-style-singleton":{version:"2.2.3",resolved:"https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",integrity:"sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",license:"MIT",dependencies:{"get-nonce":"^1.0.0",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/resolve-pkg-maps":{version:"1.0.0",resolved:"https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",integrity:"sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",dev:!0,license:"MIT",funding:{url:"https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"}},"node_modules/rollup":{version:"4.62.2",resolved:"https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",integrity:"sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",dev:!0,license:"MIT",dependencies:{"@types/estree":"1.0.9"},bin:{rollup:"dist/bin/rollup"},engines:{node:">=18.0.0",npm:">=8.0.0"},optionalDependencies:{"@rollup/rollup-android-arm-eabi":"4.62.2","@rollup/rollup-android-arm64":"4.62.2","@rollup/rollup-darwin-arm64":"4.62.2","@rollup/rollup-darwin-x64":"4.62.2","@rollup/rollup-freebsd-arm64":"4.62.2","@rollup/rollup-freebsd-x64":"4.62.2","@rollup/rollup-linux-arm-gnueabihf":"4.62.2","@rollup/rollup-linux-arm-musleabihf":"4.62.2","@rollup/rollup-linux-arm64-gnu":"4.62.2","@rollup/rollup-linux-arm64-musl":"4.62.2","@rollup/rollup-linux-loong64-gnu":"4.62.2","@rollup/rollup-linux-loong64-musl":"4.62.2","@rollup/rollup-linux-ppc64-gnu":"4.62.2","@rollup/rollup-linux-ppc64-musl":"4.62.2","@rollup/rollup-linux-riscv64-gnu":"4.62.2","@rollup/rollup-linux-riscv64-musl":"4.62.2","@rollup/rollup-linux-s390x-gnu":"4.62.2","@rollup/rollup-linux-x64-gnu":"4.62.2","@rollup/rollup-linux-x64-musl":"4.62.2","@rollup/rollup-openbsd-x64":"4.62.2","@rollup/rollup-openharmony-arm64":"4.62.2","@rollup/rollup-win32-arm64-msvc":"4.62.2","@rollup/rollup-win32-ia32-msvc":"4.62.2","@rollup/rollup-win32-x64-gnu":"4.62.2","@rollup/rollup-win32-x64-msvc":"4.62.2",fsevents:"~2.3.2"}},"node_modules/scheduler":{version:"0.23.2",resolved:"https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",integrity:"sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",license:"MIT",dependencies:{"loose-envify":"^1.1.0"}},"node_modules/semver":{version:"6.3.1",resolved:"https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",integrity:"sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",dev:!0,license:"ISC",bin:{semver:"bin/semver.js"}},"node_modules/source-map-js":{version:"1.2.1",resolved:"https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",integrity:"sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",dev:!0,license:"BSD-3-Clause",engines:{node:">=0.10.0"}},"node_modules/tailwindcss":{version:"4.2.2",resolved:"https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",integrity:"sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",dev:!0,license:"MIT"},"node_modules/tapable":{version:"2.3.3",resolved:"https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",integrity:"sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",dev:!0,license:"MIT",engines:{node:">=6"},funding:{type:"opencollective",url:"https://opencollective.com/webpack"}},"node_modules/tinyglobby":{version:"0.2.17",resolved:"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",integrity:"sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",dev:!0,license:"MIT",dependencies:{fdir:"^6.5.0",picomatch:"^4.0.4"},engines:{node:">=12.0.0"},funding:{url:"https://github.com/sponsors/SuperchupuDev"}},"node_modules/tslib":{version:"2.8.1",resolved:"https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",integrity:"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",license:"0BSD"},"node_modules/tsx":{version:"4.19.4",resolved:"https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz",integrity:"sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==",dev:!0,license:"MIT",dependencies:{esbuild:"~0.25.0","get-tsconfig":"^4.7.5"},bin:{tsx:"dist/cli.mjs"},engines:{node:">=18.0.0"},optionalDependencies:{fsevents:"~2.3.3"}},"node_modules/typescript":{version:"5.8.2",resolved:"https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",integrity:"sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",dev:!0,license:"Apache-2.0",bin:{tsc:"bin/tsc",tsserver:"bin/tsserver"},engines:{node:">=14.17"}},"node_modules/undici-types":{version:"6.21.0",resolved:"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",integrity:"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",dev:!0,license:"MIT"},"node_modules/update-browserslist-db":{version:"1.2.3",resolved:"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",integrity:"sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",dev:!0,funding:[{type:"opencollective",url:"https://opencollective.com/browserslist"},{type:"tidelift",url:"https://tidelift.com/funding/github/npm/browserslist"},{type:"github",url:"https://github.com/sponsors/ai"}],license:"MIT",dependencies:{escalade:"^3.2.0",picocolors:"^1.1.1"},bin:{"update-browserslist-db":"cli.js"},peerDependencies:{browserslist:">= 4.21.0"}},"node_modules/use-callback-ref":{version:"1.3.3",resolved:"https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",integrity:"sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",license:"MIT",dependencies:{tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/use-sidecar":{version:"1.1.3",resolved:"https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",integrity:"sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",license:"MIT",dependencies:{"detect-node-es":"^1.1.0",tslib:"^2.0.0"},engines:{node:">=10"},peerDependencies:{"@types/react":"*",react:"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"},peerDependenciesMeta:{"@types/react":{optional:!0}}},"node_modules/vite":{version:"6.3.5",resolved:"https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",integrity:"sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",dev:!0,license:"MIT",dependencies:{esbuild:"^0.25.0",fdir:"^6.4.4",picomatch:"^4.0.2",postcss:"^8.5.3",rollup:"^4.34.9",tinyglobby:"^0.2.13"},bin:{vite:"bin/vite.js"},engines:{node:"^18.0.0 || ^20.0.0 || >=22.0.0"},funding:{url:"https://github.com/vitejs/vite?sponsor=1"},optionalDependencies:{fsevents:"~2.3.3"},peerDependencies:{"@types/node":"^18.0.0 || ^20.0.0 || >=22.0.0",jiti:">=1.21.0",less:"*",lightningcss:"^1.21.0",sass:"*","sass-embedded":"*",stylus:"*",sugarss:"*",terser:"^5.16.0",tsx:"^4.8.1",yaml:"^2.4.2"},peerDependenciesMeta:{"@types/node":{optional:!0},jiti:{optional:!0},less:{optional:!0},lightningcss:{optional:!0},sass:{optional:!0},"sass-embedded":{optional:!0},stylus:{optional:!0},sugarss:{optional:!0},terser:{optional:!0},tsx:{optional:!0},yaml:{optional:!0}}},"node_modules/yallist":{version:"3.1.1",resolved:"https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",integrity:"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",dev:!0,license:"ISC"}}};function readTemplateBlockSource2(relativePath){let fileUrl=[new URL(`../template-blocks/${relativePath}`,import.meta.url),new URL(`../../src/template-blocks/${relativePath}`,import.meta.url)].find(candidate=>existsSync3(candidate));if(!fileUrl)throw new Error(`Missing template block source for ${relativePath}`);return readFileSync3(fileUrl,"utf8")}function scaffoldTemplateBlock2(relativePath,outputPath){return{path:outputPath,content:readTemplateBlockSource2(relativePath)}}function buildAppYamlSource(templatePackageName){return[`name: ${templatePackageName}`,"version: 0.1.0","entry:"," command: npm run dev"," port: 3000"," health_check: /healthz",""].join(`
|
|
2143
|
+
`)}function buildPackageJsonManifest(templatePackageName){return{name:templatePackageName,version:"0.1.0",private:!0,packageManager:"npm@10.9.2",engines:{node:">=20.0.0"},type:"module",scripts:{dev:"node ./scripts/dev.mjs","dev:web":"vite --config vite.config.ts","dev:server":"tsx watch src/server/entry.ts",build:"npm run build:web && npm run build:server","build:web":"vite build","build:server":"tsc -p tsconfig.server.json",preview:"vite preview",start:"node dist/server/entry.js"},dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",tsx:"4.19.4",typescript:"5.8.2",vite:"6.3.5"}}}function buildPackageJsonSource(templatePackageName){return JSON.stringify(buildPackageJsonManifest(templatePackageName),null,2)+`
|
|
2144
|
+
`}function buildPackageLockSource(templatePackageName){let lockfile=structuredClone(BACKEND_APP_NODE_PACKAGE_LOCK);return lockfile.name=templatePackageName,lockfile.packages[""].name=templatePackageName,JSON.stringify(lockfile,null,2)+`
|
|
2145
2145
|
`}function buildReadmeSource(){return["# Backend App \u4F7F\u7528\u8BF4\u660E","","\u8FD9\u4E2A\u6A21\u677F\u9002\u5408\u9700\u8981\u79C1\u6709 API\u3001\u6570\u636E\u5E93\u3001Webhook\u3001\u4EFB\u52A1\u5904\u7406\uFF0C\u6216\u9700\u8981\u670D\u52A1\u7AEF\u76F4\u51FA HTML \u7684 SEO \u53CB\u597D\u9875\u9762\u578B\u8F7B\u5E94\u7528\u3002","\u5B83\u7684\u524D\u7AEF\u9875\u9762\u5C42\u548C\u524D\u7AEF\u6A21\u677F\u4FDD\u6301\u540C\u4E00\u5957\u4F7F\u7528\u65B9\u5F0F\uFF0C\u4F46\u9ED8\u8BA4\u4F1A\u4F18\u5148\u751F\u6210\u4E00\u6761\u670D\u52A1\u7AEF SEO \u9875\u9762\u4E3B\u94FE\u3002","","## \u5148\u770B\u8FD9\u51E0\u4E2A\u76EE\u5F55","","- `src/web/*`\uFF1A\u524D\u7AEF\u9875\u9762\u3001\u7EC4\u4EF6\u548C\u5E73\u53F0\u63A5\u5165","- `src/server/entry.ts`\uFF1A\u670D\u52A1\u5165\u53E3","- `src/server/app.ts`\uFF1AHTTP \u8DEF\u7531\u88C5\u914D\uFF0C\u4E5F\u662F platform-managed \u8584\u58F3\u5165\u53E3","- `src/server/routes/api.ts`\uFF1A\u4E1A\u52A1 API","- `src/server/routes/seo-pages.ts`\uFF1ASEO \u9875\u9762\u4E3B\u94FE\u8DEF\u7531\uFF0C\u4E5F\u662F platform-managed \u8584\u58F3\u5165\u53E3","- `src/server/lib/seo-html.ts`\uFF1A\u9875\u9762 HTML \u7EC4\u88C5\u5668","- `src/server/lib/cms-seo.ts`\uFF1ACMS SEO \u6570\u636E\u67E5\u8BE2\u4E0E\u6620\u5C04","- `src/server/platform/cms.ts`\uFF1A\u670D\u52A1\u7AEF CMS helper","- `src/server/content/site-config.ts`\uFF1A\u7AD9\u70B9\u7EA7 SEO \u914D\u7F6E","- `src/server/content/static-pages.ts`\uFF1A\u9759\u6001\u9875\u5185\u5BB9","- `src/server/platform/data-form.ts`\uFF1A\u670D\u52A1\u7AEF Data Form helper","- `src/server/platform/runtime.ts`\uFF1A\u670D\u52A1\u7AEF\u5E73\u53F0\u63A5\u5165","- `resources/db/migrations/*.sql`\uFF1A\u6570\u636E\u5E93\u8FC1\u79FB","- `index.html`\uFF1A\u524D\u7AEF app shell \u6A21\u677F\uFF0Cserver \u4F1A\u5728\u8FD4\u56DE\u524D\u6CE8\u5165\u8FD0\u884C\u65F6\u914D\u7F6E\u548C `<base href>`","- `public/auth` \u4E0E `public/__app`\uFF1A\u767B\u5F55\u9875\u9759\u6001\u5165\u53E3\u3001\u767B\u5F55\u9875\u6587\u6848\u548C\u5C40\u90E8\u6837\u5F0F\u8986\u76D6","","## \u9ED8\u8BA4\u9875\u9762\u4E3B\u94FE","","- `/`\uFF1A\u670D\u52A1\u7AEF\u9996\u9875\uFF0C\u9996\u5C4F HTML \u53EF\u76F4\u63A5\u6293\u53D6","- `/about`\uFF1A\u670D\u52A1\u7AEF\u9759\u6001\u9875\u793A\u4F8B","- `/contact`\uFF1A\u670D\u52A1\u7AEF\u8054\u7CFB\u9875\u793A\u4F8B","- `/articles`\uFF1A\u670D\u52A1\u7AEF CMS \u5217\u8868\u9875","- `/articles/:slug`\uFF1A\u670D\u52A1\u7AEF CMS \u8BE6\u60C5\u9875","- `/app`\uFF1A\u524D\u7AEF SPA \u5E94\u7528\u9996\u9875\uFF0C\u5BF9\u5E94 `src/web/pages/HomePage.tsx`","- `/protected`\uFF1A\u524D\u7AEF\u4FDD\u62A4\u9875\u793A\u4F8B\uFF0C\u5BF9\u5E94 `src/web/pages/ProtectedPage.tsx`","- `/form`\uFF1A\u524D\u7AEF\u8868\u5355\u9875\u793A\u4F8B\uFF0C\u5BF9\u5E94 `src/web/pages/FormPage.tsx`","- `/cms`\uFF1A\u524D\u7AEF CMS \u80FD\u529B\u793A\u4F8B\u9875\uFF0C\u5BF9\u5E94 `src/web/pages/CmsPage.tsx`\uFF0C\u4E0D\u4F5C\u4E3A\u6B63\u5F0F\u5185\u5BB9\u7AD9\u4E3B\u8DEF\u5F84","","## \u63A8\u8350\u5F00\u53D1\u65B9\u5F0F","","- \u65E5\u5E38\u5F00\u53D1\u76F4\u63A5\u7528 `platform dev`\uFF0C\u6A21\u677F\u4F1A\u81EA\u52A8\u62C9\u8D77\u524D\u7AEF\u70ED\u66F4\u65B0\u548C server \u81EA\u52A8\u91CD\u542F\u3002","- \u9700\u8981\u8054\u8C03\u8FDC\u7AEF\u80FD\u529B\u65F6\u7EE7\u7EED\u5728 `platform dev` \u4E0A\u52A0 `--remote-bindings`\uFF0C\u4F8B\u5982 `platform dev --remote-bindings=db`\u3002","- \u4E91\u7AEF\u9A8C\u8BC1\u7528 `platform preview generate`\uFF0C\u6B63\u5F0F\u53D1\u5E03\u7528 `platform publish`\u3002","- SEO \u9875\u9762\u4F18\u5148\u4ECE `src/server/*` \u8D77\u6B65\uFF1B\u524D\u7AEF `src/web/*` \u53EA\u627F\u62C5 SPA \u5E94\u7528\u9996\u9875\u3001\u8868\u5355\u9875\u3001\u4FDD\u62A4\u9875\u548C\u80FD\u529B\u793A\u4F8B\u9875\u3002","- \u6D4F\u89C8\u5668\u59CB\u7EC8\u8BBF\u95EE public port\uFF0C`/api` \u548C `/healthz` \u4F1A\u901A\u8FC7 Vite \u4EE3\u7406\u5230\u672C\u5730 backend \u8FDB\u7A0B\uFF1B\u6392\u67E5\u672C\u5730\u8054\u8C03\u95EE\u9898\u65F6\u5148\u6309\u8FD9\u4E2A\u5FC3\u667A\u7406\u89E3\u3002","- \u65B0\u5EFA app \u4F1A\u9ED8\u8BA4\u751F\u6210 `.platform/platform-blocks.lock.json`\uFF1B\u5982\u679C\u4F60 checkout \u7684\u662F\u5386\u53F2 app\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt` \u8865\u7EB3\u7BA1\u3002","- \u63A8\u8350\u540C\u6B65\u987A\u5E8F\uFF1A`platform app sync-platform-blocks --dry-run` -> `--apply` -> \u672C\u5730\u9A8C\u8BC1\uFF1B\u9700\u8981\u65F6\u518D `--rollback --last`\u3002","","## \u5E38\u89C1\u5751","","- \u4E0D\u8981\u5728\u9875\u9762\u91CC\u5199\u6B7B `/previews/...`\u3001`/apps/...`\u3001`https://...` \u8FD9\u7C7B\u5E73\u53F0\u8DEF\u5F84\u524D\u7F00\u3002","- \u6D4F\u89C8\u5668\u4FA7\u8BF7\u6C42\u548C\u8DF3\u8F6C\u4F18\u5148\u7528\u6A21\u677F\u5DF2\u6709 helper\uFF1B\u5982\u679C\u53EA\u662F\u540C\u6E90\u63A5\u53E3\u6216\u9759\u6001\u8D44\u6E90\uFF0C\u4F18\u5148\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 `./api/...`\u3001`./assets/...`\u3002",'- \u4E0D\u8981\u76F4\u63A5\u5199\u6839\u8DEF\u5F84\u5F15\u7528\uFF0C\u4F8B\u5982 `fetch(\'/api/...\')`\u3001`href="/..."`\u3001`src="/..."`\uFF0C\u8FD9\u7C7B\u5199\u6CD5\u5728 preview path \u6A21\u5F0F\u4E0B\u6700\u5BB9\u6613\u51FA\u9519\u3002',"- `src/web/*` \u8D1F\u8D23\u524D\u7AEF\u4EA4\u4E92\u578B\u9875\u9762\uFF1B`src/server/*` \u8D1F\u8D23\u79C1\u6709 API \u4E0E SEO \u9875\u9762\u76F4\u51FA\uFF0C\u4E0D\u8981\u628A\u4E24\u5C42\u804C\u8D23\u6DF7\u5728\u4E00\u8D77\u3002","- \u60F3\u6539\u670D\u52A1\u7AEF\u9996\u9875\u3001\u9759\u6001\u9875\u3001\u6587\u7AE0\u5217\u8868\u548C\u6587\u7AE0\u8BE6\u60C5\uFF0C\u5C31\u6539 `src/server/*`\uFF1B\u60F3\u6539\u65E7\u7684 SPA \u5E94\u7528\u9996\u9875\u6216\u4EA4\u4E92\u793A\u4F8B\u9875\uFF0C\u5C31\u6539 `src/web/*`\u3002","- \u82E5\u53EA\u662F\u4E1A\u52A1 API \u6269\u5C55\uFF0C\u4F18\u5148\u65B0\u589E\u81EA\u5DF1\u7684 server \u6A21\u5757\u6216\u8DEF\u7531\uFF0C\u4E0D\u8981\u5148\u6539 `src/server/app.ts` \u8FD9\u7C7B\u5E73\u53F0\u8584\u58F3\u5165\u53E3\u3002","- \u65B0\u589E\u79C1\u6709\u63A5\u53E3\u4F18\u5148\u4ECE `src/server/routes/api.ts` \u8D77\u6B65\uFF1B\u65B0\u589E SEO \u9875\u9762\u4F18\u5148\u4ECE `src/server/routes/seo-pages.ts` \u8D77\u6B65\u3002","- \u9700\u8981\u5728 server \u5185\u90E8\u53D7\u63A7\u8BFB\u5199 Data Form \u8D44\u6E90\u65F6\uFF0C\u4F18\u5148\u590D\u7528 `src/server/platform/data-form.ts`\uFF0C\u4E0D\u8981\u624B\u5199\u5E73\u884C fetch client\u3002","- \u9700\u8981\u5728 server \u5185\u90E8\u8BFB\u53D6 CMS \u5185\u5BB9\u65F6\uFF0C\u4F18\u5148\u590D\u7528 `src/server/platform/cms.ts`\uFF0C\u4E0D\u8981\u5728\u6BCF\u4E2A\u9875\u9762\u91CC\u5206\u6563\u624B\u5199\u8BF7\u6C42\u3002","","## \u6570\u636E\u5E93\u4ECE\u54EA\u91CC\u5F00\u59CB","","- \u9996\u6761 migration \u4ECE `resources/db/migrations/0001_init.sql` \u5F00\u59CB\u6539\u3002","- \u8FD9\u4E2A\u6587\u4EF6\u9ED8\u8BA4\u662F\u6CE8\u91CA\u6001\u793A\u4F8B\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u521B\u5EFA\u771F\u5B9E\u8868\u3002","- \u9700\u8981\u843D\u5E93\u65F6\uFF0C\u5148\u628A\u5B83\u6539\u6210\u7B2C\u4E00\u6761\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C\u5E73\u53F0\u7684 DB migrate \u6D41\u7A0B\u3002","- \u6539\u5B8C\u540E\u5EFA\u8BAE\u7ACB\u523B\u6267\u884C `platform db migrate`\uFF0C\u518D\u7528 `platform db status` \u6216 `platform db query` \u9A8C\u8BC1\u8868\u7ED3\u6784\u662F\u5426\u5DF2\u751F\u6548\u3002","","## Data Form \u4ECE\u54EA\u91CC\u5F00\u59CB","","- `Data Form` \u7684\u58F0\u660E\u5165\u53E3\u7EA6\u5B9A\u5728 `resources/data-forms/*.yaml`\u3002","- \u6A21\u677F\u9ED8\u8BA4\u63D0\u4F9B `resources/data-forms/README.md` \u548C `0001_event_signup.yaml.example`\u3002","- `.yaml.example` \u662F\u6CE8\u91CA\u6001\u793A\u4F8B\uFF0C\u4E0D\u4F1A\u88AB `platform data-form validate` \u626B\u63CF\u3002","- \u793A\u4F8B\u5B57\u6BB5\u4E0E\u9ED8\u8BA4 `/form` \u9875\u9762\u4FDD\u6301\u4E00\u81F4\uFF1B\u628A\u5B83\u590D\u5236\u6216\u6539\u540D\u6210\u6B63\u5F0F `*.yaml` \u540E\u5373\u53EF\u76F4\u63A5\u63A5\u771F\u5B9E\u63D0\u4EA4\u6D41\u7A0B\u3002","","## \u4E00\u6761\u7ECF\u9A8C","","- \u5982\u679C\u4E1A\u52A1\u8FD8\u4E0D\u9700\u8981\u79C1\u6709 API \u6216\u6570\u636E\u5E93\uFF0C\u4F18\u5148\u5148\u7528\u524D\u7AEF\u6A21\u677F\u8D77\u6B65\uFF1B\u9700\u8981\u540E\u7AEF\u80FD\u529B\u65F6\uFF0C\u518D\u8FC1\u5230\u8FD9\u4E2A\u6A21\u677F\u5373\u53EF\uFF0C\u524D\u7AEF\u9875\u9762\u5C42\u53EF\u4EE5\u57FA\u672C\u539F\u6837\u590D\u7528\u3002","","## \u6A21\u677F\u66F4\u65B0\u4E0E\u5E73\u53F0\u7EF4\u62A4\u533A","","- `src/web/platform/*`\u3001`src/server/platform/*`\u3001`src/server/app.ts`\u3001`src/server/routes/seo-pages.ts` \u4E0E `.platform/platform-blocks.lock.json` \u9ED8\u8BA4\u5C5E\u4E8E\u7CFB\u7EDF\u7EDF\u4E00\u7EF4\u62A4\u533A\u3002","- \u5E73\u53F0\u6A21\u677F\u5347\u7EA7\u65F6\uFF0C\u4F18\u5148\u6267\u884C `platform app sync-platform-blocks --dry-run` \u770B\u5DEE\u5F02\uFF1B\u786E\u8BA4\u65E0\u51B2\u7A81\u540E\u518D\u6267\u884C `--apply`\u3002","- \u5982\u679C\u5F53\u524D\u5DE5\u7A0B\u662F\u5386\u53F2 app \u4E14\u8FD8\u6CA1\u6709 `.platform/platform-blocks.lock.json`\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt`\uFF0C\u518D\u8FDB\u5165\u540E\u7EED\u5347\u7EA7\u3002","- \u82E5\u4F60\u4E3B\u52A8\u4FEE\u6539\u4E86\u8FD9\u4E9B platform-managed \u6587\u4EF6\uFF0C\u540E\u7EED `--apply` \u53EF\u80FD\u8FDB\u5165 conflict\uFF1B\u8FD9\u5C5E\u4E8E\u4FDD\u62A4\u884C\u4E3A\uFF0C\u4E0D\u4F1A\u9759\u9ED8\u8986\u76D6\u3002","- Agent \u5F00\u53D1\u4E1A\u52A1\u529F\u80FD\u65F6\uFF0C\u524D\u7AEF\u4EA4\u4E92\u4F18\u5148\u653E\u5728 `src/web/pages`\u3001`src/web/components`\u3001`public/__app/*`\uFF0C\u540E\u7AEF\u4E1A\u52A1\u63A5\u53E3\u4F18\u5148\u653E\u5728 `src/server/routes/api.ts` \u548C\u4E1A\u52A1\u81EA\u6709\u6A21\u5757\uFF0C\u4E0D\u8981\u5148\u6539\u5E73\u53F0\u8584\u58F3\u3002","- \u82E5 apply \u540E\u9700\u8981\u56DE\u9000\uFF0C\u53EA\u652F\u6301 `platform app sync-platform-blocks --rollback --last`\uFF0C\u5B83\u4F1A\u6062\u590D\u6700\u8FD1\u4E00\u6B21\u771F\u5B9E\u8986\u76D6\u3002",""].join(`
|
|
2146
2146
|
`)}function buildEnvExampleSource(templatePackageName){return[`APP_ID=${templatePackageName}`,"TENANT_ID=","APP_ENV=preview","PUBLIC_APP_BASE_URL=http://127.0.0.1:3000","BACKEND_DEV_PORT=3001","CONTROL_API_BASE_URL=http://127.0.0.1:7001","RUNTIME_API_BASE_URL=","PUBLIC_API_BASE_URL=","CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES=","SOURCE_VERSION_ID=",""].join(`
|
|
2147
2147
|
`)}function buildTsconfigSource(){return JSON.stringify({compilerOptions:{target:"ES2022",useDefineForClassFields:!0,lib:["ES2022","DOM","DOM.Iterable"],module:"ESNext",skipLibCheck:!0,moduleResolution:"Bundler",allowImportingTsExtensions:!1,resolveJsonModule:!0,isolatedModules:!0,noEmit:!0,jsx:"react-jsx",strict:!0,noFallthroughCasesInSwitch:!0,baseUrl:".",paths:{"@platform/*":["src/web/platform/*"]},types:["vite/client","node"]},include:["src/web","vite.config.ts"]},null,2)+`
|
|
2148
2148
|
`}function buildServerTsconfigSource(){return JSON.stringify({compilerOptions:{target:"ES2022",module:"NodeNext",moduleResolution:"NodeNext",outDir:"dist/server",rootDir:"src/server",strict:!0,noEmitOnError:!0,esModuleInterop:!0,skipLibCheck:!0,types:["node"]},include:["src/server"]},null,2)+`
|
|
2149
|
-
`}function buildDockerfileSource(){return["# syntax=docker/dockerfile:1.7","FROM node:20-bookworm-slim AS base","ARG NPM_CONFIG_REGISTRY","ENV NPM_CONFIG_REGISTRY=${NPM_CONFIG_REGISTRY}","WORKDIR /app","","FROM base AS deps","COPY package.json ./package.json","COPY package-lock.json ./package-lock.json","RUN --mount=type=cache,id=platform-lightapp-npm-cache,target=/root/.npm npm
|
|
2149
|
+
`}function buildDockerfileSource(){return["# syntax=docker/dockerfile:1.7","FROM node:20-bookworm-slim AS base","ARG NPM_CONFIG_REGISTRY","ENV NPM_CONFIG_REGISTRY=${NPM_CONFIG_REGISTRY}","WORKDIR /app","","FROM base AS deps","COPY package.json ./package.json","COPY package-lock.json ./package-lock.json","RUN --mount=type=cache,id=platform-lightapp-npm-cache,target=/root/.npm npx --yes npm@10.9.2 ci --no-audit --no-fund","","FROM deps AS build","COPY . .","RUN npm run build","","FROM base AS runtime","ENV NODE_ENV=production","COPY --from=build /app/package.json ./package.json","COPY --from=build /app/package-lock.json ./package-lock.json","COPY --from=build /app/node_modules ./node_modules","COPY --from=build /app/dist ./dist","EXPOSE 3000",'CMD ["node", "dist/server/entry.js"]',""].join(`
|
|
2150
2150
|
`)}function buildViteConfigSource(){return['import { defineConfig } from "vite";','import react from "@vitejs/plugin-react";','import tailwindcss from "@tailwindcss/vite";','import { createPlatformViteDevSupportPlugin } from "./src/web/platform/dev/vite/proxy";',"","const backendDevProxyTarget = process.env.BACKEND_DEV_PROXY_TARGET?.trim();",'const backendSeoPageRoutes = ["/", "/about", "/contact", "/articles*", "/robots.txt", "/sitemap.xml"];',"","export default defineConfig({",' base: "./",'," plugins: [react(), tailwindcss(), createPlatformViteDevSupportPlugin({ backendPageRoutes: backendSeoPageRoutes })],"," server: {"," port: Number(process.env.PORT || 3000),"," proxy: backendDevProxyTarget"," ? {",' "/api": { target: backendDevProxyTarget, changeOrigin: true },',' "/healthz": { target: backendDevProxyTarget, changeOrigin: true },'," }"," : undefined,"," },","});",""].join(`
|
|
2151
2151
|
`)}function buildLocalDevScriptSource(){return['import { spawn } from "node:child_process";','import { createServer as createNetServer } from "node:net";','import process from "node:process";',"",'const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";',"const preferredPublicPort = Number(process.env.PORT || 3000);",'const explicitPublicAppBaseUrl = trimTrailingSlash(process.env.PUBLIC_APP_BASE_URL || "");',"const implicitPublicAppBaseUrl = `http://127.0.0.1:${preferredPublicPort}`;","const publicPort = await resolveAvailablePort(preferredPublicPort);","const publicAppBaseUrl = explicitPublicAppBaseUrl && explicitPublicAppBaseUrl !== implicitPublicAppBaseUrl"," ? explicitPublicAppBaseUrl"," : `http://127.0.0.1:${publicPort}`;","const preferredBackendPort = Number(process.env.BACKEND_DEV_PORT || publicPort + 1);","const backendPort = await resolveAvailablePort(preferredBackendPort);","const backendDevProxyTarget = `http://127.0.0.1:${backendPort}`;","","console.log(`[backend-app-node] local dev web=${publicAppBaseUrl} server=${backendDevProxyTarget}`);","","const sharedEnv = {"," ...process.env,"," PUBLIC_APP_BASE_URL: publicAppBaseUrl,"," APP_BASE_URL: publicAppBaseUrl,"," BACKEND_DEV_PROXY_TARGET: backendDevProxyTarget,","};","","const children = [",' spawnProcess(npmCommand, ["run", "dev:web", "--", "--host", "0.0.0.0", "--port", String(publicPort)], {'," ...sharedEnv,"," PORT: String(publicPort),"," }),",' spawnProcess(npmCommand, ["run", "dev:server"], {'," ...sharedEnv,"," PORT: String(backendPort),"," }),","];","","let shuttingDown = false;","","function trimTrailingSlash(value) {",' return value.length > 1 ? value.replace(/\\/+$/u, "") : value;',"}","","function spawnProcess(command, args, env) {"," return spawn(command, args, {"," env,",' stdio: "inherit",'," shell: false,"," });","}","","function shutdown(exitCode = 0) {"," if (shuttingDown) {"," return;"," }"," shuttingDown = true;"," for (const child of children) {"," if (!child.killed) {",' child.kill("SIGTERM");'," }"," }"," setTimeout(() => process.exit(exitCode), 50);","}","","for (const child of children) {",' child.on("exit", (code, signal) => {'," if (shuttingDown) {"," return;"," }"," if (signal) {"," console.error(`[backend-app-node] dev child exited via signal ${signal}`);"," shutdown(1);"," return;"," }"," shutdown(code || 0);"," });",' child.on("error", (error) => {'," console.error(`[backend-app-node] failed to start dev child: ${error instanceof Error ? error.message : String(error)}`);"," shutdown(1);"," });","}","",'process.on("SIGINT", () => shutdown(0));','process.on("SIGTERM", () => shutdown(0));',"","async function resolveAvailablePort(preferredPort) {"," if (await canBindPort(preferredPort)) {"," return preferredPort;"," }"," return allocateEphemeralPort();","}","","async function canBindPort(port) {"," return new Promise((resolve) => {"," const server = createNetServer();"," const finish = (available) => {"," server.removeAllListeners();"," resolve(available);"," };",' server.once("error", () => finish(false));'," server.listen(port, () => {"," server.close(() => finish(true));"," });"," });","}","","async function allocateEphemeralPort() {"," return new Promise((resolve, reject) => {"," const server = createNetServer();",' server.once("error", reject);'," server.listen(0, () => {"," const address = server.address();",' if (!address || typeof address === "string") {',' server.close(() => reject(new Error("expected TCP address")));'," return;"," }"," server.close((error) => {"," if (error) {"," reject(error);"," return;"," }"," resolve(address.port);"," });"," });"," });","}",""].join(`
|
|
2152
2152
|
`)}function buildIndexHtmlSource(){return["<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="UTF-8" />',' <meta name="viewport" content="width=device-width, initial-scale=1.0" />'," <title>Backend App</title>"," </head>"," <body>",' <div id="root" data-platform-spa-root></div>',' <script type="module" src="./src/web/main.tsx"></script>'," </body>","</html>",""].join(`
|
|
@@ -2171,10 +2171,9 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2171
2171
|
`)}function buildDataFormsReadmeSource(){return["# Data Form","","\u8FD9\u4E2A\u76EE\u5F55\u7528\u4E8E\u58F0\u660E `Data Form` \u8D44\u6E90\u3002","","- `platform data-form validate` / `inspect` / `apply` \u53EA\u4F1A\u626B\u63CF `*.yaml` \u6216 `*.yml`\u3002","- \u6A21\u677F\u63D0\u4F9B\u7684 `0001_event_signup.yaml.example` \u662F\u6CE8\u91CA\u6001\u793A\u4F8B\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u53C2\u4E0E\u6821\u9A8C\u6216\u5E94\u7528\u3002","- \u9ED8\u8BA4 `/form` \u9875\u4F1A\u4F18\u5148\u5C1D\u8BD5\u8BFB\u53D6\u771F\u5B9E `event_signup` \u8D44\u6E90\uFF1B\u82E5\u5F53\u524D\u73AF\u5883\u5C1A\u672A apply\uFF0C\u5219\u81EA\u52A8\u56DE\u9000\u5230\u793A\u4F8B schema\u3002","- \u9700\u8981\u542F\u7528\u771F\u5B9E\u5199\u5165\u65F6\uFF0C\u628A\u793A\u4F8B\u590D\u5236\u6216\u6539\u540D\u6210 `*.yaml` \u540E\u518D\u5F00\u59CB\u7F16\u8F91\uFF0C\u5E76\u6267\u884C `platform data-form validate / inspect / apply`\u3002",""].join(`
|
|
2172
2172
|
`)}function buildDataFormExampleSource(){return["# Data Form scaffold example","#","# \u4F7F\u7528\u65B9\u5F0F\uFF1A","# 1. \u590D\u5236\u5F53\u524D\u6587\u4EF6\u4E3A `0001_event_signup.yaml` \u6216\u5176\u4ED6 `*.yaml` \u6587\u4EF6","# 2. \u6309\u4E1A\u52A1\u9700\u6C42\u4FEE\u6539\u5B57\u6BB5","# 3. \u518D\u6267\u884C `platform data-form validate / inspect / apply`","# 4. \u9ED8\u8BA4 `/form` \u9875\u4F1A\u81EA\u52A8\u4ECE\u793A\u4F8B\u56DE\u9000\u5207\u6362\u5230\u771F\u5B9E\u8D44\u6E90\uFF0C\u65E0\u9700\u518D\u6539\u9875\u9762\u4EE3\u7801","#","# resource_key: event_signup","# display_name: \u6D3B\u52A8\u62A5\u540D","# resource_kind: anonymous_submission","# # \u5176\u5B83\u5F52\u5C5E\u3001\u5171\u4EAB\u3001\u9ED8\u8BA4\u6743\u9650\u4F1A\u7531\u7CFB\u7EDF\u63A8\u5BFC\uFF1B\u4EC5\u5728\u5171\u4EAB\u6216\u7279\u6B8A\u6743\u9650\u573A\u666F\u518D\u8865\u663E\u5F0F\u914D\u7F6E","# fields:","# - name: title","# type: text","# label: \u6807\u9898","# required: true","# max_length: 80","# - name: contact_email","# type: email","# label: \u8054\u7CFB\u90AE\u7BB1","# required: false","# max: 120","# - name: category","# type: select","# label: \u5206\u7C7B","# required: false","# options:","# values:","# - label: \u54A8\u8BE2","# value: consulting","# - label: \u4EA7\u54C1\u53CD\u9988","# value: feedback","# - label: \u6D3B\u52A8\u62A5\u540D","# value: event","# - name: tags","# type: multiselect","# label: \u6807\u7B7E","# required: false","# options:","# values:","# - label: \u7D27\u6025","# value: urgent","# - label: \u4F1A\u5458","# value: member","# - label: \u7EBF\u4E0B","# value: offline","# - name: event_date","# type: date","# label: \u6D3B\u52A8\u65E5\u671F","# required: false","# - name: budget","# type: number","# label: \u9884\u7B97","# required: false","# min: 0","# - name: cover_image","# type: image","# label: \u5C01\u9762\u56FE","# required: false","# max_size_mb: 3","# - name: attachments","# type: files","# label: \u9644\u4EF6","# required: false","# max_files: 2","# max_size_mb: 5","# - name: summary","# type: text","# label: \u8BF4\u660E","# required: false","# max: 300","# multiline: true","# - name: agree_terms","# type: bool","# label: \u6211\u5DF2\u9605\u8BFB\u5E76\u540C\u610F\u8BF4\u660E","# required: true",""].join(`
|
|
2173
2173
|
`)}function buildBackendAppNodeTemplateFiles(){let templatePackageName=DEFAULT_TEMPLATE_PACKAGE_NAME;return[{path:"app.yaml",content:buildAppYamlSource(templatePackageName)},{path:"package.json",content:buildPackageJsonSource(templatePackageName)},{path:"package-lock.json",content:buildPackageLockSource(templatePackageName)},{path:"README.md",content:buildReadmeSource()},{path:".env.example",content:buildEnvExampleSource(templatePackageName)},{path:"tsconfig.json",content:buildTsconfigSource()},{path:"tsconfig.server.json",content:buildServerTsconfigSource()},{path:"Dockerfile",content:buildDockerfileSource()},{path:"vite.config.ts",content:buildViteConfigSource()},{path:"index.html",content:buildIndexHtmlSource()},{path:"scripts/dev.mjs",content:buildLocalDevScriptSource()},{path:"src/web/main.tsx",content:buildWebMainSource()},...buildWebSharedPageFiles("src/web",{buildRouterAppSource,buildHomePageSource:()=>buildHomePageSource({badgeLabel:"Backend App",heroTitle:"\u8F7B\u5E94\u7528\u540E\u7AEF\u8D77\u70B9\u5DF2\u5C31\u7EEA",heroDescription:"\u8FD9\u662F\u5E26\u79C1\u6709\u540E\u7AEF\u80FD\u529B\u7684\u8F7B\u5E94\u7528\u8D77\u70B9\u3002\u9ED8\u8BA4\u9875\u9762\u4E0E\u524D\u7AEF\u6A21\u677F\u5171\u4EAB\u540C\u4E00\u5957\u767B\u5F55\u6001\u3001\u4FDD\u62A4\u9875\u4E0E CMS \u5185\u5BB9\u6D41\uFF0C\u540E\u7EED\u4F60\u53EA\u9700\u8981\u5728\u6B64\u57FA\u7840\u4E0A\u7EE7\u7EED\u6DFB\u52A0\u79C1\u6709 API\u3001\u6570\u636E\u5199\u5165\u4E0E\u4EFB\u52A1\u5904\u7406\u80FD\u529B\u3002"}),buildFormPageSource,buildEventSignupFormSource,buildProtectedPageSource,buildCmsPageSource}),{path:"src/web/styles/index.css",content:buildStylesSource()},{path:"src/web/styles/cms-content.css",content:buildCmsContentStylesSource()},{path:"src/web/vite-env.d.ts",content:buildWebViteEnvSource()},...buildWebSharedDataFormUiFiles("src/web"),{path:"public/auth/index.html",content:buildServerAuthPageHtmlSource()},{path:"public/__app/auth-ui.config.json",content:buildServerAuthUiConfigJsonSource()},{path:"public/__app/auth-ui.override.css",content:buildServerAuthUiOverrideCssSource()},...buildWebSharedPlatformFiles("src/web",{buildPlatformConfigSource,buildPlatformClientSource,buildPlatformErrorsSource,buildCapabilitiesIndexSource,buildCapabilitySource}),{path:"src/server/entry.ts",content:buildServerEntrySource()},{path:"src/server/app.ts",content:buildServerAppSource()},{path:"src/server/routes/api.ts",content:buildServerApiRouteSource()},{path:"src/server/routes/seo-pages.ts",content:buildServerSeoPagesRouteSource()},{path:"src/server/lib/seo-html.ts",content:buildServerSeoHtmlSource()},{path:"src/server/lib/page-meta.ts",content:buildServerPageMetaSource()},{path:"src/server/lib/cms-seo.ts",content:buildServerCmsSeoSource()},{path:"src/server/platform/cms.ts",content:buildServerPlatformCmsSource()},{path:"src/server/content/site-config.ts",content:buildServerSiteConfigSource()},{path:"src/server/content/static-pages.ts",content:buildServerStaticPagesSource()},scaffoldTemplateBlock2("server/request-context.ts","src/server/platform/request-context.ts"),scaffoldTemplateBlock2("server/route-strip.ts","src/server/platform/route-strip.ts"),scaffoldTemplateBlock2("server/html-injection.ts","src/server/platform/html-injection.ts"),scaffoldTemplateBlock2("server/proxy-routing.ts","src/server/platform/proxy-routing.ts"),scaffoldTemplateBlock2("contract/capabilities.ts","src/server/platform/contract/capabilities.ts"),scaffoldTemplateBlock2("contract/route-path-patterns.ts","src/server/platform/contract/route-path-patterns.ts"),scaffoldTemplateBlock2("contract/runtime-config.ts","src/server/platform/contract/runtime-config.ts"),scaffoldTemplateBlock2("protocol/auth-routes.ts","src/server/platform/protocol/auth-routes.ts"),scaffoldTemplateBlock2("protocol/public-app-routes.ts","src/server/platform/protocol/public-app-routes.ts"),scaffoldTemplateBlock2("protocol/cms-routes.ts","src/server/platform/protocol/cms-routes.ts"),scaffoldTemplateBlock2("protocol/route-map.ts","src/server/platform/protocol/route-map.ts"),scaffoldTemplateBlock2("dev-support/node/auth-shell.ts","src/server/platform/dev/node/auth-shell.ts"),scaffoldTemplateBlock2("dev-support/node/proxy.ts","src/server/platform/dev/node/proxy.ts"),scaffoldTemplateBlock2("dev-support/node/runtime-config.ts","src/server/platform/dev/node/runtime-config.ts"),{path:"src/server/platform/data-form.ts",content:buildServerPlatformDataFormSource()},{path:"src/server/platform/runtime.ts",content:buildServerPlatformRuntimeSource()},{path:"resources/db/migrations/README.md",content:buildServerMigrationReadmeSource()},{path:"resources/db/migrations/0001_init.sql",content:buildServerMigrationExampleSource()},{path:"resources/data-forms/README.md",content:buildDataFormsReadmeSource()},{path:"resources/data-forms/0001_event_signup.yaml.example",content:buildDataFormExampleSource()}]}function assembleBackendAppNodeTemplate(){let files=buildBackendAppNodeTemplateFiles(),manifest=buildPlatformBlocksManifestFromTemplateFiles("backend-app-node",files);return[...files,{path:".platform/platform-blocks.lock.json",content:stringifyPlatformBlocksLockfile(buildPlatformBlocksLockfile(manifest))}]}function buildAppYamlSource2(templatePackageName){return[`name: ${templatePackageName}`,"version: 0.1.0","entry:"," command: npm run dev -- --host 0.0.0.0"," port: 3000"," health_check: /",""].join(`
|
|
2174
|
-
`)}function buildPackageJsonSource2(templatePackageName){return JSON.stringify({name:templatePackageName,version:"0.1.0",private:!0,type:"module",scripts:{dev:"vite",build:"tsc --noEmit && vite build && node ./scripts/page-render-postbuild.mjs",preview:"vite preview"},dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",typescript:"5.8.2",vite:"6.3.5"}},null,2)+`
|
|
2175
|
-
`}function buildPackageLockSource2(templatePackageName){return
|
|
2176
|
-
`}function buildPnpmWorkspaceSource(){return["packages:"," - .","allowBuilds:"," esbuild: true"," msw: true",""].join(`
|
|
2177
|
-
`)}function buildReadmeSource2(){return["# Frontend App \u4F7F\u7528\u8BF4\u660E","","\u8FD9\u4E2A\u6A21\u677F\u9002\u5408\u7EAF\u524D\u7AEF\u8F7B\u5E94\u7528\u3001\u5185\u5BB9\u5B98\u7F51\u3001\u6D3B\u52A8\u9875\u3001\u8868\u5355\u9875\u548C\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u4EE3\u7801\u5E76\u5165\u573A\u666F\u3002","\u4F60\u53EF\u4EE5\u628A\u5B83\u5F53\u6210\u666E\u901A\u7684 `React + Vite + TypeScript + Tailwind` \u9879\u76EE\u6765\u5F00\u53D1\uFF0C\u5E73\u53F0\u63A5\u5165\u5DF2\u7ECF\u6536\u53E3\u5728\u6A21\u677F\u91CC\u3002","","## \u5148\u770B\u8FD9\u51E0\u4E2A\u76EE\u5F55","","- `src/pages`\uFF1A\u4E1A\u52A1\u9875\u9762","- `src/components`\uFF1A\u901A\u7528\u7EC4\u4EF6","- `src/features/event-signup/*`\uFF1A\u53EF\u590D\u7528\u7684\u5B8C\u6574\u8868\u5355\u793A\u4F8B\uFF0C\u4E5F\u53EF\u88AB\u9875\u9762\u6E32\u67D3\u8BE6\u60C5\u9875\u6309 React Island \u65B9\u5F0F\u6302\u8F7D","- `src/platform/*`\uFF1A\u5E73\u53F0\u63A5\u5165\u5C42\uFF0C\u4E5F\u662F platform-managed scope\uFF1BP2 \u4E4B\u540E\u9ED8\u8BA4\u7531 `platform app sync-platform-blocks` \u7BA1\u7406","- `src/page-render/react-islands.tsx`\uFF1A\u9759\u6001 HTML \u9875\u9762\u5C40\u90E8 React \u589E\u5F3A\u6CE8\u518C\u8868\u4E0E\u6302\u8F7D helper","- `src/styles/*`\uFF1A\u5168\u5C40\u6837\u5F0F\u548C\u6B63\u6587\u6837\u5F0F","- `page-render/*`\uFF1A\u9875\u9762\u6E32\u67D3\u8DEF\u7531\u6CE8\u518C\u3001CMS \u7ED1\u5B9A\u548C shell \u914D\u7F6E","- `public/site/*`\uFF1A\u9875\u9762\u6E32\u67D3\u793A\u4F8B\u7684\u7AD9\u70B9 HTML \u6A21\u677F","- `public/shared/*`\uFF1A\u9759\u6001\u5185\u5BB9\u7AD9\u5171\u4EAB\u58F3\u3001\u811A\u672C\u548C\u6837\u5F0F\u76EE\u5F55","- `public/auth` \u4E0E `public/__app`\uFF1A\u767B\u5F55\u9875\u58F3\u3001\u767B\u5F55\u9875\u6587\u6848\u548C\u5C40\u90E8\u6837\u5F0F\u8986\u76D6","","## \u9ED8\u8BA4\u9875\u9762\u8DEF\u7531","","- `/`\uFF1A\u9996\u9875\uFF0C\u5BF9\u5E94 `src/pages/HomePage.tsx`","- `/form`\uFF1A\u8868\u5355\u9875\u793A\u4F8B\uFF0C\u5BF9\u5E94 `src/pages/FormPage.tsx`","- `/app`\uFF1A\u4FDD\u62A4\u9875\uFF0C\u5BF9\u5E94 `src/pages/ProtectedPage.tsx`","- `/cms`\uFF1ACMS \u793A\u4F8B\u9875\uFF0C\u5BF9\u5E94 `src/pages/CmsPage.tsx`","- `/articles`\uFF1A\u9875\u9762\u6E32\u67D3\u5217\u8868\u793A\u4F8B\uFF0C\u8BE6\u60C5\u9875\u4ECE\u5217\u8868\u5361\u7247\u8FDB\u5165","","## \u63A8\u8350\u5F00\u53D1\u65B9\u5F0F","","- \u7EAF\u9875\u9762\u5F00\u53D1\u76F4\u63A5\u7528 `platform dev`\u3002","- \u9700\u8981\u8054\u8C03 Auth / CMS / Workflow \u7B49\u5E73\u53F0\u80FD\u529B\u65F6\u7528 `platform dev --remote-bindings`\u3002","- \u4E91\u7AEF\u9A8C\u8BC1\u7528 `platform preview generate`\uFF0C\u6B63\u5F0F\u53D1\u5E03\u7528 `platform publish`\u3002","- \u6A21\u677F\u9ED8\u8BA4\u9644\u5E26\u4E00\u5957\u9875\u9762\u6E32\u67D3\u793A\u4F8B\uFF1A`/articles` \u5217\u8868\u9875\u3001\u8BE6\u60C5\u9875\u6A21\u677F\u3001`page-render/*.json` \u7ED1\u5B9A\u914D\u7F6E\u548C shell \u914D\u7F6E\u3002","- \u9875\u9762\u6E32\u67D3\u66F4\u9002\u5408\u5185\u5BB9\u5217\u8868\u9875\u3001\u5185\u5BB9\u8BE6\u60C5\u9875\u3001\u4E13\u9898\u9875\u3001\u843D\u5730\u9875\u7B49\u9700\u8981\u9996\u5C4F\u53EF\u6293\u53D6 HTML \u7684 SEO \u573A\u666F\u3002","- \u82E5\u4F60\u9700\u8981\u7EE7\u7EED\u6269\u5C55\u9875\u9762\u6E32\u67D3\uFF0C\u76F4\u63A5\u4FEE\u6539\u9879\u76EE\u6839\u7684 `page-render/registry.json`\u3001`page-render/pages/*.json`\u3001`page-render/shells/*.json`\uFF1B\u6A21\u677F build \u4F1A\u81EA\u52A8\u628A\u5B83\u4EEC\u6253\u8FDB `dist/page-render/`\u3002","- `platform dev` \u5728\u5F53\u524D\u76EE\u5F55\u7F3A\u5C11 `node_modules` \u65F6\u4F1A\u6309 lockfile \u81EA\u52A8\u5B89\u88C5\u4F9D\u8D56\uFF1B`platform preview generate --local-build` \u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5\uFF0C\u5148\u624B\u52A8\u6267\u884C\u4E00\u6B21\u4F9D\u8D56\u5B89\u88C5\u3002","- \u4E1A\u52A1\u4EE3\u7801\u6309\u5E38\u89C4\u524D\u7AEF\u65B9\u5F0F\u5199\uFF0C\u65E0\u9700\u7406\u89E3\u5E73\u53F0\u5165\u53E3\u5DEE\u5F02\uFF0C\u7EDF\u4E00\u6309\u8BED\u4E49\u8DEF\u7531\u548C helper \u5F00\u53D1\u3002","- \u65B0\u5EFA app \u4F1A\u9ED8\u8BA4\u751F\u6210 `.platform/platform-blocks.lock.json`\uFF1B\u5982\u679C\u4F60 checkout \u7684\u662F\u5386\u53F2 app\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt` \u8865\u7EB3\u7BA1\u3002","- \u63A8\u8350\u540C\u6B65\u987A\u5E8F\uFF1A`platform app sync-platform-blocks --dry-run` -> `--apply` -> \u672C\u5730\u9A8C\u8BC1\uFF1B\u9700\u8981\u65F6\u518D `--rollback --last`\u3002","","## \u5E38\u89C1\u5751","","- \u4E91\u7AEF `platform preview generate` \u4F9D\u8D56\u5F53\u524D\u6A21\u677F\u5185\u7F6E\u7684 `pnpm-workspace.yaml` \u6765\u653E\u884C `esbuild`\u3001`msw` \u7B49 build scripts\uFF1B\u4E0D\u8981\u968F\u624B\u5220\u6389\u8FD9\u4E2A\u6587\u4EF6\uFF0C\u5426\u5219\u4E91\u7AEF\u6784\u5EFA\u53EF\u80FD\u5931\u8D25\u3002","- \u4E0D\u8981\u5728\u9875\u9762\u91CC\u5199\u6B7B `/previews/...`\u3001`/apps/...`\u3001`https://...` \u8FD9\u7C7B\u5E73\u53F0\u8DEF\u5F84\u524D\u7F00\u3002","- \u6D4F\u89C8\u5668\u4FA7\u8BF7\u6C42\u548C\u8DF3\u8F6C\u4F18\u5148\u7528\u6A21\u677F\u5DF2\u6709 helper\uFF1B\u5982\u679C\u53EA\u662F\u9759\u6001\u8D44\u6E90\u6216\u540C\u6E90\u63A5\u53E3\uFF0C\u4F18\u5148\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 `./api/...`\u3001`./assets/...`\u3002",'- \u4E0D\u8981\u76F4\u63A5\u5199\u6839\u8DEF\u5F84\u5F15\u7528\uFF0C\u4F8B\u5982 `fetch(\'/api/...\')`\u3001`href="/..."`\u3001`src="/..."`\uFF0C\u8FD9\u7C7B\u5199\u6CD5\u5728 preview path \u6A21\u5F0F\u4E0B\u6700\u5BB9\u6613\u51FA\u9519\u3002',"- \u4E0D\u8981\u628A `.platform/source-context.json` \u5F53\u6210\u9875\u9762\u8FD0\u884C\u65F6\u914D\u7F6E\u6765\u6E90\uFF0C\u4E5F\u4E0D\u8981\u5728\u4EE3\u7801\u91CC\u5199\u6B7B `appId`\u3001`tenantId`\u3002","- \u9875\u9762\u6E32\u67D3\u6A21\u677F\u9002\u5408\u4F7F\u7528\u9759\u6001\u53EF\u679A\u4E3E class\uFF08\u542B Tailwind class\uFF09\uFF1B\u4E0D\u8981\u4F9D\u8D56\u8FD0\u884C\u65F6\u62FC\u63A5 class \u540E\u518D\u8BA9\u6784\u5EFA\u5668\u8865\u6837\u5F0F\u3002","","## \u9875\u9762\u6E32\u67D3\u793A\u4F8B\u4ECE\u54EA\u91CC\u5F00\u59CB","","- `public/site/article-list.html`\uFF1A\u5185\u5BB9\u5217\u8868\u9875 HTML \u6A21\u677F","- `public/site/article-detail.html`\uFF1A\u5185\u5BB9\u8BE6\u60C5\u9875 HTML \u6A21\u677F","- `src/page-render/react-islands.tsx`\uFF1AReact Island \u6CE8\u518C\u4E0E\u6302\u8F7D\u5165\u53E3\uFF0C\u7ED9\u9759\u6001 HTML \u9875\u9762\u8865\u5C40\u90E8\u4EA4\u4E92","- `src/features/event-signup/EventSignupForm.tsx`\uFF1A\u6A21\u677F\u81EA\u5E26\u7684\u5B8C\u6574\u8868\u5355\u7EC4\u4EF6\uFF0C\u53EF\u5728 SPA \u9875\u9762\u548C\u9759\u6001\u8BE6\u60C5\u9875\u4E2D\u590D\u7528","- `page-render/registry.json`\uFF1A\u9875\u9762\u6E32\u67D3\u8DEF\u7531\u6CE8\u518C\u5165\u53E3","- `page-render/pages/article-list.page-render.json`\uFF1A\u5217\u8868\u9875 collection \u7ED1\u5B9A\u3001\u5206\u9875\u3001\u8FC7\u6EE4\u3001\u8BE6\u60C5\u8DF3\u8F6C","- `page-render/pages/article-detail.page-render.json`\uFF1A\u8BE6\u60C5\u9875\u6B63\u6587\u7ED1\u5B9A\u548C\u63A8\u8350\u5217\u8868\u7ED1\u5B9A","- `page-render/shells/default.shell.json`\uFF1Aheader / footer \u53EF\u590D\u7528\u58F3\u914D\u7F6E","- Agent \u6269\u5C55\u9875\u9762\u6E32\u67D3\u65F6\uFF0C\u4F18\u5148\u6539\u4E0A\u9762\u8FD9\u4E9B\u6587\u4EF6\uFF1B\u53EA\u6709\u5728\u505A SPA \u9875\u9762\u6216\u5E73\u53F0\u80FD\u529B\u63A5\u7EBF\u65F6\uFF0C\u518D\u56DE\u5230 `src/pages/*` \u4E0E `src/platform/*`\u3002","","## \u4EC0\u4E48\u65F6\u5019\u6539 `src/platform/*`","","- \u9700\u8981\u63A5 Auth / CMS / Workflow / Blob \u7B49\u5E73\u53F0\u80FD\u529B\u65F6\u518D\u770B\u8FD9\u91CC\u3002","- \u666E\u901A\u9875\u9762\u3001\u7EC4\u4EF6\u3001\u6837\u5F0F\u6539\u9020\u4F18\u5148\u53EA\u52A8 `src/pages`\u3001`src/components`\u3001`src/styles`\u3002","- \u82E5\u53EA\u662F\u60F3\u505A\u4E1A\u52A1\u5B9A\u5236\uFF0C\u4E0D\u8981\u5148\u6539 `src/platform/*`\uFF1B\u5148\u5224\u65AD\u662F\u5426\u80FD\u653E\u5728 `src/pages`\u3001`src/components`\u3001`public/__app/*` \u89E3\u51B3\u3002","- \u5982\u679C\u8981\u6539\u767B\u5F55\u9875\u54C1\u724C\u3001\u8F7B\u6587\u6848\u6216\u5C40\u90E8\u6837\u5F0F\uFF0C\u4F18\u5148\u770B `public/auth/index.html`\u3001`public/__app/auth-ui.config.json`\u3001`public/__app/auth-ui.override.css`\u3002","- \u5982\u679C\u8131\u79BB\u5E73\u53F0\u5355\u72EC\u6253\u5F00\u9875\u9762\uFF0C\u5E73\u53F0\u80FD\u529B\u53EF\u80FD\u4F1A\u964D\u7EA7\u6216\u9700\u8981\u663E\u5F0F\u8865\u73AF\u5883\u53D8\u91CF\uFF0C\u8FD9\u5C5E\u4E8E\u9884\u671F\u884C\u4E3A\u3002","","## Data Form \u4ECE\u54EA\u91CC\u5F00\u59CB","","- `Data Form` \u7684\u58F0\u660E\u5165\u53E3\u7EA6\u5B9A\u5728 `resources/data-forms/*.yaml`\u3002","- \u6A21\u677F\u9ED8\u8BA4\u63D0\u4F9B `resources/data-forms/README.md` \u548C `0001_event_signup.yaml.example`\u3002","- `.yaml.example` \u662F\u6CE8\u91CA\u6001\u793A\u4F8B\uFF0C\u4E0D\u4F1A\u88AB `platform data-form validate` \u626B\u63CF\u3002","- \u793A\u4F8B\u5B57\u6BB5\u4E0E\u9ED8\u8BA4 `/form` \u9875\u9762\u4FDD\u6301\u4E00\u81F4\uFF1B\u628A\u5B83\u590D\u5236\u6216\u6539\u540D\u6210\u6B63\u5F0F `*.yaml` \u540E\u5373\u53EF\u76F4\u63A5\u63A5\u771F\u5B9E\u63D0\u4EA4\u6D41\u7A0B\u3002","","## \u6A21\u677F\u66F4\u65B0\u4E0E\u5E73\u53F0\u7EF4\u62A4\u533A","","- `src/platform/*` \u4E0E `.platform/platform-blocks.lock.json` \u9ED8\u8BA4\u5C5E\u4E8E\u7CFB\u7EDF\u7EDF\u4E00\u7EF4\u62A4\u533A\uFF1B\u666E\u901A\u4E1A\u52A1\u8FED\u4EE3\u4E0D\u8981\u628A\u5B83\u4EEC\u5F53\u6210\u81EA\u7531\u6539\u9020\u533A\u3002","- \u5E73\u53F0\u6A21\u677F\u5347\u7EA7\u65F6\uFF0C\u4F18\u5148\u6267\u884C `platform app sync-platform-blocks --dry-run` \u770B\u5DEE\u5F02\uFF1B\u786E\u8BA4\u65E0\u51B2\u7A81\u540E\u518D\u6267\u884C `--apply`\u3002","- \u5982\u679C\u5F53\u524D\u5DE5\u7A0B\u662F\u5386\u53F2 app \u4E14\u8FD8\u6CA1\u6709 `.platform/platform-blocks.lock.json`\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt`\uFF0C\u518D\u8FDB\u5165\u540E\u7EED\u5347\u7EA7\u3002","- \u82E5\u4F60\u4E3B\u52A8\u4FEE\u6539\u4E86 `src/platform/*`\uFF0C\u540E\u7EED `--apply` \u5F88\u53EF\u80FD\u8FDB\u5165 conflict\uFF1B\u8FD9\u5C5E\u4E8E\u4FDD\u62A4\u884C\u4E3A\uFF0C\u4E0D\u4F1A\u9759\u9ED8\u8986\u76D6\u3002","- Agent \u5F00\u53D1\u4E1A\u52A1\u529F\u80FD\u65F6\uFF0C\u4F18\u5148\u6539 `src/pages`\u3001`src/components`\u3001`src/styles`\u3001`public/__app/*`\uFF1B\u53EA\u6709\u786E\u5B9E\u5728\u8865\u5E73\u53F0\u80FD\u529B\u63A5\u7EBF\u65F6\uFF0C\u624D\u8FDB\u5165 `src/platform/*`\u3002","- \u82E5 apply \u540E\u9700\u8981\u56DE\u9000\uFF0C\u53EA\u652F\u6301 `platform app sync-platform-blocks --rollback --last`\uFF0C\u5B83\u4F1A\u6062\u590D\u6700\u8FD1\u4E00\u6B21\u771F\u5B9E\u8986\u76D6\u3002",""].join(`
|
|
2174
|
+
`)}function buildPackageJsonSource2(templatePackageName){return JSON.stringify({name:templatePackageName,version:"0.1.0",private:!0,packageManager:"npm@10.9.2",engines:{node:">=20.0.0"},type:"module",scripts:{dev:"vite",build:"tsc --noEmit && vite build && node ./scripts/page-render-postbuild.mjs",preview:"vite preview"},dependencies:{"@radix-ui/react-checkbox":"^1.3.3","@radix-ui/react-popover":"^1.1.15","@radix-ui/react-select":"^2.2.6","lucide-react":"^0.577.0",react:"18.3.1","react-day-picker":"^9.11.1","react-dom":"18.3.1"},devDependencies:{"@tailwindcss/vite":"4.2.2","@types/node":"22.15.17","@types/react":"19.2.2","@types/react-dom":"19.2.2","@vitejs/plugin-react":"4.3.4",tailwindcss:"4.2.2",typescript:"5.8.2",vite:"6.3.5"}},null,2)+`
|
|
2175
|
+
`}function buildPackageLockSource2(templatePackageName){let lockfile=structuredClone(FRONTEND_APP_VITE_PACKAGE_LOCK);return lockfile.name=templatePackageName,lockfile.packages[""].name=templatePackageName,JSON.stringify(lockfile,null,2)+`
|
|
2176
|
+
`}function buildReadmeSource2(){return["# Frontend App \u4F7F\u7528\u8BF4\u660E","","\u8FD9\u4E2A\u6A21\u677F\u9002\u5408\u7EAF\u524D\u7AEF\u8F7B\u5E94\u7528\u3001\u5185\u5BB9\u5B98\u7F51\u3001\u6D3B\u52A8\u9875\u3001\u8868\u5355\u9875\u548C\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u4EE3\u7801\u5E76\u5165\u573A\u666F\u3002","\u4F60\u53EF\u4EE5\u628A\u5B83\u5F53\u6210\u666E\u901A\u7684 `React + Vite + TypeScript + Tailwind` \u9879\u76EE\u6765\u5F00\u53D1\uFF0C\u5E73\u53F0\u63A5\u5165\u5DF2\u7ECF\u6536\u53E3\u5728\u6A21\u677F\u91CC\u3002","","## \u5148\u770B\u8FD9\u51E0\u4E2A\u76EE\u5F55","","- `src/pages`\uFF1A\u4E1A\u52A1\u9875\u9762","- `src/components`\uFF1A\u901A\u7528\u7EC4\u4EF6","- `src/features/event-signup/*`\uFF1A\u53EF\u590D\u7528\u7684\u5B8C\u6574\u8868\u5355\u793A\u4F8B\uFF0C\u4E5F\u53EF\u88AB\u9875\u9762\u6E32\u67D3\u8BE6\u60C5\u9875\u6309 React Island \u65B9\u5F0F\u6302\u8F7D","- `src/platform/*`\uFF1A\u5E73\u53F0\u63A5\u5165\u5C42\uFF0C\u4E5F\u662F platform-managed scope\uFF1BP2 \u4E4B\u540E\u9ED8\u8BA4\u7531 `platform app sync-platform-blocks` \u7BA1\u7406","- `src/page-render/react-islands.tsx`\uFF1A\u9759\u6001 HTML \u9875\u9762\u5C40\u90E8 React \u589E\u5F3A\u6CE8\u518C\u8868\u4E0E\u6302\u8F7D helper","- `src/styles/*`\uFF1A\u5168\u5C40\u6837\u5F0F\u548C\u6B63\u6587\u6837\u5F0F","- `page-render/*`\uFF1A\u9875\u9762\u6E32\u67D3\u8DEF\u7531\u6CE8\u518C\u3001CMS \u7ED1\u5B9A\u548C shell \u914D\u7F6E","- `public/site/*`\uFF1A\u9875\u9762\u6E32\u67D3\u793A\u4F8B\u7684\u7AD9\u70B9 HTML \u6A21\u677F","- `public/shared/*`\uFF1A\u9759\u6001\u5185\u5BB9\u7AD9\u5171\u4EAB\u58F3\u3001\u811A\u672C\u548C\u6837\u5F0F\u76EE\u5F55","- `public/auth` \u4E0E `public/__app`\uFF1A\u767B\u5F55\u9875\u58F3\u3001\u767B\u5F55\u9875\u6587\u6848\u548C\u5C40\u90E8\u6837\u5F0F\u8986\u76D6","","## \u9ED8\u8BA4\u9875\u9762\u8DEF\u7531","","- `/`\uFF1A\u9996\u9875\uFF0C\u5BF9\u5E94 `src/pages/HomePage.tsx`","- `/form`\uFF1A\u8868\u5355\u9875\u793A\u4F8B\uFF0C\u5BF9\u5E94 `src/pages/FormPage.tsx`","- `/app`\uFF1A\u4FDD\u62A4\u9875\uFF0C\u5BF9\u5E94 `src/pages/ProtectedPage.tsx`","- `/cms`\uFF1ACMS \u793A\u4F8B\u9875\uFF0C\u5BF9\u5E94 `src/pages/CmsPage.tsx`","- `/articles`\uFF1A\u9875\u9762\u6E32\u67D3\u5217\u8868\u793A\u4F8B\uFF0C\u8BE6\u60C5\u9875\u4ECE\u5217\u8868\u5361\u7247\u8FDB\u5165","","## \u63A8\u8350\u5F00\u53D1\u65B9\u5F0F","","- \u7EAF\u9875\u9762\u5F00\u53D1\u76F4\u63A5\u7528 `platform dev`\u3002","- \u9700\u8981\u8054\u8C03 Auth / CMS / Workflow \u7B49\u5E73\u53F0\u80FD\u529B\u65F6\u7528 `platform dev --remote-bindings`\u3002","- \u4E91\u7AEF\u9A8C\u8BC1\u7528 `platform preview generate`\uFF0C\u6B63\u5F0F\u53D1\u5E03\u7528 `platform publish`\u3002","- \u6A21\u677F\u9ED8\u8BA4\u9644\u5E26\u4E00\u5957\u9875\u9762\u6E32\u67D3\u793A\u4F8B\uFF1A`/articles` \u5217\u8868\u9875\u3001\u8BE6\u60C5\u9875\u6A21\u677F\u3001`page-render/*.json` \u7ED1\u5B9A\u914D\u7F6E\u548C shell \u914D\u7F6E\u3002","- \u9875\u9762\u6E32\u67D3\u66F4\u9002\u5408\u5185\u5BB9\u5217\u8868\u9875\u3001\u5185\u5BB9\u8BE6\u60C5\u9875\u3001\u4E13\u9898\u9875\u3001\u843D\u5730\u9875\u7B49\u9700\u8981\u9996\u5C4F\u53EF\u6293\u53D6 HTML \u7684 SEO \u573A\u666F\u3002","- \u82E5\u4F60\u9700\u8981\u7EE7\u7EED\u6269\u5C55\u9875\u9762\u6E32\u67D3\uFF0C\u76F4\u63A5\u4FEE\u6539\u9879\u76EE\u6839\u7684 `page-render/registry.json`\u3001`page-render/pages/*.json`\u3001`page-render/shells/*.json`\uFF1B\u6A21\u677F build \u4F1A\u81EA\u52A8\u628A\u5B83\u4EEC\u6253\u8FDB `dist/page-render/`\u3002","- `platform dev` \u5728\u5F53\u524D\u76EE\u5F55\u7F3A\u5C11 `node_modules` \u65F6\u4F1A\u6309 lockfile \u81EA\u52A8\u5B89\u88C5\u4F9D\u8D56\uFF1B`platform preview generate --local-build` \u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5\uFF0C\u5148\u624B\u52A8\u6267\u884C\u4E00\u6B21\u4F9D\u8D56\u5B89\u88C5\u3002","- \u4E1A\u52A1\u4EE3\u7801\u6309\u5E38\u89C4\u524D\u7AEF\u65B9\u5F0F\u5199\uFF0C\u65E0\u9700\u7406\u89E3\u5E73\u53F0\u5165\u53E3\u5DEE\u5F02\uFF0C\u7EDF\u4E00\u6309\u8BED\u4E49\u8DEF\u7531\u548C helper \u5F00\u53D1\u3002","- \u65B0\u5EFA app \u4F1A\u9ED8\u8BA4\u751F\u6210 `.platform/platform-blocks.lock.json`\uFF1B\u5982\u679C\u4F60 checkout \u7684\u662F\u5386\u53F2 app\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt` \u8865\u7EB3\u7BA1\u3002","- \u63A8\u8350\u540C\u6B65\u987A\u5E8F\uFF1A`platform app sync-platform-blocks --dry-run` -> `--apply` -> \u672C\u5730\u9A8C\u8BC1\uFF1B\u9700\u8981\u65F6\u518D `--rollback --last`\u3002","","## \u5E38\u89C1\u5751","","- \u4E91\u7AEF `platform preview generate` \u4E0E\u672C\u5730\u5B89\u88C5\u5171\u7528\u5F53\u524D\u6A21\u677F\u5185\u7F6E\u7684 `package-lock.json`\uFF0C\u5E76\u4EE5 `npm ci` \u6309\u9501\u5B9A\u7248\u672C\u5B89\u88C5\uFF1B\u4F9D\u8D56\u53D8\u66F4\u540E\u9700\u540C\u6B65\u66F4\u65B0 lockfile\u3002","- \u4E0D\u8981\u5728\u9875\u9762\u91CC\u5199\u6B7B `/previews/...`\u3001`/apps/...`\u3001`https://...` \u8FD9\u7C7B\u5E73\u53F0\u8DEF\u5F84\u524D\u7F00\u3002","- \u6D4F\u89C8\u5668\u4FA7\u8BF7\u6C42\u548C\u8DF3\u8F6C\u4F18\u5148\u7528\u6A21\u677F\u5DF2\u6709 helper\uFF1B\u5982\u679C\u53EA\u662F\u9759\u6001\u8D44\u6E90\u6216\u540C\u6E90\u63A5\u53E3\uFF0C\u4F18\u5148\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 `./api/...`\u3001`./assets/...`\u3002",'- \u4E0D\u8981\u76F4\u63A5\u5199\u6839\u8DEF\u5F84\u5F15\u7528\uFF0C\u4F8B\u5982 `fetch(\'/api/...\')`\u3001`href="/..."`\u3001`src="/..."`\uFF0C\u8FD9\u7C7B\u5199\u6CD5\u5728 preview path \u6A21\u5F0F\u4E0B\u6700\u5BB9\u6613\u51FA\u9519\u3002',"- \u4E0D\u8981\u628A `.platform/source-context.json` \u5F53\u6210\u9875\u9762\u8FD0\u884C\u65F6\u914D\u7F6E\u6765\u6E90\uFF0C\u4E5F\u4E0D\u8981\u5728\u4EE3\u7801\u91CC\u5199\u6B7B `appId`\u3001`tenantId`\u3002","- \u9875\u9762\u6E32\u67D3\u6A21\u677F\u9002\u5408\u4F7F\u7528\u9759\u6001\u53EF\u679A\u4E3E class\uFF08\u542B Tailwind class\uFF09\uFF1B\u4E0D\u8981\u4F9D\u8D56\u8FD0\u884C\u65F6\u62FC\u63A5 class \u540E\u518D\u8BA9\u6784\u5EFA\u5668\u8865\u6837\u5F0F\u3002","","## \u9875\u9762\u6E32\u67D3\u793A\u4F8B\u4ECE\u54EA\u91CC\u5F00\u59CB","","- `public/site/article-list.html`\uFF1A\u5185\u5BB9\u5217\u8868\u9875 HTML \u6A21\u677F","- `public/site/article-detail.html`\uFF1A\u5185\u5BB9\u8BE6\u60C5\u9875 HTML \u6A21\u677F","- `src/page-render/react-islands.tsx`\uFF1AReact Island \u6CE8\u518C\u4E0E\u6302\u8F7D\u5165\u53E3\uFF0C\u7ED9\u9759\u6001 HTML \u9875\u9762\u8865\u5C40\u90E8\u4EA4\u4E92","- `src/features/event-signup/EventSignupForm.tsx`\uFF1A\u6A21\u677F\u81EA\u5E26\u7684\u5B8C\u6574\u8868\u5355\u7EC4\u4EF6\uFF0C\u53EF\u5728 SPA \u9875\u9762\u548C\u9759\u6001\u8BE6\u60C5\u9875\u4E2D\u590D\u7528","- `page-render/registry.json`\uFF1A\u9875\u9762\u6E32\u67D3\u8DEF\u7531\u6CE8\u518C\u5165\u53E3","- `page-render/pages/article-list.page-render.json`\uFF1A\u5217\u8868\u9875 collection \u7ED1\u5B9A\u3001\u5206\u9875\u3001\u8FC7\u6EE4\u3001\u8BE6\u60C5\u8DF3\u8F6C","- `page-render/pages/article-detail.page-render.json`\uFF1A\u8BE6\u60C5\u9875\u6B63\u6587\u7ED1\u5B9A\u548C\u63A8\u8350\u5217\u8868\u7ED1\u5B9A","- `page-render/shells/default.shell.json`\uFF1Aheader / footer \u53EF\u590D\u7528\u58F3\u914D\u7F6E","- Agent \u6269\u5C55\u9875\u9762\u6E32\u67D3\u65F6\uFF0C\u4F18\u5148\u6539\u4E0A\u9762\u8FD9\u4E9B\u6587\u4EF6\uFF1B\u53EA\u6709\u5728\u505A SPA \u9875\u9762\u6216\u5E73\u53F0\u80FD\u529B\u63A5\u7EBF\u65F6\uFF0C\u518D\u56DE\u5230 `src/pages/*` \u4E0E `src/platform/*`\u3002","","## \u4EC0\u4E48\u65F6\u5019\u6539 `src/platform/*`","","- \u9700\u8981\u63A5 Auth / CMS / Workflow / Blob \u7B49\u5E73\u53F0\u80FD\u529B\u65F6\u518D\u770B\u8FD9\u91CC\u3002","- \u666E\u901A\u9875\u9762\u3001\u7EC4\u4EF6\u3001\u6837\u5F0F\u6539\u9020\u4F18\u5148\u53EA\u52A8 `src/pages`\u3001`src/components`\u3001`src/styles`\u3002","- \u82E5\u53EA\u662F\u60F3\u505A\u4E1A\u52A1\u5B9A\u5236\uFF0C\u4E0D\u8981\u5148\u6539 `src/platform/*`\uFF1B\u5148\u5224\u65AD\u662F\u5426\u80FD\u653E\u5728 `src/pages`\u3001`src/components`\u3001`public/__app/*` \u89E3\u51B3\u3002","- \u5982\u679C\u8981\u6539\u767B\u5F55\u9875\u54C1\u724C\u3001\u8F7B\u6587\u6848\u6216\u5C40\u90E8\u6837\u5F0F\uFF0C\u4F18\u5148\u770B `public/auth/index.html`\u3001`public/__app/auth-ui.config.json`\u3001`public/__app/auth-ui.override.css`\u3002","- \u5982\u679C\u8131\u79BB\u5E73\u53F0\u5355\u72EC\u6253\u5F00\u9875\u9762\uFF0C\u5E73\u53F0\u80FD\u529B\u53EF\u80FD\u4F1A\u964D\u7EA7\u6216\u9700\u8981\u663E\u5F0F\u8865\u73AF\u5883\u53D8\u91CF\uFF0C\u8FD9\u5C5E\u4E8E\u9884\u671F\u884C\u4E3A\u3002","","## Data Form \u4ECE\u54EA\u91CC\u5F00\u59CB","","- `Data Form` \u7684\u58F0\u660E\u5165\u53E3\u7EA6\u5B9A\u5728 `resources/data-forms/*.yaml`\u3002","- \u6A21\u677F\u9ED8\u8BA4\u63D0\u4F9B `resources/data-forms/README.md` \u548C `0001_event_signup.yaml.example`\u3002","- `.yaml.example` \u662F\u6CE8\u91CA\u6001\u793A\u4F8B\uFF0C\u4E0D\u4F1A\u88AB `platform data-form validate` \u626B\u63CF\u3002","- \u793A\u4F8B\u5B57\u6BB5\u4E0E\u9ED8\u8BA4 `/form` \u9875\u9762\u4FDD\u6301\u4E00\u81F4\uFF1B\u628A\u5B83\u590D\u5236\u6216\u6539\u540D\u6210\u6B63\u5F0F `*.yaml` \u540E\u5373\u53EF\u76F4\u63A5\u63A5\u771F\u5B9E\u63D0\u4EA4\u6D41\u7A0B\u3002","","## \u6A21\u677F\u66F4\u65B0\u4E0E\u5E73\u53F0\u7EF4\u62A4\u533A","","- `src/platform/*` \u4E0E `.platform/platform-blocks.lock.json` \u9ED8\u8BA4\u5C5E\u4E8E\u7CFB\u7EDF\u7EDF\u4E00\u7EF4\u62A4\u533A\uFF1B\u666E\u901A\u4E1A\u52A1\u8FED\u4EE3\u4E0D\u8981\u628A\u5B83\u4EEC\u5F53\u6210\u81EA\u7531\u6539\u9020\u533A\u3002","- \u5E73\u53F0\u6A21\u677F\u5347\u7EA7\u65F6\uFF0C\u4F18\u5148\u6267\u884C `platform app sync-platform-blocks --dry-run` \u770B\u5DEE\u5F02\uFF1B\u786E\u8BA4\u65E0\u51B2\u7A81\u540E\u518D\u6267\u884C `--apply`\u3002","- \u5982\u679C\u5F53\u524D\u5DE5\u7A0B\u662F\u5386\u53F2 app \u4E14\u8FD8\u6CA1\u6709 `.platform/platform-blocks.lock.json`\uFF0C\u5148\u6267\u884C `platform app sync-platform-blocks --adopt`\uFF0C\u518D\u8FDB\u5165\u540E\u7EED\u5347\u7EA7\u3002","- \u82E5\u4F60\u4E3B\u52A8\u4FEE\u6539\u4E86 `src/platform/*`\uFF0C\u540E\u7EED `--apply` \u5F88\u53EF\u80FD\u8FDB\u5165 conflict\uFF1B\u8FD9\u5C5E\u4E8E\u4FDD\u62A4\u884C\u4E3A\uFF0C\u4E0D\u4F1A\u9759\u9ED8\u8986\u76D6\u3002","- Agent \u5F00\u53D1\u4E1A\u52A1\u529F\u80FD\u65F6\uFF0C\u4F18\u5148\u6539 `src/pages`\u3001`src/components`\u3001`src/styles`\u3001`public/__app/*`\uFF1B\u53EA\u6709\u786E\u5B9E\u5728\u8865\u5E73\u53F0\u80FD\u529B\u63A5\u7EBF\u65F6\uFF0C\u624D\u8FDB\u5165 `src/platform/*`\u3002","- \u82E5 apply \u540E\u9700\u8981\u56DE\u9000\uFF0C\u53EA\u652F\u6301 `platform app sync-platform-blocks --rollback --last`\uFF0C\u5B83\u4F1A\u6062\u590D\u6700\u8FD1\u4E00\u6B21\u771F\u5B9E\u8986\u76D6\u3002",""].join(`
|
|
2178
2177
|
`)}function buildEnvExampleSource2(templatePackageName){return[`APP_ID=${templatePackageName}`,"TENANT_ID=","APP_ENV=preview","PUBLIC_APP_BASE_URL=http://127.0.0.1:3000","CONTROL_API_BASE_URL=http://127.0.0.1:7001","RUNTIME_API_BASE_URL=","PUBLIC_API_BASE_URL=","CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES=","SOURCE_VERSION_ID=",""].join(`
|
|
2179
2178
|
`)}function buildTsconfigSource2(){return JSON.stringify({compilerOptions:{target:"ES2022",useDefineForClassFields:!0,lib:["ES2022","DOM","DOM.Iterable"],module:"ESNext",skipLibCheck:!0,moduleResolution:"Bundler",allowImportingTsExtensions:!1,resolveJsonModule:!0,isolatedModules:!0,noEmit:!0,jsx:"react-jsx",strict:!0,noFallthroughCasesInSwitch:!0,types:["vite/client","node"]},include:["src"]},null,2)+`
|
|
2180
2179
|
`}function buildViteConfigSource2(){return['import { defineConfig } from "vite";','import react from "@vitejs/plugin-react";','import tailwindcss from "@tailwindcss/vite";','import { createPlatformViteDevSupportPlugin } from "./src/platform/dev/vite/proxy";',"","export default defineConfig({",' base: "./",'," server: {"," port: Number(process.env.PORT || 3000),"," },"," plugins: [react(), tailwindcss(), createPlatformViteDevSupportPlugin()],","});",""].join(`
|
|
@@ -2193,7 +2192,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2193
2192
|
`}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
2193
|
`)}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
2194
|
`)}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".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(`
|
|
2195
|
+
`)}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:"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
2196
|
`))}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
2197
|
`);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
2198
|
`))}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)}
|
|
@@ -2223,8 +2222,8 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2223
2222
|
`));return}throw new Error("`platform asset tag` \u4EC5\u652F\u6301 `list`\u3001`add <asset-id> <label>`\u3001`remove <asset-id> <label>`\u3002")}function readStringOption(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasOption(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function readCsvOption(args,key){return(readStringOption(args,key)??"").split(",").map(item=>item.trim()).filter(Boolean)}function readBooleanOption(args,key){let value=readStringOption(args,key);if(value!==void 0){if(value==="true")return!0;if(value==="false")return!1;throw new Error(`\`--${key}\` \u4EC5\u652F\u6301 true \u6216 false\u3002`)}}function readNumberOption(args,key){let value=readStringOption(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed))throw new Error(`\`--${key}\` \u9700\u8981\u6570\u5B57\u3002`);return Math.trunc(parsed)}function readMediaTypeOption(args){let value=readStringOption(args,"media-type");if(value){if(value==="image"||value==="video")return value;throw new Error("`--media-type` \u4EC5\u652F\u6301 image \u6216 video\u3002")}}function readOrientationOption(args){let value=readStringOption(args,"orientation");if(value){if(value==="landscape"||value==="portrait"||value==="square")return value;throw new Error("`--orientation` \u4EC5\u652F\u6301 landscape\u3001portrait\u3001square\u3002")}}function readVariantKindOption(args){let value=readStringOption(args,"variant");if(value){if(value==="thumbnail"||value==="sm"||value==="md"||value==="lg"||value==="cover")return value;throw new Error("`--variant` \u4EC5\u652F\u6301 thumbnail\u3001sm\u3001md\u3001lg\u3001cover\u3002")}}function pickRecommendedAnalysisSource(detail){let mdUrl=detail.variant_urls.md;if(mdUrl)return{kind:"md",url:mdUrl};let smUrl=detail.variant_urls.sm;if(smUrl)return{kind:"sm",url:smUrl};let thumbnailUrl=detail.variant_urls.thumbnail;return thumbnailUrl?{kind:"thumbnail",url:thumbnailUrl}:{kind:"original",url:detail.original_url}}function hasHelpFlag(args){return args.options.help===!0||args.options.h===!0}function formatVariantLines(variantUrls){let lines=Object.entries(variantUrls).filter(entry=>typeof entry[1]=="string"&&entry[1].length>0).map(([kind,url])=>`variant.${kind}: ${url}`);return lines.length>0?lines:["variant: -"]}function normalizeNullableCliText(value){let normalized=value?.trim()??"";return normalized||null}function buildAnalyzeUpdateTemplate(assetId){return[`platform asset update ${assetId} \\`,' --summary "..." \\',' --caption "..." \\',' --scene "..." \\',' --objects "..." \\',' --tags "..."'].join(`
|
|
2224
2223
|
`)}function flattenShellContinuation(template){return template.replace(/\s*\\\s*\n\s*/g," ").replace(/\s{2,}/g," ").trim()}function buildVariantFileName(originalFileName,variants,variantKind){let variant=variants.find(item=>item.variant_kind===variantKind),extension=variant?inferExtensionFromMimeType(variant.mime_type):extname2(originalFileName)||".bin";return`${basename2(originalFileName,extname2(originalFileName))}.${variantKind}${extension}`}function inferExtensionFromMimeType(mimeType){switch(mimeType){case"image/jpeg":return".jpg";case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"video/mp4":return".mp4";case"video/webm":return".webm";default:return".bin"}}function resolveOutputPath(explicitOutputPath,fileName){if(explicitOutputPath)return resolve3(explicitOutputPath);let directory=mkdtempSync(join(tmpdir(),"platform-asset-"));return join(directory,fileName)}function formatAssetError(error,action){return error instanceof PlatformApiError?new Error([`\u7D20\u6750 ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
|
|
2225
2224
|
`)):error instanceof Error?error:new Error(`\u7D20\u6750 ${action} \u5931\u8D25\u3002`)}function formatAppCreateCheckoutError(input){let causeMessage=input.cause instanceof Error?input.cause.message:String(input.cause),retryCommand=["platform app checkout","--tenant",quoteCliArgument(input.tenantId),"--app",quoteCliArgument(input.appId),...input.targetDir?["--dir",quoteCliArgument(input.targetDir)]:[]].join(" ");return new Error(["\u4E91\u7AEF\u5E94\u7528\u5DF2\u7ECF\u521B\u5EFA\uFF0C\u4F46\u672C\u5730 checkout \u5931\u8D25\uFF1B\u4E91\u7AEF\u5E94\u7528\u672A\u56DE\u6EDA\u3002",`tenant_id: ${input.tenantId}`,`app_id: ${input.appId}`,`\u672C\u5730\u9519\u8BEF: ${causeMessage}`,"\u53EF\u4FEE\u590D\u672C\u5730\u76EE\u5F55\u95EE\u9898\u540E\u91CD\u8BD5\uFF1A",` ${retryCommand}`].join(`
|
|
2226
|
-
`))}function quoteCliArgument(value){return/^[A-Za-z0-9._:/-]+$/u.test(value)?value:JSON.stringify(value)}import{existsSync as existsSync9,mkdirSync as mkdirSync4,readdirSync as readdirSync3,readFileSync as readFileSync9,writeFileSync as writeFileSync5}from"node:fs";import{dirname as dirname6,join as join5,resolve as resolve7}from"node:path";import YAML2 from"yaml";import{createServer}from"node:http";import{createHash as createHash3,randomBytes}from"node:crypto";import{chmodSync,existsSync as existsSync7,mkdirSync as mkdirSync2,readFileSync as readFileSync7,writeFileSync as writeFileSync3}from"node:fs";import{existsSync as existsSync6,mkdirSync,writeFileSync as writeFileSync2}from"node:fs";import{homedir}from"node:os";import{dirname as dirname4,join as join3,resolve as resolve5}from"node:path";import{fileURLToPath as fileURLToPath4}from"node:url";import{existsSync as existsSync4,readFileSync as readFileSync5}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var AUTH_CLI_CLIENT_ID_KEYS=["AUTH_CLI_CLIENT_ID","LOGTO_CLI_APP_ID"],AUTH_CLI_REDIRECT_URI_KEYS=["AUTH_CLI_REDIRECT_URI","LOGTO_CLI_REDIRECT_URI"],AUTH_TENANT_CLIENT_ID_KEYS=["AUTH_TENANT_CLIENT_ID","LOGTO_TENANT_APP_ID","LOGTO_APP_ID"],AUTH_TENANT_REDIRECT_URI_KEYS=["AUTH_TENANT_REDIRECT_URI","LOGTO_TENANT_REDIRECT_URI"];function readTrimmedConfigValue(source,key){let value=source?.[key]?.trim();if(!(!value||/^<.+>$/.test(value)))return value}function readAuthConfigValue(keys,env=process.env){for(let key of keys){let fromEnv=readTrimmedConfigValue(env,key);if(fromEnv)return fromEnv}let defaults=getDistributionProfile().defaults??{};for(let key of keys){let fromDefaults=readTrimmedConfigValue(defaults,key);if(fromDefaults)return fromDefaults}}var defaultDeveloperProfile={name:"developer",defaults:{CONTROL_API_BASE_URL:"http://localhost:7001",PUBLIC_API_BASE_URL:"http://localhost:7007",RUNTIME_API_BASE_URL:"http://127.0.0.1.nip.io",OIDC_ISSUER:"http://localhost:3001/oidc",OIDC_AUDIENCE:"platform",LOGTO_CLI_REDIRECT_URI:"http://localhost:7300/callback",LOGTO_TENANT_REDIRECT_URI:"http://localhost:7102/callback"}},cachedProfile=null;function getDistributionProfile(){if(cachedProfile)return cachedProfile;let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return cachedProfile=defaultDeveloperProfile,cachedProfile;try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return cachedProfile=normalizeDistributionProfile(packageJson.platformDistributionProfile),cachedProfile}catch{return cachedProfile=defaultDeveloperProfile,cachedProfile}}function applyDistributionProfileDefaults(env=process.env){let profile=getDistributionProfile();for(let[key,value]of Object.entries(profile.defaults??{}))typeof value!="string"||value.trim().length===0||typeof env[key]=="string"&&env[key].trim().length>0||(env[key]=value);return profile}function getCliPackageVersion(){let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return"0.0.0";try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return typeof packageJson.version=="string"&&packageJson.version.trim().length>0?packageJson.version.trim():"0.0.0"}catch{return"0.0.0"}}function normalizeDistributionProfile(input){if(!input||input.name!=="developer"&&input.name!=="test-only"&&input.name!=="sandbox"&&input.name!=="nonprod"&&input.name!=="prod")return defaultDeveloperProfile;let defaults=input.name==="developer"?{...defaultDeveloperProfile.defaults}:{};for(let[key,value]of Object.entries(input.defaults??{}))typeof value=="string"&&value.trim().length>0&&(defaults[key]=value.trim());return{name:input.name,defaults}}function resolvePackageJsonPath(){let distDir=dirname2(fileURLToPath2(import.meta.url)),candidates=[join2(distDir,"..","package.json"),join2(distDir,"..","..","package.json")];for(let candidate of candidates)if(existsSync4(candidate))return candidate;return null}import{existsSync as existsSync5,readFileSync as readFileSync6,statSync
|
|
2227
|
-
`)),this.operation=operation,this.path=
|
|
2225
|
+
`))}function quoteCliArgument(value){return/^[A-Za-z0-9._:/-]+$/u.test(value)?value:JSON.stringify(value)}import{existsSync as existsSync9,mkdirSync as mkdirSync4,readdirSync as readdirSync3,readFileSync as readFileSync9,writeFileSync as writeFileSync5}from"node:fs";import{dirname as dirname6,join as join5,resolve as resolve7}from"node:path";import YAML2 from"yaml";import{createServer}from"node:http";import{createHash as createHash3,randomBytes}from"node:crypto";import{chmodSync,existsSync as existsSync7,mkdirSync as mkdirSync2,readFileSync as readFileSync7,writeFileSync as writeFileSync3}from"node:fs";import{existsSync as existsSync6,mkdirSync,writeFileSync as writeFileSync2}from"node:fs";import{homedir}from"node:os";import{dirname as dirname4,join as join3,resolve as resolve5}from"node:path";import{fileURLToPath as fileURLToPath4}from"node:url";import{existsSync as existsSync4,readFileSync as readFileSync5}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var AUTH_CLI_CLIENT_ID_KEYS=["AUTH_CLI_CLIENT_ID","LOGTO_CLI_APP_ID"],AUTH_CLI_REDIRECT_URI_KEYS=["AUTH_CLI_REDIRECT_URI","LOGTO_CLI_REDIRECT_URI"],AUTH_TENANT_CLIENT_ID_KEYS=["AUTH_TENANT_CLIENT_ID","LOGTO_TENANT_APP_ID","LOGTO_APP_ID"],AUTH_TENANT_REDIRECT_URI_KEYS=["AUTH_TENANT_REDIRECT_URI","LOGTO_TENANT_REDIRECT_URI"];function readTrimmedConfigValue(source,key){let value=source?.[key]?.trim();if(!(!value||/^<.+>$/.test(value)))return value}function readAuthConfigValue(keys,env=process.env){for(let key of keys){let fromEnv=readTrimmedConfigValue(env,key);if(fromEnv)return fromEnv}let defaults=getDistributionProfile().defaults??{};for(let key of keys){let fromDefaults=readTrimmedConfigValue(defaults,key);if(fromDefaults)return fromDefaults}}var defaultDeveloperProfile={name:"developer",defaults:{CONTROL_API_BASE_URL:"http://localhost:7001",PUBLIC_API_BASE_URL:"http://localhost:7007",RUNTIME_API_BASE_URL:"http://127.0.0.1.nip.io",OIDC_ISSUER:"http://localhost:3001/oidc",OIDC_AUDIENCE:"platform",LOGTO_CLI_REDIRECT_URI:"http://localhost:7300/callback",LOGTO_TENANT_REDIRECT_URI:"http://localhost:7102/callback"}},cachedProfile=null;function getDistributionProfile(){if(cachedProfile)return cachedProfile;let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return cachedProfile=defaultDeveloperProfile,cachedProfile;try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return cachedProfile=normalizeDistributionProfile(packageJson.platformDistributionProfile),cachedProfile}catch{return cachedProfile=defaultDeveloperProfile,cachedProfile}}function applyDistributionProfileDefaults(env=process.env){let profile=getDistributionProfile();for(let[key,value]of Object.entries(profile.defaults??{}))typeof value!="string"||value.trim().length===0||typeof env[key]=="string"&&env[key].trim().length>0||(env[key]=value);return profile}function getCliPackageVersion(){let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return"0.0.0";try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return typeof packageJson.version=="string"&&packageJson.version.trim().length>0?packageJson.version.trim():"0.0.0"}catch{return"0.0.0"}}function normalizeDistributionProfile(input){if(!input||input.name!=="developer"&&input.name!=="test-only"&&input.name!=="sandbox"&&input.name!=="nonprod"&&input.name!=="prod")return defaultDeveloperProfile;let defaults=input.name==="developer"?{...defaultDeveloperProfile.defaults}:{};for(let[key,value]of Object.entries(input.defaults??{}))typeof value=="string"&&value.trim().length>0&&(defaults[key]=value.trim());return{name:input.name,defaults}}function resolvePackageJsonPath(){let distDir=dirname2(fileURLToPath2(import.meta.url)),candidates=[join2(distDir,"..","package.json"),join2(distDir,"..","..","package.json")];for(let candidate of candidates)if(existsSync4(candidate))return candidate;return null}import{existsSync as existsSync5,readFileSync as readFileSync6,statSync}from"node:fs";import{dirname as dirname3,resolve as resolve4}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function stripQuotes(value){return value.startsWith('"')&&value.endsWith('"')||value.startsWith("'")&&value.endsWith("'")?value.slice(1,-1):value}function hasWorkspaceMarker(directory){return existsSync5(resolve4(directory,"pnpm-workspace.yaml"))}function getInvocationCwd(){let candidates=[process.env.PLATFORM_INVOCATION_CWD,process.env.INIT_CWD,process.env.PWD,process.cwd()];for(let candidate of candidates){if(!candidate||candidate.trim().length===0)continue;let resolved=resolve4(candidate);if(existsSync5(resolved))try{if(statSync(resolved).isDirectory())return resolved}catch{continue}}return resolve4(process.cwd())}function tryFindWorkspaceRoot(startDir=getInvocationCwd()){let current=resolve4(startDir);for(;;){if(hasWorkspaceMarker(current))return current;let parent=dirname3(current);if(parent===current)return null;current=parent}}function findWorkspaceRoot(startDir=getInvocationCwd()){return tryFindWorkspaceRoot(startDir)??resolve4(startDir)}function loadDotenvFiles(startDir=getInvocationCwd()){let workspaceRoot=findWorkspaceRoot(startDir),appRoot=resolve4(startDir),cliModuleRoot=resolve4(dirname3(fileURLToPath3(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot),developerLocalEnvFile=getDistributionProfile().name==="developer"?resolve4(process.env.PLATFORM_LOCAL_CLI_ENV_FILE?.trim()||resolve4(workspaceRoot,"TMP","local-cli.env")):null,candidates=[resolve4(workspaceRoot,".env"),resolve4(workspaceRoot,".env.local"),...developerLocalEnvFile?[developerLocalEnvFile]:[],resolve4(appRoot,".env"),resolve4(appRoot,".env.local"),resolve4(cliWorkspaceRoot,".env"),resolve4(cliWorkspaceRoot,".env.local"),resolve4(cliModuleRoot,".env"),resolve4(cliModuleRoot,".env.local")],visited=new Set;for(let filePath of candidates){if(visited.has(filePath)||(visited.add(filePath),!existsSync5(filePath)))continue;let lines=readFileSync6(filePath,"utf8").split(/\r?\n/u);for(let line of lines){let trimmed=line.trim();if(trimmed.length===0||trimmed.startsWith("#"))continue;let separatorIndex=trimmed.indexOf("=");if(separatorIndex<=0)continue;let key=trimmed.slice(0,separatorIndex).trim(),value=stripQuotes(trimmed.slice(separatorIndex+1).trim());process.env[key]||(process.env[key]=value)}}}var DEFAULT_STATE_DIR_NAME=".platform",LOCAL_DEVELOPER_STATE_DIR=join3("TMP","local-cli-state"),WORKSPACE_FALLBACK_STATE_DIR=join3("TMP","local-cli-state-fallback"),WORKSPACE_FALLBACK_MARKER=".state-fallback-active",activeFallbackStateDir=null,emittedFallbackWarnings=new Set,CliStateAccessError=class extends Error{operation;path;cause;constructor(operation,path3,cause){super([`\u65E0\u6CD5${operation} CLI \u672C\u5730\u72B6\u6001\u6587\u4EF6\uFF1A${path3}`,"\u8FD9\u901A\u5E38\u662F\u56E0\u4E3A\u5F53\u524D HOME / PLATFORM_STATE_DIR \u5BF9\u5E94\u76EE\u5F55\u4E0D\u53EF\u5199\uFF0C\u6216\u8FD0\u884C\u5728\u53D7\u9650\u6C99\u7BB1\u73AF\u5883\u4E2D\u3002","\u53EF\u5C1D\u8BD5\uFF1A","1. \u91CD\u65B0\u6267\u884C\u5E76\u786E\u8BA4\u5F53\u524D\u8D26\u53F7\u5BF9\u8BE5\u76EE\u5F55\u6709\u5199\u6743\u9650","2. \u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR` \u6307\u5411\u4E00\u4E2A\u53EF\u5199\u76EE\u5F55","3. \u82E5\u5728\u9694\u79BB\u73AF\u5883\u4E2D\u8FD0\u884C\uFF0C\u53EF\u4E3A\u8BE5\u73AF\u5883\u5355\u72EC\u914D\u7F6E `HOME` \u6216 `PLATFORM_STATE_DIR`"].join(`
|
|
2226
|
+
`)),this.operation=operation,this.path=path3,this.cause=cause,this.name="CliStateAccessError"}};function resolveDeveloperStateDir(){let cliModuleRoot=resolve5(dirname4(fileURLToPath4(import.meta.url)),".."),workspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve5(workspaceRoot,LOCAL_DEVELOPER_STATE_DIR)}function resolveWorkspaceFallbackStateDir(startDir=getInvocationCwd()){let workspaceRoot=tryFindWorkspaceRoot(startDir);return workspaceRoot?resolve5(workspaceRoot,WORKSPACE_FALLBACK_STATE_DIR):null}function resolveCliStateLocation(options={}){let configured=options.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim()??"";if(configured)return{dir:resolve5(configured),source:"configured"};if(activeFallbackStateDir)return{dir:activeFallbackStateDir,source:"workspace-fallback"};if((options.distributionProfileName??getDistributionProfile().name)==="developer")return{dir:resolveDeveloperStateDir(),source:"developer"};let fallbackDir=resolveWorkspaceFallbackStateDir(options.startDir);return fallbackDir&&existsSync6(resolve5(fallbackDir,WORKSPACE_FALLBACK_MARKER))?{dir:fallbackDir,source:"workspace-fallback"}:{dir:join3(options.homeDir??homedir(),DEFAULT_STATE_DIR_NAME),source:"home"}}function isCliStateAccessFailure(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"&&["EACCES","EPERM","EROFS"].includes(error.code??"")}function activateWorkspaceFallback(startDir=getInvocationCwd()){let fallbackDir=resolveWorkspaceFallbackStateDir(startDir);return fallbackDir?(mkdirSync(fallbackDir,{recursive:!0}),writeFileSync2(resolve5(fallbackDir,WORKSPACE_FALLBACK_MARKER),`active
|
|
2228
2227
|
`,"utf8"),activeFallbackStateDir=fallbackDir,fallbackDir):null}function emitFallbackWarning(originalPath,fallbackDir){emittedFallbackWarnings.has(fallbackDir)||(emittedFallbackWarnings.add(fallbackDir),console.warn([`\u68C0\u6D4B\u5230 CLI state \u9ED8\u8BA4\u76EE\u5F55\u4E0D\u53EF\u5199\uFF1A${originalPath}`,`\u5DF2\u81EA\u52A8\u5207\u6362\u5230\u4ED3\u5E93\u5185\u672C\u5730\u72B6\u6001\u76EE\u5F55\uFF1A${fallbackDir}`,"\u5982\u9700\u56FA\u5B9A\u8BE5\u884C\u4E3A\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR`\u3002"].join(`
|
|
2229
2228
|
`)))}function withCliStateFileWriteFallback(args){let primary=resolveCliStateLocation(args.resolution),primaryPath=join3(primary.dir,args.fileName);try{return args.write({filePath:primaryPath,stateDir:primary.dir})}catch(error){if(!isCliStateAccessFailure(error))throw error;let configuredStateDir=args.resolution?.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim();if(primary.source!=="home"||configuredStateDir?.trim())throw new CliStateAccessError(args.operation,primaryPath,error);try{let fallbackDir=activateWorkspaceFallback(args.resolution?.startDir);if(!fallbackDir)throw new CliStateAccessError(args.operation,primaryPath,error);emitFallbackWarning(primaryPath,fallbackDir);let fallbackPath=join3(fallbackDir,args.fileName);try{return args.write({filePath:fallbackPath,stateDir:fallbackDir})}catch(fallbackError){throw isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,fallbackPath,fallbackError):fallbackError}}catch(fallbackError){throw fallbackError instanceof CliStateAccessError?fallbackError:isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,primaryPath,fallbackError):fallbackError}}}function resolveCliStateDir(options={}){return resolveCliStateLocation(options).dir}function resolveCliStateFilePath(fileName){return join3(resolveCliStateDir(),fileName)}var DEFAULT_CONTROL_API_BASE_URL="http://localhost:7001",DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES="end_user_auth,cms",runtimeEndpointCapabilities=["end_user_auth","workflow","end_user_notification"],publicEndpointCapabilities=["cms","asset_library"];function getControlApiBaseUrl(env=process.env){let configured=env.CONTROL_API_BASE_URL?.trim();if(configured&&configured.length>0)return configured;let profileDefault=getDistributionProfile().defaults?.CONTROL_API_BASE_URL?.trim();return profileDefault&&profileDefault.length>0?profileDefault:DEFAULT_CONTROL_API_BASE_URL}function resolveControlApiEndpoint(args={}){let env=args.env??process.env,controlApiBaseUrl=getControlApiBaseUrl(env),allowlist=readRuntimeEndpointCapabilityAllowlist(env);return(args.requestClass==="runtime"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl:args.requestClass==="public"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl:void 0)??controlApiBaseUrl}function listResolvedControlApiEndpoints(env=process.env){let controlApiBaseUrl=getControlApiBaseUrl(env),runtimeBaseUrl=readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl,publicBaseUrl=readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl,allowlist=parseRuntimeEndpointCapabilityAllowlist(readRuntimeEndpointCapabilityAllowlist(env)),runtimeCapabilities=filterAllowedEndpointCapabilities(runtimeEndpointCapabilities,allowlist),publicCapabilities=filterAllowedEndpointCapabilities(publicEndpointCapabilities,allowlist);return[{role:"control",baseUrl:controlApiBaseUrl,enabled:!0,capabilities:[],requestClass:"control"},{role:"runtime",baseUrl:runtimeBaseUrl,enabled:runtimeBaseUrl!=null&&runtimeCapabilities.length>0,capabilities:runtimeCapabilities,requestClass:"runtime",...runtimeBaseUrl==null?{reason:"not_configured"}:runtimeCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}},{role:"public",baseUrl:publicBaseUrl,enabled:publicBaseUrl!=null&&publicCapabilities.length>0,capabilities:publicCapabilities,requestClass:"public",...publicBaseUrl==null?{reason:"not_configured"}:publicCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}}]}function createControlApiSdk(args){return createPlatformSdk({baseUrl:args.baseUrl??resolveControlApiEndpoint({capability:args.capability,requestClass:args.requestClass}),getHeaders:()=>({Authorization:`Bearer ${args.accessToken}`,...args.tenantId?{"X-Tenant-Id":args.tenantId}:{},...Object.fromEntries(Object.entries(args.extraHeaders??{}).filter(([,value])=>value!=null))})})}function readOptionalBaseUrl(value){let trimmed=value?.trim();return trimmed&&trimmed.length>0?trimmed:void 0}function isRuntimeEndpointCapabilityEnabled(capability,rawAllowlist){if(!capability)return!1;let allowlist=parseRuntimeEndpointCapabilityAllowlist(rawAllowlist);return allowlist.has("*")||allowlist.has(capability)}function readRuntimeEndpointCapabilityAllowlist(env){return Object.prototype.hasOwnProperty.call(env,"CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES")?env.CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES:DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES}function parseRuntimeEndpointCapabilityAllowlist(value){return new Set((value??"").split(/[,\s]+/u).map(item=>item.trim()).filter(item=>item.length>0))}function filterAllowedEndpointCapabilities(capabilities,allowlist){return allowlist.has("*")?[...capabilities]:capabilities.filter(capability=>allowlist.has(capability))}var TOKEN_REFRESH_SKEW_MS=6e4,PAT_LOGIN_VALIDITY_MS=10080*60*1e3,CliSessionExpiredError=class extends Error{detail;constructor(detail){super(detail&&detail.trim().length>0?`CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF08${detail.trim()}\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C \`platform login\`\u3002`:"CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002"),this.detail=detail,this.name="CliSessionExpiredError"}};function sleep(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}function normalizeOidcGrantFailure(detail){let normalized=detail?.trim();return normalized&&(/(^|[\s:_-])(invalid_grant)([\s:_-]|$)/iu.test(normalized)||/grant request is invalid/iu.test(normalized))?normalized:null}function mapTokenFailureToAuthError(args){let detail=normalizeOidcGrantFailure(args.errorDescription)??normalizeOidcGrantFailure(args.error);return detail?new CliSessionExpiredError(detail):new Error(args.errorDescription??args.error??args.fallback)}function maybeWrapCredentialRefreshError(error){if(error instanceof CliSessionExpiredError)throw error;if(error instanceof Error){let detail=normalizeOidcGrantFailure(error.message);if(detail)throw new CliSessionExpiredError(detail)}throw error}function applyResource(params,audience){if(audience){if(/^[a-z][a-z0-9+.-]*:/iu.test(audience)){params.set("resource",audience);return}params.set("audience",audience)}}function normalizeAuthorizationPrompt(scopes,prompt){let normalized=(prompt??"").split(/\s+/u).map(item=>item.trim()).filter(Boolean);return scopes.includes("offline_access")&&!normalized.includes("consent")&&normalized.push("consent"),normalized.length>0?normalized.join(" "):void 0}function getLoginSuccessHtml(){return`<!DOCTYPE html>
|
|
2230
2229
|
<html lang="zh-CN">
|
|
@@ -2362,10 +2361,10 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
|
|
|
2362
2361
|
</body>
|
|
2363
2362
|
</html>`}function escapeHtml(s){return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}async function discoverOidcEndpoints(issuer){let discoveryUrl=`${issuer.endsWith("/")?issuer.slice(0,-1):issuer}/.well-known/openid-configuration`,response=await fetch(discoveryUrl);if(!response.ok)throw new Error(`\u83B7\u53D6 OIDC discovery \u5931\u8D25: ${response.status}`);let document=await response.json();if(!document.authorization_endpoint||!document.token_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11\u6388\u6743\u6216 token \u7AEF\u70B9");return{authorization_endpoint:document.authorization_endpoint,device_authorization_endpoint:document.device_authorization_endpoint,token_endpoint:document.token_endpoint}}function getCredentialPath(){return resolveCliStateFilePath("credentials.json")}function getCliContextPath(){return resolveCliStateFilePath("context.json")}function loadStoredCredentials(){let credentialsPath=getCredentialPath();return existsSync7(credentialsPath)?JSON.parse(readFileSync7(credentialsPath,"utf8")):null}function selectApiToken(credentials){return looksLikeJwt(credentials.access_token)?credentials.access_token:looksLikeJwt(credentials.id_token)?credentials.id_token:credentials.access_token}function loadStoredCliContext(){let cliContextPath=getCliContextPath();return existsSync7(cliContextPath)?JSON.parse(readFileSync7(cliContextPath,"utf8")):null}function persistCredentials(credentials){withCliStateFileWriteFallback({fileName:"credentials.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync2(stateDir,{recursive:!0}),writeFileSync3(filePath,`${JSON.stringify(credentials,null,2)}
|
|
2364
2363
|
`,"utf8"),chmodSync(filePath,384)}})}function resolveStoredClientId(credentials){return credentials.client_id?.trim()||readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS)||readAuthConfigValue(AUTH_TENANT_CLIENT_ID_KEYS)}function readJwtExpiryMs(token){if(!looksLikeJwt(token))return null;try{let[,payload]=token.split("."),decoded=JSON.parse(Buffer.from(payload,"base64url").toString("utf8"));return typeof decoded.exp=="number"&&Number.isFinite(decoded.exp)?decoded.exp*1e3:null}catch{return null}}function isCredentialExpired(credentials,now=Date.now()){if(typeof credentials.expires_in=="number"&&Number.isFinite(credentials.expires_in)){let issuedAt=Date.parse(credentials.issued_at);if(Number.isFinite(issuedAt))return issuedAt+credentials.expires_in*1e3-TOKEN_REFRESH_SKEW_MS<=now}let jwtExpiry=readJwtExpiryMs(credentials.access_token)??readJwtExpiryMs(credentials.id_token);return typeof jwtExpiry=="number"?jwtExpiry-TOKEN_REFRESH_SKEW_MS<=now:!1}function canUsePatExchange(credentials,now=Date.now()){if(credentials.credential_mode!=="pat_exchange"||!credentials.exchange_subject_token||!credentials.exchange_subject_token_type||!resolveStoredClientId(credentials)||!credentials.mode_expires_at)return!1;let expiresAt=Date.parse(credentials.mode_expires_at);return Number.isFinite(expiresAt)&&expiresAt>now}async function refreshCredentials(credentials){let issuer=process.env.OIDC_ISSUER?.trim()||getDistributionProfile().defaults?.OIDC_ISSUER?.trim();if(!issuer)throw new Error("\u5F53\u524D\u73AF\u5883\u7F3A\u5C11 OIDC_ISSUER\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 CLI \u51ED\u636E\u3002");let clientId=resolveStoredClientId(credentials);if(!clientId)throw new Error("\u5F53\u524D\u51ED\u636E\u7F3A\u5C11 client_id\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 CLI \u51ED\u636E\u3002");if(!credentials.refresh_token)throw new Error("\u5F53\u524D\u51ED\u636E\u7F3A\u5C11 refresh_token\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002");let endpoints=await discoverOidcEndpoints(issuer),body=new URLSearchParams;body.set("grant_type","refresh_token"),body.set("client_id",clientId),body.set("refresh_token",credentials.refresh_token),applyResource(body,process.env.OIDC_AUDIENCE?.trim()||getDistributionProfile().defaults?.OIDC_AUDIENCE?.trim());let response=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),payload=await response.json();if(!response.ok)throw mapTokenFailureToAuthError({error:payload.error,errorDescription:payload.error_description,fallback:"\u5237\u65B0 CLI token \u5931\u8D25"});if(typeof payload.access_token!="string"||payload.access_token.length===0)throw new Error("\u5237\u65B0\u540E\u7684 token \u54CD\u5E94\u7F3A\u5C11 access_token");let nextCredentials={access_token:payload.access_token,id_token:typeof payload.id_token=="string"?payload.id_token:credentials.id_token,refresh_token:typeof payload.refresh_token=="string"?payload.refresh_token:credentials.refresh_token,client_id:clientId,token_type:payload.token_type??credentials.token_type,expires_in:typeof payload.expires_in=="number"?payload.expires_in:credentials.expires_in,scope:payload.scope??credentials.scope,issued_at:new Date().toISOString(),credential_mode:credentials.credential_mode??"interactive",exchange_subject_token:credentials.exchange_subject_token,exchange_subject_token_type:credentials.exchange_subject_token_type,mode_expires_at:credentials.mode_expires_at};return persistCredentials(nextCredentials),nextCredentials}async function exchangePatCredentials(credentials){let issuer=process.env.OIDC_ISSUER?.trim()||getDistributionProfile().defaults?.OIDC_ISSUER?.trim();if(!issuer)throw new Error("\u5F53\u524D\u73AF\u5883\u7F3A\u5C11 OIDC_ISSUER\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 PAT \u51ED\u636E\u3002");let clientId=resolveStoredClientId(credentials);if(!clientId)throw new Error("\u5F53\u524D PAT \u51ED\u636E\u7F3A\u5C11 client_id\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0\u3002");if(!credentials.exchange_subject_token||!credentials.exchange_subject_token_type)throw new Error("\u5F53\u524D PAT \u51ED\u636E\u7F3A\u5C11 subject_token\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login --pat <token>`\u3002");if(credentials.mode_expires_at){let hardExpiry=Date.parse(credentials.mode_expires_at);if(Number.isFinite(hardExpiry)&&hardExpiry<=Date.now())throw new Error("\u5F53\u524D PAT \u767B\u5F55\u5DF2\u8D85\u8FC7 7 \u5929\u6709\u6548\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login --pat <token>`\u3002")}let endpoints=await discoverOidcEndpoints(issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",clientId),body.set("subject_token",credentials.exchange_subject_token),body.set("subject_token_type",credentials.exchange_subject_token_type),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),credentials.scope?.trim()&&body.set("scope",credentials.scope.trim()),applyResource(body,process.env.OIDC_AUDIENCE?.trim()||getDistributionProfile().defaults?.OIDC_AUDIENCE?.trim());let response=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),payload=await response.json();if(!response.ok)throw mapTokenFailureToAuthError({error:payload.error,errorDescription:payload.error_description,fallback:"PAT \u4EA4\u6362 access token \u5931\u8D25"});if(typeof payload.access_token!="string"||payload.access_token.length===0)throw new Error("PAT \u4EA4\u6362\u540E\u7684 token \u54CD\u5E94\u7F3A\u5C11 access_token");let nextCredentials={access_token:payload.access_token,id_token:typeof payload.id_token=="string"?payload.id_token:credentials.id_token,client_id:clientId,token_type:payload.token_type??credentials.token_type,expires_in:typeof payload.expires_in=="number"?payload.expires_in:credentials.expires_in,scope:payload.scope??credentials.scope,issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:credentials.exchange_subject_token,exchange_subject_token_type:credentials.exchange_subject_token_type,mode_expires_at:credentials.mode_expires_at};return persistCredentials(nextCredentials),nextCredentials}async function loadStoredCredentialsEnsuringFresh(options={}){let credentials=loadStoredCredentials();if(!credentials)return null;let expired=isCredentialExpired(credentials);if(!options.forceRefresh&&!expired)return credentials;if(credentials.refresh_token)try{return refreshCredentials(credentials)}catch(error){maybeWrapCredentialRefreshError(error)}if(canUsePatExchange(credentials))try{return exchangePatCredentials(credentials)}catch(error){maybeWrapCredentialRefreshError(error)}if(expired)throw new Error("\u5F53\u524D\u51ED\u636E\u5DF2\u8FC7\u671F\u4E14\u4E0D\u652F\u6301\u81EA\u52A8\u5237\u65B0\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login` \u6216 `platform login --pat <token>`\u3002");return credentials}function persistCliContext(context){withCliStateFileWriteFallback({fileName:"context.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync2(stateDir,{recursive:!0}),writeFileSync3(filePath,`${JSON.stringify({...context,updated_at:new Date().toISOString()},null,2)}
|
|
2365
|
-
`,"utf8"),chmodSync(filePath,384)}})}async function performDeviceCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer);if(!endpoints.device_authorization_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9");let authBody=new URLSearchParams;authBody.set("client_id",config2.clientId),authBody.set("scope",config2.scopes.join(" ")),applyResource(authBody,config2.audience);let deviceResponse=await fetch(endpoints.device_authorization_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:authBody}),devicePayload=await deviceResponse.json();if(!deviceResponse.ok)throw new Error(devicePayload.error_description??devicePayload.error??"\u7533\u8BF7 device_code \u5931\u8D25");await config2.onPrompt?.({verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code,expiresIn:devicePayload.expires_in});let intervalSeconds=Math.max(devicePayload.interval??5,1),deadline=Date.now()+devicePayload.expires_in*1e3;for(;Date.now()<deadline;){await sleep(intervalSeconds*1e3);let tokenBody=new URLSearchParams;tokenBody.set("grant_type","urn:ietf:params:oauth:grant-type:device_code"),tokenBody.set("device_code",devicePayload.device_code),tokenBody.set("client_id",config2.clientId);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(tokenResponse.ok)return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code};if(tokenPayload.error!=="authorization_pending"){if(tokenPayload.error==="slow_down"){await sleep(intervalSeconds*1e3);continue}throw new Error(tokenPayload.error_description??tokenPayload.error??"\u8F6E\u8BE2 token \u5931\u8D25")}}throw new Error("Device Code \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`")}async function performAuthorizationCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),redirectUrl=new URL(config2.redirectUri);if(redirectUrl.protocol!=="http:")throw new Error("CLI \u6D4F\u89C8\u5668\u6388\u6743\u4EC5\u652F\u6301 http \u56DE\u8C03\u5730\u5740");let state=randomBytes(16).toString("base64url"),nonce=randomBytes(16).toString("base64url"),codeVerifier=randomBytes(32).toString("base64url"),codeChallenge=createHash3("sha256").update(codeVerifier).digest("base64url"),authorizationUrl=new URL(endpoints.authorization_endpoint);authorizationUrl.searchParams.set("client_id",config2.clientId),authorizationUrl.searchParams.set("redirect_uri",config2.redirectUri),authorizationUrl.searchParams.set("response_type","code"),authorizationUrl.searchParams.set("scope",config2.scopes.join(" ")),authorizationUrl.searchParams.set("state",state),authorizationUrl.searchParams.set("nonce",nonce),authorizationUrl.searchParams.set("code_challenge",codeChallenge),authorizationUrl.searchParams.set("code_challenge_method","S256");let normalizedPrompt=normalizeAuthorizationPrompt(config2.scopes,config2.prompt);normalizedPrompt&&authorizationUrl.searchParams.set("prompt",normalizedPrompt),applyResource(authorizationUrl.searchParams,config2.audience);let callbackResult=await new Promise((resolve19,reject)=>{let timeout=setTimeout(()=>{server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`"))},3e5),server=createServer((req,res)=>{let url=new URL(req.url??"/",config2.redirectUri);if(url.pathname!==redirectUrl.pathname){res.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Not Found");return}let returnedState=url.searchParams.get("state"),error=url.searchParams.get("error"),code2=url.searchParams.get("code");if(error){clearTimeout(timeout);let errMsg=url.searchParams.get("error_description")??error;res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml(errMsg)),server.close(()=>{}),reject(new Error(errMsg));return}if(!code2||returnedState!==state){clearTimeout(timeout),res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11\u6388\u6743\u7801\u6216 state \u4E0D\u5339\u914D\u3002")),server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11 code \u6216 state \u4E0D\u5339\u914D"));return}clearTimeout(timeout),res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginSuccessHtml()),server.close(()=>{}),resolve19({code:code2})});server.on("error",error=>{clearTimeout(timeout),reject(error)}),server.listen(Number(redirectUrl.port||80),redirectUrl.hostname,async()=>{try{await config2.onPrompt?.({authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri})}catch(error){clearTimeout(timeout),server.close(()=>{}),reject(error)}})}),tokenBody=new URLSearchParams;tokenBody.set("grant_type","authorization_code"),tokenBody.set("client_id",config2.clientId),tokenBody.set("code",callbackResult.code),tokenBody.set("redirect_uri",config2.redirectUri),tokenBody.set("code_verifier",codeVerifier),applyResource(tokenBody,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"\u6388\u6743\u7801\u6362\u53D6 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri}}async function performPatTokenExchangeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",config2.clientId),body.set("subject_token",config2.subjectToken),body.set("subject_token_type",config2.subjectTokenType??"urn:logto:token-type:personal_access_token"),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),config2.scopes.length>0&&body.set("scope",config2.scopes.join(" ")),applyResource(body,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"PAT \u4EA4\u6362 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:typeof tokenPayload.id_token=="string"?tokenPayload.id_token:void 0,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope??config2.scopes.join(" "),issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:config2.subjectToken,exchange_subject_token_type:config2.subjectTokenType??"urn:logto:token-type:personal_access_token",mode_expires_at:new Date(Date.now()+PAT_LOGIN_VALIDITY_MS).toISOString()}}async function fetchWhoAmI(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()}async function fetchTenantOverview(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"dashboard",requestClass:"control"}).getTenantOverview()}async function listTenantWorkspaces(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,capability:"auth",requestClass:"control"}).listTenantWorkspaces()}function looksLikeJwt(token){if(!token)return!1;let parts=token.split(".");return parts.length>=2&&parts.every(part=>part.length>0)}import{existsSync as existsSync8,mkdirSync as mkdirSync3,mkdtempSync as mkdtempSync2,readdirSync as readdirSync2,readFileSync as readFileSync8,renameSync,rmSync,statSync as statSync3,writeFileSync as writeFileSync4}from"node:fs";import{createServer as createNetServer}from"node:net";import{basename as basename3,dirname as dirname5,join as join4,relative,resolve as resolve6}from"node:path";import YAML from"yaml";var DEFAULT_APP_TEMPLATE_KEY="frontend-app-vite";function normalizeAppTemplateKey(value){if(typeof value>"u"||value.trim().length===0)return;let normalized=value.trim();if(normalized==="frontend-app-vite")return"frontend-app-vite";if(normalized==="backend-app-node")return"backend-app-node";throw new Error(`\u4E0D\u652F\u6301\u7684\u5E94\u7528\u6A21\u677F: ${normalized}\u3002\u5F53\u524D\u4EC5\u652F\u6301 \`frontend-app-vite\`\u3001\`backend-app-node\`\u3002\u65E7\u6A21\u677F\u5DF2\u4E0B\u7EBF\u3002`)}var PLATFORM_DIRECTORY=".platform",APP_MANIFEST_FILE="app.yaml",LEGACY_BINDING_FILE=join4(PLATFORM_DIRECTORY,"config.json"),SOURCE_CONTEXT_FILE=join4(PLATFORM_DIRECTORY,"source-context.json"),PLATFORM_BLOCKS_LOCKFILE=join4(PLATFORM_DIRECTORY,"platform-blocks.lock.json").replace(/\\/g,"/"),SOURCE_WORKSPACE_BYTES_LIMIT=50*1024*1024,SOURCE_WORKSPACE_ASSET_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".ico",".bmp",".avif",".mp4",".mp3",".wav",".ogg",".pdf",".woff",".woff2",".ttf",".otf",".eot",".zip",".gz"]);function ensureDirectory(directory){mkdirSync3(directory,{recursive:!0})}function writeFileIfMissing(path2,content){if(existsSync8(path2))throw new Error(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${path2}`);ensureDirectory(dirname5(path2)),writeFileSync4(path2,content,"utf8")}function listFilesRecursively(root,current=root){if(!existsSync8(current)||!statSync3(current).isDirectory())return[];let files=[];for(let entry of readdirSync2(current,{withFileTypes:!0})){let absolutePath=join4(current,entry.name);if(entry.isDirectory()){files.push(...listFilesRecursively(root,absolutePath));continue}entry.isFile()&&files.push(relative(root,absolutePath))}return files.sort((left,right)=>left.localeCompare(right))}function seedRuntimeSdkVendor(targetDir){let workspaceRoot=findWorkspaceRoot(),runtimeSdkDistDir=join4(workspaceRoot,"packages","runtime-sdk","dist");if(!existsSync8(runtimeSdkDistDir)||!statSync3(runtimeSdkDistDir).isDirectory())throw new Error(`\u7F3A\u5C11\u6D4F\u89C8\u5668\u4FA7 runtime-sdk \u6784\u5EFA\u4EA7\u7269\uFF1A${runtimeSdkDistDir}\u3002\u8BF7\u5148\u6267\u884C \`pnpm --filter @platform/runtime-sdk build\`\uFF0C\u518D\u91CD\u65B0\u521D\u59CB\u5316\u8F7B\u5E94\u7528\u6A21\u677F\u3002`);let created=[];for(let relativePath of listFilesRecursively(runtimeSdkDistDir)){let sourcePath=join4(runtimeSdkDistDir,relativePath),outputPath=join4(targetDir,"vendor","runtime-sdk",relativePath);writeFileIfMissing(outputPath,readFileSync8(sourcePath,"utf8")),created.push(relative(process.cwd(),outputPath))}return created}function normalizeAppManifest(input){let name=typeof input?.name=="string"&&input.name.trim().length>0?input.name.trim():"light-app",moduleName=typeof input?.module=="string"&&input.module.trim().length>0?input.module.trim():"light-app",templateKey=typeof input?.template_key=="string"&&input.template_key.trim().length>0?input.template_key.trim():DEFAULT_APP_TEMPLATE_KEY,normalizedEnvironments=Array.isArray(input?.environments)&&input.environments.length>0?input.environments.map(environment=>typeof environment?.name=="string"&&environment.name.trim().length>0?{name:environment.name.trim()}:null).filter(environment=>environment!==null):[];return{name,version:typeof input?.version=="string"&&input.version.trim().length>0?input.version.trim():"0.1.0",module:moduleName,template_key:templateKey,dev:{auto_restart:input?.dev?.auto_restart===!0},entry:{command:typeof input?.entry?.command=="string"&&input.entry.command.trim().length>0?input.entry.command.trim():"npm run dev",port:typeof input?.entry?.port=="number"&&Number.isFinite(input.entry.port)&&input.entry.port>0?input.entry.port:3e3,health_check:typeof input?.entry?.health_check=="string"&&input.entry.health_check.trim().length>0?input.entry.health_check.trim():"/healthz"},required_skills:Array.isArray(input?.required_skills)?input.required_skills.filter(Boolean):["db","auth"],permissions:Array.isArray(input?.permissions)?input.permissions.filter(Boolean):["app:read","app:write","app:publish"],env_vars:Array.isArray(input?.env_vars)?input.env_vars.filter(Boolean):["PORT","NODE_ENV","APP_ID","APP_ENV","TENANT_ID","DATABASE_URL","DATABASE_SCHEMA","CONTROL_API_BASE_URL"],runtime:{cpu:typeof input?.runtime?.cpu=="string"&&input.runtime.cpu.trim().length>0?input.runtime.cpu.trim():"250m",memory_mb:typeof input?.runtime?.memory_mb=="number"&&Number.isFinite(input.runtime.memory_mb)&&input.runtime.memory_mb>0?input.runtime.memory_mb:256},environments:normalizedEnvironments.length>0?normalizedEnvironments:[{name:"preview"},{name:"prod"}]}}function initProject(targetDir,_appName,templateKey=DEFAULT_APP_TEMPLATE_KEY){let absoluteTargetDir=resolve6(getInvocationCwd(),targetDir);ensureDirectory(absoluteTargetDir);let createdFiles=[],normalizedTemplateKey=normalizeAppTemplateKey(templateKey)??DEFAULT_APP_TEMPLATE_KEY,scaffoldFiles=normalizedTemplateKey==="frontend-app-vite"?assembleFrontendAppViteTemplate():normalizedTemplateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();for(let file of scaffoldFiles){let outputPath=join4(absoluteTargetDir,file.path);writeFileIfMissing(outputPath,file.content),createdFiles.push(relative(getInvocationCwd(),outputPath))}let vendorCreated=scaffoldFiles.some(file=>file.path.startsWith("vendor/runtime-sdk/")||file.path.startsWith("src/vendor/runtime-sdk/"))?[]:seedRuntimeSdkVendor(absoluteTargetDir);return[...createdFiles,...vendorCreated]}function scaffoldAppDebugSurface(startDir,scaffold){let appRoot=findAppRoot(startDir),appJsPath=join4(appRoot,"src","app.js");if(!existsSync8(appJsPath))throw new Error(`\u672A\u627E\u5230\u5E94\u7528\u5165\u53E3\u6587\u4EF6: ${appJsPath}`);let spec=getAppDebugScaffoldSpec(scaffold),createdFiles=[],updatedFiles=[],targetFilePath=join4(appRoot,spec.filePath);existsSync8(targetFilePath)||(ensureDirectory(dirname5(targetFilePath)),writeFileSync4(targetFilePath,spec.source,"utf8"),createdFiles.push(relative(appRoot,targetFilePath).replace(/\\/g,"/")));let appSource=readFileSync8(appJsPath,"utf8"),nextSource=injectDebugRouteIntoAppSource(appSource,spec);return nextSource!==appSource&&(writeFileSync4(appJsPath,nextSource,"utf8"),updatedFiles.push(relative(appRoot,appJsPath).replace(/\\/g,"/"))),{appRoot,createdFiles,updatedFiles,routePath:spec.routePath}}function readAppManifest(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),manifestPath=join4(appRoot,APP_MANIFEST_FILE),raw=readFileSync8(manifestPath,"utf8"),manifest=normalizeAppManifest(YAML.parse(raw));if(!manifest||typeof manifest!="object")throw new Error(`\u65E0\u6548\u7684 app.yaml: ${manifestPath}`);return{directory:appRoot,path:manifestPath,manifest}}function readLegacyBinding(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),bindingPath=join4(appRoot,LEGACY_BINDING_FILE);if(!existsSync8(bindingPath))return null;let raw=JSON.parse(readFileSync8(bindingPath,"utf8")),binding={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at??new Date(0).toISOString(),workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,validated_at:raw.validated_at};return{path:bindingPath,binding}}function readBinding(startDir=getInvocationCwd()){let sourceContext=readSourceContext(startDir);if(sourceContext?.sourceContext.tenant_id&&sourceContext.sourceContext.app_id){let context=sourceContext.sourceContext;return{path:sourceContext.path,binding:{schema_version:1,tenant_id:context.tenant_id,app_id:context.app_id,env:context.env||"preview",linked_at:context.linked_at??context.checked_out_at??context.updated_at,workspace_name:context.workspace_name,app_name:context.app_name,app_display_name:context.app_display_name,validated_at:context.validated_at}}}return readLegacyBinding(startDir)}function writeBinding(startDir,binding){let result=updateSourceContext(startDir,{tenant_id:binding.tenant_id,app_id:binding.app_id,env:binding.env,workspace_name:binding.workspace_name,app_name:binding.app_name,app_display_name:binding.app_display_name,validated_at:binding.validated_at,linked_at:new Date().toISOString()});return{appRoot:result.appRoot,path:result.path}}function readSourceContext(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),sourceContextPath=join4(appRoot,SOURCE_CONTEXT_FILE);if(!existsSync8(sourceContextPath))return null;let raw=JSON.parse(readFileSync8(sourceContextPath,"utf8")),sourceContext={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at,validated_at:raw.validated_at,workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,template_key:raw.template_key,default_directory:raw.default_directory,generated_from_template:typeof raw.generated_from_template=="boolean"?raw.generated_from_template:void 0,base_source_version_id:raw.base_source_version_id,checked_out_at:raw.checked_out_at,last_submitted_source_version_id:raw.last_submitted_source_version_id,last_submitted_at:raw.last_submitted_at,last_preview_source_version_id:raw.last_preview_source_version_id,last_preview_build_id:raw.last_preview_build_id,last_preview_generated_at:raw.last_preview_generated_at,control_plane:raw.control_plane&&typeof raw.control_plane=="object"?raw.control_plane:void 0,updated_at:raw.updated_at??new Date(0).toISOString()};return{path:sourceContextPath,sourceContext}}function writeSourceContext(startDir,sourceContext){let appRoot=findAppRoot(startDir),path2=join4(appRoot,SOURCE_CONTEXT_FILE);return ensureDirectory(dirname5(path2)),writeFileSync4(path2,`${JSON.stringify({schema_version:1,...sourceContext,updated_at:new Date().toISOString()},null,2)}
|
|
2366
|
-
`,"utf8"),{appRoot,path:
|
|
2364
|
+
`,"utf8"),chmodSync(filePath,384)}})}async function performDeviceCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer);if(!endpoints.device_authorization_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9");let authBody=new URLSearchParams;authBody.set("client_id",config2.clientId),authBody.set("scope",config2.scopes.join(" ")),applyResource(authBody,config2.audience);let deviceResponse=await fetch(endpoints.device_authorization_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:authBody}),devicePayload=await deviceResponse.json();if(!deviceResponse.ok)throw new Error(devicePayload.error_description??devicePayload.error??"\u7533\u8BF7 device_code \u5931\u8D25");await config2.onPrompt?.({verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code,expiresIn:devicePayload.expires_in});let intervalSeconds=Math.max(devicePayload.interval??5,1),deadline=Date.now()+devicePayload.expires_in*1e3;for(;Date.now()<deadline;){await sleep(intervalSeconds*1e3);let tokenBody=new URLSearchParams;tokenBody.set("grant_type","urn:ietf:params:oauth:grant-type:device_code"),tokenBody.set("device_code",devicePayload.device_code),tokenBody.set("client_id",config2.clientId);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(tokenResponse.ok)return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code};if(tokenPayload.error!=="authorization_pending"){if(tokenPayload.error==="slow_down"){await sleep(intervalSeconds*1e3);continue}throw new Error(tokenPayload.error_description??tokenPayload.error??"\u8F6E\u8BE2 token \u5931\u8D25")}}throw new Error("Device Code \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`")}async function performAuthorizationCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),redirectUrl=new URL(config2.redirectUri);if(redirectUrl.protocol!=="http:")throw new Error("CLI \u6D4F\u89C8\u5668\u6388\u6743\u4EC5\u652F\u6301 http \u56DE\u8C03\u5730\u5740");let state=randomBytes(16).toString("base64url"),nonce=randomBytes(16).toString("base64url"),codeVerifier=randomBytes(32).toString("base64url"),codeChallenge=createHash3("sha256").update(codeVerifier).digest("base64url"),authorizationUrl=new URL(endpoints.authorization_endpoint);authorizationUrl.searchParams.set("client_id",config2.clientId),authorizationUrl.searchParams.set("redirect_uri",config2.redirectUri),authorizationUrl.searchParams.set("response_type","code"),authorizationUrl.searchParams.set("scope",config2.scopes.join(" ")),authorizationUrl.searchParams.set("state",state),authorizationUrl.searchParams.set("nonce",nonce),authorizationUrl.searchParams.set("code_challenge",codeChallenge),authorizationUrl.searchParams.set("code_challenge_method","S256");let normalizedPrompt=normalizeAuthorizationPrompt(config2.scopes,config2.prompt);normalizedPrompt&&authorizationUrl.searchParams.set("prompt",normalizedPrompt),applyResource(authorizationUrl.searchParams,config2.audience);let callbackResult=await new Promise((resolve19,reject)=>{let timeout=setTimeout(()=>{server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`"))},3e5),server=createServer((req,res)=>{let url=new URL(req.url??"/",config2.redirectUri);if(url.pathname!==redirectUrl.pathname){res.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Not Found");return}let returnedState=url.searchParams.get("state"),error=url.searchParams.get("error"),code2=url.searchParams.get("code");if(error){clearTimeout(timeout);let errMsg=url.searchParams.get("error_description")??error;res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml(errMsg)),server.close(()=>{}),reject(new Error(errMsg));return}if(!code2||returnedState!==state){clearTimeout(timeout),res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11\u6388\u6743\u7801\u6216 state \u4E0D\u5339\u914D\u3002")),server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11 code \u6216 state \u4E0D\u5339\u914D"));return}clearTimeout(timeout),res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginSuccessHtml()),server.close(()=>{}),resolve19({code:code2})});server.on("error",error=>{clearTimeout(timeout),reject(error)}),server.listen(Number(redirectUrl.port||80),redirectUrl.hostname,async()=>{try{await config2.onPrompt?.({authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri})}catch(error){clearTimeout(timeout),server.close(()=>{}),reject(error)}})}),tokenBody=new URLSearchParams;tokenBody.set("grant_type","authorization_code"),tokenBody.set("client_id",config2.clientId),tokenBody.set("code",callbackResult.code),tokenBody.set("redirect_uri",config2.redirectUri),tokenBody.set("code_verifier",codeVerifier),applyResource(tokenBody,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"\u6388\u6743\u7801\u6362\u53D6 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri}}async function performPatTokenExchangeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",config2.clientId),body.set("subject_token",config2.subjectToken),body.set("subject_token_type",config2.subjectTokenType??"urn:logto:token-type:personal_access_token"),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),config2.scopes.length>0&&body.set("scope",config2.scopes.join(" ")),applyResource(body,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"PAT \u4EA4\u6362 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:typeof tokenPayload.id_token=="string"?tokenPayload.id_token:void 0,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope??config2.scopes.join(" "),issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:config2.subjectToken,exchange_subject_token_type:config2.subjectTokenType??"urn:logto:token-type:personal_access_token",mode_expires_at:new Date(Date.now()+PAT_LOGIN_VALIDITY_MS).toISOString()}}async function fetchWhoAmI(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()}async function fetchTenantOverview(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"dashboard",requestClass:"control"}).getTenantOverview()}async function listTenantWorkspaces(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,capability:"auth",requestClass:"control"}).listTenantWorkspaces()}function looksLikeJwt(token){if(!token)return!1;let parts=token.split(".");return parts.length>=2&&parts.every(part=>part.length>0)}import{existsSync as existsSync8,mkdirSync as mkdirSync3,mkdtempSync as mkdtempSync2,readdirSync as readdirSync2,readFileSync as readFileSync8,renameSync,rmSync,statSync as statSync2,writeFileSync as writeFileSync4}from"node:fs";import{createServer as createNetServer}from"node:net";import{basename as basename3,dirname as dirname5,join as join4,relative,resolve as resolve6}from"node:path";import YAML from"yaml";var DEFAULT_APP_TEMPLATE_KEY="frontend-app-vite";function normalizeAppTemplateKey(value){if(typeof value>"u"||value.trim().length===0)return;let normalized=value.trim();if(normalized==="frontend-app-vite")return"frontend-app-vite";if(normalized==="backend-app-node")return"backend-app-node";throw new Error(`\u4E0D\u652F\u6301\u7684\u5E94\u7528\u6A21\u677F: ${normalized}\u3002\u5F53\u524D\u4EC5\u652F\u6301 \`frontend-app-vite\`\u3001\`backend-app-node\`\u3002\u65E7\u6A21\u677F\u5DF2\u4E0B\u7EBF\u3002`)}var PLATFORM_DIRECTORY=".platform",APP_MANIFEST_FILE="app.yaml",LEGACY_BINDING_FILE=join4(PLATFORM_DIRECTORY,"config.json"),SOURCE_CONTEXT_FILE=join4(PLATFORM_DIRECTORY,"source-context.json"),PLATFORM_BLOCKS_LOCKFILE=join4(PLATFORM_DIRECTORY,"platform-blocks.lock.json").replace(/\\/g,"/"),SOURCE_WORKSPACE_BYTES_LIMIT=50*1024*1024,SOURCE_WORKSPACE_ASSET_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".ico",".bmp",".avif",".mp4",".mp3",".wav",".ogg",".pdf",".woff",".woff2",".ttf",".otf",".eot",".zip",".gz"]);function ensureDirectory(directory){mkdirSync3(directory,{recursive:!0})}function writeFileIfMissing(path3,content){if(existsSync8(path3))throw new Error(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${path3}`);ensureDirectory(dirname5(path3)),writeFileSync4(path3,content,"utf8")}function listFilesRecursively(root,current=root){if(!existsSync8(current)||!statSync2(current).isDirectory())return[];let files=[];for(let entry of readdirSync2(current,{withFileTypes:!0})){let absolutePath=join4(current,entry.name);if(entry.isDirectory()){files.push(...listFilesRecursively(root,absolutePath));continue}entry.isFile()&&files.push(relative(root,absolutePath))}return files.sort((left,right)=>left.localeCompare(right))}function seedRuntimeSdkVendor(targetDir){let workspaceRoot=findWorkspaceRoot(),runtimeSdkDistDir=join4(workspaceRoot,"packages","runtime-sdk","dist");if(!existsSync8(runtimeSdkDistDir)||!statSync2(runtimeSdkDistDir).isDirectory())throw new Error(`\u7F3A\u5C11\u6D4F\u89C8\u5668\u4FA7 runtime-sdk \u6784\u5EFA\u4EA7\u7269\uFF1A${runtimeSdkDistDir}\u3002\u8BF7\u5148\u6267\u884C \`pnpm --filter @platform/runtime-sdk build\`\uFF0C\u518D\u91CD\u65B0\u521D\u59CB\u5316\u8F7B\u5E94\u7528\u6A21\u677F\u3002`);let created=[];for(let relativePath of listFilesRecursively(runtimeSdkDistDir)){let sourcePath=join4(runtimeSdkDistDir,relativePath),outputPath=join4(targetDir,"vendor","runtime-sdk",relativePath);writeFileIfMissing(outputPath,readFileSync8(sourcePath,"utf8")),created.push(relative(process.cwd(),outputPath))}return created}function normalizeAppManifest(input){let name=typeof input?.name=="string"&&input.name.trim().length>0?input.name.trim():"light-app",moduleName=typeof input?.module=="string"&&input.module.trim().length>0?input.module.trim():"light-app",templateKey=typeof input?.template_key=="string"&&input.template_key.trim().length>0?input.template_key.trim():DEFAULT_APP_TEMPLATE_KEY,normalizedEnvironments=Array.isArray(input?.environments)&&input.environments.length>0?input.environments.map(environment=>typeof environment?.name=="string"&&environment.name.trim().length>0?{name:environment.name.trim()}:null).filter(environment=>environment!==null):[];return{name,version:typeof input?.version=="string"&&input.version.trim().length>0?input.version.trim():"0.1.0",module:moduleName,template_key:templateKey,dev:{auto_restart:input?.dev?.auto_restart===!0},entry:{command:typeof input?.entry?.command=="string"&&input.entry.command.trim().length>0?input.entry.command.trim():"npm run dev",port:typeof input?.entry?.port=="number"&&Number.isFinite(input.entry.port)&&input.entry.port>0?input.entry.port:3e3,health_check:typeof input?.entry?.health_check=="string"&&input.entry.health_check.trim().length>0?input.entry.health_check.trim():"/healthz"},required_skills:Array.isArray(input?.required_skills)?input.required_skills.filter(Boolean):["db","auth"],permissions:Array.isArray(input?.permissions)?input.permissions.filter(Boolean):["app:read","app:write","app:publish"],env_vars:Array.isArray(input?.env_vars)?input.env_vars.filter(Boolean):["PORT","NODE_ENV","APP_ID","APP_ENV","TENANT_ID","DATABASE_URL","DATABASE_SCHEMA","CONTROL_API_BASE_URL"],runtime:{cpu:typeof input?.runtime?.cpu=="string"&&input.runtime.cpu.trim().length>0?input.runtime.cpu.trim():"250m",memory_mb:typeof input?.runtime?.memory_mb=="number"&&Number.isFinite(input.runtime.memory_mb)&&input.runtime.memory_mb>0?input.runtime.memory_mb:256},environments:normalizedEnvironments.length>0?normalizedEnvironments:[{name:"preview"},{name:"prod"}]}}function initProject(targetDir,_appName,templateKey=DEFAULT_APP_TEMPLATE_KEY){let absoluteTargetDir=resolve6(getInvocationCwd(),targetDir);ensureDirectory(absoluteTargetDir);let createdFiles=[],normalizedTemplateKey=normalizeAppTemplateKey(templateKey)??DEFAULT_APP_TEMPLATE_KEY,scaffoldFiles=normalizedTemplateKey==="frontend-app-vite"?assembleFrontendAppViteTemplate():normalizedTemplateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();for(let file of scaffoldFiles){let outputPath=join4(absoluteTargetDir,file.path);writeFileIfMissing(outputPath,file.content),createdFiles.push(relative(getInvocationCwd(),outputPath))}let vendorCreated=scaffoldFiles.some(file=>file.path.startsWith("vendor/runtime-sdk/")||file.path.startsWith("src/vendor/runtime-sdk/"))?[]:seedRuntimeSdkVendor(absoluteTargetDir);return[...createdFiles,...vendorCreated]}function scaffoldAppDebugSurface(startDir,scaffold){let appRoot=findAppRoot(startDir),appJsPath=join4(appRoot,"src","app.js");if(!existsSync8(appJsPath))throw new Error(`\u672A\u627E\u5230\u5E94\u7528\u5165\u53E3\u6587\u4EF6: ${appJsPath}`);let spec=getAppDebugScaffoldSpec(scaffold),createdFiles=[],updatedFiles=[],targetFilePath=join4(appRoot,spec.filePath);existsSync8(targetFilePath)||(ensureDirectory(dirname5(targetFilePath)),writeFileSync4(targetFilePath,spec.source,"utf8"),createdFiles.push(relative(appRoot,targetFilePath).replace(/\\/g,"/")));let appSource=readFileSync8(appJsPath,"utf8"),nextSource=injectDebugRouteIntoAppSource(appSource,spec);return nextSource!==appSource&&(writeFileSync4(appJsPath,nextSource,"utf8"),updatedFiles.push(relative(appRoot,appJsPath).replace(/\\/g,"/"))),{appRoot,createdFiles,updatedFiles,routePath:spec.routePath}}function readAppManifest(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),manifestPath=join4(appRoot,APP_MANIFEST_FILE),raw=readFileSync8(manifestPath,"utf8"),manifest=normalizeAppManifest(YAML.parse(raw));if(!manifest||typeof manifest!="object")throw new Error(`\u65E0\u6548\u7684 app.yaml: ${manifestPath}`);return{directory:appRoot,path:manifestPath,manifest}}function readLegacyBinding(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),bindingPath=join4(appRoot,LEGACY_BINDING_FILE);if(!existsSync8(bindingPath))return null;let raw=JSON.parse(readFileSync8(bindingPath,"utf8")),binding={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at??new Date(0).toISOString(),workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,validated_at:raw.validated_at};return{path:bindingPath,binding}}function readBinding(startDir=getInvocationCwd()){let sourceContext=readSourceContext(startDir);if(sourceContext?.sourceContext.tenant_id&&sourceContext.sourceContext.app_id){let context=sourceContext.sourceContext;return{path:sourceContext.path,binding:{schema_version:1,tenant_id:context.tenant_id,app_id:context.app_id,env:context.env||"preview",linked_at:context.linked_at??context.checked_out_at??context.updated_at,workspace_name:context.workspace_name,app_name:context.app_name,app_display_name:context.app_display_name,validated_at:context.validated_at}}}return readLegacyBinding(startDir)}function writeBinding(startDir,binding){let result=updateSourceContext(startDir,{tenant_id:binding.tenant_id,app_id:binding.app_id,env:binding.env,workspace_name:binding.workspace_name,app_name:binding.app_name,app_display_name:binding.app_display_name,validated_at:binding.validated_at,linked_at:new Date().toISOString()});return{appRoot:result.appRoot,path:result.path}}function readSourceContext(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),sourceContextPath=join4(appRoot,SOURCE_CONTEXT_FILE);if(!existsSync8(sourceContextPath))return null;let raw=JSON.parse(readFileSync8(sourceContextPath,"utf8")),sourceContext={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at,validated_at:raw.validated_at,workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,template_key:raw.template_key,default_directory:raw.default_directory,generated_from_template:typeof raw.generated_from_template=="boolean"?raw.generated_from_template:void 0,base_source_version_id:raw.base_source_version_id,checked_out_at:raw.checked_out_at,last_submitted_source_version_id:raw.last_submitted_source_version_id,last_submitted_at:raw.last_submitted_at,last_preview_source_version_id:raw.last_preview_source_version_id,last_preview_build_id:raw.last_preview_build_id,last_preview_generated_at:raw.last_preview_generated_at,control_plane:raw.control_plane&&typeof raw.control_plane=="object"?raw.control_plane:void 0,updated_at:raw.updated_at??new Date(0).toISOString()};return{path:sourceContextPath,sourceContext}}function writeSourceContext(startDir,sourceContext){let appRoot=findAppRoot(startDir),path3=join4(appRoot,SOURCE_CONTEXT_FILE);return ensureDirectory(dirname5(path3)),writeFileSync4(path3,`${JSON.stringify({schema_version:1,...sourceContext,updated_at:new Date().toISOString()},null,2)}
|
|
2365
|
+
`,"utf8"),{appRoot,path:path3}}function updateSourceContext(startDir,patch){let appRoot=findAppRoot(startDir),existing=readSourceContext(appRoot)?.sourceContext,legacyBinding=readLegacyBinding(appRoot)?.binding;return writeSourceContext(appRoot,{tenant_id:patch.tenant_id??existing?.tenant_id??legacyBinding?.tenant_id??"",app_id:patch.app_id??existing?.app_id??legacyBinding?.app_id??"",env:patch.env??existing?.env??legacyBinding?.env??"preview",linked_at:patch.linked_at??existing?.linked_at??legacyBinding?.linked_at,validated_at:patch.validated_at??existing?.validated_at??legacyBinding?.validated_at,workspace_name:patch.workspace_name??existing?.workspace_name??legacyBinding?.workspace_name,app_name:patch.app_name??existing?.app_name??legacyBinding?.app_name,app_display_name:patch.app_display_name??existing?.app_display_name??legacyBinding?.app_display_name,template_key:patch.template_key??existing?.template_key,default_directory:patch.default_directory??existing?.default_directory,generated_from_template:typeof patch.generated_from_template=="boolean"?patch.generated_from_template:existing?.generated_from_template,base_source_version_id:patch.base_source_version_id??existing?.base_source_version_id,checked_out_at:patch.checked_out_at??existing?.checked_out_at,last_submitted_source_version_id:patch.last_submitted_source_version_id??existing?.last_submitted_source_version_id,last_submitted_at:patch.last_submitted_at??existing?.last_submitted_at,last_preview_source_version_id:patch.last_preview_source_version_id??existing?.last_preview_source_version_id,last_preview_build_id:patch.last_preview_build_id??existing?.last_preview_build_id,last_preview_generated_at:patch.last_preview_generated_at??existing?.last_preview_generated_at,control_plane:patch.control_plane??existing?.control_plane})}function checkoutSourceWorkspace(targetDir,files,sourceContext){let absoluteTargetDir=resolve6(getInvocationCwd(),targetDir);if(validatePortableWorkspacePaths(files),existsSync8(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF08\u5305\u62EC\u7A7A\u76EE\u5F55\uFF09: ${absoluteTargetDir}`);let parentDir=dirname5(absoluteTargetDir);ensureDirectory(parentDir);let stagingDir=mkdtempSync2(join4(parentDir,`.${basename3(absoluteTargetDir)}.platform-checkout-`));try{for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);writeFileIfMissing(join4(stagingDir,normalizedPath),file.content)}let now=new Date().toISOString();if(writeFileIfMissing(join4(stagingDir,SOURCE_CONTEXT_FILE),`${JSON.stringify({schema_version:1,...sourceContext,linked_at:sourceContext.linked_at??now,updated_at:now},null,2)}
|
|
2367
2366
|
`),existsSync8(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5728\u68C0\u51FA\u8FC7\u7A0B\u4E2D\u88AB\u521B\u5EFA\uFF0C\u62D2\u7EDD\u8986\u76D6: ${absoluteTargetDir}`);renameSync(stagingDir,absoluteTargetDir)}catch(error){throw rmSync(stagingDir,{recursive:!0,force:!0}),error}return files.map(file=>relative(getInvocationCwd(),join4(absoluteTargetDir,normalizePortableWorkspacePath(file.path))))}function validatePortableWorkspacePaths(files){let canonicalPaths=new Map;for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);if(normalizedPath.toLowerCase()===SOURCE_CONTEXT_FILE.replace(/\\/gu,"/").toLowerCase())throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5\uFF08CLI \u4FDD\u7559\u8DEF\u5F84\uFF09: ${file.path}`);let canonicalPath=normalizedPath.normalize("NFC").toLowerCase(),collision=canonicalPaths.get(canonicalPath);if(collision)throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u51B2\u7A81: ${collision} <-> ${file.path}`);canonicalPaths.set(canonicalPath,file.path)}for(let[canonicalPath,originalPath]of canonicalPaths){let segments=canonicalPath.split("/");for(let index=1;index<segments.length;index+=1){let parentPath=segments.slice(0,index).join("/"),parentOriginalPath=canonicalPaths.get(parentPath);if(parentOriginalPath)throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u51B2\u7A81\uFF08\u6587\u4EF6\u4E0E\u76EE\u5F55\u91CD\u540D\uFF09: ${parentOriginalPath} <-> ${originalPath}`)}}}function normalizePortableWorkspacePath(inputPath){let normalizedSeparators=inputPath.replace(/\\/gu,"/");if(!normalizedSeparators||normalizedSeparators.startsWith("/")||/^[A-Za-z]:/u.test(normalizedSeparators))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${inputPath}`);let segments=normalizedSeparators.split("/");for(let segment of segments){if(!segment||segment==="."||segment==="..")throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${inputPath}`);if(/[<>:"|?*\u0000-\u001F]/u.test(segment))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u5305\u542B Windows \u975E\u6CD5\u5B57\u7B26: ${inputPath}`);if(/[. ]$/u.test(segment))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u542B\u5C3E\u968F\u70B9\u6216\u7A7A\u683C: ${inputPath}`);let baseName=segment.split(".")[0]??segment;if(/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu.test(baseName))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u4F7F\u7528 Windows \u4FDD\u7559\u540D: ${inputPath}`)}return segments.map(segment=>segment.normalize("NFC")).join("/")}function collectSourceWorkspaceFiles(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),files=walkSourceWorkspace(appRoot,appRoot);return{appRoot,files}}function assertSourceWorkspaceCloudUploadPolicy(appRoot,commandLabel){let stats=scanSourceWorkspaceUploadPolicy(appRoot,appRoot);if(stats.sourceBytes>SOURCE_WORKSPACE_BYTES_LIMIT)throw new Error(`\u5F53\u524D\u6E90\u7801\u5305\u4F53\u79EF ${stats.sourceBytes} bytes\uFF0C\u8D85\u8FC7\u4E91\u7AEF\u6E90\u7801\u4E0A\u4F20\u4E0A\u9650 ${SOURCE_WORKSPACE_BYTES_LIMIT} bytes\u3002`);if(stats.assetHits.length>0)throw new Error([`\u68C0\u6D4B\u5230\u672C\u5730\u7D20\u6750\u8D44\u6E90\uFF0C\u5F53\u524D \`${commandLabel}\` \u4E0D\u8D1F\u8D23\u7D20\u6750\u4E0A\u4F20\u56DE\u5199\u3002`,"Agent \u8BF7\u5148\u53C2\u8003 Skill \u6587\u6863 `design-import.md` \u6267\u884C\u8BBE\u8BA1\u6E90\u7801\u9884\u5904\u7406\uFF0C\u5C06\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u7D20\u6750\u5E93\u5E76\u628A\u6E90\u7801\u6539\u5199\u4E3A\u7D20\u6750\u5E93\u5F15\u7528\u540E\u518D\u8BD5\u3002",`\u793A\u4F8B\u547D\u4E2D: ${stats.assetHits.slice(0,10).join(", ")}`].join(`
|
|
2368
|
-
`));return stats}function detectPathBaseRuntimeViolations(files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_http_client",regex:/\baxios(?:\.(?:get|post|put|patch|delete|head|options))?\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let file of files){if(!textFilePattern.test(file.path)||/^README\.md$/i.test(file.path)||isPlatformDevSupportFile(file.path))continue;let lines=file.content.split(/\r?\n/);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({path:file.path,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function isPlatformDevSupportFile(
|
|
2367
|
+
`));return stats}function detectPathBaseRuntimeViolations(files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_http_client",regex:/\baxios(?:\.(?:get|post|put|patch|delete|head|options))?\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let file of files){if(!textFilePattern.test(file.path)||/^README\.md$/i.test(file.path)||isPlatformDevSupportFile(file.path))continue;let lines=file.content.split(/\r?\n/);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({path:file.path,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function isPlatformDevSupportFile(path3){return path3.startsWith("src/platform/dev/")||path3.startsWith("src/web/platform/dev/")||path3.startsWith("src/server/platform/dev/")}function scanSourceWorkspaceUploadPolicy(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),sourceBytes=0,assetHits=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,entry.isDirectory())){if(entry.isDirectory()){let nested=scanSourceWorkspaceUploadPolicy(appRoot,absolutePath);sourceBytes+=nested.sourceBytes,assetHits.push(...nested.assetHits);continue}entry.isFile()&&(sourceBytes+=statSync2(absolutePath).size,isSourceWorkspaceAssetPath(relativePath)&&assetHits.push(relativePath))}}return{sourceBytes,assetHits}}function shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(!normalized)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")?!0:new Set([".git",".platform","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)}function isSourceWorkspaceAssetPath(relativePath){let lower=relativePath.toLowerCase(),dotIndex=lower.lastIndexOf(".");return dotIndex<0?!1:SOURCE_WORKSPACE_ASSET_EXTENSIONS.has(lower.slice(dotIndex))}function walkSourceWorkspace(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),files=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspacePath(relativePath,entry.isDirectory())){if(entry.isDirectory()){files.push(...walkSourceWorkspace(appRoot,absolutePath));continue}entry.isFile()&&files.push({path:relativePath,content:readFileSync8(absolutePath,"utf8")})}}return files.sort((left,right)=>left.path.localeCompare(right.path))}function shouldIgnoreSourceWorkspacePath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(normalized.length===0)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")&&topLevel!==".platform"||new Set([".git","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)?!0:topLevel===".platform"?isDirectory?normalized===".platform/platform-blocks.history":normalized!==PLATFORM_BLOCKS_LOCKFILE:!!(!isDirectory&&new Set([".DS_Store",".env",".env.local",".env.dev",".env.ci"]).has(normalized))}function findAppRoot(startDir=getInvocationCwd()){let current=resolve6(getInvocationCwd(),startDir);for(;;){let manifestPath=join4(current,APP_MANIFEST_FILE);if(existsSync8(manifestPath)&&statSync2(manifestPath).isFile())return current;let parent=dirname5(current);if(parent===current)throw new Error("\u672A\u627E\u5230 app.yaml\u3002\u4F18\u5148\u5EFA\u8BAE\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u5F97\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u660E\u786E\u8981\u5728\u5F53\u524D\u7A7A\u76EE\u5F55\u521D\u59CB\u5316\uFF0C\u518D\u6267\u884C `platform init <project-name>`\u3002");current=parent}}function getAppDebugScaffoldSpec(scaffold){return scaffold==="auth-debug"?{kind:scaffold,routePath:"/debug/auth",filePath:"src/lib/debug-auth-page.js",importLine:'import { renderAuthDebugPage } from "./lib/debug-auth-page.js";',renderCall:"renderAuthDebugPage()",source:buildAuthDebugPageSource()}:scaffold==="cms-debug"?{kind:scaffold,routePath:"/debug/cms",filePath:"src/lib/debug-cms-page.js",importLine:'import { renderCmsDebugPage } from "./lib/debug-cms-page.js";',renderCall:"renderCmsDebugPage()",source:buildCmsDebugPageSource()}:scaffold==="db-debug"?{kind:scaffold,routePath:"/debug/db",filePath:"src/lib/debug-db-page.js",importLine:'import { renderDbDebugPage } from "./lib/debug-db-page.js";',renderCall:"renderDbDebugPage()",source:buildDbDebugPageSource(),extraRouteBlocks:[[' if (pathname === "/api/debug/db-context" && req.method === "GET") {'," sendJson(res, 200, {"," app_id: config.appId,"," tenant_id: config.tenantId || null,"," env: config.appEnv,"," request_id: requestId,"," database_ready: Boolean(config.databaseUrl),"," database_schema: config.databaseSchema || null,"," database_capability_version: process.env.DATABASE_CAPABILITY_VERSION || null,"," database_runtime_role: process.env.DATABASE_RUNTIME_ROLE || null,"," database_migrator_role: process.env.DATABASE_MIGRATOR_ROLE || null"," });"," return;"," }",""].join(`
|
|
2369
2368
|
`)]}:{kind:scaffold,routePath:"/debug/workflow",filePath:"src/lib/debug-workflow-page.js",importLine:'import { renderWorkflowDebugPage } from "./lib/debug-workflow-page.js";',renderCall:"renderWorkflowDebugPage()",source:buildWorkflowDebugPageSource()}}function injectDebugRouteIntoAppSource(source,spec){let next=source;if(!next.includes(spec.importLine)){let importMarker='import { readRuntimeAsset } from "./lib/runtime-assets.js";';if(!next.includes(importMarker))throw new Error("\u65E0\u6CD5\u5728 src/app.js \u4E2D\u627E\u5230 runtime-assets import\uFF0C\u6682\u65F6\u65E0\u6CD5\u81EA\u52A8\u6CE8\u5165 debug scaffold \u8DEF\u7531\u3002");next=next.replace(importMarker,`${spec.importLine}
|
|
2370
2369
|
${importMarker}`)}if(!next.includes(`pathname === "${spec.routePath}"`)){let routeMarker=' sendJsonError(res, requestId, 404, "not_found", "Route not found");';if(!next.includes(routeMarker))throw new Error("\u65E0\u6CD5\u5728 src/app.js \u4E2D\u627E\u5230 404 \u8DEF\u7531\u843D\u70B9\uFF0C\u6682\u65F6\u65E0\u6CD5\u81EA\u52A8\u6CE8\u5165 debug scaffold \u8DEF\u7531\u3002");let routeBlock=[` if (pathname === "${spec.routePath}" && req.method === "GET") {`,' res.setHeader("content-type", "text/html; charset=utf-8");'," res.writeHead(200);",` res.end(${spec.renderCall});`," return;"," }",""].join(`
|
|
2371
2370
|
`);next=next.replace(routeMarker,`${routeBlock}
|
|
@@ -2374,10 +2373,10 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
|
|
|
2374
2373
|
`)}function buildWorkflowDebugPageSource(){return["export function renderWorkflowDebugPage() {"," return `<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="utf-8" />',' <meta name="viewport" content="width=device-width, initial-scale=1" />'," <title>Workflow Debug</title>"," <style>",' :root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color-scheme: light; }'," body { margin: 0; background: #f8fafc; color: #0f172a; }"," main { width: min(1080px, calc(100vw - 32px)); margin: 40px auto; padding: 32px; border-radius: 24px; background: #fff; border: 1px solid #e2e8f0; box-shadow: 0 24px 80px rgba(15,23,42,.08); }"," h1 { margin: 0 0 12px; font-size: 32px; }"," p { margin: 0 0 12px; color: #475569; line-height: 1.7; }"," .status { margin-top: 16px; padding: 12px 14px; border-radius: 14px; border: 1px solid #e2e8f0; background: #f8fafc; color: #334155; }"," .status-neutral { background: #f8fafc; border-color: #e2e8f0; color: #334155; }"," .status-success { background: #ecfdf5; border-color: #86efac; color: #166534; }"," .status-warning { background: #fffbeb; border-color: #fcd34d; color: #92400e; }"," .status-error { background: #fff1f2; border-color: #fecdd3; color: #be123c; }"," .hero { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: 16px; margin-top: 20px; }"," .grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 16px; }"," .card { border: 1px solid #e2e8f0; border-radius: 16px; padding: 16px; }"," .label { font-size: 12px; color: #64748b; }"," .value { margin-top: 8px; font-weight: 600; word-break: break-word; }"," .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }"," .actions, .inline-actions { display: flex; gap: 12px; flex-wrap: wrap; }"," .actions { margin-top: 16px; }"," input { width: 100%; border: 1px solid #cbd5e1; border-radius: 12px; padding: 12px 14px; font: inherit; }"," button, a { border: 0; border-radius: 12px; padding: 12px 16px; font: inherit; font-weight: 600; cursor: pointer; background: #0f172a; color: #fff; text-decoration: none; display: inline-flex; align-items: center; }"," button.secondary, a.secondary { background: #fff; color: #0f172a; border: 1px solid #cbd5e1; }"," .list { display: grid; gap: 12px; margin-top: 16px; }"," .item { border: 1px solid #e2e8f0; border-radius: 14px; padding: 14px; }"," .muted { color: #64748b; font-size: 14px; }"," @media (max-width: 920px) { .hero, .grid { grid-template-columns: 1fr; } }"," </style>"," </head>"," <body>"," <main>"," <h1>Workflow \u6700\u5C0F\u8054\u8C03\u9875</h1>"," <p>\u8FD9\u4E2A\u9875\u9762\u53EA\u7528\u4E8E\u672C\u5730\u6216 preview \u8054\u8C03 workflow \u8FD0\u884C\u65F6\u3002\u5B83\u4E0D\u4F1A\u4FEE\u6539\u4F60\u7684\u4E1A\u52A1\u9875\uFF0C\u53EA\u63D0\u4F9B\u6700\u5C0F\u7684\u5BF9\u8C61\u72B6\u6001\u8BFB\u53D6\u3001\u542F\u52A8\u6D41\u7A0B\u3001\u52A8\u4F5C\u6267\u884C\u4E0E\u5F85\u529E\u67E5\u770B\u3002</p>",' <div class="status status-neutral" id="status">\u6B63\u5728\u6821\u9A8C\u5F53\u524D\u7EC8\u7AEF\u7528\u6237\u4F1A\u8BDD...</div>',' <div class="hero">',' <div class="card">',' <div class="grid" style="margin-top:0">',' <div><div class="label">Definition Key</div><input id="definition-key" type="text" placeholder="\u4F8B\u5982 wf-demo-simple-approval" /></div>',' <div><div class="label">Object Type</div><input id="object-type" type="text" placeholder="\u4F8B\u5982 demo_request" /></div>',' <div><div class="label">Object ID</div><input id="object-id" type="text" value="demo-request-001" /></div>',' <div><div class="label">\u52A8\u4F5C\u5907\u6CE8</div><input id="comment" type="text" placeholder="\u4F8B\u5982\uFF1A\u4FE1\u606F\u5B8C\u6574\uFF0C\u901A\u8FC7" /></div>'," </div>",' <div class="actions">',' <button id="start" type="button">\u542F\u52A8\u6D41\u7A0B</button>',' <button class="secondary" id="refresh" type="button">\u5237\u65B0\u72B6\u6001</button>',' <a class="secondary" href="/app">\u8FD4\u56DE\u4E1A\u52A1\u9875</a>'," </div>"," </div>",' <div class="card">',' <div class="label">\u5F53\u524D\u5B9E\u4F8B</div><div class="value mono" id="instance-id">-</div>',' <div class="label" style="margin-top:16px">\u5F53\u524D\u72B6\u6001</div><div class="value" id="state">-</div>',' <div class="label" style="margin-top:16px">\u751F\u547D\u5468\u671F</div><div class="value mono" id="lifecycle">-</div>',' <div class="label" style="margin-top:16px">\u53EF\u6267\u884C\u52A8\u4F5C</div><div class="inline-actions" id="available-actions" style="margin-top:8px"></div>'," </div>"," </div>",' <div class="grid">',' <div class="card"><div class="label">\u5F53\u524D\u7528\u6237\u5F85\u529E</div><div class="list" id="tasks"></div></div>',' <div class="card"><div class="label">\u65F6\u95F4\u7EBF</div><div class="list" id="timeline"></div></div>'," </div>"," </main>",' <script type="module">'," import { getPlatformRuntimeApp, requireReadyEndUser, getRuntimeStatusFromAccess, getRuntimeStatusFromError, applyRuntimeStatus } from '/assets/platform-runtime.js';"," const appRuntime = getPlatformRuntimeApp();"," const statusEl = document.getElementById('status');"," const definitionKeyEl = document.getElementById('definition-key');"," const objectTypeEl = document.getElementById('object-type');"," const objectIdEl = document.getElementById('object-id');"," const commentEl = document.getElementById('comment');"," const instanceIdEl = document.getElementById('instance-id');"," const stateEl = document.getElementById('state');"," const lifecycleEl = document.getElementById('lifecycle');"," const actionsEl = document.getElementById('available-actions');"," const tasksEl = document.getElementById('tasks');"," const timelineEl = document.getElementById('timeline');"," const startEl = document.getElementById('start');"," const refreshEl = document.getElementById('refresh');"," function readValue(element) { return String(element?.value || '').trim(); }",` function renderEmpty(element, text) { element.innerHTML = '<div class="item muted">' + escapeHtml(text) + '</div>'; }`," function setBusy(isBusy, message) {"," startEl.disabled = isBusy;"," refreshEl.disabled = isBusy;"," actionsEl.querySelectorAll('button').forEach((button) => { button.disabled = isBusy; });"," if (message) applyRuntimeStatus(statusEl, { tone: 'neutral', message });"," }"," function renderState(state) {"," instanceIdEl.textContent = state?.instanceId || '-';"," stateEl.textContent = state?.currentStateDisplayName || state?.currentStateKey || '\u5C1A\u672A\u542F\u52A8';"," lifecycleEl.textContent = state?.lifecycleStatus || (state?.hasActiveInstance ? 'active' : 'idle');"," const actions = Array.isArray(state?.availableActions) ? state.availableActions : [];"," if (actions.length === 0) { renderEmpty(actionsEl, '\u5F53\u524D\u6CA1\u6709\u53EF\u6267\u884C\u52A8\u4F5C\u3002'); return; }",` actionsEl.innerHTML = actions.map((action) => '<button type="button" data-instance-id="' + escapeHtml(state.instanceId || '') + '" data-action-key="' + escapeHtml(action.actionKey) + '">' + escapeHtml(action.displayName) + '</button>').join('');`," }"," function renderTasks(items, currentObjectId) {"," if (!Array.isArray(items) || items.length === 0) { renderEmpty(tasksEl, '\u5F53\u524D\u7528\u6237\u6682\u65E0\u5F85\u529E\u3002'); return; }"," tasksEl.innerHTML = items.map((task) => {",` const actions = (task.availableActions || []).map((action) => '<button type="button" class="secondary" data-task-instance-id="' + escapeHtml(task.instanceId) + '" data-action-key="' + escapeHtml(action.actionKey) + '">' + escapeHtml(action.displayName) + '</button>').join('');`,` return '<div class="item"><strong>' + escapeHtml(task.definitionDisplayName || task.definitionKey) + '</strong><div class="muted mono">' + escapeHtml(task.objectType) + ' / ' + escapeHtml(task.objectId) + '</div><div class="muted">\u72B6\u6001\uFF1A' + escapeHtml(task.currentStateDisplayName || task.currentStateKey || '-') + (task.objectId === currentObjectId ? ' \xB7 \u5F53\u524D\u5BF9\u8C61' : '') + '</div><div class="inline-actions" style="margin-top:8px">' + actions + '</div></div>';`," }).join('');"," }"," function renderTimeline(items) {"," if (!Array.isArray(items) || items.length === 0) { renderEmpty(timelineEl, '\u6682\u65E0\u65F6\u95F4\u7EBF\u3002'); return; }",` timelineEl.innerHTML = items.map((item) => '<div class="item"><strong>' + escapeHtml(item.actionDisplayName || item.actionKey || 'start') + '</strong><div class="muted">' + escapeHtml(item.fromStateDisplayName || item.fromStateKey || '-') + ' -> ' + escapeHtml(item.toStateDisplayName || item.toStateKey || '-') + '</div><div class="muted">\u6267\u884C\u4EBA\uFF1A' + escapeHtml(item.actorDisplayName || item.actorId || '-') + '</div></div>').join('');`," }"," async function refreshWorkflow() {"," const objectType = readValue(objectTypeEl);"," const objectId = readValue(objectIdEl);"," if (!objectType || !objectId) {"," renderEmpty(actionsEl, '\u8BF7\u5148\u586B\u5199 object type \u548C object id\u3002');"," renderEmpty(tasksEl, '\u8BF7\u5148\u586B\u5199 object type \u548C object id\u3002');"," renderEmpty(timelineEl, '\u8BF7\u5148\u586B\u5199 object type \u548C object id\u3002');"," stateEl.textContent = '-'; lifecycleEl.textContent = '-'; instanceIdEl.textContent = '-';"," applyRuntimeStatus(statusEl, { tone: 'warning', message: '\u5237\u65B0\u524D\u9700\u8981\u5148\u586B\u5199 object type \u548C object id\u3002' });"," return;"," }"," setBusy(true, '\u6B63\u5728\u5237\u65B0 workflow \u72B6\u6001...');"," try {"," const [state, tasks, timeline] = await Promise.all(["," appRuntime.getWorkflowObjectState({ objectType, objectId }),"," appRuntime.listMyTasks({ status: 'pending', limit: 20 }),"," appRuntime.listWorkflowTimeline({ objectType, objectId }).catch(() => [])"," ]);"," renderState(state);"," renderTasks(tasks.items || [], objectId);"," renderTimeline(timeline);"," applyRuntimeStatus(statusEl, { tone: 'success', message: 'Workflow \u8FD0\u884C\u65F6\u8BF7\u6C42\u6210\u529F\u3002' });"," } catch (error) {"," renderEmpty(actionsEl, '\u72B6\u6001\u8BFB\u53D6\u5931\u8D25\u3002');"," renderEmpty(tasksEl, '\u5F85\u529E\u8BFB\u53D6\u5931\u8D25\u3002');"," renderEmpty(timelineEl, '\u65F6\u95F4\u7EBF\u8BFB\u53D6\u5931\u8D25\u3002');"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'Workflow \u8C03\u8BD5\u8BF7\u6C42\u5931\u8D25\u3002'));"," } finally {"," setBusy(false);"," }"," }"," async function startWorkflow() {"," const definitionKey = readValue(definitionKeyEl);"," const objectType = readValue(objectTypeEl);"," const objectId = readValue(objectIdEl);"," if (!definitionKey || !objectType || !objectId) {"," applyRuntimeStatus(statusEl, { tone: 'warning', message: '\u542F\u52A8\u524D\u9700\u8981\u586B\u5199 definition key\u3001object type \u548C object id\u3002' });"," return;"," }"," setBusy(true, '\u6B63\u5728\u542F\u52A8 workflow...');"," try {"," await appRuntime.startWorkflow({ definitionKey, objectType, objectId, payload: { source: 'workflow-debug-page' } });"," await refreshWorkflow();"," } catch (error) {"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'Workflow \u542F\u52A8\u5931\u8D25\u3002'));"," setBusy(false);"," }"," }"," async function runAction(instanceId, actionKey) {"," setBusy(true, '\u6B63\u5728\u6267\u884C workflow \u52A8\u4F5C...');"," try {"," await appRuntime.performWorkflowAction({ instanceId, actionKey, comment: readValue(commentEl) || undefined });"," await refreshWorkflow();"," } catch (error) {"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'Workflow \u52A8\u4F5C\u6267\u884C\u5931\u8D25\u3002'));"," setBusy(false);"," }"," }"," async function bootstrap() {"," try {"," const session = await requireReadyEndUser({ returnTo: '/debug/workflow', redirectToSignIn: true });"," applyRuntimeStatus(statusEl, getRuntimeStatusFromAccess(session.access));"," if (session.ready) { await refreshWorkflow(); }"," } catch (error) {"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'Workflow \u8C03\u8BD5\u9875\u521D\u59CB\u5316\u5931\u8D25\u3002'));"," }"," }"," startEl.addEventListener('click', () => { void startWorkflow(); });"," refreshEl.addEventListener('click', () => { void refreshWorkflow(); });"," actionsEl.addEventListener('click', (event) => {"," const button = event.target instanceof HTMLElement ? event.target.closest('button[data-action-key][data-instance-id]') : null;"," if (!button) return;"," void runAction(button.getAttribute('data-instance-id') || '', button.getAttribute('data-action-key') || '');"," });"," tasksEl.addEventListener('click', (event) => {"," const button = event.target instanceof HTMLElement ? event.target.closest('button[data-task-instance-id][data-action-key]') : null;"," if (!button) return;"," void runAction(button.getAttribute('data-task-instance-id') || '', button.getAttribute('data-action-key') || '');"," });"," function escapeHtml(value) {",` return String(value || '').replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');`," }"," void bootstrap();"," </script>"," </body>","</html>`;","}",""].join(`
|
|
2375
2374
|
`)}function buildCmsDebugPageSource(){return["export function renderCmsDebugPage() {"," return `<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="utf-8" />',' <meta name="viewport" content="width=device-width, initial-scale=1" />'," <title>CMS Debug</title>"," <style>",' :root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color-scheme: light; }'," body { margin: 0; background: #f8fafc; color: #0f172a; }"," main { width: min(1080px, calc(100vw - 32px)); margin: 40px auto; padding: 32px; border-radius: 24px; background: #fff; border: 1px solid #e2e8f0; box-shadow: 0 24px 80px rgba(15,23,42,.08); }"," h1 { margin: 0 0 12px; font-size: 32px; }"," p { margin: 0 0 12px; color: #475569; line-height: 1.7; }"," .status { margin-top: 16px; padding: 12px 14px; border-radius: 14px; border: 1px solid #e2e8f0; background: #f8fafc; color: #334155; }"," .status-neutral { background: #f8fafc; border-color: #e2e8f0; color: #334155; }"," .status-success { background: #ecfdf5; border-color: #86efac; color: #166534; }"," .status-warning { background: #fffbeb; border-color: #fcd34d; color: #92400e; }"," .status-error { background: #fff1f2; border-color: #fecdd3; color: #be123c; }"," .hero { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 20px; }"," .card { border: 1px solid #e2e8f0; border-radius: 16px; padding: 16px; }"," .label { font-size: 12px; color: #64748b; }"," .value { margin-top: 8px; font-weight: 600; word-break: break-word; }"," .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }"," .actions { display: flex; gap: 12px; margin-top: 16px; flex-wrap: wrap; }"," input { width: 100%; border: 1px solid #cbd5e1; border-radius: 12px; padding: 12px 14px; font: inherit; box-sizing: border-box; }"," button, a { border: 0; border-radius: 12px; padding: 12px 16px; font: inherit; font-weight: 600; cursor: pointer; background: #0f172a; color: #fff; text-decoration: none; display: inline-flex; align-items: center; }"," button.secondary, a.secondary { background: #fff; color: #0f172a; border: 1px solid #cbd5e1; }"," .list { display: grid; gap: 12px; margin-top: 16px; }"," .item { border: 1px solid #e2e8f0; border-radius: 14px; padding: 14px; }"," .muted { color: #64748b; font-size: 14px; }"," pre { margin: 0; white-space: pre-wrap; word-break: break-word; }"," @media (max-width: 920px) { .hero { grid-template-columns: 1fr; } }"," </style>"," </head>"," <body>"," <main>"," <h1>CMS \u6700\u5C0F\u8054\u8C03\u9875</h1>"," <p>\u8FD9\u4E2A\u9875\u9762\u53EA\u7528\u4E8E\u672C\u5730\u6216 preview \u8054\u8C03 CMS \u8FD0\u884C\u65F6\u3002\u5B83\u4F1A\u76F4\u63A5\u9A8C\u8BC1 collection \u5217\u8868\u3001collection meta\u3001\u5185\u5BB9\u5217\u8868\u4E0E slug \u8BFB\u53D6\uFF0C\u4E0D\u5C5E\u4E8E\u6B63\u5F0F\u4E1A\u52A1\u9875\u9762\u3002</p>",' <div class="status status-neutral" id="status">\u6B63\u5728\u6821\u9A8C CMS \u8FD0\u884C\u65F6...</div>',' <div class="hero">',' <div class="card">',' <div class="label">Collection</div>',' <input id="collection" type="text" value="article" />',' <div class="label" style="margin-top:16px">Slug</div>',' <input id="slug" type="text" placeholder="\u4F8B\u5982 cms-demo-entry" />',' <div class="actions">',' <button id="refresh" type="button">\u5237\u65B0</button>',' <button class="secondary" id="load-slug" type="button">\u6309 Slug \u8BFB\u53D6</button>',' <a class="secondary" href="/app">\u8FD4\u56DE\u4E1A\u52A1\u9875</a>'," </div>"," </div>",' <div class="card">',' <div class="label">\u5F53\u524D\u79DF\u6237</div><div class="value mono" id="tenant-id">-</div>',' <div class="label" style="margin-top:16px">Collection Meta</div><div class="value"><pre id="meta">-</pre></div>'," </div>"," </div>",' <div class="hero">',' <div class="card"><div class="label">Collection \u5217\u8868</div><div class="list" id="collections"></div></div>',' <div class="card"><div class="label">\u5185\u5BB9\u5217\u8868</div><div class="list" id="items"></div></div>'," </div>",' <div class="card" style="margin-top:16px"><div class="label">\u5F53\u524D\u6761\u76EE</div><div class="value"><pre id="item-detail">-</pre></div></div>'," </main>",' <script type="module">'," import { getPlatformRuntimeApp, getRuntimeStatusFromError, applyRuntimeStatus } from '/assets/platform-runtime.js';"," const appRuntime = getPlatformRuntimeApp();"," const statusEl = document.getElementById('status');"," const tenantIdEl = document.getElementById('tenant-id');"," const collectionEl = document.getElementById('collection');"," const slugEl = document.getElementById('slug');"," const metaEl = document.getElementById('meta');"," const collectionsEl = document.getElementById('collections');"," const itemsEl = document.getElementById('items');"," const itemDetailEl = document.getElementById('item-detail');"," const refreshEl = document.getElementById('refresh');"," const loadSlugEl = document.getElementById('load-slug');"," let tenantId = '';"," function readCollection() { return String(collectionEl.value || '').trim(); }"," function readSlug() { return String(slugEl.value || '').trim(); }",` function renderEmpty(element, text) { element.innerHTML = '<div class="item muted">' + escapeHtml(text) + '</div>'; }`," function renderCollections(items) {"," if (!Array.isArray(items) || items.length === 0) { renderEmpty(collectionsEl, '\u6682\u65E0\u53EF\u89C1 collection\u3002'); return; }",` collectionsEl.innerHTML = items.map((item) => '<div class="item"><strong>' + escapeHtml(item.label || item.collection) + '</strong><div class="muted mono">' + escapeHtml(item.collection) + '</div><div class="muted">template: ' + escapeHtml(item.template || '-') + '</div></div>').join('');`," }"," function renderItems(items) {"," if (!Array.isArray(items) || items.length === 0) { renderEmpty(itemsEl, '\u5F53\u524D collection \u6682\u65E0\u5DF2\u53D1\u5E03\u5185\u5BB9\u3002'); return; }",` itemsEl.innerHTML = items.map((item) => '<div class="item"><strong>' + escapeHtml(item.content?.title || item.system?.slug || item.system?.id || '-') + '</strong><div class="muted mono">' + escapeHtml(item.system?.slug || '-') + '</div><div class="muted">status: ' + escapeHtml(item.system?.publish_status || '-') + '</div></div>').join('');`," }"," async function refreshCms() {"," const collection = readCollection();"," if (!tenantId) {"," const context = await fetch('/api/me').then((item) => item.json()).catch(() => null);"," tenantId = typeof context?.tenant_id === 'string' ? context.tenant_id : '';"," tenantIdEl.textContent = tenantId || '-';"," }"," if (!tenantId || !collection) {"," applyRuntimeStatus(statusEl, { tone: 'warning', message: '\u5237\u65B0\u524D\u9700\u8981 tenantId \u548C collection\u3002' });"," return;"," }"," applyRuntimeStatus(statusEl, { tone: 'neutral', message: '\u6B63\u5728\u5237\u65B0 CMS \u72B6\u6001...' });"," try {"," const [collections, meta, list] = await Promise.all(["," appRuntime.listCmsCollections({ tenantId }),"," appRuntime.getCmsCollectionMeta({ tenantId, collection }),"," appRuntime.listCmsItems({ tenantId, collection, page: 1, pageSize: 10 }).catch(() => ({ items: [], total: 0, page: 1, page_size: 10 }))"," ]);"," renderCollections(collections.items || []);"," renderItems(list.items || []);"," metaEl.textContent = JSON.stringify(meta, null, 2);"," itemDetailEl.textContent = '-';"," applyRuntimeStatus(statusEl, { tone: 'success', message: 'CMS \u8FD0\u884C\u65F6\u8BF7\u6C42\u6210\u529F\u3002' });"," } catch (error) {"," renderEmpty(collectionsEl, 'Collection \u8BFB\u53D6\u5931\u8D25\u3002');"," renderEmpty(itemsEl, '\u5185\u5BB9\u5217\u8868\u8BFB\u53D6\u5931\u8D25\u3002');"," metaEl.textContent = '-';"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'CMS \u8C03\u8BD5\u8BF7\u6C42\u5931\u8D25\u3002'));"," }"," }"," async function loadBySlug() {"," const collection = readCollection();"," if (!tenantId) {"," const context = await fetch('/api/me').then((item) => item.json()).catch(() => null);"," tenantId = typeof context?.tenant_id === 'string' ? context.tenant_id : '';"," tenantIdEl.textContent = tenantId || '-';"," }"," const slug = readSlug();"," if (!tenantId || !collection || !slug) {"," applyRuntimeStatus(statusEl, { tone: 'warning', message: '\u6309 slug \u8BFB\u53D6\u524D\u9700\u8981 tenantId\u3001collection \u548C slug\u3002' });"," return;"," }"," applyRuntimeStatus(statusEl, { tone: 'neutral', message: '\u6B63\u5728\u6309 slug \u8BFB\u53D6 CMS \u6761\u76EE...' });"," try {"," const item = await appRuntime.getCmsItemBySlug({ tenantId, collection, slug });"," itemDetailEl.textContent = JSON.stringify(item, null, 2);"," applyRuntimeStatus(statusEl, { tone: 'success', message: 'CMS \u6761\u76EE\u8BFB\u53D6\u6210\u529F\u3002' });"," } catch (error) {"," itemDetailEl.textContent = '-';"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'CMS \u6761\u76EE\u8BFB\u53D6\u5931\u8D25\u3002'));"," }"," }"," refreshEl.addEventListener('click', () => { void refreshCms(); });"," loadSlugEl.addEventListener('click', () => { void loadBySlug(); });"," function escapeHtml(value) {",` return String(value || '').replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');`," }"," void refreshCms();"," </script>"," </body>","</html>`;","}",""].join(`
|
|
2376
2375
|
`)}function buildDbDebugPageSource(){return["export function renderDbDebugPage() {"," return `<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="utf-8" />',' <meta name="viewport" content="width=device-width, initial-scale=1" />'," <title>DB Debug</title>"," <style>",' :root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color-scheme: light; }'," body { margin: 0; background: #f8fafc; color: #0f172a; }"," main { width: min(1080px, calc(100vw - 32px)); margin: 40px auto; padding: 32px; border-radius: 24px; background: #fff; border: 1px solid #e2e8f0; box-shadow: 0 24px 80px rgba(15,23,42,.08); }"," h1 { margin: 0 0 12px; font-size: 32px; }"," p { margin: 0 0 12px; color: #475569; line-height: 1.7; }"," .status { margin-top: 16px; padding: 12px 14px; border-radius: 14px; border: 1px solid #e2e8f0; background: #f8fafc; color: #334155; }"," .status-neutral { background: #f8fafc; border-color: #e2e8f0; color: #334155; }"," .status-success { background: #ecfdf5; border-color: #86efac; color: #166534; }"," .status-warning { background: #fffbeb; border-color: #fcd34d; color: #92400e; }"," .status-error { background: #fff1f2; border-color: #fecdd3; color: #be123c; }"," .grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 20px; }"," .card { border: 1px solid #e2e8f0; border-radius: 16px; padding: 16px; }"," .label { font-size: 12px; color: #64748b; }"," .value { margin-top: 8px; font-weight: 600; word-break: break-word; }"," .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }"," .actions { display: flex; gap: 12px; margin-top: 20px; flex-wrap: wrap; }"," button, a { border: 0; border-radius: 12px; padding: 12px 16px; font: inherit; font-weight: 600; cursor: pointer; background: #0f172a; color: #fff; text-decoration: none; display: inline-flex; align-items: center; }"," button.secondary, a.secondary { background: #fff; color: #0f172a; border: 1px solid #cbd5e1; }"," ul { margin: 0; padding-left: 20px; color: #334155; }"," li { margin: 8px 0; }"," pre { margin: 0; white-space: pre-wrap; word-break: break-word; }"," @media (max-width: 720px) { .grid { grid-template-columns: 1fr; } }"," </style>"," </head>"," <body>"," <main>"," <h1>DB \u6700\u5C0F\u8054\u8C03\u9875</h1>"," <p>\u8FD9\u4E2A\u9875\u9762\u53EA\u7528\u4E8E\u672C\u5730\u6216 preview \u8054\u8C03\u5E73\u53F0 DB \u7ED1\u5B9A\uFF0C\u4E0D\u5C5E\u4E8E\u6B63\u5F0F\u4E1A\u52A1\u9875\u9762\u3002\u5B83\u4F1A\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u7684 DB \u7ED1\u5B9A\u4E0A\u4E0B\u6587\uFF0C\u5E76\u63D0\u793A\u4F60\u7EE7\u7EED\u4F7F\u7528 `platform db` \u548C `platform dev --remote-bindings` \u9A8C\u8BC1\u771F\u5B9E\u8868\u7ED3\u6784\u4E0E\u67E5\u8BE2\u3002</p>",' <div class="status status-neutral" id="status">\u6B63\u5728\u8BFB\u53D6 DB \u7ED1\u5B9A\u4E0A\u4E0B\u6587...</div>',' <div class="grid">',' <div class="card"><div class="label">\u5F53\u524D\u79DF\u6237 / \u5E94\u7528 / \u73AF\u5883</div><div class="value mono" id="identity">-</div></div>',' <div class="card"><div class="label">DATABASE_URL \u6CE8\u5165\u72B6\u6001</div><div class="value mono" id="db-ready">-</div></div>',' <div class="card"><div class="label">DATABASE_SCHEMA</div><div class="value mono" id="db-schema">-</div></div>',' <div class="card"><div class="label">Capability Version</div><div class="value mono" id="db-capability">-</div></div>'," </div>",' <div class="card" style="margin-top:16px"><div class="label">\u540E\u7AEF\u8FD4\u56DE\u7684 DB \u4E0A\u4E0B\u6587</div><div class="value"><pre id="db-context">-</pre></div></div>',' <div class="card" style="margin-top:16px"><div class="label">\u4E0B\u4E00\u6B65\u5EFA\u8BAE</div><div class="value"><ul><li>\u5148\u8DD1 <code>platform db status</code> \u770B binding / schema / migration\u3002</li><li>\u518D\u8DD1 <code>platform db tables</code> \u6216 <code>platform db query --sql "SELECT ..."</code> \u786E\u8BA4\u771F\u5B9E\u8868\u7ED3\u6784\u3002</li><li>\u5982\u679C\u4F60\u8981\u9A8C\u8BC1\u5E94\u7528\u4EE3\u7801\u76F4\u8FDE DB\uFF0C\u4F7F\u7528 <code>platform dev --remote-bindings</code>\uFF0C\u4E0D\u8981\u53EA\u8DD1\u666E\u901A <code>platform dev</code>\u3002</li></ul></div></div>',' <div class="actions">',' <button id="refresh" type="button">\u5237\u65B0\u72B6\u6001</button>',' <a class="secondary" href="/app">\u8FD4\u56DE\u4E1A\u52A1\u9875</a>'," </div>"," </main>",' <script type="module">'," import { getRuntimeStatusFromError, applyRuntimeStatus } from '/assets/platform-runtime.js';"," const statusEl = document.getElementById('status');"," const identityEl = document.getElementById('identity');"," const dbReadyEl = document.getElementById('db-ready');"," const dbSchemaEl = document.getElementById('db-schema');"," const dbCapabilityEl = document.getElementById('db-capability');"," const dbContextEl = document.getElementById('db-context');"," const refreshEl = document.getElementById('refresh');"," async function refreshDbDebug() {"," applyRuntimeStatus(statusEl, { tone: 'neutral', message: '\u6B63\u5728\u8BFB\u53D6 DB \u8C03\u8BD5\u72B6\u6001...' });"," try {"," const [context, dbContext] = await Promise.all(["," fetch('/api/me').then((item) => item.json()).catch(() => null),"," fetch('/api/debug/db-context').then((item) => item.json()).catch(() => null)"," ]);"," identityEl.textContent = [dbContext?.tenant_id || context?.tenant_id || '-', dbContext?.app_id || context?.app_id || '-', dbContext?.env || context?.env || '-'].join(' / ');"," dbReadyEl.textContent = dbContext?.database_ready ? 'ready' : 'not_injected';"," dbSchemaEl.textContent = dbContext?.database_schema || '-';"," dbCapabilityEl.textContent = dbContext?.database_capability_version || '-';"," dbContextEl.textContent = dbContext ? JSON.stringify(dbContext, null, 2) : '-';"," applyRuntimeStatus(statusEl, dbContext?.database_ready"," ? { tone: 'success', message: '\u5DF2\u68C0\u6D4B\u5230 DATABASE_URL\u3002\u4E0B\u4E00\u6B65\u8BF7\u7528 platform db tables/query \u9A8C\u8BC1\u771F\u5B9E\u8868\u7ED3\u6784\u3002' }"," : { tone: 'warning', message: '\u5F53\u524D\u8FD8\u6CA1\u68C0\u6D4B\u5230 DATABASE_URL\u3002\u82E5\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u8BF7\u6539\u7528 platform dev --remote-bindings\u3002' });"," } catch (error) {"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'DB \u8C03\u8BD5\u9875\u521D\u59CB\u5316\u5931\u8D25\u3002'));"," }"," }"," refreshEl.addEventListener('click', () => { void refreshDbDebug(); });"," void refreshDbDebug();"," </script>"," </body>","</html>`;","}",""].join(`
|
|
2377
|
-
`)}function resolveWorkspaceDevTarget(target){if(!target)return null;let workspaceRoot=findWorkspaceRoot();return{command:`corepack pnpm --filter ${target.startsWith("@platform/")?target:`@platform/${target}`} dev`,cwd:workspaceRoot}}function buildDevEnvironment(binding,runtimeBindings={}){return{...process.env,PLATFORM_ACTIVE_TENANT_ID:binding?.tenant_id??"",PLATFORM_ACTIVE_APP_ID:binding?.app_id??"",PLATFORM_ACTIVE_ENV:binding?.env??"",PLATFORM_ACTIVE_APP_NAME:binding?.app_name??"",APP_ID:process.env.APP_ID??binding?.app_id??"",APP_ENV:process.env.APP_ENV??binding?.env??"preview",TENANT_ID:process.env.TENANT_ID??runtimeBindings.TENANT_ID??binding?.tenant_id??"",PUBLIC_APP_BASE_URL:process.env.PUBLIC_APP_BASE_URL??runtimeBindings.PUBLIC_APP_BASE_URL??"",CONTROL_API_BASE_URL:process.env.CONTROL_API_BASE_URL??runtimeBindings.CONTROL_API_BASE_URL??DEFAULT_CONTROL_API_BASE_URL,DATABASE_URL:process.env.DATABASE_URL??runtimeBindings.DATABASE_URL??"",DATABASE_SCHEMA:process.env.DATABASE_SCHEMA??runtimeBindings.DATABASE_SCHEMA??"",DATABASE_MIGRATOR_ROLE:process.env.DATABASE_MIGRATOR_ROLE??runtimeBindings.DATABASE_MIGRATOR_ROLE??"",DATABASE_RUNTIME_ROLE:process.env.DATABASE_RUNTIME_ROLE??runtimeBindings.DATABASE_RUNTIME_ROLE??"",DATABASE_CAPABILITY_VERSION:process.env.DATABASE_CAPABILITY_VERSION??runtimeBindings.DATABASE_CAPABILITY_VERSION??""}}function detectLocalDependencyInstallPlan(appDir){let packageJsonPath=join4(appDir,"package.json"),nodeModulesPath=join4(appDir,"node_modules");if(!existsSync8(packageJsonPath)
|
|
2376
|
+
`)}function resolveWorkspaceDevTarget(target){if(!target)return null;let workspaceRoot=findWorkspaceRoot();return{command:`corepack pnpm --filter ${target.startsWith("@platform/")?target:`@platform/${target}`} dev`,cwd:workspaceRoot}}function buildDevEnvironment(binding,runtimeBindings={}){return{...process.env,PLATFORM_ACTIVE_TENANT_ID:binding?.tenant_id??"",PLATFORM_ACTIVE_APP_ID:binding?.app_id??"",PLATFORM_ACTIVE_ENV:binding?.env??"",PLATFORM_ACTIVE_APP_NAME:binding?.app_name??"",APP_ID:process.env.APP_ID??binding?.app_id??"",APP_ENV:process.env.APP_ENV??binding?.env??"preview",TENANT_ID:process.env.TENANT_ID??runtimeBindings.TENANT_ID??binding?.tenant_id??"",PUBLIC_APP_BASE_URL:process.env.PUBLIC_APP_BASE_URL??runtimeBindings.PUBLIC_APP_BASE_URL??"",CONTROL_API_BASE_URL:process.env.CONTROL_API_BASE_URL??runtimeBindings.CONTROL_API_BASE_URL??DEFAULT_CONTROL_API_BASE_URL,DATABASE_URL:process.env.DATABASE_URL??runtimeBindings.DATABASE_URL??"",DATABASE_SCHEMA:process.env.DATABASE_SCHEMA??runtimeBindings.DATABASE_SCHEMA??"",DATABASE_MIGRATOR_ROLE:process.env.DATABASE_MIGRATOR_ROLE??runtimeBindings.DATABASE_MIGRATOR_ROLE??"",DATABASE_RUNTIME_ROLE:process.env.DATABASE_RUNTIME_ROLE??runtimeBindings.DATABASE_RUNTIME_ROLE??"",DATABASE_CAPABILITY_VERSION:process.env.DATABASE_CAPABILITY_VERSION??runtimeBindings.DATABASE_CAPABILITY_VERSION??""}}function detectLocalDependencyInstallPlan(appDir){let packageJsonPath=join4(appDir,"package.json"),nodeModulesPath=join4(appDir,"node_modules");if(!existsSync8(packageJsonPath))return null;let packageJson=JSON.parse(readFileSync8(packageJsonPath,"utf8")),declaredPackageManager=typeof packageJson.packageManager=="string"?packageJson.packageManager.trim():"",declaredPackageManagerName=declaredPackageManager.includes("@")?declaredPackageManager.slice(0,declaredPackageManager.lastIndexOf("@")):declaredPackageManager,lockfiles=["package-lock.json","pnpm-lock.yaml","yarn.lock"].filter(fileName=>existsSync8(join4(appDir,fileName)));if(lockfiles.length>1)throw new Error(`[conflicting_lockfiles] \u68C0\u6D4B\u5230\u591A\u4E2A\u5305\u7BA1\u7406\u5668 lockfile\uFF1A${lockfiles.join(", ")}\u3002\u8BF7\u53EA\u4FDD\u7559\u9879\u76EE\u58F0\u660E\u7684\u5305\u7BA1\u7406\u5668 lockfile \u540E\u91CD\u8BD5\u3002`);let lockfilePackageManagers={"package-lock.json":"npm","pnpm-lock.yaml":"pnpm","yarn.lock":"yarn"},lockfile=lockfiles[0];if(declaredPackageManagerName&&lockfile&&lockfilePackageManagers[lockfile]!==declaredPackageManagerName)throw new Error(`[package_manager_lock_mismatch] packageManager ${declaredPackageManager} \u4E0E ${lockfile} \u4E0D\u5339\u914D\u3002\u8BF7\u4FDD\u7559\u4E0E packageManager \u4E00\u81F4\u7684 lockfile \u540E\u91CD\u8BD5\u3002`);return existsSync8(nodeModulesPath)?null:lockfile==="package-lock.json"?declaredPackageManagerName==="npm"&&declaredPackageManager?{command:"npx",args:["--yes",declaredPackageManager,"ci","--no-audit","--no-fund"],lockfile:"package-lock.json"}:{command:"npm",args:["ci","--no-audit","--no-fund"],lockfile:"package-lock.json"}:lockfile==="pnpm-lock.yaml"?{command:"corepack",args:["pnpm","install","--frozen-lockfile"],lockfile:"pnpm-lock.yaml"}:lockfile==="yarn.lock"?{command:"yarn",args:["install","--frozen-lockfile"],lockfile:"yarn.lock"}:null}function detectRequestedRemoteBindings(startDir=process.cwd()){let capabilities=new Set;try{let appRoot=findAppRoot(startDir);workspaceHasEffectiveDbMigration(appRoot)&&capabilities.add("db")}catch{return[]}return[...capabilities]}function templatePrefersPlatformCapabilityBindings(templateKey){return templateKey==="frontend-app-vite"||templateKey==="backend-app-node"}function recommendDevCommandForTemplate(templateKey,options={}){return(options.requestedRemoteBindings??[]).includes("db")?"platform dev --remote-bindings=db":templatePrefersPlatformCapabilityBindings(templateKey)?"platform dev --remote-bindings":null}function workspaceHasEffectiveDbMigration(appRoot){let migrationsDir=join4(appRoot,"resources","db","migrations");if(!existsSync8(migrationsDir)||!statSync2(migrationsDir).isDirectory())return!1;for(let entry of readdirSync2(migrationsDir,{withFileTypes:!0})){if(!entry.isFile())continue;if(readFileSync8(join4(migrationsDir,entry.name),"utf8").split(`
|
|
2378
2377
|
`).map(line=>line.replace(/--.*$/,"").trim()).filter(Boolean).join(`
|
|
2379
2378
|
`).trim().length>0)return!0}return!1}async function resolveAvailableLocalDevPort(preferredPort,options={}){let host=options.host;return await canBindPort(preferredPort,host)?{port:preferredPort,reusedPreferred:!0}:{port:await allocateEphemeralPort(host),reusedPreferred:!1}}async function canBindPort(port,host){return new Promise(resolve19=>{let server=createNetServer(),finish=available=>{server.removeAllListeners(),resolve19(available)};server.once("error",()=>{finish(!1)});let onListening=()=>{server.close(()=>finish(!0))};if(host){server.listen(port,host,onListening);return}server.listen(port,onListening)})}async function allocateEphemeralPort(host){return new Promise((resolve19,reject)=>{let server=createNetServer();server.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))});let onListening=()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u4E3A\u672C\u5730 dev \u5206\u914D\u56DE\u9000\u7AEF\u53E3\u3002")));return}let{port}=address;server.close(error=>{if(error){reject(error);return}resolve19(port)})};if(host){server.listen(0,host,onListening);return}server.listen(0,onListening)})}function collectDevPreflight(startDir=process.cwd(),target,runtimeBindings={}){let{manifest,directory}=readAppManifest(startDir),linked=readBinding(startDir);if(!linked?.binding.tenant_id||!linked.binding.app_id){let sourceContextPath=join4(directory,SOURCE_CONTEXT_FILE);throw new Error(existsSync8(sourceContextPath)?"\u5F53\u524D\u9879\u76EE\u672A\u7ED1\u5B9A tenant/app/env\u3002\u4F18\u5148\u5EFA\u8BAE\u6267\u884C `platform app create ...` \u6216 `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u53D6\u4E00\u4E2A\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u8981\u4FEE\u590D\u5F53\u524D\u76EE\u5F55\uFF0C\u518D\u624B\u52A8\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002":"\u5F53\u524D\u76EE\u5F55\u5DF2\u68C0\u6D4B\u5230 `app.yaml`\uFF0C\u4F46\u7F3A\u5C11 `.platform/source-context.json`\uFF0C\u770B\u8D77\u6765\u50CF\u4E00\u4E2A\u5DF2\u8FC1\u79FB\u6216\u672A\u91CD\u65B0\u7ED1\u5B9A\u7684\u5E94\u7528\u5DE5\u7A0B\u3002\u8BF7\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview` \u91CD\u65B0\u7ED1\u5B9A\u5F53\u524D\u76EE\u5F55\u3002")}let sourceContext=readSourceContext(startDir)?.sourceContext,workspaceTarget=resolveWorkspaceDevTarget(target),command=workspaceTarget?.command??manifest.entry.command,cwd=workspaceTarget?.cwd??directory,env=buildDevEnvironment(linked.binding,runtimeBindings),port=Number(env.PORT||manifest.entry.port||3e3);env.PUBLIC_APP_BASE_URL||(env.PUBLIC_APP_BASE_URL=`http://127.0.0.1:${port}`);let healthPath=manifest.entry.health_check||"/healthz",resolvedTemplateKey=typeof sourceContext?.template_key=="string"&&sourceContext.template_key.trim().length>0?sourceContext.template_key.trim():manifest.template_key,devCommandAnalysis=analyzeDevCommand(command,cwd),previewAddressMayChange=!manifest.dev.auto_restart&&devCommandAnalysis.portMayChange,warnings=["\u5F53\u524D\u9ED8\u8BA4\u8D70\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF1A\u672C\u5730\u5F00\u53D1\u4E0D\u8981\u6C42 registry\u3001kind\u3001ingress-nginx \u6216 build-runner\u3002",`\u5F53\u524D\u542F\u52A8\u547D\u4EE4\u6765\u81EA app.yaml \u7684 entry.command\uFF1A${command}`];return manifest.dev.auto_restart?warnings.push("\u5F53\u524D app.yaml \u5DF2\u914D\u7F6E `dev.auto_restart: true`\uFF1BCLI \u4F1A\u5728\u68C0\u6D4B\u5230\u6E90\u7801\u53D8\u66F4\u540E\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002"):devCommandAnalysis.managedByCommand?warnings.push(devCommandAnalysis.message):warnings.push("\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"),env.DATABASE_URL||warnings.push("\u672A\u68C0\u6D4B\u5230 DATABASE_URL\uFF1B\u672C\u5730\u6A21\u677F\u63A5\u53E3\u548C\u9875\u9762\u5F00\u53D1\u4ECD\u53EF\u7EE7\u7EED\u3002\u82E5\u4F60\u9700\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u518D\u6267\u884C `platform dev --remote-bindings` \u6216\u624B\u52A8\u8BBE\u7F6E\u672C\u5730\u73AF\u5883\u53D8\u91CF\u3002"),templatePrefersPlatformCapabilityBindings(resolvedTemplateKey)&&warnings.push("\u5F53\u524D\u5B98\u65B9\u6A21\u677F\u9ED8\u8BA4\u5E26 Auth / CMS / Data Form \u793A\u4F8B\u9875\u3002\u82E5\u4F60\u8981\u8054\u8C03\u8FD9\u4E9B\u771F\u5B9E\u5E73\u53F0\u80FD\u529B\uFF0C\u5EFA\u8BAE\u76F4\u63A5\u6267\u884C `platform dev --remote-bindings`\u3002"),!process.env.PUBLIC_APP_BASE_URL&&!runtimeBindings.PUBLIC_APP_BASE_URL&&warnings.push(`\u672A\u663E\u5F0F\u914D\u7F6E PUBLIC_APP_BASE_URL\uFF1B\u672C\u5730 dev \u5DF2\u4E34\u65F6\u56DE\u9000\u4E3A ${env.PUBLIC_APP_BASE_URL}\u3002`),resolvedTemplateKey&&resolvedTemplateKey!=="frontend-app-vite"&&resolvedTemplateKey!=="backend-app-node"&&warnings.push(`\u5F53\u524D\u6A21\u677F\u4E3A ${resolvedTemplateKey}\uFF0C\u8BF7\u786E\u8BA4\u5165\u53E3\u547D\u4EE4\u4E0E\u5065\u5EB7\u68C0\u67E5\u8DEF\u5F84\u5DF2\u7ECF\u548C app.yaml \u5BF9\u9F50\u3002`),{binding:linked.binding,manifest,templateKey:resolvedTemplateKey,directory,command,cwd,env,healthcheckUrl:`http://localhost:${port}${healthPath}`,previewAddressMayChange,warnings}}function analyzeDevCommand(command,cwd){if(/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch)/iu.test(command))return{managedByCommand:!0,portMayChange:/\bvite\b/iu.test(command),message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u5DF2\u5305\u542B watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"};let npmScriptMatch=command.trim().match(/^(?:npm|pnpm|yarn)\s+run\s+([a-zA-Z0-9:_-]+)|^corepack\s+pnpm\s+run\s+([a-zA-Z0-9:_-]+)/u),scriptName=npmScriptMatch?.[1]??npmScriptMatch?.[2];if(!scriptName)return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};let packageJsonPath=join4(cwd,"package.json");if(!existsSync8(packageJsonPath))return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};try{let scriptCommand=JSON.parse(readFileSync8(packageJsonPath,"utf8")).scripts?.[scriptName];if(typeof scriptCommand=="string"&&/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch|scripts\/dev\.mjs|scripts\\dev\.mjs)/iu.test(scriptCommand))return{managedByCommand:!0,portMayChange:/\bvite\b|scripts\/dev\.mjs|scripts\\dev\.mjs/iu.test(scriptCommand),message:scriptCommand.includes("scripts/dev.mjs")?"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7\u6A21\u677F\u81EA\u5E26\u7684\u672C\u5730 dev \u7F16\u6392\u811A\u672C\u542F\u52A8\uFF1B\u524D\u7AEF\u70ED\u66F4\u65B0\u4E0E\u670D\u52A1\u7AEF\u81EA\u52A8\u91CD\u542F\u7531\u6A21\u677F\u81EA\u5DF1\u7BA1\u7406\uFF0CCLI \u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002":"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7 package.json script \u81EA\u5E26 watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"}}catch{return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}async function runAppLibraryCommand(args,deps={}){let subcommand=args.rest[0];if(hasHelpFlag2(args)||args.rest.length===0||subcommand==="help"){printAppLibraryHelp();return}let sdk=deps.sdk,tenantId=deps.tenantId;if(!sdk||!tenantId){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");if(tenantId=deps.tenantId??resolveTenantId(args),!tenantId)throw new Error("`platform app-library` \u9700\u8981 tenant \u4E0A\u4E0B\u6587\u3002\u8BF7\u5148\u5728\u5F53\u524D\u9879\u76EE\u7ED1\u5B9A tenant/app\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant`\u3002");sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"dashboard",requestClass:"control"})}switch(subcommand){case"list":await runList(args,sdk);return;case"search":await runSearch(args,sdk);return;case"inspect":await runInspect(args,sdk);return;case"source":await runSource(args,sdk);return;case"config":await runConfig(args);return;case"open":await runOpen(args,deps);return;case"checkout":await runCheckout(args,sdk);return;case"create":await runCreate(args,sdk);return;case"update":await runUpdate(args,sdk);return;case"submit":await runSubmit(args,sdk,deps);return;case"publish":await runStateAction(args,sdk,"publish");return;case"unpublish":await runStateAction(args,sdk,"unpublish");return;case"archive":await runStateAction(args,sdk,"archive");return;case"delete":await runDelete(args,sdk);return;default:throw new Error("`platform app-library` \u4EC5\u652F\u6301 `list`\u3001`search`\u3001`inspect`\u3001`source`\u3001`config`\u3001`open`\u3001`checkout`\u3001`create`\u3001`update`\u3001`submit`\u3001`publish`\u3001`unpublish`\u3001`archive`\u3001`delete`\u3002")}}function printAppLibraryHelp(){process.stdout.write(["platform app-library <command>","","Commands:"," platform app-library list [--query <keyword>] [--status draft|published|unpublished|archived] [--tag <tag>] [--template-key <key>] [--visibility private|public] [--full] [--json]"," platform app-library search <keyword> [--status draft|published|unpublished|archived] [--full] [--json]"," platform app-library inspect <entry-id> [--json]"," platform app-library source tree <entry-id> [--json]"," platform app-library source read <entry-id> <path> [--json]"," platform app-library source search <entry-id> <query> [--json]"," platform app-library config init [--file app-library.yaml] [--force]"," platform app-library config validate [--file app-library.yaml] [--json]"," platform app-library open <entry-id> [--no-browser]"," platform app-library checkout <entry-id> [--dir <target-dir>] [--write-config] [--no-config] [--json]"," platform app-library create [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library update <entry-id> [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library submit <entry-id> [--file app-library.yaml] [--json]"," platform app-library publish <entry-id> [--json]"," platform app-library unpublish <entry-id> [--json]"," platform app-library archive <entry-id> [--json]"," platform app-library delete <entry-id> [--json]","","Notes:"," - \u521D\u671F\u4EC5\u652F\u6301 `example-app` \u6761\u76EE"," - `list` / `search` \u9ED8\u8BA4\u8FD4\u56DE\u8F7B\u6458\u8981\uFF1B\u5982\u9700\u5B8C\u6574\u5B57\u6BB5\u8BF7\u663E\u5F0F\u4F20 `--full`\uFF0C\u6216\u8FDB\u4E00\u6B65\u6267\u884C `inspect`"," - `list` / `search` \u9ED8\u8BA4\u4F1A\u67E5\u8BE2\u672C\u79DF\u6237 + \u8DE8\u79DF\u6237\u5DF2\u53D1\u5E03\u6761\u76EE\uFF1B\u5982\u663E\u5F0F\u4F20 `--status draft|unpublished|archived`\uFF0C\u5219\u4EC5\u67E5\u8BE2\u672C\u79DF\u6237\u6761\u76EE"," - `submit` \u9700\u8981\u5728\u672C\u5730\u8F7B\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u4F1A\u8BFB\u53D6\u5F53\u524D\u6E90\u7801\u5DE5\u4F5C\u533A\u5E76\u4E0A\u4F20\u4E3A\u5F53\u524D\u5FEB\u7167"," - \u5143\u6570\u636E\u9ED8\u8BA4\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u6839\u76EE\u5F55\u4E0B\u7684 `app-library.yaml`\uFF0CCLI flags \u53EF\u8986\u76D6\u540C\u540D\u5B57\u6BB5"," - `create` / `update` \u5728\u68C0\u6D4B\u5230\u73B0\u6709\u914D\u7F6E\u6587\u4EF6\u6216\u663E\u5F0F\u4F20\u5165 `--write-config` \u65F6\uFF0C\u4F1A\u628A\u6700\u65B0\u5143\u6570\u636E\u56DE\u5199\u5230 `app-library.yaml`"," - `checkout` \u9ED8\u8BA4\u5728\u76EE\u6807\u6E90\u7801\u4E0D\u5305\u542B `app-library.yaml` \u65F6\u81EA\u52A8\u751F\u6210\u4E00\u4EFD\uFF1B\u53EF\u7528 `--write-config` \u5F3A\u5236\u8986\u76D6\uFF0C`--no-config` \u8DF3\u8FC7"," - `open` \u9ED8\u8BA4\u6253\u5F00\u672C\u5730 tenant-workbench \u7684 `#app-library/<entry-id>` \u8DEF\u7531"," - `source tree/read/search` \u7528\u4E8E\u4E0D checkout \u7684\u4E91\u7AEF\u6E90\u7801\u7406\u89E3",""].join(`
|
|
2380
|
-
`))}async function runList(args,sdk){let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query:readStringOption2(args,"query"),status,template_key:readStringOption2(args,"template-key"),tag:readStringOption2(args,"tag"),visibility:readVisibilityOption(args,"visibility"),include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"list")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runSearch(args,sdk){let query=args.rest[1]?.trim();if(!query)throw new Error("`platform app-library search` \u9700\u8981 <keyword>\u3002");let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query,status,include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"search")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`query: ${query}`,`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runInspect(args,sdk){let config2=loadAppLibraryConfigOptional(),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library inspect` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let[entry,source]=await Promise.all([sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect")}),sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect(source)")})]);writeJsonOrText(args.options.json===!0,{entry,source},[`entry_id: ${entry.entry_id}`,`name: ${entry.name}`,`type: ${entry.type==="example_app"?"example-app":entry.type}`,`status: ${entry.status}`,`library: ${entry.library.name} (${entry.library.visibility})`,`summary: ${entry.summary?.trim()||"-"}`,`tags: ${entry.tags.length?entry.tags.join(", "):"-"}`,`template_key: ${entry.template_key??"-"}`,`capabilities: ${entry.capability_dependencies.length?entry.capability_dependencies.map(item=>item.minVersion?`${item.capability}@${item.minVersion}`:item.capability).join(", "):"-"}`,`current_snapshot_id: ${entry.current_snapshot_id??"-"}`,`source_files: ${source.files.length}`,`key_files: ${source.files.filter(file=>file.is_key_file).slice(0,8).map(file=>file.path).join(", ")||"-"}`,`next.inspect: platform app-library inspect ${entry.entry_id} --json`,`next.checkout: platform app-library checkout ${entry.entry_id} --dir ./${sanitizeDirectoryName(entry.name||entry.entry_id)}`])}async function runSource(args,sdk){let action=args.rest[1];if(action==="tree"){await runSourceTree(args,sdk);return}if(action==="read"){await runSourceRead(args,sdk);return}if(action==="search"){await runSourceSearch(args,sdk);return}throw new Error("`platform app-library source` \u4EC5\u652F\u6301 `tree`\u3001`read`\u3001`search`\u3002")}async function runConfig(args){let action=args.rest[1];if(action==="init"){runConfigInit(args);return}if(action==="validate"){runConfigValidate(args);return}throw new Error("`platform app-library config` \u4EC5\u652F\u6301 `init`\u3001`validate`\u3002")}async function runSourceTree(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source tree` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"source(tree)")});writeJsonOrText(args.options.json===!0,source,[`entry_id: ${entryId}`,`snapshot_id: ${source.snapshot_id}`,`files: ${source.files.length}`,...source.files.map(file=>{let markers=[file.is_key_file?"key":null,file.is_text?"text":"binary",file.ext||"-"].filter(Boolean).join(", ");return`- ${file.path} [${markers}]`})])}async function runSourceRead(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source read` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let
|
|
2379
|
+
`))}async function runList(args,sdk){let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query:readStringOption2(args,"query"),status,template_key:readStringOption2(args,"template-key"),tag:readStringOption2(args,"tag"),visibility:readVisibilityOption(args,"visibility"),include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"list")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runSearch(args,sdk){let query=args.rest[1]?.trim();if(!query)throw new Error("`platform app-library search` \u9700\u8981 <keyword>\u3002");let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query,status,include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"search")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`query: ${query}`,`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runInspect(args,sdk){let config2=loadAppLibraryConfigOptional(),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library inspect` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let[entry,source]=await Promise.all([sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect")}),sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect(source)")})]);writeJsonOrText(args.options.json===!0,{entry,source},[`entry_id: ${entry.entry_id}`,`name: ${entry.name}`,`type: ${entry.type==="example_app"?"example-app":entry.type}`,`status: ${entry.status}`,`library: ${entry.library.name} (${entry.library.visibility})`,`summary: ${entry.summary?.trim()||"-"}`,`tags: ${entry.tags.length?entry.tags.join(", "):"-"}`,`template_key: ${entry.template_key??"-"}`,`capabilities: ${entry.capability_dependencies.length?entry.capability_dependencies.map(item=>item.minVersion?`${item.capability}@${item.minVersion}`:item.capability).join(", "):"-"}`,`current_snapshot_id: ${entry.current_snapshot_id??"-"}`,`source_files: ${source.files.length}`,`key_files: ${source.files.filter(file=>file.is_key_file).slice(0,8).map(file=>file.path).join(", ")||"-"}`,`next.inspect: platform app-library inspect ${entry.entry_id} --json`,`next.checkout: platform app-library checkout ${entry.entry_id} --dir ./${sanitizeDirectoryName(entry.name||entry.entry_id)}`])}async function runSource(args,sdk){let action=args.rest[1];if(action==="tree"){await runSourceTree(args,sdk);return}if(action==="read"){await runSourceRead(args,sdk);return}if(action==="search"){await runSourceSearch(args,sdk);return}throw new Error("`platform app-library source` \u4EC5\u652F\u6301 `tree`\u3001`read`\u3001`search`\u3002")}async function runConfig(args){let action=args.rest[1];if(action==="init"){runConfigInit(args);return}if(action==="validate"){runConfigValidate(args);return}throw new Error("`platform app-library config` \u4EC5\u652F\u6301 `init`\u3001`validate`\u3002")}async function runSourceTree(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source tree` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"source(tree)")});writeJsonOrText(args.options.json===!0,source,[`entry_id: ${entryId}`,`snapshot_id: ${source.snapshot_id}`,`files: ${source.files.length}`,...source.files.map(file=>{let markers=[file.is_key_file?"key":null,file.is_text?"text":"binary",file.ext||"-"].filter(Boolean).join(", ");return`- ${file.path} [${markers}]`})])}async function runSourceRead(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source read` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let path3=args.rest[3]?.trim()||readStringOption2(args,"path");if(!path3)throw new Error("`platform app-library source read` \u9700\u8981 <path>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--path`\u3002");let response=await sdk.readLightAppLibraryEntrySourceFile(entryId,path3).catch(error=>{throw formatAppLibraryError(error,"source(read)")});if(args.options.json===!0){writeJsonOrText(!0,response,[]);return}process.stdout.write(`# ${response.file.path}
|
|
2381
2380
|
|
|
2382
2381
|
`),process.stdout.write(`${response.file.content}${response.file.content.endsWith(`
|
|
2383
2382
|
`)?"":`
|
|
@@ -2385,47 +2384,52 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
|
|
|
2385
2384
|
`),!opened&&args.options["no-browser"]!==!0&&process.stdout.write(`\u672A\u80FD\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE\u4E0A\u9762\u7684 URL\u3002
|
|
2386
2385
|
`),process.stdout.write(`inspect: platform app-library inspect ${entryId}
|
|
2387
2386
|
`),process.stdout.write(`checkout: platform app-library checkout ${entryId} --dir ./${sanitizeDirectoryName(entryId)}
|
|
2388
|
-
`)}function resolveTenantId(args){let binding=tryReadBinding(),context=loadStoredCliContext();return readStringOption2(args,"tenant")??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id}function resolveEntryId(args,config2){return args.rest[1]?.trim()||readStringOption2(args,"entry")||config2?.entry_id?.trim()}function resolvePositionalOrConfigEntryId(args,positionalIndex){return args.rest[positionalIndex]?.trim()||readStringOption2(args,"entry")||loadAppLibraryConfigOptional()?.entry_id?.trim()}function loadAppLibraryConfigOptional(filePath){let resolvedPath=resolveAppLibraryConfigPath(filePath);if(!resolvedPath||!existsSync9(resolvedPath))return null;let parsed=YAML2.parse(readFileSync9(resolvedPath,"utf8"));return parsed&&typeof parsed=="object"?parsed:null}function resolveAppLibraryConfigPath(filePath){if(filePath?.trim())return resolve7(process.cwd(),filePath.trim());try{return join5(findAppRoot(process.cwd()),"app-library.yaml")}catch{return null}}function resolveWritableAppLibraryConfigPath(filePath){return filePath?.trim()?resolve7(process.cwd(),filePath.trim()):resolveAppLibraryConfigPath()??join5(process.cwd(),"app-library.yaml")}function buildCreatePayload(args,config2){return{name:readStringOption2(args,"name")??config2?.name??"",...readStringOption2(args,"summary")??config2?.summary?{summary:readStringOption2(args,"summary")??config2?.summary}:{},...readTagsOption(args,config2)?.length?{tags:readTagsOption(args,config2)}:{},...readStringOption2(args,"readme")??config2?.readme?{readme:readStringOption2(args,"readme")??config2?.readme}:{},...readStringOption2(args,"template-key")??config2?.template_key?{template_key:readStringOption2(args,"template-key")??config2?.template_key}:{},...config2?.capability_dependencies?.length?{capability_dependencies:config2.capability_dependencies}:{},...readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id}:{},...readStringOption2(args,"source-app-id")??config2?.source_app_id?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id}:{},...readStringOption2(args,"source-version-id")??config2?.source_version_id?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id}:{},...readStringOption2(args,"created-from")??config2?.created_from?{created_from:readStringOption2(args,"created-from")??config2?.created_from}:{}}}function buildUpdatePayload(args,config2){return{...readStringOption2(args,"name")??config2?.name?{name:readStringOption2(args,"name")??config2?.name}:{},...hasOption2(args,"summary")||config2?.summary!==void 0?{summary:readStringOption2(args,"summary")??config2?.summary??null}:{},...hasOption2(args,"tags")||config2?.tags?{tags:readTagsOption(args,config2)??[]}:{},...hasOption2(args,"readme")||config2?.readme!==void 0?{readme:readStringOption2(args,"readme")??config2?.readme??null}:{},...hasOption2(args,"template-key")||config2?.template_key!==void 0?{template_key:readStringOption2(args,"template-key")??config2?.template_key??null}:{},...config2?.capability_dependencies?{capability_dependencies:config2.capability_dependencies}:{},...hasOption2(args,"screenshot-asset-id")||config2?.screenshot_asset_id!==void 0?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id??null}:{},...hasOption2(args,"source-app-id")||config2?.source_app_id!==void 0?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id??null}:{},...hasOption2(args,"source-version-id")||config2?.source_version_id!==void 0?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id??null}:{},...hasOption2(args,"created-from")||config2?.created_from!==void 0?{created_from:readStringOption2(args,"created-from")??config2?.created_from??null}:{}}}function readTagsOption(args,config2){let explicit=readCsvOption2(args,"tags");return explicit.length>0?explicit:config2?.tags}function readStringOption2(args,key){let value=args.options[key];return typeof value=="string"&&value.trim()||void 0}function readCsvOption2(args,key){let value=readStringOption2(args,key);return value?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function readStatusOption(args,key){let value=readStringOption2(args,key);return value==="draft"||value==="published"||value==="unpublished"||value==="archived"?value:void 0}function readVisibilityOption(args,key){let value=readStringOption2(args,key);return value==="private"||value==="public"?value:void 0}function hasOption2(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function hasHelpFlag2(args){return args.options.help===!0||args.options.h===!0}function tryReadBinding(){try{return readBinding(process.cwd())?.binding}catch{return null}}function ensureEmptyDirectory(directory){if(existsSync9(directory)){if(readdirSync3(directory).length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6: ${directory}`);return}mkdirSync4(directory,{recursive:!0})}function writeWorkspaceFile(root,relativePath,content){let normalizedPath=relativePath.replace(/^\/+/g,"");if(!normalizedPath||normalizedPath.startsWith("..")||normalizedPath.includes("../")||normalizedPath.includes("..\\"))throw new Error(`\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${relativePath}`);let outputPath=join5(root,normalizedPath);mkdirSync4(dirname6(outputPath),{recursive:!0}),writeFileSync5(outputPath,content,"utf8")}function sanitizeDirectoryName(value){return value.trim().toLowerCase().replace(/[^\p{L}\p{N}._-]+/gu,"-").replace(/^-+|-+$/g,"")||"light-app-library-entry"}function maybeWriteConfig(configPath,currentConfig,entry,args){configPath&&(!currentConfig&&args.options["write-config"]!==!0||saveAppLibraryConfig(configPath,materializeConfig(currentConfig,entry)))}function saveAppLibraryConfig(path2,config2){mkdirSync4(dirname6(path2),{recursive:!0}),writeFileSync5(path2,YAML2.stringify(config2),"utf8")}function runConfigInit(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(existsSync9(configPath)&&args.options.force!==!0)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${configPath}\u3002\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u5165 --force\u3002`);saveAppLibraryConfig(configPath,{name:"",summary:"",tags:[],readme:"",capability_dependencies:[]}),writeJsonOrText(args.options.json===!0,{path:configPath,created:!0},["\u5DF2\u751F\u6210\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93\u914D\u7F6E\u6A21\u677F\u3002",`path: ${configPath}`,"next: \u7F16\u8F91 app-library.yaml \u540E\uFF0C\u53EF\u6267\u884C `platform app-library config validate` \u6216 `platform app-library create`\u3002"])}function runConfigValidate(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(!existsSync9(configPath))throw new Error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);let raw=loadAppLibraryConfigOptional(configPath);if(!raw)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E3A\u7A7A\u6216\u683C\u5F0F\u975E\u6CD5: ${configPath}`);let normalized=validateAppLibraryConfig(raw,configPath);writeJsonOrText(args.options.json===!0,{path:configPath,config:normalized,valid:!0},["app-library.yaml \u6821\u9A8C\u901A\u8FC7\u3002",`path: ${configPath}`,`name: ${normalized.name}`,`tags: ${normalized.tags?.length??0}`,`capability_dependencies: ${normalized.capability_dependencies?.length??0}`])}function validateAppLibraryConfig(config2,configPath){let fail=message=>{throw new Error(`app-library.yaml \u6821\u9A8C\u5931\u8D25: ${message} (${configPath})`)},rawName=config2.name,normalizedName=typeof rawName=="string"?rawName.trim():"";return normalizedName||fail("`name` \u5FC5\u586B\u4E14\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.summary!==void 0&&typeof config2.summary!="string"&&fail("`summary` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.readme!==void 0&&typeof config2.readme!="string"&&fail("`readme` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.template_key!==void 0&&typeof config2.template_key!="string"&&fail("`template_key` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.entry_id!==void 0&&typeof config2.entry_id!="string"&&fail("`entry_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.screenshot_asset_id!==void 0&&typeof config2.screenshot_asset_id!="string"&&fail("`screenshot_asset_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_app_id!==void 0&&typeof config2.source_app_id!="string"&&fail("`source_app_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_version_id!==void 0&&typeof config2.source_version_id!="string"&&fail("`source_version_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.created_from!==void 0&&typeof config2.created_from!="string"&&fail("`created_from` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.tags!==void 0&&!Array.isArray(config2.tags)&&fail("`tags` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4"),config2.tags?.some(item=>typeof item!="string"||!item.trim())&&fail("`tags` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.capability_dependencies!==void 0&&!Array.isArray(config2.capability_dependencies)&&fail("`capability_dependencies` \u5FC5\u987B\u4E3A\u6570\u7EC4"),config2.capability_dependencies?.some(item=>!item||typeof item!="object"||typeof item.capability!="string"||!item.capability.trim())&&fail("`capability_dependencies` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u5305\u542B\u975E\u7A7A\u5B57\u7B26\u4E32 `capability`"),config2.capability_dependencies?.some(item=>item.minVersion!==void 0&&typeof item.minVersion!="string")&&fail("`capability_dependencies[].minVersion` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),{entry_id:config2.entry_id?.trim()||void 0,name:normalizedName,summary:config2.summary??"",tags:config2.tags?.map(item=>item.trim()).filter(Boolean)??[],readme:config2.readme??"",template_key:config2.template_key?.trim()||void 0,capability_dependencies:config2.capability_dependencies?.map(item=>({capability:item.capability.trim(),...item.minVersion?.trim()?{minVersion:item.minVersion.trim()}:{}}))??[],screenshot_asset_id:config2.screenshot_asset_id?.trim()||void 0,source_app_id:config2.source_app_id?.trim()||void 0,source_version_id:config2.source_version_id?.trim()||void 0,created_from:config2.created_from?.trim()||void 0}}function materializeConfig(currentConfig,entry){return{...currentConfig,entry_id:entry.entry_id,name:entry.name,summary:entry.summary??"",tags:entry.tags??[],readme:entry.readme??"",template_key:entry.template_key??void 0,screenshot_asset_id:entry.screenshot_asset_id??void 0,source_app_id:entry.source_app_id??void 0,source_version_id:entry.source_version_id??void 0,created_from:entry.created_from??void 0,capability_dependencies:entry.capability_dependencies??[]}}function writeJsonOrText(json,payload,lines){if(json){process.stdout.write(`${JSON.stringify(payload,null,2)}
|
|
2387
|
+
`)}function resolveTenantId(args){let binding=tryReadBinding(),context=loadStoredCliContext();return readStringOption2(args,"tenant")??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id}function resolveEntryId(args,config2){return args.rest[1]?.trim()||readStringOption2(args,"entry")||config2?.entry_id?.trim()}function resolvePositionalOrConfigEntryId(args,positionalIndex){return args.rest[positionalIndex]?.trim()||readStringOption2(args,"entry")||loadAppLibraryConfigOptional()?.entry_id?.trim()}function loadAppLibraryConfigOptional(filePath){let resolvedPath=resolveAppLibraryConfigPath(filePath);if(!resolvedPath||!existsSync9(resolvedPath))return null;let parsed=YAML2.parse(readFileSync9(resolvedPath,"utf8"));return parsed&&typeof parsed=="object"?parsed:null}function resolveAppLibraryConfigPath(filePath){if(filePath?.trim())return resolve7(process.cwd(),filePath.trim());try{return join5(findAppRoot(process.cwd()),"app-library.yaml")}catch{return null}}function resolveWritableAppLibraryConfigPath(filePath){return filePath?.trim()?resolve7(process.cwd(),filePath.trim()):resolveAppLibraryConfigPath()??join5(process.cwd(),"app-library.yaml")}function buildCreatePayload(args,config2){return{name:readStringOption2(args,"name")??config2?.name??"",...readStringOption2(args,"summary")??config2?.summary?{summary:readStringOption2(args,"summary")??config2?.summary}:{},...readTagsOption(args,config2)?.length?{tags:readTagsOption(args,config2)}:{},...readStringOption2(args,"readme")??config2?.readme?{readme:readStringOption2(args,"readme")??config2?.readme}:{},...readStringOption2(args,"template-key")??config2?.template_key?{template_key:readStringOption2(args,"template-key")??config2?.template_key}:{},...config2?.capability_dependencies?.length?{capability_dependencies:config2.capability_dependencies}:{},...readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id}:{},...readStringOption2(args,"source-app-id")??config2?.source_app_id?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id}:{},...readStringOption2(args,"source-version-id")??config2?.source_version_id?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id}:{},...readStringOption2(args,"created-from")??config2?.created_from?{created_from:readStringOption2(args,"created-from")??config2?.created_from}:{}}}function buildUpdatePayload(args,config2){return{...readStringOption2(args,"name")??config2?.name?{name:readStringOption2(args,"name")??config2?.name}:{},...hasOption2(args,"summary")||config2?.summary!==void 0?{summary:readStringOption2(args,"summary")??config2?.summary??null}:{},...hasOption2(args,"tags")||config2?.tags?{tags:readTagsOption(args,config2)??[]}:{},...hasOption2(args,"readme")||config2?.readme!==void 0?{readme:readStringOption2(args,"readme")??config2?.readme??null}:{},...hasOption2(args,"template-key")||config2?.template_key!==void 0?{template_key:readStringOption2(args,"template-key")??config2?.template_key??null}:{},...config2?.capability_dependencies?{capability_dependencies:config2.capability_dependencies}:{},...hasOption2(args,"screenshot-asset-id")||config2?.screenshot_asset_id!==void 0?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id??null}:{},...hasOption2(args,"source-app-id")||config2?.source_app_id!==void 0?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id??null}:{},...hasOption2(args,"source-version-id")||config2?.source_version_id!==void 0?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id??null}:{},...hasOption2(args,"created-from")||config2?.created_from!==void 0?{created_from:readStringOption2(args,"created-from")??config2?.created_from??null}:{}}}function readTagsOption(args,config2){let explicit=readCsvOption2(args,"tags");return explicit.length>0?explicit:config2?.tags}function readStringOption2(args,key){let value=args.options[key];return typeof value=="string"&&value.trim()||void 0}function readCsvOption2(args,key){let value=readStringOption2(args,key);return value?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function readStatusOption(args,key){let value=readStringOption2(args,key);return value==="draft"||value==="published"||value==="unpublished"||value==="archived"?value:void 0}function readVisibilityOption(args,key){let value=readStringOption2(args,key);return value==="private"||value==="public"?value:void 0}function hasOption2(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function hasHelpFlag2(args){return args.options.help===!0||args.options.h===!0}function tryReadBinding(){try{return readBinding(process.cwd())?.binding}catch{return null}}function ensureEmptyDirectory(directory){if(existsSync9(directory)){if(readdirSync3(directory).length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6: ${directory}`);return}mkdirSync4(directory,{recursive:!0})}function writeWorkspaceFile(root,relativePath,content){let normalizedPath=relativePath.replace(/^\/+/g,"");if(!normalizedPath||normalizedPath.startsWith("..")||normalizedPath.includes("../")||normalizedPath.includes("..\\"))throw new Error(`\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${relativePath}`);let outputPath=join5(root,normalizedPath);mkdirSync4(dirname6(outputPath),{recursive:!0}),writeFileSync5(outputPath,content,"utf8")}function sanitizeDirectoryName(value){return value.trim().toLowerCase().replace(/[^\p{L}\p{N}._-]+/gu,"-").replace(/^-+|-+$/g,"")||"light-app-library-entry"}function maybeWriteConfig(configPath,currentConfig,entry,args){configPath&&(!currentConfig&&args.options["write-config"]!==!0||saveAppLibraryConfig(configPath,materializeConfig(currentConfig,entry)))}function saveAppLibraryConfig(path3,config2){mkdirSync4(dirname6(path3),{recursive:!0}),writeFileSync5(path3,YAML2.stringify(config2),"utf8")}function runConfigInit(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(existsSync9(configPath)&&args.options.force!==!0)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${configPath}\u3002\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u5165 --force\u3002`);saveAppLibraryConfig(configPath,{name:"",summary:"",tags:[],readme:"",capability_dependencies:[]}),writeJsonOrText(args.options.json===!0,{path:configPath,created:!0},["\u5DF2\u751F\u6210\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93\u914D\u7F6E\u6A21\u677F\u3002",`path: ${configPath}`,"next: \u7F16\u8F91 app-library.yaml \u540E\uFF0C\u53EF\u6267\u884C `platform app-library config validate` \u6216 `platform app-library create`\u3002"])}function runConfigValidate(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(!existsSync9(configPath))throw new Error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);let raw=loadAppLibraryConfigOptional(configPath);if(!raw)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E3A\u7A7A\u6216\u683C\u5F0F\u975E\u6CD5: ${configPath}`);let normalized=validateAppLibraryConfig(raw,configPath);writeJsonOrText(args.options.json===!0,{path:configPath,config:normalized,valid:!0},["app-library.yaml \u6821\u9A8C\u901A\u8FC7\u3002",`path: ${configPath}`,`name: ${normalized.name}`,`tags: ${normalized.tags?.length??0}`,`capability_dependencies: ${normalized.capability_dependencies?.length??0}`])}function validateAppLibraryConfig(config2,configPath){let fail=message=>{throw new Error(`app-library.yaml \u6821\u9A8C\u5931\u8D25: ${message} (${configPath})`)},rawName=config2.name,normalizedName=typeof rawName=="string"?rawName.trim():"";return normalizedName||fail("`name` \u5FC5\u586B\u4E14\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.summary!==void 0&&typeof config2.summary!="string"&&fail("`summary` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.readme!==void 0&&typeof config2.readme!="string"&&fail("`readme` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.template_key!==void 0&&typeof config2.template_key!="string"&&fail("`template_key` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.entry_id!==void 0&&typeof config2.entry_id!="string"&&fail("`entry_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.screenshot_asset_id!==void 0&&typeof config2.screenshot_asset_id!="string"&&fail("`screenshot_asset_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_app_id!==void 0&&typeof config2.source_app_id!="string"&&fail("`source_app_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_version_id!==void 0&&typeof config2.source_version_id!="string"&&fail("`source_version_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.created_from!==void 0&&typeof config2.created_from!="string"&&fail("`created_from` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.tags!==void 0&&!Array.isArray(config2.tags)&&fail("`tags` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4"),config2.tags?.some(item=>typeof item!="string"||!item.trim())&&fail("`tags` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.capability_dependencies!==void 0&&!Array.isArray(config2.capability_dependencies)&&fail("`capability_dependencies` \u5FC5\u987B\u4E3A\u6570\u7EC4"),config2.capability_dependencies?.some(item=>!item||typeof item!="object"||typeof item.capability!="string"||!item.capability.trim())&&fail("`capability_dependencies` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u5305\u542B\u975E\u7A7A\u5B57\u7B26\u4E32 `capability`"),config2.capability_dependencies?.some(item=>item.minVersion!==void 0&&typeof item.minVersion!="string")&&fail("`capability_dependencies[].minVersion` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),{entry_id:config2.entry_id?.trim()||void 0,name:normalizedName,summary:config2.summary??"",tags:config2.tags?.map(item=>item.trim()).filter(Boolean)??[],readme:config2.readme??"",template_key:config2.template_key?.trim()||void 0,capability_dependencies:config2.capability_dependencies?.map(item=>({capability:item.capability.trim(),...item.minVersion?.trim()?{minVersion:item.minVersion.trim()}:{}}))??[],screenshot_asset_id:config2.screenshot_asset_id?.trim()||void 0,source_app_id:config2.source_app_id?.trim()||void 0,source_version_id:config2.source_version_id?.trim()||void 0,created_from:config2.created_from?.trim()||void 0}}function materializeConfig(currentConfig,entry){return{...currentConfig,entry_id:entry.entry_id,name:entry.name,summary:entry.summary??"",tags:entry.tags??[],readme:entry.readme??"",template_key:entry.template_key??void 0,screenshot_asset_id:entry.screenshot_asset_id??void 0,source_app_id:entry.source_app_id??void 0,source_version_id:entry.source_version_id??void 0,created_from:entry.created_from??void 0,capability_dependencies:entry.capability_dependencies??[]}}function writeJsonOrText(json,payload,lines){if(json){process.stdout.write(`${JSON.stringify(payload,null,2)}
|
|
2389
2388
|
`);return}process.stdout.write(`${lines.join(`
|
|
2390
2389
|
`)}
|
|
2391
|
-
`)}function formatEntrySummary(item,index,full){let typeLabel=item.type==="example_app"?"example-app":item.type,tenantLabel=item.library?.tenant_id??"-",tags=item.tags.length?item.tags.slice(0,3).join(", "):"-",capabilities=item.capability_dependencies?.length?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";if(!full)return[`[${index}] ${item.name} (${item.entry_id})`,` ${item.status} \xB7 ${typeLabel} \xB7 ${item.template_key??"-"} \xB7 tenant=${tenantLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${tags}`,` capabilities: ${capabilities}`];let fullCapabilities=item.capability_dependencies?.length?item.capability_dependencies.map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";return[`[${index}] ${item.name} (${item.entry_id})`,` status: ${item.status} type: ${typeLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${item.tags.length?item.tags.join(", "):"-"}`,` template: ${item.template_key??"-"} snapshot: ${item.current_snapshot_id??"-"}`,` capabilities: ${fullCapabilities}`]}function toEntryListBriefPayload(response){return{items:response.items.map(item=>({entry_id:item.entry_id,name:item.name,summary:item.summary??"",status:item.status,type:item.type,template_key:item.template_key??null,tags:Array.isArray(item.tags)?item.tags.slice(0,3):[],capability_dependencies:Array.isArray(item.capability_dependencies)?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability):[],library:item.library?{tenant_id:item.library.tenant_id,visibility:item.library.visibility}:void 0}))}}function formatAppLibraryError(error,stage){return error instanceof PlatformApiError?new Error(`app-library ${stage} failed: ${error.message}${error.code?` (${error.code})`:""}`):error instanceof Error?error:new Error(`app-library ${stage} failed`)}async function tryOpenBrowser(url){return(await openExternal(url)).opened}import{
|
|
2392
|
-
`;return writeFileSync6(
|
|
2393
|
-
`,"utf8"),historyDir}function restoreLastPlatformBlocksHistory(appRoot){let historyDir=getPlatformBlocksHistoryLastDir(appRoot),metadataPath=join8(historyDir,"metadata.json");if(!existsSync12(metadataPath))throw new Error("\u65E0\u53EF\u56DE\u9000\u7684\u6700\u8FD1\u4E00\u6B21 apply\u3002");let metadata=JSON.parse(readFileSync12(metadataPath,"utf8")),restoredFiles=[],removedFiles=[];for(let file of metadata.managed_files_overwritten){let targetPath=join8(appRoot,file.path);if(!file.existed_before){rmSync2(targetPath,{force:!0}),removedFiles.push(file.path);continue}let snapshotPath=join8(historyDir,"files",file.path),content=readFileSync12(snapshotPath,"utf8");mkdirSync6(dirname8(targetPath),{recursive:!0}),writeFileSync7(targetPath,content,"utf8"),restoredFiles.push(file.path)}let lockfilePath=getPlatformBlocksLockfilePath(appRoot);return mkdirSync6(dirname8(lockfilePath),{recursive:!0}),writeFileSync7(lockfilePath,readFileSync12(join8(historyDir,metadata.lockfile_before_path),"utf8"),"utf8"),{restoredFiles,removedFiles,lockfilePath:relative2(appRoot,lockfilePath).replace(/\\/g,"/")}}function hasLastPlatformBlocksHistory(appRoot){return existsSync12(join8(getPlatformBlocksHistoryLastDir(appRoot),"metadata.json"))}
|
|
2390
|
+
`)}function formatEntrySummary(item,index,full){let typeLabel=item.type==="example_app"?"example-app":item.type,tenantLabel=item.library?.tenant_id??"-",tags=item.tags.length?item.tags.slice(0,3).join(", "):"-",capabilities=item.capability_dependencies?.length?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";if(!full)return[`[${index}] ${item.name} (${item.entry_id})`,` ${item.status} \xB7 ${typeLabel} \xB7 ${item.template_key??"-"} \xB7 tenant=${tenantLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${tags}`,` capabilities: ${capabilities}`];let fullCapabilities=item.capability_dependencies?.length?item.capability_dependencies.map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";return[`[${index}] ${item.name} (${item.entry_id})`,` status: ${item.status} type: ${typeLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${item.tags.length?item.tags.join(", "):"-"}`,` template: ${item.template_key??"-"} snapshot: ${item.current_snapshot_id??"-"}`,` capabilities: ${fullCapabilities}`]}function toEntryListBriefPayload(response){return{items:response.items.map(item=>({entry_id:item.entry_id,name:item.name,summary:item.summary??"",status:item.status,type:item.type,template_key:item.template_key??null,tags:Array.isArray(item.tags)?item.tags.slice(0,3):[],capability_dependencies:Array.isArray(item.capability_dependencies)?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability):[],library:item.library?{tenant_id:item.library.tenant_id,visibility:item.library.visibility}:void 0}))}}function formatAppLibraryError(error,stage){return error instanceof PlatformApiError?new Error(`app-library ${stage} failed: ${error.message}${error.code?` (${error.code})`:""}`):error instanceof Error?error:new Error(`app-library ${stage} failed`)}async function tryOpenBrowser(url){return(await openExternal(url)).opened}import{existsSync as existsSync14,mkdirSync as mkdirSync7,readFileSync as readFileSync14,unlinkSync,writeFileSync as writeFileSync8}from"node:fs";import{dirname as dirname9,isAbsolute,join as join9,resolve as resolve8,sep}from"node:path";import{createHash as createHash4}from"node:crypto";import{existsSync as existsSync10,readFileSync as readFileSync10}from"node:fs";import{join as join6}from"node:path";function inspectPlatformBlocksAdoptability(appRoot,manifest){let files=manifest.managed_files.map(file=>{let current=readCurrentSha(appRoot,file.path);return current?current===file.content_sha256?{path:file.path,status:"match"}:{path:file.path,status:"drift"}:{path:file.path,status:"missing"}});return{adoptable:files.every(file=>file.status==="match"),files}}function computePlatformBlocksDiff(appRoot,manifest,lockfile){let lockFiles=new Map(lockfile.managed_files.map(file=>[file.path,file])),targetFiles=new Map(manifest.managed_files.map(file=>[file.path,file])),targetDiff=manifest.managed_files.map(file=>{let current_sha256=readCurrentSha(appRoot,file.path),lock_sha256=lockFiles.get(file.path)?.applied_sha256??null;return current_sha256===file.content_sha256?{path:file.path,status:lock_sha256===file.content_sha256?"noop":"lock_refresh",current_sha256,lock_sha256,target_sha256:file.content_sha256}:current_sha256===null||current_sha256===lock_sha256?{path:file.path,status:"safe_update",current_sha256,lock_sha256,target_sha256:file.content_sha256}:{path:file.path,status:"conflict",current_sha256,lock_sha256,target_sha256:file.content_sha256}}),removedDiff=lockfile.managed_files.filter(file=>!targetFiles.has(file.path)).map(file=>{let current_sha256=readCurrentSha(appRoot,file.path);return current_sha256===null?{path:file.path,status:"lock_refresh",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}:{path:file.path,status:current_sha256===file.applied_sha256?"safe_remove":"conflict",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}});return[...targetDiff,...removedDiff]}function determinePlatformBlocksApplyOutcome(diff){return diff.some(file=>file.status==="conflict")?"conflict":diff.some(file=>file.status==="safe_update"||file.status==="safe_remove")?"updated":diff.some(file=>file.status==="lock_refresh")?"lock_refreshed":"noop"}function checksumContent(content){return`sha256-${createHash4("sha256").update(content).digest("hex")}`}function readCurrentSha(appRoot,relativePath){let absolutePath=join6(appRoot,relativePath);return existsSync10(absolutePath)?checksumContent(readFileSync10(absolutePath,"utf8")):null}import{existsSync as existsSync12,mkdirSync as mkdirSync6,readFileSync as readFileSync12,readdirSync as readdirSync4,rmSync as rmSync2,writeFileSync as writeFileSync7}from"node:fs";import{dirname as dirname8,join as join8,relative as relative2}from"node:path";import{dirname as dirname7,join as join7}from"node:path";import{existsSync as existsSync11,mkdirSync as mkdirSync5,readFileSync as readFileSync11,writeFileSync as writeFileSync6}from"node:fs";var PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH=".platform/platform-blocks.lock.json";function getPlatformBlocksLockfilePath(appRoot){return join7(appRoot,PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH)}function readPlatformBlocksLockfile(startDir){let{directory:appRoot}=readAppManifest(startDir),path3=getPlatformBlocksLockfilePath(appRoot);if(!existsSync11(path3))return null;let raw=readFileSync11(path3,"utf8"),lockfile=JSON.parse(raw);return{appRoot,path:path3,lockfile,raw}}function writePlatformBlocksLockfile(appRoot,content){let path3=getPlatformBlocksLockfilePath(appRoot);mkdirSync5(dirname7(path3),{recursive:!0});let serialized=typeof content=="string"?content:`${JSON.stringify(content,null,2)}
|
|
2391
|
+
`;return writeFileSync6(path3,serialized,"utf8"),path3}function resolvePlatformBlocksTemplateKey(startDir){let{directory:appRoot}=readAppManifest(startDir),sourceContextTemplateKey=normalizeAppTemplateKey(readSourceContext(appRoot)?.sourceContext.template_key);if(sourceContextTemplateKey)return sourceContextTemplateKey;let lockfileTemplateKey=normalizeAppTemplateKey(readPlatformBlocksLockfile(appRoot)?.lockfile.template_key);if(lockfileTemplateKey)return lockfileTemplateKey;throw new Error("\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u5DE5\u7A0B\u7684\u6A21\u677F\u3002\u8BF7\u5148\u901A\u8FC7 checkout/\u7ED1\u5B9A\u4E0A\u4E0B\u6587\u8FDB\u5165\u53D7\u652F\u6301\u7684 frontend/backend app \u5DE5\u7A0B\u3002")}var HISTORY_LAST_RELATIVE_DIR=".platform/platform-blocks.history/last";function getPlatformBlocksHistoryLastDir(appRoot){return join8(appRoot,HISTORY_LAST_RELATIVE_DIR)}function writeLastPlatformBlocksHistory(appRoot,args){let historyDir=getPlatformBlocksHistoryLastDir(appRoot);rmSync2(historyDir,{recursive:!0,force:!0}),mkdirSync6(join8(historyDir,"files"),{recursive:!0});for(let file of args.files){if(!file.existed_before||typeof file.content!="string")continue;let snapshotPath=join8(historyDir,"files",file.path);mkdirSync6(dirname8(snapshotPath),{recursive:!0}),writeFileSync7(snapshotPath,file.content,"utf8")}writeFileSync7(join8(historyDir,"lockfile.before.json"),args.lockfileBefore,"utf8"),writeFileSync7(join8(historyDir,"lockfile.after.json"),args.lockfileAfter,"utf8");let metadata={template_key:args.templateKey,platform_blocks_revision_before:args.revisionBefore,platform_blocks_revision_after:args.revisionAfter,managed_files_overwritten:args.files.map(file=>({path:file.path,existed_before:file.existed_before})),lockfile_before_path:"lockfile.before.json",lockfile_after_path:"lockfile.after.json",created_at:new Date().toISOString()};return writeFileSync7(join8(historyDir,"metadata.json"),`${JSON.stringify(metadata,null,2)}
|
|
2392
|
+
`,"utf8"),historyDir}function restoreLastPlatformBlocksHistory(appRoot){let historyDir=getPlatformBlocksHistoryLastDir(appRoot),metadataPath=join8(historyDir,"metadata.json");if(!existsSync12(metadataPath))throw new Error("\u65E0\u53EF\u56DE\u9000\u7684\u6700\u8FD1\u4E00\u6B21 apply\u3002");let metadata=JSON.parse(readFileSync12(metadataPath,"utf8")),restoredFiles=[],removedFiles=[];for(let file of metadata.managed_files_overwritten){let targetPath=join8(appRoot,file.path);if(!file.existed_before){rmSync2(targetPath,{force:!0}),removedFiles.push(file.path);continue}let snapshotPath=join8(historyDir,"files",file.path),content=readFileSync12(snapshotPath,"utf8");mkdirSync6(dirname8(targetPath),{recursive:!0}),writeFileSync7(targetPath,content,"utf8"),restoredFiles.push(file.path)}let lockfilePath=getPlatformBlocksLockfilePath(appRoot);return mkdirSync6(dirname8(lockfilePath),{recursive:!0}),writeFileSync7(lockfilePath,readFileSync12(join8(historyDir,metadata.lockfile_before_path),"utf8"),"utf8"),{restoredFiles,removedFiles,lockfilePath:relative2(appRoot,lockfilePath).replace(/\\/g,"/")}}function hasLastPlatformBlocksHistory(appRoot){return existsSync12(join8(getPlatformBlocksHistoryLastDir(appRoot),"metadata.json"))}import{existsSync as existsSync13,lstatSync as lstatSync2,readFileSync as readFileSync13}from"node:fs";import path2 from"node:path";var PlatformBlocksVerifyError=class extends Error{result;code="platform_blocks_verify_failed";constructor(result){let failures=result.checks.filter(check=>check.status==="failed"),details=failures.map(check=>{let location=check.path?` path=${check.path}`:"",detail=check.detail?` ${check.detail}`:"";return`- ${check.reason??"unknown"}${location}${detail}`});super([`[platform_blocks_verify_failed] \u5E73\u53F0\u5757\u6821\u9A8C\u5931\u8D25\uFF1A${failures.length}/${result.checks.length} \u9879\u672A\u901A\u8FC7\u3002`,...details].join(`
|
|
2393
|
+
`)),this.result=result,this.name="PlatformBlocksVerifyError"}};function verifyPlatformBlocksWorkspace(input){let appRoot=path2.resolve(input.appRoot),manifest;try{manifest=getPlatformBlocksManifest(input.templateKey)}catch(error){return failedResult({name:"template_supported",status:"failed",reason:"unsupported_template",detail:toErrorMessage2(error)})}let lockfilePath=getPlatformBlocksLockfilePath(appRoot);if(!existsSync13(lockfilePath))return failedResult({name:"lockfile_present",status:"failed",reason:"lockfile_missing",path:".platform/platform-blocks.lock.json",detail:"\u7F3A\u5C11\u5E73\u53F0\u5757 lockfile\u3002"});let lockfile;try{let record=readPlatformBlocksLockfile(appRoot);if(!record||!isPlatformBlocksLockfile(record.lockfile))throw new Error("lockfile schema is invalid");lockfile=record.lockfile}catch(error){return failedResult({name:"lockfile_valid",status:"failed",reason:"lockfile_invalid",path:".platform/platform-blocks.lock.json",detail:toErrorMessage2(error)})}let checks=[{name:"lockfile_present",status:"passed"},{name:"lockfile_valid",status:"passed"}],versionMatches=lockfile.template_key===input.templateKey&&lockfile.platform_blocks_release===manifest.platform_blocks_release&&lockfile.platform_blocks_revision===manifest.platform_blocks_revision;checks.push(versionMatches?{name:"manifest_version",status:"passed"}:{name:"manifest_version",status:"failed",reason:"manifest_version_mismatch",detail:`lock=${lockfile.template_key}@${lockfile.platform_blocks_revision} target=${manifest.template_key}@${manifest.platform_blocks_revision}`});let manifestFiles=new Map(manifest.managed_files.map(file=>[file.path,file])),lockPaths=new Set;for(let file of lockfile.managed_files){if(lockPaths.add(file.path),!(isSafeManagedPath(appRoot,input.templateKey,file.path)&&manifestFiles.has(file.path))){checks.push({name:`managed_path:${file.path}`,status:"failed",reason:"unsafe_managed_path",path:file.path,detail:"lockfile \u8DEF\u5F84\u8D8A\u754C\u3001\u683C\u5F0F\u975E\u6CD5\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D manifest\u3002"});continue}let manifestFile=manifestFiles.get(file.path);file.block_id===manifestFile.block_id&&file.policy===manifestFile.policy&&file.applied_sha256===manifestFile.content_sha256||checks.push({name:`lockfile_entry:${file.path}`,status:"failed",reason:"lockfile_entry_mismatch",path:file.path,detail:`lock=${file.block_id}/${file.policy}/${file.applied_sha256} manifest=${manifestFile.block_id}/${manifestFile.policy}/${manifestFile.content_sha256}`});let absolutePath=path2.resolve(appRoot,...file.path.split("/"));if(!existsSync13(absolutePath)){checks.push({name:`managed_file:${file.path}`,status:"failed",reason:"managed_file_missing",path:file.path,detail:"\u6258\u7BA1\u6587\u4EF6\u4E0D\u5B58\u5728\u3002"});continue}let stats=lstatSync2(absolutePath);if(!stats.isFile()||stats.isSymbolicLink()){checks.push({name:`managed_path:${file.path}`,status:"failed",reason:"unsafe_managed_path",path:file.path,detail:"\u6258\u7BA1\u8DEF\u5F84\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u6216\u4E3A\u7B26\u53F7\u94FE\u63A5\u3002"});continue}let actualSha=checksumContent(readFileSync13(absolutePath,"utf8"));checks.push(actualSha===manifestFile.content_sha256?{name:`managed_file:${file.path}`,status:"passed",path:file.path}:{name:`managed_file:${file.path}`,status:"failed",reason:"managed_file_drifted",path:file.path,detail:`actual=${actualSha} manifest=${manifestFile.content_sha256}`})}for(let file of manifest.managed_files)lockPaths.has(file.path)||checks.push({name:`lockfile_entry:${file.path}`,status:"failed",reason:"lockfile_entry_missing",path:file.path,detail:"\u5F53\u524D manifest \u7684\u6258\u7BA1\u6587\u4EF6\u672A\u8BB0\u5F55\u5728 lockfile\u3002"});return{status:checks.every(check=>check.status==="passed")?"passed":"failed",checks}}function assertPlatformBlocksVerified(result){if(result.status!=="passed")throw new PlatformBlocksVerifyError(result)}function isSafeManagedPath(appRoot,templateKey,relativePath){if(!relativePath||relativePath.includes("\\")||path2.posix.isAbsolute(relativePath)||path2.win32.isAbsolute(relativePath)||path2.posix.normalize(relativePath)!==relativePath||relativePath.split("/").some(segment=>segment===""||segment==="."||segment==="..")||!isManagedPlatformFilePath(templateKey,relativePath))return!1;let absolutePath=path2.resolve(appRoot,...relativePath.split("/")),relative8=path2.relative(appRoot,absolutePath);return relative8.length>0&&!relative8.startsWith("..")&&!path2.isAbsolute(relative8)}function isPlatformBlocksLockfile(value){if(!value||typeof value!="object")return!1;let candidate=value;return typeof candidate.schema_version=="number"&&typeof candidate.template_key=="string"&&typeof candidate.platform_blocks_revision=="string"&&typeof candidate.applied_at=="string"&&Array.isArray(candidate.managed_files)&&candidate.managed_files.every(file=>!!file&&typeof file.path=="string"&&typeof file.block_id=="string"&&file.policy==="replace"&&typeof file.applied_sha256=="string")&&!!candidate.last_sync&&typeof candidate.last_sync?.mode=="string"&&typeof candidate.last_sync?.tool_version=="string"}function failedResult(check){return{status:"failed",checks:[check]}}function toErrorMessage2(error){return error instanceof Error?error.message:String(error)}var CLI_TOOL_VERSION=`@voobase/cli@${getCliPackageVersion()}`;function runAppSyncPlatformBlocksCommand(args){let{directory:appRoot}=readAppManifest(args.cwd);if(args.rollbackLast){let restored=restoreLastPlatformBlocksHistory(appRoot);return{mode:"rollback",appRoot,restoredFiles:restored.restoredFiles,removedFiles:restored.removedFiles,lockfilePath:restored.lockfilePath}}let templateKey=resolvePlatformBlocksTemplateKey(appRoot),manifest=getPlatformBlocksManifest(templateKey),templateFiles=buildTemplateFileMap(templateKey),lockRecord=readPlatformBlocksLockfile(appRoot);if(args.verify&&!args.apply)return{mode:"verify",appRoot,templateKey,targetRevision:manifest.platform_blocks_revision,verify:runPlatformBlocksVerify(appRoot,templateKey)};if(args.adopt){if(lockRecord)return{mode:"adopt",appRoot,templateKey,status:"already_managed",targetRevision:manifest.platform_blocks_revision,lockfilePath:lockRecord.path};let adopt=inspectPlatformBlocksAdoptability(appRoot,manifest);if(!adopt.adoptable){let problems=adopt.files.filter(file=>file.status!=="match").map(file=>`${file.path}=${file.status}`).join(", ");throw new Error(`\u5F53\u524D\u5DE5\u7A0B\u5C1A\u672A\u8FBE\u5230 adopt \u6761\u4EF6\uFF1A${problems}`)}let nextLockfile=buildPlatformBlocksLockfile(manifest,{mode:"adopt",toolVersion:CLI_TOOL_VERSION}),lockfilePath=writePlatformBlocksLockfile(appRoot,stringifyPlatformBlocksLockfile(nextLockfile));return{mode:"adopt",appRoot,templateKey,status:"adopted",targetRevision:manifest.platform_blocks_revision,lockfilePath}}if(args.apply){if(!lockRecord)throw new Error("\u7F3A\u5C11 `.platform/platform-blocks.lock.json`\uFF0C\u8BF7\u5148\u6267\u884C `platform app sync-platform-blocks --adopt`\u3002");let diff2=computePlatformBlocksDiff(appRoot,manifest,lockRecord.lockfile),outcome=determinePlatformBlocksApplyOutcome(diff2);if(outcome==="conflict"){let conflictList=diff2.filter(file=>file.status==="conflict").map(file=>file.path).join(", ");throw new Error(`\u68C0\u6D4B\u5230\u5E73\u53F0\u5757\u51B2\u7A81\uFF0C\u5DF2\u62D2\u7EDD apply\uFF1A${conflictList}`)}let nextLockfile=buildPlatformBlocksLockfile(manifest,{mode:outcome==="lock_refreshed"?"lock_refreshed":"apply",toolVersion:CLI_TOOL_VERSION}),nextLockfileRaw=stringifyPlatformBlocksLockfile(nextLockfile);if(outcome==="updated"){for(let file of diff2.filter(item=>item.status==="safe_remove"))assertSafeManagedRemovalPath(appRoot,templateKey,file.path);let snapshots=diff2.filter(file=>file.status==="safe_update"||file.status==="safe_remove").map(file=>buildHistorySnapshot(appRoot,file.path));for(let file of diff2.filter(item=>item.status==="safe_update")){let target=templateFiles.get(file.path);if(typeof target!="string")throw new Error(`\u6A21\u677F\u7F3A\u5C11\u76EE\u6807\u6587\u4EF6\uFF1A${file.path}`);writeManagedFile(appRoot,file.path,target)}for(let file of diff2.filter(item=>item.status==="safe_remove"))removeManagedFile(appRoot,file.path);writePlatformBlocksLockfile(appRoot,nextLockfileRaw),writeLastPlatformBlocksHistory(appRoot,{templateKey,revisionBefore:lockRecord.lockfile.platform_blocks_revision,revisionAfter:manifest.platform_blocks_revision,files:snapshots,lockfileBefore:lockRecord.raw,lockfileAfter:nextLockfileRaw});let verify2=args.verify?runPlatformBlocksVerify(appRoot,templateKey):void 0;return{mode:"apply",appRoot,templateKey,status:outcome,targetRevision:manifest.platform_blocks_revision,updatedFiles:diff2.filter(file=>file.status==="safe_update").map(file=>file.path),removedFiles:diff2.filter(file=>file.status==="safe_remove").map(file=>file.path),lockfilePath:lockRecord.path,historyUpdated:!0,verify:verify2}}if(outcome==="lock_refreshed"){writePlatformBlocksLockfile(appRoot,nextLockfileRaw);let verify2=args.verify?runPlatformBlocksVerify(appRoot,templateKey):void 0;return{mode:"apply",appRoot,templateKey,status:outcome,targetRevision:manifest.platform_blocks_revision,updatedFiles:[],removedFiles:[],lockfilePath:lockRecord.path,historyUpdated:!1,verify:verify2}}let verify=args.verify?runPlatformBlocksVerify(appRoot,templateKey):void 0;return{mode:"apply",appRoot,templateKey,status:"noop",targetRevision:manifest.platform_blocks_revision,updatedFiles:[],removedFiles:[],lockfilePath:lockRecord.path,historyUpdated:!1,verify}}if(!lockRecord){let adopt=inspectPlatformBlocksAdoptability(appRoot,manifest);return{mode:"dry-run",appRoot,templateKey,targetRevision:manifest.platform_blocks_revision,managedFiles:manifest.managed_files.length,lockfilePresent:!1,adoptable:adopt.adoptable}}let diff=computePlatformBlocksDiff(appRoot,manifest,lockRecord.lockfile);return{mode:"dry-run",appRoot,templateKey,targetRevision:manifest.platform_blocks_revision,managedFiles:manifest.managed_files.length,lockfilePresent:!0,safeUpdates:diff.filter(file=>file.status==="safe_update").length,safeRemovals:diff.filter(file=>file.status==="safe_remove").length,lockRefreshes:diff.filter(file=>file.status==="lock_refresh").length,conflicts:diff.filter(file=>file.status==="conflict").length,noopFiles:diff.filter(file=>file.status==="noop").length}}function formatAppSyncPlatformBlocksResult(result){return result.mode==="rollback"?["\u5E73\u53F0\u5757\u5DF2\u56DE\u9000\u5230\u6700\u8FD1\u4E00\u6B21\u5FEB\u7167\u3002",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,result.restoredFiles.length>0?`\u6062\u590D\u6587\u4EF6:
|
|
2394
2394
|
- ${result.restoredFiles.join(`
|
|
2395
2395
|
- `)}`:"\u6062\u590D\u6587\u4EF6: -",result.removedFiles.length>0?`\u5220\u9664\u6587\u4EF6:
|
|
2396
2396
|
- ${result.removedFiles.join(`
|
|
2397
2397
|
- `)}`:"\u5220\u9664\u6587\u4EF6: -",`lockfile: ${result.lockfilePath}`,""].join(`
|
|
2398
2398
|
`):result.mode==="adopt"?[result.status==="adopted"?"\u5E73\u53F0\u5757\u5DF2\u7EB3\u7BA1\u3002":"\u5F53\u524D\u5DE5\u7A0B\u5DF2\u7EB3\u7BA1\uFF0C\u65E0\u9700\u91CD\u590D adopt\u3002",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,`\u6A21\u677F: ${result.templateKey}`,`target revision: ${result.targetRevision}`,`lockfile: ${result.lockfilePath}`,""].join(`
|
|
2399
|
+
`):result.mode==="verify"?["\u5E73\u53F0\u5757 verify \u7ED3\u679C",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,`\u6A21\u677F: ${result.templateKey}`,`target revision: ${result.targetRevision}`,formatPlatformBlocksVerifySummary(result.verify),""].join(`
|
|
2399
2400
|
`):result.mode==="apply"?[`\u5E73\u53F0\u5757 apply \u7ED3\u679C: ${result.status}`,`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,`\u6A21\u677F: ${result.templateKey}`,`target revision: ${result.targetRevision}`,result.updatedFiles.length>0?`\u66F4\u65B0\u6587\u4EF6:
|
|
2400
2401
|
- ${result.updatedFiles.join(`
|
|
2401
2402
|
- `)}`:"\u66F4\u65B0\u6587\u4EF6: -",result.removedFiles.length>0?`\u5220\u9664\u6587\u4EF6:
|
|
2402
2403
|
- ${result.removedFiles.join(`
|
|
2403
|
-
- `)}`:"\u5220\u9664\u6587\u4EF6: -",`lockfile: ${result.lockfilePath}`,`history: ${result.historyUpdated?"updated":"unchanged"}`,result.verify?formatPlatformBlocksVerifySummary(result.verify
|
|
2404
|
+
- `)}`:"\u5220\u9664\u6587\u4EF6: -",`lockfile: ${result.lockfilePath}`,`history: ${result.historyUpdated?"updated":"unchanged"}`,result.verify?formatPlatformBlocksVerifySummary(result.verify):"",""].join(`
|
|
2404
2405
|
`):["\u5E73\u53F0\u5757 dry-run \u7ED3\u679C",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,`\u6A21\u677F: ${result.templateKey}`,`target revision: ${result.targetRevision}`,`managed files: ${result.managedFiles}`,`lockfile: ${result.lockfilePresent?"present":"missing"}`,typeof result.adoptable=="boolean"?`adoptable: ${result.adoptable?"yes":"no"}`:"",typeof result.safeUpdates=="number"?`safe updates: ${result.safeUpdates}`:"",typeof result.safeRemovals=="number"?`safe removals: ${result.safeRemovals}`:"",typeof result.lockRefreshes=="number"?`lock refreshes: ${result.lockRefreshes}`:"",typeof result.conflicts=="number"?`conflicts: ${result.conflicts}`:"",typeof result.noopFiles=="number"?`noop files: ${result.noopFiles}`:"",hasLastPlatformBlocksHistory(result.appRoot)?"rollback last: available":"rollback last: unavailable",""].filter(Boolean).join(`
|
|
2405
|
-
`)}function buildTemplateFileMap(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return new Map(files.map(file=>[file.path,file.content]))}function buildHistorySnapshot(appRoot,relativePath){let absolutePath=join9(appRoot,relativePath);return
|
|
2406
|
-
`))}function parseArgs(argv){let result={workspaceDir:"",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}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJson(filePath){return JSON.parse(
|
|
2407
|
-
`,"utf8")}function assertDirectory(pathValue,label){let stats=
|
|
2406
|
+
`)}function buildTemplateFileMap(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return new Map(files.map(file=>[file.path,file.content]))}function buildHistorySnapshot(appRoot,relativePath){let absolutePath=join9(appRoot,relativePath);return existsSync14(absolutePath)?{path:relativePath,existed_before:!0,content:readFileSync14(absolutePath,"utf8")}:{path:relativePath,existed_before:!1}}function writeManagedFile(appRoot,relativePath,content){let absolutePath=join9(appRoot,relativePath);mkdirSync7(dirname9(absolutePath),{recursive:!0}),writeFileSync8(absolutePath,content,"utf8")}function removeManagedFile(appRoot,relativePath){let absolutePath=resolve8(appRoot,relativePath);existsSync14(absolutePath)&&unlinkSync(absolutePath)}function assertSafeManagedRemovalPath(appRoot,templateKey,relativePath){let normalizedRoot=resolve8(appRoot),insideAppRoot=resolve8(normalizedRoot,relativePath).startsWith(`${normalizedRoot}${sep}`);if(isAbsolute(relativePath)||!insideAppRoot||!isManagedPlatformFilePath(templateKey,relativePath))throw new Error(`\u9501\u6587\u4EF6\u5305\u542B\u975E\u6CD5\u7684\u6258\u7BA1\u5220\u9664\u8DEF\u5F84\uFF0C\u5DF2\u62D2\u7EDD apply\uFF1A${relativePath}`)}function runPlatformBlocksVerify(appRoot,templateKey){let result=verifyPlatformBlocksWorkspace({appRoot,templateKey});return assertPlatformBlocksVerified(result),result}function formatPlatformBlocksVerifySummary(result){let passed=result.checks.filter(check=>check.status==="passed").length;return`verify: ${result.status} checks=${passed}/${result.checks.length}`}import{randomUUID}from"node:crypto";import{copyFileSync,existsSync as existsSync16,lstatSync as lstatSync3,mkdirSync as mkdirSync8,readFileSync as readFileSync16,readdirSync as readdirSync5,renameSync as renameSync2,rmSync as rmSync3,writeFileSync as writeFileSync9}from"node:fs";import{basename as basename4,dirname as dirname10,isAbsolute as isAbsolute2,join as join11,relative as relative3,resolve as resolve9}from"node:path";import{existsSync as existsSync15,readFileSync as readFileSync15}from"node:fs";import{join as join10}from"node:path";var SOURCE_CONTEXT_PATH=join10(".platform","source-context.json");function readJsonIfExists(filePath){return existsSync15(filePath)?JSON.parse(readFileSync15(filePath,"utf8")):null}function detectTemplateKeyFromWorkspace(workspaceDir){let sourceContext=readJsonIfExists(join10(workspaceDir,SOURCE_CONTEXT_PATH));if(sourceContext?.template_key){let normalized=normalizeAppTemplateKey(sourceContext.template_key);if(normalized==="frontend-app-vite"||normalized==="backend-app-node")return normalized}return existsSync15(join10(workspaceDir,"src","web","app.tsx"))||existsSync15(join10(workspaceDir,"src","server","entry.ts"))?"backend-app-node":(existsSync15(join10(workspaceDir,"src","app.tsx"))||existsSync15(join10(workspaceDir,"src","main.tsx")),"frontend-app-vite")}function resolveAppImportLayout(workspaceDir){let templateKey=detectTemplateKeyFromWorkspace(workspaceDir),frontendRoot=templateKey==="backend-app-node"?"src/web":"src",importedUpstreamRoot=join10(frontendRoot,"imported-upstream").replace(/\\/g,"/"),preservedWorkspaceFiles=["app.yaml","package.json","vite.config.ts","index.html",`${frontendRoot}/main.tsx`,`${frontendRoot}/app.tsx`,`${frontendRoot}/platform`,"public/auth/index.html","public/__app"];return templateKey==="backend-app-node"&&preservedWorkspaceFiles.push("Dockerfile","src/server"),{template_key:templateKey,frontend_root:frontendRoot,imported_upstream_root:importedUpstreamRoot,preserved_workspace_files:preservedWorkspaceFiles}}var REQUIRED_WORKSPACE_FILES=["app.yaml","package.json"],FRONTEND_MERGEABLE_SOURCE_DIRS=["pages","components","styles","lib","imports"];function printAppImportMergeUsage(){process.stdout.write(["platform app import merge","","\u7528\u6CD5\uFF1A"," platform app import merge [--workspace-dir <template-workspace-dir>] [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06 `.design-import/upstream-clean-source/` \u7684\u53EF\u8FC1\u79FB\u76EE\u5F55\u5B89\u5168\u5E76\u5165\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 imported-upstream \u843D\u70B9\uFF0C\u4FDD\u7559\u6A21\u677F\u5165\u53E3\u4E0E\u5E73\u53F0\u5951\u7EA6\u6587\u4EF6\u7531\u6A21\u677F\u4E3B\u5BFC\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(`
|
|
2407
|
+
`))}function parseArgs(argv){let result={workspaceDir:"",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}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJson(filePath){return JSON.parse(readFileSync16(filePath,"utf8"))}function writeJson(filePath,payload){writeFileSync9(filePath,`${JSON.stringify(payload,null,2)}
|
|
2408
|
+
`,"utf8")}function assertDirectory(pathValue,label){let stats=lstatSync3(pathValue,{throwIfNoEntry:!1});if(stats?.isSymbolicLink())throw new Error(`${label} \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${pathValue}`);if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function isSafeSourceDirectory(pathValue,label){let stats=lstatSync3(pathValue,{throwIfNoEntry:!1});if(!stats)return!1;if(stats.isSymbolicLink())throw new Error(`${label} \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${pathValue}`);return stats.isDirectory()}function validateMergeEntry(sourcePath){let sourceStats=lstatSync3(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`merge \u6E90\u8DEF\u5F84\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`merge \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${sourcePath}`);if(sourceStats.isDirectory()){for(let entry of readdirSync5(sourcePath,{withFileTypes:!0}))validateMergeEntry(join11(sourcePath,entry.name));return}if(!sourceStats.isFile())throw new Error(`merge \u4E0D\u652F\u6301\u590D\u5236\u8BE5\u7C7B\u578B\u7684\u6587\u4EF6: ${sourcePath}`)}function copyMergeEntry(sourcePath,targetPath){let sourceStats=lstatSync3(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`merge \u6E90\u8DEF\u5F84\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`merge \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${sourcePath}`);if(sourceStats.isDirectory()){mkdirSync8(targetPath,{recursive:!0});for(let entry of readdirSync5(sourcePath,{withFileTypes:!0}))copyMergeEntry(join11(sourcePath,entry.name),join11(targetPath,entry.name));return}if(sourceStats.isFile()){copyFileSync(sourcePath,targetPath);return}throw new Error(`merge \u4E0D\u652F\u6301\u590D\u5236\u8BE5\u7C7B\u578B\u7684\u6587\u4EF6: ${sourcePath}`)}function assertSafeTargetParent(workspaceDir,targetPath){let targetParent=dirname10(targetPath),relativeParent=relative3(workspaceDir,targetParent);if(relativeParent.startsWith("..")||isAbsolute2(relativeParent))throw new Error(`merge \u76EE\u6807\u8DEF\u5F84\u8D85\u51FA\u6A21\u677F\u5DE5\u4F5C\u533A: ${targetPath}`);let currentPath=workspaceDir;for(let segment of relativeParent.split(/[\\/]+/u).filter(Boolean)){currentPath=join11(currentPath,segment);let stats=lstatSync3(currentPath,{throwIfNoEntry:!1});if(stats){if(stats.isSymbolicLink())throw new Error(`merge \u76EE\u6807\u7236\u8DEF\u5F84\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${currentPath}`);if(!stats.isDirectory())throw new Error(`merge \u76EE\u6807\u7236\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55: ${currentPath}`)}}if(lstatSync3(targetPath,{throwIfNoEntry:!1})?.isSymbolicLink())throw new Error(`merge \u76EE\u6807\u8DEF\u5F84\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${targetPath}`)}function describeError(error){return error instanceof Error?error.message:String(error)}function replaceMergeTargets(operations,deps={}){let renameEntry=deps.renameEntry??renameSync2,removeEntry=deps.removeEntry??rmSync3;try{for(let operation of operations)lstatSync3(operation.targetPath,{throwIfNoEntry:!1})&&(renameEntry(operation.targetPath,operation.backupPath),operation.backedUp=!0),operation.tempPath&&(renameEntry(operation.tempPath,operation.targetPath),operation.installed=!0)}catch(error){let rollbackFailures=[],attemptRollback=(label,action)=>{try{action()}catch(rollbackError){rollbackFailures.push(`${label}: ${describeError(rollbackError)}`)}};for(let operation of[...operations].reverse())operation.installed&&attemptRollback(`remove installed target ${operation.targetPath}`,()=>removeEntry(operation.targetPath,{recursive:!0,force:!0})),operation.backedUp&&attemptRollback(`restore backup ${operation.backupPath} -> ${operation.targetPath}`,()=>renameEntry(operation.backupPath,operation.targetPath)),operation.tempPath&&attemptRollback(`remove temporary target ${operation.tempPath}`,()=>removeEntry(operation.tempPath,{recursive:!0,force:!0}));throw rollbackFailures.length>0?new Error(`merge \u76EE\u6807\u66FF\u6362\u5931\u8D25: ${describeError(error)}; \u56DE\u6EDA\u5F02\u5E38: ${rollbackFailures.join("; ")}`,{cause:error}):error}for(let operation of operations)if(operation.backedUp)try{removeEntry(operation.backupPath,{recursive:!0,force:!0})}catch(cleanupError){process.stderr.write(`[app import merge] warning: merge \u5DF2\u5B8C\u6210\uFF0C\u4F46\u65E7\u76EE\u6807\u5907\u4EFD\u6E05\u7406\u5931\u8D25: ${operation.backupPath}: ${describeError(cleanupError)}
|
|
2409
|
+
`)}}function cleanupMergeTemps(paths,removeEntry=rmSync3){for(let pathValue of paths.filter(Boolean))try{removeEntry(pathValue,{recursive:!0,force:!0})}catch(cleanupError){process.stderr.write(`[app import merge] warning: merge \u4E34\u65F6\u76EE\u5F55\u6E05\u7406\u5931\u8D25: ${pathValue}: ${describeError(cleanupError)}
|
|
2410
|
+
`)}}function validateWorkspace(workspaceDir){assertDirectory(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES.filter(file=>!existsSync16(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,deps={}){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=existsSync16(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=isSafeSourceDirectory(upstreamSrcDir,"upstream clean-source/src"),upstreamPublicExists=isSafeSourceDirectory(upstreamPublicDir,"upstream clean-source/public");importSummary.source_detected_type==="frontend-app"&&assertDirectory(upstreamSrcDir,"upstream clean-source/src");let mergedPaths=[],skippedPaths=[],sourceMergeEntries=[];if(importSummary.source_detected_type==="frontend-app"&&upstreamSrcExists)for(let name of FRONTEND_MERGEABLE_SOURCE_DIRS){let sourcePath=join11(upstreamSrcDir,name);if(!isSafeSourceDirectory(sourcePath,`upstream clean-source/src/${name}`)){skippedPaths.push(`src/${name}`);continue}validateMergeEntry(sourcePath),sourceMergeEntries.push({name,sourcePath});let targetPath=join11(mergedTargetDir,name);mergedPaths.push({source:`src/${name}`,target:`${layout.imported_upstream_root}/${name}`})}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");if(upstreamPublicExists?(validateMergeEntry(upstreamPublicDir),mergedPaths.push({source:"public",target:"public/imported-upstream"})):skippedPaths.push("public"),!args.dryRun){assertSafeTargetParent(workspaceDir,mergedTargetDir),assertSafeTargetParent(workspaceDir,mergedPublicTargetDir),mkdirSync8(dirname10(mergedTargetDir),{recursive:!0}),mkdirSync8(dirname10(mergedPublicTargetDir),{recursive:!0});let runId=randomUUID(),mergedTempDir=join11(dirname10(mergedTargetDir),`.${basename4(mergedTargetDir)}.merge-${runId}.tmp`),publicTempDir=upstreamPublicExists?join11(dirname10(mergedPublicTargetDir),`.${basename4(mergedPublicTargetDir)}.merge-${runId}.tmp`):"",operations=[{targetPath:mergedTargetDir,tempPath:mergedTempDir,backupPath:join11(dirname10(mergedTargetDir),`.${basename4(mergedTargetDir)}.merge-${runId}.bak`),backedUp:!1,installed:!1},{targetPath:mergedPublicTargetDir,tempPath:publicTempDir,backupPath:join11(dirname10(mergedPublicTargetDir),`.${basename4(mergedPublicTargetDir)}.merge-${runId}.bak`),backedUp:!1,installed:!1}];try{mkdirSync8(mergedTempDir,{recursive:!1});for(let entry of sourceMergeEntries)copyMergeEntry(entry.sourcePath,join11(mergedTempDir,entry.name));upstreamPublicExists&©MergeEntry(upstreamPublicDir,publicTempDir),replaceMergeTargets(operations,deps)}catch(error){throw cleanupMergeTemps([mergedTempDir,publicTempDir],deps.removeEntry),error}}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
2411
|
`);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
2412
|
`)+`
|
|
2410
|
-
`)}import{createHash as createHash5}from"node:crypto";import{copyFileSync,existsSync as
|
|
2413
|
+
`)}import{createHash as createHash5}from"node:crypto";import{copyFileSync as copyFileSync2,existsSync as existsSync17,lstatSync as lstatSync4,mkdtempSync as mkdtempSync3,mkdirSync as mkdirSync9,readFileSync as readFileSync17,readdirSync as readdirSync6,rmSync as rmSync4,statSync as statSync3,unlinkSync as unlinkSync2,writeFileSync as writeFileSync10}from"node:fs";import{spawn}from"node:child_process";import{basename as basename5,dirname as dirname11,extname as extname3,join as join12,relative as relative4,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
2414
|
`)}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
|
-
`))}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/bmp":case"image/x-ms-bmp":return".bmp";case"image/x-icon":case"image/vnd.microsoft.icon":return".ico";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";case"image/bmp":case"image/x-ms-bmp":return"remote-image.bmp";case"image/x-icon":case"image/vnd.microsoft.icon":return"remote-image.ico";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)||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(`
|
|
2415
|
+
`))}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(!existsSync17(filePath))return fallbackValue;try{return JSON.parse(readFileSync17(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(dirname11(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(dirname11(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=readdirSync6(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=readdirSync6(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=readFileSync17(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:relative4(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=>relative4(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=readFileSync17(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(dirname11(sourceFilePath),match2[1]));for(let match2 of sourceText.matchAll(CSS_URL_PATTERN))found.add(resolve10(dirname11(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=readFileSync17(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(relative4(rootDir,sourceFilePath));continue}referencedAssets.set(absoluteRef,{absolute_path:absoluteRef,relative_path:relative4(rootDir,absoluteRef),referenced_by:[relative4(rootDir,sourceFilePath)]})}}for(let asset of referencedAssets.values()){let stats=statSync3(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:basename5(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:existsSync17(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=relative4(rootDir,filePath);if(!textFilePattern.test(relativePath))continue;let lines=readFileSync17(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=relative4(dirname11(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=readFileSync17(absolutePath,"utf8"),rewritten=rewritePathBaseRefsInContent(report.project_dir,absolutePath,before);rewritten.changed&&(args.dryRun||writeFileSync10(absolutePath,rewritten.content,"utf8"),rewrittenFiles.push(relative4(report.project_dir,absolutePath)),rewriteEntries.push({file:relative4(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=readdirSync6(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+=statSync3(fullPath).size)}}return visit(rootDir),total}function collectPreflightWarnings(rootDir,localAssetCandidates){let warnings=[];existsSync17(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/bmp":case"image/x-ms-bmp":return".bmp";case"image/x-icon":case"image/vnd.microsoft.icon":return".ico";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";case"image/bmp":case"image/x-ms-bmp":return"remote-image.bmp";case"image/x-icon":case"image/vnd.microsoft.icon":return"remote-image.ico";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}
|
|
2416
|
+
${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:existsSync17(headerPath)?readFileSync17(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):readFileSync17(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(basename5(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(!existsSync17(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync17(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=relative4(rootDir,resolve10(dirname11(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=relative4(rootDir,resolve10(dirname11(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=readFileSync17(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(relative4(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(!existsSync17(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=readdirSync6(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=lstatSync4(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 readdirSync6(sourcePath,{withFileTypes:!0}))copyWorkspaceEntry(join12(sourcePath,entry.name),join12(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir(dirname11(targetPath)),copyFileSync2(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=readFileSync17(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:basename5(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:basename5(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:basename5(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
2417
|
`);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
2418
|
`)}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
2419
|
`,"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)}
|
|
2417
2420
|
`,"utf8");let rewriteResult=await runRewrite(args,report,cacheContext,deps),localUploadResult=await runUploadLocal(args,report,cacheContext,deps),localUploadFullReport={...report,mode:"upload-local",uploaded_assets:[],uploaded_local_assets:localUploadResult.uploaded_local_assets,rewritten_files:[],warnings:[...localUploadResult.warnings]};writeJson2(join12(reportsDir,"local-asset-report.json"),localUploadFullReport),writeFileSync10(join12(reportsDir,"local-asset-report.md"),`${renderMarkdown(localUploadFullReport)}
|
|
2418
2421
|
`,"utf8");let localRewriteResult=await runRewriteLocal({...args,localReport:join12(reportsDir,"local-asset-report.json")},report,files,cacheContext);(cacheContext.stats.remote_reused>0||cacheContext.stats.local_reused>0)&&(cacheContext.stats.resumed_from_cache=!0);let assetInventory=buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir),importManifestWithCache=buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext),warningsPayload=buildWarningsPayload(report,importManifestWithCache,reportsDir,cacheContext);return writeJson2(join12(reportsDir,"asset-inventory.json"),assetInventory),writeJson2(join12(reportsDir,"import-manifest.json"),importManifestWithCache),writeJson2(join12(reportsDir,"warnings.json"),warningsPayload),writeJson2(join12(reportsDir,"pending-videos.json"),{pending_videos:report.pending_videos}),writeFileSync10(join12(reportsDir,"import-manifest.md"),`${renderMarkdown({...report,mode:"preprocess",uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets,rewritten_files:importManifestWithCache.rewritten_files,deleted_clean_source_assets:importManifestWithCache.deleted_clean_source_assets,warnings:importManifestWithCache.warnings})}
|
|
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=
|
|
2422
|
+
`,"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=statSync3(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
2423
|
`);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
2424
|
`)+`
|
|
2422
|
-
`)}import{
|
|
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
|
|
2424
|
-
|
|
2425
|
+
`)}import{copyFileSync as copyFileSync3,existsSync as existsSync18,lstatSync as lstatSync5,mkdirSync as mkdirSync10,mkdtempSync as mkdtempSync4,readFileSync as readFileSync18,readdirSync as readdirSync7,renameSync as renameSync3,rmSync as rmSync5,statSync as statSync4,writeFileSync as writeFileSync11}from"node:fs";import{basename as basename6,dirname as dirname12,isAbsolute as isAbsolute3,join as join13,relative as relative5,resolve as resolve11,sep as sep2}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(`
|
|
2426
|
+
`))}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 assertPathWithinTrustedRoot(trustedRoot,pathValue,label,options={}){let absoluteRoot=resolve11(trustedRoot),absolutePath=resolve11(pathValue),relativePath=relative5(absoluteRoot,absolutePath);if(relativePath===".."||relativePath.startsWith(`..${sep2}`)||isAbsolute3(relativePath))throw new Error(`${label} \u8D85\u51FA\u53D7\u4FE1\u6839\u76EE\u5F55: ${absolutePath}`);let componentPath=absoluteRoot;if(!options.trustRoot){let rootStats=lstatSync5(componentPath,{throwIfNoEntry:!1});if(!rootStats)throw new Error(`${label} \u53D7\u4FE1\u6839\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${absoluteRoot}`);if(rootStats.isSymbolicLink())throw new Error(`${label} \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${componentPath}`)}for(let component of relativePath?relativePath.split(sep2).filter(Boolean):[]){componentPath=join13(componentPath,component);let stats=lstatSync5(componentPath,{throwIfNoEntry:!1});if(!stats)break;if(stats.isSymbolicLink())throw new Error(`${label} \u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${componentPath}`)}}function validateImportEntry(sourcePath){let sourceStats=lstatSync5(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`\u5F85\u590D\u5236\u7684\u5BFC\u5165\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`\u5BFC\u5165\u4EA7\u7269\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${sourcePath}`);if(sourceStats.isDirectory()){for(let entry of readdirSync7(sourcePath,{withFileTypes:!0}))validateImportEntry(join13(sourcePath,entry.name));return}if(!sourceStats.isFile())throw new Error(`\u5BFC\u5165\u4EA7\u7269\u5305\u542B\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ${sourcePath}`)}function copyImportEntry(sourcePath,targetPath){let sourceStats=lstatSync5(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`\u5F85\u590D\u5236\u7684\u5BFC\u5165\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`\u5BFC\u5165\u4EA7\u7269\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5: ${sourcePath}`);if(sourceStats.isDirectory()){ensureDir2(targetPath);for(let entry of readdirSync7(sourcePath,{withFileTypes:!0}))copyImportEntry(join13(sourcePath,entry.name),join13(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir2(dirname12(targetPath)),copyFileSync3(sourcePath,targetPath);return}throw new Error(`\u5BFC\u5165\u4EA7\u7269\u5305\u542B\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ${sourcePath}`)}function assertReplaceableImportRoot(designImportRoot){assertPathWithinTrustedRoot(dirname12(designImportRoot),designImportRoot,"stage \u76EE\u6807\u8DEF\u5F84",{trustRoot:!0});let existingStats=lstatSync5(designImportRoot,{throwIfNoEntry:!1});if(existingStats&&!existingStats.isDirectory())throw new Error(`stage \u76EE\u6807\u5FC5\u987B\u662F\u76EE\u5F55: ${designImportRoot}`)}function replaceImportRoot(stagedRoot,designImportRoot,deps={}){let rename=deps.rename??renameSync3,remove=deps.remove??rmSync5,warn=deps.warn??(message=>process.stderr.write(`${message}
|
|
2427
|
+
`));if(assertReplaceableImportRoot(designImportRoot),!lstatSync5(designImportRoot,{throwIfNoEntry:!1})){rename(stagedRoot,designImportRoot);return}let backupRoot=`${designImportRoot}.backup-${process.pid}-${Date.now()}`;if(existsSync18(backupRoot))throw new Error(`stage \u5907\u4EFD\u76EE\u5F55\u5DF2\u5B58\u5728: ${backupRoot}`);rename(designImportRoot,backupRoot);try{rename(stagedRoot,designImportRoot)}catch(error){try{rename(backupRoot,designImportRoot)}catch(rollbackError){throw new Error(`stage \u66FF\u6362\u5931\u8D25\u4E14\u65E7\u4EA7\u7269\u56DE\u6EDA\u5931\u8D25: ${error.message}; rollback: ${rollbackError.message}`)}throw error}try{remove(backupRoot,{recursive:!0,force:!0})}catch(error){warn(`[app import stage] \u65B0\u4EA7\u7269\u5DF2\u751F\u6548\uFF0C\u4F46\u65E7\u4EA7\u7269\u5907\u4EFD\u6E05\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u624B\u52A8\u5220\u9664: ${backupRoot} (${error.message})`)}}function writeJson3(filePath,payload){writeFileSync11(filePath,`${JSON.stringify(payload,null,2)}
|
|
2428
|
+
`,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync18(filePath,"utf8"))}function assertDirectory2(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 resolveManifestPath(inputPath){let absolute=resolve11(inputPath),stats=statSync4(absolute,{throwIfNoEntry:!1});if(!stats)throw new Error(`\u672A\u627E\u5230\u9884\u5904\u7406\u8F93\u5165: ${absolute}`);if(stats.isFile()){if(basename6(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(existsSync18(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=>!existsSync18(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 readdirSync7(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=>existsSync18(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 collectReportFiles(sourceReportsDir){return REPORT_FILE_NAMES.filter(fileName=>existsSync18(join13(sourceReportsDir,fileName)))}function stageReports(sourceReportsDir,stagedReportsDir,reportFiles){for(let fileName of reportFiles){let sourcePath=join13(sourceReportsDir,fileName);copyImportEntry(sourcePath,join13(stagedReportsDir,fileName))}}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(dirname12(manifestPath)),preprocessInput=resolve11(args.preprocess),preprocessInputRoot=statSync4(preprocessInput,{throwIfNoEntry:!1})?.isFile()?dirname12(preprocessInput):preprocessInput;assertPathWithinTrustedRoot(preprocessInputRoot,manifestPath,"\u9884\u5904\u7406 manifest \u8DEF\u5F84");let copiedReports=collectReportFiles(reportsDir);for(let reportFile of copiedReports)validateImportEntry(join13(reportsDir,reportFile));let importManifest=readJson2(manifestPath),preflightReport=readJson2(join13(reportsDir,"preflight-report.json")),warningsReport=readJson2(join13(reportsDir,"warnings.json")),sourceRoot=resolve11(importManifest.source_dir),cleanSourceDir=resolve11(importManifest.clean_source_dir);assertPathWithinTrustedRoot(sourceRoot,reportsDir,"\u9884\u5904\u7406 reports \u8DEF\u5F84"),assertPathWithinTrustedRoot(sourceRoot,cleanSourceDir,"clean-source \u8DEF\u5F84"),assertDirectory2(cleanSourceDir,"clean-source"),validateImportEntry(cleanSourceDir);let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join13(workspaceDir,".design-import");assertReplaceableImportRoot(designImportRoot);let stagedCleanSourceDir=join13(designImportRoot,"upstream-clean-source"),stagedReportsDir=join13(designImportRoot,"reports"),summary=buildImportSummary(args,{workspaceDir,manifestPath,importManifest,preflightReport,warningsReport,layout,stagedCleanSourceDir,stagedReportsDir});if(!args.dryRun){let temporaryRoot=mkdtempSync4(join13(workspaceDir,".design-import.stage-"));try{let temporaryReportsDir=join13(temporaryRoot,"reports");ensureDir2(temporaryReportsDir),copyImportEntry(cleanSourceDir,join13(temporaryRoot,"upstream-clean-source")),stageReports(reportsDir,temporaryReportsDir,copiedReports),writeJson3(join13(temporaryRoot,"import-summary.json"),summary),replaceImportRoot(temporaryRoot,designImportRoot)}catch(error){throw rmSync5(temporaryRoot,{recursive:!0,force:!0}),error}}let output={...summary,copied_report_files:copiedReports};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
|
|
2425
2429
|
`);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
2430
|
`)+`
|
|
2427
|
-
`)}import{existsSync as
|
|
2428
|
-
`))}function parseArgs4(argv){let result={workspaceDir:"",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==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJsonIfExists3(filePath,fallbackValue=null){return
|
|
2431
|
+
`)}import{existsSync as existsSync19,readFileSync as readFileSync19,statSync as statSync5}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(`
|
|
2432
|
+
`))}function parseArgs4(argv){let result={workspaceDir:"",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==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJsonIfExists3(filePath,fallbackValue=null){return existsSync19(filePath)?JSON.parse(readFileSync19(filePath,"utf8")):fallbackValue}function assertDirectory3(pathValue,label){let stats=statSync5(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace3(workspaceDir){assertDirectory3(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES2.filter(file=>!existsSync19(join14(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 listMissingItems(state){let missing=[];return state.hasPreprocessManifest||missing.push(".design-import/reports/import-manifest.json"),state.hasPreflightReport||missing.push(".design-import/reports/preflight-report.json"),state.hasWarningsReport||missing.push(".design-import/reports/warnings.json"),state.hasImportSummary||missing.push(".design-import/import-summary.json"),state.mergeRequired&&(state.hasMergeSummary||missing.push(".design-import/merge-summary.json"),state.hasImportedUpstreamDir||missing.push(`${state.importedUpstreamRoot}/`)),missing}function deriveStatus(state){return state.hasImportSummary?state.mergeRequired&&(!state.hasMergeSummary||!state.hasImportedUpstreamDir)?"needs_merge":state.sourcePreprocessExecutionMode==="dry-run"?"needs_apply_preprocess":"ready_for_manual_wiring":"needs_stage"}function buildNextSteps(status,state){switch(status){case"needs_stage":return["\u5148\u6267\u884C platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>","\u786E\u8BA4 .design-import/upstream-clean-source/ \u4E0E .design-import/reports/ \u5DF2\u751F\u6210"];case"needs_merge":return["\u6267\u884C platform app import merge",`\u786E\u8BA4 ${state.importedUpstreamRoot}/ \u5DF2\u751F\u6210\uFF0C\u518D\u5F00\u59CB\u4EBA\u5DE5\u63A5\u7EBF`];case"needs_apply_preprocess":return["\u5F53\u524D\u4E0A\u6E38\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1B\u8BF7\u91CD\u65B0\u6267\u884C platform app import preprocess\uFF08\u975E --dry-run\uFF09","\u91CD\u65B0 stage / merge \u540E\u518D\u7EE7\u7EED\u6A21\u677F\u63A5\u7EBF"];default:return state.templateKey==="backend-app-node"?["\u5728 src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]:["\u5728 src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A\u54CD\u5E94\u5F0F\u4FEE\u6B63\u4E0E CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]}}async function runAppImportVerifyCli(argv){let args=parseArgs4(argv);if(args.help){printAppImportVerifyUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve12(args.workspaceDir);validateWorkspace3(workspaceDir);let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join14(workspaceDir,".design-import"),reportsDir=join14(designImportRoot,"reports"),importManifestPath=join14(reportsDir,"import-manifest.json"),preflightReportPath=join14(reportsDir,"preflight-report.json"),warningsReportPath=join14(reportsDir,"warnings.json"),importSummaryPath=join14(designImportRoot,"import-summary.json"),mergeSummaryPath=join14(designImportRoot,"merge-summary.json"),importedUpstreamDir=join14(workspaceDir,...layout.imported_upstream_root.split("/")),sourceContextPath=join14(workspaceDir,".platform","source-context.json"),importManifest=readJsonIfExists3(importManifestPath,{}),preflightReport=readJsonIfExists3(preflightReportPath,{}),warningsReport=readJsonIfExists3(warningsReportPath,{}),importSummary=readJsonIfExists3(importSummaryPath,{}),mergeSummary=readJsonIfExists3(mergeSummaryPath,{}),state={hasPreprocessManifest:existsSync19(importManifestPath),hasPreflightReport:existsSync19(preflightReportPath),hasWarningsReport:existsSync19(warningsReportPath),hasImportSummary:existsSync19(importSummaryPath),hasMergeSummary:existsSync19(mergeSummaryPath),hasImportedUpstreamDir:existsSync19(importedUpstreamDir),mergeRequired:!0,templateKey:layout.template_key,frontendRoot:layout.frontend_root,importedUpstreamRoot:layout.imported_upstream_root,hasSourceContext:existsSync19(sourceContextPath),sourcePreprocessExecutionMode:importSummary.source_preprocess_execution_mode||importManifest.execution_mode||"unknown",pendingVideosCount:Array.isArray(importManifest.pending_videos)?importManifest.pending_videos.length:Array.isArray(warningsReport.pending_videos)?warningsReport.pending_videos.length:0,pendingManualItemsCount:Array.isArray(warningsReport.pending_manual_items)?warningsReport.pending_manual_items.length:0,pathBaseViolationsRemaining:Array.isArray(preflightReport.path_base_violations_remaining)?preflightReport.path_base_violations_remaining.length:0,cleanSourcePackageBytes:importManifest.clean_source_package_bytes??null,upstreamSourcePackageBytes:preflightReport.upstream_source_package_bytes??null,mergedPathsCount:Array.isArray(mergeSummary.merged_paths)?mergeSummary.merged_paths.length:0},status=deriveStatus(state),output={tool:"app-import-verify",version:1,mode:"verify",workspace_dir:workspaceDir,design_import_dir:designImportRoot,target_template_key:layout.template_key,frontend_root:layout.frontend_root,imported_upstream_dir:layout.imported_upstream_root,status,state,missing_items:listMissingItems(state),next_steps:buildNextSteps(status,state)};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
|
|
2429
2433
|
`);return}process.stdout.write(["third-party design verify completed",`workspace_dir: ${output.workspace_dir}`,`status: ${output.status}`,`source_preprocess_execution_mode: ${output.state.sourcePreprocessExecutionMode}`,`has_import_summary: ${output.state.hasImportSummary}`,`has_merge_summary: ${output.state.hasMergeSummary}`,`has_imported_upstream_dir: ${output.state.hasImportedUpstreamDir}`,`pending_videos: ${output.state.pendingVideosCount}`,`pending_manual_items: ${output.state.pendingManualItemsCount}`,`path_base_violations_remaining: ${output.state.pathBaseViolationsRemaining}`,`missing_items: ${output.missing_items.length}`].join(`
|
|
2430
2434
|
`)+`
|
|
2431
2435
|
`)}function hasFlag(args,key){return args.options[key]===!0}function readOption(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function currentWorkspaceDir(){return process.env.PLATFORM_INVOCATION_CWD||process.env.INIT_CWD||process.cwd()}function printAppImportHelp(subcommand){switch(subcommand){case"preprocess":printAppImportPreprocessUsage();return;case"stage":printAppImportStageUsage();return;case"merge":printAppImportMergeUsage();return;case"verify":printAppImportVerifyUsage();return;default:process.stdout.write(["platform app import","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app import preprocess \u751F\u6210 clean-source \u4E0E\u9884\u5904\u7406\u62A5\u544A"," platform app import stage \u628A clean-source \u4E0E reports stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," platform app import merge \u6309\u6A21\u677F\u524D\u7AEF\u6839\u76EE\u5F55\u628A\u4E0A\u6E38\u5185\u5BB9\u5B89\u5168\u5E76\u5165 imported-upstream \u843D\u70B9"," platform app import verify \u6821\u9A8C preprocess / stage / merge \u4EA7\u7269\u72B6\u6001","","\u8BF4\u660E\uFF1A"," \u5F53\u524D P0 \u81EA\u52A8\u5316\u53EA\u8986\u76D6\u6700\u8017\u65F6\u3001\u6700\u673A\u68B0\u7684\u4E09\u6BB5\uFF1Apreprocess / stage / merge\u3002"," create / wiring / CMS-DB-Auth \u63A5\u7EBF\u4ECD\u7531\u6A21\u677F\u5DE5\u4F5C\u533A\u4E0E\u4EBA\u5DE5\u5DE5\u7A0B\u5316\u627F\u63A5\u3002",""].join(`
|
|
@@ -2455,8 +2459,8 @@ detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ${
|
|
|
2455
2459
|
detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build validate \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
|
|
2456
2460
|
`))}return error instanceof Error?error:new Error(`platform build validate \u5931\u8D25: ${appId}/${sourceVersionId}`)}function formatBuildRunError(error,appId,sourceVersionId){if(error instanceof PlatformApiError){let suffix=error.detail?`
|
|
2457
2461
|
detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
|
|
2458
|
-
`))}return error instanceof Error?error:new Error(`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`)}import{readFileSync as
|
|
2459
|
-
`))}async function runBlobUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform blob upload` \u9700\u8981 <file-path>\u3002");let filePath=resolve13(filePathArg),fileName=
|
|
2462
|
+
`))}return error instanceof Error?error:new Error(`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`)}import{readFileSync as readFileSync20}from"node:fs";import{basename as basename7,extname as extname4,resolve as resolve13}from"node:path";async function runBlobCommand(args,deps){if(hasHelpFlag4(args)||args.rest.length===0){printBlobHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runBlobUpload(args,deps);return}if(subcommand==="list"){await runBlobList(args,deps);return}if(subcommand==="get"){await runBlobGet(args,deps);return}if(subcommand==="url"){await runBlobUrl(args,deps);return}throw new Error("`platform blob` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`url`\u3002")}function isBlobHelpRequest(args){return hasHelpFlag4(args)||args.rest.length===0}function printBlobHelp(){process.stdout.write(["platform blob <command>","","Commands:"," platform blob upload <file-path> [--app <app-id>] [--content-type <mime>] [--client-request-id <id>] [--json]"," platform blob list [--app <app-id>] [--q <keyword>] [--cursor <cursor>] [--limit <n>] [--json]"," platform blob get <blob-id> [--json]"," platform blob url <blob-id> [--ttl-seconds <n>] [--json]","","Notes:"," - Object Storage \u5F53\u524D\u8D70 tenant \u63A7\u5236\u9762\uFF0C\u4E0D\u8D70 public/runtime SDK"," - `upload` \u590D\u7528\u4E09\u6B65\u5F0F\u4E0A\u4F20\uFF1Acreate session -> upload binary -> complete"," - `url` \u9ED8\u8BA4\u7B7E\u53D1 1 \u5C0F\u65F6\u4E0B\u8F7D\u94FE\u63A5",""].join(`
|
|
2463
|
+
`))}async function runBlobUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform blob upload` \u9700\u8981 <file-path>\u3002");let filePath=resolve13(filePathArg),fileName=basename7(filePath),content=new Uint8Array(readFileSync20(filePath)),contentType=readStringOption4(args,"content-type")?.trim()||inferMimeType(fileName),appId=readStringOption4(args,"app")?.trim(),clientRequestId=readStringOption4(args,"client-request-id")?.trim(),session=await deps.sdk.createTenantBlobUploadSession({original_filename:fileName,content_type:contentType,size_bytes:content.byteLength,...appId?{app_id:appId}:{},...clientRequestId?{client_request_id:clientRequestId}:{}}).catch(error=>{throw formatBlobError(error,"upload(create session)")});await deps.sdk.uploadTenantBlobBinary(session.upload_session_id,{content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}).catch(error=>{throw formatBlobError(error,"upload(content)")});let response=await deps.sdk.completeTenantBlobUpload(session.upload_session_id,{size_bytes:content.byteLength}).catch(error=>{throw formatBlobError(error,"upload(complete)")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify({upload_session:session,result:response},null,2)}
|
|
2460
2464
|
`);return}process.stdout.write(["Blob \u5DF2\u4E0A\u4F20\u3002",`tenant: ${deps.tenantId}`,`blob: ${response.blob_id}`,`upload_session: ${response.upload_session_id}`,`file: ${fileName}`,`content_type: ${contentType}`,`size: ${content.byteLength} bytes`,`source: ${appId?`app:${appId}`:"tenant_workbench"}`,""].join(`
|
|
2461
2465
|
`))}async function runBlobList(args,deps){let response=await deps.sdk.listTenantBlobs({...readStringOption4(args,"app")?{app_id:readStringOption4(args,"app")}:{},...readStringOption4(args,"q")?{q:readStringOption4(args,"q")}:{},...readStringOption4(args,"cursor")?{cursor:readStringOption4(args,"cursor")}:{},...readNumberOption2(args,"limit")!==void 0?{limit:readNumberOption2(args,"limit")}:{}}).catch(error=>{throw formatBlobError(error,"list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2462
2466
|
`);return}process.stdout.write([`tenant: ${deps.tenantId}`,`items: ${response.items.length}`,`next_cursor: ${response.next_cursor??"-"}`,...response.items.map(item=>[item.blob_id,item.original_filename,`source=${item.source_type}`,`mime=${item.content_type??"-"}`,`size=${item.size_bytes}`,`created_at=${item.created_at}`].join(" ")),""].join(`
|
|
@@ -2465,15 +2469,15 @@ detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ru
|
|
|
2465
2469
|
`))}async function runBlobUrl(args,deps){let blobId=args.rest[1];if(!blobId)throw new Error("`platform blob url` \u9700\u8981 <blob-id>\u3002");let ttlSeconds=readNumberOption2(args,"ttl-seconds")??3600,response=await deps.sdk.issueTenantBlobDownloadUrl(blobId,{ttl_seconds:ttlSeconds}).catch(error=>{throw formatBlobError(error,"url")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2466
2470
|
`);return}process.stdout.write([response.url,`expires_at: ${response.expires_at}`,`ttl_seconds: ${ttlSeconds}`,`tenant: ${deps.tenantId}`,""].join(`
|
|
2467
2471
|
`))}function readStringOption4(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption2(args,key){let value=readStringOption4(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed)||parsed<=0)throw new Error(`\`--${key}\` \u9700\u8981\u6B63\u6574\u6570\u3002`);return Math.trunc(parsed)}function hasHelpFlag4(args){return args.options.help===!0||args.options.h===!0}function inferMimeType(fileName){switch(extname4(fileName).toLowerCase()){case".json":return"application/json";case".pdf":return"application/pdf";case".txt":return"text/plain";case".csv":return"text/csv";case".html":return"text/html";case".md":return"text/markdown";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".gif":return"image/gif";case".webp":return"image/webp";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";case".zip":return"application/zip";default:return"application/octet-stream"}}function formatBlobError(error,action){return error instanceof PlatformApiError?new Error([`Blob ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
|
|
2468
|
-
`)):error instanceof Error?error:new Error(`Blob ${action} \u5931\u8D25\u3002`)}function buildTenantAssetReference2(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function resolveCmsAttachAssetField(fields,fieldName){let field=fields.find(entry=>entry.name===fieldName);if(!field)throw new Error(`Collection does not contain field \`${fieldName}\`.`);if(field.type!=="image"&&field.type!=="images")throw new Error(`\u5B57\u6BB5 \`${fieldName}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return field}function isAssetReferenceRecord(value){return typeof value=="object"&&value!==null&&typeof value.asset_id=="string"}function dedupeAssetReferences(values){let seen=new Set,deduped=[];for(let value of values)seen.has(value.asset_id)||(seen.add(value.asset_id),deduped.push(value));return deduped}function buildCmsAttachAssetPayload(args){let assetReferences=args.assets.map(buildTenantAssetReference2),nextContent=normalizeCmsContentForWrite2(args.item.content,args.fields);if(args.field.type==="image"){if(assetReferences.length!==1)throw new Error("\u5355\u56FE\u5B57\u6BB5\u4E00\u6B21\u53EA\u80FD\u6302\u8F7D\u4E00\u4E2A\u7D20\u6750\u3002");nextContent[args.field.name]=assetReferences[0]}else if(args.field.type==="images"){let currentValues=Array.isArray(args.item.content[args.field.name])?args.item.content[args.field.name].filter(isAssetReferenceRecord):[];nextContent[args.field.name]=dedupeAssetReferences(args.replace?assetReferences:[...currentValues,...assetReferences])}else throw new Error(`\u5B57\u6BB5 \`${args.field.name}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return{collection:args.item.collection,system:{...args.item.system.publish_status?{publish_status:args.item.system.publish_status}:{},...args.item.system.slug?{slug:args.item.system.slug}:{},...args.item.system.tags?{tags:[...args.item.system.tags]}:{},...Object.prototype.hasOwnProperty.call(args.item.system,"category_id")?{category_id:args.item.system.category_id??null}:{},...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:nextContent}}function normalizeCmsContentForWrite2(content,fields){let normalized={...content};for(let field of fields){let currentValue=normalized[field.name];if(field.type==="relation"){typeof currentValue=="object"&¤tValue!==null&&typeof currentValue.id=="string"&&(normalized[field.name]=currentValue.id);continue}field.type==="relations"&&Array.isArray(currentValue)&&(normalized[field.name]=currentValue.map(item=>typeof item=="string"?item:typeof item=="object"&&item!==null&&typeof item.id=="string"?item.id:null).filter(item=>typeof item=="string"))}return normalized}import{existsSync as
|
|
2472
|
+
`)):error instanceof Error?error:new Error(`Blob ${action} \u5931\u8D25\u3002`)}function buildTenantAssetReference2(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function resolveCmsAttachAssetField(fields,fieldName){let field=fields.find(entry=>entry.name===fieldName);if(!field)throw new Error(`Collection does not contain field \`${fieldName}\`.`);if(field.type!=="image"&&field.type!=="images")throw new Error(`\u5B57\u6BB5 \`${fieldName}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return field}function isAssetReferenceRecord(value){return typeof value=="object"&&value!==null&&typeof value.asset_id=="string"}function dedupeAssetReferences(values){let seen=new Set,deduped=[];for(let value of values)seen.has(value.asset_id)||(seen.add(value.asset_id),deduped.push(value));return deduped}function buildCmsAttachAssetPayload(args){let assetReferences=args.assets.map(buildTenantAssetReference2),nextContent=normalizeCmsContentForWrite2(args.item.content,args.fields);if(args.field.type==="image"){if(assetReferences.length!==1)throw new Error("\u5355\u56FE\u5B57\u6BB5\u4E00\u6B21\u53EA\u80FD\u6302\u8F7D\u4E00\u4E2A\u7D20\u6750\u3002");nextContent[args.field.name]=assetReferences[0]}else if(args.field.type==="images"){let currentValues=Array.isArray(args.item.content[args.field.name])?args.item.content[args.field.name].filter(isAssetReferenceRecord):[];nextContent[args.field.name]=dedupeAssetReferences(args.replace?assetReferences:[...currentValues,...assetReferences])}else throw new Error(`\u5B57\u6BB5 \`${args.field.name}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return{collection:args.item.collection,system:{...args.item.system.publish_status?{publish_status:args.item.system.publish_status}:{},...args.item.system.slug?{slug:args.item.system.slug}:{},...args.item.system.tags?{tags:[...args.item.system.tags]}:{},...Object.prototype.hasOwnProperty.call(args.item.system,"category_id")?{category_id:args.item.system.category_id??null}:{},...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:nextContent}}function normalizeCmsContentForWrite2(content,fields){let normalized={...content};for(let field of fields){let currentValue=normalized[field.name];if(field.type==="relation"){typeof currentValue=="object"&¤tValue!==null&&typeof currentValue.id=="string"&&(normalized[field.name]=currentValue.id);continue}field.type==="relations"&&Array.isArray(currentValue)&&(normalized[field.name]=currentValue.map(item=>typeof item=="string"?item:typeof item=="object"&&item!==null&&typeof item.id=="string"?item.id:null).filter(item=>typeof item=="string"))}return normalized}import{existsSync as existsSync20,readFileSync as readFileSync21}from"node:fs";import{createConnection}from"node:net";import{dirname as dirname13,resolve as resolve14}from"node:path";import process2 from"node:process";function isLikelyControlApiConnectionError(error){if(!(error instanceof Error))return!1;let message=error.message.toLowerCase();if(message.includes("fetch failed")||message.includes("econnrefused")||message.includes("failed to fetch"))return!0;let cause=error.cause;if(cause&&typeof cause=="object"&&"code"in cause){let code2=String(cause.code).toLowerCase();return code2==="econnrefused"||code2==="enotfound"||code2==="econnreset"}return!1}function isControlApiDiagnosticError(error){return error instanceof PlatformApiError&&(error.category==="capability_health"||error.category==="runtime_binding"||error.code==="capability_unavailable"||error.code==="runtime_binding_missing")}function formatControlApiDiagnosticErrorText(error){let lines=["control-api diagnostic error:",`- code: ${error.code??"unknown"}`,`- category: ${error.category??"unknown"}`,`- capability: ${error.capability??"unknown"}`,`- message: ${error.message}`];return error.requestId&&lines.push(`- request_id: ${error.requestId}`),error.remediation&&lines.push(`- action: ${error.remediation}`),`${lines.join(`
|
|
2469
2473
|
`)}
|
|
2470
2474
|
`}async function collectControlApiFailureDiagnostics(baseUrl=getControlApiBaseUrl(),startDir=process2.cwd()){let parsedBaseUrl=new URL(baseUrl),isLocal=isLocalControlApiUrl(parsedBaseUrl),healthz=await probeEndpoint(new URL("/healthz",parsedBaseUrl)),readyz=healthz.status==="ok"||healthz.status==="failed"?await probeEndpoint(new URL("/readyz",parsedBaseUrl)):{status:"skipped",httpStatus:null},port=Number.parseInt(parsedBaseUrl.port||(parsedBaseUrl.protocol==="https:"?"443":"80"),10),host=normalizeProbeHost(parsedBaseUrl.hostname),lock=isLocal?readControlApiDevLock(startDir,port):emptyLock(),listening=isLocal?await isPortListening(host,port):null,diagnosis=buildDiagnosis({healthz,readyz,isLocal,lockExists:lock.exists,pidAlive:lock.pid_alive,portListening:listening}),endpoints=await collectEndpointDiagnostics(baseUrl,healthz),capabilityHealth=extractCapabilityHealthDiagnostics(healthz.body);return{control_api:{base_url:baseUrl,reachable:healthz.status==="ok"||healthz.status==="failed",healthz:{status:healthz.status==="not_ready"?"failed":healthz.status,http_status:healthz.httpStatus},readyz:{status:readyz.status,http_status:readyz.httpStatus}},capability_health:capabilityHealth,endpoints,local_dev:{is_local_base_url:isLocal,lock,port:{host,port,listening}},diagnosis,recommendations:buildRecommendations(diagnosis.code,isLocal)}}function formatControlApiFailureDiagnosticsText(diagnostics){return formatControlApiDiagnosticsText(diagnostics,"control-api unreachable:")}function formatControlApiDiagnosticsText(diagnostics,title="control-api diagnostics:"){let lines=[title,`- base_url: ${diagnostics.control_api.base_url}`,`- healthz: ${diagnostics.control_api.healthz.status}${diagnostics.control_api.healthz.http_status==null?"":` (${diagnostics.control_api.healthz.http_status})`}`,`- readyz: ${diagnostics.control_api.readyz.status}${diagnostics.control_api.readyz.http_status==null?"":` (${diagnostics.control_api.readyz.http_status})`}`];return lines.push(`- endpoint control: ${diagnostics.endpoints.control.healthz.status}`,`- endpoint runtime: ${formatEndpointState(diagnostics.endpoints.runtime)}`,`- endpoint public: ${formatEndpointState(diagnostics.endpoints.public)}`),diagnostics.capability_health.degraded.length>0&&lines.push(`- degraded capabilities: ${formatHealthItems(diagnostics.capability_health.degraded)}`),diagnostics.capability_health.workers.length>0&&lines.push(`- degraded workers: ${formatHealthItems(diagnostics.capability_health.workers)}`),diagnostics.local_dev.is_local_base_url&&lines.push(`- lock: ${diagnostics.local_dev.lock.exists?`exists pid=${diagnostics.local_dev.lock.pid??"-"} alive=${diagnostics.local_dev.lock.pid_alive??"-"}`:"missing"}`,`- port: ${diagnostics.local_dev.port.listening?"listening":"not listening"}`),lines.push(`- likely_cause: ${diagnostics.diagnosis.code}`,...diagnostics.recommendations.map(item=>`- action: ${item}`)),`${lines.join(`
|
|
2471
2475
|
`)}
|
|
2472
|
-
`}async function collectEndpointDiagnostics(controlBaseUrl,controlHealthz){let endpoints=listResolvedControlApiEndpoints({...process2.env,CONTROL_API_BASE_URL:controlBaseUrl}),results=await Promise.all(endpoints.map(async endpoint=>{if(endpoint.role==="control")return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:controlHealthz.status,http_status:controlHealthz.httpStatus}};if(!endpoint.enabled||endpoint.baseUrl==null)return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!1,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,reason:endpoint.reason,healthz:{status:"skipped",http_status:null}};let healthz=await probeEndpoint(new URL("/healthz",endpoint.baseUrl));return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:healthz.status,http_status:healthz.httpStatus}}}));return{control:results.find(endpoint=>endpoint.role==="control"),runtime:results.find(endpoint=>endpoint.role==="runtime"),public:results.find(endpoint=>endpoint.role==="public")}}function formatEndpointState(endpoint){return endpoint.enabled?`${endpoint.healthz.status}${endpoint.healthz.http_status==null?"":` (${endpoint.healthz.http_status})`}`:`${endpoint.reason??"disabled"}${endpoint.base_url?` (${endpoint.base_url})`:""}`}async function probeEndpoint(url){try{let response=await fetch(url,{signal:AbortSignal.timeout(1200)}),body=await readJsonBody(response);return response.ok?{status:"ok",httpStatus:response.status,body}:{status:response.status===503?"not_ready":"failed",httpStatus:response.status,body}}catch{return{status:"unreachable",httpStatus:null}}}async function readJsonBody(response){let text2=await response.text().catch(()=>"");if(text2)try{return JSON.parse(text2)}catch{return}}function extractCapabilityHealthDiagnostics(body){if(!body||typeof body!="object")return{status:null,degraded:[],workers:[]};let record=body;return{status:typeof record.status=="string"?record.status:null,degraded:extractDegradedHealthItems(record.capabilities),workers:extractDegradedHealthItems(record.workers)}}function extractDegradedHealthItems(input){return!input||typeof input!="object"?[]:Object.entries(input).map(([key,value])=>toHealthDiagnostic(key,value)).filter(item=>!!item)}function toHealthDiagnostic(key,value){if(!value||typeof value!="object")return null;let record=value,status=typeof record.status=="string"?record.status:"unknown";return status!=="degraded"&&status!=="unavailable"?null:{key,status,summary:typeof record.summary=="string"?record.summary:"",issues:Array.isArray(record.issues)?record.issues.filter(item=>typeof item=="string"):[],...typeof record.check_level=="string"?{check_level:record.check_level}:{}}}function formatHealthItems(items){return items.map(item=>{let issueText=item.issues.length>0?` issues=${item.issues.join(",")}`:"",levelText=item.check_level?` level=${item.check_level}`:"";return`${item.key}:${item.status}${levelText}${issueText}`}).join("; ")}function isLocalControlApiUrl(url){return url.hostname==="localhost"||url.hostname==="127.0.0.1"||url.hostname==="0.0.0.0"}function normalizeProbeHost(host){return host==="0.0.0.0"?"127.0.0.1":host}function readControlApiDevLock(startDir,port){let
|
|
2473
|
-
`)}function computeChecksum2(input){return`sha256:${createHash6("sha256").update(input).digest("hex")}`}function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toStringArray(value){if(Array.isArray(value))return value.filter(item=>typeof item=="string").map(item=>item.trim()).filter(Boolean);if(typeof value=="string")return value.split(",").map(item=>item.trim()).filter(Boolean)}function toOptionalString(value){return typeof value=="string"&&value.trim().length>0?value.trim():void 0}function isMarkdownFilePath(filePath){let extension=extname5(filePath).toLowerCase();return extension===".md"||extension===".markdown"}function normalizeSourcePath(filePath){let normalized=
|
|
2476
|
+
`}async function collectEndpointDiagnostics(controlBaseUrl,controlHealthz){let endpoints=listResolvedControlApiEndpoints({...process2.env,CONTROL_API_BASE_URL:controlBaseUrl}),results=await Promise.all(endpoints.map(async endpoint=>{if(endpoint.role==="control")return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:controlHealthz.status,http_status:controlHealthz.httpStatus}};if(!endpoint.enabled||endpoint.baseUrl==null)return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!1,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,reason:endpoint.reason,healthz:{status:"skipped",http_status:null}};let healthz=await probeEndpoint(new URL("/healthz",endpoint.baseUrl));return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:healthz.status,http_status:healthz.httpStatus}}}));return{control:results.find(endpoint=>endpoint.role==="control"),runtime:results.find(endpoint=>endpoint.role==="runtime"),public:results.find(endpoint=>endpoint.role==="public")}}function formatEndpointState(endpoint){return endpoint.enabled?`${endpoint.healthz.status}${endpoint.healthz.http_status==null?"":` (${endpoint.healthz.http_status})`}`:`${endpoint.reason??"disabled"}${endpoint.base_url?` (${endpoint.base_url})`:""}`}async function probeEndpoint(url){try{let response=await fetch(url,{signal:AbortSignal.timeout(1200)}),body=await readJsonBody(response);return response.ok?{status:"ok",httpStatus:response.status,body}:{status:response.status===503?"not_ready":"failed",httpStatus:response.status,body}}catch{return{status:"unreachable",httpStatus:null}}}async function readJsonBody(response){let text2=await response.text().catch(()=>"");if(text2)try{return JSON.parse(text2)}catch{return}}function extractCapabilityHealthDiagnostics(body){if(!body||typeof body!="object")return{status:null,degraded:[],workers:[]};let record=body;return{status:typeof record.status=="string"?record.status:null,degraded:extractDegradedHealthItems(record.capabilities),workers:extractDegradedHealthItems(record.workers)}}function extractDegradedHealthItems(input){return!input||typeof input!="object"?[]:Object.entries(input).map(([key,value])=>toHealthDiagnostic(key,value)).filter(item=>!!item)}function toHealthDiagnostic(key,value){if(!value||typeof value!="object")return null;let record=value,status=typeof record.status=="string"?record.status:"unknown";return status!=="degraded"&&status!=="unavailable"?null:{key,status,summary:typeof record.summary=="string"?record.summary:"",issues:Array.isArray(record.issues)?record.issues.filter(item=>typeof item=="string"):[],...typeof record.check_level=="string"?{check_level:record.check_level}:{}}}function formatHealthItems(items){return items.map(item=>{let issueText=item.issues.length>0?` issues=${item.issues.join(",")}`:"",levelText=item.check_level?` level=${item.check_level}`:"";return`${item.key}:${item.status}${levelText}${issueText}`}).join("; ")}function isLocalControlApiUrl(url){return url.hostname==="localhost"||url.hostname==="127.0.0.1"||url.hostname==="0.0.0.0"}function normalizeProbeHost(host){return host==="0.0.0.0"?"127.0.0.1":host}function readControlApiDevLock(startDir,port){let path3=findControlApiLockPath(startDir,port);if(!path3||!existsSync20(path3))return{path:path3,exists:!1,pid:null,pid_alive:null};let raw=readFileSync21(path3,"utf8").trim(),pid=parseLockPid(raw);return{path:path3,exists:!0,pid,pid_alive:pid==null?null:isPidRunning(pid)}}function emptyLock(){return{path:null,exists:!1,pid:null,pid_alive:null}}function findControlApiLockPath(startDir,port){let current=resolve14(startDir);for(;;){let candidate=resolve14(current,"services","control-api",`.dev-server.${port}.lock`);if(existsSync20(resolve14(current,"services","control-api")))return candidate;let parent=dirname13(current);if(parent===current)return null;current=parent}}function parseLockPid(raw){if(!raw)return null;try{let parsed=JSON.parse(raw),pid=Number.parseInt(String(parsed.pid??""),10);return Number.isFinite(pid)&&pid>0?pid:null}catch{let pid=Number.parseInt(raw,10);return Number.isFinite(pid)&&pid>0?pid:null}}function isPidRunning(pid){try{return process2.kill(pid,0),!0}catch{return!1}}function isPortListening(host,port){return new Promise(resolvePromise=>{let socket=createConnection({host,port});socket.setTimeout(800),socket.once("connect",()=>{socket.destroy(),resolvePromise(!0)}),socket.once("timeout",()=>{socket.destroy(),resolvePromise(!1)}),socket.once("error",()=>{socket.destroy(),resolvePromise(!1)})})}function buildDiagnosis(args){return args.healthz.status==="ok"&&args.readyz.status==="ok"?{category:"control_api_infrastructure",code:"control_api_ok",message:"control-api is reachable and ready"}:args.readyz.status==="not_ready"?{category:"control_api_infrastructure",code:"readyz_not_ready",message:"control-api is reachable but not ready"}:args.isLocal&&args.lockExists&&args.pidAlive===!0&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_manager_alive_but_http_not_ready",message:"control-api dev manager is alive but HTTP server is not listening"}:args.isLocal&&args.lockExists&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_lock_exists_port_not_listening",message:"control-api dev lock exists but HTTP port is not listening"}:{category:"control_api_infrastructure",code:args.healthz.status==="unreachable"?"healthz_unreachable":"control_api_unreachable",message:"control-api is unreachable"}}function buildRecommendations(code2,isLocal){return code2==="control_api_ok"?[]:isLocal?code2==="dev_manager_alive_but_http_not_ready"||code2==="dev_lock_exists_port_not_listening"?["restart `pnpm --filter @platform/control-api dev`"]:["start `pnpm --filter @platform/control-api dev`"]:["check CONTROL_API_BASE_URL, network connectivity, and environment configuration"]}function normalizeCategorySlug(value){return value.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"category"}function parseCmsCategoryPath(path3){let segments=path3.split("/").map(segment=>segment.trim()).filter(Boolean);if(segments.length===0)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\u3002");return segments.map(name=>({name,slug:normalizeCategorySlug(name)}))}function findCmsCategoryPathMatch(categories,parentId,segment){return categories.find(node=>(node.parent_id??null)===parentId&&node.slug===segment.slug)??categories.find(node=>(node.parent_id??null)===parentId&&node.name===segment.name)??null}async function ensureCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,ensuredNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,ensuredNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}let created=await args.createCategory(segment,parentId);categories.push(created),finalNode=created,parentId=created.id,ensuredNodes.push({id:created.id,name:created.name,slug:created.slug,parent_id:created.parent_id??null,action:"created"})}if(!finalNode)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u89E3\u6790\u5931\u8D25\uFF0C\u672A\u751F\u6210\u76EE\u6807\u5206\u7C7B\u3002");return{categories,finalNode,ensuredNodes}}function planCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,plannedNodeCounter=0,plannedNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,plannedNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}plannedNodes.push({id:null,name:segment.name,slug:segment.slug,parent_id:parentId,action:"created"}),finalNode=null,plannedNodeCounter+=1,parentId=`__planned_category_${plannedNodeCounter}`}return{finalNode,plannedNodes}}import{createHash as createHash6}from"node:crypto";import{readdirSync as readdirSync8,statSync as statSync6}from"node:fs";import{basename as basename8,extname as extname5,join as join15,relative as relative6,resolve as resolve15}from"node:path";import YAML3 from"yaml";function normalizeLineEndings(input){return input.replace(/\r\n/g,`
|
|
2477
|
+
`)}function computeChecksum2(input){return`sha256:${createHash6("sha256").update(input).digest("hex")}`}function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toStringArray(value){if(Array.isArray(value))return value.filter(item=>typeof item=="string").map(item=>item.trim()).filter(Boolean);if(typeof value=="string")return value.split(",").map(item=>item.trim()).filter(Boolean)}function toOptionalString(value){return typeof value=="string"&&value.trim().length>0?value.trim():void 0}function isMarkdownFilePath(filePath){let extension=extname5(filePath).toLowerCase();return extension===".md"||extension===".markdown"}function normalizeSourcePath(filePath){let normalized=relative6(process.cwd(),filePath).replace(/\\/g,"/");return normalized.length>0&&!normalized.startsWith("..")?normalized:filePath.replace(/\\/g,"/")}function inferDefaultTitleFromPath(filePath){let title=basename8(filePath,extname5(filePath)).trim();return title.length>0?title:void 0}function inferDefaultSlugFromPath(filePath){let slug=basename8(filePath,extname5(filePath)).trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);return slug.length>0?slug:void 0}function normalizeItemIdSegment(value){return value.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function inferItemIdFromPrefix(prefix,filePath){let normalizedPrefix=normalizeItemIdSegment(prefix)||"cms-item",normalizedSource=filePath.replace(/\.[^.]+$/,""),pathSegment=normalizeItemIdSegment(normalizedSource),hash=createHash6("sha256").update(filePath).digest("hex").slice(0,8),readableSegment=pathSegment.length>0?pathSegment.slice(0,64):"item";return`${normalizedPrefix}-${readableSegment}-${hash}`}function collectMarkdownImportSources(targetPath,recursive){let absoluteTargetPath=resolve15(targetPath),stats=statSync6(absoluteTargetPath);if(stats.isFile()){if(!isMarkdownFilePath(absoluteTargetPath))throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\uFF1A${targetPath}`);return[{absolutePath:absoluteTargetPath,sourcePath:normalizeSourcePath(absoluteTargetPath)}]}if(!stats.isDirectory())throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\u6216\u76EE\u5F55\uFF1A${targetPath}`);let collected=[],visitDirectory=directoryPath=>{let entries=readdirSync8(directoryPath,{withFileTypes:!0}).sort((left,right)=>left.name.localeCompare(right.name));for(let entry of entries){let entryPath=join15(directoryPath,entry.name);if(entry.isDirectory()){recursive&&visitDirectory(entryPath);continue}!entry.isFile()||!isMarkdownFilePath(entryPath)||collected.push({absolutePath:entryPath,sourcePath:normalizeSourcePath(entryPath)})}};return visitDirectory(absoluteTargetPath),collected}function parseMarkdownWithFrontmatter(input){let raw=normalizeLineEndings(input),checksum3=computeChecksum2(raw);if(!raw.startsWith(`---
|
|
2474
2478
|
`))return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let closingIndex=raw.indexOf(`
|
|
2475
2479
|
---
|
|
2476
|
-
`,4);if(closingIndex===-1)return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let frontmatterSource=raw.slice(4,closingIndex),body=raw.slice(closingIndex+5).trim(),parsed=YAML3.parse(frontmatterSource);return{frontmatter:isPlainObject(parsed)?parsed:{},body,raw,checksum:checksum3}}function buildMarkdownItemPayload(args){let parsed=parseMarkdownWithFrontmatter(args.markdownContent),frontmatter={...parsed.frontmatter},title=args.title??toOptionalString(frontmatter.title)??inferDefaultTitleFromPath(args.markdownPath),slug=args.slug??toOptionalString(frontmatter.slug)??inferDefaultSlugFromPath(args.markdownPath),summary=args.summary??toOptionalString(frontmatter.summary),tags=args.tags??toStringArray(frontmatter.tags),categoryId=args.categoryId??toOptionalString(frontmatter.category_id)??null,publishStatus=args.publishStatus??toOptionalString(frontmatter.publish_status)??"draft";delete frontmatter.title,delete frontmatter.slug,delete frontmatter.summary,delete frontmatter.tags,delete frontmatter.category_id,delete frontmatter.publish_status;let content={...frontmatter,body:parsed.body};return title&&(content.title=title),summary&&(content.summary=summary),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:publishStatus,...slug?{slug}:{},...tags!==void 0?{tags}:{},...categoryId?{category_id:categoryId}:{},content_format:"markdown",source:{source_type:"markdown",source_url:null,source_path:args.markdownPath,source_raw:parsed.raw,checksum:parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"markdown-importer.v1"}},content}}function resolveMarkdownImportLookupKey(payload){return typeof payload.item_id=="string"&&payload.item_id.trim().length>0?{kind:"item_id",value:payload.item_id}:typeof payload.system.slug=="string"&&payload.system.slug.trim().length>0?{kind:"slug",value:payload.system.slug}:null}function summarizeMarkdownImportResults(items){let importedOrPlanned=0,skipped=0,draft=0,published=0,archived=0;for(let item of items){if(item.state==="skipped"?skipped+=1:importedOrPlanned+=1,item.publish_status==="draft"){draft+=1;continue}if(item.publish_status==="published"){published+=1;continue}item.publish_status==="archived"&&(archived+=1)}return{total:items.length,imported_or_planned:importedOrPlanned,skipped,draft,published,archived}}function normalizeSlugCandidate(value){return value.trim().slice(0,120)}function applySlugSuffix(baseSlug,suffix){let suffixText=`-${suffix}`;return`${baseSlug.slice(0,Math.max(1,120-suffixText.length))}${suffixText}`}async function findTenantCmsItemByExactSlug(args){let normalizedSlug=normalizeSlugCandidate(args.slug);if(!normalizedSlug)return null;let page=1,pageSize=100;for(;;){let response=await args.sdk.listTenantCmsItems({collection:args.collection,page,pageSize,query:normalizedSlug}),matched=response.items.find(item=>item.system.slug===normalizedSlug);if(matched)return matched;if(page*pageSize>=response.total||response.items.length===0)return null;page+=1}}async function resolveUniqueTenantCmsSlug(args){let normalizedSlug=args.slug?normalizeSlugCandidate(args.slug):void 0;if(!normalizedSlug)return{slug:void 0,adjusted:!1};let candidate=normalizedSlug,suffix=2;for(;;){let conflictsInBatch=args.reservedSlugs?.has(candidate)??!1,existing=conflictsInBatch?null:await findTenantCmsItemByExactSlug({sdk:args.sdk,collection:args.collection,slug:candidate});if(!conflictsInBatch&&(!existing||existing.system.id===args.itemId))return{slug:candidate,adjusted:candidate!==normalizedSlug,originalSlug:candidate!==normalizedSlug?normalizedSlug:void 0};candidate=applySlugSuffix(normalizedSlug,suffix),suffix+=1}}import{createHash as createHash7}from"node:crypto";import{URL as URL3}from"node:url";import{Readability}from"@mozilla/readability";import{JSDOM}from"jsdom";import sanitizeHtml from"sanitize-html";function computeChecksum3(input){return`sha256:${createHash7("sha256").update(input).digest("hex")}`}function stripUnsupportedJsonChars(value){return value.replace(/\u0000/g,"")}function trimToUndefined2(value){let normalized=value?.trim();return normalized||void 0}function getMetaContent(document,key){let selectors=[`meta[property="${key}"]`,`meta[name="${key}"]`,`meta[itemprop="${key}"]`];for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.getAttribute("content"));if(value)return value}}function getFirstText(document,selectors){for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.textContent);if(value)return value}}function normalizeUrl2(value,baseUrl){if(!value)return;let trimmed=value.trim();if(trimmed)try{return new URL3(trimmed,baseUrl).toString()}catch{return}}function escapeHtmlAttribute(value){return value.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function inferMimeTypeFromUrl2(value){if(!value)return;let pathname=(()=>{try{return new URL3(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg"}function extractArticleImageCandidates(document,baseUrl){let selectors=[".news-detail .image.parbase img",".news-detail .news-img img",".news-detail .richtext img","article img","main img"],results=[],seen=new Set;for(let selector of selectors)for(let image2 of document.querySelectorAll(selector)){let className=image2.getAttribute("class")?.toLowerCase()??"",parentClassName=image2.parentElement?.getAttribute("class")?.toLowerCase()??"";if(className.includes("qrcode")||className.includes("qr-code")||parentClassName.includes("qrcode")||parentClassName.includes("qr-code"))continue;let rawSrc=image2.getAttribute("src")??image2.getAttribute("data-src")??image2.getAttribute("data-original")??image2.getAttribute("data-original-src")??image2.getAttribute("data-lazy-src")??void 0,absoluteUrl=normalizeUrl2(rawSrc??void 0,baseUrl);!absoluteUrl||seen.has(absoluteUrl)||absoluteUrl.startsWith("data:")||(seen.add(absoluteUrl),results.push({url:absoluteUrl,alt:trimToUndefined2(image2.getAttribute("alt")??image2.getAttribute("title")??void 0)}))}return results}function normalizePublishedAt(value){if(!value)return;let timestamp=Date.parse(value);if(!Number.isNaN(timestamp))return new Date(timestamp).toISOString()}function inferDefaultTitleFromUrl(value){try{let parsed=new URL3(value),segment=parsed.pathname.replace(/\/+$/,"").split("/").filter(Boolean).at(-1)?.trim();return segment&&segment.length>0?decodeURIComponent(segment):parsed.hostname}catch{return}}function stripPageExtension(value){if(value)return value.replace(/\.(html?|xhtml|shtml)$/i,"")}function inferDefaultSlug(args){let candidates=[stripPageExtension(inferDefaultTitleFromUrl(args.resolvedUrl)),stripPageExtension(inferDefaultTitleFromUrl(args.requestedUrl)),args.title];for(let candidate of candidates){let normalized=candidate?.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);if(normalized)return normalized}}function absolutizeRichTextHtml(html,baseUrl){let body=new JSDOM(`<body>${html}</body>`,{url:baseUrl}).window.document.body;for(let anchor of body.querySelectorAll("a[href]")){let href=anchor.getAttribute("href"),absoluteHref=normalizeUrl2(href??void 0,baseUrl);absoluteHref&&anchor.setAttribute("href",absoluteHref)}let firstImageUrl;for(let image2 of body.querySelectorAll("img[src]")){let src=image2.getAttribute("src"),absoluteSrc=normalizeUrl2(src??void 0,baseUrl);absoluteSrc&&(image2.setAttribute("src",absoluteSrc),firstImageUrl??=absoluteSrc)}return{html:body.innerHTML,firstImageUrl}}function sanitizeArticleHtml(html){return sanitizeHtml(html,{allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","blockquote","pre","code","ul","ol","li","strong","em","b","i","del","a","img","table","thead","tbody","tr","th","td"],allowedAttributes:{a:["href","title"],img:["src","alt","title"],code:["class"],pre:["class"]},allowedSchemes:["http","https","mailto"],disallowedTagsMode:"discard"})}async function fetchUrlImportSource(url,fetchImpl=fetch){let response=await fetchImpl(url,{redirect:"follow",headers:{"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","cache-control":"no-cache",pragma:"no-cache"}});if(!response.ok)throw new Error(`URL \u6293\u53D6\u5931\u8D25\uFF1AHTTP ${response.status}`);let raw=stripUnsupportedJsonChars(await response.text());if(!trimToUndefined2(raw))throw new Error("URL \u9875\u9762\u5185\u5BB9\u4E3A\u7A7A\u3002");return{requestedUrl:url,resolvedUrl:response.url||url,raw,checksum:computeChecksum3(raw)}}function parseUrlImportHtml(args){let metadataDocument=new JSDOM(args.raw,{url:args.resolvedUrl}).window.document,articleImageCandidates=extractArticleImageCandidates(metadataDocument,args.resolvedUrl),readabilityDom=new JSDOM(args.raw,{url:args.resolvedUrl}),article=new Readability(readabilityDom.window.document).parse();if(!article?.content||!trimToUndefined2(article.textContent))throw new Error("\u672A\u80FD\u4ECE\u9875\u9762\u4E2D\u63D0\u53D6\u6B63\u6587\u3002");let{html:articleHtml,firstImageUrl}=absolutizeRichTextHtml(article.content,args.resolvedUrl),cleanedHtml=sanitizeArticleHtml(articleHtml).trim();if(!cleanedHtml)throw new Error("\u9875\u9762\u6B63\u6587\u5728\u6E05\u6D17\u540E\u4E3A\u7A7A\u3002");let leadImage=articleImageCandidates[0];if(!firstImageUrl&&leadImage){let altText=leadImage.alt?` alt="${escapeHtmlAttribute(leadImage.alt)}"`:' alt=""';cleanedHtml=`<p><img src="${escapeHtmlAttribute(leadImage.url)}"${altText} /></p>${cleanedHtml}`}let title=getMetaContent(metadataDocument,"og:title")??getMetaContent(metadataDocument,"twitter:title")??trimToUndefined2(metadataDocument.title)??trimToUndefined2(article.title)??getFirstText(metadataDocument,["h1"]),summary=getMetaContent(metadataDocument,"og:description")??getMetaContent(metadataDocument,"description")??trimToUndefined2(article.excerpt),metaCoverUrl=normalizeUrl2(getMetaContent(metadataDocument,"og:image"),args.resolvedUrl)??normalizeUrl2(getMetaContent(metadataDocument,"twitter:image"),args.resolvedUrl),bodyCoverUrl=firstImageUrl,coverUrl=leadImage?.url??bodyCoverUrl??metaCoverUrl,coverMimeType=coverUrl===metaCoverUrl?getMetaContent(metadataDocument,"og:image:type")??inferMimeTypeFromUrl2(coverUrl):inferMimeTypeFromUrl2(coverUrl)??getMetaContent(metadataDocument,"og:image:type"),sourceAuthor=getMetaContent(metadataDocument,"article:author")??getMetaContent(metadataDocument,"author")??getMetaContent(metadataDocument,"parsely-author")??getFirstText(metadataDocument,['[rel="author"]','[itemprop="author"]',".author",".ArticleAuthor-name"]),sourceSite=getMetaContent(metadataDocument,"og:site_name")??(()=>{try{return new URL3(args.resolvedUrl).hostname.replace(/^www\./,"")}catch{return}})(),sourcePublishedAt=normalizePublishedAt(getMetaContent(metadataDocument,"article:published_time")??getMetaContent(metadataDocument,"publishdate")??trimToUndefined2(metadataDocument.querySelector("time[datetime]")?.getAttribute("datetime")));return{requestedUrl:args.requestedUrl,resolvedUrl:args.resolvedUrl,title,summary,coverUrl,coverMimeType,sourceAuthor,sourceSite,sourcePublishedAt,body:cleanedHtml,contentFormat:"html",raw:args.raw,checksum:args.checksum??computeChecksum3(args.raw),warnings:[]}}function buildUrlItemPayload(args){let title=args.title??args.parsed.title??inferDefaultTitleFromUrl(args.parsed.resolvedUrl),slug=args.slug??inferDefaultSlug(args.parsed),summary=args.summary??args.parsed.summary,content={body:args.parsed.body,source_url:args.parsed.resolvedUrl};title&&(content.title=title),summary&&(content.summary=summary),args.parsed.sourceAuthor&&(content.source_author=args.parsed.sourceAuthor),args.parsed.sourceSite&&(content.source_site=args.parsed.sourceSite),args.parsed.sourcePublishedAt&&(content.source_published_at=args.parsed.sourcePublishedAt);let cover=resolveImportedUrlCover({parsed:args.parsed,cover:args.cover,title});return cover&&(content.cover=cover),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:args.publishStatus??"draft",...slug?{slug}:{},...args.tags&&args.tags.length>0?{tags:args.tags}:{},...args.categoryId!==void 0?{category_id:args.categoryId}:{},content_format:args.parsed.contentFormat,source:{source_type:"url",source_url:args.parsed.resolvedUrl,source_path:null,source_raw:args.parsed.raw,checksum:args.parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"url-importer.v1"}},content}}function resolveImportedUrlCover(args){if(args.cover?.mode==="asset"||args.cover?.mode==="remote")return args.cover.value;if(args.cover?.mode!=="none"&&args.parsed.coverUrl)return{title:args.title??"Remote cover",...args.parsed.coverMimeType?{mime_type:args.parsed.coverMimeType}:{},original_url:args.parsed.coverUrl}}async function assetizeParsedUrlImages(args){if(!args.includeBody&&!args.includeCover)return{parsed:args.parsed,cover:{mode:"none"},warnings:[]};let assetization=await assetizeExternalImagesInHtml({sdk:args.sdk,html:args.includeBody?args.parsed.body:"",baseUrl:args.parsed.resolvedUrl,coverUrl:args.includeCover?args.parsed.coverUrl:void 0,coverTitle:args.parsed.title,coverMimeType:args.parsed.coverMimeType,bodyTitle:args.parsed.title});return{parsed:{...args.parsed,body:args.includeBody?assetization.html:args.parsed.body},cover:assetization.cover,warnings:assetization.warnings}}function restrictItemPayloadToSchemaFields(payload,fields){let allowedFieldNames=new Set(fields.map(field=>field.name)),nextContent=Object.fromEntries(Object.entries(payload.content).filter(([key])=>allowedFieldNames.has(key))),droppedFields=Object.keys(payload.content).filter(key=>!allowedFieldNames.has(key));return{payload:{...payload,content:nextContent},droppedFields}}import process3 from"node:process";import{existsSync as existsSync21,readFileSync as readFileSync22}from"node:fs";import{join as join17}from"node:path";import{createHash as createHash9}from"node:crypto";import{existsSync as existsSync20,readdirSync as readdirSync8,readFileSync as readFileSync21}from"node:fs";import{basename as basename8,join as join16,relative as relative5}from"node:path";function assertNonEmptyString(value,field){if(typeof value!="string"||value.trim().length===0)throw new Error(`Auth policy field \`${field}\` must be a non-empty string.`);return value.trim()}function normalizePermissions(value){if(!Array.isArray(value))throw new Error("Auth policy field `permissions` must be an array.");let permissions=value.map((item,index)=>assertNonEmptyString(item,`permissions[${index}]`));return[...new Set(permissions)]}function normalizeAuthPolicy(input){if(typeof input!="object"||input===null)throw new Error("Auth policy must be an object.");let record=input;return{version:assertNonEmptyString(record.version,"version"),role:assertNonEmptyString(record.role,"role"),permissions:normalizePermissions(record.permissions)}}function deriveAuthResourceKey(policy,fallbackName){if(typeof policy=="object"&&policy!==null){let record=policy;if(typeof record.role=="string"&&record.role.trim().length>0)return`auth/${record.role.trim()}`;if(typeof record.policy=="string"&&record.policy.trim().length>0)return`auth/${record.policy.trim()}`}return`auth/${fallbackName}`}var DATA_FORM_ACCESS_SCOPES=["public","own","admin"];var DATA_FORM_GENERATED_SOURCE_TAG="data_form_generated";function buildSourceTagComment(source){return`-- source: ${source}`}function renderColumn(column){let parts=[`${column.column_name} ${column.data_type}`];return parts.push(column.nullable?"NULL":"NOT NULL"),column.default_sql!==void 0&&parts.push(`DEFAULT ${column.default_sql}`),parts.join(" ")}function renderCreateTable(tableName,columns){return[`CREATE TABLE IF NOT EXISTS ${tableName} (`,columns.map(column=>` ${renderColumn(column)}`).join(`,
|
|
2480
|
+
`,4);if(closingIndex===-1)return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let frontmatterSource=raw.slice(4,closingIndex),body=raw.slice(closingIndex+5).trim(),parsed=YAML3.parse(frontmatterSource);return{frontmatter:isPlainObject(parsed)?parsed:{},body,raw,checksum:checksum3}}function buildMarkdownItemPayload(args){let parsed=parseMarkdownWithFrontmatter(args.markdownContent),frontmatter={...parsed.frontmatter},title=args.title??toOptionalString(frontmatter.title)??inferDefaultTitleFromPath(args.markdownPath),slug=args.slug??toOptionalString(frontmatter.slug)??inferDefaultSlugFromPath(args.markdownPath),summary=args.summary??toOptionalString(frontmatter.summary),tags=args.tags??toStringArray(frontmatter.tags),categoryId=args.categoryId??toOptionalString(frontmatter.category_id)??null,publishStatus=args.publishStatus??toOptionalString(frontmatter.publish_status)??"draft";delete frontmatter.title,delete frontmatter.slug,delete frontmatter.summary,delete frontmatter.tags,delete frontmatter.category_id,delete frontmatter.publish_status;let content={...frontmatter,body:parsed.body};return title&&(content.title=title),summary&&(content.summary=summary),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:publishStatus,...slug?{slug}:{},...tags!==void 0?{tags}:{},...categoryId?{category_id:categoryId}:{},content_format:"markdown",source:{source_type:"markdown",source_url:null,source_path:args.markdownPath,source_raw:parsed.raw,checksum:parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"markdown-importer.v1"}},content}}function resolveMarkdownImportLookupKey(payload){return typeof payload.item_id=="string"&&payload.item_id.trim().length>0?{kind:"item_id",value:payload.item_id}:typeof payload.system.slug=="string"&&payload.system.slug.trim().length>0?{kind:"slug",value:payload.system.slug}:null}function summarizeMarkdownImportResults(items){let importedOrPlanned=0,skipped=0,draft=0,published=0,archived=0;for(let item of items){if(item.state==="skipped"?skipped+=1:importedOrPlanned+=1,item.publish_status==="draft"){draft+=1;continue}if(item.publish_status==="published"){published+=1;continue}item.publish_status==="archived"&&(archived+=1)}return{total:items.length,imported_or_planned:importedOrPlanned,skipped,draft,published,archived}}function normalizeSlugCandidate(value){return value.trim().slice(0,120)}function applySlugSuffix(baseSlug,suffix){let suffixText=`-${suffix}`;return`${baseSlug.slice(0,Math.max(1,120-suffixText.length))}${suffixText}`}async function findTenantCmsItemByExactSlug(args){let normalizedSlug=normalizeSlugCandidate(args.slug);if(!normalizedSlug)return null;let page=1,pageSize=100;for(;;){let response=await args.sdk.listTenantCmsItems({collection:args.collection,page,pageSize,query:normalizedSlug}),matched=response.items.find(item=>item.system.slug===normalizedSlug);if(matched)return matched;if(page*pageSize>=response.total||response.items.length===0)return null;page+=1}}async function resolveUniqueTenantCmsSlug(args){let normalizedSlug=args.slug?normalizeSlugCandidate(args.slug):void 0;if(!normalizedSlug)return{slug:void 0,adjusted:!1};let candidate=normalizedSlug,suffix=2;for(;;){let conflictsInBatch=args.reservedSlugs?.has(candidate)??!1,existing=conflictsInBatch?null:await findTenantCmsItemByExactSlug({sdk:args.sdk,collection:args.collection,slug:candidate});if(!conflictsInBatch&&(!existing||existing.system.id===args.itemId))return{slug:candidate,adjusted:candidate!==normalizedSlug,originalSlug:candidate!==normalizedSlug?normalizedSlug:void 0};candidate=applySlugSuffix(normalizedSlug,suffix),suffix+=1}}import{createHash as createHash7}from"node:crypto";import{URL as URL3}from"node:url";import{Readability}from"@mozilla/readability";import{JSDOM}from"jsdom";import sanitizeHtml from"sanitize-html";function computeChecksum3(input){return`sha256:${createHash7("sha256").update(input).digest("hex")}`}function stripUnsupportedJsonChars(value){return value.replace(/\u0000/g,"")}function trimToUndefined2(value){let normalized=value?.trim();return normalized||void 0}function getMetaContent(document,key){let selectors=[`meta[property="${key}"]`,`meta[name="${key}"]`,`meta[itemprop="${key}"]`];for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.getAttribute("content"));if(value)return value}}function getFirstText(document,selectors){for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.textContent);if(value)return value}}function normalizeUrl2(value,baseUrl){if(!value)return;let trimmed=value.trim();if(trimmed)try{return new URL3(trimmed,baseUrl).toString()}catch{return}}function escapeHtmlAttribute(value){return value.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function inferMimeTypeFromUrl2(value){if(!value)return;let pathname=(()=>{try{return new URL3(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg"}function extractArticleImageCandidates(document,baseUrl){let selectors=[".news-detail .image.parbase img",".news-detail .news-img img",".news-detail .richtext img","article img","main img"],results=[],seen=new Set;for(let selector of selectors)for(let image2 of document.querySelectorAll(selector)){let className=image2.getAttribute("class")?.toLowerCase()??"",parentClassName=image2.parentElement?.getAttribute("class")?.toLowerCase()??"";if(className.includes("qrcode")||className.includes("qr-code")||parentClassName.includes("qrcode")||parentClassName.includes("qr-code"))continue;let rawSrc=image2.getAttribute("src")??image2.getAttribute("data-src")??image2.getAttribute("data-original")??image2.getAttribute("data-original-src")??image2.getAttribute("data-lazy-src")??void 0,absoluteUrl=normalizeUrl2(rawSrc??void 0,baseUrl);!absoluteUrl||seen.has(absoluteUrl)||absoluteUrl.startsWith("data:")||(seen.add(absoluteUrl),results.push({url:absoluteUrl,alt:trimToUndefined2(image2.getAttribute("alt")??image2.getAttribute("title")??void 0)}))}return results}function normalizePublishedAt(value){if(!value)return;let timestamp=Date.parse(value);if(!Number.isNaN(timestamp))return new Date(timestamp).toISOString()}function inferDefaultTitleFromUrl(value){try{let parsed=new URL3(value),segment=parsed.pathname.replace(/\/+$/,"").split("/").filter(Boolean).at(-1)?.trim();return segment&&segment.length>0?decodeURIComponent(segment):parsed.hostname}catch{return}}function stripPageExtension(value){if(value)return value.replace(/\.(html?|xhtml|shtml)$/i,"")}function inferDefaultSlug(args){let candidates=[stripPageExtension(inferDefaultTitleFromUrl(args.resolvedUrl)),stripPageExtension(inferDefaultTitleFromUrl(args.requestedUrl)),args.title];for(let candidate of candidates){let normalized=candidate?.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);if(normalized)return normalized}}function absolutizeRichTextHtml(html,baseUrl){let body=new JSDOM(`<body>${html}</body>`,{url:baseUrl}).window.document.body;for(let anchor of body.querySelectorAll("a[href]")){let href=anchor.getAttribute("href"),absoluteHref=normalizeUrl2(href??void 0,baseUrl);absoluteHref&&anchor.setAttribute("href",absoluteHref)}let firstImageUrl;for(let image2 of body.querySelectorAll("img[src]")){let src=image2.getAttribute("src"),absoluteSrc=normalizeUrl2(src??void 0,baseUrl);absoluteSrc&&(image2.setAttribute("src",absoluteSrc),firstImageUrl??=absoluteSrc)}return{html:body.innerHTML,firstImageUrl}}function sanitizeArticleHtml(html){return sanitizeHtml(html,{allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","blockquote","pre","code","ul","ol","li","strong","em","b","i","del","a","img","table","thead","tbody","tr","th","td"],allowedAttributes:{a:["href","title"],img:["src","alt","title"],code:["class"],pre:["class"]},allowedSchemes:["http","https","mailto"],disallowedTagsMode:"discard"})}async function fetchUrlImportSource(url,fetchImpl=fetch){let response=await fetchImpl(url,{redirect:"follow",headers:{"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","cache-control":"no-cache",pragma:"no-cache"}});if(!response.ok)throw new Error(`URL \u6293\u53D6\u5931\u8D25\uFF1AHTTP ${response.status}`);let raw=stripUnsupportedJsonChars(await response.text());if(!trimToUndefined2(raw))throw new Error("URL \u9875\u9762\u5185\u5BB9\u4E3A\u7A7A\u3002");return{requestedUrl:url,resolvedUrl:response.url||url,raw,checksum:computeChecksum3(raw)}}function parseUrlImportHtml(args){let metadataDocument=new JSDOM(args.raw,{url:args.resolvedUrl}).window.document,articleImageCandidates=extractArticleImageCandidates(metadataDocument,args.resolvedUrl),readabilityDom=new JSDOM(args.raw,{url:args.resolvedUrl}),article=new Readability(readabilityDom.window.document).parse();if(!article?.content||!trimToUndefined2(article.textContent))throw new Error("\u672A\u80FD\u4ECE\u9875\u9762\u4E2D\u63D0\u53D6\u6B63\u6587\u3002");let{html:articleHtml,firstImageUrl}=absolutizeRichTextHtml(article.content,args.resolvedUrl),cleanedHtml=sanitizeArticleHtml(articleHtml).trim();if(!cleanedHtml)throw new Error("\u9875\u9762\u6B63\u6587\u5728\u6E05\u6D17\u540E\u4E3A\u7A7A\u3002");let leadImage=articleImageCandidates[0];if(!firstImageUrl&&leadImage){let altText=leadImage.alt?` alt="${escapeHtmlAttribute(leadImage.alt)}"`:' alt=""';cleanedHtml=`<p><img src="${escapeHtmlAttribute(leadImage.url)}"${altText} /></p>${cleanedHtml}`}let title=getMetaContent(metadataDocument,"og:title")??getMetaContent(metadataDocument,"twitter:title")??trimToUndefined2(metadataDocument.title)??trimToUndefined2(article.title)??getFirstText(metadataDocument,["h1"]),summary=getMetaContent(metadataDocument,"og:description")??getMetaContent(metadataDocument,"description")??trimToUndefined2(article.excerpt),metaCoverUrl=normalizeUrl2(getMetaContent(metadataDocument,"og:image"),args.resolvedUrl)??normalizeUrl2(getMetaContent(metadataDocument,"twitter:image"),args.resolvedUrl),bodyCoverUrl=firstImageUrl,coverUrl=leadImage?.url??bodyCoverUrl??metaCoverUrl,coverMimeType=coverUrl===metaCoverUrl?getMetaContent(metadataDocument,"og:image:type")??inferMimeTypeFromUrl2(coverUrl):inferMimeTypeFromUrl2(coverUrl)??getMetaContent(metadataDocument,"og:image:type"),sourceAuthor=getMetaContent(metadataDocument,"article:author")??getMetaContent(metadataDocument,"author")??getMetaContent(metadataDocument,"parsely-author")??getFirstText(metadataDocument,['[rel="author"]','[itemprop="author"]',".author",".ArticleAuthor-name"]),sourceSite=getMetaContent(metadataDocument,"og:site_name")??(()=>{try{return new URL3(args.resolvedUrl).hostname.replace(/^www\./,"")}catch{return}})(),sourcePublishedAt=normalizePublishedAt(getMetaContent(metadataDocument,"article:published_time")??getMetaContent(metadataDocument,"publishdate")??trimToUndefined2(metadataDocument.querySelector("time[datetime]")?.getAttribute("datetime")));return{requestedUrl:args.requestedUrl,resolvedUrl:args.resolvedUrl,title,summary,coverUrl,coverMimeType,sourceAuthor,sourceSite,sourcePublishedAt,body:cleanedHtml,contentFormat:"html",raw:args.raw,checksum:args.checksum??computeChecksum3(args.raw),warnings:[]}}function buildUrlItemPayload(args){let title=args.title??args.parsed.title??inferDefaultTitleFromUrl(args.parsed.resolvedUrl),slug=args.slug??inferDefaultSlug(args.parsed),summary=args.summary??args.parsed.summary,content={body:args.parsed.body,source_url:args.parsed.resolvedUrl};title&&(content.title=title),summary&&(content.summary=summary),args.parsed.sourceAuthor&&(content.source_author=args.parsed.sourceAuthor),args.parsed.sourceSite&&(content.source_site=args.parsed.sourceSite),args.parsed.sourcePublishedAt&&(content.source_published_at=args.parsed.sourcePublishedAt);let cover=resolveImportedUrlCover({parsed:args.parsed,cover:args.cover,title});return cover&&(content.cover=cover),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:args.publishStatus??"draft",...slug?{slug}:{},...args.tags&&args.tags.length>0?{tags:args.tags}:{},...args.categoryId!==void 0?{category_id:args.categoryId}:{},content_format:args.parsed.contentFormat,source:{source_type:"url",source_url:args.parsed.resolvedUrl,source_path:null,source_raw:args.parsed.raw,checksum:args.parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"url-importer.v1"}},content}}function resolveImportedUrlCover(args){if(args.cover?.mode==="asset"||args.cover?.mode==="remote")return args.cover.value;if(args.cover?.mode!=="none"&&args.parsed.coverUrl)return{title:args.title??"Remote cover",...args.parsed.coverMimeType?{mime_type:args.parsed.coverMimeType}:{},original_url:args.parsed.coverUrl}}async function assetizeParsedUrlImages(args){if(!args.includeBody&&!args.includeCover)return{parsed:args.parsed,cover:{mode:"none"},warnings:[]};let assetization=await assetizeExternalImagesInHtml({sdk:args.sdk,html:args.includeBody?args.parsed.body:"",baseUrl:args.parsed.resolvedUrl,coverUrl:args.includeCover?args.parsed.coverUrl:void 0,coverTitle:args.parsed.title,coverMimeType:args.parsed.coverMimeType,bodyTitle:args.parsed.title});return{parsed:{...args.parsed,body:args.includeBody?assetization.html:args.parsed.body},cover:assetization.cover,warnings:assetization.warnings}}function restrictItemPayloadToSchemaFields(payload,fields){let allowedFieldNames=new Set(fields.map(field=>field.name)),nextContent=Object.fromEntries(Object.entries(payload.content).filter(([key])=>allowedFieldNames.has(key))),droppedFields=Object.keys(payload.content).filter(key=>!allowedFieldNames.has(key));return{payload:{...payload,content:nextContent},droppedFields}}import process3 from"node:process";import{existsSync as existsSync22,readFileSync as readFileSync23}from"node:fs";import{join as join17}from"node:path";import{createHash as createHash9}from"node:crypto";import{existsSync as existsSync21,readdirSync as readdirSync9,readFileSync as readFileSync22}from"node:fs";import{basename as basename9,join as join16,relative as relative7}from"node:path";function assertNonEmptyString(value,field){if(typeof value!="string"||value.trim().length===0)throw new Error(`Auth policy field \`${field}\` must be a non-empty string.`);return value.trim()}function normalizePermissions(value){if(!Array.isArray(value))throw new Error("Auth policy field `permissions` must be an array.");let permissions=value.map((item,index)=>assertNonEmptyString(item,`permissions[${index}]`));return[...new Set(permissions)]}function normalizeAuthPolicy(input){if(typeof input!="object"||input===null)throw new Error("Auth policy must be an object.");let record=input;return{version:assertNonEmptyString(record.version,"version"),role:assertNonEmptyString(record.role,"role"),permissions:normalizePermissions(record.permissions)}}function deriveAuthResourceKey(policy,fallbackName){if(typeof policy=="object"&&policy!==null){let record=policy;if(typeof record.role=="string"&&record.role.trim().length>0)return`auth/${record.role.trim()}`;if(typeof record.policy=="string"&&record.policy.trim().length>0)return`auth/${record.policy.trim()}`}return`auth/${fallbackName}`}var DATA_FORM_ACCESS_SCOPES=["public","own","admin"];var DATA_FORM_GENERATED_SOURCE_TAG="data_form_generated";function buildSourceTagComment(source){return`-- source: ${source}`}function renderColumn(column){let parts=[`${column.column_name} ${column.data_type}`];return parts.push(column.nullable?"NULL":"NOT NULL"),column.default_sql!==void 0&&parts.push(`DEFAULT ${column.default_sql}`),parts.join(" ")}function renderCreateTable(tableName,columns){return[`CREATE TABLE IF NOT EXISTS ${tableName} (`,columns.map(column=>` ${renderColumn(column)}`).join(`,
|
|
2477
2481
|
`),");"].join(`
|
|
2478
2482
|
`)}function renderAlterColumn(tableName,columnName,nullable,defaultSql){let statements=[];return nullable!==void 0&&statements.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${nullable?"DROP NOT NULL":"SET NOT NULL"};`),defaultSql!==void 0&&statements.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} SET DEFAULT ${defaultSql};`),statements}function renderDataFormDiffSql(diff){let statements=[buildSourceTagComment(diff.source),`-- resource_key: ${diff.resource_key}`,`-- table_name: ${diff.table_name}`,""];for(let operation of diff.operations)switch(operation.kind){case"create_table":statements.push(renderCreateTable(operation.table_name,operation.columns));break;case"add_column":statements.push(`ALTER TABLE ${operation.table_name} ADD COLUMN ${renderColumn(operation.column)};`);break;case"alter_column":statements.push(...renderAlterColumn(operation.table_name,operation.column_name,operation.nullable,operation.default_sql));break}return`${statements.filter(item=>item.length>0).join(`
|
|
2479
2483
|
`)}
|
|
@@ -2500,11 +2504,11 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2500
2504
|
`)}var DATA_FORM_RUNTIME_ROUTE_PREFIX="/api/public/apps";function buildDataFormRuntimeBasePath(appId){return`${DATA_FORM_RUNTIME_ROUTE_PREFIX}/${encodeURIComponent(appId)}/data-form`}function buildDataFormRuntimeResourcesPath(appId){return`${buildDataFormRuntimeBasePath(appId)}/resources`}function buildDataFormRuntimeRecordsPath(appId,resourceKey){return`${buildDataFormRuntimeResourcesPath(appId)}/${encodeURIComponent(resourceKey)}/records`}function buildDataFormRuntimeRecordPath(appId,resourceKey,recordId){return`${buildDataFormRuntimeRecordsPath(appId,resourceKey)}/${encodeURIComponent(recordId)}`}function normalizeDataFormRuntimeListQuery(query){return{page:normalizePositiveInteger(query.page,1),page_size:normalizePositiveInteger(query.page_size,20),owner_scope:query.owner_scope==="all"?"all":"me",q:typeof query.q=="string"?query.q.trim():""}}function normalizePositiveInteger(value,fallback){if(!Number.isFinite(value)||value===void 0)return fallback;let normalized=Math.floor(value);return normalized>0?normalized:fallback}function buildWorkflowObjectModelSummary(args){let objectTypes=new Set;for(let definition of args.definitions)definition.object_type&&objectTypes.add(definition.object_type);for(let binding of args.bindings)binding.object_type&&objectTypes.add(binding.object_type);return Array.from(objectTypes).sort((left,right)=>left.localeCompare(right)).map(objectType=>{let definitions=args.definitions.filter(item=>item.object_type===objectType),bindings=args.bindings.filter(item=>item.object_type===objectType),bindingDefinitionKeys=Array.from(new Set(bindings.map(item=>item.definition_key))).sort((left,right)=>left.localeCompare(right)),definitionKeys=Array.from(new Set([...definitions.map(item=>item.definition_key),...bindingDefinitionKeys])).sort((left,right)=>left.localeCompare(right)),relatedRoleBindings=args.roleBindings.filter(item=>bindingDefinitionKeys.includes(item.definition_key));return{object_type:objectType,default_definition_key:bindingDefinitionKeys.length===1?bindingDefinitionKeys[0]:definitions.length===1?definitions[0]?.definition_key:void 0,definition_keys:definitionKeys,binding_definition_keys:bindingDefinitionKeys,role_keys:Array.from(new Set(relatedRoleBindings.map(item=>item.role_key))).sort((left,right)=>left.localeCompare(right)),principal_role_keys:Array.from(new Set(relatedRoleBindings.map(item=>item.principal_role_key))).sort((left,right)=>left.localeCompare(right)),target_scopes:Array.from(new Set(bindings.map(item=>item.target_scope))).sort((left,right)=>left.localeCompare(right))}})}async function syncLocalControlPlaneSummary(args){try{let summary=await collectControlPlaneSummary(args);updateSourceContext(args.startDir??process.cwd(),{tenant_id:args.tenantId,app_id:args.appId,control_plane:summary})}catch{}}async function collectControlPlaneSummary(args){let[authInspect,dbPreview,dbProd,workflowDefinitions,workflowBindings,deploymentTimeline,cmsCollections]=await Promise.all([args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.getTenantAppDbInstance(args.appId,"preview").catch(()=>null),args.sdk.getTenantAppDbInstance(args.appId,"prod").catch(()=>null),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[]),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listTenantCmsCollections().catch(()=>({items:[]}))]),previewDeployment=deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),previewAuth=authInspect?.environments.find(item=>item.env==="preview"),prodAuth=authInspect?.environments.find(item=>item.env==="prod"),workflowRoleBindings=(await Promise.all(workflowBindings.map(binding=>args.sdk.listWorkflowRoleBindings({target_scope:binding.target_scope,target_id:binding.target_id,definition_key:binding.definition_key}).catch(()=>[])))).flat(),cmsCollectionDetails=await Promise.all(cmsCollections.items.map(async item=>{let discovered=await args.sdk.discoverTenantCmsCollection(item.collection).catch(()=>null);return{...item,has_active_schema:!!discovered?.active_schema,has_draft_schema:!!discovered?.draft_schema,categories_count:discovered?.categories.length??0}}));return{synced_at:new Date().toISOString(),auth:{inspect_status:authInspect?.inspect_status??null,issues:authInspect?.issues??[],environments:{preview:previewAuth?{status:previewAuth.status,missing_binding_keys:previewAuth.missing_binding_keys,issues:previewAuth.issues}:void 0,prod:prodAuth?{status:prodAuth.status,missing_binding_keys:prodAuth.missing_binding_keys,issues:prodAuth.issues}:void 0}},db:{preview:dbPreview?{bound:dbPreview.bound,status:dbPreview.status,schema_name:dbPreview.schema_name??null,database_name:dbPreview.database_name??null,tables_count:typeof dbPreview.tables_count=="number"?dbPreview.tables_count:null,latest_migration:dbPreview.latest_migration?.migration_path??null}:void 0,prod:dbProd?{bound:dbProd.bound,status:dbProd.status,schema_name:dbProd.schema_name??null,database_name:dbProd.database_name??null,tables_count:typeof dbProd.tables_count=="number"?dbProd.tables_count:null,latest_migration:dbProd.latest_migration?.migration_path??null}:void 0},workflow:{active_definition_count:workflowDefinitions.length,binding_count:workflowBindings.length,definition_keys:workflowDefinitions.map(item=>item.definition_key),definitions:workflowDefinitions.map(item=>({definition_key:item.definition_key,object_type:item.object_type,status:item.status})),bindings:workflowBindings.map(item=>({definition_key:item.definition_key,target_scope:item.target_scope,target_id:item.target_id,object_type:item.object_type,status:item.status,role_binding_count:workflowRoleBindings.filter(binding=>binding.definition_key===item.definition_key&&binding.target_id===item.target_id).length})),role_bindings:workflowRoleBindings.map(item=>({definition_key:item.definition_key,role_key:item.role_key,actor_scope:item.actor_scope,principal_role_key:item.principal_role_key})),object_models:buildWorkflowObjectModelSummary({definitions:workflowDefinitions,bindings:workflowBindings,roleBindings:workflowRoleBindings})},cms:{collection_count:cmsCollectionDetails.length,collections:cmsCollectionDetails.map(item=>({collection:item.collection,label:item.label,template:item.template,collection_status:item.collection_status,item_count:item.item_count,has_draft:item.has_draft,schema_status:item.schema_status,schema_version:item.schema_version,has_active_schema:item.has_active_schema,has_draft_schema:item.has_draft_schema,categories_count:item.categories_count}))},runtime:{preview:previewDeployment?{health:previewDeployment.health??null,source_version_id:previewDeployment.source_version_id??null,preview_url:previewDeployment.preview_url??null}:void 0,prod:prodDeployment?{health:prodDeployment.health??null,source_version_id:prodDeployment.source_version_id??null}:void 0}}}import YAML4 from"yaml";var GENERATED_AUTH_MANIFEST_PATH=".platform/generated/auth/end-user-auth.json",GENERATED_AUTH_POLICY={version:"0.1.0",role:"end-user-auth",permissions:["auth:enabled"]};async function runResourcesCommand(args){let subcommand=args.rest[0];if(subcommand!=="diff"&&subcommand!=="apply"&&subcommand!=="rollback")throw new Error("`platform resources` \u4EC5\u652F\u6301 `diff`\u3001`apply` \u6216 `rollback` \u5B50\u547D\u4EE4\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption5(args,"tenant")??binding?.tenant_id,appId=readStringOption5(args,"app")??binding?.app_id,env=readStringOption5(args,"env")??binding?.env??"preview",baseSnapshotId=readStringOption5(args,"base-snapshot"),targetSnapshotId=args.rest[1]??readStringOption5(args,"target-snapshot");if(!tenantId||!appId)throw new Error("`platform resources` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(subcommand==="rollback"&&!targetSnapshotId)throw new Error("`platform resources rollback` \u9700\u8981 `<snapshot-id>` \u6216 `--target-snapshot <snapshot-id>`\u3002");let requestedBy=await resolveRequestedBy2({accessToken:selectApiToken(credentials),tenantId});subcommand!=="rollback"&&readAppManifest(appRoot);let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"}),localResources=await collectEffectiveResources(appRoot,{sdk,appId});if(subcommand==="rollback"){let approveId=readStringOption5(args,"approve-id"),rollbackPayload={operation:"rollback",tenant_id:tenantId,app_id:appId,env,target_snapshot_id:targetSnapshotId,requested_by:requestedBy,reason:readStringOption5(args,"reason")??"manual_resource_rollback",...approveId?{approve_id:approveId}:{}},result2=await withPendingFeedback(args.options.json===!0,`\u6B63\u5728\u6267\u884C\u8D44\u6E90\u56DE\u9000: ${appId}/${env} -> ${targetSnapshotId}`,"\u8D44\u6E90\u56DE\u9000\u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u5BA1\u6279\u6821\u9A8C\u3001\u5FEB\u7167\u88C5\u8F7D\u4E0E\u8D44\u6E90\u5E94\u7528...",()=>sdk.rollbackResources(rollbackPayload)).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,targetSnapshotId,approveId})});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
|
|
2501
2505
|
`);return}printRollback(result2,appRoot,env);return}let payload={operation:subcommand==="apply"?"apply":"diff",tenant_id:tenantId,app_id:appId,env,requested_by:requestedBy,...subcommand==="apply"&&args.options["dry-run"]===!0?{dry_run:!0}:{},...baseSnapshotId?{base_snapshot_id:baseSnapshotId}:{},local_resources:localResources};if(subcommand==="diff"){let result2=await sdk.diffResources(payload).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,baseSnapshotId})});if(await syncLocalControlPlaneSummary({sdk,startDir:appRoot,tenantId,appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
|
|
2502
2506
|
`);return}printDiff(result2,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"});return}let result=await withPendingFeedback(args.options.json===!0,`\u6B63\u5728\u6267\u884C\u8D44\u6E90\u53D8\u66F4: ${appId}/${env}${baseSnapshotId?`\uFF0C\u57FA\u7EBF ${baseSnapshotId}`:"\uFF0C\u57FA\u7EBF\u5C06\u81EA\u52A8\u89E3\u6790"}`,"\u8D44\u6E90 Apply \u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u57FA\u7EBF\u89E3\u6790\u3001diff\u3001\u9501\u6821\u9A8C\u4E0E\u8D44\u6E90\u7F16\u6392...",()=>sdk.applyResources(payload)).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,baseSnapshotId})});if(await syncLocalControlPlaneSummary({sdk,startDir:appRoot,tenantId,appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(result,null,2)}
|
|
2503
|
-
`);return}printApply(result,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"})}async function resolveRequestedBy2(args){return(await createControlApiSdk({accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()).subject_id}function readStringOption5(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}async function collectEffectiveResources(appRoot,options){let dbResources=collectDbResources(appRoot),authResources=collectAuthResources(appRoot);if(authResources.length>0||!options?.sdk||!options.appId)return[...dbResources,...authResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path));let bridgedAuthResources=await collectBridgedAuthResources(options.sdk,options.appId);return[...dbResources,...authResources,...bridgedAuthResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectDbResources(appRoot){let directory=join16(appRoot,"resources","db","migrations"),sqlResources=
|
|
2507
|
+
`);return}printApply(result,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"})}async function resolveRequestedBy2(args){return(await createControlApiSdk({accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()).subject_id}function readStringOption5(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}async function collectEffectiveResources(appRoot,options){let dbResources=collectDbResources(appRoot),authResources=collectAuthResources(appRoot);if(authResources.length>0||!options?.sdk||!options.appId)return[...dbResources,...authResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path));let bridgedAuthResources=await collectBridgedAuthResources(options.sdk,options.appId);return[...dbResources,...authResources,...bridgedAuthResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectDbResources(appRoot){let directory=join16(appRoot,"resources","db","migrations"),sqlResources=existsSync21(directory)?readdirSync9(directory).filter(entry=>entry.endsWith(".sql")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),sql=readFileSync22(filePath,"utf8"),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"db",resource_key:`db/${basename9(entry,".sql")}`,manifest_path:manifestPath,checksum:checksum2(sql),spec:{kind:"migration",sql,statements_count:sql.split(";").map(part=>part.trim()).filter(Boolean).length}}}):[],dataFormDirectory=join16(appRoot,"resources","data-forms"),dataFormResources=existsSync21(dataFormDirectory)?readdirSync9(dataFormDirectory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(dataFormDirectory,entry),raw=YAML4.parse(readFileSync22(filePath,"utf8")),schema=normalizeDataFormResourceSchema(raw),manifestPath=toWorkspaceRelative(appRoot,filePath),artifact=buildDataFormMigrationArtifact({schema,sourceManifestPath:manifestPath});return{resource_type:"db",resource_key:artifact.resource_key,manifest_path:manifestPath,checksum:artifact.checksum,spec:{kind:"migration",sql:artifact.sql,statements_count:artifact.statements_count,source:artifact.source,table_name:artifact.table_name,source_manifest_path:artifact.source_manifest_path,source_of_truth:"data_form_schema",data_form_resource:schema}}}):[];return[...sqlResources,...dataFormResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectAuthResources(appRoot){let directory=join16(appRoot,"resources","auth","policies");return existsSync21(directory)?readdirSync9(directory).filter(entry=>entry.endsWith(".json")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),raw=readFileSync22(filePath,"utf8"),policy=normalizeAuthPolicy(JSON.parse(raw)),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,basename9(entry,".json")),manifest_path:manifestPath,checksum:checksum2(raw),spec:{kind:"policy",policy}}}):[]}async function collectBridgedAuthResources(sdk,appId){if((await sdk.getTenantAppEndUserAuthConfig(appId)).auth_enabled!==!0)return[];let policy=normalizeAuthPolicy(GENERATED_AUTH_POLICY),raw=JSON.stringify(policy,null,2);return[{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,"end-user-auth"),manifest_path:GENERATED_AUTH_MANIFEST_PATH,checksum:checksum2(raw),spec:{kind:"policy",policy}}]}function toWorkspaceRelative(appRoot,filePath){return relative7(appRoot,filePath).split("\\").join("/")}function checksum2(value){return createHash9("sha256").update(value).digest("hex")}function printDiff(result,appRoot,options){let lines=[`\u8D44\u6E90 Diff \u5DF2\u5B8C\u6210\uFF0C\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`\u672C\u5730\u8D44\u6E90: ${result.resources.local_count}\uFF0C\u8FDC\u7AEF\u8D44\u6E90: ${result.resources.remote_count}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`];if(result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative7(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`+(change.previous_checksum?` (${change.previous_checksum} -> ${change.checksum??"deleted"})`:""))}process.stdout.write(`${lines.join(`
|
|
2504
2508
|
`)}
|
|
2505
|
-
`)}function printApply(result,appRoot,options){let lines=[`\u8D44\u6E90 Apply ${result.status==="failed"?"\u5931\u8D25":"\u5B8C\u6210"}${result.dry_run?"\uFF08dry-run\uFF09":""}`,`\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`status: ${result.status}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`,`\u6267\u884C\u8D44\u6E90: ${result.summary.applied}\uFF0CDB ${result.summary.db_resources}\uFF0CAuth ${result.summary.auth_resources}`];if(result.result_snapshot_id&&lines.push(`\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),result.db_skill&&lines.push(`DB Skill: ${result.db_skill.binding_key} -> ${result.db_skill.tenant_database_id} (schema=${result.db_skill.schema_name})`),result.auth_skill&&lines.push(`Auth Skill: ${result.auth_skill.binding_key} -> ${result.auth_skill.skill_instance_id}`),result.errors&&result.errors.length>0&&lines.push(`errors: ${result.errors.join(" | ")}`),result.status==="succeeded"&&result.result_snapshot_id&&lines.push(`\u4E0B\u4E00\u6B21 diff/apply \u53EF\u76F4\u63A5\u4F7F\u7528: --base-snapshot ${result.result_snapshot_id}`),result.status==="dry_run"&&lines.push("\u4E0B\u4E00\u6B65: \u786E\u8BA4\u7ED3\u679C\u65E0\u8BEF\u540E\uFF0C\u53BB\u6389 `--dry-run` \u518D\u6267\u884C\u4E00\u6B21 apply\u3002"),result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${
|
|
2509
|
+
`)}function printApply(result,appRoot,options){let lines=[`\u8D44\u6E90 Apply ${result.status==="failed"?"\u5931\u8D25":"\u5B8C\u6210"}${result.dry_run?"\uFF08dry-run\uFF09":""}`,`\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`status: ${result.status}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`,`\u6267\u884C\u8D44\u6E90: ${result.summary.applied}\uFF0CDB ${result.summary.db_resources}\uFF0CAuth ${result.summary.auth_resources}`];if(result.result_snapshot_id&&lines.push(`\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),result.db_skill&&lines.push(`DB Skill: ${result.db_skill.binding_key} -> ${result.db_skill.tenant_database_id} (schema=${result.db_skill.schema_name})`),result.auth_skill&&lines.push(`Auth Skill: ${result.auth_skill.binding_key} -> ${result.auth_skill.skill_instance_id}`),result.errors&&result.errors.length>0&&lines.push(`errors: ${result.errors.join(" | ")}`),result.status==="succeeded"&&result.result_snapshot_id&&lines.push(`\u4E0B\u4E00\u6B21 diff/apply \u53EF\u76F4\u63A5\u4F7F\u7528: --base-snapshot ${result.result_snapshot_id}`),result.status==="dry_run"&&lines.push("\u4E0B\u4E00\u6B65: \u786E\u8BA4\u7ED3\u679C\u65E0\u8BEF\u540E\uFF0C\u53BB\u6389 `--dry-run` \u518D\u6267\u884C\u4E00\u6B21 apply\u3002"),result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative7(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`)}process.stdout.write(`${lines.join(`
|
|
2506
2510
|
`)}
|
|
2507
|
-
`)}function printRollback(result,appRoot,env){let lines=[`\u8D44\u6E90 Rollback ${result.status==="failed"?"\u5931\u8D25":"\u5B8C\u6210"}\uFF0C\u76EE\u6807\u5FEB\u7167: ${result.target_snapshot_id}`,`status: ${result.status}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`,`\u6267\u884C\u8D44\u6E90: ${result.summary.applied}\uFF0CDB ${result.summary.db_resources}\uFF0CAuth ${result.summary.auth_resources}`];result.failure_stage&&lines.push(`failure_stage: ${result.failure_stage}`),result.result_snapshot_id&&lines.push(`\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),result.errors&&result.errors.length>0&&lines.push(`errors: ${result.errors.join(" | ")}`),result.status==="succeeded"&&result.result_snapshot_id&&(lines.push(`\u56DE\u9000\u5B8C\u6210\u540E\u65B0\u7684\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),lines.push(`\u540E\u7EED\u82E5\u7EE7\u7EED\u8D44\u6E90\u8FED\u4EE3\uFF0C\u8BF7\u6539\u7528: --base-snapshot ${result.result_snapshot_id}`));for(let hint of buildRollbackHints(result,env))lines.push(hint);if(result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${
|
|
2511
|
+
`)}function printRollback(result,appRoot,env){let lines=[`\u8D44\u6E90 Rollback ${result.status==="failed"?"\u5931\u8D25":"\u5B8C\u6210"}\uFF0C\u76EE\u6807\u5FEB\u7167: ${result.target_snapshot_id}`,`status: ${result.status}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`,`\u6267\u884C\u8D44\u6E90: ${result.summary.applied}\uFF0CDB ${result.summary.db_resources}\uFF0CAuth ${result.summary.auth_resources}`];result.failure_stage&&lines.push(`failure_stage: ${result.failure_stage}`),result.result_snapshot_id&&lines.push(`\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),result.errors&&result.errors.length>0&&lines.push(`errors: ${result.errors.join(" | ")}`),result.status==="succeeded"&&result.result_snapshot_id&&(lines.push(`\u56DE\u9000\u5B8C\u6210\u540E\u65B0\u7684\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),lines.push(`\u540E\u7EED\u82E5\u7EE7\u7EED\u8D44\u6E90\u8FED\u4EE3\uFF0C\u8BF7\u6539\u7528: --base-snapshot ${result.result_snapshot_id}`));for(let hint of buildRollbackHints(result,env))lines.push(hint);if(result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative7(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`)}process.stdout.write(`${lines.join(`
|
|
2508
2512
|
`)}
|
|
2509
2513
|
`)}function formatChangePrefix(changeType){switch(changeType){case"added":return"+";case"modified":return"~";case"deleted":return"-"}return"?"}async function withPendingFeedback(jsonOutput,startMessage,waitingMessage,action){if(jsonOutput)return action();process.stderr.write(`${startMessage}
|
|
2510
2514
|
`);let timer=setTimeout(()=>{process.stderr.write(`${waitingMessage}
|
|
@@ -2519,9 +2523,9 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2519
2523
|
`)}
|
|
2520
2524
|
`);return}if(subcommand==="query"){let sql=readStringOption6(args,"sql");if(!sql)throw new Error('`platform db query` \u9700\u8981 `--sql "SELECT ..."`\u3002');let result=await sdk.queryTenantAppDb(context.appId,{env,sql});process3.stdout.write(`${JSON.stringify(result,null,2)}
|
|
2521
2525
|
`);return}let origin=deriveWorkbenchOrigin();process3.stdout.write(["\u5DE5\u4F5C\u53F0\u6570\u636E\u9875\u5165\u53E3\uFF1A",`${origin}/#apps`,`\u5E94\u7528: ${context.appId}`,`\u73AF\u5883: ${env}`,""].join(`
|
|
2522
|
-
`))}function buildDbStatusWarnings(result,startDir){if(!result.bound)return[];let warnings=[];if((result.tables_count??0)===0){let latestMigrationPath=result.latest_migration?.migration_path,looksLikeScaffold=latestMigrationPath?isLikelyEmptyMigrationScaffold(startDir,latestMigrationPath):!1;warnings.push(looksLikeScaffold?"\u63D0\u793A: \u5F53\u524D schema \u4ECD\u4E3A 0 \u8868\uFF0C\u4E14\u672C\u5730\u6700\u65B0 migration \u770B\u8D77\u6765\u8FD8\u662F\u7A7A scaffold\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A resources/db/migrations/ \u4E0B\u7684\u793A\u4F8B\u6CE8\u91CA\u6539\u6210\u771F\u5B9E\u5EFA\u8868 SQL\uFF0C\u518D\u6267\u884C `platform db migrate`\u3002":"\u63D0\u793A: \u5F53\u524D schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u8865\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate` \u548C `platform db tables`\u3002")}return warnings}function isLikelyEmptyMigrationScaffold(startDir,migrationPath){try{let appRoot=findAppRoot(startDir),absolutePath=join17(appRoot,migrationPath);return
|
|
2526
|
+
`))}function buildDbStatusWarnings(result,startDir){if(!result.bound)return[];let warnings=[];if((result.tables_count??0)===0){let latestMigrationPath=result.latest_migration?.migration_path,looksLikeScaffold=latestMigrationPath?isLikelyEmptyMigrationScaffold(startDir,latestMigrationPath):!1;warnings.push(looksLikeScaffold?"\u63D0\u793A: \u5F53\u524D schema \u4ECD\u4E3A 0 \u8868\uFF0C\u4E14\u672C\u5730\u6700\u65B0 migration \u770B\u8D77\u6765\u8FD8\u662F\u7A7A scaffold\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A resources/db/migrations/ \u4E0B\u7684\u793A\u4F8B\u6CE8\u91CA\u6539\u6210\u771F\u5B9E\u5EFA\u8868 SQL\uFF0C\u518D\u6267\u884C `platform db migrate`\u3002":"\u63D0\u793A: \u5F53\u524D schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u8865\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate` \u548C `platform db tables`\u3002")}return warnings}function isLikelyEmptyMigrationScaffold(startDir,migrationPath){try{let appRoot=findAppRoot(startDir),absolutePath=join17(appRoot,migrationPath);return existsSync22(absolutePath)?readFileSync23(absolutePath,"utf8").split(`
|
|
2523
2527
|
`).map(line=>line.replace(/--.*$/,"").trim()).filter(Boolean).join(`
|
|
2524
|
-
`).trim().length===0:!1}catch{return!1}}function resolveDbContext(args){let storedContext=loadStoredCliContext(),binding;try{binding=readBinding(findAppRoot(process3.cwd()))?.binding}catch{binding=void 0}let tenantId=readStringOption6(args,"tenant")??binding?.tenant_id??storedContext?.selected_app_tenant_id,appId=readStringOption6(args,"app")??binding?.app_id??storedContext?.selected_app_id,env=readStringOption6(args,"env")??binding?.env??storedContext?.selected_app_env??"preview";return{tenantId,appId,env}}function readStringOption6(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function deriveWorkbenchOrigin(){let redirectUri=process3.env.AUTH_TENANT_REDIRECT_URI?.trim()||process3.env.LOGTO_TENANT_REDIRECT_URI?.trim()||"http://localhost:7102/callback";try{return new URL(redirectUri).origin}catch{return"http://localhost:7102"}}import{existsSync as
|
|
2528
|
+
`).trim().length===0:!1}catch{return!1}}function resolveDbContext(args){let storedContext=loadStoredCliContext(),binding;try{binding=readBinding(findAppRoot(process3.cwd()))?.binding}catch{binding=void 0}let tenantId=readStringOption6(args,"tenant")??binding?.tenant_id??storedContext?.selected_app_tenant_id,appId=readStringOption6(args,"app")??binding?.app_id??storedContext?.selected_app_id,env=readStringOption6(args,"env")??binding?.env??storedContext?.selected_app_env??"preview";return{tenantId,appId,env}}function readStringOption6(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function deriveWorkbenchOrigin(){let redirectUri=process3.env.AUTH_TENANT_REDIRECT_URI?.trim()||process3.env.LOGTO_TENANT_REDIRECT_URI?.trim()||"http://localhost:7102/callback";try{return new URL(redirectUri).origin}catch{return"http://localhost:7102"}}import{existsSync as existsSync23,readdirSync as readdirSync10,readFileSync as readFileSync24}from"node:fs";import{join as join18}from"node:path";import YAML5 from"yaml";async function runDataFormCommand(args){let subcommand=args.rest[0]??"help";if(args.options.help===!0||args.options.h===!0||subcommand==="help"){printDataFormHelp(args.rest[1]);return}if(!["validate","compile","inspect","apply","records"].includes(subcommand))throw new Error(`\u672A\u77E5 data-form \u5B50\u547D\u4EE4: ${subcommand}`);if(subcommand==="records"){await runDataFormRecordsCommand(args);return}if(subcommand==="apply"){if(readStringOption7(args.options,"resource"))throw new Error("`platform data-form apply` \u4E0D\u652F\u6301 `--resource`\u3002\u8BF7\u5148\u7528 validate/compile/inspect \u68C0\u67E5\u5355\u4E2A\u8D44\u6E90\uFF0C\u518D\u6267\u884C\u6574\u5E94\u7528\u8D44\u6E90 apply\u3002");await runResourcesCommand({rest:["apply"],options:args.options});return}let appRoot=findAppRoot(process.cwd()),loaded=loadDataFormSchemas(appRoot,readStringOption7(args.options,"resource"));if(loaded.length===0)throw new Error("\u672A\u627E\u5230 `resources/data-forms/*.yaml`\u3002");if(subcommand==="validate"){let result=loaded.map(item=>({manifest_path:item.manifestPath,resource_key:item.schema.resource_key,field_count:item.schema.fields.length,valid:validateDataFormResourceSchema(item.schema)}));if(args.options.json===!0){process.stdout.write(`${JSON.stringify({items:result},null,2)}
|
|
2525
2529
|
`);return}process.stdout.write(`${result.map(item=>`OK ${item.resource_key} ${item.manifest_path} fields=${item.field_count}`).join(`
|
|
2526
2530
|
`)}
|
|
2527
2531
|
`);return}if(subcommand==="inspect"){let inspected=loaded.map(item=>({manifest_path:item.manifestPath,schema:item.schema,artifact:buildDataFormMigrationArtifact({schema:item.schema,sourceManifestPath:item.manifestPath})}));if(args.options.json===!0){process.stdout.write(`${JSON.stringify({items:inspected.map(item=>({manifest_path:item.manifest_path,schema:item.schema,generated_migration:{source:item.artifact.source,source_manifest_path:item.artifact.source_manifest_path,resource_key:item.artifact.resource_key,table_name:item.artifact.table_name,checksum:item.artifact.checksum,statements_count:item.artifact.statements_count,sql:item.artifact.sql}}))},null,2)}
|
|
@@ -2541,7 +2545,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2541
2545
|
`))])}async function requestDataFormRuntime(fetchImpl,url,headers){let response=await fetchImpl(url,{method:"GET",headers}),text2=await response.text(),payload=text2.trim()?JSON.parse(text2):{};if(!response.ok){let error=payload.error;throw new Error(error?.message??`Request failed: ${response.status}`)}return payload}function writeJsonOrText2(json,payload,lines){if(json){process.stdout.write(`${JSON.stringify(payload,null,2)}
|
|
2542
2546
|
`);return}process.stdout.write(`${lines.join(`
|
|
2543
2547
|
`)}
|
|
2544
|
-
`)}function loadDataFormSchemas(appRoot,resourceKey){let directory=join18(appRoot,"resources","data-forms");if(!
|
|
2548
|
+
`)}function loadDataFormSchemas(appRoot,resourceKey){let directory=join18(appRoot,"resources","data-forms");if(!existsSync23(directory))return[];let targetResourceKey=typeof resourceKey=="string"?resourceKey.trim():"";return readdirSync10(directory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let manifestPath=join18("resources","data-forms",entry),raw=YAML5.parse(readFileSync24(join18(directory,entry),"utf8")),schema=normalizeDataFormResourceSchema(raw);return validateDataFormResourceSchema(schema),{manifestPath,schema}}).filter(item=>!targetResourceKey||item.schema.resource_key===targetResourceKey)}function serializeCompileResult(item){return{manifest_path:item.manifest_path,resource_key:item.resource_key,table_name:item.result.table.table_name,operations:item.result.diff.operations,sql:item.result.sql}}function readStringOption7(options,key){let value=options[key];return typeof value=="string"?value:void 0}function parseOptionalInteger(value){if(!value)return;let parsed=Number.parseInt(value,10);return Number.isFinite(parsed)?parsed:void 0}function normalizeOwnerScope(value){return value==="all"?"all":value==="me"?"me":void 0}function normalizeRuntimeEnv(value){return value==="prod"?"prod":"preview"}function printDataFormHelp(subcommand){if(subcommand==="validate"){process.stdout.write(["platform data-form validate",""," platform data-form validate [--resource <resource-key>] [--json]",""," \u6821\u9A8C\u5F53\u524D\u5E94\u7528\u76EE\u5F55\u4E0B\u7684 `resources/data-forms/*.yaml`\u3002"].join(`
|
|
2545
2549
|
`)+`
|
|
2546
2550
|
`);return}if(subcommand==="compile"){process.stdout.write(["platform data-form compile",""," platform data-form compile [--resource <resource-key>] [--json]",""," \u628A `Data Form schema` \u7F16\u8BD1\u6210\u9996\u671F DB migration SQL \u4EA7\u7269\u9884\u89C8\u3002"].join(`
|
|
2547
2551
|
`)+`
|
|
@@ -2553,8 +2557,8 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2553
2557
|
`)+`
|
|
2554
2558
|
`);return}process.stdout.write(["platform data-form",""," platform data-form validate [--resource <resource-key>] [--json]"," platform data-form compile [--resource <resource-key>] [--json]"," platform data-form inspect [--resource <resource-key>] [--json]"," platform data-form apply [--env preview|prod] [--dry-run] [--json]"," platform data-form records --resource <resource-key> [--record <record-id>] [--env preview|prod] [--page <n>] [--page-size <n>] [--owner-scope me|all] [--q <keyword>] [--json]",""," \u672C\u5730\u6821\u9A8C\u3001\u67E5\u770B\u751F\u6210 migration\u3001\u901A\u8FC7\u73B0\u6709\u8D44\u6E90\u4E3B\u94FE\u5E94\u7528 `resources/data-forms/*.yaml`\uFF0C\u5E76\u901A\u8FC7 runtime API \u67E5\u8BE2\u8BB0\u5F55\u3002"].join(`
|
|
2555
2559
|
`)+`
|
|
2556
|
-
`)}import{spawn as spawn2}from"node:child_process";import net from"node:net";import WebSocket from"ws";async function prepareLocalDevDatabaseBindings(runtimeBindings,options={}){let databaseUrl=runtimeBindings.DATABASE_URL?.trim();if(!databaseUrl)return{bindings:runtimeBindings,warnings:[],cleanup:null};let proxyTransport=runtimeBindings.DATABASE_PROXY_TRANSPORT?.trim(),proxyWsUrl=runtimeBindings.DATABASE_PROXY_WS_URL?.trim();if(proxyTransport==="ws_tunnel"&&proxyWsUrl)return await prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,proxyWsUrl);if(!shouldTunnelDatabaseUrl(databaseUrl))return{bindings:runtimeBindings,warnings:[],cleanup:null};if(!((process.env.PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL||"").trim()==="1"))throw new Error(["dev_runtime_binding_not_available","\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\uFF0C`platform dev --remote-bindings` \u5DF2\u62D2\u7EDD\u4F7F\u7528\u79C1\u7F51\u6570\u636E\u5E93\u5730\u5740\u3002","\u8BF7\u5148\u6539\u7528 `platform preview` \u9A8C\u8BC1\u771F\u5B9E\u5199\u5E93\u94FE\u8DEF\uFF1B\u5982\u4E3A\u5E73\u53F0\u7BA1\u7406\u5458\u5185\u90E8\u6392\u969C\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL=1` \u540E\u91CD\u8BD5\u3002"].join(" "));let sshHost=(options.sshHost||process.env.TEST_ENV_SSH_HOST||"").trim();if(!sshHost)throw new Error("\u5F53\u524D\u5DF2\u663E\u5F0F\u542F\u7528\u5185\u90E8 SSH \u515C\u5E95\uFF0C\u4F46\u672A\u914D\u7F6E TEST_ENV_SSH_HOST\uFF0C\u65E0\u6CD5\u5EFA\u7ACB\u672C\u5730 SSH \u96A7\u9053\u3002");let parsed=new URL(databaseUrl),remoteHost=parsed.hostname,remotePort=Number(parsed.port||"5432"),localPort=await allocateLocalPort(),child=spawn2("ssh",["-o","ExitOnForwardFailure=yes","-o","BatchMode=yes","-o","ConnectTimeout=8","-N","-L",`127.0.0.1:${localPort}:${remoteHost}:${remotePort}`,sshHost],{stdio:"ignore"});try{await waitForTunnelReady(localPort,child)}catch(error){throw child.kill("SIGTERM"),await waitForChildExit(child),error}let localUrl=rewriteDatabaseUrlForLocalPort(databaseUrl,localPort);return{bindings:{...runtimeBindings,DATABASE_URL:localUrl},warnings:[`\u68C0\u6D4B\u5230\u79C1\u7F51 DB host\uFF08${remoteHost}:${remotePort}\uFF09\uFF0C\u5DF2\u901A\u8FC7 SSH \u96A7\u9053\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{child.kill("SIGTERM"),await waitForChildExit(child)}}}async function prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,wsUrl){let localPort=await allocateLocalPort(),sockets=new Set,bridges=new Set,server=net.createServer(clientSocket=>{clientSocket.setNoDelay(!0),sockets.add(clientSocket);let bridge=new WebSocket(wsUrl);bridges.add(bridge);let closeBoth=()=>{sockets.delete(clientSocket),bridges.delete(bridge),clientSocket.destroyed||clientSocket.destroy(),(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close()};bridge.on("open",()=>{clientSocket.on("data",chunk=>{bridge.readyState===WebSocket.OPEN&&bridge.send(chunk)}),clientSocket.resume()}),bridge.on("message",payload=>{clientSocket.write(Buffer.isBuffer(payload)?payload:Buffer.from(payload))}),bridge.on("close",closeBoth),bridge.on("error",closeBoth),clientSocket.on("close",closeBoth),clientSocket.on("error",closeBoth),clientSocket.pause()});return await listenLocalServer(server,localPort),{bindings:{...runtimeBindings,DATABASE_URL:rewriteDatabaseUrlForLocalPort(databaseUrl,localPort)},warnings:[`\u68C0\u6D4B\u5230\u6B63\u5F0F dev proxy WebSocket \u6570\u636E\u9762\uFF0C\u5DF2\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{for(let socket of sockets)socket.destroyed||socket.destroy();for(let bridge of bridges)(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close();await closeServer(server)}}}function shouldTunnelDatabaseUrl(databaseUrl){try{let url=new URL(databaseUrl);return shouldTunnelHostname(url.hostname)}catch{return!1}}function rewriteDatabaseUrlForLocalPort(databaseUrl,localPort){let url=new URL(databaseUrl);return url.hostname="127.0.0.1",url.port=String(localPort),url.toString()}function shouldTunnelHostname(hostname){let value=hostname.trim().toLowerCase();return!value||["localhost","127.0.0.1"].includes(value)?!1:!!(["host.docker.internal","host.containers.internal"].includes(value)||isPrivateIpv4(value))}function isPrivateIpv4(hostname){let parts=hostname.split(".");if(parts.length!==4||parts.some(part=>!/^\d+$/.test(part)))return!1;let[a,b]=parts.map(part=>Number(part));return a===10||a===192&&b===168||a===172&&b>=16&&b<=31}async function allocateLocalPort(){return await new Promise((resolve19,reject)=>{let server=net.createServer();server.once("error",reject),server.listen(0,"127.0.0.1",()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u5206\u914D\u672C\u5730\u7AEF\u53E3\u3002")));return}let port=address.port;server.close(error=>{if(error){reject(error);return}resolve19(port)})})})}async function listenLocalServer(server,port){await new Promise((resolve19,reject)=>{server.once("error",reject),server.listen(port,"127.0.0.1",()=>{server.off("error",reject),resolve19()})})}async function closeServer(server){await new Promise(resolve19=>{server.close(()=>resolve19())})}async function waitForTunnelReady(localPort,child){let startedAt=Date.now();for(;Date.now()-startedAt<1e4;){if(child.exitCode!==null)throw new Error(`SSH \u96A7\u9053\u8FDB\u7A0B\u63D0\u524D\u9000\u51FA\uFF08code=${child.exitCode}\uFF09\u3002`);if(await canConnect("127.0.0.1",localPort))return;await sleep3(200)}throw new Error(`SSH \u96A7\u9053\u672A\u5728\u9884\u671F\u65F6\u95F4\u5185\u5C31\u7EEA\uFF1A127.0.0.1:${localPort}`)}async function canConnect(host,port){return await new Promise(resolve19=>{let socket=net.createConnection({host,port}),done=value=>{socket.removeAllListeners(),socket.destroyed||socket.destroy(),resolve19(value)};socket.once("connect",()=>done(!0)),socket.once("error",()=>done(!1)),socket.setTimeout(500,()=>done(!1))})}async function waitForChildExit(child){await new Promise(resolve19=>{if(child.exitCode!==null){resolve19();return}child.once("exit",()=>resolve19()),setTimeout(()=>resolve19(),1e3)})}function sleep3(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}import{spawn as spawn3}from"node:child_process";import{watch}from"node:fs";import process4 from"node:process";var IGNORED_PATH_SEGMENTS=new Set(["node_modules",".git",".platform","dist",".next"]),RESTART_DEBOUNCE_MS=250;async function runDevSupervisor(options){let platform=options.platform??process4.platform,spawnImpl=options.spawnImpl??spawn3,terminateProcessTreeImpl=options.terminateProcessTreeImpl??terminateProcessTree,signalSource=options.signalSource??process4,restartDebounceMs=options.restartDebounceMs??RESTART_DEBOUNCE_MS,expectedStops=new WeakSet,state={child:null,watcher:null,restartTimer:null,stopping:!1,restarting:!1,restartPending:!1,cleanupPromise:null},runPromise=new Promise((resolve19,reject)=>{state.resolveRun=resolve19,state.rejectRun=reject}),stopChild=async()=>{let child=state.child;if(!child)return;expectedStops.add(child);let exitPromise=waitForChildExit2(child);if(typeof child.pid=="number"){try{await terminateProcessTreeImpl(child.pid,{platform})}catch(error){if(child.exitCode===null&&child.signalCode===null)throw error}await exitPromise}else child.kill("SIGTERM");state.child===child&&(state.child=null)},cleanup=()=>(state.cleanupPromise||(state.stopping=!0,state.restartTimer&&(clearTimeout(state.restartTimer),state.restartTimer=null),state.watcher?.close(),state.watcher=null,state.cleanupPromise=stopChild()),state.cleanupPromise),handleSignal=signal=>{cleanup().then(()=>{let exitCode=signal==="SIGINT"?130:143;(options.setExitCode??(code2=>{process4.exitCode=code2}))(exitCode),state.resolveRun?.()}).catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},handleSigint=()=>handleSignal("SIGINT"),handleSigterm=()=>handleSignal("SIGTERM");signalSource.once("SIGINT",handleSigint),signalSource.once("SIGTERM",handleSigterm);let startChild=()=>{let child=spawnImpl(options.command,{cwd:options.cwd,env:options.env,stdio:"inherit",shell:!0,detached:platform!=="win32"});state.child=child,child.on("exit",(code2,signal)=>{if(state.child===child&&(state.child=null),!(expectedStops.has(child)||state.stopping||state.restarting)){if(signal){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u9000\u51FA\uFF0C\u72B6\u6001\u7801 ${code2}`));return}state.resolveRun?.()}}),child.on("error",error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},performPendingRestarts=async()=>{if(!(state.restarting||state.stopping)){state.restarting=!0;try{for(;state.restartPending&&!state.stopping;)state.restartPending=!1,await stopChild(),state.stopping||startChild()}finally{state.restarting=!1}}},scheduleRestart=changedPath=>{let normalized=typeof changedPath=="string"?changedPath:changedPath?.toString("utf8");normalized&&normalized.split(/[\\/]+/u).filter(Boolean).some(segment=>IGNORED_PATH_SEGMENTS.has(segment))||(state.restartTimer&&clearTimeout(state.restartTimer),state.restartTimer=setTimeout(()=>{state.restartTimer=null,state.restartPending=!0,options.onWatching?.(`\u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4${normalized?`\uFF1A${normalized}`:""}\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B...`),performPendingRestarts().catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},restartDebounceMs))};if(options.watchRoot)try{state.watcher=watch(options.watchRoot,{recursive:!0},(_eventType,filename)=>{scheduleRestart(filename)}),options.onWatching?.("\u5DF2\u542F\u7528\u6587\u4EF6\u76D1\u542C\uFF1B\u6E90\u7801\u53D8\u66F4\u540E\u5C06\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002")}catch{options.onWatching?.("\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u9012\u5F52\u6587\u4EF6\u76D1\u542C\uFF1Bdev \u5B50\u8FDB\u7A0B\u5C06\u4FDD\u6301\u5355\u6B21\u542F\u52A8\u3002")}startChild();try{await runPromise}finally{try{await cleanup()}finally{signalSource.removeListener("SIGINT",handleSigint),signalSource.removeListener("SIGTERM",handleSigterm)}}}function waitForChildExit2(child){return child.exitCode!==null||child.signalCode!==null?Promise.resolve():new Promise(resolve19=>{child.once("exit",()=>resolve19())})}import{chmodSync as chmodSync2,existsSync as existsSync23,mkdirSync as mkdirSync11,readFileSync as readFileSync24,rmSync as rmSync6,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname13,resolve as resolve16}from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import YAML6 from"yaml";var MANAGED_ENV_KEYS=["CONTROL_API_BASE_URL","PUBLIC_API_BASE_URL","RUNTIME_API_BASE_URL","OIDC_ISSUER","OIDC_AUDIENCE","LOGTO_CLI_APP_ID","LOGTO_CLI_REDIRECT_URI","LOGTO_TENANT_APP_ID","LOGTO_TENANT_REDIRECT_URI","TEST_ENV_PROFILE"];function getEnvironmentProfilePath(){return resolveCliStateFilePath("environment.json")}function loadStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();return existsSync23(envProfilePath)?JSON.parse(readFileSync24(envProfilePath,"utf8")):null}function persistStoredEnvironmentProfile(input){withCliStateFileWriteFallback({fileName:"environment.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync11(stateDir,{recursive:!0}),writeFileSync12(filePath,`${JSON.stringify({active_profile:input.active_profile,values:normalizeProfileValues(input.values),updated_at:new Date().toISOString()},null,2)}
|
|
2557
|
-
`,"utf8"),chmodSync2(filePath,384)}})}function clearStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();
|
|
2560
|
+
`)}import{spawn as spawn2}from"node:child_process";import net from"node:net";import WebSocket from"ws";async function prepareLocalDevDatabaseBindings(runtimeBindings,options={}){let databaseUrl=runtimeBindings.DATABASE_URL?.trim();if(!databaseUrl)return{bindings:runtimeBindings,warnings:[],cleanup:null};let proxyTransport=runtimeBindings.DATABASE_PROXY_TRANSPORT?.trim(),proxyWsUrl=runtimeBindings.DATABASE_PROXY_WS_URL?.trim();if(proxyTransport==="ws_tunnel"&&proxyWsUrl)return await prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,proxyWsUrl);if(!shouldTunnelDatabaseUrl(databaseUrl))return{bindings:runtimeBindings,warnings:[],cleanup:null};if(!((process.env.PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL||"").trim()==="1"))throw new Error(["dev_runtime_binding_not_available","\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\uFF0C`platform dev --remote-bindings` \u5DF2\u62D2\u7EDD\u4F7F\u7528\u79C1\u7F51\u6570\u636E\u5E93\u5730\u5740\u3002","\u8BF7\u5148\u6539\u7528 `platform preview` \u9A8C\u8BC1\u771F\u5B9E\u5199\u5E93\u94FE\u8DEF\uFF1B\u5982\u4E3A\u5E73\u53F0\u7BA1\u7406\u5458\u5185\u90E8\u6392\u969C\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL=1` \u540E\u91CD\u8BD5\u3002"].join(" "));let sshHost=(options.sshHost||process.env.TEST_ENV_SSH_HOST||"").trim();if(!sshHost)throw new Error("\u5F53\u524D\u5DF2\u663E\u5F0F\u542F\u7528\u5185\u90E8 SSH \u515C\u5E95\uFF0C\u4F46\u672A\u914D\u7F6E TEST_ENV_SSH_HOST\uFF0C\u65E0\u6CD5\u5EFA\u7ACB\u672C\u5730 SSH \u96A7\u9053\u3002");let parsed=new URL(databaseUrl),remoteHost=parsed.hostname,remotePort=Number(parsed.port||"5432"),localPort=await allocateLocalPort(),child=spawn2("ssh",["-o","ExitOnForwardFailure=yes","-o","BatchMode=yes","-o","ConnectTimeout=8","-N","-L",`127.0.0.1:${localPort}:${remoteHost}:${remotePort}`,sshHost],{stdio:"ignore"});try{await waitForTunnelReady(localPort,child)}catch(error){throw child.kill("SIGTERM"),await waitForChildExit(child),error}let localUrl=rewriteDatabaseUrlForLocalPort(databaseUrl,localPort);return{bindings:{...runtimeBindings,DATABASE_URL:localUrl},warnings:[`\u68C0\u6D4B\u5230\u79C1\u7F51 DB host\uFF08${remoteHost}:${remotePort}\uFF09\uFF0C\u5DF2\u901A\u8FC7 SSH \u96A7\u9053\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{child.kill("SIGTERM"),await waitForChildExit(child)}}}async function prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,wsUrl){let localPort=await allocateLocalPort(),sockets=new Set,bridges=new Set,server=net.createServer(clientSocket=>{clientSocket.setNoDelay(!0),sockets.add(clientSocket);let bridge=new WebSocket(wsUrl);bridges.add(bridge);let closeBoth=()=>{sockets.delete(clientSocket),bridges.delete(bridge),clientSocket.destroyed||clientSocket.destroy(),(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close()};bridge.on("open",()=>{clientSocket.on("data",chunk=>{bridge.readyState===WebSocket.OPEN&&bridge.send(chunk)}),clientSocket.resume()}),bridge.on("message",payload=>{clientSocket.write(Buffer.isBuffer(payload)?payload:Buffer.from(payload))}),bridge.on("close",closeBoth),bridge.on("error",closeBoth),clientSocket.on("close",closeBoth),clientSocket.on("error",closeBoth),clientSocket.pause()});return await listenLocalServer(server,localPort),{bindings:{...runtimeBindings,DATABASE_URL:rewriteDatabaseUrlForLocalPort(databaseUrl,localPort)},warnings:[`\u68C0\u6D4B\u5230\u6B63\u5F0F dev proxy WebSocket \u6570\u636E\u9762\uFF0C\u5DF2\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{for(let socket of sockets)socket.destroyed||socket.destroy();for(let bridge of bridges)(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close();await closeServer(server)}}}function shouldTunnelDatabaseUrl(databaseUrl){try{let url=new URL(databaseUrl);return shouldTunnelHostname(url.hostname)}catch{return!1}}function rewriteDatabaseUrlForLocalPort(databaseUrl,localPort){let url=new URL(databaseUrl);return url.hostname="127.0.0.1",url.port=String(localPort),url.toString()}function shouldTunnelHostname(hostname){let value=hostname.trim().toLowerCase();return!value||["localhost","127.0.0.1"].includes(value)?!1:!!(["host.docker.internal","host.containers.internal"].includes(value)||isPrivateIpv4(value))}function isPrivateIpv4(hostname){let parts=hostname.split(".");if(parts.length!==4||parts.some(part=>!/^\d+$/.test(part)))return!1;let[a,b]=parts.map(part=>Number(part));return a===10||a===192&&b===168||a===172&&b>=16&&b<=31}async function allocateLocalPort(){return await new Promise((resolve19,reject)=>{let server=net.createServer();server.once("error",reject),server.listen(0,"127.0.0.1",()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u5206\u914D\u672C\u5730\u7AEF\u53E3\u3002")));return}let port=address.port;server.close(error=>{if(error){reject(error);return}resolve19(port)})})})}async function listenLocalServer(server,port){await new Promise((resolve19,reject)=>{server.once("error",reject),server.listen(port,"127.0.0.1",()=>{server.off("error",reject),resolve19()})})}async function closeServer(server){await new Promise(resolve19=>{server.close(()=>resolve19())})}async function waitForTunnelReady(localPort,child){let startedAt=Date.now();for(;Date.now()-startedAt<1e4;){if(child.exitCode!==null)throw new Error(`SSH \u96A7\u9053\u8FDB\u7A0B\u63D0\u524D\u9000\u51FA\uFF08code=${child.exitCode}\uFF09\u3002`);if(await canConnect("127.0.0.1",localPort))return;await sleep3(200)}throw new Error(`SSH \u96A7\u9053\u672A\u5728\u9884\u671F\u65F6\u95F4\u5185\u5C31\u7EEA\uFF1A127.0.0.1:${localPort}`)}async function canConnect(host,port){return await new Promise(resolve19=>{let socket=net.createConnection({host,port}),done=value=>{socket.removeAllListeners(),socket.destroyed||socket.destroy(),resolve19(value)};socket.once("connect",()=>done(!0)),socket.once("error",()=>done(!1)),socket.setTimeout(500,()=>done(!1))})}async function waitForChildExit(child){await new Promise(resolve19=>{if(child.exitCode!==null){resolve19();return}child.once("exit",()=>resolve19()),setTimeout(()=>resolve19(),1e3)})}function sleep3(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}import{spawn as spawn3}from"node:child_process";import{watch}from"node:fs";import process4 from"node:process";var IGNORED_PATH_SEGMENTS=new Set(["node_modules",".git",".platform","dist",".next"]),RESTART_DEBOUNCE_MS=250;async function runDevSupervisor(options){let platform=options.platform??process4.platform,spawnImpl=options.spawnImpl??spawn3,terminateProcessTreeImpl=options.terminateProcessTreeImpl??terminateProcessTree,signalSource=options.signalSource??process4,restartDebounceMs=options.restartDebounceMs??RESTART_DEBOUNCE_MS,expectedStops=new WeakSet,state={child:null,watcher:null,restartTimer:null,stopping:!1,restarting:!1,restartPending:!1,cleanupPromise:null},runPromise=new Promise((resolve19,reject)=>{state.resolveRun=resolve19,state.rejectRun=reject}),stopChild=async()=>{let child=state.child;if(!child)return;expectedStops.add(child);let exitPromise=waitForChildExit2(child);if(typeof child.pid=="number"){try{await terminateProcessTreeImpl(child.pid,{platform})}catch(error){if(child.exitCode===null&&child.signalCode===null)throw error}await exitPromise}else child.kill("SIGTERM");state.child===child&&(state.child=null)},cleanup=()=>(state.cleanupPromise||(state.stopping=!0,state.restartTimer&&(clearTimeout(state.restartTimer),state.restartTimer=null),state.watcher?.close(),state.watcher=null,state.cleanupPromise=stopChild()),state.cleanupPromise),handleSignal=signal=>{cleanup().then(()=>{let exitCode=signal==="SIGINT"?130:143;(options.setExitCode??(code2=>{process4.exitCode=code2}))(exitCode),state.resolveRun?.()}).catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},handleSigint=()=>handleSignal("SIGINT"),handleSigterm=()=>handleSignal("SIGTERM");signalSource.once("SIGINT",handleSigint),signalSource.once("SIGTERM",handleSigterm);let startChild=()=>{let child=spawnImpl(options.command,{cwd:options.cwd,env:options.env,stdio:"inherit",shell:!0,detached:platform!=="win32"});state.child=child,child.on("exit",(code2,signal)=>{if(state.child===child&&(state.child=null),!(expectedStops.has(child)||state.stopping||state.restarting)){if(signal){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u9000\u51FA\uFF0C\u72B6\u6001\u7801 ${code2}`));return}state.resolveRun?.()}}),child.on("error",error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},performPendingRestarts=async()=>{if(!(state.restarting||state.stopping)){state.restarting=!0;try{for(;state.restartPending&&!state.stopping;)state.restartPending=!1,await stopChild(),state.stopping||startChild()}finally{state.restarting=!1}}},scheduleRestart=changedPath=>{let normalized=typeof changedPath=="string"?changedPath:changedPath?.toString("utf8");normalized&&normalized.split(/[\\/]+/u).filter(Boolean).some(segment=>IGNORED_PATH_SEGMENTS.has(segment))||(state.restartTimer&&clearTimeout(state.restartTimer),state.restartTimer=setTimeout(()=>{state.restartTimer=null,state.restartPending=!0,options.onWatching?.(`\u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4${normalized?`\uFF1A${normalized}`:""}\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B...`),performPendingRestarts().catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},restartDebounceMs))};if(options.watchRoot)try{state.watcher=watch(options.watchRoot,{recursive:!0},(_eventType,filename)=>{scheduleRestart(filename)}),options.onWatching?.("\u5DF2\u542F\u7528\u6587\u4EF6\u76D1\u542C\uFF1B\u6E90\u7801\u53D8\u66F4\u540E\u5C06\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002")}catch{options.onWatching?.("\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u9012\u5F52\u6587\u4EF6\u76D1\u542C\uFF1Bdev \u5B50\u8FDB\u7A0B\u5C06\u4FDD\u6301\u5355\u6B21\u542F\u52A8\u3002")}startChild();try{await runPromise}finally{try{await cleanup()}finally{signalSource.removeListener("SIGINT",handleSigint),signalSource.removeListener("SIGTERM",handleSigterm)}}}function waitForChildExit2(child){return child.exitCode!==null||child.signalCode!==null?Promise.resolve():new Promise(resolve19=>{child.once("exit",()=>resolve19())})}import{chmodSync as chmodSync2,existsSync as existsSync24,mkdirSync as mkdirSync11,readFileSync as readFileSync25,rmSync as rmSync6,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname14,resolve as resolve16}from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import YAML6 from"yaml";var MANAGED_ENV_KEYS=["CONTROL_API_BASE_URL","PUBLIC_API_BASE_URL","RUNTIME_API_BASE_URL","OIDC_ISSUER","OIDC_AUDIENCE","LOGTO_CLI_APP_ID","LOGTO_CLI_REDIRECT_URI","LOGTO_TENANT_APP_ID","LOGTO_TENANT_REDIRECT_URI","TEST_ENV_PROFILE"];function getEnvironmentProfilePath(){return resolveCliStateFilePath("environment.json")}function loadStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();return existsSync24(envProfilePath)?JSON.parse(readFileSync25(envProfilePath,"utf8")):null}function persistStoredEnvironmentProfile(input){withCliStateFileWriteFallback({fileName:"environment.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync11(stateDir,{recursive:!0}),writeFileSync12(filePath,`${JSON.stringify({active_profile:input.active_profile,values:normalizeProfileValues(input.values),updated_at:new Date().toISOString()},null,2)}
|
|
2561
|
+
`,"utf8"),chmodSync2(filePath,384)}})}function clearStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();existsSync24(envProfilePath)&&rmSync6(envProfilePath)}function applyStoredEnvironmentProfile(env=process.env){let stored=loadStoredEnvironmentProfile();if(!stored)return null;for(let key of MANAGED_ENV_KEYS){let current=env[key];if(typeof current=="string"&¤t.trim().length>0)continue;let nextValue=stored.values[key];typeof nextValue=="string"&&nextValue.trim().length>0&&(env[key]=nextValue)}return stored}function listKnownEnvironmentProfiles(startDir=getInvocationCwd()){return loadEnvironmentProfileRegistry(startDir).map(profile=>({name:profile.name,values:resolveProfileValues(profile)}))}function resolveKnownEnvironmentProfile(profileName,startDir=getInvocationCwd()){let matched=loadEnvironmentProfileRegistry(startDir).find(profile=>profile.name===profileName);return matched?{name:matched.name,values:resolveProfileValues(matched)}:null}function normalizeProfileValues(values){let normalized={};for(let key of MANAGED_ENV_KEYS){let value=values[key];if(typeof value!="string")continue;let trimmed=value.trim();trimmed.length>0&&(normalized[key]=trimmed)}return normalized}function resolveProfileValues(profile){let values={},scheme=profile.topology?.scheme?.trim(),controlHost=profile.hosts?.control?.trim(),publicHost=profile.hosts?.public?.trim(),runtimeHost=profile.hosts?.runtime?.trim(),authHost=profile.hosts?.auth?.trim(),tenantHost=profile.hosts?.tenant?.trim(),issuer=profile.auth?.issuer?.trim(),audience=profile.auth?.audience?.trim();return scheme&&controlHost&&(values.CONTROL_API_BASE_URL=`${scheme}://${controlHost}`),scheme&&publicHost&&(values.PUBLIC_API_BASE_URL=`${scheme}://${publicHost}`),scheme&&runtimeHost&&(values.RUNTIME_API_BASE_URL=`${scheme}://${runtimeHost}`),issuer&&(values.OIDC_ISSUER=issuer),audience&&(values.OIDC_AUDIENCE=audience),tenantHost&&scheme&&(values.LOGTO_TENANT_REDIRECT_URI=`${scheme}://${tenantHost}/callback`),authHost&&profile.name==="local"?values.LOGTO_CLI_REDIRECT_URI="http://localhost:7300/callback":authHost&&(values.LOGTO_CLI_REDIRECT_URI="http://127.0.0.1:7300/callback"),values.TEST_ENV_PROFILE=profile.name,values}function loadEnvironmentProfileRegistry(startDir){let registryPath=resolveEnvironmentRegistryPath(startDir);if(!existsSync24(registryPath))return[];let parsed=YAML6.parse(readFileSync25(registryPath,"utf8"));return Array.isArray(parsed?.profiles)?parsed.profiles:[]}function resolveEnvironmentRegistryPath(startDir){let invocationWorkspaceRoot=findWorkspaceRoot(startDir),invocationCandidate=resolve16(invocationWorkspaceRoot,"deploy","registry","environment-profiles.yaml");if(existsSync24(invocationCandidate))return invocationCandidate;let cliModuleRoot=resolve16(dirname14(fileURLToPath5(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve16(cliWorkspaceRoot,"deploy","registry","environment-profiles.yaml")}async function runLogsCommand(args){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption8(args,"tenant")??binding?.tenant_id,appId=readStringOption8(args,"app")??binding?.app_id,env=readStringOption8(args,"env")??binding?.env??"preview",releaseId=readStringOption8(args,"release"),limit=readNumberOption3(args,"limit")??100,follow=args.options.follow===!0,from=readStringOption8(args,"from")??new Date(Date.now()-900*1e3).toISOString(),to=readStringOption8(args,"to")??new Date().toISOString();if(!tenantId||!appId)throw new Error("`platform logs` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"}),payload={tenant_id:tenantId,app_id:appId,env,...releaseId?{release_id:releaseId}:{},from,to,limit,follow};if(!follow){let result=await sdk.queryLogs(payload);printLogs(result,args.options.json===!0);return}let seen=new Set,currentFrom=from;for(;;){let result=await sdk.queryLogs({...payload,from:currentFrom,to:new Date().toISOString(),follow:!0});if(args.options.json===!0)process.stdout.write(`${JSON.stringify(result,null,2)}
|
|
2558
2562
|
`);else for(let entry of result.entries)seen.has(entry.id)||(seen.add(entry.id),process.stdout.write(`${formatEntry(entry)}
|
|
2559
2563
|
`));result.entries.length>0&&(currentFrom=result.entries[result.entries.length-1]?.timestamp??currentFrom),await sleep4(2e3)}}function printLogs(result,asJson){if(asJson){process.stdout.write(`${JSON.stringify(result,null,2)}
|
|
2560
2564
|
`);return}if(result.entries.length===0){process.stdout.write(`\u672A\u67E5\u8BE2\u5230\u65E5\u5FD7\u3002
|
|
@@ -2606,7 +2610,9 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2606
2610
|
`))}async function buildPreviewBindingHintLines(sdk,appId,env){let authInspect=await sdk.getTenantAppEndUserAuthInspect(appId).catch(()=>null),dbInstance=await sdk.getTenantAppDbInstance(appId,env).catch(()=>null),authEnv=authInspect?.environments.find(item=>item.env===env)??null;return buildPreviewBindingHintLinesFromState({appId,env,authInspect,authEnv,dbInstance})}function buildPreviewBindingHintLinesFromState(args){let lines=[];if(args.authEnv&&args.authInspect){lines.push(`runtime_hint.auth.${args.env}: ${args.authEnv.status} missing=[${args.authEnv.missing_binding_keys.join(", ")||"-"}] issues=[${args.authEnv.issues.join(", ")||"-"}]`);let authActions=formatPreviewAuthSuggestedActions(args.appId,args.env,args.authInspect,args.authEnv);authActions.length>0&&lines.push(`runtime_hint.auth_actions: ${authActions.join(" | ")}`)}return args.dbInstance&&!args.dbInstance.bound&&(lines.push(`runtime_hint.db.${args.env}: ${args.dbInstance.status??"not_bound"}`),lines.push(`runtime_hint.db_actions: platform resources apply --env ${args.env}`)),lines}async function buildPreviewSuccessPostCheckPayload(sdk,appId,preview){if(preview.status!=="active")return{status:"ready",lines:[]};let runtimeHintLines=await buildPreviewBindingHintLines(sdk,appId,"preview");return runtimeHintLines.length===0&&preview.runtime.health==="healthy"?{status:"ready",lines:[]}:{status:"warning",lines:["Preview \u5DF2\u751F\u6210\uFF0C\u4F46\u8FD0\u884C\u65F6\u540E\u7F6E\u68C0\u67E5\u4ECD\u6709\u7F3A\u53E3\u3002",`runtime_health: ${preview.runtime.health}`,...runtimeHintLines,"\u5EFA\u8BAE: \u5148\u6267\u884C `platform app diagnose --env preview`\uFF0C\u518D\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\u9875\u9762\u8054\u8C03\u3002"]}}function formatPreviewAuthSuggestedActions(appId,env,inspect,authEnv){let actions=new Set;for(let action of inspect.suggested_actions??[])switch(action){case"enable_auth":actions.add(`platform auth configure --app ${appId} --enable`);break;case"bind_user_store":actions.add(`platform auth bind --app ${appId} --action bind --user-store-id <user-store-id>`);break;case"reapply_auth_resources":actions.add(`platform resources apply --env ${env}`);break;case"check_runtime_bindings":actions.add(`platform auth inspect --app ${appId}`);break;default:break}return authEnv.status!=="ready"&&actions.add(`platform auth inspect --app ${appId}`),(authEnv.missing_binding_keys.length>0||authEnv.issues.includes("binding_missing"))&&actions.add(`platform resources apply --env ${env}`),Array.from(actions)}import{join as join20}from"node:path";function isReauthRequiredPlatformError(error){return error instanceof PlatformApiError&&[401,403].includes(error.status)}function requiresLoginRecovery(error){return error instanceof CliSessionExpiredError||isReauthRequiredPlatformError(error)?!0:error instanceof Error?[/未找到本地凭据/u,/当前凭据已过期且不支持自动刷新/u,/当前 PAT 登录已超过 7 天有效期/u,/当前凭据缺少 refresh_token/u,/当前 PAT 凭据缺少 subject_token/u,/请重新执行 `platform login/u].some(pattern=>pattern.test(error.message)):!1}function formatReauthHint(options={}){let lines=["\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A",`1. \u6267\u884C \`${options.credentialMode==="pat_exchange"?"platform login --pat <token>":"platform login"}\` \u6062\u590D CLI \u767B\u5F55\u6001`,"2. \u6267\u884C `platform whoami` \u786E\u8BA4\u51ED\u636E\u5DF2\u6062\u590D","3. \u518D\u91CD\u8BD5\u521A\u624D\u7684\u547D\u4EE4"];return options.credentialPath&&lines.push(`\u5F53\u524D\u51ED\u636E\u6587\u4EF6: ${options.credentialPath}`),lines.join(`
|
|
2607
2611
|
`)}function formatCliStateAccessHint(options={}){let recommendedStateDir=options.workspaceRoot?join20(options.workspaceRoot,"TMP","local-cli-state"):null,lines=["\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A"];return recommendedStateDir?(lines.push(`1. \u663E\u5F0F\u8BBE\u7F6E\u53EF\u5199\u72B6\u6001\u76EE\u5F55\uFF0C\u4F8B\u5982 \`PLATFORM_STATE_DIR="${recommendedStateDir}" platform login\``),lines.push(`2. \u518D\u6267\u884C \`PLATFORM_STATE_DIR="${recommendedStateDir}" platform whoami\` \u786E\u8BA4\u72B6\u6001\u76EE\u5F55\u4E0E\u767B\u5F55\u6001\u53EF\u7528`),lines.push("3. \u6700\u540E\u91CD\u8BD5\u521A\u624D\u7684\u547D\u4EE4"),lines.join(`
|
|
2608
2612
|
`)):(lines.push("1. \u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR` \u6307\u5411\u4E00\u4E2A\u53EF\u5199\u76EE\u5F55\u540E\u91CD\u8BD5"),lines.push("2. \u91CD\u65B0\u6267\u884C `platform login` \u6216 `platform whoami` \u9A8C\u8BC1\u8BE5\u76EE\u5F55\u53EF\u7528"),lines.join(`
|
|
2609
|
-
`))}function
|
|
2613
|
+
`))}function formatDependencyInstallFailureHint(lockfile){return lockfile==="package-lock.json"?["\u4F9D\u8D56\u5B89\u88C5\u6062\u590D\u5EFA\u8BAE\uFF1A","- `package.json` \u4E0E `package-lock.json` \u53EF\u80FD\u4E0D\u4E00\u81F4\uFF0CCLI \u4E0D\u4F1A\u81EA\u52A8\u56DE\u9000\u5230\u975E\u786E\u5B9A\u6027\u5B89\u88C5\u3002","- \u82E5\u8BE5\u76EE\u5F55\u6765\u81EA\u5E73\u53F0\u6A21\u677F\uFF0C\u8BF7\u5220\u9664\u5F53\u524D\u76EE\u5F55\u540E\u91CD\u65B0 checkout\uFF1B\u82E5\u95EE\u9898\u4ECD\u5B58\u5728\uFF0C\u8BF7\u53CD\u9988\u6A21\u677F lockfile\u3002","- \u82E5\u8FD9\u662F\u4F60\u7EF4\u62A4\u7684\u6E90\u7801\uFF0C\u8BF7\u5728\u53D7\u63A7\u5F00\u53D1\u73AF\u5883\u66F4\u65B0\u5E76\u63D0\u4EA4 lockfile \u540E\u91CD\u8BD5\u3002"].join(`
|
|
2614
|
+
`):["\u4F9D\u8D56\u5B89\u88C5\u6062\u590D\u5EFA\u8BAE\uFF1A",`- \u8BF7\u786E\u8BA4 package metadata \u4E0E ${lockfile} \u4E00\u81F4\u3002`,"- CLI \u4E0D\u4F1A\u81EA\u52A8\u6539\u5199 lockfile\uFF1B\u8BF7\u4FEE\u590D\u5E76\u63D0\u4EA4\u540E\u91CD\u8BD5\u3002"].join(`
|
|
2615
|
+
`)}var MINIMUM_NODE_VERSION="20.0.0";function assertSupportedNodeVersion(version=process.versions.node){let match2=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(version),major=match2?Number(match2[1]):Number.NaN;if(!Number.isInteger(major)||major<20)throw new Error(`[unsupported_node_version] \u5F53\u524D Node.js ${version} \u4E0D\u53D7\u652F\u6301\uFF1Bplatform CLI \u8981\u6C42 Node.js >=${MINIMUM_NODE_VERSION}\u3002\u8BF7\u5347\u7EA7 Node.js \u540E\u91CD\u8BD5\u3002`)}function chooseDefaultTenantWorkspace(workspaces){if(workspaces.length===1)return workspaces[0]??null;let ownerWorkspaces=workspaces.filter(item=>item.roles.includes("owner"));return ownerWorkspaces.length===1?ownerWorkspaces[0]??null:null}import{execSync}from"node:child_process";async function runDeployCommand(args){if(hasHelpFlag7(args)){printDeployHelp();return}let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption12(args,"tenant")??binding?.tenant_id,appId=readStringOption12(args,"app")??binding?.app_id,env=args.options.prod===!0?"prod":readStringOption12(args,"env")??binding?.env??"preview",version=readRequiredOption(args,"version",env),artifactUrl=readRequiredOption(args,"artifact-url",env),artifactDigest=readRequiredOption(args,"artifact-digest",env),sourceVersionId=readStringOption12(args,"source-version"),sourceSnapshotId=readStringOption12(args,"source-snapshot")??inferSourceSnapshotId(sourceVersionId),resourceSnapshotId=readStringOption12(args,"resource-snapshot"),gitSha=readStringOption12(args,"git-sha")??inferGitSha(appRoot,sourceVersionId),approvedBy=readStringOption12(args,"approved-by"),promoteFromReleaseId=readStringOption12(args,"promote-from");if(!tenantId||!appId)throw new Error("`platform deploy` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(env==="prod"&&!approvedBy)throw new Error(["`platform deploy --prod` \u9700\u8981 `--approved-by <subject-id>`\u3002","\u8BF4\u660E\uFF1A\u5F53\u524D prod \u53D1\u5E03\u4ECD\u4EE5\u53D1\u5E03\u4FA7\u5BA1\u6279\u6807\u8BC6\u4F5C\u4E3A\u95E8\u7981\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A","1. \u5148\u786E\u8BA4\u5BA1\u6279\u4E3B\u4F53\u7684 subject_id\u3002","2. \u518D\u6267\u884C `platform deploy --prod --approved-by <subject-id> ...`\u3002"].join(`
|
|
2610
2616
|
`));let{manifest}=readAppManifest(appRoot),apiToken=selectApiToken(credentials),requestedBy=await resolveRequestedBy4(apiToken,tenantId),sdk=createSdk(apiToken,tenantId),payload={tenant_id:tenantId,app_id:appId,env,artifact_url:artifactUrl,artifact_digest:artifactDigest,...gitSha?{git_commit_sha:gitSha}:{},...sourceSnapshotId?{source_snapshot_id:sourceSnapshotId}:{},...sourceVersionId?{source_version_id:sourceVersionId}:{},...resourceSnapshotId?{resource_snapshot_id:resourceSnapshotId}:{},manifest_snapshot:{name:manifest.name,module:manifest.module,entry:manifest.entry,runtime:manifest.runtime},...promoteFromReleaseId?{promote_from_release_id:promoteFromReleaseId}:{},...approvedBy?{approved_by:approvedBy}:{},requested_by:requestedBy,version},result=await withPendingFeedback3(args.options.json===!0,`\u6B63\u5728\u53D1\u8D77 ${env} \u53D1\u5E03: ${appId}/${version}`,"\u53D1\u5E03\u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85 release\u3001deployment \u4E0E\u8FD0\u884C\u65F6\u5065\u5EB7\u68C0\u67E5\u7ED3\u679C...",()=>sdk.deployRelease(payload)).catch(error=>{throw formatReleaseCommandError({error,command:"deploy",env,approvedBy,promoteFromReleaseId,sourceVersionId,resourceSnapshotId})});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result,null,2)}
|
|
2611
2617
|
`);return}printDeployResult(result)}async function runRollbackCommand(args){if(hasHelpFlag7(args)){printRollbackHelp();return}let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption12(args,"tenant")??binding?.tenant_id,appId=readStringOption12(args,"app")??binding?.app_id,env=readStringOption12(args,"env")??binding?.env??"preview",targetRelease=args.rest[0],reason=readStringOption12(args,"reason")??"manual_rollback";if(!tenantId||!appId)throw new Error("`platform rollback` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(!targetRelease)throw new Error(["`platform rollback <version-or-release-id>` \u7F3A\u5C11\u76EE\u6807\u7248\u672C\u3002","\u53EF\u4F7F\u7528 release id \u6216\u7248\u672C\u53F7\u4F5C\u4E3A\u76EE\u6807\uFF0C\u4F8B\u5982\uFF1A","1. `platform rollback rel_xxx`","2. `platform rollback v0.2.0`","\u5EFA\u8BAE\u4F18\u5148\u4F7F\u7528\u6700\u8FD1\u4E00\u6B21 deploy/rollback \u8F93\u51FA\u4E2D\u7684 `release`\u3001`current_release` \u6216\u7248\u672C\u53F7\u3002"].join(`
|
|
2612
2618
|
`));let apiToken=selectApiToken(credentials),requestedBy=await resolveRequestedBy4(apiToken,tenantId),sdk=createSdk(apiToken,tenantId),result=await withPendingFeedback3(args.options.json===!0,`\u6B63\u5728\u53D1\u8D77\u56DE\u6EDA: ${appId}/${env} -> ${targetRelease}`,"\u56DE\u6EDA\u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85 release \u5207\u6362\u4E0E\u8FD0\u884C\u65F6\u72B6\u6001\u56DE\u5199...",()=>sdk.rollbackRelease({tenant_id:tenantId,app_id:appId,env,target_release_id:targetRelease,reason,requested_by:requestedBy})).catch(error=>{throw formatReleaseCommandError({error,command:"rollback",env,targetRelease})});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result,null,2)}
|
|
@@ -2620,7 +2626,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2620
2626
|
`)}async function withPendingFeedback3(jsonOutput,startMessage,waitingMessage,action){if(jsonOutput)return action();process.stderr.write(`${startMessage}
|
|
2621
2627
|
`);let timer=setTimeout(()=>{process.stderr.write(`${waitingMessage}
|
|
2622
2628
|
`)},1500);try{return await action()}finally{clearTimeout(timer)}}function formatReleaseCommandError(args){if(!(args.error instanceof PlatformApiError))return args.error instanceof Error?args.error:new Error("\u53D1\u5E03\u547D\u4EE4\u6267\u884C\u5931\u8D25");let apiError=args.error,lines=[buildPrimaryReleaseErrorLine(apiError)],recoveryActions=buildReleaseRecoveryActions({...args,error:apiError});if(recoveryActions.length>0){lines.push("\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A");for(let action of recoveryActions)lines.push(action)}return apiError.requestId&&lines.push(`request_id: ${apiError.requestId}`),new Error(lines.join(`
|
|
2623
|
-
`))}function buildPrimaryReleaseErrorLine(error){switch(error.code){case"release_approval_required":return"prod \u53D1\u5E03\u9700\u8981\u5BA1\u6279\u6807\u8BC6\uFF1A\u5F53\u524D\u5FC5\u987B\u643A\u5E26 `--approved-by <subject-id>`\u3002";case"stable_release_not_found":return"\u627E\u4E0D\u5230\u53EF\u56DE\u6EDA\u7684\u76EE\u6807 release\uFF1A\u5F53\u524D `version/release-id` \u4E0D\u5B58\u5728\u3002";case"invalid_request":return buildInvalidRequestPrimaryLine(error);default:return error.message}}function buildInvalidRequestPrimaryLine(error){let detail=error.detail??{};return detail.resource_snapshot_id?"\u8D44\u6E90\u5FEB\u7167\u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `resource_snapshot_id` \u5728\u8BE5\u5E94\u7528\u4E0B\u672A\u627E\u5230\u3002":detail.source_version_id?"\u6E90\u7801\u7248\u672C\u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `source_version_id` \u5728\u8BE5\u5E94\u7528\u4E0B\u672A\u627E\u5230\u3002":detail.promote_from_release_id?error.message.includes("same verified artifact")?"prod promote \u5931\u8D25\uFF1A\u5FC5\u987B\u63D0\u5347 preview \u5DF2\u9A8C\u8BC1\u901A\u8FC7\u7684\u540C\u4E00 artifact\u3002":"promote \u6765\u6E90 release \u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `promote_from_release_id` \u672A\u627E\u5230\u3002":error.message}function buildReleaseRecoveryActions(args){let detail=args.error.detail??{};switch(args.error.code){case"release_approval_required":return["- \u5148\u786E\u8BA4\u5F53\u524D\u5BA1\u6279\u4E3B\u4F53\u7684 subject_id\u3002","- \u518D\u6267\u884C: `platform deploy --prod --approved-by <subject-id> ...`"];case"stable_release_not_found":return[`- \u5F53\u524D\u76EE\u6807: ${args.targetRelease??"unknown"}`,"- \u5F53\u524D\u76EE\u6807\u65E2\u53EF\u80FD\u662F release id\uFF0C\u4E5F\u53EF\u4EE5\u662F\u7248\u672C\u53F7\u3002","- \u5148\u4ECE\u6700\u8FD1\u4E00\u6B21 deploy/rollback \u8F93\u51FA\u91CC\u786E\u8BA4 `release` / `current_release` / `version`\uFF0C\u518D\u91CD\u8BD5\u56DE\u6EDA\u3002"];case"invalid_request":return detail.resource_snapshot_id?[`- \u5F53\u524D\u672A\u627E\u5230\u7684\u8D44\u6E90\u5FEB\u7167: ${String(detail.resource_snapshot_id)}`,"- \u5148\u786E\u8BA4\u8BE5\u5E94\u7528\u6700\u65B0\u53EF\u7528\u7684 `resource_snapshot_id`\uFF0C\u518D\u91CD\u65B0\u6267\u884C deploy\u3002"]:detail.source_version_id?[`- \u5F53\u524D\u672A\u627E\u5230\u7684\u6E90\u7801\u7248\u672C: ${String(detail.source_version_id)}`,"- \u5148\u901A\u8FC7 `platform app versions` \u786E\u8BA4\u6B63\u786E\u7684 `source_version_id`\uFF0C\u518D\u91CD\u8BD5\u53D1\u5E03\u3002"]:detail.promote_from_release_id?args.error.message.includes("same verified artifact")?[`- \u5F53\u524D promote \u6765\u6E90 release: ${String(detail.promote_from_release_id)}`,"- \u786E\u4FDD prod \u4F7F\u7528\u4E0E preview \u9A8C\u8BC1\u901A\u8FC7\u7684 release \u5B8C\u5168\u76F8\u540C\u7684 `artifact-url` \u548C `artifact-digest`\u3002"]:[`- \u5F53\u524D\u672A\u627E\u5230\u7684 promote \u6765\u6E90: ${String(detail.promote_from_release_id)}`,"- \u5148\u786E\u8BA4 preview release \u5B58\u5728\uFF0C\u518D\u91CD\u8BD5 `--promote-from`\u3002"]:[];default:return[]}}import process6 from"node:process";import{readFileSync as
|
|
2629
|
+
`))}function buildPrimaryReleaseErrorLine(error){switch(error.code){case"release_approval_required":return"prod \u53D1\u5E03\u9700\u8981\u5BA1\u6279\u6807\u8BC6\uFF1A\u5F53\u524D\u5FC5\u987B\u643A\u5E26 `--approved-by <subject-id>`\u3002";case"stable_release_not_found":return"\u627E\u4E0D\u5230\u53EF\u56DE\u6EDA\u7684\u76EE\u6807 release\uFF1A\u5F53\u524D `version/release-id` \u4E0D\u5B58\u5728\u3002";case"invalid_request":return buildInvalidRequestPrimaryLine(error);default:return error.message}}function buildInvalidRequestPrimaryLine(error){let detail=error.detail??{};return detail.resource_snapshot_id?"\u8D44\u6E90\u5FEB\u7167\u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `resource_snapshot_id` \u5728\u8BE5\u5E94\u7528\u4E0B\u672A\u627E\u5230\u3002":detail.source_version_id?"\u6E90\u7801\u7248\u672C\u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `source_version_id` \u5728\u8BE5\u5E94\u7528\u4E0B\u672A\u627E\u5230\u3002":detail.promote_from_release_id?error.message.includes("same verified artifact")?"prod promote \u5931\u8D25\uFF1A\u5FC5\u987B\u63D0\u5347 preview \u5DF2\u9A8C\u8BC1\u901A\u8FC7\u7684\u540C\u4E00 artifact\u3002":"promote \u6765\u6E90 release \u4E0D\u5B58\u5728\uFF1A\u5F53\u524D `promote_from_release_id` \u672A\u627E\u5230\u3002":error.message}function buildReleaseRecoveryActions(args){let detail=args.error.detail??{};switch(args.error.code){case"release_approval_required":return["- \u5148\u786E\u8BA4\u5F53\u524D\u5BA1\u6279\u4E3B\u4F53\u7684 subject_id\u3002","- \u518D\u6267\u884C: `platform deploy --prod --approved-by <subject-id> ...`"];case"stable_release_not_found":return[`- \u5F53\u524D\u76EE\u6807: ${args.targetRelease??"unknown"}`,"- \u5F53\u524D\u76EE\u6807\u65E2\u53EF\u80FD\u662F release id\uFF0C\u4E5F\u53EF\u4EE5\u662F\u7248\u672C\u53F7\u3002","- \u5148\u4ECE\u6700\u8FD1\u4E00\u6B21 deploy/rollback \u8F93\u51FA\u91CC\u786E\u8BA4 `release` / `current_release` / `version`\uFF0C\u518D\u91CD\u8BD5\u56DE\u6EDA\u3002"];case"invalid_request":return detail.resource_snapshot_id?[`- \u5F53\u524D\u672A\u627E\u5230\u7684\u8D44\u6E90\u5FEB\u7167: ${String(detail.resource_snapshot_id)}`,"- \u5148\u786E\u8BA4\u8BE5\u5E94\u7528\u6700\u65B0\u53EF\u7528\u7684 `resource_snapshot_id`\uFF0C\u518D\u91CD\u65B0\u6267\u884C deploy\u3002"]:detail.source_version_id?[`- \u5F53\u524D\u672A\u627E\u5230\u7684\u6E90\u7801\u7248\u672C: ${String(detail.source_version_id)}`,"- \u5148\u901A\u8FC7 `platform app versions` \u786E\u8BA4\u6B63\u786E\u7684 `source_version_id`\uFF0C\u518D\u91CD\u8BD5\u53D1\u5E03\u3002"]:detail.promote_from_release_id?args.error.message.includes("same verified artifact")?[`- \u5F53\u524D promote \u6765\u6E90 release: ${String(detail.promote_from_release_id)}`,"- \u786E\u4FDD prod \u4F7F\u7528\u4E0E preview \u9A8C\u8BC1\u901A\u8FC7\u7684 release \u5B8C\u5168\u76F8\u540C\u7684 `artifact-url` \u548C `artifact-digest`\u3002"]:[`- \u5F53\u524D\u672A\u627E\u5230\u7684 promote \u6765\u6E90: ${String(detail.promote_from_release_id)}`,"- \u5148\u786E\u8BA4 preview release \u5B58\u5728\uFF0C\u518D\u91CD\u8BD5 `--promote-from`\u3002"]:[];default:return[]}}import process6 from"node:process";import{readFileSync as readFileSync26}from"node:fs";async function runWorkflowCommand(args){let subcommand=args.rest[0];if(!subcommand||!["template","definition","binding","role","start","action","tasks","instance","diagnose"].includes(subcommand))throw new Error("`platform workflow` \u4EC5\u652F\u6301 `template`\u3001`definition`\u3001`binding`\u3001`role`\u3001`start`\u3001`action`\u3001`tasks`\u3001`instance` \u6216 `diagnose` \u5B50\u547D\u4EE4\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let context=resolveWorkflowContext(args);if(!context.tenantId)throw new Error("`platform workflow` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u9879\u76EE\u3001\u9009\u62E9\u5E94\u7528\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant`\u3002");let resolvedContext={tenantId:context.tenantId,appId:context.appId},sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:resolvedContext.tenantId,capability:"workflow",requestClass:"control"});if(subcommand==="definition"){await runWorkflowDefinitionSubcommand(sdk,resolvedContext,args);return}if(subcommand==="template"){let action=args.rest[1];if(action==="list"){let items=await sdk.listWorkflowTemplates();process6.stdout.write(`${JSON.stringify(items,null,2)}
|
|
2624
2630
|
`);return}if(action==="inspect"){let templateKey=readStringOption13(args,"template")??args.rest[2];if(!templateKey)throw new Error("`platform workflow template inspect` \u9700\u8981 `--template <key>` \u6216\u76F4\u63A5\u4F20\u5165 `<template-key>`\u3002");let item2=(await sdk.listWorkflowTemplates()).find(candidate=>candidate.template_key===templateKey);if(!item2)throw new Error(`\u672A\u627E\u5230 Workflow template: ${templateKey}`);process6.stdout.write(`${JSON.stringify(item2,null,2)}
|
|
2625
2631
|
`);return}throw new Error("`platform workflow template` \u76EE\u524D\u4EC5\u652F\u6301 `list` \u6216 `inspect`\u3002")}if(subcommand==="role"){await runWorkflowRoleSubcommand(sdk,resolvedContext,args);return}if(subcommand==="binding"){await runWorkflowBindingSubcommand(sdk,resolvedContext,args);return}if(subcommand==="diagnose"){await runWorkflowDiagnoseSubcommand(sdk,resolvedContext,args);return}if(subcommand==="start"){let definitionKey=readStringOption13(args,"definition")??readStringOption13(args,"definition-key"),objectType=readStringOption13(args,"object-type"),objectId=readStringOption13(args,"object-id");if(!resolvedContext.appId||!definitionKey||!objectType||!objectId)throw new Error("`platform workflow start` \u9700\u8981 `--definition <key>`\u3001`--object-type <type>`\u3001`--object-id <id>` \u548C\u5E94\u7528\u4E0A\u4E0B\u6587\u3002");let item2=await sdk.startWorkflow({tenant_id:resolvedContext.tenantId,app_id:resolvedContext.appId,definition_key:definitionKey,object_type:objectType,object_id:objectId});process6.stdout.write(`${JSON.stringify(item2,null,2)}
|
|
2626
2632
|
`);return}if(subcommand==="action"){let instanceId2=readStringOption13(args,"instance")??args.rest[1],actionKey=readStringOption13(args,"action");if(!instanceId2||!actionKey)throw new Error("`platform workflow action` \u9700\u8981 `--instance <id>` \u548C `--action <key>`\u3002");let item2=await sdk.performWorkflowAction(instanceId2,{action_key:actionKey,comment:readStringOption13(args,"comment")});process6.stdout.write(`${JSON.stringify(item2,null,2)}
|
|
@@ -2635,7 +2641,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2635
2641
|
`)}async function runWorkflowBindingSubcommand(sdk,context,args){let action=args.rest[1];if(action==="list"){let items=await sdk.listWorkflowBindings({target_id:readStringOption13(args,"target-id")??readStringOption13(args,"app")??context.appId,definition_key:readStringOption13(args,"definition")??readStringOption13(args,"definition-key")});process6.stdout.write(`${JSON.stringify(items,null,2)}
|
|
2636
2642
|
`);return}if(action==="inspect"){let definitionKey=readStringOption13(args,"definition")??readStringOption13(args,"definition-key")??readStringOption13(args,"binding"),targetScope=readStringOption13(args,"target-scope")??"tenant_app",targetId=readStringOption13(args,"target-id")??readStringOption13(args,"app")??context.appId;if(!definitionKey||!targetId)throw new Error("`platform workflow binding inspect` \u9700\u8981 `--definition <key>` \u548C `--target-id <id>`\uFF1B\u5728\u8F7B\u5E94\u7528\u4E0A\u4E0B\u6587\u91CC\u53EF\u7701\u7565 `--target-id`\u3002");let item=(await sdk.listWorkflowBindings({target_id:targetId,definition_key:definitionKey})).find(candidate=>candidate.definition_key===definitionKey&&candidate.target_id===targetId);if(!item)throw new Error(`\u672A\u627E\u5230 Workflow binding: ${definitionKey} @ ${targetId}`);let[override,roleBindings]=await Promise.all([sdk.getWorkflowBindingOverride({target_scope:targetScope,target_id:targetId,definition_key:definitionKey}),sdk.listWorkflowRoleBindings({target_scope:targetScope,target_id:targetId,definition_key:definitionKey})]);process6.stdout.write(`${JSON.stringify({binding:item,override,role_bindings:roleBindings},null,2)}
|
|
2637
2643
|
`);return}if(action==="update"){let file=readStringOption13(args,"file"),payloadFromFile=file?readJsonFile(file):null,definitionKey=readStringOption13(args,"definition")??readStringOption13(args,"definition-key")??readString(payloadFromFile,"definition_key"),targetScope=readStringOption13(args,"target-scope")??readString(payloadFromFile,"target_scope")??"tenant_app",targetId=readStringOption13(args,"target-id")??readStringOption13(args,"app")??context.appId??readString(payloadFromFile,"target_id");if(!file||!definitionKey||!targetId)throw new Error("`platform workflow binding update` \u9700\u8981 `--file <override.json>`\u3001`--definition <key>`\uFF0C\u4EE5\u53CA `--target-id <id>`\uFF1B\u5728\u8F7B\u5E94\u7528\u4E0A\u4E0B\u6587\u91CC\u53EF\u7701\u7565 `--target-id`\u3002");let item=await sdk.saveWorkflowBindingOverride({tenant_id:context.tenantId,definition_key:definitionKey,target_scope:targetScope,target_id:targetId,state_overrides:payloadFromFile?.state_overrides??[],action_overrides:payloadFromFile?.action_overrides??[]});targetScope==="tenant_app"&&await syncLocalControlPlaneSummary({sdk,startDir:process6.cwd(),tenantId:context.tenantId,appId:targetId}),process6.stdout.write(`${JSON.stringify(item,null,2)}
|
|
2638
|
-
`);return}throw new Error("`platform workflow binding` \u76EE\u524D\u4EC5\u652F\u6301 `list`\u3001`inspect` \u6216 `update`\u3002")}function resolveWorkflowContext(args){let storedContext=loadStoredCliContext(),binding;try{binding=readBinding(findAppRoot(process6.cwd()))?.binding}catch{binding=void 0}return{tenantId:readStringOption13(args,"tenant")??binding?.tenant_id??storedContext?.selected_app_tenant_id,appId:readStringOption13(args,"app")??binding?.app_id??storedContext?.selected_app_id}}function readStringOption13(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readJsonOption(args,key){let value=readStringOption13(args,key);if(value)return JSON.parse(value)}function readJsonFile(
|
|
2644
|
+
`);return}throw new Error("`platform workflow binding` \u76EE\u524D\u4EC5\u652F\u6301 `list`\u3001`inspect` \u6216 `update`\u3002")}function resolveWorkflowContext(args){let storedContext=loadStoredCliContext(),binding;try{binding=readBinding(findAppRoot(process6.cwd()))?.binding}catch{binding=void 0}return{tenantId:readStringOption13(args,"tenant")??binding?.tenant_id??storedContext?.selected_app_tenant_id,appId:readStringOption13(args,"app")??binding?.app_id??storedContext?.selected_app_id}}function readStringOption13(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readJsonOption(args,key){let value=readStringOption13(args,key);if(value)return JSON.parse(value)}function readJsonFile(path3){return JSON.parse(readFileSync26(path3,"utf8"))}function readString(record,key){let value=record?.[key];return typeof value=="string"?value:void 0}function readNullableString(record,key){let value=record?.[key];return value===null?null:typeof value=="string"?value:void 0}function getDevHelpLines(){return["platform dev","","\u7B2C\u4E00\u9636\u6BB5\u53EF\u7528\u5165\u53E3\uFF1A"," platform dev"," platform dev --remote-bindings"," platform dev --remote-bindings=db"," platform dev push"," platform dev preview generate"," platform dev preview open","","\u8BF4\u660E\uFF1A"," - `platform dev` \u7EE7\u7EED\u4F5C\u4E3A\u672C\u5730\u8F7B\u91CF\u5F00\u53D1\u5165\u53E3\uFF0C\u5B9E\u9645\u6267\u884C app.yaml \u4E2D\u7684 `entry.command`"," - `platform dev` \u9ED8\u8BA4\u5355\u6B21\u542F\u52A8 `entry.command`\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F"," - \u82E5 app.yaml \u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\uFF0CCLI \u624D\u4F1A\u76D1\u542C\u6E90\u7801\u53D8\u66F4\u5E76\u81EA\u52A8\u91CD\u542F\u672C\u5730 dev \u5B50\u8FDB\u7A0B"," - `platform dev --remote-bindings` \u9ED8\u8BA4\u6309 `auto` \u6A21\u5F0F\u8FD0\u884C\uFF1A\u53EA\u5C1D\u8BD5\u6CE8\u5165\u5F53\u524D\u5DE5\u4F5C\u533A\u5DF2\u58F0\u660E\u7684\u8FDC\u7AEF binding"," - \u82E5\u5F53\u524D\u5DE5\u4F5C\u533A\u672A\u68C0\u6D4B\u5230\u771F\u5B9E DB migration\uFF0C`platform dev --remote-bindings` \u4F1A\u8DF3\u8FC7 DB binding\uFF0C\u4E0D\u963B\u65AD\u672C\u5730\u542F\u52A8"," - \u82E5\u4F60\u786E\u8BA4\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u53EF\u663E\u5F0F\u6267\u884C `platform dev --remote-bindings=db`"," - `platform dev` \u8F93\u51FA\u7684\u662F\u672C\u5730\u9884\u89C8\u5730\u5740\uFF1B\u4E91\u7AEF\u53EF\u5206\u4EAB\u7684 Preview \u9700\u8981\u5355\u72EC\u6267\u884C `platform preview generate` \u6216 `platform dev preview generate`"," - `platform dev push` \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u8986\u76D6\u63A8\u9001\u5230\u4E91\u7AEF Dev Workspace"," - `platform dev preview generate/open` \u53EA\u64CD\u4F5C\u5DE5\u4F5C\u533A Preview"," - \u6B63\u5F0F\u7248\u672C\u751F\u6210\u7EE7\u7EED\u4F7F\u7528 `platform app submit`"," - \u7B2C\u4E00\u9636\u6BB5\u4E0D\u5F15\u5165 `platform dev save`","","\u793A\u4F8B\uFF1A"," platform dev"," platform dev --remote-bindings"," platform dev --remote-bindings=db"," platform dev push"," platform dev preview generate"," platform dev preview open",' platform app submit --message "formal version"',""]}function getDevPreviewHelpLines(){return["platform dev preview","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform dev preview generate"," platform dev preview open","","\u8BF4\u660E\uFF1A"," - `generate` \u57FA\u4E8E\u4E91\u7AEF Dev Workspace \u751F\u6210\u5DE5\u4F5C\u533A Preview"," - `open` \u6253\u5F00\u5F53\u524D\u5DE5\u4F5C\u533A Preview"," - \u5DE5\u4F5C\u533A Preview \u4E0E\u7248\u672C Preview \u5171\u7528 app \u7684 Preview \u69FD\u4F4D",""]}function getDevSaveUnsupportedMessage(){return["`platform dev save` \u5728\u7B2C\u4E00\u9636\u6BB5\u672A\u5F00\u653E\u3002","\u5F53\u524D\u6B63\u5F0F\u7248\u672C\u751F\u6210\u7EE7\u7EED\u6CBF\u7528\u73B0\u6709\u6B63\u5F0F\u7248\u672C\u94FE\u8DEF\u3002",'\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A\u4F7F\u7528 `platform app submit --message "..."` \u751F\u6210\u65B0\u7684\u6B63\u5F0F\u7248\u672C\u3002'].join(`
|
|
2639
2645
|
`)}import{spawn as spawn4}from"node:child_process";var implementedWorkers=new Set(["preview-retention"]);async function runWorkerCommand(args){let worker=args.rest[0]??"help";if(worker==="help"||args.options.help===!0||args.options.h===!0){printWorkerHelp();return}if(!implementedWorkers.has(worker)){let payload={ok:!1,code:"worker_not_implemented",worker,implemented_workers:[...implementedWorkers]};args.options.json===!0?process.stderr.write(`${JSON.stringify(payload,null,2)}
|
|
2640
2646
|
`):process.stderr.write(`worker \u672A\u5B9E\u73B0: ${worker}
|
|
2641
2647
|
\u5F53\u524D\u5DF2\u5B9E\u73B0: ${[...implementedWorkers].join(", ")}
|
|
@@ -2644,7 +2650,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2644
2650
|
`))}function printVersion(){process7.stdout.write(`v${cliPackageVersion}
|
|
2645
2651
|
`)}function normalizeAppTemplateOption(value){return normalizeAppTemplateKey(value)}function readRequiredEnv(key){let value=process7.env[key];if(!value||value.trim().length===0)throw new Error(`\u7F3A\u5C11\u73AF\u5883\u53D8\u91CF: ${key}`);return value.trim()}function resolveBrowserLoginConfig(){let cliClientId=readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS),cliRedirectUri=readAuthConfigValue(AUTH_CLI_REDIRECT_URI_KEYS);if(cliClientId&&cliRedirectUri)return{clientId:cliClientId,redirectUri:cliRedirectUri,source:"cli-app"};let fallbackClientId=readAuthConfigValue(AUTH_TENANT_CLIENT_ID_KEYS),fallbackRedirectUri=readAuthConfigValue(AUTH_TENANT_REDIRECT_URI_KEYS);return!fallbackClientId||!fallbackRedirectUri?null:{clientId:fallbackClientId,redirectUri:fallbackRedirectUri,source:"workbench-fallback"}}function shouldFallbackToBrowserLogin(error){if(!(error instanceof Error))return!1;let message=error.message;return message.includes("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9")||message.includes("device_code is not allowed for this client")||message.includes("grant-type:device_code is not allowed for this client")}function readOption2(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasFlag2(args,key){return args.options[key]===!0}function printDiagnosticsHelp(){process7.stdout.write(["platform diagnostics","","\u7528\u6CD5\uFF1A"," platform diagnostics control-api [--json]","","\u8BF4\u660E\uFF1A"," \u8F93\u51FA control/runtime/public endpoint \u5206\u533A\u8BCA\u65AD\uFF0C\u4E0D\u6539\u53D8\u9ED8\u8BA4 URL\u3002"," runtime/public endpoint \u4EC5\u5728\u914D\u7F6E\u5B58\u5728\u4E14 capability allowlist \u547D\u4E2D\u65F6\u63A2\u6D4B\u3002","","\u73AF\u5883\u53D8\u91CF\uFF1A"," CONTROL_API_BASE_URL"," RUNTIME_API_BASE_URL"," PUBLIC_API_BASE_URL"," CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES",""].join(`
|
|
2646
2652
|
`))}async function runDiagnostics(args){let subcommand=args.rest[0]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")||subcommand==="help"){printDiagnosticsHelp();return}if(subcommand!=="control-api")throw printDiagnosticsHelp(),new Error(`\u672A\u77E5 diagnostics \u5B50\u547D\u4EE4: ${subcommand}`);let diagnostics=await collectControlApiFailureDiagnostics();if(args.options.json===!0){process7.stdout.write(`${JSON.stringify(diagnostics,null,2)}
|
|
2647
|
-
`);return}process7.stdout.write(formatControlApiDiagnosticsText(diagnostics))}function readIntegerOption(args,key){let raw=readOption2(args,key);if(raw===void 0)return;let value=Number(raw);if(!Number.isInteger(value))throw new Error(`\u65E0\u6548\u7684 \`--${key}\`\uFF0C\u5FC5\u987B\u662F\u6574\u6570\u3002`);return value}function readCsvOption3(args,key){let raw=readOption2(args,key);return raw?raw.split(",").map(item=>item.trim()).filter(Boolean):[]}function readJsonInput(args,key="file"){let filePath=readOption2(args,key);if(!filePath)throw new Error(`\u7F3A\u5C11 \`--${key} <path>\`\u3002`);let content=filePath==="-"?readFileSync26(0,"utf8"):readFileSync26(filePath,"utf8");try{return JSON.parse(content)}catch(error){throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON \u8F93\u5165: ${filePath==="-"?"stdin":filePath}\u3002${error instanceof Error?` ${error.message}`:""}`)}}async function findExistingTenantCmsItemForImport(args){let lookup=args.lookup;if(!lookup)return null;if(lookup.kind==="item_id")try{return{item:await args.sdk.getTenantCmsItem({collection:args.collection,id:lookup.value}),matchedBy:"item_id"}}catch(error){if(error instanceof PlatformApiError&&error.status===404)return null;throw error}let matched=(await args.sdk.listTenantCmsItems({collection:args.collection,page:1,pageSize:20,query:lookup.value})).items.find(item=>item.system.slug===lookup.value);return matched?{item:matched,matchedBy:"slug"}:null}function resolveTenantContext(args,startDir=currentInvocationDir()){let linked;try{linked=readBinding(startDir)}catch{linked=null}let storedContext=loadStoredCliContext();return readOption2(args,"tenant")??linked?.binding.tenant_id??storedContext?.selected_app_tenant_id??storedContext?.active_tenant_id}function tryReadCurrentBinding2(){try{return readBinding(currentInvocationDir())}catch{return null}}function syncSelectedAppContextFromBinding(binding){let existing=loadStoredCliContext();persistCliContext({active_tenant_id:binding.tenant_id,active_tenant_name:existing?.active_tenant_id===binding.tenant_id?existing.active_tenant_name:void 0,selected_app_tenant_id:binding.tenant_id,selected_app_id:binding.app_id,selected_app_env:binding.env,selected_app_name:binding.app_name??binding.app_id,selected_app_display_name:binding.app_display_name})}function tryReadCurrentSourceContext(){try{return readSourceContext(currentInvocationDir())}catch{return null}}function readStoredCredentialModeSafely(){try{return loadStoredCredentials()?.credential_mode}catch{return}}function readCredentialPathSafely(){try{return getCredentialPath()}catch{return}}function formatRuntimeTargetLabel(env){return env==="preview"?"\u4E91\u7AEF Preview":"\u4E91\u7AEF Prod"}function summarizePreflightAppContext(args){let binding=tryReadCurrentBinding2()?.binding??null,sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext??null,context=loadStoredCliContext(),tenantId=readOption2(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id,appId=readOption2(args,"app")??sourceContext?.app_id??binding?.app_id??context?.selected_app_id??args.rest[1],env=readOption2(args,"env")??sourceContext?.env??binding?.env??context?.selected_app_env??"preview";return sourceContext?.tenant_id&&sourceContext.app_id&&binding?.tenant_id&&binding.app_id?{status:"ready",detail:`\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A ${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:sourceContext?.tenant_id&&sourceContext.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230 source-context\uFF1A${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:binding?`${currentInvocationDir()}/.platform/config.json`:null,sourceContextPath:sourceContextResult?.path??null}:binding?.tenant_id&&binding.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230\u76EE\u5F55\u7ED1\u5B9A\uFF1A${binding.tenant_id}/${binding.app_id}/${binding.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:context?.selected_app_tenant_id&&context.selected_app_id?{status:"warning",detail:`\u5F53\u524D\u4EC5\u547D\u4E2D\u5168\u5C40 CLI \u5E94\u7528\u4E0A\u4E0B\u6587\uFF1A${context.selected_app_tenant_id}/${context.selected_app_id}/${context.selected_app_env??env}`,tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}:{status:"blocked",detail:"\u5F53\u524D\u672A\u89E3\u6790\u51FA\u53EF\u7528\u7684 tenant/app \u4E0A\u4E0B\u6587",tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}}function mergePreflightRecommendations(items){let seen=new Set,merged=[];for(let item of items){let normalized=item.trim();!normalized||seen.has(normalized)||(seen.add(normalized),merged.push(normalized))}return merged}function summarizeCheckStatuses(checks){return checks.some(item=>item.status==="blocked")?"blocked":checks.some(item=>item.status!=="ready")?"warning":"ready"}function resolveAppIdFromContext(args,positionalIndex=1){let binding=tryReadCurrentBinding2()?.binding,context=loadStoredCliContext();return readOption2(args,"app")??binding?.app_id??context?.selected_app_id??args.rest[positionalIndex]}async function collectAppControlPlaneSnapshot(args){let[overview,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings]=await Promise.all([fetchTenantOverview({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(args.credentials),tenantId:args.tenantId}),args.sdk.listTenantAppSourceVersions(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppPublishSettings(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthDiscovery(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.listTenantAppEndUsers(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppDbInstance(args.appId,args.env).catch(()=>null),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[])]),app=overview.apps.find(item=>item.id===args.appId);if(!app)throw new Error(`\u5728\u79DF\u6237 ${args.tenantId} \u4E0B\u672A\u627E\u5230\u5E94\u7528 ${args.appId}\u3002`);return{overview,app,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings}}function buildAppStatusPayload(args){let{tenantId,appId,env,snapshot}=args,authEnabled=snapshot.authConfig?.auth_enabled===!0,appUserItems=snapshot.appUsers?.items??[],blockedCount=appUserItems.filter(item=>item.status==="blocked").length,envOverview=snapshot.overview.environments.filter(item=>item.app_id===appId),previewEnv=envOverview.find(item=>item.env==="preview"),prodEnv=envOverview.find(item=>item.env==="prod"),previewDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),latestSourceVersion=snapshot.sourceVersions.items[0]??null;return{tenant_id:tenantId,app_id:appId,env,app:{display_name:snapshot.app.name,slug:snapshot.app.slug??null,template_key:snapshot.app.template_key??null,publish_status:snapshot.publishSettings?.publish_status??snapshot.app.publish_status,source_versions_count:snapshot.sourceVersions.items.length,latest_source_version_id:latestSourceVersion?.source_version_id??null,latest_source_version_message:latestSourceVersion?.message??null,latest_deployment_class_suggested:latestSourceVersion?.deployment_class_suggested??null,latest_deployment_class_post_build:latestSourceVersion?.deployment_class_post_build??null},publish:{deployment_class_confirmed:snapshot.publishSettings?.deployment_class_confirmed??null,current_deployment_class_used:snapshot.publishSettings?.current_deployment_class_used??null,current_artifact_kind:snapshot.publishSettings?.current_artifact_kind??null,current_execution_mode:snapshot.publishSettings?.current_execution_mode??null,current_object_prefix:snapshot.publishSettings?.current_object_prefix??null,public_prod_url:snapshot.publishSettings?.public_prod_url??null},auth:{enabled:authEnabled,capability_name:snapshot.authConfig?.capability_name??"auth",capability_version:snapshot.authConfig?.capability_version??null,contract_version:snapshot.authConfig?.contract_version??null,user_store_id:snapshot.authConfig?.user_store_id??null,binding_id:snapshot.authConfig?.binding_id??null,binding_mode:snapshot.authConfig?.binding_mode??null,binding_status:snapshot.authConfig?.binding_status??null,auth_template:snapshot.authConfig?.auth_template??null,ui_driver:snapshot.authConfig?.ui_driver??null,enabled_recipes:snapshot.authConfig?.enabled_recipes??[],sign_in_methods:snapshot.authConfig?.sign_in_methods?.map(item=>item.method)??[],registration_mode:snapshot.authConfig?.registration_mode??null,auto_provision_app_user:typeof snapshot.authConfig?.auto_provision_app_user=="boolean"?snapshot.authConfig.auto_provision_app_user:null,owner_service:snapshot.authConfig?.owner_service??null,last_runtime_status:snapshot.authConfig?.last_runtime_status??null,inspect_status:snapshot.authInspect?.inspect_status??null,inspect_issues:snapshot.authInspect?.issues??[],runtime_environments:snapshot.authInspect?.environments.map(item=>({env:item.env,status:item.status,missing_binding_keys:item.missing_binding_keys,issues:item.issues,updated_at:item.updated_at??null}))??[],app_user_count:appUserItems.length,blocked_app_user_count:blockedCount},runtime:{preview:{version:previewEnv?.version??null,health:previewEnv?.health??previewDeployment?.health??null,source_version_id:previewEnv?.source_version_id??previewDeployment?.source_version_id??null,preview_url:previewDeployment?.preview_url??null},prod:{version:prodEnv?.version??null,health:prodEnv?.health??prodDeployment?.health??null,source_version_id:prodEnv?.source_version_id??prodDeployment?.source_version_id??null}},db:{bound:snapshot.dbInstance?.bound??!1,status:snapshot.dbInstance?.status??null,schema_name:snapshot.dbInstance?.schema_name??null,database_name:snapshot.dbInstance?.database_name??null,tables_count:typeof snapshot.dbInstance?.tables_count=="number"?snapshot.dbInstance.tables_count:null,latest_migration:snapshot.dbInstance?.latest_migration?.migration_path??null},workflow:{active_definition_count:snapshot.workflowDefinitions.length,binding_count:snapshot.workflowBindings.length,definitions:snapshot.workflowDefinitions.map(item=>({definition_key:item.definition_key,status:item.status,object_type:item.object_type})),bindings:snapshot.workflowBindings.map(item=>({definition_key:item.definition_key,target_id:item.target_id,target_scope:item.target_scope,status:item.status}))}}}function buildAppDiagnosePayload(args){let authEnv=args.statusPayload.auth.runtime_environments.find(item=>item.env===args.env)??null,dbTablesCount=args.statusPayload.db.tables_count,databaseStatus=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?"warning":"ready":"warning",databaseDetail=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"} (0 tables)`:`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"}`:"\u5F53\u524D\u73AF\u5883\u672A\u5B8C\u6210 DB \u7ED1\u5B9A",checks={app_context:{status:args.bindingPath?"ready":"warning",detail:args.bindingPath?`\u5DF2\u7ED1\u5B9A\u9879\u76EE\u76EE\u5F55 (${args.bindingPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/config.json`"},auth_runtime:{status:args.statusPayload.auth.enabled&&authEnv?.status==="ready"?"ready":args.statusPayload.auth.enabled?"warning":"not_configured",detail:args.statusPayload.auth.enabled?authEnv?`${args.env}=${authEnv.status}`:`\u7F3A\u5C11 ${args.env} \u8FD0\u884C\u65F6\u68C0\u67E5\u7ED3\u679C`:"\u5F53\u524D app \u672A\u542F\u7528 Auth\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u767B\u5F55\uFF0C\u53EF\u5FFD\u7565"},database:{status:databaseStatus,detail:databaseDetail},workflow:{status:args.statusPayload.workflow.active_definition_count>0&&args.statusPayload.workflow.binding_count>0?"ready":args.statusPayload.workflow.active_definition_count>0?"warning":"not_configured",detail:args.statusPayload.workflow.active_definition_count>0?`definitions=${args.statusPayload.workflow.active_definition_count}, bindings=${args.statusPayload.workflow.binding_count}`:"\u5F53\u524D app \u672A\u914D\u7F6E Workflow\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u53EF\u5FFD\u7565"},preview_runtime:{status:args.env==="preview"?args.statusPayload.runtime.preview.preview_url?"ready":"warning":args.statusPayload.runtime.prod.source_version_id?"ready":"warning",detail:args.env==="preview"?args.statusPayload.runtime.preview.preview_url??"\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u4E91\u7AEF Preview \u5730\u5740":args.statusPayload.runtime.prod.source_version_id??"\u5F53\u524D\u6CA1\u6709\u4E91\u7AEF Prod \u90E8\u7F72\u7248\u672C"},source_version:{status:args.statusPayload.app.latest_source_version_id?"ready":"warning",detail:args.statusPayload.app.latest_source_version_id??"\u5F53\u524D\u5E94\u7528\u8FD8\u6CA1\u6709\u63D0\u4EA4\u8FC7\u6E90\u7801\u7248\u672C"},source_context:{status:args.sourceContextPath?"ready":"warning",detail:args.sourceContextPath?`\u5DF2\u8BB0\u5F55\u6E90\u7801\u4E0A\u4E0B\u6587 (${args.sourceContextPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/source-context.json`"}},recommendations=[];return args.bindingPath||recommendations.push("\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>`\uFF0C\u6216\u5728\u73B0\u6709\u76EE\u5F55\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002"),args.statusPayload.app.latest_source_version_id||recommendations.push('\u6267\u884C `platform app submit --message "initial iteration"` \u751F\u6210\u9996\u4E2A\u6E90\u7801\u7248\u672C\u3002'),args.statusPayload.auth.enabled&&authEnv?.status!=="ready"&&recommendations.push(`\u6267\u884C \`platform auth inspect\` \u786E\u8BA4 ${args.env} \u73AF\u5883\u7F3A\u5931\u7684\u8FD0\u884C\u65F6\u7ED1\u5B9A\uFF0C\u518D\u6839\u636E\u7ED3\u679C\u6267\u884C \`platform resources apply --env `+args.env+"`\u3002"),args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0&&recommendations.push("\u5F53\u524D DB \u5DF2\u7ED1\u5B9A\uFF0C\u4F46 schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A `resources/db/migrations/` \u91CC\u7684\u7A7A scaffold \u6539\u6210\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate`\u3001`platform db tables`\u3002"):recommendations.push("\u5982\u679C\u5F53\u524D app \u9700\u8981 DB\uFF0C\u518D\u6267\u884C `platform resources apply --env "+args.env+"`\uFF0C\u8BA9 DB \u7ED1\u5B9A\u548C\u8FC1\u79FB\u843D\u5230\u76EE\u6807\u73AF\u5883\u3002"),args.statusPayload.workflow.active_definition_count===0?recommendations.push("\u5982\u679C\u5F53\u524D app \u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u518D\u6267\u884C `platform workflow definition create ...` \u4E0E `platform workflow binding update ...`\u3002"):args.statusPayload.workflow.binding_count===0&&recommendations.push("Workflow definition \u5DF2\u5B58\u5728\uFF0C\u4F46\u7F3A\u5C11 app \u7EA7 binding\uFF1B\u8865\u6267\u884C `platform workflow binding update ...`\u3002"),args.env==="preview"&&!args.statusPayload.runtime.preview.preview_url&&recommendations.push("\u6267\u884C `platform preview generate` \u751F\u6210\u4E91\u7AEF Preview\uFF1B\u8FD9\u4E00\u6B65\u4E0D\u540C\u4E8E\u672C\u5730 `platform dev` \u9884\u89C8\u3002"),args.env==="prod"&&!args.statusPayload.runtime.prod.source_version_id&&recommendations.push("\u4E91\u7AEF Prod \u4E0D\u4F1A\u968F\u7740 Preview \u81EA\u52A8\u66F4\u65B0\uFF1B\u5982\u9700\u4E0A\u7EBF\u6B63\u5F0F\u73AF\u5883\uFF0C\u8BF7\u6267\u884C `platform publish set --source-version <srcver> --status published`\u3002"),recommendations.length===0&&recommendations.push(args.env==="prod"?"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D prod \u5DF2\u57FA\u672C ready\uFF1B\u540E\u7EED\u82E5\u8981\u5207\u6362\u6B63\u5F0F\u7248\u672C\uFF0C\u8BF7\u7EE7\u7EED\u4F7F\u7528 `platform publish`\u3002":"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D\u5E94\u7528\u5DF2\u57FA\u672C ready\uFF1B\u4E0B\u4E00\u6B65\u53EF\u76F4\u63A5\u505A\u9875\u9762\u8054\u8C03\u6216\u8FD0\u884C\u65F6\u9A8C\u8BC1\u3002"),{tenant_id:args.tenantId,app_id:args.appId,env:args.env,checks,recommendations}}function findDevPreviewTimelineItem(items,target){return items.find(item=>item.env==="preview"&&target.deploymentId&&item.deployment_id===target.deploymentId)??items.find(item=>item.env==="preview"&&target.releaseId&&item.release_id===target.releaseId)??items.find(item=>item.env==="preview"&&item.is_current_release)??null}function formatDevPreviewLines(args){let lines=[args.title,`tenant/app: ${args.tenantId}/${args.appId}`,`source version: ${args.sourceVersionId??"-"}`,`build: ${args.buildId??"-"}`,`release: ${args.releaseId??"-"}`,`deployment: ${args.deploymentId??"-"}`];return args.previewUrl&&lines.push(`preview url: ${args.previewUrl}`),args.health&&lines.push(`health: ${args.health}`),args.healthCheckUrl&&lines.push(`health_check_url: ${args.healthCheckUrl}`),args.message&&lines.push(`message: ${args.message}`),args.failureReason&&lines.push(`failure_reason: ${args.failureReason}`),args.diagnosticUrl&&lines.push(`diagnostic_url: ${args.diagnosticUrl}`),lines}function createTenantScopedSdk(credentials,tenantId,options={}){if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");return createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:options.capability,requestClass:options.requestClass??"control"})}async function loadRemoteDbRuntimeBindings(binding,requestedBindings){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)return{values:{},cleanup:null};let env=binding.env==="prod"?"prod":"preview",sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:binding.tenant_id,capability:"db",requestClass:"control"}),result=await sdk.resolveDevRuntimeBindings({app_id:binding.app_id,env,requested_bindings:requestedBindings});if(result.mode==="unavailable")throw new Error([result.message??"\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\u3002",result.remediation,result.request_id?`request_id: ${result.request_id}`:void 0].filter(item=>!!(item&&item.trim().length>0)).join(`
|
|
2653
|
+
`);return}process7.stdout.write(formatControlApiDiagnosticsText(diagnostics))}function readIntegerOption(args,key){let raw=readOption2(args,key);if(raw===void 0)return;let value=Number(raw);if(!Number.isInteger(value))throw new Error(`\u65E0\u6548\u7684 \`--${key}\`\uFF0C\u5FC5\u987B\u662F\u6574\u6570\u3002`);return value}function readCsvOption3(args,key){let raw=readOption2(args,key);return raw?raw.split(",").map(item=>item.trim()).filter(Boolean):[]}function readJsonInput(args,key="file"){let filePath=readOption2(args,key);if(!filePath)throw new Error(`\u7F3A\u5C11 \`--${key} <path>\`\u3002`);let content=filePath==="-"?readFileSync27(0,"utf8"):readFileSync27(filePath,"utf8");try{return JSON.parse(content)}catch(error){throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON \u8F93\u5165: ${filePath==="-"?"stdin":filePath}\u3002${error instanceof Error?` ${error.message}`:""}`)}}async function findExistingTenantCmsItemForImport(args){let lookup=args.lookup;if(!lookup)return null;if(lookup.kind==="item_id")try{return{item:await args.sdk.getTenantCmsItem({collection:args.collection,id:lookup.value}),matchedBy:"item_id"}}catch(error){if(error instanceof PlatformApiError&&error.status===404)return null;throw error}let matched=(await args.sdk.listTenantCmsItems({collection:args.collection,page:1,pageSize:20,query:lookup.value})).items.find(item=>item.system.slug===lookup.value);return matched?{item:matched,matchedBy:"slug"}:null}function resolveTenantContext(args,startDir=currentInvocationDir()){let linked;try{linked=readBinding(startDir)}catch{linked=null}let storedContext=loadStoredCliContext();return readOption2(args,"tenant")??linked?.binding.tenant_id??storedContext?.selected_app_tenant_id??storedContext?.active_tenant_id}function tryReadCurrentBinding2(){try{return readBinding(currentInvocationDir())}catch{return null}}function syncSelectedAppContextFromBinding(binding){let existing=loadStoredCliContext();persistCliContext({active_tenant_id:binding.tenant_id,active_tenant_name:existing?.active_tenant_id===binding.tenant_id?existing.active_tenant_name:void 0,selected_app_tenant_id:binding.tenant_id,selected_app_id:binding.app_id,selected_app_env:binding.env,selected_app_name:binding.app_name??binding.app_id,selected_app_display_name:binding.app_display_name})}function tryReadCurrentSourceContext(){try{return readSourceContext(currentInvocationDir())}catch{return null}}function readStoredCredentialModeSafely(){try{return loadStoredCredentials()?.credential_mode}catch{return}}function readCredentialPathSafely(){try{return getCredentialPath()}catch{return}}function formatRuntimeTargetLabel(env){return env==="preview"?"\u4E91\u7AEF Preview":"\u4E91\u7AEF Prod"}function summarizePreflightAppContext(args){let binding=tryReadCurrentBinding2()?.binding??null,sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext??null,context=loadStoredCliContext(),tenantId=readOption2(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id,appId=readOption2(args,"app")??sourceContext?.app_id??binding?.app_id??context?.selected_app_id??args.rest[1],env=readOption2(args,"env")??sourceContext?.env??binding?.env??context?.selected_app_env??"preview";return sourceContext?.tenant_id&&sourceContext.app_id&&binding?.tenant_id&&binding.app_id?{status:"ready",detail:`\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A ${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:sourceContext?.tenant_id&&sourceContext.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230 source-context\uFF1A${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:binding?`${currentInvocationDir()}/.platform/config.json`:null,sourceContextPath:sourceContextResult?.path??null}:binding?.tenant_id&&binding.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230\u76EE\u5F55\u7ED1\u5B9A\uFF1A${binding.tenant_id}/${binding.app_id}/${binding.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:context?.selected_app_tenant_id&&context.selected_app_id?{status:"warning",detail:`\u5F53\u524D\u4EC5\u547D\u4E2D\u5168\u5C40 CLI \u5E94\u7528\u4E0A\u4E0B\u6587\uFF1A${context.selected_app_tenant_id}/${context.selected_app_id}/${context.selected_app_env??env}`,tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}:{status:"blocked",detail:"\u5F53\u524D\u672A\u89E3\u6790\u51FA\u53EF\u7528\u7684 tenant/app \u4E0A\u4E0B\u6587",tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}}function mergePreflightRecommendations(items){let seen=new Set,merged=[];for(let item of items){let normalized=item.trim();!normalized||seen.has(normalized)||(seen.add(normalized),merged.push(normalized))}return merged}function summarizeCheckStatuses(checks){return checks.some(item=>item.status==="blocked")?"blocked":checks.some(item=>item.status!=="ready")?"warning":"ready"}function resolveAppIdFromContext(args,positionalIndex=1){let binding=tryReadCurrentBinding2()?.binding,context=loadStoredCliContext();return readOption2(args,"app")??binding?.app_id??context?.selected_app_id??args.rest[positionalIndex]}async function collectAppControlPlaneSnapshot(args){let[overview,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings]=await Promise.all([fetchTenantOverview({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(args.credentials),tenantId:args.tenantId}),args.sdk.listTenantAppSourceVersions(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppPublishSettings(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthDiscovery(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.listTenantAppEndUsers(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppDbInstance(args.appId,args.env).catch(()=>null),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[])]),app=overview.apps.find(item=>item.id===args.appId);if(!app)throw new Error(`\u5728\u79DF\u6237 ${args.tenantId} \u4E0B\u672A\u627E\u5230\u5E94\u7528 ${args.appId}\u3002`);return{overview,app,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings}}function buildAppStatusPayload(args){let{tenantId,appId,env,snapshot}=args,authEnabled=snapshot.authConfig?.auth_enabled===!0,appUserItems=snapshot.appUsers?.items??[],blockedCount=appUserItems.filter(item=>item.status==="blocked").length,envOverview=snapshot.overview.environments.filter(item=>item.app_id===appId),previewEnv=envOverview.find(item=>item.env==="preview"),prodEnv=envOverview.find(item=>item.env==="prod"),previewDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),latestSourceVersion=snapshot.sourceVersions.items[0]??null;return{tenant_id:tenantId,app_id:appId,env,app:{display_name:snapshot.app.name,slug:snapshot.app.slug??null,template_key:snapshot.app.template_key??null,publish_status:snapshot.publishSettings?.publish_status??snapshot.app.publish_status,source_versions_count:snapshot.sourceVersions.items.length,latest_source_version_id:latestSourceVersion?.source_version_id??null,latest_source_version_message:latestSourceVersion?.message??null,latest_deployment_class_suggested:latestSourceVersion?.deployment_class_suggested??null,latest_deployment_class_post_build:latestSourceVersion?.deployment_class_post_build??null},publish:{deployment_class_confirmed:snapshot.publishSettings?.deployment_class_confirmed??null,current_deployment_class_used:snapshot.publishSettings?.current_deployment_class_used??null,current_artifact_kind:snapshot.publishSettings?.current_artifact_kind??null,current_execution_mode:snapshot.publishSettings?.current_execution_mode??null,current_object_prefix:snapshot.publishSettings?.current_object_prefix??null,public_prod_url:snapshot.publishSettings?.public_prod_url??null},auth:{enabled:authEnabled,capability_name:snapshot.authConfig?.capability_name??"auth",capability_version:snapshot.authConfig?.capability_version??null,contract_version:snapshot.authConfig?.contract_version??null,user_store_id:snapshot.authConfig?.user_store_id??null,binding_id:snapshot.authConfig?.binding_id??null,binding_mode:snapshot.authConfig?.binding_mode??null,binding_status:snapshot.authConfig?.binding_status??null,auth_template:snapshot.authConfig?.auth_template??null,ui_driver:snapshot.authConfig?.ui_driver??null,enabled_recipes:snapshot.authConfig?.enabled_recipes??[],sign_in_methods:snapshot.authConfig?.sign_in_methods?.map(item=>item.method)??[],registration_mode:snapshot.authConfig?.registration_mode??null,auto_provision_app_user:typeof snapshot.authConfig?.auto_provision_app_user=="boolean"?snapshot.authConfig.auto_provision_app_user:null,owner_service:snapshot.authConfig?.owner_service??null,last_runtime_status:snapshot.authConfig?.last_runtime_status??null,inspect_status:snapshot.authInspect?.inspect_status??null,inspect_issues:snapshot.authInspect?.issues??[],runtime_environments:snapshot.authInspect?.environments.map(item=>({env:item.env,status:item.status,missing_binding_keys:item.missing_binding_keys,issues:item.issues,updated_at:item.updated_at??null}))??[],app_user_count:appUserItems.length,blocked_app_user_count:blockedCount},runtime:{preview:{version:previewEnv?.version??null,health:previewEnv?.health??previewDeployment?.health??null,source_version_id:previewEnv?.source_version_id??previewDeployment?.source_version_id??null,preview_url:previewDeployment?.preview_url??null},prod:{version:prodEnv?.version??null,health:prodEnv?.health??prodDeployment?.health??null,source_version_id:prodEnv?.source_version_id??prodDeployment?.source_version_id??null}},db:{bound:snapshot.dbInstance?.bound??!1,status:snapshot.dbInstance?.status??null,schema_name:snapshot.dbInstance?.schema_name??null,database_name:snapshot.dbInstance?.database_name??null,tables_count:typeof snapshot.dbInstance?.tables_count=="number"?snapshot.dbInstance.tables_count:null,latest_migration:snapshot.dbInstance?.latest_migration?.migration_path??null},workflow:{active_definition_count:snapshot.workflowDefinitions.length,binding_count:snapshot.workflowBindings.length,definitions:snapshot.workflowDefinitions.map(item=>({definition_key:item.definition_key,status:item.status,object_type:item.object_type})),bindings:snapshot.workflowBindings.map(item=>({definition_key:item.definition_key,target_id:item.target_id,target_scope:item.target_scope,status:item.status}))}}}function buildAppDiagnosePayload(args){let authEnv=args.statusPayload.auth.runtime_environments.find(item=>item.env===args.env)??null,dbTablesCount=args.statusPayload.db.tables_count,databaseStatus=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?"warning":"ready":"warning",databaseDetail=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"} (0 tables)`:`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"}`:"\u5F53\u524D\u73AF\u5883\u672A\u5B8C\u6210 DB \u7ED1\u5B9A",checks={app_context:{status:args.bindingPath?"ready":"warning",detail:args.bindingPath?`\u5DF2\u7ED1\u5B9A\u9879\u76EE\u76EE\u5F55 (${args.bindingPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/config.json`"},auth_runtime:{status:args.statusPayload.auth.enabled&&authEnv?.status==="ready"?"ready":args.statusPayload.auth.enabled?"warning":"not_configured",detail:args.statusPayload.auth.enabled?authEnv?`${args.env}=${authEnv.status}`:`\u7F3A\u5C11 ${args.env} \u8FD0\u884C\u65F6\u68C0\u67E5\u7ED3\u679C`:"\u5F53\u524D app \u672A\u542F\u7528 Auth\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u767B\u5F55\uFF0C\u53EF\u5FFD\u7565"},database:{status:databaseStatus,detail:databaseDetail},workflow:{status:args.statusPayload.workflow.active_definition_count>0&&args.statusPayload.workflow.binding_count>0?"ready":args.statusPayload.workflow.active_definition_count>0?"warning":"not_configured",detail:args.statusPayload.workflow.active_definition_count>0?`definitions=${args.statusPayload.workflow.active_definition_count}, bindings=${args.statusPayload.workflow.binding_count}`:"\u5F53\u524D app \u672A\u914D\u7F6E Workflow\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u53EF\u5FFD\u7565"},preview_runtime:{status:args.env==="preview"?args.statusPayload.runtime.preview.preview_url?"ready":"warning":args.statusPayload.runtime.prod.source_version_id?"ready":"warning",detail:args.env==="preview"?args.statusPayload.runtime.preview.preview_url??"\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u4E91\u7AEF Preview \u5730\u5740":args.statusPayload.runtime.prod.source_version_id??"\u5F53\u524D\u6CA1\u6709\u4E91\u7AEF Prod \u90E8\u7F72\u7248\u672C"},source_version:{status:args.statusPayload.app.latest_source_version_id?"ready":"warning",detail:args.statusPayload.app.latest_source_version_id??"\u5F53\u524D\u5E94\u7528\u8FD8\u6CA1\u6709\u63D0\u4EA4\u8FC7\u6E90\u7801\u7248\u672C"},source_context:{status:args.sourceContextPath?"ready":"warning",detail:args.sourceContextPath?`\u5DF2\u8BB0\u5F55\u6E90\u7801\u4E0A\u4E0B\u6587 (${args.sourceContextPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/source-context.json`"}},recommendations=[];return args.bindingPath||recommendations.push("\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>`\uFF0C\u6216\u5728\u73B0\u6709\u76EE\u5F55\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002"),args.statusPayload.app.latest_source_version_id||recommendations.push('\u6267\u884C `platform app submit --message "initial iteration"` \u751F\u6210\u9996\u4E2A\u6E90\u7801\u7248\u672C\u3002'),args.statusPayload.auth.enabled&&authEnv?.status!=="ready"&&recommendations.push(`\u6267\u884C \`platform auth inspect\` \u786E\u8BA4 ${args.env} \u73AF\u5883\u7F3A\u5931\u7684\u8FD0\u884C\u65F6\u7ED1\u5B9A\uFF0C\u518D\u6839\u636E\u7ED3\u679C\u6267\u884C \`platform resources apply --env `+args.env+"`\u3002"),args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0&&recommendations.push("\u5F53\u524D DB \u5DF2\u7ED1\u5B9A\uFF0C\u4F46 schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A `resources/db/migrations/` \u91CC\u7684\u7A7A scaffold \u6539\u6210\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate`\u3001`platform db tables`\u3002"):recommendations.push("\u5982\u679C\u5F53\u524D app \u9700\u8981 DB\uFF0C\u518D\u6267\u884C `platform resources apply --env "+args.env+"`\uFF0C\u8BA9 DB \u7ED1\u5B9A\u548C\u8FC1\u79FB\u843D\u5230\u76EE\u6807\u73AF\u5883\u3002"),args.statusPayload.workflow.active_definition_count===0?recommendations.push("\u5982\u679C\u5F53\u524D app \u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u518D\u6267\u884C `platform workflow definition create ...` \u4E0E `platform workflow binding update ...`\u3002"):args.statusPayload.workflow.binding_count===0&&recommendations.push("Workflow definition \u5DF2\u5B58\u5728\uFF0C\u4F46\u7F3A\u5C11 app \u7EA7 binding\uFF1B\u8865\u6267\u884C `platform workflow binding update ...`\u3002"),args.env==="preview"&&!args.statusPayload.runtime.preview.preview_url&&recommendations.push("\u6267\u884C `platform preview generate` \u751F\u6210\u4E91\u7AEF Preview\uFF1B\u8FD9\u4E00\u6B65\u4E0D\u540C\u4E8E\u672C\u5730 `platform dev` \u9884\u89C8\u3002"),args.env==="prod"&&!args.statusPayload.runtime.prod.source_version_id&&recommendations.push("\u4E91\u7AEF Prod \u4E0D\u4F1A\u968F\u7740 Preview \u81EA\u52A8\u66F4\u65B0\uFF1B\u5982\u9700\u4E0A\u7EBF\u6B63\u5F0F\u73AF\u5883\uFF0C\u8BF7\u6267\u884C `platform publish set --source-version <srcver> --status published`\u3002"),recommendations.length===0&&recommendations.push(args.env==="prod"?"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D prod \u5DF2\u57FA\u672C ready\uFF1B\u540E\u7EED\u82E5\u8981\u5207\u6362\u6B63\u5F0F\u7248\u672C\uFF0C\u8BF7\u7EE7\u7EED\u4F7F\u7528 `platform publish`\u3002":"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D\u5E94\u7528\u5DF2\u57FA\u672C ready\uFF1B\u4E0B\u4E00\u6B65\u53EF\u76F4\u63A5\u505A\u9875\u9762\u8054\u8C03\u6216\u8FD0\u884C\u65F6\u9A8C\u8BC1\u3002"),{tenant_id:args.tenantId,app_id:args.appId,env:args.env,checks,recommendations}}function findDevPreviewTimelineItem(items,target){return items.find(item=>item.env==="preview"&&target.deploymentId&&item.deployment_id===target.deploymentId)??items.find(item=>item.env==="preview"&&target.releaseId&&item.release_id===target.releaseId)??items.find(item=>item.env==="preview"&&item.is_current_release)??null}function formatDevPreviewLines(args){let lines=[args.title,`tenant/app: ${args.tenantId}/${args.appId}`,`source version: ${args.sourceVersionId??"-"}`,`build: ${args.buildId??"-"}`,`release: ${args.releaseId??"-"}`,`deployment: ${args.deploymentId??"-"}`];return args.previewUrl&&lines.push(`preview url: ${args.previewUrl}`),args.health&&lines.push(`health: ${args.health}`),args.healthCheckUrl&&lines.push(`health_check_url: ${args.healthCheckUrl}`),args.message&&lines.push(`message: ${args.message}`),args.failureReason&&lines.push(`failure_reason: ${args.failureReason}`),args.diagnosticUrl&&lines.push(`diagnostic_url: ${args.diagnosticUrl}`),lines}function createTenantScopedSdk(credentials,tenantId,options={}){if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");return createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:options.capability,requestClass:options.requestClass??"control"})}async function loadRemoteDbRuntimeBindings(binding,requestedBindings){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)return{values:{},cleanup:null};let env=binding.env==="prod"?"prod":"preview",sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:binding.tenant_id,capability:"db",requestClass:"control"}),result=await sdk.resolveDevRuntimeBindings({app_id:binding.app_id,env,requested_bindings:requestedBindings});if(result.mode==="unavailable")throw new Error([result.message??"\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\u3002",result.remediation,result.request_id?`request_id: ${result.request_id}`:void 0].filter(item=>!!(item&&item.trim().length>0)).join(`
|
|
2648
2654
|
`));return{values:result.values,cleanup:result.session_id?async()=>{try{await sdk.revokeDevRuntimeBindings({app_id:binding.app_id,env,session_id:result.session_id})}catch{}}:null}}function resolveRequestedRemoteBindings(args,startDir=process7.cwd()){let explicitValue=readOption2(args,"remote-bindings")?.trim().toLowerCase();if(!explicitValue||explicitValue==="auto")return{capabilities:detectRequestedRemoteBindings(startDir),mode:"auto"};if(explicitValue==="db")return{capabilities:["db"],mode:"db"};throw new Error("`platform dev --remote-bindings` \u76EE\u524D\u4EC5\u652F\u6301 `auto` \u6216 `db`\u3002")}async function runLogin(args){let issuer=readRequiredEnv("OIDC_ISSUER"),audience=process7.env.OIDC_AUDIENCE?.trim(),scopes=(process7.env.LOGTO_CLI_SCOPES??"openid profile offline_access").split(/\s+/u).filter(Boolean),cliClientId=readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS),browserLoginConfig=resolveBrowserLoginConfig(),pat=readOption2(args,"pat")?.trim(),credentials;if(pat){if(!cliClientId)throw new Error("`platform login --pat` \u9700\u8981\u5DF2\u914D\u7F6E `AUTH_CLI_CLIENT_ID`\uFF08\u6216\u517C\u5BB9\u65E7\u540D `LOGTO_CLI_APP_ID`\uFF09\u3002");credentials=await performPatTokenExchangeLogin({issuer,clientId:cliClientId,audience,scopes,subjectToken:pat}),persistCredentials(credentials),process7.stdout.write(["PAT \u767B\u5F55\u5DF2\u5B8C\u6210\u3002",`\u51ED\u636E\u5DF2\u5199\u5165: ${getCredentialPath()}`,"\u8BF4\u660E: \u5F53\u524D\u4E3A\u673A\u5668\u51ED\u636E\u6A21\u5F0F\uFF0CCLI \u4F1A\u5728 7 \u5929\u7A97\u53E3\u5185\u81EA\u52A8\u91CD\u65B0\u4EA4\u6362 access token\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A"," 1. platform whoami"," 2. \u5982\u9700\u957F\u671F\u4EBA\u5DE5\u5F00\u53D1\uFF0C\u4F18\u5148\u6539\u7528 `platform login` \u6D4F\u89C8\u5668\u767B\u5F55",""].join(`
|
|
2649
2655
|
`));return}if(cliClientId)try{credentials=await performDeviceCodeLogin({issuer,clientId:cliClientId,audience,scopes,onPrompt:async({verificationUri,userCode,expiresIn})=>{let{opened}=await openExternal(verificationUri);process7.stdout.write((opened?["\u5DF2\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u6388\u6743\u3002",""]:["\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u767B\u5F55\u6388\u6743\u3002",`\u9A8C\u8BC1\u5730\u5740: ${verificationUri}`,`User Code: ${userCode}`,`\u6709\u6548\u671F: ${expiresIn} \u79D2`,""]).join(`
|
|
2650
2656
|
`))}})}catch(error){if(!shouldFallbackToBrowserLogin(error))throw error;if(process7.stdout.write(`\u5F53\u524D\u73AF\u5883\u4E0D\u53EF\u7528 Device Flow\uFF0C\u81EA\u52A8\u5207\u6362\u5230\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\u3002
|
|
@@ -2673,7 +2679,8 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2673
2679
|
- `)}`:"\u65B0\u5EFA\u6587\u4EF6: -",result.updatedFiles.length>0?`\u66F4\u65B0\u6587\u4EF6:
|
|
2674
2680
|
- ${result.updatedFiles.join(`
|
|
2675
2681
|
- `)}`:"\u66F4\u65B0\u6587\u4EF6: -",`\u8BBF\u95EE\u8DEF\u5F84: ${result.routePath}`,"\u8BF4\u660E: \u8FD9\u662F\u6309\u9700\u8054\u8C03\u7528\u811A\u624B\u67B6\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728\u6B63\u5F0F\u4E1A\u52A1\u9875\u91CC\u3002",""].join(`
|
|
2676
|
-
`));return}if(subcommand==="sync-platform-blocks"){let rollback=hasFlag2(args,"rollback"),last=hasFlag2(args,"last");if(rollback&&!last)throw new Error("`platform app sync-platform-blocks --rollback` \u76EE\u524D\u53EA\u652F\u6301 `--last`\u3002");
|
|
2682
|
+
`));return}if(subcommand==="sync-platform-blocks"){let rollback=hasFlag2(args,"rollback"),last=hasFlag2(args,"last");if(rollback&&!last)throw new Error("`platform app sync-platform-blocks --rollback` \u76EE\u524D\u53EA\u652F\u6301 `--last`\u3002");let result=runAppSyncPlatformBlocksCommand({cwd:readOption2(args,"dir")??currentInvocationDir(),apply:hasFlag2(args,"apply"),adopt:hasFlag2(args,"adopt"),rollbackLast:rollback&&last,verify:hasFlag2(args,"verify")});process7.stdout.write(hasFlag2(args,"json")?`${JSON.stringify(result,null,2)}
|
|
2683
|
+
`:formatAppSyncPlatformBlocksResult(result));return}let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:resolveTenantContext(args),capability:"dashboard",requestClass:"control"});if(subcommand==="create"){let tenantId2=resolveTenantContext(args),displayName=readOption2(args,"name")??args.rest[1];if(!tenantId2||!displayName?.trim())throw new Error("`platform app create` \u9700\u8981 `--tenant` \u6216\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u4EE5\u53CA `--name`\u3002");let templateKey=normalizeAppTemplateOption(readOption2(args,"template"))??DEFAULT_APP_TEMPLATE_KEY,created=await sdk.createTenantApp({name:displayName.trim(),slug:readOption2(args,"slug"),template_key:templateKey});persistCliContext({active_tenant_id:created.tenant_id,selected_app_tenant_id:created.tenant_id,selected_app_id:created.app_id,selected_app_env:"preview",selected_app_name:created.name,selected_app_display_name:created.display_name});let requestedTargetDir=readOption2(args,"dir"),checkout;try{checkout=await checkoutAppWorkspace({sdk,tenantId:created.tenant_id,appId:created.app_id,env:"preview",targetDir:requestedTargetDir})}catch(error){throw formatAppCreateCheckoutError({cause:error,tenantId:created.tenant_id,appId:created.app_id,targetDir:requestedTargetDir})}process7.stdout.write([`\u4E91\u7AEF\u5E94\u7528\u5DF2\u521B\u5EFA\uFF1A${created.display_name} (${created.app_id})`,`\u6A21\u677F\uFF1A${created.template_key}`,"\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A",` 1. cd ${checkout.targetDir}`," 2. platform dev",""].join(`
|
|
2677
2684
|
`));return}if(subcommand==="checkout"){let tenantId2=resolveTenantContext(args),appId2=readOption2(args,"app")??args.rest[1],env2=readOption2(args,"env")??"preview",sourceVersionId=readOption2(args,"source-version");if(!tenantId2||!appId2)throw new Error("`platform app checkout` \u9700\u8981 `--tenant` \u6216\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u4EE5\u53CA `--app`\u3002");persistCliContext({active_tenant_id:tenantId2,selected_app_tenant_id:tenantId2,selected_app_id:appId2,selected_app_env:env2,selected_app_name:appId2});let checkout=await checkoutAppWorkspace({sdk,tenantId:tenantId2,appId:appId2,env:env2,targetDir:readOption2(args,"dir"),sourceVersionId});process7.stdout.write(["\u4E91\u7AEF\u6E90\u7801\u526F\u672C\u5DF2 checkout \u5230\u672C\u5730\u65B0\u76EE\u5F55\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A",` 1. cd ${checkout.targetDir}`," 2. platform dev",""].join(`
|
|
2678
2685
|
`));return}if(subcommand==="submit"){let binding=tryReadCurrentBinding2()?.binding,tenantId2=readOption2(args,"tenant")??binding?.tenant_id??resolveTenantContext(args),appId2=readOption2(args,"app")??binding?.app_id;if(!tenantId2||!appId2)throw new Error("`platform app submit` \u9700\u8981\u5728\u5DF2\u7ED1\u5B9A\u7684\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let checkedAppRoot=findAppRoot(currentInvocationDir());assertSourceWorkspaceCloudUploadPolicy(checkedAppRoot,"platform app submit");let{files,appRoot}=collectSourceWorkspaceFiles(checkedAppRoot),pathBaseViolations=detectPathBaseRuntimeViolations(files);if(readOption2(args,"template"))throw new Error("`platform app submit` \u4E0D\u652F\u6301 `--template`\u3002\u82E5\u4F60\u8981\u57FA\u4E8E\u65B0\u6A21\u677F\u521B\u5EFA\u7248\u672C\uFF0C\u8BF7\u6539\u7528 `platform app version create --template <template-key>`\u3002");if(pathBaseViolations.length>0){let examples=pathBaseViolations.slice(0,8).map(item=>`- ${item.path}:${item.line} ${item.snippet}`).join(`
|
|
2679
2686
|
`);throw new Error(["\u68C0\u6D4B\u5230 path-base \u9AD8\u98CE\u9669\u5199\u6CD5\uFF0C\u5DF2\u963B\u6B62\u63D0\u4EA4\u3002",'preview/prod \u9ED8\u8BA4\u4EE5\u8DEF\u5F84\u524D\u7F00\u90E8\u7F72\uFF0C\u6D4F\u89C8\u5668\u4FA7\u4E0D\u8981\u76F4\u63A5\u5199\u6839\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 `fetch(\'/api/...\')`\u3001`href="/..."`\u3001`src="/..."`\u3002',"\u8BF7\u6539\u7528 `buildRuntimePath(...)`\u3001`buildAuthUrl(...)`\uFF0C\u6216\u76F8\u5BF9\u8DEF\u5F84 `./api/...`\u3002","\u547D\u4E2D\u793A\u4F8B\uFF1A",examples].join(`
|
|
@@ -2687,7 +2694,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2687
2694
|
`))}function printAppHelp(subcommand){switch(subcommand){case"create":process7.stdout.write(["platform app create","","\u7528\u6CD5\uFF1A"," platform app create --tenant <tenant-id> --name <display-name> [--dir <project-name>] [--slug <slug>] [--template <key>]","","\u4F5C\u7528\uFF1A"," \u5728\u4E91\u7AEF\u521B\u5EFA\u5E94\u7528\uFF0C\u5E76\u81EA\u52A8 checkout \u5230\u672C\u5730\u76EE\u5F55\u3002","","\u652F\u6301\u6A21\u677F\uFF1A"," frontend-app-vite \u9ED8\u8BA4\u63A8\u8350\u6A21\u677F\uFF08\u9759\u6001\u4F18\u5148 / \u7B2C\u4E09\u65B9\u8BBE\u8BA1\u4EA7\u7269\u63A5\u5165 / Vite / React / Tailwind\uFF09"," backend-app-node Runtime \u6A21\u677F\uFF08Node server + shared web scaffold\uFF09",""].join(`
|
|
2688
2695
|
`));return;case"checkout":process7.stdout.write(["platform app checkout","","\u7528\u6CD5\uFF1A"," platform app checkout --tenant <tenant-id> --app <app-id> [--dir <project-name>] [--env preview|prod] [--source-version <srcver>]","","\u4F5C\u7528\uFF1A"," \u4ECE\u4E91\u7AEF\u56DE\u62C9\u5E94\u7528\u6E90\u7801\u5230\u672C\u5730\u65B0\u76EE\u5F55\u3002",""].join(`
|
|
2689
2696
|
`));return;case"submit":process7.stdout.write(["platform app submit","","\u7528\u6CD5\uFF1A",' platform app submit [--message "local iteration"] [--tenant <tenant-id>] [--app <app-id>]',"","\u4F5C\u7528\uFF1A"," \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u63D0\u4EA4\u4E3A\u65B0\u7684\u6E90\u7801\u7248\u672C\u3002"," \u82E5\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A\u5E94\u7528\uFF08\u5B58\u5728 `.platform/source-context.json`\uFF09\uFF0C\u53EF\u76F4\u63A5\u63D0\u4EA4\uFF0C\u65E0\u9700\u5148\u6267\u884C `platform app use`\u3002"," \u4E0D\u652F\u6301\u5728\u63D0\u4EA4\u65F6\u5207\u6362\u6A21\u677F\uFF1B\u82E5\u4F60\u8981\u57FA\u4E8E\u65B0\u6A21\u677F\u521B\u5EFA\u7248\u672C\uFF0C\u8BF7\u4F7F\u7528 `platform app version create --template <template-key>`\u3002"," \u8BF4\u660E\uFF1A`-h/--help` \u73B0\u5728\u53EA\u663E\u793A\u5E2E\u52A9\uFF0C\u4E0D\u4F1A\u518D\u771F\u7684\u63D0\u4EA4\u6E90\u7801\u3002",""].join(`
|
|
2690
|
-
`));return;case"sync-platform-blocks":process7.stdout.write(["platform app sync-platform-blocks","","\u7528\u6CD5\uFF1A"," platform app sync-platform-blocks [--dry-run]"," platform app sync-platform-blocks --adopt"," platform app sync-platform-blocks --apply [--verify]"," platform app sync-platform-blocks --rollback --last","","\u4F5C\u7528\uFF1A"," \u5728\u5F53\u524D\u672C\u5730 app \u5DE5\u7A0B\u5185\u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\u3002"," \u9ED8\u8BA4\u6267\u884C dry-run\uFF1B\u5386\u53F2 app \u5148\u7528 `--adopt` \u8865 lockfile\uFF0C\u518D\u6267\u884C `--apply`\u3002"," `--verify` \u4F1A\
|
|
2697
|
+
`));return;case"sync-platform-blocks":process7.stdout.write(["platform app sync-platform-blocks","","\u7528\u6CD5\uFF1A"," platform app sync-platform-blocks [--dry-run]"," platform app sync-platform-blocks --adopt"," platform app sync-platform-blocks --apply [--verify]"," platform app sync-platform-blocks --verify [--json]"," platform app sync-platform-blocks --rollback --last","","\u4F5C\u7528\uFF1A"," \u5728\u5F53\u524D\u672C\u5730 app \u5DE5\u7A0B\u5185\u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\u3002"," \u9ED8\u8BA4\u6267\u884C dry-run\uFF1B\u5386\u53F2 app \u5148\u7528 `--adopt` \u8865 lockfile\uFF0C\u518D\u6267\u884C `--apply`\u3002"," `--verify` \u4F1A\u8FDB\u7A0B\u5185\u68C0\u67E5\u5F53\u524D manifest\u3001lockfile \u4E0E\u6258\u7BA1\u6587\u4EF6\u662F\u5426\u4E00\u81F4\uFF0C\u4E0D\u4F9D\u8D56 Bash\u3002",""].join(`
|
|
2691
2698
|
`));return;case"version:create":process7.stdout.write(["platform app version create","","\u7528\u6CD5\uFF1A",' platform app version create [--message "local iteration"] --template <template-key> [--tenant <tenant-id>] [--app <app-id>]',"","\u4F5C\u7528\uFF1A"," \u5728\u5F53\u524D app \u4E0B\u57FA\u4E8E\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684\u6E90\u7801\u7248\u672C\u9AA8\u67B6\u3002"," \u8FD9\u4E0D\u4F1A\u65B0\u5EFA app\uFF0C\u4E5F\u4E0D\u4F1A\u8FC1\u79FB\u4E1A\u52A1\u6570\u636E\uFF1B\u540C\u4E00\u4E2A app \u4E0B\u65E2\u6709 DB / \u7EC8\u7AEF\u7528\u6237\u7B49\u8D44\u6E90\u4F1A\u7EE7\u7EED\u590D\u7528\u3002"," \u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A\u5E94\u7528\u65F6\uFF0C\u53EF\u76F4\u63A5\u6267\u884C\uFF0C\u65E0\u9700\u5148 `platform app use`\u3002",""].join(`
|
|
2692
2699
|
`));return;case"version:list":process7.stdout.write(["platform app version list","","\u7528\u6CD5\uFF1A"," platform app version list --tenant <tenant-id> --app <app-id>","","\u4F5C\u7528\uFF1A"," \u67E5\u770B\u5F53\u524D app \u4E0B\u5DF2\u6709\u6E90\u7801\u7248\u672C\u53CA\u5176\u6A21\u677F\u3002",""].join(`
|
|
2693
2700
|
`));return;case"versions":process7.stdout.write(["platform app versions","","\u7528\u6CD5\uFF1A"," platform app versions --tenant <tenant-id> --app <app-id>","","\u4F5C\u7528\uFF1A"," \u67E5\u770B\u5E94\u7528\u5DF2\u6709\u7684\u6E90\u7801\u7248\u672C\u5217\u8868\u3002",""].join(`
|
|
@@ -2709,13 +2716,15 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2709
2716
|
`));return}let timeline=await sdk.listTenantAppDeploymentTimeline(appId,{limit:10}).catch(()=>({items:[]})),previewItem=findDevPreviewTimelineItem(timeline.items,{deploymentId:response.deployment_id,releaseId:response.release_id});process7.stdout.write([...formatDevPreviewLines({title:"\u5DE5\u4F5C\u533A Preview \u5DF2\u751F\u6210\u3002",tenantId,appId,releaseId:response.release_id,deploymentId:response.deployment_id,buildId:previewItem?.build_id??response.build_id??null,sourceVersionId:previewItem?.source_version_id??response.source_version_id??null,previewUrl:previewItem?.preview_url??response.runtime.preview_url??null,health:previewItem?.health??response.runtime.health??null,healthCheckUrl:previewItem?.health_check_url??null,message:previewItem?.message??response.runtime.message??null,failureReason:previewItem?.failure_reason??response.runtime.failure_reason??null,diagnosticUrl:previewItem?.diagnostic_url??response.runtime.diagnostic_url??null}),"\u4E0B\u4E00\u6B65: \u82E5\u9875\u9762\u5F02\u5E38\uFF0C\u4F18\u5148\u8BB0\u5F55 build/release/deployment/source version\uFF0C\u518D\u6392\u67E5\u5BF9\u5E94\u8BCA\u65AD\u4E0E\u65E5\u5FD7\u3002",""].join(`
|
|
2710
2717
|
`));return}if(action==="open"){let credentials=await loadStoredCredentialsEnsuringFresh(),binding=tryReadCurrentBinding2()?.binding,tenantId=readOption2(args,"tenant")??binding?.tenant_id??resolveTenantContext(args),appId=readOption2(args,"app")??binding?.app_id??resolveAppIdFromContext(args,3);if(!tenantId||!appId)throw new Error("`platform dev preview open` \u9700\u8981\u5728\u5DF2\u7ED1\u5B9A\u7684\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let sdk=createTenantScopedSdk(credentials,tenantId,{capability:"dashboard"});try{let preview=await sdk.getTenantAppDevWorkspacePreview(appId),timeline=await sdk.listTenantAppDeploymentTimeline(appId,{limit:10}).catch(()=>({items:[]})),previewItem=findDevPreviewTimelineItem(timeline.items,{deploymentId:preview.deployment_id,releaseId:preview.release_id}),{opened}=await openExternal(preview.preview_url);process7.stdout.write([...formatDevPreviewLines({title:"\u5DE5\u4F5C\u533A Preview \u5DF2\u5B9A\u4F4D\u3002",tenantId:preview.tenant_id,appId:preview.app_id,releaseId:preview.release_id,deploymentId:preview.deployment_id,buildId:previewItem?.build_id??preview.build_id??null,sourceVersionId:previewItem?.source_version_id??preview.source_version_id??null,previewUrl:preview.preview_url,health:previewItem?.health??preview.health??null,healthCheckUrl:previewItem?.health_check_url??null,message:previewItem?.message??null,failureReason:previewItem?.failure_reason??null,diagnosticUrl:previewItem?.diagnostic_url??null}),opened?"\u5DF2\u5C1D\u8BD5\u5728\u9ED8\u8BA4\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u3002":"\u672A\u80FD\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u590D\u5236 preview_url\u3002",""].join(`
|
|
2711
2718
|
`))}catch(error){throw error instanceof PlatformApiError&&(error.code==="dev_workspace_preview_not_found"||error.code==="dev_workspace_preview_not_current"||error.code==="dev_workspace_preview_not_ready")?new Error([error.message,"\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A\u5148\u6267\u884C `platform dev preview generate`\uFF1B\u5982\u679C\u5F53\u524D Preview \u5DF2\u88AB\u6B63\u5F0F\u7248\u672C\u66FF\u6362\uFF0C\u9700\u8981\u91CD\u65B0\u751F\u6210\u5DE5\u4F5C\u533A Preview\u3002"].join(`
|
|
2712
|
-
`)):error}return}throw new Error(`\u672A\u77E5 dev preview \u5B50\u547D\u4EE4: ${action}`)}let target=readOption2(args,"target"),initialRuntime=collectDevPreflight(process7.cwd(),target),runtimeBindings={},bindingWarnings=[],cleanupRemoteBindings=null,remoteBindingsValue=args.options["remote-bindings"],enableRemoteBindings=remoteBindingsValue===!0||typeof remoteBindingsValue=="string",requestedRemoteBindings=enableRemoteBindings?resolveRequestedRemoteBindings(args):null;if(enableRemoteBindings)if((requestedRemoteBindings?.capabilities.length??0)===0)bindingWarnings.push(requestedRemoteBindings?.mode==="auto"?"\u5DF2\u542F\u7528 `--remote-bindings`\uFF0C\u4F46\u5F53\u524D\u5DE5\u4F5C\u533A\u672A\u68C0\u6D4B\u5230\u771F\u5B9E DB migration\uFF1B\u672C\u6B21\u8DF3\u8FC7\u8FDC\u7AEF DB binding\u3002\u82E5\u4F60\u786E\u8BA4\u9700\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u53EF\u663E\u5F0F\u6267\u884C `platform dev --remote-bindings=db`\u3002":"\u5DF2\u542F\u7528 `--remote-bindings`\uFF0C\u4F46\u5F53\u524D\u672A\u8BF7\u6C42\u4EFB\u4F55\u53EF\u7528\u7684\u8FDC\u7AEF binding\u3002");else try{let remoteBindings=await loadRemoteDbRuntimeBindings(initialRuntime.binding,requestedRemoteBindings.capabilities);runtimeBindings=remoteBindings.values;let preparedBindings=await prepareLocalDevDatabaseBindings(runtimeBindings,{sshHost:process7.env.TEST_ENV_SSH_HOST});runtimeBindings=preparedBindings.bindings,cleanupRemoteBindings=async()=>{await preparedBindings.cleanup?.(),await remoteBindings.cleanup?.()},bindingWarnings.push(...preparedBindings.warnings)}catch(error){bindingWarnings.push(error instanceof Error?`\u8FDC\u7AEF DB binding \u62C9\u53D6\u5931\u8D25\uFF0C\u5C06\u56DE\u9000\u5230\u672C\u5730\u73AF\u5883\u53D8\u91CF\uFF1A${error.message}`:"\u8FDC\u7AEF DB binding \u62C9\u53D6\u5931\u8D25\uFF0C\u5C06\u56DE\u9000\u5230\u672C\u5730\u73AF\u5883\u53D8\u91CF\u3002")}else bindingWarnings.push("\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\u9ED8\u8BA4\u4E0D\u4E3B\u52A8\u62C9\u53D6\u8FDC\u7AEF binding\uFF1B\u5982\u9700\u6309\u5DE5\u4F5C\u533A\u58F0\u660E\u81EA\u52A8\u5C1D\u8BD5\u8FDC\u7AEF\u80FD\u529B\uFF0C\u8BF7\u6267\u884C `platform dev --remote-bindings`\uFF1B\u5982\u9700\u663E\u5F0F\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u8BF7\u6267\u884C `platform dev --remote-bindings=db`\u3002");let runtime=collectDevPreflight(process7.cwd(),target,runtimeBindings),autoRestartEnabled=runtime.manifest.dev.auto_restart===!0,hasLocalPageRenderRegistry=
|
|
2719
|
+
`)):error}return}throw new Error(`\u672A\u77E5 dev preview \u5B50\u547D\u4EE4: ${action}`)}let target=readOption2(args,"target"),initialRuntime=collectDevPreflight(process7.cwd(),target),runtimeBindings={},bindingWarnings=[],cleanupRemoteBindings=null,remoteBindingsValue=args.options["remote-bindings"],enableRemoteBindings=remoteBindingsValue===!0||typeof remoteBindingsValue=="string",requestedRemoteBindings=enableRemoteBindings?resolveRequestedRemoteBindings(args):null;if(enableRemoteBindings)if((requestedRemoteBindings?.capabilities.length??0)===0)bindingWarnings.push(requestedRemoteBindings?.mode==="auto"?"\u5DF2\u542F\u7528 `--remote-bindings`\uFF0C\u4F46\u5F53\u524D\u5DE5\u4F5C\u533A\u672A\u68C0\u6D4B\u5230\u771F\u5B9E DB migration\uFF1B\u672C\u6B21\u8DF3\u8FC7\u8FDC\u7AEF DB binding\u3002\u82E5\u4F60\u786E\u8BA4\u9700\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u53EF\u663E\u5F0F\u6267\u884C `platform dev --remote-bindings=db`\u3002":"\u5DF2\u542F\u7528 `--remote-bindings`\uFF0C\u4F46\u5F53\u524D\u672A\u8BF7\u6C42\u4EFB\u4F55\u53EF\u7528\u7684\u8FDC\u7AEF binding\u3002");else try{let remoteBindings=await loadRemoteDbRuntimeBindings(initialRuntime.binding,requestedRemoteBindings.capabilities);runtimeBindings=remoteBindings.values;let preparedBindings=await prepareLocalDevDatabaseBindings(runtimeBindings,{sshHost:process7.env.TEST_ENV_SSH_HOST});runtimeBindings=preparedBindings.bindings,cleanupRemoteBindings=async()=>{await preparedBindings.cleanup?.(),await remoteBindings.cleanup?.()},bindingWarnings.push(...preparedBindings.warnings)}catch(error){bindingWarnings.push(error instanceof Error?`\u8FDC\u7AEF DB binding \u62C9\u53D6\u5931\u8D25\uFF0C\u5C06\u56DE\u9000\u5230\u672C\u5730\u73AF\u5883\u53D8\u91CF\uFF1A${error.message}`:"\u8FDC\u7AEF DB binding \u62C9\u53D6\u5931\u8D25\uFF0C\u5C06\u56DE\u9000\u5230\u672C\u5730\u73AF\u5883\u53D8\u91CF\u3002")}else bindingWarnings.push("\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\u9ED8\u8BA4\u4E0D\u4E3B\u52A8\u62C9\u53D6\u8FDC\u7AEF binding\uFF1B\u5982\u9700\u6309\u5DE5\u4F5C\u533A\u58F0\u660E\u81EA\u52A8\u5C1D\u8BD5\u8FDC\u7AEF\u80FD\u529B\uFF0C\u8BF7\u6267\u884C `platform dev --remote-bindings`\uFF1B\u5982\u9700\u663E\u5F0F\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u8BF7\u6267\u884C `platform dev --remote-bindings=db`\u3002");let runtime=collectDevPreflight(process7.cwd(),target,runtimeBindings),autoRestartEnabled=runtime.manifest.dev.auto_restart===!0,hasLocalPageRenderRegistry=existsSync25(`${runtime.cwd}/page-render/registry.json`),recommendedDevCommand=enableRemoteBindings?null:recommendDevCommandForTemplate(runtime.templateKey,{requestedRemoteBindings:requestedRemoteBindings?.capabilities??[]}),dependencyInstallWarning=await ensureLocalDevDependencies(runtime.cwd),explicitPort=typeof process7.env.PORT=="string"&&process7.env.PORT.trim().length>0,explicitBaseUrl=typeof process7.env.PUBLIC_APP_BASE_URL=="string"&&process7.env.PUBLIC_APP_BASE_URL.trim().length>0||typeof runtimeBindings.PUBLIC_APP_BASE_URL=="string"&&runtimeBindings.PUBLIC_APP_BASE_URL.trim().length>0;if(!explicitPort&&!explicitBaseUrl){let preferredPort=Number(runtime.manifest.entry.port||3e3),resolvedPort=await resolveAvailableLocalDevPort(preferredPort);resolvedPort.reusedPreferred||(runtime.env.PORT=String(resolvedPort.port),runtime.env.PUBLIC_APP_BASE_URL=`http://127.0.0.1:${resolvedPort.port}`,runtime.healthcheckUrl=`http://localhost:${resolvedPort.port}${runtime.manifest.entry.health_check||"/healthz"}`,runtime.warnings=runtime.warnings.map(warning=>warning.startsWith("\u672A\u663E\u5F0F\u914D\u7F6E PUBLIC_APP_BASE_URL\uFF1B\u672C\u5730 dev \u5DF2\u4E34\u65F6\u56DE\u9000\u4E3A ")?`\u672A\u663E\u5F0F\u914D\u7F6E PUBLIC_APP_BASE_URL\uFF1B\u672C\u5730 dev \u5DF2\u4E34\u65F6\u56DE\u9000\u4E3A ${runtime.env.PUBLIC_APP_BASE_URL}\u3002`:warning),runtime.warnings.unshift(`\u68C0\u6D4B\u5230\u672C\u5730\u7AEF\u53E3 ${preferredPort} \u5DF2\u88AB\u5360\u7528\uFF1BCLI \u5DF2\u81EA\u52A8\u56DE\u9000\u5230\u53EF\u7528\u7AEF\u53E3 ${resolvedPort.port}\u3002\u82E5\u4F60\u8981\u56FA\u5B9A\u7AEF\u53E3\uFF0C\u8BF7\u663E\u5F0F\u8BBE\u7F6E \`PORT\` \u4E0E \`PUBLIC_APP_BASE_URL\`\u3002`))}hasLocalPageRenderRegistry&&(runtime.warnings.unshift("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF1A\u672C\u5730 `platform dev` \u4E0B\uFF0C\u5DF2\u6CE8\u518C\u9875\u9762\u8DEF\u7531\u4F1A\u4F18\u5148\u6620\u5C04\u5230\u672C\u5730 HTML \u6A21\u677F\uFF0C\u7528\u4E8E\u7ED3\u6784/\u6837\u5F0F/\u57FA\u7840\u4EA4\u4E92\u9884\u89C8\uFF1B\u6B63\u5F0F\u9996\u5C4F HTML \u4ECD\u4EE5 preview / prod \u7684\u5E73\u53F0\u9875\u9762\u6E32\u67D3\u7ED3\u679C\u4E3A\u51C6\u3002"),enableRemoteBindings&&runtime.warnings.unshift("`platform dev --remote-bindings` \u53EA\u589E\u5F3A\u5E73\u53F0 API / Auth / CMS / DB \u7B49\u8054\u8C03\u80FD\u529B\uFF0C\u4E0D\u4F1A\u628A\u672C\u5730 dev \u5207\u6362\u6210\u5E73\u53F0\u670D\u52A1\u7AEF HTML \u6E32\u67D3\u3002")),enableRemoteBindings&&(bindingWarnings.push(`\u5DF2\u542F\u7528 \`--remote-bindings\`\uFF1ACLI \u4F1A\u6CE8\u5165\u771F\u5B9E\u5E73\u53F0\u7ED1\u5B9A\uFF0C\u5E76\u6CBF\u7528\u4E0E \`platform dev\` \u76F8\u540C\u7684${autoRestartEnabled?"\u81EA\u52A8\u91CD\u542F":"\u5355\u6B21\u542F\u52A8"}\u6A21\u5F0F\u3002`),bindingWarnings.push("\u82E5\u8054\u8C03 CMS / DB / Auth \u4ECD\u5F02\u5E38\uFF0C\u4F18\u5148\u6267\u884C `platform app diagnose --env preview` \u786E\u8BA4\u76EE\u6807\u5E94\u7528\u5F53\u524D\u72B6\u6001\u3002")),runtime.warnings.unshift(...bindingWarnings),dependencyInstallWarning&&runtime.warnings.unshift(dependencyInstallWarning);let hasLocalCredentials=!!loadStoredCredentials();process7.stdout.write(["dev preflight \u901A\u8FC7\u3002","\u6A21\u5F0F: \u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09",`tenant/app/env: ${runtime.binding.tenant_id}/${runtime.binding.app_id}/${runtime.binding.env}`,"\u4E0A\u4E0B\u6587\u6765\u6E90: \u5F53\u524D\u76EE\u5F55 .platform/source-context.json",`CLI \u767B\u5F55\u6001: ${hasLocalCredentials?"\u5DF2\u68C0\u6D4B\u5230\u672C\u5730\u51ED\u636E":"\u672A\u68C0\u6D4B\u5230\u672C\u5730\u51ED\u636E\uFF08\u4EC5\u672C\u5730\u9875\u9762\u5F00\u53D1\u53EF\u7EE7\u7EED\uFF1B\u82E5\u9700\u63A7\u5236\u9762\u80FD\u529B\u8BF7\u5148\u6267\u884C `platform login`\uFF09"}`,`\u5DE5\u4F5C\u76EE\u5F55: ${runtime.cwd}`,`\u542F\u52A8\u547D\u4EE4: ${runtime.command}`,`\u5EFA\u8BAE\u547D\u4EE4: ${recommendedDevCommand||"\u4FDD\u6301\u5F53\u524D `platform dev` \u5373\u53EF"}`,autoRestartEnabled?`\u6587\u4EF6\u76D1\u542C\u76EE\u5F55: ${runtime.cwd}`:"\u6587\u4EF6\u76D1\u542C\u76EE\u5F55: \u672A\u542F\u7528\uFF08\u9700\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\uFF09",runtime.previewAddressMayChange?`\u672C\u5730\u9884\u89C8\u5730\u5740: \u542F\u52A8\u540E\u4EE5 dev server \u5B9E\u9645\u8F93\u51FA\u4E3A\u51C6\uFF08\u5F53\u524D\u9884\u671F ${runtime.env.PUBLIC_APP_BASE_URL||"-"}\uFF09`:`\u672C\u5730\u9884\u89C8\u5730\u5740: ${runtime.env.PUBLIC_APP_BASE_URL||"-"}`,`\u5065\u5EB7\u68C0\u67E5: ${runtime.healthcheckUrl}`,"\u4E91\u7AEF Preview: \u5982\u9700\u751F\u6210\u4E91\u7AEF\u53EF\u5206\u4EAB\u5730\u5740\uFF0C\u8BF7\u6267\u884C `platform preview generate`\uFF1B\u82E5\u4F60\u8D70\u7684\u662F Dev Workspace \u8054\u8C03\u94FE\u8DEF\uFF0C\u518D\u6267\u884C `platform dev preview generate`\u3002",runtime.warnings.length>0?`\u63D0\u793A:
|
|
2713
2720
|
- ${runtime.warnings.join(`
|
|
2714
2721
|
- `)}`:`\u63D0\u793A:
|
|
2715
2722
|
- \u65E0`,"\u9AD8\u7EA7\u6A21\u5F0F\u63D0\u793A: \u82E5\u4F60\u8981\u9A8C\u8BC1\u5E73\u53F0\u539F\u751F\u6784\u5EFA\u3001\u771F\u5B9E preview\u3001rollback\uFF0C\u8BF7\u6539\u8D70\u5B8C\u6574\u8054\u8C03\u73AF\u5883\u3002",""].join(`
|
|
2716
2723
|
`));try{autoRestartEnabled?await runDevSupervisor({command:runtime.command,cwd:runtime.cwd,env:runtime.env,watchRoot:runtime.cwd,onWatching:message=>{process7.stdout.write(`[dev] ${message}
|
|
2717
2724
|
`)}}):await runSingleDevProcess(runtime.command,runtime.cwd,runtime.env)}finally{await cleanupRemoteBindings?.()}}async function runSingleDevProcess(command,cwd,env){await runDevSupervisor({command,cwd,env})}async function ensureLocalDevDependencies(cwd){let installPlan=detectLocalDependencyInstallPlan(cwd);if(!installPlan)return null;let renderedCommand=[installPlan.command,...installPlan.args].join(" ");return process7.stdout.write(`\u68C0\u6D4B\u5230\u5F53\u524D\u5DE5\u4F5C\u533A\u7F3A\u5C11 node_modules\uFF1B\u6B63\u5728\u6309 ${installPlan.lockfile} \u6267\u884C\u4F9D\u8D56\u5B89\u88C5\uFF1A${renderedCommand}
|
|
2718
|
-
`),await new Promise((resolve19,reject)=>{let child=
|
|
2725
|
+
`),await new Promise((resolve19,reject)=>{let child=spawnCrossPlatform(installPlan.command,installPlan.args,{cwd,env:process7.env,stdio:"inherit",shell:!1});child.on("error",error=>{let detail=error instanceof Error?error.message:String(error);reject(new Error(`${detail}
|
|
2726
|
+
${formatDependencyInstallFailureHint(installPlan.lockfile)}`))}),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF0C\u72B6\u6001\u7801 ${code2}
|
|
2727
|
+
${formatDependencyInstallFailureHint(installPlan.lockfile)}`));return}resolve19()})}),`\u68C0\u6D4B\u5230\u5F53\u524D\u5DE5\u4F5C\u533A\u7F3A\u5C11 node_modules\uFF1BCLI \u5DF2\u6309 ${installPlan.lockfile} \u81EA\u52A8\u5B8C\u6210\u4F9D\u8D56\u5B89\u88C5\u3002`}async function runAuth(args){let subcommand=args.rest[0]??"discover";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAuthHelp(args.rest[0]??"");return}if(!["discover","configure","bind","inspect","role","user-role"].includes(subcommand))throw new Error(`\u672A\u77E5 auth \u5B50\u547D\u4EE4: ${subcommand}`);let credentials=await loadStoredCredentialsEnsuringFresh(),tenantId=resolveTenantContext(args),appId=resolveAppIdFromContext(args);if(!tenantId||!appId)throw new Error("`platform auth` \u9700\u8981 `--tenant` \u6216\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u4EE5\u53CA `--app`\u3001\u5F53\u524D\u76EE\u5F55\u7ED1\u5B9A\u6216\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587\u3002");let sdk=createTenantScopedSdk(credentials,tenantId,{capability:"end_user_auth"}),jsonMode=args.options.json===!0;if(subcommand==="role"){let action2=args.rest[1]??"list";if(!["list","create","inspect","update"].includes(action2))throw new Error(`\u672A\u77E5 auth role \u5B50\u547D\u4EE4: ${action2}`);if(action2==="list"){let response3=await sdk.listTenantAppEndUserRoles(appId);if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
|
|
2719
2728
|
`);return}printAppRoleList(response3.items);return}if(action2==="create"){let roleKey2=readOption2(args,"key"),displayName=readOption2(args,"name");if(!roleKey2||!displayName)throw new Error("`platform auth role create` \u9700\u8981 `--key <role-key>` \u548C `--name <display-name>`\u3002");let response3=await sdk.createTenantAppEndUserRole(appId,{role_key:roleKey2,display_name:displayName,description:readOption2(args,"description"),status:normalizeAppRoleStatus(readOption2(args,"status"))});if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
|
|
2720
2729
|
`);return}printAppRoleDetail(response3);return}let roleKey=readOption2(args,"role");if(!roleKey)throw new Error("`platform auth role inspect/update` \u9700\u8981 `--role <role-key>`\u3002");if(action2==="inspect"){let response3=await sdk.getTenantAppEndUserRole(appId,roleKey);if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
|
|
2721
2730
|
`);return}printAppRoleDetail(response3);return}let hasDescription=Object.prototype.hasOwnProperty.call(args.options,"description"),clearDescription=hasFlag2(args,"clear-description"),payload={display_name:readOption2(args,"name"),description:clearDescription?null:hasDescription?readOption2(args,"description")??null:void 0,status:normalizeAppRoleStatus(readOption2(args,"status"))};if(payload.display_name===void 0&&payload.description===void 0&&payload.status===void 0)throw new Error("`platform auth role update` \u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u53D8\u66F4\u53C2\u6570\uFF1A`--name`\u3001`--description`\u3001`--clear-description` \u6216 `--status`\u3002");let response2=await sdk.updateTenantAppEndUserRole(appId,roleKey,payload);if(jsonMode){process7.stdout.write(`${JSON.stringify(response2,null,2)}
|
|
@@ -2731,11 +2740,11 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2731
2740
|
`);return}printCmsDiscoverOutput(response);return}if(subcommand==="import"){let importSource=args.rest[1];if(importSource!=="markdown"&&importSource!=="url")throw new Error("`platform cms import` \u5F53\u524D\u4EC5\u652F\u6301 `markdown`\u3001`url`\u3002");if(importSource==="url"){let requestedUrl=args.rest[2];if(!requestedUrl)throw new Error("`platform cms import url` \u9700\u8981 <url>\u3002");let collection2=readOption2(args,"collection")??"article",itemId=readOption2(args,"item-id"),categoryIdOption2=readOption2(args,"category-id"),categoryPathOption2=readOption2(args,"category-path"),dryRun2=hasFlag2(args,"dry-run"),skipExisting2=hasFlag2(args,"skip-existing"),assetizeImages=!hasFlag2(args,"no-assetize-images"),publishShortcut2=hasFlag2(args,"publish");if(categoryIdOption2&&categoryPathOption2)throw new Error("`platform cms import url` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--category-id` \u548C `--category-path`\u3002");if(publishShortcut2&&readOption2(args,"publish-status")!==void 0)throw new Error("`platform cms import url` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--publish` \u548C `--publish-status`\u3002");let publishStatus2=(()=>{let status=readOption2(args,"publish-status");if(status!==void 0){if(status==="draft"||status==="published"||status==="archived")return status;throw new Error("\u65E0\u6548\u7684 `--publish-status`\uFF0C\u4EC5\u652F\u6301 `draft`\u3001`published`\u3001`archived`\u3002")}})(),schemaResponse=await sdk.inspectTenantCmsSchema(collection2),schema=schemaResponse.draft_schema??schemaResponse.active_schema;if(!schema)throw new Error(`Collection \`${collection2}\` has no schema.`);let resolvedCategoryId2=categoryIdOption2??null,categoryPlan2=null,ensureCategoryId2=null;if(categoryPathOption2){let discover=await sdk.discoverTenantCmsCollection(collection2),segments=parseCmsCategoryPath(categoryPathOption2);dryRun2?(categoryPlan2=planCmsCategoryPath({categories:discover.categories,segments}),resolvedCategoryId2=categoryPlan2.finalNode?.id??null):ensureCategoryId2=async()=>(await ensureCmsCategoryPath({categories:discover.categories,segments,createCategory:async(segment,parentId)=>sdk.configureTenantCmsCategory({collection:collection2,node:{name:segment.name,slug:segment.slug,parent_id:parentId}})})).finalNode.id}let fetchedSource=await fetchUrlImportSource(requestedUrl),parsedUrl=parseUrlImportHtml(fetchedSource),builtPayload=buildUrlItemPayload({collection:collection2,parsed:parsedUrl,itemId,title:readOption2(args,"title"),slug:readOption2(args,"slug"),summary:readOption2(args,"summary"),tags:readOption2(args,"tags")===void 0?void 0:readCsvOption3(args,"tags"),categoryId:resolvedCategoryId2,publishStatus:publishShortcut2?"draft":publishStatus2,importedBy:readOption2(args,"imported-by")??"ide-agent"}),{payload,droppedFields}=restrictItemPayloadToSchemaFields(builtPayload,schema.fields),warnings=[...parsedUrl.warnings,...droppedFields.map(field=>`\u5B57\u6BB5 \`${field}\` \u672A\u51FA\u73B0\u5728\u5F53\u524D schema \u4E2D\uFF0C\u5DF2\u8DF3\u8FC7\u5199\u5165\u3002`)],lookup=payload.item_id&&payload.item_id.trim().length>0?{kind:"item_id",value:payload.item_id}:payload.system.slug?{kind:"slug",value:payload.system.slug}:null,existing=skipExisting2?await findExistingTenantCmsItemForImport({sdk,collection:collection2,lookup}):null;if(!existing&&payload.system.slug){let resolvedSlug=await resolveUniqueTenantCmsSlug({sdk,collection:collection2,slug:payload.system.slug,itemId:payload.item_id});resolvedSlug.adjusted&&resolvedSlug.slug&&(warnings.push(`slug \`${resolvedSlug.originalSlug}\` \u5DF2\u5B58\u5728\uFF0C\u5DF2\u81EA\u52A8\u8C03\u6574\u4E3A \`${resolvedSlug.slug}\``),payload.system.slug=resolvedSlug.slug)}if(dryRun2){let responsePayload={mode:"single",import:{source_type:"url",source_url:requestedUrl,resolved_url:parsedUrl.resolvedUrl,collection:collection2},item:{item_id:payload.item_id??null,slug:payload.system.slug??null,title:typeof payload.content.title=="string"?payload.content.title:null,publish_status:payload.system.publish_status??"draft",state:existing?"skipped":"planned",matched_by:existing?.matchedBy??null,category_id:payload.system.category_id??null},parsed:{source_author:parsedUrl.sourceAuthor??null,source_site:parsedUrl.sourceSite??null,source_published_at:parsedUrl.sourcePublishedAt??null,cover_url:parsedUrl.coverUrl??null},assetize_images:assetizeImages,warnings,...categoryPathOption2&&categoryPlan2?{category_path:categoryPathOption2,category_plan:categoryPlan2}:{}};if(jsonMode){process7.stdout.write(`${JSON.stringify(responsePayload,null,2)}
|
|
2732
2741
|
`);return}printCmsImportUrlDryRunOutput(responsePayload);return}if(existing){let skippedPayload={collection:collection2,sourceUrl:requestedUrl,resolvedUrl:parsedUrl.resolvedUrl,itemId:existing.item.system.id??payload.item_id??"(unknown)",publishStatus:existing.item.system.publish_status??"draft",state:"skipped",matchedBy:existing.matchedBy,warnings};if(jsonMode){process7.stdout.write(`${JSON.stringify(skippedPayload,null,2)}
|
|
2733
2742
|
`);return}printCmsImportUrlOutput(skippedPayload);return}if(ensureCategoryId2&&(payload.system.category_id=await ensureCategoryId2()),assetizeImages){let assetized=await assetizeParsedUrlImages({sdk,parsed:parsedUrl,includeBody:typeof payload.content.body=="string",includeCover:Object.prototype.hasOwnProperty.call(payload.content,"cover")});parsedUrl.body=assetized.parsed.body,warnings.push(...assetized.warnings),typeof payload.content.body=="string"&&(payload.content.body=assetized.parsed.body),assetized.cover.mode==="asset"||assetized.cover.mode==="remote"?payload.content.cover=assetized.cover.value:assetized.cover.mode==="none"&&delete payload.content.cover}let configuredItem=await sdk.configureTenantCmsItem(payload);publishShortcut2&&await sdk.applyTenantCmsPublish({collection:collection2,item_id:configuredItem.item_id,target_status:"published"});let importPayload={collection:collection2,sourceUrl:requestedUrl,resolvedUrl:parsedUrl.resolvedUrl,itemId:configuredItem.item_id,publishStatus:publishShortcut2?"published":configuredItem.publish_status,state:"imported",warnings};if(jsonMode){process7.stdout.write(`${JSON.stringify(importPayload,null,2)}
|
|
2734
|
-
`);return}printCmsImportUrlOutput(importPayload);return}let markdownPath=args.rest[2];if(!markdownPath)throw new Error("`platform cms import markdown` \u9700\u8981 <file-or-dir-path>\u3002");let collection=readOption2(args,"collection")??"article",itemIdOption=readOption2(args,"item-id"),itemIdPrefixOption=readOption2(args,"item-id-prefix"),categoryIdOption=readOption2(args,"category-id"),categoryPathOption=readOption2(args,"category-path"),tagsOption=readOption2(args,"tags"),coverAssetIdOption=readOption2(args,"cover-asset-id"),dryRun=hasFlag2(args,"dry-run"),skipExisting=hasFlag2(args,"skip-existing"),publishShortcut=hasFlag2(args,"publish");if(categoryIdOption&&categoryPathOption)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--category-id` \u548C `--category-path`\u3002");if(itemIdOption&&itemIdPrefixOption)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--item-id` \u548C `--item-id-prefix`\u3002");if(publishShortcut&&readOption2(args,"publish-status")!==void 0)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--publish` \u548C `--publish-status`\u3002");let publishStatus=(()=>{let status=readOption2(args,"publish-status");if(status!==void 0){if(status==="draft"||status==="published"||status==="archived")return status;throw new Error("\u65E0\u6548\u7684 `--publish-status`\uFF0C\u4EC5\u652F\u6301 `draft`\u3001`published`\u3001`archived`\u3002")}})(),sources=collectMarkdownImportSources(markdownPath,hasFlag2(args,"recursive"));if(sources.length===0)throw new Error(`\u672A\u5728\u76EE\u6807\u8DEF\u5F84\u4E2D\u627E\u5230 Markdown \u6587\u4EF6\uFF1A${markdownPath}`);let isBatch=sources.length>1;if(isBatch){let disallowedOptions=["item-id","title","slug","summary"].filter(key=>readOption2(args,key)!==void 0);if(disallowedOptions.length>0)throw new Error(`\u76EE\u5F55\u6279\u91CF\u5BFC\u5165\u4E0D\u652F\u6301\u8FD9\u4E9B\u5355\u6761\u8986\u76D6\u53C2\u6570\uFF1A${disallowedOptions.map(key=>`--${key}`).join("\u3001")}\u3002`)}let resolvedCategoryId=categoryIdOption??null,categoryPlan=null,ensureCategoryId=null;if(categoryPathOption){let discover=await sdk.discoverTenantCmsCollection(collection),segments=parseCmsCategoryPath(categoryPathOption);dryRun?(categoryPlan=planCmsCategoryPath({categories:discover.categories,segments}),resolvedCategoryId=categoryPlan.finalNode?.id??null):ensureCategoryId=async()=>(await ensureCmsCategoryPath({categories:discover.categories,segments,createCategory:async(segment,parentId)=>sdk.configureTenantCmsCategory({collection,node:{name:segment.name,slug:segment.slug,parent_id:parentId}})})).finalNode.id}let coverFieldName="cover",coverField=null,coverAssetResponse=null,schemaFields=null;if(coverAssetIdOption){let[schemaResponse,assetResponse]=await Promise.all([sdk.inspectTenantCmsSchema(collection),sdk.getTenantAsset(coverAssetIdOption)]),schema=schemaResponse.draft_schema??schemaResponse.active_schema;if(!schema)throw new Error(`Collection \`${collection}\` has no schema.`);if(coverField=resolveCmsAttachAssetField(schema.fields,coverFieldName),coverField.type!=="image")throw new Error("`platform cms import markdown --cover-asset-id` \u5F53\u524D\u4EC5\u652F\u6301\u6302\u5230\u5355\u56FE `cover` \u5B57\u6BB5\u3002");if(assetResponse.asset.media_type!=="image")throw new Error("`platform cms import markdown --cover-asset-id` \u5F53\u524D\u4EC5\u652F\u6301\u56FE\u7247\u7D20\u6750\u3002");schemaFields=schema.fields,coverAssetResponse=assetResponse}let preparedItems=sources.map(source=>{let itemId=itemIdOption??(itemIdPrefixOption?inferItemIdFromPrefix(itemIdPrefixOption,source.sourcePath):void 0),payload=buildMarkdownItemPayload({collection,markdownPath:source.sourcePath,markdownContent:
|
|
2743
|
+
`);return}printCmsImportUrlOutput(importPayload);return}let markdownPath=args.rest[2];if(!markdownPath)throw new Error("`platform cms import markdown` \u9700\u8981 <file-or-dir-path>\u3002");let collection=readOption2(args,"collection")??"article",itemIdOption=readOption2(args,"item-id"),itemIdPrefixOption=readOption2(args,"item-id-prefix"),categoryIdOption=readOption2(args,"category-id"),categoryPathOption=readOption2(args,"category-path"),tagsOption=readOption2(args,"tags"),coverAssetIdOption=readOption2(args,"cover-asset-id"),dryRun=hasFlag2(args,"dry-run"),skipExisting=hasFlag2(args,"skip-existing"),publishShortcut=hasFlag2(args,"publish");if(categoryIdOption&&categoryPathOption)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--category-id` \u548C `--category-path`\u3002");if(itemIdOption&&itemIdPrefixOption)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--item-id` \u548C `--item-id-prefix`\u3002");if(publishShortcut&&readOption2(args,"publish-status")!==void 0)throw new Error("`platform cms import markdown` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--publish` \u548C `--publish-status`\u3002");let publishStatus=(()=>{let status=readOption2(args,"publish-status");if(status!==void 0){if(status==="draft"||status==="published"||status==="archived")return status;throw new Error("\u65E0\u6548\u7684 `--publish-status`\uFF0C\u4EC5\u652F\u6301 `draft`\u3001`published`\u3001`archived`\u3002")}})(),sources=collectMarkdownImportSources(markdownPath,hasFlag2(args,"recursive"));if(sources.length===0)throw new Error(`\u672A\u5728\u76EE\u6807\u8DEF\u5F84\u4E2D\u627E\u5230 Markdown \u6587\u4EF6\uFF1A${markdownPath}`);let isBatch=sources.length>1;if(isBatch){let disallowedOptions=["item-id","title","slug","summary"].filter(key=>readOption2(args,key)!==void 0);if(disallowedOptions.length>0)throw new Error(`\u76EE\u5F55\u6279\u91CF\u5BFC\u5165\u4E0D\u652F\u6301\u8FD9\u4E9B\u5355\u6761\u8986\u76D6\u53C2\u6570\uFF1A${disallowedOptions.map(key=>`--${key}`).join("\u3001")}\u3002`)}let resolvedCategoryId=categoryIdOption??null,categoryPlan=null,ensureCategoryId=null;if(categoryPathOption){let discover=await sdk.discoverTenantCmsCollection(collection),segments=parseCmsCategoryPath(categoryPathOption);dryRun?(categoryPlan=planCmsCategoryPath({categories:discover.categories,segments}),resolvedCategoryId=categoryPlan.finalNode?.id??null):ensureCategoryId=async()=>(await ensureCmsCategoryPath({categories:discover.categories,segments,createCategory:async(segment,parentId)=>sdk.configureTenantCmsCategory({collection,node:{name:segment.name,slug:segment.slug,parent_id:parentId}})})).finalNode.id}let coverFieldName="cover",coverField=null,coverAssetResponse=null,schemaFields=null;if(coverAssetIdOption){let[schemaResponse,assetResponse]=await Promise.all([sdk.inspectTenantCmsSchema(collection),sdk.getTenantAsset(coverAssetIdOption)]),schema=schemaResponse.draft_schema??schemaResponse.active_schema;if(!schema)throw new Error(`Collection \`${collection}\` has no schema.`);if(coverField=resolveCmsAttachAssetField(schema.fields,coverFieldName),coverField.type!=="image")throw new Error("`platform cms import markdown --cover-asset-id` \u5F53\u524D\u4EC5\u652F\u6301\u6302\u5230\u5355\u56FE `cover` \u5B57\u6BB5\u3002");if(assetResponse.asset.media_type!=="image")throw new Error("`platform cms import markdown --cover-asset-id` \u5F53\u524D\u4EC5\u652F\u6301\u56FE\u7247\u7D20\u6750\u3002");schemaFields=schema.fields,coverAssetResponse=assetResponse}let preparedItems=sources.map(source=>{let itemId=itemIdOption??(itemIdPrefixOption?inferItemIdFromPrefix(itemIdPrefixOption,source.sourcePath):void 0),payload=buildMarkdownItemPayload({collection,markdownPath:source.sourcePath,markdownContent:readFileSync27(source.absolutePath,"utf8"),itemId,title:isBatch?void 0:readOption2(args,"title"),slug:isBatch?void 0:readOption2(args,"slug"),summary:isBatch?void 0:readOption2(args,"summary"),tags:tagsOption===void 0?void 0:readCsvOption3(args,"tags"),categoryId:resolvedCategoryId,publishStatus:publishShortcut?"draft":publishStatus,importedBy:readOption2(args,"imported-by")??"ide-agent"});return{source,payload,lookup:resolveMarkdownImportLookupKey(payload),warnings:[]}}),existingMatches=new Map;if(skipExisting)for(let preparedItem of preparedItems){let existing=await findExistingTenantCmsItemForImport({sdk,collection,lookup:preparedItem.lookup});existing&&existingMatches.set(preparedItem.source.sourcePath,existing)}if(!dryRun&&ensureCategoryId&&preparedItems.some(preparedItem=>!existingMatches.has(preparedItem.source.sourcePath))){resolvedCategoryId=await ensureCategoryId();for(let preparedItem of preparedItems)preparedItem.payload.system.category_id=resolvedCategoryId}let reservedSlugs=new Set;for(let preparedItem of preparedItems){let existing=existingMatches.get(preparedItem.source.sourcePath);if(existing){existing.item.system.slug&&reservedSlugs.add(existing.item.system.slug);continue}if(!preparedItem.payload.system.slug)continue;let resolvedSlug=await resolveUniqueTenantCmsSlug({sdk,collection,slug:preparedItem.payload.system.slug,itemId:preparedItem.payload.item_id,reservedSlugs});resolvedSlug.slug&&(resolvedSlug.adjusted&&preparedItem.warnings.push(`slug \`${resolvedSlug.originalSlug}\` \u5DF2\u5B58\u5728\uFF0C\u5DF2\u81EA\u52A8\u8C03\u6574\u4E3A \`${resolvedSlug.slug}\``),preparedItem.payload.system.slug=resolvedSlug.slug,reservedSlugs.add(resolvedSlug.slug))}if(dryRun){let plannedItems=preparedItems.map(({source,payload,warnings})=>{let existing=existingMatches.get(source.sourcePath),skipped=!!existing,state=skipped?"skipped":"planned";return{source_path:source.sourcePath,item_id:existing?.item.system.id??payload.item_id??null,item_id_source:skipped?existing.matchedBy:payload.item_id?"cli":"server-generated",slug:payload.system.slug??null,title:typeof payload.content.title=="string"?payload.content.title:null,publish_status:skipped?existing?.item.system.publish_status??payload.system.publish_status:publishShortcut?"published":payload.system.publish_status,tags:payload.system.tags??[],category_id:payload.system.category_id??null,state,matched_by:existing?.matchedBy??null,warnings,actions:skipped?["skip_existing"]:["configure_item",...coverField&&coverAssetResponse?["attach_cover_asset"]:[],...publishShortcut?["publish"]:[]]}}),dryRunOutput=isBatch?{dry_run:!0,mode:"batch",import:{source_type:"markdown",source_path:markdownPath,recursive:hasFlag2(args,"recursive"),collection},category_path_plan:categoryPathOption?{path:categoryPathOption,final_category_id:categoryPlan?.finalNode?.id??null,nodes:categoryPlan?.plannedNodes??[]}:null,cover_attachment:coverField&&coverAssetResponse?{field:coverField.name,asset_id:coverAssetResponse.asset.asset_id,title:coverAssetResponse.asset.title,mode:"replace"}:null,skip_existing:skipExisting,publish_after_import:publishShortcut,summary:summarizeMarkdownImportResults(plannedItems),items:plannedItems}:{dry_run:!0,import:{source_type:"markdown",source_path:plannedItems[0].source_path,collection},category_path_plan:categoryPathOption?{path:categoryPathOption,final_category_id:categoryPlan?.finalNode?.id??null,nodes:categoryPlan?.plannedNodes??[]}:null,cover_attachment:coverField&&coverAssetResponse?{field:coverField.name,asset_id:coverAssetResponse.asset.asset_id,title:coverAssetResponse.asset.title,mode:"replace"}:null,skip_existing:skipExisting,publish_after_import:publishShortcut,item:plannedItems[0]};if(jsonMode){process7.stdout.write(`${JSON.stringify(dryRunOutput,null,2)}
|
|
2735
2744
|
`);return}if(isBatch){printCmsImportMarkdownDryRunBatchOutput({collection,sourcePath:markdownPath,total:plannedItems.length,summary:summarizeMarkdownImportResults(plannedItems),items:plannedItems,skipExisting,publishShortcut,categoryPath:categoryPathOption,categoryPlan,coverFieldName:coverField?.name,coverAssetTitle:coverAssetResponse?.asset.title});return}printCmsImportMarkdownDryRunOutput({collection,sourcePath:plannedItems[0].source_path,itemId:plannedItems[0].item_id,itemIdSource:plannedItems[0].item_id_source,slug:plannedItems[0].slug,title:plannedItems[0].title,publishStatus:plannedItems[0].publish_status,tags:plannedItems[0].tags,categoryId:plannedItems[0].category_id,state:plannedItems[0].state,matchedBy:plannedItems[0].matched_by,categoryPath:categoryPathOption,categoryPlan,coverFieldName:coverField?.name,coverAssetTitle:coverAssetResponse?.asset.title,warnings:plannedItems[0].warnings});return}let importedItems=[];for(let{source,payload,warnings}of preparedItems){let existing=existingMatches.get(source.sourcePath);if(existing){importedItems.push({source_path:source.sourcePath,item_id:existing.item.system.id??payload.item_id??"(existing-item)",slug:existing.item.system.slug??payload.system.slug??null,publish_status:existing.item.system.publish_status??payload.system.publish_status,state:"skipped",matched_by:existing.matchedBy,warnings});continue}let response=await sdk.configureTenantCmsItem(payload);if(coverField&&coverAssetResponse&&schemaFields){let itemResponse=await sdk.getTenantCmsItem({collection,id:response.item_id}),assetPayload=buildCmsAttachAssetPayload({item:itemResponse,fields:schemaFields,field:coverField,assets:[coverAssetResponse],replace:!0});await sdk.configureTenantCmsItem({...assetPayload,item_id:response.item_id})}let finalPublishStatus=publishShortcut?(await sdk.applyTenantCmsPublish({collection,item_id:response.item_id,target_status:"published"})).publish_status:response.publish_status;importedItems.push({source_path:source.sourcePath,item_id:response.item_id,slug:payload.system.slug??null,publish_status:finalPublishStatus,state:"imported",warnings})}if(jsonMode){let summary=summarizeMarkdownImportResults(importedItems);process7.stdout.write(`${JSON.stringify(isBatch?{mode:"batch",import:{source_type:"markdown",source_path:markdownPath,recursive:hasFlag2(args,"recursive"),collection},skip_existing:skipExisting,summary,items:importedItems}:{...importedItems[0],import:{source_type:"markdown",source_path:importedItems[0].source_path,collection},skip_existing:skipExisting},null,2)}
|
|
2736
2745
|
`);return}if(isBatch){printCmsImportMarkdownBatchOutput({collection,sourcePath:markdownPath,total:importedItems.length,summary:summarizeMarkdownImportResults(importedItems),items:importedItems});return}printCmsImportMarkdownOutput({collection,sourcePath:importedItems[0].source_path,itemId:importedItems[0].item_id,publishStatus:importedItems[0].publish_status,state:importedItems[0].state,matchedBy:importedItems[0].matched_by,warnings:importedItems[0].warnings});return}if(subcommand==="attach"){if(args.rest[1]!=="asset")throw new Error("`platform cms attach` \u5F53\u524D\u4EC5\u652F\u6301 `asset`\u3002");let collection=readOption2(args,"collection"),itemId=readOption2(args,"item-id"),fieldName=readOption2(args,"field"),assetIds=readCsvOption3(args,"asset-id"),replace2=hasFlag2(args,"replace");if(!collection||!itemId||!fieldName||assetIds.length===0)throw new Error("`platform cms attach asset` \u9700\u8981 `--collection <name>`\u3001`--item-id <id>`\u3001`--field <field-name>`\u3001`--asset-id <id[,id]>`\u3002");let[schemaResponse,itemResponse,assetResponses]=await Promise.all([sdk.inspectTenantCmsSchema(collection),sdk.getTenantCmsItem({collection,id:itemId}),Promise.all(assetIds.map(assetId=>sdk.getTenantAsset(assetId)))]),schema=schemaResponse.draft_schema??schemaResponse.active_schema;if(!schema)throw new Error(`Collection \`${collection}\` has no schema.`);let field=schema.fields.find(entry=>entry.name===fieldName);if(!field)throw new Error(`Collection \`${collection}\` does not contain field \`${fieldName}\`.`);if(field.type!=="image"&&field.type!=="images")throw new Error("`platform cms attach asset` \u5F53\u524D\u4EC5\u652F\u6301 `image`\u3001`images` \u5B57\u6BB5\u3002");if(field.type==="image"&&assetIds.length!==1)throw new Error("\u5355\u56FE\u5B57\u6BB5\u4E00\u6B21\u53EA\u80FD\u6302\u8F7D\u4E00\u4E2A\u7D20\u6750\uFF1B\u5982\u9700\u591A\u4E2A\u7D20\u6750\uFF0C\u8BF7\u4F7F\u7528 `images` \u5B57\u6BB5\u3002");if(assetResponses.some(asset=>asset.asset.media_type!=="image"))throw new Error("`platform cms attach asset` \u5F53\u524D\u4EC5\u652F\u6301\u6302\u8F7D\u56FE\u7247\u7D20\u6750\u3002");let payload=buildCmsAttachAssetPayload({item:itemResponse,fields:schema.fields,field,assets:assetResponses,replace:replace2}),response=await sdk.configureTenantCmsItem({...payload,item_id:itemId});if(jsonMode){process7.stdout.write(`${JSON.stringify({collection,item_id:response.item_id,publish_status:response.publish_status,field:field.name,field_type:field.type,mode:field.type==="images"?replace2?"replace":"append":"replace",asset_ids:assetResponses.map(asset=>asset.asset.asset_id)},null,2)}
|
|
2737
|
-
`);return}printCmsAttachAssetOutput({collection,itemId:response.item_id,publishStatus:response.publish_status,fieldName:field.name,fieldType:field.type,assetIds:assetResponses.map(asset=>asset.asset.asset_id),replace:replace2});return}if(subcommand==="ensure"){if(args.rest[1]!=="category")throw new Error("`platform cms ensure` \u5F53\u524D\u4EC5\u652F\u6301 `category`\u3002");let collection=readOption2(args,"collection"),
|
|
2738
|
-
`);return}printCmsEnsureCategoryOutput({collection,path:
|
|
2746
|
+
`);return}printCmsAttachAssetOutput({collection,itemId:response.item_id,publishStatus:response.publish_status,fieldName:field.name,fieldType:field.type,assetIds:assetResponses.map(asset=>asset.asset.asset_id),replace:replace2});return}if(subcommand==="ensure"){if(args.rest[1]!=="category")throw new Error("`platform cms ensure` \u5F53\u524D\u4EC5\u652F\u6301 `category`\u3002");let collection=readOption2(args,"collection"),path3=readOption2(args,"path");if(!collection||!path3)throw new Error("`platform cms ensure category` \u9700\u8981 `--collection <name>` \u548C `--path <segment/segment>`\u3002");let segments=parseCmsCategoryPath(path3),discover=await sdk.discoverTenantCmsCollection(collection),ensuredCategory=await ensureCmsCategoryPath({categories:discover.categories,segments,createCategory:async(segment,parentId)=>sdk.configureTenantCmsCategory({collection,node:{name:segment.name,slug:segment.slug,parent_id:parentId}})}),finalNode=ensuredCategory.finalNode,ensuredNodes=ensuredCategory.ensuredNodes;if(jsonMode){process7.stdout.write(`${JSON.stringify({collection,path:path3,final_node:finalNode,ensured_nodes:ensuredNodes},null,2)}
|
|
2747
|
+
`);return}printCmsEnsureCategoryOutput({collection,path:path3,finalNode,ensuredNodes});return}if(subcommand==="list"){if(args.rest[1]!=="items")throw new Error("`platform cms list` \u5F53\u524D\u4EC5\u652F\u6301 `items`\u3002");let collection=readOption2(args,"collection");if(!collection)throw new Error("`platform cms list items` \u9700\u8981 `--collection <name>`\u3002");let status=(()=>{let value=readOption2(args,"status");if(value!==void 0){if(value==="draft"||value==="published"||value==="archived")return value;throw new Error("\u65E0\u6548\u7684 `--status`\uFF0C\u4EC5\u652F\u6301 `draft`\u3001`published`\u3001`archived`\u3002")}})(),response=await sdk.listTenantCmsItems({collection,page:readIntegerOption(args,"page"),pageSize:readIntegerOption(args,"page-size"),categoryId:readOption2(args,"category-id"),status,query:readOption2(args,"q")});if(jsonMode){process7.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2739
2748
|
`);return}printCmsTenantItemListOutput(response);return}if(subcommand==="batch"){if(args.rest[1]!=="update")throw new Error("`platform cms batch` \u5F53\u524D\u4EC5\u652F\u6301 `update`\u3002");let collection=readOption2(args,"collection"),itemIds=readCsvOption3(args,"item-id");if(!collection||itemIds.length===0)throw new Error("`platform cms batch update` \u9700\u8981 `--collection <name>` \u548C `--item-id <id[,id]>`\u3002");let categoryId=readOption2(args,"category-id"),clearCategory=hasFlag2(args,"clear-category");if(categoryId&&clearCategory)throw new Error("`platform cms batch update` \u4E0D\u80FD\u540C\u65F6\u6307\u5B9A `--category-id` \u548C `--clear-category`\u3002");let status=(()=>{let value=readOption2(args,"status");if(value!==void 0){if(value==="draft"||value==="published"||value==="archived")return value;throw new Error("\u65E0\u6548\u7684 `--status`\uFF0C\u4EC5\u652F\u6301 `draft`\u3001`published`\u3001`archived`\u3002")}})(),tagsToAdd=readCsvOption3(args,"add-tags");if(!categoryId&&!clearCategory&&!status&&tagsToAdd.length===0)throw new Error("`platform cms batch update` \u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u53D8\u66F4\u9879\uFF1A`--category-id`\u3001`--clear-category`\u3001`--add-tags`\u3001`--status`\u3002");let response=await batchUpdateTenantCmsItems({sdk,payload:{collection,item_ids:itemIds,changes:{category:clearCategory?{mode:"clear"}:categoryId?{mode:"set",category_id:categoryId}:{mode:"keep"},tags:{add:tagsToAdd},publish_status:status?{mode:"set",value:status}:{mode:"keep"}}}});if(jsonMode){process7.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2740
2749
|
`);return}printCmsBatchUpdateOutput(response);return}if(subcommand==="inspect"){let inspectTarget=args.rest[1]??"schema";if(inspectTarget==="item"){let collection=readOption2(args,"collection")??args.rest[2],itemId=readOption2(args,"id");if(!collection||!itemId)throw new Error("`platform cms inspect item` \u9700\u8981 `--collection <name>` \u548C `--id <id>`\u3002");let response=await sdk.getTenantCmsItem({collection,id:itemId});if(jsonMode){process7.stdout.write(`${JSON.stringify(response,null,2)}
|
|
2741
2750
|
`);return}printCmsTenantItemOutput(response);return}if(inspectTarget==="schema"){let collection=readOption2(args,"collection")??args.rest[2];if(!collection)throw new Error("`platform cms inspect schema` \u9700\u8981 `--collection <name>`\u3002");let response=await sdk.inspectTenantCmsSchema(collection);if(jsonMode){process7.stdout.write(`${JSON.stringify(response,null,2)}
|
|
@@ -2801,7 +2810,9 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
|
|
|
2801
2810
|
`));return}if(subcommand==="list"&&scope==="items"){process7.stdout.write(["platform cms list items","","\u7528\u6CD5\uFF1A"," platform cms list items --collection <name> [--page <n>] [--page-size <n>] [--status draft|published|archived] [--category-id <id>] [--q <keyword>] [--tenant <tenant-id>] [--json]","","\u4F5C\u7528\uFF1A"," \u5728\u79DF\u6237\u63A7\u5236\u9762\u6309 collection \u5217\u51FA item\uFF0C\u652F\u6301\u5206\u9875\u3001\u72B6\u6001\u3001\u76EE\u5F55\u548C\u5173\u952E\u5B57\u8FC7\u6EE4\u3002",""].join(`
|
|
2802
2811
|
`));return}if(subcommand==="batch"&&scope==="update"){process7.stdout.write(["platform cms batch update","","\u7528\u6CD5\uFF1A"," platform cms batch update --collection <name> --item-id <id[,id]> [--category-id <id> | --clear-category] [--add-tags <label,label>] [--status draft|published|archived] [--tenant <tenant-id>] [--json]","","\u4F5C\u7528\uFF1A"," \u6309 item id \u96C6\u5408\u6279\u91CF\u66F4\u65B0 CMS \u5185\u5BB9\u3002\u5206\u7C7B\u652F\u6301\u4FDD\u6301\u539F\u503C\u3001\u8BBE\u4E3A\u6307\u5B9A\u76EE\u5F55\u6216\u6E05\u7A7A\u4E3A\u672A\u5206\u7C7B\uFF1B\u6807\u7B7E\u4EC5\u505A\u8FFD\u52A0\u53BB\u91CD\uFF1B\u72B6\u6001\u652F\u6301\u6279\u91CF\u5207\u6362\u5230 draft/published/archived\u3002\u6267\u884C\u65F6\u9010\u6761\u5904\u7406\u5E76\u6C47\u603B\u6210\u529F/\u5931\u8D25\uFF0C\u4E0D\u4F1A\u5728\u5355\u6761\u5931\u8D25\u65F6\u6574\u4F53\u4E2D\u65AD\u3002",""].join(`
|
|
2803
2812
|
`));return}process7.stdout.write(["platform cms","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform cms discover"," platform cms configure collection"," platform cms configure item"," platform cms configure category"," platform cms import markdown"," platform cms import url"," platform cms attach asset"," platform cms ensure category"," platform cms list items"," platform cms batch update"," platform cms apply schema"," platform cms apply publish"," platform cms inspect schema"," platform cms inspect item"," platform cms inspect delivery",""].join(`
|
|
2804
|
-
`))}async function runDeploy(args){await runDeployCommand(args)}async function runRollback(args){await runRollbackCommand(args)}async function runResources(args){await runResourcesCommand(args)}async function runLogs(args){await runLogsCommand(args)}async function runBuild(args){await runBuildCommand(args)}async function runPreview(args){await runPreviewCommand(args)}async function runPublish(args){await runPublishCommand(args)}async function runWorkflow(args){await runWorkflowCommand({rest:args.rest,options:args.options})}async function runNotification(args){await runNotificationCommand({rest:args.rest,options:args.options})}async function runWorker(args){await runWorkerCommand({rest:args.rest,options:args.options})}async function runDataForm(args){await runDataFormCommand({rest:args.rest,options:args.options})}async function runAppLibrary(args){await runAppLibraryCommand({rest:args.rest,options:args.options})}async function main(){let args=parseArgs5(process7.argv.slice(2));switch(args.command){case"help":case"--help":case"-h":printHelp();return;case"version":case"--version":printVersion();return;case"login":await runLogin(args);return;case"whoami":await runWhoAmI(args);return;case"tenant":await runTenant(args);return;case"env":await runEnvironment(args);return;case"app":await runApp(args);return;case"init":runInit(args);return;case"link":await runLink(args);return;case"dev":await runDev(args);return;case"auth":await runAuth(args);return;case"cms":await runCms(args);return;case"asset":await runAsset(args);return;case"blob":await runBlob(args);return;case"db":await runDbCommand({rest:args.rest,options:args.options});return;case"data-form":await runDataForm(args);return;case"app-library":await runAppLibrary(args);return;case"workflow":await runWorkflow(args);return;case"notification":await runNotification(args);return;case"build":await runBuild(args);return;case"preview":await runPreview(args);return;case"publish":await runPublish(args);return;case"deploy":await runDeploy(args);return;case"rollback":await runRollback(args);return;case"resources":await runResources(args);return;case"logs":await runLogs(args);return;case"diagnostics":await runDiagnostics(args);return;case"worker":await runWorker(args);return;default:throw printHelp(),new Error(`\u672A\u77E5\u547D\u4EE4: ${args.command}`)}}main().catch(async error=>{let workspaceRoot=findWorkspaceRoot(),args=parseArgs5(process7.argv.slice(2))
|
|
2813
|
+
`))}async function runDeploy(args){await runDeployCommand(args)}async function runRollback(args){await runRollbackCommand(args)}async function runResources(args){await runResourcesCommand(args)}async function runLogs(args){await runLogsCommand(args)}async function runBuild(args){await runBuildCommand(args)}async function runPreview(args){await runPreviewCommand(args)}async function runPublish(args){await runPublishCommand(args)}async function runWorkflow(args){await runWorkflowCommand({rest:args.rest,options:args.options})}async function runNotification(args){await runNotificationCommand({rest:args.rest,options:args.options})}async function runWorker(args){await runWorkerCommand({rest:args.rest,options:args.options})}async function runDataForm(args){await runDataFormCommand({rest:args.rest,options:args.options})}async function runAppLibrary(args){await runAppLibraryCommand({rest:args.rest,options:args.options})}async function main(){assertSupportedNodeVersion();let args=parseArgs5(process7.argv.slice(2));switch(args.command){case"help":case"--help":case"-h":printHelp();return;case"version":case"--version":printVersion();return;case"login":await runLogin(args);return;case"whoami":await runWhoAmI(args);return;case"tenant":await runTenant(args);return;case"env":await runEnvironment(args);return;case"app":await runApp(args);return;case"init":runInit(args);return;case"link":await runLink(args);return;case"dev":await runDev(args);return;case"auth":await runAuth(args);return;case"cms":await runCms(args);return;case"asset":await runAsset(args);return;case"blob":await runBlob(args);return;case"db":await runDbCommand({rest:args.rest,options:args.options});return;case"data-form":await runDataForm(args);return;case"app-library":await runAppLibrary(args);return;case"workflow":await runWorkflow(args);return;case"notification":await runNotification(args);return;case"build":await runBuild(args);return;case"preview":await runPreview(args);return;case"publish":await runPublish(args);return;case"deploy":await runDeploy(args);return;case"rollback":await runRollback(args);return;case"resources":await runResources(args);return;case"logs":await runLogs(args);return;case"diagnostics":await runDiagnostics(args);return;case"worker":await runWorker(args);return;default:throw printHelp(),new Error(`\u672A\u77E5\u547D\u4EE4: ${args.command}`)}}main().catch(async error=>{let workspaceRoot=findWorkspaceRoot(),args=parseArgs5(process7.argv.slice(2));if(args.options.json===!0&&error instanceof PlatformBlocksVerifyError){process7.stderr.write(`${JSON.stringify({error:{code:error.code,message:error.message.split(`
|
|
2814
|
+
`,1)[0]},verify:error.result},null,2)}
|
|
2815
|
+
`),process7.exitCode=1;return}let lines=[error instanceof Error?error.message:"\u547D\u4EE4\u6267\u884C\u5931\u8D25",`\u5F53\u524D\u5DE5\u4F5C\u533A: ${workspaceRoot}`];if(requiresLoginRecovery(error)&&lines.push(formatReauthHint({credentialMode:readStoredCredentialModeSafely(),credentialPath:readCredentialPathSafely()})),error instanceof CliStateAccessError&&lines.push(formatCliStateAccessHint({workspaceRoot})),process7.stderr.write(`${lines.join(`
|
|
2805
2816
|
`)}
|
|
2806
2817
|
`),isLikelyControlApiConnectionError(error))try{let diagnostics=await collectControlApiFailureDiagnostics();args.options.json===!0?process7.stderr.write(`${JSON.stringify(diagnostics,null,2)}
|
|
2807
2818
|
`):process7.stderr.write(formatControlApiFailureDiagnosticsText(diagnostics))}catch(diagnosticError){process7.stderr.write(`control-api diagnostics failed: ${diagnosticError instanceof Error?diagnosticError.message:String(diagnosticError)}
|