@sprucelabs/schema
Version:
Static and dynamic binding plus runtime validation and transformation to ensure your app is sound. 🤓
97 lines (96 loc) • 3.12 kB
JavaScript
import SpruceError from '../errors/SpruceError.js';
import validateSchema from '../utilities/validateSchema.js';
export default class SchemaRegistry {
constructor(shouldTrack = true) {
this.schemasById = {};
this.shouldTrack = shouldTrack;
}
static getInstance() {
if (!this.instance) {
this.instance = new SchemaRegistry(typeof process !== 'undefined' &&
process.env.SHOULD_USE_SCHEMA_REGISTRY !== 'false');
}
return this.instance;
}
trackSchema(schema) {
if (!this.shouldTrack) {
return;
}
validateSchema(schema);
const id = schema.id;
if (!this.schemasById[id]) {
this.schemasById[id] = [];
}
if (this.isTrackingSchema(schema.id, schema.version, schema.namespace)) {
throw new SpruceError({
code: 'DUPLICATE_SCHEMA',
schemaId: schema.id,
version: schema.version,
namespace: schema.namespace,
});
}
this.schemasById[id].push(schema);
}
isTrackingSchema(id, version, namespace) {
if (!this.isTrackedById(id) ||
!this.getSchemaNotThrowing(id, namespace, version)) {
return false;
}
return true;
}
getAllSchemas() {
return Object.values(this.schemasById).flat();
}
getTrackingCount() {
let count = 0;
Object.keys(this.schemasById).forEach((key) => {
count += this.schemasById[key].length;
});
return count;
}
forgetAllSchemas() {
this.schemasById = {};
}
getSchema(id, version, namespace) {
if (!this.isTrackedById(id)) {
throw new SpruceError({
code: 'SCHEMA_NOT_FOUND',
schemaId: id,
namespace,
version,
});
}
const versionMatch = this.getSchemaNotThrowing(id, namespace, version);
if (!versionMatch) {
throw new SpruceError({
code: 'VERSION_NOT_FOUND',
schemaId: id,
namespace,
});
}
return versionMatch;
}
getSchemaNotThrowing(id, namespace, version) {
const namespaceMatches = namespace
? this.schemasById[id].filter((d) => d.namespace === namespace)
: this.schemasById[id];
const versionMatch = namespaceMatches.find((d) => d.version === version);
return versionMatch;
}
isTrackedById(id) {
if (!this.schemasById[id]) {
return false;
}
return true;
}
forgetSchema(id, version) {
var _a, _b;
this.schemasById[id] = (_a = this.schemasById[id]) === null || _a === void 0 ? void 0 : _a.filter((schema) => !(schema.id === id && schema.version === version));
if (((_b = this.schemasById[id]) === null || _b === void 0 ? void 0 : _b.length) === 0) {
delete this.schemasById[id];
}
}
static reset() {
delete this.instance;
}
}