@xunlei-open/create-miniapp 0.1.1-beta.5 → 0.1.1-beta.7

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/README.md CHANGED
@@ -27,7 +27,7 @@ npm run dev
27
27
  npm run package
28
28
  ```
29
29
 
30
- 开发时在迅雷客户端中加载本地应用的目录,保持 dev server 运行。打包结果位于 `release/`。
30
+ 开发时在迅雷客户端中加载本地应用的目录,保持 dev server 运行。打包结果位于 `output/`。
31
31
 
32
32
  生成项目包含创建下载任务的页面示例。应用信息和权限在 `manifest.json` 中配置,开发与构建配置使用 `miniapp.config.ts` 或 `.js`。
33
33
 
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import fs from "fs-extra";
9
9
  import validate from "validate-npm-package-name";
10
10
  import { checkbox, confirm, input, select } from "@inquirer/prompts";
11
11
  //#region package.json
12
- var version = "0.1.1-beta.5";
12
+ var version = "0.1.1-beta.7";
13
13
  //#endregion
14
14
  //#region src/utils.ts
15
15
  function toPackageName(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["packageJson.version","packageJson.version"],"sources":["../package.json","../src/utils.ts","../src/generator.ts","../src/prompts.ts","../src/index.ts"],"sourcesContent":["","import validate from \"validate-npm-package-name\";\nimport type { Feature, Framework, PackageManager, Variant } from \"./types.js\";\n\nexport function toPackageName(input: string): string {\n\treturn input\n\t\t.trim()\n\t\t.toLowerCase()\n\t\t.replace(/\\s+/g, \"-\")\n\t\t.replace(/[^a-z0-9-_]/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\nexport function assertValidPackageName(name: string): void {\n\tconst result = validate(name);\n\tif (!result.validForNewPackages) {\n\t\tconst errors = [...(result.errors ?? []), ...(result.warnings ?? [])];\n\t\tthrow new Error(`Invalid package name \"${name}\": ${errors.join(\", \")}`);\n\t}\n}\n\nconst ALL_FEATURES: Feature[] = [\"lint\", \"biome\", \"vitest\"];\n\nconst FEATURE_ALIASES: Record<string, Feature> = {\n\tlint: \"lint\",\n\teslint: \"lint\",\n\tprettier: \"lint\",\n\tbiome: \"biome\",\n\tvitest: \"vitest\",\n};\n\nconst TEMPLATE_IDS: Record<Framework, Record<Variant, string>> = {\n\tvanilla: {\n\t\tjavascript: \"vanilla\",\n\t\ttypescript: \"vanilla-ts\",\n\t},\n\tvue: {\n\t\tjavascript: \"vue\",\n\t\ttypescript: \"vue-ts\",\n\t},\n\treact: {\n\t\tjavascript: \"react\",\n\t\ttypescript: \"react-ts\",\n\t},\n};\n\n/** Map CLI framework / variant to the templates/ directory name. */\nexport function resolveTemplateId(\n\tframework: Framework,\n\tvariant: Variant,\n): string {\n\treturn TEMPLATE_IDS[framework][variant];\n}\n\nexport function parseFramework(input: string): Framework | undefined {\n\tconst key = input.trim().toLowerCase();\n\tconst map: Record<string, Framework> = {\n\t\tvanilla: \"vanilla\",\n\t\tvue: \"vue\",\n\t\treact: \"react\",\n\t};\n\treturn map[key];\n}\n\nexport function parsePackageManager(input: string): PackageManager | undefined {\n\tconst key = input.trim().toLowerCase();\n\tconst map: Record<string, PackageManager> = {\n\t\tnpm: \"npm\",\n\t\tyarn: \"yarn\",\n\t\tpnpm: \"pnpm\",\n\t};\n\treturn map[key];\n}\n\nfunction pkgFromUserAgent(\n\tuserAgent: string | undefined,\n): { name: string; version: string } | undefined {\n\tif (!userAgent) return undefined;\n\tconst pkgSpec = userAgent.split(\" \")[0];\n\tconst [name, version] = pkgSpec?.split(\"/\") ?? [];\n\tif (!name) return undefined;\n\treturn { name, version: version ?? \"\" };\n}\n\n/** Infer npm / yarn / pnpm from npx, pnpx, yarn dlx, pnpm create, etc. */\nexport function detectInvokedPackageManager(): PackageManager {\n\tconst pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);\n\tif (pkgInfo) {\n\t\tconst pm = parsePackageManager(pkgInfo.name);\n\t\tif (pm) return pm;\n\t}\n\n\tconst execPath = process.env.npm_execpath ?? \"\";\n\tif (execPath.includes(\"pnpm\")) return \"pnpm\";\n\tif (execPath.includes(\"yarn\")) return \"yarn\";\n\n\treturn \"npm\";\n}\n\nexport function pmInstallCommand(pm: PackageManager): string {\n\treturn pm === \"yarn\" ? \"yarn\" : `${pm} install`;\n}\n\nexport function pmDevCommand(pm: PackageManager): string {\n\treturn pm === \"npm\" ? \"npm run dev\" : `${pm} dev`;\n}\n\nexport function pmTestCommand(pm: PackageManager): string {\n\treturn pm === \"npm\" ? \"npm test\" : `${pm} test`;\n}\n\nexport function pmDevArgs(pm: PackageManager): string[] {\n\treturn pm === \"npm\" ? [\"run\", \"dev\"] : [\"dev\"];\n}\n\nexport function parseVariant(input: string): Variant | undefined {\n\tconst key = input.trim().toLowerCase();\n\tconst map: Record<string, Variant> = {\n\t\ttypescript: \"typescript\",\n\t\tts: \"typescript\",\n\t\tjavascript: \"javascript\",\n\t\tjs: \"javascript\",\n\t};\n\treturn map[key];\n}\n\nexport function parseFeatures(input: string): Feature[] {\n\tconst features: Feature[] = [];\n\tfor (const part of input.split(/[,+]/)) {\n\t\tconst key = part.trim().toLowerCase();\n\t\tif (!key) continue;\n\t\tconst feature = FEATURE_ALIASES[key];\n\t\tif (feature && !features.includes(feature)) {\n\t\t\tfeatures.push(feature);\n\t\t}\n\t}\n\treturn resolveMutuallyExclusiveLint(features);\n}\n\nexport function hasFeature(features: Feature[], feature: Feature): boolean {\n\treturn features.includes(feature);\n}\n\nexport function supportsOptionalFeatures(_framework: Framework): boolean {\n\treturn true;\n}\n\nexport function defaultFeatures(_framework: Framework): Feature[] {\n\treturn [];\n}\n\n/** lint and biome are mutually exclusive; prefer lint when both are present. */\nexport function resolveMutuallyExclusiveLint(features: Feature[]): Feature[] {\n\tif (features.includes(\"lint\") && features.includes(\"biome\")) {\n\t\treturn features.filter((f) => f !== \"biome\");\n\t}\n\treturn features;\n}\n\nexport function supportsBiomeLinter(framework: Framework): boolean {\n\treturn (\n\t\tframework === \"vanilla\" || framework === \"react\" || framework === \"vue\"\n\t);\n}\n\nexport function isBiomeExperimental(framework: Framework): boolean {\n\treturn framework === \"vue\";\n}\n\nexport function normalizeFeatures(\n\tfeatures: Feature[] | undefined,\n\tframework: Framework,\n): Feature[] {\n\tlet result: Feature[] = [];\n\n\tfor (const f of features ?? []) {\n\t\tif (ALL_FEATURES.includes(f) && !result.includes(f)) {\n\t\t\tresult.push(f);\n\t\t}\n\t}\n\n\tresult = resolveMutuallyExclusiveLint(result);\n\n\tif (result.includes(\"biome\") && !supportsBiomeLinter(framework)) {\n\t\tresult = result.filter((f) => f !== \"biome\");\n\t}\n\n\treturn result;\n}\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport ejs from \"ejs\";\nimport fs from \"fs-extra\";\nimport { green, red } from \"kolorist\";\nimport packageJson from \"../package.json\";\nimport type { CreateOptions, TemplateContext } from \"./types.js\";\nimport {\n\thasFeature,\n\tpmDevCommand,\n\tpmInstallCommand,\n\tpmTestCommand,\n\tresolveTemplateId,\n} from \"./utils.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nfunction getTemplatesRoot(): string {\n\t// dist/index.mjs -> ../templates ; dev tsx -> ../templates\n\treturn path.resolve(__dirname, \"../templates\");\n}\n\nfunction shouldSkip(relPath: string, options: CreateOptions): boolean {\n\tconst normalized = relPath.replace(/\\\\/g, \"/\");\n\tconst { features } = options;\n\n\tif (!hasFeature(features, \"vitest\")) {\n\t\tif (\n\t\t\tnormalized.startsWith(\"tests/\") ||\n\t\t\tnormalized.includes(\"/tests/\") ||\n\t\t\tnormalized.includes(\"vitest.config\") ||\n\t\t\tnormalized.startsWith(\"src/test/\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\tif (!hasFeature(features, \"lint\")) {\n\t\tif (\n\t\t\tnormalized.endsWith(\"eslint.config.js\") ||\n\t\t\tnormalized.endsWith(\"eslint.config.js.ejs\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tif (relPath.endsWith(\".prettierrc.ejs\")) return true;\n\t\tif (relPath.endsWith(\".prettierignore\")) return true;\n\t}\n\tif (!hasFeature(features, \"biome\")) {\n\t\tif (normalized === \"biome.json\" || normalized.endsWith(\"/biome.json\")) {\n\t\t\treturn true;\n\t\t}\n\t\tif (\n\t\t\tnormalized === \".vscode/settings.json\" ||\n\t\t\tnormalized.endsWith(\"/.vscode/settings.json\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\tif (\n\t\trelPath.endsWith(\"pnpm-lock.yaml\") ||\n\t\trelPath.endsWith(\"package-lock.json\") ||\n\t\trelPath.endsWith(\"yarn.lock\")\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nasync function renderFile(\n\tsrc: string,\n\tdest: string,\n\tcontext: TemplateContext,\n): Promise<void> {\n\tconst content = await fs.readFile(src, \"utf-8\");\n\tconst rendered = ejs.render(content, context, { rmWhitespace: false });\n\tawait fs.ensureDir(path.dirname(dest));\n\tawait fs.writeFile(dest, rendered, \"utf-8\");\n}\n\nasync function copyTemplateDir(\n\ttemplateDir: string,\n\ttargetDir: string,\n\tcontext: TemplateContext,\n\toptions: CreateOptions,\n\trelBase = \"\",\n): Promise<void> {\n\tconst entries = await fs.readdir(templateDir, { withFileTypes: true });\n\n\tfor (const entry of entries) {\n\t\tconst srcPath = path.join(templateDir, entry.name);\n\t\tconst relPath = relBase ? `${relBase}/${entry.name}` : entry.name;\n\n\t\tif (shouldSkip(relPath, options)) continue;\n\n\t\tif (entry.isDirectory()) {\n\t\t\tawait copyTemplateDir(\n\t\t\t\tsrcPath,\n\t\t\t\tpath.join(targetDir, entry.name),\n\t\t\t\tcontext,\n\t\t\t\toptions,\n\t\t\t\trelPath,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isEjs = entry.name.endsWith(\".ejs\");\n\t\tconst templateName = isEjs ? entry.name.slice(0, -4) : entry.name;\n\t\t// npm excludes .gitignore files from published tarballs, so templates\n\t\t// store the file under a portable name and restore it during generation.\n\t\tconst outName = templateName === \"_gitignore\" ? \".gitignore\" : templateName;\n\t\tconst destPath = path.join(targetDir, outName);\n\n\t\tif (isEjs) {\n\t\t\tawait renderFile(srcPath, destPath, context);\n\t\t} else {\n\t\t\tawait fs.ensureDir(path.dirname(destPath));\n\t\t\tawait fs.copy(srcPath, destPath);\n\t\t}\n\t}\n}\n\nexport async function generateProject(options: CreateOptions): Promise<string> {\n\tconst templateId = resolveTemplateId(options.framework, options.variant);\n\tconst templateDir = path.join(getTemplatesRoot(), templateId);\n\n\tif (!(await fs.pathExists(templateDir))) {\n\t\tthrow new Error(\n\t\t\t`Template \"${templateId}\" is not available (${options.framework} + ${options.variant}).`,\n\t\t);\n\t}\n\n\tconst targetDir = path.resolve(process.cwd(), options.projectName);\n\n\tif (await fs.pathExists(targetDir)) {\n\t\tconst files = await fs.readdir(targetDir);\n\t\tif (files.length > 0) {\n\t\t\tthrow new Error(`Target directory is not empty: ${targetDir}`);\n\t\t}\n\t}\n\n\tconst context: TemplateContext = {\n\t\tprojectName: options.projectName,\n\t\tpackageName: options.packageName,\n\t\tpackageManager: options.packageManager,\n\t\tvariant: options.variant,\n\t\tfeatures: options.features,\n\t\tdevkitVersion: packageJson.version,\n\t\tisTypeScript: options.variant === \"typescript\",\n\t};\n\n\tawait fs.ensureDir(targetDir);\n\tawait copyTemplateDir(templateDir, targetDir, context, options);\n\n\treturn targetDir;\n}\n\nexport function printNextSteps(\n\ttargetDir: string,\n\toptions: CreateOptions,\n\tinstalled: boolean,\n\tautoStartDev = false,\n): void {\n\tconst rel = path.relative(process.cwd(), targetDir) || \".\";\n\tconst commands: string[] = [];\n\n\tif (rel !== \".\" && !autoStartDev) {\n\t\tcommands.push(`cd ${rel}`);\n\t}\n\tconst { packageManager } = options;\n\n\tif (!installed) {\n\t\tcommands.push(pmInstallCommand(packageManager));\n\t}\n\tif (!autoStartDev) {\n\t\tcommands.push(pmDevCommand(packageManager));\n\t}\n\tif (hasFeature(options.features, \"vitest\")) {\n\t\tcommands.push(pmTestCommand(packageManager));\n\t}\n\n\tif (commands.length > 0) {\n\t\tconsole.log(green(\"\\nDone. Now run:\\n\"));\n\t\tfor (const command of commands) {\n\t\t\tconsole.log(` ${command}`);\n\t\t}\n\t\tconsole.log(\"\");\n\t} else {\n\t\tconsole.log(green(\"\\nDone.\\n\"));\n\t}\n\n\tconsole.log(\"Optional: Initialize Git in your project directory with:\\n\");\n\tconsole.log(' git init && git add -A && git commit -m \"initial commit\"');\n\tconsole.log(\"\");\n}\n\nexport function printError(err: unknown): void {\n\tconst msg = err instanceof Error ? err.message : String(err);\n\tconsole.error(red(`\\n✖ ${msg}\\n`));\n}\n","import { checkbox, confirm, input, select } from \"@inquirer/prompts\";\nimport type { CreateOptions, Feature, Framework, Variant } from \"./types.js\";\nimport {\n\tassertValidPackageName,\n\tdefaultFeatures,\n\tdetectInvokedPackageManager,\n\tisBiomeExperimental,\n\tsupportsBiomeLinter,\n\tsupportsOptionalFeatures,\n\ttoPackageName,\n} from \"./utils.js\";\n\nexport async function runPrompts(\n\tdefaults: Partial<CreateOptions> = {},\n): Promise<CreateOptions> {\n\tconst projectName = await input({\n\t\tmessage: \"Project name:\",\n\t\tdefault: defaults.projectName ?? \"xunlei-plugin-project\",\n\t});\n\n\tconst packageName = toPackageName(defaults.packageName ?? projectName);\n\tassertValidPackageName(packageName);\n\n\tconst framework = await select({\n\t\tmessage: \"Select a framework:\",\n\t\tchoices: [\n\t\t\t{ name: \"Vue\", value: \"vue\" as const },\n\t\t\t{ name: \"React\", value: \"react\" as const },\n\t\t\t{ name: \"Vanilla\", value: \"vanilla\" as const },\n\t\t],\n\t\tdefault: defaults.framework ?? \"vue\",\n\t});\n\n\tconst variant = await selectVariant(defaults.variant);\n\n\tconst features = supportsOptionalFeatures(framework)\n\t\t? await promptFeatures(\n\t\t\t\tframework,\n\t\t\t\tvariant,\n\t\t\t\tdefaults.features ?? defaultFeatures(framework),\n\t\t\t)\n\t\t: [];\n\n\tconst packageManager =\n\t\tdefaults.packageManager ?? detectInvokedPackageManager();\n\n\tconst install = await confirm({\n\t\tmessage: `Install dependencies with ${packageManager} and start now?`,\n\t\tdefault: defaults.install ?? true,\n\t});\n\n\treturn {\n\t\tprojectName,\n\t\tpackageName,\n\t\tframework,\n\t\tvariant,\n\t\tfeatures,\n\t\tpackageManager,\n\t\tinstall,\n\t};\n}\n\nasync function promptFeatures(\n\tframework: Framework,\n\t_variant: Variant,\n\tdefaultSelected: Feature[],\n): Promise<Feature[]> {\n\tconst features: Feature[] = [];\n\n\tconst wantsLint = await promptAddLinter(defaultSelected);\n\tif (wantsLint) {\n\t\tfeatures.push(await promptLintTool(framework, defaultSelected));\n\t}\n\n\tconst extra = await checkbox({\n\t\tmessage: \"Select additional features:\",\n\t\tchoices: [\n\t\t\t{\n\t\t\t\tname: \"Vitest (unit testing)\",\n\t\t\t\tvalue: \"vitest\",\n\t\t\t\tchecked: defaultSelected.includes(\"vitest\"),\n\t\t\t},\n\t\t],\n\t});\n\tfeatures.push(...(extra as Feature[]));\n\n\treturn features;\n}\n\nasync function promptAddLinter(_defaultSelected: Feature[]): Promise<boolean> {\n\treturn select({\n\t\tmessage: \"Add linter / formatter?\",\n\t\tchoices: [\n\t\t\t{ name: \"No\", value: false as const },\n\t\t\t{ name: \"Yes\", value: true as const },\n\t\t],\n\t\tdefault: true,\n\t});\n}\n\nasync function promptLintTool(\n\tframework: Framework,\n\tdefaultSelected: Feature[],\n): Promise<\"lint\" | \"biome\"> {\n\tconst biomeLabel = isBiomeExperimental(framework)\n\t\t? \"Biome (lint + format) (Experimental)\"\n\t\t: \"Biome (lint + format)\";\n\n\tconst choices = supportsBiomeLinter(framework)\n\t\t? [\n\t\t\t\t{ name: \"ESLint + Prettier\", value: \"lint\" as const },\n\t\t\t\t{ name: biomeLabel, value: \"biome\" as const },\n\t\t\t]\n\t\t: [{ name: \"ESLint + Prettier\", value: \"lint\" as const }];\n\n\treturn select({\n\t\tmessage: \"Select linter / formatter:\",\n\t\tchoices,\n\t\tdefault: defaultSelected.includes(\"biome\") ? \"biome\" : \"lint\",\n\t});\n}\n\nasync function selectVariant(defaultVariant?: Variant): Promise<Variant> {\n\treturn select({\n\t\tmessage: \"Select a variant:\",\n\t\tchoices: [\n\t\t\t{ name: \"TypeScript\", value: \"typescript\" as const },\n\t\t\t{ name: \"JavaScript\", value: \"javascript\" as const },\n\t\t],\n\t\tdefault: defaultVariant ?? \"typescript\",\n\t});\n}\n","import { Command } from \"commander\";\nimport { execa } from \"execa\";\nimport { cyan } from \"kolorist\";\nimport packageJson from \"../package.json\";\nimport { generateProject, printError, printNextSteps } from \"./generator.js\";\nimport { runPrompts } from \"./prompts.js\";\nimport type { CreateOptions, Framework, Variant } from \"./types.js\";\nimport {\n\tassertValidPackageName,\n\tdetectInvokedPackageManager,\n\tnormalizeFeatures,\n\tparseFeatures,\n\tparseFramework,\n\tparsePackageManager,\n\tparseVariant,\n\tpmDevArgs,\n\tpmDevCommand,\n\ttoPackageName,\n} from \"./utils.js\";\n\nconst CLI_NAME = \"@xunlei-open/create-miniapp\";\n\nconst program = new Command();\n\nprogram\n\t.name(CLI_NAME)\n\t.description(\"Xunlei Open Platform plugin scaffold\")\n\t.version(packageJson.version)\n\t.argument(\"[project-name]\", \"project name\")\n\t.option(\"--framework <framework>\", \"vue | react | vanilla\")\n\t.option(\"--variant <variant>\", \"typescript | javascript\")\n\t.option(\n\t\t\"--features <features>\",\n\t\t\"comma-separated: lint,biome,vitest (lint and biome are mutually exclusive; eslint/prettier alias lint)\",\n\t)\n\t.option(\"--package-manager <pm>\", \"npm | yarn | pnpm\")\n\t.option(\"--no-install\", \"skip dependency installation\")\n\t.option(\"-y, --yes\", \"use defaults and skip prompts\")\n\t.action(async (projectName: string | undefined, opts) => {\n\t\ttry {\n\t\t\tconst defaults: Partial<CreateOptions> = {};\n\t\t\tif (projectName) defaults.projectName = projectName;\n\n\t\t\tconst frameworkInput = opts.framework;\n\t\t\tif (frameworkInput) {\n\t\t\t\tconst parsed = parseFramework(frameworkInput);\n\t\t\t\tif (!parsed) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown framework: ${frameworkInput} (supported: vue | react | vanilla)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdefaults.framework = parsed;\n\t\t\t}\n\n\t\t\tconst variantInput = opts.variant;\n\t\t\tif (variantInput) {\n\t\t\t\tconst parsed = parseVariant(variantInput);\n\t\t\t\tif (!parsed) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown variant: ${variantInput} (supported: typescript | javascript)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdefaults.variant = parsed;\n\t\t\t}\n\n\t\t\tconst featuresInput = opts.features;\n\t\t\tif (featuresInput) {\n\t\t\t\tconst parsed = parseFeatures(featuresInput);\n\t\t\t\tif (parsed.length === 0) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown features: ${featuresInput} (supported: lint, biome, vitest; eslint/prettier alias lint)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdefaults.features = parsed;\n\t\t\t}\n\n\t\t\tif (opts.install === false) defaults.install = false;\n\n\t\t\tconst packageManagerInput = opts.packageManager;\n\t\t\tif (packageManagerInput) {\n\t\t\t\tconst parsed = parsePackageManager(packageManagerInput);\n\t\t\t\tif (!parsed) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Unknown package manager: ${packageManagerInput} (supported: npm | yarn | pnpm)`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdefaults.packageManager = parsed;\n\t\t\t} else {\n\t\t\t\tdefaults.packageManager = detectInvokedPackageManager();\n\t\t\t}\n\n\t\t\tconsole.log(cyan(`\\n ${CLI_NAME} \\n`));\n\t\t\tconst options = opts.yes\n\t\t\t\t? resolveOptionsFromDefaults(defaults)\n\t\t\t\t: await runPrompts(defaults);\n\t\t\tconst targetDir = await generateProject(options);\n\n\t\t\tlet installed = false;\n\t\t\tif (options.install) {\n\t\t\t\tconst { packageManager: pm } = options;\n\t\t\t\tconsole.log(cyan(`\\nInstalling dependencies (${pm})...\\n`));\n\t\t\t\tawait execa(pm, [\"install\"], {\n\t\t\t\t\tcwd: targetDir,\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t});\n\t\t\t\tinstalled = true;\n\n\t\t\t\tprintNextSteps(targetDir, options, installed, true);\n\t\t\t\tconsole.log(cyan(`\\nStarting dev server (${pmDevCommand(pm)})...\\n`));\n\t\t\t\tawait execa(pm, pmDevArgs(pm), { cwd: targetDir, stdio: \"inherit\" });\n\t\t\t} else {\n\t\t\t\tprintNextSteps(targetDir, options, installed);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tprintError(err);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nfunction resolveOptionsFromDefaults(\n\tdefaults: Partial<CreateOptions>,\n): CreateOptions {\n\tconst projectName = defaults.projectName ?? \"xunlei-plugin-project\";\n\tconst packageName = toPackageName(defaults.packageName ?? projectName);\n\tassertValidPackageName(packageName);\n\n\tconst framework = (defaults.framework ?? \"vue\") as Framework;\n\tconst variant = (defaults.variant ?? \"typescript\") as Variant;\n\n\tconst features = normalizeFeatures(defaults.features, framework);\n\tconst packageManager =\n\t\tdefaults.packageManager ?? detectInvokedPackageManager();\n\tconst install = defaults.install ?? true;\n\n\treturn {\n\t\tprojectName,\n\t\tpackageName,\n\t\tframework,\n\t\tvariant,\n\t\tfeatures,\n\t\tpackageManager,\n\t\tinstall,\n\t};\n}\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["packageJson.version","packageJson.version"],"sources":["../package.json","../src/utils.ts","../src/generator.ts","../src/prompts.ts","../src/index.ts"],"sourcesContent":["","import validate from 'validate-npm-package-name'\nimport type { Feature, Framework, PackageManager, Variant } from './types.js'\n\nexport function toPackageName(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nexport function assertValidPackageName(name: string): void {\n const result = validate(name)\n if (!result.validForNewPackages) {\n const errors = [...(result.errors ?? []), ...(result.warnings ?? [])]\n throw new Error(`Invalid package name \"${name}\": ${errors.join(', ')}`)\n }\n}\n\nconst ALL_FEATURES: Feature[] = ['lint', 'biome', 'vitest']\n\nconst FEATURE_ALIASES: Record<string, Feature> = {\n lint: 'lint',\n eslint: 'lint',\n prettier: 'lint',\n biome: 'biome',\n vitest: 'vitest',\n}\n\nconst TEMPLATE_IDS: Record<Framework, Record<Variant, string>> = {\n vanilla: {\n javascript: 'vanilla',\n typescript: 'vanilla-ts',\n },\n vue: {\n javascript: 'vue',\n typescript: 'vue-ts',\n },\n react: {\n javascript: 'react',\n typescript: 'react-ts',\n },\n}\n\n/** Map CLI framework / variant to the templates/ directory name. */\nexport function resolveTemplateId(framework: Framework, variant: Variant): string {\n return TEMPLATE_IDS[framework][variant]\n}\n\nexport function parseFramework(input: string): Framework | undefined {\n const key = input.trim().toLowerCase()\n const map: Record<string, Framework> = {\n vanilla: 'vanilla',\n vue: 'vue',\n react: 'react',\n }\n return map[key]\n}\n\nexport function parsePackageManager(input: string): PackageManager | undefined {\n const key = input.trim().toLowerCase()\n const map: Record<string, PackageManager> = {\n npm: 'npm',\n yarn: 'yarn',\n pnpm: 'pnpm',\n }\n return map[key]\n}\n\nfunction pkgFromUserAgent(userAgent: string | undefined): { name: string; version: string } | undefined {\n if (!userAgent) return undefined\n const pkgSpec = userAgent.split(' ')[0]\n const [name, version] = pkgSpec?.split('/') ?? []\n if (!name) return undefined\n return { name, version: version ?? '' }\n}\n\n/** Infer npm / yarn / pnpm from npx, pnpx, yarn dlx, pnpm create, etc. */\nexport function detectInvokedPackageManager(): PackageManager {\n const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)\n if (pkgInfo) {\n const pm = parsePackageManager(pkgInfo.name)\n if (pm) return pm\n }\n\n const execPath = process.env.npm_execpath ?? ''\n if (execPath.includes('pnpm')) return 'pnpm'\n if (execPath.includes('yarn')) return 'yarn'\n\n return 'npm'\n}\n\nexport function pmInstallCommand(pm: PackageManager): string {\n return pm === 'yarn' ? 'yarn' : `${pm} install`\n}\n\nexport function pmDevCommand(pm: PackageManager): string {\n return pm === 'npm' ? 'npm run dev' : `${pm} dev`\n}\n\nexport function pmTestCommand(pm: PackageManager): string {\n return pm === 'npm' ? 'npm test' : `${pm} test`\n}\n\nexport function pmDevArgs(pm: PackageManager): string[] {\n return pm === 'npm' ? ['run', 'dev'] : ['dev']\n}\n\nexport function parseVariant(input: string): Variant | undefined {\n const key = input.trim().toLowerCase()\n const map: Record<string, Variant> = {\n typescript: 'typescript',\n ts: 'typescript',\n javascript: 'javascript',\n js: 'javascript',\n }\n return map[key]\n}\n\nexport function parseFeatures(input: string): Feature[] {\n const features: Feature[] = []\n for (const part of input.split(/[,+]/)) {\n const key = part.trim().toLowerCase()\n if (!key) continue\n const feature = FEATURE_ALIASES[key]\n if (feature && !features.includes(feature)) {\n features.push(feature)\n }\n }\n return resolveMutuallyExclusiveLint(features)\n}\n\nexport function hasFeature(features: Feature[], feature: Feature): boolean {\n return features.includes(feature)\n}\n\nexport function supportsOptionalFeatures(_framework: Framework): boolean {\n return true\n}\n\nexport function defaultFeatures(_framework: Framework): Feature[] {\n return []\n}\n\n/** lint and biome are mutually exclusive; prefer lint when both are present. */\nexport function resolveMutuallyExclusiveLint(features: Feature[]): Feature[] {\n if (features.includes('lint') && features.includes('biome')) {\n return features.filter((f) => f !== 'biome')\n }\n return features\n}\n\nexport function supportsBiomeLinter(framework: Framework): boolean {\n return framework === 'vanilla' || framework === 'react' || framework === 'vue'\n}\n\nexport function isBiomeExperimental(framework: Framework): boolean {\n return framework === 'vue'\n}\n\nexport function normalizeFeatures(features: Feature[] | undefined, framework: Framework): Feature[] {\n let result: Feature[] = []\n\n for (const f of features ?? []) {\n if (ALL_FEATURES.includes(f) && !result.includes(f)) {\n result.push(f)\n }\n }\n\n result = resolveMutuallyExclusiveLint(result)\n\n if (result.includes('biome') && !supportsBiomeLinter(framework)) {\n result = result.filter((f) => f !== 'biome')\n }\n\n return result\n}\n","import path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport ejs from 'ejs'\nimport fs from 'fs-extra'\nimport { green, red } from 'kolorist'\nimport packageJson from '../package.json'\nimport type { CreateOptions, TemplateContext } from './types.js'\nimport { hasFeature, pmDevCommand, pmInstallCommand, pmTestCommand, resolveTemplateId } from './utils.js'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\n\nfunction getTemplatesRoot(): string {\n // dist/index.mjs -> ../templates ; dev tsx -> ../templates\n return path.resolve(__dirname, '../templates')\n}\n\nfunction shouldSkip(relPath: string, options: CreateOptions): boolean {\n const normalized = relPath.replace(/\\\\/g, '/')\n const { features } = options\n\n if (!hasFeature(features, 'vitest')) {\n if (\n normalized.startsWith('tests/') ||\n normalized.includes('/tests/') ||\n normalized.includes('vitest.config') ||\n normalized.startsWith('src/test/')\n ) {\n return true\n }\n }\n if (!hasFeature(features, 'lint')) {\n if (normalized.endsWith('eslint.config.js') || normalized.endsWith('eslint.config.js.ejs')) {\n return true\n }\n if (relPath.endsWith('.prettierrc.ejs')) return true\n if (relPath.endsWith('.prettierignore')) return true\n }\n if (!hasFeature(features, 'biome')) {\n if (normalized === 'biome.json' || normalized.endsWith('/biome.json')) {\n return true\n }\n if (normalized === '.vscode/settings.json' || normalized.endsWith('/.vscode/settings.json')) {\n return true\n }\n }\n if (relPath.endsWith('pnpm-lock.yaml') || relPath.endsWith('package-lock.json') || relPath.endsWith('yarn.lock')) {\n return true\n }\n return false\n}\n\nasync function renderFile(src: string, dest: string, context: TemplateContext): Promise<void> {\n const content = await fs.readFile(src, 'utf-8')\n const rendered = ejs.render(content, context, { rmWhitespace: false })\n await fs.ensureDir(path.dirname(dest))\n await fs.writeFile(dest, rendered, 'utf-8')\n}\n\nasync function copyTemplateDir(\n templateDir: string,\n targetDir: string,\n context: TemplateContext,\n options: CreateOptions,\n relBase = '',\n): Promise<void> {\n const entries = await fs.readdir(templateDir, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = path.join(templateDir, entry.name)\n const relPath = relBase ? `${relBase}/${entry.name}` : entry.name\n\n if (shouldSkip(relPath, options)) continue\n\n if (entry.isDirectory()) {\n await copyTemplateDir(srcPath, path.join(targetDir, entry.name), context, options, relPath)\n continue\n }\n\n const isEjs = entry.name.endsWith('.ejs')\n const templateName = isEjs ? entry.name.slice(0, -4) : entry.name\n // npm excludes .gitignore files from published tarballs, so templates\n // store the file under a portable name and restore it during generation.\n const outName = templateName === '_gitignore' ? '.gitignore' : templateName\n const destPath = path.join(targetDir, outName)\n\n if (isEjs) {\n await renderFile(srcPath, destPath, context)\n } else {\n await fs.ensureDir(path.dirname(destPath))\n await fs.copy(srcPath, destPath)\n }\n }\n}\n\nexport async function generateProject(options: CreateOptions): Promise<string> {\n const templateId = resolveTemplateId(options.framework, options.variant)\n const templateDir = path.join(getTemplatesRoot(), templateId)\n\n if (!(await fs.pathExists(templateDir))) {\n throw new Error(`Template \"${templateId}\" is not available (${options.framework} + ${options.variant}).`)\n }\n\n const targetDir = path.resolve(process.cwd(), options.projectName)\n\n if (await fs.pathExists(targetDir)) {\n const files = await fs.readdir(targetDir)\n if (files.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDir}`)\n }\n }\n\n const context: TemplateContext = {\n projectName: options.projectName,\n packageName: options.packageName,\n packageManager: options.packageManager,\n variant: options.variant,\n features: options.features,\n devkitVersion: packageJson.version,\n isTypeScript: options.variant === 'typescript',\n }\n\n await fs.ensureDir(targetDir)\n await copyTemplateDir(templateDir, targetDir, context, options)\n\n return targetDir\n}\n\nexport function printNextSteps(\n targetDir: string,\n options: CreateOptions,\n installed: boolean,\n autoStartDev = false,\n): void {\n const rel = path.relative(process.cwd(), targetDir) || '.'\n const commands: string[] = []\n\n if (rel !== '.' && !autoStartDev) {\n commands.push(`cd ${rel}`)\n }\n const { packageManager } = options\n\n if (!installed) {\n commands.push(pmInstallCommand(packageManager))\n }\n if (!autoStartDev) {\n commands.push(pmDevCommand(packageManager))\n }\n if (hasFeature(options.features, 'vitest')) {\n commands.push(pmTestCommand(packageManager))\n }\n\n if (commands.length > 0) {\n console.log(green('\\nDone. Now run:\\n'))\n for (const command of commands) {\n console.log(` ${command}`)\n }\n console.log('')\n } else {\n console.log(green('\\nDone.\\n'))\n }\n\n console.log('Optional: Initialize Git in your project directory with:\\n')\n console.log(' git init && git add -A && git commit -m \"initial commit\"')\n console.log('')\n}\n\nexport function printError(err: unknown): void {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(red(`\\n✖ ${msg}\\n`))\n}\n","import { checkbox, confirm, input, select } from '@inquirer/prompts'\nimport type { CreateOptions, Feature, Framework, Variant } from './types.js'\nimport {\n assertValidPackageName,\n defaultFeatures,\n detectInvokedPackageManager,\n isBiomeExperimental,\n supportsBiomeLinter,\n supportsOptionalFeatures,\n toPackageName,\n} from './utils.js'\n\nexport async function runPrompts(defaults: Partial<CreateOptions> = {}): Promise<CreateOptions> {\n const projectName = await input({\n message: 'Project name:',\n default: defaults.projectName ?? 'xunlei-plugin-project',\n })\n\n const packageName = toPackageName(defaults.packageName ?? projectName)\n assertValidPackageName(packageName)\n\n const framework = await select({\n message: 'Select a framework:',\n choices: [\n { name: 'Vue', value: 'vue' as const },\n { name: 'React', value: 'react' as const },\n { name: 'Vanilla', value: 'vanilla' as const },\n ],\n default: defaults.framework ?? 'vue',\n })\n\n const variant = await selectVariant(defaults.variant)\n\n const features = supportsOptionalFeatures(framework)\n ? await promptFeatures(framework, variant, defaults.features ?? defaultFeatures(framework))\n : []\n\n const packageManager = defaults.packageManager ?? detectInvokedPackageManager()\n\n const install = await confirm({\n message: `Install dependencies with ${packageManager} and start now?`,\n default: defaults.install ?? true,\n })\n\n return {\n projectName,\n packageName,\n framework,\n variant,\n features,\n packageManager,\n install,\n }\n}\n\nasync function promptFeatures(framework: Framework, _variant: Variant, defaultSelected: Feature[]): Promise<Feature[]> {\n const features: Feature[] = []\n\n const wantsLint = await promptAddLinter(defaultSelected)\n if (wantsLint) {\n features.push(await promptLintTool(framework, defaultSelected))\n }\n\n const extra = await checkbox({\n message: 'Select additional features:',\n choices: [\n {\n name: 'Vitest (unit testing)',\n value: 'vitest',\n checked: defaultSelected.includes('vitest'),\n },\n ],\n })\n features.push(...(extra as Feature[]))\n\n return features\n}\n\nasync function promptAddLinter(_defaultSelected: Feature[]): Promise<boolean> {\n return select({\n message: 'Add linter / formatter?',\n choices: [\n { name: 'No', value: false as const },\n { name: 'Yes', value: true as const },\n ],\n default: true,\n })\n}\n\nasync function promptLintTool(framework: Framework, defaultSelected: Feature[]): Promise<'lint' | 'biome'> {\n const biomeLabel = isBiomeExperimental(framework) ? 'Biome (lint + format) (Experimental)' : 'Biome (lint + format)'\n\n const choices = supportsBiomeLinter(framework)\n ? [\n { name: 'ESLint + Prettier', value: 'lint' as const },\n { name: biomeLabel, value: 'biome' as const },\n ]\n : [{ name: 'ESLint + Prettier', value: 'lint' as const }]\n\n return select({\n message: 'Select linter / formatter:',\n choices,\n default: defaultSelected.includes('biome') ? 'biome' : 'lint',\n })\n}\n\nasync function selectVariant(defaultVariant?: Variant): Promise<Variant> {\n return select({\n message: 'Select a variant:',\n choices: [\n { name: 'TypeScript', value: 'typescript' as const },\n { name: 'JavaScript', value: 'javascript' as const },\n ],\n default: defaultVariant ?? 'typescript',\n })\n}\n","import { Command } from 'commander'\nimport { execa } from 'execa'\nimport { cyan } from 'kolorist'\nimport packageJson from '../package.json'\nimport { generateProject, printError, printNextSteps } from './generator.js'\nimport { runPrompts } from './prompts.js'\nimport type { CreateOptions, Framework, Variant } from './types.js'\nimport {\n assertValidPackageName,\n detectInvokedPackageManager,\n normalizeFeatures,\n parseFeatures,\n parseFramework,\n parsePackageManager,\n parseVariant,\n pmDevArgs,\n pmDevCommand,\n toPackageName,\n} from './utils.js'\n\nconst CLI_NAME = '@xunlei-open/create-miniapp'\n\nconst program = new Command()\n\nprogram\n .name(CLI_NAME)\n .description('Xunlei Open Platform plugin scaffold')\n .version(packageJson.version)\n .argument('[project-name]', 'project name')\n .option('--framework <framework>', 'vue | react | vanilla')\n .option('--variant <variant>', 'typescript | javascript')\n .option(\n '--features <features>',\n 'comma-separated: lint,biome,vitest (lint and biome are mutually exclusive; eslint/prettier alias lint)',\n )\n .option('--package-manager <pm>', 'npm | yarn | pnpm')\n .option('--no-install', 'skip dependency installation')\n .option('-y, --yes', 'use defaults and skip prompts')\n .action(async (projectName: string | undefined, opts) => {\n try {\n const defaults: Partial<CreateOptions> = {}\n if (projectName) defaults.projectName = projectName\n\n const frameworkInput = opts.framework\n if (frameworkInput) {\n const parsed = parseFramework(frameworkInput)\n if (!parsed) {\n throw new Error(`Unknown framework: ${frameworkInput} (supported: vue | react | vanilla)`)\n }\n defaults.framework = parsed\n }\n\n const variantInput = opts.variant\n if (variantInput) {\n const parsed = parseVariant(variantInput)\n if (!parsed) {\n throw new Error(`Unknown variant: ${variantInput} (supported: typescript | javascript)`)\n }\n defaults.variant = parsed\n }\n\n const featuresInput = opts.features\n if (featuresInput) {\n const parsed = parseFeatures(featuresInput)\n if (parsed.length === 0) {\n throw new Error(\n `Unknown features: ${featuresInput} (supported: lint, biome, vitest; eslint/prettier alias lint)`,\n )\n }\n defaults.features = parsed\n }\n\n if (opts.install === false) defaults.install = false\n\n const packageManagerInput = opts.packageManager\n if (packageManagerInput) {\n const parsed = parsePackageManager(packageManagerInput)\n if (!parsed) {\n throw new Error(`Unknown package manager: ${packageManagerInput} (supported: npm | yarn | pnpm)`)\n }\n defaults.packageManager = parsed\n } else {\n defaults.packageManager = detectInvokedPackageManager()\n }\n\n console.log(cyan(`\\n ${CLI_NAME} \\n`))\n const options = opts.yes ? resolveOptionsFromDefaults(defaults) : await runPrompts(defaults)\n const targetDir = await generateProject(options)\n\n let installed = false\n if (options.install) {\n const { packageManager: pm } = options\n console.log(cyan(`\\nInstalling dependencies (${pm})...\\n`))\n await execa(pm, ['install'], {\n cwd: targetDir,\n stdio: 'inherit',\n })\n installed = true\n\n printNextSteps(targetDir, options, installed, true)\n console.log(cyan(`\\nStarting dev server (${pmDevCommand(pm)})...\\n`))\n await execa(pm, pmDevArgs(pm), { cwd: targetDir, stdio: 'inherit' })\n } else {\n printNextSteps(targetDir, options, installed)\n }\n } catch (err) {\n printError(err)\n process.exit(1)\n }\n })\n\nfunction resolveOptionsFromDefaults(defaults: Partial<CreateOptions>): CreateOptions {\n const projectName = defaults.projectName ?? 'xunlei-plugin-project'\n const packageName = toPackageName(defaults.packageName ?? projectName)\n assertValidPackageName(packageName)\n\n const framework = (defaults.framework ?? 'vue') as Framework\n const variant = (defaults.variant ?? 'typescript') as Variant\n\n const features = normalizeFeatures(defaults.features, framework)\n const packageManager = defaults.packageManager ?? detectInvokedPackageManager()\n const install = defaults.install ?? true\n\n return {\n projectName,\n packageName,\n framework,\n variant,\n features,\n packageManager,\n install,\n }\n}\n\nprogram.parse()\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xunlei-open/create-miniapp",
3
- "version": "0.1.1-beta.5",
3
+ "version": "0.1.1-beta.7",
4
4
  "description": "Create a Xunlei Miniapp with Vanilla, Vue, or React",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.jsx # 页面入口
17
17
  │ ├── App.jsx # 页面组件
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
  coverage
16
16
 
@@ -1,41 +1,41 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "jsxRuntime": "transparent",
27
- "formatter": {
28
- "semicolons": "asNeeded",
29
- "quoteStyle": "single",
30
- "trailingCommas": "all"
31
- }
32
- },
33
- "assist": {
34
- "enabled": true,
35
- "actions": {
36
- "source": {
37
- "organizeImports": "on"
38
- }
39
- }
40
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "jsxRuntime": "transparent",
27
+ "formatter": {
28
+ "semicolons": "asNeeded",
29
+ "quoteStyle": "single",
30
+ "trailingCommas": "all"
31
+ }
32
+ },
33
+ "assist": {
34
+ "enabled": true,
35
+ "actions": {
36
+ "source": {
37
+ "organizeImports": "on"
38
+ }
39
+ }
40
+ }
41
41
  }
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.tsx # 页面入口
17
17
  │ ├── App.tsx # 页面组件
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
  coverage
