create-sailor 1.3.2 → 1.3.4

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.
Files changed (3) hide show
  1. package/README.md +34 -29
  2. package/dist/index.js +130 -130
  3. package/package.json +13 -15
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import"./chunk-DGJUBN33.js";import{execSync as Ot}from"child_process";import ue from"fs";import dt from"path";import*as C from"@clack/prompts";import{Command as Li}from"commander";import R from"picocolors";import Mi from"update-notifier";import $o from"cfonts";import qo from"picocolors";import Zt from"fs";import Lt from"path";import{fileURLToPath as Bo}from"url";function Yo(){try{let t=Lt.dirname(Bo(import.meta.url));for(let o=0;o<4;o++){let n=Lt.join(t,"package.json");if(Zt.existsSync(n)){let r=Zt.readFileSync(n,"utf-8"),s=JSON.parse(r);if(s.name==="create-sailor"&&typeof s.version=="string")return s.version}t=Lt.dirname(t)}return"0.0.0-dev"}catch{return"0.0.0-dev"}}var ne=Yo();function en(){if(process.env.NO_COLOR||!process.stdout.isTTY){process.stdout.write([`Sailor v${ne}`,"AI-Native SaaS Unicorn Template","by Nebutra \xB7 https://nebutra.com","",""].join(`
3
- `));return}$o.say("Sailor",{font:"block",align:"left",colors:["#0033FE","#0BF1C3"],gradient:["#0033FE","#0BF1C3"],transitionGradient:!0,space:!1}),process.stdout.write(qo.dim(` AI-Native SaaS Template \xB7 v${ne} \xB7 nebutra.com
2
+ import"./chunk-DGJUBN33.js";import{execSync as Ot}from"child_process";import ue from"fs";import dt from"path";import*as C from"@clack/prompts";import{Command as Mi}from"commander";import R from"picocolors";import Di from"update-notifier";import Go from"cfonts";import Ho from"picocolors";import Zt from"fs";import Lt from"path";import{fileURLToPath as $o}from"url";function qo(){try{let t=Lt.dirname($o(import.meta.url));for(let o=0;o<4;o++){let n=Lt.join(t,"package.json");if(Zt.existsSync(n)){let r=Zt.readFileSync(n,"utf-8"),s=JSON.parse(r);if(s.name==="create-sailor"&&typeof s.version=="string")return s.version}t=Lt.dirname(t)}return"0.0.0-dev"}catch{return"0.0.0-dev"}}var ne=qo();function en(){if(process.env.NO_COLOR||!process.stdout.isTTY){process.stdout.write([`Sailor v${ne}`,"AI-Native SaaS Unicorn Template","by Nebutra \xB7 https://nebutra.com","",""].join(`
3
+ `));return}Go.say("Sailor",{font:"block",align:"left",colors:["#0033FE","#0BF1C3"],gradient:["#0033FE","#0BF1C3"],transitionGradient:!0,space:!1}),process.stdout.write(Ho.dim(` AI-Native SaaS Template \xB7 v${ne} \xB7 nebutra.com
4
4
 
5
- `))}import h from"picocolors";var Go={qstash:"foundation",bullmq:"foundation",upstash:"foundation",sqs:"foundation",meilisearch:"foundation",typesense:"foundation",algolia:"foundation",pgvector:"foundation",novu:"foundation",knock:"foundation",svix:"foundation","vercel-flags":"wip",growthbook:"wip",configcat:"wip",turnstile:"wip",hcaptcha:"wip","aliyun-slide":"wip"};function Ho(e){return e?Go[e]??"stable":"stable"}function St(e){switch(e){case"stable":return"";case"foundation":return"[Foundation]";case"wip":return"[WIP]";case"deprecated":return"[Deprecated]"}}function qe(e){switch(e){case"stable":return"Production-ready.";case"foundation":return"Foundation status \u2014 types + factory are complete, but provider adapters are stub-level and require external credentials.";case"wip":return"WIP \u2014 actively being built, should not be used in production.";case"deprecated":return"Deprecated \u2014 scheduled for removal, do not use."}}function tn(e){let t=[];for(let{flag:o,provider:n}of e){if(!n||n==="none")continue;let r=Ho(n);r!=="stable"&&t.push({flag:o,provider:n,status:r})}return t}function Wo(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function nn(e){let t=Wo(),o=t?"\u2693":"-",n=t?"\u25B8":"->",r=t?"\u2605":"*",s=t?"\u{1F4E7}":"*",c=["",` ${t?h.bold(`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`):`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`}`,"",` ${t?h.bold("Next:"):"Next:"}`,` ${n} cd ${e.targetDir}`];e.skippedInstall&&c.push(` ${n} pnpm install (if --no-install was set)`),c.push(` ${n} fill in .env.local ${t?h.dim("\u2192 add provider keys before booting apps"):"-> add provider keys before booting apps"}`,` ${n} pnpm db:migrate ${t?h.dim("\u2192 sync Prisma schema"):"-> sync Prisma schema"}`,` ${n} pnpm db:seed ${t?h.dim("\u2192 load example tenants and records"):"-> load example tenants and records"}`,` ${n} pnpm dev ${t?h.dim("\u2192 http://localhost:3000"):"-> http://localhost:3000"}`,"",` ${t?h.bold("Customize:"):"Customize:"}`,` ${n} pnpm brand:init ${t?h.dim("\u2192 create brand.config.ts"):"-> create brand.config.ts"}`,` ${n} pnpm brand:apply ${t?h.dim("\u2192 propagate brand changes"):"-> propagate brand changes"}`,` ${n} pnpm preset:env ${t?h.dim("\u2192 review preset env requirements"):"-> review preset env requirements"}`,"",` ${t?h.bold("Useful scripts:"):"Useful scripts:"}`,` ${n} pnpm infra:up ${t?h.dim("\u2192 start local PostgreSQL/Redis/ClickHouse"):"-> start local PostgreSQL/Redis/ClickHouse"}`,` ${n} pnpm generate:api-types ${t?h.dim("\u2192 refresh shared API client types"):"-> refresh shared API client types"}`,` ${n} pnpm lint ${t?h.dim("\u2192 quick repo sanity check"):"-> quick repo sanity check"}`);let i=e.previewSelections??[];if(i.length>0){let d=t?h.bold(h.yellow("\u26A0 Preview features selected:")):"!! Preview features selected:";c.push("",` ${d}`);for(let u of i){let S=St(u.status),U=` ${n} ${u.flag} (${u.provider}) ${S}`;c.push(t?h.yellow(U):U)}c.push("",` ${t?h.dim(qe("foundation")):qe("foundation")}`,` ${t?h.dim("You may need to contribute the provider integration yourself."):"You may need to contribute the provider integration yourself."}`,` ${t?h.dim("See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"):"See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"}`)}c.push("",` ${t?h.bold("Ship faster:"):"Ship faster:"}`,` ${r} Star us https://github.com/nebutra/nebutra-sailor`,` ${s} Free license https://nebutra.com/get-license`,""),process.stdout.write(c.join(`
5
+ `))}import E from"picocolors";var Wo={qstash:"foundation",bullmq:"foundation",upstash:"foundation",sqs:"foundation",meilisearch:"foundation",typesense:"foundation",algolia:"foundation",pgvector:"foundation",novu:"foundation",knock:"foundation",svix:"foundation","vercel-flags":"wip",growthbook:"wip",configcat:"wip",turnstile:"wip",hcaptcha:"wip","aliyun-slide":"wip"};function Xo(e){return e?Wo[e]??"stable":"stable"}function St(e){switch(e){case"stable":return"";case"foundation":return"[Foundation]";case"wip":return"[WIP]";case"deprecated":return"[Deprecated]"}}function qe(e){switch(e){case"stable":return"Production-ready.";case"foundation":return"Foundation status \u2014 types + factory are complete, but provider adapters are stub-level and require external credentials.";case"wip":return"WIP \u2014 actively being built, should not be used in production.";case"deprecated":return"Deprecated \u2014 scheduled for removal, do not use."}}function tn(e){let t=[];for(let{flag:o,provider:n}of e){if(!n||n==="none")continue;let r=Xo(n);r!=="stable"&&t.push({flag:o,provider:n,status:r})}return t}function zo(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function nn(e){let t=zo(),o=t?"\u2693":"-",n=t?"\u25B8":"->",r=t?"\u2605":"*",s=t?"\u{1F4E7}":"*",c=["",` ${t?E.bold(`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`):`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`}`,"",` ${t?E.bold("Next:"):"Next:"}`,` ${n} cd ${e.targetDir}`];e.skippedInstall&&c.push(` ${n} pnpm install (if --no-install was set)`),c.push(` ${n} fill in .env.local ${t?E.dim("\u2192 add provider keys before booting apps"):"-> add provider keys before booting apps"}`,` ${n} pnpm db:migrate ${t?E.dim("\u2192 sync Prisma schema"):"-> sync Prisma schema"}`,` ${n} pnpm db:seed ${t?E.dim("\u2192 load example tenants and records"):"-> load example tenants and records"}`,` ${n} pnpm dev ${t?E.dim("\u2192 http://localhost:3000"):"-> http://localhost:3000"}`,"",` ${t?E.bold("Customize:"):"Customize:"}`,` ${n} pnpm brand:init ${t?E.dim("\u2192 create brand.config.ts"):"-> create brand.config.ts"}`,` ${n} pnpm brand:apply ${t?E.dim("\u2192 propagate brand changes"):"-> propagate brand changes"}`,` ${n} pnpm preset:env ${t?E.dim("\u2192 review preset env requirements"):"-> review preset env requirements"}`,"",` ${t?E.bold("Useful scripts:"):"Useful scripts:"}`,` ${n} pnpm infra:up ${t?E.dim("\u2192 start local PostgreSQL/Redis/ClickHouse"):"-> start local PostgreSQL/Redis/ClickHouse"}`,` ${n} pnpm generate:api-types ${t?E.dim("\u2192 refresh shared API client types"):"-> refresh shared API client types"}`,` ${n} pnpm lint ${t?E.dim("\u2192 quick repo sanity check"):"-> quick repo sanity check"}`);let i=e.previewSelections??[];if(i.length>0){let d=t?E.bold(E.yellow("\u26A0 Preview features selected:")):"!! Preview features selected:";c.push("",` ${d}`);for(let u of i){let S=St(u.status),U=` ${n} ${u.flag} (${u.provider}) ${S}`;c.push(t?E.yellow(U):U)}c.push("",` ${t?E.dim(qe("foundation")):qe("foundation")}`,` ${t?E.dim("You may need to contribute the provider integration yourself."):"You may need to contribute the provider integration yourself."}`,` ${t?E.dim("See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"):"See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"}`)}c.push("",` ${t?E.bold("Ship faster:"):"Ship faster:"}`,` ${r} Star us https://github.com/nebutra/nebutra-sailor`,` ${s} Free license https://nebutra.com/get-license`,""),process.stdout.write(c.join(`
6
6
  `)+`
7
- `)}var Xo=`Usage: create-sailor [name] [options]
7
+ `)}var Qo=`Usage: create-sailor [name] [options]
8
8
 
9
9
  Arguments:
10
10
  name project directory (default: ./my-saas-app)
@@ -61,14 +61,14 @@ Toggles:
61
61
  -v, --version show version
62
62
 
63
63
  Examples:
64
- $ npm create sailor@latest
65
- $ npm create sailor@latest my-app -y
66
- $ npm create sailor@latest my-app --region=cn --auth=clerk
67
- $ npm create sailor@latest my-app --region=hybrid --ai=openai,deepseek
64
+ $ npx create-sailor@latest
65
+ $ npx create-sailor@latest my-app -y
66
+ $ npx create-sailor@latest my-app --region=cn --auth=clerk
67
+ $ npx create-sailor@latest my-app --region=hybrid --ai=openai,deepseek
68
68
  $ npm create sailor@latest --dry-run --region=cn
69
- `;function on(){process.stdout.write(Xo)}import Et from"picocolors";function rn(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function zo(e){let t=rn()?"\u25B8":"->",o=`[${e.index}/${e.total}]`,n=e.label.padEnd(18," ");return rn()?`${Et.dim(o)} ${Et.bold(n)} ${Et.dim(t)} ${Et.cyan(e.value)}`:`${o} ${n} ${t} ${e.value}`}function sn(e){process.stdout.write(zo(e)+`
70
- `)}var ht=[{id:"anthropic",name:"Anthropic",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.anthropic.com",envVarPrefix:"ANTHROPIC",requiredEnvVars:["ANTHROPIC_API_KEY"]},{id:"openai",name:"OpenAI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.openai.com/docs",envVarPrefix:"OPENAI",requiredEnvVars:["OPENAI_API_KEY"]},{id:"deepseek",name:"DeepSeek",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.deepseek.com/api-docs",envVarPrefix:"DEEPSEEK",requiredEnvVars:["DEEPSEEK_API_KEY"]},{id:"xai",name:"xAI (Grok)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.x.ai/api",envVarPrefix:"XAI",requiredEnvVars:["XAI_API_KEY"]},{id:"moonshot",name:"Moonshot (Kimi)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.moonshot.cn/docs",envVarPrefix:"MOONSHOT",requiredEnvVars:["MOONSHOT_API_KEY","MOONSHOT_BASE_URL"]},{id:"google",name:"Google Gemini",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://ai.google.dev/gemini-api/docs",envVarPrefix:"GOOGLE_GENERATIVE_AI",requiredEnvVars:["GOOGLE_GENERATIVE_AI_API_KEY"]},{id:"mistral",name:"Mistral AI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.mistral.ai",envVarPrefix:"MISTRAL",requiredEnvVars:["MISTRAL_API_KEY"]},{id:"cohere",name:"Cohere",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.cohere.com",envVarPrefix:"COHERE",requiredEnvVars:["COHERE_API_KEY"]},{id:"perplexity",name:"Perplexity",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.perplexity.ai",baseURL:"https://api.perplexity.ai",envVarPrefix:"PERPLEXITY",requiredEnvVars:["PERPLEXITY_API_KEY"]},{id:"ai21",name:"AI21 Labs",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.ai21.com",baseURL:"https://api.ai21.com/studio/v1",envVarPrefix:"AI21",requiredEnvVars:["AI21_API_KEY"]},{id:"upstage",name:"Upstage (Solar)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://developers.upstage.ai/docs",baseURL:"https://api.upstage.ai/v1/solar",envVarPrefix:"UPSTAGE",requiredEnvVars:["UPSTAGE_API_KEY"]},{id:"siliconflow",name:"\u7845\u57FA\u6D41\u52A8 SiliconFlow",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://docs.siliconflow.cn",baseURL:"https://api.siliconflow.cn/v1",envVarPrefix:"SILICONFLOW",requiredEnvVars:["SILICONFLOW_API_KEY"]},{id:"volcengine-ark",name:"\u706B\u5C71\u5F15\u64CE ARK (\u8C46\u5305)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://www.volcengine.com/docs/82379",baseURL:"https://ark.cn-beijing.volces.com/api/v3",envVarPrefix:"ARK",requiredEnvVars:["ARK_API_KEY"]},{id:"bailian",name:"\u767E\u70BC Bailian (\u901A\u4E49)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://help.aliyun.com/zh/model-studio",baseURL:"https://dashscope.aliyuncs.com/compatible-mode/v1",envVarPrefix:"DASHSCOPE",requiredEnvVars:["DASHSCOPE_API_KEY"]},{id:"zhipu",name:"\u667A\u8C31 AI Zhipu",category:"\u56FD\u5185\u5E73\u53F0",status:"ai-sdk",docs:"https://docs.bigmodel.cn",baseURL:"https://open.bigmodel.cn/api/paas/v4",envVarPrefix:"ZHIPU",requiredEnvVars:["ZHIPU_API_KEY"]},{id:"baichuan",name:"\u767E\u5DDD\u667A\u80FD Baichuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.baichuan-ai.com/docs",baseURL:"https://api.baichuan-ai.com/v1",envVarPrefix:"BAICHUAN",requiredEnvVars:["BAICHUAN_API_KEY"]},{id:"minimax",name:"MiniMax (ABAB)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.minimaxi.com/document/guides",baseURL:"https://api.minimax.chat/v1",envVarPrefix:"MINIMAX",requiredEnvVars:["MINIMAX_API_KEY","MINIMAX_GROUP_ID"]},{id:"stepfun",name:"\u9636\u8DC3\u661F\u8FB0 StepFun",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.stepfun.com/docs",baseURL:"https://api.stepfun.com/v1",envVarPrefix:"STEPFUN",requiredEnvVars:["STEPFUN_API_KEY"]},{id:"sensetime",name:"\u5546\u6C64 SenseNova",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.sensetime.com",baseURL:"https://api.sensenova.cn/v1",envVarPrefix:"SENSENOVA",requiredEnvVars:["SENSENOVA_API_KEY"]},{id:"tencent",name:"\u817E\u8BAF\u6DF7\u5143 Hunyuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://cloud.tencent.com/document/product/1729",baseURL:"https://api.hunyuan.cloud.tencent.com/v1",envVarPrefix:"HUNYUAN",requiredEnvVars:["HUNYUAN_API_KEY"]},{id:"lingyi",name:"\u96F6\u4E00\u4E07\u7269 Yi",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.lingyiwanwu.com/docs",baseURL:"https://api.lingyiwanwu.com/v1",envVarPrefix:"YI",requiredEnvVars:["YI_API_KEY"]},{id:"openrouter",name:"OpenRouter",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://openrouter.ai/docs",envVarPrefix:"OPENROUTER",requiredEnvVars:["OPENROUTER_API_KEY"]},{id:"vercel-gateway",name:"Vercel AI Gateway",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://vercel.com/docs/ai-gateway",envVarPrefix:"AI_GATEWAY",requiredEnvVars:["AI_GATEWAY_API_KEY"]},{id:"litellm",name:"LiteLLM Proxy",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://docs.litellm.ai",baseURL:"http://localhost:4000/v1",envVarPrefix:"LITELLM",requiredEnvVars:["LITELLM_API_KEY"]},{id:"portkey",name:"Portkey",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://portkey.ai/docs",baseURL:"https://api.portkey.ai/v1",envVarPrefix:"PORTKEY",requiredEnvVars:["PORTKEY_API_KEY"]},{id:"aws-bedrock",name:"AWS Bedrock",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://aws.amazon.com/bedrock/",envVarPrefix:"AWS_BEDROCK",requiredEnvVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"]},{id:"azure-openai",name:"Azure OpenAI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://azure.microsoft.com/en-us/products/cognitive-services/openai-service/",envVarPrefix:"AZURE_OPENAI",requiredEnvVars:["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"]},{id:"gcp-vertex",name:"GCP Vertex AI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://cloud.google.com/vertex-ai",envVarPrefix:"GOOGLE_VERTEX",requiredEnvVars:["GOOGLE_APPLICATION_CREDENTIALS"]},{id:"groq",name:"Groq",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://console.groq.com/docs",envVarPrefix:"GROQ",requiredEnvVars:["GROQ_API_KEY"]},{id:"fireworks",name:"Fireworks AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.fireworks.ai",envVarPrefix:"FIREWORKS",requiredEnvVars:["FIREWORKS_API_KEY"]},{id:"together",name:"Together AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.together.ai",envVarPrefix:"TOGETHER",requiredEnvVars:["TOGETHER_API_KEY"]},{id:"huggingface",name:"Hugging Face",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://huggingface.co/docs/inference-providers",envVarPrefix:"HF",requiredEnvVars:["HF_API_KEY"]},{id:"replicate",name:"Replicate",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://replicate.com/docs",envVarPrefix:"REPLICATE",requiredEnvVars:["REPLICATE_API_TOKEN"]},{id:"lepton",name:"Lepton AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://www.lepton.ai/docs",baseURL:"https://api.lepton.ai/v1",envVarPrefix:"LEPTON",requiredEnvVars:["LEPTON_API_KEY"]},{id:"anyscale",name:"Anyscale Endpoints",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://docs.endpoints.anyscale.com/",baseURL:"https://api.endpoints.anyscale.com/v1",envVarPrefix:"ANYSCALE",requiredEnvVars:["ANYSCALE_API_KEY"]},{id:"octoai",name:"OctoAI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://octoai.cloud/docs",baseURL:"https://text.octoai.run/v1",envVarPrefix:"OCTOAI",requiredEnvVars:["OCTOAI_TOKEN"]},{id:"deepinfra",name:"DeepInfra",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://deepinfra.com/docs",baseURL:"https://api.deepinfra.com/v1/openai",envVarPrefix:"DEEPINFRA",requiredEnvVars:["DEEPINFRA_API_KEY"]},{id:"novita",name:"Novita AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://novita.ai/docs",baseURL:"https://api.novita.ai/v3/openai",envVarPrefix:"NOVITA",requiredEnvVars:["NOVITA_API_KEY"]},{id:"black-forest-labs",name:"Black Forest Labs (FLUX)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://docs.bfl.ml",envVarPrefix:"BFL",requiredEnvVars:["BFL_API_KEY"]},{id:"elevenlabs",name:"ElevenLabs (TTS)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://elevenlabs.io/docs",envVarPrefix:"ELEVENLABS",requiredEnvVars:["ELEVENLABS_API_KEY"]},{id:"runway",name:"Runway (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://runwayml.com",envVarPrefix:"RUNWAY",requiredEnvVars:["RUNWAY_API_KEY"]},{id:"luma",name:"Luma (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://lumalabs.ai",envVarPrefix:"LUMA",requiredEnvVars:["LUMA_API_KEY"]},{id:"midjourney",name:"Midjourney",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://docs.midjourney.com",envVarPrefix:"MIDJOURNEY",requiredEnvVars:[]},{id:"ollama",name:"Ollama (\u672C\u5730)",category:"\u672C\u5730\u90E8\u7F72",status:"opencode",docs:"https://github.com/ollama/ollama",baseURL:"http://localhost:11434/v1",envVarPrefix:"OLLAMA",requiredEnvVars:["OLLAMA_BASE_URL"]},{id:"lmstudio",name:"LM Studio",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://lmstudio.ai/docs",baseURL:"http://localhost:1234/v1",envVarPrefix:"LMSTUDIO",requiredEnvVars:[]},{id:"vllm",name:"vLLM",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://docs.vllm.ai",baseURL:"http://localhost:8000/v1",envVarPrefix:"VLLM",requiredEnvVars:[]},{id:"tgi",name:"HF TGI",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://huggingface.co/docs/text-generation-inference",baseURL:"http://localhost:8080/v1",envVarPrefix:"TGI",requiredEnvVars:[]}],ta=ht.reduce((e,t)=>(e[t.category]||(e[t.category]=[]),e[t.category].push(t),e),{});var Qo="https://analytics.nebutra.com";function Jo(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function an(e,t={}){Jo(t)||(async()=>{try{let o=await import("./dist-XS6SQF6X.js");if(typeof o.createAnalyticsClient!="function")return;let n=o.createAnalyticsClient({posthog:{apiKey:process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.NEBUTRA_POSTHOG_HOST??Qo},onError:()=>{}});if(typeof n?.track!="function")return;let r=n.track("scaffold.completed",e);r&&typeof r.then=="function"&&await r.catch(()=>{})}catch{}})()}import Ge from"fs";import T from"path";var cn=[{id:"posthog",name:"PostHog",region:"both",envVars:["POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_HOST"],docs:"https://posthog.com/docs",pkgs:["posthog-js","posthog-node"],providerFile:"apps/web/src/lib/analytics/posthog.client.ts"},{id:"plausible",name:"Plausible",region:"global",envVars:["NEXT_PUBLIC_PLAUSIBLE_DOMAIN","NEXT_PUBLIC_PLAUSIBLE_SRC"],docs:"https://plausible.io/docs",providerFile:"apps/web/src/components/analytics/PlausibleScript.tsx"},{id:"umami",name:"Umami",region:"both",envVars:["NEXT_PUBLIC_UMAMI_WEBSITE_ID","NEXT_PUBLIC_UMAMI_SRC"],docs:"https://umami.is/docs",providerFile:"apps/web/src/components/analytics/UmamiScript.tsx"},{id:"mixpanel",name:"Mixpanel",region:"global",envVars:["MIXPANEL_TOKEN","NEXT_PUBLIC_MIXPANEL_TOKEN"],docs:"https://docs.mixpanel.com",pkgs:["mixpanel-browser","mixpanel"],providerFile:"apps/web/src/lib/analytics/mixpanel.client.ts"},{id:"baidu",name:"\u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji",region:"cn",envVars:["NEXT_PUBLIC_BAIDU_STATS_ID"],docs:"https://tongji.baidu.com",providerFile:"apps/web/src/components/analytics/BaiduStatsScript.tsx"},{id:"sensors",name:"\u795E\u7B56 Sensors Analytics",region:"cn",envVars:["NEXT_PUBLIC_SENSORS_SERVER_URL","NEXT_PUBLIC_SENSORS_APP_JS_URL"],docs:"https://manual.sensorsdata.cn",pkgs:["sa-sdk-javascript"],providerFile:"apps/web/src/lib/analytics/sensors.client.ts"},{id:"growingio",name:"GrowingIO",region:"cn",envVars:["NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID"],docs:"https://growingio.com/docs",providerFile:"apps/web/src/components/analytics/GrowingIoScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],ra=cn.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function pn(e){return cn.find(t=>t.id===e)}function Zo(e){Ge.mkdirSync(e,{recursive:!0})}function q(e,t){Zo(T.dirname(e)),Ge.writeFileSync(e,t)}function me(e,t){let o=T.join(e,".env.example");Ge.existsSync(o)?Ge.appendFileSync(o,`
71
- `+t):Ge.writeFileSync(o,t)}function er(e){let t=`"use client";
69
+ `;function on(){process.stdout.write(Qo)}import ht from"picocolors";function rn(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function Jo(e){let t=rn()?"\u25B8":"->",o=`[${e.index}/${e.total}]`,n=e.label.padEnd(18," ");return rn()?`${ht.dim(o)} ${ht.bold(n)} ${ht.dim(t)} ${ht.cyan(e.value)}`:`${o} ${n} ${t} ${e.value}`}function sn(e){process.stdout.write(Jo(e)+`
70
+ `)}var Et=[{id:"anthropic",name:"Anthropic",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.anthropic.com",envVarPrefix:"ANTHROPIC",requiredEnvVars:["ANTHROPIC_API_KEY"]},{id:"openai",name:"OpenAI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.openai.com/docs",envVarPrefix:"OPENAI",requiredEnvVars:["OPENAI_API_KEY"]},{id:"deepseek",name:"DeepSeek",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.deepseek.com/api-docs",envVarPrefix:"DEEPSEEK",requiredEnvVars:["DEEPSEEK_API_KEY"]},{id:"xai",name:"xAI (Grok)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.x.ai/api",envVarPrefix:"XAI",requiredEnvVars:["XAI_API_KEY"]},{id:"moonshot",name:"Moonshot (Kimi)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.moonshot.cn/docs",envVarPrefix:"MOONSHOT",requiredEnvVars:["MOONSHOT_API_KEY","MOONSHOT_BASE_URL"]},{id:"google",name:"Google Gemini",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://ai.google.dev/gemini-api/docs",envVarPrefix:"GOOGLE_GENERATIVE_AI",requiredEnvVars:["GOOGLE_GENERATIVE_AI_API_KEY"]},{id:"mistral",name:"Mistral AI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.mistral.ai",envVarPrefix:"MISTRAL",requiredEnvVars:["MISTRAL_API_KEY"]},{id:"cohere",name:"Cohere",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.cohere.com",envVarPrefix:"COHERE",requiredEnvVars:["COHERE_API_KEY"]},{id:"perplexity",name:"Perplexity",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.perplexity.ai",baseURL:"https://api.perplexity.ai",envVarPrefix:"PERPLEXITY",requiredEnvVars:["PERPLEXITY_API_KEY"]},{id:"ai21",name:"AI21 Labs",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.ai21.com",baseURL:"https://api.ai21.com/studio/v1",envVarPrefix:"AI21",requiredEnvVars:["AI21_API_KEY"]},{id:"upstage",name:"Upstage (Solar)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://developers.upstage.ai/docs",baseURL:"https://api.upstage.ai/v1/solar",envVarPrefix:"UPSTAGE",requiredEnvVars:["UPSTAGE_API_KEY"]},{id:"siliconflow",name:"\u7845\u57FA\u6D41\u52A8 SiliconFlow",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://docs.siliconflow.cn",baseURL:"https://api.siliconflow.cn/v1",envVarPrefix:"SILICONFLOW",requiredEnvVars:["SILICONFLOW_API_KEY"]},{id:"volcengine-ark",name:"\u706B\u5C71\u5F15\u64CE ARK (\u8C46\u5305)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://www.volcengine.com/docs/82379",baseURL:"https://ark.cn-beijing.volces.com/api/v3",envVarPrefix:"ARK",requiredEnvVars:["ARK_API_KEY"]},{id:"bailian",name:"\u767E\u70BC Bailian (\u901A\u4E49)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://help.aliyun.com/zh/model-studio",baseURL:"https://dashscope.aliyuncs.com/compatible-mode/v1",envVarPrefix:"DASHSCOPE",requiredEnvVars:["DASHSCOPE_API_KEY"]},{id:"zhipu",name:"\u667A\u8C31 AI Zhipu",category:"\u56FD\u5185\u5E73\u53F0",status:"ai-sdk",docs:"https://docs.bigmodel.cn",baseURL:"https://open.bigmodel.cn/api/paas/v4",envVarPrefix:"ZHIPU",requiredEnvVars:["ZHIPU_API_KEY"]},{id:"baichuan",name:"\u767E\u5DDD\u667A\u80FD Baichuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.baichuan-ai.com/docs",baseURL:"https://api.baichuan-ai.com/v1",envVarPrefix:"BAICHUAN",requiredEnvVars:["BAICHUAN_API_KEY"]},{id:"minimax",name:"MiniMax (ABAB)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.minimaxi.com/document/guides",baseURL:"https://api.minimax.chat/v1",envVarPrefix:"MINIMAX",requiredEnvVars:["MINIMAX_API_KEY","MINIMAX_GROUP_ID"]},{id:"stepfun",name:"\u9636\u8DC3\u661F\u8FB0 StepFun",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.stepfun.com/docs",baseURL:"https://api.stepfun.com/v1",envVarPrefix:"STEPFUN",requiredEnvVars:["STEPFUN_API_KEY"]},{id:"sensetime",name:"\u5546\u6C64 SenseNova",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.sensetime.com",baseURL:"https://api.sensenova.cn/v1",envVarPrefix:"SENSENOVA",requiredEnvVars:["SENSENOVA_API_KEY"]},{id:"tencent",name:"\u817E\u8BAF\u6DF7\u5143 Hunyuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://cloud.tencent.com/document/product/1729",baseURL:"https://api.hunyuan.cloud.tencent.com/v1",envVarPrefix:"HUNYUAN",requiredEnvVars:["HUNYUAN_API_KEY"]},{id:"lingyi",name:"\u96F6\u4E00\u4E07\u7269 Yi",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.lingyiwanwu.com/docs",baseURL:"https://api.lingyiwanwu.com/v1",envVarPrefix:"YI",requiredEnvVars:["YI_API_KEY"]},{id:"openrouter",name:"OpenRouter",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://openrouter.ai/docs",envVarPrefix:"OPENROUTER",requiredEnvVars:["OPENROUTER_API_KEY"]},{id:"vercel-gateway",name:"Vercel AI Gateway",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://vercel.com/docs/ai-gateway",envVarPrefix:"AI_GATEWAY",requiredEnvVars:["AI_GATEWAY_API_KEY"]},{id:"litellm",name:"LiteLLM Proxy",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://docs.litellm.ai",baseURL:"http://localhost:4000/v1",envVarPrefix:"LITELLM",requiredEnvVars:["LITELLM_API_KEY"]},{id:"portkey",name:"Portkey",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://portkey.ai/docs",baseURL:"https://api.portkey.ai/v1",envVarPrefix:"PORTKEY",requiredEnvVars:["PORTKEY_API_KEY"]},{id:"aws-bedrock",name:"AWS Bedrock",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://aws.amazon.com/bedrock/",envVarPrefix:"AWS_BEDROCK",requiredEnvVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"]},{id:"azure-openai",name:"Azure OpenAI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://azure.microsoft.com/en-us/products/cognitive-services/openai-service/",envVarPrefix:"AZURE_OPENAI",requiredEnvVars:["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"]},{id:"gcp-vertex",name:"GCP Vertex AI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://cloud.google.com/vertex-ai",envVarPrefix:"GOOGLE_VERTEX",requiredEnvVars:["GOOGLE_APPLICATION_CREDENTIALS"]},{id:"groq",name:"Groq",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://console.groq.com/docs",envVarPrefix:"GROQ",requiredEnvVars:["GROQ_API_KEY"]},{id:"fireworks",name:"Fireworks AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.fireworks.ai",envVarPrefix:"FIREWORKS",requiredEnvVars:["FIREWORKS_API_KEY"]},{id:"together",name:"Together AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.together.ai",envVarPrefix:"TOGETHER",requiredEnvVars:["TOGETHER_API_KEY"]},{id:"huggingface",name:"Hugging Face",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://huggingface.co/docs/inference-providers",envVarPrefix:"HF",requiredEnvVars:["HF_API_KEY"]},{id:"replicate",name:"Replicate",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://replicate.com/docs",envVarPrefix:"REPLICATE",requiredEnvVars:["REPLICATE_API_TOKEN"]},{id:"lepton",name:"Lepton AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://www.lepton.ai/docs",baseURL:"https://api.lepton.ai/v1",envVarPrefix:"LEPTON",requiredEnvVars:["LEPTON_API_KEY"]},{id:"anyscale",name:"Anyscale Endpoints",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://docs.endpoints.anyscale.com/",baseURL:"https://api.endpoints.anyscale.com/v1",envVarPrefix:"ANYSCALE",requiredEnvVars:["ANYSCALE_API_KEY"]},{id:"octoai",name:"OctoAI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://octoai.cloud/docs",baseURL:"https://text.octoai.run/v1",envVarPrefix:"OCTOAI",requiredEnvVars:["OCTOAI_TOKEN"]},{id:"deepinfra",name:"DeepInfra",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://deepinfra.com/docs",baseURL:"https://api.deepinfra.com/v1/openai",envVarPrefix:"DEEPINFRA",requiredEnvVars:["DEEPINFRA_API_KEY"]},{id:"novita",name:"Novita AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://novita.ai/docs",baseURL:"https://api.novita.ai/v3/openai",envVarPrefix:"NOVITA",requiredEnvVars:["NOVITA_API_KEY"]},{id:"black-forest-labs",name:"Black Forest Labs (FLUX)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://docs.bfl.ml",envVarPrefix:"BFL",requiredEnvVars:["BFL_API_KEY"]},{id:"elevenlabs",name:"ElevenLabs (TTS)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://elevenlabs.io/docs",envVarPrefix:"ELEVENLABS",requiredEnvVars:["ELEVENLABS_API_KEY"]},{id:"runway",name:"Runway (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://runwayml.com",envVarPrefix:"RUNWAY",requiredEnvVars:["RUNWAY_API_KEY"]},{id:"luma",name:"Luma (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://lumalabs.ai",envVarPrefix:"LUMA",requiredEnvVars:["LUMA_API_KEY"]},{id:"midjourney",name:"Midjourney",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://docs.midjourney.com",envVarPrefix:"MIDJOURNEY",requiredEnvVars:[]},{id:"ollama",name:"Ollama (\u672C\u5730)",category:"\u672C\u5730\u90E8\u7F72",status:"opencode",docs:"https://github.com/ollama/ollama",baseURL:"http://localhost:11434/v1",envVarPrefix:"OLLAMA",requiredEnvVars:["OLLAMA_BASE_URL"]},{id:"lmstudio",name:"LM Studio",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://lmstudio.ai/docs",baseURL:"http://localhost:1234/v1",envVarPrefix:"LMSTUDIO",requiredEnvVars:[]},{id:"vllm",name:"vLLM",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://docs.vllm.ai",baseURL:"http://localhost:8000/v1",envVarPrefix:"VLLM",requiredEnvVars:[]},{id:"tgi",name:"HF TGI",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://huggingface.co/docs/text-generation-inference",baseURL:"http://localhost:8080/v1",envVarPrefix:"TGI",requiredEnvVars:[]}],na=Et.reduce((e,t)=>(e[t.category]||(e[t.category]=[]),e[t.category].push(t),e),{});var Zo="https://analytics.nebutra.com";function er(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function an(e,t={}){er(t)||(async()=>{try{let o=await import("./dist-XS6SQF6X.js");if(typeof o.createAnalyticsClient!="function")return;let n=o.createAnalyticsClient({posthog:{apiKey:process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.NEBUTRA_POSTHOG_HOST??Zo},onError:()=>{}});if(typeof n?.track!="function")return;let r=n.track("scaffold.completed",e);r&&typeof r.then=="function"&&await r.catch(()=>{})}catch{}})()}import Ge from"fs";import T from"path";var cn=[{id:"posthog",name:"PostHog",region:"both",envVars:["POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_HOST"],docs:"https://posthog.com/docs",pkgs:["posthog-js","posthog-node"],providerFile:"apps/web/src/lib/analytics/posthog.client.ts"},{id:"plausible",name:"Plausible",region:"global",envVars:["NEXT_PUBLIC_PLAUSIBLE_DOMAIN","NEXT_PUBLIC_PLAUSIBLE_SRC"],docs:"https://plausible.io/docs",providerFile:"apps/web/src/components/analytics/PlausibleScript.tsx"},{id:"umami",name:"Umami",region:"both",envVars:["NEXT_PUBLIC_UMAMI_WEBSITE_ID","NEXT_PUBLIC_UMAMI_SRC"],docs:"https://umami.is/docs",providerFile:"apps/web/src/components/analytics/UmamiScript.tsx"},{id:"mixpanel",name:"Mixpanel",region:"global",envVars:["MIXPANEL_TOKEN","NEXT_PUBLIC_MIXPANEL_TOKEN"],docs:"https://docs.mixpanel.com",pkgs:["mixpanel-browser","mixpanel"],providerFile:"apps/web/src/lib/analytics/mixpanel.client.ts"},{id:"baidu",name:"\u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji",region:"cn",envVars:["NEXT_PUBLIC_BAIDU_STATS_ID"],docs:"https://tongji.baidu.com",providerFile:"apps/web/src/components/analytics/BaiduStatsScript.tsx"},{id:"sensors",name:"\u795E\u7B56 Sensors Analytics",region:"cn",envVars:["NEXT_PUBLIC_SENSORS_SERVER_URL","NEXT_PUBLIC_SENSORS_APP_JS_URL"],docs:"https://manual.sensorsdata.cn",pkgs:["sa-sdk-javascript"],providerFile:"apps/web/src/lib/analytics/sensors.client.ts"},{id:"growingio",name:"GrowingIO",region:"cn",envVars:["NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID"],docs:"https://growingio.com/docs",providerFile:"apps/web/src/components/analytics/GrowingIoScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],sa=cn.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function pn(e){return cn.find(t=>t.id===e)}function tr(e){Ge.mkdirSync(e,{recursive:!0})}function q(e,t){tr(T.dirname(e)),Ge.writeFileSync(e,t)}function me(e,t){let o=T.join(e,".env.example");Ge.existsSync(o)?Ge.appendFileSync(o,`
71
+ `+t):Ge.writeFileSync(o,t)}function nr(e){let t=`"use client";
72
72
  /**
73
73
  * PostHog browser SDK \u2014 lazy-initialized on first access.
74
74
  */
@@ -151,11 +151,11 @@ export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
151
151
 
152
152
  return <>{children}</>;
153
153
  }
154
- `;q(T.join(e,"src","lib","analytics","posthog.client.ts"),t),q(T.join(e,"src","lib","analytics","posthog.server.ts"),o),q(T.join(e,"src","components","analytics","AnalyticsProvider.tsx"),n)}function tr(){return`# PostHog \u2014 product analytics
154
+ `;q(T.join(e,"src","lib","analytics","posthog.client.ts"),t),q(T.join(e,"src","lib","analytics","posthog.server.ts"),o),q(T.join(e,"src","components","analytics","AnalyticsProvider.tsx"),n)}function or(){return`# PostHog \u2014 product analytics
155
155
  POSTHOG_KEY=
156
156
  NEXT_PUBLIC_POSTHOG_KEY=
157
157
  NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
158
- `}function nr(e){q(T.join(e,"src","components","analytics","PlausibleScript.tsx"),`"use client";
158
+ `}function rr(e){q(T.join(e,"src","components","analytics","PlausibleScript.tsx"),`"use client";
159
159
  /**
160
160
  * Plausible script tag \u2014 lightweight, privacy-friendly analytics.
161
161
  */
@@ -175,10 +175,10 @@ export function PlausibleScript() {
175
175
  />
176
176
  );
177
177
  }
178
- `)}function or(){return`# Plausible \u2014 privacy-friendly analytics
178
+ `)}function sr(){return`# Plausible \u2014 privacy-friendly analytics
179
179
  NEXT_PUBLIC_PLAUSIBLE_DOMAIN=
180
180
  NEXT_PUBLIC_PLAUSIBLE_SRC=https://plausible.io/js/script.js
181
- `}function rr(e){q(T.join(e,"src","components","analytics","UmamiScript.tsx"),`"use client";
181
+ `}function ir(e){q(T.join(e,"src","components","analytics","UmamiScript.tsx"),`"use client";
182
182
  /**
183
183
  * Umami analytics \u2014 self-hosted OR umami.is cloud.
184
184
  */
@@ -198,10 +198,10 @@ export function UmamiScript() {
198
198
  />
199
199
  );
200
200
  }
