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

@linnovate/blocktree

v1.4.2

Published

Tools for developers, to build services with a uniform standard (node_modules/envs/logs).

Downloads

406

Readme

Blocktree core

Tools for developers, to build services with a uniform standard (node_modules/envs/logs).


Install module

npm install @linnovate/blocktree

API

Basic server

Infrastructures

Tools

Utils

Services: Databases

Services: Api

Services: Handlers

Setup server


/**
 * Server
 * @modules [express]
 * @envs [PORT]
 * @dockerCompose
  # Server service
  server:
    image: node:18.17
    working_dir: /usr/src/app
    volumes:
      - ./:/usr/src/app
    ports:
      - 3000:3000
    env_file:
      - .env
    command:
      - /bin/sh -c "yarn && yarn start"
 */
import express from 'express';
const app = express();
const PORT = process.env.PORT || 3000;
const server = app.listen(PORT, () => console.log(`Example app listening on port ${PORT}!`));

Infrastructures


Security Express

/**
 * Security Express
 * @function SecurityExpress
 * @modules [compression@^1 helmet@^7 cors@^2]
 * @envs []
 * @param {object} the express app
 * @param {object} {
 *   corsOptions,   // see: https://www.npmjs.com/package/cors#configuring-cors 
 *   helmetOptions, // see: https://www.npmjs.com/package/helmet
 * }
 * @return {object} is done
 */
SecurityExpress(app, { corsOptions, helmetOptions } = {});

Swagger Express

/**
 * Swagger Express
 * @function SwaggerExpress
 * @modules [swagger-ui-express@^5 swagger-jsdoc@^6]
 * @envs [SWAGGER_PATH]
 * @route /api-docs
 * @param {object} the express app
 * @param {object} options {
 *   SWAGGER_PATH,               // the api docs route
 *   autoExpressPaths,           // create swagger paths by express routes (default: true)
 *   ...[swagger-ui options],    // see: https://www.npmjs.com/package/swagger-ui-express 
 *   ...[swagger-jsdoc options], // see: https://www.npmjs.com/package/swagger-jsdoc
 * }
 * @return {promise} is done
 * @routes {
 *   [get] [SWAGGER_PATH]        // the swagger ui
 *   [get] [SWAGGER_PATH].json   // the swagger docs
 * }
 */
SwaggerExpress(app);

/**
 * Example JsDoc annotated
 * @openapi
 * /login:
 *   get:
 *     description: Welcome to swagger-jsdoc!
 *     responses:
 *       200:
 *         description: Returns a mysterious string.
 */
app.get('/login', (req, res) => res.send("OK"));

Graphql Express

/**
 * Graphql Express
 * @function GraphqlExpress
 * @modules [graphql graphql-yoga@^4 ws@^8 graphql-ws@^5]
 * @envs []
 * @param {object} the express app
 * @param {array} [{
 *   directives: [{
 *     typeDefs: String,      // see: https://spec.graphql.org/draft/#sec-Type-System.Directives
 *     transformer: Function, // see: https://the-guild.dev/graphql/tools/docs/schema-directives#implementing-schema-directives
 *   }]
 *   typeDefs,    // see: https://graphql.org/learn/schema
 *   resolvers,   // see: https://graphql.org/learn/execution
 * }]
 * @param {object} the options {
 *   serverWS,    // the express server
 *   yogaOptions, // see: https://the-guild.dev/graphql/yoga-server/docs
 * }
 * @return {object} express app.next()
 *
 * @example setup Graphql:
   ---------------
   import express from 'express';
   const app = express();
   const server = app.listen(5000);
   GraphqlExpress(app, [{ typeDefs: '', resolvers: {} }], { serverWS: server, yogaOptions: {} });
 *	 
 * @example server WebSocket:
   ---------------------------
   const { createPubSub } = await import('graphql-yoga');
   const pubSub = createPubSub();
   export default {
     Mutation: {
       test: () => pubSub.publish("MY_TEST", { test: true }),
     },
     Subscription: {
       test: {
         subscribe: () => pubsub.subscribe("MY_TEST"),
       }
     }
   }
 *
 * @example client WebSocket:
   ---------------------------
   import { createClient } from 'graphql-ws';
   const client = createClient({ url: 'ws://localhost:5000/graphql' });

   const unsubscribe = client.subscribe({
     query: 'subscription { test }',
   },{
     next: (data) => console.log("next:", data),
     error: (data) => console.log("error:", data),
     complete: (data) => console.log("complete:", data),
   });
*/
GraphqlExpress(app, [{ typeDefs: '', resolvers: {} }], { serverWS: server, yogaOptions: {} });
// using AutoLoad
AutoLoad(["typeDefs", "directives", "resolvers"]).then(schemas => {
  GraphqlExpress(app, schemas, { serverWS: server, yogaOptions: {} });
});