16
16
  *.tsbuildinfo
@@ -1,41 +1,41 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "jsxRuntime": "transparent",
27
- "formatter": {
28
- "semicolons": "asNeeded",
29
- "quoteStyle": "single",
30
- "trailingCommas": "all"
31
- }
32
- },
33
- "assist": {
34
- "enabled": true,
35
- "actions": {
36
- "source": {
37
- "organizeImports": "on"
38
- }
39
- }
40
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "jsxRuntime": "transparent",
27
+ "formatter": {
28
+ "semicolons": "asNeeded",
29
+ "quoteStyle": "single",
30
+ "trailingCommas": "all"
31
+ }
32
+ },
33
+ "assist": {
34
+ "enabled": true,
35
+ "actions": {
36
+ "source": {
37
+ "organizeImports": "on"
38
+ }
39
+ }
40
+ }
41
41
  }
@@ -1,4 +1,5 @@
1
1
  import js from '@eslint/js'
2
+ import { defineConfig } from 'eslint/config'
2
3
  import reactHooks from 'eslint-plugin-react-hooks'
3
4
  import reactRefresh from 'eslint-plugin-react-refresh'
4
5
  import globals from 'globals'
@@ -6,7 +7,7 @@ import tseslint from 'typescript-eslint'
6
7
  import eslintConfigPrettier from 'eslint-config-prettier'
