Initial TrueGrowth source import

This commit is contained in:
2026-07-07 09:36:36 +08:00
commit 3b6781d695
2283 changed files with 691996 additions and 0 deletions

280
scripts/publish-npm.js Normal file
View File

@@ -0,0 +1,280 @@
#!/usr/bin/env node
/**
* npm 发布脚本
*
* 功能:
* 1. 构建项目(使用相对路径)
* 2. 在 dist 目录生成 npm 专用的 package.json
* 3. 发布到 npm
*
* 使用免费 CDN 访问:
* - unpkg: https://unpkg.com/aitu-app@版本号/index.html
* - jsdelivr: https://cdn.jsdelivr.net/npm/aitu-app@版本号/index.html
*
* 用法:
* node scripts/publish-npm.js [--dry-run] [--skip-build]
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// 配置
const CONFIG = {
// npm 包名(使用非 scoped 包名,便于公开访问)
packageName: 'aitu-app',
distDir: path.resolve(__dirname, '../dist/apps/web'),
rootPackageJson: path.resolve(__dirname, '../package.json'),
};
// 解析命令行参数
const args = process.argv.slice(2);
const isDryRun = args.includes('--dry-run');
const skipBuild = args.includes('--skip-build');
// 获取 OTP 参数 (--otp=123456)
const otpArg = args.find(arg => arg.startsWith('--otp='));
const otp = otpArg ? otpArg.split('=')[1] : null;
// 颜色输出
const colors = {
reset: '\x1b[0m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
red: '\x1b[31m',
};
function log(message, color = 'reset') {
console.log(`${colors[color]}${message}${colors.reset}`);
}
function logStep(step, message) {
log(`\n[${step}] ${message}`, 'blue');
}
function logSuccess(message) {
log(`${message}`, 'green');
}
function logWarning(message) {
log(`${message}`, 'yellow');
}
function logError(message) {
log(`${message}`, 'red');
}
// 执行命令
function exec(command, options = {}) {
log(` 执行: ${command}`, 'yellow');
try {
execSync(command, { stdio: 'inherit', ...options });
return true;
} catch (error) {
logError(`命令执行失败: ${command}`);
return false;
}
}
// 读取根目录 package.json 获取版本号
function getVersion() {
const pkg = JSON.parse(fs.readFileSync(CONFIG.rootPackageJson, 'utf-8'));
return pkg.version;
}
// 生成 npm 发布用的 package.json
function generateNpmPackageJson(version) {
const npmPackage = {
name: CONFIG.packageName,
version: version,
description: 'Opentu static assets for CDN (HTML not included)',
keywords: [
'aitu',
'whiteboard',
'mindmap',
'flowchart',
'drawing',
'AI',
'image-generation',
'video-generation'
],
homepage: 'https://opentu.ai',
repository: {
type: 'git',
url: 'https://github.com/ljquan/aitu.git'
},
bugs: {
url: 'https://github.com/ljquan/aitu/issues'
},
license: 'MIT',
author: 'ljquan',
files: [
'assets/**',
'version.json',
'icons/**',
'logo/**',
'favicon.ico',
'manifest.json'
],
publishConfig: {
access: 'public'
}
};
return npmPackage;
}
// 生成 README
function generateReadme(version) {
return `# Opentu (开图) - AI 图片视频创作工具
[![npm version](https://img.shields.io/npm/v/${CONFIG.packageName}.svg)](https://www.npmjs.com/package/${CONFIG.packageName})
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
## 在线访问
通过免费 CDN 直接访问:
### unpkg (推荐)
- **最新版**: [https://unpkg.com/${CONFIG.packageName}/index.html](https://unpkg.com/${CONFIG.packageName}/index.html)
- **指定版本**: [https://unpkg.com/${CONFIG.packageName}@${version}/index.html](https://unpkg.com/${CONFIG.packageName}@${version}/index.html)
### jsDelivr
- **最新版**: [https://cdn.jsdelivr.net/npm/${CONFIG.packageName}/index.html](https://cdn.jsdelivr.net/npm/${CONFIG.packageName}/index.html)
- **指定版本**: [https://cdn.jsdelivr.net/npm/${CONFIG.packageName}@${version}/index.html](https://cdn.jsdelivr.net/npm/${CONFIG.packageName}@${version}/index.html)
## 功能特性
- 🎨 **AI 图片生成** - 通过 Gemini 生成精美图片
- 🎬 **AI 视频生成** - 支持 Veo3、Sora-2 等模型
- 🧠 **思维导图** - 快速整理思路
- 📊 **流程图** - 可视化流程设计
- ✏️ **自由绘画** - 手绘风格绘图
- 💾 **自动保存** - 本地数据持久化
- 📱 **PWA 支持** - 可安装为桌面应用
## 本地部署
1. 下载此 npm 包的内容
2. 使用任意静态文件服务器托管
\`\`\`bash
# 使用 npx serve
npx serve ./node_modules/${CONFIG.packageName}
# 或使用 http-server
npx http-server ./node_modules/${CONFIG.packageName}
\`\`\`
## 源代码
GitHub: [https://github.com/ljquan/aitu](https://github.com/ljquan/aitu)
## 许可证
MIT License
`;
}
// 主流程
async function main() {
log('\n🚀 Opentu npm 发布脚本\n', 'blue');
if (isDryRun) {
logWarning('DRY RUN 模式 - 不会实际发布');
}
// 步骤 1: 构建项目
if (!skipBuild) {
logStep('1/4', '构建项目');
if (!exec('npm run build:web')) {
logError('构建失败');
process.exit(1);
}
logSuccess('构建完成');
} else {
logStep('1/4', '跳过构建(使用现有构建产物)');
}
// 步骤 2: 检查 dist 目录
logStep('2/4', '检查构建产物');
if (!fs.existsSync(CONFIG.distDir)) {
logError(`构建目录不存在: ${CONFIG.distDir}`);
process.exit(1);
}
const indexHtml = path.join(CONFIG.distDir, 'index.html');
if (!fs.existsSync(indexHtml)) {
logError('index.html 不存在');
process.exit(1);
}
logSuccess('构建产物检查通过');
// 步骤 3: 生成 npm package.json 和 README
logStep('3/4', '生成 npm 发布文件');
const version = getVersion();
log(` 版本号: ${version}`);
const npmPackageJson = generateNpmPackageJson(version);
const npmPackageJsonPath = path.join(CONFIG.distDir, 'package.json');
fs.writeFileSync(npmPackageJsonPath, JSON.stringify(npmPackageJson, null, 2));
logSuccess(`生成 package.json`);
const readme = generateReadme(version);
const readmePath = path.join(CONFIG.distDir, 'README.md');
fs.writeFileSync(readmePath, readme);
logSuccess(`生成 README.md`);
// 移除不需要发布的文件
const filesToRemove = ['stats.html', 'sw.js.map'];
filesToRemove.forEach(file => {
const filePath = path.join(CONFIG.distDir, file);
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
log(` 移除: ${file}`);
}
});
// 步骤 4: 发布到 npm
logStep('4/4', '发布到 npm');
if (isDryRun) {
log('\n📦 DRY RUN - 将要发布的内容:', 'yellow');
exec(`ls -la "${CONFIG.distDir}"`);
log('\n📄 package.json 内容:', 'yellow');
console.log(JSON.stringify(npmPackageJson, null, 2));
logWarning('\n使用 --dry-run 模式,未实际发布');
} else {
// 切换到 dist 目录并发布(使用 cd 确保在正确目录)
let publishCmd = `cd "${CONFIG.distDir}" && npm publish --access public --registry https://registry.npmjs.org`;
// 如果提供了 OTP添加到命令中
if (otp) {
publishCmd += ` --otp=${otp}`;
log(` 使用 OTP: ${otp.slice(0, 2)}****`);
}
if (!exec(publishCmd)) {
logError('发布失败');
if (!otp) {
log('\n💡 提示:如果启用了 2FA请使用 --otp=123456 参数', 'yellow');
log(' 例如: pnpm run npm:publish --skip-build --otp=123456', 'yellow');
}
process.exit(1);
}
logSuccess('发布成功!');
}
// 输出访问链接
log('\n🎉 完成!', 'green');
log('\n📌 CDN 访问链接:', 'blue');
log(` unpkg: https://unpkg.com/${CONFIG.packageName}@${version}/index.html`);
log(` jsdelivr: https://cdn.jsdelivr.net/npm/${CONFIG.packageName}@${version}/index.html`);
log(` 最新版: https://unpkg.com/${CONFIG.packageName}/index.html`);
}
main().catch(error => {
logError(`脚本执行失败: ${error.message}`);
process.exit(1);
});