201
- `)}function sr(){return`# Umami \u2014 self-hostable analytics
201
+ `)}function ar(){return`# Umami \u2014 self-hostable analytics
202
202
  NEXT_PUBLIC_UMAMI_WEBSITE_ID=
203
203
  NEXT_PUBLIC_UMAMI_SRC=https://cloud.umami.is/script.js
204
- `}function ir(e){let t=`"use client";
204
+ `}function cr(e){let t=`"use client";
205
205
  import mixpanel from "mixpanel-browser";
206
206
 
207
207
  let initialized = false;
@@ -240,10 +240,10 @@ export function trackServer(
240
240
  if (!c) return;
241
241
  c.track(event, { distinct_id: distinctId, ...properties });
242
242
  }
243
- `;q(T.join(e,"src","lib","analytics","mixpanel.client.ts"),t),q(T.join(e,"src","lib","analytics","mixpanel.server.ts"),o)}function ar(){return`# Mixpanel \u2014 product analytics
243
+ `;q(T.join(e,"src","lib","analytics","mixpanel.client.ts"),t),q(T.join(e,"src","lib","analytics","mixpanel.server.ts"),o)}function pr(){return`# Mixpanel \u2014 product analytics
244
244
  MIXPANEL_TOKEN=
245
245
  NEXT_PUBLIC_MIXPANEL_TOKEN=
246
- `}function cr(e){q(T.join(e,"src","components","analytics","BaiduStatsScript.tsx"),`"use client";
246
+ `}function lr(e){q(T.join(e,"src","components","analytics","BaiduStatsScript.tsx"),`"use client";
247
247
  /**
248
248
  * \u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji \u2014 hm.js \u57CB\u70B9\u811A\u672C.
249
249
  */
@@ -269,9 +269,9 @@ var _hmt = _hmt || [];
269
269
  />
270
270
  );
271
271
  }
272
- `)}function pr(){return`# \u767E\u5EA6\u7EDF\u8BA1 \u2014 \u4E2D\u56FD\u533A\u7F51\u7AD9\u5206\u6790
272
+ `)}function dr(){return`# \u767E\u5EA6\u7EDF\u8BA1 \u2014 \u4E2D\u56FD\u533A\u7F51\u7AD9\u5206\u6790
273
273
  NEXT_PUBLIC_BAIDU_STATS_ID=
274
- `}function lr(e){q(T.join(e,"src","lib","analytics","sensors.client.ts"),`"use client";
274
+ `}function ur(e){q(T.join(e,"src","lib","analytics","sensors.client.ts"),`"use client";
275
275
  /**
276
276
  * \u795E\u7B56\u5206\u6790 (Sensors Analytics) \u2014 sa-sdk-javascript \u5C01\u88C5.
277
277
  */
@@ -299,10 +299,10 @@ export function initSensors(): void {
299
299
  }
300
300
 
301
301
  export { sensors };
302
- `)}function dr(){return`# \u795E\u7B56\u5206\u6790 Sensors Analytics
302
+ `)}function mr(){return`# \u795E\u7B56\u5206\u6790 Sensors Analytics
303
303
  NEXT_PUBLIC_SENSORS_SERVER_URL=
304
304
  NEXT_PUBLIC_SENSORS_APP_JS_URL=
305
- `}function ur(e){q(T.join(e,"src","components","analytics","GrowingIoScript.tsx"),`"use client";
305
+ `}function gr(e){q(T.join(e,"src","components","analytics","GrowingIoScript.tsx"),`"use client";
306
306
  /**
307
307
  * GrowingIO CDP \u2014 inline snippet installer.
308
308
  */
@@ -327,11 +327,11 @@ gdp("send");
327
327
  />
328
328
  );
329
329
  }
330
- `)}function mr(){return`# GrowingIO \u2014 \u5168\u57CB\u70B9 CDP (\u4E2D\u56FD\u533A)
330
+ `)}function fr(){return`# GrowingIO \u2014 \u5168\u57CB\u70B9 CDP (\u4E2D\u56FD\u533A)
331
331
  NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID=
332
- `}async function ln(e,t,o="global"){let n=pn(t);if(!n||n.id==="none")return;let r=T.join(e,"apps","web");if(!Ge.existsSync(r))return;let s=n.id;try{switch(s){case"posthog":er(r),me(e,tr());return;case"plausible":nr(r),me(e,or());return;case"umami":rr(r),me(e,sr());return;case"mixpanel":ir(r),me(e,ar());return;case"baidu":cr(r),me(e,pr());return;case"sensors":lr(r),me(e,dr());return;case"growingio":ur(r),me(e,mr());return;default:return}}catch(a){throw console.error(`Failed to apply analytics selection "${t}":`,a),new Error(`Analytics scaffold for "${t}" failed \u2014 see stderr for details.`)}}import M from"fs";import ge from"path";function Mt(e){M.existsSync(e)&&M.rmSync(e,{recursive:!0,force:!0})}function dn(e,t){let o=ge.join(e,".env.example");M.existsSync(o)?M.appendFileSync(o,`
333
- `+t):M.writeFileSync(o,t)}function un(e,t){if(!M.existsSync(e))return;let o=M.readFileSync(e,"utf8"),n=o.replace(/export type AuthProviderId\s*=\s*"[^"]+"\s*\|\s*"[^"]+";/,`export type AuthProviderId = "${t}";`);n!==o&&M.writeFileSync(e,n)}function gr(e,t){let o=ge.join(e,"README.md");if(!M.existsSync(o)){M.writeFileSync(o,t);return}M.appendFileSync(o,`
334
- `+t)}async function mn(e,t){let o=ge.join(e,"packages","auth");if(!M.existsSync(o))return;if(t==="none"){Mt(o),gr(e,`
332
+ `}async function ln(e,t,o="global"){let n=pn(t);if(!n||n.id==="none")return;let r=T.join(e,"apps","web");if(!Ge.existsSync(r))return;let s=n.id;try{switch(s){case"posthog":nr(r),me(e,or());return;case"plausible":rr(r),me(e,sr());return;case"umami":ir(r),me(e,ar());return;case"mixpanel":cr(r),me(e,pr());return;case"baidu":lr(r),me(e,dr());return;case"sensors":ur(r),me(e,mr());return;case"growingio":gr(r),me(e,fr());return;default:return}}catch(a){throw console.error(`Failed to apply analytics selection "${t}":`,a),new Error(`Analytics scaffold for "${t}" failed \u2014 see stderr for details.`)}}import M from"fs";import ge from"path";function Mt(e){M.existsSync(e)&&M.rmSync(e,{recursive:!0,force:!0})}function dn(e,t){let o=ge.join(e,".env.example");M.existsSync(o)?M.appendFileSync(o,`
333
+ `+t):M.writeFileSync(o,t)}function un(e,t){if(!M.existsSync(e))return;let o=M.readFileSync(e,"utf8"),n=o.replace(/export type AuthProviderId\s*=\s*"[^"]+"\s*\|\s*"[^"]+";/,`export type AuthProviderId = "${t}";`);n!==o&&M.writeFileSync(e,n)}function yr(e,t){let o=ge.join(e,"README.md");if(!M.existsSync(o)){M.writeFileSync(o,t);return}M.appendFileSync(o,`
334
+ `+t)}async function mn(e,t){let o=ge.join(e,"packages","auth");if(!M.existsSync(o))return;if(t==="none"){Mt(o),yr(e,`
335
335
  ## Auth
336
336
 