7
8
  import eslintPluginPrettier from 'eslint-plugin-prettier'
8
9
 
9
- export default tseslint.config(
10
+ export default defineConfig(
10
11
  { ignores: ['dist', 'node_modules'] },
11
12
  js.configs.recommended,
12
13
  ...tseslint.configs.recommended,
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -1,7 +1,4 @@
1
1
  {
2
2
  "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
3
+ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
7
4
  }
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.js # 页面入口与示例逻辑
17
17
  │ └── style.css # 页面样式
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
 
16
16
  # Editor directories and files
@@ -1,40 +1,40 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "formatter": {
27
- "semicolons": "asNeeded",
28
- "quoteStyle": "single",
29
- "trailingCommas": "all"
30
- }
31
- },
32
- "assist": {
33
- "enabled": true,
34
- "actions": {
35
- "source": {
36
- "organizeImports": "on"
37
- }
38
- }
39
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "formatter": {
27
+ "semicolons": "asNeeded",
28
+ "quoteStyle": "single",
29
+ "trailingCommas": "all"
30
+ }
31
+ },
32
+ "assist": {
33
+ "enabled": true,
34
+ "actions": {
35
+ "source": {
36
+ "organizeImports": "on"
37
+ }
38
+ }
39
+ }
40
40
  }
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.ts # 页面入口与示例逻辑
17
17
  │ └── style.css # 页面样式
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
 
