Compare commits

..

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
c615526142 ci: Address code review feedback
- Fix grammatical error in Chinese text (release-info.md)
- Use jq for reliable JSON parsing instead of grep with Perl regex
- Improve error handling with clearer warning messages

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 02:37:55 +00:00
copilot-swe-agent[bot]
7105571ed7 ci: Improve release workflow with automated changelog and OneKey packages
- Created .github/release-template/release-info.md with fixed release information
- Created script/generate-changelog.sh to generate changelog from latest 10 commits (excluding release commits)
- Modified .github/workflows/release.yml to:
  - Download NapCat.Shell.Windows.OneKey.zip and NapCat.Framework.Windows.OneKey.zip from latest release
  - Generate release notes by combining fixed template with automated changelog
  - Upload OneKey packages along with other build artifacts

Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-11-07 02:35:24 +00:00
copilot-swe-agent[bot]
372b829af2 Initial plan 2025-11-07 02:30:22 +00:00
30 changed files with 316 additions and 358 deletions

View File

@@ -0,0 +1,25 @@
[使用文档](https://napneko.github.io/)
## Windows 一键包
我们提供了轻量化一键部署方案
相对于普通需要安装QQ的方案,下面已内置QQ和Napcat 阅读使用文档参考
你可以下载
NapCat.Shell.Windows.OneKey.zip (无头)
NapCat.Framework.Windows.OneKey.zip (有头)
启动后可自动化部署一键包,教程参考使用文档安装部分
## 警告
**注意QQ版本推荐使用 40768+ 版本 最低可以使用40768版本**
**默认WebUi密钥为随机密码 控制台查看**
**[9.9.22-40990 X64 Win](https://dldir1v6.qq.com/qqfile/qq/QQNT/2c9d3f6c/QQ9.9.22.40990_x64.exe)**
[LinuxX64 DEB 40990 ](https://dldir1.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-40990_amd64.deb)
[LinuxX64 RPM 40990 ](https://dldir1.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-40990_x86_64.rpm)
[LinuxArm64 DEB 40990 ](https://dldir1.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-40990_arm64.deb)
[LinuxArm64 RPM 40990 ](https://dldir1.qq.com/qqfile/qq/QQNT/ec800879/linuxqq_3.2.20-40990_aarch64.rpm)
[MAC DMG 40990 ](https://dldir1v6.qq.com/qqfile/qq/QQNT/c6cb0f5d/QQ_v6.9.82.40990.dmg)
## 如果WinX64缺少运行库或者xxx.dll
[安装运行库](https://aka.ms/vs/17/release/vc_redist.x64.exe)

View File

@@ -136,19 +136,41 @@ jobs:
- name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Clone Changes Log
run: curl -o CHANGELOG.md https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/docs/changelogs/CHANGELOG.v${{ env.VERSION }}.md
- name: Download Windows OneKey Packages
run: |
# Get latest release tag using jq for reliable JSON parsing
LATEST_RELEASE=$(curl -s https://api.github.com/repos/NapNeko/NapCatQQ/releases/latest | jq -r '.tag_name')
echo "Latest release: $LATEST_RELEASE"
# Download OneKey packages if they exist (non-zero exit code won't fail the step)
curl -f -L -o NapCat.Shell.Windows.OneKey.zip "https://github.com/NapNeko/NapCatQQ/releases/download/$LATEST_RELEASE/NapCat.Shell.Windows.OneKey.zip" || echo "Warning: NapCat.Shell.Windows.OneKey.zip not found in latest release"
curl -f -L -o NapCat.Framework.Windows.OneKey.zip "https://github.com/NapNeko/NapCatQQ/releases/download/$LATEST_RELEASE/NapCat.Framework.Windows.OneKey.zip" || echo "Warning: NapCat.Framework.Windows.OneKey.zip not found in latest release"
- name: Generate Release Notes
run: |
# Create header with version
echo "# V${{ env.VERSION }} Refactor" > RELEASE_NOTES.md
# Add fixed release information
cat .github/release-template/release-info.md >> RELEASE_NOTES.md
# Add changelog section
echo "" >> RELEASE_NOTES.md
chmod +x ./script/generate-changelog.sh
./script/generate-changelog.sh >> RELEASE_NOTES.md
- name: Create Release Draft and Upload Artifacts
uses: softprops/action-gh-release@v1
with:
name: NapCat V${{ env.VERSION }}
token: ${{ secrets.GITHUB_TOKEN }}
body_path: CHANGELOG.md
body_path: RELEASE_NOTES.md
files: |
NapCat.Framework.zip
NapCat.Shell.zip
NapCat.Framework.Windows.Once.zip
NapCat.Shell.Windows.OneKey.zip
NapCat.Framework.Windows.OneKey.zip
draft: true
build-docker:

2
.gitignore vendored
View File

@@ -15,5 +15,3 @@ devconfig/*
checkVersion.sh
bun.lockb
tests/run/
guild1.db-wal
guild1.db-shm

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ",
"slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现",
"version": "4.9.35",
"version": "4.9.26",
"icon": "./logo.png",
"authors": [
{

View File

@@ -1,30 +0,0 @@
@echo off
chcp 65001
set NAPCAT_INJECT_PATH=%cd%\napiloader.dll
set NAPCAT_LAUNCHER_PATH=%cd%\napimain.exe
set NAPCAT_MAIN_PATH=%cd%\nativeLoader.cjs
set NAPCAT_DEBUG_CONSOLE=1
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
goto :napcat_boot
)
:napcat_boot
for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
if not exist "%QQpath%" (
echo provided QQ path is invalid
pause
exit /b
)
set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" "%NAPCAT_MAIN_PATH%"
pause

View File

@@ -1,27 +0,0 @@
@echo off
chcp 65001
set NAPCAT_INJECT_PATH=%cd%\napiloader.dll
set NAPCAT_LAUNCHER_PATH=%cd%\napimain.exe
set NAPCAT_MAIN_PATH=%cd%\nativeLoader.cjs
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
goto :napcat_boot
)
:napcat_boot
for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
if not exist "%QQpath%" (
echo provided QQ path is invalid
pause
exit /b
)
set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
start "" "%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" "%NAPCAT_MAIN_PATH%"

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "4.9.35",
"version": "4.9.26",
"scripts": {
"build:universal": "npm run build:webui && npm run dev:universal || exit 1",
"build:framework": "npm run build:webui && npm run dev:framework || exit 1",

8
script/generate-changelog.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Get the latest 10 commits excluding those starting with "release:"
echo "## 更新"
echo ""
git log --oneline -20 --pretty=format:"%s" | grep -v "^release:" | head -10 | while read -r line; do
echo "- $line"
done

View File

@@ -68,13 +68,11 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
const addon = this.ensureAddon();
const info = await addon.getVideoInfo(videoPath, 'bmp24');
let format = info.format.includes(',') ? info.format.split(',')[0] ?? info.format : info.format;
console.log('[FFmpegAddonAdapter] Detected format:', format);
return {
width: info.width,
height: info.height,
duration: info.duration,
format: format,
format: info.format,
thumbnail: info.image,
};
}
@@ -90,7 +88,7 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
/**
* 转换为 PCM
*/
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number; }> {
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
const addon = this.ensureAddon();
const result = await addon.decodeAudioToPCM(filePath, pcmPath, 24000);
@@ -102,8 +100,13 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
*/
async convertFile (inputFile: string, outputFile: string, format: string): Promise<void> {
const addon = this.ensureAddon();
console.log('[FFmpegAddonAdapter] Converting file:', inputFile, 'to', outputFile, 'as', format);
await addon.decodeAudioToFmt(inputFile, outputFile, format);
if (format === 'silk' || format === 'ntsilk') {
// 使用 Addon 的 NTSILK 转换
await addon.convertToNTSilkTct(inputFile, outputFile);
} else {
throw new Error(`Format '${format}' is not supported by FFmpeg Addon`);
}
}
/**

View File

@@ -49,25 +49,23 @@ export interface AudioPCMResult {
* FFmpeg interface providing all audio/video processing methods
*/
export interface FFmpeg {
convertFile (inputFile: string, outputFile: string, format: string): Promise<{ success: boolean; }>;
/**
* Get video information including resolution, duration, format, codec and first frame thumbnail
*/
getVideoInfo (filePath: string, format?: 'bmp' | 'bmp24'): Promise<VideoInfo>;
getVideoInfo(filePath: string, format?: 'bmp' | 'bmp24'): Promise<VideoInfo>;
/**
* Get duration of audio or video file in seconds
*/
getDuration (filePath: string): Promise<number>;
getDuration(filePath: string): Promise<number>;
/**
* Convert audio file to NTSILK format (WeChat voice message format)
*/
convertToNTSilkTct (inputPath: string, outputPath: string): Promise<void>;
convertToNTSilkTct(inputPath: string, outputPath: string): Promise<void>;
/**
* Decode audio file to raw PCM data
*/
decodeAudioToPCM (filePath: string, pcmPath: string, sampleRate?: number): Promise<{ result: boolean, sampleRate: number; }>;
decodeAudioToFmt (filePath: string, pcmPath: string, format: string): Promise<{ channels: number; sampleRate: number; format: string; }>;
decodeAudioToPCM(filePath: string, pcmPath: string, sampleRate?: number): Promise<{ result: boolean, sampleRate: number }>;
}

View File

@@ -48,14 +48,6 @@ export class FFmpegService {
this.initialized = true;
}
public static getAdapterName (): string {
if (!this.adapter) {
throw new Error('FFmpeg service not initialized. Please call FFmpegService.init() first.');
}
return this.adapter.name;
}
/**
* 获取 FFmpeg 适配器
*/

View File

@@ -1 +1 @@
export const napCatVersion = '4.9.35';
export const napCatVersion = '4.9.26';

View File

@@ -17,14 +17,8 @@ export class NTQQFriendApi {
async getBuddyV2SimpleInfoMap () {
const buddyService = this.context.session.getBuddyService();
let uids: string[] = [];
if (this.core.context.basicInfoWrapper.requireMinNTQQBuild('41679')) {
const buddyListV2NT = await buddyService.getBuddyListV2('0', true, BuddyListReqType.KNOMAL);
uids = buddyListV2NT.data.flatMap(item => item.buddyUids);
} else {
const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
uids = buddyListV2.data.flatMap(item => item.buddyUids);
}
const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
const uids = buddyListV2.data.flatMap(item => item.buddyUids);
return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
@@ -53,15 +47,10 @@ export class NTQQFriendApi {
async getBuddyV2ExWithCate () {
const buddyService = this.context.session.getBuddyService();
let uids: string[] = [];
let buddyListV2: Awaited<ReturnType<typeof buddyService.getBuddyListV2>>['data'];
if (this.core.context.basicInfoWrapper.requireMinNTQQBuild('41679')) {
buddyListV2 = (await buddyService.getBuddyListV2('0', true, BuddyListReqType.KNOMAL)).data;
uids = buddyListV2.flatMap(item => item.buddyUids);
} else {
buddyListV2 = (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
uids = buddyListV2.flatMap(item => item.buddyUids);
}
const buddyListV2 = (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
const uids = buddyListV2.flatMap(item => {
return item.buddyUids;
});
const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',

View File

@@ -3,133 +3,122 @@ import { NodeIKernelBuddyListener } from '@/core/listeners';
import { BuddyListReqType } from '@/core/types/user';
export interface NodeIKernelBuddyService {
getBuddyListV2 (callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & {
getBuddyListV2(callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & {
data: Array<{
categoryId: number,
categorySortId: number,
categroyName: string,
categroyMbCount: number,
onlineCount: number,
buddyUids: Array<string>;
}>;
}>;
getBuddyListV2 (callFrom: string, isPullRefresh: boolean, reqType: BuddyListReqType): Promise<GeneralCallResult & {
data: Array<{
categoryId: number,
categorySortId: number,
categroyName: string,
categroyMbCount: number,
onlineCount: number,
buddyUids: Array<string>;
}>;
buddyUids: Array<string>
}>
}>;
getBuddyListFromCache(reqType: BuddyListReqType): Promise<Array<
{
categoryId: number, // 9999为特别关心
categorySortId: number, // 排序方式
categroyName: string, // 分类名
categroyMbCount: number, // 不懂
onlineCount: number, // 在线数目
buddyUids: Array<string>// Uids
}>>;
getBuddyListFromCache (reqType: BuddyListReqType): Promise<Array<
{
categoryId: number, // 9999为特别关心
categorySortId: number, // 排序方式
categroyName: string, // 分类名
categroyMbCount: number, // 不懂
onlineCount: number, // 在线数目
buddyUids: Array<string>;// Uids
}>>;
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;
addKernelBuddyListener (listener: NodeIKernelBuddyListener): number;
getAllBuddyCount(): number;
getAllBuddyCount (): number;
removeKernelBuddyListener (listenerId: number): void;
removeKernelBuddyListener(listenerId: number): void;
// getBuddyList(nocache: boolean): Promise<GeneralCallResult>;
getBuddyNick (uid: number): string;
getBuddyNick(uid: number): string;
getBuddyRemark (uid: number): string;
getBuddyRemark(uid: number): string;
setBuddyRemark (param: { uid: string, remark: string, signInfo?: unknown; }): void;
setBuddyRemark(param: { uid: string, remark: string, signInfo?: unknown }): void;
getAvatarUrl (uid: number): string;
getAvatarUrl(uid: number): string;
isBuddy (uid: string): boolean;
isBuddy(uid: string): boolean;
getCategoryNameWithUid (uid: number): string;
getCategoryNameWithUid(uid: number): string;
getTargetBuddySetting (uid: number): unknown;
getTargetBuddySetting(uid: number): unknown;
getTargetBuddySettingByType (uid: number, type: number): unknown;
getTargetBuddySettingByType(uid: number, type: number): unknown;
getBuddyReqUnreadCnt (): number;
getBuddyReqUnreadCnt(): number;
getBuddyReq (): Promise<GeneralCallResult>;
getBuddyReq(): Promise<GeneralCallResult>;
delBuddyReq (uid: number): void;
delBuddyReq(uid: number): void;
clearBuddyReqUnreadCnt (): Promise<GeneralCallResult>;
clearBuddyReqUnreadCnt(): Promise<GeneralCallResult>;
reqToAddFriends (uid: number, msg: string): void;
reqToAddFriends(uid: number, msg: string): void;
setSpacePermission (uid: number, permission: number): void;
setSpacePermission(uid: number, permission: number): void;
approvalFriendRequest (arg: {
approvalFriendRequest(arg: {
friendUid: string;
reqTime: string;
accept: boolean;
}): Promise<void>;
delBuddy (param: {
delBuddy(param: {
friendUid: string;
tempBlock: boolean;
tempBothDel: boolean;
}): Promise<unknown>;
delBatchBuddy (uids: number[]): void;
delBatchBuddy(uids: number[]): void;
getSmartInfos (uid: number): unknown;
getSmartInfos(uid: number): unknown;
setBuddyCategory (uid: number, category: number): void;
setBuddyCategory(uid: number, category: number): void;
setBatchBuddyCategory (uids: number[], category: number): void;
setBatchBuddyCategory(uids: number[], category: number): void;
addCategory (category: string): void;
addCategory(category: string): void;
delCategory (category: string): void;
delCategory(category: string): void;
renameCategory (oldCategory: string, newCategory: string): void;
renameCategory(oldCategory: string, newCategory: string): void;
resortCategory (categorys: string[]): void;
resortCategory(categorys: string[]): void;
pullCategory (uid: number, category: string): void;
pullCategory(uid: number, category: string): void;
setTop (uid: number, isTop: boolean): void;
setTop(uid: number, isTop: boolean): void;
SetSpecialCare (uid: number, isSpecialCare: boolean): void;
SetSpecialCare(uid: number, isSpecialCare: boolean): void;
setMsgNotify (uid: number, isNotify: boolean): void;
setMsgNotify(uid: number, isNotify: boolean): void;
hasBuddyList (): boolean;
hasBuddyList(): boolean;
setBlock (uid: number, isBlock: boolean): void;
setBlock(uid: number, isBlock: boolean): void;
isBlocked (uid: number): boolean;
isBlocked(uid: number): boolean;
modifyAddMeSetting (setting: unknown): void;
modifyAddMeSetting(setting: unknown): void;
getAddMeSetting (): unknown;
getAddMeSetting(): unknown;
getDoubtBuddyReq (reqId: string, num: number, uk: string): Promise<GeneralCallResult>;
getDoubtBuddyReq(reqId: string, num: number, uk:string): Promise<GeneralCallResult>;
getDoubtBuddyUnreadNum (): number;
getDoubtBuddyUnreadNum(): number;
approvalDoubtBuddyReq (uid: string, str1: string, str2: string): void;
approvalDoubtBuddyReq(uid: string, str1: string, str2: string): void;
delDoubtBuddyReq (uid: number): void;
delDoubtBuddyReq(uid: number): void;
delAllDoubtBuddyReq (): Promise<GeneralCallResult>;
delAllDoubtBuddyReq(): Promise<GeneralCallResult>;
reportDoubtBuddyReqUnread (): void;
reportDoubtBuddyReqUnread(): void;
getBuddyRecommendContactArkJson (uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string; }>;
getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string }>;
isNull (): boolean;
isNull(): boolean;
}

View File

@@ -7,7 +7,7 @@ import { FFmpegService } from '@/common/ffmpeg';
const out_format = ['mp3', 'amr', 'wma', 'm4a', 'spx', 'ogg', 'wav', 'flac'];
type Payload = {
out_format: string;
out_format: string
} & GetFilePayload;
export default class GetRecord extends GetFileBase {
@@ -28,12 +28,8 @@ export default class GetRecord extends GetFileBase {
try {
await fs.access(outputFile);
} catch {
if (FFmpegService.getAdapterName() === 'FFmpegAddon') {
await FFmpegService.convertFile(inputFile, outputFile, payload.out_format);
} else {
await this.decodeFile(inputFile, pcmFile);
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
}
await this.decodeFile(inputFile, pcmFile);
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
}
const base64Data = await fs.readFile(outputFile, { encoding: 'base64' });
res.file = outputFile;

View File

@@ -37,7 +37,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
await checkFileExist(path, 5000);
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
if (ImageUploadResult.errCode !== 0) {
throw new Error(`群公告${payload.image}设置失败,图片上传失败 错误信息:${ImageUploadResult.errMsg}`);
throw new Error(`群公告${payload.image}设置失败,图片上传失败`);
}
unlink(path).catch(() => { });

View File

@@ -47,12 +47,8 @@ export class DownloadFileRecordStream extends BaseDownloadStream<Payload, Downlo
streamPath = outputFile;
} catch {
// 尝试解码 silk 到 pcm 再用 ffmpeg 转换
if (FFmpegService.getAdapterName() === 'FFmpegAddon') {
await FFmpegService.convertFile(downloadPath, outputFile, payload.out_format);
} else {
await this.decodeFile(downloadPath, pcmFile);
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
}
await this.decodeFile(downloadPath, pcmFile);
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
streamPath = outputFile;
}
}

Binary file not shown.

View File

@@ -6,205 +6,204 @@ import { builtinModules } from 'module';
import { performanceMonitorPlugin } from './vite-plugin-performance-monitor';
//依赖排除
const external = [
'silk-wasm',
'ws',
'express'
'silk-wasm',
'ws',
'express'
];
const nodeModules = [...builtinModules, builtinModules.map((m) => `node:${m}`)].flat();
let startScripts: string[] | undefined = undefined;
if (process.env.NAPCAT_BUILDSYS == 'linux') {
startScripts = [];
startScripts = [];
} else if (process.env.NAPCAT_BUILDSYS == 'win32') {
startScripts = ['./script/KillQQ.bat'];
startScripts = ['./script/KillQQ.bat'];
} else {
startScripts = ['./script/KillQQ.bat'];
startScripts = ['./script/KillQQ.bat'];
}
const UniversalBaseConfigPlugin: PluginOption[] = [
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './manifest.json', dest: 'dist' },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
{ src: './src/framework/napcat.cjs', dest: 'dist' },
{ src: './src/framework/preload.cjs', dest: 'dist' },
{ src: './src/framework/renderer.js', dest: 'dist' },
{ src: './package.json', dest: 'dist' },
{ src: './logo.png', dest: 'dist' },
{ src: './launcher/', dest: 'dist', flatten: true },
...startScripts.map((startScript) => {
return { src: startScript, dest: 'dist' };
}),
],
}),
nodeResolve(),
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './manifest.json', dest: 'dist' },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
{ src: './src/framework/napcat.cjs', dest: 'dist' },
{ src: './src/framework/preload.cjs', dest: 'dist' },
{ src: './src/framework/renderer.js', dest: 'dist' },
{ src: './package.json', dest: 'dist' },
{ src: './logo.png', dest: 'dist' },
{ src: './launcher/', dest: 'dist', flatten: true },
...startScripts.map((startScript) => {
return { src: startScript, dest: 'dist' };
}),
],
}),
nodeResolve(),
];
const FrameworkBaseConfigPlugin: PluginOption[] = [
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './napiloader/', dest: 'dist', flatten: true },
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './manifest.json', dest: 'dist' },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
{ src: './src/framework/napcat.cjs', dest: 'dist' },
{ src: './src/framework/nativeLoader.cjs', dest: 'dist' },
{ src: './src/framework/preload.cjs', dest: 'dist' },
{ src: './src/framework/renderer.js', dest: 'dist' },
{ src: './package.json', dest: 'dist' },
{ src: './logo.png', dest: 'dist' },
],
}),
nodeResolve(),
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './manifest.json', dest: 'dist' },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
{ src: './src/framework/napcat.cjs', dest: 'dist' },
{ src: './src/framework/nativeLoader.cjs', dest: 'dist' },
{ src: './src/framework/preload.cjs', dest: 'dist' },
{ src: './src/framework/renderer.js', dest: 'dist' },
{ src: './package.json', dest: 'dist' },
{ src: './logo.png', dest: 'dist' },
],
}),
nodeResolve(),
];
const ShellBaseConfigPlugin: PluginOption[] = [
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './package.json', dest: 'dist' },
{ src: './launcher/', dest: 'dist', flatten: true },
...startScripts.map((startScript) => {
return { src: startScript, dest: 'dist' };
}),
],
}),
nodeResolve(),
// performanceMonitorPlugin({
// enabled: process.env.NODE_ENV !== 'production',
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
// include: [/\.ts$/, /\.js$/]
// }),
cp({
targets: [
{ src: './src/native/', dest: 'dist/native', flatten: false },
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
{ src: './package.json', dest: 'dist' },
{ src: './launcher/', dest: 'dist', flatten: true },
...startScripts.map((startScript) => {
return { src: startScript, dest: 'dist' };
}),
],
}),
nodeResolve(),
];
const UniversalBaseConfig = () =>
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/universal/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/universal/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
const ShellBaseConfig = () =>
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/shell/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/shell/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
const FrameworkBaseConfig = () =>
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/framework/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
defineConfig({
resolve: {
conditions: ['node', 'default'],
alias: {
'@/core': resolve(__dirname, './src/core'),
'@': resolve(__dirname, './src'),
'@webapi': resolve(__dirname, './src/webui/src'),
},
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
build: {
sourcemap: false,
target: 'esnext',
minify: false,
lib: {
entry: {
napcat: 'src/framework/napcat.ts',
'audio-worker': 'src/common/audio-worker.ts',
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
},
formats: ['es'],
fileName: (_, entryName) => `${entryName}.mjs`,
},
rollupOptions: {
external: [...nodeModules, ...external],
},
},
});
export default defineConfig(({ mode }): UserConfig => {
if (mode === 'shell') {
return {
...ShellBaseConfig(),
plugins: [...ShellBaseConfigPlugin],
};
} else if (mode == 'universal') {
return {
...UniversalBaseConfig(),
plugins: [...UniversalBaseConfigPlugin],
};
} else if (mode == 'shell-analysis') {
return {
...ShellBaseConfig(),
plugins: [
performanceMonitorPlugin({
exclude: [/node_modules/, /\.min\./, /performance-monitor\.ts$/, /packet/],
include: [/\.ts$/, /\.js$/]
}),
...ShellBaseConfigPlugin
],
};
} else
return {
...FrameworkBaseConfig(),
plugins: [...FrameworkBaseConfigPlugin],
};
if (mode === 'shell') {
return {
...ShellBaseConfig(),
plugins: [...ShellBaseConfigPlugin],
};
} else if (mode == 'universal') {
return {
...UniversalBaseConfig(),
plugins: [...UniversalBaseConfigPlugin],
};
} else if (mode == 'shell-analysis') {
return {
...ShellBaseConfig(),
plugins: [
performanceMonitorPlugin({
exclude: [/node_modules/, /\.min\./, /performance-monitor\.ts$/, /packet/],
include: [/\.ts$/, /\.js$/]
}),
...ShellBaseConfigPlugin
],
};
} else
return {
...FrameworkBaseConfig(),
plugins: [...FrameworkBaseConfigPlugin],
};
});