@unito/integration-debugger
Version:
The Unito Integration Debugger
102 lines (101 loc) • 5.13 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const integration_api_1 = require("@unito/integration-api");
const CrawlerDriver = __importStar(require("../crawlerDriver"));
const helpers_1 = require("./helpers");
/**
* We do not support filter on complex object, so we exclude OBJECT, REFERENCE and BLOB for now.
*
* Using white listing to avoid unintentional modification
*/
const SUPPORTED_FIELD_TYPES = new Map([
[integration_api_1.FieldValueTypes.BOOLEAN, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.DATE, integration_api_1.OperatorTypes.GREATER_THAN_OR_EQUAL],
[integration_api_1.FieldValueTypes.DATETIME, integration_api_1.OperatorTypes.GREATER_THAN_OR_EQUAL],
[integration_api_1.FieldValueTypes.DURATION, integration_api_1.OperatorTypes.LESSER_THAN],
[integration_api_1.FieldValueTypes.EMAIL, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.RICH_TEXT_HTML, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.INTEGER, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.RICH_TEXT_MARKDOWN, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.NUMBER, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.STRING, integration_api_1.OperatorTypes.EQUAL],
[integration_api_1.FieldValueTypes.URL, integration_api_1.OperatorTypes.EQUAL],
]);
/**
* Check: Filter Items in a collection based on their fields.
*
* We filter on every field types except Objects and References.
*
* For example, if the item "foo" (collection at "/foos") with a string field and a date field
* the following step is produced:
*
* GetCollection /foos?filter=bar=expectedValue,createdDate>=2023-11-31
*
* The result of this step must be sucessful and have a valid shape, but no additional validation is done since
* its a **best effort** type of thing, integration may still return items that do not correspond to the filter.
*/
const check = {
label: 'Filter Items by fields',
prepareOnPreparedSteps: false,
validateOnError: false,
activatedByDefault: true,
prepare: async (stepResult, crawlerDriver) => {
const step = stepResult.step;
// To perform this operation, we need to know the schema of the items in the collection.
if (step.operation !== CrawlerDriver.Operation.GetCollection || !step.schemaPath) {
return [];
}
// We take all fields supporting filters (see SUPPORTED_FIELD_TYPES)
const filterFields = crawlerDriver.getFieldSchemas(step.schemaPath)?.filter(field => SUPPORTED_FIELD_TYPES.has(field.type)) ?? [];
if (!filterFields.length) {
return [];
}
const operatorPerFieldName = new Map(filterFields.map(field => [field.name, SUPPORTED_FIELD_TYPES.get(field.type)]));
const item = await crawlerDriver.generator.generate(filterFields ?? []);
// Append filter to the existing path's queryParams, in case any are already present.
const queryParams = (0, helpers_1.extractQueryParams)(step.path);
const existingFilters = queryParams.get('filter')?.split(',') ?? [];
const newFilters = Object.entries(item).map(([name, value]) => `${name}${operatorPerFieldName.get(name)}${value}`);
if (existingFilters.length && existingFilters.every(filter => newFilters.includes(filter))) {
return [];
}
const filters = Array.from(new Set(existingFilters.concat(newFilters)));
queryParams.set('filter', filters.join(','));
step.path = [step.path.split('?').at(0), queryParams.toString()].join('?');
return [step];
},
};
exports.default = check;
;