337
337
  Auth was skipped at scaffold time (\`--auth=none\`). Add your preferred auth provider manually (e.g. Clerk, Better Auth, NextAuth).
@@ -341,7 +341,7 @@ CLERK_SECRET_KEY=
341
341
  `);return}if(t==="betterauth"){Mt(ge.join(n,"clerk.ts")),un(r,"better-auth"),dn(e,`# Better Auth
342
342
  BETTER_AUTH_SECRET=
343
343
  BETTER_AUTH_URL=http://localhost:3000
344
- `);return}}var nt=[{id:"wechat",name:"\u5FAE\u4FE1\u5F00\u653E\u5E73\u53F0",region:"cn",envVars:["WECHAT_APP_ID","WECHAT_APP_SECRET"],docs:"https://open.weixin.qq.com/cgi-bin/showdocument",callbackUrl:"/api/auth/callback/wechat",tokenEndpoint:"https://api.weixin.qq.com/sns/oauth2/access_token"},{id:"qq",name:"QQ \u767B\u5F55",region:"cn",envVars:["QQ_APP_ID","QQ_APP_KEY"],docs:"https://wiki.connect.qq.com",callbackUrl:"/api/auth/callback/qq",tokenEndpoint:"https://graph.qq.com/oauth2.0/token"},{id:"dingtalk",name:"\u9489\u9489",region:"cn",envVars:["DINGTALK_APP_ID","DINGTALK_APP_SECRET"],docs:"https://open.dingtalk.com/document/",callbackUrl:"/api/auth/callback/dingtalk",tokenEndpoint:"https://api.dingtalk.com/v1.0/oauth2/userAccessToken"},{id:"workweixin",name:"\u4F01\u4E1A\u5FAE\u4FE1",region:"cn",envVars:["WORKWEIXIN_CORP_ID","WORKWEIXIN_AGENT_ID","WORKWEIXIN_SECRET"],docs:"https://developer.work.weixin.qq.com",callbackUrl:"/api/auth/callback/workweixin",tokenEndpoint:"https://qyapi.weixin.qq.com/cgi-bin/gettoken"},{id:"feishu",name:"\u98DE\u4E66 / Lark",region:"cn",envVars:["FEISHU_APP_ID","FEISHU_APP_SECRET"],docs:"https://open.feishu.cn/document/",callbackUrl:"/api/auth/callback/feishu",tokenEndpoint:"https://open.feishu.cn/open-apis/authen/v1/access_token"},{id:"weibo",name:"\u5FAE\u535A",region:"cn",envVars:["WEIBO_APP_KEY","WEIBO_APP_SECRET"],docs:"https://open.weibo.com/wiki/",callbackUrl:"/api/auth/callback/weibo",tokenEndpoint:"https://api.weibo.com/oauth2/access_token"}],fr=new Set(nt.map(e=>e.id));function gn(e){return nt.find(t=>t.id===e)}function fn(e){if(!e)return[];let t=e.split(",").map(r=>r.trim().toLowerCase()).filter(Boolean);if(t.includes("none"))return[];let o=[],n=new Set;for(let r of t)fr.has(r)&&!n.has(r)&&(o.push(r),n.add(r));return o}import ye from"fs";import fe from"path";function yr(e,t){let o=`// apps/web/src/app/api/auth/callback/${e.id}/route.ts
344
+ `);return}}var nt=[{id:"wechat",name:"\u5FAE\u4FE1\u5F00\u653E\u5E73\u53F0",region:"cn",envVars:["WECHAT_APP_ID","WECHAT_APP_SECRET"],docs:"https://open.weixin.qq.com/cgi-bin/showdocument",callbackUrl:"/api/auth/callback/wechat",tokenEndpoint:"https://api.weixin.qq.com/sns/oauth2/access_token"},{id:"qq",name:"QQ \u767B\u5F55",region:"cn",envVars:["QQ_APP_ID","QQ_APP_KEY"],docs:"https://wiki.connect.qq.com",callbackUrl:"/api/auth/callback/qq",tokenEndpoint:"https://graph.qq.com/oauth2.0/token"},{id:"dingtalk",name:"\u9489\u9489",region:"cn",envVars:["DINGTALK_APP_ID","DINGTALK_APP_SECRET"],docs:"https://open.dingtalk.com/document/",callbackUrl:"/api/auth/callback/dingtalk",tokenEndpoint:"https://api.dingtalk.com/v1.0/oauth2/userAccessToken"},{id:"workweixin",name:"\u4F01\u4E1A\u5FAE\u4FE1",region:"cn",envVars:["WORKWEIXIN_CORP_ID","WORKWEIXIN_AGENT_ID","WORKWEIXIN_SECRET"],docs:"https://developer.work.weixin.qq.com",callbackUrl:"/api/auth/callback/workweixin",tokenEndpoint:"https://qyapi.weixin.qq.com/cgi-bin/gettoken"},{id:"feishu",name:"\u98DE\u4E66 / Lark",region:"cn",envVars:["FEISHU_APP_ID","FEISHU_APP_SECRET"],docs:"https://open.feishu.cn/document/",callbackUrl:"/api/auth/callback/feishu",tokenEndpoint:"https://open.feishu.cn/open-apis/authen/v1/access_token"},{id:"weibo",name:"\u5FAE\u535A",region:"cn",envVars:["WEIBO_APP_KEY","WEIBO_APP_SECRET"],docs:"https://open.weibo.com/wiki/",callbackUrl:"/api/auth/callback/weibo",tokenEndpoint:"https://api.weibo.com/oauth2/access_token"}],Sr=new Set(nt.map(e=>e.id));function gn(e){return nt.find(t=>t.id===e)}function fn(e){if(!e)return[];let t=e.split(",").map(r=>r.trim().toLowerCase()).filter(Boolean);if(t.includes("none"))return[];let o=[],n=new Set;for(let r of t)Sr.has(r)&&!n.has(r)&&(o.push(r),n.add(r));return o}import ye from"fs";import fe from"path";function hr(e,t){let o=`// apps/web/src/app/api/auth/callback/${e.id}/route.ts
345
345
  // Generated by create-sailor \u2014 OAuth callback for ${e.name}
346
346
  // Primary auth provider: ${t}
347
347
  // Docs: ${e.docs}`,n={wechat:` const tokenRes = await fetch(
@@ -466,7 +466,7 @@ ${n[e.id]}
466
466
  void state;
467
467
  return NextResponse.redirect(new URL("/dashboard", req.url));
468
468
  }
469
- `}function Sr(e){return`"use client";
469
+ `}function Er(e){return`"use client";
470
470
 
471
471
  /**
472
472
  * SocialLoginButtons \u2014 generated by create-sailor.
@@ -509,23 +509,23 @@ export function SocialLoginButtons() {
509
509
  </div>
510
510
  );
511
511
  }
512
- `}function yn(e){ye.mkdirSync(e,{recursive:!0})}function Er(e,t){let o=fe.join(e,".env.example");ye.existsSync(o)?ye.appendFileSync(o,`
513
- `+t):ye.writeFileSync(o,t)}function hr(e){let t=`# ${e.name} (${e.id}) \u2014 ${e.docs}`,o=e.envVars.map(n=>`${n}=`).join(`
512
+ `}function yn(e){ye.mkdirSync(e,{recursive:!0})}function vr(e,t){let o=fe.join(e,".env.example");ye.existsSync(o)?ye.appendFileSync(o,`
513
+ `+t):ye.writeFileSync(o,t)}function _r(e){let t=`# ${e.name} (${e.id}) \u2014 ${e.docs}`,o=e.envVars.map(n=>`${n}=`).join(`
514
514
  `);return`${t}
515
515
  ${o}
516
- `}async function Sn(e,t,o){if(!t||t.length===0)return;let n=fe.join(e,"apps","web");if(!ye.existsSync(n))return;let r=new Set,s=[];for(let d of t){if(r.has(d))continue;r.add(d);let u=gn(d);u&&s.push(u)}if(s.length===0)return;for(let d of s)Er(e,hr(d));let a=fe.join(n,"src","app","api","auth","callback");for(let d of s){let u=fe.join(a,d.id);yn(u);let S=fe.join(u,"route.ts");ye.writeFileSync(S,yr(d,o))}let c=fe.join(n,"src","components","auth");yn(c);let i=fe.join(c,"SocialLoginButtons.tsx");ye.writeFileSync(i,Sr(s))}import oe from"fs";import Dt from"path";var vt=[{id:"upstash-redis",name:"Upstash Redis",region:"both",envVars:["UPSTASH_REDIS_REST_URL","UPSTASH_REDIS_REST_TOKEN"],docs:"https://upstash.com/docs/redis",description:"Serverless Redis"},{id:"vercel-kv",name:"Vercel KV",region:"global",envVars:["KV_URL","KV_REST_API_URL","KV_REST_API_TOKEN","KV_REST_API_READ_ONLY_TOKEN"],docs:"https://vercel.com/docs/storage/vercel-kv",description:"Vercel native KV"},{id:"redis",name:"Redis (self-hosted)",region:"both",envVars:["REDIS_URL"],docs:"https://redis.io/docs/",description:"Self-hosted Redis"},{id:"dragonfly",name:"Dragonfly",region:"global",envVars:["DRAGONFLY_URL"],docs:"https://www.dragonflydb.io/docs",description:"Drop-in Redis replacement, faster"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip cache package"}];function En(e){return vt.find(t=>t.id===e)}var Ea=vt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function hn(e){return oe.existsSync(e)?oe.readFileSync(e,"utf-8"):null}function vr(e,t){let o=Dt.join(e,".env.example"),n=hn(o);if(n===null)return;let r=`# Cache: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
517
- `);oe.appendFileSync(o,s)}function _r(e,t,o){let n=Dt.join(e,".env.example"),r=hn(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?oe.writeFileSync(n,r.replace(s,`${t}="${o}"`)):oe.appendFileSync(n,`${t}="${o}"
518
- `)}async function vn(e,t,o){let n=Dt.join(e,"packages","cache");if(t==="none"){oe.existsSync(n)&&oe.rmSync(n,{recursive:!0,force:!0});return}let r=En(t);if(!r)throw new Error(`Unknown cache provider "${t}". Valid ids: ${vt.map(s=>s.id).join(", ")}`);oe.existsSync(n)&&(vr(e,r),_r(e,"CACHE_PROVIDER",t))}var _t=[{id:"turnstile",name:"Cloudflare Turnstile",region:"global",envVars:["NEXT_PUBLIC_TURNSTILE_SITE_KEY","TURNSTILE_SECRET_KEY"],docs:"https://developers.cloudflare.com/turnstile/",description:"Free, privacy-focused captcha alternative"},{id:"hcaptcha",name:"hCaptcha",region:"global",envVars:["NEXT_PUBLIC_HCAPTCHA_SITE_KEY","HCAPTCHA_SECRET_KEY"],docs:"https://docs.hcaptcha.com/",description:"Privacy-respecting captcha"},{id:"aliyun-slide",name:"\u963F\u91CC\u4E91\u9A8C\u8BC1\u7801 2.0",region:"cn",envVars:["ALIYUN_CAPTCHA_ACCESS_KEY_ID","ALIYUN_CAPTCHA_ACCESS_KEY_SECRET","ALIYUN_CAPTCHA_APP_KEY","NEXT_PUBLIC_ALIYUN_CAPTCHA_APP_KEY"],docs:"https://help.aliyun.com/product/28308.html",description:"\u963F\u91CC\u4E91\u667A\u80FD\u9A8C\u8BC1 (\u6ED1\u5757/\u65E0\u75D5)"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function _n(e){return _t.find(t=>t.id===e)}var Ia=_t.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});import J from"fs";import Ft from"path";function G(e,t){let o=Ft.join(e,".env.example");if(!J.existsSync(o)||t.envVars.length===0)return;let r=`# ${t.category??t.name}: ${t.name}`;if(J.readFileSync(o,"utf-8").includes(r))return;let c=["","# =============================================",r,t.docs?`# Docs: ${t.docs}`:null,"# =============================================",...t.envVars.map(i=>`${i}=""`),""].filter(i=>i!==null).join(`
516
+ `}async function Sn(e,t,o){if(!t||t.length===0)return;let n=fe.join(e,"apps","web");if(!ye.existsSync(n))return;let r=new Set,s=[];for(let d of t){if(r.has(d))continue;r.add(d);let u=gn(d);u&&s.push(u)}if(s.length===0)return;for(let d of s)vr(e,_r(d));let a=fe.join(n,"src","app","api","auth","callback");for(let d of s){let u=fe.join(a,d.id);yn(u);let S=fe.join(u,"route.ts");ye.writeFileSync(S,hr(d,o))}let c=fe.join(n,"src","components","auth");yn(c);let i=fe.join(c,"SocialLoginButtons.tsx");ye.writeFileSync(i,Er(s))}import oe from"fs";import Dt from"path";var vt=[{id:"upstash-redis",name:"Upstash Redis",region:"both",envVars:["UPSTASH_REDIS_REST_URL","UPSTASH_REDIS_REST_TOKEN"],docs:"https://upstash.com/docs/redis",description:"Serverless Redis"},{id:"vercel-kv",name:"Vercel KV",region:"global",envVars:["KV_URL","KV_REST_API_URL","KV_REST_API_TOKEN","KV_REST_API_READ_ONLY_TOKEN"],docs:"https://vercel.com/docs/storage/vercel-kv",description:"Vercel native KV"},{id:"redis",name:"Redis (self-hosted)",region:"both",envVars:["REDIS_URL"],docs:"https://redis.io/docs/",description:"Self-hosted Redis"},{id:"dragonfly",name:"Dragonfly",region:"global",envVars:["DRAGONFLY_URL"],docs:"https://www.dragonflydb.io/docs",description:"Drop-in Redis replacement, faster"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip cache package"}];function hn(e){return vt.find(t=>t.id===e)}var Ea=vt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function En(e){return oe.existsSync(e)?oe.readFileSync(e,"utf-8"):null}function Pr(e,t){let o=Dt.join(e,".env.example"),n=En(o);if(n===null)return;let r=`# Cache: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
517
+ `);oe.appendFileSync(o,s)}function br(e,t,o){let n=Dt.join(e,".env.example"),r=En(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?oe.writeFileSync(n,r.replace(s,`${t}="${o}"`)):oe.appendFileSync(n,`${t}="${o}"
518
+ `)}async function vn(e,t,o){let n=Dt.join(e,"packages","cache");if(t==="none"){oe.existsSync(n)&&oe.rmSync(n,{recursive:!0,force:!0});return}let r=hn(t);if(!r)throw new Error(`Unknown cache provider "${t}". Valid ids: ${vt.map(s=>s.id).join(", ")}`);oe.existsSync(n)&&(Pr(e,r),br(e,"CACHE_PROVIDER",t))}var _t=[{id:"turnstile",name:"Cloudflare Turnstile",region:"global",envVars:["NEXT_PUBLIC_TURNSTILE_SITE_KEY","TURNSTILE_SECRET_KEY"],docs:"https://developers.cloudflare.com/turnstile/",description:"Free, privacy-focused captcha alternative"},{id:"hcaptcha",name:"hCaptcha",region:"global",envVars:["NEXT_PUBLIC_HCAPTCHA_SITE_KEY","HCAPTCHA_SECRET_KEY"],docs:"https://docs.hcaptcha.com/",description:"Privacy-respecting captcha"},{id:"aliyun-slide",name:"\u963F\u91CC\u4E91\u9A8C\u8BC1\u7801 2.0",region:"cn",envVars:["ALIYUN_CAPTCHA_ACCESS_KEY_ID","ALIYUN_CAPTCHA_ACCESS_KEY_SECRET","ALIYUN_CAPTCHA_APP_KEY","NEXT_PUBLIC_ALIYUN_CAPTCHA_APP_KEY"],docs:"https://help.aliyun.com/product/28308.html",description:"\u963F\u91CC\u4E91\u667A\u80FD\u9A8C\u8BC1 (\u6ED1\u5757/\u65E0\u75D5)"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function _n(e){return _t.find(t=>t.id===e)}var Ca=_t.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});import J from"fs";import Ft from"path";function G(e,t){let o=Ft.join(e,".env.example");if(!J.existsSync(o)||t.envVars.length===0)return;let r=`# ${t.category??t.name}: ${t.name}`;if(J.readFileSync(o,"utf-8").includes(r))return;let c=["","# =============================================",r,t.docs?`# Docs: ${t.docs}`:null,"# =============================================",...t.envVars.map(i=>`${i}=""`),""].filter(i=>i!==null).join(`
519
519
  `);J.appendFileSync(o,c)}function H(e,t,o){let n=Ft.join(e,".env.example");if(!J.existsSync(n))return;let r=J.readFileSync(n,"utf-8"),s=`${t}="${o}"`,a=new RegExp(`^${t}=.*$`,"m");if(a.test(r)){J.writeFileSync(n,r.replace(a,s));return}let c=r.endsWith(`
520
520
  `)?"":`
521
521
  `;J.appendFileSync(n,`${c}${s}
522
- `)}function B(e,t){let o=Ft.join(e,"packages",t);J.existsSync(o)&&J.rmSync(o,{recursive:!0,force:!0})}async function Pn(e,t,o="global"){let n=_n(t);if(!n)throw new Error(`Unknown captcha provider "${t}". Valid ids: ${_t.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"captcha");return}n.envVars.length>0&&G(e,{category:"Captcha",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CAPTCHA_PROVIDER",n.id)}import bt from"fs";import Pr from"path";var Pt=[{id:"sanity",name:"Sanity",region:"global",envVars:["SANITY_PROJECT_ID","SANITY_DATASET","SANITY_API_TOKEN","SANITY_API_VERSION"],docs:"https://www.sanity.io/docs",description:"Structured content platform with Studio"},{id:"contentful",name:"Contentful",region:"global",envVars:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","CONTENTFUL_PREVIEW_ACCESS_TOKEN"],docs:"https://www.contentful.com/developers/docs/",description:"Headless CMS"},{id:"strapi",name:"Strapi",region:"both",envVars:["STRAPI_URL","STRAPI_API_TOKEN"],docs:"https://docs.strapi.io",description:"Open-source self-hosted CMS"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function bn(e){return Pt.find(t=>t.id===e)}var Ta=Pt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function In(e,t,o="global"){let n=bn(t);if(!n)throw new Error(`Unknown CMS provider "${t}". Valid ids: ${Pt.map(s=>s.id).join(", ")}`);let r=Pr.join(e,"apps","studio");if(n.id==="none"){B(e,"sanity"),bt.existsSync(r)&&bt.rmSync(r,{recursive:!0,force:!0});return}n.id!=="sanity"&&(B(e,"sanity"),bt.existsSync(r)&&bt.rmSync(r,{recursive:!0,force:!0})),n.envVars.length>0&&G(e,{category:"CMS",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CMS_PROVIDER",n.id)}import A from"fs";import I from"path";var br=I.join("apps","web"),jt=I.join("src","components","compliance"),ot=I.join("src","app","[locale]");function W(e){return I.join(e,br)}function Ir(e){A.mkdirSync(e,{recursive:!0})}function Y(e,t){Ir(I.dirname(e)),A.writeFileSync(e,t,"utf8")}function Vt(e,t){let o=I.join(e,".env.example");if(A.existsSync(o)){if(A.readFileSync(o,"utf8").includes(t.split(`
522
+ `)}function B(e,t){let o=Ft.join(e,"packages",t);J.existsSync(o)&&J.rmSync(o,{recursive:!0,force:!0})}async function Pn(e,t,o="global"){let n=_n(t);if(!n)throw new Error(`Unknown captcha provider "${t}". Valid ids: ${_t.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"captcha");return}n.envVars.length>0&&G(e,{category:"Captcha",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CAPTCHA_PROVIDER",n.id)}import bt from"fs";import Ir from"path";var Pt=[{id:"sanity",name:"Sanity",region:"global",envVars:["SANITY_PROJECT_ID","SANITY_DATASET","SANITY_API_TOKEN","SANITY_API_VERSION"],docs:"https://www.sanity.io/docs",description:"Structured content platform with Studio"},{id:"contentful",name:"Contentful",region:"global",envVars:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","CONTENTFUL_PREVIEW_ACCESS_TOKEN"],docs:"https://www.contentful.com/developers/docs/",description:"Headless CMS"},{id:"strapi",name:"Strapi",region:"both",envVars:["STRAPI_URL","STRAPI_API_TOKEN"],docs:"https://docs.strapi.io",description:"Open-source self-hosted CMS"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function bn(e){return Pt.find(t=>t.id===e)}var Oa=Pt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function In(e,t,o="global"){let n=bn(t);if(!n)throw new Error(`Unknown CMS provider "${t}". Valid ids: ${Pt.map(s=>s.id).join(", ")}`);let r=Ir.join(e,"apps","studio");if(n.id==="none"){B(e,"sanity"),bt.existsSync(r)&&bt.rmSync(r,{recursive:!0,force:!0});return}n.id!=="sanity"&&(B(e,"sanity"),bt.existsSync(r)&&bt.rmSync(r,{recursive:!0,force:!0})),n.envVars.length>0&&G(e,{category:"CMS",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CMS_PROVIDER",n.id)}import A from"fs";import I from"path";var Cr=I.join("apps","web"),jt=I.join("src","components","compliance"),ot=I.join("src","app","[locale]");function W(e){return I.join(e,Cr)}function Ar(e){A.mkdirSync(e,{recursive:!0})}function Y(e,t){Ar(I.dirname(e)),A.writeFileSync(e,t,"utf8")}function Vt(e,t){let o=I.join(e,".env.example");if(A.existsSync(o)){if(A.readFileSync(o,"utf8").includes(t.split(`
523
523
  `)[0]??""))return;A.appendFileSync(o,`
524
524
  `+t+`
525
525
  `)}else A.writeFileSync(o,t+`
526
526
  `)}var rt=`> **TEMPLATE \u2014 NOT LEGAL ADVICE.** This document is a boilerplate scaffold only.
527
527
  > Consult a qualified lawyer in every jurisdiction you operate in before publishing.
528
- > \u672C\u6587\u6863\u4E3A\u6A21\u677F\u811A\u624B\u67B6\uFF0C\u4E0D\u6784\u6210\u6CD5\u5F8B\u610F\u89C1\u3002\u53D1\u5E03\u524D\u8BF7\u54A8\u8BE2\u76F8\u5173\u53F8\u6CD5\u8F96\u533A\u7684\u5408\u683C\u5F8B\u5E08\u3002`,Cr=`import Link from "next/link";
528
+ > \u672C\u6587\u6863\u4E3A\u6A21\u677F\u811A\u624B\u67B6\uFF0C\u4E0D\u6784\u6210\u6CD5\u5F8B\u610F\u89C1\u3002\u53D1\u5E03\u524D\u8BF7\u54A8\u8BE2\u76F8\u5173\u53F8\u6CD5\u8F96\u533A\u7684\u5408\u683C\u5F8B\u5E08\u3002`,wr=`import Link from "next/link";
529
529
  import { IcpFooter } from "@/components/compliance/IcpFooter";
530
530
  import { PublicSecurityFooter } from "@/components/compliance/PublicSecurityFooter";
531
531
 
@@ -576,7 +576,7 @@ export function Footer({ region = "global" }: FooterProps) {
576
576
  </footer>
577
577
  );
578
578
  }
579
- `,Ar=`export function IcpFooter() {
579
+ `,Rr=`export function IcpFooter() {
580
580
  const icp = process.env.NEXT_PUBLIC_ICP_BEIAN;
581
581
  if (!icp) return null;
582
582
  return (
@@ -590,7 +590,7 @@ export function Footer({ region = "global" }: FooterProps) {
590
590
  </a>
591
591
  );
592
592
  }
593
- `,wr=`export function PublicSecurityFooter() {
593
+ `,Nr=`export function PublicSecurityFooter() {
594
594
  const psb = process.env.NEXT_PUBLIC_PSB_BEIAN;
595
595
  const psbCode = process.env.NEXT_PUBLIC_PSB_CODE;
596
596
  if (!psb) return null;
@@ -607,7 +607,7 @@ export function Footer({ region = "global" }: FooterProps) {
607
607
  </a>
608
608
  );
609
609
  }
610
- `,Rr=`"use client";
610
+ `,xr=`"use client";
611
611
 
612
612
  import { useCallback, useEffect, useState } from "react";
613
613
 
@@ -834,7 +834,7 @@ function CategoryRow({ id, title, description, checked, disabled, onChange }: Ca
834
834
  </label>
835
835
  );
836
836
  }
837
- `,Nr=`interface AigcDisclaimerProps {
837
+ `,kr=`interface AigcDisclaimerProps {
838
838
  className?: string;
839
839
  }
840
840
 
@@ -854,7 +854,7 @@ export function AigcDisclaimer({ className }: AigcDisclaimerProps) {
854
854
  </div>
855
855
  );
856
856
  }
857
- `,xr=`---
857
+ `,Tr=`---
858
858
  title: Privacy Policy / \u9690\u79C1\u653F\u7B56
859
859
  description: How {{COMPANY_NAME}} collects, uses, shares, and protects personal information.
860
860
  lastUpdated: 2026-01-01
@@ -999,7 +999,7 @@ or in-app notification before the change takes effect.
999
999
  **Data Controller / \u6570\u636E\u63A7\u5236\u8005:** {{COMPANY_NAME}}
1000
1000
  **Address / \u5730\u5740:** {{COMPANY_ADDRESS}}
1001
1001
  **Email / \u90AE\u7BB1:** {{COMPANY_CONTACT_EMAIL}}
1002
- `,kr=`---
1002
+ `,Or=`---
1003
1003
  title: Terms of Service / \u670D\u52A1\u6761\u6B3E
1004
1004
  description: Terms governing your use of {{COMPANY_NAME}}.
1005
1005
  lastUpdated: 2026-01-01
@@ -1118,7 +1118,7 @@ conflict-of-laws principles. Disputes shall be resolved in the competent courts
1118
1118
  ## 11. Contact / \u8054\u7CFB\u65B9\u5F0F
1119
1119
 
1120
1120
  {{COMPANY_NAME}} \xB7 {{COMPANY_ADDRESS}} \xB7 {{COMPANY_CONTACT_EMAIL}}
1121
- `,Tr=`---
1121
+ `,Ur=`---
1122
1122
  title: AIGC Disclosure / \u751F\u6210\u5F0F AI \u670D\u52A1\u8BF4\u660E
1123
1123
  description: Disclosure required by \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300B
1124
1124
  lastUpdated: 2026-01-01
@@ -1200,7 +1200,7 @@ human professional.
1200
1200
 
1201
1201
  AI \u8F93\u51FA\u53EF\u80FD\u4E0D\u51C6\u786E\u3001\u5B58\u5728\u504F\u89C1\u6216\u8FC7\u65F6\u3002**\u8BF7\u52FF**\u5728\u672A\u7ECF\u5408\u683C\u4E13\u4E1A\u4EBA\u58EB\u72EC\u7ACB\u6838\u5B9E\u7684\u60C5\u51B5\u4E0B\uFF0C\u5C06 AI \u8F93\u51FA
1202
1202
  \u7528\u4E8E\u533B\u7597\u3001\u6CD5\u5F8B\u3001\u91D1\u878D\u6216\u5B89\u5168\u6538\u5173\u7684\u51B3\u7B56\u3002
1203
- `,Or=`---
1203
+ `,Lr=`---
1204
1204
  title: Cross-Border Data Notice / \u6570\u636E\u51FA\u5883\u544A\u77E5
1205
1205
  description: Notice of cross-border transfer of personal information, per PIPL.
1206
1206
  lastUpdated: 2026-01-01
@@ -1265,7 +1265,7 @@ Refusal may limit your ability to use features that rely on overseas services.
1265
1265
  - \u4F20\u8F93\u4E2D\u52A0\u5BC6 (TLS 1.2+) \u53CA\u9759\u6001\u52A0\u5BC6 (AES-256)\u3002
1266
1266
  - \u5408\u540C\u6761\u6B3E\u8981\u6C42\u5883\u5916\u63A5\u6536\u65B9\u63D0\u4F9B\u7B49\u540C\u4E8E PIPL \u7684\u4FDD\u62A4\u3002
1267
1267
  - \u8BBF\u95EE\u63A7\u5236\u3001\u5BA1\u8BA1\u65E5\u5FD7\u548C\u8FDD\u89C4\u901A\u77E5\u7A0B\u5E8F\u3002
1268
- `,Ur=`---
1268
+ `,Mr=`---
1269
1269
  title: Personal Information Collection List / \u4E2A\u4EBA\u4FE1\u606F\u6536\u96C6\u6E05\u5355
1270
1270
  description: Itemized list of personal information collected, per PIPL Article 17.
1271
1271
  lastUpdated: 2026-01-01
@@ -1307,19 +1307,19 @@ To exercise your rights (access, rectify, delete, export, withdraw consent), con
1307
1307
  **{{COMPANY_CONTACT_EMAIL}}**.
1308
1308
 
1309
1309
  \u5982\u9700\u884C\u4F7F\u60A8\u7684\u6743\u5229\uFF08\u8BBF\u95EE\u3001\u66F4\u6B63\u3001\u5220\u9664\u3001\u5BFC\u51FA\u3001\u64A4\u56DE\u540C\u610F\uFF09\uFF0C\u8BF7\u8054\u7CFB **{{COMPANY_CONTACT_EMAIL}}**\u3002
1310
- `;async function Lr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","Footer.tsx");Y(n,Cr);let r=I.join(o,"src","components","compliance","README.md");Y(r,["# Compliance Components","",`Auto-generated by \`create-sailor\` for region: \`${t}\`.`,"","## Mounting the Footer","","```tsx",'import { Footer } from "@/components/compliance/Footer";','import { CookieBanner } from "@/components/compliance/CookieBanner";',"","export default function RootLayout({ children }) {"," return ("," <html>"," <body>"," {children}",` <Footer region="${t}" />`," <CookieBanner />"," </body>"," </html>"," );","}","```","","## Placeholders","","Policy MDX files contain `{{COMPANY_NAME}}`, `{{COMPANY_ADDRESS}}`,","`{{COMPANY_CONTACT_EMAIL}}`, `{{GOVERNING_JURISDICTION}}`, and","`{{AIGC_ALGORITHM_FILING_NUMBER}}`. These are filled by the `brand-apply` step.",""].join(`
1311
- `))}async function Mr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","CookieBanner.tsx");Y(n,Rr)}async function Dr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"privacy","page.mdx");Y(n,xr)}async function Fr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"terms","page.mdx");Y(n,kr)}async function jr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"IcpFooter.tsx");Y(o,Ar),Vt(e,["# Chinese ICP filing (\u5DE5\u4FE1\u90E8 ICP \u5907\u6848) \u2014 required to legally host a","# public-facing site from mainland China. Apply at https://beian.miit.gov.cn/",'NEXT_PUBLIC_ICP_BEIAN="" # \u5982 \u82CFICP\u59072024XXXXXX\u53F7'].join(`
1312
- `))}async function Vr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"PublicSecurityFooter.tsx");Y(o,wr),Vt(e,["# Chinese Public Security Bureau filing (\u516C\u5B89\u8054\u7F51\u5907\u6848)","# Required in addition to ICP. Apply at http://www.beian.gov.cn/",'NEXT_PUBLIC_PSB_BEIAN="" # \u5982 \u82CF\u516C\u7F51\u5B89\u5907 32011402XXXXXX\u53F7','NEXT_PUBLIC_PSB_CODE="" # 14-digit record code'].join(`
1313
- `))}async function Kr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"AigcDisclaimer.tsx");Y(o,Nr),Vt(e,["# Generative AI algorithm filing (\u7B97\u6CD5\u5907\u6848\u53F7) \u2014 required by","# \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300Bfor services offered in China.",'NEXT_PUBLIC_AIGC_FILING_NUMBER="" # e.g. \u7F51\u4FE1\u7B97\u5907XXXXXXXX\u53F7'].join(`
1314
- `))}async function Br(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"aigc-disclosure","page.mdx");Y(o,Tr)}async function Yr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"cross-border-data","page.mdx");Y(o,Or)}async function $r(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"pii-collection","page.mdx");Y(o,Ur)}async function Cn(e,t){try{await Lr(e,t),await Mr(e,t),await Dr(e,t),await Fr(e,t),(t==="cn"||t==="hybrid")&&(await jr(e),await Vr(e),await Kr(e),await Br(e),await Yr(e),await $r(e))}catch(o){throw console.error("applyComplianceTemplates failed:",o),new Error(`Failed to apply compliance templates for region "${t}". Check that ${e} is writable.`)}}import qr from"fs";import Gr from"path";async function An(e,t){let o=Gr.join(e,"nebutra.config.json");qr.writeFileSync(o,JSON.stringify(t,null,2)+`
1315
- `)}import re from"fs";import Kt from"path";function Hr(e){re.existsSync(e)&&re.rmSync(e,{recursive:!0,force:!0})}function wn(e,t){return e.replace(/provider\s*=\s*"postgresql"/,`provider = "${t}"`)}function Wr(e){return e.replace(/^\s*directUrl\s*=\s*env\([^)]*\)\s*\n/gm,"")}function Rn(e){let t=e.replace(/^\s*extensions\s*=\s*\[[^\]]*\]\s*\n/gm,"");return t=t.replace(/previewFeatures\s*=\s*\[\s*"postgresqlExtensions"\s*\]\s*\n/g,""),t}function Xr(e,t){let o=Kt.join(e,".env.example");re.existsSync(o)?re.appendFileSync(o,`
1316
- `+t):re.writeFileSync(o,t)}async function Nn(e,t,o){let n=Kt.join(e,"packages","db");if(t==="none"){Hr(n);return}let r=Kt.join(n,"prisma","schema.prisma"),s;if(t==="postgresql"?s=`postgresql://postgres:postgres@localhost:5432/${o}`:t==="mysql"?s=`mysql://root:root@localhost:3306/${o}`:s="file:./dev.db",Xr(e,`# Database (${t})
1310
+ `;async function Dr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","Footer.tsx");Y(n,wr);let r=I.join(o,"src","components","compliance","README.md");Y(r,["# Compliance Components","",`Auto-generated by \`create-sailor\` for region: \`${t}\`.`,"","## Mounting the Footer","","```tsx",'import { Footer } from "@/components/compliance/Footer";','import { CookieBanner } from "@/components/compliance/CookieBanner";',"","export default function RootLayout({ children }) {"," return ("," <html>"," <body>"," {children}",` <Footer region="${t}" />`," <CookieBanner />"," </body>"," </html>"," );","}","```","","## Placeholders","","Policy MDX files contain `{{COMPANY_NAME}}`, `{{COMPANY_ADDRESS}}`,","`{{COMPANY_CONTACT_EMAIL}}`, `{{GOVERNING_JURISDICTION}}`, and","`{{AIGC_ALGORITHM_FILING_NUMBER}}`. These are filled by the `brand-apply` step.",""].join(`
1311
+ `))}async function Fr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","CookieBanner.tsx");Y(n,xr)}async function jr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"privacy","page.mdx");Y(n,Tr)}async function Vr(e,t){let o=W(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"terms","page.mdx");Y(n,Or)}async function Kr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"IcpFooter.tsx");Y(o,Rr),Vt(e,["# Chinese ICP filing (\u5DE5\u4FE1\u90E8 ICP \u5907\u6848) \u2014 required to legally host a","# public-facing site from mainland China. Apply at https://beian.miit.gov.cn/",'NEXT_PUBLIC_ICP_BEIAN="" # \u5982 \u82CFICP\u59072024XXXXXX\u53F7'].join(`
1312
+ `))}async function Br(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"PublicSecurityFooter.tsx");Y(o,Nr),Vt(e,["# Chinese Public Security Bureau filing (\u516C\u5B89\u8054\u7F51\u5907\u6848)","# Required in addition to ICP. Apply at http://www.beian.gov.cn/",'NEXT_PUBLIC_PSB_BEIAN="" # \u5982 \u82CF\u516C\u7F51\u5B89\u5907 32011402XXXXXX\u53F7','NEXT_PUBLIC_PSB_CODE="" # 14-digit record code'].join(`
1313
+ `))}async function Yr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,jt,"AigcDisclaimer.tsx");Y(o,kr),Vt(e,["# Generative AI algorithm filing (\u7B97\u6CD5\u5907\u6848\u53F7) \u2014 required by","# \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300Bfor services offered in China.",'NEXT_PUBLIC_AIGC_FILING_NUMBER="" # e.g. \u7F51\u4FE1\u7B97\u5907XXXXXXXX\u53F7'].join(`
1314
+ `))}async function $r(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"aigc-disclosure","page.mdx");Y(o,Ur)}async function qr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"cross-border-data","page.mdx");Y(o,Lr)}async function Gr(e){let t=W(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"pii-collection","page.mdx");Y(o,Mr)}async function Cn(e,t){try{await Dr(e,t),await Fr(e,t),await jr(e,t),await Vr(e,t),(t==="cn"||t==="hybrid")&&(await Kr(e),await Br(e),await Yr(e),await $r(e),await qr(e),await Gr(e))}catch(o){throw console.error("applyComplianceTemplates failed:",o),new Error(`Failed to apply compliance templates for region "${t}". Check that ${e} is writable.`)}}import Hr from"fs";import Wr from"path";async function An(e,t){let o=Wr.join(e,"nebutra.config.json");Hr.writeFileSync(o,JSON.stringify(t,null,2)+`
1315
+ `)}import re from"fs";import Kt from"path";function Xr(e){re.existsSync(e)&&re.rmSync(e,{recursive:!0,force:!0})}function wn(e,t){return e.replace(/provider\s*=\s*"postgresql"/,`provider = "${t}"`)}function zr(e){return e.replace(/^\s*directUrl\s*=\s*env\([^)]*\)\s*\n/gm,"")}function Rn(e){let t=e.replace(/^\s*extensions\s*=\s*\[[^\]]*\]\s*\n/gm,"");return t=t.replace(/previewFeatures\s*=\s*\[\s*"postgresqlExtensions"\s*\]\s*\n/g,""),t}function Qr(e,t){let o=Kt.join(e,".env.example");re.existsSync(o)?re.appendFileSync(o,`
1316
+ `+t):re.writeFileSync(o,t)}async function Nn(e,t,o){let n=Kt.join(e,"packages","db");if(t==="none"){Xr(n);return}let r=Kt.join(n,"prisma","schema.prisma"),s;if(t==="postgresql"?s=`postgresql://postgres:postgres@localhost:5432/${o}`:t==="mysql"?s=`mysql://root:root@localhost:3306/${o}`:s="file:./dev.db",Qr(e,`# Database (${t})
1317
1317
  DATABASE_URL="${s}"
1318
- `),!re.existsSync(r))return;let a=re.readFileSync(r,"utf8"),c=a;t==="mysql"?(c=wn(c,"mysql"),c=Rn(c)):t==="sqlite"&&(c=wn(c,"sqlite"),c=Wr(c),c=Rn(c)),c!==a&&re.writeFileSync(r,c)}import st from"fs";import D from"path";import{fileURLToPath as zr}from"url";var Qr=zr(import.meta.url),Jr=D.dirname(Qr);async function xn(e,t){if(t==="none")return;let o=D.join(Jr,"../../templates/deploy");t==="vercel"?await st.promises.copyFile(D.join(o,"vercel.json"),D.join(e,"vercel.json")):t==="railway"?await st.promises.copyFile(D.join(o,"railway.toml"),D.join(e,"railway.toml")):t==="cloudflare"?await st.promises.copyFile(D.join(o,"wrangler.toml"),D.join(e,"wrangler.toml")):t==="selfhost"&&(await st.promises.copyFile(D.join(o,"docker-compose.yml"),D.join(e,"docker-compose.yml")),await st.promises.copyFile(D.join(o,"Dockerfile.web"),D.join(e,"Dockerfile.web")))}import se from"fs";import Se from"path";import{fileURLToPath as Zr}from"url";var es=Zr(import.meta.url),kn=Se.dirname(es),ts=/\.(md|mdx|json|ts|tsx|js|mjs|cjs|yaml|yml)$/;function ns(e){let t=[Se.join(kn,"..","templates","docs",e),Se.join(kn,"..","..","templates","docs",e)];for(let o of t)if(se.existsSync(o))return o;return t[0]}async function Tn(e,t){if(t.framework==="none")return;let o=(t.framework==="fumadocs","fumadocs"),n=ns(o),r=Se.join(e,"apps","docs");if(!se.existsSync(n))throw new Error(`Docs template not found: ${n}`);On(n,r),Un(r,{"{PRODUCT_NAME}":t.projectName})}function On(e,t){se.mkdirSync(t,{recursive:!0});for(let o of se.readdirSync(e,{withFileTypes:!0})){let n=Se.join(e,o.name),r=Se.join(t,o.name);o.isDirectory()?On(n,r):se.copyFileSync(n,r)}}function Un(e,t){for(let o of se.readdirSync(e,{withFileTypes:!0})){let n=Se.join(e,o.name);if(o.isDirectory())Un(n,t);else if(ts.test(o.name)){let r=se.readFileSync(n,"utf-8");for(let[s,a]of Object.entries(t))r=r.split(s).join(a);se.writeFileSync(n,r)}}}import he from"fs";import Ee from"path";var It=[{id:"resend",name:"Resend",region:"global",envVars:["RESEND_API_KEY","RESEND_FROM"],docs:"https://resend.com/docs",pkg:"resend",pkgVersion:"^4.0.1"},{id:"postmark",name:"Postmark",region:"global",envVars:["POSTMARK_API_KEY","POSTMARK_FROM"],docs:"https://postmarkapp.com/developer",pkg:"postmark",pkgVersion:"^4.0.5"},{id:"ses",name:"AWS SES",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SES_REGION","SES_FROM"],docs:"https://docs.aws.amazon.com/ses",pkg:"@aws-sdk/client-sesv2",pkgVersion:"^3.658.0"},{id:"aliyun-dm",name:"\u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001",region:"cn",envVars:["ALIYUN_DM_ACCESS_KEY","ALIYUN_DM_ACCESS_SECRET","ALIYUN_DM_ACCOUNT_NAME","ALIYUN_DM_FROM_ALIAS"],docs:"https://help.aliyun.com/product/29412.html",pkg:"@alicloud/dm20151123",pkgVersion:"^3.0.0"},{id:"tencent-ses",name:"\u817E\u8BAF\u4E91 SES",region:"cn",envVars:["TENCENT_SECRET_ID","TENCENT_SECRET_KEY","TENCENT_SES_FROM_EMAIL"],docs:"https://cloud.tencent.com/document/product/1288",pkg:"tencentcloud-sdk-nodejs-ses",pkgVersion:"^4.0.900"},{id:"netease",name:"\u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1",region:"cn",envVars:["NETEASE_USER","NETEASE_PASS","NETEASE_FROM"],docs:"https://qiye.163.com/help",pkg:"nodemailer",pkgVersion:"^6.9.15"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function Ln(e){return It.find(t=>t.id===e)}var nc=It.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var ve="@nebutra/email";function Bt(e,t){he.mkdirSync(Ee.dirname(e),{recursive:!0}),he.writeFileSync(e,t)}function os(e,t){let o=Ee.join(e,".env.example");he.existsSync(o)?he.appendFileSync(o,`
1319
- `+t):he.writeFileSync(o,t)}function rs(e){if(e.envVars.length===0)return"";let t=`# Email provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
1318
+ `),!re.existsSync(r))return;let a=re.readFileSync(r,"utf8"),c=a;t==="mysql"?(c=wn(c,"mysql"),c=Rn(c)):t==="sqlite"&&(c=wn(c,"sqlite"),c=zr(c),c=Rn(c)),c!==a&&re.writeFileSync(r,c)}import st from"fs";import D from"path";import{fileURLToPath as Jr}from"url";var Zr=Jr(import.meta.url),es=D.dirname(Zr);async function xn(e,t){if(t==="none")return;let o=D.join(es,"../../templates/deploy");t==="vercel"?await st.promises.copyFile(D.join(o,"vercel.json"),D.join(e,"vercel.json")):t==="railway"?await st.promises.copyFile(D.join(o,"railway.toml"),D.join(e,"railway.toml")):t==="cloudflare"?await st.promises.copyFile(D.join(o,"wrangler.toml"),D.join(e,"wrangler.toml")):t==="selfhost"&&(await st.promises.copyFile(D.join(o,"docker-compose.yml"),D.join(e,"docker-compose.yml")),await st.promises.copyFile(D.join(o,"Dockerfile.web"),D.join(e,"Dockerfile.web")))}import se from"fs";import Se from"path";import{fileURLToPath as ts}from"url";var ns=ts(import.meta.url),kn=Se.dirname(ns),os=/\.(md|mdx|json|ts|tsx|js|mjs|cjs|yaml|yml)$/;function rs(e){let t=[Se.join(kn,"..","templates","docs",e),Se.join(kn,"..","..","templates","docs",e)];for(let o of t)if(se.existsSync(o))return o;return t[0]}async function Tn(e,t){if(t.framework==="none")return;let o=(t.framework==="fumadocs","fumadocs"),n=rs(o),r=Se.join(e,"apps","docs");if(!se.existsSync(n))throw new Error(`Docs template not found: ${n}`);On(n,r),Un(r,{"{PRODUCT_NAME}":t.projectName})}function On(e,t){se.mkdirSync(t,{recursive:!0});for(let o of se.readdirSync(e,{withFileTypes:!0})){let n=Se.join(e,o.name),r=Se.join(t,o.name);o.isDirectory()?On(n,r):se.copyFileSync(n,r)}}function Un(e,t){for(let o of se.readdirSync(e,{withFileTypes:!0})){let n=Se.join(e,o.name);if(o.isDirectory())Un(n,t);else if(os.test(o.name)){let r=se.readFileSync(n,"utf-8");for(let[s,a]of Object.entries(t))r=r.split(s).join(a);se.writeFileSync(n,r)}}}import Ee from"fs";import he from"path";var It=[{id:"resend",name:"Resend",region:"global",envVars:["RESEND_API_KEY","RESEND_FROM"],docs:"https://resend.com/docs",pkg:"resend",pkgVersion:"^4.0.1"},{id:"postmark",name:"Postmark",region:"global",envVars:["POSTMARK_API_KEY","POSTMARK_FROM"],docs:"https://postmarkapp.com/developer",pkg:"postmark",pkgVersion:"^4.0.5"},{id:"ses",name:"AWS SES",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SES_REGION","SES_FROM"],docs:"https://docs.aws.amazon.com/ses",pkg:"@aws-sdk/client-sesv2",pkgVersion:"^3.658.0"},{id:"aliyun-dm",name:"\u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001",region:"cn",envVars:["ALIYUN_DM_ACCESS_KEY","ALIYUN_DM_ACCESS_SECRET","ALIYUN_DM_ACCOUNT_NAME","ALIYUN_DM_FROM_ALIAS"],docs:"https://help.aliyun.com/product/29412.html",pkg:"@alicloud/dm20151123",pkgVersion:"^3.0.0"},{id:"tencent-ses",name:"\u817E\u8BAF\u4E91 SES",region:"cn",envVars:["TENCENT_SECRET_ID","TENCENT_SECRET_KEY","TENCENT_SES_FROM_EMAIL"],docs:"https://cloud.tencent.com/document/product/1288",pkg:"tencentcloud-sdk-nodejs-ses",pkgVersion:"^4.0.900"},{id:"netease",name:"\u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1",region:"cn",envVars:["NETEASE_USER","NETEASE_PASS","NETEASE_FROM"],docs:"https://qiye.163.com/help",pkg:"nodemailer",pkgVersion:"^6.9.15"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function Ln(e){return It.find(t=>t.id===e)}var oc=It.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var ve="@nebutra/email";function Bt(e,t){Ee.mkdirSync(he.dirname(e),{recursive:!0}),Ee.writeFileSync(e,t)}function ss(e,t){let o=he.join(e,".env.example");Ee.existsSync(o)?Ee.appendFileSync(o,`
1319
+ `+t):Ee.writeFileSync(o,t)}function is(e){if(e.envVars.length===0)return"";let t=`# Email provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
1320
1320
  `);return`${t}
1321
1321
  ${o}
1322
- `}var ss=`/**
1322
+ `}var as=`/**
1323
1323
  * Public inputs accepted by the \`sendEmail\` wrapper.
1324
1324
  * Keep the surface minimal \u2014 individual providers may accept more, but
1325
1325
  * consumers should code against this shape for portability.
@@ -1339,7 +1339,7 @@ export interface SendEmailResult {
1339
1339
  /** Raw provider response \u2014 useful for debugging, not a stable contract. */
1340
1340
  raw?: unknown;
1341
1341
  }
