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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@overture-stack/lyric

v0.16.0

Published

Data Submission system

Readme

Lyric

NPM Version

Install

npm i @overture-stack/lyric

Configuration

Provider

Import AppConfig and provider from @overture-stack/lyric module to initialize the provider with custom configuration:

import { AppConfig, provider } from '@overture-stack/lyric';

const appConfig: AppConfig = {
	auth: {
		enabled: false,
	}
	db: {
		host: 'localhost', // Database hostname or IP address
		port: 5432, // Database port
		database: 'my_database', // Name of the database
		user: 'db_user', // Username for database authentication
		password: 'secure_password', // Password for database authentication
	},
	features: {
		audit: {
			enabled: true, // Enable audit functionality (true/false)
		},
		recordHierarchy: {
			pluralizeSchemasName: false, // Enable or disable automatic schema name pluralization (true/false)
		},
	},
	idService: {
		useLocal: true, // Use local ID generation (true/false)
		customAlphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890', // Custom alphabet for ID generation
		customSize: 12, // Size of the generated ID
	},
	logger: {
		level: 'info', // Logging level (e.g., 'debug', 'info', 'warn', 'error')
	},
	schemaService: {
		url: 'https://api.lectern-service.com', // URL of the schema service
	},
};


const lyricProvider = provider(appConfig);

Auth Custom Handler

The authentication custom handler is a customizable function that can be used to verify user authentication and grant write and read permissions to organizations. It is used by the auth middleware to process incoming requests before any operation is executed, and to identify the user for audit purposes on these endpoints.

The handler receives an argument of type Request and returns a UserSessionResult response type, which provides information about the user's session or any errors encountered during the process.

This result UserSessionResult object may include the following:

  • user: A UserSession object containing details of the authenticated user:

    	{
    		username: string;
    		isAdmin: boolean;
    		allowedWriteOrganizations: string[];
    		allowedReadOrganizations: string[];
    	}
    • username: A string representing the user's identifier (e.g., email address).
    • isAdmin: A boolean value indicating whether the user has admin privileges. If true, the user has write access to all organizations.
    • allowedWriteOrganizations: An array of strings representing the organizations to which the user is allowed to write data.
    • allowedReadOrganizations: An array of strings representing the organizations to which the user is allowed to read data.

When an authentication error occurs, the system should return the following error details:

  • errorCode: A numeric code representing an error that occurred while processing the session request.
  • errorMessage: A descriptive message detailing the specific error, if an errorCode is provided.

Note: To include additional properties in the UserSession object (for example: groups, department or any other application specific information), you can create a custom user session type that extends UserSession. Example:

type CustomUserSession = UserSession & {
  department?: string;
  groups?: string[];
};

Example how to implement a custom auth handler:

import { type Request } from 'express';
import { type UserSessionResult } from '@overture-stack/lyric';
import jwt from 'jsonwebtoken';

const authHandler = (req: Request): UserSessionResult<CustomUserSession> => {
    // Extract the token from the request header
    const authHeader = req.headers['authorization'];

    // Check if the Authorization header exists and starts with "Bearer"
	if (!authHeader || !authHeader.startsWith('Bearer ')) {
		return {
			errorCode: 401,
			errorMessage: 'Unauthorized: No token provided'
		}
	}

	// Extract the token by removing the "Bearer " prefix
	const token = authHeader.split(' ')[1];

    try {
		// Verify the token using a public key
		const publicKey = process.env.JWT_PUBLIC_KEY!;
		const decodedToken = jwt.verify(token, publicKey);

		// Return the user session information after successfully verifying the  token
		return {
			user: {
				username: decodedToken.username, // Extract username from the decoded token
				isAdmin: decodedToken.isAdmin, // Check if the user has admin privileges
				allowedWriteOrganizations: decodedToken.writeScopes, // Get the list of organizations the user can write to
				allowedReadOrganizations: decodedToken.readScopes, // Get the list of organizations the user can read
				groups: decodedToken.groups, // List of the groups the user is part of
			 },
		};
	} catch (err) {
		 // If the token is invalid or an error occurs, return a forbidden error
		return {
			errorCode: 403,
			errorMessage: 'Forbidden: Invalid token'
		}
	}
};

To enable the authentication handler function, set enabled: true in the auth section of the AppConfig object, and provide your custom authentication handler with the customAuthHandler property.

By default, all HTTP methods are protected. Optionally, you can specify which methods to protect by setting the protectedMethods array (e.g., ['DELETE', 'POST', 'PUT']).

import { AppConfig, provider, UserSession } from '@overture-stack/lyric';

const appConfig: AppConfig = {
	...// Other configuration
	auth: {
		enabled: true,
		customAuthHandler: authHandler,
		// Optionally add protected methods
		protectedMethods: ['DELETE', 'POST', 'PUT'],
	};
}

On Finish Commit Callback function

The onFinishCommit callback function is executed automatically when a commit event is completed. This function provides the ability to customize the behavior or perform any additional actions after the commit is finished, using the result of the commit operation.

Example:

const onFinishCommitCallback: (resultOnCommit: ResultOnCommit) => {
    // Check if there are inserts, updates, or deletes
    if (resultOnCommit.data) {
      const { inserts, updates, deletes } = resultOnCommit.data;

      // Log the results to the console
      console.log(`Inserts: ${inserts.length}`);
      console.log(`Updates: ${updates.length}`);
      console.log(`Deletes: ${deletes.length}`);
    }

    // You can also perform additional custom actions here
    // For example index the data, or make another API call
  }

To use the onFinishCommit callback, it requires to be defined in the AppConfig object:


const appConfig: AppConfig = {
	...// Other configuration
	onFinishCommit: onFinishCommitCallback;
}

Usage

Express Routers

Use any of the resources available on provider on a Express server:

import express from 'express';

const app = express();

app.use('/submission', lyricProvider.routers.submission);

Database Migrations

Import migrate function from @overture-stack/lyric module to run Database migrations

import { migrate } from '@overture-stack/lyric';

migrate({
	host: 'localhost', // Database hostname or IP address
	port: 5432, // Database port
	database: 'my_database', // Name of the database
	user: 'db_user', // Username for database authentication
	password: 'secure_password', // Password for database authentication
});

Support & Contributions