UNPKG

@directctrl/fixturelibrary

Version:

Utility library making it easy to work with the open-fixture-library.

230 lines 9.57 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FixtureLibrary = void 0; const ajv_1 = __importDefault(require("ajv")); const ajv_formats_1 = __importDefault(require("ajv-formats")); const fs_extra_1 = require("fs-extra"); const fixtureindex_1 = require("./fixtureindex"); const webhandler_1 = require("./webhandler"); const schema = __importStar(require("./ofl-schema/ofl-fixture.json")); const filehandler_1 = require("./filehandler"); /** * The Fixture Library * * The main class for managing DMX-Fixtures. * ## Example - `commonJs` * ```js * const { FixtureLibrary } = require('fixturelibrary'); * const fl = new FixtureLibrary(); * * async function foo(){ * // Fetching a Fixture from the Library * const fixture = await fl.getFixture('cameo/auro-spot-300'); * console.log(`${fixture.name} has ${fixture.modes.length} Modes.`); * * // This will return true since we're validating a fixture from Ofl. * console.log(fl.validate(fixture)); * } * ``` * * ## Example - `ESM/TS` * ```ts * import { FixtureLibrary } from 'fixturelibrary'; * * const fl = new FixtureLibrary(); * const fixture = await fl.getFixture('arri/broadcaster-2-plus'); * ``` */ class FixtureLibrary { /** * @param webAccess if web requests are allowed */ constructor(webAccess = true) { this.webAccess = webAccess; this.fixtureIndex = new fixtureindex_1.FixtureIndex(); // Loading the index file // Trying to recreate index from savefile: index.json // Improvements: Async or filestreams? if ((0, fs_extra_1.pathExistsSync)(`${filehandler_1.storageDirectory}/index.json`)) { try { this.fixtureIndex.setIndex((0, fs_extra_1.readJSONSync)(`${filehandler_1.storageDirectory}/index.json`)); } catch (error) { console.error(error); } } // Json Validation Setup this.ajv = new ajv_1.default({ verbose: true, strict: false, allErrors: true, discriminator: true, }).addKeyword('version').addFormat('color-hex', true); (0, ajv_formats_1.default)(this.ajv); } /** * Saving the Index to a file to be available after execution. */ async saveIndex() { (0, filehandler_1.writeJsonFile)('index.json', this.fixtureIndex.getIndex(), true); } /** * Get a Fixture from the Library or OFL if allowed. * This relies on reading definitions from file/web and caching. * Execution time depends on the size of the definition (.6 - 4ms) and if it was cached (.01ms). * In Case it needs to be downloaded, it will take alot longer. (depending on your connection) * @param key Key of the fixture * @param override if existing entries should be overwritten * @returns Fixture Definition or undefined if not found */ async getFixture(key) { // At first trying to get cached fixture definitions let fixture = this.fixtureIndex.fixtureFromCache(key); if (fixture) return fixture; const item = await this.fixtureIndex.getIndexItem(key); if (item?.path) { fixture = await (0, filehandler_1.readJsonFile)(item.path); if (fixture) this.fixtureIndex.cacheFixture(key, fixture); // If we find a url in the index we download the fixture } else if (this.webAccess) { let file; const sha = item?.sha; if (item?.url) { file = await (0, webhandler_1.request)(key); // If a github Sha is stored, we can request the fixture from github } else if (item?.sha && this.webAccess) { file = await (0, webhandler_1.githubRawFixtureRequest)(`${key}.json`); } if (file) { fixture = await this.setFixture(key, file, sha, true, true); } } return fixture; } /** * Adding a new fixture to the Library. * @param key new and unique fixture key * @param fixture Fixture Definition * @param sha The version SHA of the fixture (Can be usefull for Versioning) * @param validate If the fixture should be validated against the OFL Schema * @param override If existing entries should be overwritten * @returns The passed Fixture Definition to enable method chaining */ async setFixture(key, fixture, sha = '', validate = true, override = false) { if (!fixture) return undefined; if (this.fixtureIndex.hasIndexItem(key) && !override) return undefined; if (validate && !this.validate(fixture)) return undefined; // If the key is new and the definition is valid, we save it to file await (0, filehandler_1.writeJsonFile)(key, fixture, override); this.fixtureIndex.setIndexItem(key, { path: key, sha }); this.fixtureIndex.cacheFixture(key, fixture); await this.saveIndex(); return fixture; } /** * Validate a fixture definition against the Open Fixture Library Schema * @param fixture the fixture definition * @returns wether the fixture is applicable to the schema or not */ validate(fixture) { const valid = this.ajv.validate(schema, fixture); if (!valid) console.error(this.ajv.errors); return valid; } /** * This call has a long executiontime and is therefore **Not Recommended** to be used in scripts! * Please use `npx syncOfl shallow` instead! * * Insteadof {@link downloadOfl}, this only downloads the references to the OFL fixtures * and none of the files. * @returns List of all the fixtures which got updated. */ async fetchOfl() { if (!this.webAccess) return console.error('Web Access is disabled'); const ofl = await (0, webhandler_1.fetchOflFixtureDirectory)(); const updatedFixtures = []; ofl?.forEach(async (fixture) => { if (fixture.path !== 'manufacturers.json') { // Removing the .json from the end of the file const key = fixture.path.slice(0, -5); const item = this.fixtureIndex.getIndexItem(key); // If the SHA of the fixture doens't match, the index gets overwritten if (item?.sha !== fixture.sha) { this.fixtureIndex.setIndexItem(key, { sha: fixture.sha }); updatedFixtures.push(key); } } }); await this.saveIndex(); return updatedFixtures; } /** * This call has a long executiontime and is therefore **Not Recommended** to be used in scripts! * Please use `npx syncOfl` instead! * * **ONLY** available when allowing web access usage. * Downloading the whole Open Fixture Library to the fixture index. * The Fixtureindex should, after a successfull download, have an additional ~30KB in size. * @returns List of all the fixtures which got updated. */ async downloadOfl() { if (!this.webAccess) return console.error('Web Access is disabled'); const ofl = await (0, webhandler_1.fetchOflFixtureDirectory)(); const updatedFixtures = []; ofl?.forEach(async (fixture) => { if (fixture.path !== 'manufacturers.json') { // Removing the .json from the end of the file const key = fixture.path.slice(0, -5); const item = this.fixtureIndex.getIndexItem(key); // If the SHA of the fixture doens't match, the index gets overwritten if ((item?.path && item?.sha !== fixture.sha) || !item?.path) { updatedFixtures.push(key); // eslint-disable-next-line no-await-in-loop const file = await (0, webhandler_1.githubRawFixtureRequest)(`${key}.json`); await this.setFixture(key, file, fixture.sha, false, true); } } }); await this.saveIndex(); return updatedFixtures; } } exports.FixtureLibrary = FixtureLibrary; exports.default = FixtureLibrary; //# sourceMappingURL=fixturelibrary.js.map