@voobase/cli 0.1.1-nonprod.2086 → 0.1.1-nonprod.2100

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.
@@ -2222,7 +2222,7 @@ 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 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(`
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:"http://localhost:7001",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
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
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`
@@ -2317,7 +2317,7 @@ foreach ($sidValue in @($currentSid.Value, 'S-1-5-18', 'S-1-5-32-544')) {
2317
2317
  Set-Acl -LiteralPath $credentialPath -AclObject $acl
2318
2318
  `;function hardenWindowsCredentialFileAcl(filePath){let result=spawnSync3(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
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;return platform==="win32"?new WindowsDpapiCredentialStore({blobPath:join5(options.stateDir,"credentials.dpapi"),service:resolveCredentialStoreService(options.profileName,options.stateDir)}):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 applyApiResource(params,resource){resource&&params.set("resource",resource)}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>
2320
+ `)}function createCredentialStore(options){let platform=options.platform??process.platform;return platform==="win32"?new WindowsDpapiCredentialStore({blobPath:join5(options.stateDir,"credentials.dpapi"),service:resolveCredentialStoreService(options.profileName,options.stateDir)}):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 applyApiResource(params,resource){if(resource){try{new URL(resource)}catch{throw new Error("OIDC_AUDIENCE must be an absolute URI when used as the Logto API resource")}params.set("resource",resource)}}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>
2321
2321
  <html lang="zh-CN">
2322
2322
  <head>
2323
2323
  <meta charset="utf-8" />
@@ -2451,8 +2451,8 @@ Set-Acl -LiteralPath $credentialPath -AclObject $acl
2451
2451
  <p class="close-hint">\u8BF7\u91CD\u65B0\u5728\u7EC8\u7AEF\u6267\u884C platform login</p>
2452
2452
  </div>
2453
2453
  </body>
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` \u5B8C\u6210\u5F53\u524D\u5E73\u53F0\u7684\u51ED\u636E\u8FC1\u79FB\u6216\u654F\u611F\u5B57\u6BB5\u51C0\u5316\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){if(looksLikeJwt(credentials.access_token)){if(isJwtCurrent(credentials.access_token))return credentials.access_token;if(!credentials.id_token)throw new CliSessionExpiredError("access token \u5DF2\u8FC7\u671F")}if(credentials.id_token){if(looksLikeJwt(credentials.id_token)&&isJwtCurrent(credentials.id_token))return credentials.id_token;throw new CliSessionExpiredError("ID Token \u5DF2\u8FC7\u671F\u6216\u683C\u5F0F\u65E0\u6548")}return 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 isJwtCurrent(token,now=Date.now()){let expiresAt=readJwtExpiryMs(token);return expiresAt!==null&&expiresAt>now}function isCredentialExpired(credentials,now=Date.now()){if(looksLikeJwt(credentials.access_token)){let accessTokenExpiry=readJwtExpiryMs(credentials.access_token);return accessTokenExpiry===null||accessTokenExpiry-TOKEN_REFRESH_SKEW_MS<=now}if(credentials.id_token!==void 0){let idTokenExpiry=readJwtExpiryMs(credentials.id_token);return idTokenExpiry===null||idTokenExpiry-TOKEN_REFRESH_SKEW_MS<=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}return!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),applyApiResource(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 selectApiToken(nextCredentials),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()),applyApiResource(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(" ")),applyApiResource(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),applyApiResource(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),applyApiResource(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(" ")),applyApiResource(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)}
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` \u5B8C\u6210\u5F53\u524D\u5E73\u53F0\u7684\u51ED\u636E\u8FC1\u79FB\u6216\u654F\u611F\u5B57\u6BB5\u51C0\u5316\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){if(looksLikeJwt(credentials.access_token)&&isJwtCurrent(credentials.access_token))return credentials.access_token;throw new CliSessionExpiredError("control-api access token \u4E0D\u53EF\u7528")}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 isJwtCurrent(token,now=Date.now()){let expiresAt=readJwtExpiryMs(token);return expiresAt!==null&&expiresAt>now}function isCredentialExpired(credentials,now=Date.now()){if(looksLikeJwt(credentials.access_token)){let accessTokenExpiry=readJwtExpiryMs(credentials.access_token);return accessTokenExpiry===null||accessTokenExpiry-TOKEN_REFRESH_SKEW_MS<=now}return!0}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),applyApiResource(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 selectApiToken(nextCredentials),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()),applyApiResource(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 selectApiToken(nextCredentials),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(" ")),applyApiResource(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),applyApiResource(authorizationUrl.searchParams,config2.audience);let callbackPort=Number(redirectUrl.port||80),callbackResult=await new Promise((resolve20,reject)=>{let 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){let errMsg=url.searchParams.get("error_description")??error;res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml(errMsg),()=>rejectLogin(new Error(errMsg)));return}if(!code2||returnedState!==state){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"),()=>rejectLogin(new Error("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11 code \u6216 state \u4E0D\u5339\u914D")));return}res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginSuccessHtml(),()=>resolveLogin({code:code2}))}),settled=!1,timeout,waitingInterval,cleanupAndSettle=settle=>{if(!settled){if(settled=!0,timeout&&clearTimeout(timeout),waitingInterval&&clearInterval(waitingInterval),server.listening){server.close(()=>settle()),server.closeAllConnections();return}settle()}},resolveLogin=result=>{cleanupAndSettle(()=>resolve20(result))},rejectLogin=error=>{cleanupAndSettle(()=>reject(error))};timeout=setTimeout(()=>rejectLogin(new Error("\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`")),Math.max(config2.timeoutMs??300*1e3,1)),server.on("error",error=>{if(error.code==="EADDRINUSE"){rejectLogin(new Error(`CLI \u767B\u5F55\u56DE\u8C03\u7AEF\u53E3 ${redirectUrl.hostname}:${callbackPort} \u5DF2\u88AB\u5360\u7528\uFF1B\u8BF7\u5173\u95ED\u5360\u7528\u8BE5\u7AEF\u53E3\u7684\u65E7\u767B\u5F55\u8FDB\u7A0B\u540E\u91CD\u8BD5\u3002`));return}rejectLogin(error)}),server.listen(callbackPort,redirectUrl.hostname,()=>{config2.onWaiting&&(waitingInterval=setInterval(()=>{Promise.resolve().then(()=>config2.onWaiting?.()).catch(rejectLogin)},Math.max(config2.waitingIntervalMs??6e4,1)),waitingInterval.unref()),Promise.resolve().then(()=>config2.onPrompt?.({authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri})).catch(rejectLogin)})}),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),applyApiResource(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(" ")),applyApiResource(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
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
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
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(`
@@ -2529,7 +2529,8 @@ ${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:erro
2529
2529
  `)}function formatAuthMethodLabel(method){switch(method){case"admin_provisioned_password":return"\u90AE\u7BB1\u5BC6\u7801";case"email_magic_link":return"\u90AE\u7BB1 Magic Link";case"phone_sms_otp":return"\u624B\u673A\u9A8C\u8BC1\u7801";case"wechat_oauth":return"\u5FAE\u4FE1\u767B\u5F55"}}function appendDiagnosticFields(message,input){let lines=[message];return typeof input.detail?.feature_key=="string"&&lines.push(`Feature: ${input.detail.feature_key}`),input.code&&lines.push(`Code: ${input.code}`),input.requestId&&lines.push(`Request ID: ${input.requestId}`),lines.join(`
2530
2530
  `)}function formatAuthorizationCodeLoginPrompt(input){return input.opened?`\u5DF2\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B8C\u6210\u6388\u6743\u7801\u767B\u5F55\u3002
2531
2531
  `:[input.source==="cli-app"?"\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":"\u4F7F\u7528 workbench \u914D\u7F6E\u56DE\u9000\u6267\u884C\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\uFF0C\u5E76\u5F3A\u5236 prompt=login consent \u4EE5\u907F\u514D\u590D\u7528\u9519\u8BEF SSO \u4F1A\u8BDD\u5E76\u6362\u53D6 refresh token\u3002","\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\u7801\u767B\u5F55\u3002",`\u6388\u6743\u5730\u5740: ${input.authorizationUrl}`,`\u56DE\u8C03\u5730\u5740: ${input.redirectUri}`,input.source==="workbench-fallback"?"\u82E5\u56DE\u8C03\u7AEF\u53E3\u88AB\u672C\u5730 workbench \u5360\u7528\uFF0C\u8BF7\u5148\u6682\u65F6\u505C\u6B62\u5BF9\u5E94\u670D\u52A1\u540E\u91CD\u8BD5\u3002":"\u8BF7\u786E\u8BA4\u8BE5\u56DE\u8C03\u5730\u5740\u5DF2\u5728\u4E13\u7528 CLI App \u4E2D\u6CE8\u518C\u3002",""].join(`
2532
- `)}function normalizeAuthTemplate(value){if(value!==void 0){if(AUTH_CONFIGURE_TEMPLATE_VALUES.includes(value))return value;throw new Error(`\u65E0\u6548\u7684 \`--template\`\uFF0C\u4EC5\u652F\u6301 ${AUTH_CONFIGURE_TEMPLATE_VALUES_TEXT}\u3002`)}}function buildAuthConfigurePayload(options){let templatePayload=buildTemplatePayload(options.template);if(options.enablePhoneSmsOtp===!1&&templatePayload.enable_phone_sms_otp===!0)throw new Error("\u5F53\u524D `--template` \u4F9D\u8D56 `phone_sms_otp`\uFF0C\u4E0D\u80FD\u540C\u65F6\u4F20 `--disable-phone-sms-otp`\u3002");return{auth_enabled:options.enable?!0:void 0,user_store_id:options.userStoreId,auth_template:templatePayload.auth_template,enable_admin_provisioned_password:options.enableAdminProvisionedPassword,enable_phone_sms_otp:typeof options.enablePhoneSmsOtp=="boolean"?options.enablePhoneSmsOtp:templatePayload.enable_phone_sms_otp,enabled_sign_in_methods:templatePayload.enabled_sign_in_methods,default_sign_in_method:templatePayload.default_sign_in_method,registration_mode:templatePayload.registration_mode}}function hasAuthConfigureChanges(payload){return payload.auth_enabled!==void 0||payload.user_store_id!==void 0||payload.auth_template!==void 0||payload.enable_admin_provisioned_password!==void 0||payload.enable_phone_sms_otp!==void 0||payload.enabled_sign_in_methods!==void 0||payload.default_sign_in_method!==void 0||payload.registration_mode!==void 0}function buildTemplatePayload(template){switch(template){case"phone_sms_otp_only":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["phone_sms_otp"],default_sign_in_method:"phone_sms_otp",registration_mode:"open"};case"email_magic_link_and_phone_sms_otp":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["email_magic_link","phone_sms_otp"],default_sign_in_method:"email_magic_link",registration_mode:"open"};case"email_magic_link_only":case"admin_password_only":case"email_magic_link_and_admin_password":return{auth_template:template};default:return{}}}var BUILD_POLL_INTERVAL_MS=1500,BUILD_POLL_TIMEOUT_MS=18e4;async function runBuildCommand(args){if(hasHelpFlag3(args)){printBuildHelp(args.rest[0]);return}let subcommand=args.rest[0];if(subcommand!=="get"&&subcommand!=="events"&&subcommand!=="validate"&&subcommand!=="run")throw new Error("`platform build` \u4EC5\u652F\u6301 `run`\u3001`get <build-id>`\u3001`events <build-id>` \u6216 `validate --source-version <srcver>`\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 binding;try{binding=readBinding(process.cwd())?.binding}catch{binding=null}let tenantId=readStringOption3(args,"tenant")??binding?.tenant_id,buildId=args.rest[1]??readStringOption3(args,"build");if((subcommand==="get"||subcommand==="events")&&!buildId)throw new Error(`\`platform build ${subcommand}\` \u9700\u8981 <build-id>\uFF0C\u6216\u4F20\u5165 \`--build <build-id>\`\u3002`);let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"});if(subcommand==="run"){let appId=readStringOption3(args,"app")??binding?.app_id,sourceVersionId=readStringOption3(args,"source-version")??readStringOption3(args,"source_version");if(!tenantId||!appId||!sourceVersionId)throw new Error("`platform build run` \u9700\u8981 `--source-version <srcver>`\uFF0C\u4EE5\u53CA\u5DF2\u7ED1\u5B9A\u76EE\u5F55\u6216 `--tenant` / `--app`\u3002");let requestedBy=await resolveRequestedBy(sdk),buildConfig=await resolveBuildRunConfig(sdk,appId,sourceVersionId,readBuildConfig(args.options)),created=await sdk.createBuild({tenant_id:tenantId,app_id:appId,source_version_id:sourceVersionId,requested_by:requestedBy,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}}).catch(error=>{throw formatBuildRunError(error,appId,sourceVersionId)}),wait=args.options.wait===!0;if(args.options.json===!0&&!wait){process.stdout.write(`${JSON.stringify(created,null,2)}
2532
+ `)}function formatAuthorizationCodeLoginWaiting(){return`\u4ECD\u5728\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\uFF0C\u8BF7\u5728\u5DF2\u6253\u5F00\u7684\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u767B\u5F55\u3002
2533
+ `}function normalizeAuthTemplate(value){if(value!==void 0){if(AUTH_CONFIGURE_TEMPLATE_VALUES.includes(value))return value;throw new Error(`\u65E0\u6548\u7684 \`--template\`\uFF0C\u4EC5\u652F\u6301 ${AUTH_CONFIGURE_TEMPLATE_VALUES_TEXT}\u3002`)}}function buildAuthConfigurePayload(options){let templatePayload=buildTemplatePayload(options.template);if(options.enablePhoneSmsOtp===!1&&templatePayload.enable_phone_sms_otp===!0)throw new Error("\u5F53\u524D `--template` \u4F9D\u8D56 `phone_sms_otp`\uFF0C\u4E0D\u80FD\u540C\u65F6\u4F20 `--disable-phone-sms-otp`\u3002");return{auth_enabled:options.enable?!0:void 0,user_store_id:options.userStoreId,auth_template:templatePayload.auth_template,enable_admin_provisioned_password:options.enableAdminProvisionedPassword,enable_phone_sms_otp:typeof options.enablePhoneSmsOtp=="boolean"?options.enablePhoneSmsOtp:templatePayload.enable_phone_sms_otp,enabled_sign_in_methods:templatePayload.enabled_sign_in_methods,default_sign_in_method:templatePayload.default_sign_in_method,registration_mode:templatePayload.registration_mode}}function hasAuthConfigureChanges(payload){return payload.auth_enabled!==void 0||payload.user_store_id!==void 0||payload.auth_template!==void 0||payload.enable_admin_provisioned_password!==void 0||payload.enable_phone_sms_otp!==void 0||payload.enabled_sign_in_methods!==void 0||payload.default_sign_in_method!==void 0||payload.registration_mode!==void 0}function buildTemplatePayload(template){switch(template){case"phone_sms_otp_only":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["phone_sms_otp"],default_sign_in_method:"phone_sms_otp",registration_mode:"open"};case"email_magic_link_and_phone_sms_otp":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["email_magic_link","phone_sms_otp"],default_sign_in_method:"email_magic_link",registration_mode:"open"};case"email_magic_link_only":case"admin_password_only":case"email_magic_link_and_admin_password":return{auth_template:template};default:return{}}}var BUILD_POLL_INTERVAL_MS=1500,BUILD_POLL_TIMEOUT_MS=18e4;async function runBuildCommand(args){if(hasHelpFlag3(args)){printBuildHelp(args.rest[0]);return}let subcommand=args.rest[0];if(subcommand!=="get"&&subcommand!=="events"&&subcommand!=="validate"&&subcommand!=="run")throw new Error("`platform build` \u4EC5\u652F\u6301 `run`\u3001`get <build-id>`\u3001`events <build-id>` \u6216 `validate --source-version <srcver>`\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 binding;try{binding=readBinding(process.cwd())?.binding}catch{binding=null}let tenantId=readStringOption3(args,"tenant")??binding?.tenant_id,buildId=args.rest[1]??readStringOption3(args,"build");if((subcommand==="get"||subcommand==="events")&&!buildId)throw new Error(`\`platform build ${subcommand}\` \u9700\u8981 <build-id>\uFF0C\u6216\u4F20\u5165 \`--build <build-id>\`\u3002`);let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"});if(subcommand==="run"){let appId=readStringOption3(args,"app")??binding?.app_id,sourceVersionId=readStringOption3(args,"source-version")??readStringOption3(args,"source_version");if(!tenantId||!appId||!sourceVersionId)throw new Error("`platform build run` \u9700\u8981 `--source-version <srcver>`\uFF0C\u4EE5\u53CA\u5DF2\u7ED1\u5B9A\u76EE\u5F55\u6216 `--tenant` / `--app`\u3002");let requestedBy=await resolveRequestedBy(sdk),buildConfig=await resolveBuildRunConfig(sdk,appId,sourceVersionId,readBuildConfig(args.options)),created=await sdk.createBuild({tenant_id:tenantId,app_id:appId,source_version_id:sourceVersionId,requested_by:requestedBy,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}}).catch(error=>{throw formatBuildRunError(error,appId,sourceVersionId)}),wait=args.options.wait===!0;if(args.options.json===!0&&!wait){process.stdout.write(`${JSON.stringify(created,null,2)}
2533
2534
  `);return}if(!wait){printBuildStarted(created);return}let completed=await waitForBuild(sdk,created.id);if(args.options.json===!0){process.stdout.write(`${JSON.stringify(completed,null,2)}
2534
2535
  `);return}printBuildCompletion(completed);return}if(subcommand==="get"){let result2=await sdk.getBuild(buildId).catch(error=>{throw formatBuildCommandError(error,"get",buildId)});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
2535
2536
  `);return}printBuild(result2);return}if(subcommand==="validate"){let appId=readStringOption3(args,"app")??binding?.app_id,sourceVersionId=readStringOption3(args,"source-version")??readStringOption3(args,"source_version");if(!appId||!sourceVersionId)throw new Error("`platform build validate` \u9700\u8981 `--app <app-id>` \u4E0E `--source-version <srcver>`\uFF1B\u82E5\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A\uFF0C\u53EF\u7701\u7565 `--app`\u3002");let buildConfig=readBuildConfig(args.options),result2=await sdk.getBuildPrecheck(appId,{source_version_id:sourceVersionId,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}}).catch(error=>{throw formatBuildValidateError(error,appId,sourceVersionId)});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
@@ -2761,9 +2762,9 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2761
2762
  `):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(`
2762
2763
  `)),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"?["\u6CE8\u610F: \u4E3A\u5B89\u5168\u8D77\u89C1\u4E0D\u4F1A\u4FDD\u5B58\u539F\u59CB PAT\uFF0C\u5F53\u524D access token \u5230\u671F\u540E\u9700\u91CD\u65B0\u767B\u5F55\u3002"]:["\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(`
2763
2764
  `));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(`
2764
- `))}})}catch(error){if(!shouldFallbackToBrowserLogin(error))throw error;if(!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
2765
+ `))}})}catch(error){if(!shouldFallbackToBrowserLogin(error))throw error;if(!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",onWaiting:()=>{process7.stdout.write(formatAuthorizationCodeLoginWaiting())},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
2765
2766
  `:`\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
2766
- `),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}`,...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(`
2767
+ `),credentials=await performAuthorizationCodeLogin({issuer,clientId:browserLoginConfig.clientId,redirectUri:browserLoginConfig.redirectUri,audience,scopes,prompt:"login",onWaiting:()=>{process7.stdout.write(formatAuthorizationCodeLoginWaiting())},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}`,...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(`
2767
2768
  `))}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)}
