@unito/integration-debugger
Version:
The Unito Integration Debugger
124 lines (123 loc) • 6.41 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const integration_api_1 = require("@unito/integration-api");
const crawler_1 = require("../crawler");
const helpers_1 = require("./helpers");
/**
* Check: Validate field types and semantics used in Unito
*
* We validate that fields of a relation have the correct type and semantic to be used in Unito.
*
* A classic comment must have:
* - a field of type html/markdown/string with the semantic "description"
* - a field of type datetime with the semantic "createdAt" (not required)
* - a field of type reference with the semantic "user" (not required)
*
*/
const check = {
label: 'Item - field types and semantics',
prepareOnPreparedSteps: false,
validateOnError: false,
activatedByDefault: true,
prepare: async (_stepResult, _crawlerDriver) => {
return [];
},
validate: (step, _crawlerDriver) => {
if (step.operation !== crawler_1.Operation.GetItem || !step.payloadOut) {
return;
}
const payload = step.payloadOut;
for (const relation of payload.relations) {
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.DESCRIPTION);
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.USER, { allowDuplicates: true });
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.PARENT, { allowDuplicates: true });
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.CREATED_AT);
const createdAtField = relation.schema.fields.find(field => field.semantic === integration_api_1.Semantics.CREATED_AT);
if (!createdAtField) {
step.warnings.push({
keyword: 'unito',
message: `The relation does not have a field with the semantic '${integration_api_1.Semantics.CREATED_AT}'.`,
detailedMessage: `Add the semantic '${integration_api_1.Semantics.CREATED_AT}' on one of your fields to unlock test mode of this item.`,
instancePath: step.path,
schemaPath: step.schemaPath ?? '',
params: {
code: `MISSING_CREATED_AT`,
},
});
}
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.UPDATED_AT);
const updatedAtField = relation.schema.fields.find(field => field.semantic === integration_api_1.Semantics.UPDATED_AT);
if (!updatedAtField) {
step.warnings.push({
keyword: 'unito',
message: `The relation does not have a field with the semantic '${integration_api_1.Semantics.UPDATED_AT}'.`,
detailedMessage: `Add the semantic '${integration_api_1.Semantics.UPDATED_AT}' on one of your fields to unlock incremental synchronization of this item.`,
instancePath: step.path,
schemaPath: step.schemaPath ?? '',
params: {
code: `MISSING_UPDATED_AT`,
},
});
}
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.PROVIDER_URL);
const providerUrlField = relation.schema.fields.find(field => field.semantic === integration_api_1.Semantics.PROVIDER_URL);
if (!providerUrlField) {
step.warnings.push({
keyword: 'unito',
message: `The relation does not have a field with the semantic '${integration_api_1.Semantics.PROVIDER_URL}'.`,
detailedMessage: `Add the semantic '${integration_api_1.Semantics.PROVIDER_URL}' on one of your fields to display a direct link in the UI.`,
instancePath: step.path,
schemaPath: step.schemaPath ?? '',
params: {
code: `MISSING_PROVIDER_URL`,
},
});
}
checkFieldSemanticAndType(step, relation, integration_api_1.Semantics.DISPLAY_NAME);
const displayNameField = relation.schema.fields.find(field => field.semantic === integration_api_1.Semantics.DISPLAY_NAME);
if (!displayNameField) {
step.warnings.push({
keyword: 'unito',
message: `The relation does not have a field with the semantic '${integration_api_1.Semantics.DISPLAY_NAME}'.`,
detailedMessage: `Add the semantic '${integration_api_1.Semantics.PROVIDER_URL}' on one of your fields to better display this item in the UI.`,
instancePath: step.path,
schemaPath: step.schemaPath ?? '',
params: {
code: `MISSING_DISPLAY_NAME`,
},
});
}
}
},
};
function checkFieldSemanticAndType(step, relation, semantic, { allowDuplicates } = { allowDuplicates: false }) {
const fields = relation.schema.fields.filter(field => field.semantic === semantic);
if (fields.length > 1 && !allowDuplicates) {
step.errors.push({
keyword: 'unito',
message: `The relation has multiple fields with the same Semantics.`,
detailedMessage: `The relation has multiple fields with the semantic '${semantic}'.`,
instancePath: step.path,
schemaPath: step.schemaPath ?? '',
params: {
code: `DUPLICATE_${semantic.toUpperCase()}`,
},
});
}
const expectedTypes = (0, helpers_1.getSemanticSupportedFieldTypes)(semantic);
for (const field of fields) {
if (field.type && !expectedTypes?.includes(field.type)) {
step.errors.push({
keyword: 'unito',
message: `The field type is not supported.`,
detailedMessage: `The field ${field.name} with semantic ${integration_api_1.Semantics.DESCRIPTION}' should be of type '${expectedTypes?.join("', '")}.`,
schemaPath: step.schemaPath ?? '',
instancePath: step.path,
params: {
code: `INVALID_${semantic.toUpperCase()}_TYPE`,
},
});
}
}
}
exports.default = check;