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

@janiscommerce/client-creator

v7.0.0

Published

A package that wraps all the client creation in Janis Services

Downloads

2,181

Readme

client-creator

Build Status Coverage Status npm version

Introduction

This package includes all the generic functionality to create, update and remove a client from the services. Its main purpose is to avoid code repetition.

:inbox_tray: Installation

npm install @janiscommerce/client-creator

:hammer_and_wrench: Configuration

After installing this package you should create or update the following files:

Service Settings

You should configure the database config in your service for the new clients using the package Settings and the newClientsDatabases field

.janiscommercerc.json

{
  "newClientsDatabases": {
    "default": { // DB config that the new clients will use
      "type": "mongodb",
      "database": "janis-{{code}}" // necessary to add dynamic database name. Since 3.0.0
    },
    "other-database": {
      "write": {
        "type": "solr",
        "database": "core-{{code}}"
      },
      "read": {
        "type": "solr",
        "host": "host-read-solr",
        "database": "core-{{code}}"
      }
    }
  }
}

If we create a brand-new-client client with the previous settings, we will get the following client

{
  "code": "brand-new-client",
  "databases": {
    "default": {
      "write": {
        "type": "mongodb",
        "database": "janis-brand-new-client"
      }
    },
    "other-database": {
      "write": {
        "type": "solr",
        "database": "core-brand-new-client"
      },
      "read": {
        "type": "solr",
        "database": "core-brand-new-client"
      }
    }
  },
  "status": "active"
}

🔑 Secrets

The package will get the secret using the JANIS_SERVICE_NAME environment variable. If the secret was found, the result will be merged with the settings found in the janiscommercerc.json in the newClientsDatabases field.

The Secrets are stored in AWS Secrets Manager and obtained with the package @janiscommerce/aws-secrets-manager

In the example will be used a new client brand-new-client.

  1. Settings in file.
{
  "newClientsDatabases": {
    "default": {
      "type": "mongodb",
      "database": "janis-{{code}}"
    }
  }
}
  1. Secret fetched.
{
	"databases": {
    "default": {
      "write": {
        "host": "mongodb+srv://some-host.mongodb.net",
        "user": "secure-user",
        "password": "secure-password",
      }
    }
	}
}
  1. Settings merged after fetching the Secret
{
	"default": {
		"write": {
			"type": "mongodb",
			"database": "janis-brand-new-client",
			"host": "mongodb+srv://some-host.mongodb.net",
			"user": "secure-user",
			"password": "secure-password",
		}
	}
}

Skip Credential Fetching

To skip the fetch of the credentials, it can be used the setting skipFetchCredentials set as true.

{
  "newClientsDatabases": {
    "default": {
      "write": {
        "type": "mongodb",
        "skipFetchCredentials": true,
        "protocol": "mongodb+srv://",
        "host": "mongodb+srv://some-host.mongodb.net",
        "user": "some-user",
        "password": "insecure-password"
      }
    }
  }
}

ClientModel

At ./[MS_PATH]/models/client.js

'use strict';

const { ModelClient } = require('@janiscommerce/client-creator');

module.exports = ModelClient;

:sparkles::new::sparkles: Additional Fields Additional fields is a getter that allows the service to customize the clients fields, this is useful when a service needs their own custom data in clients.

:information_source: This will affect Client Create API and also Client Updated Event behavior

When a client is created or modified, the current client will be obtained from ID service and only the additional fields that exist in the getter will be saved in the service along with the basic client fields.

Model configuration

'use strict';

const { ModelClient } = require('@janiscommerce/client-creator');

module.exports = class MyModelClient extends ModelClient {

  static get additionalFields() {
    return [
      'myAdditionalField',
      'anotherAdditionalField'
    ]
  }
};

If a new client is created with these additional fields:

{
  "name": "Some Client",
  "code": "some-client",
  "myAdditionalField": "some-additional-data",
  "anotherAdditionalField": "another-additional-data",
  "unusedAdditionalField": "unused-data"
}

The client will be saved in the service with only the specified additional fields:

{
  "name": "Some Client",
  "code": "some-client",
  "myAdditionalField": "some-additional-data",
  "anotherAdditionalField": "another-additional-data"
}

APICreate

This Api will create new clients received in clients parameter.

Parameters:

  • clients string Array: The clients codes to be created. optional
  • processClients boolean: If received as true will compare Service clients with Janis ID clients and create, update or remove clients when needed. optional

File location ./[MS_PATH]/api/client/post.js