Elastic Indexer Express

/**
 * Elastic Indexer Express
 * @function ElasticIndexerExpress
 * @modules [@elastic/elasticsearch@^8 pino@^8]
 * @envs [ELASTIC_INDEXER_PATH, ELASTICSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} the express app
 * @param {object} options {
 *   ELASTIC_INDEXER_PATH,    // the api docs route (default: /elastic-indexer)
 *   configs: [{     // {null|array}
 *     ELASTICSEARCH_URL, // the elastic service url (http[s]://[host][:port])
 *     index,      // {string} the elastic alias name
 *     mappings,   // {null|object} the elastic mappings (neets for create/clone index)
 *     settings,   // {null|object} the elastic settings (neets for create/clone index)
 *     bulk,       // {null|object} the elastic bulk options (neets for routing and more)
 *     keyId,      // {null|string} the elastic doc key (neets for update a doc)
 *     mode,       // {null|enum:new,clone,sync} "new" is using a new empty index, "clone" is using a clone of the last index, "sync" is using the current index. (default: "new") 
 *     keepAliasesCount,  // {null|number} how many elastic index passes to save
 *   }],
 *   batchCallback, // async (offset, config, reports) => ([])
 *   testCallback,  // async (config, reports) => true
 * }
 * @return {promise:object} the reports data
 * @routes {
 *   [post] [ELASTIC_INDEXER_PATH]/build/:indexName
 *   [post] [ELASTIC_INDEXER_PATH]/stop/:indexName
 *   [post] [ELASTIC_INDEXER_PATH]/restore/:indexName/:backup
 *   [get]  [ELASTIC_INDEXER_PATH]/backups/:indexName
 *   [get]  [ELASTIC_INDEXER_PATH]/search?:indexName?:text?:from?:size?
 * }
*/
ElasticIndexerExpress(app, {
  configs: [{
    ELASTICSEARCH_URL: 'http://localhost:9200',
    index: 'test',
  }],
  batchCallback: async (offset, config) => !offset && [{ count: 1 }, { count: 2 }],
});
// Or with auth
app.use('/admin', passport.authenticate('...'));
ElasticIndexerExpress(app, {
  ELASTIC_INDEXER_PATH: '/admin/elastic-indexer',
  // ...
});

Mongo Indexer Express

/**
 * Mongo Indexer Express
 * @function MongoIndexerExpress
 * @modules [mongodb@^6 pino@^8]
 * @envs [MONGO_INDEXER_PATH, MONGO_URI, LOG_SERVICE_NAME]
 * @param {object} the express app
 * @param {object} options {
 *   MONGO_INDEXER_PATH,    // the api docs route (default: /elastic-indexer)
 *   configs: [{     // {null|array}
 *     MONGO_URI,       // the mongo service uri (mongodb://[user]:[pass]@[host]:[port]/[db_name]?authSource=admin)
 *     collectionName,  // {null|string} the mongo collection name
 *     keyId,           // {null|string} the mongo doc key
 *     mode,            // {null|enum:new,clone,sync} "new" is using a new empty index, "clone" is using a clone of the last index, "sync" is using the current index. (default: "new") 
 *     keepAliasesCount,  // {null|number} how many elastic index passes to save
 *     mongoClientOptions,
 *   }],
 *   batchCallback, // async (offset, config, reports) => ([])
 *   testCallback,  // async (config, reports) => true
 * }
 * @return {promise:object} the reports data
 * @routes {
 *   [post] [MONGO_INDEXER_PATH]/build/:collectionName
 *   [post] [MONGO_INDEXER_PATH]/stop/:collectionName
 *   [post] [MONGO_INDEXER_PATH]/restore/:collectionName/:backup
 *   [get]  [MONGO_INDEXER_PATH]/backups/:collectionName
 *   [get]  [MONGO_INDEXER_PATH]/search?:collectionName?:text?:from?:size?
 * }
*/
MongoIndexerExpress(app, {
  configs: [{
    MONGO_URI: 'mongodb://root:root@localhost:27017/test?authSource=admin',
    collectionName: 'items',
  }],
  batchCallback: async (offset, config, reports) => !offset && [{ count: 1 }, { count: 2 }],
});
// Or with auth
app.use('/admin', passport.authenticate('...'));
MongoIndexerExpress(app, {
  MONGO_INDEXER_PATH: '/admin/mongo-indexer',
  // ...
});

