npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@commercetools-test-data/core

v10.10.1

Published

This package provides the core functions to define the data models

Downloads

28,218

Readme

@commercetools-test-data/core

This package provides the core functions to define the data models.

Install

$ pnpm add -D @commercetools-test-data/core

Creating a new data model

Models are defined in the models/* workspace and are grouped by domain in different packages.

To create a new model, add a new package in the models workspace with the following structure:

models/<package_name>
├── LICENSE
├── README.md
├── index.ts
├── package.json
├── src
│   └── <model_name>
│       ├── builder.ts
│       ├── generator.ts
│       ├── index.ts
│       ├── presets
│       │   └── index.ts
│       ├── transformers.ts
│       └── types.ts
├── tsconfig.declarations.json
└── tsconfig.json

To define and build new models, you need to use the core package @commercetools-test-data/core.

Builder

A builder is the result of the data model. Builders allow compositions with other models and to transform the data into different shapes, for example rest or graphql.

When you want to get the generated data, you would build the model (builder).

Builders are essentially composed by a generator and (optionally) transformers.

Generator

A generator is what describes the initial model shape and data. Most of the fields can and should be initialized with some values. You can define random values using fake or static values.

import type { TAuthor } from './types';
import { Generator, fake } from '@commercetools-test-data/core';

const generator = Generator<TAuthor>({
  fields: {
    firstName: fake((f) => f.person.firstName()),
    locale: 'en',
  },
});

The shape of the generator model is what usually is used in the UI and does not need transformation.

Models can have nested fields, like object or arrays. Most of the time those are also defined as models. In this case, the generator can define the value of the nested field as null. Those nested models are then built in the builder and or the transformers.

For example, the author model can have a list of books:

import type { TAuthor } from './types';
import { Generator, fake } from '@commercetools-test-data/core';

const generator = Generator<TAuthor>({
  fields: {
    firstName: fake((f) => f.person.firstName()),
    locale: 'en',
    books: null,
  },
});

Books are defined as another model:

import type { TBook } from './types';
import { Generator, fake } from '@commercetools-test-data/core';

const generator = Generator<TBook>({
  name: 'Book',
  fields: {
    title: fake((f) => f.lorem.words()),
  },
});

When defining the builder for the Author, we can then initialize the books field by referencing the Book model.

import type { TAuthor } from './types';
import { Builder } from '@commercetools-test-data/core';
import * as Book from '../book';

const Author = Builder<TAuthor>({
  generator,
  transformers,
}).books([Book.random()]);

At the same time, we also need to tell the transformers that the books field can be built. We do that by specifying the field in the buildFields option:

import type { TAuthor, TAuthorGraphql } from './types';
import { Transformer } from '@commercetools-test-data/core';

const transformers = {
  graphql: Transformer<TAuthor, TAuthorGraphql>('graphql', {
    buildFields: ['books'],
    // ...
  }),
};

Transformers

A transformer is used to transform the data defined in the generator (the initial model) to another shape.

There are 3 available transformer types:

  • default: this is the "identity" transformer. You would use the build() method to get the generated data according to the initial shape.
  • graphql: this is the transformer for GraphQL data shapes. You would use the buildGraphql() method to get the generated data transformed into a GraphQL shape.
  • rest: this is the transformer for REST data shapes. You would use the buildRest() method to get the generated data transformed into a REST shape.

Defining a graphql and/or a rest transformer is optional and depends on what the specific data requirements are.

For example, for the Author we can define a graphql transformer like this:

import type { TAuthor, TAuthorGraphql } from './types';
import { Transformer } from '@commercetools-test-data/core';

const transformers = {
  graphql: Transformer<TAuthor, TAuthorGraphql>('graphql', {
    buildFields: ['books'],
    addFields: () => ({
      __typename: 'Author',
    }),
  }),
};

Then calling Author.random().buildGraphql<TAuthorGraphql>() will generate the data with the __typename field.

A transformer can be configured with different options:

  • buildFields: a list of fields that are defined as other data models. This is necessary so that transformers of these nested models are also executed.
  • removeFields: a list of fields that should be removed from the model.
  • addFields: a function that should return an object with new fields that needs to be added to the model. The object is then merged with the initial data. The function gets an object argument with the initial fields object, in case it's needed to construct the new object.
  • replaceFields: a function that should return the fully transformed value. This is useful for example when transforming data into different data types, for example an object into an array of objects. The function gets an object argument with the initial fields object, in case it's needed to construct the value.

The replaceFields option is mutually exclusive in regards to the addFields and removeFields options.

Presets

Presets are pre-configured models (builders) that can be defined for specific use cases and re-used.

For example:

// presets/author-with-one-book.ts
import type { TAuthorBuilder } from './types';
import * as Book from '../../book';
import Author from './builder';

const preset = (): TAuthorBuilder => Author.random().books([Book.random()]);
export default preset;

// presets/index.ts
export { default as authorWithOneBook } from './author-with-one-book';

Note that the preset exports a function. The function is useful in case the preset requires to use some random data, using the faker package. This ensures that on every function invocation, the returned data is indeed random.

For example:

// presets/author-with-one-book.ts
import type { TAuthorBuilder } from './types';
import { faker } from '@faker-js/faker';
import * as Book from '../../book';
import Author from './builder';

const preset = (): TAuthorBuilder =>
  Author.random().books([Book.random().title(faker.helpers.words())]);
export default preset;

// presets/index.ts
export { default as authorWithOneBook } from './author-with-one-book';

Types

The types.ts file contains the TypeScript representations of the models and transformed models.