Basic version

'use strict';

const { APICreate } = require('@janiscommerce/client-creator');

module.exports = APICreate;

postSaveHook(clientCodes, clients)

Receives the clientCodes and clients from the API.

Parameters:

  • clientCodes string Array: The client created codes.
  • clients object Array: The clients created objects that were saved.

:information_source: This hook is used when received clients or processClients (when need to create)

'use strict';

const { APICreate } = require('@janiscommerce/client-creator');

module.exports = class ClientCreateAPI extends APICreate {

  async postSaveHook(clientCodes, clients) {

      await myPostSaveMethod(clientCodes);

      clientCodes.forEach(clientCode => {
          console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
      })

      clients.forEach(({ databases, status }) => {
        console.log(`This epic client has ${databases.length} databases and its status is ${status}`)
      })
    }
};

postUpdateHook(clients)

Hook called after update clients.

:information_source: This hook is used when received processClients (when no need to create)

Parameters:

  • clients object: The recently updated client.

postRemoveHook(clients)

Hook called after remove clients.

:information_source: This hook is used when received processClients (when found clients to remove in service)

Parameters:

  • clientsCodes string Array: The recently removed client codes.

ListenerCreated

This listener handles a created event emitted by Janis ID service. It allows to create a new client in the core database and set a new database for him.

File location ./[MS_PATH]/event-listeners/id/client/created.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerCreated } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerCreated, ...args);

postSaveHook(clientCode, client)

Receives the clientCode and client from the event.

Parameters:

  • clientCode string: The client created code of the created client.
  • client object: The client created object that was saved.
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerCreated } = require('@janiscommerce/client-creator');

class ClientCreatedListener extends ListenerCreated {

  async postSaveHook(clientCode, client) {
    console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
    console.log(`Saved client has ${client.databases.length} databases! Whoaaa`)
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientCreatedListener, ...args);

ListenerUpdated

This listener handles an updated event emitted by Janis ID service. It allows to activate or deactivate a client by changing his status.

File location ./[MS_PATH]/event-listeners/id/client/updated.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerUpdated } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerUpdated, ...args);

postSaveHook(currentClient)

Receives the currentClient from the event.

Parameters:

  • currentClient object: The recently updated client.
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerUpdated } = require('@janiscommerce/client-creator');

class ClientUpdatedListener extends ListenerUpdated {

  async postSaveHook(currentClient) {
    console.log(`Saved client ${currentClient.name}, now i'm gonna do something great`);
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientUpdatedListener, ...args);

ListenerRemoved

This listener handles a removed event emitted by Janis ID service. It allows to remove a client from the core clients database and drop his database.

File location ./[MS_PATH]/event-listeners/id/client/removed.js

Basic version

'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerRemoved } = require('@janiscommerce/client-creator');

module.exports.handler = (...args) => ServerlessHandler.handle(ListenerRemoved, ...args);

postRemovedHook(clientCode)

Receives the removed clientCode from the API.

Parameters:

  • clientCode string: The client removed code.
'use strict';

const { ServerlessHandler } = require('@janiscommerce/event-listener');
const { ListenerRemoved } = require('@janiscommerce/client-creator');

class ClientRemovedListener extends ListenerRemoved {

  async postRemovedHook(clientCode) {
    console.log(`Saved client ${clientCode}, now i'm gonna do something great`);
  }
}

module.exports.handler = (...args) => ServerlessHandler.handle(ClientRemovedListener, ...args);

Serverless functions

The package exports clientFunctions, an array with serverless functions to simplify the usage. It has the hooks for the Create Api and Listeners.

At ./serverless.js

'use strict';

const { helper } = require('sls-helper'); // eslint-disable-line
const { clientFunctions } = require('@janiscommerce/client-creator');

module.exports = helper({
	hooks: [
		// other hooks
		...clientFunctions
	]
});

Schemas

Add schemas for the Client Created, Updated and Removed event listeners and the Create Client API post. Subscribe to events.

At ./schemas/client/ add these two files:

At ./schemas/event-listeners/id/client add this file:

At ./events/src/id/ add this file:

Tests and coverage

The default Api and Listeners (:warning: without customization) not need to be tested.

To avoid coverage leaks, in ./.nycrc

{
  "exclude": [
    //... other excluded files
    "src/event-listeners/id/client/",
    "src/models/client.js",
    "src/api/client/post.js"
  ]
}

:warning: If exists any customization of the files, do not add the file to the .nycrc and add the corresponding tests.