1
0
mirror of https://github.com/koloml/furbooru-tagging-assistant.git synced 2025-12-24 07:12:57 +00:00

Implemented separate class for importing/exporting the entities

This commit is contained in:
2024-11-12 16:19:13 +04:00
parent 01e538c5c2
commit c15fae7c3d
3 changed files with 138 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
import {validateImportedEntity} from "$lib/extension/transporting/validators.js";
import {exportEntityToObject} from "$lib/extension/transporting/exporters.js";
import StorageEntity from "./base/StorageEntity.js";
import {compressToEncodedURIComponent, decompressFromEncodedURIComponent} from "lz-string";
type EntityConstructor<T extends StorageEntity> =
(new (id: string, settings: Record<string, any>) => T)
& typeof StorageEntity;
export default class EntitiesTransporter<EntityType extends StorageEntity> {
readonly #targetEntityConstructor: EntityConstructor<EntityType>;
constructor(entityConstructor: EntityConstructor<EntityType>) {
this.#targetEntityConstructor = entityConstructor;
}
importFromJSON(jsonString: string): EntityType {
const importedObject = this.#tryParsingAsJSON(jsonString);
if (!importedObject) {
throw new Error('Invalid JSON!');
}
validateImportedEntity(
importedObject,
this.#targetEntityConstructor._entityName
);
return new this.#targetEntityConstructor(
importedObject.id,
importedObject
);
}
importFromCompressedJSON(compressedJsonString: string): EntityType {
return this.importFromJSON(
decompressFromEncodedURIComponent(compressedJsonString)
)
}
exportToJSON(entityObject: EntityType): string {
if (!(entityObject instanceof this.#targetEntityConstructor)) {
throw new TypeError('Transporter should be connected to the same entity to export!');
}
const exportableObject = exportEntityToObject(
entityObject,
this.#targetEntityConstructor._entityName
);
return JSON.stringify(exportableObject, null, 2);
}
exportToCompressedJSON(entityObject: EntityType): string {
return compressToEncodedURIComponent(this.exportToJSON(entityObject));
}
#tryParsingAsJSON(jsonString: string): Record<string, any> | null {
let jsonObject: Record<string, any> | null = null;
try {
jsonObject = JSON.parse(jsonString);
} catch (e) {
}
if (typeof jsonObject !== "object") {
throw new TypeError("Should be an object!");
}
return jsonObject
}
}

View File

@@ -0,0 +1,26 @@
/**
* @type {Map<string, ((entity: import('../base/StorageEntity.js').default) => Record<string, any>)>}
*/
const entitiesExporters = new Map([
['profiles', /** @param {import('../entities/MaintenanceProfile.js').default} entity */entity => {
return {
v: 1,
id: entity.id,
name: entity.settings.name,
tags: entity.settings.tags,
}
}]
])
/**
* @param entityInstance
* @param {string} entityName
* @returns {Record<string, *>}
*/
export function exportEntityToObject(entityInstance, entityName) {
if (!entitiesExporters.has(entityName)) {
throw new Error(`Missing exporter for entity: ${entityName}`);
}
return entitiesExporters.get(entityName).call(null, entityInstance);
}

View File

@@ -0,0 +1,39 @@
/**
* Map of validators for each entity. Function should throw the error if validation failed.
* @type {Map<string, ((importedObject: Object) => void)>}
*/
const entitiesValidators = new Map([
['profiles', importedObject => {
if (importedObject.v !== 1) {
throw new Error('Unsupported version!');
}
if (
!importedObject.id
|| typeof importedObject.id !== "string"
|| !importedObject.name
|| typeof importedObject.name !== "string"
|| !importedObject.tags
|| !Array.isArray(importedObject.tags)
) {
throw new Error('Invalid profile format detected!');
}
}]
])
/**
* Validate the structure of the entity.
* @param {Object} importedObject Object imported from JSON.
* @param {string} entityName Name of the entity to validate. Should be loaded from the entity class.
* @throws {Error} Error in case validation failed with the reason stored in the message.
*/
export function validateImportedEntity(importedObject, entityName) {
if (!entitiesValidators.has(entityName)) {
console.error(`Trying to validate entity without the validator present! Entity name: ${entityName}`);
return;
}
entitiesValidators
.get(entityName)
.call(null, importedObject);
}