| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import fs from 'node:fs';
- import path from 'node:path';
- import { execFileSync } from 'node:child_process';
- import { fileURLToPath } from 'node:url';
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
- const rootDir = path.resolve(__dirname, '..');
- const cloudDir = path.join(rootDir, 'cloud-functions');
- const outDir = path.join(cloudDir, 'deployable');
- const sessionSourcePath = path.join(cloudDir, '_session.js');
- const parseClassStoreSourcePath = path.join(cloudDir, '_parseClassStore.js');
- const targetFiles = [
- '01-manifestManager.js',
- '02-taskManager.js',
- '03-historyManager.js',
- '04-resultManager.js',
- '05-remixManager.js',
- '06-voiceManager.js',
- '09-uploadManager.js',
- '13-douyinInsightManager.js',
- '14-systemStorageManager.js',
- '15-fileAssetManager.js',
- ];
- const sessionSource = stripCommonJsExport(read(sessionSourcePath)).trim();
- const parseClassStoreSource = stripCommonJsExport(read(parseClassStoreSourcePath)).trim();
- fs.mkdirSync(outDir, { recursive: true });
- for (const file of targetFiles) {
- const sourcePath = path.join(cloudDir, file);
- const source = read(sourcePath);
- const transformed = inlineLocalRequires(source, file);
- const helperSources = [sessionSource];
- if (transformed.usesParseClassStore) {
- helperSources.push(parseClassStoreSource);
- }
- const banner = [
- '/**',
- ` * ${file} 的 fmode 单文件部署版。`,
- ' * 本文件由 scripts/build-cloud-functions.mjs 生成。',
- ' * 请不要手动修改本文件;如需改动,请修改 cloud-functions 源码后重新生成。',
- ' */',
- '',
- ].join('\n');
- const output = `${banner}${helperSources.join('\n\n')}\n\n${transformed.source}`;
- const outputPath = path.join(outDir, file);
- fs.writeFileSync(outputPath, output, 'utf8');
- checkSyntax(outputPath);
- console.log(`built ${path.relative(rootDir, outputPath)}`);
- }
- console.log('云函数单文件部署包已生成');
- function inlineLocalRequires(source, file) {
- const sessionResult = inlineRequire(
- source,
- './_session',
- '上方已内联 _session.js 的登录态和权限校验逻辑,用于 fmode 单文件部署。',
- );
- if (!sessionResult.replaced) {
- throw new Error(`${file} does not import ./_session`);
- }
- const parseStoreResult = inlineRequire(
- sessionResult.source,
- './_parseClassStore',
- '上方已内联 _parseClassStore.js 的 Parse Class 存储工具,用于 fmode 单文件部署。',
- );
- const withoutRequire = parseStoreResult.source;
- if (withoutRequire.includes("require('./_session')") || withoutRequire.includes('require("./_session")')) {
- throw new Error(`${file} still contains ./_session require after transform`);
- }
- if (
- withoutRequire.includes("require('./_parseClassStore')") ||
- withoutRequire.includes('require("./_parseClassStore")')
- ) {
- throw new Error(`${file} still contains ./_parseClassStore require after transform`);
- }
- return {
- source: withoutRequire.trim(),
- usesParseClassStore: parseStoreResult.replaced,
- };
- }
- function inlineRequire(source, requirePath, comment) {
- let replaced = false;
- const escapedPath = requirePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- const pattern = new RegExp(`const\\s*\\{([\\s\\S]*?)\\}\\s*=\\s*require\\(['"]${escapedPath}['"]\\);?`, 'm');
- const next = source.replace(pattern, (_match, imports) => {
- replaced = true;
- return buildAliases(imports, comment);
- });
- return { source: next, replaced };
- }
- function buildAliases(imports, comment) {
- const lines = [];
- for (const raw of imports.split(',')) {
- const item = raw.trim();
- if (!item) continue;
- const aliasMatch = item.match(/^([A-Za-z_$][\w$]*)\s*:\s*([A-Za-z_$][\w$]*)$/);
- if (aliasMatch) {
- lines.push(`const ${aliasMatch[2]} = ${aliasMatch[1]};`);
- }
- }
- return lines.length ? `// ${comment}\n${lines.join('\n')}` : `// ${comment}`;
- }
- function stripCommonJsExport(source) {
- return source.replace(/module\.exports\s*=\s*\{[\s\S]*?\};?\s*$/m, '');
- }
- function read(filePath) {
- return fs.readFileSync(filePath, 'utf8');
- }
- function checkSyntax(filePath) {
- execFileSync(process.execPath, ['--check', filePath], { stdio: 'pipe' });
- }
|