1342
- `;function is(){return`/**
1342
+ `;function cs(){return`/**
1343
1343
  * @${ve.slice(1)} \u2014 Resend transactional email wrapper.
1344
1344
  *
1345
1345
  * Docs: https://resend.com/docs
@@ -1378,7 +1378,7 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1378
1378
  }
1379
1379
 
1380
1380
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1381
- `}function as(){return`/**
1381
+ `}function ps(){return`/**
1382
1382
  * @${ve.slice(1)} \u2014 Postmark transactional email wrapper.
1383
1383
  *
1384
1384
  * Docs: https://postmarkapp.com/developer
@@ -1416,7 +1416,7 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1416
1416
  }
1417
1417
 
1418
1418
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1419
- `}function cs(){return`/**
1419
+ `}function ls(){return`/**
1420
1420
  * @${ve.slice(1)} \u2014 AWS SES v2 transactional email wrapper.
1421
1421
  *
1422
1422
  * Docs: https://docs.aws.amazon.com/ses
@@ -1472,7 +1472,7 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1472
1472
  }
1473
1473
 
1474
1474
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1475
- `}function ps(){return`/**
1475
+ `}function ds(){return`/**
1476
1476
  * @${ve.slice(1)} \u2014 \u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001 (Aliyun DirectMail) wrapper.
1477
1477
  *
1478
1478
  * Docs: https://help.aliyun.com/product/29412.html
@@ -1522,7 +1522,7 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1522
1522
  }
1523
1523
 
1524
1524
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1525
- `}function ls(){return`/**
1525
+ `}function us(){return`/**
1526
1526
  * @${ve.slice(1)} \u2014 \u817E\u8BAF\u4E91 SES wrapper.
1527
1527
  *
1528
1528
  * Docs: https://cloud.tencent.com/document/product/1288
@@ -1570,7 +1570,7 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1570
1570
  }
1571
1571
 
1572
1572
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1573
- `}function ds(){return`/**
1573
+ `}function ms(){return`/**
1574
1574
  * @${ve.slice(1)} \u2014 \u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1 via SMTP (nodemailer).
1575
1575
  *
1576
1576
  * Docs: https://qiye.163.com/help
@@ -1608,9 +1608,9 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1608
1608
  }
1609
1609
 
1610
1610
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1611
- `}function us(e){switch(e){case"resend":return is();case"postmark":return as();case"ses":return cs();case"aliyun-dm":return ps();case"tencent-ses":return ls();case"netease":return ds();case"none":return`export {};
1612
- `}}function ms(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),e.id==="aliyun-dm"&&(t["@alicloud/openapi-client"]="^0.4.12");let o={name:ve,version:"0.1.0",private:!0,description:`Transactional email via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
1613
- `}async function Mn(e,t,o){if(t==="none")return;let n=Ln(t);if(!n)throw new Error(`Unknown email provider "${t}". Valid ids: ${It.map(a=>a.id).join(", ")}`);let r=Ee.join(e,"packages","email"),s=Ee.join(r,"src");he.existsSync(s)&&he.rmSync(s,{recursive:!0,force:!0}),Bt(Ee.join(r,"package.json"),ms(n)),Bt(Ee.join(s,"types.ts"),ss),Bt(Ee.join(s,"index.ts"),us(n.id)),os(e,rs(n))}import Ct from"fs";import Dn from"path";async function Fn(e,t){let o=`# Automatically injected by create-sailor
1611
+ `}function gs(e){switch(e){case"resend":return cs();case"postmark":return ps();case"ses":return ls();case"aliyun-dm":return ds();case"tencent-ses":return us();case"netease":return ms();case"none":return`export {};
1612
+ `}}function fs(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),e.id==="aliyun-dm"&&(t["@alicloud/openapi-client"]="^0.4.12");let o={name:ve,version:"0.1.0",private:!0,description:`Transactional email via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
1613
+ `}async function Mn(e,t,o){if(t==="none")return;let n=Ln(t);if(!n)throw new Error(`Unknown email provider "${t}". Valid ids: ${It.map(a=>a.id).join(", ")}`);let r=he.join(e,"packages","email"),s=he.join(r,"src");Ee.existsSync(s)&&Ee.rmSync(s,{recursive:!0,force:!0}),Bt(he.join(r,"package.json"),fs(n)),Bt(he.join(s,"types.ts"),as),Bt(he.join(s,"index.ts"),gs(n.id)),ss(e,is(n))}import Ct from"fs";import Dn from"path";async function Fn(e,t){let o=`# Automatically injected by create-sailor
1614
1614
  DATABASE_URL="${String(t.databaseUrl)}"
1615
1615
 
1616
1616
  NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="${String(t.clerkPublishable)}"
@@ -1618,13 +1618,13 @@ CLERK_SECRET_KEY="${String(t.clerkSecret)}"
1618
1618
 
1619
1619
  NEXT_PUBLIC_SITE_URL="http://localhost:3000"
1620
1620
  `,n=Dn.join(e,".env"),r=Dn.join(e,".env.local");!Ct.existsSync(n)&&!Ct.existsSync(r)?Ct.writeFileSync(r,o):Ct.appendFileSync(r,`
1621
- `+o)}import Vn from"crypto";import it from"fs";import jn from"path";function _e(e){return Vn.randomBytes(e).toString("base64").replace(/=+$/,"")}function gs(e){return Vn.randomBytes(e).toString("hex")}function fs(){return{AUTH_SECRET:_e(32),NEXTAUTH_SECRET:_e(32),BETTER_AUTH_SECRET:_e(32),JWT_SECRET:_e(32),WEBHOOK_SECRET:gs(16),ENCRYPTION_KEY:_e(32),API_SECRET_KEY:_e(32),SESSION_SECRET:_e(32)}}function ys(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Ss(e,t,o){let n=new RegExp(`^(?!#)\\s*${t}=.*$`,"gm"),r=ys(o);return e.replace(n,`${t}="${r}"`)}async function Kn(e){let t=jn.join(e,".env.example"),o=jn.join(e,".env.local");if(!it.existsSync(t))return null;try{let n=it.readFileSync(t,"utf8"),r=fs(),a=it.existsSync(o)?it.readFileSync(o,"utf8"):n;for(let c of Object.keys(r))a=Ss(a,c,r[c]);return it.writeFileSync(o,a),r}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate env secrets: ${r}`),new Error(`Unable to write .env.local: ${r}`)}}var At=[{id:"vercel-flags",name:"Vercel Flags SDK",region:"global",envVars:["FLAGS_SECRET"],docs:"https://vercel.com/docs/workflow-collaboration/feature-flags",description:"Native Vercel feature flags"},{id:"growthbook",name:"GrowthBook",region:"both",envVars:["GROWTHBOOK_API_HOST","GROWTHBOOK_CLIENT_KEY","GROWTHBOOK_DECRYPTION_KEY"],docs:"https://docs.growthbook.io",description:"Open-source A/B testing + flags"},{id:"configcat",name:"ConfigCat",region:"global",envVars:["CONFIGCAT_SDK_KEY"],docs:"https://configcat.com/docs/",description:"Feature flag & config management"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Bn(e){return At.find(t=>t.id===e)}var fc=At.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Yn(e,t,o="global"){let n=Bn(t);if(!n)throw new Error(`Unknown feature-flags provider "${t}". Valid ids: ${At.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"feature-flags");return}n.envVars.length>0&&G(e,{category:"Feature Flags",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"FEATURE_FLAGS_PROVIDER",n.id)}import{execFileSync as Es}from"child_process";import x from"fs";import hs from"os";import ie from"path";import vs from"ignore";var _s={mirror:{repo:process.env.SAILOR_TEMPLATE_REPO||"Nebutra/Sailor-Template",ref:process.env.SAILOR_TEMPLATE_REF||"main",applyIgnore:!1,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"},main:{repo:"Nebutra/Nebutra-Sailor",ref:"main",applyIgnore:!0,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"}};function Ps(e,t){return`https://github.com/${e}/archive/refs/heads/${t}.tar.gz`}function bs(e,t){return`https://github.com/${e}/archive/${t}.tar.gz`}function Is(e){return/^[0-9a-f]{7,40}$/i.test(e)}async function Cs(e,t){if(Is(t))return t;let o=await fetch(`https://api.github.com/repos/${e}/commits/${encodeURIComponent(t)}`,{headers:{Accept:"application/vnd.github+json","User-Agent":"create-sailor"}});if(!o.ok)throw new Error(`Failed to resolve ${e}@${t} (GitHub API ${o.status})`);let n=await o.json();if(typeof n.sha!="string"||n.sha.length===0)throw new Error(`GitHub API did not return a commit SHA for ${e}@${t}`);return n.sha}function Gn(e,t,o){let n=x.readdirSync(t,{withFileTypes:!0});for(let r of n){if(r.name==="node_modules"||r.name===".git")continue;let s=ie.join(t,r.name),a=ie.relative(e,s).split(ie.sep).join("/");r.isDirectory()?(o.push(a+"/"),Gn(e,s,o)):o.push(a)}}function As(e){let t=ie.join(e,".templateignore");if(!x.existsSync(t))return;let o=x.readFileSync(t,"utf8"),n=vs().add(o),r=[];Gn(e,e,r);let s=r.map(i=>i.endsWith("/")?i.slice(0,-1):i),a=new Set(n.filter(s)),c=s.filter(i=>!a.has(i)).sort((i,d)=>d.split("/").length-i.split("/").length);for(let i of c){let d=ie.join(e,i);try{x.existsSync(d)&&x.rmSync(d,{recursive:!0,force:!0})}catch{}}try{x.existsSync(t)&&x.rmSync(t,{force:!0})}catch{}}async function $n(e,t){let o=await fetch(e,{headers:{Accept:"application/octet-stream","User-Agent":"create-sailor"}});if(!o.ok)throw new Error(`Failed to download archive (${o.status})`);let n=Buffer.from(await o.arrayBuffer());if(n.byteLength<1024)throw new Error(`Downloaded archive is unexpectedly small (${n.byteLength} bytes)`);x.writeFileSync(t,n);let r=x.statSync(t);if(r.size!==n.byteLength)throw new Error(`Archive write verification failed (${r.size} != ${n.byteLength})`);return r.size}function qn(e,t){Es("tar",["-xzf",e,"-C",t,"--strip-components=1"],{stdio:"ignore"})}function Hn(e){try{let t=x.readdirSync(e);for(let o of t)x.rmSync(ie.join(e,o),{recursive:!0,force:!0})}catch{}}async function ws(e,t){let o=x.mkdtempSync(ie.join(hs.tmpdir(),"create-sailor-")),n=ie.join(o,"template.tar.gz");try{let r=await Cs(e.repo,e.ref);await $n(bs(e.repo,r),n),qn(n,t)}catch(r){if(!e.allowMutableFallback)throw r;Hn(t),await $n(Ps(e.repo,e.ref),n),qn(n,t)}finally{x.rmSync(o,{recursive:!0,force:!0})}}async function Wn(e){x.mkdirSync(e,{recursive:!0});let o=process.env.SAILOR_TEMPLATE_SOURCE==="main"?["main"]:["mirror","main"],n;for(let r of o){let s=_s[r];try{if(await ws(s,e),s.applyIgnore)try{As(e)}catch(a){throw new Error(`Template cloned, but .templateignore processing failed: ${a instanceof Error?a.message:String(a)}`)}return}catch(a){n=a instanceof Error?a:new Error(String(a)),Hn(e)}}throw new Error(`Failed to download the template from any source. Last error: ${n?.message??"unknown"}
1621
+ `+o)}import Vn from"crypto";import it from"fs";import jn from"path";function _e(e){return Vn.randomBytes(e).toString("base64").replace(/=+$/,"")}function ys(e){return Vn.randomBytes(e).toString("hex")}function Ss(){return{AUTH_SECRET:_e(32),NEXTAUTH_SECRET:_e(32),BETTER_AUTH_SECRET:_e(32),JWT_SECRET:_e(32),WEBHOOK_SECRET:ys(16),ENCRYPTION_KEY:_e(32),API_SECRET_KEY:_e(32),SESSION_SECRET:_e(32)}}function hs(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Es(e,t,o){let n=new RegExp(`^(?!#)\\s*${t}=.*$`,"gm"),r=hs(o);return e.replace(n,`${t}="${r}"`)}async function Kn(e){let t=jn.join(e,".env.example"),o=jn.join(e,".env.local");if(!it.existsSync(t))return null;try{let n=it.readFileSync(t,"utf8"),r=Ss(),a=it.existsSync(o)?it.readFileSync(o,"utf8"):n;for(let c of Object.keys(r))a=Es(a,c,r[c]);return it.writeFileSync(o,a),r}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate env secrets: ${r}`),new Error(`Unable to write .env.local: ${r}`)}}var At=[{id:"vercel-flags",name:"Vercel Flags SDK",region:"global",envVars:["FLAGS_SECRET"],docs:"https://vercel.com/docs/workflow-collaboration/feature-flags",description:"Native Vercel feature flags"},{id:"growthbook",name:"GrowthBook",region:"both",envVars:["GROWTHBOOK_API_HOST","GROWTHBOOK_CLIENT_KEY","GROWTHBOOK_DECRYPTION_KEY"],docs:"https://docs.growthbook.io",description:"Open-source A/B testing + flags"},{id:"configcat",name:"ConfigCat",region:"global",envVars:["CONFIGCAT_SDK_KEY"],docs:"https://configcat.com/docs/",description:"Feature flag & config management"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Bn(e){return At.find(t=>t.id===e)}var yc=At.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Yn(e,t,o="global"){let n=Bn(t);if(!n)throw new Error(`Unknown feature-flags provider "${t}". Valid ids: ${At.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"feature-flags");return}n.envVars.length>0&&G(e,{category:"Feature Flags",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"FEATURE_FLAGS_PROVIDER",n.id)}import{execFileSync as Gn}from"child_process";import x from"fs";import vs from"os";import ie from"path";import _s from"ignore";var Ps={mirror:{repo:process.env.SAILOR_TEMPLATE_REPO||"Nebutra/Sailor-Template",ref:process.env.SAILOR_TEMPLATE_REF||"main",applyIgnore:!1,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"},main:{repo:"Nebutra/Nebutra-Sailor",ref:"main",applyIgnore:!0,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"}};function bs(e,t){return`https://github.com/${e}/archive/refs/heads/${t}.tar.gz`}function Is(e,t){return`https://github.com/${e}/archive/${t}.tar.gz`}function Hn(e){return/^[0-9a-f]{7,40}$/i.test(e)}function Cs(e,t){let o=`https://github.com/${e}.git`,n=[`refs/heads/${t}`,`refs/tags/${t}`];for(let r of n)try{let s=Gn("git",["ls-remote",o,r],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(!s)continue;let[a]=s.split(/\s+/);if(Hn(a))return a}catch{}return null}async function As(e,t){if(Hn(t))return t;let o=await fetch(`https://api.github.com/repos/${e}/commits/${encodeURIComponent(t)}`,{headers:{Accept:"application/vnd.github+json","User-Agent":"create-sailor"}});if(!o.ok){let r=Cs(e,t);if(r)return r;throw new Error(`Failed to resolve ${e}@${t} (GitHub API ${o.status})`)}let n=await o.json();if(typeof n.sha!="string"||n.sha.length===0)throw new Error(`GitHub API did not return a commit SHA for ${e}@${t}`);return n.sha}function Wn(e,t,o){let n=x.readdirSync(t,{withFileTypes:!0});for(let r of n){if(r.name==="node_modules"||r.name===".git")continue;let s=ie.join(t,r.name),a=ie.relative(e,s).split(ie.sep).join("/");r.isDirectory()?(o.push(a+"/"),Wn(e,s,o)):o.push(a)}}function ws(e){let t=ie.join(e,".templateignore");if(!x.existsSync(t))return;let o=x.readFileSync(t,"utf8"),n=_s().add(o),r=[];Wn(e,e,r);let s=r.map(i=>i.endsWith("/")?i.slice(0,-1):i),a=new Set(n.filter(s)),c=s.filter(i=>!a.has(i)).sort((i,d)=>d.split("/").length-i.split("/").length);for(let i of c){let d=ie.join(e,i);try{x.existsSync(d)&&x.rmSync(d,{recursive:!0,force:!0})}catch{}}try{x.existsSync(t)&&x.rmSync(t,{force:!0})}catch{}}async function $n(e,t){let o=await fetch(e,{headers:{Accept:"application/octet-stream","User-Agent":"create-sailor"}});if(!o.ok)throw new Error(`Failed to download archive (${o.status})`);let n=Buffer.from(await o.arrayBuffer());if(n.byteLength<1024)throw new Error(`Downloaded archive is unexpectedly small (${n.byteLength} bytes)`);x.writeFileSync(t,n);let r=x.statSync(t);if(r.size!==n.byteLength)throw new Error(`Archive write verification failed (${r.size} != ${n.byteLength})`);return r.size}function qn(e,t){Gn("tar",["-xzf",e,"-C",t,"--strip-components=1"],{stdio:"ignore"})}function Xn(e){try{let t=x.readdirSync(e);for(let o of t)x.rmSync(ie.join(e,o),{recursive:!0,force:!0})}catch{}}async function Rs(e,t){let o=x.mkdtempSync(ie.join(vs.tmpdir(),"create-sailor-")),n=ie.join(o,"template.tar.gz");try{let r=await As(e.repo,e.ref);await $n(Is(e.repo,r),n),qn(n,t)}catch(r){if(!e.allowMutableFallback)throw r;Xn(t),await $n(bs(e.repo,e.ref),n),qn(n,t)}finally{x.rmSync(o,{recursive:!0,force:!0})}}async function zn(e){x.mkdirSync(e,{recursive:!0});let o=process.env.SAILOR_TEMPLATE_SOURCE==="main"?["main"]:["mirror","main"],n;for(let r of o){let s=Ps[r];try{if(await Rs(s,e),s.applyIgnore)try{ws(e)}catch(a){throw new Error(`Template cloned, but .templateignore processing failed: ${a instanceof Error?a.message:String(a)}`)}return}catch(a){n=a instanceof Error?a:new Error(String(a)),Xn(e)}}throw new Error(`Failed to download the template from any source. Last error: ${n?.message??"unknown"}
1622
1622
 
1623
1623
  Ensure you have internet access and 'tar' installed.
1624
- You can override the source with SAILOR_TEMPLATE_REPO / SAILOR_TEMPLATE_REF env vars.`)}import Pe from"fs";import Yt from"path";async function Xn(e,t){let o=Yt.join(e,"packages","mcp");if(t==="off"){Pe.existsSync(o)&&Pe.rmSync(o,{recursive:!0,force:!0});let r=Yt.join(e,"packages","cli","src","commands","mcp-server.ts");Pe.existsSync(r)&&Pe.rmSync(r,{force:!0});return}let n=Yt.join(e,".env.example");if(Pe.existsSync(n)){let r=Pe.readFileSync(n,"utf-8"),s="# MCP Server (Agent-friendly API)";if(!r.includes(s)){let a=["","# =============================================",s,"# Docs: https://modelcontextprotocol.io","# =============================================","# MCP server exposes your SaaS capabilities to AI agents via MCP protocol.","# Run: pnpm mcp-server (starts stdio server)","# No config required for stdio transport. HTTP transport needs:",'MCP_HTTP_PORT="3100"','MCP_API_KEY=""',""].join(`
1625
- `);Pe.appendFileSync(n,a)}}}import at from"fs";import zn from"path";async function Qn(e,t,o){let n=zn.join(e,"packages","metering"),r;if(t==="auto"?r=o!=="none"?"on":"off":t==="on"||t==="off"?r=t:r="off",r==="off"){at.existsSync(n)&&at.rmSync(n,{recursive:!0,force:!0});return}let s=zn.join(e,".env.example");if(!at.existsSync(s))return;let a=at.readFileSync(s,"utf-8"),c="# Metering (usage-based billing)";if(!a.includes(c)){let i=["","# =============================================",c,"# Docs: see packages/metering/README.md","# =============================================","# ClickHouse-based metering pipeline for consumption billing.",'CLICKHOUSE_URL=""','CLICKHOUSE_USER="default"','CLICKHOUSE_PASSWORD=""','CLICKHOUSE_DATABASE="metering"',""].join(`
1626
- `);at.appendFileSync(s,i)}}import He from"fs";import O from"path";var Jn=[{id:"sentry",name:"Sentry",region:"both",envVars:["SENTRY_DSN","NEXT_PUBLIC_SENTRY_DSN"],docs:"https://docs.sentry.io",pkg:"@sentry/nextjs",instrumentationFile:"apps/web/instrumentation.ts"},{id:"datadog",name:"Datadog",region:"global",envVars:["DD_API_KEY","DD_APP_KEY","DD_SITE"],docs:"https://docs.datadoghq.com",pkg:"dd-trace",instrumentationFile:"apps/web/instrumentation.ts"},{id:"bugsnag",name:"Bugsnag",region:"global",envVars:["BUGSNAG_API_KEY","NEXT_PUBLIC_BUGSNAG_API_KEY"],docs:"https://docs.bugsnag.com",pkg:"@bugsnag/js",instrumentationFile:"apps/web/src/lib/monitoring/bugsnag.ts"},{id:"aliyun-arms",name:"\u963F\u91CC\u4E91 ARMS",region:"cn",envVars:["ALIYUN_ARMS_LICENSE_KEY","ALIYUN_ARMS_APP_NAME","NEXT_PUBLIC_ARMS_PID"],docs:"https://help.aliyun.com/product/34364.html",instrumentationFile:"apps/web/src/components/monitoring/ArmsScript.tsx"},{id:"tingyun",name:"\u542C\u4E91 TingYun",region:"cn",envVars:["TINGYUN_LICENSE_KEY","NEXT_PUBLIC_TINGYUN_APP_KEY"],docs:"https://www.tingyun.com/docs",instrumentationFile:"apps/web/src/components/monitoring/TingYunScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Tc=Jn.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function Zn(e){return Jn.find(t=>t.id===e)}function Rs(e){He.mkdirSync(e,{recursive:!0})}function X(e,t){Rs(O.dirname(e)),He.writeFileSync(e,t)}function ct(e,t){let o=O.join(e,".env.example");He.existsSync(o)?He.appendFileSync(o,`
1627
- `+t):He.writeFileSync(o,t)}function Ns(e){let t=`import * as Sentry from "@sentry/nextjs";
1624
+ You can override the source with SAILOR_TEMPLATE_REPO / SAILOR_TEMPLATE_REF env vars.`)}import Pe from"fs";import Yt from"path";async function Qn(e,t){let o=Yt.join(e,"packages","mcp");if(t==="off"){Pe.existsSync(o)&&Pe.rmSync(o,{recursive:!0,force:!0});let r=Yt.join(e,"packages","cli","src","commands","mcp-server.ts");Pe.existsSync(r)&&Pe.rmSync(r,{force:!0});return}let n=Yt.join(e,".env.example");if(Pe.existsSync(n)){let r=Pe.readFileSync(n,"utf-8"),s="# MCP Server (Agent-friendly API)";if(!r.includes(s)){let a=["","# =============================================",s,"# Docs: https://modelcontextprotocol.io","# =============================================","# MCP server exposes your SaaS capabilities to AI agents via MCP protocol.","# Run: pnpm mcp-server (starts stdio server)","# No config required for stdio transport. HTTP transport needs:",'MCP_HTTP_PORT="3100"','MCP_API_KEY=""',""].join(`
1625
+ `);Pe.appendFileSync(n,a)}}}import at from"fs";import Jn from"path";async function Zn(e,t,o){let n=Jn.join(e,"packages","metering"),r;if(t==="auto"?r=o!=="none"?"on":"off":t==="on"||t==="off"?r=t:r="off",r==="off"){at.existsSync(n)&&at.rmSync(n,{recursive:!0,force:!0});return}let s=Jn.join(e,".env.example");if(!at.existsSync(s))return;let a=at.readFileSync(s,"utf-8"),c="# Metering (usage-based billing)";if(!a.includes(c)){let i=["","# =============================================",c,"# Docs: see packages/metering/README.md","# =============================================","# ClickHouse-based metering pipeline for consumption billing.",'CLICKHOUSE_URL=""','CLICKHOUSE_USER="default"','CLICKHOUSE_PASSWORD=""','CLICKHOUSE_DATABASE="metering"',""].join(`
1626
+ `);at.appendFileSync(s,i)}}import He from"fs";import O from"path";var eo=[{id:"sentry",name:"Sentry",region:"both",envVars:["SENTRY_DSN","NEXT_PUBLIC_SENTRY_DSN"],docs:"https://docs.sentry.io",pkg:"@sentry/nextjs",instrumentationFile:"apps/web/instrumentation.ts"},{id:"datadog",name:"Datadog",region:"global",envVars:["DD_API_KEY","DD_APP_KEY","DD_SITE"],docs:"https://docs.datadoghq.com",pkg:"dd-trace",instrumentationFile:"apps/web/instrumentation.ts"},{id:"bugsnag",name:"Bugsnag",region:"global",envVars:["BUGSNAG_API_KEY","NEXT_PUBLIC_BUGSNAG_API_KEY"],docs:"https://docs.bugsnag.com",pkg:"@bugsnag/js",instrumentationFile:"apps/web/src/lib/monitoring/bugsnag.ts"},{id:"aliyun-arms",name:"\u963F\u91CC\u4E91 ARMS",region:"cn",envVars:["ALIYUN_ARMS_LICENSE_KEY","ALIYUN_ARMS_APP_NAME","NEXT_PUBLIC_ARMS_PID"],docs:"https://help.aliyun.com/product/34364.html",instrumentationFile:"apps/web/src/components/monitoring/ArmsScript.tsx"},{id:"tingyun",name:"\u542C\u4E91 TingYun",region:"cn",envVars:["TINGYUN_LICENSE_KEY","NEXT_PUBLIC_TINGYUN_APP_KEY"],docs:"https://www.tingyun.com/docs",instrumentationFile:"apps/web/src/components/monitoring/TingYunScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Oc=eo.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function to(e){return eo.find(t=>t.id===e)}function Ns(e){He.mkdirSync(e,{recursive:!0})}function X(e,t){Ns(O.dirname(e)),He.writeFileSync(e,t)}function ct(e,t){let o=O.join(e,".env.example");He.existsSync(o)?He.appendFileSync(o,`
1627
+ `+t):He.writeFileSync(o,t)}function xs(e){let t=`import * as Sentry from "@sentry/nextjs";
1628
1628
 
1629
1629
  Sentry.init({
1630
1630
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
@@ -1667,14 +1667,14 @@ export async function register() {
1667
1667
  }
1668
1668
 
1669
1669
  export { captureRequestError as onRequestError } from "@sentry/nextjs";
1670
- `;X(O.join(e,"sentry.client.config.ts"),t),X(O.join(e,"sentry.server.config.ts"),o),X(O.join(e,"sentry.edge.config.ts"),n),X(O.join(e,"instrumentation.ts"),r)}function xs(){return`# Sentry \u2014 error tracking + performance monitoring
1670
+ `;X(O.join(e,"sentry.client.config.ts"),t),X(O.join(e,"sentry.server.config.ts"),o),X(O.join(e,"sentry.edge.config.ts"),n),X(O.join(e,"instrumentation.ts"),r)}function ks(){return`# Sentry \u2014 error tracking + performance monitoring
1671
1671
  # Get your DSN from https://sentry.io/settings/projects/<project>/keys/
1672
1672
  SENTRY_DSN=
1673
1673
  NEXT_PUBLIC_SENTRY_DSN=
1674
1674
  SENTRY_ORG=
1675
1675
  SENTRY_PROJECT=
1676
1676
  SENTRY_AUTH_TOKEN=
1677
- `}function ks(e){let t=`/**
1677
+ `}function Ts(e){let t=`/**
1678
1678
  * Next.js instrumentation hook \u2014 wires Datadog APM (dd-trace) into Node runtime.
1679
1679
  * Edge runtime is not supported by dd-trace; only nodejs is initialized.
1680
1680
  */
