@edirect/template
TypeScript icon, indicating that this package has built-in type declarations

1.2.4 • Public • Published

@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 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
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: "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
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: ["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"
      }
    ]
  }
*/

Package Sidebar

Install

npm i @edirect/template

Weekly Downloads

58

Version

1.2.4

License

ISC

Unpacked Size

40.9 kB

Total Files

12

Last publish

Collaborators

  • rodrigo.prado
  • diogo.bolttech
  • mathais
  • robertoakang
  • samuelbolttech
  • gcmercante
  • herberts.fortuna
  • bruno.gomes
  • danielkhalebbatista
  • andsfranbolt
  • guilherme_benedeti
  • pauloazevedo-ed
  • rafael.jourdan
  • joaoferreirabolttech
  • iquirino.bolttech
  • lukaspiccinibt
  • adailson.bolttech
  • palvares_bolttech
  • plinio.altoe
  • edirectamorim
  • ricardo.coelho
  • layunne-bolttech
  • mayko.calazans
  • david.pereira
  • paulomarchi