1.0.16 • Published 8 months ago

@heliyos/heliyos-api-core v1.0.16

Weekly downloads
-
License
ISC
Repository
github
Last release
8 months ago

@heliyos/heliyos-api-core

This repository contains Heliyos's core API functions and middlewares. It's a private package hosted on npm.

Table of Contents

Installation

  1. Add .npmrc file in your project root:
registry.npmjs.org/:_authToken=${NPM_TOKEN}
  1. Install the package:
npm install @heliyos/heliyos-api-core

Core Modules

App Configuration

The core app setup provides middleware configuration and error handling.

import { core_app } from "@heliyos/heliyos-api-core";
import userRoutes from "./routes/user";

const routes = [userRoutes];

const options = {
  staticDir: true, // Enable static file serving
  skipExternals: false, // Skip external middleware
  skipInternals: false, // Skip internal middleware
  excludedHeaderRegexString: "", // Regex for excluding headers
};

const app = express();
await core_app(app, routes, options);

Authentication

Handles user authentication with support for Basic Auth, Bearer tokens, and API keys.

import { authentication } from "@heliyos/heliyos-api-core";

// Use as middleware
app.use(authentication);

// Required environment variables:
// SECRET_OF_SERVER
// BASE_URL_AUTH_SERVER
// SECRET_OF_AUTH_SERVER

Authorization

Role-based access control for resources.

import { authorize_user } from "@heliyos/heliyos-api-core";

const checkAccess = async (
  organizationId: number,
  userId: number,
  action: string
) => {
  const { isAllowed, userRole } = await authorize_user(
    organizationId,
    userId,
    action
  );
  return isAllowed;
};

Axios HTTP Client

Pre-configured Axios instances for internal services.

import { axios } from "@heliyos/heliyos-api-core";

// Available instances:
await axios.auth_server.get("/endpoint");
await axios.billing_server.post("/endpoint", data);
await axios.event_server.put("/endpoint", data);
await axios.notification_server.delete("/endpoint");
await axios.user_server.patch("/endpoint", data);

// Required environment variables for each server:
// BASE_URL_AUTH_SERVER + SECRET_OF_AUTH_SERVER
// BASE_URL_BILLING_SERVER + SECRET_OF_BILLING_SERVER
// BASE_URL_EVENT_API_SERVER + SECRET_OF_EVENT_API_SERVER
// BASE_URL_NOTIFICATION_SERVER + SECRET_OF_NOTIFICATION_SERVER
// BASE_URL_USERS_SERVER + SECRET_OF_USERS_SERVER

Database (Knex)

Database connection and query builder with pagination support.

import { knex } from "@heliyos/heliyos-api-core";

// Regular queries
const users = await knex("users").where({ active: true });

// With pagination
const results = await knex("users")
  .where({ active: true })
  .paginate(page, limit);

// Results format:
// {
//   data: Array<T>,
//   meta: {
//     page: number,
//     limit: number,
//     offset: number,
//     count: number
//   }
// }

// Required environment variables:
// DATABASE_URL

Validation

Input validation using Joi.

import { validate, joiObject } from "@heliyos/heliyos-api-core";

const schema = (joi) =>
  joi.object({
    name: joi.string().required(),
    email: joi.string().email().required(),
  });

// Validate input
validate(inputData, schema);

// Using joiObject directly
const customSchema = joiObject.object({
  // schema definition
});

Redis Client

Redis connection management.

import { createRedisClient } from "@heliyos/heliyos-api-core";

const redisClient = createRedisClient({
  url: "redis://localhost:6379",
});

Pusher

Real-time event broadcasting.

import { pusherTrigger, pusherTriggerBatch } from "@heliyos/heliyos-api-core";

// Single event
await pusherTrigger("channel-name", "event-name", { data: "payload" });

// Batch events
const batch = [
  { channel: "channel1", name: "event1", data: {} },
  { channel: "channel2", name: "event2", data: {} },
];
await pusherTriggerBatch(batch);

// Required environment variables:
// PUSHER_APP_ID
// PUSHER_KEY
// PUSHER_SECRET
// PUSHER_CLUSTER

SQS (Message Queue)

AWS SQS integration for message queuing.

import { SQSUtil } from "@heliyos/heliyos-api-core";

const sqs = new SQSUtil();

// Write message
await sqs.write(
  {
    resource: "users",
    type: "INSERT",
    objectId: { name: "user_id", value: "123" },
    data: { name: "John" },
  },
  "queue-url",
  "optional-group-id"
);

// Read message
const messages = await sqs.read("queue-url");

// Delete message
await sqs.delete(receiptHandle, "queue-url");

Email Services

Email sending with template support using Resend.

import { resendSendEmail } from "@heliyos/heliyos-api-core";

await resendSendEmail(
  ["recipient@example.com"],
  "template-id",
  { name: "John" },
  "Email Subject"
);

// Required environment variables:
// RESEND_API_KEY
// RESEND_FROM_RECIPIENT