OpenId Express

/**
 * Open Id Express 
 * @function OpenIdExpress
 * @modules [openid-client@^5]
 * @envs [ISSUER_CLIENT_ID, ISSUER_CLIENT_SECRET, ISSUER_URL, ISSUER_REDIRECT_URI, WEBSITE_URL]
 * @param {object} the express app
 * @param {object} the options {
 *  issuer_url,          // (default: process.env.ISSUER_URL)
 *  client_id,           // (default: process.env.CLIENT_ID)
 *  client_secret,       // (default: process.env.CLIENT_SECRET)
 *  redirect_uri,        // (default: process.env.REDIRECT_URI)
 *  callback(req, res, tokenSet),   // return the tokenSet callback [optional]
 *  website_url,         // (default: process.env.WEBSITE_URL)
 *  cookieOptions,       // (default: { secure: true, sameSite: 'None', maxAge: 20 * 3600000 }) 
 * }
 * @return {promise} 
 * @docs https://www.npmjs.com/package/openid-client
*/
OpenIdExpress(app, {});

Tools


JWT Parser

/**
 * JWT Parser
 * @function JWTParser
 * @modules [jsonwebtoken@^8 pino@^8 pino-pretty@^10]
 * @envs [JWT_SECRET_KEY, LOG_SERVICE_NAME]
 * @param {string} token
 * @param {string} JWT_SECRET_KEY
 * @param {array} algorithms (default: ['RS256'])
 * @return {promise} the jwt parsing
 * @docs https://www.npmjs.com/package/jsonwebtoken
 */
const data = await JWTParser(token);

AutoLoad

/**
 * AutoLoad es6 modules from a dirs list
 * @function AutoLoad
 * @modules []
 * @envs []
 * @param {array} dirs - ["typeDefs", "directives", "resolvers"]
 * @param {string} baseUrl - "src"
 * @return {object} the modules
 * @example const { typeDefs, directives, resolvers } = await AutoLoad(["typeDefs", "directives", "resolvers"]);
 */
const { typeDefs, directives, resolvers } = await AutoLoad(["typeDefs", "directives", "resolvers"]);

Elastic Indexer

/**
 * Elastic Indexer.
 * @function ElasticIndexer
 * @modules [@elastic/elasticsearch@^8 pino@^8]
 * @envs [ELASTICSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} {
     ELASTICSEARCH_URL, // the elastic service url (http[s]://[host][:port])
     index,      // {string} the elastic alias name
     mappings,   // {null|object} the elastic mappings (neets for create/clone index)
     settings,   // {null|object} the elastic settings (neets for create/clone index)
     bulk,       // {null|object} the elastic bulk options (neets for routing and more)
     keyId,      // {null|string} the elastic doc key (neets for update a doc) (default: "id")
     mode,       // {null|enum:new,clone,sync} "new" is using a new empty index, "clone" is using a clone of the last index, "sync" is using the current index. (default: "new") 
     keepAliasesCount,  // {null|number} how many elastic index passes to save
     serviceSDK, // {null|object} the client service sdk (default: ElasticClient)
   }
 * @param {function} async batchCallback(offset, config, reports)
 * @param {function} async testCallback(config, reports)
 * @return {promise:object} the reports data
 * @dockerCompose
  # Elastic service
  elastic:
    image: elasticsearch:8.5.3
    volumes:
      - ./.elastic:/usr/share/elasticsearch/data
    environment:
    - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    - "discovery.type=single-node"
    - "xpack.security.enabled=false"
    ports:
      - 9200:9200
      - 9300:9300
 */
