@voobase/cli 0.1.1-nonprod.2050 → 0.1.1-nonprod.2068

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.
@@ -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&&currentValue<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>
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&&currentValue<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 existsSync28,readFileSync as readFileSync29}from"node:fs";import{resolve as resolve19}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" />
@@ -2192,7 +2192,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2192
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(`
2193
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(`
2194
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(`
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(`
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,{win32}from"node:path";import crossSpawn from"cross-spawn";import{zipSync}from"fflate";function spawnCrossPlatform(command,args,options={}){return crossSpawn(command,[...args],{...options,shell:!1})}function resolveWindowsPowerShellExecutable(env=process.env){let configuredRoot=env.SystemRoot?.trim()||env.WINDIR?.trim(),windowsRoot=configuredRoot&&win32.isAbsolute(configuredRoot)?configuredRoot:"C:\\Windows";return win32.join(windowsRoot,"System32","WindowsPowerShell","v1.0","powershell.exe")}async function terminateProcessTree(pid,options={}){if((options.platform??process.platform)==="win32"){let spawnImpl=options.spawnImpl??nodeSpawn;await new Promise((resolve20,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}resolve20()})});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(resolve20=>{let child;try{child=spawnImpl(launcher.command,launcher.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(error){resolve20({opened:!1,error:toErrorMessage(error)});return}child.once("error",error=>{resolve20({opened:!1,error:toErrorMessage(error)})}),child.once("spawn",()=>{child.unref(),resolve20({opened:!0})})})}async function createZipBuffer(directory){let archive=Object.create(null);return await addDirectoryToArchive(path.resolve(directory),"",archive),zipSync(archive,{level:6})}async function addDirectoryToArchive(directory,relativeDirectory,archive){let entries=await readdir(directory,{withFileTypes:!0});entries.sort((left,right)=>compareCodeUnits(left.name,right.name));for(let entry of entries){let absolutePath=path.join(directory,entry.name),relativePath=relativeDirectory?`${relativeDirectory}/${entry.name}`:entry.name;if(entry.isDirectory()){await addDirectoryToArchive(absolutePath,relativePath,archive);continue}if(entry.isSymbolicLink())throw new Error(`Cannot add symbolic link to portable ZIP archive: ${relativePath}`);if(!entry.isFile())throw new Error(`Cannot add unsupported filesystem entry to ZIP archive: ${relativePath}`);if(relativePath==="__proto__")throw new Error("Cannot add reserved root ZIP entry name: __proto__");archive[relativePath]=[await readFile(absolutePath),{mtime:new Date(1980,0,1,0,0,0)}]}}function compareCodeUnits(left,right){return left<right?-1:left>right?1:0}function toErrorMessage(error){return error instanceof Error?error.message:String(error)}async function runAssetCommand(args,deps){if(hasHelpFlag(args)||args.rest.length===0){printAssetHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runAssetUpload(args,deps);return}if(subcommand==="list"){await runAssetList(args,deps);return}if(subcommand==="folder"){await runAssetFolder(args,deps);return}if(subcommand==="get"){await runAssetGet(args,deps);return}if(subcommand==="move"){await runAssetMove(args,deps);return}if(subcommand==="update"){await runAssetUpdate(args,deps);return}if(subcommand==="analyze"){await runAssetAnalyze(args,deps);return}if(subcommand==="open"){await runAssetOpen(args,deps);return}if(subcommand==="download"){await runAssetDownload(args,deps);return}if(subcommand==="tag"){await runAssetTag(args,deps);return}throw new Error("`platform asset` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`move`\u3001`update`\u3001`analyze`\u3001`open`\u3001`download`\u3001`folder`\u3001`tag`\u3002")}function printAssetHelp(){process.stdout.write(["platform asset <command>","","Commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>] [--json]"," platform asset list [--q <keyword>] [--media-type image|video] [--mime-type <mime>] [--folder-id <folder-id>] [--tag-ids <id,id>] [--has-ocr true|false] [--has-person true|false] [--is-svg true|false] [--scene <scene>] [--objects <name,name>] [--safety-flags <flag,flag>] [--orientation landscape|portrait|square] [--page <n>] [--limit <n>] [--json]"," platform asset folder list [--json]"," platform asset folder create <name> [--parent-folder-id <folder-id>] [--json]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id>] [--root] [--json]"," platform asset get <asset-id> [--json]"," platform asset move <asset-id> [--folder-id <folder-id> | --root] [--json]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--summary <text>] [--caption <text>] [--scene <scene>] [--objects <name,name>] [--ocr <text>] [--colors <hex,hex>] [--safety-flags <flag,flag>] [--tags <label,label>] [--json]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>] [--json]"," platform asset tag add <asset-id> <label> [--json]"," platform asset tag remove <asset-id> <label> [--json]","","Notes:"," - \u7B2C\u4E00\u9636\u6BB5\u4EE5 tenant/workspace \u4E3A\u4E3B\uFF0C\u4E0D\u8981\u6C42 app/consumer \u4E0A\u4E0B\u6587"," - `list` \u652F\u6301\u7CBE\u786E\u68C0\u7D22 + \u7ED3\u6784\u5316\u8FC7\u6EE4\uFF1B\u4E0D\u5355\u72EC\u63D0\u4F9B `search` \u5B50\u547D\u4EE4"," - `update` \u4E00\u6B21\u547D\u4EE4\u53EF patch \u591A\u4E2A\u5143\u6570\u636E\u5B57\u6BB5\uFF1B\u4E0D\u66FF\u6362\u539F\u59CB\u6587\u4EF6"," - `analyze` \u4E0D\u8C03\u7528\u89C6\u89C9\u6A21\u578B\u3001\u4E0D\u4E0A\u4F20\u56FE\u7247\uFF1B\u4EC5\u6839\u636E\u5143\u6570\u636E\u7ED9\u51FA\u300C\u4E0B\u8F7D\u54EA\u4E00\u7248 + \u5982\u4F55 update\u300D\u7684\u5EFA\u8BAE\uFF1B`--json` \u8F93\u51FA\u540C\u4E0A\u7ED3\u6784\u4FBF\u4E8E\u811A\u672C\u89E3\u6790"," - `analyze` \u53EF\u7528\u4E8E\u7ED9\u4EBA\u5DE5\u6216\u52A9\u624B\u751F\u6210\u5206\u6790\u64CD\u4F5C\u63D0\u793A\uFF0C\u4E0D\u76F4\u63A5\u8BFB\u53D6\u50CF\u7D20\u5185\u5BB9"," - `open` \u4F1A\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6\uFF1B\u672A\u6307\u5B9A `--output` \u65F6\u4F1A\u5199\u5165\u4E34\u65F6\u76EE\u5F55\u5E76\u5C1D\u8BD5\u6253\u5F00"," - `download --variant` \u7528\u4E8E\u660E\u786E\u4E0B\u8F7D\u6307\u5B9A\u53D8\u4F53\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6253\u5F00",""].join(`
2196
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)}
2197
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(`
2198
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)}
@@ -2222,10 +2222,102 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2222
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(`
2223
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(`
2224
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(`
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
2225
+ `))}function quoteCliArgument(value){return/^[A-Za-z0-9._:/-]+$/u.test(value)?value:JSON.stringify(value)}import{existsSync as existsSync12,mkdirSync as mkdirSync7,readdirSync as readdirSync4,readFileSync as readFileSync11,writeFileSync as writeFileSync7}from"node:fs";import{dirname as dirname8,join as join8,resolve as resolve8}from"node:path";import YAML2 from"yaml";import{createServer}from"node:http";import{createHash as createHash5,randomBytes as randomBytes3}from"node:crypto";import{chmodSync as chmodSync3,existsSync as existsSync10,mkdirSync as mkdirSync5,readdirSync as readdirSync2,readFileSync as readFileSync9,unlinkSync as unlinkSync4,writeFileSync as writeFileSync5}from"node:fs";import{join as join6}from"node:path";import{existsSync as existsSync6,mkdirSync,writeFileSync as writeFileSync2}from"node:fs";import{homedir}from"node:os";import{dirname as dirname4,isAbsolute,join as join3,relative,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 startDir=options.startDir??getInvocationCwd(),workspaceRoot=tryFindWorkspaceRoot(startDir),createLocation=(dir,source)=>({dir,source,insideWorkspace:source==="developer"||source==="workspace-fallback"||(workspaceRoot?isPathInside(workspaceRoot,dir):!1)}),configured=options.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim()??"";if(configured)return createLocation(resolve5(configured),"configured");if(activeFallbackStateDir)return createLocation(activeFallbackStateDir,"workspace-fallback");if((options.distributionProfileName??getDistributionProfile().name)==="developer")return createLocation(resolveDeveloperStateDir(),"developer");let fallbackDir=resolveWorkspaceFallbackStateDir(startDir);return fallbackDir&&existsSync6(resolve5(fallbackDir,WORKSPACE_FALLBACK_MARKER))?createLocation(fallbackDir,"workspace-fallback"):createLocation(join3(options.homeDir??homedir(),DEFAULT_STATE_DIR_NAME),"home")}function isPathInside(parentDir,candidatePath){let relativePath=relative(resolve5(parentDir),resolve5(candidatePath));return relativePath===""||!relativePath.startsWith("..")&&!isAbsolute(relativePath)}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
2227
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(`
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>
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)}import{spawnSync}from"node:child_process";import{createHash as createHash3,randomBytes}from"node:crypto";import{chmodSync,existsSync as existsSync7,lstatSync as lstatSync2,mkdirSync as mkdirSync2,readFileSync as readFileSync7,renameSync,unlinkSync,writeFileSync as writeFileSync3}from"node:fs";import{join as join4}from"node:path";var CREDENTIAL_WARNING_STATE_FILE="credential-warning-state.json",DEFAULT_WARNING_INTERVAL_MS=1440*60*1e3,WINDOWS_ACL_SCRIPT=String.raw`
2229
+ $ErrorActionPreference = 'Stop'
2230
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
2231
+ $credentialPath = $env:VOOBASE_CREDENTIAL_PATH
2232
+ if ([string]::IsNullOrWhiteSpace($credentialPath)) { throw 'credential path missing' }
2233
+ $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
2234
+ $currentSid = $identity.User.Value
2235
+ $acl = Get-Acl -LiteralPath $credentialPath
2236
+ $sddl = $acl.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::All)
2237
+ $rawDescriptor = New-Object System.Security.AccessControl.RawSecurityDescriptor($sddl)
2238
+ $rules = @()
2239
+ foreach ($rule in $acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])) {
2240
+ $rules += @{
2241
+ sid = $rule.IdentityReference.Value
2242
+ type = [int]$rule.AccessControlType
2243
+ rights = [int64]$rule.FileSystemRights
2244
+ }
2245
+ }
2246
+ @{
2247
+ owner_sid = $acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value
2248
+ current_sid = $currentSid
2249
+ dacl_present = ($null -ne $rawDescriptor.DiscretionaryAcl)
2250
+ rules = $rules
2251
+ } | ConvertTo-Json -Compress -Depth 4
2252
+ `;function inspectCredentialSecurity(options={}){let platform=options.platform??process.platform,stateLocation=options.stateLocation??resolveCliStateLocation(options.stateResolution),credentialPath=options.credentialsPath??join4(stateLocation.dir,"credentials.json"),credentialsExist=options.credentialsExist??existsSync7(credentialPath),backend=options.backend??(credentialsExist?"file":"none");if(!credentialsExist&&backend==="none")return{status:"ok",code:"credential_security_ok",backend,legacy_plaintext:!1,state:serializeStateLocation(stateLocation),credential_path:credentialPath,permissions:{status:"not_applicable",detail:"no_local_credentials"},findings:[]};let findings=[];stateLocation.insideWorkspace&&findings.push({code:"credential_state_in_workspace",level:"warning",message:"CLI \u51ED\u636E\u72B6\u6001\u76EE\u5F55\u4F4D\u4E8E\u5F53\u524D\u5DE5\u4F5C\u533A\u5185\uFF0C\u672C\u6B21\u547D\u4EE4\u5C06\u7EE7\u7EED\u6267\u884C\u3002",action:"\u5C06 PLATFORM_STATE_DIR \u8C03\u6574\u5230\u5F53\u524D\u7528\u6237\u4E13\u5C5E\u76EE\u5F55\u540E\u91CD\u65B0\u767B\u5F55\u3002"}),credentialsExist&&findings.push({code:"credential_store_legacy_plaintext",level:"warning",message:"CLI \u51ED\u636E\u4ECD\u4FDD\u5B58\u5728\u517C\u5BB9\u660E\u6587\u6587\u4EF6\u4E2D\uFF0C\u672C\u6B21\u547D\u4EE4\u5C06\u7EE7\u7EED\u6267\u884C\u3002",action:"\u8FD0\u884C `platform diagnostics credentials` \u67E5\u770B\u5B89\u5168\u72B6\u6001\u4E0E\u8FC1\u79FB\u5EFA\u8BAE\u3002"});let permissions=credentialsExist?inspectCredentialPermissions(credentialPath,platform,options):{status:"not_applicable",detail:"no_legacy_plaintext"};return permissions.status==="warning"?findings.push({code:"credential_acl_too_broad",level:"warning",message:"\u51ED\u636E\u6587\u4EF6\u6743\u9650\u53EF\u80FD\u5141\u8BB8\u975E\u9884\u671F\u672C\u673A\u4E3B\u4F53\u8BFB\u53D6\uFF0C\u672C\u6B21\u547D\u4EE4\u5C06\u7EE7\u7EED\u6267\u884C\u3002",action:"\u8FD0\u884C `platform diagnostics credentials` \u67E5\u770B\u8DEF\u5F84\uFF0C\u5E76\u6536\u7D27\u8BE5\u6587\u4EF6\u53CA\u7236\u76EE\u5F55\u6743\u9650\u3002"}):permissions.status==="unknown"&&findings.push({code:"credential_acl_unverified",level:"warning",message:"\u5F53\u524D\u65E0\u6CD5\u53EF\u9760\u5224\u65AD\u51ED\u636E\u6587\u4EF6\u6743\u9650\uFF0C\u672C\u6B21\u547D\u4EE4\u5C06\u7EE7\u7EED\u6267\u884C\u3002",action:"\u8FD0\u884C `platform diagnostics credentials` \u67E5\u770B\u8BCA\u65AD\u8BE6\u60C5\u3002"}),{status:findings.some(finding=>finding.level==="error")?"error":findings.length>0?"warning":"ok",code:findings[0]?.code??"credential_security_ok",backend,legacy_plaintext:credentialsExist,state:serializeStateLocation(stateLocation),credential_path:credentialPath,permissions,findings}}function formatCredentialSecurityReportText(report){let lines=["credential security diagnostics:",`- status: ${report.status}`,`- code: ${report.code}`,`- backend: ${report.backend}`,`- state_dir: ${report.state.dir}`,`- state_source: ${report.state.source}`,`- credential_path: ${report.credential_path}`,`- legacy_plaintext: ${report.legacy_plaintext}`,`- permissions: ${report.permissions.status} (${report.permissions.detail})`];for(let finding of report.findings)lines.push(`- warning [${finding.code}]: ${finding.message}`),lines.push(`- action: ${finding.action}`);return`${lines.join(`
2253
+ `)}
2254
+ `}function emitCredentialSecurityWarnings(report,options={}){let warningFindings=report.findings.filter(finding=>finding.level==="warning");if(warningFindings.length===0)return!1;let now=options.now??new Date,fingerprint=createCredentialWarningFingerprint(report),readState=options.readState??(()=>readCredentialWarningState(report.state.dir)),writeState=options.writeState??(state=>writeCredentialWarningState(report.state.dir,state)),previous=readState(),lastNotifiedAt=previous?Date.parse(previous.last_notified_at):Number.NaN;if(previous?.fingerprint===fingerprint&&Number.isFinite(lastNotifiedAt)&&now.getTime()-lastNotifiedAt>=0&&now.getTime()-lastNotifiedAt<(options.intervalMs??DEFAULT_WARNING_INTERVAL_MS))return!1;let message=warningFindings.flatMap(finding=>[`[${finding.code}] ${finding.message}`,`\u5EFA\u8BAE\uFF1A${finding.action}`]).join(`
2255
+ `);(options.emit??(value=>process.stderr.write(`${value}
2256
+ `)))(message);try{writeState({fingerprint,last_notified_at:now.toISOString()})}catch{}return!0}function createCredentialWarningFingerprint(report){return createHash3("sha256").update(JSON.stringify({backend:report.backend,state_dir:report.state.dir,state_source:report.state.source,inside_workspace:report.state.inside_workspace,permission_detail:report.permissions.detail,findings:report.findings.map(finding=>finding.code).sort()})).digest("hex")}function readCredentialWarningState(stateDir){try{let payload=JSON.parse(readFileSync7(join4(stateDir,CREDENTIAL_WARNING_STATE_FILE),"utf8"));if(typeof payload.fingerprint=="string"&&typeof payload.last_notified_at=="string")return{fingerprint:payload.fingerprint,last_notified_at:payload.last_notified_at}}catch{}return null}function writeCredentialWarningState(stateDir,state){mkdirSync2(stateDir,{recursive:!0});let targetPath=join4(stateDir,CREDENTIAL_WARNING_STATE_FILE),temporaryPath=`${targetPath}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;writeFileSync3(temporaryPath,`${JSON.stringify(state,null,2)}
2257
+ `,"utf8");try{chmodSync(temporaryPath,384),renameSync(temporaryPath,targetPath)}catch(error){try{existsSync7(temporaryPath)&&unlinkSync(temporaryPath)}catch{}throw error}}function inspectCredentialPermissions(credentialPath,platform,options){if(platform==="win32"){if(options.probeWindowsAcl===!1)return{status:"unknown",detail:"windows_acl_probe_deferred"};try{return(options.windowsAclInspector??inspectWindowsCredentialAcl)(credentialPath)}catch{return{status:"unknown",detail:"windows_acl_probe_failed"}}}try{let stat2=(options.statCredential??(path3=>{let value=lstatSync2(path3);return{mode:value.mode,uid:value.uid,isFile:value.isFile()}}))(credentialPath);if(stat2.isFile===!1)return{status:"unknown",detail:"credential_path_not_regular_file"};let currentUid=options.currentUid??(typeof process.getuid=="function"?process.getuid():void 0),mode=stat2.mode&511;return currentUid===void 0?{status:"unknown",detail:"posix_current_uid_unavailable"}:(mode&63)===0&&stat2.uid===currentUid?{status:"secure",detail:"owner_read_write_only"}:{status:"warning",detail:(mode&63)!==0?"posix_mode_too_broad":"posix_owner_mismatch"}}catch{return{status:"unknown",detail:"posix_permission_probe_failed"}}}function inspectWindowsCredentialAcl(credentialPath){let result=spawnSync(resolveWindowsPowerShellExecutable(),["-NoLogo","-NoProfile","-NonInteractive","-Command",WINDOWS_ACL_SCRIPT],{encoding:"utf8",env:{...process.env,VOOBASE_CREDENTIAL_PATH:credentialPath},shell:!1,timeout:5e3,windowsHide:!0});if(result.error||result.status!==0)return{status:"unknown",detail:result.error?.code==="ETIMEDOUT"?"windows_acl_probe_timeout":"windows_acl_probe_failed"};try{return classifyWindowsAclPayload(JSON.parse(result.stdout.trim()))}catch{}return{status:"unknown",detail:"windows_acl_probe_invalid_output"}}function classifyWindowsAclPayload(value){if(!isWindowsAclPayload(value))return{status:"unknown",detail:"windows_acl_probe_invalid_output"};if(value.owner_sid!==value.current_sid)return{status:"warning",detail:"windows_acl_owner_mismatch"};if(!value.dacl_present)return{status:"warning",detail:"windows_null_dacl"};let allowedReadSids=new Set([value.current_sid,"S-1-5-18","S-1-5-32-544"]);return value.rules.some(rule=>rule.type===0&&(rule.rights&1)!==0&&!allowedReadSids.has(rule.sid))?{status:"warning",detail:"unexpected_read_acl"}:{status:"secure",detail:"current_user_acl"}}function isWindowsAclPayload(value){if(!value||typeof value!="object")return!1;let payload=value;return typeof payload.owner_sid=="string"&&typeof payload.current_sid=="string"&&typeof payload.dacl_present=="boolean"&&Array.isArray(payload.rules)&&payload.rules.every(rule=>!!rule&&typeof rule=="object"&&typeof rule.sid=="string"&&typeof rule.type=="number"&&typeof rule.rights=="number")}function serializeStateLocation(stateLocation){return{dir:stateLocation.dir,source:stateLocation.source,inside_workspace:stateLocation.insideWorkspace}}import{createHash as createHash4,randomBytes as randomBytes2}from"node:crypto";import{spawnSync as spawnSync4}from"node:child_process";import{chmodSync as chmodSync2,existsSync as existsSync9,mkdirSync as mkdirSync4,readFileSync as readFileSync8,renameSync as renameSync2,unlinkSync as unlinkSync3,writeFileSync as writeFileSync4}from"node:fs";import{dirname as dirname6,join as join5,resolve as resolve6}from"node:path";import{spawnSync as spawnSync2}from"node:child_process";var MacOSKeychainCredentialStore=class{options;backend="keychain";spawnSyncImpl;constructor(options){this.options=options,this.spawnSyncImpl=options.spawnSyncImpl??spawnSync2}exists(){let result=this.run(["find-generic-password","-a",this.options.account,"-s",this.options.service]);return result.status===44?!1:(this.assertSucceeded(result),!0)}read(){let result=this.run(["find-generic-password","-a",this.options.account,"-s",this.options.service,"-w"]);if(result.status===44)return null;this.assertSucceeded(result);try{return parseStoredCredentials(result.stdout.trim(),this.backend)}catch(error){throw error instanceof CredentialStoreCorruptedError?error:new CredentialStoreCorruptedError(this.backend)}}write(value){let result=this.run(["add-generic-password","-a",this.options.account,"-s",this.options.service,"-U","-w"],`${JSON.stringify(value)}
2258
+ `);this.assertSucceeded(result)}delete(){let result=this.run(["delete-generic-password","-a",this.options.account,"-s",this.options.service]);result.status!==44&&this.assertSucceeded(result)}run(args,input){return this.spawnSyncImpl("/usr/bin/security",args,{encoding:"utf8",input,shell:!1,timeout:8e3,windowsHide:!0,maxBuffer:2*1024*1024})}assertSucceeded(result){if(!result.error&&result.status===0)return;let code2=result.error?.code,reason=code2==="ENOENT"?"command_missing":code2==="ETIMEDOUT"?"timeout":result.status===36||result.status===51?"access_denied":"operation_failed";throw new CredentialStoreUnavailableError(this.backend,reason)}};import{spawnSync as spawnSync3}from"node:child_process";import{existsSync as existsSync8,mkdirSync as mkdirSync3,unlinkSync as unlinkSync2}from"node:fs";import{dirname as dirname5}from"node:path";var DPAPI_SCRIPT=String.raw`
2259
+ $ErrorActionPreference = 'Stop'
2260
+ [Console]::InputEncoding = [System.Text.Encoding]::UTF8
2261
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
2262
+ $credentialPath = $env:VOOBASE_CREDENTIAL_PATH
2263
+ $operation = $env:VOOBASE_CREDENTIAL_OPERATION
2264
+ $service = $env:VOOBASE_CREDENTIAL_SERVICE
2265
+ if ([string]::IsNullOrWhiteSpace($credentialPath)) { throw 'credential path missing' }
2266
+ $sha = [System.Security.Cryptography.SHA256]::Create()
2267
+ try {
2268
+ $entropy = $sha.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($service))
2269
+ } finally {
2270
+ $sha.Dispose()
2271
+ }
2272
+ if ($operation -eq 'write') {
2273
+ $plain = [Console]::In.ReadToEnd()
2274
+ $cipher = [System.Security.Cryptography.ProtectedData]::Protect(
2275
+ [System.Text.Encoding]::UTF8.GetBytes($plain),
2276
+ $entropy,
2277
+ [System.Security.Cryptography.DataProtectionScope]::CurrentUser
2278
+ )
2279
+ $temporaryPath = "$credentialPath.tmp-$PID-$([Guid]::NewGuid().ToString('N'))"
2280
+ [System.IO.File]::WriteAllBytes($temporaryPath, $cipher)
2281
+ Move-Item -LiteralPath $temporaryPath -Destination $credentialPath -Force
2282
+ exit 0
2283
+ }
2284
+ if ($operation -eq 'read') {
2285
+ $cipher = [System.IO.File]::ReadAllBytes($credentialPath)
2286
+ $plainBytes = [System.Security.Cryptography.ProtectedData]::Unprotect(
2287
+ $cipher,
2288
+ $entropy,
2289
+ [System.Security.Cryptography.DataProtectionScope]::CurrentUser
2290
+ )
2291
+ [Console]::Out.Write([System.Text.Encoding]::UTF8.GetString($plainBytes))
2292
+ exit 0
2293
+ }
2294
+ throw 'unsupported credential operation'
2295
+ `,WindowsDpapiCredentialStore=class{options;backend="dpapi";spawnSyncImpl;constructor(options){this.options=options,this.spawnSyncImpl=options.spawnSyncImpl??spawnSync3}exists(){return existsSync8(this.options.blobPath)}read(){if(!existsSync8(this.options.blobPath))return null;let result=this.run("read");this.assertSucceeded(result);try{return parseStoredCredentials(result.stdout.trim(),this.backend)}catch(error){throw error instanceof CredentialStoreCorruptedError?error:new CredentialStoreCorruptedError(this.backend)}}write(value){mkdirSync3(dirname5(this.options.blobPath),{recursive:!0});let result=this.run("write",JSON.stringify(value));this.assertSucceeded(result)}delete(){try{unlinkSync2(this.options.blobPath)}catch(error){if(error.code!=="ENOENT")throw new CredentialStoreUnavailableError(this.backend,"operation_failed")}}run(operation,input){return this.spawnSyncImpl(resolveWindowsPowerShellExecutable(),["-NoLogo","-NoProfile","-NonInteractive","-Command",DPAPI_SCRIPT],{encoding:"utf8",input,env:{...process.env,VOOBASE_CREDENTIAL_OPERATION:operation,VOOBASE_CREDENTIAL_PATH:this.options.blobPath,VOOBASE_CREDENTIAL_SERVICE:this.options.service},shell:!1,timeout:8e3,windowsHide:!0,maxBuffer:2*1024*1024})}assertSucceeded(result){if(!result.error&&result.status===0)return;let code2=result.error?.code,reason=code2==="ENOENT"?"command_missing":code2==="ETIMEDOUT"?"timeout":result.status===5?"access_denied":"operation_failed";throw new CredentialStoreUnavailableError(this.backend,reason)}};var CredentialStoreUnavailableError=class extends Error{backend;reason;code="credential_secure_store_unavailable";constructor(backend,reason){super(`Credential store ${backend} is unavailable (${reason}).`),this.backend=backend,this.reason=reason,this.name="CredentialStoreUnavailableError"}},CredentialStoreCorruptedError=class extends Error{backend;code="credential_store_corrupted";constructor(backend){super(`Credential store ${backend} contains invalid data.`),this.backend=backend,this.name="CredentialStoreCorruptedError"}},FileCredentialStore=class{filePath;options;backend="file";constructor(filePath,options={}){this.filePath=filePath,this.options=options}exists(){return existsSync9(this.filePath)}read(){if(!existsSync9(this.filePath))return null;try{return parseStoredCredentials(readFileSync8(this.filePath,"utf8"),this.backend)}catch(error){throw error instanceof CredentialStoreCorruptedError?error:new CredentialStoreUnavailableError(this.backend,"operation_failed")}}write(value){let parentDir=dirname6(this.filePath);mkdirSync4(parentDir,{recursive:!0});let temporaryPath=`${this.filePath}.tmp-${process.pid}-${randomBytes2(4).toString("hex")}`;try{writeFileSync4(temporaryPath,"",{encoding:"utf8",flag:"wx",mode:384}),chmodSync2(temporaryPath,384)}catch{throw tryDeleteFile(temporaryPath),new CredentialStoreUnavailableError(this.backend,"operation_failed")}if((this.options.platform??process.platform)==="win32"){let aclHardened=!1;try{aclHardened=(this.options.windowsAclHardener??hardenWindowsCredentialFileAcl)(temporaryPath)}catch{aclHardened=!1}if(!aclHardened)try{(this.options.onSecurityWarning??defaultFileStoreSecurityWarning)("credential_acl_unverified")}catch{}}try{writeFileSync4(temporaryPath,`${JSON.stringify(value,null,2)}
2296
+ `,{encoding:"utf8",flag:"r+"}),renameSync2(temporaryPath,this.filePath)}catch{throw tryDeleteFile(temporaryPath),new CredentialStoreUnavailableError(this.backend,"operation_failed")}}delete(){tryDeleteFile(this.filePath)}},FileCredentialBackendPreference=class{filePath;constructor(filePath){this.filePath=filePath}isFilePreferred(){try{return JSON.parse(readFileSync8(this.filePath,"utf8")).preferred_backend==="file"}catch{return!1}}preferFile(){let parentDir=dirname6(this.filePath);mkdirSync4(parentDir,{recursive:!0});let temporaryPath=`${this.filePath}.tmp-${process.pid}-${randomBytes2(4).toString("hex")}`;try{writeFileSync4(temporaryPath,`${JSON.stringify({preferred_backend:"file",reason:"secure_cleanup_failed"},null,2)}
2297
+ `,{encoding:"utf8",flag:"wx",mode:384}),chmodSync2(temporaryPath,384),renameSync2(temporaryPath,this.filePath)}catch{throw tryDeleteFile(temporaryPath),new CredentialStoreUnavailableError("file","operation_failed")}}clear(){tryDeleteFile(this.filePath)}};function readCredentialsWithFallback(options){if(options.backendPreference?.isFilePreferred()){let preferredCredentials=options.legacyStore.read();if(preferredCredentials)return{credentials:preferredCredentials,backend:options.legacyStore.backend,warnings:["credential_secure_store_unavailable"]};try{options.backendPreference.clear()}catch{}}let secureFailure;if(options.secureStore)try{let secureCredentials=options.secureStore.read();if(secureCredentials)return{credentials:secureCredentials,backend:options.secureStore.backend,warnings:[]}}catch(error){secureFailure=error}try{let legacyCredentials=options.legacyStore.read();if(legacyCredentials)return{credentials:legacyCredentials,backend:options.legacyStore.backend,warnings:deduplicateWarnings([secureFailure?classifySecureStoreFailureWithLegacyFallback(secureFailure):"credential_migration_pending"])}}catch(error){throw error instanceof CredentialStoreCorruptedError||error instanceof CredentialStoreUnavailableError?error:new CredentialStoreUnavailableError("file","operation_failed")}if(secureFailure)throw secureFailure instanceof CredentialStoreCorruptedError||secureFailure instanceof CredentialStoreUnavailableError?secureFailure:new CredentialStoreUnavailableError(options.secureStore?.backend??"file","operation_failed");return{credentials:null,backend:"none",warnings:[]}}function writeCredentialsWithFallback(value,options){if(options.secureStore)try{options.secureStore.write(value);let verified=options.secureStore.read();if(!verified||!credentialsEqual(value,verified))throw new CredentialStoreCorruptedError(options.secureStore.backend);try{options.legacyStore.delete();try{options.backendPreference?.clear()}catch{}return{backend:options.secureStore.backend,warnings:[],legacyDeleted:!0}}catch{return{backend:options.secureStore.backend,warnings:["credential_migration_failed"],legacyDeleted:!1}}}catch{options.legacyStore.write(toFileFallbackCredentials(value));let secureDeleted=!1;try{options.secureStore.delete(),secureDeleted=!0}catch{secureDeleted=!1}if(secureDeleted)try{options.backendPreference?.clear()}catch{}else{if(!options.backendPreference)throw new CredentialStoreUnavailableError(options.secureStore.backend,"operation_failed");options.backendPreference.preferFile()}return{backend:options.legacyStore.backend,warnings:["credential_secure_store_unavailable"],legacyDeleted:!1}}return options.legacyStore.write(toFileFallbackCredentials(value)),{backend:options.legacyStore.backend,warnings:[],legacyDeleted:!1}}function migrateLegacyCredentials(options){let legacyCredentials;try{legacyCredentials=options.legacyStore.read()}catch{return{status:"failed",backend:"file",warnings:["credential_migration_failed"],legacyDeleted:!1}}if(!legacyCredentials){if(!options.secureStore)return{status:"not_needed",backend:"none",warnings:[],legacyDeleted:!1};try{return{status:"not_needed",backend:options.secureStore.read()?options.secureStore.backend:"none",warnings:[],legacyDeleted:!1}}catch(error){return{status:"failed",backend:options.secureStore.backend,warnings:[classifySecureStoreFailure(error)],legacyDeleted:!1}}}if(!options.secureStore)return{status:"failed",backend:"file",warnings:["credential_secure_store_unavailable"],legacyDeleted:!1};if(!options.backendPreference?.isFilePreferred())try{if(options.secureStore.read())try{options.legacyStore.delete();try{options.backendPreference?.clear()}catch{}return{status:"not_needed",backend:options.secureStore.backend,warnings:[],legacyDeleted:!0}}catch{return{status:"failed",backend:options.secureStore.backend,warnings:["credential_migration_failed"],legacyDeleted:!1}}}catch(error){if(!(error instanceof CredentialStoreCorruptedError))return{status:"failed",backend:options.secureStore.backend,warnings:["credential_secure_store_unavailable"],legacyDeleted:!1}}try{options.secureStore.write(legacyCredentials);let verified=options.secureStore.read();if(!verified||!credentialsEqual(legacyCredentials,verified))throw new CredentialStoreCorruptedError(options.secureStore.backend);options.legacyStore.delete();try{options.backendPreference?.clear()}catch{}return{status:"migrated",backend:options.secureStore.backend,warnings:[],legacyDeleted:!0}}catch{try{options.secureStore.delete()}catch{}return{status:"failed",backend:options.secureStore.backend,warnings:["credential_migration_failed"],legacyDeleted:!1}}}function toFileFallbackCredentials(value){let{exchange_subject_token:_subjectToken,exchange_subject_token_type:_subjectTokenType,mode_expires_at:_modeExpiresAt,...safeValue}=value;return safeValue.credential_mode==="pat_exchange"&&(safeValue.credential_mode="seeded_token"),safeValue}function credentialsEqual(left,right){return JSON.stringify(left)===JSON.stringify(right)}function classifySecureStoreFailure(error){return error instanceof CredentialStoreCorruptedError?"credential_store_corrupted":"credential_secure_store_unavailable"}function classifySecureStoreFailureWithLegacyFallback(error){return error instanceof CredentialStoreCorruptedError?"credential_migration_failed":"credential_secure_store_unavailable"}function deduplicateWarnings(warnings){return[...new Set(warnings)]}var WINDOWS_HARDEN_ACL_SCRIPT=String.raw`
2298
+ $ErrorActionPreference = 'Stop'
2299
+ $credentialPath = $env:VOOBASE_CREDENTIAL_PATH
2300
+ if ([string]::IsNullOrWhiteSpace($credentialPath)) { throw 'credential path missing' }
2301
+ $currentSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
2302
+ $acl = Get-Acl -LiteralPath $credentialPath
2303
+ $acl.SetAccessRuleProtection($true, $false)
2304
+ foreach ($existingRule in @($acl.Access)) {
2305
+ $acl.PurgeAccessRules($existingRule.IdentityReference)
2306
+ }
2307
+ $acl.SetOwner($currentSid)
2308
+ foreach ($sidValue in @($currentSid.Value, 'S-1-5-18', 'S-1-5-32-544')) {
2309
+ $sid = New-Object System.Security.Principal.SecurityIdentifier($sidValue)
2310
+ $rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
2311
+ $sid,
2312
+ [System.Security.AccessControl.FileSystemRights]::FullControl,
2313
+ [System.Security.AccessControl.AccessControlType]::Allow
2314
+ )
2315
+ [void]$acl.AddAccessRule($rule)
2316
+ }
2317
+ Set-Acl -LiteralPath $credentialPath -AclObject $acl
2318
+ `;function hardenWindowsCredentialFileAcl(filePath){let result=spawnSync4(resolveWindowsPowerShellExecutable(),["-NoLogo","-NoProfile","-NonInteractive","-Command",WINDOWS_HARDEN_ACL_SCRIPT],{encoding:"utf8",env:{...process.env,VOOBASE_CREDENTIAL_PATH:filePath},shell:!1,timeout:8e3,windowsHide:!0,maxBuffer:2097152});return!result.error&&result.status===0}function defaultFileStoreSecurityWarning(code2){process.stderr.write(`[${code2}] Windows \u51ED\u636E\u6587\u4EF6\u5DF2\u5199\u5165\uFF0C\u4F46\u672A\u80FD\u786E\u8BA4\u5F53\u524D\u7528\u6237\u4E13\u5C5E ACL\uFF1B\u672C\u6B21\u767B\u5F55\u5C06\u7EE7\u7EED\u3002
2319
+ \u5EFA\u8BAE\uFF1A\u8FD0\u884C \`platform diagnostics credentials\` \u67E5\u770B\u6743\u9650\u72B6\u6001\u3002
2320
+ `)}function createCredentialStore(options){let platform=options.platform??process.platform,service=resolveCredentialStoreService(options.profileName,options.stateDir);return platform==="darwin"?new MacOSKeychainCredentialStore({service,account:"credentials"}):platform==="win32"?new WindowsDpapiCredentialStore({blobPath:join5(options.stateDir,"credentials.dpapi"),service}):new FileCredentialStore(join5(options.stateDir,"credentials.json"),{platform})}function resolveCredentialStoreService(profileName,stateDir){let stateIdentity=createHash4("sha256").update(resolve6(stateDir)).digest("hex").slice(0,16);return`cn.voobase.platform-cli.${sanitizeProfileName(profileName)}.${stateIdentity}`}function parseStoredCredentials(serialized,backend){try{let value=JSON.parse(serialized);if(!value||typeof value!="object"||typeof value.access_token!="string"||typeof value.issued_at!="string")throw new Error("invalid credential shape");return value}catch{throw new CredentialStoreCorruptedError(backend)}}function sanitizeProfileName(profileName){return profileName.trim().toLowerCase().replace(/[^a-z0-9._-]+/gu,"-")||"default"}function tryDeleteFile(filePath){try{unlinkSync3(filePath)}catch(error){if(error.code!=="ENOENT")throw new CredentialStoreUnavailableError("file","operation_failed")}}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,credentialOriginBackend=Symbol("credentialOriginBackend"),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(resolve20=>{setTimeout(resolve20,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>
2229
2321
  <html lang="zh-CN">
2230
2322
  <head>
2231
2323
  <meta charset="utf-8" />
@@ -2359,12 +2451,11 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2359
2451
  <p class="close-hint">\u8BF7\u91CD\u65B0\u5728\u7EC8\u7AEF\u6267\u884C platform login</p>
2360
2452
  </div>
2361
2453
  </body>
2362
- </html>`}function escapeHtml(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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)}
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)}
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)}
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(`
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(`
2454
+ </html>`}function escapeHtml(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}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 getCliStateDir(){return resolveCliStateDir()}var CliLegacyCredentialStore=class{platform;backend="file";constructor(platform){this.platform=platform}exists(){return existsSync10(getCredentialPath())}read(){return new FileCredentialStore(getCredentialPath(),{platform:this.platform}).read()}write(value){withCliStateFileWriteFallback({fileName:"credentials.json",operation:"\u5199\u5165",write:({filePath})=>new FileCredentialStore(filePath,{platform:this.platform}).write(value)})}delete(){new FileCredentialStore(getCredentialPath(),{platform:this.platform}).delete()}};function resolveCredentialStores(options={}){let stateDir=options.stateDir??getCliStateDir(),platform=options.platform??process.platform,profileName=options.profileName??getDistributionProfile().name,legacyStore=options.legacyStore??(options.stateDir?new FileCredentialStore(join6(stateDir,"credentials.json"),{platform}):new CliLegacyCredentialStore(platform)),hasInjectedStore=Object.prototype.hasOwnProperty.call(options,"secureStore")||Object.prototype.hasOwnProperty.call(options,"legacyStore"),backendPreference=options.backendPreference??(hasInjectedStore?{isFilePreferred:()=>!1,preferFile:()=>{},clear:()=>{}}:new FileCredentialBackendPreference(join6(stateDir,"credential-backend-preference.json")));if(Object.prototype.hasOwnProperty.call(options,"secureStore"))return{secureStore:options.secureStore??null,legacyStore,backendPreference};if(profileName==="developer"||profileName==="test-only")return{secureStore:null,legacyStore,backendPreference};let selectedStore=createCredentialStore({platform,stateDir,profileName});return{secureStore:selectedStore.backend==="file"?null:selectedStore,legacyStore,backendPreference}}function markCredentialOrigin(credentials,backend){return Object.defineProperty(credentials,credentialOriginBackend,{value:backend,enumerable:!1,configurable:!0}),credentials}function getCredentialOrigin(credentials){return credentials[credentialOriginBackend]}function emitCredentialStoreWarnings(warnings,backend){if(warnings.length===0&&backend!=="file"){let report2=inspectCredentialSecurity({credentialsPath:getCredentialPath(),credentialsExist:existsSync10(getCredentialPath()),backend,probeWindowsAcl:!1});emitCredentialSecurityWarnings(report2);return}let report=inspectCredentialSecurity({credentialsPath:getCredentialPath(),credentialsExist:existsSync10(getCredentialPath()),backend,probeWindowsAcl:!1}),existingCodes=new Set(report.findings.map(finding=>finding.code));for(let code2 of warnings){if(existingCodes.has(code2))continue;let detail=credentialStoreWarningDetail(code2);report.findings.push({code:code2,level:code2==="credential_store_corrupted"?"error":"warning",...detail})}report.status=report.findings.some(finding=>finding.level==="error")?"error":report.findings.length>0?"warning":"ok",report.code=report.findings[0]?.code??"credential_security_ok",emitCredentialSecurityWarnings(report)}function credentialStoreWarningDetail(code2){switch(code2){case"credential_migration_pending":return{message:"\u68C0\u6D4B\u5230\u65E7\u7248\u660E\u6587\u51ED\u636E\uFF0C\u5F53\u524D\u767B\u5F55\u6001\u4ECD\u53EF\u7EE7\u7EED\u4F7F\u7528\u3002",action:"\u8FD0\u884C `platform credentials migrate` \u8FC1\u79FB\u5230\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u3002"};case"credential_migration_failed":return{message:"\u51ED\u636E\u5B89\u5168\u8FC1\u79FB\u672A\u5B8C\u6210\uFF0C\u5DF2\u4FDD\u7559\u539F\u6709\u53EF\u7528\u767B\u5F55\u6001\u3002",action:"\u8FD0\u884C `platform diagnostics credentials` \u67E5\u770B\u72B6\u6001\u540E\u91CD\u8BD5\u8FC1\u79FB\u3002"};case"credential_store_corrupted":return{message:"\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u4E2D\u7684 CLI \u51ED\u636E\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u5DF2\u5C1D\u8BD5\u517C\u5BB9\u51ED\u636E\u3002",action:"\u5982\u65E0\u517C\u5BB9\u51ED\u636E\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002"};default:return{message:"\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u5F53\u524D\u4E0D\u53EF\u7528\uFF0C\u5DF2\u4F7F\u7528\u517C\u5BB9\u6587\u4EF6\u4E14\u672C\u6B21\u547D\u4EE4\u7EE7\u7EED\u6267\u884C\u3002",action:"\u8FD0\u884C `platform diagnostics credentials` \u67E5\u770B\u72B6\u6001\u5E76\u5728\u6062\u590D\u540E\u91CD\u8BD5\u8FC1\u79FB\u3002"}}}function loadStoredCredentials(storageOptions={}){let stores=resolveCredentialStores(storageOptions),result=readCredentialsWithFallback(stores);return emitCredentialStoreWarnings(result.warnings,result.backend),result.credentials&&result.backend!=="none"?markCredentialOrigin(result.credentials,result.backend):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 existsSync10(cliContextPath)?JSON.parse(readFileSync9(cliContextPath,"utf8")):null}function persistCredentials(credentials,storageOptions={}){let stores=resolveCredentialStores(storageOptions),result=writeCredentialsWithFallback(credentials,stores);return markCredentialOrigin(credentials,result.backend),emitCredentialStoreWarnings(result.warnings,result.backend),result}function migrateStoredCredentials(storageOptions={}){let stores=resolveCredentialStores(storageOptions),result=migrateLegacyCredentials(stores);return emitCredentialStoreWarnings(result.warnings,result.backend),result}function inspectStoredCredentialSecurity(storageOptions={}){let stores=resolveCredentialStores(storageOptions),credentialsPath=getCredentialPath(),legacyExists=stores.legacyStore.exists?.()??existsSync10(credentialsPath),backend=legacyExists?"file":"none",secureWarning=null;if(stores.secureStore?.exists)try{stores.secureStore.exists()&&(backend=stores.secureStore.backend)}catch(error){secureWarning=error instanceof Error&&"code"in error&&error.code==="credential_store_corrupted"?"credential_store_corrupted":"credential_secure_store_unavailable"}let report=inspectCredentialSecurity({credentialsPath,credentialsExist:legacyExists,backend});return secureWarning&&!report.findings.some(finding=>finding.code===secureWarning)&&(report.findings.push({code:secureWarning,level:secureWarning==="credential_store_corrupted"?"error":"warning",...credentialStoreWarningDetail(secureWarning)}),report.status=secureWarning==="credential_store_corrupted"?"error":"warning",report.code=report.findings[0]?.code??secureWarning),report}function clearStoredAuthentication(storageOptions={}){let stateDir=storageOptions.stateDir??getCliStateDir(),stores=resolveCredentialStores({...storageOptions,stateDir}),cleared=[],failed=[],attempt=(target,operation)=>{try{operation(),cleared.push(target)}catch{failed.push({target})}};stores.secureStore&&attempt(stores.secureStore.backend,()=>stores.secureStore.delete()),attempt("legacy_file",()=>stores.legacyStore.delete()),attempt("account_context",()=>deleteFileIfPresent(join6(stateDir,"context.json"))),attempt("warning_state",()=>deleteFileIfPresent(join6(stateDir,"credential-warning-state.json"))),attempt("backend_preference",()=>deleteFileIfPresent(join6(stateDir,"credential-backend-preference.json")));try{let temporaryFailures=deleteCredentialTemporaryFiles(stateDir,storageOptions.temporaryFileDeleter??deleteFileIfPresent);temporaryFailures.length===0&&cleared.push("orphan_temporary_files"),failed.push(...temporaryFailures.map(name=>({target:`orphan_temporary_file:${name}`})))}catch{failed.push({target:"orphan_temporary_files"})}return{status:failed.length>0?"partial":"cleared",cleared,failed}}function deleteFileIfPresent(filePath){try{unlinkSync4(filePath)}catch(error){if(error.code!=="ENOENT")throw error}}function deleteCredentialTemporaryFiles(stateDir,deleter){let entries;try{entries=readdirSync2(stateDir,{withFileTypes:!0,encoding:"utf8"})}catch(error){if(error.code==="ENOENT")return[];throw error}let failed=[];for(let entry of entries)if(!(!entry.isFile()||!/^(?:credentials\.json|credentials\.dpapi|credential-warning-state\.json|credential-backend-preference\.json)\.tmp-[a-z0-9-]+$/iu.test(entry.name)))try{deleter(join6(stateDir,entry.name))}catch{failed.push(entry.name)}return failed}function persistRefreshedCredentials(nextCredentials,previousCredentials,storageOptions){let stores=resolveCredentialStores(storageOptions);if(getCredentialOrigin(previousCredentials)==="file"){stores.legacyStore.write(toFileFallbackCredentials(nextCredentials)),markCredentialOrigin(nextCredentials,"file");let result={backend:"file",warnings:[],legacyDeleted:!1};return emitCredentialStoreWarnings(result.warnings,result.backend),result}return persistCredentials(nextCredentials,{...storageOptions,...stores})}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,storageOptions){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 persistRefreshedCredentials(nextCredentials,credentials,storageOptions),nextCredentials}async function exchangePatCredentials(credentials,storageOptions){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 persistRefreshedCredentials(nextCredentials,credentials,storageOptions),nextCredentials}async function loadStoredCredentialsEnsuringFresh(options={}){let storageOptions=options.storage??{},credentials=loadStoredCredentials(storageOptions);if(!credentials)return null;let expired=isCredentialExpired(credentials);if(!options.forceRefresh&&!expired)return credentials;if(credentials.refresh_token)try{return refreshCredentials(credentials,storageOptions)}catch(error){maybeWrapCredentialRefreshError(error)}if(canUsePatExchange(credentials))try{return exchangePatCredentials(credentials,storageOptions)}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})=>{mkdirSync5(stateDir,{recursive:!0}),writeFileSync5(filePath,`${JSON.stringify({...context,updated_at:new Date().toISOString()},null,2)}
2455
+ `,"utf8"),chmodSync3(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=randomBytes3(16).toString("base64url"),nonce=randomBytes3(16).toString("base64url"),codeVerifier=randomBytes3(32).toString("base64url"),codeChallenge=createHash5("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((resolve20,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(()=>{}),resolve20({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 existsSync11,mkdirSync as mkdirSync6,mkdtempSync as mkdtempSync2,readdirSync as readdirSync3,readFileSync as readFileSync10,renameSync as renameSync3,rmSync,statSync as statSync2,writeFileSync as writeFileSync6}from"node:fs";import{createServer as createNetServer}from"node:net";import{basename as basename3,dirname as dirname7,join as join7,relative as relative2,resolve as resolve7}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=join7(PLATFORM_DIRECTORY,"config.json"),SOURCE_CONTEXT_FILE=join7(PLATFORM_DIRECTORY,"source-context.json"),PLATFORM_BLOCKS_LOCKFILE=join7(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){mkdirSync6(directory,{recursive:!0})}function writeFileIfMissing(path3,content){if(existsSync11(path3))throw new Error(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${path3}`);ensureDirectory(dirname7(path3)),writeFileSync6(path3,content,"utf8")}function listFilesRecursively(root,current=root){if(!existsSync11(current)||!statSync2(current).isDirectory())return[];let files=[];for(let entry of readdirSync3(current,{withFileTypes:!0})){let absolutePath=join7(current,entry.name);if(entry.isDirectory()){files.push(...listFilesRecursively(root,absolutePath));continue}entry.isFile()&&files.push(relative2(root,absolutePath))}return files.sort((left,right)=>left.localeCompare(right))}function seedRuntimeSdkVendor(targetDir){let workspaceRoot=findWorkspaceRoot(),runtimeSdkDistDir=join7(workspaceRoot,"packages","runtime-sdk","dist");if(!existsSync11(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=join7(runtimeSdkDistDir,relativePath),outputPath=join7(targetDir,"vendor","runtime-sdk",relativePath);writeFileIfMissing(outputPath,readFileSync10(sourcePath,"utf8")),created.push(relative2(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=resolve7(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=join7(absoluteTargetDir,file.path);writeFileIfMissing(outputPath,file.content),createdFiles.push(relative2(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=join7(appRoot,"src","app.js");if(!existsSync11(appJsPath))throw new Error(`\u672A\u627E\u5230\u5E94\u7528\u5165\u53E3\u6587\u4EF6: ${appJsPath}`);let spec=getAppDebugScaffoldSpec(scaffold),createdFiles=[],updatedFiles=[],targetFilePath=join7(appRoot,spec.filePath);existsSync11(targetFilePath)||(ensureDirectory(dirname7(targetFilePath)),writeFileSync6(targetFilePath,spec.source,"utf8"),createdFiles.push(relative2(appRoot,targetFilePath).replace(/\\/g,"/")));let appSource=readFileSync10(appJsPath,"utf8"),nextSource=injectDebugRouteIntoAppSource(appSource,spec);return nextSource!==appSource&&(writeFileSync6(appJsPath,nextSource,"utf8"),updatedFiles.push(relative2(appRoot,appJsPath).replace(/\\/g,"/"))),{appRoot,createdFiles,updatedFiles,routePath:spec.routePath}}function readAppManifest(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),manifestPath=join7(appRoot,APP_MANIFEST_FILE),raw=readFileSync10(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=join7(appRoot,LEGACY_BINDING_FILE);if(!existsSync11(bindingPath))return null;let raw=JSON.parse(readFileSync10(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=join7(appRoot,SOURCE_CONTEXT_FILE);if(!existsSync11(sourceContextPath))return null;let raw=JSON.parse(readFileSync10(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=join7(appRoot,SOURCE_CONTEXT_FILE);return ensureDirectory(dirname7(path3)),writeFileSync6(path3,`${JSON.stringify({schema_version:1,...sourceContext,updated_at:new Date().toISOString()},null,2)}
2456
+ `,"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=resolve7(getInvocationCwd(),targetDir);if(validatePortableWorkspacePaths(files),existsSync11(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=dirname7(absoluteTargetDir);ensureDirectory(parentDir);let stagingDir=mkdtempSync2(join7(parentDir,`.${basename3(absoluteTargetDir)}.platform-checkout-`));try{for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);writeFileIfMissing(join7(stagingDir,normalizedPath),file.content)}let now=new Date().toISOString();if(writeFileIfMissing(join7(stagingDir,SOURCE_CONTEXT_FILE),`${JSON.stringify({schema_version:1,...sourceContext,linked_at:sourceContext.linked_at??now,updated_at:now},null,2)}
2457
+ `),existsSync11(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5728\u68C0\u51FA\u8FC7\u7A0B\u4E2D\u88AB\u521B\u5EFA\uFF0C\u62D2\u7EDD\u8986\u76D6: ${absoluteTargetDir}`);renameSync3(stagingDir,absoluteTargetDir)}catch(error){throw rmSync(stagingDir,{recursive:!0,force:!0}),error}return files.map(file=>relative2(getInvocationCwd(),join7(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(`
2458
+ `));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=readdirSync3(currentDir,{withFileTypes:!0}),sourceBytes=0,assetHits=[];for(let entry of entries){let absolutePath=join7(currentDir,entry.name),relativePath=relative2(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=readdirSync3(currentDir,{withFileTypes:!0}),files=[];for(let entry of entries){let absolutePath=join7(currentDir,entry.name),relativePath=relative2(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:readFileSync10(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=resolve7(getInvocationCwd(),startDir);for(;;){let manifestPath=join7(current,APP_MANIFEST_FILE);if(existsSync11(manifestPath)&&statSync2(manifestPath).isFile())return current;let parent=dirname7(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(`
2368
2459
  `)]}:{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}
2369
2460
  ${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(`
2370
2461
  `);next=next.replace(routeMarker,`${routeBlock}
@@ -2373,24 +2464,24 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
2373
2464
  `)}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('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#39;');`," }"," void bootstrap();"," </script>"," </body>","</html>`;","}",""].join(`
2374
2465
  `)}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('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#39;');`," }"," void refreshCms();"," </script>"," </body>","</html>`;","}",""].join(`
2375
2466
  `)}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(`
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(`
2467
+ `)}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=join7(appDir,"package.json"),nodeModulesPath=join7(appDir,"node_modules");if(!existsSync11(packageJsonPath))return null;let packageJson=JSON.parse(readFileSync10(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=>existsSync11(join7(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 existsSync11(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=join7(appRoot,"resources","db","migrations");if(!existsSync11(migrationsDir)||!statSync2(migrationsDir).isDirectory())return!1;for(let entry of readdirSync3(migrationsDir,{withFileTypes:!0})){if(!entry.isFile())continue;if(readFileSync10(join7(migrationsDir,entry.name),"utf8").split(`
2377
2468
  `).map(line=>line.replace(/--.*$/,"").trim()).filter(Boolean).join(`
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(`
2469
+ `).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(resolve20=>{let server=createNetServer(),finish=available=>{server.removeAllListeners(),resolve20(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((resolve20,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}resolve20(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=join7(directory,SOURCE_CONTEXT_FILE);throw new Error(existsSync11(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=join7(cwd,"package.json");if(!existsSync11(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(readFileSync10(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(`
2379
2470
  `))}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}
2380
2471
 
2381
2472
  `),process.stdout.write(`${response.file.content}${response.file.content.endsWith(`
2382
2473
  `)?"":`
2383
- `}`)}async function runSourceSearch(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source search` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let query=args.rest[3]?.trim()||readStringOption2(args,"query");if(!query)throw new Error("`platform app-library source search` \u9700\u8981 <query>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--query`\u3002");let response=await sdk.searchLightAppLibraryEntrySource(entryId,query).catch(error=>{throw formatAppLibraryError(error,"source(search)")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`query: ${query}`,`items: ${response.items.length}`,...response.items.map(item=>`- ${item.path}${item.excerpt?` :: ${item.excerpt}`:""}`)])}async function runCreate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),payload=buildCreatePayload(args,config2);if(!payload.name?.trim())throw new Error("`platform app-library create` \u9700\u8981\u540D\u79F0\u3002\u8BF7\u5728 `app-library.yaml` \u4E2D\u8BBE\u7F6E `name`\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--name`\u3002");let response=await sdk.createLightAppLibraryEntry(payload).catch(error=>{throw formatAppLibraryError(error,"create")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u8349\u7A3F\u5DF2\u521B\u5EFA\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runUpdate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library update` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"update")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u5DF2\u66F4\u65B0\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runSubmit(args,sdk,deps){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library submit` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");if(config2){let updatedEntry=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"submit(update-metadata)")});maybeWriteConfig(configPath,config2,updatedEntry,args)}let{files,appRoot}=(deps.collectWorkspaceFiles??collectSourceWorkspaceFiles)(process.cwd()),response=await sdk.submitLightAppLibraryEntrySnapshot(entryId,{files}).catch(error=>{throw formatAppLibraryError(error,"submit")});writeJsonOrText(args.options.json===!0,{snapshot:response,app_root:appRoot},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5FEB\u7167\u5DF2\u63D0\u4EA4\u3002",`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`files: ${response.files_count}`,`bytes: ${response.content_bytes}`,`app_root: ${appRoot}`])}async function runStateAction(args,sdk,action){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error(`\`platform app-library ${action}\` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 \`app-library.yaml\` \u4E2D\u63D0\u4F9B \`entry_id\`\u3002`);let response=action==="publish"?await sdk.publishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"publish")}):action==="unpublish"?await sdk.unpublishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"unpublish")}):await sdk.archiveLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"archive")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${response.entry_id}`,`status: ${response.status}`])}async function runDelete(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library delete` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.deleteLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"delete")});writeJsonOrText(args.options.json===!0,response,[`\u5DF2\u5220\u9664\u6761\u76EE ${response.entry_id}`])}async function runCheckout(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library checkout` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let entry=await sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(entry)")}),source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(source)")}),targetDir=readStringOption2(args,"dir")??sanitizeDirectoryName(entry.name||entry.entry_id),absoluteTargetDir=resolve7(process.cwd(),targetDir);ensureEmptyDirectory(absoluteTargetDir);let sourceIncludesConfig=!1;for(let file of source.files){file.path==="app-library.yaml"&&(sourceIncludesConfig=!0);let payload=await sdk.readLightAppLibraryEntrySourceFile(entryId,file.path).catch(error=>{throw formatAppLibraryError(error,`checkout(file:${file.path})`)});writeWorkspaceFile(absoluteTargetDir,payload.file.path,payload.file.content)}let generatedConfigPath=join5(absoluteTargetDir,"app-library.yaml");args.options["no-config"]!==!0&&(args.options["write-config"]===!0||!sourceIncludesConfig)&&saveAppLibraryConfig(generatedConfigPath,materializeConfig(null,entry)),writeJsonOrText(args.options.json===!0,{entry_id:entryId,dir:absoluteTargetDir,files:source.files.length},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5DF2 checkout \u5230\u672C\u5730\u76EE\u5F55\u3002",`entry_id: ${entryId}`,`dir: ${absoluteTargetDir}`,`files: ${source.files.length}`,...args.options["no-config"]===!0?[]:args.options["write-config"]===!0||!sourceIncludesConfig?[`config: ${generatedConfigPath}`]:[]])}async function runOpen(args,deps){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library open` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let url=`http://127.0.0.1:${process.env.TENANT_WORKBENCH_PORT?.trim()||"7102"}/#app-library/${encodeURIComponent(entryId)}`,opened=args.options["no-browser"]===!0?!1:await(deps.openBrowser??tryOpenBrowser)(url);process.stdout.write(`${url}
2474
+ `}`)}async function runSourceSearch(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source search` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let query=args.rest[3]?.trim()||readStringOption2(args,"query");if(!query)throw new Error("`platform app-library source search` \u9700\u8981 <query>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--query`\u3002");let response=await sdk.searchLightAppLibraryEntrySource(entryId,query).catch(error=>{throw formatAppLibraryError(error,"source(search)")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`query: ${query}`,`items: ${response.items.length}`,...response.items.map(item=>`- ${item.path}${item.excerpt?` :: ${item.excerpt}`:""}`)])}async function runCreate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),payload=buildCreatePayload(args,config2);if(!payload.name?.trim())throw new Error("`platform app-library create` \u9700\u8981\u540D\u79F0\u3002\u8BF7\u5728 `app-library.yaml` \u4E2D\u8BBE\u7F6E `name`\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--name`\u3002");let response=await sdk.createLightAppLibraryEntry(payload).catch(error=>{throw formatAppLibraryError(error,"create")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u8349\u7A3F\u5DF2\u521B\u5EFA\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runUpdate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library update` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"update")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u5DF2\u66F4\u65B0\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runSubmit(args,sdk,deps){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library submit` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");if(config2){let updatedEntry=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"submit(update-metadata)")});maybeWriteConfig(configPath,config2,updatedEntry,args)}let{files,appRoot}=(deps.collectWorkspaceFiles??collectSourceWorkspaceFiles)(process.cwd()),response=await sdk.submitLightAppLibraryEntrySnapshot(entryId,{files}).catch(error=>{throw formatAppLibraryError(error,"submit")});writeJsonOrText(args.options.json===!0,{snapshot:response,app_root:appRoot},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5FEB\u7167\u5DF2\u63D0\u4EA4\u3002",`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`files: ${response.files_count}`,`bytes: ${response.content_bytes}`,`app_root: ${appRoot}`])}async function runStateAction(args,sdk,action){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error(`\`platform app-library ${action}\` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 \`app-library.yaml\` \u4E2D\u63D0\u4F9B \`entry_id\`\u3002`);let response=action==="publish"?await sdk.publishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"publish")}):action==="unpublish"?await sdk.unpublishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"unpublish")}):await sdk.archiveLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"archive")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${response.entry_id}`,`status: ${response.status}`])}async function runDelete(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library delete` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.deleteLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"delete")});writeJsonOrText(args.options.json===!0,response,[`\u5DF2\u5220\u9664\u6761\u76EE ${response.entry_id}`])}async function runCheckout(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library checkout` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let entry=await sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(entry)")}),source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(source)")}),targetDir=readStringOption2(args,"dir")??sanitizeDirectoryName(entry.name||entry.entry_id),absoluteTargetDir=resolve8(process.cwd(),targetDir);ensureEmptyDirectory(absoluteTargetDir);let sourceIncludesConfig=!1;for(let file of source.files){file.path==="app-library.yaml"&&(sourceIncludesConfig=!0);let payload=await sdk.readLightAppLibraryEntrySourceFile(entryId,file.path).catch(error=>{throw formatAppLibraryError(error,`checkout(file:${file.path})`)});writeWorkspaceFile(absoluteTargetDir,payload.file.path,payload.file.content)}let generatedConfigPath=join8(absoluteTargetDir,"app-library.yaml");args.options["no-config"]!==!0&&(args.options["write-config"]===!0||!sourceIncludesConfig)&&saveAppLibraryConfig(generatedConfigPath,materializeConfig(null,entry)),writeJsonOrText(args.options.json===!0,{entry_id:entryId,dir:absoluteTargetDir,files:source.files.length},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5DF2 checkout \u5230\u672C\u5730\u76EE\u5F55\u3002",`entry_id: ${entryId}`,`dir: ${absoluteTargetDir}`,`files: ${source.files.length}`,...args.options["no-config"]===!0?[]:args.options["write-config"]===!0||!sourceIncludesConfig?[`config: ${generatedConfigPath}`]:[]])}async function runOpen(args,deps){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library open` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let url=`http://127.0.0.1:${process.env.TENANT_WORKBENCH_PORT?.trim()||"7102"}/#app-library/${encodeURIComponent(entryId)}`,opened=args.options["no-browser"]===!0?!1:await(deps.openBrowser??tryOpenBrowser)(url);process.stdout.write(`${url}
2384
2475
  `),!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
2385
2476
  `),process.stdout.write(`inspect: platform app-library inspect ${entryId}
2386
2477
  `),process.stdout.write(`checkout: platform app-library checkout ${entryId} --dir ./${sanitizeDirectoryName(entryId)}
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)}
2478
+ `)}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||!existsSync12(resolvedPath))return null;let parsed=YAML2.parse(readFileSync11(resolvedPath,"utf8"));return parsed&&typeof parsed=="object"?parsed:null}function resolveAppLibraryConfigPath(filePath){if(filePath?.trim())return resolve8(process.cwd(),filePath.trim());try{return join8(findAppRoot(process.cwd()),"app-library.yaml")}catch{return null}}function resolveWritableAppLibraryConfigPath(filePath){return filePath?.trim()?resolve8(process.cwd(),filePath.trim()):resolveAppLibraryConfigPath()??join8(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(existsSync12(directory)){if(readdirSync4(directory).length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6: ${directory}`);return}mkdirSync7(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=join8(root,normalizedPath);mkdirSync7(dirname8(outputPath),{recursive:!0}),writeFileSync7(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){mkdirSync7(dirname8(path3),{recursive:!0}),writeFileSync7(path3,YAML2.stringify(config2),"utf8")}function runConfigInit(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(existsSync12(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(!existsSync12(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)}
2388
2479
  `);return}process.stdout.write(`${lines.join(`
2389
2480
  `)}
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:
2481
+ `)}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 existsSync17,mkdirSync as mkdirSync10,readFileSync as readFileSync16,unlinkSync as unlinkSync5,writeFileSync as writeFileSync10}from"node:fs";import{dirname as dirname11,isAbsolute as isAbsolute2,join as join12,resolve as resolve9,sep}from"node:path";import{createHash as createHash6}from"node:crypto";import{existsSync as existsSync13,readFileSync as readFileSync12}from"node:fs";import{join as join9}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-${createHash6("sha256").update(content).digest("hex")}`}function readCurrentSha(appRoot,relativePath){let absolutePath=join9(appRoot,relativePath);return existsSync13(absolutePath)?checksumContent(readFileSync12(absolutePath,"utf8")):null}import{existsSync as existsSync15,mkdirSync as mkdirSync9,readFileSync as readFileSync14,readdirSync as readdirSync5,rmSync as rmSync2,writeFileSync as writeFileSync9}from"node:fs";import{dirname as dirname10,join as join11,relative as relative3}from"node:path";import{dirname as dirname9,join as join10}from"node:path";import{existsSync as existsSync14,mkdirSync as mkdirSync8,readFileSync as readFileSync13,writeFileSync as writeFileSync8}from"node:fs";var PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH=".platform/platform-blocks.lock.json";function getPlatformBlocksLockfilePath(appRoot){return join10(appRoot,PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH)}function readPlatformBlocksLockfile(startDir){let{directory:appRoot}=readAppManifest(startDir),path3=getPlatformBlocksLockfilePath(appRoot);if(!existsSync14(path3))return null;let raw=readFileSync13(path3,"utf8"),lockfile=JSON.parse(raw);return{appRoot,path:path3,lockfile,raw}}function writePlatformBlocksLockfile(appRoot,content){let path3=getPlatformBlocksLockfilePath(appRoot);mkdirSync8(dirname9(path3),{recursive:!0});let serialized=typeof content=="string"?content:`${JSON.stringify(content,null,2)}
2482
+ `;return writeFileSync8(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 join11(appRoot,HISTORY_LAST_RELATIVE_DIR)}function writeLastPlatformBlocksHistory(appRoot,args){let historyDir=getPlatformBlocksHistoryLastDir(appRoot);rmSync2(historyDir,{recursive:!0,force:!0}),mkdirSync9(join11(historyDir,"files"),{recursive:!0});for(let file of args.files){if(!file.existed_before||typeof file.content!="string")continue;let snapshotPath=join11(historyDir,"files",file.path);mkdirSync9(dirname10(snapshotPath),{recursive:!0}),writeFileSync9(snapshotPath,file.content,"utf8")}writeFileSync9(join11(historyDir,"lockfile.before.json"),args.lockfileBefore,"utf8"),writeFileSync9(join11(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 writeFileSync9(join11(historyDir,"metadata.json"),`${JSON.stringify(metadata,null,2)}
2483
+ `,"utf8"),historyDir}function restoreLastPlatformBlocksHistory(appRoot){let historyDir=getPlatformBlocksHistoryLastDir(appRoot),metadataPath=join11(historyDir,"metadata.json");if(!existsSync15(metadataPath))throw new Error("\u65E0\u53EF\u56DE\u9000\u7684\u6700\u8FD1\u4E00\u6B21 apply\u3002");let metadata=JSON.parse(readFileSync14(metadataPath,"utf8")),restoredFiles=[],removedFiles=[];for(let file of metadata.managed_files_overwritten){let targetPath=join11(appRoot,file.path);if(!file.existed_before){rmSync2(targetPath,{force:!0}),removedFiles.push(file.path);continue}let snapshotPath=join11(historyDir,"files",file.path),content=readFileSync14(snapshotPath,"utf8");mkdirSync9(dirname10(targetPath),{recursive:!0}),writeFileSync9(targetPath,content,"utf8"),restoredFiles.push(file.path)}let lockfilePath=getPlatformBlocksLockfilePath(appRoot);return mkdirSync9(dirname10(lockfilePath),{recursive:!0}),writeFileSync9(lockfilePath,readFileSync14(join11(historyDir,metadata.lockfile_before_path),"utf8"),"utf8"),{restoredFiles,removedFiles,lockfilePath:relative3(appRoot,lockfilePath).replace(/\\/g,"/")}}function hasLastPlatformBlocksHistory(appRoot){return existsSync15(join11(getPlatformBlocksHistoryLastDir(appRoot),"metadata.json"))}import{existsSync as existsSync16,lstatSync as lstatSync3,readFileSync as readFileSync15}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(`
2484
+ `)),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(!existsSync16(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(!existsSync16(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=lstatSync3(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(readFileSync15(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("/")),relative9=path2.relative(appRoot,absolutePath);return relative9.length>0&&!relative9.startsWith("..")&&!path2.isAbsolute(relative9)}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
2485
  - ${result.restoredFiles.join(`
2395
2486
  - `)}`:"\u6062\u590D\u6587\u4EF6: -",result.removedFiles.length>0?`\u5220\u9664\u6587\u4EF6:
2396
2487
  - ${result.removedFiles.join(`
@@ -2403,33 +2494,33 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
2403
2494
  - ${result.removedFiles.join(`
2404
2495
  - `)}`:"\u5220\u9664\u6587\u4EF6: -",`lockfile: ${result.lockfilePath}`,`history: ${result.historyUpdated?"updated":"unchanged"}`,result.verify?formatPlatformBlocksVerifySummary(result.verify):"",""].join(`
2405
2496
  `):["\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(`
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)}
2497
+ `)}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=join12(appRoot,relativePath);return existsSync17(absolutePath)?{path:relativePath,existed_before:!0,content:readFileSync16(absolutePath,"utf8")}:{path:relativePath,existed_before:!1}}function writeManagedFile(appRoot,relativePath,content){let absolutePath=join12(appRoot,relativePath);mkdirSync10(dirname11(absolutePath),{recursive:!0}),writeFileSync10(absolutePath,content,"utf8")}function removeManagedFile(appRoot,relativePath){let absolutePath=resolve9(appRoot,relativePath);existsSync17(absolutePath)&&unlinkSync5(absolutePath)}function assertSafeManagedRemovalPath(appRoot,templateKey,relativePath){let normalizedRoot=resolve9(appRoot),insideAppRoot=resolve9(normalizedRoot,relativePath).startsWith(`${normalizedRoot}${sep}`);if(isAbsolute2(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 existsSync19,lstatSync as lstatSync4,mkdirSync as mkdirSync11,readFileSync as readFileSync18,readdirSync as readdirSync6,renameSync as renameSync4,rmSync as rmSync3,writeFileSync as writeFileSync11}from"node:fs";import{basename as basename4,dirname as dirname12,isAbsolute as isAbsolute3,join as join14,relative as relative4,resolve as resolve10}from"node:path";import{existsSync as existsSync18,readFileSync as readFileSync17}from"node:fs";import{join as join13}from"node:path";var SOURCE_CONTEXT_PATH=join13(".platform","source-context.json");function readJsonIfExists(filePath){return existsSync18(filePath)?JSON.parse(readFileSync17(filePath,"utf8")):null}function detectTemplateKeyFromWorkspace(workspaceDir){let sourceContext=readJsonIfExists(join13(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 existsSync18(join13(workspaceDir,"src","web","app.tsx"))||existsSync18(join13(workspaceDir,"src","server","entry.ts"))?"backend-app-node":(existsSync18(join13(workspaceDir,"src","app.tsx"))||existsSync18(join13(workspaceDir,"src","main.tsx")),"frontend-app-vite")}function resolveAppImportLayout(workspaceDir){let templateKey=detectTemplateKeyFromWorkspace(workspaceDir),frontendRoot=templateKey==="backend-app-node"?"src/web":"src",importedUpstreamRoot=join13(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(`
2498
+ `))}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(readFileSync18(filePath,"utf8"))}function writeJson(filePath,payload){writeFileSync11(filePath,`${JSON.stringify(payload,null,2)}
2499
+ `,"utf8")}function assertDirectory(pathValue,label){let stats=lstatSync4(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=lstatSync4(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=lstatSync4(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 readdirSync6(sourcePath,{withFileTypes:!0}))validateMergeEntry(join14(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=lstatSync4(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()){mkdirSync11(targetPath,{recursive:!0});for(let entry of readdirSync6(sourcePath,{withFileTypes:!0}))copyMergeEntry(join14(sourcePath,entry.name),join14(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=dirname12(targetPath),relativeParent=relative4(workspaceDir,targetParent);if(relativeParent.startsWith("..")||isAbsolute3(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=join14(currentPath,segment);let stats=lstatSync4(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(lstatSync4(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??renameSync4,removeEntry=deps.removeEntry??rmSync3;try{for(let operation of operations)lstatSync4(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
2500
  `)}}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&&copyMergeEntry(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)}
2501
+ `)}}function validateWorkspace(workspaceDir){assertDirectory(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES.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 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=resolve10(args.workspaceDir);validateWorkspace(workspaceDir);let designImportRoot=join14(workspaceDir,".design-import"),importSummaryPath=join14(designImportRoot,"import-summary.json"),importManifestPath=join14(designImportRoot,"reports","import-manifest.json"),upstreamCleanSourceDir=join14(designImportRoot,"upstream-clean-source");assertDirectory(designImportRoot,".design-import"),assertDirectory(upstreamCleanSourceDir,"upstream-clean-source");let importSummary=readJson(importSummaryPath),importManifest=existsSync19(importManifestPath)?readJson(importManifestPath):{},layout=resolveAppImportLayout(workspaceDir),mergedTargetDir=join14(workspaceDir,...layout.imported_upstream_root.split("/")),upstreamSrcDir=join14(upstreamCleanSourceDir,"src"),upstreamPublicDir=join14(upstreamCleanSourceDir,"public"),mergedPublicTargetDir=join14(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=join14(upstreamSrcDir,name);if(!isSafeSourceDirectory(sourcePath,`upstream clean-source/src/${name}`)){skippedPaths.push(`src/${name}`);continue}validateMergeEntry(sourcePath),sourceMergeEntries.push({name,sourcePath});let targetPath=join14(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),mkdirSync11(dirname12(mergedTargetDir),{recursive:!0}),mkdirSync11(dirname12(mergedPublicTargetDir),{recursive:!0});let runId=randomUUID(),mergedTempDir=join14(dirname12(mergedTargetDir),`.${basename4(mergedTargetDir)}.merge-${runId}.tmp`),publicTempDir=upstreamPublicExists?join14(dirname12(mergedPublicTargetDir),`.${basename4(mergedPublicTargetDir)}.merge-${runId}.tmp`):"",operations=[{targetPath:mergedTargetDir,tempPath:mergedTempDir,backupPath:join14(dirname12(mergedTargetDir),`.${basename4(mergedTargetDir)}.merge-${runId}.bak`),backedUp:!1,installed:!1},{targetPath:mergedPublicTargetDir,tempPath:publicTempDir,backupPath:join14(dirname12(mergedPublicTargetDir),`.${basename4(mergedPublicTargetDir)}.merge-${runId}.bak`),backedUp:!1,installed:!1}];try{mkdirSync11(mergedTempDir,{recursive:!1});for(let entry of sourceMergeEntries)copyMergeEntry(entry.sourcePath,join14(mergedTempDir,entry.name));upstreamPublicExists&&copyMergeEntry(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(join14(designImportRoot,"merge-summary.json"),summary),args.json){process.stdout.write(`${JSON.stringify(summary,null,2)}
2411
2502
  `);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(`
2412
2503
  `)+`
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}
2504
+ `)}import{createHash as createHash7}from"node:crypto";import{copyFileSync as copyFileSync2,existsSync as existsSync20,lstatSync as lstatSync5,mkdtempSync as mkdtempSync3,mkdirSync as mkdirSync12,readFileSync as readFileSync19,readdirSync as readdirSync7,rmSync as rmSync4,statSync as statSync3,unlinkSync as unlinkSync6,writeFileSync as writeFileSync12}from"node:fs";import{spawn}from"node:child_process";import{basename as basename5,dirname as dirname13,extname as extname3,join as join15,relative as relative5,resolve as resolve11}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}
2414
2505
  `)}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(`
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(/^(&quot;?|&#34;?|&apos;?|&#39;?)+/iu,"").replace(/(&quot;?|&#34;?|&apos;?|&#39;?)+$/iu,"").replace(/&amp;/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(`
2506
+ `))}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(!existsSync20(filePath))return fallbackValue;try{return JSON.parse(readFileSync19(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(dirname13(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(dirname13(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=readdirSync7(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join15(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=readdirSync7(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join15(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(/^(&quot;?|&#34;?|&apos;?|&#39;?)+/iu,"").replace(/(&quot;?|&#34;?|&apos;?|&#39;?)+$/iu,"").replace(/&amp;/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=readFileSync19(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:relative5(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=join15(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=>relative5(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=readFileSync19(filePath);return createHash7("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(resolve11(dirname13(sourceFilePath),match2[1]));for(let match2 of sourceText.matchAll(CSS_URL_PATTERN))found.add(resolve11(dirname13(sourceFilePath),match2[2]));return found}function collectLocalAssetCandidates(rootDir,sourceFiles,assetFiles){let assetPathSet=new Set(assetFiles.map(filePath=>resolve11(filePath))),byHash=new Map,referencedAssets=new Map;for(let sourceFilePath of sourceFiles){let raw=readFileSync19(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(relative5(rootDir,sourceFilePath));continue}referencedAssets.set(absoluteRef,{absolute_path:absoluteRef,relative_path:relative5(rootDir,absoluteRef),referenced_by:[relative5(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:existsSync20(join15(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=relative5(rootDir,filePath);if(!textFilePattern.test(relativePath))continue;let lines=readFileSync19(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=join15(rootDir,normalizedTarget),relativePath=relative5(dirname13(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=readFileSync19(absolutePath,"utf8"),rewritten=rewritePathBaseRefsInContent(report.project_dir,absolutePath,before);rewritten.changed&&(args.dryRun||writeFileSync12(absolutePath,rewritten.content,"utf8"),rewrittenFiles.push(relative5(report.project_dir,absolutePath)),rewriteEntries.push({file:relative5(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=readdirSync7(currentDir,{withFileTypes:!0});for(let entry of entries){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;let fullPath=join15(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=[];existsSync20(join15(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}
2507
+ ${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(join15(tmpdir2(),"platform-assetize-remote-")),outputPath=join15(tempRoot,"remote.bin"),headerPath=join15(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:existsSync20(headerPath)?readFileSync19(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):readFileSync19(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 join15(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?resolve11(args.localReport):join15(reportDir,"local-asset-report.json")}function loadLocalUploadMappings(reportPath){if(!existsSync20(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync19(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=relative5(rootDir,resolve11(dirname13(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=relative5(rootDir,resolve11(dirname13(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=readFileSync19(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||writeFileSync12(absolutePath,after,"utf8"),rewrittenFiles.push(relative5(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=join15(report.project_dir,sourcePath);if(!existsSync20(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||unlinkSync6(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=readdirSync7(sourceDir,{withFileTypes:!0});for(let entry of entries)DEFAULT_SKIP_DIRS.has(entry.name)||copyWorkspaceEntry(join15(sourceDir,entry.name),join15(cleanSourceDir,entry.name))}function copyWorkspaceEntry(sourcePath,targetPath){let sourceStats=lstatSync5(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 readdirSync7(sourcePath,{withFileTypes:!0}))copyWorkspaceEntry(join15(sourcePath,entry.name),join15(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir(dirname13(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:join15(reportsDir,"preflight-report.json"),asset_inventory:join15(reportsDir,"asset-inventory.json"),import_manifest:join15(reportsDir,"import-manifest.json"),pending_videos:join15(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(join15(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=join15(tempRoot,`${index+1}-${downloaded.fileName}`);writeFileSync12(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:${createHash7("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=join15(report.project_dir,relativePath),before=readFileSync19(absolutePath,"utf8"),after=before;for(let[originalUrl,finalUrl]of replacements)after=replaceUrlInContent(after,originalUrl,finalUrl);after!==before&&(writeFileSync12(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(join15(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=join15(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(`
2417
2508
  `);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(`
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)}
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)}
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)}
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})}
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)}
2509
+ `)}function escapeMdCell(value){return value.replace(/\|/gu,"\\|")}function ensureDir(dirPath){mkdirSync12(dirPath,{recursive:!0})}function writeJson2(filePath,payload){writeFileSync12(filePath,`${JSON.stringify(payload,null,2)}
2510
+ `,"utf8")}async function runPreprocess(args,sourceDir,deps){let preprocessRoot=join15(sourceDir,".design-preprocess"),cleanSourceDir=join15(preprocessRoot,"clean-source"),reportsDir=join15(preprocessRoot,"reports"),cacheDir=join15(preprocessRoot,"cache"),cacheFile=join15(cacheDir,"assets.json"),lockFile=join15(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(join15(reportsDir,"preflight-report.json"),buildPreflightPayload(report,sourceDir,cleanSourceDir,{detectedType,upstreamSourcePackageBytes,cleanSourcePackageBytesBeforeRewrite,pathBaseViolationsDetected,pathBaseRewrites:pathBaseRewriteResult.rewrite_entries,pathBaseViolationsRemaining,preflightWarnings})),writeFileSync12(join15(reportsDir,"preflight-report.md"),`${renderMarkdown(report)}
2511
+ `,"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(join15(reportsDir,"local-asset-report.json"),localUploadFullReport),writeFileSync12(join15(reportsDir,"local-asset-report.md"),`${renderMarkdown(localUploadFullReport)}
2512
+ `,"utf8");let localRewriteResult=await runRewriteLocal({...args,localReport:join15(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(join15(reportsDir,"asset-inventory.json"),assetInventory),writeJson2(join15(reportsDir,"import-manifest.json"),importManifestWithCache),writeJson2(join15(reportsDir,"warnings.json"),warningsPayload),writeJson2(join15(reportsDir,"pending-videos.json"),{pending_videos:report.pending_videos}),writeFileSync12(join15(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})}
2513
+ `,"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=resolve11(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:join15(result.reports_dir,"preflight-report.json"),asset_inventory:join15(result.reports_dir,"asset-inventory.json"),import_manifest:join15(result.reports_dir,"import-manifest.json"),warnings:join15(result.reports_dir,"warnings.json"),pending_videos:join15(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)}
2423
2514
  `);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(`
2424
2515
  `)+`
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)}
2516
+ `)}import{copyFileSync as copyFileSync3,existsSync as existsSync21,lstatSync as lstatSync6,mkdirSync as mkdirSync13,mkdtempSync as mkdtempSync4,readFileSync as readFileSync20,readdirSync as readdirSync8,renameSync as renameSync5,rmSync as rmSync5,statSync as statSync4,writeFileSync as writeFileSync13}from"node:fs";import{basename as basename6,dirname as dirname14,isAbsolute as isAbsolute4,join as join16,relative as relative6,resolve as resolve12,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(`
2517
+ `))}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){mkdirSync13(dirPath,{recursive:!0})}function assertPathWithinTrustedRoot(trustedRoot,pathValue,label,options={}){let absoluteRoot=resolve12(trustedRoot),absolutePath=resolve12(pathValue),relativePath=relative6(absoluteRoot,absolutePath);if(relativePath===".."||relativePath.startsWith(`..${sep2}`)||isAbsolute4(relativePath))throw new Error(`${label} \u8D85\u51FA\u53D7\u4FE1\u6839\u76EE\u5F55: ${absolutePath}`);let componentPath=absoluteRoot;if(!options.trustRoot){let rootStats=lstatSync6(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=join16(componentPath,component);let stats=lstatSync6(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=lstatSync6(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 readdirSync8(sourcePath,{withFileTypes:!0}))validateImportEntry(join16(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=lstatSync6(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 readdirSync8(sourcePath,{withFileTypes:!0}))copyImportEntry(join16(sourcePath,entry.name),join16(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir2(dirname14(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(dirname14(designImportRoot),designImportRoot,"stage \u76EE\u6807\u8DEF\u5F84",{trustRoot:!0});let existingStats=lstatSync6(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??renameSync5,remove=deps.remove??rmSync5,warn=deps.warn??(message=>process.stderr.write(`${message}
2518
+ `));if(assertReplaceableImportRoot(designImportRoot),!lstatSync6(designImportRoot,{throwIfNoEntry:!1})){rename(stagedRoot,designImportRoot);return}let backupRoot=`${designImportRoot}.backup-${process.pid}-${Date.now()}`;if(existsSync21(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){writeFileSync13(filePath,`${JSON.stringify(payload,null,2)}
2519
+ `,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync20(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=resolve12(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=[join16(absolute,"reports","import-manifest.json"),join16(absolute,"import-manifest.json"),join16(absolute,".design-preprocess","reports","import-manifest.json")];for(let candidate of candidates)if(existsSync21(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=>!existsSync21(join16(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 readdirSync8(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=>existsSync21(join16(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=>existsSync21(join16(sourceReportsDir,fileName)))}function stageReports(sourceReportsDir,stagedReportsDir,reportFiles){for(let fileName of reportFiles){let sourcePath=join16(sourceReportsDir,fileName);copyImportEntry(sourcePath,join16(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=resolve12(args.workspaceDir);validateWorkspace2(workspaceDir);let manifestPath=resolveManifestPath(args.preprocess),reportsDir=resolve12(dirname14(manifestPath)),preprocessInput=resolve12(args.preprocess),preprocessInputRoot=statSync4(preprocessInput,{throwIfNoEntry:!1})?.isFile()?dirname14(preprocessInput):preprocessInput;assertPathWithinTrustedRoot(preprocessInputRoot,manifestPath,"\u9884\u5904\u7406 manifest \u8DEF\u5F84");let copiedReports=collectReportFiles(reportsDir);for(let reportFile of copiedReports)validateImportEntry(join16(reportsDir,reportFile));let importManifest=readJson2(manifestPath),preflightReport=readJson2(join16(reportsDir,"preflight-report.json")),warningsReport=readJson2(join16(reportsDir,"warnings.json")),sourceRoot=resolve12(importManifest.source_dir),cleanSourceDir=resolve12(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=join16(workspaceDir,".design-import");assertReplaceableImportRoot(designImportRoot);let stagedCleanSourceDir=join16(designImportRoot,"upstream-clean-source"),stagedReportsDir=join16(designImportRoot,"reports"),summary=buildImportSummary(args,{workspaceDir,manifestPath,importManifest,preflightReport,warningsReport,layout,stagedCleanSourceDir,stagedReportsDir});if(!args.dryRun){let temporaryRoot=mkdtempSync4(join16(workspaceDir,".design-import.stage-"));try{let temporaryReportsDir=join16(temporaryRoot,"reports");ensureDir2(temporaryReportsDir),copyImportEntry(cleanSourceDir,join16(temporaryRoot,"upstream-clean-source")),stageReports(reportsDir,temporaryReportsDir,copiedReports),writeJson3(join16(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)}
2429
2520
  `);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(`
2430
2521
  `)+`
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)}
2522
+ `)}import{existsSync as existsSync22,readFileSync as readFileSync21,statSync as statSync5}from"node:fs";import{join as join17,resolve as resolve13}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(`
2523
+ `))}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 existsSync22(filePath)?JSON.parse(readFileSync21(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=>!existsSync22(join17(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=resolve13(args.workspaceDir);validateWorkspace3(workspaceDir);let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join17(workspaceDir,".design-import"),reportsDir=join17(designImportRoot,"reports"),importManifestPath=join17(reportsDir,"import-manifest.json"),preflightReportPath=join17(reportsDir,"preflight-report.json"),warningsReportPath=join17(reportsDir,"warnings.json"),importSummaryPath=join17(designImportRoot,"import-summary.json"),mergeSummaryPath=join17(designImportRoot,"merge-summary.json"),importedUpstreamDir=join17(workspaceDir,...layout.imported_upstream_root.split("/")),sourceContextPath=join17(workspaceDir,".platform","source-context.json"),importManifest=readJsonIfExists3(importManifestPath,{}),preflightReport=readJsonIfExists3(preflightReportPath,{}),warningsReport=readJsonIfExists3(warningsReportPath,{}),importSummary=readJsonIfExists3(importSummaryPath,{}),mergeSummary=readJsonIfExists3(mergeSummaryPath,{}),state={hasPreprocessManifest:existsSync22(importManifestPath),hasPreflightReport:existsSync22(preflightReportPath),hasWarningsReport:existsSync22(warningsReportPath),hasImportSummary:existsSync22(importSummaryPath),hasMergeSummary:existsSync22(mergeSummaryPath),hasImportedUpstreamDir:existsSync22(importedUpstreamDir),mergeRequired:!0,templateKey:layout.template_key,frontendRoot:layout.frontend_root,importedUpstreamRoot:layout.imported_upstream_root,hasSourceContext:existsSync22(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)}
2433
2524
  `);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(`
2434
2525
  `)+`
2435
2526
  `)}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(`
@@ -2453,14 +2544,14 @@ ${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:erro
2453
2544
  `)}
2454
2545
  `)}async function loadBuildCliMetadata(sdk,appId,sourceVersionId){let[sourceVersions,publishSettings]=await Promise.all([sdk.listTenantAppSourceVersions(appId).catch(()=>({items:[]})),sdk.getTenantAppPublishSettings(appId).catch(()=>null)]);return{sourceVersion:sourceVersions.items.find(item=>item.source_version_id===sourceVersionId)??null,publishSettings}}function readStringOption3(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasHelpFlag3(args){return args.options.help===!0||args.options.h===!0}function printBuildHelp(subcommand){if(subcommand==="run"){process.stdout.write(["platform build run","","\u8BF4\u660E\uFF1A\u8FD9\u662F\u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\u3002\u5E38\u89C4\u7248\u672C\u9884\u89C8\u4F18\u5148\u4F7F\u7528 `platform preview generate`\u3002","","\u7528\u6CD5\uFF1A"," platform build run --source-version <srcver> [--wait] [--tenant <tenant-id>] [--app <app-id>]","","\u53EF\u9009\u6784\u5EFA\u914D\u7F6E\uFF1A"," --dockerfile <path>"," --context-subdir <dir>"," --target <stage>","","\u8BF4\u660E\uFF1A"," \u53D1\u8D77\u771F\u5B9E\u4E91\u7AEF\u6784\u5EFA\uFF1B\u9ED8\u8BA4\u7ACB\u5373\u8FD4\u56DE build id\uFF0C\u52A0 `--wait` \u5219\u7B49\u5F85\u6784\u5EFA\u7ED3\u675F\u3002",""].join(`
2455
2546
  `));return}process.stdout.write(["platform build","","\u8BF4\u660E\uFF1A\u8FD9\u662F\u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\u3002\u666E\u901A\u5F00\u53D1\u4E0E\u9A8C\u8BC1\u4E3B\u8DEF\u5F84\u4F18\u5148\u4F7F\u7528 `platform preview` / `platform publish`\u3002","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform build validate --app <app-id> --source-version <srcver> --target static","","\u8BF4\u660E\uFF1A"," - `run` \u53D1\u8D77\u771F\u5B9E\u4E91\u7AEF\u6784\u5EFA"," - `get/events` \u67E5\u8BE2\u6784\u5EFA\u72B6\u6001\u4E0E\u4E8B\u4EF6"," - `validate` \u53EA\u505A\u6784\u5EFA\u524D\u9884\u68C0\u67E5",""].join(`
2456
- `))}function readBuildConfig(options){let dockerfilePath=typeof options.dockerfile=="string"?options.dockerfile:void 0,contextSubdir=typeof options["context-subdir"]=="string"?options["context-subdir"]:void 0,target=typeof options.target=="string"?options.target:void 0;return{...dockerfilePath?{dockerfile_path:dockerfilePath}:{},...contextSubdir?{context_subdir:contextSubdir}:{},...target?{target}:{}}}async function resolveBuildRunConfig(sdk,appId,sourceVersionId,buildConfig){if(buildConfig.target)return buildConfig;try{return(await sdk.getBuildPrecheck(appId,{source_version_id:sourceVersionId,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}})).normalized_build_config??buildConfig}catch(error){if(!isBuildPrecheckFallbackAllowed(error))throw error;return buildConfig}}function isBuildPrecheckFallbackAllowed(error){return!(error instanceof PlatformApiError)||error.code==="capability_unavailable"?!0:error.status>=500}async function resolveRequestedBy(sdk){return(await sdk.getWhoAmI()).subject_id}async function waitForBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus(build.status)||Date.now()-startedAt>=timeoutMs)return build;await sleep2(intervalMs)}}function isTerminalBuildStatus(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function sleep2(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}function formatBuildCommandError(error,subcommand,buildId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2547
+ `))}function readBuildConfig(options){let dockerfilePath=typeof options.dockerfile=="string"?options.dockerfile:void 0,contextSubdir=typeof options["context-subdir"]=="string"?options["context-subdir"]:void 0,target=typeof options.target=="string"?options.target:void 0;return{...dockerfilePath?{dockerfile_path:dockerfilePath}:{},...contextSubdir?{context_subdir:contextSubdir}:{},...target?{target}:{}}}async function resolveBuildRunConfig(sdk,appId,sourceVersionId,buildConfig){if(buildConfig.target)return buildConfig;try{return(await sdk.getBuildPrecheck(appId,{source_version_id:sourceVersionId,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}})).normalized_build_config??buildConfig}catch(error){if(!isBuildPrecheckFallbackAllowed(error))throw error;return buildConfig}}function isBuildPrecheckFallbackAllowed(error){return!(error instanceof PlatformApiError)||error.code==="capability_unavailable"?!0:error.status>=500}async function resolveRequestedBy(sdk){return(await sdk.getWhoAmI()).subject_id}async function waitForBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus(build.status)||Date.now()-startedAt>=timeoutMs)return build;await sleep2(intervalMs)}}function isTerminalBuildStatus(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function sleep2(ms){return new Promise(resolve20=>{setTimeout(resolve20,ms)})}function formatBuildCommandError(error,subcommand,buildId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2457
2548
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ${subcommand} \u5931\u8D25: ${buildId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
2458
2549
  `))}return error instanceof Error?error:new Error(`platform build ${subcommand} \u5931\u8D25: ${buildId}`)}function formatBuildValidateError(error,appId,sourceVersionId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2459
2550
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build validate \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
2460
2551
  `))}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?`
2461
2552
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
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)}
2553
+ `))}return error instanceof Error?error:new Error(`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`)}import{readFileSync as readFileSync22}from"node:fs";import{basename as basename7,extname as extname4,resolve as resolve14}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(`
2554
+ `))}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=resolve14(filePathArg),fileName=basename7(filePath),content=new Uint8Array(readFileSync22(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)}
2464
2555
  `);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(`
2465
2556
  `))}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)}
2466
2557
  `);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(`
@@ -2469,15 +2560,15 @@ detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ru
2469
2560
  `))}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)}
2470
2561
  `);return}process.stdout.write([response.url,`expires_at: ${response.expires_at}`,`ttl_seconds: ${ttlSeconds}`,`tenant: ${deps.tenantId}`,""].join(`
2471
2562
  `))}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(`
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"&&currentValue!==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(`
2563
+ `)):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"&&currentValue!==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 existsSync23,readFileSync as readFileSync23}from"node:fs";import{createConnection}from"node:net";import{dirname as dirname15,resolve as resolve15}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(`
2473
2564
  `)}
2474
2565
  `}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(`
2475
2566
  `)}
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(`---
2567
+ `}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||!existsSync23(path3))return{path:path3,exists:!1,pid:null,pid_alive:null};let raw=readFileSync23(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=resolve15(startDir);for(;;){let candidate=resolve15(current,"services","control-api",`.dev-server.${port}.lock`);if(existsSync23(resolve15(current,"services","control-api")))return candidate;let parent=dirname15(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 createHash8}from"node:crypto";import{readdirSync as readdirSync9,statSync as statSync6}from"node:fs";import{basename as basename8,extname as extname5,join as join18,relative as relative7,resolve as resolve16}from"node:path";import YAML3 from"yaml";function normalizeLineEndings(input){return input.replace(/\r\n/g,`
2568
+ `)}function computeChecksum2(input){return`sha256:${createHash8("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=relative7(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=createHash8("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=resolve16(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=readdirSync9(directoryPath,{withFileTypes:!0}).sort((left,right)=>left.name.localeCompare(right.name));for(let entry of entries){let entryPath=join18(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(`---
2478
2569
  `))return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let closingIndex=raw.indexOf(`
2479
2570
  ---
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,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}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(`,
2571
+ `,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 createHash9}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:${createHash9("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,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}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 existsSync25,readFileSync as readFileSync25}from"node:fs";import{join as join20}from"node:path";import{createHash as createHash11}from"node:crypto";import{existsSync as existsSync24,readdirSync as readdirSync10,readFileSync as readFileSync24}from"node:fs";import{basename as basename9,join as join19,relative as relative8}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(`,
2481
2572
  `),");"].join(`
2482
2573
  `)}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(`
2483
2574
  `)}
@@ -2496,7 +2587,7 @@ detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ru
2496
2587
  `:">",result};Renderer.prototype.renderInline=function(tokens,options,env){let result="",rules=this.rules;for(let i=0,len=tokens.length;i<len;i++){let type=tokens[i].type;typeof rules[type]<"u"?result+=rules[type](tokens,i,options,env,this):result+=this.renderToken(tokens,i,options)}return result};Renderer.prototype.renderInlineAsText=function(tokens,options,env){let result="";for(let i=0,len=tokens.length;i<len;i++)switch(tokens[i].type){case"text":result+=tokens[i].content;break;case"image":result+=this.renderInlineAsText(tokens[i].children,options,env);break;case"html_inline":case"html_block":result+=tokens[i].content;break;case"softbreak":case"hardbreak":result+=`
2497
2588
  `;break;default:}return result};Renderer.prototype.render=function(tokens,options,env){let result="",rules=this.rules;for(let i=0,len=tokens.length;i<len;i++){let type=tokens[i].type;type==="inline"?result+=this.renderInline(tokens[i].children,options,env):typeof rules[type]<"u"?result+=rules[type](tokens,i,options,env,this):result+=this.renderToken(tokens,i,options,env)}return result};var renderer_default=Renderer;function Ruler(){this.__rules__=[],this.__cache__=null}Ruler.prototype.__find__=function(name){for(let i=0;i<this.__rules__.length;i++)if(this.__rules__[i].name===name)return i;return-1};Ruler.prototype.__compile__=function(){let self=this,chains=[""];self.__rules__.forEach(function(rule){rule.enabled&&rule.alt.forEach(function(altName){chains.indexOf(altName)<0&&chains.push(altName)})}),self.__cache__={},chains.forEach(function(chain){self.__cache__[chain]=[],self.__rules__.forEach(function(rule){rule.enabled&&(chain&&rule.alt.indexOf(chain)<0||self.__cache__[chain].push(rule.fn))})})};Ruler.prototype.at=function(name,fn,options){let index=this.__find__(name),opt=options||{};if(index===-1)throw new Error("Parser rule not found: "+name);this.__rules__[index].fn=fn,this.__rules__[index].alt=opt.alt||[],this.__cache__=null};Ruler.prototype.before=function(beforeName,ruleName,fn,options){let index=this.__find__(beforeName),opt=options||{};if(index===-1)throw new Error("Parser rule not found: "+beforeName);this.__rules__.splice(index,0,{name:ruleName,enabled:!0,fn,alt:opt.alt||[]}),this.__cache__=null};Ruler.prototype.after=function(afterName,ruleName,fn,options){let index=this.__find__(afterName),opt=options||{};if(index===-1)throw new Error("Parser rule not found: "+afterName);this.__rules__.splice(index+1,0,{name:ruleName,enabled:!0,fn,alt:opt.alt||[]}),this.__cache__=null};Ruler.prototype.push=function(ruleName,fn,options){let opt=options||{};this.__rules__.push({name:ruleName,enabled:!0,fn,alt:opt.alt||[]}),this.__cache__=null};Ruler.prototype.enable=function(list2,ignoreInvalid){Array.isArray(list2)||(list2=[list2]);let result=[];return list2.forEach(function(name){let idx=this.__find__(name);if(idx<0){if(ignoreInvalid)return;throw new Error("Rules manager: invalid rule name "+name)}this.__rules__[idx].enabled=!0,result.push(name)},this),this.__cache__=null,result};Ruler.prototype.enableOnly=function(list2,ignoreInvalid){Array.isArray(list2)||(list2=[list2]),this.__rules__.forEach(function(rule){rule.enabled=!1}),this.enable(list2,ignoreInvalid)};Ruler.prototype.disable=function(list2,ignoreInvalid){Array.isArray(list2)||(list2=[list2]);let result=[];return list2.forEach(function(name){let idx=this.__find__(name);if(idx<0){if(ignoreInvalid)return;throw new Error("Rules manager: invalid rule name "+name)}this.__rules__[idx].enabled=!1,result.push(name)},this),this.__cache__=null,result};Ruler.prototype.getRules=function(chainName){return this.__cache__===null&&this.__compile__(),this.__cache__[chainName]||[]};var ruler_default=Ruler;function Token(type,tag,nesting){this.type=type,this.tag=tag,this.attrs=null,this.map=null,this.nesting=nesting,this.level=0,this.children=null,this.content="",this.markup="",this.info="",this.meta=null,this.block=!1,this.hidden=!1}Token.prototype.attrIndex=function(name){if(!this.attrs)return-1;let attrs=this.attrs;for(let i=0,len=attrs.length;i<len;i++)if(attrs[i][0]===name)return i;return-1};Token.prototype.attrPush=function(attrData){this.attrs?this.attrs.push(attrData):this.attrs=[attrData]};Token.prototype.attrSet=function(name,value){let idx=this.attrIndex(name),attrData=[name,value];idx<0?this.attrPush(attrData):this.attrs[idx]=attrData};Token.prototype.attrGet=function(name){let idx=this.attrIndex(name),value=null;return idx>=0&&(value=this.attrs[idx][1]),value};Token.prototype.attrJoin=function(name,value){let idx=this.attrIndex(name);idx<0?this.attrPush([name,value]):this.attrs[idx][1]=this.attrs[idx][1]+" "+value};var token_default=Token;function StateCore(src,md,env){this.src=src,this.env=env,this.tokens=[],this.inlineMode=!1,this.md=md}StateCore.prototype.Token=token_default;var state_core_default=StateCore;var NEWLINES_RE=/\r\n?|\n/g,NULL_RE=/\0/g;function normalize(state){let str;str=state.src.replace(NEWLINES_RE,`
2498
2589
  `),str=str.replace(NULL_RE,"\uFFFD"),state.src=str}function block(state){let token;state.inlineMode?(token=new state.Token("inline","",0),token.content=state.src,token.map=[0,1],token.children=[],state.tokens.push(token)):state.md.block.parse(state.src,state.md,state.env,state.tokens)}function inline(state){let tokens=state.tokens;for(let i=0,l=tokens.length;i<l;i++){let tok=tokens[i];tok.type==="inline"&&state.md.inline.parse(tok.content,state.md,state.env,tok.children)}}function isLinkOpen(str){return/^<a[>\s]/i.test(str)}function isLinkClose(str){return/^<\/a\s*>/i.test(str)}function linkify(state){let blockTokens=state.tokens;if(state.md.options.linkify)for(let j=0,l=blockTokens.length;j<l;j++){if(blockTokens[j].type!=="inline"||!state.md.linkify.pretest(blockTokens[j].content))continue;let tokens=blockTokens[j].children,htmlLinkLevel=0;for(let i=tokens.length-1;i>=0;i--){let currentToken=tokens[i];if(currentToken.type==="link_close"){for(i--;tokens[i].level!==currentToken.level&&tokens[i].type!=="link_open";)i--;continue}if(currentToken.type==="html_inline"&&(isLinkOpen(currentToken.content)&&htmlLinkLevel>0&&htmlLinkLevel--,isLinkClose(currentToken.content)&&htmlLinkLevel++),!(htmlLinkLevel>0)&&currentToken.type==="text"&&state.md.linkify.test(currentToken.content)){let text2=currentToken.content,links=state.md.linkify.match(text2),nodes=[],level=currentToken.level,lastPos=0;links.length>0&&links[0].index===0&&i>0&&tokens[i-1].type==="text_special"&&(links=links.slice(1));for(let ln=0;ln<links.length;ln++){let url=links[ln].url,fullUrl=state.md.normalizeLink(url);if(!state.md.validateLink(fullUrl))continue;let urlText=links[ln].text;links[ln].schema?links[ln].schema==="mailto:"&&!/^mailto:/i.test(urlText)?urlText=state.md.normalizeLinkText("mailto:"+urlText).replace(/^mailto:/,""):urlText=state.md.normalizeLinkText(urlText):urlText=state.md.normalizeLinkText("http://"+urlText).replace(/^http:\/\//,"");let pos=links[ln].index;if(pos>lastPos){let token=new state.Token("text","",0);token.content=text2.slice(lastPos,pos),token.level=level,nodes.push(token)}let token_o=new state.Token("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.level=level++,token_o.markup="linkify",token_o.info="auto",nodes.push(token_o);let token_t=new state.Token("text","",0);token_t.content=urlText,token_t.level=level,nodes.push(token_t);let token_c=new state.Token("link_close","a",-1);token_c.level=--level,token_c.markup="linkify",token_c.info="auto",nodes.push(token_c),lastPos=links[ln].lastIndex}if(lastPos<text2.length){let token=new state.Token("text","",0);token.content=text2.slice(lastPos),token.level=level,nodes.push(token)}blockTokens[j].children=tokens=arrayReplaceAt(tokens,i,nodes)}}}}var RARE_RE=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,SCOPED_ABBR_TEST_RE=/\((c|tm|r)\)/i,SCOPED_ABBR_RE=/\((c|tm|r)\)/ig,SCOPED_ABBR={c:"\xA9",r:"\xAE",tm:"\u2122"};function replaceFn(match2,name){return SCOPED_ABBR[name.toLowerCase()]}function replace_scoped(inlineTokens){let inside_autolink=0;for(let i=inlineTokens.length-1;i>=0;i--){let token=inlineTokens[i];token.type==="text"&&!inside_autolink&&(token.content=token.content.replace(SCOPED_ABBR_RE,replaceFn)),token.type==="link_open"&&token.info==="auto"&&inside_autolink--,token.type==="link_close"&&token.info==="auto"&&inside_autolink++}}function replace_rare(inlineTokens){let inside_autolink=0;for(let i=inlineTokens.length-1;i>=0;i--){let token=inlineTokens[i];token.type==="text"&&!inside_autolink&&RARE_RE.test(token.content)&&(token.content=token.content.replace(/\+-/g,"\xB1").replace(/\.{2,}/g,"\u2026").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---(?=[^-]|$)/mg,"$1\u2014").replace(/(^|\s)--(?=\s|$)/mg,"$1\u2013").replace(/(^|[^-\s])--(?=[^-\s]|$)/mg,"$1\u2013")),token.type==="link_open"&&token.info==="auto"&&inside_autolink--,token.type==="link_close"&&token.info==="auto"&&inside_autolink++}}function replace(state){let blkIdx;if(state.md.options.typographer)for(blkIdx=state.tokens.length-1;blkIdx>=0;blkIdx--)state.tokens[blkIdx].type==="inline"&&(SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)&&replace_scoped(state.tokens[blkIdx].children),RARE_RE.test(state.tokens[blkIdx].content)&&replace_rare(state.tokens[blkIdx].children))}var QUOTE_TEST_RE=/['"]/,QUOTE_RE=/['"]/g,APOSTROPHE="\u2019";function replaceAt(str,index,ch){return str.slice(0,index)+ch+str.slice(index+1)}function process_inlines(tokens,state){let j,stack=[];for(let i=0;i<tokens.length;i++){let token=tokens[i],thisLevel=tokens[i].level;for(j=stack.length-1;j>=0&&!(stack[j].level<=thisLevel);j--);if(stack.length=j+1,token.type!=="text")continue;let text2=token.content,pos=0,max=text2.length;OUTER:for(;pos<max;){QUOTE_RE.lastIndex=pos;let t=QUOTE_RE.exec(text2);if(!t)break;let canOpen=!0,canClose=!0;pos=t.index+1;let isSingle=t[0]==="'",lastChar=32;if(t.index-1>=0)lastChar=text2.charCodeAt(t.index-1);else for(j=i-1;j>=0&&!(tokens[j].type==="softbreak"||tokens[j].type==="hardbreak");j--)if(tokens[j].content){lastChar=tokens[j].content.charCodeAt(tokens[j].content.length-1);break}let nextChar=32;if(pos<max)nextChar=text2.charCodeAt(pos);else for(j=i+1;j<tokens.length&&!(tokens[j].type==="softbreak"||tokens[j].type==="hardbreak");j++)if(tokens[j].content){nextChar=tokens[j].content.charCodeAt(0);break}let isLastPunctChar=isMdAsciiPunct(lastChar)||isPunctChar(String.fromCharCode(lastChar)),isNextPunctChar=isMdAsciiPunct(nextChar)||isPunctChar(String.fromCharCode(nextChar)),isLastWhiteSpace=isWhiteSpace(lastChar),isNextWhiteSpace=isWhiteSpace(nextChar);if(isNextWhiteSpace?canOpen=!1:isNextPunctChar&&(isLastWhiteSpace||isLastPunctChar||(canOpen=!1)),isLastWhiteSpace?canClose=!1:isLastPunctChar&&(isNextWhiteSpace||isNextPunctChar||(canClose=!1)),nextChar===34&&t[0]==='"'&&lastChar>=48&&lastChar<=57&&(canClose=canOpen=!1),canOpen&&canClose&&(canOpen=isLastPunctChar,canClose=isNextPunctChar),!canOpen&&!canClose){isSingle&&(token.content=replaceAt(token.content,t.index,APOSTROPHE));continue}if(canClose)for(j=stack.length-1;j>=0;j--){let item=stack[j];if(stack[j].level<thisLevel)break;if(item.single===isSingle&&stack[j].level===thisLevel){item=stack[j];let openQuote,closeQuote;isSingle?(openQuote=state.md.options.quotes[2],closeQuote=state.md.options.quotes[3]):(openQuote=state.md.options.quotes[0],closeQuote=state.md.options.quotes[1]),token.content=replaceAt(token.content,t.index,closeQuote),tokens[item.token].content=replaceAt(tokens[item.token].content,item.pos,openQuote),pos+=closeQuote.length-1,item.token===i&&(pos+=openQuote.length-1),text2=token.content,max=text2.length,stack.length=j;continue OUTER}}canOpen?stack.push({token:i,pos:t.index,single:isSingle,level:thisLevel}):canClose&&isSingle&&(token.content=replaceAt(token.content,t.index,APOSTROPHE))}}}function smartquotes(state){if(state.md.options.typographer)for(let blkIdx=state.tokens.length-1;blkIdx>=0;blkIdx--)state.tokens[blkIdx].type!=="inline"||!QUOTE_TEST_RE.test(state.tokens[blkIdx].content)||process_inlines(state.tokens[blkIdx].children,state)}function text_join(state){let curr,last,blockTokens=state.tokens,l=blockTokens.length;for(let j=0;j<l;j++){if(blockTokens[j].type!=="inline")continue;let tokens=blockTokens[j].children,max=tokens.length;for(curr=0;curr<max;curr++)tokens[curr].type==="text_special"&&(tokens[curr].type="text");for(curr=last=0;curr<max;curr++)tokens[curr].type==="text"&&curr+1<max&&tokens[curr+1].type==="text"?tokens[curr+1].content=tokens[curr].content+tokens[curr+1].content:(curr!==last&&(tokens[last]=tokens[curr]),last++);curr!==last&&(tokens.length=last)}}var _rules=[["normalize",normalize],["block",block],["inline",inline],["linkify",linkify],["replacements",replace],["smartquotes",smartquotes],["text_join",text_join]];function Core(){this.ruler=new ruler_default;for(let i=0;i<_rules.length;i++)this.ruler.push(_rules[i][0],_rules[i][1])}Core.prototype.process=function(state){let rules=this.ruler.getRules("");for(let i=0,l=rules.length;i<l;i++)rules[i](state)};Core.prototype.State=state_core_default;var parser_core_default=Core;function StateBlock(src,md,env,tokens){this.src=src,this.md=md,this.env=env,this.tokens=tokens,this.bMarks=[],this.eMarks=[],this.tShift=[],this.sCount=[],this.bsCount=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.ddIndent=-1,this.listIndent=-1,this.parentType="root",this.level=0;let s=this.src;for(let start=0,pos=0,indent=0,offset=0,len=s.length,indent_found=!1;pos<len;pos++){let ch=s.charCodeAt(pos);if(!indent_found)if(isSpace(ch)){indent++,ch===9?offset+=4-offset%4:offset++;continue}else indent_found=!0;(ch===10||pos===len-1)&&(ch!==10&&pos++,this.bMarks.push(start),this.eMarks.push(pos),this.tShift.push(indent),this.sCount.push(offset),this.bsCount.push(0),indent_found=!1,indent=0,offset=0,start=pos+1)}this.bMarks.push(s.length),this.eMarks.push(s.length),this.tShift.push(0),this.sCount.push(0),this.bsCount.push(0),this.lineMax=this.bMarks.length-1}StateBlock.prototype.push=function(type,tag,nesting){let token=new token_default(type,tag,nesting);return token.block=!0,nesting<0&&this.level--,token.level=this.level,nesting>0&&this.level++,this.tokens.push(token),token};StateBlock.prototype.isEmpty=function(line){return this.bMarks[line]+this.tShift[line]>=this.eMarks[line]};StateBlock.prototype.skipEmptyLines=function(from){for(let max=this.lineMax;from<max&&!(this.bMarks[from]+this.tShift[from]<this.eMarks[from]);from++);return from};StateBlock.prototype.skipSpaces=function(pos){for(let max=this.src.length;pos<max;pos++){let ch=this.src.charCodeAt(pos);if(!isSpace(ch))break}return pos};StateBlock.prototype.skipSpacesBack=function(pos,min){if(pos<=min)return pos;for(;pos>min;)if(!isSpace(this.src.charCodeAt(--pos)))return pos+1;return pos};StateBlock.prototype.skipChars=function(pos,code2){for(let max=this.src.length;pos<max&&this.src.charCodeAt(pos)===code2;pos++);return pos};StateBlock.prototype.skipCharsBack=function(pos,code2,min){if(pos<=min)return pos;for(;pos>min;)if(code2!==this.src.charCodeAt(--pos))return pos+1;return pos};StateBlock.prototype.getLines=function(begin,end,indent,keepLastLF){if(begin>=end)return"";let queue=new Array(end-begin);for(let i=0,line=begin;line<end;line++,i++){let lineIndent=0,lineStart=this.bMarks[line],first=lineStart,last;for(line+1<end||keepLastLF?last=this.eMarks[line]+1:last=this.eMarks[line];first<last&&lineIndent<indent;){let ch=this.src.charCodeAt(first);if(isSpace(ch))ch===9?lineIndent+=4-(lineIndent+this.bsCount[line])%4:lineIndent++;else if(first-lineStart<this.tShift[line])lineIndent++;else break;first++}lineIndent>indent?queue[i]=new Array(lineIndent-indent+1).join(" ")+this.src.slice(first,last):queue[i]=this.src.slice(first,last)}return queue.join("")};StateBlock.prototype.Token=token_default;var state_block_default=StateBlock;var MAX_AUTOCOMPLETED_CELLS=65536;function getLine(state,line){let pos=state.bMarks[line]+state.tShift[line],max=state.eMarks[line];return state.src.slice(pos,max)}function escapedSplit(str){let result=[],max=str.length,pos=0,ch=str.charCodeAt(pos),isEscaped=!1,lastPos=0,current="";for(;pos<max;)ch===124&&(isEscaped?(current+=str.substring(lastPos,pos-1),lastPos=pos):(result.push(current+str.substring(lastPos,pos)),current="",lastPos=pos+1)),isEscaped=ch===92,pos++,ch=str.charCodeAt(pos);return result.push(current+str.substring(lastPos)),result}function table(state,startLine,endLine,silent){if(startLine+2>endLine)return!1;let nextLine=startLine+1;if(state.sCount[nextLine]<state.blkIndent||state.sCount[nextLine]-state.blkIndent>=4)return!1;let pos=state.bMarks[nextLine]+state.tShift[nextLine];if(pos>=state.eMarks[nextLine])return!1;let firstCh=state.src.charCodeAt(pos++);if(firstCh!==124&&firstCh!==45&&firstCh!==58||pos>=state.eMarks[nextLine])return!1;let secondCh=state.src.charCodeAt(pos++);if(secondCh!==124&&secondCh!==45&&secondCh!==58&&!isSpace(secondCh)||firstCh===45&&isSpace(secondCh))return!1;for(;pos<state.eMarks[nextLine];){let ch=state.src.charCodeAt(pos);if(ch!==124&&ch!==45&&ch!==58&&!isSpace(ch))return!1;pos++}let lineText=getLine(state,startLine+1),columns=lineText.split("|"),aligns=[];for(let i=0;i<columns.length;i++){let t=columns[i].trim();if(!t){if(i===0||i===columns.length-1)continue;return!1}if(!/^:?-+:?$/.test(t))return!1;t.charCodeAt(t.length-1)===58?aligns.push(t.charCodeAt(0)===58?"center":"right"):t.charCodeAt(0)===58?aligns.push("left"):aligns.push("")}if(lineText=getLine(state,startLine).trim(),lineText.indexOf("|")===-1||state.sCount[startLine]-state.blkIndent>=4)return!1;columns=escapedSplit(lineText),columns.length&&columns[0]===""&&columns.shift(),columns.length&&columns[columns.length-1]===""&&columns.pop();let columnCount=columns.length;if(columnCount===0||columnCount!==aligns.length)return!1;if(silent)return!0;let oldParentType=state.parentType;state.parentType="table";let terminatorRules=state.md.block.ruler.getRules("blockquote"),token_to=state.push("table_open","table",1),tableLines=[startLine,0];token_to.map=tableLines;let token_tho=state.push("thead_open","thead",1);token_tho.map=[startLine,startLine+1];let token_htro=state.push("tr_open","tr",1);token_htro.map=[startLine,startLine+1];for(let i=0;i<columns.length;i++){let token_ho=state.push("th_open","th",1);aligns[i]&&(token_ho.attrs=[["style","text-align:"+aligns[i]]]);let token_il=state.push("inline","",0);token_il.content=columns[i].trim(),token_il.children=[],state.push("th_close","th",-1)}state.push("tr_close","tr",-1),state.push("thead_close","thead",-1);let tbodyLines,autocompletedCells=0;for(nextLine=startLine+2;nextLine<endLine&&!(state.sCount[nextLine]<state.blkIndent);nextLine++){let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate||(lineText=getLine(state,nextLine).trim(),!lineText)||state.sCount[nextLine]-state.blkIndent>=4||(columns=escapedSplit(lineText),columns.length&&columns[0]===""&&columns.shift(),columns.length&&columns[columns.length-1]===""&&columns.pop(),autocompletedCells+=columnCount-columns.length,autocompletedCells>MAX_AUTOCOMPLETED_CELLS))break;if(nextLine===startLine+2){let token_tbo=state.push("tbody_open","tbody",1);token_tbo.map=tbodyLines=[startLine+2,0]}let token_tro=state.push("tr_open","tr",1);token_tro.map=[nextLine,nextLine+1];for(let i=0;i<columnCount;i++){let token_tdo=state.push("td_open","td",1);aligns[i]&&(token_tdo.attrs=[["style","text-align:"+aligns[i]]]);let token_il=state.push("inline","",0);token_il.content=columns[i]?columns[i].trim():"",token_il.children=[],state.push("td_close","td",-1)}state.push("tr_close","tr",-1)}return tbodyLines&&(state.push("tbody_close","tbody",-1),tbodyLines[1]=nextLine),state.push("table_close","table",-1),tableLines[1]=nextLine,state.parentType=oldParentType,state.line=nextLine,!0}function code(state,startLine,endLine){if(state.sCount[startLine]-state.blkIndent<4)return!1;let nextLine=startLine+1,last=nextLine;for(;nextLine<endLine;){if(state.isEmpty(nextLine)){nextLine++;continue}if(state.sCount[nextLine]-state.blkIndent>=4){nextLine++,last=nextLine;continue}break}state.line=last;let token=state.push("code_block","code",0);return token.content=state.getLines(startLine,last,4+state.blkIndent,!1)+`
2499
- `,token.map=[startLine,state.line],!0}function fence(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4||pos+3>max)return!1;let marker=state.src.charCodeAt(pos);if(marker!==126&&marker!==96)return!1;let mem=pos;pos=state.skipChars(pos,marker);let len=pos-mem;if(len<3)return!1;let markup=state.src.slice(mem,pos),params=state.src.slice(pos,max);if(marker===96&&params.indexOf(String.fromCharCode(marker))>=0)return!1;if(silent)return!0;let nextLine=startLine,haveEndMarker=!1;for(;nextLine++,!(nextLine>=endLine||(pos=mem=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],pos<max&&state.sCount[nextLine]<state.blkIndent));)if(state.src.charCodeAt(pos)===marker&&!(state.sCount[nextLine]-state.blkIndent>=4)&&(pos=state.skipChars(pos,marker),!(pos-mem<len)&&(pos=state.skipSpaces(pos),!(pos<max)))){haveEndMarker=!0;break}len=state.sCount[startLine],state.line=nextLine+(haveEndMarker?1:0);let token=state.push("fence","code",0);return token.info=params,token.content=state.getLines(startLine+1,nextLine,len,!0),token.markup=markup,token.map=[startLine,state.line],!0}function blockquote(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],oldLineMax=state.lineMax;if(state.sCount[startLine]-state.blkIndent>=4||state.src.charCodeAt(pos)!==62)return!1;if(silent)return!0;let oldBMarks=[],oldBSCount=[],oldSCount=[],oldTShift=[],terminatorRules=state.md.block.ruler.getRules("blockquote"),oldParentType=state.parentType;state.parentType="blockquote";let lastLineEmpty=!1,nextLine;for(nextLine=startLine;nextLine<endLine;nextLine++){let isOutdented=state.sCount[nextLine]<state.blkIndent;if(pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],pos>=max)break;if(state.src.charCodeAt(pos++)===62&&!isOutdented){let initial=state.sCount[nextLine]+1,spaceAfterMarker,adjustTab;state.src.charCodeAt(pos)===32?(pos++,initial++,adjustTab=!1,spaceAfterMarker=!0):state.src.charCodeAt(pos)===9?(spaceAfterMarker=!0,(state.bsCount[nextLine]+initial)%4===3?(pos++,initial++,adjustTab=!1):adjustTab=!0):spaceAfterMarker=!1;let offset=initial;for(oldBMarks.push(state.bMarks[nextLine]),state.bMarks[nextLine]=pos;pos<max;){let ch=state.src.charCodeAt(pos);if(isSpace(ch))ch===9?offset+=4-(offset+state.bsCount[nextLine]+(adjustTab?1:0))%4:offset++;else break;pos++}lastLineEmpty=pos>=max,oldBSCount.push(state.bsCount[nextLine]),state.bsCount[nextLine]=state.sCount[nextLine]+1+(spaceAfterMarker?1:0),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]=offset-initial,oldTShift.push(state.tShift[nextLine]),state.tShift[nextLine]=pos-state.bMarks[nextLine];continue}if(lastLineEmpty)break;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate){state.lineMax=nextLine,state.blkIndent!==0&&(oldBMarks.push(state.bMarks[nextLine]),oldBSCount.push(state.bsCount[nextLine]),oldTShift.push(state.tShift[nextLine]),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]-=state.blkIndent);break}oldBMarks.push(state.bMarks[nextLine]),oldBSCount.push(state.bsCount[nextLine]),oldTShift.push(state.tShift[nextLine]),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]=-1}let oldIndent=state.blkIndent;state.blkIndent=0;let token_o=state.push("blockquote_open","blockquote",1);token_o.markup=">";let lines=[startLine,0];token_o.map=lines,state.md.block.tokenize(state,startLine,nextLine);let token_c=state.push("blockquote_close","blockquote",-1);token_c.markup=">",state.lineMax=oldLineMax,state.parentType=oldParentType,lines[1]=state.line;for(let i=0;i<oldTShift.length;i++)state.bMarks[i+startLine]=oldBMarks[i],state.tShift[i+startLine]=oldTShift[i],state.sCount[i+startLine]=oldSCount[i],state.bsCount[i+startLine]=oldBSCount[i];return state.blkIndent=oldIndent,!0}function hr(state,startLine,endLine,silent){let max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4)return!1;let pos=state.bMarks[startLine]+state.tShift[startLine],marker=state.src.charCodeAt(pos++);if(marker!==42&&marker!==45&&marker!==95)return!1;let cnt=1;for(;pos<max;){let ch=state.src.charCodeAt(pos++);if(ch!==marker&&!isSpace(ch))return!1;ch===marker&&cnt++}if(cnt<3)return!1;if(silent)return!0;state.line=startLine+1;let token=state.push("hr","hr",0);return token.map=[startLine,state.line],token.markup=Array(cnt+1).join(String.fromCharCode(marker)),!0}function skipBulletListMarker(state,startLine){let max=state.eMarks[startLine],pos=state.bMarks[startLine]+state.tShift[startLine],marker=state.src.charCodeAt(pos++);if(marker!==42&&marker!==45&&marker!==43)return-1;if(pos<max){let ch=state.src.charCodeAt(pos);if(!isSpace(ch))return-1}return pos}function skipOrderedListMarker(state,startLine){let start=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],pos=start;if(pos+1>=max)return-1;let ch=state.src.charCodeAt(pos++);if(ch<48||ch>57)return-1;for(;;){if(pos>=max)return-1;if(ch=state.src.charCodeAt(pos++),ch>=48&&ch<=57){if(pos-start>=10)return-1;continue}if(ch===41||ch===46)break;return-1}return pos<max&&(ch=state.src.charCodeAt(pos),!isSpace(ch))?-1:pos}function markTightParagraphs(state,idx){let level=state.level+2;for(let i=idx+2,l=state.tokens.length-2;i<l;i++)state.tokens[i].level===level&&state.tokens[i].type==="paragraph_open"&&(state.tokens[i+2].hidden=!0,state.tokens[i].hidden=!0,i+=2)}function list(state,startLine,endLine,silent){let max,pos,start,token,nextLine=startLine,tight=!0;if(state.sCount[nextLine]-state.blkIndent>=4||state.listIndent>=0&&state.sCount[nextLine]-state.listIndent>=4&&state.sCount[nextLine]<state.blkIndent)return!1;let isTerminatingParagraph=!1;silent&&state.parentType==="paragraph"&&state.sCount[nextLine]>=state.blkIndent&&(isTerminatingParagraph=!0);let isOrdered,markerValue,posAfterMarker;if((posAfterMarker=skipOrderedListMarker(state,nextLine))>=0){if(isOrdered=!0,start=state.bMarks[nextLine]+state.tShift[nextLine],markerValue=Number(state.src.slice(start,posAfterMarker-1)),isTerminatingParagraph&&markerValue!==1)return!1}else if((posAfterMarker=skipBulletListMarker(state,nextLine))>=0)isOrdered=!1;else return!1;if(isTerminatingParagraph&&state.skipSpaces(posAfterMarker)>=state.eMarks[nextLine])return!1;if(silent)return!0;let markerCharCode=state.src.charCodeAt(posAfterMarker-1),listTokIdx=state.tokens.length;isOrdered?(token=state.push("ordered_list_open","ol",1),markerValue!==1&&(token.attrs=[["start",markerValue]])):token=state.push("bullet_list_open","ul",1);let listLines=[nextLine,0];token.map=listLines,token.markup=String.fromCharCode(markerCharCode);let prevEmptyEnd=!1,terminatorRules=state.md.block.ruler.getRules("list"),oldParentType=state.parentType;for(state.parentType="list";nextLine<endLine;){pos=posAfterMarker,max=state.eMarks[nextLine];let initial=state.sCount[nextLine]+posAfterMarker-(state.bMarks[nextLine]+state.tShift[nextLine]),offset=initial;for(;pos<max;){let ch=state.src.charCodeAt(pos);if(ch===9)offset+=4-(offset+state.bsCount[nextLine])%4;else if(ch===32)offset++;else break;pos++}let contentStart=pos,indentAfterMarker;contentStart>=max?indentAfterMarker=1:indentAfterMarker=offset-initial,indentAfterMarker>4&&(indentAfterMarker=1);let indent=initial+indentAfterMarker;token=state.push("list_item_open","li",1),token.markup=String.fromCharCode(markerCharCode);let itemLines=[nextLine,0];token.map=itemLines,isOrdered&&(token.info=state.src.slice(start,posAfterMarker-1));let oldTight=state.tight,oldTShift=state.tShift[nextLine],oldSCount=state.sCount[nextLine],oldListIndent=state.listIndent;if(state.listIndent=state.blkIndent,state.blkIndent=indent,state.tight=!0,state.tShift[nextLine]=contentStart-state.bMarks[nextLine],state.sCount[nextLine]=offset,contentStart>=max&&state.isEmpty(nextLine+1)?state.line=Math.min(state.line+2,endLine):state.md.block.tokenize(state,nextLine,endLine,!0),(!state.tight||prevEmptyEnd)&&(tight=!1),prevEmptyEnd=state.line-nextLine>1&&state.isEmpty(state.line-1),state.blkIndent=state.listIndent,state.listIndent=oldListIndent,state.tShift[nextLine]=oldTShift,state.sCount[nextLine]=oldSCount,state.tight=oldTight,token=state.push("list_item_close","li",-1),token.markup=String.fromCharCode(markerCharCode),nextLine=state.line,itemLines[1]=nextLine,nextLine>=endLine||state.sCount[nextLine]<state.blkIndent||state.sCount[nextLine]-state.blkIndent>=4)break;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break;if(isOrdered){if(posAfterMarker=skipOrderedListMarker(state,nextLine),posAfterMarker<0)break;start=state.bMarks[nextLine]+state.tShift[nextLine]}else if(posAfterMarker=skipBulletListMarker(state,nextLine),posAfterMarker<0)break;if(markerCharCode!==state.src.charCodeAt(posAfterMarker-1))break}return isOrdered?token=state.push("ordered_list_close","ol",-1):token=state.push("bullet_list_close","ul",-1),token.markup=String.fromCharCode(markerCharCode),listLines[1]=nextLine,state.line=nextLine,state.parentType=oldParentType,tight&&markTightParagraphs(state,listTokIdx),!0}function reference(state,startLine,_endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],nextLine=startLine+1;if(state.sCount[startLine]-state.blkIndent>=4||state.src.charCodeAt(pos)!==91)return!1;function getNextLine(nextLine2){let endLine=state.lineMax;if(nextLine2>=endLine||state.isEmpty(nextLine2))return null;let isContinuation=!1;if(state.sCount[nextLine2]-state.blkIndent>3&&(isContinuation=!0),state.sCount[nextLine2]<0&&(isContinuation=!0),!isContinuation){let terminatorRules=state.md.block.ruler.getRules("reference"),oldParentType=state.parentType;state.parentType="reference";let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine2,endLine,!0)){terminate=!0;break}if(state.parentType=oldParentType,terminate)return null}let pos2=state.bMarks[nextLine2]+state.tShift[nextLine2],max2=state.eMarks[nextLine2];return state.src.slice(pos2,max2+1)}let str=state.src.slice(pos,max+1);max=str.length;let labelEnd=-1;for(pos=1;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===91)return!1;if(ch===93){labelEnd=pos;break}else if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(ch===92&&(pos++,pos<max&&str.charCodeAt(pos)===10)){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}}if(labelEnd<0||str.charCodeAt(labelEnd+1)!==58)return!1;for(pos=labelEnd+2;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(!isSpace(ch))break}let destRes=state.md.helpers.parseLinkDestination(str,pos,max);if(!destRes.ok)return!1;let href=state.md.normalizeLink(destRes.str);if(!state.md.validateLink(href))return!1;pos=destRes.pos;let destEndPos=pos,destEndLineNo=nextLine,start=pos;for(;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(!isSpace(ch))break}let titleRes=state.md.helpers.parseLinkTitle(str,pos,max);for(;titleRes.can_continue;){let lineContent=getNextLine(nextLine);if(lineContent===null)break;str+=lineContent,pos=max,max=str.length,nextLine++,titleRes=state.md.helpers.parseLinkTitle(str,pos,max,titleRes)}let title;for(pos<max&&start!==pos&&titleRes.ok?(title=titleRes.str,pos=titleRes.pos):(title="",pos=destEndPos,nextLine=destEndLineNo);pos<max;){let ch=str.charCodeAt(pos);if(!isSpace(ch))break;pos++}if(pos<max&&str.charCodeAt(pos)!==10&&title)for(title="",pos=destEndPos,nextLine=destEndLineNo;pos<max;){let ch=str.charCodeAt(pos);if(!isSpace(ch))break;pos++}if(pos<max&&str.charCodeAt(pos)!==10)return!1;let label=normalizeReference(str.slice(1,labelEnd));return label?(silent||(typeof state.env.references>"u"&&(state.env.references={}),typeof state.env.references[label]>"u"&&(state.env.references[label]={title,href}),state.line=nextLine),!0):!1}var html_blocks_default=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"];var attr_name="[a-zA-Z_:][a-zA-Z0-9:._-]*",unquoted="[^\"'=<>`\\x00-\\x20]+",single_quoted="'[^']*'",double_quoted='"[^"]*"',attr_value="(?:"+unquoted+"|"+single_quoted+"|"+double_quoted+")",attribute="(?:\\s+"+attr_name+"(?:\\s*=\\s*"+attr_value+")?)",open_tag="<[A-Za-z][A-Za-z0-9\\-]*"+attribute+"*\\s*\\/?>",close_tag="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",comment="<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->",processing="<[?][\\s\\S]*?[?]>",declaration="<![A-Za-z][^>]*>",cdata="<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",HTML_TAG_RE=new RegExp("^(?:"+open_tag+"|"+close_tag+"|"+comment+"|"+processing+"|"+declaration+"|"+cdata+")"),HTML_OPEN_CLOSE_TAG_RE=new RegExp("^(?:"+open_tag+"|"+close_tag+")");var HTML_SEQUENCES=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^<!--/,/-->/,!0],[/^<\?/,/\?>/,!0],[/^<![A-Z]/,/>/,!0],[/^<!\[CDATA\[/,/\]\]>/,!0],[new RegExp("^</?("+html_blocks_default.join("|")+")(?=(\\s|/?>|$))","i"),/^$/,!0],[new RegExp(HTML_OPEN_CLOSE_TAG_RE.source+"\\s*$"),/^$/,!1]];function html_block(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4||!state.md.options.html||state.src.charCodeAt(pos)!==60)return!1;let lineText=state.src.slice(pos,max),i=0;for(;i<HTML_SEQUENCES.length&&!HTML_SEQUENCES[i][0].test(lineText);i++);if(i===HTML_SEQUENCES.length)return!1;if(silent)return HTML_SEQUENCES[i][2];let nextLine=startLine+1;if(!HTML_SEQUENCES[i][1].test(lineText)){for(;nextLine<endLine&&!(state.sCount[nextLine]<state.blkIndent);nextLine++)if(pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],lineText=state.src.slice(pos,max),HTML_SEQUENCES[i][1].test(lineText)){lineText.length!==0&&nextLine++;break}}state.line=nextLine;let token=state.push("html_block","",0);return token.map=[startLine,nextLine],token.content=state.getLines(startLine,nextLine,state.blkIndent,!0),!0}function heading(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4)return!1;let ch=state.src.charCodeAt(pos);if(ch!==35||pos>=max)return!1;let level=1;for(ch=state.src.charCodeAt(++pos);ch===35&&pos<max&&level<=6;)level++,ch=state.src.charCodeAt(++pos);if(level>6||pos<max&&!isSpace(ch))return!1;if(silent)return!0;max=state.skipSpacesBack(max,pos);let tmp=state.skipCharsBack(max,35,pos);tmp>pos&&isSpace(state.src.charCodeAt(tmp-1))&&(max=tmp),state.line=startLine+1;let token_o=state.push("heading_open","h"+String(level),1);token_o.markup="########".slice(0,level),token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);token_i.content=state.src.slice(pos,max).trim(),token_i.map=[startLine,state.line],token_i.children=[];let token_c=state.push("heading_close","h"+String(level),-1);return token_c.markup="########".slice(0,level),!0}function lheading(state,startLine,endLine){let terminatorRules=state.md.block.ruler.getRules("paragraph");if(state.sCount[startLine]-state.blkIndent>=4)return!1;let oldParentType=state.parentType;state.parentType="paragraph";let level=0,marker,nextLine=startLine+1;for(;nextLine<endLine&&!state.isEmpty(nextLine);nextLine++){if(state.sCount[nextLine]-state.blkIndent>3)continue;if(state.sCount[nextLine]>=state.blkIndent){let pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine];if(pos<max&&(marker=state.src.charCodeAt(pos),(marker===45||marker===61)&&(pos=state.skipChars(pos,marker),pos=state.skipSpaces(pos),pos>=max))){level=marker===61?1:2;break}}if(state.sCount[nextLine]<0)continue;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break}if(!level)return!1;let content=state.getLines(startLine,nextLine,state.blkIndent,!1).trim();state.line=nextLine+1;let token_o=state.push("heading_open","h"+String(level),1);token_o.markup=String.fromCharCode(marker),token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);token_i.content=content,token_i.map=[startLine,state.line-1],token_i.children=[];let token_c=state.push("heading_close","h"+String(level),-1);return token_c.markup=String.fromCharCode(marker),state.parentType=oldParentType,!0}function paragraph(state,startLine,endLine){let terminatorRules=state.md.block.ruler.getRules("paragraph"),oldParentType=state.parentType,nextLine=startLine+1;for(state.parentType="paragraph";nextLine<endLine&&!state.isEmpty(nextLine);nextLine++){if(state.sCount[nextLine]-state.blkIndent>3||state.sCount[nextLine]<0)continue;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break}let content=state.getLines(startLine,nextLine,state.blkIndent,!1).trim();state.line=nextLine;let token_o=state.push("paragraph_open","p",1);token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);return token_i.content=content,token_i.map=[startLine,state.line],token_i.children=[],state.push("paragraph_close","p",-1),state.parentType=oldParentType,!0}var _rules2=[["table",table,["paragraph","reference"]],["code",code],["fence",fence,["paragraph","reference","blockquote","list"]],["blockquote",blockquote,["paragraph","reference","blockquote","list"]],["hr",hr,["paragraph","reference","blockquote","list"]],["list",list,["paragraph","reference","blockquote"]],["reference",reference],["html_block",html_block,["paragraph","reference","blockquote"]],["heading",heading,["paragraph","reference","blockquote"]],["lheading",lheading],["paragraph",paragraph]];function ParserBlock(){this.ruler=new ruler_default;for(let i=0;i<_rules2.length;i++)this.ruler.push(_rules2[i][0],_rules2[i][1],{alt:(_rules2[i][2]||[]).slice()})}ParserBlock.prototype.tokenize=function(state,startLine,endLine){let rules=this.ruler.getRules(""),len=rules.length,maxNesting=state.md.options.maxNesting,line=startLine,hasEmptyLines=!1;for(;line<endLine&&(state.line=line=state.skipEmptyLines(line),!(line>=endLine||state.sCount[line]<state.blkIndent));){if(state.level>=maxNesting){state.line=endLine;break}let prevLine=state.line,ok=!1;for(let i=0;i<len;i++)if(ok=rules[i](state,line,endLine,!1),ok){if(prevLine>=state.line)throw new Error("block rule didn't increment state.line");break}if(!ok)throw new Error("none of the block rules matched");state.tight=!hasEmptyLines,state.isEmpty(state.line-1)&&(hasEmptyLines=!0),line=state.line,line<endLine&&state.isEmpty(line)&&(hasEmptyLines=!0,line++,state.line=line)}};ParserBlock.prototype.parse=function(src,md,env,outTokens){if(!src)return;let state=new this.State(src,md,env,outTokens);this.tokenize(state,state.line,state.lineMax)};ParserBlock.prototype.State=state_block_default;var parser_block_default=ParserBlock;function StateInline(src,md,env,outTokens){this.src=src,this.env=env,this.md=md,this.tokens=outTokens,this.tokens_meta=Array(outTokens.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0}StateInline.prototype.pushPending=function(){let token=new token_default("text","",0);return token.content=this.pending,token.level=this.pendingLevel,this.tokens.push(token),this.pending="",token};StateInline.prototype.push=function(type,tag,nesting){this.pending&&this.pushPending();let token=new token_default(type,tag,nesting),token_meta=null;return nesting<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),token.level=this.level,nesting>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],token_meta={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(token),this.tokens_meta.push(token_meta),token};StateInline.prototype.scanDelims=function(start,canSplitWord){let max=this.posMax,marker=this.src.charCodeAt(start),lastChar=start>0?this.src.charCodeAt(start-1):32,pos=start;for(;pos<max&&this.src.charCodeAt(pos)===marker;)pos++;let count=pos-start,nextChar=pos<max?this.src.charCodeAt(pos):32,isLastPunctChar=isMdAsciiPunct(lastChar)||isPunctChar(String.fromCharCode(lastChar)),isNextPunctChar=isMdAsciiPunct(nextChar)||isPunctChar(String.fromCharCode(nextChar)),isLastWhiteSpace=isWhiteSpace(lastChar),isNextWhiteSpace=isWhiteSpace(nextChar),left_flanking=!isNextWhiteSpace&&(!isNextPunctChar||isLastWhiteSpace||isLastPunctChar),right_flanking=!isLastWhiteSpace&&(!isLastPunctChar||isNextWhiteSpace||isNextPunctChar);return{can_open:left_flanking&&(canSplitWord||!right_flanking||isLastPunctChar),can_close:right_flanking&&(canSplitWord||!left_flanking||isNextPunctChar),length:count}};StateInline.prototype.Token=token_default;var state_inline_default=StateInline;function isTerminatorChar(ch){switch(ch){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}function text(state,silent){let pos=state.pos;for(;pos<state.posMax&&!isTerminatorChar(state.src.charCodeAt(pos));)pos++;return pos===state.pos?!1:(silent||(state.pending+=state.src.slice(state.pos,pos)),state.pos=pos,!0)}var SCHEME_RE=/(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i;function linkify2(state,silent){if(!state.md.options.linkify||state.linkLevel>0)return!1;let pos=state.pos,max=state.posMax;if(pos+3>max||state.src.charCodeAt(pos)!==58||state.src.charCodeAt(pos+1)!==47||state.src.charCodeAt(pos+2)!==47)return!1;let match2=state.pending.match(SCHEME_RE);if(!match2)return!1;let proto=match2[1],link2=state.md.linkify.matchAtStart(state.src.slice(pos-proto.length));if(!link2)return!1;let url=link2.url;if(url.length<=proto.length)return!1;let urlEnd=url.length;for(;urlEnd>0&&url.charCodeAt(urlEnd-1)===42;)urlEnd--;urlEnd!==url.length&&(url=url.slice(0,urlEnd));let fullUrl=state.md.normalizeLink(url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){state.pending=state.pending.slice(0,-proto.length);let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="linkify",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="linkify",token_c.info="auto"}return state.pos+=url.length-proto.length,!0}function newline(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==10)return!1;let pmax=state.pending.length-1,max=state.posMax;if(!silent)if(pmax>=0&&state.pending.charCodeAt(pmax)===32)if(pmax>=1&&state.pending.charCodeAt(pmax-1)===32){let ws=pmax-1;for(;ws>=1&&state.pending.charCodeAt(ws-1)===32;)ws--;state.pending=state.pending.slice(0,ws),state.push("hardbreak","br",0)}else state.pending=state.pending.slice(0,-1),state.push("softbreak","br",0);else state.push("softbreak","br",0);for(pos++;pos<max&&isSpace(state.src.charCodeAt(pos));)pos++;return state.pos=pos,!0}var ESCAPED=[];for(let i=0;i<256;i++)ESCAPED.push(0);"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(ch){ESCAPED[ch.charCodeAt(0)]=1});function escape2(state,silent){let pos=state.pos,max=state.posMax;if(state.src.charCodeAt(pos)!==92||(pos++,pos>=max))return!1;let ch1=state.src.charCodeAt(pos);if(ch1===10){for(silent||state.push("hardbreak","br",0),pos++;pos<max&&(ch1=state.src.charCodeAt(pos),!!isSpace(ch1));)pos++;return state.pos=pos,!0}let escapedStr=state.src[pos];if(ch1>=55296&&ch1<=56319&&pos+1<max){let ch2=state.src.charCodeAt(pos+1);ch2>=56320&&ch2<=57343&&(escapedStr+=state.src[pos+1],pos++)}let origStr="\\"+escapedStr;if(!silent){let token=state.push("text_special","",0);ch1<256&&ESCAPED[ch1]!==0?token.content=escapedStr:token.content=origStr,token.markup=origStr,token.info="escape"}return state.pos=pos+1,!0}function backtick(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==96)return!1;let start=pos;pos++;let max=state.posMax;for(;pos<max&&state.src.charCodeAt(pos)===96;)pos++;let marker=state.src.slice(start,pos),openerLength=marker.length;if(state.backticksScanned&&(state.backticks[openerLength]||0)<=start)return silent||(state.pending+=marker),state.pos+=openerLength,!0;let matchEnd=pos,matchStart;for(;(matchStart=state.src.indexOf("`",matchEnd))!==-1;){for(matchEnd=matchStart+1;matchEnd<max&&state.src.charCodeAt(matchEnd)===96;)matchEnd++;let closerLength=matchEnd-matchStart;if(closerLength===openerLength){if(!silent){let token=state.push("code_inline","code",0);token.markup=marker,token.content=state.src.slice(pos,matchStart).replace(/\n/g," ").replace(/^ (.+) $/,"$1")}return state.pos=matchEnd,!0}state.backticks[closerLength]=matchStart}return state.backticksScanned=!0,silent||(state.pending+=marker),state.pos+=openerLength,!0}function strikethrough_tokenize(state,silent){let start=state.pos,marker=state.src.charCodeAt(start);if(silent||marker!==126)return!1;let scanned=state.scanDelims(state.pos,!0),len=scanned.length,ch=String.fromCharCode(marker);if(len<2)return!1;let token;len%2&&(token=state.push("text","",0),token.content=ch,len--);for(let i=0;i<len;i+=2)token=state.push("text","",0),token.content=ch+ch,state.delimiters.push({marker,length:0,token:state.tokens.length-1,end:-1,open:scanned.can_open,close:scanned.can_close});return state.pos+=scanned.length,!0}function postProcess(state,delimiters){let token,loneMarkers=[],max=delimiters.length;for(let i=0;i<max;i++){let startDelim=delimiters[i];if(startDelim.marker!==126||startDelim.end===-1)continue;let endDelim=delimiters[startDelim.end];token=state.tokens[startDelim.token],token.type="s_open",token.tag="s",token.nesting=1,token.markup="~~",token.content="",token=state.tokens[endDelim.token],token.type="s_close",token.tag="s",token.nesting=-1,token.markup="~~",token.content="",state.tokens[endDelim.token-1].type==="text"&&state.tokens[endDelim.token-1].content==="~"&&loneMarkers.push(endDelim.token-1)}for(;loneMarkers.length;){let i=loneMarkers.pop(),j=i+1;for(;j<state.tokens.length&&state.tokens[j].type==="s_close";)j++;j--,i!==j&&(token=state.tokens[j],state.tokens[j]=state.tokens[i],state.tokens[i]=token)}}function strikethrough_postProcess(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;postProcess(state,state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&postProcess(state,tokens_meta[curr].delimiters)}var strikethrough_default={tokenize:strikethrough_tokenize,postProcess:strikethrough_postProcess};function emphasis_tokenize(state,silent){let start=state.pos,marker=state.src.charCodeAt(start);if(silent||marker!==95&&marker!==42)return!1;let scanned=state.scanDelims(state.pos,marker===42);for(let i=0;i<scanned.length;i++){let token=state.push("text","",0);token.content=String.fromCharCode(marker),state.delimiters.push({marker,length:scanned.length,token:state.tokens.length-1,end:-1,open:scanned.can_open,close:scanned.can_close})}return state.pos+=scanned.length,!0}function postProcess2(state,delimiters){let max=delimiters.length;for(let i=max-1;i>=0;i--){let startDelim=delimiters[i];if(startDelim.marker!==95&&startDelim.marker!==42||startDelim.end===-1)continue;let endDelim=delimiters[startDelim.end],isStrong=i>0&&delimiters[i-1].end===startDelim.end+1&&delimiters[i-1].marker===startDelim.marker&&delimiters[i-1].token===startDelim.token-1&&delimiters[startDelim.end+1].token===endDelim.token+1,ch=String.fromCharCode(startDelim.marker),token_o=state.tokens[startDelim.token];token_o.type=isStrong?"strong_open":"em_open",token_o.tag=isStrong?"strong":"em",token_o.nesting=1,token_o.markup=isStrong?ch+ch:ch,token_o.content="";let token_c=state.tokens[endDelim.token];token_c.type=isStrong?"strong_close":"em_close",token_c.tag=isStrong?"strong":"em",token_c.nesting=-1,token_c.markup=isStrong?ch+ch:ch,token_c.content="",isStrong&&(state.tokens[delimiters[i-1].token].content="",state.tokens[delimiters[startDelim.end+1].token].content="",i--)}}function emphasis_post_process(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;postProcess2(state,state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&postProcess2(state,tokens_meta[curr].delimiters)}var emphasis_default={tokenize:emphasis_tokenize,postProcess:emphasis_post_process};function link(state,silent){let code2,label,res,ref,href="",title="",start=state.pos,parseReference=!0;if(state.src.charCodeAt(state.pos)!==91)return!1;let oldPos=state.pos,max=state.posMax,labelStart=state.pos+1,labelEnd=state.md.helpers.parseLinkLabel(state,state.pos,!0);if(labelEnd<0)return!1;let pos=labelEnd+1;if(pos<max&&state.src.charCodeAt(pos)===40){for(parseReference=!1,pos++;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(pos>=max)return!1;if(start=pos,res=state.md.helpers.parseLinkDestination(state.src,pos,state.posMax),res.ok){for(href=state.md.normalizeLink(res.str),state.md.validateLink(href)?pos=res.pos:href="",start=pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(res=state.md.helpers.parseLinkTitle(state.src,pos,state.posMax),pos<max&&start!==pos&&res.ok)for(title=res.str,pos=res.pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);}(pos>=max||state.src.charCodeAt(pos)!==41)&&(parseReference=!0),pos++}if(parseReference){if(typeof state.env.references>"u")return!1;if(pos<max&&state.src.charCodeAt(pos)===91?(start=pos+1,pos=state.md.helpers.parseLinkLabel(state,pos),pos>=0?label=state.src.slice(start,pos++):pos=labelEnd+1):pos=labelEnd+1,label||(label=state.src.slice(labelStart,labelEnd)),ref=state.env.references[normalizeReference(label)],!ref)return state.pos=oldPos,!1;href=ref.href,title=ref.title}if(!silent){state.pos=labelStart,state.posMax=labelEnd;let token_o=state.push("link_open","a",1),attrs=[["href",href]];token_o.attrs=attrs,title&&attrs.push(["title",title]),state.linkLevel++,state.md.inline.tokenize(state),state.linkLevel--,state.push("link_close","a",-1)}return state.pos=pos,state.posMax=max,!0}function image(state,silent){let code2,content,label,pos,ref,res,title,start,href="",oldPos=state.pos,max=state.posMax;if(state.src.charCodeAt(state.pos)!==33||state.src.charCodeAt(state.pos+1)!==91)return!1;let labelStart=state.pos+2,labelEnd=state.md.helpers.parseLinkLabel(state,state.pos+1,!1);if(labelEnd<0)return!1;if(pos=labelEnd+1,pos<max&&state.src.charCodeAt(pos)===40){for(pos++;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(pos>=max)return!1;for(start=pos,res=state.md.helpers.parseLinkDestination(state.src,pos,state.posMax),res.ok&&(href=state.md.normalizeLink(res.str),state.md.validateLink(href)?pos=res.pos:href=""),start=pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(res=state.md.helpers.parseLinkTitle(state.src,pos,state.posMax),pos<max&&start!==pos&&res.ok)for(title=res.str,pos=res.pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);else title="";if(pos>=max||state.src.charCodeAt(pos)!==41)return state.pos=oldPos,!1;pos++}else{if(typeof state.env.references>"u")return!1;if(pos<max&&state.src.charCodeAt(pos)===91?(start=pos+1,pos=state.md.helpers.parseLinkLabel(state,pos),pos>=0?label=state.src.slice(start,pos++):pos=labelEnd+1):pos=labelEnd+1,label||(label=state.src.slice(labelStart,labelEnd)),ref=state.env.references[normalizeReference(label)],!ref)return state.pos=oldPos,!1;href=ref.href,title=ref.title}if(!silent){content=state.src.slice(labelStart,labelEnd);let tokens=[];state.md.inline.parse(content,state.md,state.env,tokens);let token=state.push("image","img",0),attrs=[["src",href],["alt",""]];token.attrs=attrs,token.children=tokens,token.content=content,title&&attrs.push(["title",title])}return state.pos=pos,state.posMax=max,!0}var EMAIL_RE=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,AUTOLINK_RE=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function autolink(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==60)return!1;let start=state.pos,max=state.posMax;for(;;){if(++pos>=max)return!1;let ch=state.src.charCodeAt(pos);if(ch===60)return!1;if(ch===62)break}let url=state.src.slice(start+1,pos);if(AUTOLINK_RE.test(url)){let fullUrl=state.md.normalizeLink(url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="autolink",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="autolink",token_c.info="auto"}return state.pos+=url.length+2,!0}if(EMAIL_RE.test(url)){let fullUrl=state.md.normalizeLink("mailto:"+url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="autolink",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="autolink",token_c.info="auto"}return state.pos+=url.length+2,!0}return!1}function isLinkOpen2(str){return/^<a[>\s]/i.test(str)}function isLinkClose2(str){return/^<\/a\s*>/i.test(str)}function isLetter(ch){let lc=ch|32;return lc>=97&&lc<=122}function html_inline(state,silent){if(!state.md.options.html)return!1;let max=state.posMax,pos=state.pos;if(state.src.charCodeAt(pos)!==60||pos+2>=max)return!1;let ch=state.src.charCodeAt(pos+1);if(ch!==33&&ch!==63&&ch!==47&&!isLetter(ch))return!1;let match2=state.src.slice(pos).match(HTML_TAG_RE);if(!match2)return!1;if(!silent){let token=state.push("html_inline","",0);token.content=match2[0],isLinkOpen2(token.content)&&state.linkLevel++,isLinkClose2(token.content)&&state.linkLevel--}return state.pos+=match2[0].length,!0}var DIGITAL_RE=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,NAMED_RE=/^&([a-z][a-z0-9]{1,31});/i;function entity(state,silent){let pos=state.pos,max=state.posMax;if(state.src.charCodeAt(pos)!==38||pos+1>=max)return!1;if(state.src.charCodeAt(pos+1)===35){let match2=state.src.slice(pos).match(DIGITAL_RE);if(match2){if(!silent){let code2=match2[1][0].toLowerCase()==="x"?parseInt(match2[1].slice(1),16):parseInt(match2[1],10),token=state.push("text_special","",0);token.content=isValidEntityCode(code2)?fromCodePoint2(code2):fromCodePoint2(65533),token.markup=match2[0],token.info="entity"}return state.pos+=match2[0].length,!0}}else{let match2=state.src.slice(pos).match(NAMED_RE);if(match2){let decoded=decodeHTML(match2[0]);if(decoded!==match2[0]){if(!silent){let token=state.push("text_special","",0);token.content=decoded,token.markup=match2[0],token.info="entity"}return state.pos+=match2[0].length,!0}}}return!1}function processDelimiters(delimiters){let openersBottom={},max=delimiters.length;if(!max)return;let headerIdx=0,lastTokenIdx=-2,jumps=[];for(let closerIdx=0;closerIdx<max;closerIdx++){let closer=delimiters[closerIdx];if(jumps.push(0),(delimiters[headerIdx].marker!==closer.marker||lastTokenIdx!==closer.token-1)&&(headerIdx=closerIdx),lastTokenIdx=closer.token,closer.length=closer.length||0,!closer.close)continue;openersBottom.hasOwnProperty(closer.marker)||(openersBottom[closer.marker]=[-1,-1,-1,-1,-1,-1]);let minOpenerIdx=openersBottom[closer.marker][(closer.open?3:0)+closer.length%3],openerIdx=headerIdx-jumps[headerIdx]-1,newMinOpenerIdx=openerIdx;for(;openerIdx>minOpenerIdx;openerIdx-=jumps[openerIdx]+1){let opener=delimiters[openerIdx];if(opener.marker===closer.marker&&opener.open&&opener.end<0){let isOddMatch=!1;if((opener.close||closer.open)&&(opener.length+closer.length)%3===0&&(opener.length%3!==0||closer.length%3!==0)&&(isOddMatch=!0),!isOddMatch){let lastJump=openerIdx>0&&!delimiters[openerIdx-1].open?jumps[openerIdx-1]+1:0;jumps[closerIdx]=closerIdx-openerIdx+lastJump,jumps[openerIdx]=lastJump,closer.open=!1,opener.end=closerIdx,opener.close=!1,newMinOpenerIdx=-1,lastTokenIdx=-2;break}}}newMinOpenerIdx!==-1&&(openersBottom[closer.marker][(closer.open?3:0)+(closer.length||0)%3]=newMinOpenerIdx)}}function link_pairs(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;processDelimiters(state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&processDelimiters(tokens_meta[curr].delimiters)}function fragments_join(state){let curr,last,level=0,tokens=state.tokens,max=state.tokens.length;for(curr=last=0;curr<max;curr++)tokens[curr].nesting<0&&level--,tokens[curr].level=level,tokens[curr].nesting>0&&level++,tokens[curr].type==="text"&&curr+1<max&&tokens[curr+1].type==="text"?tokens[curr+1].content=tokens[curr].content+tokens[curr+1].content:(curr!==last&&(tokens[last]=tokens[curr]),last++);curr!==last&&(tokens.length=last)}var _rules3=[["text",text],["linkify",linkify2],["newline",newline],["escape",escape2],["backticks",backtick],["strikethrough",strikethrough_default.tokenize],["emphasis",emphasis_default.tokenize],["link",link],["image",image],["autolink",autolink],["html_inline",html_inline],["entity",entity]],_rules22=[["balance_pairs",link_pairs],["strikethrough",strikethrough_default.postProcess],["emphasis",emphasis_default.postProcess],["fragments_join",fragments_join]];function ParserInline(){this.ruler=new ruler_default;for(let i=0;i<_rules3.length;i++)this.ruler.push(_rules3[i][0],_rules3[i][1]);this.ruler2=new ruler_default;for(let i=0;i<_rules22.length;i++)this.ruler2.push(_rules22[i][0],_rules22[i][1])}ParserInline.prototype.skipToken=function(state){let pos=state.pos,rules=this.ruler.getRules(""),len=rules.length,maxNesting=state.md.options.maxNesting,cache=state.cache;if(typeof cache[pos]<"u"){state.pos=cache[pos];return}let ok=!1;if(state.level<maxNesting){for(let i=0;i<len;i++)if(state.level++,ok=rules[i](state,!0),state.level--,ok){if(pos>=state.pos)throw new Error("inline rule didn't increment state.pos");break}}else state.pos=state.posMax;ok||state.pos++,cache[pos]=state.pos};ParserInline.prototype.tokenize=function(state){let rules=this.ruler.getRules(""),len=rules.length,end=state.posMax,maxNesting=state.md.options.maxNesting;for(;state.pos<end;){let prevPos=state.pos,ok=!1;if(state.level<maxNesting){for(let i=0;i<len;i++)if(ok=rules[i](state,!1),ok){if(prevPos>=state.pos)throw new Error("inline rule didn't increment state.pos");break}}if(ok){if(state.pos>=end)break;continue}state.pending+=state.src[state.pos++]}state.pending&&state.pushPending()};ParserInline.prototype.parse=function(str,md,env,outTokens){let state=new this.State(str,md,env,outTokens);this.tokenize(state);let rules=this.ruler2.getRules(""),len=rules.length;for(let i=0;i<len;i++)rules[i](state)};ParserInline.prototype.State=state_inline_default;var parser_inline_default=ParserInline;function re_default(opts){let re={};opts=opts||{},re.src_Any=regex_default.source,re.src_Cc=regex_default2.source,re.src_Z=regex_default6.source,re.src_P=regex_default4.source,re.src_ZPCc=[re.src_Z,re.src_P,re.src_Cc].join("|"),re.src_ZCc=[re.src_Z,re.src_Cc].join("|");let text_separators="[><\uFF5C]";return re.src_pseudo_letter="(?:(?!"+text_separators+"|"+re.src_ZPCc+")"+re.src_Any+")",re.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",re.src_auth="(?:(?:(?!"+re.src_ZCc+"|[@/\\[\\]()]).)+@)?",re.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",re.src_host_terminator="(?=$|"+text_separators+"|"+re.src_ZPCc+")(?!"+(opts["---"]?"-(?!--)|":"-|")+"_|:\\d|\\.-|\\.(?!$|"+re.src_ZPCc+"))",re.src_path="(?:[/?#](?:(?!"+re.src_ZCc+"|"+text_separators+`|[()[\\]{}.,"'?!\\-;]).|\\[(?:(?!`+re.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+re.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+re.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+re.src_ZCc+`|["]).)+\\"|\\'(?:(?!`+re.src_ZCc+"|[']).)+\\'|\\'(?="+re.src_pseudo_letter+"|[-])|\\.{2,}[a-zA-Z0-9%/&]|\\.(?!"+re.src_ZCc+"|[.]|$)|"+(opts["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+",(?!"+re.src_ZCc+"|$)|;(?!"+re.src_ZCc+"|$)|\\!+(?!"+re.src_ZCc+"|[!]|$)|\\?(?!"+re.src_ZCc+"|[?]|$))+|\\/)?",re.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*',re.src_xn="xn--[a-z0-9\\-]{1,59}",re.src_domain_root="(?:"+re.src_xn+"|"+re.src_pseudo_letter+"{1,63})",re.src_domain="(?:"+re.src_xn+"|(?:"+re.src_pseudo_letter+")|(?:"+re.src_pseudo_letter+"(?:-|"+re.src_pseudo_letter+"){0,61}"+re.src_pseudo_letter+"))",re.src_host="(?:(?:(?:(?:"+re.src_domain+")\\.)*"+re.src_domain+"))",re.tpl_host_fuzzy="(?:"+re.src_ip4+"|(?:(?:(?:"+re.src_domain+")\\.)+(?:%TLDS%)))",re.tpl_host_no_ip_fuzzy="(?:(?:(?:"+re.src_domain+")\\.)+(?:%TLDS%))",re.src_host_strict=re.src_host+re.src_host_terminator,re.tpl_host_fuzzy_strict=re.tpl_host_fuzzy+re.src_host_terminator,re.src_host_port_strict=re.src_host+re.src_port+re.src_host_terminator,re.tpl_host_port_fuzzy_strict=re.tpl_host_fuzzy+re.src_port+re.src_host_terminator,re.tpl_host_port_no_ip_fuzzy_strict=re.tpl_host_no_ip_fuzzy+re.src_port+re.src_host_terminator,re.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+re.src_ZPCc+"|>|$))",re.tpl_email_fuzzy="(^|"+text_separators+'|"|\\(|'+re.src_ZCc+")("+re.src_email_name+"@"+re.tpl_host_fuzzy_strict+")",re.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+re.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+re.tpl_host_port_fuzzy_strict+re.src_path+")",re.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+re.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+re.tpl_host_port_no_ip_fuzzy_strict+re.src_path+")",re}function assign2(obj){return Array.prototype.slice.call(arguments,1).forEach(function(source){source&&Object.keys(source).forEach(function(key){obj[key]=source[key]})}),obj}function _class2(obj){return Object.prototype.toString.call(obj)}function isString2(obj){return _class2(obj)==="[object String]"}function isObject(obj){return _class2(obj)==="[object Object]"}function isRegExp(obj){return _class2(obj)==="[object RegExp]"}function isFunction(obj){return _class2(obj)==="[object Function]"}function escapeRE2(str){return str.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}var defaultOptions={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};function isOptionsObj(obj){return Object.keys(obj||{}).reduce(function(acc,k){return acc||defaultOptions.hasOwnProperty(k)},!1)}var defaultSchemas={"http:":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.http||(self.re.http=new RegExp("^\\/\\/"+self.re.src_auth+self.re.src_host_port_strict+self.re.src_path,"i")),self.re.http.test(tail)?tail.match(self.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.no_http||(self.re.no_http=new RegExp("^"+self.re.src_auth+"(?:localhost|(?:(?:"+self.re.src_domain+")\\.)+"+self.re.src_domain_root+")"+self.re.src_port+self.re.src_host_terminator+self.re.src_path,"i")),self.re.no_http.test(tail)?pos>=3&&text2[pos-3]===":"||pos>=3&&text2[pos-3]==="/"?0:tail.match(self.re.no_http)[0].length:0}},"mailto:":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.mailto||(self.re.mailto=new RegExp("^"+self.re.src_email_name+"@"+self.re.src_host_strict,"i")),self.re.mailto.test(tail)?tail.match(self.re.mailto)[0].length:0}}},tlds_2ch_src_re="a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]",tlds_default="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");function resetScanCache(self){self.__index__=-1,self.__text_cache__=""}function createValidator(re){return function(text2,pos){let tail=text2.slice(pos);return re.test(tail)?tail.match(re)[0].length:0}}function createNormalizer(){return function(match2,self){self.normalize(match2)}}function compile(self){let re=self.re=re_default(self.__opts__),tlds2=self.__tlds__.slice();self.onCompile(),self.__tlds_replaced__||tlds2.push(tlds_2ch_src_re),tlds2.push(re.src_xn),re.src_tlds=tlds2.join("|");function untpl(tpl){return tpl.replace("%TLDS%",re.src_tlds)}re.email_fuzzy=RegExp(untpl(re.tpl_email_fuzzy),"i"),re.link_fuzzy=RegExp(untpl(re.tpl_link_fuzzy),"i"),re.link_no_ip_fuzzy=RegExp(untpl(re.tpl_link_no_ip_fuzzy),"i"),re.host_fuzzy_test=RegExp(untpl(re.tpl_host_fuzzy_test),"i");let aliases=[];self.__compiled__={};function schemaError(name,val){throw new Error('(LinkifyIt) Invalid schema "'+name+'": '+val)}Object.keys(self.__schemas__).forEach(function(name){let val=self.__schemas__[name];if(val===null)return;let compiled={validate:null,link:null};if(self.__compiled__[name]=compiled,isObject(val)){isRegExp(val.validate)?compiled.validate=createValidator(val.validate):isFunction(val.validate)?compiled.validate=val.validate:schemaError(name,val),isFunction(val.normalize)?compiled.normalize=val.normalize:val.normalize?schemaError(name,val):compiled.normalize=createNormalizer();return}if(isString2(val)){aliases.push(name);return}schemaError(name,val)}),aliases.forEach(function(alias){self.__compiled__[self.__schemas__[alias]]&&(self.__compiled__[alias].validate=self.__compiled__[self.__schemas__[alias]].validate,self.__compiled__[alias].normalize=self.__compiled__[self.__schemas__[alias]].normalize)}),self.__compiled__[""]={validate:null,normalize:createNormalizer()};let slist=Object.keys(self.__compiled__).filter(function(name){return name.length>0&&self.__compiled__[name]}).map(escapeRE2).join("|");self.re.schema_test=RegExp("(^|(?!_)(?:[><\uFF5C]|"+re.src_ZPCc+"))("+slist+")","i"),self.re.schema_search=RegExp("(^|(?!_)(?:[><\uFF5C]|"+re.src_ZPCc+"))("+slist+")","ig"),self.re.schema_at_start=RegExp("^"+self.re.schema_search.source,"i"),self.re.pretest=RegExp("("+self.re.schema_test.source+")|("+self.re.host_fuzzy_test.source+")|@","i"),resetScanCache(self)}function Match(self,shift){let start=self.__index__,end=self.__last_index__,text2=self.__text_cache__.slice(start,end);this.schema=self.__schema__.toLowerCase(),this.index=start+shift,this.lastIndex=end+shift,this.raw=text2,this.text=text2,this.url=text2}function createMatch(self,shift){let match2=new Match(self,shift);return self.__compiled__[match2.schema].normalize(match2,self),match2}function LinkifyIt(schemas,options){if(!(this instanceof LinkifyIt))return new LinkifyIt(schemas,options);options||isOptionsObj(schemas)&&(options=schemas,schemas={}),this.__opts__=assign2({},defaultOptions,options),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=assign2({},defaultSchemas,schemas),this.__compiled__={},this.__tlds__=tlds_default,this.__tlds_replaced__=!1,this.re={},compile(this)}LinkifyIt.prototype.add=function(schema,definition){return this.__schemas__[schema]=definition,compile(this),this};LinkifyIt.prototype.set=function(options){return this.__opts__=assign2(this.__opts__,options),this};LinkifyIt.prototype.test=function(text2){if(this.__text_cache__=text2,this.__index__=-1,!text2.length)return!1;let m,ml,me,len,shift,next,re,tld_pos,at_pos;if(this.re.schema_test.test(text2)){for(re=this.re.schema_search,re.lastIndex=0;(m=re.exec(text2))!==null;)if(len=this.testSchemaAt(text2,m[2],re.lastIndex),len){this.__schema__=m[2],this.__index__=m.index+m[1].length,this.__last_index__=m.index+m[0].length+len;break}}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(tld_pos=text2.search(this.re.host_fuzzy_test),tld_pos>=0&&(this.__index__<0||tld_pos<this.__index__)&&(ml=text2.match(this.__opts__.fuzzyIP?this.re.link_fuzzy:this.re.link_no_ip_fuzzy))!==null&&(shift=ml.index+ml[1].length,(this.__index__<0||shift<this.__index__)&&(this.__schema__="",this.__index__=shift,this.__last_index__=ml.index+ml[0].length))),this.__opts__.fuzzyEmail&&this.__compiled__["mailto:"]&&(at_pos=text2.indexOf("@"),at_pos>=0&&(me=text2.match(this.re.email_fuzzy))!==null&&(shift=me.index+me[1].length,next=me.index+me[0].length,(this.__index__<0||shift<this.__index__||shift===this.__index__&&next>this.__last_index__)&&(this.__schema__="mailto:",this.__index__=shift,this.__last_index__=next))),this.__index__>=0};LinkifyIt.prototype.pretest=function(text2){return this.re.pretest.test(text2)};LinkifyIt.prototype.testSchemaAt=function(text2,schema,pos){return this.__compiled__[schema.toLowerCase()]?this.__compiled__[schema.toLowerCase()].validate(text2,pos,this):0};LinkifyIt.prototype.match=function(text2){let result=[],shift=0;this.__index__>=0&&this.__text_cache__===text2&&(result.push(createMatch(this,shift)),shift=this.__last_index__);let tail=shift?text2.slice(shift):text2;for(;this.test(tail);)result.push(createMatch(this,shift)),tail=tail.slice(this.__last_index__),shift+=this.__last_index__;return result.length?result:null};LinkifyIt.prototype.matchAtStart=function(text2){if(this.__text_cache__=text2,this.__index__=-1,!text2.length)return null;let m=this.re.schema_at_start.exec(text2);if(!m)return null;let len=this.testSchemaAt(text2,m[2],m[0].length);return len?(this.__schema__=m[2],this.__index__=m.index+m[1].length,this.__last_index__=m.index+m[0].length+len,createMatch(this,0)):null};LinkifyIt.prototype.tlds=function(list2,keepOld){return list2=Array.isArray(list2)?list2:[list2],keepOld?(this.__tlds__=this.__tlds__.concat(list2).sort().filter(function(el,idx,arr){return el!==arr[idx-1]}).reverse(),compile(this),this):(this.__tlds__=list2.slice(),this.__tlds_replaced__=!0,compile(this),this)};LinkifyIt.prototype.normalize=function(match2){match2.schema||(match2.url="http://"+match2.url),match2.schema==="mailto:"&&!/^mailto:/i.test(match2.url)&&(match2.url="mailto:"+match2.url)};LinkifyIt.prototype.onCompile=function(){};var linkify_it_default=LinkifyIt;var import_punycode=__toESM(require_punycode(),1);var default_default={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}};var zero_default={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["paragraph"]},inline:{rules:["text"],rules2:["balance_pairs","fragments_join"]}}};var commonmark_default={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["blockquote","code","fence","heading","hr","html_block","lheading","list","reference","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","html_inline","image","link","newline","text"],rules2:["balance_pairs","emphasis","fragments_join"]}}};var config={default:default_default,zero:zero_default,commonmark:commonmark_default},BAD_PROTO_RE=/^(vbscript|javascript|file|data):/,GOOD_DATA_RE=/^data:image\/(gif|png|jpeg|webp);/;function validateLink(url){let str=url.trim().toLowerCase();return BAD_PROTO_RE.test(str)?GOOD_DATA_RE.test(str):!0}var RECODE_HOSTNAME_FOR=["http:","https:","mailto:"];function normalizeLink(url){let parsed=parse_default(url,!0);if(parsed.hostname&&(!parsed.protocol||RECODE_HOSTNAME_FOR.indexOf(parsed.protocol)>=0))try{parsed.hostname=import_punycode.default.toASCII(parsed.hostname)}catch{}return encode_default(format(parsed))}function normalizeLinkText(url){let parsed=parse_default(url,!0);if(parsed.hostname&&(!parsed.protocol||RECODE_HOSTNAME_FOR.indexOf(parsed.protocol)>=0))try{parsed.hostname=import_punycode.default.toUnicode(parsed.hostname)}catch{}return decode_default(format(parsed),decode_default.defaultChars+"%")}function MarkdownIt(presetName,options){if(!(this instanceof MarkdownIt))return new MarkdownIt(presetName,options);options||isString(presetName)||(options=presetName||{},presetName="default"),this.inline=new parser_inline_default,this.block=new parser_block_default,this.core=new parser_core_default,this.renderer=new renderer_default,this.linkify=new linkify_it_default,this.validateLink=validateLink,this.normalizeLink=normalizeLink,this.normalizeLinkText=normalizeLinkText,this.utils=utils_exports,this.helpers=assign({},helpers_exports),this.options={},this.configure(presetName),options&&this.set(options)}MarkdownIt.prototype.set=function(options){return assign(this.options,options),this};MarkdownIt.prototype.configure=function(presets){let self=this;if(isString(presets)){let presetName=presets;if(presets=config[presetName],!presets)throw new Error('Wrong `markdown-it` preset "'+presetName+'", check name')}if(!presets)throw new Error("Wrong `markdown-it` preset, can't be empty");return presets.options&&self.set(presets.options),presets.components&&Object.keys(presets.components).forEach(function(name){presets.components[name].rules&&self[name].ruler.enableOnly(presets.components[name].rules),presets.components[name].rules2&&self[name].ruler2.enableOnly(presets.components[name].rules2)}),this};MarkdownIt.prototype.enable=function(list2,ignoreInvalid){let result=[];Array.isArray(list2)||(list2=[list2]),["core","block","inline"].forEach(function(chain){result=result.concat(this[chain].ruler.enable(list2,!0))},this),result=result.concat(this.inline.ruler2.enable(list2,!0));let missed=list2.filter(function(name){return result.indexOf(name)<0});if(missed.length&&!ignoreInvalid)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+missed);return this};MarkdownIt.prototype.disable=function(list2,ignoreInvalid){let result=[];Array.isArray(list2)||(list2=[list2]),["core","block","inline"].forEach(function(chain){result=result.concat(this[chain].ruler.disable(list2,!0))},this),result=result.concat(this.inline.ruler2.disable(list2,!0));let missed=list2.filter(function(name){return result.indexOf(name)<0});if(missed.length&&!ignoreInvalid)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+missed);return this};MarkdownIt.prototype.use=function(plugin){let args=[this].concat(Array.prototype.slice.call(arguments,1));return plugin.apply(plugin,args),this};MarkdownIt.prototype.parse=function(src,env){if(typeof src!="string")throw new Error("Input data should be a String");let state=new this.core.State(src,this,env);return this.core.process(state),state.tokens};MarkdownIt.prototype.render=function(src,env){return env=env||{},this.renderer.render(this.parse(src,env),this.options,env)};MarkdownIt.prototype.parseInline=function(src,env){let state=new this.core.State(src,this,env);return state.inlineMode=!0,this.core.process(state),state.tokens};MarkdownIt.prototype.renderInline=function(src,env){return env=env||{},this.renderer.render(this.parseInline(src,env),this.options,env)};var lib_default=MarkdownIt;function sanitizeCmsUrl(url){let value=url.trim();return/^(https?:|mailto:)/iu.test(value)||value.startsWith("/")||value.startsWith("#")?value:"#"}var cmsMarkdownRenderer=(()=>{let renderer=new lib_default({html:!1,linkify:!0,breaks:!1}),defaultLinkOpen=renderer.renderer.rules.link_open??((tokens,idx,options,_env,self)=>self.renderToken(tokens,idx,options));renderer.renderer.rules.link_open=(tokens,idx,options,env,self)=>{let hrefIndex=tokens[idx]?.attrIndex("href")??-1;if(hrefIndex>=0){let href=tokens[idx]?.attrs?.[hrefIndex]?.[1]??"";tokens[idx]?.attrs?.splice(hrefIndex,1,["href",sanitizeCmsUrl(href)])}return tokens[idx]?.attrSet("target","_blank"),tokens[idx]?.attrSet("rel","noreferrer noopener"),defaultLinkOpen(tokens,idx,options,env,self)};let defaultImage=renderer.renderer.rules.image??((tokens,idx,options,_env,self)=>self.renderToken(tokens,idx,options));return renderer.renderer.rules.image=(tokens,idx,options,env,self)=>{let srcIndex=tokens[idx]?.attrIndex("src")??-1;if(srcIndex>=0){let src=tokens[idx]?.attrs?.[srcIndex]?.[1]??"";tokens[idx]?.attrs?.splice(srcIndex,1,["src",sanitizeCmsUrl(src)])}return defaultImage(tokens,idx,options,env,self)},renderer})();var DATA_FORM_EXTENSION_FIELD_TYPES=["json","time"],DATA_FORM_FIELD_TYPES=[...CMS_FIELD_TYPES,...DATA_FORM_EXTENSION_FIELD_TYPES],DATA_FORM_UNSUPPORTED_FIELD_TYPES=["computed","rich_text"];function isDataFormCmsSharedFieldType(value){return typeof value=="string"&&CMS_FIELD_TYPES.includes(value)}function isDataFormFieldType(value){return typeof value=="string"&&DATA_FORM_FIELD_TYPES.includes(value)}function isDataFormUnsupportedFieldType(value){return typeof value=="string"&&DATA_FORM_UNSUPPORTED_FIELD_TYPES.includes(value)}var DATA_FORM_SHARING_MODES=["app_scoped","shared"];var DATA_FORM_RESOURCE_KINDS=["anonymous_submission","end_user_owned","admin_managed"],DATA_FORM_OWNER_TYPES=["none","identity"],DATA_FORM_RESOURCE_OWNER_TYPES=["app","tenant"],DATA_FORM_CONSUMER_ACCESS_MODES=["read_only","read_write"],DATA_FORM_SOURCE_OF_TRUTH="data_form_schema",DATA_FORM_SYSTEM_FIELD_NAMES=["record_id","resource_key","tenant_id","app_id","owner_identity_id","owner_app_user_id","source_app_id","source_channel","submit_context","created_by_identity_id","updated_by_identity_id","created_at","updated_at"];function assertObject2(value,message){if(typeof value!="object"||value===null||Array.isArray(value))throw new Error(message);return value}function asString2(value,field,options={}){if(typeof value=="string"){let normalized=value.trim();if(options.allowEmpty||normalized.length>0)return normalized}if(options.fallback!==void 0)return options.fallback;throw new Error(`Data Form field \`${field}\` must be a non-empty string.`)}function asOptionalString(value,field){if(value!=null){if(typeof value=="string")return value.trim();throw new Error(`Data Form field \`${field}\` must be a string when provided.`)}}function asOptionalStringArray(value,field){if(value!=null){if(!Array.isArray(value))throw new Error(`Data Form field \`${field}\` must be an array of strings when provided.`);return value.map((item,index)=>asString2(item,`${field}[${index}]`))}}function asBoolean2(value,field,fallback=!1){if(typeof value=="boolean")return value;if(value===void 0)return fallback;throw new Error(`Data Form field \`${field}\` must be a boolean.`)}function asNumber2(value,field,fallback){if(typeof value=="number"&&Number.isFinite(value))return value;if(value===void 0&&fallback!==void 0)return fallback;throw new Error(`Data Form field \`${field}\` must be a finite number.`)}function normalizeEnumValue(value,values,field,fallback){if(value===void 0)return fallback;if(typeof value=="string"){let normalized=value.trim();if(values.includes(normalized))return normalized}throw new Error(`Data Form field \`${field}\` must be one of: ${values.join(", ")}.`)}function normalizeAccessScope(value,field,fallback){if(value===void 0)return fallback;if(typeof value=="string"&&DATA_FORM_ACCESS_SCOPES.includes(value))return value;throw new Error(`Data Form field \`${field}\` must be one of: ${DATA_FORM_ACCESS_SCOPES.join(", ")}.`)}function defaultAccessPolicy(resourceKind){switch(resourceKind){case"anonymous_submission":return{create:"public",read:"admin",update:"admin"};case"end_user_owned":return{create:"own",read:"own",update:"own"};case"admin_managed":default:return{create:"admin",read:"admin",update:"admin"}}}function defaultOwnerTypeForResourceKind(resourceKind){switch(resourceKind){case"end_user_owned":return"identity";case"anonymous_submission":case"admin_managed":default:return"none"}}function normalizeAccessPolicy(value,resourceKind){let defaults=defaultAccessPolicy(resourceKind);if(value===void 0)return defaults;let record=assertObject2(value,"Data Form access_policy must be an object.");return{create:normalizeAccessScope(record.create,"access_policy.create",defaults.create),read:normalizeAccessScope(record.read,"access_policy.read",defaults.read),update:normalizeAccessScope(record.update,"access_policy.update",defaults.update)}}function defaultConsumerAccessMode(sharingMode){return"read_only"}function normalizeRichTextContentFormat(value,fieldName){if(value!==void 0){if(isCmsContentFormat(value))return value;throw new Error(`Data Form field \`${fieldName}.content_format\` must be \`markdown\` or \`html\`.`)}}function normalizeJsonFieldSpec(record){let validationRecord=record.validation===void 0?void 0:assertObject2(record.validation,"Data Form json field validation must be an object.");return{name:asString2(record.name,"fields[].name"),label:asString2(record.label,"fields[].label"),type:"json",required:asBoolean2(record.required,"fields[].required"),default:record.default??null,description:asString2(record.description,"fields[].description",{allowEmpty:!0,fallback:""}),order:asNumber2(record.order,"fields[].order"),readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,"fields[].readonly"),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,"fields[].system_managed"),validation:validationRecord?.max_size===void 0?void 0:{max_size:asNumber2(validationRecord.max_size,"fields[].validation.max_size")}}}function normalizeTimeFieldSpec(record,fieldName,implicitValidation){return{name:fieldName,label:asString2(record.label,`${fieldName}.label`),type:"time",required:asBoolean2(record.required,`${fieldName}.required`),default:record.default??"",description:asString2(record.description,`${fieldName}.description`,{allowEmpty:!0,fallback:""}),order:asNumber2(record.order,`${fieldName}.order`),readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,`${fieldName}.readonly`),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,`${fieldName}.system_managed`),validation:normalizeValidationAliases(record,"text",fieldName,implicitValidation)}}function normalizeFieldTypeAlias(rawType,fieldName){switch(rawType){case"email":return{normalizedType:"text",implicitValidation:{pattern:"^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"}};case"phone":return{normalizedType:"text",implicitValidation:{pattern:"^1\\d{10}$"}};case"url":return{normalizedType:"url",implicitValidation:{allowed_protocols:["https","http"]}};case"multiselect":return{normalizedType:"multi_select"};case"textarea":return{normalizedType:"text",implicitUi:{multiline:!0}};case"datetime":return{normalizedType:"date",implicitUi:{with_time:!0}};case"markdown":return{normalizedType:"text",implicitUi:{multiline:!0},implicitContentFormat:"markdown"};case"richtext":return{normalizedType:"text",implicitUi:{multiline:!0},implicitContentFormat:"html"};case"time":return{normalizedType:"time",implicitValidation:{pattern:"^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$"}};default:return{normalizedType:rawType}}}function resolvePhonePattern(record,fieldName){switch(record.locale===void 0?"zh-CN":asString2(record.locale,`${fieldName}.locale`)){case"zh-CN":return"^1\\d{10}$";case"e164":case"international":return"^\\+[1-9]\\d{6,14}$";default:throw new Error(`Data Form field \`${fieldName}.locale\` currently only supports \`zh-CN\`, \`e164\`, or \`international\`.`)}}function normalizeFieldTypeAliasWithRecord(rawType,record,fieldName){return rawType==="phone"?{normalizedType:"text",implicitValidation:{pattern:resolvePhonePattern(record,fieldName)}}:normalizeFieldTypeAlias(rawType,fieldName)}function toBytesFromMb(value){return Math.round(value*1024*1024)}var ACCEPT_ALIAS_TO_MIME={pdf:"application/pdf",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp"};function defaultImageMimeTypes(){return["image/png","image/jpeg","image/webp"]}function normalizeValidationAliases(record,rawType,fieldName,implicitValidation){let explicitValidation=record.validation===void 0?void 0:assertObject2(record.validation,`Data Form field \`${fieldName}.validation\` must be an object.`),normalized={...implicitValidation??{},...explicitValidation??{}};return record.min!==void 0&&(normalized[rawType==="number"?"min":"min_length"]=asNumber2(record.min,`${fieldName}.min`)),record.max!==void 0&&(normalized[rawType==="number"?"max":"max_length"]=asNumber2(record.max,`${fieldName}.max`)),record.max_files!==void 0&&(normalized.max_count=asNumber2(record.max_files,`${fieldName}.max_files`)),record.max_size_mb!==void 0&&(normalized.max_size=toBytesFromMb(asNumber2(record.max_size_mb,`${fieldName}.max_size_mb`))),Object.keys(normalized).length>0?normalized:void 0}function normalizeUiAliases(record,fieldName){let requestedType=typeof record.type=="string"?record.type.trim():"",typeAlias=requestedType?normalizeFieldTypeAliasWithRecord(requestedType,record,fieldName):void 0,existingUi=record.ui===void 0?void 0:assertObject2(record.ui,`Data Form field \`${fieldName}.ui\` must be an object.`),normalizedUi={...typeAlias?.implicitUi??{},...existingUi??{}};return record.multiline!==void 0&&(normalizedUi.multiline=asBoolean2(record.multiline,`${fieldName}.multiline`)),Object.keys(normalizedUi).length>0?normalizedUi:void 0}function normalizeAcceptAliases(record,rawType,fieldName){if(record.accept!==void 0)return Array.isArray(record.accept)?{mime_types:record.accept.map((item,index)=>{let alias=asString2(item,`${fieldName}.accept[${index}]`).toLowerCase(),resolved=ACCEPT_ALIAS_TO_MIME[alias];if(!resolved)throw new Error(`Data Form field \`${fieldName}.accept[${index}]\` uses unsupported alias \`${alias}\`.`);return resolved})}:assertObject2(record.accept,`Data Form field \`${fieldName}.accept\` must be an object or string array.`);if(rawType==="image")return{mime_types:defaultImageMimeTypes()}}function normalizeDataFormFieldSpec(input){let record=assertObject2(input,"Data Form field spec must be an object."),fieldName=asString2(record.name,"fields[].name"),requestedType=asString2(record.type,`${fieldName}.type`),typeAlias=normalizeFieldTypeAliasWithRecord(requestedType,record,fieldName),rawType=typeAlias.normalizedType;if(isDataFormUnsupportedFieldType(requestedType))throw new Error(`Data Form field \`${fieldName}\` uses unsupported type \`${requestedType}\`. Use \`text + ui.multiline\` or \`content_format\` semantics instead.`);if(!isDataFormFieldType(rawType))throw new Error(`Data Form field \`${fieldName}\` uses unknown type \`${requestedType}\`.`);if(rawType==="json")return normalizeJsonFieldSpec(record);if(rawType==="time")return normalizeTimeFieldSpec(record,fieldName,typeAlias.implicitValidation);if(!isDataFormCmsSharedFieldType(rawType))throw new Error(`Data Form field \`${fieldName}\` cannot normalize type \`${rawType}\`.`);let normalizedCmsField=normalizeCmsFieldSpec({...record,accept:normalizeAcceptAliases(record,rawType,fieldName),ui:normalizeUiAliases(record,fieldName),validation:normalizeValidationAliases(record,requestedType,fieldName,typeAlias.implicitValidation),type:rawType}),contentFormat=normalizeRichTextContentFormat(record.content_format,fieldName)??typeAlias.implicitContentFormat;return{...normalizedCmsField,readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,`${fieldName}.readonly`),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,`${fieldName}.system_managed`),content_format:contentFormat}}function normalizeDataFormResourceSchema(input,options={}){let record=assertObject2(input,"Data Form resource schema must be an object."),resourceKey=asString2(record.resource_key??record.resource??options.defaultResourceKey,"resource_key"),resourceKind=normalizeEnumValue(record.resource_kind,DATA_FORM_RESOURCE_KINDS,"resource_kind","anonymous_submission"),ownerType=normalizeEnumValue(record.owner_type,DATA_FORM_OWNER_TYPES,"owner_type",defaultOwnerTypeForResourceKind(resourceKind)),resourceOwnerType=normalizeEnumValue(record.resource_owner_type,DATA_FORM_RESOURCE_OWNER_TYPES,"resource_owner_type","app"),sharingMode=normalizeEnumValue(record.sharing_mode,DATA_FORM_SHARING_MODES,"sharing_mode","app_scoped"),consumerAppIds=asOptionalStringArray(record.consumer_app_ids,"consumer_app_ids"),consumerAccess=normalizeEnumValue(record.consumer_access,DATA_FORM_CONSUMER_ACCESS_MODES,"consumer_access",defaultConsumerAccessMode(sharingMode)),fieldsInput=record.fields;if(!Array.isArray(fieldsInput))throw new Error("Data Form field `fields` must be an array.");return{resource_key:resourceKey,display_name:asString2(record.display_name,"display_name",{fallback:resourceKey}),description:asOptionalString(record.description,"description"),resource_kind:resourceKind,owner_type:ownerType,resource_owner_type:resourceOwnerType,resource_owner_id:asOptionalString(record.resource_owner_id,"resource_owner_id"),sharing_mode:sharingMode,consumer_app_ids:consumerAppIds,consumer_access:consumerAccess,access_policy:normalizeAccessPolicy(record.access_policy,resourceKind),fields:fieldsInput.map(field=>normalizeDataFormFieldSpec(field)),source_of_truth:DATA_FORM_SOURCE_OF_TRUTH}}function assertUniqueFieldNames(fields){let seen=new Set,reserved=new Set(DATA_FORM_SYSTEM_FIELD_NAMES);for(let field of fields){if(reserved.has(field.name))throw new Error(`Data Form field \`${field.name}\` is reserved for system columns.`);if(seen.has(field.name))throw new Error(`Data Form field \`${field.name}\` is duplicated.`);seen.add(field.name)}}function assertJsonFieldConstraints(field){let value=field.default;if(!(value===null||Array.isArray(value)||typeof value=="object"&&value!==null))throw new Error(`Data Form json field \`${field.name}\` must default to an object, array, or null.`)}function assertSharedFieldConstraints(field){let cmsField=field;if((field.type==="relation"||field.type==="relations")&&!field.relation_target?.collection)throw new Error(`Data Form relation field \`${field.name}\` must declare relation_target.collection.`);if(field.content_format!==void 0&&field.type!=="text")throw new Error(`Data Form field \`${field.name}\` can only use content_format when type is \`text\`.`);if(field.type==="relations"&&!isCmsMultiValueFieldType(field.type))throw new Error(`Data Form field \`${field.name}\` relation configuration is invalid.`);field.type==="image"||field.type==="images"||field.type==="file"||field.type}function assertTimeFieldConstraints(field){if(field.content_format!==void 0)throw new Error(`Data Form field \`${field.name}\` cannot use content_format when type is \`time\`.`)}function validateDataFormResourceSchema(input){let schema=normalizeDataFormResourceSchema(input);assertUniqueFieldNames(schema.fields);for(let field of schema.fields){if(field.type==="json"){assertJsonFieldConstraints(field);continue}if(field.type==="time"){assertTimeFieldConstraints(field);continue}assertSharedFieldConstraints(field)}if(schema.resource_kind==="end_user_owned"&&schema.owner_type!=="identity")throw new Error("Data Form resource_kind `end_user_owned` requires owner_type `identity`.");if(schema.resource_kind==="anonymous_submission"&&schema.owner_type==="identity")throw new Error("Data Form resource_kind `anonymous_submission` must not require identity ownership.");if(schema.access_policy.create==="own"&&schema.owner_type!=="identity")throw new Error("Data Form access_policy.create `own` requires owner_type `identity`.");if((schema.access_policy.read==="own"||schema.access_policy.update==="own")&&schema.owner_type!=="identity")throw new Error("Data Form access_policy with `own` scope requires owner_type `identity`.");if(schema.resource_owner_type==="tenant"&&schema.sharing_mode!=="shared")throw new Error("Data Form resource_owner_type `tenant` requires sharing_mode `shared`.");if(schema.sharing_mode==="shared"&&schema.resource_owner_type==="app"&&(schema.consumer_app_ids?.length??0)===0)throw new Error("Shared app-owned Data Form resources must declare consumer_app_ids.");if(schema.sharing_mode!=="shared"&&schema.consumer_access==="read_write")throw new Error("Data Form consumer_access `read_write` requires sharing_mode `shared`.");return schema}function byColumnName(columns){return new Map(columns.map(column=>[column.column_name,column]))}function diffDataFormTables(args){let previous=args.previous,next=args.next;if(!previous)return{source:DATA_FORM_GENERATED_SOURCE_TAG,resource_key:next.resource_key,table_name:next.table_name,operations:[{kind:"create_table",table_name:next.table_name,columns:next.columns}]};let previousColumns=byColumnName(previous.columns),operations=[];for(let column of next.columns){let existing=previousColumns.get(column.column_name);if(!existing){operations.push({kind:"add_column",table_name:next.table_name,column});continue}(existing.nullable!==column.nullable||existing.default_sql!==column.default_sql)&&operations.push({kind:"alter_column",table_name:next.table_name,column_name:column.column_name,...existing.nullable!==column.nullable?{nullable:column.nullable}:{},...existing.default_sql!==column.default_sql?{default_sql:column.default_sql}:{}})}return{source:DATA_FORM_GENERATED_SOURCE_TAG,resource_key:next.resource_key,table_name:next.table_name,operations}}function quoteJson(value){return`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function normalizeTableName(resourceKey){let normalized=resourceKey.trim().toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/^_+|_+$/g,"");return normalized.endsWith("_records")?normalized:`${normalized}_records`}function compileFieldColumn(field){switch(field.type){case"text":case"url":case"select":return{column_name:field.name,data_type:"TEXT",nullable:!field.required,default_sql:typeof field.default=="string"?`'${field.default.replace(/'/g,"''")}'`:void 0};case"number":return{column_name:field.name,data_type:"NUMERIC",nullable:!field.required,default_sql:typeof field.default=="number"?String(field.default):void 0};case"bool":return{column_name:field.name,data_type:"BOOLEAN",nullable:!field.required,default_sql:typeof field.default=="boolean"?field.default?"TRUE":"FALSE":void 0};case"date":return{column_name:field.name,data_type:field.ui?.with_time?"TIMESTAMPTZ":"DATE",nullable:!field.required};case"time":return{column_name:field.name,data_type:"TEXT",nullable:!field.required,default_sql:typeof field.default=="string"?`'${field.default.replace(/'/g,"''")}'`:void 0};case"multi_select":case"image":case"images":case"file":case"files":case"relation":case"relations":case"json":return{column_name:field.name,data_type:"JSONB",nullable:!field.required,default_sql:field.default===void 0||field.default===null?void 0:quoteJson(field.default)}}}function buildSystemColumns(){return[{column_name:"record_id",data_type:"TEXT PRIMARY KEY",nullable:!1},{column_name:"resource_key",data_type:"TEXT",nullable:!1},{column_name:"tenant_id",data_type:"TEXT",nullable:!1},{column_name:"app_id",data_type:"TEXT",nullable:!1},{column_name:"owner_identity_id",data_type:"TEXT",nullable:!0},{column_name:"owner_app_user_id",data_type:"TEXT",nullable:!0},{column_name:"source_app_id",data_type:"TEXT",nullable:!1},{column_name:"source_channel",data_type:"TEXT",nullable:!0},{column_name:"submit_context",data_type:"JSONB",nullable:!0},{column_name:"created_by_identity_id",data_type:"TEXT",nullable:!0},{column_name:"updated_by_identity_id",data_type:"TEXT",nullable:!0},{column_name:"created_at",data_type:"TIMESTAMPTZ",nullable:!1,default_sql:"NOW()"},{column_name:"updated_at",data_type:"TIMESTAMPTZ",nullable:!1,default_sql:"NOW()"}]}function buildDataFormTableModel(input){let table_name=normalizeTableName(input.resource_key);return{resource_key:input.resource_key,table_name,columns:[...buildSystemColumns(),...input.fields.map(field=>compileFieldColumn(field))]}}function compileDataFormSchema(input){let schema=validateDataFormResourceSchema(input.next),previousSchema=input.previous?validateDataFormResourceSchema(input.previous):null,table2=buildDataFormTableModel(schema),previousTable=previousSchema?buildDataFormTableModel(previousSchema):null,diff=diffDataFormTables({previous:previousTable,next:table2}),sql=renderDataFormDiffSql(diff);return{schema,table:table2,diff,sql}}import{createHash as createHash8}from"node:crypto";function buildDataFormMigrationArtifact(args){let sourceTag=args.sourceTag??DATA_FORM_GENERATED_SOURCE_TAG,compiled=compileDataFormSchema({previous:args.previous,next:args.schema}),sql=ensureSourceManifestComment(compiled.sql,args.sourceManifestPath,sourceTag);return{source:sourceTag,sql,checksum:createHash8("sha256").update(sql).digest("hex"),statements_count:countExecutableSqlStatements(sql),resource_key:`db/data-form/${args.schema.resource_key}`,source_manifest_path:args.sourceManifestPath,table_name:compiled.table.table_name}}function ensureSourceManifestComment(sql,sourceManifestPath,sourceTag){let marker=buildSourceTagComment(sourceTag),manifestComment=`-- source manifest: ${sourceManifestPath}`,normalized=sql.trimStart();return normalized.startsWith(marker)?normalized.includes(manifestComment)?sql:sql.replace(marker,`${marker}
2590
+ `,token.map=[startLine,state.line],!0}function fence(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4||pos+3>max)return!1;let marker=state.src.charCodeAt(pos);if(marker!==126&&marker!==96)return!1;let mem=pos;pos=state.skipChars(pos,marker);let len=pos-mem;if(len<3)return!1;let markup=state.src.slice(mem,pos),params=state.src.slice(pos,max);if(marker===96&&params.indexOf(String.fromCharCode(marker))>=0)return!1;if(silent)return!0;let nextLine=startLine,haveEndMarker=!1;for(;nextLine++,!(nextLine>=endLine||(pos=mem=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],pos<max&&state.sCount[nextLine]<state.blkIndent));)if(state.src.charCodeAt(pos)===marker&&!(state.sCount[nextLine]-state.blkIndent>=4)&&(pos=state.skipChars(pos,marker),!(pos-mem<len)&&(pos=state.skipSpaces(pos),!(pos<max)))){haveEndMarker=!0;break}len=state.sCount[startLine],state.line=nextLine+(haveEndMarker?1:0);let token=state.push("fence","code",0);return token.info=params,token.content=state.getLines(startLine+1,nextLine,len,!0),token.markup=markup,token.map=[startLine,state.line],!0}function blockquote(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],oldLineMax=state.lineMax;if(state.sCount[startLine]-state.blkIndent>=4||state.src.charCodeAt(pos)!==62)return!1;if(silent)return!0;let oldBMarks=[],oldBSCount=[],oldSCount=[],oldTShift=[],terminatorRules=state.md.block.ruler.getRules("blockquote"),oldParentType=state.parentType;state.parentType="blockquote";let lastLineEmpty=!1,nextLine;for(nextLine=startLine;nextLine<endLine;nextLine++){let isOutdented=state.sCount[nextLine]<state.blkIndent;if(pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],pos>=max)break;if(state.src.charCodeAt(pos++)===62&&!isOutdented){let initial=state.sCount[nextLine]+1,spaceAfterMarker,adjustTab;state.src.charCodeAt(pos)===32?(pos++,initial++,adjustTab=!1,spaceAfterMarker=!0):state.src.charCodeAt(pos)===9?(spaceAfterMarker=!0,(state.bsCount[nextLine]+initial)%4===3?(pos++,initial++,adjustTab=!1):adjustTab=!0):spaceAfterMarker=!1;let offset=initial;for(oldBMarks.push(state.bMarks[nextLine]),state.bMarks[nextLine]=pos;pos<max;){let ch=state.src.charCodeAt(pos);if(isSpace(ch))ch===9?offset+=4-(offset+state.bsCount[nextLine]+(adjustTab?1:0))%4:offset++;else break;pos++}lastLineEmpty=pos>=max,oldBSCount.push(state.bsCount[nextLine]),state.bsCount[nextLine]=state.sCount[nextLine]+1+(spaceAfterMarker?1:0),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]=offset-initial,oldTShift.push(state.tShift[nextLine]),state.tShift[nextLine]=pos-state.bMarks[nextLine];continue}if(lastLineEmpty)break;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate){state.lineMax=nextLine,state.blkIndent!==0&&(oldBMarks.push(state.bMarks[nextLine]),oldBSCount.push(state.bsCount[nextLine]),oldTShift.push(state.tShift[nextLine]),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]-=state.blkIndent);break}oldBMarks.push(state.bMarks[nextLine]),oldBSCount.push(state.bsCount[nextLine]),oldTShift.push(state.tShift[nextLine]),oldSCount.push(state.sCount[nextLine]),state.sCount[nextLine]=-1}let oldIndent=state.blkIndent;state.blkIndent=0;let token_o=state.push("blockquote_open","blockquote",1);token_o.markup=">";let lines=[startLine,0];token_o.map=lines,state.md.block.tokenize(state,startLine,nextLine);let token_c=state.push("blockquote_close","blockquote",-1);token_c.markup=">",state.lineMax=oldLineMax,state.parentType=oldParentType,lines[1]=state.line;for(let i=0;i<oldTShift.length;i++)state.bMarks[i+startLine]=oldBMarks[i],state.tShift[i+startLine]=oldTShift[i],state.sCount[i+startLine]=oldSCount[i],state.bsCount[i+startLine]=oldBSCount[i];return state.blkIndent=oldIndent,!0}function hr(state,startLine,endLine,silent){let max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4)return!1;let pos=state.bMarks[startLine]+state.tShift[startLine],marker=state.src.charCodeAt(pos++);if(marker!==42&&marker!==45&&marker!==95)return!1;let cnt=1;for(;pos<max;){let ch=state.src.charCodeAt(pos++);if(ch!==marker&&!isSpace(ch))return!1;ch===marker&&cnt++}if(cnt<3)return!1;if(silent)return!0;state.line=startLine+1;let token=state.push("hr","hr",0);return token.map=[startLine,state.line],token.markup=Array(cnt+1).join(String.fromCharCode(marker)),!0}function skipBulletListMarker(state,startLine){let max=state.eMarks[startLine],pos=state.bMarks[startLine]+state.tShift[startLine],marker=state.src.charCodeAt(pos++);if(marker!==42&&marker!==45&&marker!==43)return-1;if(pos<max){let ch=state.src.charCodeAt(pos);if(!isSpace(ch))return-1}return pos}function skipOrderedListMarker(state,startLine){let start=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],pos=start;if(pos+1>=max)return-1;let ch=state.src.charCodeAt(pos++);if(ch<48||ch>57)return-1;for(;;){if(pos>=max)return-1;if(ch=state.src.charCodeAt(pos++),ch>=48&&ch<=57){if(pos-start>=10)return-1;continue}if(ch===41||ch===46)break;return-1}return pos<max&&(ch=state.src.charCodeAt(pos),!isSpace(ch))?-1:pos}function markTightParagraphs(state,idx){let level=state.level+2;for(let i=idx+2,l=state.tokens.length-2;i<l;i++)state.tokens[i].level===level&&state.tokens[i].type==="paragraph_open"&&(state.tokens[i+2].hidden=!0,state.tokens[i].hidden=!0,i+=2)}function list(state,startLine,endLine,silent){let max,pos,start,token,nextLine=startLine,tight=!0;if(state.sCount[nextLine]-state.blkIndent>=4||state.listIndent>=0&&state.sCount[nextLine]-state.listIndent>=4&&state.sCount[nextLine]<state.blkIndent)return!1;let isTerminatingParagraph=!1;silent&&state.parentType==="paragraph"&&state.sCount[nextLine]>=state.blkIndent&&(isTerminatingParagraph=!0);let isOrdered,markerValue,posAfterMarker;if((posAfterMarker=skipOrderedListMarker(state,nextLine))>=0){if(isOrdered=!0,start=state.bMarks[nextLine]+state.tShift[nextLine],markerValue=Number(state.src.slice(start,posAfterMarker-1)),isTerminatingParagraph&&markerValue!==1)return!1}else if((posAfterMarker=skipBulletListMarker(state,nextLine))>=0)isOrdered=!1;else return!1;if(isTerminatingParagraph&&state.skipSpaces(posAfterMarker)>=state.eMarks[nextLine])return!1;if(silent)return!0;let markerCharCode=state.src.charCodeAt(posAfterMarker-1),listTokIdx=state.tokens.length;isOrdered?(token=state.push("ordered_list_open","ol",1),markerValue!==1&&(token.attrs=[["start",markerValue]])):token=state.push("bullet_list_open","ul",1);let listLines=[nextLine,0];token.map=listLines,token.markup=String.fromCharCode(markerCharCode);let prevEmptyEnd=!1,terminatorRules=state.md.block.ruler.getRules("list"),oldParentType=state.parentType;for(state.parentType="list";nextLine<endLine;){pos=posAfterMarker,max=state.eMarks[nextLine];let initial=state.sCount[nextLine]+posAfterMarker-(state.bMarks[nextLine]+state.tShift[nextLine]),offset=initial;for(;pos<max;){let ch=state.src.charCodeAt(pos);if(ch===9)offset+=4-(offset+state.bsCount[nextLine])%4;else if(ch===32)offset++;else break;pos++}let contentStart=pos,indentAfterMarker;contentStart>=max?indentAfterMarker=1:indentAfterMarker=offset-initial,indentAfterMarker>4&&(indentAfterMarker=1);let indent=initial+indentAfterMarker;token=state.push("list_item_open","li",1),token.markup=String.fromCharCode(markerCharCode);let itemLines=[nextLine,0];token.map=itemLines,isOrdered&&(token.info=state.src.slice(start,posAfterMarker-1));let oldTight=state.tight,oldTShift=state.tShift[nextLine],oldSCount=state.sCount[nextLine],oldListIndent=state.listIndent;if(state.listIndent=state.blkIndent,state.blkIndent=indent,state.tight=!0,state.tShift[nextLine]=contentStart-state.bMarks[nextLine],state.sCount[nextLine]=offset,contentStart>=max&&state.isEmpty(nextLine+1)?state.line=Math.min(state.line+2,endLine):state.md.block.tokenize(state,nextLine,endLine,!0),(!state.tight||prevEmptyEnd)&&(tight=!1),prevEmptyEnd=state.line-nextLine>1&&state.isEmpty(state.line-1),state.blkIndent=state.listIndent,state.listIndent=oldListIndent,state.tShift[nextLine]=oldTShift,state.sCount[nextLine]=oldSCount,state.tight=oldTight,token=state.push("list_item_close","li",-1),token.markup=String.fromCharCode(markerCharCode),nextLine=state.line,itemLines[1]=nextLine,nextLine>=endLine||state.sCount[nextLine]<state.blkIndent||state.sCount[nextLine]-state.blkIndent>=4)break;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break;if(isOrdered){if(posAfterMarker=skipOrderedListMarker(state,nextLine),posAfterMarker<0)break;start=state.bMarks[nextLine]+state.tShift[nextLine]}else if(posAfterMarker=skipBulletListMarker(state,nextLine),posAfterMarker<0)break;if(markerCharCode!==state.src.charCodeAt(posAfterMarker-1))break}return isOrdered?token=state.push("ordered_list_close","ol",-1):token=state.push("bullet_list_close","ul",-1),token.markup=String.fromCharCode(markerCharCode),listLines[1]=nextLine,state.line=nextLine,state.parentType=oldParentType,tight&&markTightParagraphs(state,listTokIdx),!0}function reference(state,startLine,_endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine],nextLine=startLine+1;if(state.sCount[startLine]-state.blkIndent>=4||state.src.charCodeAt(pos)!==91)return!1;function getNextLine(nextLine2){let endLine=state.lineMax;if(nextLine2>=endLine||state.isEmpty(nextLine2))return null;let isContinuation=!1;if(state.sCount[nextLine2]-state.blkIndent>3&&(isContinuation=!0),state.sCount[nextLine2]<0&&(isContinuation=!0),!isContinuation){let terminatorRules=state.md.block.ruler.getRules("reference"),oldParentType=state.parentType;state.parentType="reference";let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine2,endLine,!0)){terminate=!0;break}if(state.parentType=oldParentType,terminate)return null}let pos2=state.bMarks[nextLine2]+state.tShift[nextLine2],max2=state.eMarks[nextLine2];return state.src.slice(pos2,max2+1)}let str=state.src.slice(pos,max+1);max=str.length;let labelEnd=-1;for(pos=1;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===91)return!1;if(ch===93){labelEnd=pos;break}else if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(ch===92&&(pos++,pos<max&&str.charCodeAt(pos)===10)){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}}if(labelEnd<0||str.charCodeAt(labelEnd+1)!==58)return!1;for(pos=labelEnd+2;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(!isSpace(ch))break}let destRes=state.md.helpers.parseLinkDestination(str,pos,max);if(!destRes.ok)return!1;let href=state.md.normalizeLink(destRes.str);if(!state.md.validateLink(href))return!1;pos=destRes.pos;let destEndPos=pos,destEndLineNo=nextLine,start=pos;for(;pos<max;pos++){let ch=str.charCodeAt(pos);if(ch===10){let lineContent=getNextLine(nextLine);lineContent!==null&&(str+=lineContent,max=str.length,nextLine++)}else if(!isSpace(ch))break}let titleRes=state.md.helpers.parseLinkTitle(str,pos,max);for(;titleRes.can_continue;){let lineContent=getNextLine(nextLine);if(lineContent===null)break;str+=lineContent,pos=max,max=str.length,nextLine++,titleRes=state.md.helpers.parseLinkTitle(str,pos,max,titleRes)}let title;for(pos<max&&start!==pos&&titleRes.ok?(title=titleRes.str,pos=titleRes.pos):(title="",pos=destEndPos,nextLine=destEndLineNo);pos<max;){let ch=str.charCodeAt(pos);if(!isSpace(ch))break;pos++}if(pos<max&&str.charCodeAt(pos)!==10&&title)for(title="",pos=destEndPos,nextLine=destEndLineNo;pos<max;){let ch=str.charCodeAt(pos);if(!isSpace(ch))break;pos++}if(pos<max&&str.charCodeAt(pos)!==10)return!1;let label=normalizeReference(str.slice(1,labelEnd));return label?(silent||(typeof state.env.references>"u"&&(state.env.references={}),typeof state.env.references[label]>"u"&&(state.env.references[label]={title,href}),state.line=nextLine),!0):!1}var html_blocks_default=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"];var attr_name="[a-zA-Z_:][a-zA-Z0-9:._-]*",unquoted="[^\"'=<>`\\x00-\\x20]+",single_quoted="'[^']*'",double_quoted='"[^"]*"',attr_value="(?:"+unquoted+"|"+single_quoted+"|"+double_quoted+")",attribute="(?:\\s+"+attr_name+"(?:\\s*=\\s*"+attr_value+")?)",open_tag="<[A-Za-z][A-Za-z0-9\\-]*"+attribute+"*\\s*\\/?>",close_tag="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",comment="<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->",processing="<[?][\\s\\S]*?[?]>",declaration="<![A-Za-z][^>]*>",cdata="<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",HTML_TAG_RE=new RegExp("^(?:"+open_tag+"|"+close_tag+"|"+comment+"|"+processing+"|"+declaration+"|"+cdata+")"),HTML_OPEN_CLOSE_TAG_RE=new RegExp("^(?:"+open_tag+"|"+close_tag+")");var HTML_SEQUENCES=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^<!--/,/-->/,!0],[/^<\?/,/\?>/,!0],[/^<![A-Z]/,/>/,!0],[/^<!\[CDATA\[/,/\]\]>/,!0],[new RegExp("^</?("+html_blocks_default.join("|")+")(?=(\\s|/?>|$))","i"),/^$/,!0],[new RegExp(HTML_OPEN_CLOSE_TAG_RE.source+"\\s*$"),/^$/,!1]];function html_block(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4||!state.md.options.html||state.src.charCodeAt(pos)!==60)return!1;let lineText=state.src.slice(pos,max),i=0;for(;i<HTML_SEQUENCES.length&&!HTML_SEQUENCES[i][0].test(lineText);i++);if(i===HTML_SEQUENCES.length)return!1;if(silent)return HTML_SEQUENCES[i][2];let nextLine=startLine+1;if(!HTML_SEQUENCES[i][1].test(lineText)){for(;nextLine<endLine&&!(state.sCount[nextLine]<state.blkIndent);nextLine++)if(pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine],lineText=state.src.slice(pos,max),HTML_SEQUENCES[i][1].test(lineText)){lineText.length!==0&&nextLine++;break}}state.line=nextLine;let token=state.push("html_block","",0);return token.map=[startLine,nextLine],token.content=state.getLines(startLine,nextLine,state.blkIndent,!0),!0}function heading(state,startLine,endLine,silent){let pos=state.bMarks[startLine]+state.tShift[startLine],max=state.eMarks[startLine];if(state.sCount[startLine]-state.blkIndent>=4)return!1;let ch=state.src.charCodeAt(pos);if(ch!==35||pos>=max)return!1;let level=1;for(ch=state.src.charCodeAt(++pos);ch===35&&pos<max&&level<=6;)level++,ch=state.src.charCodeAt(++pos);if(level>6||pos<max&&!isSpace(ch))return!1;if(silent)return!0;max=state.skipSpacesBack(max,pos);let tmp=state.skipCharsBack(max,35,pos);tmp>pos&&isSpace(state.src.charCodeAt(tmp-1))&&(max=tmp),state.line=startLine+1;let token_o=state.push("heading_open","h"+String(level),1);token_o.markup="########".slice(0,level),token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);token_i.content=state.src.slice(pos,max).trim(),token_i.map=[startLine,state.line],token_i.children=[];let token_c=state.push("heading_close","h"+String(level),-1);return token_c.markup="########".slice(0,level),!0}function lheading(state,startLine,endLine){let terminatorRules=state.md.block.ruler.getRules("paragraph");if(state.sCount[startLine]-state.blkIndent>=4)return!1;let oldParentType=state.parentType;state.parentType="paragraph";let level=0,marker,nextLine=startLine+1;for(;nextLine<endLine&&!state.isEmpty(nextLine);nextLine++){if(state.sCount[nextLine]-state.blkIndent>3)continue;if(state.sCount[nextLine]>=state.blkIndent){let pos=state.bMarks[nextLine]+state.tShift[nextLine],max=state.eMarks[nextLine];if(pos<max&&(marker=state.src.charCodeAt(pos),(marker===45||marker===61)&&(pos=state.skipChars(pos,marker),pos=state.skipSpaces(pos),pos>=max))){level=marker===61?1:2;break}}if(state.sCount[nextLine]<0)continue;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break}if(!level)return!1;let content=state.getLines(startLine,nextLine,state.blkIndent,!1).trim();state.line=nextLine+1;let token_o=state.push("heading_open","h"+String(level),1);token_o.markup=String.fromCharCode(marker),token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);token_i.content=content,token_i.map=[startLine,state.line-1],token_i.children=[];let token_c=state.push("heading_close","h"+String(level),-1);return token_c.markup=String.fromCharCode(marker),state.parentType=oldParentType,!0}function paragraph(state,startLine,endLine){let terminatorRules=state.md.block.ruler.getRules("paragraph"),oldParentType=state.parentType,nextLine=startLine+1;for(state.parentType="paragraph";nextLine<endLine&&!state.isEmpty(nextLine);nextLine++){if(state.sCount[nextLine]-state.blkIndent>3||state.sCount[nextLine]<0)continue;let terminate=!1;for(let i=0,l=terminatorRules.length;i<l;i++)if(terminatorRules[i](state,nextLine,endLine,!0)){terminate=!0;break}if(terminate)break}let content=state.getLines(startLine,nextLine,state.blkIndent,!1).trim();state.line=nextLine;let token_o=state.push("paragraph_open","p",1);token_o.map=[startLine,state.line];let token_i=state.push("inline","",0);return token_i.content=content,token_i.map=[startLine,state.line],token_i.children=[],state.push("paragraph_close","p",-1),state.parentType=oldParentType,!0}var _rules2=[["table",table,["paragraph","reference"]],["code",code],["fence",fence,["paragraph","reference","blockquote","list"]],["blockquote",blockquote,["paragraph","reference","blockquote","list"]],["hr",hr,["paragraph","reference","blockquote","list"]],["list",list,["paragraph","reference","blockquote"]],["reference",reference],["html_block",html_block,["paragraph","reference","blockquote"]],["heading",heading,["paragraph","reference","blockquote"]],["lheading",lheading],["paragraph",paragraph]];function ParserBlock(){this.ruler=new ruler_default;for(let i=0;i<_rules2.length;i++)this.ruler.push(_rules2[i][0],_rules2[i][1],{alt:(_rules2[i][2]||[]).slice()})}ParserBlock.prototype.tokenize=function(state,startLine,endLine){let rules=this.ruler.getRules(""),len=rules.length,maxNesting=state.md.options.maxNesting,line=startLine,hasEmptyLines=!1;for(;line<endLine&&(state.line=line=state.skipEmptyLines(line),!(line>=endLine||state.sCount[line]<state.blkIndent));){if(state.level>=maxNesting){state.line=endLine;break}let prevLine=state.line,ok=!1;for(let i=0;i<len;i++)if(ok=rules[i](state,line,endLine,!1),ok){if(prevLine>=state.line)throw new Error("block rule didn't increment state.line");break}if(!ok)throw new Error("none of the block rules matched");state.tight=!hasEmptyLines,state.isEmpty(state.line-1)&&(hasEmptyLines=!0),line=state.line,line<endLine&&state.isEmpty(line)&&(hasEmptyLines=!0,line++,state.line=line)}};ParserBlock.prototype.parse=function(src,md,env,outTokens){if(!src)return;let state=new this.State(src,md,env,outTokens);this.tokenize(state,state.line,state.lineMax)};ParserBlock.prototype.State=state_block_default;var parser_block_default=ParserBlock;function StateInline(src,md,env,outTokens){this.src=src,this.env=env,this.md=md,this.tokens=outTokens,this.tokens_meta=Array(outTokens.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0}StateInline.prototype.pushPending=function(){let token=new token_default("text","",0);return token.content=this.pending,token.level=this.pendingLevel,this.tokens.push(token),this.pending="",token};StateInline.prototype.push=function(type,tag,nesting){this.pending&&this.pushPending();let token=new token_default(type,tag,nesting),token_meta=null;return nesting<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),token.level=this.level,nesting>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],token_meta={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(token),this.tokens_meta.push(token_meta),token};StateInline.prototype.scanDelims=function(start,canSplitWord){let max=this.posMax,marker=this.src.charCodeAt(start),lastChar=start>0?this.src.charCodeAt(start-1):32,pos=start;for(;pos<max&&this.src.charCodeAt(pos)===marker;)pos++;let count=pos-start,nextChar=pos<max?this.src.charCodeAt(pos):32,isLastPunctChar=isMdAsciiPunct(lastChar)||isPunctChar(String.fromCharCode(lastChar)),isNextPunctChar=isMdAsciiPunct(nextChar)||isPunctChar(String.fromCharCode(nextChar)),isLastWhiteSpace=isWhiteSpace(lastChar),isNextWhiteSpace=isWhiteSpace(nextChar),left_flanking=!isNextWhiteSpace&&(!isNextPunctChar||isLastWhiteSpace||isLastPunctChar),right_flanking=!isLastWhiteSpace&&(!isLastPunctChar||isNextWhiteSpace||isNextPunctChar);return{can_open:left_flanking&&(canSplitWord||!right_flanking||isLastPunctChar),can_close:right_flanking&&(canSplitWord||!left_flanking||isNextPunctChar),length:count}};StateInline.prototype.Token=token_default;var state_inline_default=StateInline;function isTerminatorChar(ch){switch(ch){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}function text(state,silent){let pos=state.pos;for(;pos<state.posMax&&!isTerminatorChar(state.src.charCodeAt(pos));)pos++;return pos===state.pos?!1:(silent||(state.pending+=state.src.slice(state.pos,pos)),state.pos=pos,!0)}var SCHEME_RE=/(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i;function linkify2(state,silent){if(!state.md.options.linkify||state.linkLevel>0)return!1;let pos=state.pos,max=state.posMax;if(pos+3>max||state.src.charCodeAt(pos)!==58||state.src.charCodeAt(pos+1)!==47||state.src.charCodeAt(pos+2)!==47)return!1;let match2=state.pending.match(SCHEME_RE);if(!match2)return!1;let proto=match2[1],link2=state.md.linkify.matchAtStart(state.src.slice(pos-proto.length));if(!link2)return!1;let url=link2.url;if(url.length<=proto.length)return!1;let urlEnd=url.length;for(;urlEnd>0&&url.charCodeAt(urlEnd-1)===42;)urlEnd--;urlEnd!==url.length&&(url=url.slice(0,urlEnd));let fullUrl=state.md.normalizeLink(url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){state.pending=state.pending.slice(0,-proto.length);let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="linkify",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="linkify",token_c.info="auto"}return state.pos+=url.length-proto.length,!0}function newline(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==10)return!1;let pmax=state.pending.length-1,max=state.posMax;if(!silent)if(pmax>=0&&state.pending.charCodeAt(pmax)===32)if(pmax>=1&&state.pending.charCodeAt(pmax-1)===32){let ws=pmax-1;for(;ws>=1&&state.pending.charCodeAt(ws-1)===32;)ws--;state.pending=state.pending.slice(0,ws),state.push("hardbreak","br",0)}else state.pending=state.pending.slice(0,-1),state.push("softbreak","br",0);else state.push("softbreak","br",0);for(pos++;pos<max&&isSpace(state.src.charCodeAt(pos));)pos++;return state.pos=pos,!0}var ESCAPED=[];for(let i=0;i<256;i++)ESCAPED.push(0);"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(ch){ESCAPED[ch.charCodeAt(0)]=1});function escape2(state,silent){let pos=state.pos,max=state.posMax;if(state.src.charCodeAt(pos)!==92||(pos++,pos>=max))return!1;let ch1=state.src.charCodeAt(pos);if(ch1===10){for(silent||state.push("hardbreak","br",0),pos++;pos<max&&(ch1=state.src.charCodeAt(pos),!!isSpace(ch1));)pos++;return state.pos=pos,!0}let escapedStr=state.src[pos];if(ch1>=55296&&ch1<=56319&&pos+1<max){let ch2=state.src.charCodeAt(pos+1);ch2>=56320&&ch2<=57343&&(escapedStr+=state.src[pos+1],pos++)}let origStr="\\"+escapedStr;if(!silent){let token=state.push("text_special","",0);ch1<256&&ESCAPED[ch1]!==0?token.content=escapedStr:token.content=origStr,token.markup=origStr,token.info="escape"}return state.pos=pos+1,!0}function backtick(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==96)return!1;let start=pos;pos++;let max=state.posMax;for(;pos<max&&state.src.charCodeAt(pos)===96;)pos++;let marker=state.src.slice(start,pos),openerLength=marker.length;if(state.backticksScanned&&(state.backticks[openerLength]||0)<=start)return silent||(state.pending+=marker),state.pos+=openerLength,!0;let matchEnd=pos,matchStart;for(;(matchStart=state.src.indexOf("`",matchEnd))!==-1;){for(matchEnd=matchStart+1;matchEnd<max&&state.src.charCodeAt(matchEnd)===96;)matchEnd++;let closerLength=matchEnd-matchStart;if(closerLength===openerLength){if(!silent){let token=state.push("code_inline","code",0);token.markup=marker,token.content=state.src.slice(pos,matchStart).replace(/\n/g," ").replace(/^ (.+) $/,"$1")}return state.pos=matchEnd,!0}state.backticks[closerLength]=matchStart}return state.backticksScanned=!0,silent||(state.pending+=marker),state.pos+=openerLength,!0}function strikethrough_tokenize(state,silent){let start=state.pos,marker=state.src.charCodeAt(start);if(silent||marker!==126)return!1;let scanned=state.scanDelims(state.pos,!0),len=scanned.length,ch=String.fromCharCode(marker);if(len<2)return!1;let token;len%2&&(token=state.push("text","",0),token.content=ch,len--);for(let i=0;i<len;i+=2)token=state.push("text","",0),token.content=ch+ch,state.delimiters.push({marker,length:0,token:state.tokens.length-1,end:-1,open:scanned.can_open,close:scanned.can_close});return state.pos+=scanned.length,!0}function postProcess(state,delimiters){let token,loneMarkers=[],max=delimiters.length;for(let i=0;i<max;i++){let startDelim=delimiters[i];if(startDelim.marker!==126||startDelim.end===-1)continue;let endDelim=delimiters[startDelim.end];token=state.tokens[startDelim.token],token.type="s_open",token.tag="s",token.nesting=1,token.markup="~~",token.content="",token=state.tokens[endDelim.token],token.type="s_close",token.tag="s",token.nesting=-1,token.markup="~~",token.content="",state.tokens[endDelim.token-1].type==="text"&&state.tokens[endDelim.token-1].content==="~"&&loneMarkers.push(endDelim.token-1)}for(;loneMarkers.length;){let i=loneMarkers.pop(),j=i+1;for(;j<state.tokens.length&&state.tokens[j].type==="s_close";)j++;j--,i!==j&&(token=state.tokens[j],state.tokens[j]=state.tokens[i],state.tokens[i]=token)}}function strikethrough_postProcess(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;postProcess(state,state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&postProcess(state,tokens_meta[curr].delimiters)}var strikethrough_default={tokenize:strikethrough_tokenize,postProcess:strikethrough_postProcess};function emphasis_tokenize(state,silent){let start=state.pos,marker=state.src.charCodeAt(start);if(silent||marker!==95&&marker!==42)return!1;let scanned=state.scanDelims(state.pos,marker===42);for(let i=0;i<scanned.length;i++){let token=state.push("text","",0);token.content=String.fromCharCode(marker),state.delimiters.push({marker,length:scanned.length,token:state.tokens.length-1,end:-1,open:scanned.can_open,close:scanned.can_close})}return state.pos+=scanned.length,!0}function postProcess2(state,delimiters){let max=delimiters.length;for(let i=max-1;i>=0;i--){let startDelim=delimiters[i];if(startDelim.marker!==95&&startDelim.marker!==42||startDelim.end===-1)continue;let endDelim=delimiters[startDelim.end],isStrong=i>0&&delimiters[i-1].end===startDelim.end+1&&delimiters[i-1].marker===startDelim.marker&&delimiters[i-1].token===startDelim.token-1&&delimiters[startDelim.end+1].token===endDelim.token+1,ch=String.fromCharCode(startDelim.marker),token_o=state.tokens[startDelim.token];token_o.type=isStrong?"strong_open":"em_open",token_o.tag=isStrong?"strong":"em",token_o.nesting=1,token_o.markup=isStrong?ch+ch:ch,token_o.content="";let token_c=state.tokens[endDelim.token];token_c.type=isStrong?"strong_close":"em_close",token_c.tag=isStrong?"strong":"em",token_c.nesting=-1,token_c.markup=isStrong?ch+ch:ch,token_c.content="",isStrong&&(state.tokens[delimiters[i-1].token].content="",state.tokens[delimiters[startDelim.end+1].token].content="",i--)}}function emphasis_post_process(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;postProcess2(state,state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&postProcess2(state,tokens_meta[curr].delimiters)}var emphasis_default={tokenize:emphasis_tokenize,postProcess:emphasis_post_process};function link(state,silent){let code2,label,res,ref,href="",title="",start=state.pos,parseReference=!0;if(state.src.charCodeAt(state.pos)!==91)return!1;let oldPos=state.pos,max=state.posMax,labelStart=state.pos+1,labelEnd=state.md.helpers.parseLinkLabel(state,state.pos,!0);if(labelEnd<0)return!1;let pos=labelEnd+1;if(pos<max&&state.src.charCodeAt(pos)===40){for(parseReference=!1,pos++;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(pos>=max)return!1;if(start=pos,res=state.md.helpers.parseLinkDestination(state.src,pos,state.posMax),res.ok){for(href=state.md.normalizeLink(res.str),state.md.validateLink(href)?pos=res.pos:href="",start=pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(res=state.md.helpers.parseLinkTitle(state.src,pos,state.posMax),pos<max&&start!==pos&&res.ok)for(title=res.str,pos=res.pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);}(pos>=max||state.src.charCodeAt(pos)!==41)&&(parseReference=!0),pos++}if(parseReference){if(typeof state.env.references>"u")return!1;if(pos<max&&state.src.charCodeAt(pos)===91?(start=pos+1,pos=state.md.helpers.parseLinkLabel(state,pos),pos>=0?label=state.src.slice(start,pos++):pos=labelEnd+1):pos=labelEnd+1,label||(label=state.src.slice(labelStart,labelEnd)),ref=state.env.references[normalizeReference(label)],!ref)return state.pos=oldPos,!1;href=ref.href,title=ref.title}if(!silent){state.pos=labelStart,state.posMax=labelEnd;let token_o=state.push("link_open","a",1),attrs=[["href",href]];token_o.attrs=attrs,title&&attrs.push(["title",title]),state.linkLevel++,state.md.inline.tokenize(state),state.linkLevel--,state.push("link_close","a",-1)}return state.pos=pos,state.posMax=max,!0}function image(state,silent){let code2,content,label,pos,ref,res,title,start,href="",oldPos=state.pos,max=state.posMax;if(state.src.charCodeAt(state.pos)!==33||state.src.charCodeAt(state.pos+1)!==91)return!1;let labelStart=state.pos+2,labelEnd=state.md.helpers.parseLinkLabel(state,state.pos+1,!1);if(labelEnd<0)return!1;if(pos=labelEnd+1,pos<max&&state.src.charCodeAt(pos)===40){for(pos++;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(pos>=max)return!1;for(start=pos,res=state.md.helpers.parseLinkDestination(state.src,pos,state.posMax),res.ok&&(href=state.md.normalizeLink(res.str),state.md.validateLink(href)?pos=res.pos:href=""),start=pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);if(res=state.md.helpers.parseLinkTitle(state.src,pos,state.posMax),pos<max&&start!==pos&&res.ok)for(title=res.str,pos=res.pos;pos<max&&(code2=state.src.charCodeAt(pos),!(!isSpace(code2)&&code2!==10));pos++);else title="";if(pos>=max||state.src.charCodeAt(pos)!==41)return state.pos=oldPos,!1;pos++}else{if(typeof state.env.references>"u")return!1;if(pos<max&&state.src.charCodeAt(pos)===91?(start=pos+1,pos=state.md.helpers.parseLinkLabel(state,pos),pos>=0?label=state.src.slice(start,pos++):pos=labelEnd+1):pos=labelEnd+1,label||(label=state.src.slice(labelStart,labelEnd)),ref=state.env.references[normalizeReference(label)],!ref)return state.pos=oldPos,!1;href=ref.href,title=ref.title}if(!silent){content=state.src.slice(labelStart,labelEnd);let tokens=[];state.md.inline.parse(content,state.md,state.env,tokens);let token=state.push("image","img",0),attrs=[["src",href],["alt",""]];token.attrs=attrs,token.children=tokens,token.content=content,title&&attrs.push(["title",title])}return state.pos=pos,state.posMax=max,!0}var EMAIL_RE=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,AUTOLINK_RE=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function autolink(state,silent){let pos=state.pos;if(state.src.charCodeAt(pos)!==60)return!1;let start=state.pos,max=state.posMax;for(;;){if(++pos>=max)return!1;let ch=state.src.charCodeAt(pos);if(ch===60)return!1;if(ch===62)break}let url=state.src.slice(start+1,pos);if(AUTOLINK_RE.test(url)){let fullUrl=state.md.normalizeLink(url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="autolink",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="autolink",token_c.info="auto"}return state.pos+=url.length+2,!0}if(EMAIL_RE.test(url)){let fullUrl=state.md.normalizeLink("mailto:"+url);if(!state.md.validateLink(fullUrl))return!1;if(!silent){let token_o=state.push("link_open","a",1);token_o.attrs=[["href",fullUrl]],token_o.markup="autolink",token_o.info="auto";let token_t=state.push("text","",0);token_t.content=state.md.normalizeLinkText(url);let token_c=state.push("link_close","a",-1);token_c.markup="autolink",token_c.info="auto"}return state.pos+=url.length+2,!0}return!1}function isLinkOpen2(str){return/^<a[>\s]/i.test(str)}function isLinkClose2(str){return/^<\/a\s*>/i.test(str)}function isLetter(ch){let lc=ch|32;return lc>=97&&lc<=122}function html_inline(state,silent){if(!state.md.options.html)return!1;let max=state.posMax,pos=state.pos;if(state.src.charCodeAt(pos)!==60||pos+2>=max)return!1;let ch=state.src.charCodeAt(pos+1);if(ch!==33&&ch!==63&&ch!==47&&!isLetter(ch))return!1;let match2=state.src.slice(pos).match(HTML_TAG_RE);if(!match2)return!1;if(!silent){let token=state.push("html_inline","",0);token.content=match2[0],isLinkOpen2(token.content)&&state.linkLevel++,isLinkClose2(token.content)&&state.linkLevel--}return state.pos+=match2[0].length,!0}var DIGITAL_RE=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,NAMED_RE=/^&([a-z][a-z0-9]{1,31});/i;function entity(state,silent){let pos=state.pos,max=state.posMax;if(state.src.charCodeAt(pos)!==38||pos+1>=max)return!1;if(state.src.charCodeAt(pos+1)===35){let match2=state.src.slice(pos).match(DIGITAL_RE);if(match2){if(!silent){let code2=match2[1][0].toLowerCase()==="x"?parseInt(match2[1].slice(1),16):parseInt(match2[1],10),token=state.push("text_special","",0);token.content=isValidEntityCode(code2)?fromCodePoint2(code2):fromCodePoint2(65533),token.markup=match2[0],token.info="entity"}return state.pos+=match2[0].length,!0}}else{let match2=state.src.slice(pos).match(NAMED_RE);if(match2){let decoded=decodeHTML(match2[0]);if(decoded!==match2[0]){if(!silent){let token=state.push("text_special","",0);token.content=decoded,token.markup=match2[0],token.info="entity"}return state.pos+=match2[0].length,!0}}}return!1}function processDelimiters(delimiters){let openersBottom={},max=delimiters.length;if(!max)return;let headerIdx=0,lastTokenIdx=-2,jumps=[];for(let closerIdx=0;closerIdx<max;closerIdx++){let closer=delimiters[closerIdx];if(jumps.push(0),(delimiters[headerIdx].marker!==closer.marker||lastTokenIdx!==closer.token-1)&&(headerIdx=closerIdx),lastTokenIdx=closer.token,closer.length=closer.length||0,!closer.close)continue;openersBottom.hasOwnProperty(closer.marker)||(openersBottom[closer.marker]=[-1,-1,-1,-1,-1,-1]);let minOpenerIdx=openersBottom[closer.marker][(closer.open?3:0)+closer.length%3],openerIdx=headerIdx-jumps[headerIdx]-1,newMinOpenerIdx=openerIdx;for(;openerIdx>minOpenerIdx;openerIdx-=jumps[openerIdx]+1){let opener=delimiters[openerIdx];if(opener.marker===closer.marker&&opener.open&&opener.end<0){let isOddMatch=!1;if((opener.close||closer.open)&&(opener.length+closer.length)%3===0&&(opener.length%3!==0||closer.length%3!==0)&&(isOddMatch=!0),!isOddMatch){let lastJump=openerIdx>0&&!delimiters[openerIdx-1].open?jumps[openerIdx-1]+1:0;jumps[closerIdx]=closerIdx-openerIdx+lastJump,jumps[openerIdx]=lastJump,closer.open=!1,opener.end=closerIdx,opener.close=!1,newMinOpenerIdx=-1,lastTokenIdx=-2;break}}}newMinOpenerIdx!==-1&&(openersBottom[closer.marker][(closer.open?3:0)+(closer.length||0)%3]=newMinOpenerIdx)}}function link_pairs(state){let tokens_meta=state.tokens_meta,max=state.tokens_meta.length;processDelimiters(state.delimiters);for(let curr=0;curr<max;curr++)tokens_meta[curr]&&tokens_meta[curr].delimiters&&processDelimiters(tokens_meta[curr].delimiters)}function fragments_join(state){let curr,last,level=0,tokens=state.tokens,max=state.tokens.length;for(curr=last=0;curr<max;curr++)tokens[curr].nesting<0&&level--,tokens[curr].level=level,tokens[curr].nesting>0&&level++,tokens[curr].type==="text"&&curr+1<max&&tokens[curr+1].type==="text"?tokens[curr+1].content=tokens[curr].content+tokens[curr+1].content:(curr!==last&&(tokens[last]=tokens[curr]),last++);curr!==last&&(tokens.length=last)}var _rules3=[["text",text],["linkify",linkify2],["newline",newline],["escape",escape2],["backticks",backtick],["strikethrough",strikethrough_default.tokenize],["emphasis",emphasis_default.tokenize],["link",link],["image",image],["autolink",autolink],["html_inline",html_inline],["entity",entity]],_rules22=[["balance_pairs",link_pairs],["strikethrough",strikethrough_default.postProcess],["emphasis",emphasis_default.postProcess],["fragments_join",fragments_join]];function ParserInline(){this.ruler=new ruler_default;for(let i=0;i<_rules3.length;i++)this.ruler.push(_rules3[i][0],_rules3[i][1]);this.ruler2=new ruler_default;for(let i=0;i<_rules22.length;i++)this.ruler2.push(_rules22[i][0],_rules22[i][1])}ParserInline.prototype.skipToken=function(state){let pos=state.pos,rules=this.ruler.getRules(""),len=rules.length,maxNesting=state.md.options.maxNesting,cache=state.cache;if(typeof cache[pos]<"u"){state.pos=cache[pos];return}let ok=!1;if(state.level<maxNesting){for(let i=0;i<len;i++)if(state.level++,ok=rules[i](state,!0),state.level--,ok){if(pos>=state.pos)throw new Error("inline rule didn't increment state.pos");break}}else state.pos=state.posMax;ok||state.pos++,cache[pos]=state.pos};ParserInline.prototype.tokenize=function(state){let rules=this.ruler.getRules(""),len=rules.length,end=state.posMax,maxNesting=state.md.options.maxNesting;for(;state.pos<end;){let prevPos=state.pos,ok=!1;if(state.level<maxNesting){for(let i=0;i<len;i++)if(ok=rules[i](state,!1),ok){if(prevPos>=state.pos)throw new Error("inline rule didn't increment state.pos");break}}if(ok){if(state.pos>=end)break;continue}state.pending+=state.src[state.pos++]}state.pending&&state.pushPending()};ParserInline.prototype.parse=function(str,md,env,outTokens){let state=new this.State(str,md,env,outTokens);this.tokenize(state);let rules=this.ruler2.getRules(""),len=rules.length;for(let i=0;i<len;i++)rules[i](state)};ParserInline.prototype.State=state_inline_default;var parser_inline_default=ParserInline;function re_default(opts){let re={};opts=opts||{},re.src_Any=regex_default.source,re.src_Cc=regex_default2.source,re.src_Z=regex_default6.source,re.src_P=regex_default4.source,re.src_ZPCc=[re.src_Z,re.src_P,re.src_Cc].join("|"),re.src_ZCc=[re.src_Z,re.src_Cc].join("|");let text_separators="[><\uFF5C]";return re.src_pseudo_letter="(?:(?!"+text_separators+"|"+re.src_ZPCc+")"+re.src_Any+")",re.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",re.src_auth="(?:(?:(?!"+re.src_ZCc+"|[@/\\[\\]()]).)+@)?",re.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",re.src_host_terminator="(?=$|"+text_separators+"|"+re.src_ZPCc+")(?!"+(opts["---"]?"-(?!--)|":"-|")+"_|:\\d|\\.-|\\.(?!$|"+re.src_ZPCc+"))",re.src_path="(?:[/?#](?:(?!"+re.src_ZCc+"|"+text_separators+`|[()[\\]{}.,"'?!\\-;]).|\\[(?:(?!`+re.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+re.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+re.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+re.src_ZCc+`|["]).)+\\"|\\'(?:(?!`+re.src_ZCc+"|[']).)+\\'|\\'(?="+re.src_pseudo_letter+"|[-])|\\.{2,}[a-zA-Z0-9%/&]|\\.(?!"+re.src_ZCc+"|[.]|$)|"+(opts["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+",(?!"+re.src_ZCc+"|$)|;(?!"+re.src_ZCc+"|$)|\\!+(?!"+re.src_ZCc+"|[!]|$)|\\?(?!"+re.src_ZCc+"|[?]|$))+|\\/)?",re.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*',re.src_xn="xn--[a-z0-9\\-]{1,59}",re.src_domain_root="(?:"+re.src_xn+"|"+re.src_pseudo_letter+"{1,63})",re.src_domain="(?:"+re.src_xn+"|(?:"+re.src_pseudo_letter+")|(?:"+re.src_pseudo_letter+"(?:-|"+re.src_pseudo_letter+"){0,61}"+re.src_pseudo_letter+"))",re.src_host="(?:(?:(?:(?:"+re.src_domain+")\\.)*"+re.src_domain+"))",re.tpl_host_fuzzy="(?:"+re.src_ip4+"|(?:(?:(?:"+re.src_domain+")\\.)+(?:%TLDS%)))",re.tpl_host_no_ip_fuzzy="(?:(?:(?:"+re.src_domain+")\\.)+(?:%TLDS%))",re.src_host_strict=re.src_host+re.src_host_terminator,re.tpl_host_fuzzy_strict=re.tpl_host_fuzzy+re.src_host_terminator,re.src_host_port_strict=re.src_host+re.src_port+re.src_host_terminator,re.tpl_host_port_fuzzy_strict=re.tpl_host_fuzzy+re.src_port+re.src_host_terminator,re.tpl_host_port_no_ip_fuzzy_strict=re.tpl_host_no_ip_fuzzy+re.src_port+re.src_host_terminator,re.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+re.src_ZPCc+"|>|$))",re.tpl_email_fuzzy="(^|"+text_separators+'|"|\\(|'+re.src_ZCc+")("+re.src_email_name+"@"+re.tpl_host_fuzzy_strict+")",re.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+re.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+re.tpl_host_port_fuzzy_strict+re.src_path+")",re.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uFF5C]|"+re.src_ZPCc+"))((?![$+<=>^`|\uFF5C])"+re.tpl_host_port_no_ip_fuzzy_strict+re.src_path+")",re}function assign2(obj){return Array.prototype.slice.call(arguments,1).forEach(function(source){source&&Object.keys(source).forEach(function(key){obj[key]=source[key]})}),obj}function _class2(obj){return Object.prototype.toString.call(obj)}function isString2(obj){return _class2(obj)==="[object String]"}function isObject(obj){return _class2(obj)==="[object Object]"}function isRegExp(obj){return _class2(obj)==="[object RegExp]"}function isFunction(obj){return _class2(obj)==="[object Function]"}function escapeRE2(str){return str.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}var defaultOptions={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};function isOptionsObj(obj){return Object.keys(obj||{}).reduce(function(acc,k){return acc||defaultOptions.hasOwnProperty(k)},!1)}var defaultSchemas={"http:":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.http||(self.re.http=new RegExp("^\\/\\/"+self.re.src_auth+self.re.src_host_port_strict+self.re.src_path,"i")),self.re.http.test(tail)?tail.match(self.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.no_http||(self.re.no_http=new RegExp("^"+self.re.src_auth+"(?:localhost|(?:(?:"+self.re.src_domain+")\\.)+"+self.re.src_domain_root+")"+self.re.src_port+self.re.src_host_terminator+self.re.src_path,"i")),self.re.no_http.test(tail)?pos>=3&&text2[pos-3]===":"||pos>=3&&text2[pos-3]==="/"?0:tail.match(self.re.no_http)[0].length:0}},"mailto:":{validate:function(text2,pos,self){let tail=text2.slice(pos);return self.re.mailto||(self.re.mailto=new RegExp("^"+self.re.src_email_name+"@"+self.re.src_host_strict,"i")),self.re.mailto.test(tail)?tail.match(self.re.mailto)[0].length:0}}},tlds_2ch_src_re="a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]",tlds_default="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");function resetScanCache(self){self.__index__=-1,self.__text_cache__=""}function createValidator(re){return function(text2,pos){let tail=text2.slice(pos);return re.test(tail)?tail.match(re)[0].length:0}}function createNormalizer(){return function(match2,self){self.normalize(match2)}}function compile(self){let re=self.re=re_default(self.__opts__),tlds2=self.__tlds__.slice();self.onCompile(),self.__tlds_replaced__||tlds2.push(tlds_2ch_src_re),tlds2.push(re.src_xn),re.src_tlds=tlds2.join("|");function untpl(tpl){return tpl.replace("%TLDS%",re.src_tlds)}re.email_fuzzy=RegExp(untpl(re.tpl_email_fuzzy),"i"),re.link_fuzzy=RegExp(untpl(re.tpl_link_fuzzy),"i"),re.link_no_ip_fuzzy=RegExp(untpl(re.tpl_link_no_ip_fuzzy),"i"),re.host_fuzzy_test=RegExp(untpl(re.tpl_host_fuzzy_test),"i");let aliases=[];self.__compiled__={};function schemaError(name,val){throw new Error('(LinkifyIt) Invalid schema "'+name+'": '+val)}Object.keys(self.__schemas__).forEach(function(name){let val=self.__schemas__[name];if(val===null)return;let compiled={validate:null,link:null};if(self.__compiled__[name]=compiled,isObject(val)){isRegExp(val.validate)?compiled.validate=createValidator(val.validate):isFunction(val.validate)?compiled.validate=val.validate:schemaError(name,val),isFunction(val.normalize)?compiled.normalize=val.normalize:val.normalize?schemaError(name,val):compiled.normalize=createNormalizer();return}if(isString2(val)){aliases.push(name);return}schemaError(name,val)}),aliases.forEach(function(alias){self.__compiled__[self.__schemas__[alias]]&&(self.__compiled__[alias].validate=self.__compiled__[self.__schemas__[alias]].validate,self.__compiled__[alias].normalize=self.__compiled__[self.__schemas__[alias]].normalize)}),self.__compiled__[""]={validate:null,normalize:createNormalizer()};let slist=Object.keys(self.__compiled__).filter(function(name){return name.length>0&&self.__compiled__[name]}).map(escapeRE2).join("|");self.re.schema_test=RegExp("(^|(?!_)(?:[><\uFF5C]|"+re.src_ZPCc+"))("+slist+")","i"),self.re.schema_search=RegExp("(^|(?!_)(?:[><\uFF5C]|"+re.src_ZPCc+"))("+slist+")","ig"),self.re.schema_at_start=RegExp("^"+self.re.schema_search.source,"i"),self.re.pretest=RegExp("("+self.re.schema_test.source+")|("+self.re.host_fuzzy_test.source+")|@","i"),resetScanCache(self)}function Match(self,shift){let start=self.__index__,end=self.__last_index__,text2=self.__text_cache__.slice(start,end);this.schema=self.__schema__.toLowerCase(),this.index=start+shift,this.lastIndex=end+shift,this.raw=text2,this.text=text2,this.url=text2}function createMatch(self,shift){let match2=new Match(self,shift);return self.__compiled__[match2.schema].normalize(match2,self),match2}function LinkifyIt(schemas,options){if(!(this instanceof LinkifyIt))return new LinkifyIt(schemas,options);options||isOptionsObj(schemas)&&(options=schemas,schemas={}),this.__opts__=assign2({},defaultOptions,options),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=assign2({},defaultSchemas,schemas),this.__compiled__={},this.__tlds__=tlds_default,this.__tlds_replaced__=!1,this.re={},compile(this)}LinkifyIt.prototype.add=function(schema,definition){return this.__schemas__[schema]=definition,compile(this),this};LinkifyIt.prototype.set=function(options){return this.__opts__=assign2(this.__opts__,options),this};LinkifyIt.prototype.test=function(text2){if(this.__text_cache__=text2,this.__index__=-1,!text2.length)return!1;let m,ml,me,len,shift,next,re,tld_pos,at_pos;if(this.re.schema_test.test(text2)){for(re=this.re.schema_search,re.lastIndex=0;(m=re.exec(text2))!==null;)if(len=this.testSchemaAt(text2,m[2],re.lastIndex),len){this.__schema__=m[2],this.__index__=m.index+m[1].length,this.__last_index__=m.index+m[0].length+len;break}}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(tld_pos=text2.search(this.re.host_fuzzy_test),tld_pos>=0&&(this.__index__<0||tld_pos<this.__index__)&&(ml=text2.match(this.__opts__.fuzzyIP?this.re.link_fuzzy:this.re.link_no_ip_fuzzy))!==null&&(shift=ml.index+ml[1].length,(this.__index__<0||shift<this.__index__)&&(this.__schema__="",this.__index__=shift,this.__last_index__=ml.index+ml[0].length))),this.__opts__.fuzzyEmail&&this.__compiled__["mailto:"]&&(at_pos=text2.indexOf("@"),at_pos>=0&&(me=text2.match(this.re.email_fuzzy))!==null&&(shift=me.index+me[1].length,next=me.index+me[0].length,(this.__index__<0||shift<this.__index__||shift===this.__index__&&next>this.__last_index__)&&(this.__schema__="mailto:",this.__index__=shift,this.__last_index__=next))),this.__index__>=0};LinkifyIt.prototype.pretest=function(text2){return this.re.pretest.test(text2)};LinkifyIt.prototype.testSchemaAt=function(text2,schema,pos){return this.__compiled__[schema.toLowerCase()]?this.__compiled__[schema.toLowerCase()].validate(text2,pos,this):0};LinkifyIt.prototype.match=function(text2){let result=[],shift=0;this.__index__>=0&&this.__text_cache__===text2&&(result.push(createMatch(this,shift)),shift=this.__last_index__);let tail=shift?text2.slice(shift):text2;for(;this.test(tail);)result.push(createMatch(this,shift)),tail=tail.slice(this.__last_index__),shift+=this.__last_index__;return result.length?result:null};LinkifyIt.prototype.matchAtStart=function(text2){if(this.__text_cache__=text2,this.__index__=-1,!text2.length)return null;let m=this.re.schema_at_start.exec(text2);if(!m)return null;let len=this.testSchemaAt(text2,m[2],m[0].length);return len?(this.__schema__=m[2],this.__index__=m.index+m[1].length,this.__last_index__=m.index+m[0].length+len,createMatch(this,0)):null};LinkifyIt.prototype.tlds=function(list2,keepOld){return list2=Array.isArray(list2)?list2:[list2],keepOld?(this.__tlds__=this.__tlds__.concat(list2).sort().filter(function(el,idx,arr){return el!==arr[idx-1]}).reverse(),compile(this),this):(this.__tlds__=list2.slice(),this.__tlds_replaced__=!0,compile(this),this)};LinkifyIt.prototype.normalize=function(match2){match2.schema||(match2.url="http://"+match2.url),match2.schema==="mailto:"&&!/^mailto:/i.test(match2.url)&&(match2.url="mailto:"+match2.url)};LinkifyIt.prototype.onCompile=function(){};var linkify_it_default=LinkifyIt;var import_punycode=__toESM(require_punycode(),1);var default_default={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}};var zero_default={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["paragraph"]},inline:{rules:["text"],rules2:["balance_pairs","fragments_join"]}}};var commonmark_default={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"\u201C\u201D\u2018\u2019",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["blockquote","code","fence","heading","hr","html_block","lheading","list","reference","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","html_inline","image","link","newline","text"],rules2:["balance_pairs","emphasis","fragments_join"]}}};var config={default:default_default,zero:zero_default,commonmark:commonmark_default},BAD_PROTO_RE=/^(vbscript|javascript|file|data):/,GOOD_DATA_RE=/^data:image\/(gif|png|jpeg|webp);/;function validateLink(url){let str=url.trim().toLowerCase();return BAD_PROTO_RE.test(str)?GOOD_DATA_RE.test(str):!0}var RECODE_HOSTNAME_FOR=["http:","https:","mailto:"];function normalizeLink(url){let parsed=parse_default(url,!0);if(parsed.hostname&&(!parsed.protocol||RECODE_HOSTNAME_FOR.indexOf(parsed.protocol)>=0))try{parsed.hostname=import_punycode.default.toASCII(parsed.hostname)}catch{}return encode_default(format(parsed))}function normalizeLinkText(url){let parsed=parse_default(url,!0);if(parsed.hostname&&(!parsed.protocol||RECODE_HOSTNAME_FOR.indexOf(parsed.protocol)>=0))try{parsed.hostname=import_punycode.default.toUnicode(parsed.hostname)}catch{}return decode_default(format(parsed),decode_default.defaultChars+"%")}function MarkdownIt(presetName,options){if(!(this instanceof MarkdownIt))return new MarkdownIt(presetName,options);options||isString(presetName)||(options=presetName||{},presetName="default"),this.inline=new parser_inline_default,this.block=new parser_block_default,this.core=new parser_core_default,this.renderer=new renderer_default,this.linkify=new linkify_it_default,this.validateLink=validateLink,this.normalizeLink=normalizeLink,this.normalizeLinkText=normalizeLinkText,this.utils=utils_exports,this.helpers=assign({},helpers_exports),this.options={},this.configure(presetName),options&&this.set(options)}MarkdownIt.prototype.set=function(options){return assign(this.options,options),this};MarkdownIt.prototype.configure=function(presets){let self=this;if(isString(presets)){let presetName=presets;if(presets=config[presetName],!presets)throw new Error('Wrong `markdown-it` preset "'+presetName+'", check name')}if(!presets)throw new Error("Wrong `markdown-it` preset, can't be empty");return presets.options&&self.set(presets.options),presets.components&&Object.keys(presets.components).forEach(function(name){presets.components[name].rules&&self[name].ruler.enableOnly(presets.components[name].rules),presets.components[name].rules2&&self[name].ruler2.enableOnly(presets.components[name].rules2)}),this};MarkdownIt.prototype.enable=function(list2,ignoreInvalid){let result=[];Array.isArray(list2)||(list2=[list2]),["core","block","inline"].forEach(function(chain){result=result.concat(this[chain].ruler.enable(list2,!0))},this),result=result.concat(this.inline.ruler2.enable(list2,!0));let missed=list2.filter(function(name){return result.indexOf(name)<0});if(missed.length&&!ignoreInvalid)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+missed);return this};MarkdownIt.prototype.disable=function(list2,ignoreInvalid){let result=[];Array.isArray(list2)||(list2=[list2]),["core","block","inline"].forEach(function(chain){result=result.concat(this[chain].ruler.disable(list2,!0))},this),result=result.concat(this.inline.ruler2.disable(list2,!0));let missed=list2.filter(function(name){return result.indexOf(name)<0});if(missed.length&&!ignoreInvalid)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+missed);return this};MarkdownIt.prototype.use=function(plugin){let args=[this].concat(Array.prototype.slice.call(arguments,1));return plugin.apply(plugin,args),this};MarkdownIt.prototype.parse=function(src,env){if(typeof src!="string")throw new Error("Input data should be a String");let state=new this.core.State(src,this,env);return this.core.process(state),state.tokens};MarkdownIt.prototype.render=function(src,env){return env=env||{},this.renderer.render(this.parse(src,env),this.options,env)};MarkdownIt.prototype.parseInline=function(src,env){let state=new this.core.State(src,this,env);return state.inlineMode=!0,this.core.process(state),state.tokens};MarkdownIt.prototype.renderInline=function(src,env){return env=env||{},this.renderer.render(this.parseInline(src,env),this.options,env)};var lib_default=MarkdownIt;function sanitizeCmsUrl(url){let value=url.trim();return/^(https?:|mailto:)/iu.test(value)||value.startsWith("/")||value.startsWith("#")?value:"#"}var cmsMarkdownRenderer=(()=>{let renderer=new lib_default({html:!1,linkify:!0,breaks:!1}),defaultLinkOpen=renderer.renderer.rules.link_open??((tokens,idx,options,_env,self)=>self.renderToken(tokens,idx,options));renderer.renderer.rules.link_open=(tokens,idx,options,env,self)=>{let hrefIndex=tokens[idx]?.attrIndex("href")??-1;if(hrefIndex>=0){let href=tokens[idx]?.attrs?.[hrefIndex]?.[1]??"";tokens[idx]?.attrs?.splice(hrefIndex,1,["href",sanitizeCmsUrl(href)])}return tokens[idx]?.attrSet("target","_blank"),tokens[idx]?.attrSet("rel","noreferrer noopener"),defaultLinkOpen(tokens,idx,options,env,self)};let defaultImage=renderer.renderer.rules.image??((tokens,idx,options,_env,self)=>self.renderToken(tokens,idx,options));return renderer.renderer.rules.image=(tokens,idx,options,env,self)=>{let srcIndex=tokens[idx]?.attrIndex("src")??-1;if(srcIndex>=0){let src=tokens[idx]?.attrs?.[srcIndex]?.[1]??"";tokens[idx]?.attrs?.splice(srcIndex,1,["src",sanitizeCmsUrl(src)])}return defaultImage(tokens,idx,options,env,self)},renderer})();var DATA_FORM_EXTENSION_FIELD_TYPES=["json","time"],DATA_FORM_FIELD_TYPES=[...CMS_FIELD_TYPES,...DATA_FORM_EXTENSION_FIELD_TYPES],DATA_FORM_UNSUPPORTED_FIELD_TYPES=["computed","rich_text"];function isDataFormCmsSharedFieldType(value){return typeof value=="string"&&CMS_FIELD_TYPES.includes(value)}function isDataFormFieldType(value){return typeof value=="string"&&DATA_FORM_FIELD_TYPES.includes(value)}function isDataFormUnsupportedFieldType(value){return typeof value=="string"&&DATA_FORM_UNSUPPORTED_FIELD_TYPES.includes(value)}var DATA_FORM_SHARING_MODES=["app_scoped","shared"];var DATA_FORM_RESOURCE_KINDS=["anonymous_submission","end_user_owned","admin_managed"],DATA_FORM_OWNER_TYPES=["none","identity"],DATA_FORM_RESOURCE_OWNER_TYPES=["app","tenant"],DATA_FORM_CONSUMER_ACCESS_MODES=["read_only","read_write"],DATA_FORM_SOURCE_OF_TRUTH="data_form_schema",DATA_FORM_SYSTEM_FIELD_NAMES=["record_id","resource_key","tenant_id","app_id","owner_identity_id","owner_app_user_id","source_app_id","source_channel","submit_context","created_by_identity_id","updated_by_identity_id","created_at","updated_at"];function assertObject2(value,message){if(typeof value!="object"||value===null||Array.isArray(value))throw new Error(message);return value}function asString2(value,field,options={}){if(typeof value=="string"){let normalized=value.trim();if(options.allowEmpty||normalized.length>0)return normalized}if(options.fallback!==void 0)return options.fallback;throw new Error(`Data Form field \`${field}\` must be a non-empty string.`)}function asOptionalString(value,field){if(value!=null){if(typeof value=="string")return value.trim();throw new Error(`Data Form field \`${field}\` must be a string when provided.`)}}function asOptionalStringArray(value,field){if(value!=null){if(!Array.isArray(value))throw new Error(`Data Form field \`${field}\` must be an array of strings when provided.`);return value.map((item,index)=>asString2(item,`${field}[${index}]`))}}function asBoolean2(value,field,fallback=!1){if(typeof value=="boolean")return value;if(value===void 0)return fallback;throw new Error(`Data Form field \`${field}\` must be a boolean.`)}function asNumber2(value,field,fallback){if(typeof value=="number"&&Number.isFinite(value))return value;if(value===void 0&&fallback!==void 0)return fallback;throw new Error(`Data Form field \`${field}\` must be a finite number.`)}function normalizeEnumValue(value,values,field,fallback){if(value===void 0)return fallback;if(typeof value=="string"){let normalized=value.trim();if(values.includes(normalized))return normalized}throw new Error(`Data Form field \`${field}\` must be one of: ${values.join(", ")}.`)}function normalizeAccessScope(value,field,fallback){if(value===void 0)return fallback;if(typeof value=="string"&&DATA_FORM_ACCESS_SCOPES.includes(value))return value;throw new Error(`Data Form field \`${field}\` must be one of: ${DATA_FORM_ACCESS_SCOPES.join(", ")}.`)}function defaultAccessPolicy(resourceKind){switch(resourceKind){case"anonymous_submission":return{create:"public",read:"admin",update:"admin"};case"end_user_owned":return{create:"own",read:"own",update:"own"};case"admin_managed":default:return{create:"admin",read:"admin",update:"admin"}}}function defaultOwnerTypeForResourceKind(resourceKind){switch(resourceKind){case"end_user_owned":return"identity";case"anonymous_submission":case"admin_managed":default:return"none"}}function normalizeAccessPolicy(value,resourceKind){let defaults=defaultAccessPolicy(resourceKind);if(value===void 0)return defaults;let record=assertObject2(value,"Data Form access_policy must be an object.");return{create:normalizeAccessScope(record.create,"access_policy.create",defaults.create),read:normalizeAccessScope(record.read,"access_policy.read",defaults.read),update:normalizeAccessScope(record.update,"access_policy.update",defaults.update)}}function defaultConsumerAccessMode(sharingMode){return"read_only"}function normalizeRichTextContentFormat(value,fieldName){if(value!==void 0){if(isCmsContentFormat(value))return value;throw new Error(`Data Form field \`${fieldName}.content_format\` must be \`markdown\` or \`html\`.`)}}function normalizeJsonFieldSpec(record){let validationRecord=record.validation===void 0?void 0:assertObject2(record.validation,"Data Form json field validation must be an object.");return{name:asString2(record.name,"fields[].name"),label:asString2(record.label,"fields[].label"),type:"json",required:asBoolean2(record.required,"fields[].required"),default:record.default??null,description:asString2(record.description,"fields[].description",{allowEmpty:!0,fallback:""}),order:asNumber2(record.order,"fields[].order"),readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,"fields[].readonly"),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,"fields[].system_managed"),validation:validationRecord?.max_size===void 0?void 0:{max_size:asNumber2(validationRecord.max_size,"fields[].validation.max_size")}}}function normalizeTimeFieldSpec(record,fieldName,implicitValidation){return{name:fieldName,label:asString2(record.label,`${fieldName}.label`),type:"time",required:asBoolean2(record.required,`${fieldName}.required`),default:record.default??"",description:asString2(record.description,`${fieldName}.description`,{allowEmpty:!0,fallback:""}),order:asNumber2(record.order,`${fieldName}.order`),readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,`${fieldName}.readonly`),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,`${fieldName}.system_managed`),validation:normalizeValidationAliases(record,"text",fieldName,implicitValidation)}}function normalizeFieldTypeAlias(rawType,fieldName){switch(rawType){case"email":return{normalizedType:"text",implicitValidation:{pattern:"^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"}};case"phone":return{normalizedType:"text",implicitValidation:{pattern:"^1\\d{10}$"}};case"url":return{normalizedType:"url",implicitValidation:{allowed_protocols:["https","http"]}};case"multiselect":return{normalizedType:"multi_select"};case"textarea":return{normalizedType:"text",implicitUi:{multiline:!0}};case"datetime":return{normalizedType:"date",implicitUi:{with_time:!0}};case"markdown":return{normalizedType:"text",implicitUi:{multiline:!0},implicitContentFormat:"markdown"};case"richtext":return{normalizedType:"text",implicitUi:{multiline:!0},implicitContentFormat:"html"};case"time":return{normalizedType:"time",implicitValidation:{pattern:"^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d)?$"}};default:return{normalizedType:rawType}}}function resolvePhonePattern(record,fieldName){switch(record.locale===void 0?"zh-CN":asString2(record.locale,`${fieldName}.locale`)){case"zh-CN":return"^1\\d{10}$";case"e164":case"international":return"^\\+[1-9]\\d{6,14}$";default:throw new Error(`Data Form field \`${fieldName}.locale\` currently only supports \`zh-CN\`, \`e164\`, or \`international\`.`)}}function normalizeFieldTypeAliasWithRecord(rawType,record,fieldName){return rawType==="phone"?{normalizedType:"text",implicitValidation:{pattern:resolvePhonePattern(record,fieldName)}}:normalizeFieldTypeAlias(rawType,fieldName)}function toBytesFromMb(value){return Math.round(value*1024*1024)}var ACCEPT_ALIAS_TO_MIME={pdf:"application/pdf",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp"};function defaultImageMimeTypes(){return["image/png","image/jpeg","image/webp"]}function normalizeValidationAliases(record,rawType,fieldName,implicitValidation){let explicitValidation=record.validation===void 0?void 0:assertObject2(record.validation,`Data Form field \`${fieldName}.validation\` must be an object.`),normalized={...implicitValidation??{},...explicitValidation??{}};return record.min!==void 0&&(normalized[rawType==="number"?"min":"min_length"]=asNumber2(record.min,`${fieldName}.min`)),record.max!==void 0&&(normalized[rawType==="number"?"max":"max_length"]=asNumber2(record.max,`${fieldName}.max`)),record.max_files!==void 0&&(normalized.max_count=asNumber2(record.max_files,`${fieldName}.max_files`)),record.max_size_mb!==void 0&&(normalized.max_size=toBytesFromMb(asNumber2(record.max_size_mb,`${fieldName}.max_size_mb`))),Object.keys(normalized).length>0?normalized:void 0}function normalizeUiAliases(record,fieldName){let requestedType=typeof record.type=="string"?record.type.trim():"",typeAlias=requestedType?normalizeFieldTypeAliasWithRecord(requestedType,record,fieldName):void 0,existingUi=record.ui===void 0?void 0:assertObject2(record.ui,`Data Form field \`${fieldName}.ui\` must be an object.`),normalizedUi={...typeAlias?.implicitUi??{},...existingUi??{}};return record.multiline!==void 0&&(normalizedUi.multiline=asBoolean2(record.multiline,`${fieldName}.multiline`)),Object.keys(normalizedUi).length>0?normalizedUi:void 0}function normalizeAcceptAliases(record,rawType,fieldName){if(record.accept!==void 0)return Array.isArray(record.accept)?{mime_types:record.accept.map((item,index)=>{let alias=asString2(item,`${fieldName}.accept[${index}]`).toLowerCase(),resolved=ACCEPT_ALIAS_TO_MIME[alias];if(!resolved)throw new Error(`Data Form field \`${fieldName}.accept[${index}]\` uses unsupported alias \`${alias}\`.`);return resolved})}:assertObject2(record.accept,`Data Form field \`${fieldName}.accept\` must be an object or string array.`);if(rawType==="image")return{mime_types:defaultImageMimeTypes()}}function normalizeDataFormFieldSpec(input){let record=assertObject2(input,"Data Form field spec must be an object."),fieldName=asString2(record.name,"fields[].name"),requestedType=asString2(record.type,`${fieldName}.type`),typeAlias=normalizeFieldTypeAliasWithRecord(requestedType,record,fieldName),rawType=typeAlias.normalizedType;if(isDataFormUnsupportedFieldType(requestedType))throw new Error(`Data Form field \`${fieldName}\` uses unsupported type \`${requestedType}\`. Use \`text + ui.multiline\` or \`content_format\` semantics instead.`);if(!isDataFormFieldType(rawType))throw new Error(`Data Form field \`${fieldName}\` uses unknown type \`${requestedType}\`.`);if(rawType==="json")return normalizeJsonFieldSpec(record);if(rawType==="time")return normalizeTimeFieldSpec(record,fieldName,typeAlias.implicitValidation);if(!isDataFormCmsSharedFieldType(rawType))throw new Error(`Data Form field \`${fieldName}\` cannot normalize type \`${rawType}\`.`);let normalizedCmsField=normalizeCmsFieldSpec({...record,accept:normalizeAcceptAliases(record,rawType,fieldName),ui:normalizeUiAliases(record,fieldName),validation:normalizeValidationAliases(record,requestedType,fieldName,typeAlias.implicitValidation),type:rawType}),contentFormat=normalizeRichTextContentFormat(record.content_format,fieldName)??typeAlias.implicitContentFormat;return{...normalizedCmsField,readonly:record.readonly===void 0?void 0:asBoolean2(record.readonly,`${fieldName}.readonly`),system_managed:record.system_managed===void 0?void 0:asBoolean2(record.system_managed,`${fieldName}.system_managed`),content_format:contentFormat}}function normalizeDataFormResourceSchema(input,options={}){let record=assertObject2(input,"Data Form resource schema must be an object."),resourceKey=asString2(record.resource_key??record.resource??options.defaultResourceKey,"resource_key"),resourceKind=normalizeEnumValue(record.resource_kind,DATA_FORM_RESOURCE_KINDS,"resource_kind","anonymous_submission"),ownerType=normalizeEnumValue(record.owner_type,DATA_FORM_OWNER_TYPES,"owner_type",defaultOwnerTypeForResourceKind(resourceKind)),resourceOwnerType=normalizeEnumValue(record.resource_owner_type,DATA_FORM_RESOURCE_OWNER_TYPES,"resource_owner_type","app"),sharingMode=normalizeEnumValue(record.sharing_mode,DATA_FORM_SHARING_MODES,"sharing_mode","app_scoped"),consumerAppIds=asOptionalStringArray(record.consumer_app_ids,"consumer_app_ids"),consumerAccess=normalizeEnumValue(record.consumer_access,DATA_FORM_CONSUMER_ACCESS_MODES,"consumer_access",defaultConsumerAccessMode(sharingMode)),fieldsInput=record.fields;if(!Array.isArray(fieldsInput))throw new Error("Data Form field `fields` must be an array.");return{resource_key:resourceKey,display_name:asString2(record.display_name,"display_name",{fallback:resourceKey}),description:asOptionalString(record.description,"description"),resource_kind:resourceKind,owner_type:ownerType,resource_owner_type:resourceOwnerType,resource_owner_id:asOptionalString(record.resource_owner_id,"resource_owner_id"),sharing_mode:sharingMode,consumer_app_ids:consumerAppIds,consumer_access:consumerAccess,access_policy:normalizeAccessPolicy(record.access_policy,resourceKind),fields:fieldsInput.map(field=>normalizeDataFormFieldSpec(field)),source_of_truth:DATA_FORM_SOURCE_OF_TRUTH}}function assertUniqueFieldNames(fields){let seen=new Set,reserved=new Set(DATA_FORM_SYSTEM_FIELD_NAMES);for(let field of fields){if(reserved.has(field.name))throw new Error(`Data Form field \`${field.name}\` is reserved for system columns.`);if(seen.has(field.name))throw new Error(`Data Form field \`${field.name}\` is duplicated.`);seen.add(field.name)}}function assertJsonFieldConstraints(field){let value=field.default;if(!(value===null||Array.isArray(value)||typeof value=="object"&&value!==null))throw new Error(`Data Form json field \`${field.name}\` must default to an object, array, or null.`)}function assertSharedFieldConstraints(field){let cmsField=field;if((field.type==="relation"||field.type==="relations")&&!field.relation_target?.collection)throw new Error(`Data Form relation field \`${field.name}\` must declare relation_target.collection.`);if(field.content_format!==void 0&&field.type!=="text")throw new Error(`Data Form field \`${field.name}\` can only use content_format when type is \`text\`.`);if(field.type==="relations"&&!isCmsMultiValueFieldType(field.type))throw new Error(`Data Form field \`${field.name}\` relation configuration is invalid.`);field.type==="image"||field.type==="images"||field.type==="file"||field.type}function assertTimeFieldConstraints(field){if(field.content_format!==void 0)throw new Error(`Data Form field \`${field.name}\` cannot use content_format when type is \`time\`.`)}function validateDataFormResourceSchema(input){let schema=normalizeDataFormResourceSchema(input);assertUniqueFieldNames(schema.fields);for(let field of schema.fields){if(field.type==="json"){assertJsonFieldConstraints(field);continue}if(field.type==="time"){assertTimeFieldConstraints(field);continue}assertSharedFieldConstraints(field)}if(schema.resource_kind==="end_user_owned"&&schema.owner_type!=="identity")throw new Error("Data Form resource_kind `end_user_owned` requires owner_type `identity`.");if(schema.resource_kind==="anonymous_submission"&&schema.owner_type==="identity")throw new Error("Data Form resource_kind `anonymous_submission` must not require identity ownership.");if(schema.access_policy.create==="own"&&schema.owner_type!=="identity")throw new Error("Data Form access_policy.create `own` requires owner_type `identity`.");if((schema.access_policy.read==="own"||schema.access_policy.update==="own")&&schema.owner_type!=="identity")throw new Error("Data Form access_policy with `own` scope requires owner_type `identity`.");if(schema.resource_owner_type==="tenant"&&schema.sharing_mode!=="shared")throw new Error("Data Form resource_owner_type `tenant` requires sharing_mode `shared`.");if(schema.sharing_mode==="shared"&&schema.resource_owner_type==="app"&&(schema.consumer_app_ids?.length??0)===0)throw new Error("Shared app-owned Data Form resources must declare consumer_app_ids.");if(schema.sharing_mode!=="shared"&&schema.consumer_access==="read_write")throw new Error("Data Form consumer_access `read_write` requires sharing_mode `shared`.");return schema}function byColumnName(columns){return new Map(columns.map(column=>[column.column_name,column]))}function diffDataFormTables(args){let previous=args.previous,next=args.next;if(!previous)return{source:DATA_FORM_GENERATED_SOURCE_TAG,resource_key:next.resource_key,table_name:next.table_name,operations:[{kind:"create_table",table_name:next.table_name,columns:next.columns}]};let previousColumns=byColumnName(previous.columns),operations=[];for(let column of next.columns){let existing=previousColumns.get(column.column_name);if(!existing){operations.push({kind:"add_column",table_name:next.table_name,column});continue}(existing.nullable!==column.nullable||existing.default_sql!==column.default_sql)&&operations.push({kind:"alter_column",table_name:next.table_name,column_name:column.column_name,...existing.nullable!==column.nullable?{nullable:column.nullable}:{},...existing.default_sql!==column.default_sql?{default_sql:column.default_sql}:{}})}return{source:DATA_FORM_GENERATED_SOURCE_TAG,resource_key:next.resource_key,table_name:next.table_name,operations}}function quoteJson(value){return`'${JSON.stringify(value).replace(/'/g,"''")}'::jsonb`}function normalizeTableName(resourceKey){let normalized=resourceKey.trim().toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/^_+|_+$/g,"");return normalized.endsWith("_records")?normalized:`${normalized}_records`}function compileFieldColumn(field){switch(field.type){case"text":case"url":case"select":return{column_name:field.name,data_type:"TEXT",nullable:!field.required,default_sql:typeof field.default=="string"?`'${field.default.replace(/'/g,"''")}'`:void 0};case"number":return{column_name:field.name,data_type:"NUMERIC",nullable:!field.required,default_sql:typeof field.default=="number"?String(field.default):void 0};case"bool":return{column_name:field.name,data_type:"BOOLEAN",nullable:!field.required,default_sql:typeof field.default=="boolean"?field.default?"TRUE":"FALSE":void 0};case"date":return{column_name:field.name,data_type:field.ui?.with_time?"TIMESTAMPTZ":"DATE",nullable:!field.required};case"time":return{column_name:field.name,data_type:"TEXT",nullable:!field.required,default_sql:typeof field.default=="string"?`'${field.default.replace(/'/g,"''")}'`:void 0};case"multi_select":case"image":case"images":case"file":case"files":case"relation":case"relations":case"json":return{column_name:field.name,data_type:"JSONB",nullable:!field.required,default_sql:field.default===void 0||field.default===null?void 0:quoteJson(field.default)}}}function buildSystemColumns(){return[{column_name:"record_id",data_type:"TEXT PRIMARY KEY",nullable:!1},{column_name:"resource_key",data_type:"TEXT",nullable:!1},{column_name:"tenant_id",data_type:"TEXT",nullable:!1},{column_name:"app_id",data_type:"TEXT",nullable:!1},{column_name:"owner_identity_id",data_type:"TEXT",nullable:!0},{column_name:"owner_app_user_id",data_type:"TEXT",nullable:!0},{column_name:"source_app_id",data_type:"TEXT",nullable:!1},{column_name:"source_channel",data_type:"TEXT",nullable:!0},{column_name:"submit_context",data_type:"JSONB",nullable:!0},{column_name:"created_by_identity_id",data_type:"TEXT",nullable:!0},{column_name:"updated_by_identity_id",data_type:"TEXT",nullable:!0},{column_name:"created_at",data_type:"TIMESTAMPTZ",nullable:!1,default_sql:"NOW()"},{column_name:"updated_at",data_type:"TIMESTAMPTZ",nullable:!1,default_sql:"NOW()"}]}function buildDataFormTableModel(input){let table_name=normalizeTableName(input.resource_key);return{resource_key:input.resource_key,table_name,columns:[...buildSystemColumns(),...input.fields.map(field=>compileFieldColumn(field))]}}function compileDataFormSchema(input){let schema=validateDataFormResourceSchema(input.next),previousSchema=input.previous?validateDataFormResourceSchema(input.previous):null,table2=buildDataFormTableModel(schema),previousTable=previousSchema?buildDataFormTableModel(previousSchema):null,diff=diffDataFormTables({previous:previousTable,next:table2}),sql=renderDataFormDiffSql(diff);return{schema,table:table2,diff,sql}}import{createHash as createHash10}from"node:crypto";function buildDataFormMigrationArtifact(args){let sourceTag=args.sourceTag??DATA_FORM_GENERATED_SOURCE_TAG,compiled=compileDataFormSchema({previous:args.previous,next:args.schema}),sql=ensureSourceManifestComment(compiled.sql,args.sourceManifestPath,sourceTag);return{source:sourceTag,sql,checksum:createHash10("sha256").update(sql).digest("hex"),statements_count:countExecutableSqlStatements(sql),resource_key:`db/data-form/${args.schema.resource_key}`,source_manifest_path:args.sourceManifestPath,table_name:compiled.table.table_name}}function ensureSourceManifestComment(sql,sourceManifestPath,sourceTag){let marker=buildSourceTagComment(sourceTag),manifestComment=`-- source manifest: ${sourceManifestPath}`,normalized=sql.trimStart();return normalized.startsWith(marker)?normalized.includes(manifestComment)?sql:sql.replace(marker,`${marker}
2500
2591
  ${manifestComment}`):`${marker}
2501
2592
  ${manifestComment}
2502
2593
  ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComments(sql).split(";").map(part=>part.trim()).filter(Boolean).length}function stripSqlComments(sql){return sql.replace(/\/\*[\s\S]*?\*\//g,"").split(`
@@ -2504,11 +2595,11 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2504
2595
  `)}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)}
2505
2596
  `);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)}
2506
2597
  `);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)}
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(`
2598
+ `);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=join19(appRoot,"resources","db","migrations"),sqlResources=existsSync24(directory)?readdirSync10(directory).filter(entry=>entry.endsWith(".sql")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join19(directory,entry),sql=readFileSync24(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=join19(appRoot,"resources","data-forms"),dataFormResources=existsSync24(dataFormDirectory)?readdirSync10(dataFormDirectory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join19(dataFormDirectory,entry),raw=YAML4.parse(readFileSync24(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=join19(appRoot,"resources","auth","policies");return existsSync24(directory)?readdirSync10(directory).filter(entry=>entry.endsWith(".json")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join19(directory,entry),raw=readFileSync24(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 relative8(appRoot,filePath).split("\\").join("/")}function checksum2(value){return createHash11("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)} ${relative8(appRoot,join19(appRoot,change.manifest_path)).split("\\").join("/")}`+(change.previous_checksum?` (${change.previous_checksum} -> ${change.checksum??"deleted"})`:""))}process.stdout.write(`${lines.join(`
2508
2599
  `)}
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(`
2600
+ `)}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)} ${relative8(appRoot,join19(appRoot,change.manifest_path)).split("\\").join("/")}`)}process.stdout.write(`${lines.join(`
2510
2601
  `)}
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(`
2602
+ `)}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)} ${relative8(appRoot,join19(appRoot,change.manifest_path)).split("\\").join("/")}`)}process.stdout.write(`${lines.join(`
2512
2603
  `)}
2513
2604
  `)}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}
2514
2605
  `);let timer=setTimeout(()=>{process.stderr.write(`${waitingMessage}
@@ -2523,9 +2614,9 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2523
2614
  `)}
2524
2615
  `);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)}
2525
2616
  `);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(`
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(`
2617
+ `))}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=join20(appRoot,migrationPath);return existsSync25(absolutePath)?readFileSync25(absolutePath,"utf8").split(`
2527
2618
  `).map(line=>line.replace(/--.*$/,"").trim()).filter(Boolean).join(`
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)}
2619
+ `).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 existsSync26,readdirSync as readdirSync11,readFileSync as readFileSync26}from"node:fs";import{join as join21}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)}
2529
2620
  `);return}process.stdout.write(`${result.map(item=>`OK ${item.resource_key} ${item.manifest_path} fields=${item.field_count}`).join(`
2530
2621
  `)}
2531
2622
  `);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)}
@@ -2545,7 +2636,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2545
2636
  `))])}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)}
2546
2637
  `);return}process.stdout.write(`${lines.join(`
2547
2638
  `)}
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(`
2639
+ `)}function loadDataFormSchemas(appRoot,resourceKey){let directory=join21(appRoot,"resources","data-forms");if(!existsSync26(directory))return[];let targetResourceKey=typeof resourceKey=="string"?resourceKey.trim():"";return readdirSync11(directory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let manifestPath=join21("resources","data-forms",entry),raw=YAML5.parse(readFileSync26(join21(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(`
2549
2640
  `)+`
2550
2641
  `);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(`
2551
2642
  `)+`
@@ -2557,13 +2648,13 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2557
2648
  `)+`
2558
2649
  `);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(`
2559
2650
  `)+`
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"&&current.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)}
2651
+ `)}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((resolve20,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}resolve20(port)})})})}async function listenLocalServer(server,port){await new Promise((resolve20,reject)=>{server.once("error",reject),server.listen(port,"127.0.0.1",()=>{server.off("error",reject),resolve20()})})}async function closeServer(server){await new Promise(resolve20=>{server.close(()=>resolve20())})}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(resolve20=>{let socket=net.createConnection({host,port}),done=value=>{socket.removeAllListeners(),socket.destroyed||socket.destroy(),resolve20(value)};socket.once("connect",()=>done(!0)),socket.once("error",()=>done(!1)),socket.setTimeout(500,()=>done(!1))})}async function waitForChildExit(child){await new Promise(resolve20=>{if(child.exitCode!==null){resolve20();return}child.once("exit",()=>resolve20()),setTimeout(()=>resolve20(),1e3)})}function sleep3(ms){return new Promise(resolve20=>{setTimeout(resolve20,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((resolve20,reject)=>{state.resolveRun=resolve20,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(resolve20=>{child.once("exit",()=>resolve20())})}import{chmodSync as chmodSync4,existsSync as existsSync27,mkdirSync as mkdirSync14,readFileSync as readFileSync27,rmSync as rmSync6,writeFileSync as writeFileSync14}from"node:fs";import{dirname as dirname16,resolve as resolve17}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 existsSync27(envProfilePath)?JSON.parse(readFileSync27(envProfilePath,"utf8")):null}function persistStoredEnvironmentProfile(input){withCliStateFileWriteFallback({fileName:"environment.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync14(stateDir,{recursive:!0}),writeFileSync14(filePath,`${JSON.stringify({active_profile:input.active_profile,values:normalizeProfileValues(input.values),updated_at:new Date().toISOString()},null,2)}
2652
+ `,"utf8"),chmodSync4(filePath,384)}})}function clearStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();existsSync27(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"&&current.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(!existsSync27(registryPath))return[];let parsed=YAML6.parse(readFileSync27(registryPath,"utf8"));return Array.isArray(parsed?.profiles)?parsed.profiles:[]}function resolveEnvironmentRegistryPath(startDir){let invocationWorkspaceRoot=findWorkspaceRoot(startDir),invocationCandidate=resolve17(invocationWorkspaceRoot,"deploy","registry","environment-profiles.yaml");if(existsSync27(invocationCandidate))return invocationCandidate;let cliModuleRoot=resolve17(dirname16(fileURLToPath5(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve17(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)}
2562
2653
  `);else for(let entry of result.entries)seen.has(entry.id)||(seen.add(entry.id),process.stdout.write(`${formatEntry(entry)}
2563
2654
  `));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)}
2564
2655
  `);return}if(result.entries.length===0){process.stdout.write(`\u672A\u67E5\u8BE2\u5230\u65E5\u5FD7\u3002
2565
2656
  `);return}for(let entry of result.entries)process.stdout.write(`${formatEntry(entry)}
2566
- `)}function formatEntry(entry){return`[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.source}/${entry.stream}: ${entry.message}`}function readStringOption8(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption3(args,key){let value=readStringOption8(args,key);if(!value)return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function sleep4(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}import process5 from"node:process";async function runNotificationCommand(args){let subcommand=args.rest[0];if(!subcommand||!["inbox","announce","delivery","end-user"].includes(subcommand))throw new Error("`platform notification` \u4EC5\u652F\u6301 `inbox`\u3001`announce`\u3001`delivery` \u6216 `end-user` \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=resolveNotificationContext(args),sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:context.tenantId,capability:"notification",requestClass:"control"});if(subcommand==="inbox"){await runInboxSubcommand(sdk,context,args);return}if(subcommand==="delivery"){if(!context.tenantId)throw new Error("`platform notification delivery` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let items=await sdk.listNotificationDeliveries({app_id:readStringOption9(args,"app")??context.appId,status:readStringOption9(args,"status")});process5.stdout.write(`${JSON.stringify(items,null,2)}
2657
+ `)}function formatEntry(entry){return`[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.source}/${entry.stream}: ${entry.message}`}function readStringOption8(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption3(args,key){let value=readStringOption8(args,key);if(!value)return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function sleep4(ms){return new Promise(resolve20=>{setTimeout(resolve20,ms)})}import process5 from"node:process";async function runNotificationCommand(args){let subcommand=args.rest[0];if(!subcommand||!["inbox","announce","delivery","end-user"].includes(subcommand))throw new Error("`platform notification` \u4EC5\u652F\u6301 `inbox`\u3001`announce`\u3001`delivery` \u6216 `end-user` \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=resolveNotificationContext(args),sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:context.tenantId,capability:"notification",requestClass:"control"});if(subcommand==="inbox"){await runInboxSubcommand(sdk,context,args);return}if(subcommand==="delivery"){if(!context.tenantId)throw new Error("`platform notification delivery` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let items=await sdk.listNotificationDeliveries({app_id:readStringOption9(args,"app")??context.appId,status:readStringOption9(args,"status")});process5.stdout.write(`${JSON.stringify(items,null,2)}
2567
2658
  `);return}if(subcommand==="end-user"){await runEndUserSubcommand(sdk,context,args);return}await runAnnounceSubcommand(sdk,context,args)}async function runInboxSubcommand(sdk,context,args){let action=args.rest[1]??"list";if(action==="list"){if(!context.tenantId)throw new Error("`platform notification inbox list` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let response=await sdk.listNotificationInbox({app_id:readStringOption9(args,"app")??context.appId,inbox_type:readStringOption9(args,"type"),status:readStringOption9(args,"status"),limit:readNumberOption4(args,"limit")});process5.stdout.write(`${JSON.stringify(response,null,2)}
2568
2659
  `);return}if(action==="update"){if(!context.tenantId)throw new Error("`platform notification inbox update` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let itemId=readStringOption9(args,"item")??args.rest[2],status=readStringOption9(args,"status");if(!itemId||!status||!isWritableInboxStatus(status))throw new Error("`platform notification inbox update` \u9700\u8981 `<item-id>` \u6216 `--item <id>`\uFF0C\u4EE5\u53CA `--status unread|read|dismissed|archived`\u3002");let item=await sdk.updateNotificationInboxItemStatus(itemId,{status});process5.stdout.write(`${JSON.stringify(item,null,2)}
2569
2660
  `);return}throw new Error("`platform notification inbox` \u76EE\u524D\u4EC5\u652F\u6301 `list` \u6216 `update`\u3002")}async function runAnnounceSubcommand(sdk,context,args){let scope=args.rest[1];if(scope==="platform"){let tenantId=readStringOption9(args,"tenant")??context.tenantId,title=readStringOption9(args,"title");if(!tenantId||!title)throw new Error("`platform notification announce platform` \u9700\u8981 `--tenant <tenant-id>` \u548C `--title <text>`\u3002");let item=await sdk.announcePlatformNotification({tenant_id:tenantId,title,body:readStringOption9(args,"body")??null,level:readStringOption9(args,"level")});process5.stdout.write(`${JSON.stringify(item,null,2)}
@@ -2580,15 +2671,15 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2580
2671
  `));let settings=await context.sdk.updateTenantAppPublishSettings(context.appId,{source_version_id:targetSourceVersionId});if(await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:process.cwd(),tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(settings,null,2)}
2581
2672
  `);return}printPublishSettings(settings,{title:`\u5E94\u7528\u6B63\u5F0F\u7248\u672C\u5DF2\u5207\u56DE: ${context.appId}`})}async function loadPublishContext(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 binding=tryReadCurrentBinding()?.binding,tenantId=readStringOption10(args,"tenant")??binding?.tenant_id,appId=readStringOption10(args,"app")??binding?.app_id;if(!tenantId||!appId)throw new Error("`platform publish` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let apiToken=selectApiToken(credentials);return{tenantId,appId,sdk:createControlApiSdk({accessToken:apiToken,tenantId,capability:"dashboard",requestClass:"control"})}}function tryReadCurrentBinding(){try{return readBinding(findAppRoot(process.cwd()))}catch{return null}}function resolvePublishSubcommand(args){let subcommand=args.rest[0];return subcommand?subcommand==="status"||subcommand==="set"||subcommand==="rollback"?subcommand:null:"status"}function hasHelpFlag5(args){return args.options.help===!0||args.options.h===!0}function readStringOption10(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readPublishStatusOption(args){let value=readStringOption10(args,"status");return value==="published"||value==="unpublished"?value:void 0}function printPublishHelp(){process.stdout.write(["platform publish","","\u7528\u6CD5\uFF1A"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","\u8BF4\u660E\uFF1A"," - `platform publish` \u9ED8\u8BA4\u7B49\u4EF7\u4E8E `platform publish status`"," - `publish status` \u67E5\u770B\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," - `publish set` \u4FEE\u6539\u53D1\u5E03\u72B6\u6001\uFF0C\u6216\u5207\u6362\u5F53\u524D\u90E8\u7F72\u7248\u672C"," - `publish rollback` \u5C06\u5F53\u524D\u6B63\u5F0F\u7248\u672C\u5207\u56DE\u6307\u5B9A\u6E90\u7801\u7248\u672C",""].join(`
2582
2673
  `))}function printPublishSettings(settings,context){let candidateLines=settings.candidates.length>0?settings.candidates.map((candidate,index)=>{let label=candidate.message?.trim()||candidate.source_version_id;return`${index+1}. ${label} ${candidate.source_version_id}`}):["- \u65E0\u53EF\u9009\u7248\u672C"];process.stdout.write([context.title,`\u53D1\u5E03\u72B6\u6001: ${settings.publish_status==="published"?"\u5DF2\u53D1\u5E03":"\u672A\u53D1\u5E03"}`,`\u786E\u8BA4\u90E8\u7F72\u5F62\u6001: ${settings.deployment_class_confirmed??"-"}`,`\u5F53\u524D\u90E8\u7F72\u7248\u672C: ${settings.current_source_version_id??"-"}`,`\u5F53\u524D release: ${settings.current_release_id??"-"}`,`\u5F53\u524D deployment: ${settings.current_deployment_id??"-"}`,`\u5F53\u524D\u90E8\u7F72\u5F62\u6001: ${settings.current_deployment_class_used??"-"}`,`\u5F53\u524D\u4EA7\u7269\u7C7B\u578B: ${settings.current_artifact_kind??"-"}`,`\u5F53\u524D\u6267\u884C\u6A21\u5F0F: ${settings.current_execution_mode??"-"}`,`\u8FD0\u884C\u9A71\u52A8: ${settings.current_runtime_driver??"-"}`,`\u8FD0\u884C\u5B9E\u4F8B: ${settings.current_runtime_instance_id??"-"}`,`\u5F53\u524D\u5BF9\u8C61\u524D\u7F00: ${settings.current_object_prefix??"-"}`,`\u516C\u5F00\u6B63\u5F0F\u5165\u53E3: ${settings.public_prod_url??"-"}`,`\u8FD0\u884C\u5065\u5EB7\u68C0\u67E5: ${settings.current_runtime_health_check_url??"-"}`,"\u53EF\u9009\u6B63\u5F0F\u7248\u672C:",...candidateLines,""].join(`
2583
- `))}import{createHash as createHash10}from"node:crypto";import{readFile as readFile2,stat}from"node:fs/promises";import{join as join19,resolve as resolve17}from"node:path";function resolvePreviewProjectContext(appRoot,args){let sourceContext=readSourceContext(appRoot)?.sourceContext,binding=readBinding(appRoot)?.binding;return{tenantId:readStringOption11(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id,appId:readStringOption11(args,"app")??sourceContext?.app_id??binding?.app_id}}var SOURCE_VERSION_REUSE_SCAN_LIMIT=5,BUILD_REUSE_SCAN_LIMIT=20,PREVIEW_BUILD_POLL_TIMEOUT_MS=180*1e3,PREVIEW_BUILD_POLL_INTERVAL_MS=1500;async function runPreviewCommand(args){if(hasHelpFlag6(args)){printPreviewHelp(resolveExplicitPreviewMode(args));return}if(resolvePreviewMode(args)==="open"){await runPreviewOpenCommand(args);return}await runPreviewGenerateCommand(args)}async function runPreviewGenerateCommand(args){let context=await loadPreviewContext(args),requestedBy=await resolveRequestedBy3(context.sdk),fromBuildId=readStringOption11(args,"from-build"),explicitSourceVersionId=readStringOption11(args,"source-version"),noWait=args.options["no-wait"]===!0,forceBuild=args.options["force-build"]===!0,localBuild=args.options["local-build"]===!0||readStringOption11(args,"build-mode")==="local";if(args.options["wait-build-only"]===!0)throw new Error("`platform preview generate --wait-build-only` \u5DF2\u79FB\u9664\uFF1B\u8BF7\u6539\u7528 `platform build run --source-version <srcver> --wait`\u3002");let autoResources=await maybeAutoApplyPreviewResources({args,context,requestedBy,sourceVersionId:explicitSourceVersionId,fromBuildId});if(fromBuildId){let preview=await context.sdk.createTenantAppPreview(context.appId,{build_id:fromBuildId}).catch(async error=>{throw await formatPreviewCommandError(context.sdk,error,{appId:context.appId,buildId:fromBuildId,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for explicit build: ${fromBuildId}`);if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:fromBuildId,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);process.stdout.write(`${JSON.stringify({auto_resources:autoResources,preview,post_check:postCheck3},null,2)}
2674
+ `))}import{createHash as createHash12}from"node:crypto";import{readFile as readFile2,stat}from"node:fs/promises";import{join as join22,resolve as resolve18}from"node:path";function resolvePreviewProjectContext(appRoot,args){let sourceContext=readSourceContext(appRoot)?.sourceContext,binding=readBinding(appRoot)?.binding;return{tenantId:readStringOption11(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id,appId:readStringOption11(args,"app")??sourceContext?.app_id??binding?.app_id}}var SOURCE_VERSION_REUSE_SCAN_LIMIT=5,BUILD_REUSE_SCAN_LIMIT=20,PREVIEW_BUILD_POLL_TIMEOUT_MS=180*1e3,PREVIEW_BUILD_POLL_INTERVAL_MS=1500;async function runPreviewCommand(args){if(hasHelpFlag6(args)){printPreviewHelp(resolveExplicitPreviewMode(args));return}if(resolvePreviewMode(args)==="open"){await runPreviewOpenCommand(args);return}await runPreviewGenerateCommand(args)}async function runPreviewGenerateCommand(args){let context=await loadPreviewContext(args),requestedBy=await resolveRequestedBy3(context.sdk),fromBuildId=readStringOption11(args,"from-build"),explicitSourceVersionId=readStringOption11(args,"source-version"),noWait=args.options["no-wait"]===!0,forceBuild=args.options["force-build"]===!0,localBuild=args.options["local-build"]===!0||readStringOption11(args,"build-mode")==="local";if(args.options["wait-build-only"]===!0)throw new Error("`platform preview generate --wait-build-only` \u5DF2\u79FB\u9664\uFF1B\u8BF7\u6539\u7528 `platform build run --source-version <srcver> --wait`\u3002");let autoResources=await maybeAutoApplyPreviewResources({args,context,requestedBy,sourceVersionId:explicitSourceVersionId,fromBuildId});if(fromBuildId){let preview=await context.sdk.createTenantAppPreview(context.appId,{build_id:fromBuildId}).catch(async error=>{throw await formatPreviewCommandError(context.sdk,error,{appId:context.appId,buildId:fromBuildId,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for explicit build: ${fromBuildId}`);if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:fromBuildId,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);process.stdout.write(`${JSON.stringify({auto_resources:autoResources,preview,post_check:postCheck3},null,2)}
2584
2675
  `);return}let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);printPreviewDeployResult(preview,{buildId:fromBuildId,fromBuildId,postCheck:postCheck2});return}let buildConfig=readBuildConfig2(args.options),sourceVersionId=explicitSourceVersionId,createdSourceVersionId,reusedSourceVersionId,localWorkspaceFiles=[];if((!sourceVersionId||localBuild)&&(assertSourceWorkspaceCloudUploadPolicy(context.appRoot,localBuild?"--local-build":"platform preview generate"),localWorkspaceFiles=collectSourceWorkspaceFiles(context.appRoot).files),!sourceVersionId){let sourceVersionResolution=await resolvePreviewSourceVersion({sdk:context.sdk,appId:context.appId,appRoot:context.appRoot,localFiles:localWorkspaceFiles,message:readStringOption11(args,"message")??"preview from local workspace"});sourceVersionId=sourceVersionResolution.sourceVersionId,createdSourceVersionId=sourceVersionResolution.createdSourceVersionId,reusedSourceVersionId=sourceVersionResolution.reusedSourceVersionId}if(localBuild){await runLocalBuildPreviewFlow({args,context,requestedBy,sourceVersionId,localWorkspace:localWorkspaceFiles,autoResources,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,buildConfig});return}let previewOutcome=await requestPreviewFromSourceVersion({sdk:context.sdk,appId:context.appId,appRoot:context.appRoot,sourceVersionId,buildConfig,forceBuild});if(previewOutcome.kind==="build_started"){if(!noWait){let continued=await continuePreviewAfterBuild({sdk:context.sdk,appId:context.appId,build:previewOutcome.build});if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:continued.preview.source_version_id,last_preview_build_id:continued.build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,continued.preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",auto_resources:autoResources,build:continued.build,preview:continued.preview,post_check:postCheck3,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2585
2676
  `);return}let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,continued.preview);printPreviewDeployResult(continued.preview,{buildId:continued.build.id,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,postCheck:postCheck2});return}if(args.options.json===!0){process.stdout.write(`${JSON.stringify({stage:"build_started",auto_resources:autoResources,build:previewOutcome.build,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2586
2677
  `);return}printPreviewBuildStarted(previewOutcome.build,{createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId});return}if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:previewOutcome.build.source_version_id,last_preview_build_id:previewOutcome.build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,previewOutcome.preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",auto_resources:autoResources,build:previewOutcome.build,preview:previewOutcome.preview,post_check:postCheck2,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2587
2678
  `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,previewOutcome.preview);printPreviewDeployResult(previewOutcome.preview,{buildId:previewOutcome.build.id,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,postCheck})}async function resolvePreviewSourceVersion(args){let matchedSourceVersionId=await findMatchingLocalSourceVersion(args);if(matchedSourceVersionId)return{sourceVersionId:matchedSourceVersionId,reusedSourceVersionId:matchedSourceVersionId};let submitted=await args.sdk.createTenantAppSourceVersion(args.appId,{files:args.localFiles,message:args.message}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,stage:"submit"})});return updateSourceContext(args.appRoot,{tenant_id:submitted.tenant_id,app_id:submitted.app_id,env:"preview",template_key:submitted.template_key,last_submitted_source_version_id:submitted.source_version_id,last_submitted_at:submitted.created_at}),{sourceVersionId:submitted.source_version_id,createdSourceVersionId:submitted.source_version_id}}async function findMatchingLocalSourceVersion(args){let sourceContext=readSourceContext(args.appRoot)?.sourceContext,candidateIds=collectReusableSourceVersionCandidates(sourceContext);for(let sourceVersionId of candidateIds)if(await sourceVersionMatchesLocalWorkspace(args.sdk,args.appId,sourceVersionId,args.localFiles))return sourceVersionId;let listedVersions=await args.sdk.listTenantAppSourceVersions(args.appId).then(response=>response.items.slice(0,SOURCE_VERSION_REUSE_SCAN_LIMIT).map(item=>item.source_version_id)).catch(()=>[]);for(let sourceVersionId of listedVersions)if(!candidateIds.includes(sourceVersionId)&&await sourceVersionMatchesLocalWorkspace(args.sdk,args.appId,sourceVersionId,args.localFiles))return sourceVersionId;return null}async function sourceVersionMatchesLocalWorkspace(sdk,appId,sourceVersionId,localFiles){let workspace=await sdk.getTenantAppSourceWorkspace(appId,{sourceVersionId}).catch(()=>null);return workspace?.source_version_id?sourceWorkspaceFilesEqual(localFiles,workspace.files):!1}async function findReusableSuccessfulBuild(args){let lastPreviewBuildId=readSourceContext(args.appRoot)?.sourceContext?.last_preview_build_id;if(lastPreviewBuildId){let lastPreviewBuild=await args.sdk.getBuild(lastPreviewBuildId).catch(()=>null);if(isReusableSuccessfulBuild(lastPreviewBuild,args.sourceVersionId,args.buildConfig))return lastPreviewBuild}return(await args.sdk.listBuilds(args.appId,{limit:BUILD_REUSE_SCAN_LIMIT}).then(response=>response.items).catch(()=>[])).find(build=>isReusableSuccessfulBuild(build,args.sourceVersionId,args.buildConfig))??null}async function runLocalBuildPreviewFlow(args){assertLocalBuildArgsAllowed(args.args,args.buildConfig),await assertExplicitSourceVersionMatchesWorkspace(args);let localPrecheck=await runLocalBuildSourcePrecheck(args.context.appRoot);if((readAppManifest(args.context.appRoot).manifest.template_key?.trim()||readSourceContext(args.context.appRoot)?.sourceContext.template_key?.trim())!=="frontend-app-vite")throw new Error("`platform preview generate --local-build` \u9996\u7248\u4EC5\u652F\u6301 `frontend-app-vite`\u3002");let buildPrecheck=await args.context.sdk.getBuildPrecheck(args.context.appId,{source_version_id:args.sourceVersionId,build_config:{target:"static"}});if(buildPrecheck.result==="unsupported")throw new Error(["\u5F53\u524D\u6E90\u7801\u7248\u672C\u672A\u901A\u8FC7\u5E73\u53F0\u9759\u6001\u6784\u5EFA\u9884\u68C0\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002",...buildPrecheck.issues.map(issue=>`${issue.severity}: ${issue.code} ${issue.message}`)].join(`
2588
2679
  `));let session=await args.context.sdk.createLocalBuildSession({tenant_id:args.context.tenantId,app_id:args.context.appId,source_version_id:args.sourceVersionId,requested_by:args.requestedBy,build_config:{target:"static"}}),archive=await buildLocalStaticBundleArchive(args.context.appRoot);await args.context.sdk.uploadTenantBlobBinary(session.upload.upload_session_id,{content:archive.content,content_type:"application/zip",upload_url:session.upload.upload_url,headers:session.upload.headers});let build=await args.context.sdk.completeLocalBuildSession(session.build.id,{upload_session_id:session.upload.upload_session_id,sha256:archive.sha256Hex,size_bytes:archive.content.byteLength}).catch(async error=>{throw await formatPreviewCommandError(args.context.sdk,error,{appId:args.context.appId,buildId:session.build.id,stage:"build"})}),preview=await args.context.sdk.createTenantAppPreview(args.context.appId,{build_id:build.id}).catch(async error=>{throw await formatPreviewCommandError(args.context.sdk,error,{appId:args.context.appId,buildId:build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed local build: ${build.id}`);if(updateSourceContext(args.context.appRoot,{tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:args.context.sdk,startDir:args.context.appRoot,tenantId:args.context.tenantId,appId:args.context.appId}),args.args.options.json===!0){let postCheck2=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",mode:"local_build",auto_resources:args.autoResources,local_precheck:localPrecheck,build,preview,post_check:postCheck2,...args.reusedSourceVersionId?{reused_source_version_id:args.reusedSourceVersionId}:{},...args.createdSourceVersionId?{created_source_version_id:args.createdSourceVersionId}:{}},null,2)}
2589
- `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);printPreviewDeployResult(preview,{buildId:build.id,createdSourceVersionId:args.createdSourceVersionId,reusedSourceVersionId:args.reusedSourceVersionId,requestedSourceVersionId:args.requestedSourceVersionId,postCheck})}function assertLocalBuildArgsAllowed(args,buildConfig){if(readStringOption11(args,"from-build"))throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--from-build`\u3002");if(args.options["force-build"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--force-build`\uFF1B\u672C\u5730\u6A21\u5F0F\u9ED8\u8BA4\u6BCF\u6B21\u90FD\u91CD\u65B0\u6784\u5EFA\u3002");if(args.options["no-wait"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--no-wait`\u3002");if(buildConfig.dockerfile_path||buildConfig.context_subdir)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--dockerfile` \u6216 `--context-subdir`\u3002");if(buildConfig.target&&buildConfig.target!=="static")throw new Error("`platform preview generate --local-build` \u4EC5\u652F\u6301\u9759\u6001\u76EE\u6807\u3002")}async function assertExplicitSourceVersionMatchesWorkspace(args){if(!args.requestedSourceVersionId)return;let workspace=await args.context.sdk.getTenantAppSourceWorkspace(args.context.appId,{sourceVersionId:args.sourceVersionId});if(!sourceWorkspaceFilesEqual(args.localWorkspace,workspace.files))throw new Error("\u663E\u5F0F `--source-version` \u4E0E\u5F53\u524D\u672C\u5730\u5DE5\u4F5C\u533A\u4E0D\u4E00\u81F4\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002")}async function runLocalBuildSourcePrecheck(appRoot){let stats=assertSourceWorkspaceCloudUploadPolicy(appRoot,"--local-build");return{source_bytes:stats.sourceBytes,asset_hits:stats.assetHits}}async function buildLocalStaticBundleArchive(appRoot){await runLocalBuildCommand(appRoot);let outputDir=resolve17(appRoot,"dist");if(!await pathExists(join19(outputDir,"index.html")))throw new Error("\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/index.html`\uFF0C\u4E0D\u80FD\u6267\u884C\u4E0A\u4F20\u3002");await validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir);let zipped=await createZipArchiveBuffer(outputDir),sha256Hex=createHash10("sha256").update(zipped).digest("hex");return{content:zipped,sha256Hex}}async function validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir){let sourceRegistryPath=join19(appRoot,"page-render","registry.json");if(!await pathExists(sourceRegistryPath))return;let distRegistryPath=join19(outputDir,"page-render","registry.json"),distAssetsManifestPath=join19(outputDir,"page-render","assets-manifest.json");if(!await pathExists(distRegistryPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/registry.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");if(!await pathExists(distAssetsManifestPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/assets-manifest.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");await parseJsonFileOrThrow(distRegistryPath,"dist/page-render/registry.json"),await parseJsonFileOrThrow(distAssetsManifestPath,"dist/page-render/assets-manifest.json")}async function runLocalBuildCommand(appRoot){let packageJson=JSON.parse(await readFile2(join19(appRoot,"package.json"),"utf8")),hasPnpmLock=await pathExists(join19(appRoot,"pnpm-lock.yaml")),hasYarnLock=await pathExists(join19(appRoot,"yarn.lock")),packageManager=typeof packageJson.packageManager=="string"?packageJson.packageManager:"",command=packageManager.startsWith("pnpm@")||hasPnpmLock?["corepack","pnpm","run","build"]:packageManager.startsWith("yarn@")||hasYarnLock?["corepack","yarn","run","build"]:["npm","run","build"];await runSubprocess(command[0],command.slice(1),appRoot)}async function runSubprocess(command,commandArgs,cwd){await new Promise((resolvePromise,rejectPromise)=>{if(command!=="corepack"&&command!=="npm"){rejectPromise(new Error(`\u4E0D\u652F\u6301\u7684\u672C\u5730\u6784\u5EFA\u547D\u4EE4: ${command}`));return}let child=spawnCrossPlatform(command,commandArgs,{cwd,stdio:"inherit",env:{...process.env,NODE_ENV:"development",NPM_CONFIG_PRODUCTION:"false",npm_config_production:"false"}});child.on("error",rejectPromise),child.on("exit",code2=>{if(code2===0){resolvePromise();return}rejectPromise(new Error(`\u672C\u5730\u6784\u5EFA\u5931\u8D25: ${command} ${commandArgs.join(" ")} (exit ${code2??"unknown"})`))})})}async function createZipArchiveBuffer(targetDir){return createZipBuffer(targetDir)}async function pathExists(targetPath){try{return await stat(targetPath),!0}catch{return!1}}async function parseJsonFileOrThrow(filePath,label){let raw=await readFile2(filePath,"utf8");try{return JSON.parse(raw)}catch(error){throw new Error(`${label} \u4E0D\u662F\u5408\u6CD5 JSON: ${error instanceof Error?error.message:String(error)}`)}}async function requestPreviewFromSourceVersion(args){try{let preview=await args.sdk.createTenantAppPreview(args.appId,{source_version_id:args.sourceVersionId,...Object.keys(args.buildConfig).length>0?{build_config:args.buildConfig}:{},...args.forceBuild?{force_rebuild:!0}:{}});return isPreviewBuildPendingResponse(preview)?{kind:"build_started",build:await args.sdk.getBuild(preview.build_id).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:preview.build_id,stage:"build"})})}:{kind:"preview_completed",build:preview.build_id?await args.sdk.getBuild(preview.build_id):await loadPreviewBuildBySourceVersion(args),preview}}catch(error){throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,sourceVersionId:args.sourceVersionId,stage:"preview"})}}async function continuePreviewAfterBuild(args){let completedBuild=await waitForPreviewBuild(args.sdk,args.build.id);if(completedBuild.status==="cancelled"){let reusedBuildId=extractReusedBuildId2(completedBuild);if(reusedBuildId){let reusedBuild=await args.sdk.getBuild(reusedBuildId).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:reusedBuildId,stage:"build"})});return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:reusedBuild})}}return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:completedBuild})}async function createPreviewFromBuild(args){if(args.build.status!=="succeeded")throw formatPreviewBuildNotReadyError(args.build);let preview=await args.sdk.createTenantAppPreview(args.appId,{build_id:args.build.id}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,buildId:args.build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed build: ${args.build.id}`);return{build:args.build,preview}}async function waitForPreviewBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??PREVIEW_BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??PREVIEW_BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus2(build.status))return build;if(Date.now()-startedAt>=timeoutMs)throw formatPreviewBuildTimeoutError(build,timeoutMs);await sleep5(intervalMs)}}function isTerminalBuildStatus2(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId2(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function formatPreviewBuildNotReadyError(build){let lines=["Preview \u672A\u7EE7\u7EED\u53D1\u5E03\uFF0C\u56E0\u4E3A build \u672A\u6210\u529F\u5B8C\u6210\u3002",`build: ${build.id}`,`status: ${build.status}`,...build.error_code?[`error_code: ${build.error_code}`]:[],...build.error_message?[`error_message: ${build.error_message}`]:[],...build.log_ref?[`log_ref: ${build.log_ref}`]:[],`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u6216 \`platform build events ${build.id}\` \u7EE7\u7EED\u6392\u67E5\u3002`];return new Error(lines.join(`
2680
+ `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);printPreviewDeployResult(preview,{buildId:build.id,createdSourceVersionId:args.createdSourceVersionId,reusedSourceVersionId:args.reusedSourceVersionId,requestedSourceVersionId:args.requestedSourceVersionId,postCheck})}function assertLocalBuildArgsAllowed(args,buildConfig){if(readStringOption11(args,"from-build"))throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--from-build`\u3002");if(args.options["force-build"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--force-build`\uFF1B\u672C\u5730\u6A21\u5F0F\u9ED8\u8BA4\u6BCF\u6B21\u90FD\u91CD\u65B0\u6784\u5EFA\u3002");if(args.options["no-wait"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--no-wait`\u3002");if(buildConfig.dockerfile_path||buildConfig.context_subdir)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--dockerfile` \u6216 `--context-subdir`\u3002");if(buildConfig.target&&buildConfig.target!=="static")throw new Error("`platform preview generate --local-build` \u4EC5\u652F\u6301\u9759\u6001\u76EE\u6807\u3002")}async function assertExplicitSourceVersionMatchesWorkspace(args){if(!args.requestedSourceVersionId)return;let workspace=await args.context.sdk.getTenantAppSourceWorkspace(args.context.appId,{sourceVersionId:args.sourceVersionId});if(!sourceWorkspaceFilesEqual(args.localWorkspace,workspace.files))throw new Error("\u663E\u5F0F `--source-version` \u4E0E\u5F53\u524D\u672C\u5730\u5DE5\u4F5C\u533A\u4E0D\u4E00\u81F4\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002")}async function runLocalBuildSourcePrecheck(appRoot){let stats=assertSourceWorkspaceCloudUploadPolicy(appRoot,"--local-build");return{source_bytes:stats.sourceBytes,asset_hits:stats.assetHits}}async function buildLocalStaticBundleArchive(appRoot){await runLocalBuildCommand(appRoot);let outputDir=resolve18(appRoot,"dist");if(!await pathExists(join22(outputDir,"index.html")))throw new Error("\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/index.html`\uFF0C\u4E0D\u80FD\u6267\u884C\u4E0A\u4F20\u3002");await validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir);let zipped=await createZipArchiveBuffer(outputDir),sha256Hex=createHash12("sha256").update(zipped).digest("hex");return{content:zipped,sha256Hex}}async function validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir){let sourceRegistryPath=join22(appRoot,"page-render","registry.json");if(!await pathExists(sourceRegistryPath))return;let distRegistryPath=join22(outputDir,"page-render","registry.json"),distAssetsManifestPath=join22(outputDir,"page-render","assets-manifest.json");if(!await pathExists(distRegistryPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/registry.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");if(!await pathExists(distAssetsManifestPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/assets-manifest.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");await parseJsonFileOrThrow(distRegistryPath,"dist/page-render/registry.json"),await parseJsonFileOrThrow(distAssetsManifestPath,"dist/page-render/assets-manifest.json")}async function runLocalBuildCommand(appRoot){let packageJson=JSON.parse(await readFile2(join22(appRoot,"package.json"),"utf8")),hasPnpmLock=await pathExists(join22(appRoot,"pnpm-lock.yaml")),hasYarnLock=await pathExists(join22(appRoot,"yarn.lock")),packageManager=typeof packageJson.packageManager=="string"?packageJson.packageManager:"",command=packageManager.startsWith("pnpm@")||hasPnpmLock?["corepack","pnpm","run","build"]:packageManager.startsWith("yarn@")||hasYarnLock?["corepack","yarn","run","build"]:["npm","run","build"];await runSubprocess(command[0],command.slice(1),appRoot)}async function runSubprocess(command,commandArgs,cwd){await new Promise((resolvePromise,rejectPromise)=>{if(command!=="corepack"&&command!=="npm"){rejectPromise(new Error(`\u4E0D\u652F\u6301\u7684\u672C\u5730\u6784\u5EFA\u547D\u4EE4: ${command}`));return}let child=spawnCrossPlatform(command,commandArgs,{cwd,stdio:"inherit",env:{...process.env,NODE_ENV:"development",NPM_CONFIG_PRODUCTION:"false",npm_config_production:"false"}});child.on("error",rejectPromise),child.on("exit",code2=>{if(code2===0){resolvePromise();return}rejectPromise(new Error(`\u672C\u5730\u6784\u5EFA\u5931\u8D25: ${command} ${commandArgs.join(" ")} (exit ${code2??"unknown"})`))})})}async function createZipArchiveBuffer(targetDir){return createZipBuffer(targetDir)}async function pathExists(targetPath){try{return await stat(targetPath),!0}catch{return!1}}async function parseJsonFileOrThrow(filePath,label){let raw=await readFile2(filePath,"utf8");try{return JSON.parse(raw)}catch(error){throw new Error(`${label} \u4E0D\u662F\u5408\u6CD5 JSON: ${error instanceof Error?error.message:String(error)}`)}}async function requestPreviewFromSourceVersion(args){try{let preview=await args.sdk.createTenantAppPreview(args.appId,{source_version_id:args.sourceVersionId,...Object.keys(args.buildConfig).length>0?{build_config:args.buildConfig}:{},...args.forceBuild?{force_rebuild:!0}:{}});return isPreviewBuildPendingResponse(preview)?{kind:"build_started",build:await args.sdk.getBuild(preview.build_id).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:preview.build_id,stage:"build"})})}:{kind:"preview_completed",build:preview.build_id?await args.sdk.getBuild(preview.build_id):await loadPreviewBuildBySourceVersion(args),preview}}catch(error){throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,sourceVersionId:args.sourceVersionId,stage:"preview"})}}async function continuePreviewAfterBuild(args){let completedBuild=await waitForPreviewBuild(args.sdk,args.build.id);if(completedBuild.status==="cancelled"){let reusedBuildId=extractReusedBuildId2(completedBuild);if(reusedBuildId){let reusedBuild=await args.sdk.getBuild(reusedBuildId).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:reusedBuildId,stage:"build"})});return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:reusedBuild})}}return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:completedBuild})}async function createPreviewFromBuild(args){if(args.build.status!=="succeeded")throw formatPreviewBuildNotReadyError(args.build);let preview=await args.sdk.createTenantAppPreview(args.appId,{build_id:args.build.id}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,buildId:args.build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed build: ${args.build.id}`);return{build:args.build,preview}}async function waitForPreviewBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??PREVIEW_BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??PREVIEW_BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus2(build.status))return build;if(Date.now()-startedAt>=timeoutMs)throw formatPreviewBuildTimeoutError(build,timeoutMs);await sleep5(intervalMs)}}function isTerminalBuildStatus2(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId2(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function formatPreviewBuildNotReadyError(build){let lines=["Preview \u672A\u7EE7\u7EED\u53D1\u5E03\uFF0C\u56E0\u4E3A build \u672A\u6210\u529F\u5B8C\u6210\u3002",`build: ${build.id}`,`status: ${build.status}`,...build.error_code?[`error_code: ${build.error_code}`]:[],...build.error_message?[`error_message: ${build.error_message}`]:[],...build.log_ref?[`log_ref: ${build.log_ref}`]:[],`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u6216 \`platform build events ${build.id}\` \u7EE7\u7EED\u6392\u67E5\u3002`];return new Error(lines.join(`
2590
2681
  `))}function formatPreviewBuildTimeoutError(build,timeoutMs){return new Error(["Preview \u7B49\u5F85 build \u8D85\u65F6\uFF0C\u5C1A\u672A\u81EA\u52A8\u7EE7\u7EED\u53D1\u5E03\u3002",`build: ${build.id}`,`status: ${build.status}`,`timeout_ms: ${timeoutMs}`,`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u89C2\u5BDF\u72B6\u6001\uFF1B\u5982\u5DF2\u6210\u529F\uFF0C\u53EF\u6267\u884C \`platform preview generate --from-build ${build.id}\`\u3002`].join(`
2591
- `))}function sleep5(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}async function loadPreviewBuildBySourceVersion(args){let build=await findReusableSuccessfulBuild({sdk:args.sdk,appId:args.appId,appRoot:args.appRoot,sourceVersionId:args.sourceVersionId,buildConfig:args.buildConfig});if(!build)throw new Error(`preview \u5DF2\u521B\u5EFA\uFF0C\u4F46\u672A\u80FD\u5B9A\u4F4D\u5BF9\u5E94 build: ${args.appId}/${args.sourceVersionId}`);return build}function collectReusableSourceVersionCandidates(sourceContext){return Array.from(new Set([sourceContext?.last_preview_source_version_id,sourceContext?.last_submitted_source_version_id,sourceContext?.base_source_version_id].filter(value=>typeof value=="string"&&value.length>0)))}function sourceWorkspaceFilesEqual(localFiles,remoteFiles){if(localFiles.length!==remoteFiles.length)return!1;for(let index=0;index<localFiles.length;index+=1){let local=localFiles[index],remote=remoteFiles[index];if(!remote||local.path!==remote.path||local.content!==remote.content)return!1}return!0}function isReusableSuccessfulBuild(build,sourceVersionId,buildConfig){return!build||build.status!=="succeeded"||build.lifecycle_status&&build.lifecycle_status!=="active"||build.source_version_id!==sourceVersionId?!1:buildConfigEqual(build.build_config,buildConfig)}function buildConfigEqual(left,right){return normalizeBuildConfig(left).key===normalizeBuildConfig(right).key}function normalizeBuildConfig(buildConfig){let normalized={...buildConfig?.dockerfile_path?{dockerfile_path:buildConfig.dockerfile_path}:{},...buildConfig?.context_subdir?{context_subdir:buildConfig.context_subdir}:{},...buildConfig?.target?{target:buildConfig.target}:{}};return{...normalized,key:JSON.stringify(normalized)}}async function maybeAutoApplyPreviewResources(args){let skipReason=resolvePreviewAutoResourcesSkipReason(args.args.options);if(skipReason)return{status:"skipped",reason:skipReason};let localResources=await collectEffectiveResources(args.context.appRoot,{sdk:args.context.sdk,appId:args.context.appId});if(localResources.length===0)return{status:"skipped",reason:"no_local_resources"};let payload={operation:"diff",tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",requested_by:args.requestedBy,local_resources:localResources},diff=await args.context.sdk.diffResources(payload).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"diff"})});if(diff.summary.added===0&&diff.summary.modified===0&&diff.summary.deleted===0)return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u662F\u6700\u65B0\uFF0C\u8DF3\u8FC7\u81EA\u52A8 apply\u3002\u57FA\u7EBF\u5FEB\u7167: ${diff.base_snapshot_id}
2682
+ `))}function sleep5(ms){return new Promise(resolve20=>{setTimeout(resolve20,ms)})}async function loadPreviewBuildBySourceVersion(args){let build=await findReusableSuccessfulBuild({sdk:args.sdk,appId:args.appId,appRoot:args.appRoot,sourceVersionId:args.sourceVersionId,buildConfig:args.buildConfig});if(!build)throw new Error(`preview \u5DF2\u521B\u5EFA\uFF0C\u4F46\u672A\u80FD\u5B9A\u4F4D\u5BF9\u5E94 build: ${args.appId}/${args.sourceVersionId}`);return build}function collectReusableSourceVersionCandidates(sourceContext){return Array.from(new Set([sourceContext?.last_preview_source_version_id,sourceContext?.last_submitted_source_version_id,sourceContext?.base_source_version_id].filter(value=>typeof value=="string"&&value.length>0)))}function sourceWorkspaceFilesEqual(localFiles,remoteFiles){if(localFiles.length!==remoteFiles.length)return!1;for(let index=0;index<localFiles.length;index+=1){let local=localFiles[index],remote=remoteFiles[index];if(!remote||local.path!==remote.path||local.content!==remote.content)return!1}return!0}function isReusableSuccessfulBuild(build,sourceVersionId,buildConfig){return!build||build.status!=="succeeded"||build.lifecycle_status&&build.lifecycle_status!=="active"||build.source_version_id!==sourceVersionId?!1:buildConfigEqual(build.build_config,buildConfig)}function buildConfigEqual(left,right){return normalizeBuildConfig(left).key===normalizeBuildConfig(right).key}function normalizeBuildConfig(buildConfig){let normalized={...buildConfig?.dockerfile_path?{dockerfile_path:buildConfig.dockerfile_path}:{},...buildConfig?.context_subdir?{context_subdir:buildConfig.context_subdir}:{},...buildConfig?.target?{target:buildConfig.target}:{}};return{...normalized,key:JSON.stringify(normalized)}}async function maybeAutoApplyPreviewResources(args){let skipReason=resolvePreviewAutoResourcesSkipReason(args.args.options);if(skipReason)return{status:"skipped",reason:skipReason};let localResources=await collectEffectiveResources(args.context.appRoot,{sdk:args.context.sdk,appId:args.context.appId});if(localResources.length===0)return{status:"skipped",reason:"no_local_resources"};let payload={operation:"diff",tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",requested_by:args.requestedBy,local_resources:localResources},diff=await args.context.sdk.diffResources(payload).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"diff"})});if(diff.summary.added===0&&diff.summary.modified===0&&diff.summary.deleted===0)return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u662F\u6700\u65B0\uFF0C\u8DF3\u8FC7\u81EA\u52A8 apply\u3002\u57FA\u7EBF\u5FEB\u7167: ${diff.base_snapshot_id}
2592
2683
  `),{status:"no_changes",base_snapshot_id:diff.base_snapshot_id,summary:diff.summary};let applyPayload={...payload,operation:"apply"},applyResult=await withPendingFeedback2(args.args.options.json===!0,`\u68C0\u6D4B\u5230 preview \u5B58\u5728\u672A\u5E94\u7528\u8D44\u6E90\u53D8\u66F4\uFF0C\u5DF2\u81EA\u52A8\u6267\u884C resources apply: ${args.context.appId}/preview`,"preview \u8D44\u6E90 apply \u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u57FA\u7EBF\u89E3\u6790\u3001diff \u4E0E\u8D44\u6E90\u7F16\u6392...",()=>args.context.sdk.applyResources(applyPayload)).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"apply",baseSnapshotId:diff.base_snapshot_id})});if(applyResult.status!=="succeeded")throw new Error([`preview \u8D44\u6E90\u81EA\u52A8 apply \u672A\u6210\u529F: ${args.context.appId}/preview`,`status: ${applyResult.status}`,`base_snapshot: ${applyResult.base_snapshot_id}`,...applyResult.result_snapshot_id?[`result_snapshot: ${applyResult.result_snapshot_id}`]:[],...applyResult.errors&&applyResult.errors.length>0?[`errors: ${applyResult.errors.join(" | ")}`]:[]].join(`
2593
2684
  `));return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u81EA\u52A8\u8865\u9F50\uFF1A\u65B0\u589E ${applyResult.summary.added}\uFF0C\u4FEE\u6539 ${applyResult.summary.modified}\uFF0C\u5220\u9664 ${applyResult.summary.deleted}
2594
2685
  `),{status:"applied",base_snapshot_id:applyResult.base_snapshot_id,result_snapshot_id:applyResult.result_snapshot_id,summary:applyResult.summary}}function resolvePreviewAutoResourcesSkipReason(options){return options["no-apply-resources"]===!0?"disabled":null}async function runPreviewOpenCommand(args){let context=await loadPreviewContext(args),sourceVersionId=readStringOption11(args,"source-version"),timeline=await context.sdk.listTenantAppDeploymentTimeline(context.appId,{limit:50}),previewItem=findOpenablePreviewDeployment(timeline.items,sourceVersionId);if(!previewItem?.preview_url)throw sourceVersionId?new Error([`\u672A\u627E\u5230\u53EF\u6253\u5F00\u7684 Preview: ${sourceVersionId}`,"\u8BF4\u660E\uFF1A\u8BE5\u7248\u672C\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684 Preview \u5730\u5740\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A\u5148\u6267\u884C `platform preview generate --source-version <srcver>`\u3002"].join(`
@@ -2607,8 +2698,8 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2607
2698
  `))}function resolveExplicitPreviewMode(args){let subcommand=args.rest[0];if(subcommand==="generate"||subcommand==="open")return subcommand}function resolvePreviewMode(args){let explicitMode=resolveExplicitPreviewMode(args);return explicitMode||(hasGenerateOnlyOptions(args.options)?"generate":"open")}function hasGenerateOnlyOptions(options){return["from-build","no-wait","no-apply-resources","dockerfile","context-subdir","target","local-build","build-mode","force-build","message"].some(key=>key in options)}function isPreviewBuildPendingResponse(value){return!value||typeof value!="object"?!1:"operation"in value&&value.operation==="deploy"&&"env"in value&&value.env==="preview"&&"status"in value&&value.status==="building"&&"build_id"in value&&typeof value.build_id=="string"&&value.build_id.length>0}function findOpenablePreviewDeployment(items,sourceVersionId){for(let item of items)if(item.env==="preview"&&item.preview_url&&item.deployment_status==="succeeded"&&!(sourceVersionId&&item.source_version_id!==sourceVersionId))return item;return null}async function withPendingFeedback2(jsonOutput,startMessage,waitingMessage,action){if(jsonOutput)return action();process.stderr.write(`${startMessage}
2608
2699
  `);let timer=setTimeout(()=>{process.stderr.write(`${waitingMessage}
2609
2700
  `)},1500);try{return await action()}finally{clearTimeout(timer)}}async function formatPreviewAutoResourcesError(sdk,error,context){if(!(error instanceof PlatformApiError))return error instanceof Error?error:new Error("preview \u81EA\u52A8\u8D44\u6E90 apply \u5931\u8D25");let lines=[`preview \u81EA\u52A8\u8D44\u6E90 ${context.stage} \u5931\u8D25: ${context.appId}/${context.env}`,`code: ${error.code}`,`message: ${error.message}`];return context.baseSnapshotId&&lines.push(`base_snapshot: ${context.baseSnapshotId}`),error.requestId&&lines.push(`request_id: ${error.requestId}`),error.detail&&lines.push(`detail: ${JSON.stringify(error.detail)}`),lines.push(...await buildPreviewBindingHintLines(sdk,context.appId,context.env)),lines.push("\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A\u53EF\u6539\u7528 `platform preview generate --no-apply-resources` \u8DF3\u8FC7\u81EA\u52A8 apply\uFF0C\u6216\u5148\u624B\u52A8\u6267\u884C `platform resources diff/apply --env preview`\u3002"),lines.push("\u8865\u5145\u5EFA\u8BAE\uFF1A\u6267\u884C `platform app diagnose --env preview`\uFF0C\u786E\u8BA4\u5F53\u524D preview \u662F\u5426\u5DF2\u7ECF ready for runtime validation\u3002"),new Error(lines.join(`
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(`
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(`
2701
+ `))}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 join23}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(`
2702
+ `)}function formatCliStateAccessHint(options={}){let recommendedStateDir=options.workspaceRoot?join23(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(`
2612
2703
  `)):(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(`
2613
2704
  `))}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
2705
  `):["\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(`
@@ -2626,7 +2717,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2626
2717
  `)}async function withPendingFeedback3(jsonOutput,startMessage,waitingMessage,action){if(jsonOutput)return action();process.stderr.write(`${startMessage}
2627
2718
  `);let timer=setTimeout(()=>{process.stderr.write(`${waitingMessage}
2628
2719
  `)},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(`
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)}
2720
+ `))}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 readFileSync28}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)}
2630
2721
  `);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)}
2631
2722
  `);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)}
2632
2723
  `);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)}
@@ -2641,22 +2732,36 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2641
2732
  `)}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)}
2642
2733
  `);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)}
2643
2734
  `);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)}
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(`
2735
+ `);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(readFileSync28(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(`
2645
2736
  `)}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)}
2646
2737
  `):process.stderr.write(`worker \u672A\u5B9E\u73B0: ${worker}
2647
2738
  \u5F53\u524D\u5DF2\u5B9E\u73B0: ${[...implementedWorkers].join(", ")}
2648
2739
  `),process.exitCode=1;return}await spawnControlApiWorker([worker,...serializeOptions(args.options)])}function printWorkerHelp(){process.stdout.write(["platform worker","","\u7528\u6CD5\uFF1A"," platform worker preview-retention [--once] [--dry-run] [--tenant <tenant-id>] [--app <app-id>] [--ttl-hours <n>] [--limit <n>] [--json]","","\u8BF4\u660E\uFF1A"," worker \u547D\u4EE4\u662F\u672C\u5730\u5F00\u53D1/\u8FD0\u7EF4\u5165\u53E3\uFF0C\u4F1A\u8F6C\u4EA4\u7ED9 @platform/control-api \u7684 worker \u5B9E\u73B0\u3002"," preview-retention \u9ED8\u8BA4\u4EE5\u524D\u53F0\u5E38\u9A7B worker \u8FD0\u884C\uFF1B\u52A0 --once \u65F6\u53EA\u6267\u884C\u4E00\u6B21\u3002",""].join(`
2649
- `))}function serializeOptions(options){let result=[];for(let[key,value]of Object.entries(options))key==="help"||key==="h"||(result.push(`--${key}`),typeof value=="string"&&result.push(value));return result}async function spawnControlApiWorker(args){await new Promise((resolve19,reject)=>{let child=spawn4("corepack",["pnpm","--silent","--filter","@platform/control-api","worker",...args],{stdio:"inherit"});child.on("error",reject),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`control-api worker exited by signal ${signal}`));return}code2&&code2!==0&&(process.exitCode=code2),resolve19()})})}applyStoredEnvironmentProfile();applyDistributionProfileDefaults();loadDotenvFiles();var distributionProfile=getDistributionProfile(),cliPackageVersion=getCliPackageVersion();function persistActiveTenantSelection(tenant){let currentContext=loadStoredCliContext();persistCliContext({active_tenant_id:tenant.tenant_id,active_tenant_name:tenant.name,selected_app_tenant_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_tenant_id,selected_app_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_id,selected_app_env:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_env,selected_app_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_name,selected_app_display_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_display_name})}function currentInvocationDir(){return getInvocationCwd()}function parseArgs5(argv){let[command="help",...rest]=argv,options={},positionals=[];for(let index=0;index<rest.length;index+=1){let current=rest[index];if(current==="--help"){options.help=!0;continue}if(current==="-h"){options.h=!0;continue}if(!current.startsWith("--")){positionals.push(current);continue}let[key,inlineValue]=current.slice(2).split("=",2);if(inlineValue!==void 0){options[key]=inlineValue;continue}let next=rest[index+1];if(next&&!next.startsWith("--")){options[key]=next,index+=1;continue}options[key]=!0}return{command,rest:positionals,options}}function printHelp(){let envCommandLines=distributionProfile.name!=="developer"?[]:[" env use <profile> \u5207\u6362 CLI \u73AF\u5883 profile\uFF08\u5982 local / test\uFF09"," env current \u67E5\u770B\u5F53\u524D CLI \u73AF\u5883 profile"," env list \u67E5\u770B\u53EF\u7528 CLI \u73AF\u5883 profile"];process7.stdout.write(["platform <command>","","Commands:"," login \u5168\u5C40\u767B\u5F55\u5E76\u4FDD\u5B58\u51ED\u636E"," version \u8F93\u51FA\u5F53\u524D CLI \u7248\u672C\u53F7"," app create \u5728\u4E91\u7AEF\u521B\u5EFA\u5E94\u7528\uFF0C\u5E76 checkout \u5230\u672C\u5730\u65B0\u76EE\u5F55"," app checkout \u4ECE\u4E91\u7AEF checkout \u5E94\u7528\u6E90\u7801\u526F\u672C\u5230\u672C\u5730\u65B0\u76EE\u5F55"," app submit \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u63D0\u4EA4\u4E3A\u65B0\u7684\u4E91\u7AEF\u6E90\u7801\u7248\u672C"," app version create \u5728\u5F53\u524D app \u4E0B\u57FA\u4E8E\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C\u9AA8\u67B6"," app version list \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app versions \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app status \u67E5\u770B\u5E94\u7528\u63A7\u5236\u9762\u603B\u89C8\uFF08\u542B Auth / DB / \u7248\u672C\u6982\u51B5\uFF09"," app diagnose \u67E5\u770B\u5E94\u7528\u662F\u5426\u5DF2 ready for runtime validation"," app preflight \u4E00\u6B21\u6027\u6267\u884C whoami / app current / app diagnose \u98CE\u683C\u68C0\u67E5"," app sync-platform-blocks \u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\uFF08dry-run / adopt / apply / rollback --last\uFF09"," app import preprocess \u9884\u5904\u7406\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u751F\u6210 clean-source \u4E0E\u62A5\u544A"," app import stage \u628A clean-source \u4E0E\u62A5\u544A stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," app import merge \u628A\u4E0A\u6E38 src \u5B89\u5168\u5E76\u5165 src/imported-upstream/"," app scaffold \u6309\u9700\u6CE8\u5165\u672C\u5730 debug scaffold\uFF08auth/workflow/cms/db\uFF09"," app-library \u7BA1\u7406\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93 example-app \u6761\u76EE"," app use \u517C\u5BB9\u8DEF\u5F84\uFF1A\u4E3A init/link/dev \u9009\u62E9\u76EE\u6807\u5E94\u7528"," app current \u67E5\u770B\u5F53\u524D\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587"," tenant use <id> \u8BBE\u7F6E\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587"," tenant current \u67E5\u770B\u5F53\u524D\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587",...envCommandLines," whoami \u8C03\u7528 Control API \u8F93\u51FA\u5F53\u524D\u4E3B\u4F53"," preview \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u53EF\u7528 Preview\uFF1B\u751F\u6210\u8BF7\u7528 `platform preview generate`"," init [name] \u751F\u6210\u9879\u76EE\u9AA8\u67B6\uFF0C\u5E76\u81EA\u52A8\u5199\u5165\u5DF2\u9009\u5E94\u7528\u7ED1\u5B9A"," link \u7ED1\u5B9A tenant/app/env \u5230\u5F53\u524D\u5E94\u7528\u76EE\u5F55"," dev \u9ED8\u8BA4\u8F7B\u91CF\u5F00\u53D1\u5165\u53E3\uFF1A\u6CE8\u5165\u7ED1\u5B9A\u540E\u542F\u52A8\u672C\u5730\u5F00\u53D1\u6001"," dev push \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u8986\u76D6\u63A8\u9001\u5230\u4E91\u7AEF Dev Workspace"," dev preview generate \u57FA\u4E8E\u4E91\u7AEF Dev Workspace \u751F\u6210\u5DE5\u4F5C\u533A Preview"," auth \u7BA1\u7406 Auth \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / bind / inspect\uFF09"," cms \u7BA1\u7406 CMS \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / apply / inspect\uFF09"," asset \u7BA1\u7406\u79DF\u6237\u5171\u4EAB\u7D20\u6750\uFF08upload / list / folder / get / update / analyze / move / open / tag\uFF09"," blob \u7BA1\u7406 Object Storage Blob\uFF08upload / list / get / url\uFF09"," db \u67E5\u770B DB \u72B6\u6001\u3001\u8868\u7ED3\u6784\u4E0E\u53EA\u8BFB\u67E5\u8BE2"," data-form \u6821\u9A8C/\u7F16\u8BD1/apply/query Data Form schema \u4E0E\u8BB0\u5F55"," workflow \u7BA1\u7406 Workflow \u57FA\u5EA7\u80FD\u529B\uFF08template / definition / binding / runtime\uFF09"," notification \u7BA1\u7406 Notification \u57FA\u5EA7\u80FD\u529B\uFF08inbox / announce / delivery\uFF09"," publish \u7BA1\u7406\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," resources \u6267\u884C\u8D44\u6E90 diff/apply/rollback"," logs \u67E5\u8BE2\u8FD0\u884C\u65F6\u65E5\u5FD7\uFF0C\u652F\u6301 --follow"," diagnostics \u5E73\u53F0\u672C\u5730\u8BCA\u65AD\uFF08control-api endpoint / readiness\uFF09"," worker \u542F\u52A8\u5E73\u53F0\u540E\u53F0 worker\uFF08preview-retention\uFF09","","Advanced commands:"," build \u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\uFF1A\u53D1\u8D77\u548C\u67E5\u8BE2 build"," deploy \u8FC7\u6E21\u5165\u53E3\uFF1A\u9AD8\u7EA7\u53D1\u5E03\uFF08artifact / promote\uFF09"," rollback \u8FC7\u6E21\u5165\u53E3\uFF1A\u56DE\u6EDA\u5230\u76EE\u6807 release \u6216\u7248\u672C","","App commands:"," platform app create --tenant <tenant-id> --name <display-name> --dir <project-name> [--template frontend-app-vite|backend-app-node]"," platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," platform app checkout --tenant <tenant-id> --app <app-id> --source-version <srcver>",' platform app submit --message "local iteration"',' platform app version create --message "switch template" --template backend-app-node'," platform app versions --tenant <tenant-id> --app <app-id>"," platform app status [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app sync-platform-blocks [--dry-run|--adopt|--apply|--rollback --last]"," platform app diagnose [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run]"," platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>"," platform app import merge [--workspace-dir <template-workspace-dir>]"," platform app scaffold <auth-debug|workflow-debug|cms-debug|db-debug>"," platform app-library list"," platform app-library config init"," platform app-library inspect entry-demo"," platform app-library checkout entry-demo --dir ./example-app-demo",' platform app-library create --name "Data Form Verify" --summary "\u672C\u5730\u9A8C\u8BC1\u540E\u7684\u793A\u4F8B\u5E94\u7528"'," platform app-library submit entry-demo"," platform app use --tenant <tenant-id> --app <app-id> --env preview"," platform app current","","DB commands:"," platform db status"," platform db history --limit 10"," platform db migrate [--dry-run]"," platform db tables",' platform db query --sql "SELECT ... LIMIT 5"'," platform db open","","Auth commands:"," platform auth discover [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth configure [--tenant <tenant-id>] [--app <app-id>] --enable [--template <template>] [--user-store-id <id>] [--enable-admin-password|--disable-admin-password] [--enable-phone-sms-otp|--disable-phone-sms-otp] [--json]"," platform auth bind [--tenant <tenant-id>] [--app <app-id>] [--action bind|rebind|disable] [--user-store-id <id>] [--json]"," platform auth inspect [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role list [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role create [--tenant <tenant-id>] [--app <app-id>] --key <role-key> --name <display-name> [--description <text>] [--status active|disabled] [--json]"," platform auth role inspect [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--json]"," platform auth role update [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--name <display-name>] [--description <text> | --clear-description] [--status active|disabled] [--json]"," platform auth user-role list [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> [--json]"," platform auth user-role assign [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role replace [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role remove [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --role <role-key> [--json]","","CMS commands:"," platform cms discover [--collection <name>] [--json]"," platform cms configure collection --file <spec.json> [--json]"," platform cms configure item --file <item.json> [--item-id <item-id>] [--json]"," platform cms configure category --collection <name> --name <name> --slug <slug> [--parent-id <id>] [--order <n>] [--json]"," platform cms import markdown <file> [--collection <name>] [--item-id <item-id> | --item-id-prefix <prefix>] [--tags <label,label>] [--category-path <segment/segment>] [--cover-asset-id <asset-id>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--dry-run] [--json]"," platform cms import url <url> [--collection <name>] [--item-id <item-id>] [--tags <label,label>] [--category-path <segment/segment>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--no-assetize-images] [--dry-run] [--json]"," platform cms attach asset --collection <name> --item-id <id> --field <field-name> --asset-id <id[,id]> [--replace] [--json]"," platform cms ensure category --collection <name> --path <segment/segment> [--json]"," platform cms list items --collection <name> [--page <n>] [--page-size <n>] [--status draft|published|archived] [--category-id <id>] [--q <keyword>] [--json]"," platform cms batch update --collection <name> --item-id <id[,id]> [--category-id <id> | --clear-category] [--add-tags <label,label>] [--status draft|published|archived] [--json]"," platform cms apply schema --collection <name> --version <n> [--json]"," platform cms apply publish --collection <name> --item-id <id> --status draft|published|archived [--json]"," platform cms inspect schema --collection <name> [--json]"," platform cms inspect item --collection <name> --id <id> [--json]"," platform cms inspect delivery list --collection <name> [--page <n>] [--page-size <n>] [--tag <tag>] [--category-id <id>] [--json]"," platform cms inspect delivery get --collection <name> (--slug <slug> | --id <id>) [--json]"," platform cms inspect delivery categories --collection <name> [--json]","","Asset commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>]"," platform asset list [--q <keyword>] [--media-type image|video] [--folder-id <folder-id>] [--page <n>] [--limit <n>]"," platform asset folder list"," platform asset folder create <name> [--parent-folder-id <folder-id>]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id> | --root]"," platform asset get <asset-id>"," platform asset move <asset-id> [--folder-id <folder-id> | --root]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--tags <label,label>]"," 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>]"," platform asset tag add <asset-id> <label>"," platform asset tag remove <asset-id> <label>","","Preview commands:"," platform preview"," platform preview open [--source-version <srcver>]"," platform preview generate [--source-version <srcver>]"," platform preview generate --from-build <build-id>","","Publish commands:"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","Workflow commands:"," platform workflow template list"," platform workflow template inspect --template <key>"," platform workflow definition list [--status draft|active|inactive]"," platform workflow definition inspect --definition <key>"," platform workflow definition create --definition <key> --app <app-id> [--template <template-key> | --object-type <type> --schema <json>]"," platform workflow binding list [--app <app-id>] [--definition <key>]"," platform workflow binding inspect --definition <key> [--target-id <id>]"," platform workflow binding update --definition <key> [--target-id <id>] --file <override.json>"," platform workflow role bind --definition <key> --app <app-id> --file <bindings.json> # \u4F4E\u5C42\u9AD8\u7EA7\u5165\u53E3"," platform workflow diagnose [--app <app-id>]"," platform workflow start --definition <key> --object-type <type> --object-id <id>"," platform workflow action --instance <instance-id> --action <action-key>"," platform workflow tasks [--status pending]"," platform workflow instance <instance-id>","","Notification commands:"," platform notification inbox list [--app <app-id>] [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification inbox update <item-id> --status unread|read|dismissed|archived"," platform notification announce platform --tenant <tenant-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification announce app --tenant <tenant-id> --app <app-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification delivery [--app <app-id>] [--status pending|running|succeeded|failed|dead]"," platform notification end-user users --app <app-id>"," platform notification end-user inbox --app <app-id> --end-user <app-user-id> [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification end-user unread --app <app-id> --end-user <app-user-id>"," platform notification end-user publish --app <app-id> --end-user <app-user-id> --title <text> [--body <text>] [--kind notification|alert|announcement]"," platform notification end-user announcement --app <app-id> --end-user <app-user-id> --title <text> --body <text>"," platform notification end-user reminder --app <app-id> --end-user <app-user-id> --title <text> --remind-at <ISO datetime> [--body <text>]","","Advanced release commands:"," platform deploy [--source-version <srcver>] [--prod]"," platform rollback <release-id|version>","","Advanced build commands:"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform logs --follow"," platform diagnostics control-api [--json]"," platform worker preview-retention [--once] [--dry-run] [--json]","","Resource commands:"," platform resources diff --base-snapshot <rsnap-id>"," platform resources apply --base-snapshot <rsnap-id>"," platform resources rollback <rsnap-id> --approve-id <approve-id>","","Examples:"," platform login"," platform login --pat <personal-access-token>"," platform env use local"," platform env use test"," platform env current",' platform app create --tenant t-default --name "\u6D3B\u52A8\u9080\u8BF7\u51FD" --dir invite-frontend',' platform app create --tenant t-default --name "\u62A5\u540D\u52A9\u624B" --dir signup-runtime --template backend-app-node',' platform app create --tenant t-default --name "\u8425\u9500\u9875" --dir landing-page --template frontend-app-vite',' platform app create --tenant t-default --name "\u4E1A\u52A1\u540E\u53F0" --dir ops-console --template backend-app-node'," platform app checkout --tenant t-default --app app-demo --dir app-demo"," platform app checkout --tenant t-default --app app-demo --source-version srcver-123",' platform app submit --message "local iteration"'," platform dev push"," platform dev preview generate"," platform dev preview open",' platform asset upload ./logo.png --title "\u54C1\u724C Logo"'," platform asset folder create \u54C1\u724C\u7D20\u6750"," platform asset folder rename asset-folder-123 --name \u54C1\u724C\u89C6\u89C9 --root"," platform asset folder list"," platform asset list --q logo --tag-ids tag-1,tag-2 --page 2"," platform asset get asset-123"," platform asset move asset-123 --folder-id asset-folder-123",' platform asset update asset-123 --title "\u9996\u9875 Hero \u56FE" --scene outdoor --tags hero,homepage'," platform asset analyze asset-123"," platform asset open asset-123"," platform asset download asset-123 --variant md"," platform asset tag list --asset asset-123"," platform asset tag add asset-123 logo"," platform asset tag remove asset-123 logo"," platform app versions --tenant t-default --app app-demo"," platform whoami --tenant t-default"," platform build get build-123"," platform build events build-123"," platform build run --source-version srcver-123"," platform build validate --app app-demo --source-version srcver-123"," platform preview"," platform preview open --source-version srcver-123"," platform preview generate"," platform preview generate --source-version srcver-123"," platform publish"," platform publish status"," platform publish set --status unpublished"," platform publish set --source-version srcver-123 --status published"," platform publish rollback srcver-122"," cd signup-lite && platform dev"," cd signup-lite && platform dev push"," cd signup-lite && platform dev preview generate"," cd signup-lite && platform dev preview open"," platform deploy --source-version srcver-123"," platform deploy --prod"," platform rollback v0.2.0","","Other examples:"," platform app current"," platform tenant use t-default"," platform tenant current"," platform db status"," platform db history --limit 10"," platform db tables",' platform db query --sql "SELECT * FROM example_items LIMIT 5"'," platform auth discover --app app-demo"," platform auth configure --app app-demo --enable --template email_magic_link_only"," platform auth configure --app app-demo --enable --template phone_sms_otp_only"," platform auth configure --app app-demo --enable --template email_magic_link_and_phone_sms_otp"," platform auth configure --app app-demo --enable --enable-phone-sms-otp"," platform auth bind --app app-checkin --action bind --user-store-id us_xxx"," platform auth inspect --app app-demo --json"," platform cms discover"," platform cms discover --collection article"," platform cms configure collection --file ./cms/article.collection.json"," platform cms configure item --file ./cms/article.item.json"," platform cms import markdown ./docs/post.md --collection article --tags cms,agent --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --cover-asset-id asset-123 --publish"," platform cms import url https://zhuanlan.zhihu.com/p/488185988 --collection article --tags cms,url --dry-run"," platform cms import url https://example.com/post --collection article --no-assetize-images"," platform cms import markdown ./docs/articles --collection article --recursive --item-id-prefix article-doc --skip-existing"," platform cms import markdown ./docs/post.md --collection article --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --dry-run --json"," platform cms import markdown ./docs/post.md --collection article --skip-existing --publish"," platform cms attach asset --collection article --item-id cms-item-123 --field cover --asset-id asset-123"," platform cms ensure category --collection article --path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03"," platform cms list items --collection article --status draft"," platform cms batch update --collection article --item-id item-a,item-b --category-id cms-category-123 --add-tags cms,cli --status published"," platform cms apply schema --collection article --version 1"," platform cms inspect schema --collection article --json"," platform cms inspect item --collection article --id cms-item-123"," platform cms inspect delivery list --collection article --tag cms"," platform cms inspect delivery get --collection article --slug introducing-cms-base"," platform resources diff --base-snapshot rsnap-123"," platform resources apply --base-snapshot rsnap-123"," platform resources rollback rsnap-122 --approve-id approve-123"," platform logs --follow","","Compatible path examples:"," platform app use --tenant t-default --app app-demo --env preview"," platform init demo-app"," platform link --tenant t-default --app app-demo --env preview"," platform dev --target tenant-workbench"," platform dev --remote-bindings"," platform dev --remote-bindings=db",""].join(`
2740
+ `))}function serializeOptions(options){let result=[];for(let[key,value]of Object.entries(options))key==="help"||key==="h"||(result.push(`--${key}`),typeof value=="string"&&result.push(value));return result}async function spawnControlApiWorker(args){await new Promise((resolve20,reject)=>{let child=spawn4("corepack",["pnpm","--silent","--filter","@platform/control-api","worker",...args],{stdio:"inherit"});child.on("error",reject),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`control-api worker exited by signal ${signal}`));return}code2&&code2!==0&&(process.exitCode=code2),resolve20()})})}applyStoredEnvironmentProfile();applyDistributionProfileDefaults();loadDotenvFiles();var distributionProfile=getDistributionProfile(),cliPackageVersion=getCliPackageVersion();function persistActiveTenantSelection(tenant){let currentContext=loadStoredCliContext();persistCliContext({active_tenant_id:tenant.tenant_id,active_tenant_name:tenant.name,selected_app_tenant_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_tenant_id,selected_app_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_id,selected_app_env:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_env,selected_app_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_name,selected_app_display_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_display_name})}function currentInvocationDir(){return getInvocationCwd()}function parseArgs5(argv){let[command="help",...rest]=argv,options={},positionals=[];for(let index=0;index<rest.length;index+=1){let current=rest[index];if(current==="--help"){options.help=!0;continue}if(current==="-h"){options.h=!0;continue}if(!current.startsWith("--")){positionals.push(current);continue}let[key,inlineValue]=current.slice(2).split("=",2);if(inlineValue!==void 0){options[key]=inlineValue;continue}let next=rest[index+1];if(next&&!next.startsWith("--")){options[key]=next,index+=1;continue}options[key]=!0}return{command,rest:positionals,options}}function printHelp(){let envCommandLines=distributionProfile.name!=="developer"?[]:[" env use <profile> \u5207\u6362 CLI \u73AF\u5883 profile\uFF08\u5982 local / test\uFF09"," env current \u67E5\u770B\u5F53\u524D CLI \u73AF\u5883 profile"," env list \u67E5\u770B\u53EF\u7528 CLI \u73AF\u5883 profile"];process7.stdout.write(["platform <command>","","Commands:"," login \u5168\u5C40\u767B\u5F55\u5E76\u4FDD\u5B58\u51ED\u636E"," logout \u6E05\u7406\u672C\u5730\u767B\u5F55\u51ED\u636E\u4E0E\u8D26\u53F7\u4E0A\u4E0B\u6587"," credentials migrate \u5C06\u65E7\u660E\u6587\u51ED\u636E\u8FC1\u79FB\u5230\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8"," version \u8F93\u51FA\u5F53\u524D CLI \u7248\u672C\u53F7"," app create \u5728\u4E91\u7AEF\u521B\u5EFA\u5E94\u7528\uFF0C\u5E76 checkout \u5230\u672C\u5730\u65B0\u76EE\u5F55"," app checkout \u4ECE\u4E91\u7AEF checkout \u5E94\u7528\u6E90\u7801\u526F\u672C\u5230\u672C\u5730\u65B0\u76EE\u5F55"," app submit \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u63D0\u4EA4\u4E3A\u65B0\u7684\u4E91\u7AEF\u6E90\u7801\u7248\u672C"," app version create \u5728\u5F53\u524D app \u4E0B\u57FA\u4E8E\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C\u9AA8\u67B6"," app version list \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app versions \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app status \u67E5\u770B\u5E94\u7528\u63A7\u5236\u9762\u603B\u89C8\uFF08\u542B Auth / DB / \u7248\u672C\u6982\u51B5\uFF09"," app diagnose \u67E5\u770B\u5E94\u7528\u662F\u5426\u5DF2 ready for runtime validation"," app preflight \u4E00\u6B21\u6027\u6267\u884C whoami / app current / app diagnose \u98CE\u683C\u68C0\u67E5"," app sync-platform-blocks \u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\uFF08dry-run / adopt / apply / rollback --last\uFF09"," app import preprocess \u9884\u5904\u7406\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u751F\u6210 clean-source \u4E0E\u62A5\u544A"," app import stage \u628A clean-source \u4E0E\u62A5\u544A stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," app import merge \u628A\u4E0A\u6E38 src \u5B89\u5168\u5E76\u5165 src/imported-upstream/"," app scaffold \u6309\u9700\u6CE8\u5165\u672C\u5730 debug scaffold\uFF08auth/workflow/cms/db\uFF09"," app-library \u7BA1\u7406\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93 example-app \u6761\u76EE"," app use \u517C\u5BB9\u8DEF\u5F84\uFF1A\u4E3A init/link/dev \u9009\u62E9\u76EE\u6807\u5E94\u7528"," app current \u67E5\u770B\u5F53\u524D\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587"," tenant use <id> \u8BBE\u7F6E\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587"," tenant current \u67E5\u770B\u5F53\u524D\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587",...envCommandLines," whoami \u8C03\u7528 Control API \u8F93\u51FA\u5F53\u524D\u4E3B\u4F53"," preview \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u53EF\u7528 Preview\uFF1B\u751F\u6210\u8BF7\u7528 `platform preview generate`"," init [name] \u751F\u6210\u9879\u76EE\u9AA8\u67B6\uFF0C\u5E76\u81EA\u52A8\u5199\u5165\u5DF2\u9009\u5E94\u7528\u7ED1\u5B9A"," link \u7ED1\u5B9A tenant/app/env \u5230\u5F53\u524D\u5E94\u7528\u76EE\u5F55"," dev \u9ED8\u8BA4\u8F7B\u91CF\u5F00\u53D1\u5165\u53E3\uFF1A\u6CE8\u5165\u7ED1\u5B9A\u540E\u542F\u52A8\u672C\u5730\u5F00\u53D1\u6001"," dev push \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u8986\u76D6\u63A8\u9001\u5230\u4E91\u7AEF Dev Workspace"," dev preview generate \u57FA\u4E8E\u4E91\u7AEF Dev Workspace \u751F\u6210\u5DE5\u4F5C\u533A Preview"," auth \u7BA1\u7406 Auth \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / bind / inspect\uFF09"," cms \u7BA1\u7406 CMS \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / apply / inspect\uFF09"," asset \u7BA1\u7406\u79DF\u6237\u5171\u4EAB\u7D20\u6750\uFF08upload / list / folder / get / update / analyze / move / open / tag\uFF09"," blob \u7BA1\u7406 Object Storage Blob\uFF08upload / list / get / url\uFF09"," db \u67E5\u770B DB \u72B6\u6001\u3001\u8868\u7ED3\u6784\u4E0E\u53EA\u8BFB\u67E5\u8BE2"," data-form \u6821\u9A8C/\u7F16\u8BD1/apply/query Data Form schema \u4E0E\u8BB0\u5F55"," workflow \u7BA1\u7406 Workflow \u57FA\u5EA7\u80FD\u529B\uFF08template / definition / binding / runtime\uFF09"," notification \u7BA1\u7406 Notification \u57FA\u5EA7\u80FD\u529B\uFF08inbox / announce / delivery\uFF09"," publish \u7BA1\u7406\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," resources \u6267\u884C\u8D44\u6E90 diff/apply/rollback"," logs \u67E5\u8BE2\u8FD0\u884C\u65F6\u65E5\u5FD7\uFF0C\u652F\u6301 --follow"," diagnostics \u5E73\u53F0\u672C\u5730\u8BCA\u65AD\uFF08control-api / credentials\uFF09"," worker \u542F\u52A8\u5E73\u53F0\u540E\u53F0 worker\uFF08preview-retention\uFF09","","Advanced commands:"," build \u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\uFF1A\u53D1\u8D77\u548C\u67E5\u8BE2 build"," deploy \u8FC7\u6E21\u5165\u53E3\uFF1A\u9AD8\u7EA7\u53D1\u5E03\uFF08artifact / promote\uFF09"," rollback \u8FC7\u6E21\u5165\u53E3\uFF1A\u56DE\u6EDA\u5230\u76EE\u6807 release \u6216\u7248\u672C","","App commands:"," platform app create --tenant <tenant-id> --name <display-name> --dir <project-name> [--template frontend-app-vite|backend-app-node]"," platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," platform app checkout --tenant <tenant-id> --app <app-id> --source-version <srcver>",' platform app submit --message "local iteration"',' platform app version create --message "switch template" --template backend-app-node'," platform app versions --tenant <tenant-id> --app <app-id>"," platform app status [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app sync-platform-blocks [--dry-run|--adopt|--apply|--rollback --last]"," platform app diagnose [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run]"," platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>"," platform app import merge [--workspace-dir <template-workspace-dir>]"," platform app scaffold <auth-debug|workflow-debug|cms-debug|db-debug>"," platform app-library list"," platform app-library config init"," platform app-library inspect entry-demo"," platform app-library checkout entry-demo --dir ./example-app-demo",' platform app-library create --name "Data Form Verify" --summary "\u672C\u5730\u9A8C\u8BC1\u540E\u7684\u793A\u4F8B\u5E94\u7528"'," platform app-library submit entry-demo"," platform app use --tenant <tenant-id> --app <app-id> --env preview"," platform app current","","DB commands:"," platform db status"," platform db history --limit 10"," platform db migrate [--dry-run]"," platform db tables",' platform db query --sql "SELECT ... LIMIT 5"'," platform db open","","Auth commands:"," platform auth discover [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth configure [--tenant <tenant-id>] [--app <app-id>] --enable [--template <template>] [--user-store-id <id>] [--enable-admin-password|--disable-admin-password] [--enable-phone-sms-otp|--disable-phone-sms-otp] [--json]"," platform auth bind [--tenant <tenant-id>] [--app <app-id>] [--action bind|rebind|disable] [--user-store-id <id>] [--json]"," platform auth inspect [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role list [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role create [--tenant <tenant-id>] [--app <app-id>] --key <role-key> --name <display-name> [--description <text>] [--status active|disabled] [--json]"," platform auth role inspect [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--json]"," platform auth role update [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--name <display-name>] [--description <text> | --clear-description] [--status active|disabled] [--json]"," platform auth user-role list [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> [--json]"," platform auth user-role assign [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role replace [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role remove [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --role <role-key> [--json]","","CMS commands:"," platform cms discover [--collection <name>] [--json]"," platform cms configure collection --file <spec.json> [--json]"," platform cms configure item --file <item.json> [--item-id <item-id>] [--json]"," platform cms configure category --collection <name> --name <name> --slug <slug> [--parent-id <id>] [--order <n>] [--json]"," platform cms import markdown <file> [--collection <name>] [--item-id <item-id> | --item-id-prefix <prefix>] [--tags <label,label>] [--category-path <segment/segment>] [--cover-asset-id <asset-id>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--dry-run] [--json]"," platform cms import url <url> [--collection <name>] [--item-id <item-id>] [--tags <label,label>] [--category-path <segment/segment>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--no-assetize-images] [--dry-run] [--json]"," platform cms attach asset --collection <name> --item-id <id> --field <field-name> --asset-id <id[,id]> [--replace] [--json]"," platform cms ensure category --collection <name> --path <segment/segment> [--json]"," platform cms list items --collection <name> [--page <n>] [--page-size <n>] [--status draft|published|archived] [--category-id <id>] [--q <keyword>] [--json]"," platform cms batch update --collection <name> --item-id <id[,id]> [--category-id <id> | --clear-category] [--add-tags <label,label>] [--status draft|published|archived] [--json]"," platform cms apply schema --collection <name> --version <n> [--json]"," platform cms apply publish --collection <name> --item-id <id> --status draft|published|archived [--json]"," platform cms inspect schema --collection <name> [--json]"," platform cms inspect item --collection <name> --id <id> [--json]"," platform cms inspect delivery list --collection <name> [--page <n>] [--page-size <n>] [--tag <tag>] [--category-id <id>] [--json]"," platform cms inspect delivery get --collection <name> (--slug <slug> | --id <id>) [--json]"," platform cms inspect delivery categories --collection <name> [--json]","","Asset commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>]"," platform asset list [--q <keyword>] [--media-type image|video] [--folder-id <folder-id>] [--page <n>] [--limit <n>]"," platform asset folder list"," platform asset folder create <name> [--parent-folder-id <folder-id>]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id> | --root]"," platform asset get <asset-id>"," platform asset move <asset-id> [--folder-id <folder-id> | --root]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--tags <label,label>]"," 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>]"," platform asset tag add <asset-id> <label>"," platform asset tag remove <asset-id> <label>","","Preview commands:"," platform preview"," platform preview open [--source-version <srcver>]"," platform preview generate [--source-version <srcver>]"," platform preview generate --from-build <build-id>","","Publish commands:"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","Workflow commands:"," platform workflow template list"," platform workflow template inspect --template <key>"," platform workflow definition list [--status draft|active|inactive]"," platform workflow definition inspect --definition <key>"," platform workflow definition create --definition <key> --app <app-id> [--template <template-key> | --object-type <type> --schema <json>]"," platform workflow binding list [--app <app-id>] [--definition <key>]"," platform workflow binding inspect --definition <key> [--target-id <id>]"," platform workflow binding update --definition <key> [--target-id <id>] --file <override.json>"," platform workflow role bind --definition <key> --app <app-id> --file <bindings.json> # \u4F4E\u5C42\u9AD8\u7EA7\u5165\u53E3"," platform workflow diagnose [--app <app-id>]"," platform workflow start --definition <key> --object-type <type> --object-id <id>"," platform workflow action --instance <instance-id> --action <action-key>"," platform workflow tasks [--status pending]"," platform workflow instance <instance-id>","","Notification commands:"," platform notification inbox list [--app <app-id>] [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification inbox update <item-id> --status unread|read|dismissed|archived"," platform notification announce platform --tenant <tenant-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification announce app --tenant <tenant-id> --app <app-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification delivery [--app <app-id>] [--status pending|running|succeeded|failed|dead]"," platform notification end-user users --app <app-id>"," platform notification end-user inbox --app <app-id> --end-user <app-user-id> [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification end-user unread --app <app-id> --end-user <app-user-id>"," platform notification end-user publish --app <app-id> --end-user <app-user-id> --title <text> [--body <text>] [--kind notification|alert|announcement]"," platform notification end-user announcement --app <app-id> --end-user <app-user-id> --title <text> --body <text>"," platform notification end-user reminder --app <app-id> --end-user <app-user-id> --title <text> --remind-at <ISO datetime> [--body <text>]","","Advanced release commands:"," platform deploy [--source-version <srcver>] [--prod]"," platform rollback <release-id|version>","","Advanced build commands:"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform logs --follow"," platform diagnostics control-api [--json]"," platform diagnostics credentials [--json] [--strict]"," platform worker preview-retention [--once] [--dry-run] [--json]","","Resource commands:"," platform resources diff --base-snapshot <rsnap-id>"," platform resources apply --base-snapshot <rsnap-id>"," platform resources rollback <rsnap-id> --approve-id <approve-id>","","Examples:"," platform login"," platform login --pat <personal-access-token>"," platform env use local"," platform env use test"," platform env current",' platform app create --tenant t-default --name "\u6D3B\u52A8\u9080\u8BF7\u51FD" --dir invite-frontend',' platform app create --tenant t-default --name "\u62A5\u540D\u52A9\u624B" --dir signup-runtime --template backend-app-node',' platform app create --tenant t-default --name "\u8425\u9500\u9875" --dir landing-page --template frontend-app-vite',' platform app create --tenant t-default --name "\u4E1A\u52A1\u540E\u53F0" --dir ops-console --template backend-app-node'," platform app checkout --tenant t-default --app app-demo --dir app-demo"," platform app checkout --tenant t-default --app app-demo --source-version srcver-123",' platform app submit --message "local iteration"'," platform dev push"," platform dev preview generate"," platform dev preview open",' platform asset upload ./logo.png --title "\u54C1\u724C Logo"'," platform asset folder create \u54C1\u724C\u7D20\u6750"," platform asset folder rename asset-folder-123 --name \u54C1\u724C\u89C6\u89C9 --root"," platform asset folder list"," platform asset list --q logo --tag-ids tag-1,tag-2 --page 2"," platform asset get asset-123"," platform asset move asset-123 --folder-id asset-folder-123",' platform asset update asset-123 --title "\u9996\u9875 Hero \u56FE" --scene outdoor --tags hero,homepage'," platform asset analyze asset-123"," platform asset open asset-123"," platform asset download asset-123 --variant md"," platform asset tag list --asset asset-123"," platform asset tag add asset-123 logo"," platform asset tag remove asset-123 logo"," platform app versions --tenant t-default --app app-demo"," platform whoami --tenant t-default"," platform build get build-123"," platform build events build-123"," platform build run --source-version srcver-123"," platform build validate --app app-demo --source-version srcver-123"," platform preview"," platform preview open --source-version srcver-123"," platform preview generate"," platform preview generate --source-version srcver-123"," platform publish"," platform publish status"," platform publish set --status unpublished"," platform publish set --source-version srcver-123 --status published"," platform publish rollback srcver-122"," cd signup-lite && platform dev"," cd signup-lite && platform dev push"," cd signup-lite && platform dev preview generate"," cd signup-lite && platform dev preview open"," platform deploy --source-version srcver-123"," platform deploy --prod"," platform rollback v0.2.0","","Other examples:"," platform app current"," platform tenant use t-default"," platform tenant current"," platform db status"," platform db history --limit 10"," platform db tables",' platform db query --sql "SELECT * FROM example_items LIMIT 5"'," platform auth discover --app app-demo"," platform auth configure --app app-demo --enable --template email_magic_link_only"," platform auth configure --app app-demo --enable --template phone_sms_otp_only"," platform auth configure --app app-demo --enable --template email_magic_link_and_phone_sms_otp"," platform auth configure --app app-demo --enable --enable-phone-sms-otp"," platform auth bind --app app-checkin --action bind --user-store-id us_xxx"," platform auth inspect --app app-demo --json"," platform cms discover"," platform cms discover --collection article"," platform cms configure collection --file ./cms/article.collection.json"," platform cms configure item --file ./cms/article.item.json"," platform cms import markdown ./docs/post.md --collection article --tags cms,agent --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --cover-asset-id asset-123 --publish"," platform cms import url https://zhuanlan.zhihu.com/p/488185988 --collection article --tags cms,url --dry-run"," platform cms import url https://example.com/post --collection article --no-assetize-images"," platform cms import markdown ./docs/articles --collection article --recursive --item-id-prefix article-doc --skip-existing"," platform cms import markdown ./docs/post.md --collection article --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --dry-run --json"," platform cms import markdown ./docs/post.md --collection article --skip-existing --publish"," platform cms attach asset --collection article --item-id cms-item-123 --field cover --asset-id asset-123"," platform cms ensure category --collection article --path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03"," platform cms list items --collection article --status draft"," platform cms batch update --collection article --item-id item-a,item-b --category-id cms-category-123 --add-tags cms,cli --status published"," platform cms apply schema --collection article --version 1"," platform cms inspect schema --collection article --json"," platform cms inspect item --collection article --id cms-item-123"," platform cms inspect delivery list --collection article --tag cms"," platform cms inspect delivery get --collection article --slug introducing-cms-base"," platform resources diff --base-snapshot rsnap-123"," platform resources apply --base-snapshot rsnap-123"," platform resources rollback rsnap-122 --approve-id approve-123"," platform logs --follow","","Compatible path examples:"," platform app use --tenant t-default --app app-demo --env preview"," platform init demo-app"," platform link --tenant t-default --app app-demo --env preview"," platform dev --target tenant-workbench"," platform dev --remote-bindings"," platform dev --remote-bindings=db",""].join(`
2650
2741
  `))}function printVersion(){process7.stdout.write(`v${cliPackageVersion}
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(`
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)}
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(`
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(`
2742
+ `)}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]"," platform diagnostics credentials [--json] [--strict]","","\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"," credentials \u53EA\u8F93\u51FA\u5B58\u50A8\u540E\u7AEF\u3001state \u8DEF\u5F84\u548C\u6743\u9650\u5224\u65AD\uFF0C\u4E0D\u8BFB\u53D6\u6216\u8F93\u51FA token\u3002"," credentials warning \u9ED8\u8BA4\u9000\u51FA\u7801\u4E3A 0\uFF1B\u4EC5\u663E\u5F0F --strict \u8FD4\u56DE\u975E\u96F6\u3002","","\u73AF\u5883\u53D8\u91CF\uFF1A"," CONTROL_API_BASE_URL"," RUNTIME_API_BASE_URL"," PUBLIC_API_BASE_URL"," CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES",""].join(`
2743
+ `))}async function runDiagnostics(args){let subcommand=args.rest[0]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")||subcommand==="help"){printDiagnosticsHelp();return}if(subcommand==="credentials"){let diagnostics2=inspectStoredCredentialSecurity();args.options.json===!0?process7.stdout.write(`${JSON.stringify(diagnostics2,null,2)}
2744
+ `):process7.stdout.write(formatCredentialSecurityReportText(diagnostics2)),hasFlag2(args,"strict")&&diagnostics2.status!=="ok"&&(process7.exitCode=2);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)}
2745
+ `);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==="-"?readFileSync29(0,"utf8"):readFileSync29(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(`
2746
+ `));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")}function printCredentialsHelp(){process7.stdout.write(["platform credentials","","\u7528\u6CD5\uFF1A"," platform credentials migrate [--json]","","\u8BF4\u660E\uFF1A"," \u5C06\u65E7 credentials.json \u8FC1\u79FB\u5230 macOS Keychain \u6216 Windows DPAPI\u3002"," \u53EA\u6709\u5B89\u5168\u5B58\u50A8\u5199\u5165\u5E76\u56DE\u8BFB\u6821\u9A8C\u6210\u529F\u540E\u624D\u5220\u9664\u65E7\u660E\u6587\u6587\u4EF6\u3002"," \u8FC1\u79FB\u5931\u8D25\u4F1A\u4FDD\u7559\u539F\u767B\u5F55\u6001\uFF0C\u5E76\u7ED9\u51FA\u660E\u786E\u63D0\u793A\u3002",""].join(`
2747
+ `))}async function runCredentials(args){let subcommand=args.rest[0]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")||subcommand==="help"){printCredentialsHelp();return}if(subcommand!=="migrate")throw printCredentialsHelp(),new Error(`\u672A\u77E5 credentials \u5B50\u547D\u4EE4: ${subcommand}`);let result=migrateStoredCredentials(),output={status:result.status,backend:result.backend,legacy_deleted:result.legacyDeleted,warnings:result.warnings};hasFlag2(args,"json")?process7.stdout.write(`${JSON.stringify(output,null,2)}
2748
+ `):result.status==="migrated"?process7.stdout.write(`\u51ED\u636E\u8FC1\u79FB\u5B8C\u6210\u3002
2749
+ \u5B58\u50A8\u540E\u7AEF: ${result.backend}
2750
+ \u65E7\u660E\u6587\u5DF2\u5220\u9664: \u662F
2751
+ `):result.status==="not_needed"?process7.stdout.write(`\u65E0\u9700\u8FC1\u79FB\u3002
2752
+ \u5F53\u524D\u5B58\u50A8\u540E\u7AEF: ${result.backend}
2753
+ `):process7.stdout.write(`\u51ED\u636E\u8FC1\u79FB\u672A\u5B8C\u6210\uFF0C\u539F\u6709\u53EF\u7528\u767B\u5F55\u6001\u5DF2\u4FDD\u7559\u3002
2754
+ \u5F53\u524D\u5B58\u50A8\u540E\u7AEF: ${result.backend}
2755
+ \u5EFA\u8BAE\uFF1A\u8FD0\u884C \`platform diagnostics credentials\` \u540E\u91CD\u8BD5\u3002
2756
+ `),result.status==="failed"&&(process7.exitCode=2)}function printLogoutHelp(){process7.stdout.write(["platform logout","","\u7528\u6CD5\uFF1A"," platform logout [--json]","","\u8BF4\u660E\uFF1A"," \u6E05\u7406\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u3001\u517C\u5BB9\u51ED\u636E\u6587\u4EF6\u548C\u5168\u5C40 tenant/app \u9009\u62E9\u4E0A\u4E0B\u6587\u3002"," \u4FDD\u7559 environment profile \u548C\u9879\u76EE\u5185 .platform/source-context.json \u7ED1\u5B9A\u3002"," \u672C\u547D\u4EE4\u53EA\u6E05\u7406\u672C\u5730\u72B6\u6001\uFF0C\u4E0D\u64A4\u9500\u6D4F\u89C8\u5668 SSO \u6216\u670D\u52A1\u7AEF token\u3002",""].join(`
2757
+ `))}async function runLogout(args){if(hasFlag2(args,"help")||hasFlag2(args,"h")){printLogoutHelp();return}if(args.rest.length>0)throw printLogoutHelp(),new Error(`\u672A\u77E5 logout \u53C2\u6570: ${args.rest.join(" ")}`);let unsupportedOptions=Object.entries(args.options).filter(([key,value])=>!["help","h","json"].includes(key)||value!==!0);if(unsupportedOptions.length>0)throw new Error(`logout \u4E0D\u652F\u6301\u53C2\u6570: ${unsupportedOptions.map(([key])=>`--${key}`).join(", ")}\u3002\u672C\u6B21\u672A\u6267\u884C\u4EFB\u4F55\u6E05\u7406\uFF1B\u53EF\u8FD0\u884C \`platform logout --help\` \u67E5\u770B\u7528\u6CD5\u3002`);let result=clearStoredAuthentication(),stateDir=getCliStateDir(),output={status:result.status,state_dir:stateDir,cleared:result.cleared,failed:result.failed,preserved:["environment_profile","project_source_context"]};hasFlag2(args,"json")?process7.stdout.write(`${JSON.stringify(output,null,2)}
2758
+ `):process7.stdout.write([result.status==="cleared"?"\u672C\u5730 CLI \u767B\u5F55\u6001\u5DF2\u6E05\u7406\u3002":"\u672C\u5730 CLI \u767B\u5F55\u6001\u5DF2\u90E8\u5206\u6E05\u7406\u3002",`state \u76EE\u5F55: ${stateDir}`,"\u5DF2\u4FDD\u7559: environment profile\u3001\u9879\u76EE\u5185 .platform/source-context.json",...result.failed.length>0?[`\u672A\u6E05\u7406\u9879: ${result.failed.map(item=>item.target).join(", ")}`,"\u5EFA\u8BAE\uFF1A\u5173\u95ED\u5360\u7528\u7A0B\u5E8F\u6216\u89E3\u9501\u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u540E\u91CD\u8BD5 `platform logout`\u3002"]:[],""].join(`
2759
+ `)),result.status==="partial"&&(process7.exitCode=2)}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});let persistence2=persistCredentials(credentials);process7.stdout.write(["PAT \u767B\u5F55\u5DF2\u5B8C\u6210\u3002",`\u51ED\u636E\u5B58\u50A8\u540E\u7AEF: ${persistence2.backend}`,...persistence2.backend==="file"?[`\u517C\u5BB9\u51ED\u636E\u6587\u4EF6: ${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",...persistence2.backend==="file"?["\u6CE8\u610F: \u7CFB\u7EDF\u5B89\u5168\u5B58\u50A8\u4E0D\u53EF\u7528\uFF0C\u539F\u59CB PAT \u672A\u5199\u5165\u6587\u4EF6\uFF1B\u5F53\u524D access token \u5230\u671F\u540E\u9700\u91CD\u65B0\u767B\u5F55\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(`
2655
2760
  `));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(`
2656
2761
  `))}})}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
2657
2762
  `),!browserLoginConfig)throw new Error("\u5F53\u524D\u73AF\u5883\u7F3A\u5C11\u53EF\u7528\u4E8E\u6D4F\u89C8\u5668\u767B\u5F55\u7684\u914D\u7F6E\uFF0C\u8BF7\u8865\u9F50 `AUTH_CLI_REDIRECT_URI`\uFF08\u6216\u517C\u5BB9\u65E7\u540D `LOGTO_CLI_REDIRECT_URI`\uFF09\uFF0C\u6216\u63D0\u4F9B `AUTH_TENANT_CLIENT_ID / AUTH_TENANT_REDIRECT_URI`\uFF08\u65E7\u540D `LOGTO_TENANT_*`\uFF09\u4F5C\u4E3A\u56DE\u9000\u3002");credentials=await performAuthorizationCodeLogin({issuer,clientId:browserLoginConfig.clientId,redirectUri:browserLoginConfig.redirectUri,audience,scopes,prompt:"login",onPrompt:async({authorizationUrl,redirectUri})=>{let{opened}=await openExternal(authorizationUrl);process7.stdout.write(formatAuthorizationCodeLoginPrompt({opened,authorizationUrl,redirectUri,source:browserLoginConfig.source}))}})}else{if(!browserLoginConfig)throw new Error("\u7F3A\u5C11\u6D4F\u89C8\u5668\u767B\u5F55\u914D\u7F6E\uFF1A\u8BF7\u4F18\u5148\u8865\u9F50 `AUTH_CLI_CLIENT_ID / AUTH_CLI_REDIRECT_URI`\uFF08\u517C\u5BB9\u65E7\u540D `LOGTO_CLI_*`\uFF09\uFF1B\u82E5\u6682\u65F6\u65E0\u6CD5\u63D0\u4F9B\uFF0C\u518D\u8865\u9F50 `AUTH_TENANT_CLIENT_ID / AUTH_TENANT_REDIRECT_URI`\uFF08\u517C\u5BB9\u65E7\u540D `LOGTO_TENANT_*`\uFF09\u4F5C\u4E3A\u56DE\u9000\u3002");process7.stdout.write(browserLoginConfig.source==="cli-app"?`\u5F53\u524D\u4F7F\u7528\u4E13\u7528 CLI App \u6267\u884C\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\uFF0C\u5E76\u81EA\u52A8\u9644\u5E26 consent \u4EE5\u6362\u53D6 refresh token\u3002
2658
2763
  `:`\u672A\u914D\u7F6E\u5B8C\u6574\u4E13\u7528 CLI \u6D4F\u89C8\u5668\u767B\u5F55\u53C2\u6570\uFF0C\u81EA\u52A8\u56DE\u9000\u590D\u7528 workbench \u767B\u5F55\u914D\u7F6E\uFF0C\u5E76\u5F3A\u5236 prompt=login consent\u3002
2659
- `),credentials=await performAuthorizationCodeLogin({issuer,clientId:browserLoginConfig.clientId,redirectUri:browserLoginConfig.redirectUri,audience,scopes,prompt:"login",onPrompt:async({authorizationUrl,redirectUri})=>{let{opened}=await openExternal(authorizationUrl);process7.stdout.write(formatAuthorizationCodeLoginPrompt({opened,authorizationUrl,redirectUri,source:browserLoginConfig.source}))}})}persistCredentials({...credentials,credential_mode:"interactive"});let autoSelectedTenant=null,autoSelectionNote=null;try{let workspaces=await listTenantWorkspaces({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(credentials)});autoSelectedTenant=chooseDefaultTenantWorkspace(workspaces.items),autoSelectedTenant?persistActiveTenantSelection(autoSelectedTenant):workspaces.items.length>1&&(autoSelectionNote="\u68C0\u6D4B\u5230\u591A\u4E2A\u53EF\u7528\u79DF\u6237\uFF0C\u672A\u81EA\u52A8\u5207\u6362\u9ED8\u8BA4\u79DF\u6237\uFF1B\u8BF7\u6267\u884C `platform tenant use <tenant-id>`\u3002")}catch(error){autoSelectionNote=`\u9ED8\u8BA4\u79DF\u6237\u81EA\u52A8\u9009\u62E9\u5931\u8D25\uFF1A${error.message}`}process7.stdout.write(["\u767B\u5F55\u5DF2\u5B8C\u6210\u3002",`\u51ED\u636E\u5DF2\u5199\u5165: ${getCredentialPath()}`,...autoSelectedTenant?[`\u9ED8\u8BA4\u79DF\u6237\u5DF2\u81EA\u52A8\u8BBE\u7F6E: ${autoSelectedTenant.tenant_id} (${autoSelectedTenant.name})`,`\u4E0A\u4E0B\u6587\u5DF2\u5199\u5165: ${getCliContextPath()}`]:autoSelectionNote?[autoSelectionNote]:[],"\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A"," 1. platform whoami",' 2. \u65B0\u5EFA\u5E94\u7528\uFF1Aplatform app create --tenant <tenant-id> --name "<app-name>" --dir <project-name>'," 3. \u7F16\u8F91\u5DF2\u6709\u5E94\u7528\uFF1Aplatform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," 4. cd <project-name> && platform dev"," 5. \u9ED8\u8BA4\u5148\u8D70\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF1B\u771F\u5B9E build / preview \u8054\u8C03\u5C5E\u4E8E\u9AD8\u7EA7\u8DEF\u5F84",""].join(`
2764
+ `),credentials=await performAuthorizationCodeLogin({issuer,clientId:browserLoginConfig.clientId,redirectUri:browserLoginConfig.redirectUri,audience,scopes,prompt:"login",onPrompt:async({authorizationUrl,redirectUri})=>{let{opened}=await openExternal(authorizationUrl);process7.stdout.write(formatAuthorizationCodeLoginPrompt({opened,authorizationUrl,redirectUri,source:browserLoginConfig.source}))}})}let persistence=persistCredentials({...credentials,credential_mode:"interactive"}),autoSelectedTenant=null,autoSelectionNote=null;try{let workspaces=await listTenantWorkspaces({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(credentials)});autoSelectedTenant=chooseDefaultTenantWorkspace(workspaces.items),autoSelectedTenant?persistActiveTenantSelection(autoSelectedTenant):workspaces.items.length>1&&(autoSelectionNote="\u68C0\u6D4B\u5230\u591A\u4E2A\u53EF\u7528\u79DF\u6237\uFF0C\u672A\u81EA\u52A8\u5207\u6362\u9ED8\u8BA4\u79DF\u6237\uFF1B\u8BF7\u6267\u884C `platform tenant use <tenant-id>`\u3002")}catch(error){autoSelectionNote=`\u9ED8\u8BA4\u79DF\u6237\u81EA\u52A8\u9009\u62E9\u5931\u8D25\uFF1A${error.message}`}process7.stdout.write(["\u767B\u5F55\u5DF2\u5B8C\u6210\u3002",`\u51ED\u636E\u5B58\u50A8\u540E\u7AEF: ${persistence.backend}`,...persistence.backend==="file"?[`\u517C\u5BB9\u51ED\u636E\u6587\u4EF6: ${getCredentialPath()}`]:[],...autoSelectedTenant?[`\u9ED8\u8BA4\u79DF\u6237\u5DF2\u81EA\u52A8\u8BBE\u7F6E: ${autoSelectedTenant.tenant_id} (${autoSelectedTenant.name})`,`\u4E0A\u4E0B\u6587\u5DF2\u5199\u5165: ${getCliContextPath()}`]:autoSelectionNote?[autoSelectionNote]:[],"\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A"," 1. platform whoami",' 2. \u65B0\u5EFA\u5E94\u7528\uFF1Aplatform app create --tenant <tenant-id> --name "<app-name>" --dir <project-name>'," 3. \u7F16\u8F91\u5DF2\u6709\u5E94\u7528\uFF1Aplatform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," 4. cd <project-name> && platform dev"," 5. \u9ED8\u8BA4\u5148\u8D70\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF1B\u771F\u5B9E build / preview \u8054\u8C03\u5C5E\u4E8E\u9AD8\u7EA7\u8DEF\u5F84",""].join(`
2660
2765
  `))}async function runWhoAmI(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 tenantId=resolveTenantContext(args),payload=await fetchWhoAmI({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(credentials),tenantId});process7.stdout.write(`${JSON.stringify(payload,null,2)}
2661
2766
  `)}async function runTenant(args){let subcommand=args.rest[0]??"current";if(subcommand==="current"){let context=loadStoredCliContext();if(!context?.active_tenant_id){process7.stdout.write(`\u5F53\u524D\u672A\u8BBE\u7F6E\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\u3002
2662
2767
  `);return}process7.stdout.write([`\u5F53\u524D\u9ED8\u8BA4\u79DF\u6237: ${context.active_tenant_id}`,`\u79DF\u6237\u540D\u79F0: ${context.active_tenant_name??"-"}`,`\u66F4\u65B0\u65F6\u95F4: ${context.updated_at}`,`\u4E0A\u4E0B\u6587\u6587\u4EF6: ${getCliContextPath()}`,""].join(`
@@ -2668,7 +2773,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2668
2773
  `));return}if(subcommand==="clear"){clearStoredEnvironmentProfile(),process7.stdout.write(`CLI \u73AF\u5883 profile \u5DF2\u6E05\u9664\u3002
2669
2774
  \u914D\u7F6E\u6587\u4EF6: ${getEnvironmentProfilePath()}
2670
2775
 
2671
- `);return}if(subcommand!=="use")throw new Error(`\u672A\u77E5 env \u5B50\u547D\u4EE4: ${subcommand}`);let profileName=args.rest[1]??readOption2(args,"profile");if(!profileName)throw new Error("`platform env use` \u9700\u8981\u4E00\u4E2A profile \u540D\u79F0\uFF0C\u4F8B\u5982 `platform env use test`\u3002");let resolved=resolveKnownEnvironmentProfile(profileName);if(!resolved){let available=listKnownEnvironmentProfiles().map(item=>item.name).join(", ");throw new Error(available?`\u672A\u77E5\u73AF\u5883 profile: ${profileName}\u3002\u53EF\u7528 profile: ${available}`:`\u672A\u77E5\u73AF\u5883 profile: ${profileName}`)}let values={...resolved.values,...readManagedEnvironmentOverrides(args)};persistStoredEnvironmentProfile({active_profile:resolved.name,values}),printEnvironmentProfileDetail({profileName:resolved.name,values,path:getEnvironmentProfilePath()})}async function runApp(args){let subcommand=args.rest[0]??"current";if(subcommand==="import"){let importAssetSdk=null,importSourceDir=resolve18(readOption2(args,"dir")??process7.env.PLATFORM_INVOCATION_CWD??process7.env.INIT_CWD??process7.cwd());return runAppImportCommand(args,{uploadAsset:async input=>{if(!importAssetSdk){let credentials2=await loadStoredCredentialsEnsuringFresh(),tenantId2=resolveTenantContext(args,importSourceDir);if(!tenantId2)throw new Error("\u672A\u89E3\u6790\u51FA\u7D20\u6750\u4E0A\u4F20\u6240\u9700\u7684 tenant \u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u6267\u884C `platform tenant use <tenant-id>` \u6216\u5728\u5DF2\u7ED1\u5B9A\u5E94\u7528\u76EE\u5F55\u4E2D\u91CD\u8BD5\u3002");importAssetSdk=createTenantScopedSdk(credentials2,tenantId2,{capability:"asset_library"})}return uploadTenantAssetBinary(importAssetSdk,input)}})}if(subcommand==="version"){let nestedSubcommand=args.rest[1]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(`version:${nestedSubcommand}`);return}if(nestedSubcommand==="help"){process7.stdout.write(["platform app version","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app version create \u5728\u5F53\u524D app \u4E0B\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C"," platform app version list \u67E5\u770B\u5F53\u524D app \u4E0B\u5DF2\u6709\u6E90\u7801\u7248\u672C",""].join(`
2776
+ `);return}if(subcommand!=="use")throw new Error(`\u672A\u77E5 env \u5B50\u547D\u4EE4: ${subcommand}`);let profileName=args.rest[1]??readOption2(args,"profile");if(!profileName)throw new Error("`platform env use` \u9700\u8981\u4E00\u4E2A profile \u540D\u79F0\uFF0C\u4F8B\u5982 `platform env use test`\u3002");let resolved=resolveKnownEnvironmentProfile(profileName);if(!resolved){let available=listKnownEnvironmentProfiles().map(item=>item.name).join(", ");throw new Error(available?`\u672A\u77E5\u73AF\u5883 profile: ${profileName}\u3002\u53EF\u7528 profile: ${available}`:`\u672A\u77E5\u73AF\u5883 profile: ${profileName}`)}let values={...resolved.values,...readManagedEnvironmentOverrides(args)};persistStoredEnvironmentProfile({active_profile:resolved.name,values}),printEnvironmentProfileDetail({profileName:resolved.name,values,path:getEnvironmentProfilePath()})}async function runApp(args){let subcommand=args.rest[0]??"current";if(subcommand==="import"){let importAssetSdk=null,importSourceDir=resolve19(readOption2(args,"dir")??process7.env.PLATFORM_INVOCATION_CWD??process7.env.INIT_CWD??process7.cwd());return runAppImportCommand(args,{uploadAsset:async input=>{if(!importAssetSdk){let credentials2=await loadStoredCredentialsEnsuringFresh(),tenantId2=resolveTenantContext(args,importSourceDir);if(!tenantId2)throw new Error("\u672A\u89E3\u6790\u51FA\u7D20\u6750\u4E0A\u4F20\u6240\u9700\u7684 tenant \u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u6267\u884C `platform tenant use <tenant-id>` \u6216\u5728\u5DF2\u7ED1\u5B9A\u5E94\u7528\u76EE\u5F55\u4E2D\u91CD\u8BD5\u3002");importAssetSdk=createTenantScopedSdk(credentials2,tenantId2,{capability:"asset_library"})}return uploadTenantAssetBinary(importAssetSdk,input)}})}if(subcommand==="version"){let nestedSubcommand=args.rest[1]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(`version:${nestedSubcommand}`);return}if(nestedSubcommand==="help"){process7.stdout.write(["platform app version","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app version create \u5728\u5F53\u524D app \u4E0B\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C"," platform app version list \u67E5\u770B\u5F53\u524D app \u4E0B\u5DF2\u6709\u6E90\u7801\u7248\u672C",""].join(`
2672
2777
  `));return}if(nestedSubcommand==="create"){let credentials2=await loadStoredCredentialsEnsuringFresh();if(!credentials2)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let binding=tryReadCurrentBinding2()?.binding,tenantId2=readOption2(args,"tenant")??binding?.tenant_id??resolveTenantContext(args),appId2=readOption2(args,"app")??binding?.app_id,templateKey=normalizeAppTemplateOption(readOption2(args,"template"));if(!tenantId2||!appId2)throw new Error("`platform app version create` \u9700\u8981\u5728\u5DF2\u7ED1\u5B9A\u7684\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(!templateKey)throw new Error("`platform app version create` \u9700\u8981\u663E\u5F0F\u4F20\u5165 `--template <template-key>`\u3002");let response=await createControlApiSdk({accessToken:selectApiToken(credentials2),tenantId:tenantId2,capability:"dashboard",requestClass:"control"}).createTenantAppSourceVersionFromTemplate(appId2,{template_key:templateKey,message:readOption2(args,"message")});syncSelectedAppContextFromBinding({tenant_id:response.tenant_id,app_id:response.app_id,env:binding?.env??"preview",app_name:binding?.app_name,app_display_name:binding?.app_display_name}),process7.stdout.write([`\u6E90\u7801\u7248\u672C\u5DF2\u521B\u5EFA\uFF1A${response.source_version_id}`,`tenant/app: ${response.tenant_id}/${response.app_id}`,`\u6A21\u677F: ${response.template_key}`,`\u6587\u4EF6\u6570: ${response.files_count}`,response.message?`\u8BF4\u660E: ${response.message}`:"\u8BF4\u660E: -","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A",` 1. platform app checkout --tenant ${response.tenant_id} --app ${response.app_id} --source-version ${response.source_version_id} --dir <project-name>`," 2. \u5728\u65B0\u76EE\u5F55\u4E2D\u7EE7\u7EED\u672C\u5730\u4FEE\u6539"," 3. \u5B8C\u6210\u540E\u6267\u884C `platform app submit` \u63D0\u4EA4\u540E\u7EED\u8FED\u4EE3",""].join(`
2673
2778
  `));return}if(nestedSubcommand==="list")return runApp({...args,rest:["versions",...args.rest.slice(2)]});throw new Error("`platform app version` \u76EE\u524D\u652F\u6301 `create` \u6216 `list`\u3002")}if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(subcommand);return}let context=loadStoredCliContext();if(subcommand==="current"){let sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext,hasProjectContext=!!(sourceContext?.tenant_id&&sourceContext.app_id);if(!(hasProjectContext?sourceContext?.app_id:context?.selected_app_id)){process7.stdout.write(`\u5F53\u524D\u672A\u9009\u62E9\u5E94\u7528\u4E0A\u4E0B\u6587\u3002
2674
2779
  `);return}process7.stdout.write((hasProjectContext?[`\u5F53\u524D\u5E94\u7528: ${sourceContext?.app_id}`,`\u5E94\u7528\u5C55\u793A\u540D: ${sourceContext?.app_display_name??sourceContext?.app_name??"-"}`,`\u79DF\u6237: ${sourceContext?.tenant_id??"-"}`,`\u73AF\u5883: ${sourceContext?.env??"preview"}`,`checkout \u57FA\u7EBF\u6E90\u7801\u7248\u672C: ${sourceContext?.base_source_version_id??"-"}`,`\u6700\u8FD1\u63D0\u4EA4\u6E90\u7801\u7248\u672C: ${sourceContext?.last_submitted_source_version_id??"-"}`,`\u6700\u8FD1 preview \u6E90\u7801\u7248\u672C: ${sourceContext?.last_preview_source_version_id??"-"}`,"\u4E0A\u4E0B\u6587\u6765\u6E90: \u5F53\u524D\u76EE\u5F55 .platform/source-context.json",`\u76EE\u5F55\u7ED1\u5B9A\u6587\u4EF6: ${sourceContextResult?.path??"-"}`,context?.selected_app_id?`\u5168\u5C40\u515C\u5E95\u4E0A\u4E0B\u6587: ${getCliContextPath()}`:"\u5168\u5C40\u515C\u5E95\u4E0A\u4E0B\u6587: -",""]:[`\u5F53\u524D\u5E94\u7528: ${context?.selected_app_id}`,`\u5E94\u7528\u5C55\u793A\u540D: ${context?.selected_app_display_name??context?.selected_app_name??"-"}`,`\u79DF\u6237: ${context?.selected_app_tenant_id??"-"}`,`\u73AF\u5883: ${context?.selected_app_env??"preview"}`,`checkout \u57FA\u7EBF\u6E90\u7801\u7248\u672C: ${sourceContext?.base_source_version_id??"-"}`,`\u6700\u8FD1\u63D0\u4EA4\u6E90\u7801\u7248\u672C: ${sourceContext?.last_submitted_source_version_id??"-"}`,`\u6700\u8FD1 preview \u6E90\u7801\u7248\u672C: ${sourceContext?.last_preview_source_version_id??"-"}`,"\u4E0A\u4E0B\u6587\u6765\u6E90: \u5168\u5C40 CLI context",`\u4E0A\u4E0B\u6587\u6587\u4EF6: ${getCliContextPath()}`,sourceContextResult?.path?`\u5F53\u524D\u76EE\u5F55 source-context: ${sourceContextResult.path}`:"\u5F53\u524D\u76EE\u5F55 source-context: -",""]).join(`
@@ -2716,15 +2821,15 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2716
2821
  `));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(`
2717
2822
  `));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(`
2718
2823
  `))}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(`
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:
2824
+ `)):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=existsSync28(`${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:
2720
2825
  - ${runtime.warnings.join(`
2721
2826
  - `)}`:`\u63D0\u793A:
2722
2827
  - \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(`
2723
2828
  `));try{autoRestartEnabled?await runDevSupervisor({command:runtime.command,cwd:runtime.cwd,env:runtime.env,watchRoot:runtime.cwd,onWatching:message=>{process7.stdout.write(`[dev] ${message}
2724
2829
  `)}}):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}
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}
2830
+ `),await new Promise((resolve20,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
2831
  ${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)}
2832
+ ${formatDependencyInstallFailureHint(installPlan.lockfile)}`));return}resolve20()})}),`\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)}
2728
2833
  `);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)}
2729
2834
  `);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)}
2730
2835
  `);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)}
@@ -2740,7 +2845,7 @@ ${formatDependencyInstallFailureHint(installPlan.lockfile)}`));return}resolve19(
2740
2845
  `);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)}
2741
2846
  `);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)}
2742
2847
  `);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)}
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)}
2848
+ `);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:readFileSync29(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)}
2744
2849
  `);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)}
2745
2850
  `);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)}
2746
2851
  `);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)}
@@ -2810,7 +2915,7 @@ ${formatDependencyInstallFailureHint(installPlan.lockfile)}`));return}resolve19(
2810
2915
  `));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(`
2811
2916
  `));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(`
2812
2917
  `));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(`
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(`
2918
+ `))}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"logout":await runLogout(args);return;case"credentials":await runCredentials(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
2919
  `,1)[0]},verify:error.result},null,2)}
2815
2920
  `),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(`
2816
2921
  `)}