#!/usr/bin/env node 'use strict'; /** * Mock ProPresenter looks API, for developing the ProPresenter Look module * without the real thing. * * node tools/pp-looks-mock.js [port] (default 1601) * --every how often the live look changes (default 8) * --password demand ?password= like a locked ProPresenter * --no-list answer 404 for /v1/looks (an older ProPresenter) * * Point the module at host 127.0.0.1 and this port. Every few changes the * live look is "modified by hand", so it matches no saved look. */ const http = require('http'); const crypto = require('crypto'); const args = process.argv.slice(2); const flag = (name) => { const i = args.indexOf(name); return i >= 0 ? args[i + 1] : undefined; }; const port = Number(args.find((a) => /^\d+$/.test(a))) || 1601; const every = Number(flag('--every')) || 8; const password = flag('--password') || ''; const noList = args.includes('--no-list'); const screen = (on) => ({ video_input: false, media: on, slide: on, announcements: on, props: on, messages: on, presentation: null, mask: null }); const saved = ['Normal', 'Lyrics Only', 'Sermon', 'Countdown', 'Video Only'].map((name, index) => ({ id: { uuid: crypto.randomUUID(), name, index }, screens: [screen(true), screen(index !== 4)], })); let live = 0; let modified = false; let changes = 0; const liveUuid = crypto.randomUUID(); setInterval(() => { changes += 1; modified = changes % 4 === 0; if (!modified) live = (live + 1) % saved.length; console.log(`live look → ${saved[live].id.name}${modified ? ' (modified)' : ''}`); }, every * 1000); function currentLook() { return { id: { uuid: liveUuid, name: saved[live].id.name, index: modified ? saved.length : live }, screens: saved[live].screens, }; } http.createServer((req, res) => { const url = new URL(req.url, 'http://x'); const send = (code, body) => { res.writeHead(code, { 'Content-Type': 'application/json' }); res.end(body === undefined ? '' : JSON.stringify(body)); }; if (password && url.searchParams.get('password') !== password) return send(401, { error: 'password' }); if (url.pathname === '/version') return send(200, { name: 'Mock', platform: 'mac', os_version: '15', host_description: 'ProPresenter 21.0 (mock)' }); if (url.pathname === '/v1/looks') return noList ? send(404) : send(200, saved); if (url.pathname === '/v1/look/current') return send(200, currentLook()); send(404); }).listen(port, () => { console.log(`mock ProPresenter looks on http://127.0.0.1:${port} — live look changes every ${every}s`); console.log(`live look → ${saved[live].id.name}`); });