@@ -1722,7 +1722,7 @@ export function initDatadogRum(): void {
1722
1722
  });
1723
1723
  initialized = true;
1724
1724
  }
1725
- `;X(O.join(e,"instrumentation.ts"),t),X(O.join(e,"src","lib","monitoring","datadog-rum.ts"),o)}function Ts(){return`# Datadog \u2014 APM + RUM
1725
+ `;X(O.join(e,"instrumentation.ts"),t),X(O.join(e,"src","lib","monitoring","datadog-rum.ts"),o)}function Os(){return`# Datadog \u2014 APM + RUM
1726
1726
  # Server APM (dd-trace)
1727
1727
  DD_API_KEY=
1728
1728
  DD_APP_KEY=
@@ -1737,7 +1737,7 @@ NEXT_PUBLIC_DD_SITE=datadoghq.com
1737
1737
  NEXT_PUBLIC_DD_SERVICE=sailor-web
1738
1738
  NEXT_PUBLIC_DD_ENV=production
1739
1739
  NEXT_PUBLIC_DD_VERSION=
1740
- `}function Os(e){let t=`/**
1740
+ `}function Us(e){let t=`/**
1741
1741
  * Bugsnag server-side initialization.
1742
1742
  * Import this once at the top of your server entrypoint or a shared init module.
1743
1743
  */
@@ -1786,11 +1786,11 @@ export function getBugsnagErrorBoundary() {
1786
1786
  errorBoundary = plugin.createErrorBoundary(React) as typeof errorBoundary;
1787
1787
  return errorBoundary;
1788
1788
  }
1789
- `;X(O.join(e,"src","lib","monitoring","bugsnag.server.ts"),t),X(O.join(e,"src","lib","monitoring","bugsnag.client.tsx"),o)}function Us(){return`# Bugsnag \u2014 error tracking
1789
+ `;X(O.join(e,"src","lib","monitoring","bugsnag.server.ts"),t),X(O.join(e,"src","lib","monitoring","bugsnag.client.tsx"),o)}function Ls(){return`# Bugsnag \u2014 error tracking
1790
1790
  BUGSNAG_API_KEY=
1791
1791
  NEXT_PUBLIC_BUGSNAG_API_KEY=
1792
1792
  APP_VERSION=
