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

@chickyky/arangoose-adminjs-adapter

v0.0.5

Published

AdminJS database adapter for arangoose (ArangoDB)

Downloads

176

Readme

@arangoose/adminjs-adapter

AdminJS v7 database adapter for arangoose. Register it once and pass arangoose models straight to AdminJS as resources.

Install

Not published to npm — consumed through the workspace:

// your app's package.json
"dependencies": {
  "arangoose": "workspace:*",
  "@arangoose/adminjs-adapter": "workspace:*"
}

adminjs (^7.0.0) is a peer dependency.

Node >= 20.19 required. AdminJS v7 is ESM-only and this adapter is built as CommonJS, so it relies on require() of an ES module — unflagged in Node 20.19 / 22.12 and later.

Setup

import AdminJS from 'adminjs';
import AdminJSExpress from '@adminjs/express';
import express from 'express';
import { connect } from 'arangoose';
import * as AdminJSArangoose from '@arangoose/adminjs-adapter';

import { UserModel, PostModel } from './models';

AdminJS.registerAdapter({
  Database: AdminJSArangoose.Database,
  Resource: AdminJSArangoose.Resource,
});

await connect({
  url: process.env.ARANGO_URL!,
  database: process.env.ARANGO_DB!,
  username: process.env.ARANGO_USER,
  password: process.env.ARANGO_PASSWORD,
});

await UserModel.ensureCollection();
await PostModel.ensureCollection();

const admin = new AdminJS({
  rootPath: '/admin',
  resources: [
    { resource: UserModel, options: { navigation: { name: 'Data' } } },
    { resource: PostModel },
  ],
});

const app = express();
app.use(admin.options.rootPath, AdminJSExpress.buildRouter(admin));
app.listen(3000);

Pass models via resources (recommended — it accepts per-resource options), or via databases, where each model expands to its single resource:

const admin = new AdminJS({ databases: [UserModel, PostModel] });

What gets mapped

Properties

Built from the schema definition. _key, _id and _rev are prepended and are not editable; _key is the record id AdminJS uses in URLs.

| Schema field | AdminJS property type | | ---------------------------- | --------------------- | | String | string | | Number | float | | Boolean | boolean | | Date | datetime | | Array, Object, 'Mixed' | mixed | | { ref: 'Model' } | reference |

Also carried over:

  • required: trueisRequired()
  • enum: [...]availableValues(), which AdminJS renders as a select
  • nested definitions → subProperties(), flattened as parent.child
const PostSchema = new Schema({
  title: { type: String, required: true }, // required text input
  status: { type: String, enum: ['draft', 'published'] }, // select
  author: { type: String, ref: 'User' }, // reference picker
  views: Number, // numeric input
  published: Boolean, // checkbox
  publishedAt: Date, // datetime picker
  address: { city: String }, // sub-property "address.city"
});

Filters

Equality filters, plus AdminJS from/to range filters translated to $gte/$lte and cast to the property's type. Filter paths that the resource does not declare are ignored — they arrive from the query string, so they are not passed through to AQL.

Writes

create, update and delete go through the arangoose model, so schema casting, validation, hooks and plugins all apply. Admin forms submit everything as strings; arangoose casts them back to Number/Boolean/Date before validating. _id and _rev are stripped from writes since ArangoDB manages them.

A failed validation surfaces as an error in the AdminJS form.

Exports

| Export | What it is | | -------------------------------------- | ---------------------------------------------------- | | Database | BaseDatabase implementation; wraps one model | | Resource | BaseResource implementation; the real adapter | | Property | BaseProperty implementation | | buildProperties(definition, prefix?) | Schema definition → Property[], exported for tests | | toArangooseFilter(filter) | AdminJS Filter → arangoose filter object |

Limitations

  • One resource per model. Database.resources() returns exactly one; there is no collection discovery from the database.
  • Search is exact-match. Arangoose has no $regex/$like, so AdminJS's text filters match exactly rather than substring.
  • Sorting is single-key, as AdminJS only sends one sortBy.
  • No soft-delete awareness in the UI. If a model uses softDeletePlugin, deletes from the admin panel stamp the field and the rows disappear from the list; there is no "restore" action.
  • Tenant-scoped models are scoped on list/count but not on findOne/update/delete, which are key-based. Do not expose a tenant-scoped resource to users of another tenant.