// Live dry-run of the W4 Code node against REAL AList + NocoDB, outside n8n. // Runs the exact inlined jsCode from W4-daily-reconcile.json in a vm sandbox, // with helpers.httpRequest backed by node fetch. ZERO writes (dryRun=true). // Usage: node scripts/live_dry_run_w4.js const fs = require('fs'); const path = require('path'); const vm = require('vm'); const wf = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'n8n', 'W4-daily-reconcile.json'), 'utf8')); const code = wf.nodes.find(n => n.name === 'Reconcile & Repair (Daily Full)').parameters.jsCode; const ENV = { NOCODB_URL: 'https://nocodb.hoelee.com', NOCODB_TOKEN: process.env.NOCODB_TOKEN, // from env, never hardcoded — same for passwords below NOCODB_TABLE_CUSTOMERS: 'maqb9zgvza2te3k', NOCODB_TABLE_PRODUCTS: 'molyb3pxv81l75g', NOCODB_TABLE_RESOURCES: 'm6cm7tkxzd8m18c', NOCODB_TABLE_CUSTOMERPRODUCTS: 'mvyqbv8ao7u6bct', NOCODB_TABLE_ACCESSGRANTS: 'mxdx3yhfcyej3ao', NOCODB_TABLE_RECONCILELOGS: 'mktsb7le6fqr2u1', NOCODB_FK_RECONCILELOG_CUSTOMER: 'nc_jitu___Customers_id', NOCODB_LINK_PROD_RESOURCES: 'c4ko4x8kwi16swg', ALIST_URL: process.env.ALIST_URL || 'http://192.168.1.1:5244', // DSM host port (container DNS only inside bridge) ALIST_ADMIN_USERNAME: process.env.ALIST_ADMIN_USERNAME || 'hoelee', ALIST_ADMIN_PASSWORD: process.env.ALIST_ADMIN_PASSWORD, // from env W4_DRY_RUN: 'false', }; if (!ENV.NOCODB_TOKEN || !ENV.ALIST_ADMIN_PASSWORD) { console.error('NOCODB_TOKEN + ALIST_ADMIN_PASSWORD env required'); process.exit(1); } const httpRequest = async (opts) => { const { method = 'GET', url, headers = {}, body } = opts; const res = await fetch(url, { method, headers: { ...headers, 'Content-Type': 'application/json' }, body: body !== undefined && body !== null ? JSON.stringify(body) : undefined, }); const text = await res.text(); let parsed = null; try { parsed = text ? JSON.parse(text) : null; } catch { parsed = text; } return parsed; }; const sandbox = { $env: ENV, $json: { query: { dryRun: 'true' } }, console, }; sandbox.helpers = { httpRequest }; (async () => { const fn = vm.runInNewContext(`(async function(){\n${code}\n})`, sandbox, { filename: 'w4-body-live.js' }); const result = await fn(); console.log(JSON.stringify(result.json, null, 1)); })().catch(e => { console.error('LIVE RUN FAILED:', e); process.exit(1); });