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

@owlmeans/module

v0.1.1

Published

The `@owlmeans/module` package provides a comprehensive module system for OwlMeans Common Libraries, designed for fullstack microservices and microclients development.

Downloads

16

Readme

OwlMeans Module — Shared library

The @owlmeans/module package provides a comprehensive module system for OwlMeans Common Libraries, designed for fullstack microservices and microclients development.

Overview

In the context of OwlMeans Common Libraries, a module is not a programmatic module but a URL unit in the system. Modules allow you to:

  • Declare URLs and their nesting relationships
  • Transform URLs into routes with attached handlers (backend) or specify components to render (frontend)
  • Generate final URLs for navigation or API calls on both backend and frontend
  • Provide a centralized place where all possible routes are registered
  • Enable micro-applications or micro-services to flawlessly address different parts of the system

For client-side applications, the @owlmeans/client-module package extends this base module system with client-specific capabilities such as API calls, URL generation, and request validation.

Core Concepts

Module

A module represents a URL unit that can be transformed into routes or components depending on the environment (frontend/backend). It consists of:

  • A route with URL path and alias
  • Optional guards for authentication/authorization
  • Optional gates for parameter validation
  • Optional filters for request/response validation
  • Optional handlers for processing requests

Parent-Child Relationships

Modules can be organized in hierarchical structures where child modules inherit properties from their parents, such as guards and gates.

Fullstack Consistency

A key architectural benefit of the module system is that all validators are defined at the module level using AJV (Another JSON Schema Validator) format. Since the system is designed for fullstack development (existing on both frontend and backend), these validation schemas are consistently accessible across all application services and clients. This ensures:

  • Unified validation: Same validation rules apply on both frontend and backend
  • Consistent data contracts: API contracts are shared between client and server
  • Reduced duplication: No need to define validation schemas separately for frontend and backend
  • Type safety: AJV schemas provide runtime validation that complements TypeScript's compile-time checking

API Reference

Types

CommonModule

The main module interface that extends BasicModule from @owlmeans/context.

interface CommonModule extends BasicModule {
  route: CommonRouteModel
  sticky: boolean                    // If true, router attaches this module unconditionally
  filter?: Filter                    // Request/response validation schemas
  guards?: string[]                  // Authentication guards
  gate?: string                      // Authorization gate
  gateParams?: string | string[]     // Gate parameters
  handle?: ModuleHandler             // Request handler function
  
  // Methods
  getAlias(): string
  getPath(): string
  getParentAlias(): string | null
  hasParent(): boolean
  resolve<M extends CommonModule>(): Promise<M>
  getParent<M extends CommonModule>(): M
  setService(service: string): void
  getGuards(): string[]
  getGates(): [string, string[]][]
}

ModuleHandler

Function signature for handling module requests.

interface ModuleHandler {
  <T, R extends AbstractRequest<any> = AbstractRequest<any>,
   P extends AbstractResponse<any> = AbstractResponse<any>>
  (req: R, res: P): T | Promise<T>
}

Filter

Schema definitions for request/response validation using AJV (Another JSON Schema Validator) format. All validators are defined at the module level, ensuring consistent validation schemas across both frontend and backend environments in fullstack applications.

interface Filter {
  query?: AnySchemaObject      // Query parameters validation (AJV schema)
  params?: AnySchemaObject     // Path parameters validation (AJV schema)
  body?: AnySchemaObject       // Request body validation (AJV schema)
  response?: AnySchemaObject   // Response validation (AJV schema)
  headers?: AnySchemaObject    // Headers validation (AJV schema)
}

Since the module system is designed for fullstack development, these AJV validation schemas are accessible and consistent across all application services and clients, providing unified data validation throughout the entire application stack.

AbstractRequest

Generic request interface for both frontend and backend.

interface AbstractRequest<T extends {} = {}> {
  alias: string
  auth?: Auth
  params: Record<string, string | number | undefined | null> | Partial<T>
  body?: Record<string, any> | Partial<T>
  headers: Record<string, string[] | string | undefined>
  query: Record<string, string | number | undefined | null> | Partial<T>
  path: string
  original?: any
  canceled?: boolean
  cancel?: () => void
  host?: string
  base?: string | boolean
}

AbstractResponse

Generic response interface for handling module responses.

