@directctrl/fixturelibrary
Version:
Utility library making it easy to work with the open-fixture-library.
230 lines • 9.57 kB
JavaScript
"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