@edirect/template
v1.2.4
Published
Template Module
Downloads
275
Maintainers
Readme
@edirect/template
TemplateModule is a library that provides methods to transform a payload based on a given template. The transformation includes mapping fields, applying transformers, setting default values and so on.
Installation
$ npm i --save @edirect/template
Import
import { TemplateModule } from "./TemplateModule";
Methods
Constructor
The TemplateModule class does not have a constructor.
setContext(context): void
Sets the context object to be used during the transformation.
setTemplate(template): void
Sets the template object that describes the transformation to be performed.
setTransformers(transformers: ITransformer): void
Sets the transformers to be used during the transformation.
setOptions(transformers: ITemplateOptions): void
Sets the options to be used during and after the transformation.
verifyTransformer(transformer: ITransformer, methodName: string): boolean
Verifies if a given transformer method exists.
runTransformer(transformer: string, value?: unknown): unknown | null
Runs a transformer on a given value.
- transformer - The name of the transformer to be used.
- value - The value to be transformed.
checkValue(value: any): boolean
Checks if a given value is not null, undefined, or an empty string.
setValueByCondition(object, key: string, value: unknown)
Sets a value in an object after verify using the checkValue() method.
- object - The object to be modified.
- key - The key of the value to be set.
- value - The value to be set.
transformPayload<T, U>(obj: T, template = this.template): U
Transforms a payload object on a given template.
Simple example
import { TemplateModule } from "@edirect/template";
const template = {
edirect_firstname: "subscriber.firstName",
edirect_lastname: "subscriber.lastName",
};
const dataSource = {
subscriber: {
firstName: "template",
lastName: "service",
},
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// edirect_firstname: "template",
// edirect_lastname: "service",
// }
Example with transformers
First of all, what's a transformer?
A transformer is a way to handle values with more detail and freedom.
For example:
- Mapping
- Validation
- Formatting
- Business rules
- and so on ...
Each transformer receives two parameters:
value
: specific value that you want to handlecontext
: all context (payload) that you can use to build any logical
To map a value that you'd like to use some transformer feature, you can use these options:
fields
: it's an array with a data source path, and the first value that is found will be used.transformer
: it's a JS function, where you receive value and context as parameters and have all freedom to handle and return a valuedefaultValue
it's an option if the engine doesn't find any value in the fields data source array or the transformer doesn't return a value.
File name: baseTransformers.ts
import { ITransformer, ITransformerParams } from "@edirect/template";
const upperCase = ({ value }: ITransformerParams): string | null => {
return value ? String(value).toUpperCase() : null;
};
const fullName = ({ context }: ITransformerParams): string | null => {
try {
const { firstName, lastName } = context.subscriber;
return `${firstName} ${lastName}`;
} catch (error) {
return null;
}
};
const transformers: ITransformer = {
upperCase,
fullName,
};
export default transformers;
File name: index.ts
import { TemplateModule } from "@edirect/template";
import baseTransformers from "./baseTransformers";
const template = {
edirect_firstname: {
fields: ["firstName", "subscriber.firstName"],
transformer: "upperCase",
defaultValue: "First Name - Default",
},
edirect_lastname: {
fields: ["lastName", "subscriber.lastName"],
},
edirect_fullname: {
transformer: "fullName",
},
edirect_phone: {
fields: ["phoneNumber", "subscriber.phoneNumber"],
defaultValue: "999999999",
},
timeZone: {
defaultValue: "Time zone in Porto (GMT+1)",
},
};
const dataSource = {
subscriber: {
firstName: "template",
lastName: "service",
},
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setContext(dataSource);
templateModule.setTransformers(baseTransformers);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// edirect_firstname: "TEMPLATE",
// edirect_lastname: "service",
// edirect_fullname: "template service",
// edirect_phone: "999999999",
// timeZone: "Time zone in Porto (GMT+1)",
// }
Example with nested object + transformers
Note
: the transformer notation uses three keys to identify an object as being a transformer: fields, transformer, and defaultValue, if there are at least 1 of these keys, the engine will consider the object as being a transformer, on the other hand, if there isn't, the engine will consider as a nested object to mapper all information.
File name: baseTransformers.ts
import { ITransformer, ITransformerParams } from "@edirect/template";
const upperCase = ({ value }: ITransformerParams): string | null => {
return value ? String(value).toUpperCase() : null;
};
const transformers: ITransformer = {
upperCase,
};
export default transformers;
File name: index.ts
import { TemplateModule } from "@edirect/template";
import baseTransformers from "./baseTransformers";
const template = {
order: {
date: "order.date",
value: "order.value",
subscriber: {
name: "sub.name",
phone: "sub.phone",
email: {
fields: ["email", "sub.email"],
},
address: {
street: "sub.add.stt",
number: "sub.add.num",
city: {
fields: ["sub.add.city"],
transformer: "upperCase",
},
state: {
fields: ["sub.add.stt"],
transformer: "upperCase",
},
zip: {
fields: ["sub.add.zip"],
defaultValue: "0000-000",
},
},
},
},
};
const dataSource = {
order: {
value: 1000.0,
date: "2000-01-01",
},
sub: {
name: "name-test",
phone: "999999999",
email: "[email protected]",
add: {
st: "st-test",
num: 100,
city: "city-test",
stt: "state-test",
zip: "zip-test",
},
},
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setContext(dataSource);
templateModule.setTransformers(baseTransformers);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// order: {
// date: "2000-01-01",
// value: 1000,
// subscriber: {
// name: "name-test",
// phone: "999999999",
// email: "[email protected]",
// address: {
// street: "state-test",
// number: 100,
// city: "CITY-TEST",
// state: "STATE-TEST",
// zip: "zip-test",
// },
// },
// },
// }
Example with arrays + transformers
Note
: When it comes to arrays mapper, we need to have in mind that is required use this two keys: arraySource and arrayTemplate.
arraySource
: source path where the engine will seek the information to mapperarrayTemplate
: template that will be used for each object within the array
File name: baseTransformers.ts
import { ITransformer, ITransformerParams } from "@edirect/template";
const upperCase = ({ value }: ITransformerParams): string | null => {
return value ? String(value).toUpperCase() : null;
};
const transformers: ITransformer = {
upperCase,
};
export default transformers;
File name: index.ts
import { TemplateModule } from "@edirect/template";
import baseTransformers from "./baseTransformers";
const template = {
quote: {
orders: {
arraySource: "order",
arrayTemplate: {
value: "value",
date: "date",
products: {
arraySource: "products",
arrayTemplate: {
id: "id",
value: "value",
description: {
fields: ["description"],
transformer: "upperCase",
defaultValue: "Default description",
},
categories: "categories",
},
},
},
},
},
};
const dataSource = {
order: [
{
value: 1000.0,
date: "2000-01-01",
products: [
{
id: "id-test-1",
value: 1000,
description: "description-test 1",
categories: ["category-1"],
},
{
id: "id-test-2",
value: 2000,
description: "description-test 2",
categories: ["category-1", "category-2"],
},
{
id: "id-test-3",
value: 3000,
categories: ["category-1", "category-2", "category-3"],
},
],
},
],
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setContext(dataSource);
templateModule.setTransformers(baseTransformers);
const result = templateModule.transformPayload(dataSource);
console.log(result);
//{
// quote: {
// orders: [
// {
// value: 1000,
// date: "2000-01-01",
// products: [
// {
// id: "id-test-1",
// value: 1000,
// description: "DESCRIPTION-TEST 1",
// categories: ["category-1"],
// },
// {
// id: "id-test-2",
// value: 2000,
// description: "DESCRIPTION-TEST 2",
// categories: ["category-1", "category-2"],
// },
// {
// id: "id-test-3",
// value: 3000,
// description: "Default description",
// categories: ["category-1", "category-2", "category-3"],
// },
// ],
// },
// ],
// },
// }
Template example with transformer + transformerParams
File name: baseTransformers.ts
import { ITransformer, ITransformerParams } from "@edirect/template";
const concat = (
{ value }: ITransformerParams,
...itensToConcat: string[]
): string => {
const arrayToConcat = [value, ...itensToConcat];
return arrayToConcat.join("");
};
const concatWithSeparator = (
{ value }: ITransformerParams,
separator: string,
...itensToConcat: string[]
): string => {
const arrayToConcat = [value, ...itensToConcat];
return arrayToConcat.join(separator);
};
const transformers: ITransformer = {
concat,
concatWithSeparator,
};
export default transformers;
File name: index.ts
import { TemplateModule } from "@edirect/template";
import baseTransformers from "./baseTransformers";
const template = {
status: "status",
concatenated_result: {
fields: ["lead_id"],
transformer: "concat",
transformerParams: [
"-",
"${person_number}",
"/",
"${person_number2}",
"_",
"${person_number3}",
],
},
concatenated_result2: {
fields: ["lead_id"],
transformer: "concatWithSeparator",
transformerParams: [
"-",
"${person_number}",
"${person_number2}",
"${person_number3}",
],
},
};
const dataSource = {
status: true,
lead_id: "FR-14af3f",
person_number: 123,
person_number2: 456,
person_number3: 789,
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setContext(dataSource);
templateModule.setTransformers(baseTransformers);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// status: true,
// concatenated_result: "FR-14af3f-123/456_789",
// concatenated_result2: "FR-14af3f-123-456-789"
// }
Template example with transformer + transformerParams + complexParams
File name: baseTransformers.ts
import { ITransformer, ITransformerParams } from "@edirect/template";
const translator = ({ value }: ITransformerParams, translateDict: Record<string, string>): string => {
const translated = translateDict.?[value];
if (!translated) return null;
return translated;
};
const transformers: ITransformer = {
translator,
};
export default transformers;
File name: index.ts
import { TemplateModule } from "@edirect/template";
import baseTransformers from "./baseTransformers";
const template = {
status: {
fields: ["status"],
transformer: "translator",
transformerParams: [
{
ERROR: "ERROR",
RECHAZADA: "REJECTED",
},
],
},
};
const dataSource = {
status: "RECHAZADA",
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setContext(dataSource);
templateModule.setTransformers(baseTransformers);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// status: "REJECTED",
// }
Example inferring types to transformPayload
import { TemplateModule } from "@edirect/template";
interface DataSource {
subscriber: {
firstName: string;
lastName: string;
};
}
interface TransformedData {
edirect_firstname: string;
edirect_lastname: string;
}
function transformData(dataSource: DataSource): TransformedData {
const template = {
edirect_firstname: "subscriber.firstName",
edirect_lastname: "subscriber.lastName",
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
return templateModule.transformPayload<TransformedData>(dataSource);
}
const dataSource = {
subscriber: {
firstName: "template",
lastName: "service",
},
};
console.log(transformData(dataSource));
// {
// edirect_firstname: "template",
// edirect_lastname: "service",
// }
Example with Options
Options:
- omitEmptyFields?: boolean;
import { TemplateModule } from "@edirect/template";
const template = {
edirect_firstname: "subscriber.firstName",
edirect_lastname: "subscriber.lastName",
edirect_age: "subscriber.age",
};
const dataSource = {
subscriber: {
firstName: "template",
lastName: "service",
age: "",
},
};
const options = { omitEmptyFields: true };
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
templateModule.setOptions(options);
const result = templateModule.transformPayload(dataSource);
console.log(result);
// {
// edirect_firstname: "template",
// edirect_lastname: "service",
// }
Example using simple arrays
import { TemplateModule } from "@edirect/template";
const template = {
emails: {
arraySource: "subscriber.emails",
simpleArray: true,
arrayTemplate: {
type: {
defaultValue: "personal",
},
value: "value",
},
},
};
const dataSource = {
subscriber: {
emails: ["[email protected]", "[email protected]"],
},
};
const templateModule = new TemplateModule();
templateModule.setTemplate(template);
const result = templateModule.transformPayload(dataSource);
console.log(result);
/*
{
"emails": [
{
"type": "personal",
"value": "[email protected]"
},
{
"type": "personal",
"value": "[email protected]"
}
]
}
*/