interface AbstractResponse<T> {
  responseProvider?: any
  value?: T
  outcome?: ModuleOutcome
  error?: Error
  resolve(value: T, outcome?: ModuleOutcome): void
  reject(error: Error): void
}

Core Functions

module(route, opts?)

Creates a new module instance.

function module(route: CommonRouteModel, opts?: CommonModuleOptions): CommonModule

Parameters:

  • route: CommonRouteModel - The route configuration
  • opts: CommonModuleOptions - Optional module configuration

Returns: CommonModule instance

Example:

import { module } from '@owlmeans/module'
import { route } from '@owlmeans/route'

const userModule = module(route('users', '/users'), {
  sticky: true,
  guards: ['authenticated']
})

parent(module, aliasOrParent, _parent?)

Sets parent-child relationships between modules.

function parent<T extends CommonModule | CommonModule[]>(
  module: T, 
  aliasOrParent: string, 
  _parent?: string
): T

Parameters:

  • module: CommonModule or CommonModule[] - Module(s) to set parent for
  • aliasOrParent: string - Parent alias or module alias (when working with arrays)
  • _parent: string - Parent name (required when working with arrays)

Returns: The module(s) with parent relationship set

Example:

const userModule = module(route('users', '/users'))
const userProfileModule = module(route('user-profile', '/profile'))

parent(userProfileModule, 'users') // Sets users as parent of user-profile

Helper Functions

filter(filter, opts?)

Creates module options with filter configuration.

function filter(filter: Filter, opts?: CommonModuleOptions): CommonModuleOptions

Example:

const userModule = module(route('users', '/users'), filter({
  query: { type: 'object', properties: { limit: { type: 'number' } } }
}))

guard(guard, opts?)

Adds authentication guard to module options.

function guard(guard: string, opts?: CommonModuleOptions): CommonModuleOptions

Example:

const adminModule = module(route('admin', '/admin'), guard('admin'))

gate(gate, params, opts?)

Adds authorization gate with parameters to module options.

function gate(gate: string, params: string | string[], opts?: CommonModuleOptions): CommonModuleOptions

Example:

const userModule = module(route('user', '/user/:id'), gate('user-access', ['id']))

provideResponse(originalResponse?)

Creates an abstract response handler.

function provideResponse<T>(originalResponse?: unknown): AbstractResponse<T>

Example:

const response = provideResponse<UserData>()
response.resolve(userData, ModuleOutcome.Ok)

clone(modules, from, to, service)

Clones an existing module with new alias and service.

function clone<M extends CommonModule>(
  modules: M[], 
  from: string, 
  to: string, 
  service: string
): void

Parameters:

  • modules: M[] - Array of modules to add cloned module to
  • from: string - Source module alias
  • to: string - New module alias
  • service: string - Service name for the cloned module

Filter Building Functions

These functions create validation filters using AJV (Another JSON Schema Validator) format. All schemas are defined at the module level and remain consistent across both frontend and backend environments, ensuring unified validation throughout your fullstack application.

body(schema, filter?)

Creates or extends a filter with body validation schema using AJV format.

function body<T>(schema: JSONSchemaType<T>, filter?: Filter): Filter

query(schema, filter?)

Creates or extends a filter with query parameters validation schema using AJV format.

function query<T>(schema: JSONSchemaType<T>, filter?: Filter): Filter

params(schema, filter?)

Creates or extends a filter with path parameters validation schema using AJV format.

function params<T>(schema: JSONSchemaType<T>, filter?: Filter): Filter

response(schema, code?, filter?)

Creates or extends a filter with response validation schema using AJV format.

function response<T>(schema: JSONSchemaType<T>, code?: number, filter?: Filter): Filter

headers(schema, filter?)

Creates or extends a filter with headers validation schema using AJV format.

function headers<T>(schema: JSONSchemaType<T>, filter?: Filter): Filter

Example with AJV Schema Format:

import { body, query, params, response } from '@owlmeans/module'

// AJV schema for request body validation
const userFilter = body({
  type: 'object',
  properties: {
    name: { type: 'string' },
    email: { type: 'string' }
  },
  required: ['name', 'email']
}, query({
  type: 'object',
  properties: {
    include: { type: 'string', enum: ['profile', 'preferences'] }
  }
}))