const reports = await ElasticIndexer({ index: "my_name", mappings: {}, settings: {} }, (offset, config, reports) => [], (config, reports) => true);
/**
 * Restore Elastic Indexer.
 * @function RestoreElasticIndexer
 * @modules [@elastic/elasticsearch@^8 pino@^8 pino-pretty@^10]
 * @envs [ELASTICSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} {
     ELASTICSEARCH_URL, // the elastic service url (http[s]://[host][:port])
     aliasName,      // {string} the elastic alias name
     indexName,      // {string} the elastic index name
   }
 * @return {bool} is done
 */
const isDone = await RestoreElasticIndexer({ ELASTICSEARCH_URL, aliasName, indexName });
/**
 * Elastic Indexer Backups.
 * @function ElasticIndexerBackups
 * @modules [@elastic/elasticsearch@^8 pino@^8 pino-pretty@^10]
 * @envs [ELASTICSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} {
     ELASTICSEARCH_URL, // the elastic host (http[s]://[host][:port])
     aliasName,         // {string} the elastic alias name
   }
 * @return {object} { data, actives }
 */
const { data, actives } = await ElasticIndexerBackups({ ELASTICSEARCH_URL, aliasName });

Mongo Indexer

/**
 * Mongo Indexer.
 * @function MongoIndexer
 * @modules [mongodb@^6 pino@^8 pino-pretty@^10]
 * @envs [MONGO_URI, LOG_SERVICE_NAME]
 * @param {object} {
     MONGO_URI,       // the mongo service uri (mongodb://[user]:[pass]@[host]:[port]/[db_name]?authSource=admin)
     collectionName,  // {null|string} the mongo collection name
     keyId,           // {null|string} the mongo doc key
     mode,            // {null|enum:new,clone,sync} "new" is using a new empty index, "clone" is using a clone of the last index, "sync" is using the current index. (default: "new") 
     keepAliasesCount,  // {null|number} how many index passes to save
     mongoClientOptions,
   }
 * @param {function} async batchCallback(offset, config, reports) [{ ... , deleted: true }]
 * @param {function} async testCallback(config, reports)
 * @return {promise} is done
 * @example const isDone = await MongoIndexer(config, async (offset, config, reports) => [], async (config) => true);
 * @dockerCompose
  # Mongo service
  mongo:
    image: mongo:7-jammy
    volumes:
      - ./.mongo:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root
    ports:
      - 27017:27017
 * */
const isDone = await MongoIndexer({ MONGO_URI, collectionName: "articles" }, async (offset, config, reports) => [], async (config) => true);
/**
 * Restore Mongo Indexer.
 * @function RestoreMongoIndexer
 * @modules [mongodb@^6 pino@^8 pino-pretty@^10]
 * @envs [MONGO_URI, LOG_SERVICE_NAME]
 * @param {object} {
     MONGO_URI,      // the mongo service uri (mongodb://[user]:[pass]@[host]:[port]/[db_name]?authSource=admin)
     aliasName,      // {string} the alias name
     indexName,      // {string} the index name
     lastIndexCount: // {number} the count of lasts index
   }
 * @return {bool} is done
 */
const isDone = await RestoreMongoIndexer({ MONGO_URI, aliasName, indexName });
/**
 * Mongo Indexer Backups.
 * @function MongoIndexerBackups
 * @modules [mongodb@^6 pino@^8 pino-pretty@^10]
 * @envs [MONGO_URI, LOG_SERVICE_NAME]
 * @param {object} {
     MONGO_URI,     // the mongo service uri (mongodb://[user]:[pass]@[host]:[port]/[db_name]?authSource=admin)
     aliasName,     // {string} the alias name
   }
 * @return {object} { data, actives }
 * @example const backupsList = await MongoIndexerBackups({ MONGO_URI, aliasName });
 */
