"use strict"; // The JSON examples of Amazon's interface pages. test/fixtures/alexa-docs// holds the examples of // https://developer.amazon.com/docs/alexaplus/device-apis/.html as the page printed them on 2026-09-28, one // file per example, named after the heading it stands under. const fs = require("node:fs"); const path = require("node:path"); const DOCS = path.join(__dirname, "..", "fixtures", "alexa-docs"); const ZOO = path.join(__dirname, "..", "fixtures", "zoo", "discovery.json"); /** One example: doc("alexa-powercontroller", "TurnOn.directive"). */ function doc(page, name) { return JSON.parse(fs.readFileSync(path.join(DOCS, page, `${name}.json`), "utf8")); } /** The names of the examples of a page that end in suffix: examples("alexa-powercontroller", ".directive"). */ function examples(page, suffix = "") { return fs.readdirSync(path.join(DOCS, page)) .filter((file) => file.endsWith(`${suffix}.json`)) .map((file) => file.slice(0, -".json".length)) .sort(); } /** The capability objects of one interface in a discovery example, in the order of the example. */ function capabilities(page, namespace, name = "discovery") { const [endpoint] = doc(page, name).event.payload.endpoints; return endpoint.capabilities.filter((capability) => capability.interface === namespace); } /** * Every value of a property of one interface that the examples of a page show, as { example, property }: what the * Response, StateReport and ChangeReport examples report, and the property examples of the page itself. */ function reported(page, namespace) { const found = []; for (const example of examples(page)) { const { event, context, ...property } = doc(page, example); if (example.endsWith(".property")) found.push({ example, property: { namespace, ...property } }); if (!event) continue; const change = event.payload && event.payload.change; // Several ChangeReport examples print the context as one property instead of { properties: [...] } const contextProperties = context && (context.properties || (context.namespace ? [context] : [])); found.push(...[...(change ? change.properties : []), ...(contextProperties || [])].map((each) => ({ example, property: each }))); } return found.filter(({ property }) => property.namespace === namespace); } /** * An endpoint of the zoo: the 22 test devices built on alex2node 1.5.2, as their discovery answer was on 2026-09-28 * when Alexa accepted all of them. Six had their capability JSON corrected by hand, because 1.5.2 had no way to * declare it: zoo-blinds, zoo-blower, zoo-heater, zoo-lock, zoo-motion, and zoo-health-lamp-31 for its version. */ function zoo(endpointId) { const endpoint = JSON.parse(fs.readFileSync(ZOO, "utf8")).find((each) => each.endpointId === endpointId); if (!endpoint) throw new Error(`${endpointId} is not in the zoo`); return endpoint; } module.exports = { doc, examples, capabilities, reported, zoo };