1793
- `}function Ls(e){X(O.join(e,"src","components","monitoring","ArmsScript.tsx"),`"use client";
1793
+ `}function Ms(e){X(O.join(e,"src","components","monitoring","ArmsScript.tsx"),`"use client";
1794
1794
  /**
1795
1795
  * \u963F\u91CC\u4E91 ARMS (Application Real-time Monitoring Service) browser agent.
1796
1796
  * Injects the official JS agent via next/script.
@@ -1811,11 +1811,11 @@ export function ArmsScript() {
1811
1811
  />
1812
1812
  );
1813
1813
  }
1814
- `)}function Ms(){return`# \u963F\u91CC\u4E91 ARMS \u2014 APM (\u4E2D\u56FD\u533A)
1814
+ `)}function Ds(){return`# \u963F\u91CC\u4E91 ARMS \u2014 APM (\u4E2D\u56FD\u533A)
1815
1815
  ALIYUN_ARMS_LICENSE_KEY=
1816
1816
  ALIYUN_ARMS_APP_NAME=
1817
1817
  NEXT_PUBLIC_ARMS_PID=
1818
- `}function Ds(e){X(O.join(e,"src","components","monitoring","TingYunScript.tsx"),`"use client";
1818
+ `}function Fs(e){X(O.join(e,"src","components","monitoring","TingYunScript.tsx"),`"use client";
1819
1819
  /**
1820
1820
  * \u542C\u4E91 Browser Agent (\u524D\u7AEF\u6027\u80FD\u76D1\u63A7).
1821
1821
  * Docs: https://www.tingyun.com/docs
@@ -1833,12 +1833,12 @@ export function TingYunScript() {
1833
1833
  />
1834
1834
  );
1835
1835
  }
1836
- `)}function Fs(){return`# \u542C\u4E91 TingYun \u2014 APM (\u4E2D\u56FD\u533A)
1836
+ `)}function js(){return`# \u542C\u4E91 TingYun \u2014 APM (\u4E2D\u56FD\u533A)
1837
1837
  TINGYUN_LICENSE_KEY=
1838
1838
  NEXT_PUBLIC_TINGYUN_APP_KEY=
1839
- `}async function eo(e,t,o="global"){let n=Zn(t);if(!n||n.id==="none")return;let r=O.join(e,"apps","web");if(!He.existsSync(r))return;let s=n.id;try{switch(s){case"sentry":Ns(r),ct(e,xs());return;case"datadog":ks(r),ct(e,Ts());return;case"bugsnag":Os(r),ct(e,Us());return;case"aliyun-arms":Ls(r),ct(e,Ms());return;case"tingyun":Ds(r),ct(e,Fs());return;default:return}}catch(a){throw console.error(`Failed to apply monitoring selection "${t}":`,a),new Error(`Monitoring scaffold for "${t}" failed \u2014 see stderr for details.`)}}var wt=[{id:"novu",name:"Novu",region:"both",envVars:["NOVU_API_KEY","NOVU_APPLICATION_IDENTIFIER"],docs:"https://docs.novu.co",description:"Multi-channel notification infrastructure"},{id:"knock",name:"Knock",region:"global",envVars:["KNOCK_API_KEY","KNOCK_SIGNING_KEY","KNOCK_PUBLIC_API_KEY"],docs:"https://docs.knock.app",description:"Product notifications platform"},{id:"custom",name:"Custom (direct dispatchers)",region:"both",envVars:[],docs:"",description:"Use email + sms + push directly"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function to(e){return wt.find(t=>t.id===e)}var Fc=wt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function no(e,t,o="global"){let n=to(t);if(!n)throw new Error(`Unknown notifications provider "${t}". Valid ids: ${wt.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"notifications");return}n.envVars.length>0&&G(e,{category:"Notifications",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"NOTIFICATIONS_PROVIDER",n.id)}import $t from"fs";import js from"path";async function oo(e,t){let o=js.join(e,"package.json");if($t.existsSync(o)){let n=$t.readFileSync(o,"utf8"),r=JSON.parse(n);r.name=t,r.version="0.1.0",$t.writeFileSync(o,JSON.stringify(r,null,2)+`
1840
- `)}}import Z from"fs";import pt from"path";var Vs=["stripe","lemonsqueezy","chinapay","polar"];function ro(e){Z.existsSync(e)&&Z.rmSync(e,{recursive:!0,force:!0})}function Ks(e){switch(e){case"stripe":return["stripe"];case"lemon":return["lemonsqueezy"];case"wechat":case"alipay":return["chinapay"]}}function Bs(e,t){let o=pt.join(e,".env.example");Z.existsSync(o)?Z.appendFileSync(o,`
1841
- `+t):Z.writeFileSync(o,t)}function Ys(e){switch(e){case"stripe":return`# Stripe
1839
+ `}async function no(e,t,o="global"){let n=to(t);if(!n||n.id==="none")return;let r=O.join(e,"apps","web");if(!He.existsSync(r))return;let s=n.id;try{switch(s){case"sentry":xs(r),ct(e,ks());return;case"datadog":Ts(r),ct(e,Os());return;case"bugsnag":Us(r),ct(e,Ls());return;case"aliyun-arms":Ms(r),ct(e,Ds());return;case"tingyun":Fs(r),ct(e,js());return;default:return}}catch(a){throw console.error(`Failed to apply monitoring selection "${t}":`,a),new Error(`Monitoring scaffold for "${t}" failed \u2014 see stderr for details.`)}}var wt=[{id:"novu",name:"Novu",region:"both",envVars:["NOVU_API_KEY","NOVU_APPLICATION_IDENTIFIER"],docs:"https://docs.novu.co",description:"Multi-channel notification infrastructure"},{id:"knock",name:"Knock",region:"global",envVars:["KNOCK_API_KEY","KNOCK_SIGNING_KEY","KNOCK_PUBLIC_API_KEY"],docs:"https://docs.knock.app",description:"Product notifications platform"},{id:"custom",name:"Custom (direct dispatchers)",region:"both",envVars:[],docs:"",description:"Use email + sms + push directly"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function oo(e){return wt.find(t=>t.id===e)}var jc=wt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function ro(e,t,o="global"){let n=oo(t);if(!n)throw new Error(`Unknown notifications provider "${t}". Valid ids: ${wt.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"notifications");return}n.envVars.length>0&&G(e,{category:"Notifications",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"NOTIFICATIONS_PROVIDER",n.id)}import $t from"fs";import Vs from"path";async function so(e,t){let o=Vs.join(e,"package.json");if($t.existsSync(o)){let n=$t.readFileSync(o,"utf8"),r=JSON.parse(n);r.name=t,r.version="0.1.0",$t.writeFileSync(o,JSON.stringify(r,null,2)+`
1840
+ `)}}import Z from"fs";import pt from"path";var Ks=["stripe","lemonsqueezy","chinapay","polar"];function io(e){Z.existsSync(e)&&Z.rmSync(e,{recursive:!0,force:!0})}function Bs(e){switch(e){case"stripe":return["stripe"];case"lemon":return["lemonsqueezy"];case"wechat":case"alipay":return["chinapay"]}}function Ys(e,t){let o=pt.join(e,".env.example");Z.existsSync(o)?Z.appendFileSync(o,`
1841
+ `+t):Z.writeFileSync(o,t)}function $s(e){switch(e){case"stripe":return`# Stripe
1842
1842
  STRIPE_SECRET_KEY=
1843
1843
  STRIPE_WEBHOOK_SECRET=
1844
1844
  `;case"lemon":return`# Lemon Squeezy
@@ -1853,13 +1853,13 @@ CHINAPAY_WECHAT_ENABLED=true
1853
1853
  CHINAPAY_APP_ID=
1854
1854
  CHINAPAY_APP_SECRET=
1855
1855
  CHINAPAY_ALIPAY_ENABLED=true
1856
- `}}async function so(e,t){let o=pt.join(e,"packages","billing");if(!Z.existsSync(o))return;if(t==="none"){ro(o);return}let n=pt.join(o,"src"),r=new Set(Ks(t));for(let a of Vs)r.has(a)||ro(pt.join(n,a));let s=pt.join(n,"checkout","types.ts");if(Z.existsSync(s)){let a=t==="stripe"?"stripe":t==="lemon"?"lemonsqueezy":"chinapay",c=Z.readFileSync(s,"utf8"),i=c.replace(/export type CheckoutProviderType\s*=\s*[^;]+;/,`export type CheckoutProviderType = "${a}";`);i!==c&&Z.writeFileSync(s,i)}Bs(e,Ys(t))}import ae from"fs";import We from"path";var co=new Set(["siliconflow","volcengine-ark","bailian","moonshot"]),qt=/@sailor:([^\s*]+)/;function $s(e,t){let{providerIds:o,customEndpoint:n}=t;if(e.startsWith("provider:")){let r=e.slice(9);return{marker:e,keep:o.includes(r)}}if(e==="cn-compatible"){let r=o.some(s=>co.has(s));return{marker:e,keep:r||!!n}}if(e.startsWith("cn-instance:")){let r=e.slice(12);return{marker:e,keep:o.includes(r)}}return e==="custom-endpoint"?{marker:e,keep:!!n}:e==="registry-entries"?{marker:e,keep:!0}:{marker:e,keep:!0}}function io(e){return e.replace(/\s*\/\/\s*@sailor:[^\n]*$/,"")}function ao(e){return e.replace(/\s*#\s*@sailor:[^\n]*$/,"")}function po(e,t){let o=e.split(`
1857
- `),n=[],r=e.includes("#"),s=0;for(;s<o.length;){let a=o[s],c=a.match(qt);if(!c){n.push(a),s++;continue}let{marker:i,keep:d}=$s(c[1],t);if(i==="registry-entries"){n.push(r?ao(a):io(a)),s++;continue}if(d){let u=r?ao(a):io(a);u.trim().length>0&&n.push(u);let S=s+1;for(;S<o.length&&o[S].trim()!==""&&!qt.test(o[S]);)n.push(o[S]),S++;S<o.length&&o[S].trim()===""&&(n.push(o[S]),S++),s=S}else{let u=s+1;for(;u<o.length&&o[u].trim()!==""&&!qt.test(o[u]);)u++;u<o.length&&o[u].trim()===""&&u++,s=u}}return qs(n.join(`
1858
- `),t)}function qs(e,t){let{providerIds:o,customEndpoint:n}=t,r=new Set;for(let d of o)["openai","anthropic","google","mistral","xai"].includes(d)&&r.add(d),r.add(d.replace(/-/g,"_")),r.add(d);n&&r.add("custom");let s=/createProviderRegistry\(\{([\s\S]*?)\}\)/,a=e.match(s);if(!a)return e;let i=a[1].split(`
1856
+ `}}async function ao(e,t){let o=pt.join(e,"packages","billing");if(!Z.existsSync(o))return;if(t==="none"){io(o);return}let n=pt.join(o,"src"),r=new Set(Bs(t));for(let a of Ks)r.has(a)||io(pt.join(n,a));let s=pt.join(n,"checkout","types.ts");if(Z.existsSync(s)){let a=t==="stripe"?"stripe":t==="lemon"?"lemonsqueezy":"chinapay",c=Z.readFileSync(s,"utf8"),i=c.replace(/export type CheckoutProviderType\s*=\s*[^;]+;/,`export type CheckoutProviderType = "${a}";`);i!==c&&Z.writeFileSync(s,i)}Ys(e,$s(t))}import ae from"fs";import We from"path";var lo=new Set(["siliconflow","volcengine-ark","bailian","moonshot"]),qt=/@sailor:([^\s*]+)/;function qs(e,t){let{providerIds:o,customEndpoint:n}=t;if(e.startsWith("provider:")){let r=e.slice(9);return{marker:e,keep:o.includes(r)}}if(e==="cn-compatible"){let r=o.some(s=>lo.has(s));return{marker:e,keep:r||!!n}}if(e.startsWith("cn-instance:")){let r=e.slice(12);return{marker:e,keep:o.includes(r)}}return e==="custom-endpoint"?{marker:e,keep:!!n}:e==="registry-entries"?{marker:e,keep:!0}:{marker:e,keep:!0}}function co(e){return e.replace(/\s*\/\/\s*@sailor:[^\n]*$/,"")}function po(e){return e.replace(/\s*#\s*@sailor:[^\n]*$/,"")}function uo(e,t){let o=e.split(`
1857
+ `),n=[],r=e.includes("#"),s=0;for(;s<o.length;){let a=o[s],c=a.match(qt);if(!c){n.push(a),s++;continue}let{marker:i,keep:d}=qs(c[1],t);if(i==="registry-entries"){n.push(r?po(a):co(a)),s++;continue}if(d){let u=r?po(a):co(a);u.trim().length>0&&n.push(u);let S=s+1;for(;S<o.length&&o[S].trim()!==""&&!qt.test(o[S]);)n.push(o[S]),S++;S<o.length&&o[S].trim()===""&&(n.push(o[S]),S++),s=S}else{let u=s+1;for(;u<o.length&&o[u].trim()!==""&&!qt.test(o[u]);)u++;u<o.length&&o[u].trim()===""&&u++,s=u}}return Gs(n.join(`
1858
+ `),t)}function Gs(e,t){let{providerIds:o,customEndpoint:n}=t,r=new Set;for(let d of o)["openai","anthropic","google","mistral","xai"].includes(d)&&r.add(d),r.add(d.replace(/-/g,"_")),r.add(d);n&&r.add("custom");let s=/createProviderRegistry\(\{([\s\S]*?)\}\)/,a=e.match(s);if(!a)return e;let i=a[1].split(`
1859
1859
  `).filter(d=>{let u=d.trim();if(u===""||u.startsWith("//"))return!0;let S=u.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*,?$/);return S?r.has(S[1]):!0}).join(`
1860
- `);return e.replace(s,`createProviderRegistry({${i}})`)}function Gs(e,t){let o=We.join(t,"registry.ts.template"),n=ae.readFileSync(o,"utf-8");return po(n,e)}function Hs(e,t){let o=We.join(t,".env.example.template"),n=ae.readFileSync(o,"utf-8");return po(n,e)}async function lo(e,t,o){let n=Gs(t,o),r=Hs(t,o),s=We.join(e,"packages/agents/src");await ae.promises.mkdir(s,{recursive:!0}),await ae.promises.writeFile(We.join(s,"registry.ts"),n),await ae.promises.appendFile(We.join(e,".env.example"),`
1861
- `+r);let a={ai:"latest"},{providerIds:c,customEndpoint:i}=t;(c.includes("openai")||i||c.some(u=>co.has(u)))&&(a["@ai-sdk/openai"]="latest",a["@ai-sdk/openai-compatible"]="latest"),c.includes("anthropic")&&(a["@ai-sdk/anthropic"]="latest"),c.includes("google")&&(a["@ai-sdk/google"]="latest"),c.includes("mistral")&&(a["@ai-sdk/mistral"]="latest"),c.includes("xai")&&(a["@ai-sdk/openai"]="latest");let d=We.join(e,"package.json");if(ae.existsSync(d)){let u=JSON.parse(await ae.promises.readFile(d,"utf-8"));u.dependencies||(u.dependencies={});for(let[S,U]of Object.entries(a))u.dependencies[S]=U;await ae.promises.writeFile(d,JSON.stringify(u,null,2)+`
1862
- `)}}import g from"fs";import v from"path";function uo(e,t){if(!g.existsSync(e))return;let o=g.readdirSync(e);for(let n of o){let r=v.join(e,n);g.statSync(r).isDirectory()?uo(r,t):t(r)}}async function mo(e,t){let o=v.join(e,"package.json");if(!g.existsSync(o))return;let n=JSON.parse(g.readFileSync(o,"utf8"));if(t.orm!=="prisma"){let r=v.join(e,"packages","db");if(g.existsSync(r)){let s=v.join(r,"prisma");g.existsSync(s)&&g.rmSync(s,{recursive:!0,force:!0});let a=v.join(r,"package.json");if(g.existsSync(a)){let i=JSON.parse(g.readFileSync(a,"utf8"));i.dependencies&&delete i.dependencies["@prisma/client"],i.devDependencies&&delete i.devDependencies.prisma,g.writeFileSync(a,JSON.stringify(i,null,2)+`
1860
+ `);return e.replace(s,`createProviderRegistry({${i}})`)}function Hs(e,t){let o=We.join(t,"registry.ts.template"),n=ae.readFileSync(o,"utf-8");return uo(n,e)}function Ws(e,t){let o=We.join(t,".env.example.template"),n=ae.readFileSync(o,"utf-8");return uo(n,e)}async function mo(e,t,o){let n=Hs(t,o),r=Ws(t,o),s=We.join(e,"packages/agents/src");await ae.promises.mkdir(s,{recursive:!0}),await ae.promises.writeFile(We.join(s,"registry.ts"),n),await ae.promises.appendFile(We.join(e,".env.example"),`
1861
+ `+r);let a={ai:"latest"},{providerIds:c,customEndpoint:i}=t;(c.includes("openai")||i||c.some(u=>lo.has(u)))&&(a["@ai-sdk/openai"]="latest",a["@ai-sdk/openai-compatible"]="latest"),c.includes("anthropic")&&(a["@ai-sdk/anthropic"]="latest"),c.includes("google")&&(a["@ai-sdk/google"]="latest"),c.includes("mistral")&&(a["@ai-sdk/mistral"]="latest"),c.includes("xai")&&(a["@ai-sdk/openai"]="latest");let d=We.join(e,"package.json");if(ae.existsSync(d)){let u=JSON.parse(await ae.promises.readFile(d,"utf-8"));u.dependencies||(u.dependencies={});for(let[S,U]of Object.entries(a))u.dependencies[S]=U;await ae.promises.writeFile(d,JSON.stringify(u,null,2)+`
1862
+ `)}}import g from"fs";import v from"path";function go(e,t){if(!g.existsSync(e))return;let o=g.readdirSync(e);for(let n of o){let r=v.join(e,n);g.statSync(r).isDirectory()?go(r,t):t(r)}}async function fo(e,t){let o=v.join(e,"package.json");if(!g.existsSync(o))return;let n=JSON.parse(g.readFileSync(o,"utf8"));if(t.orm!=="prisma"){let r=v.join(e,"packages","db");if(g.existsSync(r)){let s=v.join(r,"prisma");g.existsSync(s)&&g.rmSync(s,{recursive:!0,force:!0});let a=v.join(r,"package.json");if(g.existsSync(a)){let i=JSON.parse(g.readFileSync(a,"utf8"));i.dependencies&&delete i.dependencies["@prisma/client"],i.devDependencies&&delete i.devDependencies.prisma,g.writeFileSync(a,JSON.stringify(i,null,2)+`
1863
1863
  `)}let c=v.join(r,"src","index.ts");g.existsSync(c)&&g.writeFileSync(c,`
1864
1864
  export const prisma = {} as any;
1865
1865
  export const db = {} as any;
@@ -1906,7 +1906,7 @@ export type UsageAggregate = any;
1906
1906
  export type UsageLedgerEntry = any;
1907
1907
  export type UsageType = any;
1908
1908
  export type UsageLedgerSource = any;
1909
- `)}n.scripts?.postinstall&&(n.scripts.postinstall=n.scripts.postinstall.replace(/prisma generate/g,'echo "ORM Disabled"'))}if(!t.i18n){let r=v.join(e,"apps");if(g.existsSync(r)){let s=g.readdirSync(r);for(let a of s){let c=v.join(r,a);if(!g.statSync(c).isDirectory())continue;let i=v.join(c,"src","app");if(!g.existsSync(i))continue;["[lang]","[locale]"].forEach(E=>{let l=v.join(i,E);if(g.existsSync(l)){let N=g.readdirSync(l);for(let ut of N)g.renameSync(v.join(l,ut),v.join(i,ut));g.rmdirSync(l)}}),["src/middleware.ts","middleware.ts"].forEach(E=>{let l=v.join(c,E);g.existsSync(l)&&g.rmSync(l)});let d=v.join(c,"src","lib");g.existsSync(d)||g.mkdirSync(d,{recursive:!0});let u=v.join(d,"mock-i18n.ts");g.writeFileSync(u,`
1909
+ `)}n.scripts?.postinstall&&(n.scripts.postinstall=n.scripts.postinstall.replace(/prisma generate/g,'echo "ORM Disabled"'))}if(!t.i18n){let r=v.join(e,"apps");if(g.existsSync(r)){let s=g.readdirSync(r);for(let a of s){let c=v.join(r,a);if(!g.statSync(c).isDirectory())continue;let i=v.join(c,"src","app");if(!g.existsSync(i))continue;["[lang]","[locale]"].forEach(h=>{let l=v.join(i,h);if(g.existsSync(l)){let N=g.readdirSync(l);for(let ut of N)g.renameSync(v.join(l,ut),v.join(i,ut));g.rmdirSync(l)}}),["src/middleware.ts","middleware.ts"].forEach(h=>{let l=v.join(c,h);g.existsSync(l)&&g.rmSync(l)});let d=v.join(c,"src","lib");g.existsSync(d)||g.mkdirSync(d,{recursive:!0});let u=v.join(d,"mock-i18n.ts");g.writeFileSync(u,`
1910
1910
  import React from 'react';
1911
1911
  export function useTranslations(namespace?: string): any { return (key: string) => key; }
1912
1912
  export function useLocale() { return 'en'; }
@@ -1945,15 +1945,15 @@ export function defineRouting<T>(config: T): T { return config; }
1945
1945
  `),g.writeFileSync(v.join(d,"mock-i18n-index.ts"),`
1946
1946
  export * from './mock-i18n';
1947
1947
  export { default } from './mock-i18n';
1948
- `);let F=v.join(c,"tsconfig.json");if(g.existsSync(F))try{let E=g.readFileSync(F,"utf8");if(E.includes('"paths": {')){let l=E.replace(/"paths":\s*\{/,`"paths": {
1948
+ `);let F=v.join(c,"tsconfig.json");if(g.existsSync(F))try{let h=g.readFileSync(F,"utf8");if(h.includes('"paths": {')){let l=h.replace(/"paths":\s*\{/,`"paths": {
1949
1949
  "next-intl": ["./src/lib/mock-i18n"],
1950
- "next-intl/*": ["./src/lib/mock-i18n"],`);g.writeFileSync(F,l)}}catch{}let ee=v.join(c,"src");g.existsSync(ee)&&uo(ee,E=>{if(!E.endsWith(".ts")&&!E.endsWith(".tsx"))return;let l=g.readFileSync(E,"utf8"),N=!1;E.endsWith("src/app/layout.tsx")&&l.includes("../providers")&&(l=l.replace(/from\s+['"]\.\.\/providers['"]/g,"from './providers'"),N=!0),l=l.replace(/params:\s*Promise<\{[^}]*(lang|locale)[^}]*\}>/g,"params: any"),l=l.replace(/\(\{\s*params\s*\}\s*:\s*\{\s*params:\s*any\s*\}\)/g,"({ params }: any)"),l.match(/locale\s*:\s*any/)&&(l=l.replace(/locale\s*:\s*any/g,"locale: string"),N=!0),l.match(/lang\s*:\s*any/)&&(l=l.replace(/lang\s*:\s*any/g,"lang: string"),N=!0),l.match(/requestLocale\s*:\s*any/)&&(l=l.replace(/requestLocale\s*:\s*any/g,"requestLocale: string"),N=!0),l.match(/\(locale\s*=\s*(.*)\)/)&&(l=l.replace(/\(locale\s*=\s*(.*)\)/g,"() "),N=!0),l.match(/export\s+default\s+async\s+function\s+LangLayout/)&&(l=l.replace(/export\s+default\s+async\s+function\s+LangLayout\s*\(\s*\{\s*children\s*,\s*params\s*\}\s*:\s*LangLayoutProps\s*\)/g,"export default async function LangLayout({ children }: { children: React.ReactNode })"),N=!0),(E.endsWith("src/app/layout.tsx")||E.endsWith("src/app/sitemap.ts")||E.endsWith("src/app/robots.ts")||E.endsWith("src/components/ui/locale-switcher.tsx")||E.endsWith("src/app/(marketing)/blog/[slug]/page.tsx"))&&(l=l.replace(/const\s+\{\s*lang\s*\}\s*=\s*(await\s+)?params;?/g,'const lang = "en";'),l=l.replace(/const\s+\{\s*locale\s*\}\s*=\s*(await\s+)?params;?/g,'const locale = "en";'),l=l.replace(/const\s+locale\s*=\s*lang\s+as\s+Locale;?/g,'const locale = "en";'),l=l.replace(/\(l\)\s*=>/g,"(l: any) =>"),N=!0),E.endsWith("src/i18n/request.ts")&&(l=l.replace(/async\s*\(\{\s*requestLocale\s*\}\)/g,"async ({ requestLocale }: any)"),N=!0),(l.match(/locale\s*:/)||l.match(/lang\s*:/))&&(N=!0),N&&g.writeFileSync(E,l)});let Xe=v.join(c,"package.json");if(g.existsSync(Xe)){let E=JSON.parse(g.readFileSync(Xe,"utf8"));E.dependencies&&delete E.dependencies["next-intl"],g.writeFileSync(Xe,JSON.stringify(E,null,2)+`
1950
+ "next-intl/*": ["./src/lib/mock-i18n"],`);g.writeFileSync(F,l)}}catch{}let ee=v.join(c,"src");g.existsSync(ee)&&go(ee,h=>{if(!h.endsWith(".ts")&&!h.endsWith(".tsx"))return;let l=g.readFileSync(h,"utf8"),N=!1;h.endsWith("src/app/layout.tsx")&&l.includes("../providers")&&(l=l.replace(/from\s+['"]\.\.\/providers['"]/g,"from './providers'"),N=!0),l=l.replace(/params:\s*Promise<\{[^}]*(lang|locale)[^}]*\}>/g,"params: any"),l=l.replace(/\(\{\s*params\s*\}\s*:\s*\{\s*params:\s*any\s*\}\)/g,"({ params }: any)"),l.match(/locale\s*:\s*any/)&&(l=l.replace(/locale\s*:\s*any/g,"locale: string"),N=!0),l.match(/lang\s*:\s*any/)&&(l=l.replace(/lang\s*:\s*any/g,"lang: string"),N=!0),l.match(/requestLocale\s*:\s*any/)&&(l=l.replace(/requestLocale\s*:\s*any/g,"requestLocale: string"),N=!0),l.match(/\(locale\s*=\s*(.*)\)/)&&(l=l.replace(/\(locale\s*=\s*(.*)\)/g,"() "),N=!0),l.match(/export\s+default\s+async\s+function\s+LangLayout/)&&(l=l.replace(/export\s+default\s+async\s+function\s+LangLayout\s*\(\s*\{\s*children\s*,\s*params\s*\}\s*:\s*LangLayoutProps\s*\)/g,"export default async function LangLayout({ children }: { children: React.ReactNode })"),N=!0),(h.endsWith("src/app/layout.tsx")||h.endsWith("src/app/sitemap.ts")||h.endsWith("src/app/robots.ts")||h.endsWith("src/components/ui/locale-switcher.tsx")||h.endsWith("src/app/(marketing)/blog/[slug]/page.tsx"))&&(l=l.replace(/const\s+\{\s*lang\s*\}\s*=\s*(await\s+)?params;?/g,'const lang = "en";'),l=l.replace(/const\s+\{\s*locale\s*\}\s*=\s*(await\s+)?params;?/g,'const locale = "en";'),l=l.replace(/const\s+locale\s*=\s*lang\s+as\s+Locale;?/g,'const locale = "en";'),l=l.replace(/\(l\)\s*=>/g,"(l: any) =>"),N=!0),h.endsWith("src/i18n/request.ts")&&(l=l.replace(/async\s*\(\{\s*requestLocale\s*\}\)/g,"async ({ requestLocale }: any)"),N=!0),(l.match(/locale\s*:/)||l.match(/lang\s*:/))&&(N=!0),N&&g.writeFileSync(h,l)});let Xe=v.join(c,"package.json");if(g.existsSync(Xe)){let h=JSON.parse(g.readFileSync(Xe,"utf8"));h.dependencies&&delete h.dependencies["next-intl"],g.writeFileSync(Xe,JSON.stringify(h,null,2)+`
1951
1951
  `)}}}}g.writeFileSync(o,JSON.stringify(n,null,2)+`
1952
- `)}import{getSchema as Ws,printSchema as Xs}from"@mrleebo/prisma-ast";var zs=/^\/\/\/\s*@conditional\(([A-Za-z][A-Za-z0-9_-]*)=([^)]+)\)\s*$/;function Qs(e){return e.type==="comment"&&e.text.trim().startsWith("///")}function Js(e){let t=zs.exec(e.trim());if(!t)return null;let[,o,n]=t,r=n.split("|").map(s=>s.trim()).filter(s=>s.length>0);return{flag:o,values:r}}function Zs(e,t){for(let o=t-1;o>=0;o--){let n=e[o];if(n.type==="comment"){let r=Js(n.text);if(r)return{annIndex:o,parsed:r};continue}break}return null}function Gt(e,t){let o=Ws(e),n=new Set;for(let c=0;c<o.list.length;c++){if(o.list[c].type!=="model")continue;let d=Zs(o.list,c);if(!d)continue;let u=t[d.parsed.flag];if(u!==void 0&&d.parsed.values.includes(u))n.add(d.annIndex);else{n.add(c);for(let F=c-1;F>=0;F--){let ee=o.list[F];if(ee.type==="comment"&&Qs(ee)){n.add(F);continue}break}let U=o.list[c+1];U&&U.type==="break"&&n.add(c+1)}}let r=o.list.filter((c,i)=>!n.has(i)),s=[];for(let c of r){let i=s[s.length-1];c.type==="break"&&i&&i.type==="break"||s.push(c)}return Xs({type:"schema",list:s})}import ce from"fs";import Ht from"path";var Rt=[{id:"qstash",name:"Upstash QStash",region:"both",envVars:["QSTASH_TOKEN","QSTASH_CURRENT_SIGNING_KEY","QSTASH_NEXT_SIGNING_KEY"],docs:"https://upstash.com/docs/qstash",description:"Serverless HTTP-based queue"},{id:"bullmq",name:"BullMQ",region:"both",envVars:["REDIS_URL"],docs:"https://docs.bullmq.io",description:"Redis-backed job queue"},{id:"upstash",name:"Upstash Kafka",region:"both",envVars:["UPSTASH_KAFKA_REST_URL","UPSTASH_KAFKA_REST_USERNAME","UPSTASH_KAFKA_REST_PASSWORD"],docs:"https://upstash.com/docs/kafka",description:"Serverless Kafka"},{id:"sqs",name:"AWS SQS",region:"global",envVars:["AWS_SQS_QUEUE_URL","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],docs:"https://docs.aws.amazon.com/AWSSimpleQueueService/",description:"AWS managed queue"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip queue package"}];function go(e){return Rt.find(t=>t.id===e)}var op=Rt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function fo(e){return ce.existsSync(e)?ce.readFileSync(e,"utf-8"):null}function ei(e,t){let o=Ht.join(e,".env.example"),n=fo(o);if(n===null)return;let r=`# Queue: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
1953
- `);ce.appendFileSync(o,s)}function ti(e,t,o){let n=Ht.join(e,".env.example"),r=fo(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?ce.writeFileSync(n,r.replace(s,`${t}="${o}"`)):ce.appendFileSync(n,`${t}="${o}"
1954
- `)}async function yo(e,t,o){let n=Ht.join(e,"packages","queue");if(t==="none"){ce.existsSync(n)&&ce.rmSync(n,{recursive:!0,force:!0});return}let r=go(t);if(!r)throw new Error(`Unknown queue provider "${t}". Valid ids: ${Rt.map(s=>s.id).join(", ")}`);ce.existsSync(n)&&(ei(e,r),ti(e,"QUEUE_PROVIDER",t))}import pe from"fs";import Wt from"path";var Nt=[{id:"meilisearch",name:"Meilisearch",region:"both",envVars:["MEILISEARCH_HOST","MEILISEARCH_MASTER_KEY"],docs:"https://docs.meilisearch.com",description:"Self-hostable search"},{id:"typesense",name:"Typesense",region:"both",envVars:["TYPESENSE_HOST","TYPESENSE_PORT","TYPESENSE_PROTOCOL","TYPESENSE_API_KEY"],docs:"https://typesense.org/docs",description:"Open-source search"},{id:"algolia",name:"Algolia",region:"global",envVars:["ALGOLIA_APP_ID","ALGOLIA_ADMIN_API_KEY","ALGOLIA_SEARCH_API_KEY"],docs:"https://www.algolia.com/doc/",description:"Managed search as a service"},{id:"pgvector",name:"pgvector (Postgres)",region:"both",envVars:["DATABASE_URL"],docs:"https://github.com/pgvector/pgvector",description:"Postgres vector + full-text"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip search package"}];function So(e){return Nt.find(t=>t.id===e)}var pp=Nt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function Eo(e){return pe.existsSync(e)?pe.readFileSync(e,"utf-8"):null}function ni(e,t){let o=Wt.join(e,".env.example"),n=Eo(o);if(n===null)return;let r=`# Search: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
1955
- `);pe.appendFileSync(o,s)}function oi(e,t,o){let n=Wt.join(e,".env.example"),r=Eo(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?pe.writeFileSync(n,r.replace(s,`${t}="${o}"`)):pe.appendFileSync(n,`${t}="${o}"
1956
- `)}async function ho(e,t,o){let n=Wt.join(e,"packages","search");if(t==="none"){pe.existsSync(n)&&pe.rmSync(n,{recursive:!0,force:!0});return}let r=So(t);if(!r)throw new Error(`Unknown search provider "${t}". Valid ids: ${Nt.map(s=>s.id).join(", ")}`);pe.existsSync(n)&&(ni(e,r),oi(e,"SEARCH_PROVIDER",t))}import le from"fs";import be from"path";function ri(e){let t=[be.join(e,"packages","db"),be.join(e,"apps","web")];for(let o of t){let n=be.join(o,"prisma","schema.prisma");if(le.existsSync(n))return{packageDir:o,seedPath:be.join(o,"prisma","seed.ts"),packageJsonPath:be.join(o,"package.json")}}return null}function si(e){try{let t=le.readFileSync(e,"utf8"),o=new Set,n=/^\s*model\s+(\w+)\s*\{/gm,r=n.exec(t);for(;r;)o.add(r[1]),r=n.exec(t);return o}catch{return new Set}}function ii(e,t){return!t||e==="none"?` // Skipping admin user \u2014 auth=${JSON.stringify(e)} (or no User model).`:e==="clerk"?` try {
1952
+ `)}import{getSchema as Xs,printSchema as zs}from"@mrleebo/prisma-ast";var Qs=/^\/\/\/\s*@conditional\(([A-Za-z][A-Za-z0-9_-]*)=([^)]+)\)\s*$/;function Js(e){return e.type==="comment"&&e.text.trim().startsWith("///")}function Zs(e){let t=Qs.exec(e.trim());if(!t)return null;let[,o,n]=t,r=n.split("|").map(s=>s.trim()).filter(s=>s.length>0);return{flag:o,values:r}}function ei(e,t){for(let o=t-1;o>=0;o--){let n=e[o];if(n.type==="comment"){let r=Zs(n.text);if(r)return{annIndex:o,parsed:r};continue}break}return null}function Gt(e,t){let o=Xs(e),n=new Set;for(let c=0;c<o.list.length;c++){if(o.list[c].type!=="model")continue;let d=ei(o.list,c);if(!d)continue;let u=t[d.parsed.flag];if(u!==void 0&&d.parsed.values.includes(u))n.add(d.annIndex);else{n.add(c);for(let F=c-1;F>=0;F--){let ee=o.list[F];if(ee.type==="comment"&&Js(ee)){n.add(F);continue}break}let U=o.list[c+1];U&&U.type==="break"&&n.add(c+1)}}let r=o.list.filter((c,i)=>!n.has(i)),s=[];for(let c of r){let i=s[s.length-1];c.type==="break"&&i&&i.type==="break"||s.push(c)}return zs({type:"schema",list:s})}import ce from"fs";import Ht from"path";var Rt=[{id:"qstash",name:"Upstash QStash",region:"both",envVars:["QSTASH_TOKEN","QSTASH_CURRENT_SIGNING_KEY","QSTASH_NEXT_SIGNING_KEY"],docs:"https://upstash.com/docs/qstash",description:"Serverless HTTP-based queue"},{id:"bullmq",name:"BullMQ",region:"both",envVars:["REDIS_URL"],docs:"https://docs.bullmq.io",description:"Redis-backed job queue"},{id:"upstash",name:"Upstash Kafka",region:"both",envVars:["UPSTASH_KAFKA_REST_URL","UPSTASH_KAFKA_REST_USERNAME","UPSTASH_KAFKA_REST_PASSWORD"],docs:"https://upstash.com/docs/kafka",description:"Serverless Kafka"},{id:"sqs",name:"AWS SQS",region:"global",envVars:["AWS_SQS_QUEUE_URL","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],docs:"https://docs.aws.amazon.com/AWSSimpleQueueService/",description:"AWS managed queue"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip queue package"}];function yo(e){return Rt.find(t=>t.id===e)}var rp=Rt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function So(e){return ce.existsSync(e)?ce.readFileSync(e,"utf-8"):null}function ti(e,t){let o=Ht.join(e,".env.example"),n=So(o);if(n===null)return;let r=`# Queue: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
1953
+ `);ce.appendFileSync(o,s)}function ni(e,t,o){let n=Ht.join(e,".env.example"),r=So(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?ce.writeFileSync(n,r.replace(s,`${t}="${o}"`)):ce.appendFileSync(n,`${t}="${o}"
1954
+ `)}async function ho(e,t,o){let n=Ht.join(e,"packages","queue");if(t==="none"){ce.existsSync(n)&&ce.rmSync(n,{recursive:!0,force:!0});return}let r=yo(t);if(!r)throw new Error(`Unknown queue provider "${t}". Valid ids: ${Rt.map(s=>s.id).join(", ")}`);ce.existsSync(n)&&(ti(e,r),ni(e,"QUEUE_PROVIDER",t))}import pe from"fs";import Wt from"path";var Nt=[{id:"meilisearch",name:"Meilisearch",region:"both",envVars:["MEILISEARCH_HOST","MEILISEARCH_MASTER_KEY"],docs:"https://docs.meilisearch.com",description:"Self-hostable search"},{id:"typesense",name:"Typesense",region:"both",envVars:["TYPESENSE_HOST","TYPESENSE_PORT","TYPESENSE_PROTOCOL","TYPESENSE_API_KEY"],docs:"https://typesense.org/docs",description:"Open-source search"},{id:"algolia",name:"Algolia",region:"global",envVars:["ALGOLIA_APP_ID","ALGOLIA_ADMIN_API_KEY","ALGOLIA_SEARCH_API_KEY"],docs:"https://www.algolia.com/doc/",description:"Managed search as a service"},{id:"pgvector",name:"pgvector (Postgres)",region:"both",envVars:["DATABASE_URL"],docs:"https://github.com/pgvector/pgvector",description:"Postgres vector + full-text"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip search package"}];function Eo(e){return Nt.find(t=>t.id===e)}var lp=Nt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function vo(e){return pe.existsSync(e)?pe.readFileSync(e,"utf-8"):null}function oi(e,t){let o=Wt.join(e,".env.example"),n=vo(o);if(n===null)return;let r=`# Search: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].join(`
1955
+ `);pe.appendFileSync(o,s)}function ri(e,t,o){let n=Wt.join(e,".env.example"),r=vo(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?pe.writeFileSync(n,r.replace(s,`${t}="${o}"`)):pe.appendFileSync(n,`${t}="${o}"
1956
+ `)}async function _o(e,t,o){let n=Wt.join(e,"packages","search");if(t==="none"){pe.existsSync(n)&&pe.rmSync(n,{recursive:!0,force:!0});return}let r=Eo(t);if(!r)throw new Error(`Unknown search provider "${t}". Valid ids: ${Nt.map(s=>s.id).join(", ")}`);pe.existsSync(n)&&(oi(e,r),ri(e,"SEARCH_PROVIDER",t))}import le from"fs";import be from"path";function si(e){let t=[be.join(e,"packages","db"),be.join(e,"apps","web")];for(let o of t){let n=be.join(o,"prisma","schema.prisma");if(le.existsSync(n))return{packageDir:o,seedPath:be.join(o,"prisma","seed.ts"),packageJsonPath:be.join(o,"package.json")}}return null}function ii(e){try{let t=le.readFileSync(e,"utf8"),o=new Set,n=/^\s*model\s+(\w+)\s*\{/gm,r=n.exec(t);for(;r;)o.add(r[1]),r=n.exec(t);return o}catch{return new Set}}function ai(e,t){return!t||e==="none"?` // Skipping admin user \u2014 auth=${JSON.stringify(e)} (or no User model).`:e==="clerk"?` try {
1957
1957
  const admin = await prisma.user.create({
1958
1958
  data: {
1959
1959
  clerkId: "user_mock_admin",
@@ -1984,7 +1984,7 @@ export { default } from './mock-i18n';
1984
1984
  console.log("\\u2713 Created admin user:", admin.email);
1985
1985
  } catch (err) {
1986
1986
  console.warn("\\u26A0 Admin user creation skipped:", (err as Error).message);
1987
- }`}function ai(e,t){let o=t.has("Tenant"),n=t.has("User"),r=t.has("Project"),s=ii(e,n),a=o?` let tenants: Array<{ id: string; name: string }> = [];
1987
+ }`}function ci(e,t){let o=t.has("Tenant"),n=t.has("User"),r=t.has("Project"),s=ai(e,n),a=o?` let tenants: Array<{ id: string; name: string }> = [];
1988
1988
  try {
1989
1989
  tenants = await Promise.all([
1990
1990
  prisma.tenant.create({
@@ -2053,12 +2053,12 @@ main()
2053
2053
  .finally(async () => {
2054
2054
  await prisma.$disconnect();
2055
2055
  });
2056
- `}function ci(e){if(le.existsSync(e))try{let t=le.readFileSync(e,"utf8"),o=JSON.parse(t),n=o.scripts??{},r=!1;n["db:seed"]||(n["db:seed"]="prisma db seed",r=!0);let s=o.prisma??{};if(s.seed||(s.seed="tsx prisma/seed.ts",r=!0),!r)return;let a={...o,scripts:n,prisma:s};le.writeFileSync(e,JSON.stringify(a,null,2)+`
2057
- `)}catch(t){let o=t instanceof Error?t.message:String(t);console.warn(`[create-sailor] Failed to patch seed scripts in ${e}: ${o}`)}}async function vo(e,t){let o=ri(e);if(o)try{let n=be.join(o.packageDir,"prisma","schema.prisma"),r=si(n),s=ai(t,r),a=be.dirname(o.seedPath);le.existsSync(a)||le.mkdirSync(a,{recursive:!0}),le.writeFileSync(o.seedPath,s),ci(o.packageJsonPath)}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate seed data: ${r}`),new Error(`Unable to write prisma/seed.ts: ${r}`)}}import de from"fs";import Ie from"path";var xt=[{id:"twilio",name:"Twilio",region:"global",envVars:["TWILIO_ACCOUNT_SID","TWILIO_AUTH_TOKEN","TWILIO_FROM_NUMBER"],docs:"https://www.twilio.com/docs/sms",pkgs:["twilio"]},{id:"messagebird",name:"MessageBird (Bird)",region:"global",envVars:["MESSAGEBIRD_ACCESS_KEY","MESSAGEBIRD_ORIGINATOR"],docs:"https://developers.messagebird.com/api/sms-messaging/",pkgs:["messagebird"]},{id:"plivo",name:"Plivo",region:"global",envVars:["PLIVO_AUTH_ID","PLIVO_AUTH_TOKEN","PLIVO_FROM_NUMBER"],docs:"https://www.plivo.com/docs/sms/",pkgs:["plivo"]},{id:"aliyun-sms",name:"\u963F\u91CC\u4E91\u77ED\u4FE1 Aliyun SMS",region:"cn",envVars:["ALIYUN_SMS_ACCESS_KEY","ALIYUN_SMS_ACCESS_SECRET","ALIYUN_SMS_SIGN_NAME","ALIYUN_SMS_TEMPLATE_CODE","ALIYUN_SMS_ENDPOINT"],docs:"https://help.aliyun.com/product/44282.html",pkgs:["@alicloud/dysmsapi20170525","@alicloud/openapi-client"]},{id:"tencent-sms",name:"\u817E\u8BAF\u4E91\u77ED\u4FE1 Tencent SMS",region:"cn",envVars:["TENCENT_SMS_SECRET_ID","TENCENT_SMS_SECRET_KEY","TENCENT_SMS_SDK_APP_ID","TENCENT_SMS_SIGN_NAME","TENCENT_SMS_TEMPLATE_ID","TENCENT_SMS_REGION"],docs:"https://cloud.tencent.com/document/product/382",pkgs:["tencentcloud-sdk-nodejs-sms"]},{id:"yunpian",name:"\u4E91\u7247 Yunpian",region:"cn",envVars:["YUNPIAN_API_KEY","YUNPIAN_SIGN"],docs:"https://www.yunpian.com/official/document/sms/zh_CN/introduction_product_intro",pkgs:["yunpian-nodejs-sdk"]},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Ep=xt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function _o(e){return xt.find(t=>t.id===e)}var pi="@nebutra/sms",li={twilio:"^5.3.6",messagebird:"^4.0.1",plivo:"^4.73.0","@alicloud/dysmsapi20170525":"^2.0.24","@alicloud/openapi-client":"^0.4.12","tencentcloud-sdk-nodejs-sms":"^4.0.970","yunpian-nodejs-sdk":"^0.0.2"};function Xt(e,t){de.mkdirSync(Ie.dirname(e),{recursive:!0}),de.writeFileSync(e,t)}function di(e,t){let o=Ie.join(e,".env.example");de.existsSync(o)?de.appendFileSync(o,`
2058
- `+t):de.writeFileSync(o,t)}function ui(e){if(e.envVars.length===0)return"";let t=`# SMS provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2056
+ `}function pi(e){if(le.existsSync(e))try{let t=le.readFileSync(e,"utf8"),o=JSON.parse(t),n=o.scripts??{},r=!1;n["db:seed"]||(n["db:seed"]="prisma db seed",r=!0);let s=o.prisma??{};if(s.seed||(s.seed="tsx prisma/seed.ts",r=!0),!r)return;let a={...o,scripts:n,prisma:s};le.writeFileSync(e,JSON.stringify(a,null,2)+`
2057
+ `)}catch(t){let o=t instanceof Error?t.message:String(t);console.warn(`[create-sailor] Failed to patch seed scripts in ${e}: ${o}`)}}async function Po(e,t){let o=si(e);if(o)try{let n=be.join(o.packageDir,"prisma","schema.prisma"),r=ii(n),s=ci(t,r),a=be.dirname(o.seedPath);le.existsSync(a)||le.mkdirSync(a,{recursive:!0}),le.writeFileSync(o.seedPath,s),pi(o.packageJsonPath)}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate seed data: ${r}`),new Error(`Unable to write prisma/seed.ts: ${r}`)}}import de from"fs";import Ie from"path";var xt=[{id:"twilio",name:"Twilio",region:"global",envVars:["TWILIO_ACCOUNT_SID","TWILIO_AUTH_TOKEN","TWILIO_FROM_NUMBER"],docs:"https://www.twilio.com/docs/sms",pkgs:["twilio"]},{id:"messagebird",name:"MessageBird (Bird)",region:"global",envVars:["MESSAGEBIRD_ACCESS_KEY","MESSAGEBIRD_ORIGINATOR"],docs:"https://developers.messagebird.com/api/sms-messaging/",pkgs:["messagebird"]},{id:"plivo",name:"Plivo",region:"global",envVars:["PLIVO_AUTH_ID","PLIVO_AUTH_TOKEN","PLIVO_FROM_NUMBER"],docs:"https://www.plivo.com/docs/sms/",pkgs:["plivo"]},{id:"aliyun-sms",name:"\u963F\u91CC\u4E91\u77ED\u4FE1 Aliyun SMS",region:"cn",envVars:["ALIYUN_SMS_ACCESS_KEY","ALIYUN_SMS_ACCESS_SECRET","ALIYUN_SMS_SIGN_NAME","ALIYUN_SMS_TEMPLATE_CODE","ALIYUN_SMS_ENDPOINT"],docs:"https://help.aliyun.com/product/44282.html",pkgs:["@alicloud/dysmsapi20170525","@alicloud/openapi-client"]},{id:"tencent-sms",name:"\u817E\u8BAF\u4E91\u77ED\u4FE1 Tencent SMS",region:"cn",envVars:["TENCENT_SMS_SECRET_ID","TENCENT_SMS_SECRET_KEY","TENCENT_SMS_SDK_APP_ID","TENCENT_SMS_SIGN_NAME","TENCENT_SMS_TEMPLATE_ID","TENCENT_SMS_REGION"],docs:"https://cloud.tencent.com/document/product/382",pkgs:["tencentcloud-sdk-nodejs-sms"]},{id:"yunpian",name:"\u4E91\u7247 Yunpian",region:"cn",envVars:["YUNPIAN_API_KEY","YUNPIAN_SIGN"],docs:"https://www.yunpian.com/official/document/sms/zh_CN/introduction_product_intro",pkgs:["yunpian-nodejs-sdk"]},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Ep=xt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function bo(e){return xt.find(t=>t.id===e)}var li="@nebutra/sms",di={twilio:"^5.3.6",messagebird:"^4.0.1",plivo:"^4.73.0","@alicloud/dysmsapi20170525":"^2.0.24","@alicloud/openapi-client":"^0.4.12","tencentcloud-sdk-nodejs-sms":"^4.0.970","yunpian-nodejs-sdk":"^0.0.2"};function Xt(e,t){de.mkdirSync(Ie.dirname(e),{recursive:!0}),de.writeFileSync(e,t)}function ui(e,t){let o=Ie.join(e,".env.example");de.existsSync(o)?de.appendFileSync(o,`
2058
+ `+t):de.writeFileSync(o,t)}function mi(e){if(e.envVars.length===0)return"";let t=`# SMS provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2059
2059
  `);return`${t}
2060
2060
  ${o}
2061
- `}var mi=`/**
2061
+ `}var gi=`/**
2062
2062
  * Inputs for the \`sendSms\` wrapper. Keep this surface portable across
2063
2063
  * providers \u2014 provider-specific options belong in the wrapper itself.
2064
2064
  */
@@ -2078,7 +2078,7 @@ export interface SendSmsResult {
2078
2078
  provider: string;
2079
2079
  raw?: unknown;
2080
2080
  }
2081
- `;function gi(){return`import twilio from "twilio";
2081
+ `;function fi(){return`import twilio from "twilio";
2082
2082
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2083
2083
 
2084
2084
  let client: ReturnType<typeof twilio> | null = null;
@@ -2113,7 +2113,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2113
2113
  }
2114
2114
 
2115
2115
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2116
- `}function fi(){return`import messagebird from "messagebird";
2116
+ `}function yi(){return`import messagebird from "messagebird";
2117
2117
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2118
2118
 
2119
2119
  let client: ReturnType<typeof messagebird> | null = null;
@@ -2151,7 +2151,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2151
2151
  }
2152
2152
 
2153
2153
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2154
- `}function yi(){return`import plivo from "plivo";
2154
+ `}function Si(){return`import plivo from "plivo";
2155
2155
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2156
2156
 
2157
2157
  let client: InstanceType<typeof plivo.Client> | null = null;
@@ -2190,7 +2190,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2190
2190
  }
2191
2191
 
2192
2192
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2193
- `}function Si(){return`import Dysmsapi, { SendSmsRequest } from "@alicloud/dysmsapi20170525";
2193
+ `}function hi(){return`import Dysmsapi, { SendSmsRequest } from "@alicloud/dysmsapi20170525";
2194
2194
  import * as $OpenApi from "@alicloud/openapi-client";
2195
2195
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2196
2196
 
@@ -2304,7 +2304,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2304
2304
  }
2305
2305
 
2306
2306
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2307
- `}function hi(){return`// @ts-expect-error \u2014 yunpian-nodejs-sdk ships no type declarations
2307
+ `}function vi(){return`// @ts-expect-error \u2014 yunpian-nodejs-sdk ships no type declarations
2308
2308
  import Yunpian from "yunpian-nodejs-sdk";
2309
2309
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2310
2310
 
@@ -2356,13 +2356,13 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2356
2356
  }
2357
2357
 
