diff --git a/src/main.ts b/src/main.ts
index 4af8c5b..cb5e80d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -507,15 +507,15 @@ export default class MediaDbPlugin extends Plugin {
for (const defaultProperty of defaultPropertyMappingModel.properties) {
let newProperty = newPropertyMappingModel.properties.find(x => x.property === defaultProperty.property);
if (newProperty === undefined) {
+ // default property is an instance
newProperties.push(defaultProperty);
} else {
- newProperties.push(newProperty);
+ // newProperty is just an object and take locked status from default property
+ newProperties.push(new PropertyMapping(newProperty.property, newProperty.newProperty, newProperty.mapping, defaultProperty.locked));
}
}
- newPropertyMappingModel.properties = newProperties;
-
- newPropertyMappings.push(newPropertyMappingModel);
+ newPropertyMappings.push(new PropertyMappingModel(newPropertyMappingModel.type, newProperties));
}
}
loadedSettings.propertyMappingModels = newPropertyMappings;
diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts
index 12aa4e2..a1e41a6 100644
--- a/src/settings/PropertyMapper.ts
+++ b/src/settings/PropertyMapper.ts
@@ -16,15 +16,23 @@ export class PropertyMapper {
* @param obj
*/
convertObject(obj: object): object {
+ console.log('test1');
+
if (!obj.hasOwnProperty('type')) {
return obj;
}
+ console.log('test2');
// @ts-ignore
- if (MEDIA_TYPES.contains(obj.type)) {
+ console.log(obj.type);
+
+ // @ts-ignore
+ if (MEDIA_TYPES.filter(x => x.toString() == obj.type).length < 1) {
return obj;
}
+ console.log('test3');
+
// @ts-ignore
const propertyMappings = this.plugin.settings.propertyMappingModels.find(x => x.type === obj.type).properties;
diff --git a/src/settings/PropertyMapping.ts b/src/settings/PropertyMapping.ts
index e68bdfc..a221918 100644
--- a/src/settings/PropertyMapping.ts
+++ b/src/settings/PropertyMapping.ts
@@ -1,4 +1,4 @@
-import {containsOnlyLettersAndUnderscores} from '../utils/Utils';
+import {containsOnlyLettersAndUnderscores, PropertyMappingNameConflictError, PropertyMappingValidationError} from '../utils/Utils';
import {MediaType} from '../utils/MediaType';
export enum PropertyMappingOption {
@@ -9,9 +9,73 @@ export enum PropertyMappingOption {
export const propertyMappingOptions = [PropertyMappingOption.Default, PropertyMappingOption.Map, PropertyMappingOption.Remove];
-export interface PropertyMappingModel {
- type: MediaType,
- properties: PropertyMapping[],
+export class PropertyMappingModel {
+ type: MediaType;
+ properties: PropertyMapping[];
+
+ constructor(type: MediaType, properties?: PropertyMapping[]) {
+ this.type = type;
+ this.properties = properties ?? [];
+ }
+
+ validate(): { res: boolean, err?: Error } {
+ // check properties
+ for (const property of this.properties) {
+ const propertyValidation = property.validate();
+ if (!propertyValidation.res) {
+ return {
+ res: false,
+ err: propertyValidation.err,
+ };
+ }
+ }
+
+ // check for name collisions
+ for (const property of this.getMappedProperties()) {
+ const propertiesWithSameTarget = this.getMappedProperties().filter(x => x.newProperty === property.newProperty);
+ if (propertiesWithSameTarget.length === 0) {
+ // if we get there, then something in this code is wrong
+ } else if (propertiesWithSameTarget.length === 1) {
+ // all good
+ } else {
+ // two or more properties are mapped to the same property
+ return {
+ res: false,
+ err: new PropertyMappingNameConflictError(`Multiple remapped properties (${propertiesWithSameTarget.map(x => x.toString()).toString()}) may not share the same name.`),
+ };
+ }
+ }
+ // remapped properties may not have the same name as any original property
+ for (const property of this.getMappedProperties()) {
+ const propertiesWithSameTarget = this.properties.filter(x => x.newProperty === property.property);
+ if (propertiesWithSameTarget.length === 0) {
+ // all good
+ } else {
+ // a mapped property shares the same name with an original property
+ return {
+ res: false,
+ err: new PropertyMappingNameConflictError(`Remapped property (${property}) may not share it's new name with an existing property.`),
+ };
+ }
+ }
+
+ return {
+ res: true,
+ };
+ }
+
+ getMappedProperties() {
+ return this.properties.filter(x => x.mapping === PropertyMappingOption.Map);
+ }
+
+ copy(): PropertyMappingModel {
+ const copy = new PropertyMappingModel(this.type);
+ for (const property of this.properties) {
+ const propertyCopy = new PropertyMapping(property.property, property.newProperty, property.mapping, property.locked);
+ copy.properties.push(propertyCopy);
+ }
+ return copy;
+ }
}
export class PropertyMapping {
@@ -49,16 +113,47 @@ export class PropertyMapping {
*/
}
- validate(): string {
+ validate(): { res: boolean, err?: Error } {
+ // locked property may only be default
+ if (this.locked) {
+ if (this.mapping === PropertyMappingOption.Remove) {
+ return {
+ res: false,
+ err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": locked property may not be removed.`),
+ };
+ }
+ if (this.mapping === PropertyMappingOption.Map) {
+ return {
+ res: false,
+ err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": locked property may not be remapped.`),
+ };
+ }
+ }
+
+ if (this.mapping === PropertyMappingOption.Default) {
+ return {res: true};
+ }
+ if (this.mapping === PropertyMappingOption.Remove) {
+ return {res: true};
+ }
+
if (!this.property || !containsOnlyLettersAndUnderscores(this.property)) {
- return `Error in conversion rule "${this.toString()}": property may not be empty and only contain letters and underscores.`;
+ return {
+ res: false,
+ err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": property may not be empty and only contain letters and underscores.`),
+ };
}
if (!this.newProperty || !containsOnlyLettersAndUnderscores(this.newProperty)) {
- return `Error in conversion rule "${this.toString()}": new property may not be empty and only contain letters and underscores.`;
+ return {
+ res: false,
+ err: new PropertyMappingValidationError(`Error in property mapping "${this.toString()}": new property may not be empty and only contain letters and underscores.`),
+ };
}
- return '';
+ return {
+ res: true,
+ };
}
toString(): string {
diff --git a/src/settings/PropertyMappingModelsComponent.svelte b/src/settings/PropertyMappingModelsComponent.svelte
index 1e14b20..f5d1af8 100644
--- a/src/settings/PropertyMappingModelsComponent.svelte
+++ b/src/settings/PropertyMappingModelsComponent.svelte
@@ -49,10 +49,15 @@
margin: 0;
}
- .media-db-plugin-property-binding-to {
+ .media-db-plugin-property-mapping-to {
display: flex;
align-items: center;
}
+
+ .media-db-plugin-property-mapping-validation {
+ color: var(--text-error);
+ margin-bottom: 5px;
+ }
@@ -81,18 +86,25 @@
{#if property.mapping === PropertyMappingOption.Map}
-
- { /each }
+ { /each }
-