create-avalanche-app 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/api.ts
|
|
4
|
-
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
4
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
5
5
|
import path2 from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
|
|
@@ -50,6 +50,7 @@ async function scaffold({
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// src/api.ts
|
|
53
|
+
var WEB3AUTH_MODAL_VERSION = "11.2.0";
|
|
53
54
|
var templatesDir = path2.join(
|
|
54
55
|
path2.dirname(fileURLToPath(import.meta.url)),
|
|
55
56
|
"..",
|
|
@@ -80,12 +81,28 @@ async function scaffoldApp(opts) {
|
|
|
80
81
|
__AVAKIT_DEP__: opts.local ? "workspace:*" : `^${opts.avakitVersion ?? "0.1.0"}`
|
|
81
82
|
};
|
|
82
83
|
const files = await scaffold({ templateDir, targetDir: opts.targetDir, replacements });
|
|
84
|
+
if (opts.wallet === "web3auth") {
|
|
85
|
+
addDependency(
|
|
86
|
+
path2.join(opts.targetDir, "package.json"),
|
|
87
|
+
"@web3auth/modal",
|
|
88
|
+
WEB3AUTH_MODAL_VERSION
|
|
89
|
+
);
|
|
90
|
+
}
|
|
83
91
|
return { targetDir: opts.targetDir, files };
|
|
84
92
|
}
|
|
93
|
+
function addDependency(pkgPath, name, version) {
|
|
94
|
+
if (!existsSync(pkgPath)) return;
|
|
95
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
96
|
+
pkg.dependencies = Object.fromEntries(
|
|
97
|
+
Object.entries({ ...pkg.dependencies, [name]: version }).sort(([a], [b]) => a.localeCompare(b))
|
|
98
|
+
);
|
|
99
|
+
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
85
102
|
|
|
86
103
|
export {
|
|
87
104
|
templatesDir,
|
|
88
105
|
listTemplates,
|
|
89
106
|
scaffoldApp
|
|
90
107
|
};
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-UU7ZIK6L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api.ts","../src/scaffold.ts"],"sourcesContent":["/**\n * Programmatic API for the scaffolder — used by the CLI (src/index.ts) and by\n * @avakit/mcp's `scaffold_app` tool. Keeps template resolution and placeholder\n * replacement in one place.\n */\n\nimport { existsSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { scaffold } from \"./scaffold.js\";\n\n/** Web3Auth Modal SDK version added to apps that use the social-login wallet. */\nconst WEB3AUTH_MODAL_VERSION = \"11.2.0\";\n\nexport const templatesDir = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"templates\",\n);\n\nexport interface TemplateInfo {\n id: string;\n title: string;\n description: string;\n contracts: boolean;\n}\n\nexport function listTemplates(): TemplateInfo[] {\n return readdirSync(templatesDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => {\n const manifestPath = path.join(templatesDir, e.name, \"manifest.json\");\n const manifest = existsSync(manifestPath)\n ? (JSON.parse(readFileSync(manifestPath, \"utf8\")) as Partial<TemplateInfo>)\n : {};\n return {\n id: e.name,\n title: manifest.title ?? e.name,\n description: manifest.description ?? \"\",\n contracts: manifest.contracts ?? false,\n };\n });\n}\n\nexport type WalletId = \"web3auth\" | \"injected\";\nexport type ChainId = \"fuji\" | \"c-chain\";\n\nexport interface ScaffoldAppOptions {\n projectName: string;\n /** Absolute target directory. */\n targetDir: string;\n template: string;\n wallet?: WalletId;\n chain?: ChainId;\n /** Link @avakit/* via workspace instead of npm versions (repo dev only). */\n local?: boolean;\n /** @avakit version range used when not linking locally. */\n avakitVersion?: string;\n}\n\nexport interface ScaffoldAppResult {\n targetDir: string;\n files: string[];\n}\n\nexport async function scaffoldApp(opts: ScaffoldAppOptions): Promise<ScaffoldAppResult> {\n const templateDir = path.join(templatesDir, opts.template);\n if (!existsSync(templateDir)) {\n throw new Error(\n `Unknown template \"${opts.template}\". Available: ${listTemplates()\n .map((t) => t.id)\n .join(\", \")}`,\n );\n }\n\n const replacements: Record<string, string> = {\n __PROJECT_NAME__: opts.projectName,\n __CHAIN_CONST__: opts.chain === \"c-chain\" ? \"cChain\" : \"fuji\",\n __AVAKIT_DEP__: opts.local ? \"workspace:*\" : `^${opts.avakitVersion ?? \"0.1.0\"}`,\n };\n\n const files = await scaffold({ templateDir, targetDir: opts.targetDir, replacements });\n\n // The social-login wallet needs @web3auth/modal (an optional peer of\n // @avakit/core). Add it to the app so `web3authAdapter` can load at runtime.\n if (opts.wallet === \"web3auth\") {\n addDependency(\n path.join(opts.targetDir, \"package.json\"),\n \"@web3auth/modal\",\n WEB3AUTH_MODAL_VERSION,\n );\n }\n\n return { targetDir: opts.targetDir, files };\n}\n\nfunction addDependency(pkgPath: string, name: string, version: string): void {\n if (!existsSync(pkgPath)) return;\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as {\n dependencies?: Record<string, string>;\n };\n pkg.dependencies = Object.fromEntries(\n Object.entries({ ...pkg.dependencies, [name]: version }).sort(([a], [b]) => a.localeCompare(b)),\n );\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n}\n","import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Template files are stored with dot-prefixes stripped so they ship cleanly in\n * an npm package (npm refuses to publish a literal `.gitignore`, etc.). On\n * scaffold we restore the leading dot per path segment.\n */\nconst RENAME_SEGMENT: Record<string, string> = {\n gitignore: \".gitignore\",\n \"env.example\": \".env.example\",\n cursor: \".cursor\",\n};\n\n/** Template-only files that must NOT be copied into the generated project. */\nconst TEMPLATE_ONLY = new Set([\"manifest.json\"]);\n\nexport interface ScaffoldOptions {\n templateDir: string;\n targetDir: string;\n /** Literal placeholder → value, applied to every text file's contents. */\n replacements: Record<string, string>;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files = await Promise.all(\n entries.map((entry) => {\n const full = path.join(dir, entry.name);\n return entry.isDirectory() ? walk(full) : Promise.resolve([full]);\n }),\n );\n return files.flat();\n}\n\n/** Copy a template into targetDir, renaming dot-files and replacing placeholders. */\nexport async function scaffold({\n templateDir,\n targetDir,\n replacements,\n}: ScaffoldOptions): Promise<string[]> {\n const files = await walk(templateDir);\n const written: string[] = [];\n\n for (const abs of files) {\n const rel = path.relative(templateDir, abs);\n if (TEMPLATE_ONLY.has(rel)) {\n continue;\n }\n const outRel = rel\n .split(path.sep)\n .map((segment) => RENAME_SEGMENT[segment] ?? segment)\n .join(path.sep);\n const outPath = path.join(targetDir, outRel);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n\n let content = await readFile(abs, \"utf8\");\n for (const [token, value] of Object.entries(replacements)) {\n content = content.split(token).join(value);\n }\n await writeFile(outPath, content);\n written.push(outRel);\n }\n\n return written;\n}\n"],"mappings":";;;AAMA,SAAS,YAAY,aAAa,cAAc,qBAAqB;AACrE,OAAOA,WAAU;AACjB,SAAS,qBAAqB;;;ACR9B,SAAS,OAAO,SAAS,UAAU,iBAAiB;AACpD,OAAO,UAAU;AAOjB,IAAM,iBAAyC;AAAA,EAC7C,WAAW;AAAA,EACX,eAAe;AAAA,EACf,QAAQ;AACV;AAGA,IAAM,gBAAgB,oBAAI,IAAI,CAAC,eAAe,CAAC;AAS/C,eAAe,KAAK,KAAgC;AAClD,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,QAAQ,IAAI,CAAC,UAAU;AACrB,YAAM,OAAO,KAAK,KAAK,KAAK,MAAM,IAAI;AACtC,aAAO,MAAM,YAAY,IAAI,KAAK,IAAI,IAAI,QAAQ,QAAQ,CAAC,IAAI,CAAC;AAAA,IAClE,CAAC;AAAA,EACH;AACA,SAAO,MAAM,KAAK;AACpB;AAGA,eAAsB,SAAS;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,QAAQ,MAAM,KAAK,WAAW;AACpC,QAAM,UAAoB,CAAC;AAE3B,aAAW,OAAO,OAAO;AACvB,UAAM,MAAM,KAAK,SAAS,aAAa,GAAG;AAC1C,QAAI,cAAc,IAAI,GAAG,GAAG;AAC1B;AAAA,IACF;AACA,UAAM,SAAS,IACZ,MAAM,KAAK,GAAG,EACd,IAAI,CAAC,YAAY,eAAe,OAAO,KAAK,OAAO,EACnD,KAAK,KAAK,GAAG;AAChB,UAAM,UAAU,KAAK,KAAK,WAAW,MAAM;AAE3C,UAAM,MAAM,KAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAEtD,QAAI,UAAU,MAAM,SAAS,KAAK,MAAM;AACxC,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACzD,gBAAU,QAAQ,MAAM,KAAK,EAAE,KAAK,KAAK;AAAA,IAC3C;AACA,UAAM,UAAU,SAAS,OAAO;AAChC,YAAQ,KAAK,MAAM;AAAA,EACrB;AAEA,SAAO;AACT;;;ADtDA,IAAM,yBAAyB;AAExB,IAAM,eAAeC,MAAK;AAAA,EAC/BA,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EAC3C;AAAA,EACA;AACF;AASO,SAAS,gBAAgC;AAC9C,SAAO,YAAY,cAAc,EAAE,eAAe,KAAK,CAAC,EACrD,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7B,IAAI,CAAC,MAAM;AACV,UAAM,eAAeA,MAAK,KAAK,cAAc,EAAE,MAAM,eAAe;AACpE,UAAM,WAAW,WAAW,YAAY,IACnC,KAAK,MAAM,aAAa,cAAc,MAAM,CAAC,IAC9C,CAAC;AACL,WAAO;AAAA,MACL,IAAI,EAAE;AAAA,MACN,OAAO,SAAS,SAAS,EAAE;AAAA,MAC3B,aAAa,SAAS,eAAe;AAAA,MACrC,WAAW,SAAS,aAAa;AAAA,IACnC;AAAA,EACF,CAAC;AACL;AAuBA,eAAsB,YAAY,MAAsD;AACtF,QAAM,cAAcA,MAAK,KAAK,cAAc,KAAK,QAAQ;AACzD,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,UAAM,IAAI;AAAA,MACR,qBAAqB,KAAK,QAAQ,iBAAiB,cAAc,EAC9D,IAAI,CAAC,MAAM,EAAE,EAAE,EACf,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AAEA,QAAM,eAAuC;AAAA,IAC3C,kBAAkB,KAAK;AAAA,IACvB,iBAAiB,KAAK,UAAU,YAAY,WAAW;AAAA,IACvD,gBAAgB,KAAK,QAAQ,gBAAgB,IAAI,KAAK,iBAAiB,OAAO;AAAA,EAChF;AAEA,QAAM,QAAQ,MAAM,SAAS,EAAE,aAAa,WAAW,KAAK,WAAW,aAAa,CAAC;AAIrF,MAAI,KAAK,WAAW,YAAY;AAC9B;AAAA,MACEA,MAAK,KAAK,KAAK,WAAW,cAAc;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,KAAK,WAAW,MAAM;AAC5C;AAEA,SAAS,cAAc,SAAiB,MAAc,SAAuB;AAC3E,MAAI,CAAC,WAAW,OAAO,EAAG;AAC1B,QAAM,MAAM,KAAK,MAAM,aAAa,SAAS,MAAM,CAAC;AAGpD,MAAI,eAAe,OAAO;AAAA,IACxB,OAAO,QAAQ,EAAE,GAAG,IAAI,cAAc,CAAC,IAAI,GAAG,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA,EAChG;AACA,gBAAc,SAAS,GAAG,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AAAA,CAAI;AAC5D;","names":["path","path"]}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
listTemplates,
|
|
4
4
|
scaffoldApp
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UU7ZIK6L.js";
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
8
|
import { spawnSync } from "child_process";
|
|
@@ -10,7 +10,7 @@ import { existsSync, readdirSync } from "fs";
|
|
|
10
10
|
import path from "path";
|
|
11
11
|
import * as p from "@clack/prompts";
|
|
12
12
|
import pc from "picocolors";
|
|
13
|
-
var VERSION = "0.1.
|
|
13
|
+
var VERSION = "0.1.2";
|
|
14
14
|
function parseArgs(argv) {
|
|
15
15
|
const opts = { yes: false, local: false, install: true };
|
|
16
16
|
const rest = argv.slice(2);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { type ChainId, listTemplates, scaffoldApp, type WalletId } from \"./api.js\";\n\nconst VERSION = \"0.1.1\";\n\ntype PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\ninterface Options {\n projectName?: string;\n template?: string;\n wallet?: WalletId;\n chain?: ChainId;\n pm?: PackageManager;\n yes: boolean;\n local: boolean;\n install: boolean;\n}\n\nfunction parseArgs(argv: string[]): Options {\n const opts: Options = { yes: false, local: false, install: true };\n const rest = argv.slice(2);\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n const next = () => rest[++i];\n switch (arg) {\n case \"--yes\":\n case \"-y\":\n opts.yes = true;\n break;\n case \"--local\":\n opts.local = true;\n break;\n case \"--no-install\":\n opts.install = false;\n break;\n case \"--template\":\n case \"-t\":\n opts.template = next();\n break;\n case \"--wallet\":\n case \"-w\":\n opts.wallet = next() as WalletId;\n break;\n case \"--chain\":\n case \"-c\":\n opts.chain = next() as ChainId;\n break;\n case \"--pm\":\n opts.pm = next() as PackageManager;\n break;\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${VERSION}\\n`);\n process.exit(0);\n break;\n case \"--help\":\n case \"-h\":\n printHelp();\n process.exit(0);\n break;\n default:\n if (arg && !arg.startsWith(\"-\") && !opts.projectName) {\n opts.projectName = arg;\n }\n }\n }\n return opts;\n}\n\nfunction printHelp(): void {\n process.stdout.write(\n [\n \"create-avalanche-app — scaffold a batteries-included Avalanche dapp\",\n \"\",\n \"Usage: npm create avalanche-app@latest [name] [options]\",\n \"\",\n \"Options:\",\n \" -t, --template <id> minimal | nft-mint | token-gated-app | erc20-token\",\n \" -w, --wallet <id> web3auth | injected (default: web3auth)\",\n \" -c, --chain <id> fuji | c-chain (default: fuji)\",\n \" --pm <manager> pnpm | npm | yarn | bun\",\n \" -y, --yes skip prompts (non-interactive)\",\n \" --no-install do not install dependencies\",\n \" --local link @avakit/* via workspace (repo dev only)\",\n \" -v, --version print version\",\n \" -h, --help print this help\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n\nfunction isValidName(name: string): boolean {\n return /^[a-z0-9][a-z0-9._-]*$/.test(name);\n}\n\nasync function resolveOptions(\n opts: Options,\n): Promise<Required<Omit<Options, \"yes\" | \"local\" | \"install\">>> {\n const templates = listTemplates();\n const templateIds = templates.map((t) => t.id);\n\n if (opts.yes) {\n const projectName = opts.projectName ?? \"my-avax-app\";\n return {\n projectName,\n template: opts.template && templateIds.includes(opts.template) ? opts.template : \"minimal\",\n wallet: opts.wallet ?? \"web3auth\",\n chain: opts.chain ?? \"fuji\",\n pm: opts.pm ?? \"pnpm\",\n };\n }\n\n p.intro(pc.bgCyan(pc.black(\" create-avalanche-app \")));\n\n const projectName =\n opts.projectName ??\n (await p.text({\n message: \"Project name?\",\n placeholder: \"my-avax-app\",\n defaultValue: \"my-avax-app\",\n validate: (v) => (!v || isValidName(v) ? undefined : \"Use lowercase letters, digits, - . _\"),\n }));\n if (p.isCancel(projectName)) cancel();\n\n const template =\n opts.template ??\n (await p.select({\n message: \"Template?\",\n options: templates.map((t) => ({ value: t.id, label: t.title, hint: t.description })),\n initialValue: \"minimal\",\n }));\n if (p.isCancel(template)) cancel();\n\n const wallet =\n opts.wallet ??\n (await p.select({\n message: \"Wallet provider?\",\n options: [\n { value: \"web3auth\", label: \"Social login (Web3Auth)\", hint: \"free, recommended\" },\n { value: \"injected\", label: \"Browser wallet (Core / MetaMask)\" },\n ],\n initialValue: \"web3auth\",\n }));\n if (p.isCancel(wallet)) cancel();\n\n const chain =\n opts.chain ??\n (await p.select({\n message: \"Target chain?\",\n options: [\n { value: \"fuji\", label: \"Avalanche Fuji (testnet)\", hint: \"recommended\" },\n { value: \"c-chain\", label: \"Avalanche C-Chain (mainnet)\" },\n ],\n initialValue: \"fuji\",\n }));\n if (p.isCancel(chain)) cancel();\n\n const pm =\n opts.pm ??\n (await p.select({\n message: \"Package manager?\",\n options: ([\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const).map((m) => ({ value: m, label: m })),\n initialValue: \"pnpm\",\n }));\n if (p.isCancel(pm)) cancel();\n\n return {\n projectName: projectName as string,\n template: template as string,\n wallet: wallet as WalletId,\n chain: chain as ChainId,\n pm: pm as PackageManager,\n };\n}\n\nfunction cancel(): never {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n}\n\nasync function main(): Promise<void> {\n const opts = parseArgs(process.argv);\n const resolved = await resolveOptions(opts);\n\n const targetDir = path.resolve(process.cwd(), resolved.projectName);\n if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {\n process.stderr.write(\n pc.red(`\\nDirectory \"${resolved.projectName}\" already exists and is not empty.\\n`),\n );\n process.exit(1);\n }\n\n const spin = opts.yes ? null : p.spinner();\n spin?.start(\"Scaffolding project\");\n const { files } = await scaffoldApp({\n projectName: resolved.projectName,\n targetDir,\n template: resolved.template,\n wallet: resolved.wallet,\n chain: resolved.chain,\n local: opts.local,\n avakitVersion: VERSION,\n });\n spin?.stop(`Created ${files.length} files`);\n\n if (opts.install) {\n const installSpin = opts.yes ? null : p.spinner();\n installSpin?.start(`Installing dependencies with ${resolved.pm}`);\n const result = spawnSync(resolved.pm, [\"install\"], {\n cwd: targetDir,\n stdio: opts.yes ? \"inherit\" : \"ignore\",\n });\n if (result.status === 0) {\n installSpin?.stop(\"Dependencies installed\");\n } else {\n installSpin?.stop(pc.yellow(\"Install skipped/failed — run it manually\"));\n }\n }\n\n const next = [\n `cd ${resolved.projectName}`,\n ...(opts.install ? [] : [`${resolved.pm} install`]),\n ...(resolved.wallet === \"web3auth\"\n ? [\"cp .env.example .env.local # add your Web3Auth client ID\"]\n : []),\n `${resolved.pm} run dev`,\n ];\n\n if (opts.yes) {\n process.stdout.write(`\\nDone. Next steps:\\n ${next.join(\"\\n \")}\\n`);\n } else {\n p.note(next.join(\"\\n\"), \"Next steps\");\n p.outro(pc.green(\"Your Avalanche dapp is ready.\"));\n }\n}\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `\\n${pc.red(\"Error:\")} ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exit(1);\n});\n"],"mappings":"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","names":["projectName","cancel"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { type ChainId, listTemplates, scaffoldApp, type WalletId } from \"./api.js\";\n\nconst VERSION = \"0.1.2\";\n\ntype PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\ninterface Options {\n projectName?: string;\n template?: string;\n wallet?: WalletId;\n chain?: ChainId;\n pm?: PackageManager;\n yes: boolean;\n local: boolean;\n install: boolean;\n}\n\nfunction parseArgs(argv: string[]): Options {\n const opts: Options = { yes: false, local: false, install: true };\n const rest = argv.slice(2);\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n const next = () => rest[++i];\n switch (arg) {\n case \"--yes\":\n case \"-y\":\n opts.yes = true;\n break;\n case \"--local\":\n opts.local = true;\n break;\n case \"--no-install\":\n opts.install = false;\n break;\n case \"--template\":\n case \"-t\":\n opts.template = next();\n break;\n case \"--wallet\":\n case \"-w\":\n opts.wallet = next() as WalletId;\n break;\n case \"--chain\":\n case \"-c\":\n opts.chain = next() as ChainId;\n break;\n case \"--pm\":\n opts.pm = next() as PackageManager;\n break;\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${VERSION}\\n`);\n process.exit(0);\n break;\n case \"--help\":\n case \"-h\":\n printHelp();\n process.exit(0);\n break;\n default:\n if (arg && !arg.startsWith(\"-\") && !opts.projectName) {\n opts.projectName = arg;\n }\n }\n }\n return opts;\n}\n\nfunction printHelp(): void {\n process.stdout.write(\n [\n \"create-avalanche-app — scaffold a batteries-included Avalanche dapp\",\n \"\",\n \"Usage: npm create avalanche-app@latest [name] [options]\",\n \"\",\n \"Options:\",\n \" -t, --template <id> minimal | nft-mint | token-gated-app | erc20-token\",\n \" -w, --wallet <id> web3auth | injected (default: web3auth)\",\n \" -c, --chain <id> fuji | c-chain (default: fuji)\",\n \" --pm <manager> pnpm | npm | yarn | bun\",\n \" -y, --yes skip prompts (non-interactive)\",\n \" --no-install do not install dependencies\",\n \" --local link @avakit/* via workspace (repo dev only)\",\n \" -v, --version print version\",\n \" -h, --help print this help\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n\nfunction isValidName(name: string): boolean {\n return /^[a-z0-9][a-z0-9._-]*$/.test(name);\n}\n\nasync function resolveOptions(\n opts: Options,\n): Promise<Required<Omit<Options, \"yes\" | \"local\" | \"install\">>> {\n const templates = listTemplates();\n const templateIds = templates.map((t) => t.id);\n\n if (opts.yes) {\n const projectName = opts.projectName ?? \"my-avax-app\";\n return {\n projectName,\n template: opts.template && templateIds.includes(opts.template) ? opts.template : \"minimal\",\n wallet: opts.wallet ?? \"web3auth\",\n chain: opts.chain ?? \"fuji\",\n pm: opts.pm ?? \"pnpm\",\n };\n }\n\n p.intro(pc.bgCyan(pc.black(\" create-avalanche-app \")));\n\n const projectName =\n opts.projectName ??\n (await p.text({\n message: \"Project name?\",\n placeholder: \"my-avax-app\",\n defaultValue: \"my-avax-app\",\n validate: (v) => (!v || isValidName(v) ? undefined : \"Use lowercase letters, digits, - . _\"),\n }));\n if (p.isCancel(projectName)) cancel();\n\n const template =\n opts.template ??\n (await p.select({\n message: \"Template?\",\n options: templates.map((t) => ({ value: t.id, label: t.title, hint: t.description })),\n initialValue: \"minimal\",\n }));\n if (p.isCancel(template)) cancel();\n\n const wallet =\n opts.wallet ??\n (await p.select({\n message: \"Wallet provider?\",\n options: [\n { value: \"web3auth\", label: \"Social login (Web3Auth)\", hint: \"free, recommended\" },\n { value: \"injected\", label: \"Browser wallet (Core / MetaMask)\" },\n ],\n initialValue: \"web3auth\",\n }));\n if (p.isCancel(wallet)) cancel();\n\n const chain =\n opts.chain ??\n (await p.select({\n message: \"Target chain?\",\n options: [\n { value: \"fuji\", label: \"Avalanche Fuji (testnet)\", hint: \"recommended\" },\n { value: \"c-chain\", label: \"Avalanche C-Chain (mainnet)\" },\n ],\n initialValue: \"fuji\",\n }));\n if (p.isCancel(chain)) cancel();\n\n const pm =\n opts.pm ??\n (await p.select({\n message: \"Package manager?\",\n options: ([\"pnpm\", \"npm\", \"yarn\", \"bun\"] as const).map((m) => ({ value: m, label: m })),\n initialValue: \"pnpm\",\n }));\n if (p.isCancel(pm)) cancel();\n\n return {\n projectName: projectName as string,\n template: template as string,\n wallet: wallet as WalletId,\n chain: chain as ChainId,\n pm: pm as PackageManager,\n };\n}\n\nfunction cancel(): never {\n p.cancel(\"Cancelled.\");\n process.exit(0);\n}\n\nasync function main(): Promise<void> {\n const opts = parseArgs(process.argv);\n const resolved = await resolveOptions(opts);\n\n const targetDir = path.resolve(process.cwd(), resolved.projectName);\n if (existsSync(targetDir) && readdirSync(targetDir).length > 0) {\n process.stderr.write(\n pc.red(`\\nDirectory \"${resolved.projectName}\" already exists and is not empty.\\n`),\n );\n process.exit(1);\n }\n\n const spin = opts.yes ? null : p.spinner();\n spin?.start(\"Scaffolding project\");\n const { files } = await scaffoldApp({\n projectName: resolved.projectName,\n targetDir,\n template: resolved.template,\n wallet: resolved.wallet,\n chain: resolved.chain,\n local: opts.local,\n avakitVersion: VERSION,\n });\n spin?.stop(`Created ${files.length} files`);\n\n if (opts.install) {\n const installSpin = opts.yes ? null : p.spinner();\n installSpin?.start(`Installing dependencies with ${resolved.pm}`);\n const result = spawnSync(resolved.pm, [\"install\"], {\n cwd: targetDir,\n stdio: opts.yes ? \"inherit\" : \"ignore\",\n });\n if (result.status === 0) {\n installSpin?.stop(\"Dependencies installed\");\n } else {\n installSpin?.stop(pc.yellow(\"Install skipped/failed — run it manually\"));\n }\n }\n\n const next = [\n `cd ${resolved.projectName}`,\n ...(opts.install ? [] : [`${resolved.pm} install`]),\n ...(resolved.wallet === \"web3auth\"\n ? [\"cp .env.example .env.local # add your Web3Auth client ID\"]\n : []),\n `${resolved.pm} run dev`,\n ];\n\n if (opts.yes) {\n process.stdout.write(`\\nDone. Next steps:\\n ${next.join(\"\\n \")}\\n`);\n } else {\n p.note(next.join(\"\\n\"), \"Next steps\");\n p.outro(pc.green(\"Your Avalanche dapp is ready.\"));\n }\n}\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `\\n${pc.red(\"Error:\")} ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exit(1);\n});\n"],"mappings":"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","names":["projectName","cancel"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/scaffold.ts"],"sourcesContent":["/**\n * Programmatic API for the scaffolder — used by the CLI (src/index.ts) and by\n * @avakit/mcp's `scaffold_app` tool. Keeps template resolution and placeholder\n * replacement in one place.\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { scaffold } from \"./scaffold.js\";\n\nexport const templatesDir = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"templates\",\n);\n\nexport interface TemplateInfo {\n id: string;\n title: string;\n description: string;\n contracts: boolean;\n}\n\nexport function listTemplates(): TemplateInfo[] {\n return readdirSync(templatesDir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => {\n const manifestPath = path.join(templatesDir, e.name, \"manifest.json\");\n const manifest = existsSync(manifestPath)\n ? (JSON.parse(readFileSync(manifestPath, \"utf8\")) as Partial<TemplateInfo>)\n : {};\n return {\n id: e.name,\n title: manifest.title ?? e.name,\n description: manifest.description ?? \"\",\n contracts: manifest.contracts ?? false,\n };\n });\n}\n\nexport type WalletId = \"web3auth\" | \"injected\";\nexport type ChainId = \"fuji\" | \"c-chain\";\n\nexport interface ScaffoldAppOptions {\n projectName: string;\n /** Absolute target directory. */\n targetDir: string;\n template: string;\n wallet?: WalletId;\n chain?: ChainId;\n /** Link @avakit/* via workspace instead of npm versions (repo dev only). */\n local?: boolean;\n /** @avakit version range used when not linking locally. */\n avakitVersion?: string;\n}\n\nexport interface ScaffoldAppResult {\n targetDir: string;\n files: string[];\n}\n\nexport async function scaffoldApp(opts: ScaffoldAppOptions): Promise<ScaffoldAppResult> {\n const templateDir = path.join(templatesDir, opts.template);\n if (!existsSync(templateDir)) {\n throw new Error(\n `Unknown template \"${opts.template}\". Available: ${listTemplates()\n .map((t) => t.id)\n .join(\", \")}`,\n );\n }\n\n const replacements: Record<string, string> = {\n __PROJECT_NAME__: opts.projectName,\n __CHAIN_CONST__: opts.chain === \"c-chain\" ? \"cChain\" : \"fuji\",\n __AVAKIT_DEP__: opts.local ? \"workspace:*\" : `^${opts.avakitVersion ?? \"0.1.0\"}`,\n };\n\n const files = await scaffold({ templateDir, targetDir: opts.targetDir, replacements });\n return { targetDir: opts.targetDir, files };\n}\n","import { mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Template files are stored with dot-prefixes stripped so they ship cleanly in\n * an npm package (npm refuses to publish a literal `.gitignore`, etc.). On\n * scaffold we restore the leading dot per path segment.\n */\nconst RENAME_SEGMENT: Record<string, string> = {\n gitignore: \".gitignore\",\n \"env.example\": \".env.example\",\n cursor: \".cursor\",\n};\n\n/** Template-only files that must NOT be copied into the generated project. */\nconst TEMPLATE_ONLY = new Set([\"manifest.json\"]);\n\nexport interface ScaffoldOptions {\n templateDir: string;\n targetDir: string;\n /** Literal placeholder → value, applied to every text file's contents. */\n replacements: Record<string, string>;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const files = await Promise.all(\n entries.map((entry) => {\n const full = path.join(dir, entry.name);\n return entry.isDirectory() ? walk(full) : Promise.resolve([full]);\n }),\n );\n return files.flat();\n}\n\n/** Copy a template into targetDir, renaming dot-files and replacing placeholders. */\nexport async function scaffold({\n templateDir,\n targetDir,\n replacements,\n}: ScaffoldOptions): Promise<string[]> {\n const files = await walk(templateDir);\n const written: string[] = [];\n\n for (const abs of files) {\n const rel = path.relative(templateDir, abs);\n if (TEMPLATE_ONLY.has(rel)) {\n continue;\n }\n const outRel = rel\n .split(path.sep)\n .map((segment) => RENAME_SEGMENT[segment] ?? segment)\n .join(path.sep);\n const outPath = path.join(targetDir, outRel);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n\n let content = await readFile(abs, \"utf8\");\n for (const [token, value] of Object.entries(replacements)) {\n content = content.split(token).join(value);\n }\n await writeFile(outPath, content);\n written.push(outRel);\n }\n\n return written;\n}\n"],"mappings":"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","names":["path","path"]}
|