16
16
  # Editor directories and files
@@ -1,40 +1,40 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "formatter": {
27
- "semicolons": "asNeeded",
28
- "quoteStyle": "single",
29
- "trailingCommas": "all"
30
- }
31
- },
32
- "assist": {
33
- "enabled": true,
34
- "actions": {
35
- "source": {
36
- "organizeImports": "on"
37
- }
38
- }
39
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "formatter": {
27
+ "semicolons": "asNeeded",
28
+ "quoteStyle": "single",
29
+ "trailingCommas": "all"
30
+ }
31
+ },
32
+ "assist": {
33
+ "enabled": true,
34
+ "actions": {
35
+ "source": {
36
+ "organizeImports": "on"
37
+ }
38
+ }
39
+ }
40
40
  }
@@ -1,10 +1,11 @@
1
1
  import js from '@eslint/js'
2
+ import { defineConfig } from 'eslint/config'
2
3
  import globals from 'globals'
3
4
  import tseslint from 'typescript-eslint'
4
5
  import eslintConfigPrettier from 'eslint-config-prettier'
5
6
  import eslintPluginPrettier from 'eslint-plugin-prettier'
6
7
 
7
- export default tseslint.config(
8
+ export default defineConfig(
8
9
  { ignores: ['dist', 'node_modules'] },
9
10
  js.configs.recommended,
10
11
  ...tseslint.configs.recommended,
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.js # 页面入口
17
17
  │ ├── App.vue # 页面组件
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
  coverage
16
16
  *.tsbuildinfo
@@ -1,46 +1,46 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "formatter": {
27
- "semicolons": "asNeeded",
28
- "quoteStyle": "single",
29
- "trailingCommas": "all"
30
- }
31
- },
32
- "html": {
33
- "experimentalFullSupportEnabled": true,
34
- "formatter": {
35
- "enabled": true
36
- }
37
- },
38
- "assist": {
39
- "enabled": true,
40
- "actions": {
41
- "source": {
42
- "organizeImports": "on"
43
- }
44
- }
45
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "formatter": {
27
+ "semicolons": "asNeeded",
28
+ "quoteStyle": "single",
29
+ "trailingCommas": "all"
30
+ }
31
+ },
32
+ "html": {
33
+ "experimentalFullSupportEnabled": true,
34
+ "formatter": {
35
+ "enabled": true
36
+ }
37
+ },
38
+ "assist": {
39
+ "enabled": true,
40
+ "actions": {
41
+ "source": {
42
+ "organizeImports": "on"
43
+ }
44
+ }
45
+ }
46
46
  }
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -10,8 +10,8 @@
10
10
 