2358
2358
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2359
- `}function vi(e){switch(e){case"twilio":return gi();case"messagebird":return fi();case"plivo":return yi();case"aliyun-sms":return Si();case"tencent-sms":return Ei();case"yunpian":return hi();case"none":return`export {};
2360
- `}}function _i(e){let t={};for(let n of e.pkgs??[]){let r=li[n];r&&(t[n]=r)}let o={name:pi,version:"0.1.0",private:!0,description:`Transactional SMS via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2361
- `}async function Po(e,t,o="global"){if(t==="none")return;let n=_o(t);if(!n)throw new Error(`Unknown SMS provider "${t}". Valid ids: ${xt.map(a=>a.id).join(", ")}`);let r=Ie.join(e,"packages","sms");if(!de.existsSync(r))return;let s=Ie.join(r,"src");de.existsSync(s)&&de.rmSync(s,{recursive:!0,force:!0});try{Xt(Ie.join(r,"package.json"),_i(n)),Xt(Ie.join(s,"types.ts"),mi),Xt(Ie.join(s,"index.ts"),vi(n.id)),di(e,ui(n))}catch(a){throw console.error(`Failed to apply SMS selection "${t}":`,a),new Error(`SMS scaffold for "${t}" failed \u2014 see stderr for details.`)}}import Ae from"fs";import Ce from"path";var kt=[{id:"r2",name:"Cloudflare R2",region:"global",envVars:["R2_ACCOUNT_ID","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","R2_BUCKET"],docs:"https://developers.cloudflare.com/r2/api/s3/api/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"s3",name:"AWS S3",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_S3_REGION","S3_BUCKET"],docs:"https://docs.aws.amazon.com/s3/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"supabase-storage",name:"Supabase Storage",region:"global",envVars:["SUPABASE_URL","SUPABASE_SERVICE_ROLE_KEY","SUPABASE_BUCKET"],docs:"https://supabase.com/docs/guides/storage",pkg:"@supabase/supabase-js",pkgVersion:"^2.45.4"},{id:"aliyun-oss",name:"\u963F\u91CC\u4E91 OSS",region:"cn",envVars:["ALIYUN_OSS_ACCESS_KEY","ALIYUN_OSS_ACCESS_SECRET","ALIYUN_OSS_REGION","ALIYUN_OSS_BUCKET"],docs:"https://help.aliyun.com/product/31815.html",pkg:"ali-oss",pkgVersion:"^6.21.0"},{id:"tencent-cos",name:"\u817E\u8BAF\u4E91 COS",region:"cn",envVars:["TENCENT_COS_SECRET_ID","TENCENT_COS_SECRET_KEY","TENCENT_COS_BUCKET","TENCENT_COS_REGION"],docs:"https://cloud.tencent.com/document/product/436",pkg:"cos-nodejs-sdk-v5",pkgVersion:"^2.13.7"},{id:"qiniu",name:"\u4E03\u725B\u4E91 Kodo",region:"cn",envVars:["QINIU_ACCESS_KEY","QINIU_SECRET_KEY","QINIU_BUCKET","QINIU_DOMAIN"],docs:"https://developer.qiniu.com/kodo",pkg:"qiniu",pkgVersion:"^7.14.0"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function bo(e){return kt.find(t=>t.id===e)}var Ip=kt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var we="@nebutra/storage";function zt(e,t){Ae.mkdirSync(Ce.dirname(e),{recursive:!0}),Ae.writeFileSync(e,t)}function Pi(e,t){let o=Ce.join(e,".env.example");Ae.existsSync(o)?Ae.appendFileSync(o,`
2362
- `+t):Ae.writeFileSync(o,t)}function bi(e){if(e.envVars.length===0)return"";let t=`# Storage provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2359
+ `}function _i(e){switch(e){case"twilio":return fi();case"messagebird":return yi();case"plivo":return Si();case"aliyun-sms":return hi();case"tencent-sms":return Ei();case"yunpian":return vi();case"none":return`export {};
2360
+ `}}function Pi(e){let t={};for(let n of e.pkgs??[]){let r=di[n];r&&(t[n]=r)}let o={name:li,version:"0.1.0",private:!0,description:`Transactional SMS via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2361
+ `}async function Io(e,t,o="global"){if(t==="none")return;let n=bo(t);if(!n)throw new Error(`Unknown SMS provider "${t}". Valid ids: ${xt.map(a=>a.id).join(", ")}`);let r=Ie.join(e,"packages","sms");if(!de.existsSync(r))return;let s=Ie.join(r,"src");de.existsSync(s)&&de.rmSync(s,{recursive:!0,force:!0});try{Xt(Ie.join(r,"package.json"),Pi(n)),Xt(Ie.join(s,"types.ts"),gi),Xt(Ie.join(s,"index.ts"),_i(n.id)),ui(e,mi(n))}catch(a){throw console.error(`Failed to apply SMS selection "${t}":`,a),new Error(`SMS scaffold for "${t}" failed \u2014 see stderr for details.`)}}import Ae from"fs";import Ce from"path";var kt=[{id:"r2",name:"Cloudflare R2",region:"global",envVars:["R2_ACCOUNT_ID","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","R2_BUCKET"],docs:"https://developers.cloudflare.com/r2/api/s3/api/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"s3",name:"AWS S3",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_S3_REGION","S3_BUCKET"],docs:"https://docs.aws.amazon.com/s3/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"supabase-storage",name:"Supabase Storage",region:"global",envVars:["SUPABASE_URL","SUPABASE_SERVICE_ROLE_KEY","SUPABASE_BUCKET"],docs:"https://supabase.com/docs/guides/storage",pkg:"@supabase/supabase-js",pkgVersion:"^2.45.4"},{id:"aliyun-oss",name:"\u963F\u91CC\u4E91 OSS",region:"cn",envVars:["ALIYUN_OSS_ACCESS_KEY","ALIYUN_OSS_ACCESS_SECRET","ALIYUN_OSS_REGION","ALIYUN_OSS_BUCKET"],docs:"https://help.aliyun.com/product/31815.html",pkg:"ali-oss",pkgVersion:"^6.21.0"},{id:"tencent-cos",name:"\u817E\u8BAF\u4E91 COS",region:"cn",envVars:["TENCENT_COS_SECRET_ID","TENCENT_COS_SECRET_KEY","TENCENT_COS_BUCKET","TENCENT_COS_REGION"],docs:"https://cloud.tencent.com/document/product/436",pkg:"cos-nodejs-sdk-v5",pkgVersion:"^2.13.7"},{id:"qiniu",name:"\u4E03\u725B\u4E91 Kodo",region:"cn",envVars:["QINIU_ACCESS_KEY","QINIU_SECRET_KEY","QINIU_BUCKET","QINIU_DOMAIN"],docs:"https://developer.qiniu.com/kodo",pkg:"qiniu",pkgVersion:"^7.14.0"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function Co(e){return kt.find(t=>t.id===e)}var Cp=kt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var we="@nebutra/storage";function zt(e,t){Ae.mkdirSync(Ce.dirname(e),{recursive:!0}),Ae.writeFileSync(e,t)}function bi(e,t){let o=Ce.join(e,".env.example");Ae.existsSync(o)?Ae.appendFileSync(o,`
2362
+ `+t):Ae.writeFileSync(o,t)}function Ii(e){if(e.envVars.length===0)return"";let t=`# Storage provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2363
2363
  `);return`${t}
2364
2364
  ${o}
2365
- `}var Ii=`/**
2365
+ `}var Ci=`/**
2366
2366
  * Inputs for the \`uploadFile\` wrapper. Keep this surface portable across
2367
2367
  * providers \u2014 provider-specific options belong in the wrapper itself.
2368
2368
  */
@@ -2388,7 +2388,7 @@ export interface SignedUrlOptions {
2388
2388
  operation?: "get" | "put";
2389
2389
  contentType?: string;
2390
2390
  }
