实现小游戏与小程序项目创建发布

This commit is contained in:
2026-08-09 13:31:06 +08:00
parent a6fe14a8d6
commit 493b31cff0
26 changed files with 1827 additions and 39 deletions

View File

@@ -18,6 +18,7 @@ import {
createStaticProjectPackage,
ProjectPackageError,
} from '@electron/services/project-packager';
import { createProjectConfig, type ProjectType } from '../../shared/project-config';
const openRaceHook = vi.hoisted(() => ({
beforeOpen: null as null | ((path: string) => Promise<void>),
@@ -39,11 +40,17 @@ const AdmZip = require('adm-zip') as typeof import('adm-zip');
const tempDirectories: string[] = [];
async function createProject(): Promise<string> {
async function createProject(projectType: ProjectType = 'mini_game'): Promise<string> {
const projectPath = await mkdtemp(join(tmpdir(), 'makelore-project-packager-'));
tempDirectories.push(projectPath);
await mkdir(join(projectPath, 'src'), { recursive: true });
await mkdir(join(projectPath, 'public'), { recursive: true });
await mkdir(join(projectPath, '.niancode'), { recursive: true });
await writeFile(
join(projectPath, '.niancode', 'project.json'),
JSON.stringify(createProjectConfig('2026-08-09T00:00:00.000Z', projectType)),
'utf8',
);
await writeFile(
join(projectPath, 'package.json'),
JSON.stringify({
@@ -83,7 +90,6 @@ describe('project packager', () => {
await mkdir(join(projectPath, 'node_modules', 'vite'), { recursive: true });
await mkdir(join(projectPath, '.git'), { recursive: true });
await mkdir(join(projectPath, 'dist'), { recursive: true });
await mkdir(join(projectPath, '.niancode'), { recursive: true });
for (const directory of ['.ssh', '.aws', '.gnupg', '.kube', '.docker', 'secrets']) {
await mkdir(join(projectPath, directory), { recursive: true });
await writeFile(join(projectPath, directory, 'credential'), 'private', 'utf8');
@@ -91,7 +97,7 @@ describe('project packager', () => {
await writeFile(join(projectPath, 'node_modules', 'vite', 'index.js'), 'generated', 'utf8');
await writeFile(join(projectPath, '.git', 'config'), 'private', 'utf8');
await writeFile(join(projectPath, 'dist', 'index.html'), 'built', 'utf8');
await writeFile(join(projectPath, '.niancode', 'project.json'), '{}', 'utf8');
await writeFile(join(projectPath, '.niancode', 'local-state.json'), '{}', 'utf8');
await writeFile(join(projectPath, '.env'), 'TOKEN=secret', 'utf8');
await writeFile(join(projectPath, '.env.example'), 'TOKEN=replace-me', 'utf8');
await writeFile(join(projectPath, '.npmrc'), '//registry/:_authToken=secret', 'utf8');
@@ -170,6 +176,7 @@ describe('project packager', () => {
]);
expect(archive.readAsText('niancode.yml')).toBe(
'schema_version: 1\n'
+ 'project_type: mini_game\n'
+ 'kind: web\n'
+ 'runtime: static\n'
+ 'build:\n'
@@ -177,10 +184,44 @@ describe('project packager', () => {
+ ' package_manager: npm\n'
+ ' entry: index.html\n',
);
expect(first.manifest.project_type).toBe('mini_game');
expect(entries.every((entry) => entry.header.time.getFullYear() === 1980)).toBe(true);
await expect(readFile(join(projectPath, 'niancode.yml'), 'utf8')).resolves.toBe('runtime: compose\n');
});
it('writes the selected publishable project type into the generated manifest', async () => {
const projectPath = await createProject('mini_program');
const outputDirectory = await mkdtemp(join(tmpdir(), 'makelore-project-archives-'));
tempDirectories.push(outputDirectory);
const archivePath = join(outputDirectory, 'project.zip');
const summary = await createStaticProjectPackage({ projectPath, archivePath });
expect(summary.manifest.project_type).toBe('mini_program');
expect(new AdmZip(archivePath).readAsText('niancode.yml')).toContain('project_type: mini_program\n');
});
it('rejects custom projects before validating Vite source files', async () => {
const projectPath = await mkdtemp(join(tmpdir(), 'makelore-custom-packager-'));
tempDirectories.push(projectPath);
await mkdir(join(projectPath, '.niancode'), { recursive: true });
await writeFile(
join(projectPath, '.niancode', 'project.json'),
JSON.stringify(createProjectConfig('2026-08-09T00:00:00.000Z', 'custom')),
'utf8',
);
const outputDirectory = await mkdtemp(join(tmpdir(), 'makelore-project-archives-'));
tempDirectories.push(outputDirectory);
await expect(createStaticProjectPackage({
projectPath,
archivePath: join(outputDirectory, 'project.zip'),
})).rejects.toMatchObject<ProjectPackageError>({
code: 'PROJECT_TYPE_UNPUBLISHABLE',
message: '自定义项目暂未配置发布方式,请新建小游戏或小程序项目',
});
});
it('rejects a project that is not a locked npm Vite project', async () => {
const projectPath = await createProject();
await writeFile(