import fs from 'node:fs'; import { createRequire } from 'node:module'; import { compileFunction } from 'node:vm'; import ts from 'typescript'; const require = createRequire(import.meta.url); export const apply = 'Aplicar actualiza\u00e7\u00e3o do Suporte t\u00e9cnico'; export const refresh = 'Actualizar pr\u00e9via'; export const adopt = 'Confirmar leitura da pr\u00e9via actual'; export const retry = 'Repetir envio original'; export const reason = 'Actualizacao sintetica explicitamente fundamentada'; export function props(patch = {}) { return { actorId: 1, target: { database: 'support_profile_installation_test', port: 55441 }, hash: 'a'.repeat(64), code_hash: 'b'.repeat(64), installed: false, consistent: true, repairable: false, ready: true, action: 'install', schema: { state: 'base', ledger: false }, dependencies: { profiles_installed: true }, changes: [], backupDate: '2026-11-03T00:00:00Z', rollback: 'Conservar historico', commands: [], mfa_confirmed: true, ...patch, }; } export function result(request, patch = {}) { return { actor_id: 1, command_key: request.data.idempotency_key, target: props().target, migration: '2026_11_03_080000_add_technical_support_profile', code_hash: props().code_hash, installed: true, ...patch, }; } export function committed(request, patch = {}) { return props({ installed: true, action: 'none', hash: 'c'.repeat(64), schema: { state: 'support', ledger: true }, commands: [ { key: request.data.idempotency_key, code_hash: props().code_hash }, ], ...patch, }); } export function nodes(tree) { return Array.isArray(tree) ? tree.flatMap(nodes) : tree && typeof tree === 'object' ? [tree, ...nodes(tree.props?.children)] : []; } export function text(tree) { return Array.isArray(tree) ? tree.map(text).join('') : tree?.props ? text(tree.props.children) : typeof tree === 'string' || typeof tree === 'number' ? String(tree) : ''; } export function harness(initial = props(), mode = 'support') { const frames = new Map(), sent = [], reloads = [], before = new Set(), unload = new Set(); let active, cursor = 0, changed = false, effects = [], current = initial, tree, sequence = 0, confirmCalls = 0; const windowMock = { confirm() { confirmCalls++; return false; }, addEventListener(name, callback) { if (name === 'beforeunload') unload.add(callback); }, removeEventListener(name, callback) { if (name === 'beforeunload') unload.delete(callback); }, }; const state = (initialValue) => { const frame = active, i = cursor++; if (!(i in frame.cells)) frame.cells[i] = typeof initialValue === 'function' ? initialValue() : initialValue; return [ frame.cells[i], (value) => { const next = typeof value === 'function' ? value(frame.cells[i]) : value; if (!Object.is(next, frame.cells[i])) { frame.cells[i] = next; changed = true; } }, ]; }; const hooks = { useState: state, useRef(value) { const i = cursor++; active.cells[i] ??= { current: value }; return active.cells[i]; }, useEffect(callback, deps) { const frame = active, i = cursor++, prior = frame.cells[i]; if (!prior || !deps.every((value, j) => value === prior.deps[j])) { frame.cells[i] = { deps }; effects.push(() => { prior?.cleanup?.(); frame.cells[i].cleanup = callback(); }); } }, useCallback(callback, deps) { const i = cursor++, prior = active.cells[i]; if (!prior || !deps.every((value, j) => value === prior.deps[j])) active.cells[i] = { deps, callback }; return active.cells[i].callback; }, }; class ApiError extends Error { constructor(status, errors = {}) { super('SYNTHETIC HTTP ' + status); this.status = status; this.errors = errors; } } const mocks = { react: hooks, '@inertiajs/react': { Link: 'a', router: { reload: (options) => reloads.push(options), on(name, fn) { if (name === 'before') before.add(fn); return () => before.delete(fn); }, }, }, '../management/shared': { Management: 'main', button: '', control: '' }, '@/pages/management/shared': { Management: 'main', button: '', control: '', }, }; const request = (url, options = {}) => new Promise((resolve, reject) => { const entry = { url, data: options.body ? JSON.parse(options.body) : null, resolve, reject, }; (options.method === 'POST' ? sent : reloads).push(entry); }); mocks['./portal-api'] = { PortalApiError: ApiError, portalRequest: request, }; mocks['@/lib/profile-json'] = { profileJson: (url, data, method = 'POST') => request(url, { method, body: JSON.stringify(data) }), }; mocks['./operation-key'] = mocks['@/lib/operation-key'] = { createOperationKey: () => `00000000-0000-4000-8000-${String(++sequence).padStart(12, '0')}`, }; function load(path) { const code = ts.transpileModule( fs.readFileSync( new URL('../../../' + path, import.meta.url), 'utf8', ), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX, }, }, ).outputText; const module = { exports: {} }; compileFunction(code, ['require', 'module', 'exports'])( (name) => mocks[name] ?? require(name), module, module.exports, ); return module.exports; } mocks['./page-preparation-guard'] = mocks['@/lib/page-preparation-guard'] = load('resources/js/lib/page-preparation-guard.ts'); mocks['@/lib/profile-support-installation'] = load( 'resources/js/lib/profile-support-installation.ts', ); const Page = load( 'resources/js/pages/profiles/' + (mode === 'support' ? 'support-installation' : 'installation') + '.tsx', ).default; function expand(value, path, seen) { if (Array.isArray(value)) return value.map((child, i) => expand(child, path + '/' + (child?.key ?? i), seen), ); if (!value || typeof value !== 'object' || !value.props) return value; if (typeof value.type === 'function') { const id = path + '/' + value.type.name + ':' + (value.key ?? ''); seen.add(id); const frame = frames.get(id) ?? { cells: [] }; frames.set(id, frame); const previous = active, priorCursor = cursor; active = frame; cursor = 0; const rendered = value.type(value.props); active = previous; cursor = priorCursor; return { type: 'component', props: { name: value.type.name, children: expand(rendered, id, seen), }, }; } return { ...value, props: { ...value.props, children: expand( value.props.children, path + '/children', seen, ), }, }; } function render(next = current) { current = next; const previousWindow = globalThis.window; globalThis.window = windowMock; try { let loops = 0; do { changed = false; const seen = new Set(); tree = expand( { type: Page, key: 'page', props: current }, 'root', seen, ); for (const [id, frame] of frames) if (!seen.has(id)) { frame.cells.forEach((cell) => cell?.cleanup?.()); frames.delete(id); } const queue = effects; effects = []; queue.forEach((effect) => effect()); if (++loops > 12) throw Error('Component state did not settle'); } while (changed); return tree; } finally { globalThis.window = previousWindow; } } render(); return { sent, reloads, render, get props() { return current; }, get tree() { return tree; }, get confirmCalls() { return confirmCalls; }, get reason() { return nodes(tree).find((n) => n.type === 'textarea').props.value; }, button(label) { return nodes(tree).find( (n) => n.type === 'button' && text(n) === label, ); }, change(value) { nodes(tree) .find((n) => n.type === 'textarea') .props.onChange({ target: { value } }); render(); }, confirm(value = true) { nodes(tree) .find((n) => n.type === 'input' && n.props.type === 'checkbox') .props.onChange({ target: { checked: value } }); render(); }, number(index, value) { nodes(tree) .filter((n) => n.type === 'input' && n.props.type === 'number') [index].props.onChange({ target: { value } }); render(); }, get guards() { return before.size; }, click(label) { const node = this.button(label); if (!node) throw Error('Missing button ' + label); node.props.onClick(); render(); return sent.at(-1); }, async reply(value, request = sent.at(-1)) { request.resolve(value); for (let i = 0; i < 6; i++) await Promise.resolve(); render(); }, async fail(status = null, request = sent.at(-1)) { request.reject( status === null ? new Error('SYNTHETIC network loss') : new ApiError( status, status === 422 ? { note: ['SYNTHETIC rejected note'] } : {}, ), ); for (let i = 0; i < 6; i++) await Promise.resolve(); render(); }, leave(preserveState = false) { let prevented = false; const old = globalThis.window; globalThis.window = windowMock; try { for (const fn of before) fn({ detail: { visit: { method: 'get', preserveState } }, preventDefault() { prevented = true; }, }); } finally { globalThis.window = old; } return prevented; }, }; }