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

@ng-adm/core

v0.0.3

Published

The core headless library for the Angular Admin framework, providing resource management and CRUD operations without any UI components.

Readme

@ng-adm/core

The core headless library for the Angular Admin framework, providing resource management and CRUD operations without any UI components.

Features

  • Headless Architecture: No UI components, pure TypeScript
  • Resource Management: Register and manage admin resources
  • Adapter Pattern: Pluggable data adapters for different backends
  • TypeScript First: Full type safety with comprehensive interfaces
  • ESM Only: Modern ES module support

Installation

npm install @ng-adm/core

Usage

Basic Setup

import { AdminAngular, MemoryAdapter, ResourceOptions } from '@ng-adm/core';

// Create admin instance
const admin = new AdminAngular();

// Define a resource
const userResource: ResourceOptions = {
  name: 'users',
  label: 'Users',
  properties: [
    { name: 'id', type: 'number', isVisible: false },
    { name: 'name', type: 'string', required: true },
    { name: 'email', type: 'string', required: true },
    { name: 'isActive', type: 'boolean', required: true },
    { name: 'createdAt', type: 'date', isVisibleInEdit: false },
  ],
  adapter: new MemoryAdapter(),
};

// Register the resource
admin.registerResource(userResource);

// Or register multiple resources at once
admin.registerResource([userResource, anotherResource]);

Constructor-based Resource Registration

You can also initialize AdminAngular with resources directly in the constructor:

// Initialize with resources in constructor
const admin = new AdminAngular([userResource, anotherResource]);

// Or create empty and register later
const admin = new AdminAngular();
admin.registerResource(userResource);

Using Adapters

// Create adapter instance (untyped - uses BaseRecord)
const adapter = new MemoryAdapter();

// Create typed adapter instance
interface User extends BaseRecord {
  name: string;
  email: string;
  isActive: boolean;
}

const typedAdapter = new MemoryAdapter<User>();

// List records (with type inference)
const users = await typedAdapter.list({
  resource: userResource,
  params: { page: 1, limit: 10 },
});

// Create a record (fully typed)
const newUser = await typedAdapter.create(
  {
    resource: userResource,
  },
  {
    name: 'John Doe',
    email: '[email protected]',
    isActive: true,
  },
);

// Update a record (fully typed)
const updatedUser = await typedAdapter.update(
  {
    resource: userResource,
  },
  1,
  {
    name: 'Jane Doe',
  },
);

// Delete a record
await typedAdapter.delete(
  {
    resource: userResource,
  },
  1,
);

Type Safety

The MemoryAdapter supports full TypeScript type safety through generics:

// All records must extend BaseRecord
interface User extends BaseRecord {
  name: string;
  email: string;
  isActive: boolean;
  // id, createdAt, updatedAt are automatically managed
}

// Use the typed adapter
const adapter = new MemoryAdapter<User>();

// TypeScript will enforce correct types for all operations
const user = await adapter.create(context, {
  name: 'John',
  email: '[email protected]',
  isActive: true,
});
// user is typed as User with id, createdAt, updatedAt

Property Types

Supported property types:

  • string: Text fields
  • number: Numeric fields
  • boolean: True/false values
  • date: Date/time values
  • json: Complex objects
  • reference: Links to other resources

Property Configuration

const properties: PropertyOptions[] = [
  {
    name: 'title',
    type: 'string',
    label: 'Title',
    required: true,
    isVisible: true, // Show in list view
    isVisibleInShow: true, // Show in detail view
    isVisibleInEdit: true, // Show in edit form
  },
  {
    name: 'categoryId',
    type: 'reference',
    reference: 'categories', // Reference to categories resource
    required: true,
  },
];

API Reference

AdminAngular

Main class for managing resources:

Constructor:

  • new AdminAngular(resources?: ResourceOptions[]): Create instance with optional initial resources

Resource Registration:

  • registerResource(resource: ResourceOptions): Register a single resource
  • registerResource(resources: ResourceOptions[]): Register multiple resources

Resource Management:

  • getResource(name: string): Get a resource by name
  • getResources(): Get all registered resources
  • hasResource(name: string): Check if resource exists
  • unregisterResource(name: string): Remove a resource
  • getResourceCount(): Get total number of resources

BaseRecord

Base type that all stored records should extend:

type BaseRecord = {
  id: number;
  createdAt?: Date;
  updatedAt?: Date;
};

MemoryAdapter

Generic in-memory adapter for testing and development:

Type Parameters:

  • T: The type of records stored (must extend BaseRecord)

Methods:

  • list(context: ActionContext): Promise<{ data: T[]; total: number }>: List records with pagination/filtering
  • show(context: ActionContext, id): Promise<T>: Get single record
  • create(context: ActionContext, data): Promise<T>: Create new record
  • update(context: ActionContext, id, data): Promise<T>: Update existing record
  • delete(context: ActionContext, id): Promise<boolean>: Delete record
  • clear(resourceName?): Clear all data (for testing)

Usage:

// Untyped (uses BaseRecord)
const adapter = new MemoryAdapter();

// Typed
interface User extends BaseRecord {
  name: string;
  email: string;
}
const typedAdapter = new MemoryAdapter<User>();

Building

npm run build

License

MIT