UNPKG

@grouparoo/core

Version:
164 lines (143 loc) 4.33 kB
import { SourceConfigurationObject, extractNonNullParts, logModel, getParentByName, getCodeConfigLockKey, validateConfigObjectKeys, IdsByClass, getAutoBootstrappedProperty, AnyConfigurationObject, } from "../../classes/codeConfig"; import { App, Property, PropertyTypes, Source } from "../.."; // configLoader imports need to be from root import { Op } from "sequelize"; import { ConfigWriter } from "../configWriter"; export async function loadSource( configObject: SourceConfigurationObject, configObjects: AnyConfigurationObject[], externallyValidate: boolean, validate = false ): Promise<IdsByClass> { let isNew = false; const app: App = await getParentByName(App, configObject.appId); validateConfigObjectKeys(Source, configObject, ["options", "mapping"]); let source = await Source.scope(null).findOne({ where: { id: configObject.id, appId: app.id, [Op.or]: { locked: getCodeConfigLockKey(), state: "deleted", }, }, }); if (!source) { isNew = true; source = await Source.create({ id: configObject.id, name: configObject.name, type: configObject.type, appId: app.id, modelId: configObject.modelId, }); } await source.update({ type: configObject.type, name: configObject.name, modelId: configObject.modelId, }); await source.setOptions( extractNonNullParts(configObject, "options"), externallyValidate ); // a form of testing the options if (externallyValidate && (await source.previewAvailable())) { await source.sourcePreview(); } let bootstrappedProperty: Property; let mappedRecordProperty: Property; let mapping: Record<string, string> = {}; async function setMapping() { if (configObject.mapping) { mappedRecordProperty = await getParentByName( Property, Object.values(extractNonNullParts(configObject, "mapping"))[0] ); mapping[Object.keys(extractNonNullParts(configObject, "mapping"))[0]] = mappedRecordProperty.key; await source.setMapping(mapping, externallyValidate); } } const bootstrappedPropertyConfig = getAutoBootstrappedProperty( configObject, configObjects.filter((o) => o.id !== configObject.id) ); try { await setMapping(); if (bootstrappedPropertyConfig) { bootstrappedProperty = await Property.findOne({ where: { id: bootstrappedPropertyConfig.id, }, }); } } catch (error) { if ( error.toString().match(/cannot find Property/) && bootstrappedPropertyConfig ) { const property = bootstrappedPropertyConfig; if (!property || !property.options) throw error; const mappedColumn = Object.values(property.options)[0]; bootstrappedProperty = await source.bootstrapUniqueProperty({ // @ts-ignore key: property.key || property["name"], type: property.type as typeof PropertyTypes[number], mappedColumn, id: property.id, local: validate, propertyOptions: extractNonNullParts(property, "options"), }); await setMapping(); } else { throw error; } } if (isNew || source.state === "deleted") { await source.update({ state: "ready", locked: ConfigWriter.getLockKey(configObject), }); if (bootstrappedProperty) { await bootstrappedProperty.update({ state: "ready", locked: ConfigWriter.getLockKey(configObject), }); } } logModel<Source>( source, validate ? "validated" : isNew ? "created" : "updated" ); if (bootstrappedProperty) { logModel<Property>( bootstrappedProperty, validate ? "validated" : isNew ? "created" : "updated" ); } return { source: [source.id], property: bootstrappedProperty ? [bootstrappedProperty.id] : [], // might have done this }; } export async function deleteSources(ids: string[]) { const sources = await Source.scope(null).findAll({ where: { locked: getCodeConfigLockKey(), id: { [Op.notIn]: ids } }, }); for (const i in sources) { const source = sources[i]; await source.update({ state: "deleted", locked: null }); logModel<Source>(source, "deleted"); } return sources.map((instance) => instance.id); }