const { data, actives } = await MongoIndexerBackups({ MONGO_URI, aliasName });

Rabbitmq Channel

/**
 * Assert Queue
 * @function AssertQueue
 * @modules [amqplib@^0.10 pino@^8 pino-pretty@^10]
 * @envs [RABBITMQ_URI, LOG_SERVICE_NAME]
 * @param {string} queue
 * @param {function} handler
 * @param {object} options {
     RABBITMQ_URI, // the rabbitmq service url (amqp://[[username][:password]@][host][:port])
   }
 * @return {bool}
 * @dockerCompose
  # Rabbitmq service
  rabbitmq:
    image: rabbitmq:3.9.29
    environment:
      RABBITMQ_DEFAULT_USER: root
      RABBITMQ_DEFAULT_PASS: root
    ports:
      - 5672:5672
      - 15672:15672
    volumes:
      - ./rabbitmq:/var/lib/rabbitmq
 */
AssertQueue('update_item', (data) => { console.log(data) });

/**
 * Send to queue
 * @function SendToQueue
 * @modules [amqplib@^0.10 pino@^8 pino-pretty@^10]
 * @envs [RABBITMQ_URI, LOG_SERVICE_NAME]
 * @param {string} queue
 * @param {object} data
 * @param {object} options {
     RABBITMQ_URI, // the rabbitmq service url (amqp://[[username][:password]@][host][:port])
   }
 * @return {bool}
 */
SendToQueue('update_item', {});

/**
 * Rabbitmq Channel
 * @function RabbitmqChannel
 * @modules [amqplib@^0.10 pino@^8 pino-pretty@^10]
 * @envs [RABBITMQ_URI, LOG_SERVICE_NAME]
 * @param {object} options {
     RABBITMQ_URI, // the rabbitmq service url (amqp://[[username][:password]@][host][:port])
   }
 * @return {object} channel
 */
RabbitmqChannel();

Redis Proxy

/**
 * Redis Proxy
 * @function RedisProxy
 * @modules [redis@^4 pino@^8 pino-pretty@^10]
 * @envs [REDIS_URI, LOG_SERVICE_NAME]
 * @param {string} the fetch url
 * @param {null|object} the fetch options
 * @param {null|object} {
     REDIS_URI, // {string} the redis service uri (redis[s]://[[username][:password]@][host][:port][/db-number])
     noCache,   // {null|bool} is skip cache
     debug,     // {null|bool} is show logs
     callback,  // {null|function} get remote data (default: FetchClient)
     setOptions, // {null|object} the redis client.set options (https://redis.io/commands/expire/)
   }
 * @return {promise} the data
 * @dockerCompose
  # Redis service
  redis:
    image: redis:7.2.0-alpine
    volumes:
      - ./.redis:/data
    ports:
      - 6379:6379
 */
const data = await RedisProxy("[host]/api", {}, { debug: true });

Utils


Logger

/**
 * Logger.
 * @function Logger
 * @modules [pino@^8 pino-pretty@^10]
 * @param {object} {
     LOG_SERVICE_NAME,
     setupOptions: { server: serverInstance, fetch: fetchInstance, ... },
     details: { codeLine: true, ip: true },
   }
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/pino
 */
import { Logger, logger } from '@linnovate/blocktree';
await Logger({ setupOptions: {}, details: {} });
logger.info('...', '...');

Services: Databases


Elastic Client

/**
 * Elastic Client singleton.
 * @function ElasticClient
 * @modules [@elastic/elasticsearch@^8 pino@^8 pino-pretty@^10]
 * @envs [ELASTICSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} { ELASTICSEARCH_URL: "http[s]://[host][:port]" } // the elastic service url
 * @return {promise} the singleton instance
 * @docs https://www.elastic.co/guide/en/elasticsearch/reference/8.5/elasticsearch-intro.html
 * @dockerCompose
  # Elastic service
  elastic:
    image: elasticsearch:8.5.3
    volumes:
      - ./.elastic:/usr/share/elasticsearch/data
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.type=single-node"
      - "xpack.security.enabled=false"
    ports:
      - 9200:9200
      - 9300:9300
  kibana:
    image: kibana
    ports:
      - 5601:5601
    environment:
      ELASTICSEARCH_HOSTS: '["https://elastic:9200"]'
 */
