UNPKG

@unito/integration-debugger

Version:

The Unito Integration Debugger

124 lines (123 loc) 6.41 kB
"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;