49 lines
4.4 KiB
JavaScript
49 lines
4.4 KiB
JavaScript
// Build in a private source copy; never writes the installed SGF or dependencies.
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import crypto from 'node:crypto';
|
|
import {spawnSync} from 'node:child_process';
|
|
|
|
const host=fs.realpathSync(process.argv[2]||'');
|
|
if(fs.existsSync(path.join(host,'public/hot')))throw Error('Stop the source frontend watcher before freezing a candidate.');
|
|
const work=path.join('C:/laragon/data/sgf-tempo/run','candidate-ui-'+crypto.randomBytes(6).toString('hex'));
|
|
fs.mkdirSync(work,{recursive:true});
|
|
const replace=(text,old,next)=>{if(text.split(old).length!==2)throw Error('Frontend baseline changed: '+old.slice(0,70));return text.replace(old,next);};
|
|
fs.cpSync(path.join(host,'resources'),path.join(work,'resources'),{recursive:true});
|
|
for(const file of ['package.json','vite.config.js'])fs.copyFileSync(path.join(host,file),path.join(work,file));
|
|
fs.mkdirSync(path.join(work,'public/build'),{recursive:true});
|
|
fs.symlinkSync(path.join(host,'node_modules'),path.join(work,'node_modules'),'junction');
|
|
let app=fs.readFileSync(path.join(work,'resources/js/app.jsx'),'utf8');
|
|
app=replace(app,"const options = (unit === null ? ['company.view', 'company.edit', 'unit.create', 'access.manage'] : ['unit.view', 'unit.edit']).filter(p => can(p, unit));", "const options = (list?.catalogue?.[unit === null ? 'company' : 'unit'] ?? []).filter(p => can(p, unit));");
|
|
app=replace(app,'{labels[p]}','{list?.catalogue_labels?.[p] ?? labels[p] ?? p}');
|
|
app=replace(app,'{labels[g.permission]}','{list?.catalogue_labels?.[g.permission] ?? labels[g.permission] ?? g.permission}');
|
|
fs.writeFileSync(path.join(work,'resources/js/app.jsx'),app);
|
|
let home=fs.readFileSync(path.join(work,'resources/js/PurchasingHome.jsx'),'utf8');
|
|
home=replace(home,"const payables=unit!==null&&can('supplier_payables.view',unit);", "const payables=unit!==null&&can('supplier_payables.view',unit);\n const requisitions=unit!==null&&can('purchasing_requisitions.view',unit);");
|
|
home=replace(home,'<div className="actions">','<div className="actions">{requisitions&&<a href="/purchasing/internal-requisitions">Requisições internas</a>}{budget&&<a href="/purchasing/internal-requisitions/budget-setup">Preparação de centros e dotações</a>}');
|
|
home=replace(home,'!budget&&!payables&&','!budget&&!payables&&!requisitions&&');
|
|
fs.writeFileSync(path.join(work,'resources/js/PurchasingHome.jsx'),home);
|
|
let config=fs.readFileSync(path.join(work,'vite.config.js'),'utf8');
|
|
config=replace(config,'defineConfig({',`defineConfig({\n cacheDir: ${JSON.stringify(path.join(work,'vite-cache'))},`);
|
|
fs.writeFileSync(path.join(work,'vite.config.js'),config);
|
|
const result=spawnSync(process.execPath,[path.join(host,'node_modules/vite/bin/vite.js'),'build','--config',path.join(work,'vite.config.js'),'--configLoader','native'],{cwd:work,encoding:'utf8',windowsHide:true,maxBuffer:4*1024*1024,env:{...process.env,NODE_ENV:'production'}});
|
|
fs.writeFileSync(path.join(work,'build.log'),(result.stdout||'')+(result.stderr||''));
|
|
if(result.status!==0)throw Error('Candidate frontend build failed; private log '+path.join(work,'build.log'));
|
|
const original=JSON.parse(fs.readFileSync(path.join(work,'public/build/manifest.json'),'utf8'));
|
|
const assets={};
|
|
for(const chunk of Object.values(original))for(const file of [chunk.file,...(chunk.css||[]),...(chunk.assets||[])]){
|
|
if(!/^assets\/[A-Za-z0-9_-]+\.(js|css)$/.test(file))throw Error('Unsupported frontend asset '+file);
|
|
assets['integrations/sgf/frontend/'+file]=path.join(work,'public/build',file);
|
|
}
|
|
const manifest=JSON.parse(JSON.stringify(original));
|
|
for(const chunk of Object.values(manifest)){
|
|
chunk.file='modules/internal-requisitions/'+chunk.file;
|
|
if(chunk.css)chunk.css=chunk.css.map(p=>'modules/internal-requisitions/'+p);
|
|
if(chunk.assets)chunk.assets=chunk.assets.map(p=>'modules/internal-requisitions/'+p);
|
|
}
|
|
const manifestFile=path.join(work,'candidate-manifest.json');fs.writeFileSync(manifestFile,JSON.stringify(manifest,null,2)+'\n');
|
|
const overlays={'resources/js/app.jsx':path.join(work,'resources/js/app.jsx'),'resources/js/PurchasingHome.jsx':path.join(work,'resources/js/PurchasingHome.jsx'),'public/build/manifest.json':manifestFile};
|
|
const metadata={work,overlays,assets,dependency_install:false,source_host_modified:false};
|
|
const metadataFile=path.join(work,'candidate-ui.json');fs.writeFileSync(metadataFile,JSON.stringify(metadata,null,2));
|
|
console.log(JSON.stringify({metadata:metadataFile}));
|