feat: Cli 优化
This commit is contained in:
parent
c64c7e0ea0
commit
cb0e9763f0
15
config.json
15
config.json
@ -1,8 +1,13 @@
|
|||||||
{
|
{
|
||||||
|
"name": "测试",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"description": "cordova apk build",
|
||||||
|
"author": {
|
||||||
|
"name": "taolin",
|
||||||
|
"email": "taolin@taoya.art"
|
||||||
|
},
|
||||||
"homeUrl": "https://www.baidu.com",
|
"homeUrl": "https://www.baidu.com",
|
||||||
"appId": "asd",
|
"appId": "com.taoya.test",
|
||||||
"appName": "asd",
|
|
||||||
"appVersion": "1.0.0",
|
|
||||||
"packType": "debug",
|
"packType": "debug",
|
||||||
"pushEmail": "asd@qq.com"
|
"pushEmail": "taolin@taoya.art"
|
||||||
}
|
}
|
||||||
|
57
config.xml
57
config.xml
@ -1,33 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" id="com.example.tao" version="1.0.0">
|
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" id="com.taoya.test" version="1.1.1">
|
||||||
<name>APP</name>
|
<name>测试</name>
|
||||||
<description>app</description>
|
<description>cordova apk build</description>
|
||||||
<author email="dev@cordova.apache.org" href="https://cordova.apache.org"></author>
|
<author email="taolin@taoya.art">taolin</author>
|
||||||
<content src="http://test.taoya.art/" />
|
<content src="https://www.baidu.com"></content>
|
||||||
<access origin="*" />
|
<access origin="*"></access>
|
||||||
<allow-intent href="http://*/*"/>
|
<allow-intent href="http://*/*"></allow-intent>
|
||||||
<allow-intent href="https://*/*"/>
|
<allow-intent href="https://*/*"></allow-intent>
|
||||||
<allow-intent href="tel:*"/>
|
<allow-intent href="tel:*"></allow-intent>
|
||||||
<allow-intent href="sms:*"/>
|
<allow-intent href="sms:*"></allow-intent>
|
||||||
<allow-intent href="mailto:*"/>
|
<allow-intent href="mailto:*"></allow-intent>
|
||||||
<allow-intent href="geo:*"/>
|
<allow-intent href="geo:*"></allow-intent>
|
||||||
<allow-intent href="market:*"/>
|
<allow-intent href="market:*"></allow-intent>
|
||||||
|
<platform name="android">
|
||||||
<platform name="android">
|
<preference name="Fullscreen"></preference>
|
||||||
<preference name="Fullscreen" value="true"/>
|
<icon src="logo.png"></icon>
|
||||||
<icon src="logo.png"></icon>
|
</platform>
|
||||||
</platform>
|
<preference name="android-minSdkVersion" value="24"></preference>
|
||||||
|
<preference name="android-targetSdkVersion" value="35"></preference>
|
||||||
|
<preference name="android-compileSdkVersion" value="35"></preference>
|
||||||
<!-- 设置Java和Gradle版本 -->
|
<preference name="GradleVersion" value="8.7"></preference>
|
||||||
<preference name="android-minSdkVersion" value="24" />
|
<preference name="JavaVersion" value="17"></preference>
|
||||||
<preference name="android-targetSdkVersion" value="35" />
|
<preference name="AndroidXEnabled"></preference>
|
||||||
<preference name="android-compileSdkVersion" value="35" />
|
<preference name="GradlePluginKotlinEnabled"></preference>
|
||||||
<preference name="GradleVersion" value="8.7" />
|
<preference name="GradlePluginKotlinCodeStyle" value="official"></preference>
|
||||||
<preference name="JavaVersion" value="17" />
|
<preference name="GradlePluginKotlinVersion" value="1.9.24"></preference>
|
||||||
<preference name="AndroidXEnabled" value="true" />
|
|
||||||
<!-- Kotlin -->
|
|
||||||
<preference name="GradlePluginKotlinEnabled" value="true" />
|
|
||||||
<preference name="GradlePluginKotlinCodeStyle" value="official" />
|
|
||||||
<preference name="GradlePluginKotlinVersion" value="1.9.24" />
|
|
||||||
</widget>
|
</widget>
|
||||||
|
31
package-lock.json
generated
31
package-lock.json
generated
@ -32,6 +32,7 @@
|
|||||||
"cordova-plugin-vibration": "^3.1.1",
|
"cordova-plugin-vibration": "^3.1.1",
|
||||||
"es6-promise-plugin": "^4.2.2",
|
"es6-promise-plugin": "^4.2.2",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.17.0",
|
||||||
|
"fast-xml-parser": "^4.5.1",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
@ -3988,6 +3989,29 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-xml-parser": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/naturalintelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"strnum": "^1.0.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fxparser": "src/cli/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz",
|
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz",
|
||||||
@ -8562,6 +8586,13 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strnum": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmmirror.com/strnum/-/strnum-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"build": "cordova build android",
|
"build": "cordova build android",
|
||||||
"dev": "node scripts/dev.js",
|
"dev": "node scripts/dev.js",
|
||||||
"logo": "tsx scripts/logo.ts",
|
"logo": "tsx scripts/logo.ts",
|
||||||
"allInOne": "npm run clean && npm i && npm run ad"
|
"allInOne": "npm run clean && npm i && npm run ad",
|
||||||
|
"platform": "tsx scripts/platform.ts"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "taolin taolin@taoya.art",
|
"author": "taolin taolin@taoya.art",
|
||||||
@ -38,6 +39,7 @@
|
|||||||
"cordova-plugin-vibration": "^3.1.1",
|
"cordova-plugin-vibration": "^3.1.1",
|
||||||
"es6-promise-plugin": "^4.2.2",
|
"es6-promise-plugin": "^4.2.2",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.17.0",
|
||||||
|
"fast-xml-parser": "^4.5.1",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
@ -61,5 +63,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^12.1.0"
|
"commander": "^12.1.0"
|
||||||
}
|
},
|
||||||
|
"packageManager": "pnpm@8.10.2+sha1.e0b68270e89c817ff88b7be62466a2128c53af02"
|
||||||
}
|
}
|
104
scripts/build.ts
Normal file
104
scripts/build.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { readFile, writeFile } from 'node:fs/promises'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { XMLParser, XMLBuilder } from 'fast-xml-parser'
|
||||||
|
import consola from 'consola'
|
||||||
|
|
||||||
|
// 获取当前文件的目录路径
|
||||||
|
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
// 获取项目根目录路径
|
||||||
|
const root = join(__dirname, '..')
|
||||||
|
|
||||||
|
// 定义配置文件的类型接口
|
||||||
|
interface AppConfig {
|
||||||
|
name: string // 应用名称
|
||||||
|
version: string // 应用版本号
|
||||||
|
description: string // 应用描述
|
||||||
|
author: { // 作者信息
|
||||||
|
name: string // 作者名称
|
||||||
|
email: string // 作者邮箱
|
||||||
|
}
|
||||||
|
homeUrl: string // 应用主页 URL
|
||||||
|
appId: string // 应用 ID
|
||||||
|
packType: 'debug' | 'release' // 打包类型
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新 config.xml 文件的配置
|
||||||
|
* @param config 应用配置对象
|
||||||
|
*/
|
||||||
|
async function updateConfigXml(config: AppConfig) {
|
||||||
|
// 构建 config.xml 的完整路径
|
||||||
|
const xmlPath = join(root, 'config.xml')
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 读取现有的 config.xml 文件内容
|
||||||
|
const xmlContent = await readFile(xmlPath, 'utf-8')
|
||||||
|
|
||||||
|
// 创建 XML 解析器实例,配置属性处理选项
|
||||||
|
const parser = new XMLParser({
|
||||||
|
ignoreAttributes: false, // 不忽略 XML 属性
|
||||||
|
attributeNamePrefix: '@_' // 属性名称前缀
|
||||||
|
})
|
||||||
|
// 解析 XML 内容为 JavaScript 对象
|
||||||
|
const xmlObj = parser.parse(xmlContent)
|
||||||
|
|
||||||
|
// 更新配置信息
|
||||||
|
xmlObj.widget['@_version'] = config.version // 更新版本号
|
||||||
|
xmlObj.widget['@_id'] = config.appId // 更新应用 ID
|
||||||
|
xmlObj.widget.name = config.name // 更新应用名称
|
||||||
|
xmlObj.widget.description = config.description // 更新应用描述
|
||||||
|
xmlObj.widget.author = {
|
||||||
|
'#text': config.author.name, // 作者名称作为节点文本
|
||||||
|
'@_email': config.author.email // 邮箱作为属性
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新或添加 content 标签的 src 属性
|
||||||
|
if (!xmlObj.widget.content) {
|
||||||
|
xmlObj.widget.content = { '@_src': config.homeUrl }
|
||||||
|
} else {
|
||||||
|
xmlObj.widget.content['@_src'] = config.homeUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 创建 XML 构建器实例
|
||||||
|
const builder = new XMLBuilder({
|
||||||
|
ignoreAttributes: false,
|
||||||
|
attributeNamePrefix: '@_',
|
||||||
|
format: true // 启用格式化输出
|
||||||
|
})
|
||||||
|
// 将对象转换回 XML 字符串
|
||||||
|
const newXmlContent = builder.build(xmlObj)
|
||||||
|
|
||||||
|
// 将更新后的内容写回文件
|
||||||
|
await writeFile(xmlPath, newXmlContent, 'utf-8')
|
||||||
|
consola.success('config.xml has been updated')
|
||||||
|
} catch (err) {
|
||||||
|
consola.error('Failed to update config.xml:', err)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主函数:读取配置并执行更新
|
||||||
|
*/
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
// 读取 config.json 配置文件
|
||||||
|
const configPath = join(root, 'config.json')
|
||||||
|
const configContent = await readFile(configPath, 'utf-8')
|
||||||
|
const config: AppConfig = JSON.parse(configContent)
|
||||||
|
|
||||||
|
// 使用配置更新 config.xml
|
||||||
|
await updateConfigXml(config)
|
||||||
|
|
||||||
|
// TODO: 这里可以添加其他构建步骤
|
||||||
|
consola.success('Build completed successfully')
|
||||||
|
} catch (err) {
|
||||||
|
consola.error('Build failed:', err)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行主函数
|
||||||
|
main()
|
102
scripts/cmd.ts
102
scripts/cmd.ts
@ -2,9 +2,25 @@ import { z } from 'zod';
|
|||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { intro, outro, text, select, isCancel, cancel, group } from '@clack/prompts';
|
import { intro, outro, text, select, isCancel, cancel, group } from '@clack/prompts';
|
||||||
import { bgRed } from 'picocolors';
|
|
||||||
|
|
||||||
const ConfigSchema = z.object({
|
const ConfigSchema = z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "应用名称不能为空"
|
||||||
|
}),
|
||||||
|
version: z.string().regex(/^\d+\.\d+\.\d+$/, {
|
||||||
|
message: "版本号格式必须为 x.x.x"
|
||||||
|
}),
|
||||||
|
description: z.string().min(1, {
|
||||||
|
message: "应用描述不能为空"
|
||||||
|
}),
|
||||||
|
author: z.object({
|
||||||
|
name: z.string().min(1, {
|
||||||
|
message: "作者名称不能为空"
|
||||||
|
}),
|
||||||
|
email: z.string().email({
|
||||||
|
message: "作者邮箱格式不正确"
|
||||||
|
})
|
||||||
|
}),
|
||||||
homeUrl: z.string().url({
|
homeUrl: z.string().url({
|
||||||
message: "URL格式不正确"
|
message: "URL格式不正确"
|
||||||
}),
|
}),
|
||||||
@ -13,12 +29,6 @@ const ConfigSchema = z.object({
|
|||||||
}).regex(/^[a-zA-Z0-9._-]+$/, {
|
}).regex(/^[a-zA-Z0-9._-]+$/, {
|
||||||
message: "应用ID只能包含字母、数字、点、下划线和横线"
|
message: "应用ID只能包含字母、数字、点、下划线和横线"
|
||||||
}),
|
}),
|
||||||
appName: z.string().min(1, {
|
|
||||||
message: "应用名称不能为空"
|
|
||||||
}),
|
|
||||||
appVersion: z.string().regex(/^\d+\.\d+\.\d+$/, {
|
|
||||||
message: "版本号格式必须为 x.x.x"
|
|
||||||
}),
|
|
||||||
packType: z.enum(['release', 'debug'], {
|
packType: z.enum(['release', 'debug'], {
|
||||||
errorMap: () => ({ message: "打包类型必须是 release 或 debug" })
|
errorMap: () => ({ message: "打包类型必须是 release 或 debug" })
|
||||||
}),
|
}),
|
||||||
@ -34,6 +44,45 @@ async function main() {
|
|||||||
|
|
||||||
const config = await group(
|
const config = await group(
|
||||||
{
|
{
|
||||||
|
name: () => text({
|
||||||
|
message: '请输入应用名称',
|
||||||
|
validate(value) {
|
||||||
|
if (!value.length) return '应用名称不能为空';
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
version: () => text({
|
||||||
|
message: '请输入应用版本号',
|
||||||
|
validate(value) {
|
||||||
|
if (!/^\d+\.\d+\.\d+$/.test(value)) {
|
||||||
|
return '请输入正确的版本号,例如: 1.0.0';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
description: () => text({
|
||||||
|
message: '请输入应用描述',
|
||||||
|
validate(value) {
|
||||||
|
if (!value.length) return '应用描述不能为空';
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
authorName: () => text({
|
||||||
|
message: '请输入作者名称',
|
||||||
|
validate(value) {
|
||||||
|
if (!value.length) return '作者名称不能为空';
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
authorEmail: () => text({
|
||||||
|
message: '请输入作者邮箱',
|
||||||
|
validate(value) {
|
||||||
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
||||||
|
return '请输入正确的邮箱地址';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
homeUrl: () => text({
|
homeUrl: () => text({
|
||||||
message: '请输入主页URL',
|
message: '请输入主页URL',
|
||||||
validate(value) {
|
validate(value) {
|
||||||
@ -55,22 +104,6 @@ async function main() {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
appName: () => text({
|
|
||||||
message: '请输入应用名称',
|
|
||||||
validate(value) {
|
|
||||||
if (!value.length) return '应用名称不能为空';
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
|
|
||||||
appVersion: () => text({
|
|
||||||
message: '请输入应用版本号',
|
|
||||||
validate(value) {
|
|
||||||
if (!/^\d+\.\d+\.\d+$/.test(value)) {
|
|
||||||
return '请输入正确的版本号,例如: 1.0.0';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
|
|
||||||
packType: () => select({
|
packType: () => select({
|
||||||
message: '请选择打包类型',
|
message: '请选择打包类型',
|
||||||
options: [
|
options: [
|
||||||
@ -104,14 +137,29 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重构配置对象以匹配所需格式
|
||||||
|
const formattedConfig = {
|
||||||
|
name: config.name,
|
||||||
|
version: config.version,
|
||||||
|
description: config.description,
|
||||||
|
author: {
|
||||||
|
name: config.authorName,
|
||||||
|
email: config.authorEmail
|
||||||
|
},
|
||||||
|
homeUrl: config.homeUrl,
|
||||||
|
appId: config.appId,
|
||||||
|
packType: config.packType,
|
||||||
|
pushEmail: config.pushEmail
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 使用zod验证配置
|
// 使用zod验证配置
|
||||||
const result = ConfigSchema.safeParse(config);
|
const result = ConfigSchema.safeParse(formattedConfig);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
cancel('配置验证失败');
|
cancel('配置验证失败');
|
||||||
result.error.errors.forEach(error => {
|
result.error.errors.forEach(error => {
|
||||||
console.error(bgRed(` ${error.path.join('.')}: ${error.message} `));
|
console.error((` ${error.path.join('.')}: ${error.message} `));
|
||||||
});
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@ -125,7 +173,7 @@ async function main() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
cancel('保存配置文件时出错');
|
cancel('保存配置文件时出错');
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(bgRed(` ${error.message} `));
|
console.error((` ${error.message} `));
|
||||||
}
|
}
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@ -134,7 +182,7 @@ async function main() {
|
|||||||
main().catch(error => {
|
main().catch(error => {
|
||||||
cancel('发生意外错误');
|
cancel('发生意外错误');
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(bgRed(` ${error.message} `));
|
console.error((` ${error.message} `));
|
||||||
}
|
}
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
53
scripts/dist.ts
Normal file
53
scripts/dist.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { mkdir, copyFile, access } from 'node:fs/promises'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import consola from 'consola'
|
||||||
|
|
||||||
|
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
const root = join(__dirname, '..')
|
||||||
|
|
||||||
|
// 检查文件是否存在的辅助函数
|
||||||
|
async function fileExists(path: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await access(path)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// 确保 dist 目录存在
|
||||||
|
try {
|
||||||
|
await mkdir(join(root, 'dist'))
|
||||||
|
consola.info('dist directory created')
|
||||||
|
} catch (err) {
|
||||||
|
consola.info('dist directory already exists')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义 APK 文件路径
|
||||||
|
const apkPaths = {
|
||||||
|
debug: {
|
||||||
|
source: join(root, 'platforms/android/app/build/outputs/apk/debug/app-debug.apk'),
|
||||||
|
target: join(root, 'dist/app-debug.apk')
|
||||||
|
},
|
||||||
|
release: {
|
||||||
|
source: join(root, 'platforms/android/app/build/outputs/apk/release/app-release.apk'),
|
||||||
|
target: join(root, 'dist/app-release.apk')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试复制 debug 和 release 版本的 APK
|
||||||
|
for (const [type, paths] of Object.entries(apkPaths)) {
|
||||||
|
if (await fileExists(paths.source)) {
|
||||||
|
try {
|
||||||
|
await copyFile(paths.source, paths.target)
|
||||||
|
consola.success(`${type} APK copied to dist/app-${type}.apk`)
|
||||||
|
} catch (err) {
|
||||||
|
consola.warn(`Failed to copy ${type} APK:`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
2
scripts/index.ts
Normal file
2
scripts/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './dist' // 导出 dist 脚本
|
||||||
|
export * from './logo' // 替换 Logo
|
73
scripts/platform.ts
Normal file
73
scripts/platform.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { exec } from 'node:child_process'
|
||||||
|
import { promisify } from 'node:util'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { access } from 'node:fs/promises'
|
||||||
|
import consola from 'consola'
|
||||||
|
|
||||||
|
const execAsync = promisify(exec)
|
||||||
|
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
const root = join(__dirname, '..')
|
||||||
|
|
||||||
|
async function checkPlatformExists(platform: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await access(join(root, 'platforms', platform))
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addPlatform(platform: string) {
|
||||||
|
try {
|
||||||
|
// 检查平台是否已存在
|
||||||
|
const exists = await checkPlatformExists(platform)
|
||||||
|
if (exists) {
|
||||||
|
consola.info(`Platform ${platform} already exists`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加平台
|
||||||
|
consola.info(`Adding ${platform} platform...`)
|
||||||
|
const { stdout, stderr } = await execAsync(`cordova platform add ${platform}`, {
|
||||||
|
cwd: root,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
NODE_ENV: 'development'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (stderr) {
|
||||||
|
consola.warn(stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stdout) {
|
||||||
|
consola.info(stdout)
|
||||||
|
}
|
||||||
|
|
||||||
|
consola.success(`Platform ${platform} added successfully`)
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
consola.error('Failed to add platform:', error.message)
|
||||||
|
} else {
|
||||||
|
consola.error('An unknown error occurred while adding platform')
|
||||||
|
}
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
// 添加 Android 平台
|
||||||
|
await addPlatform('android')
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
consola.error('Platform addition failed:', error.message)
|
||||||
|
} else {
|
||||||
|
consola.error('An unknown error occurred')
|
||||||
|
}
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user