Skip to main content

Mocked integration

In order to enable a very quick set-up of O2S, we have prepared an integration that does not rely on any external APIs. You can also use this integration to see in details how an integration should be constructed and can help you to build your own.

Requirements

This integration is automatically installed when you start the project using the create-o2s-app script, but you can also install it manually into the API Harmonization server by running:

npm install @o2s/integrations.mocked --workspace=@o2s/api

Supported modules

This integration handles following base module from the framework:

  • articles
  • cache
  • cms
  • invoices
  • notifications
  • organizations
  • resources
  • tickets
  • users

Data sources

This integration does not use any external APIs, and instead just returns data that is already in the normalized format. For example, you can take a look into the tickets mapper where a sample notification is mocked:

const MOCK_TICKET_1: Tickets.Model.Ticket = {
id: 'EL-465 920 678',
createdAt: dateToday.toISOString(),
updatedAt: dateToday.toISOString(),
topic: 'TOPIC_1',
type: 'TYPE_1',
status: 'OPEN',
attachments: [
{
name: 'Invoice.pdf',
url: 'https://example.com/attachment.pdf',
size: 1024,
author: {
name: 'Customer support',
email: 'customer@support.com',
},
date: '2024-12-12T12:00:00',
ariaLabel: 'Download Invoice.pdf',
},
],
properties: [
{
id: 'description',
value: `...`,
},
{
id: 'address',
value: 'Lorem ipsum dolor sit',
},
{
id: 'contact',
value: 'Lorem ipsum dolor sit',
},
],
comments: [
{
author: {
name: 'Customer support',
email: 'customer@support.com',
},
date: '2024-12-12T12:00:00',
content: `...`,
},
],
};

Pagination

When it comes to returning lists of objects, a randomizer is used in order to visualize that the data can change (e.g. for pagination purposes), which means that the same list will include different items every time you request it:

function shuffleArray(array: Tickets.Model.Ticket[]) {
for (let i = array.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j] as Tickets.Model.Ticket, array[i] as Tickets.Model.Ticket];
}
}

Filtering

To visualize that filtering works, a simple filtering mechanism is also used:

let items = MOCK_TICKETS.filter(
(item) =>
(!options.topic || item.topic === options.topic) &&
(!options.type || item.type === options.type) &&
(!options.status || item.status === options.status) &&
(!options.dateFrom || new Date(item.createdAt) >= new Date(options.dateFrom)) &&
(!options.dateTo || new Date(item.createdAt) <= new Date(options.dateTo)) &&
(!options.dateFrom || new Date(item.updatedAt) >= new Date(options.dateFrom)) &&
(!options.dateTo || new Date(item.updatedAt) <= new Date(options.dateTo)),
);

Extended modules

To give an example how an integration can extend a base module from the framework, we have used notifications to extend base model with one new field:

import { Models, Notifications } from '@o2s/framework/modules';

export class Notification extends Notifications.Model.Notification {
someNewField!: string;
}

export type Notifications = Models.Pagination.Paginated<Notification>;

This extension also includes a new endpoint in the controller:

export class NotificationsController extends Notifications.Controller {
@Get()
someNewEndpoint() {
return 'someNewEndpoint';
}
}

and you can also check the mapper to see how this new can be used there.