const data = await (await ElasticClient()).search({ ... });
const client = await ElasticClient();
const data = await client.search({ ... });

OpenSearch Client

/**
 * OpenSearch Client singleton.
 * @function OpenSearchClient
 * @modules [@opensearch-project/opensearch@^2 pino@^8 pino-pretty@^10]
 * @envs [OPENSEARCH_URL, LOG_SERVICE_NAME]
 * @param {object} { OpenSearchClient: "http[s]://[host][:port]" } // the service url
 * @return {promise} the singleton instance
 * @docs https://opensearch.org/docs/latest/clients/javascript/index/
 * @dockerCompose
  # OpenSearch service
  opensearch:
    image: opensearchproject/opensearch:2
    volumes:
      - ./.opensearch:/usr/share/opensearch/data
    environment:
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Opensearch1!
      - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.type=single-node"
      - "DISABLE_SECURITY_PLUGIN=true"
    ports:
      - 9200:9200
      - 9600:9600
  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:latest
    environment:
      OPENSEARCH_HOSTS: '["https://opensearch:9200"]'
    ports:
      - 5601:5601
 */
const data = await (await OpenSearchClient()).search({ ... });
const client = await OpenSearchClient();
const data = await client.search({ ... });

Mongo Client

/**
 * Mongo Client singleton.
 * @function MongoClient
 * @modules [mongodb@^5 pino@^8 pino-pretty@^10]
 * @envs [MONGO_URI, LOG_SERVICE_NAME]
 * @param {string} MONGO_URI the mongo service uri (mongodb://[host]:[port]/[db_name])
 * @param {object} MongoClientOptions
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/mongodb
 * @dockerCompose
  # Mongo service
  mongo:
    image: mongo:7-jammy
    volumes:
      - ./.mongo:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root
    ports:
      - 27017:27017
 */
const data = await (await MongoClient()).db('...');
const mongo = await MongoClient();
const data = await mongo.db('...');

MySql Client

/**
 * MySql Client singleton.
 * @function MySqlClient
 * @modules [mysql2@^3 pino@^8 pino-pretty@^10]
 * @envs [MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB, LOG_SERVICE_NAME]
 * @param {object} { MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB }
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/mysql2
 * @dockerCompose
  # Mysql service
  mysql:
    image: mysql:8
    volumes:
      - ./.mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    ports:
      - 3306:3306
 */
const data = await (await MySqlClient()).query('...', () => {});

Redis Client

/**
 * Redis Client singleton.
 * @function RedisClient
 * @modules [redis@^4 pino@^8 pino-pretty@^10]
 * @envs [REDIS_URI, LOG_SERVICE_NAME]
 * @param {object} {
    REDIS_URI,    // {string} the redis service uri (redis[s]://[[username][:password]@][host][:port][/db-number])
    ...options,   // {null|object} the redis options: https://github.com/redis/node-redis/blob/HEAD/docs/client-configuration.md
   }
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/redis
 * @dockerCompose
  # Redis service
  redis:
    image: redis:7.2.0-alpine
    volumes:
      - ./.redis:/data
    ports:
      - 6379:6379
 */
const data = await (await RedisClient()).set('key', 'value');

Services: Apis


Fetch Client

/**
 * Fetch Client
 * @function FetchClient
 * @modules [pino@^8 pino-pretty@^10]
 * @envs [LOG_SERVICE_NAME]
 * @param {string} the fetch url
 * @param {null|object} the fetch options
 * @return {promise} the Response with parse data
 * @example const { ok, status, data } = await FetchClient("[host]/api", {});
 */
const { ok, status, data } = await FetchClient("[host]/api", {});

Graphql Client

/**
 * GraphqlClient
 * @function GraphqlClient
 * @modules [pino@^8 pino-pretty@^10]
 * @envs [LOG_SERVICE_NAME]
 * @param {string} url // see: https://jsonapi.org
 * @param {object} {
 *   query,  // {object} see: https://graphql.org/learn/queries/
 *   variables, // {object}  see: https://graphql.org/learn/queries/#variables
 *   authToken,    // {string} see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
 * }
 * @return {object} the data
 */