2768
2769
  `)}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
2769
2770
  `);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(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voobase/cli",
3
- "version": "0.1.1-nonprod.2086",
3
+ "version": "0.1.1-nonprod.2100",
4
4
  "private": false,
5
5
  "platformDistributionProfile": {
6
6
  "name": "nonprod",
@@ -9,7 +9,7 @@
9
9
  "PUBLIC_API_BASE_URL": "https://public.voobase.21epub.com",
10
10
  "RUNTIME_API_BASE_URL": "https://runtime.voobase.21epub.com",
11
11
  "OIDC_ISSUER": "https://auth.voobase.21epub.com/oidc",
12
- "OIDC_AUDIENCE": "platform",
12
+ "OIDC_AUDIENCE": "https://control.voobase.21epub.com",
13
13
  "AUTH_CLI_CLIENT_ID": "6bhf054sho0etid9nob9h",
14
14
  "AUTH_CLI_REDIRECT_URI": "http://127.0.0.1:7300/callback",
15
15
  "AUTH_TENANT_CLIENT_ID": "77oz11v81kji9vs1wqred",
@@ -56,10 +56,10 @@
56
56
  "bundleDependencies": [],
57
57
  "platformDistributionBuild": {
58
58
  "channel": "nonprod",
59
- "version": "0.1.1-nonprod.2086",
60
- "sequence": 2086,
61
- "gitSha": "6083b4f",
62
- "fullGitSha": "6083b4fc3dca9254b91769b261a91edc687381b5",
63
- "buildId": "0.1.1-nonprod.2086+6083b4f"
59
+ "version": "0.1.1-nonprod.2100",
60
+ "sequence": 2100,
61
+ "gitSha": "8bc1491",
62
+ "fullGitSha": "8bc1491ad80f446bec2c96a2b799aade08e0a49b",
63
+ "buildId": "0.1.1-nonprod.2100+8bc1491"
64
64
  }
65
65
  }