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

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

@@ -10,19 +10,26 @@ import {
writeFile,
} from 'node:fs/promises';
import { dirname, isAbsolute, join, relative, sep } from 'node:path';
import type { ProjectType } from '../../shared/project-config';
import { readProjectConfig } from '../opencode/project-config';
const require = createRequire(import.meta.url);
const AdmZip = require('adm-zip') as typeof import('adm-zip');
const GENERATED_MANIFEST = (
'schema_version: 1\n'
+ 'kind: web\n'
+ 'runtime: static\n'
+ 'build:\n'
+ ' preset: vite\n'
+ ' package_manager: npm\n'
+ ' entry: index.html\n'
);
type PublishableProjectType = Exclude<ProjectType, 'custom'>;
function generatedManifest(projectType: PublishableProjectType): string {
return (
'schema_version: 1\n'
+ `project_type: ${projectType}\n`
+ 'kind: web\n'
+ 'runtime: static\n'
+ 'build:\n'
+ ' preset: vite\n'
+ ' package_manager: npm\n'
+ ' entry: index.html\n'
);
}
const FIXED_ZIP_TIME = new Date(1980, 0, 1, 0, 0, 0, 0);
const FILE_MODE = 0o100644;
const DEFAULT_LIMITS: ProjectPackageLimits = {
@@ -125,6 +132,7 @@ export type StaticProjectPackageSummary = {
excludedPaths: string[];
manifest: {
schema_version: 1;
project_type: PublishableProjectType;
kind: 'web';
runtime: 'static';
build: {
@@ -177,9 +185,10 @@ export async function createStaticProjectPackage(input: {
}): Promise<StaticProjectPackageSummary> {
const limits = input.limits ?? DEFAULT_LIMITS;
const projectPath = await resolveProjectDirectory(input.projectPath);
const projectType = await readPublishableProjectType(projectPath);
await validateViteProject(projectPath, limits);
const scan = await scanProject(projectPath, limits);
const manifestBytes = Buffer.from(GENERATED_MANIFEST, 'utf8');
const manifestBytes = Buffer.from(generatedManifest(projectType), 'utf8');
const sourceBytes = scan.sourceBytes + manifestBytes.length;
if (sourceBytes > limits.maxSourceBytes) {
throw new ProjectPackageError(
@@ -228,6 +237,7 @@ export async function createStaticProjectPackage(input: {
excludedPaths: scan.excludedPaths,
manifest: {
schema_version: 1,
project_type: projectType,
kind: 'web',
runtime: 'static',
build: {
@@ -239,6 +249,23 @@ export async function createStaticProjectPackage(input: {
};
}
async function readPublishableProjectType(projectPath: string): Promise<PublishableProjectType> {
const result = await readProjectConfig(projectPath);
if (result.status === 'invalid') {
throw new ProjectPackageError(
'PROJECT_CONFIG_INVALID',
'项目配置无效,无法确认发布类型',
);
}
if (result.status === 'missing' || result.config.projectType === 'custom') {
throw new ProjectPackageError(
'PROJECT_TYPE_UNPUBLISHABLE',
'自定义项目暂未配置发布方式,请新建小游戏或小程序项目',
);
}
return result.config.projectType;
}
async function resolveProjectDirectory(projectPath: string): Promise<string> {
try {
const resolved = await realpath(projectPath);