Environment Management

Load environment variables from AWS Secrets Manager.

import { loadAppEnv } from "@heliyos/heliyos-api-core";

const env = await loadAppEnv();

// Required environment variables:
// ENV_SECRET_NAME

Logging

Structured logging with Winston.

import { logger } from "@heliyos/heliyos-api-core";

logger.info("Message", { meta: "data" });
logger.error("Error occurred", { error });
logger.warn("Warning message");

Development

To test changes locally:

  1. Build the package:
npm run build
  1. Create a tarball:
npm pack --pack-destination .
  1. Install in your project:
npm install /path/to/heliyos-api-core/heliyos-ai-heliyos-api-core-1.0.5.tgz

Publishing

To publish updates (admin only):

  1. Update version in package.json
npm version patch|minor|major
  1. Build the project
npm run build
  1. Publish
npm publish

Mongoose Setup and Usage Guide

This guide covers the setup and usage of Mongoose in your application, including connection management, models, queries, and utility functions.

Table of Contents

Setup

  1. Set environment variables:
env
MONGO_DATABASE_URL=mongodb://localhost:27017/your_database
MONGO_REPLICA_DATABASE_URL=mongodb://localhost:27017/your_replica_database

Connection Management

Import the connection objects:

import {
  core_mongoose,
  core_replica_mongoose,
} from "@heliyos/heliyos-api-core";

The connections are automatically cached and reused. You don't need to manage connections manually.

Check database health:

const health = await checkDatabaseHealth();
console.log("Primary connection:", health.primary);
console.log("Replica connection:", health.replica);

Creating Models

  1. Define your interface and schema:
import { Document, Schema, createModel } from "@heliyos/heliyos-api-core";
interface IUser extends Document {
  name: string;
  email: string;
  createdAt: Date;
}
const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
  createdAt: { type: Date, default: Date.now },
});
export const UserModel = createModel<IUser>("User", userSchema);
  1. Create indexes:
await ensureIndexes([UserModel]);

Querying

Basic queries:

// Find documents
const users = await UserModel.find({ name: "John" });
// Find one document
const user = await UserModel.findOne({ email: "john@example.com" });
// Create document
const newUser = await UserModel.create({
  name: "John",
  email: "john@example.com",
});

Using type-safe queries:

import { FilterQuery, UpdateQuery } from "@heliyos/heliyos-api-core";
// Type-safe find
const users = await UserModel.find({
  name: "John",
} as FilterQuery<IUser>);
// Type-safe update
await UserModel.updateOne(
  { id: userId } as FilterQuery<IUser>,
  { name: "Jane" } as UpdateQuery<IUser>
);

Pagination

Use the paginate method on any query:

const paginatedUsers = await UserModel.find().paginate<IUser>(1, 10);
console.log(paginatedUsers.data); // Array of users
console.log(paginatedUsers.meta); // { page, limit, offset, count }

Utility Functions

Bulk Operations

const operations = createBulkOperations<IUser>([
  {
    updateOne: {
      filter: { id: "123" },
      update: { name: "Updated Name" },
    },
  },
  {
    insertOne: {
      document: { name: "New User", email: "new@example.com" },
    },
  },
]);
await UserModel.bulkWrite(operations);

Transactions

const result = await withTransaction(async (session) => {
  const user = await UserModel.create([{ name: "John" }], { session });
  const post = await PostModel.create([{ userId: user.id }], { session });
  return { user, post };
});

Safe Delete

const deleted = await safeDelete(UserModel, { id: userId });
if (deleted) {
  console.log("User deleted successfully");
}

Upsert

const user = await upsertDocument(
  UserModel,
  { email: "john@example.com" },
  { name: "John", email: "john@example.com" }
);

Graceful Shutdown

process.on("SIGTERM", async () => {
  await closeConnections();
  process.exit(0);
});

Types

Common types available for import:

import {
  Document,
  Schema,
  Model,
  FilterQuery,
  UpdateQuery,
  Connection,
} from "@heliyos/heliyos-api-core";

Pagination Interface

interface Pagination<T> {
  data: T[];
  meta: {
    page: number;
    limit: number;
    offset: number;
    count: number;
  };
}

Best Practices

  1. Always use type-safe queries with FilterQuery and UpdateQuery
  2. Use transactions for operations that need to be atomic
  3. Implement proper error handling
  4. Use the utility functions provided for common operations
  5. Create indexes for frequently queried fields
  6. Use pagination for large result sets
  7. Properly handle connection events and errors
  8. Implement graceful shutdown in your application

Error Handling

Example of proper error handling:

try {
  const user = await UserModel.findById(id);
  if (!user) {
    throw new Error("User not found");
  }
  return user;
} catch (error) {
  console.error("Error fetching user:", error);
  throw error;
}

Environment-Specific Configuration

The connection setup automatically handles different environments:

  • Local development
  • Development
  • Production

Each environment can have its own connection settings and replica configuration.