// These AJV schemas are accessible on both frontend and backend
// providing consistent validation across your fullstack application

Utility Functions

isModule(object)

Type guard to check if an object is a CommonModule.

function isModule(module: Object): module is CommonModule

Example:

if (isModule(someObject)) {
  // someObject is definitely a CommonModule
  console.log(someObject.getAlias())
}

Constants

ModuleOutcome

Enumeration of possible module response outcomes.

enum ModuleOutcome {
  Ok = 'ok',
  Accepted = 'accepted',
  Created = 'created',
  Finished = 'finished'
}

Service Interfaces

GuardService

Service interface for implementing authentication guards.

interface GuardService extends InitializedService {
  token?: string
  authenticated(req?: Partial<AbstractRequest>): Promise<string | null>
  match: ModuleMatch
  handle: ModuleHandler
}

GateService

Service interface for implementing authorization gates.

interface GateService extends LazyService {
  assert: ModuleAssert  // Throws Error if assertion fails
}

Usage Examples

Basic Module Creation

import { module, guard, filter, body } from '@owlmeans/module'
import { route } from '@owlmeans/route'

// Create a simple module
const homeModule = module(route('home', '/'))

// Create a protected module with authentication
const dashboardModule = module(
  route('dashboard', '/dashboard'),
  guard('authenticated')
)

// Create a module with request validation
const createUserModule = module(
  route('create-user', '/users', { method: 'POST' }),
  filter(body({
    type: 'object',
    properties: {
      name: { type: 'string' },
      email: { type: 'string' }
    },
    required: ['name', 'email']
  }))
)

Module Hierarchies

// Create parent module
const apiModule = module(route('api', '/api'))

// Create child modules
const usersModule = module(route('users', '/users'))
const postsModule = module(route('posts', '/posts'))

// Set parent relationships
parent(usersModule, 'api')
parent(postsModule, 'api')

// Child modules inherit parent guards and gates
const userProfileModule = module(
  route('user-profile', '/profile'),
  guard('user-access')
)
parent(userProfileModule, 'users')

Module with Handler

const userModule = module(route('get-user', '/users/:id'), {
  handle: async (req, res) => {
    const userId = req.params.id
    const user = await getUserById(userId)
    res.resolve(user, ModuleOutcome.Ok)
  }
})

Complex Filter Example

import { filter, body, query, params, response } from '@owlmeans/module'

const complexModule = module(
  route('complex-api', '/api/users/:id'),
  filter(
    params({
      type: 'object',
      properties: {
        id: { type: 'string', pattern: '^[0-9]+$' }
      },
      required: ['id']
    },
    query({
      type: 'object',
      properties: {
        include: { type: 'string', enum: ['profile', 'posts'] },
        limit: { type: 'number', minimum: 1, maximum: 100 }
      }
    },
    response({
      type: 'object',
      properties: {
        user: { type: 'object' },
        profile: { type: 'object' }
      },
      required: ['user']
    })))
  )
)

Integration Patterns

Backend Integration

On the backend, modules are typically transformed into Express-like routes:

// Transform module to route with handler
app.get(userModule.getPath(), async (req, res) => {
  const moduleReq = adaptRequest(req)
  const moduleRes = provideResponse()
  
  await userModule.handle(moduleReq, moduleRes)
  
  if (moduleRes.error) {
    res.status(500).json({ error: moduleRes.error.message })
  } else {
    res.json(moduleRes.value)
  }
})

Frontend Integration

On the frontend, modules help generate URLs and determine which components to render:

// Generate URL for navigation
const userUrl = userModule.getPath() // '/users/:id'
const finalUrl = userUrl.replace(':id', userId)

// Navigate to the route
router.push(finalUrl)

Best Practices

  1. Organize modules hierarchically to take advantage of guard and gate inheritance
  2. Use meaningful aliases for modules to make them easy to reference
  3. Apply filters consistently to ensure proper validation
  4. Leverage guards and gates for security at the module level
  5. Keep modules focused on a single responsibility
  6. Use the clone function to create variations of existing modules for different services

Dependencies

This package depends on:

  • @owlmeans/route - For route management
  • @owlmeans/context - For contextual module support
  • @owlmeans/auth - For authentication integration
  • ajv - For JSON schema validation using AJV format, providing consistent validation across fullstack applications

Related Packages