UNPKG

@edirect/template

Version:
700 lines (551 loc) 15.7 kB
# @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 ```shell $ npm i --save @edirect/template ``` ### Import ```javascript 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 ```javascript 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 handle - `context`: 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 value - `defaultValue` 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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: "template.service@bolltech.io", 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: "template.service@bolltech.io", // 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 mapper - `arrayTemplate`: template that will be used for each object within the array ##### File name: baseTransformers.ts ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```javascript 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 ```typescript 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; ```js 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 ```js import { TemplateModule } from "@edirect/template"; const template = { emails: { arraySource: "subscriber.emails", simpleArray: true, arrayTemplate: { type: { defaultValue: "personal", }, value: "value", }, }, }; const dataSource = { subscriber: { emails: ["johndoe@example.com", "janedoe@example.com"], }, }; const templateModule = new TemplateModule(); templateModule.setTemplate(template); const result = templateModule.transformPayload(dataSource); console.log(result); /* { "emails": [ { "type": "personal", "value": "johndoe@example.com" }, { "type": "personal", "value": "janedoe@example.com" } ] } */ ```