11
11
  ```text
12
12
  .
13
- ├── dist/ # 开发或构建生成的代码产物
14
- ├── release/ # 打包生成的 ZIP 安装包
13
+ ├── dist/ # 开发产物,供宿主加载与 HMR
14
+ ├── output/ # 生产构建;打包成功后只保留 ZIP
15
15
  ├── src/ # 应用源码
16
16
  │ ├── main.ts # 页面入口
17
17
  │ ├── App.vue # 页面组件
@@ -10,7 +10,7 @@ lerna-debug.log*
10
10
  node_modules
11
11
  dist
12
12
  dist-ssr
13
- release
13
+ output
14
14
  *.local
15
15
  coverage
16
16
  *.tsbuildinfo
@@ -1,46 +1,46 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
- "vcs": {
4
- "enabled": false
5
- },
6
- "files": {
7
- "ignoreUnknown": false
8
- },
9
- "formatter": {
10
- "enabled": true,
11
- "indentStyle": "tab",
12
- "indentWidth": 2,
13
- "lineWidth": 120,
14
- "lineEnding": "auto"
15
- },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "correctness": {
21
- "noUndeclaredVariables": "error"
22
- }
23
- }
24
- },
25
- "javascript": {
26
- "formatter": {
27
- "semicolons": "asNeeded",
28
- "quoteStyle": "single",
29
- "trailingCommas": "all"
30
- }
31
- },
32
- "html": {
33
- "experimentalFullSupportEnabled": true,
34
- "formatter": {
35
- "enabled": true
36
- }
37
- },
38
- "assist": {
39
- "enabled": true,
40
- "actions": {
41
- "source": {
42
- "organizeImports": "on"
43
- }
44
- }
45
- }
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "vcs": {
4
+ "enabled": false
5
+ },
6
+ "files": {
7
+ "ignoreUnknown": false
8
+ },
9
+ "formatter": {
10
+ "enabled": true,
11
+ "indentStyle": "tab",
12
+ "indentWidth": 2,
13
+ "lineWidth": 120,
14
+ "lineEnding": "auto"
15
+ },
16
+ "linter": {
17
+ "enabled": true,
18
+ "rules": {
19
+ "recommended": true,
20
+ "correctness": {
21
+ "noUndeclaredVariables": "error"
22
+ }
23
+ }
24
+ },
25
+ "javascript": {
26
+ "formatter": {
27
+ "semicolons": "asNeeded",
28
+ "quoteStyle": "single",
29
+ "trailingCommas": "all"
30
+ }
31
+ },
32
+ "html": {
33
+ "experimentalFullSupportEnabled": true,
34
+ "formatter": {
35
+ "enabled": true
36
+ }
37
+ },
38
+ "assist": {
39
+ "enabled": true,
40
+ "actions": {
41
+ "source": {
42
+ "organizeImports": "on"
43
+ }
44
+ }
45
+ }
46
46
  }
@@ -1,11 +1,12 @@
1
1
  import js from '@eslint/js'
2
+ import { defineConfig } from 'eslint/config'
2
3
  import pluginVue from 'eslint-plugin-vue'
3
4
  import globals from 'globals'
4
5
  import tseslint from 'typescript-eslint'
5
6
  import eslintConfigPrettier from 'eslint-config-prettier'
6
7
  import eslintPluginPrettier from 'eslint-plugin-prettier'
7
8
 
8
- export default tseslint.config(
9
+ export default defineConfig(
9
10
  { ignores: ['dist', 'node_modules'] },
10
11
  js.configs.recommended,
11
12
  ...tseslint.configs.recommended,
@@ -1,16 +1,16 @@
1
1
  {
2
- "manifest_version": 1,
3
- "name": "示例插件",
4
- "title": "示例插件",
5
- "description": "一个迅雷微应用示例",
6
- "version": "1.0.0",
7
- "entry": {
8
- "type": "miniapp",
9
- "url": "index.html"
10
- },
11
- "window": {
12
- "width": 900,
13
- "height": 700
14
- },
15
- "permissions": ["tasks.create"]
2
+ "manifest_version": 1,
3
+ "name": "示例插件",
4
+ "title": "示例插件",
5
+ "description": "一个迅雷微应用示例",
6
+ "version": "1.0.0",
7
+ "entry": {
8
+ "type": "miniapp",
9
+ "url": "index.html"
10
+ },
11
+ "window": {
12
+ "width": 900,
13
+ "height": 700
14
+ },
15
+ "permissions": ["tasks.create"]
16
16
  }
@@ -1,7 +1,4 @@
1
1
  {
2
2
  "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
3
+ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
7
4
  }