58 lines
2.9 KiB
JavaScript
58 lines
2.9 KiB
JavaScript
// Optional integration with a local EC checkout. Execute its real bank service
|
|
// and bank migrations against disposable SQLite, with minimal fleet fixtures.
|
|
// No EC configuration, credentials, HTTP routes or production DB are loaded.
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { resolve } from 'node:path';
|
|
import vm from 'node:vm';
|
|
|
|
export function loadEcBank(directory) {
|
|
assert(directory, '--ec-root requires an EC checkout with installed dependencies');
|
|
const requireEc = createRequire(resolve(directory, 'package.json'));
|
|
const ts = requireEc('typescript');
|
|
const Database = requireEc('better-sqlite3');
|
|
function compile(file) {
|
|
const source = readFileSync(resolve(directory, 'src/lib/server', file), 'utf8');
|
|
return new vm.Script(ts.transpileModule(source, {
|
|
compilerOptions: {module:ts.ModuleKind.CommonJS, target:ts.ScriptTarget.ES2022}
|
|
}).outputText, {filename:file});
|
|
}
|
|
const service = compile('fleet/bank.ts');
|
|
const bankMigration = compile('db/bank.ts');
|
|
const credentialMigration = compile('db/bank-credentials.ts');
|
|
return guid => {
|
|
const database = new Database(':memory:');
|
|
function execute(script) {
|
|
const context = vm.createContext({
|
|
exports: {}, process: {env:{}},
|
|
require: name => {
|
|
assert.equal(name, '../db/index.js', 'unexpected EC runtime dependency');
|
|
return {db:() => database};
|
|
}
|
|
});
|
|
script.runInContext(context);
|
|
return context.exports;
|
|
}
|
|
database.exec(`
|
|
CREATE TABLE native_instances (id TEXT PRIMARY KEY, server TEXT, retired_at TEXT);
|
|
INSERT INTO native_instances VALUES ('instance', 'server', NULL);
|
|
CREATE TABLE servers (name TEXT PRIMARY KEY, destroyed_at TEXT);
|
|
INSERT INTO servers VALUES ('server', NULL);
|
|
CREATE TABLE leaderboard_matches (id INTEGER PRIMARY KEY, server TEXT, reporter_match_key TEXT, status TEXT);
|
|
INSERT INTO leaderboard_matches VALUES (1, 'server', 'match', 'active');
|
|
CREATE TABLE leaderboard_match_players (match_id INTEGER, guid TEXT, present INTEGER);
|
|
`);
|
|
database.prepare('INSERT INTO leaderboard_match_players VALUES (1, ?, 1)').run(guid);
|
|
execute(bankMigration).migrateBank(database);
|
|
execute(credentialMigration).migrateBankCredentials(database);
|
|
const {bankRequest} = execute(service);
|
|
return {
|
|
request: (action, body) => bankRequest(action, body, 'server', 'instance'),
|
|
ledger: () => database.prepare('SELECT guid, amount FROM bank_ledger ORDER BY id').all(),
|
|
requests: () => database.prepare('SELECT request_id, guid, state FROM bank_requests ORDER BY request_id').all(),
|
|
close: () => database.close()
|
|
};
|
|
};
|
|
}
|