| 1234567891011121314151617181920212223242526272829303132333435363738394041 |
- import fs from 'node:fs';
- import path from 'node:path';
- import crypto from 'node:crypto';
- import { fileURLToPath } from 'node:url';
- export function buildIdentityFunctions(base, { uploadBases = [] } = {}) {
- const directory = path.dirname(fileURLToPath(import.meta.url));
- const source = ['wecom-directory.mjs', 'employee-handlers.mjs'].map((name) => fs.readFileSync(path.join(directory, name), 'utf8').replace(/^import .*;\r?\n/gm, '').replace(/^export /gm, '')).join('\n');
- const hook = 'attachWorkshopHandlers(app,{store,data:DATA});';
- if (base.name !== 'ksfGetPublicBoard' || typeof base.code !== 'string' || base.code.split(hook).length !== 2 || base.code.includes('attachWecomEmployeeHandlers')) throw Error('UNEXPECTED_PUBLIC_FUNCTION');
- const overlay = (row) => {
- if (typeof row.code !== 'string' || row.code.split(hook).length !== 2 || row.code.includes('attachWecomEmployeeHandlers')) throw Error('UNEXPECTED_UPLOAD_FUNCTION');
- return source + '\n' + row.code.replace(hook, hook + '\n attachWecomEmployeeHandlers(app,{store,settings});');
- };
- const extended = overlay(base);
- const call = 'runDatabaseFunction("ksfGetPublicBoard",request,response,';
- if (extended.split(call).length !== 2) throw Error('UNEXPECTED_FUNCTION_ENTRY');
- const result = [
- { name: 'ksfGetPublicBoard', objectId: base.objectId, path: base.path, priorSha256: crypto.createHash('sha256').update(base.code).digest('hex'), code: extended },
- { name: 'ksfSyncWecomEmployee', path: '/ksfSyncWecomEmployee', priorSha256: null, code: extended.replace(call, 'runDatabaseFunction("ksfSyncWecomEmployee",request,response,') },
- ];
- if (uploadBases.length && (uploadBases.length !== 2 || new Set(uploadBases.map((r) => r.name)).size !== 2 || uploadBases.some((r) => !['ksfStartWorkshopSession', 'ksfSaveWorkshopTask'].includes(r.name)))) throw Error('UNEXPECTED_UPLOAD_BASES');
- for (const row of uploadBases) {
- if (row.code.split('runDatabaseFunction(' + JSON.stringify(row.name) + ',request,response,').length !== 2) throw Error('UNEXPECTED_FUNCTION_ENTRY');
- result.push({ name: row.name, objectId: row.objectId, path: row.path, priorSha256: crypto.createHash('sha256').update(row.code).digest('hex'), code: overlay(row) });
- }
- for (const entry of result) { new Function(entry.code); entry.sha256 = crypto.createHash('sha256').update(entry.code).digest('hex'); }
- return result;
- }
- if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
- const args = process.argv.slice(2);
- if (![4, 6].includes(args.length) || args[0] !== '--base' || args[2] !== '--out' || args.length === 6 && args[4] !== '--upload-bases') throw Error('Use --base PRIVATE_FUNCTION_SNAPSHOT --out NEW_ABSOLUTE_DIRECTORY [--upload-bases PRIVATE_UPLOAD_SNAPSHOTS]');
- const out = args[3];
- if (!path.isAbsolute(out) || fs.existsSync(out)) throw Error('NEW_ABSOLUTE_DIRECTORY_REQUIRED');
- const entries = buildIdentityFunctions(JSON.parse(fs.readFileSync(args[1], 'utf8')), { uploadBases: args[5] ? JSON.parse(fs.readFileSync(args[5], 'utf8')) : [] });
- fs.mkdirSync(out, { recursive: true });
- for (const entry of entries) fs.writeFileSync(path.join(out, entry.name + '.js'), entry.code);
- fs.writeFileSync(path.join(out, 'manifest.json'), JSON.stringify({ version: 'ksf.wecom-identity.20261103.v1', functions: entries.map(({ code, ...rest }) => rest) }, null, 2));
- console.log(JSON.stringify({ ok: true, functions: entries.length, out, productionWrites: 0 }));
- }
|