const data = await GraphqlClient("[host]/graphql", { query = "", variables = {}, authToken: "MY_TOKEN" });

JsonApi Client

/**
 * JsonApi client
 * @function JsonApiClient
 * @modules [pino@^8 pino-pretty@^10]
 * @envs [LOG_SERVICE_NAME]
 * @param {string} url // see: https://jsonapi.org
 * @param {object} {
 *   filters,          // {object} see: https://jsonapi.org/format/#query-parameters-families
 *   includes,         // {array}  see: https://jsonapi.org/format/#fetching-includes
 *   offset,           // {number}
 *   limit,            // {number}
 *   authToken, // {string} see: https://jsonapi.org/format/#fetching-includes
 * }
 * @return {object} the data
 */
const data = await JsonApiClient("[host]/jsonapi/node/article", { filters: { title: "my title" }, includes: ["field_image"] });

/**
 * JsonApi client action
 * @function JsonApiClientAction
 * @modules [pino@^8 pino-pretty@^10]
 * @envs [LOG_SERVICE_NAME]
 * @param {string} url // see: https://jsonapi.org
 * @param {object} {
 *   method,    // {string}
 *   body,      // {object} see: https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/creating-new-resources-post#s-basic-post-request
 *   authToken, // {string} see: https://jsonapi.org/format/#fetching-includes
 * }
 * @return {object} the data
 */
const data = await JsonApiClientAction("[host]/jsonapi/node/article", { method = "POST", body = {}, authToken = "MY_TOKEN" });

Google Storage

/**
 * Google Storage singleton.
 * @function GoogleStorage
 * @modules [@google-cloud/storage@^7 pino@^8 pino-pretty@^10]
 * @envs [GOOGLE_STORAGE_CLIENT_EMAIL, GOOGLE_STORAGE_PRIVATE_KEY, LOG_SERVICE_NAME]
 * @param {object} { GOOGLE_STORAGE_CLIENT_EMAIL, GOOGLE_STORAGE_PRIVATE_KEY }
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/@google-cloud/storage
 */
const data = await (await GoogleStorage()).bucket({ ... });

S3 Storage

/**
 * S3 Storage singleton.
 * @function S3Storage
 * @modules [@aws-sdk/client-s3@^3 pino@^8 pino-pretty@^10]
 * @envs [S3_BUCKET, S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY, LOG_SERVICE_NAME]
 * @param {object} { S3_BUCKET, S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY }
 * @return {promise} the singleton instance
 * @docs https://www.npmjs.com/package/@aws-sdk/client-s3
 */
const data = await (await S3Storage()).send(command);

Services: Handlers


Rabbitmq Client

/**
 * Rabbitmq Client singleton.
 * @function RabbitmqClient
 * @modules [amqplib@^0.10 pino@^8 pino-pretty@^10]
 * @envs [RABBITMQ_URI, LOG_SERVICE_NAME]
 * @param {object} { RABBITMQ_URI: "amqp://[[username][:password]@][host][:port]" } // the rabbitmq service url 
 * @return {promise} the singleton instance
 * @docs https://github.com/amqp-node/amqplib
 * @dockerCompose
  # Rabbitmq service
  rabbitmq:
    image: rabbitmq:3.9.29
    environment:
      RABBITMQ_DEFAULT_USER: root
      RABBITMQ_DEFAULT_PASS: root
    ports:
      - 5672:5672
 */
const data = await (await RabbitmqClient()).createChannel();

Mailer Client

/**
 * Mailer Client singleton.
 * @function MailerClient
 * @modules [nodemailer@^6 pino@^8 pino-pretty@^10]
 * @envs [MAILER_HOST, MAILER_USER, MAILER_PESS, LOG_SERVICE_NAME]
 * @param {object} { MAILER_HOST, MAILER_USER, MAILER_PESS }
 * @return {promise} the singleton instance
 * @docs https://nodemailer.com/about;
 */
const data = await (await MailerClient()).sendMail({ ... });