2391
- `;function Ci(){return`/**
2391
+ `;function Ai(){return`/**
2392
2392
  * @${we.slice(1)} \u2014 Cloudflare R2 via the S3-compatible API.
2393
2393
  *
2394
2394
  * Docs: https://developers.cloudflare.com/r2/api/s3/api/
@@ -2452,7 +2452,7 @@ export async function getSignedUrl(
2452
2452
  }
2453
2453
 
2454
2454
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2455
- `}function Ai(){return`/**
2455
+ `}function wi(){return`/**
2456
2456
  * @${we.slice(1)} \u2014 AWS S3 wrapper.
2457
2457
  *
2458
2458
  * Docs: https://docs.aws.amazon.com/s3/
@@ -2517,7 +2517,7 @@ export async function getSignedUrl(
2517
2517
  }
2518
2518
 
2519
2519
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2520
- `}function wi(){return`/**
2520
+ `}function Ri(){return`/**
2521
2521
  * @${we.slice(1)} \u2014 Supabase Storage wrapper.
2522
2522
  *
2523
2523
  * Docs: https://supabase.com/docs/guides/storage
@@ -2580,7 +2580,7 @@ export async function getSignedUrl(
2580
2580
  }
2581
2581
 
2582
2582
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2583
- `}function Ri(){return`/**
2583
+ `}function Ni(){return`/**
2584
2584
  * @${we.slice(1)} \u2014 \u963F\u91CC\u4E91 OSS wrapper via ali-oss.
2585
2585
  *
2586
2586
  * Docs: https://help.aliyun.com/product/31815.html
@@ -2627,7 +2627,7 @@ export async function getSignedUrl(
2627
2627
  }
2628
2628
 
2629
2629
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2630
- `}function Ni(){return`/**
2630
+ `}function xi(){return`/**
2631
2631
  * @${we.slice(1)} \u2014 \u817E\u8BAF\u4E91 COS wrapper via cos-nodejs-sdk-v5.
2632
2632
  *
2633
2633
  * Docs: https://cloud.tencent.com/document/product/436
@@ -2682,7 +2682,7 @@ export async function getSignedUrl(
2682
2682
  }
2683
2683
 
2684
2684
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2685
- `}function xi(){return`/**
2685
+ `}function ki(){return`/**
2686
2686
  * @${we.slice(1)} \u2014 \u4E03\u725B\u4E91 Kodo wrapper.
2687
2687
  *
2688
2688
  * Docs: https://developer.qiniu.com/kodo
@@ -2750,9 +2750,9 @@ export async function getSignedUrl(
2750
2750
  }
2751
2751
 
2752
2752
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2753
- `}function ki(e){switch(e){case"r2":return Ci();case"s3":return Ai();case"supabase-storage":return wi();case"aliyun-oss":return Ri();case"tencent-cos":return Ni();case"qiniu":return xi();case"none":return`export {};
2754
- `}}function Ti(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),(e.id==="r2"||e.id==="s3")&&(t["@aws-sdk/s3-request-presigner"]="^3.658.0");let o={name:we,version:"0.1.0",private:!0,description:`Object storage via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2755
- `}async function Io(e,t,o){if(t==="none")return;let n=bo(t);if(!n)throw new Error(`Unknown storage provider "${t}". Valid ids: ${kt.map(a=>a.id).join(", ")}`);let r=Ce.join(e,"packages","storage"),s=Ce.join(r,"src");Ae.existsSync(s)&&Ae.rmSync(s,{recursive:!0,force:!0}),zt(Ce.join(r,"package.json"),Ti(n)),zt(Ce.join(s,"types.ts"),Ii),zt(Ce.join(s,"index.ts"),ki(n.id)),Pi(e,bi(n))}var Tt=[{id:"svix",name:"Svix",region:"global",envVars:["SVIX_API_TOKEN"],docs:"https://docs.svix.com",description:"Managed webhooks platform"},{id:"custom",name:"Custom (self-hosted)",region:"both",envVars:["WEBHOOK_SIGNING_SECRET"],docs:"",description:"Custom implementation with built-in package"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Co(e){return Tt.find(t=>t.id===e)}var xp=Tt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Ao(e,t,o="global"){let n=Co(t);if(!n)throw new Error(`Unknown webhooks provider "${t}". Valid ids: ${Tt.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"webhooks");return}n.envVars.length>0&&G(e,{category:"Webhooks",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"WEBHOOKS_PROVIDER",n.id)}import Re from"fs";import lt from"path";function Oi(e){return`import Link from "next/link";
2753
+ `}function Ti(e){switch(e){case"r2":return Ai();case"s3":return wi();case"supabase-storage":return Ri();case"aliyun-oss":return Ni();case"tencent-cos":return xi();case"qiniu":return ki();case"none":return`export {};
2754
+ `}}function Oi(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),(e.id==="r2"||e.id==="s3")&&(t["@aws-sdk/s3-request-presigner"]="^3.658.0");let o={name:we,version:"0.1.0",private:!0,description:`Object storage via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2755
+ `}async function Ao(e,t,o){if(t==="none")return;let n=Co(t);if(!n)throw new Error(`Unknown storage provider "${t}". Valid ids: ${kt.map(a=>a.id).join(", ")}`);let r=Ce.join(e,"packages","storage"),s=Ce.join(r,"src");Ae.existsSync(s)&&Ae.rmSync(s,{recursive:!0,force:!0}),zt(Ce.join(r,"package.json"),Oi(n)),zt(Ce.join(s,"types.ts"),Ci),zt(Ce.join(s,"index.ts"),Ti(n.id)),bi(e,Ii(n))}var Tt=[{id:"svix",name:"Svix",region:"global",envVars:["SVIX_API_TOKEN"],docs:"https://docs.svix.com",description:"Managed webhooks platform"},{id:"custom",name:"Custom (self-hosted)",region:"both",envVars:["WEBHOOK_SIGNING_SECRET"],docs:"",description:"Custom implementation with built-in package"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function wo(e){return Tt.find(t=>t.id===e)}var kp=Tt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Ro(e,t,o="global"){let n=wo(t);if(!n)throw new Error(`Unknown webhooks provider "${t}". Valid ids: ${Tt.map(r=>r.id).join(", ")}`);if(n.id==="none"){B(e,"webhooks");return}n.envVars.length>0&&G(e,{category:"Webhooks",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"WEBHOOKS_PROVIDER",n.id)}import Re from"fs";import lt from"path";function Ui(e){return`import Link from "next/link";
2756
2756
 
2757
2757
  export default function WelcomePage() {
2758
2758
  const projectName = ${JSON.stringify(e)};
@@ -2861,7 +2861,7 @@ function Step({
2861
2861
  </li>
2862
2862
  );
2863
2863
  }
2864
- `}function Ui(e,t){return`# Next steps \u2014 ${e}
2864
+ `}function Li(e,t){return`# Next steps \u2014 ${e}
2865
2865
 
2866
2866
  Region: ${t}
2867
2867
 
@@ -2893,26 +2893,26 @@ After setup, delete the welcome route at \`apps/web/src/app/[locale]/welcome/\`.
2893
2893
  - [Documentation](/docs)
2894
2894
  - [GitHub](https://github.com/nebutra/nebutra-sailor)
2895
2895
  - [Get free license (Individual/OPC)](https://nebutra.com/get-license)
2896
- `}async function wo(e,t){let{projectName:o,region:n}=t;try{let r=lt.join(e,".sailor");Re.existsSync(r)||Re.mkdirSync(r,{recursive:!0}),Re.writeFileSync(lt.join(r,"next-steps.md"),Ui(o,n))}catch(r){let s=r instanceof Error?r.message:String(r);console.warn(`[create-sailor] Failed to write .sailor/next-steps.md: ${s}`)}try{let r=lt.join(e,"apps","web");if(!Re.existsSync(r))return;let s=lt.join(r,"src","app","[locale]","welcome");Re.existsSync(s)||Re.mkdirSync(s,{recursive:!0}),Re.writeFileSync(lt.join(s,"page.tsx"),Oi(o))}catch(r){let s=r instanceof Error?r.message:String(r);console.warn(`[create-sailor] Failed to write welcome page: ${s}`)}}var Ro="create-sailor";function p(e,t){e&&process.stdout.write(JSON.stringify(t)+`
2897
- `)}function Di(){let e=process.env.npm_config_user_agent??"";return e.startsWith("pnpm")?"pnpm":e.startsWith("yarn")?"yarn":e.startsWith("bun")?"bun":"npm"}function No(e){switch(e){case"postgres":case"postgresql":return"postgresql";case"mysql":return"mysql";case"sqlite":return"sqlite";case"none":return"none";default:return"postgresql"}}function xo(e){return e==="drizzle"?"drizzle":e==="none"?"none":"prisma"}function ko(e){return e==="lemon"||e==="lemonsqueezy"?"lemonsqueezy":e==="none"?"none":"stripe"}function To(e){if(!e)return"stripe";let t=e.toLowerCase();return t==="lemon"||t==="lemonsqueezy"?"lemon":t==="wechat"?"wechat":t==="alipay"?"alipay":t==="none"?"none":"stripe"}function Oo(e){if(!e)return"clerk";let t=e.toLowerCase();return t==="betterauth"||t==="better-auth"?"betterauth":t==="none"?"none":"clerk"}function Uo(e){if(!e)return["openai"];let t=e.split(",").map(o=>o.trim().toLowerCase());return t.includes("none")?[]:t}var Lo={mintlify:"Mintlify",docusaurus:"Docusaurus",nextra:"Nextra",vitepress:"VitePress"};function Mo(e,t){if(!e)return"fumadocs";let o=e.toLowerCase();if(o==="fumadocs"||o==="none")return o;if(o in Lo){let n=Lo[o];return t?p(!0,{event:"notice",kind:"docs-fallback",requested:o,effective:"fumadocs"}):process.stdout.write(R.yellow(`\u26A0 ${n} support is coming in v1.2. Falling back to fumadocs.
2896
+ `}async function No(e,t){let{projectName:o,region:n}=t;try{let r=lt.join(e,".sailor");Re.existsSync(r)||Re.mkdirSync(r,{recursive:!0}),Re.writeFileSync(lt.join(r,"next-steps.md"),Li(o,n))}catch(r){let s=r instanceof Error?r.message:String(r);console.warn(`[create-sailor] Failed to write .sailor/next-steps.md: ${s}`)}try{let r=lt.join(e,"apps","web");if(!Re.existsSync(r))return;let s=lt.join(r,"src","app","[locale]","welcome");Re.existsSync(s)||Re.mkdirSync(s,{recursive:!0}),Re.writeFileSync(lt.join(s,"page.tsx"),Ui(o))}catch(r){let s=r instanceof Error?r.message:String(r);console.warn(`[create-sailor] Failed to write welcome page: ${s}`)}}var xo="create-sailor";function p(e,t){e&&process.stdout.write(JSON.stringify(t)+`
2897
+ `)}function Fi(){let e=process.env.npm_config_user_agent??"";return e.startsWith("pnpm")?"pnpm":e.startsWith("yarn")?"yarn":e.startsWith("bun")?"bun":"npm"}function ko(e){switch(e){case"postgres":case"postgresql":return"postgresql";case"mysql":return"mysql";case"sqlite":return"sqlite";case"none":return"none";default:return"postgresql"}}function To(e){return e==="drizzle"?"drizzle":e==="none"?"none":"prisma"}function Oo(e){return e==="lemon"||e==="lemonsqueezy"?"lemonsqueezy":e==="none"?"none":"stripe"}function Uo(e){if(!e)return"stripe";let t=e.toLowerCase();return t==="lemon"||t==="lemonsqueezy"?"lemon":t==="wechat"?"wechat":t==="alipay"?"alipay":t==="none"?"none":"stripe"}function Lo(e){if(!e)return"clerk";let t=e.toLowerCase();return t==="betterauth"||t==="better-auth"?"betterauth":t==="none"?"none":"clerk"}function Mo(e){if(!e)return["openai"];let t=e.split(",").map(o=>o.trim().toLowerCase());return t.includes("none")?[]:t}var Do={mintlify:"Mintlify",docusaurus:"Docusaurus",nextra:"Nextra",vitepress:"VitePress"};function Fo(e,t){if(!e)return"fumadocs";let o=e.toLowerCase();if(o==="fumadocs"||o==="none")return o;if(o in Do){let n=Do[o];return t?p(!0,{event:"notice",kind:"docs-fallback",requested:o,effective:"fumadocs"}):process.stdout.write(R.yellow(`\u26A0 ${n} support is coming in v1.2. Falling back to fumadocs.
2898
2898
  `)+R.dim(` Track progress: https://github.com/Nebutra/Nebutra-Sailor/issues
2899
- `)),"fumadocs"}return"fumadocs"}function Do(e){switch(e){case"vercel":return"vercel";case"railway":return"railway";case"cloudflare":return"cloudflare";case"selfhost":return"selfhost";case"none":return"none";default:return"vercel"}}function Fo(e){if(!e)return"global";let t=e.toLowerCase();return t==="cn"?"cn":t==="hybrid"?"hybrid":"global"}function Fi(e){return{...e==="cn"?{email:"aliyun-dm",storage:"aliyun-oss",monitoring:"sentry",analytics:"baidu",sms:"aliyun-sms"}:e==="hybrid"?{email:"resend",storage:"aliyun-oss",monitoring:"sentry",analytics:"posthog",sms:"aliyun-sms"}:{email:"resend",storage:"r2",monitoring:"sentry",analytics:"posthog",sms:"twilio"},queue:"none",search:"none",cache:e==="global"?"upstash-redis":e==="cn"?"redis":"upstash-redis",notifications:"none",webhooks:"none",cms:"none",featureFlags:"none",captcha:e==="cn"?"aliyun-slide":"turnstile",mcp:"on",metering:"auto",billingMode:"usage",idp:"clerk"}}function jo(e){return e==="cn"?"wechat":"stripe"}async function ji(){let e=new Li;e.name(Ro).description("Nebutra-Sailor \u2014 AI-Native SaaS template").version(ne,"-v, --version").helpOption(!1).argument("[name]","project directory",void 0).option("-p, --pm <id>","npm | pnpm | yarn | bun").option("--region <id>","global | cn | hybrid").option("--orm <id>","prisma | drizzle | none").option("--db <id>","postgres | mysql | sqlite | none").option("--auth <id>","clerk | betterauth | none").option("--social-login <ids>","CN social login providers \u2014 wechat | qq | dingtalk | workweixin | feishu | weibo (comma-separated)").option("--payment <id>","stripe | lemon | wechat | alipay | none").option("--ai <ids>","comma-separated provider ids").option("--deploy <target>","vercel | railway | cloudflare | selfhost").option("--docs <id>","fumadocs | mintlify | docusaurus | nextra | vitepress | none").option("--email <id>","resend | postmark | ses | aliyun-dm | tencent-ses | netease | none").option("--storage <id>","r2 | s3 | supabase | aliyun-oss | tencent-cos | qiniu | none").option("--monitoring <id>","sentry | datadog | aliyun-arms | tingyun | none").option("--analytics <id>","posthog | plausible | umami | baidu | sensors | none").option("--sms <id>","twilio | aliyun-sms | tencent-sms | yunpian | none").option("--queue <id>","qstash | bullmq | upstash | sqs | none").option("--search <id>","meilisearch | typesense | algolia | pgvector | none").option("--cache <id>","upstash-redis | vercel-kv | redis | dragonfly | none").option("--notifications <id>","novu | knock | custom | none").option("--webhooks <id>","svix | custom | none").option("--cms <id>","sanity | contentful | strapi | none").option("--feature-flags <id>","vercel-flags | growthbook | configcat | none").option("--captcha <id>","turnstile | hcaptcha | aliyun-slide | none").option("--mcp <mode>","on | off (default: on)").option("--metering <mode>","auto | on | off (default: auto \u2014 auto-on when payment is set)").option("--billing-mode <mode>","usage | seat | credits (default: usage)").option("--idp <id>","clerk | oauth-server (default: clerk)").option("--i18n","enable i18n").option("--no-i18n","disable i18n").option("--no-install","skip package install").option("--no-git","skip git init").option("-y, --yes","accept all defaults (non-interactive)").option("--dry-run","preview actions without writing files").option("--json","machine-readable output").option("--no-color","disable color output").option("-h, --help","show help"),e.parse(process.argv);let t=e.opts(),[o]=e.args;t.help&&(on(),process.exit(0));let n=!!t.json,r=!!t.dryRun,s=!!t.yes,a=s||!process.stdin.isTTY;n||en(),p(n,{event:"start",version:ne});let c=o??(s?"./my-saas-app":void 0),i;if(c)i=c;else if(a)i="./my-saas-app";else{let m=await C.group({name:()=>C.text({message:"Where should we create your project?",placeholder:"./my-saas-app",defaultValue:"./my-saas-app",validate:y=>{if(y.length===0)return"Please enter a path."}})},{onCancel:()=>{process.stdout.write(R.red(`\u2718 Cancelled
2900
- `)),process.exit(130)}});i=String(m.name)}let d=dt.basename(dt.resolve(i)),u=t.pm??Di(),S=!!t.region,U=!!t.auth,F=!!t.payment,ee=!!t.ai,Xe=!!t.email,E=!!t.storage,l=!!t.monitoring,N=!!t.analytics,ut=!!t.sms,Qt=t.i18n!==void 0,f,ze,z,Qe,j,k,$=fn(t.socialLogin),te,Ne,Q,V,mt;if(a){f=Fo(t.region),ze=xo(t.orm),z=No(t.db);let m=F?t.payment:jo(f);Qe=ko(m),j=To(m),k=Oo(t.auth),te=Uo(t.ai),Q=Do(t.deploy),V=Mo(t.docs,n),mt=Qt?!!t.i18n:!0}else{let m={};if(S||(m.region=()=>C.select({message:"Target region?",options:[{value:"global",label:"global \u2014 \u6D77\u5916\u4F18\u5148"},{value:"cn",label:"cn \u2014 \u56FD\u5185\u4F18\u5148"},{value:"hybrid",label:"hybrid \u2014 \u53CC\u8F68\uFF08\u56FD\u5185+\u51FA\u6D77\uFF09"}],initialValue:"global"})),U||(m.auth=()=>C.select({message:"Auth provider?",options:[{value:"clerk",label:"Clerk"},{value:"betterauth",label:"Better Auth"},{value:"none",label:"None"}],initialValue:"clerk"})),!ee){let yt=Array.from(new Set(ht.map(w=>w.category)));m.aiCategories=()=>C.multiselect({message:"Which AI Provider categories do you want to explore? (Select multiple)",options:yt.map(w=>({value:w,label:w})),initialValues:["\u76F4\u63A5\u5B9E\u9A8C\u5BA4","\u7EDF\u4E00\u7F51\u5173"]}),m.aiProviders=({results:w})=>{let $e=w.aiCategories||[],_=ht.filter(K=>$e.includes(K.category)).map(K=>({value:K.id,label:`[${K.category}] ${K.name}`}));return _.push({value:"custom",label:"[\u81EA\u5B9A\u4E49] Custom OpenAI-compatible endpoint"}),C.multiselect({message:"Select AI Providers (Space to select, Enter to submit)",options:_,initialValues:["openai","anthropic"],required:!1})},m.enableCustom=({results:w})=>w.aiProviders?.includes("custom")?C.confirm({message:"Configure custom OpenAI-compatible endpoint?",initialValue:!0}):Promise.resolve(!1),m.customAiName=({results:w})=>w.enableCustom?C.text({message:"Custom endpoint name (e.g. proxy, local):",defaultValue:"custom",placeholder:"custom"}):Promise.resolve(void 0),m.customAiBaseUrl=({results:w})=>w.enableCustom?C.text({message:"Custom endpoint base URL (e.g. https://api.proxy.com/v1):",validate:$e=>{if($e.length===0)return"Base URL is required."}}):Promise.resolve(void 0),m.customAiApiKeyEnv=({results:w})=>w.enableCustom?C.text({message:"Environment variable name for the API Key:",defaultValue:"CUSTOM_AI_API_KEY",placeholder:"CUSTOM_AI_API_KEY"}):Promise.resolve(void 0)}let y=Object.keys(m).length>0?await C.group(m,{onCancel:()=>{process.stdout.write(R.red(`\u2718 Cancelled
2901
- `)),process.exit(130)}}):{};f=Fo(S?t.region:y.region),ze=xo(t.orm),z=No(t.db);let L=F?t.payment:jo(f);Qe=ko(L),j=To(L),k=Oo(U?t.auth:y.auth),te=ee?Uo(t.ai):y.aiProviders?.filter(yt=>yt!=="custom")??[],y.enableCustom&&(Ne={name:y.customAiName,baseURL:y.customAiBaseUrl,apiKeyEnvName:y.customAiApiKeyEnv}),Q=Do(t.deploy),V=Mo(t.docs,n),mt=Qt?!!t.i18n:!0}let P=Fi(f),xe=Xe?t.email:P.email,ke=E?t.storage:P.storage,Te=l?t.monitoring:P.monitoring,Oe=N?t.analytics:P.analytics,Ue=ut?t.sms:P.sms,Le=t.queue??P.queue,Me=t.search??P.search,Je=t.cache??P.cache,De=t.notifications??P.notifications,Fe=t.webhooks??P.webhooks,Ze=t.cms??P.cms,je=t.featureFlags??P.featureFlags,Ve=t.captcha??P.captcha,gt=t.mcp??P.mcp,et=t.metering??P.metering,Ke=t.billingMode??P.billingMode,Be=t.idp??P.idp,tt=tn([{flag:"queue",provider:Le},{flag:"search",provider:Me},{flag:"notifications",provider:De},{flag:"webhooks",provider:Fe},{flag:"feature-flags",provider:je},{flag:"captcha",provider:Ve}]);function Ut(){for(let m of tt)if(n)p(!0,{event:"warn",step:m.flag,provider:m.provider,packageStatus:m.status,message:qe(m.status)});else{let y=St(m.status);process.stdout.write(R.yellow(`\u26A0 ${m.flag}=${m.provider} ${y} \u2014 ${qe(m.status)}
2902
- `))}}let Ye={region:f,orm:ze,database:z,payment:Qe,aiProviders:te,customAiEndpoint:Ne,deployTarget:Q,docs:V,i18n:mt,email:xe,storage:ke,monitoring:Te,analytics:Oe,sms:Ue,queue:Le,search:Me,cache:Je,notifications:De,webhooks:Fe,cms:Ze,featureFlags:je,captcha:Ve,mcp:gt,metering:et,billingMode:Ke,idp:Be},ft=[["Project name",d],["Region",f],["Auth",k],["Social login",$.length>0?$.map(m=>nt.find(y=>y.id===m)?.name??m).join(", "):"none"],["ORM",ze],["Database",z],["Payment",j],["AI",Array.isArray(te)?te.join(", ")+(Ne?", custom":""):String(te)],["Email",xe],["Storage",ke],["Monitoring",Te],["Analytics",Oe],["SMS",Ue],["Deploy Target",Q],["Docs Framework",V]];n?ft.forEach(([m,y],L)=>{p(!0,{event:"step",step:m,value:y,index:L+1,total:ft.length})}):ft.forEach(([m,y],L)=>{sn({index:L+1,total:ft.length,label:m,value:y})});let Vo={databaseUrl:"postgresql://postgres:postgres@localhost:5432/nebutra",clerkPublishable:"",clerkSecret:""},Jt=Date.now();if(r){let m=te.length,y=[`clone template \u2192 ${i}`,"write nebutra.config.json",`prune template (orm=${ze}, i18n=${mt})`,`region \u2192 ${f}`,`auth \u2192 ${k==="none"?"skip (remove packages/auth)":`configure ${k}`}`,...$.length>0?[`social-login \u2192 generate ${$.length} callback route${$.length===1?"":"s"} + SocialLoginButtons.tsx (${$.join(", ")})`]:[],`db \u2192 ${z==="none"?"skip (remove packages/db)":`configure Prisma for ${z}`}`,`payment \u2192 ${j==="none"?"skip (remove packages/billing)":`configure ${j}`}`,...V!=="none"?[`docs \u2192 scaffold apps/docs (${V==="fumadocs"?"fumadocs":`${V} \u2192 fumadocs fallback`})`]:[],...m>0||Ne?[`ai-providers \u2192 generate registry.ts + env (${m}${Ne?" + custom":""} provider${m===1&&!Ne?"":"s"})`]:[],...xe!=="none"?[`email \u2192 configure ${xe}`]:[],...ke!=="none"?[`storage \u2192 configure ${ke}`]:[],...Te!=="none"?[`monitoring \u2192 configure ${Te}`]:[],...Oe!=="none"?[`analytics \u2192 configure ${Oe}`]:[],...Ue!=="none"?[`sms \u2192 configure ${Ue}`]:[],...Le!=="none"?[`queue \u2192 configure ${Le}`]:[],...Me!=="none"?[`search \u2192 configure ${Me}`]:[],...Je!=="none"?[`cache \u2192 configure ${Je}`]:[],...De!=="none"?[`notifications \u2192 configure ${De}`]:[],...Fe!=="none"?[`webhooks \u2192 configure ${Fe}`]:[],...Ze!=="none"?[`cms \u2192 configure ${Ze}`]:[],...je!=="none"?[`feature-flags \u2192 configure ${je}`]:[],...Ve!=="none"?[`captcha \u2192 configure ${Ve}`]:[],`mcp \u2192 ${gt==="on"?"enable MCP server":"remove packages/mcp"}`,`metering \u2192 ${et==="off"?"disabled":et==="auto"?Qe!=="none"?"enabled (auto: payment set)":"disabled (auto: no payment)":"enabled"}`,...Ke!=="usage"?[`billing-mode \u2192 ${Ke}`]:[],...Be!=="clerk"?[`idp \u2192 ${Be}`]:[],`compliance \u2192 inject ${f} boilerplate (ICP/Cookie/AIGC/Privacy)`,"welcome \u2192 generate dev welcome page","env \u2192 generate random secrets (AUTH_SECRET, JWT_SECRET)","seed \u2192 generate prisma/seed.ts (1 admin + 3 tenants)",...Q!=="none"?[`deploy \u2192 inject ${Q} config`]:[],"inject .env.local",t.install===!1?"skip install":`run ${u} install`,t.git===!1?"skip git init":"run git init"];if(n)y.forEach(L=>p(!0,{event:"plan",action:L})),Ut(),p(!0,{event:"done",dryRun:!0});else{process.stdout.write(`
2899
+ `)),"fumadocs"}return"fumadocs"}function jo(e){switch(e){case"vercel":return"vercel";case"railway":return"railway";case"cloudflare":return"cloudflare";case"selfhost":return"selfhost";case"none":return"none";default:return"vercel"}}function Vo(e){if(!e)return"global";let t=e.toLowerCase();return t==="cn"?"cn":t==="hybrid"?"hybrid":"global"}function ji(e){return{...e==="cn"?{email:"aliyun-dm",storage:"aliyun-oss",monitoring:"sentry",analytics:"baidu",sms:"aliyun-sms"}:e==="hybrid"?{email:"resend",storage:"aliyun-oss",monitoring:"sentry",analytics:"posthog",sms:"aliyun-sms"}:{email:"resend",storage:"r2",monitoring:"sentry",analytics:"posthog",sms:"twilio"},queue:"none",search:"none",cache:e==="global"?"upstash-redis":e==="cn"?"redis":"upstash-redis",notifications:"none",webhooks:"none",cms:"none",featureFlags:"none",captcha:e==="cn"?"aliyun-slide":"turnstile",mcp:"on",metering:"auto",billingMode:"usage",idp:"clerk"}}function Ko(e){return e==="cn"?"wechat":"stripe"}async function Vi(){let e=new Mi;e.name(xo).description("Nebutra-Sailor \u2014 AI-Native SaaS template").version(ne,"-v, --version").helpOption(!1).argument("[name]","project directory",void 0).option("-p, --pm <id>","npm | pnpm | yarn | bun").option("--region <id>","global | cn | hybrid").option("--orm <id>","prisma | drizzle | none").option("--db <id>","postgres | mysql | sqlite | none").option("--auth <id>","clerk | betterauth | none").option("--social-login <ids>","CN social login providers \u2014 wechat | qq | dingtalk | workweixin | feishu | weibo (comma-separated)").option("--payment <id>","stripe | lemon | wechat | alipay | none").option("--ai <ids>","comma-separated provider ids").option("--deploy <target>","vercel | railway | cloudflare | selfhost").option("--docs <id>","fumadocs | mintlify | docusaurus | nextra | vitepress | none").option("--email <id>","resend | postmark | ses | aliyun-dm | tencent-ses | netease | none").option("--storage <id>","r2 | s3 | supabase | aliyun-oss | tencent-cos | qiniu | none").option("--monitoring <id>","sentry | datadog | aliyun-arms | tingyun | none").option("--analytics <id>","posthog | plausible | umami | baidu | sensors | none").option("--sms <id>","twilio | aliyun-sms | tencent-sms | yunpian | none").option("--queue <id>","qstash | bullmq | upstash | sqs | none").option("--search <id>","meilisearch | typesense | algolia | pgvector | none").option("--cache <id>","upstash-redis | vercel-kv | redis | dragonfly | none").option("--notifications <id>","novu | knock | custom | none").option("--webhooks <id>","svix | custom | none").option("--cms <id>","sanity | contentful | strapi | none").option("--feature-flags <id>","vercel-flags | growthbook | configcat | none").option("--captcha <id>","turnstile | hcaptcha | aliyun-slide | none").option("--mcp <mode>","on | off (default: on)").option("--metering <mode>","auto | on | off (default: auto \u2014 auto-on when payment is set)").option("--billing-mode <mode>","usage | seat | credits (default: usage)").option("--idp <id>","clerk | oauth-server (default: clerk)").option("--i18n","enable i18n").option("--no-i18n","disable i18n").option("--no-install","skip package install").option("--no-git","skip git init").option("-y, --yes","accept all defaults (non-interactive)").option("--dry-run","preview actions without writing files").option("--json","machine-readable output").option("--no-color","disable color output").option("-h, --help","show help"),e.parse(process.argv);let t=e.opts(),[o]=e.args;t.help&&(on(),process.exit(0));let n=!!t.json,r=!!t.dryRun,s=!!t.yes,a=s||!process.stdin.isTTY;n||en(),p(n,{event:"start",version:ne});let c=o??(s?"./my-saas-app":void 0),i;if(c)i=c;else if(a)i="./my-saas-app";else{let m=await C.group({name:()=>C.text({message:"Where should we create your project?",placeholder:"./my-saas-app",defaultValue:"./my-saas-app",validate:y=>{if(y.length===0)return"Please enter a path."}})},{onCancel:()=>{process.stdout.write(R.red(`\u2718 Cancelled
2900
+ `)),process.exit(130)}});i=String(m.name)}let d=dt.basename(dt.resolve(i)),u=t.pm??Fi(),S=!!t.region,U=!!t.auth,F=!!t.payment,ee=!!t.ai,Xe=!!t.email,h=!!t.storage,l=!!t.monitoring,N=!!t.analytics,ut=!!t.sms,Qt=t.i18n!==void 0,f,ze,z,Qe,j,k,$=fn(t.socialLogin),te,Ne,Q,V,mt;if(a){f=Vo(t.region),ze=To(t.orm),z=ko(t.db);let m=F?t.payment:Ko(f);Qe=Oo(m),j=Uo(m),k=Lo(t.auth),te=Mo(t.ai),Q=jo(t.deploy),V=Fo(t.docs,n),mt=Qt?!!t.i18n:!0}else{let m={};if(S||(m.region=()=>C.select({message:"Target region?",options:[{value:"global",label:"global \u2014 \u6D77\u5916\u4F18\u5148"},{value:"cn",label:"cn \u2014 \u56FD\u5185\u4F18\u5148"},{value:"hybrid",label:"hybrid \u2014 \u53CC\u8F68\uFF08\u56FD\u5185+\u51FA\u6D77\uFF09"}],initialValue:"global"})),U||(m.auth=()=>C.select({message:"Auth provider?",options:[{value:"clerk",label:"Clerk"},{value:"betterauth",label:"Better Auth"},{value:"none",label:"None"}],initialValue:"clerk"})),!ee){let yt=Array.from(new Set(Et.map(w=>w.category)));m.aiCategories=()=>C.multiselect({message:"Which AI Provider categories do you want to explore? (Select multiple)",options:yt.map(w=>({value:w,label:w})),initialValues:["\u76F4\u63A5\u5B9E\u9A8C\u5BA4","\u7EDF\u4E00\u7F51\u5173"]}),m.aiProviders=({results:w})=>{let $e=w.aiCategories||[],_=Et.filter(K=>$e.includes(K.category)).map(K=>({value:K.id,label:`[${K.category}] ${K.name}`}));return _.push({value:"custom",label:"[\u81EA\u5B9A\u4E49] Custom OpenAI-compatible endpoint"}),C.multiselect({message:"Select AI Providers (Space to select, Enter to submit)",options:_,initialValues:["openai","anthropic"],required:!1})},m.enableCustom=({results:w})=>w.aiProviders?.includes("custom")?C.confirm({message:"Configure custom OpenAI-compatible endpoint?",initialValue:!0}):Promise.resolve(!1),m.customAiName=({results:w})=>w.enableCustom?C.text({message:"Custom endpoint name (e.g. proxy, local):",defaultValue:"custom",placeholder:"custom"}):Promise.resolve(void 0),m.customAiBaseUrl=({results:w})=>w.enableCustom?C.text({message:"Custom endpoint base URL (e.g. https://api.proxy.com/v1):",validate:$e=>{if($e.length===0)return"Base URL is required."}}):Promise.resolve(void 0),m.customAiApiKeyEnv=({results:w})=>w.enableCustom?C.text({message:"Environment variable name for the API Key:",defaultValue:"CUSTOM_AI_API_KEY",placeholder:"CUSTOM_AI_API_KEY"}):Promise.resolve(void 0)}let y=Object.keys(m).length>0?await C.group(m,{onCancel:()=>{process.stdout.write(R.red(`\u2718 Cancelled
2901
+ `)),process.exit(130)}}):{};f=Vo(S?t.region:y.region),ze=To(t.orm),z=ko(t.db);let L=F?t.payment:Ko(f);Qe=Oo(L),j=Uo(L),k=Lo(U?t.auth:y.auth),te=ee?Mo(t.ai):y.aiProviders?.filter(yt=>yt!=="custom")??[],y.enableCustom&&(Ne={name:y.customAiName,baseURL:y.customAiBaseUrl,apiKeyEnvName:y.customAiApiKeyEnv}),Q=jo(t.deploy),V=Fo(t.docs,n),mt=Qt?!!t.i18n:!0}let P=ji(f),xe=Xe?t.email:P.email,ke=h?t.storage:P.storage,Te=l?t.monitoring:P.monitoring,Oe=N?t.analytics:P.analytics,Ue=ut?t.sms:P.sms,Le=t.queue??P.queue,Me=t.search??P.search,Je=t.cache??P.cache,De=t.notifications??P.notifications,Fe=t.webhooks??P.webhooks,Ze=t.cms??P.cms,je=t.featureFlags??P.featureFlags,Ve=t.captcha??P.captcha,gt=t.mcp??P.mcp,et=t.metering??P.metering,Ke=t.billingMode??P.billingMode,Be=t.idp??P.idp,tt=tn([{flag:"queue",provider:Le},{flag:"search",provider:Me},{flag:"notifications",provider:De},{flag:"webhooks",provider:Fe},{flag:"feature-flags",provider:je},{flag:"captcha",provider:Ve}]);function Ut(){for(let m of tt)if(n)p(!0,{event:"warn",step:m.flag,provider:m.provider,packageStatus:m.status,message:qe(m.status)});else{let y=St(m.status);process.stdout.write(R.yellow(`\u26A0 ${m.flag}=${m.provider} ${y} \u2014 ${qe(m.status)}
2902
+ `))}}let Ye={region:f,orm:ze,database:z,payment:Qe,aiProviders:te,customAiEndpoint:Ne,deployTarget:Q,docs:V,i18n:mt,email:xe,storage:ke,monitoring:Te,analytics:Oe,sms:Ue,queue:Le,search:Me,cache:Je,notifications:De,webhooks:Fe,cms:Ze,featureFlags:je,captcha:Ve,mcp:gt,metering:et,billingMode:Ke,idp:Be},ft=[["Project name",d],["Region",f],["Auth",k],["Social login",$.length>0?$.map(m=>nt.find(y=>y.id===m)?.name??m).join(", "):"none"],["ORM",ze],["Database",z],["Payment",j],["AI",Array.isArray(te)?te.join(", ")+(Ne?", custom":""):String(te)],["Email",xe],["Storage",ke],["Monitoring",Te],["Analytics",Oe],["SMS",Ue],["Deploy Target",Q],["Docs Framework",V]];n?ft.forEach(([m,y],L)=>{p(!0,{event:"step",step:m,value:y,index:L+1,total:ft.length})}):ft.forEach(([m,y],L)=>{sn({index:L+1,total:ft.length,label:m,value:y})});let Bo={databaseUrl:"postgresql://postgres:postgres@localhost:5432/nebutra",clerkPublishable:"",clerkSecret:""},Jt=Date.now();if(r){let m=te.length,y=[`clone template \u2192 ${i}`,"write nebutra.config.json",`prune template (orm=${ze}, i18n=${mt})`,`region \u2192 ${f}`,`auth \u2192 ${k==="none"?"skip (remove packages/auth)":`configure ${k}`}`,...$.length>0?[`social-login \u2192 generate ${$.length} callback route${$.length===1?"":"s"} + SocialLoginButtons.tsx (${$.join(", ")})`]:[],`db \u2192 ${z==="none"?"skip (remove packages/db)":`configure Prisma for ${z}`}`,`payment \u2192 ${j==="none"?"skip (remove packages/billing)":`configure ${j}`}`,...V!=="none"?[`docs \u2192 scaffold apps/docs (${V==="fumadocs"?"fumadocs":`${V} \u2192 fumadocs fallback`})`]:[],...m>0||Ne?[`ai-providers \u2192 generate registry.ts + env (${m}${Ne?" + custom":""} provider${m===1&&!Ne?"":"s"})`]:[],...xe!=="none"?[`email \u2192 configure ${xe}`]:[],...ke!=="none"?[`storage \u2192 configure ${ke}`]:[],...Te!=="none"?[`monitoring \u2192 configure ${Te}`]:[],...Oe!=="none"?[`analytics \u2192 configure ${Oe}`]:[],...Ue!=="none"?[`sms \u2192 configure ${Ue}`]:[],...Le!=="none"?[`queue \u2192 configure ${Le}`]:[],...Me!=="none"?[`search \u2192 configure ${Me}`]:[],...Je!=="none"?[`cache \u2192 configure ${Je}`]:[],...De!=="none"?[`notifications \u2192 configure ${De}`]:[],...Fe!=="none"?[`webhooks \u2192 configure ${Fe}`]:[],...Ze!=="none"?[`cms \u2192 configure ${Ze}`]:[],...je!=="none"?[`feature-flags \u2192 configure ${je}`]:[],...Ve!=="none"?[`captcha \u2192 configure ${Ve}`]:[],`mcp \u2192 ${gt==="on"?"enable MCP server":"remove packages/mcp"}`,`metering \u2192 ${et==="off"?"disabled":et==="auto"?Qe!=="none"?"enabled (auto: payment set)":"disabled (auto: no payment)":"enabled"}`,...Ke!=="usage"?[`billing-mode \u2192 ${Ke}`]:[],...Be!=="clerk"?[`idp \u2192 ${Be}`]:[],`compliance \u2192 inject ${f} boilerplate (ICP/Cookie/AIGC/Privacy)`,"welcome \u2192 generate dev welcome page","env \u2192 generate random secrets (AUTH_SECRET, JWT_SECRET)","seed \u2192 generate prisma/seed.ts (1 admin + 3 tenants)",...Q!=="none"?[`deploy \u2192 inject ${Q} config`]:[],"inject .env.local",t.install===!1?"skip install":`run ${u} install`,t.git===!1?"skip git init":"run git init"];if(n)y.forEach(L=>p(!0,{event:"plan",action:L})),Ut(),p(!0,{event:"done",dryRun:!0});else{process.stdout.write(`
2903
2903
  `+R.bold(`Dry run \u2014 planned actions:
2904
2904
  `));for(let L of y)process.stdout.write(` \u2022 ${L}
2905
2905
  `);tt.length>0&&(process.stdout.write(`
2906
2906
  `+R.bold(R.yellow(`Preview-status providers selected:
2907
2907
  `))),Ut()),process.stdout.write(R.dim(`
2908
2908
  No files were written.
2909
- `))}process.exit(0)}let Ko=async()=>{process.stdout.write(`
2909
+ `))}process.exit(0)}let Yo=async()=>{process.stdout.write(`
2910
2910
  `+R.red(`\u2718 Cancelled
2911
2911
  `)),ue.existsSync(i)&&await C.confirm({message:`Cleanup partial install at ${i}?`,initialValue:!0})===!0&&(ue.rmSync(i,{recursive:!0,force:!0}),process.stdout.write(R.dim(` \u2713 Removed ${i}
2912
- `))),process.exit(130)};process.on("SIGINT",Ko);try{p(n,{event:"step",step:"clone",status:"start"}),await Wn(i),p(n,{event:"step",step:"clone",status:"ok"}),p(n,{event:"step",step:"package",status:"start"}),await oo(i,d),p(n,{event:"step",step:"package",status:"ok"}),p(n,{event:"step",step:"config",status:"start"}),await An(i,Ye),p(n,{event:"step",step:"config",status:"ok"}),p(n,{event:"step",step:"prune",status:"start"}),await mo(i,Ye),p(n,{event:"step",step:"prune",status:"ok"});let m=dt.join(i,"packages/db/prisma/schema.prisma");if(ue.existsSync(m)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let b=ue.readFileSync(m,"utf-8"),_=Gt(b,{auth:k,payment:j,"billing-mode":Ke,idp:Be,template:"saas"});ue.writeFileSync(m,_),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(b){let _=b instanceof Error?b.message:String(b);p(n,{event:"step",step:"schema-prune",status:"error",error:_})}}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"auth",choice:k,status:"start"}),await mn(i,k),p(n,{event:"step",step:"auth",choice:k,status:"ok"}),$.length>0?(p(n,{event:"step",step:"social-login",providers:$,status:"start"}),await Sn(i,$,k),p(n,{event:"step",step:"social-login",providers:$,status:"ok"})):p(n,{event:"step",step:"social-login",status:"skip"}),p(n,{event:"step",step:"db",choice:z,status:"start"}),await Nn(i,z,d),p(n,{event:"step",step:"db",choice:z,status:"ok"}),p(n,{event:"step",step:"payment",choice:j,status:"start"}),await so(i,j),p(n,{event:"step",step:"payment",choice:j,status:"ok"}),await Mn(i,xe,f),n&&p(!0,{event:"step",step:"email",choice:xe,status:"ok"}),await Io(i,ke,f),n&&p(!0,{event:"step",step:"storage",choice:ke,status:"ok"}),await eo(i,Te,f),n&&p(!0,{event:"step",step:"monitoring",choice:Te,status:"ok"}),await ln(i,Oe,f),n&&p(!0,{event:"step",step:"analytics",choice:Oe,status:"ok"}),await Po(i,Ue,f),n&&p(!0,{event:"step",step:"sms",choice:Ue,status:"ok"}),await yo(i,Le,f),n&&p(!0,{event:"step",step:"queue",choice:Le,status:"ok"}),await ho(i,Me,f),n&&p(!0,{event:"step",step:"search",choice:Me,status:"ok"}),await vn(i,Je,f),n&&p(!0,{event:"step",step:"cache",choice:Je,status:"ok"}),await no(i,De,f),n&&p(!0,{event:"step",step:"notifications",choice:De,status:"ok"}),await Ao(i,Fe,f),n&&p(!0,{event:"step",step:"webhooks",choice:Fe,status:"ok"}),await In(i,Ze,f),n&&p(!0,{event:"step",step:"cms",choice:Ze,status:"ok"}),await Yn(i,je,f),n&&p(!0,{event:"step",step:"feature-flags",choice:je,status:"ok"}),await Pn(i,Ve,f),n&&p(!0,{event:"step",step:"captcha",choice:Ve,status:"ok"}),await Xn(i,gt),n&&p(!0,{event:"step",step:"mcp",mode:gt,status:"ok"}),await Qn(i,et,Qe),n&&p(!0,{event:"step",step:"metering",mode:et,status:"ok"}),Ye.orm==="prisma"&&Ye.database!=="none"){let b=dt.join(i,"packages/db/prisma/schema.prisma");if(ue.existsSync(b)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let _=ue.readFileSync(b,"utf8"),K=Gt(_,{auth:k,payment:j,"billing-mode":Ke,idp:Be,template:"saas"});ue.writeFileSync(b,K),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(_){let K=_ instanceof Error?_.message:String(_);p(n,{event:"step",step:"schema-prune",status:"error",error:K})}}else p(n,{event:"step",step:"schema-prune",status:"skip"})}else p(n,{event:"step",step:"schema-prune",status:"skip"});p(n,{event:"step",step:"billing-mode",choice:Ke,status:"ok"}),p(n,{event:"step",step:"idp",choice:Be,status:"ok"}),await Cn(i,f),n&&p(!0,{event:"step",step:"compliance",region:f,status:"ok"}),await Kn(i),await vo(i,k),await wo(i,{projectName:d,region:f}),p(n,{event:"step",step:"ai-providers",status:"start"});let y={providerIds:Ye.aiProviders,customEndpoint:Ye.customAiEndpoint},L=dt.join(i,"packages/ai-providers/templates");if(await lo(i,y,L),p(n,{event:"step",step:"ai-providers",status:"ok"}),p(n,{event:"step",step:"docs",status:"start"}),V!=="none"?(await Tn(i,{framework:V,projectName:d}),p(n,{event:"step",step:"docs",framework:"fumadocs",requested:V,status:"ok"})):p(n,{event:"step",step:"docs",status:"skip"}),p(n,{event:"step",step:"deploy-target",status:"start"}),Q!=="none"&&await xn(i,Q),p(n,{event:"step",step:"deploy-target",status:"ok"}),p(n,{event:"step",step:"env",status:"start"}),await Fn(i,Vo),p(n,{event:"step",step:"env",status:"ok"}),t.install!==!1){let b=u==="bun"?"bun install":`${u} install`;n?p(!0,{event:"step",step:"install",pm:u,status:"start"}):process.stdout.write(R.dim(` Installing dependencies with ${u}\u2026
2912
+ `))),process.exit(130)};process.on("SIGINT",Yo);try{p(n,{event:"step",step:"clone",status:"start"}),await zn(i),p(n,{event:"step",step:"clone",status:"ok"}),p(n,{event:"step",step:"package",status:"start"}),await so(i,d),p(n,{event:"step",step:"package",status:"ok"}),p(n,{event:"step",step:"config",status:"start"}),await An(i,Ye),p(n,{event:"step",step:"config",status:"ok"}),p(n,{event:"step",step:"prune",status:"start"}),await fo(i,Ye),p(n,{event:"step",step:"prune",status:"ok"});let m=dt.join(i,"packages/db/prisma/schema.prisma");if(ue.existsSync(m)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let b=ue.readFileSync(m,"utf-8"),_=Gt(b,{auth:k,payment:j,"billing-mode":Ke,idp:Be,template:"saas"});ue.writeFileSync(m,_),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(b){let _=b instanceof Error?b.message:String(b);p(n,{event:"step",step:"schema-prune",status:"error",error:_})}}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"auth",choice:k,status:"start"}),await mn(i,k),p(n,{event:"step",step:"auth",choice:k,status:"ok"}),$.length>0?(p(n,{event:"step",step:"social-login",providers:$,status:"start"}),await Sn(i,$,k),p(n,{event:"step",step:"social-login",providers:$,status:"ok"})):p(n,{event:"step",step:"social-login",status:"skip"}),p(n,{event:"step",step:"db",choice:z,status:"start"}),await Nn(i,z,d),p(n,{event:"step",step:"db",choice:z,status:"ok"}),p(n,{event:"step",step:"payment",choice:j,status:"start"}),await ao(i,j),p(n,{event:"step",step:"payment",choice:j,status:"ok"}),await Mn(i,xe,f),n&&p(!0,{event:"step",step:"email",choice:xe,status:"ok"}),await Ao(i,ke,f),n&&p(!0,{event:"step",step:"storage",choice:ke,status:"ok"}),await no(i,Te,f),n&&p(!0,{event:"step",step:"monitoring",choice:Te,status:"ok"}),await ln(i,Oe,f),n&&p(!0,{event:"step",step:"analytics",choice:Oe,status:"ok"}),await Io(i,Ue,f),n&&p(!0,{event:"step",step:"sms",choice:Ue,status:"ok"}),await ho(i,Le,f),n&&p(!0,{event:"step",step:"queue",choice:Le,status:"ok"}),await _o(i,Me,f),n&&p(!0,{event:"step",step:"search",choice:Me,status:"ok"}),await vn(i,Je,f),n&&p(!0,{event:"step",step:"cache",choice:Je,status:"ok"}),await ro(i,De,f),n&&p(!0,{event:"step",step:"notifications",choice:De,status:"ok"}),await Ro(i,Fe,f),n&&p(!0,{event:"step",step:"webhooks",choice:Fe,status:"ok"}),await In(i,Ze,f),n&&p(!0,{event:"step",step:"cms",choice:Ze,status:"ok"}),await Yn(i,je,f),n&&p(!0,{event:"step",step:"feature-flags",choice:je,status:"ok"}),await Pn(i,Ve,f),n&&p(!0,{event:"step",step:"captcha",choice:Ve,status:"ok"}),await Qn(i,gt),n&&p(!0,{event:"step",step:"mcp",mode:gt,status:"ok"}),await Zn(i,et,Qe),n&&p(!0,{event:"step",step:"metering",mode:et,status:"ok"}),Ye.orm==="prisma"&&Ye.database!=="none"){let b=dt.join(i,"packages/db/prisma/schema.prisma");if(ue.existsSync(b)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let _=ue.readFileSync(b,"utf8"),K=Gt(_,{auth:k,payment:j,"billing-mode":Ke,idp:Be,template:"saas"});ue.writeFileSync(b,K),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(_){let K=_ instanceof Error?_.message:String(_);p(n,{event:"step",step:"schema-prune",status:"error",error:K})}}else p(n,{event:"step",step:"schema-prune",status:"skip"})}else p(n,{event:"step",step:"schema-prune",status:"skip"});p(n,{event:"step",step:"billing-mode",choice:Ke,status:"ok"}),p(n,{event:"step",step:"idp",choice:Be,status:"ok"}),await Cn(i,f),n&&p(!0,{event:"step",step:"compliance",region:f,status:"ok"}),await Kn(i),await Po(i,k),await No(i,{projectName:d,region:f}),p(n,{event:"step",step:"ai-providers",status:"start"});let y={providerIds:Ye.aiProviders,customEndpoint:Ye.customAiEndpoint},L=dt.join(i,"packages/ai-providers/templates");if(await mo(i,y,L),p(n,{event:"step",step:"ai-providers",status:"ok"}),p(n,{event:"step",step:"docs",status:"start"}),V!=="none"?(await Tn(i,{framework:V,projectName:d}),p(n,{event:"step",step:"docs",framework:"fumadocs",requested:V,status:"ok"})):p(n,{event:"step",step:"docs",status:"skip"}),p(n,{event:"step",step:"deploy-target",status:"start"}),Q!=="none"&&await xn(i,Q),p(n,{event:"step",step:"deploy-target",status:"ok"}),p(n,{event:"step",step:"env",status:"start"}),await Fn(i,Bo),p(n,{event:"step",step:"env",status:"ok"}),t.install!==!1){let b=u==="bun"?"bun install":`${u} install`;n?p(!0,{event:"step",step:"install",pm:u,status:"start"}):process.stdout.write(R.dim(` Installing dependencies with ${u}\u2026
2913
2913
  `));try{Ot(b,{cwd:i,stdio:n?"ignore":"inherit"}),p(n,{event:"step",step:"install",status:"ok"})}catch(_){let K=_ instanceof Error?_.message:String(_);n?p(!0,{event:"step",step:"install",status:"error",error:K}):process.stdout.write(R.yellow(` \u26A0 install failed \u2014 run '${b}' manually.
2914
2914
  `))}}else p(n,{event:"step",step:"install",status:"skip"});if(t.git!==!1){n&&p(!0,{event:"step",step:"git-init",status:"start"});try{Ot("git init -q",{cwd:i,stdio:"ignore"}),Ot("git add -A",{cwd:i,stdio:"ignore"}),Ot('git -c user.email=you@example.com -c user.name="You" commit -q -m "chore: initial scaffold from create-sailor"',{cwd:i,stdio:"ignore"}),p(n,{event:"step",step:"git-init",status:"ok"})}catch(b){let _=b instanceof Error?b.message:String(b);n?p(!0,{event:"step",step:"git-init",status:"error",error:_}):process.stdout.write(R.yellow(` \u26A0 git init skipped \u2014 not fatal.
2915
- `))}}else p(n,{event:"step",step:"git-init",status:"skip"});let $e=Math.max(1,Math.round((Date.now()-Jt)/1e3));an({template_version:ne,package_manager:u,region:f,auth:k,payment:j,ai_providers:te,deploy_target:Q,duration_ms:Date.now()-Jt}),tt.length>0&&Ut(),n?p(!0,{event:"done",status:"ok",elapsedSec:$e,targetDir:i,previewSelections:tt}):nn({elapsedSec:$e,targetDir:i,skippedInstall:t.install===!1,previewSelections:tt});try{Mi({pkg:{name:Ro,version:ne},updateCheckInterval:1e3*60*60*24}).notify({defer:!1,isGlobal:!0})}catch{}process.exit(0)}catch(m){let y=m instanceof Error?m.message:String(m);n?p(!0,{event:"error",message:y}):process.stdout.write(R.red(`
2915
+ `))}}else p(n,{event:"step",step:"git-init",status:"skip"});let $e=Math.max(1,Math.round((Date.now()-Jt)/1e3));an({template_version:ne,package_manager:u,region:f,auth:k,payment:j,ai_providers:te,deploy_target:Q,duration_ms:Date.now()-Jt}),tt.length>0&&Ut(),n?p(!0,{event:"done",status:"ok",elapsedSec:$e,targetDir:i,previewSelections:tt}):nn({elapsedSec:$e,targetDir:i,skippedInstall:t.install===!1,previewSelections:tt});try{Di({pkg:{name:xo,version:ne},updateCheckInterval:1e3*60*60*24}).notify({defer:!1,isGlobal:!0})}catch{}process.exit(0)}catch(m){let y=m instanceof Error?m.message:String(m);n?p(!0,{event:"error",message:y}):process.stdout.write(R.red(`
2916
2916
  \u2718 Failed: ${y}
2917
- `)),process.exit(1)}}ji().catch(e=>{process.stderr.write(String(e)+`
2917
+ `)),process.exit(1)}}Vi().catch(e=>{process.stderr.write(String(e)+`
2918
2918
  `),process.exit(1)});