import * as dotenv from 'dotenv'; import * as fs from 'node:fs'; import { z } from 'zod'; import path = require('node:path'); const EnvVariables = z.object({ DIST_PATH: z.string().default('./dist'), SCREEPS_SERVER: z.url().default('https://screeps.com'), SCREEPS_TOKEN: z.string(), SCREEPS_BRANCH: z.string().default('default'), }); type EnvVariables = z.infer; const readEnv = (): EnvVariables => { return EnvVariables.parse(process.env); }; type ScriptPayload = { branch: string; modules: Record; }; type ScreepsHeaders = { 'X-Token': string; } & object; const publishScript = async ( screeps_server: string, payload: ScriptPayload, headers: ScreepsHeaders ) => { const resp = await fetch(screeps_server + '/api/user/code', { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers, }, body: JSON.stringify(payload), }); if (!resp.ok) { const text = await resp.text(); throw new Error(`Upload failed: ${resp.status} ${text}`); } }; const genModuleKey = (filePath: string): string => { filePath = filePath.split(path.sep).slice(1).join(path.sep); return filePath.split('.')[0].split(path.sep).join('.'); }; const parseDist = (dist_path: string): Record => { let modules: Record = {}; const files = fs.readdirSync(dist_path, { withFileTypes: true }); for (const file of files) { if (file.isDirectory()) { const subModules = parseDist(path.join(dist_path, file.name)); modules = { ...modules, ...subModules, }; continue; } if (!file.name.endsWith('.js')) { continue; } const filePath = path.join(dist_path, file.name); const module_key = genModuleKey(filePath); modules[module_key] = fs.readFileSync(filePath, 'utf-8'); } return modules; }; const main = async () => { dotenv.config(); const env = readEnv(); const payload: ScriptPayload = { branch: env.SCREEPS_BRANCH, modules: parseDist(env.DIST_PATH), }; const headers: ScreepsHeaders = { 'X-Token': env.SCREEPS_TOKEN, }; await publishScript(env.SCREEPS_SERVER, payload, headers); }; main() .then(() => { console.log('Script published successfully!'); }) .catch((error) => { console.error(error); });