| 123456789101112131415161718192021222324252627282930313233 |
- import ts from 'typescript';import {readFileSync} from 'node:fs';
- import {withXiaoshuRuntime} from './lib/xiaoshu-runtime-compat.mjs';
- function tree(source){return ts.createSourceFile('gateway.js',source,ts.ScriptTarget.Latest,true,ts.ScriptKind.JS);}
- function lastFunction(source,name){return tree(source).statements.filter(n=>ts.isFunctionDeclaration(n)&&n.name?.text===name).at(-1);}
- function patchFunction(source,nodeText,name){const node=lastFunction(source,name);return node?source.slice(0,node.getStart())+nodeText+source.slice(node.end):source+'\n'+nodeText+'\n';}
- export function patchReadPressureGateway(baseline,kind){
- const marker='// XIAOSHU_ISOLATED_RUNTIME_COMPAT_V1';let source=baseline;
- if(kind==='ops'){
- const history=readFileSync(new URL('./cloud/lesson-records.js',import.meta.url),'utf8'),parsed=tree(history);
- const owned=new Set(['lessonHistoryBase','lessonHistoryTypeRows','lessonHistoryRead','lessonHistoryPage','lessonHistoryPageData','lessonHistoryPlan']);
- for(const node of parsed.statements)if(ts.isFunctionDeclaration(node)&&owned.has(node.name.text))source=patchFunction(source,node.getText(parsed),node.name.text);
- if(!source.includes('const LESSON_RECORDS_VERSION='))source="const LESSON_RECORDS_VERSION='2026-10-13-lesson-records-v10';\n"+source;
- const exports=readFileSync(new URL('./cloud/lesson-export.js',import.meta.url),'utf8'),exportsTree=tree(exports);
- for(const node of exportsTree.statements)if(ts.isFunctionDeclaration(node))source=patchFunction(source,node.getText(exportsTree),node.name.text);
- const operations=['create','status','cancel','download','maintenance','claim','snapshot','chunk','finish','fail','release'];
- const handler=lastFunction(source,'xiaoshuBusinessHandler')||lastFunction(source,'handler');if(!handler)throw Error('Missing operations handler');
- let text=handler.getText();const anchor="if(operation==='ops/lessons/list')";if(!text.includes(anchor))throw Error('Missing lesson route anchor');
- const routes=operations.filter(name=>!text.includes("operation==='ops/lessons/export/"+name+"'")).map(name=>"if(operation==='ops/lessons/export/"+name+"') return response.json({success:true,data:await lessonExport"+name[0].toUpperCase()+name.slice(1)+"(context,input)});\n ").join('');
- text=text.replace(anchor,routes+anchor);source=source.slice(0,handler.getStart())+text+source.slice(handler.end);
- const version=lastFunction(source,'operationsScopeVersion');if(version&&!version.getText().includes("to_regprocedure('xs_read_version(text,text)')")){
- const replacement=version.getText().replace('{',`{\n const installed=await Psql.one("SELECT to_regprocedure('xs_read_version(text,text)') IS NOT NULL installed");if(installed.installed)return(await Psql.one('SELECT xs_read_version($1,$2) version',[companyId,scope])).version;\n`);source=source.slice(0,version.getStart())+replacement+source.slice(version.end);
- }
- const parsedSource=tree(source),store=parsedSource.statements.find(n=>ts.isVariableStatement(n)&&n.declarationList.declarations.some(d=>d.name.getText()==='STORE_OPERATIONS'));
- if(store&&!store.getText().includes('ops/lessons/export/create')){const replacement=store.getText().replace("'ops/lessons/list'", "'ops/lessons/export/create','ops/lessons/export/status','ops/lessons/export/cancel','ops/lessons/export/download','ops/lessons/list'");if(replacement===store.getText())throw Error('Missing store route anchor');source=source.slice(0,store.getStart())+replacement+source.slice(store.end);}
- }
- if(lastFunction(source,'xiaoshuBusinessHandler')){
- const oldWrapper=lastFunction(source,'handler');if(!oldWrapper?.getText().includes('resolveXiaoshuRuntime')||!oldWrapper.getText().includes('xiaoshuBusinessHandler'))throw Error('Unknown production runtime wrapper');
- const wrapper=withXiaoshuRuntime('async function handler(request,response){return null;}',{readPressure:kind}),parsed=tree(wrapper);
- const replace=new Set(['readPressurePolicy','readPressureStable','readPressureDb','dispatchReadPressure','handler']);
- for(const node of parsed.statements)if(ts.isFunctionDeclaration(node)&&replace.has(node.name.text))source=patchFunction(source,node.getText(parsed),node.name.text);
- }else source=withXiaoshuRuntime(source,{readPressure:kind});
- new Function(source);return source;
- }
|