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

@gftdcojp/resourcebox

v0.4.0

Published

TypeBox-inspired RDF Resource type builder with SHACL validation and OWL ontology support for TypeScript

Readme

ResourceBox

TypeBox-inspired RDF Resource type builder with SHACL Core validation, RDFS/OWL Lite reasoning, and Neptune SigV4 client for TypeScript

ResourceBox provides a clean, TypeScript-first API for defining RDF resources, OWL ontologies, and SHACL constraints. Inspired by TypeBox's elegant design, ResourceBox brings type safety and validation to the semantic web.

Features

  • 🎯 TypeBox-like API: Fluent, intuitive schema definition
  • 🔒 Type Safety: Full TypeScript type inference with Resource.Static<T>
  • Triple Validation: Structural (JSON Schema) + Semantic (SHACL) + Inference (RDFS/OWL Lite)
  • 🧠 Lightweight Reasoning: RDFS closure + OWL Lite (equivalentClass, inverseOf) support
  • 🌐 JSON-LD: Automatic @context generation
  • 📦 Four Layers: Onto (OWL/RDFS) → Inference (RDFS/OWL Lite) → Resource (Data) → Shape (SHACL Core)
  • 🔗 Composable: Build complex ontologies from simple pieces
  • 🚀 Production Ready: Neptune VPC proxy, comprehensive testing, linting

Design Philosophy

  • TS静的型とRDF/OWL/SHACLの合一、関数合成、標準準拠のランタイム検証
    • Unify TypeScript static types with RDF, OWL, and SHACL; compose schemas functionally; validate at runtime against open standards.
    • Inspired by the TypeBox approach of “Json Schema Type Builder with Static Type Resolution,” adapted to the semantic web stack. See TypeBox.

Installation

pnpm add @gftdcojp/resourcebox

Quick Start

Basic Example

import { Onto, Resource, Shape } from '@gftdcojp/resourcebox';

// 1. Define ontology (optional but recommended)
const foaf = Onto.Namespace({
  prefix: "foaf",
  uri: "http://xmlns.com/foaf/0.1/"
});

const Person = Onto.Class({
  iri: foaf("Person"),
  label: "Person"
});

const name = Onto.Property({
  iri: foaf("name"),
  domain: [Person],
  range: [Onto.Datatype.String],
  functional: true
});

// 2. Define resource schema (TypeBox-inspired)
const PersonResource = Resource.Object({
  "@id": Resource.String({ format: "uri" }),
  "@type": Resource.Literal([foaf("Person")]),
  
  name: Resource.String({
    property: name,
    minLength: 1,
    required: true
  }),
  
  email: Resource.String({
    property: foaf("mbox"),
    format: "email",
    optional: true
  }),
  
  friends: Resource.Array(
    Resource.Ref(Person),
    { property: foaf("knows") }
  )
}, {
  class: Person
});

// 3. Type inference (like TypeBox)
type Person = Resource.Static<typeof PersonResource>;
// → { "@id": string; "@type": OntoIRI[]; name: string; email?: string; friends: string[] }

// 4. Validate data
const validData = {
  "@id": "http://example.org/john",
  "@type": [foaf("Person")],
  name: "John Doe",
  email: "[email protected]",
  friends: ["http://example.org/jane"]
};

const result = Resource.validate(PersonResource, validData);
if (result.ok) {
  console.log("✓ Valid:", result.data);
} else {
  console.error("✗ Errors:", result.errors);
}

// 5. Generate JSON-LD context
const context = Resource.context(PersonResource, {
  includeNamespaces: true,
  namespaces: {
    foaf: "http://xmlns.com/foaf/0.1/"
  }
});

API Overview

ResourceBox has three main layers:

1. Onto Layer (OWL/RDFS Ontology)

Define vocabulary, classes, properties, and relationships.

// Namespace
const ex = Onto.Namespace({ prefix: "ex", uri: "http://example.org/" });
const foaf = Onto.FOAF;  // Built-in: FOAF, RDF, RDFS, OWL, XSD

// Class
const Person = Onto.Class({
  iri: ex("Person"),
  label: "Person",
  comment: "A human being",
  subClassOf: [foaf("Agent")]
});

// Property
const age = Onto.Property({
  iri: ex("age"),
  label: "age",
  domain: [Person],
  range: [Onto.Datatype.Integer],
  functional: true
});

// Built-in XSD Datatypes
Onto.Datatype.String
Onto.Datatype.Integer
Onto.Datatype.Boolean
Onto.Datatype.Date
Onto.Datatype.DateTime
// ... and more
// OWL class expressions (no reasoning, JSON-LD export only)
const ActivityOrCapability = Onto.Expressions.Union([
  ex("Activity"),
  ex("Capability"),
]);

const Artifact = Onto.Class({
  iri: ex("Artifact"),
  equivalentClass: [ActivityOrCapability],
});

// Ontology container + JSON-LD export
const ont = Onto.OntologyContainer({
  iri: ex("dodaf"),
  imports: [Onto.OWL("Thing")],
  classes: [Person, Artifact],
  properties: [age],
});

const owlJsonLd = Onto.toJsonLd(ont);

2. Resource Layer (Data Structure)

Define data structures with TypeBox-like API.

// Primitives
Resource.String({ minLength: 1, maxLength: 100, pattern: "^[A-Z]" })
Resource.Number({ minimum: 0, maximum: 150 })
Resource.Boolean()

// Complex types
Resource.Object({
  name: Resource.String(),
  age: Resource.Number({ optional: true })
})

Resource.Array(Resource.String(), { minItems: 1, uniqueItems: true })

// References
Resource.Ref(Person)  // IRI reference to another resource

// Literals
Resource.Literal(["foaf:Person"])  // Constant value

// Optional
Resource.Optional(Resource.String())
// or
Resource.String({ optional: true })

// With RDF property mapping
Resource.String({
  property: foaf("name"),  // Link to ontology
  required: true,
  minLength: 1
})

// Type inference
type PersonType = Resource.Static<typeof PersonResource>;

3. Shape Layer (SHACL Constraints)

Define SHACL shapes for semantic validation.

// Manual shape definition
const PersonShape = Shape.Define({
  targetClass: Person,
  
  property: {
    name: Shape.Property({
      path: foaf("name"),
      datatype: Onto.Datatype.String,
      minCount: 1,
      maxCount: 1,
      pattern: "^[A-Z]"
    }),
    
    age: Shape.Property({
      path: ex("age"),
      datatype: Onto.Datatype.Integer,
      minInclusive: 0,
      maxInclusive: 150
    })
  },
  
  closed: true
});

// Auto-generate from Resource
const AutoShape = Shape.fromResource(PersonResource, {
  strict: true
});

// Validate against shape
const result = Shape.validate(PersonShape, data);
if (!result.ok) {
  console.error(result.violations);
}

Validation

ResourceBox provides two levels of validation:

1. Structural Validation (JSON Schema)

Validates data structure, types, and formats using Ajv.

const result = Resource.validate(PersonResource, data);
// Checks: required fields, types, string lengths, patterns, etc.

2. Semantic Validation (SHACL)

Validates RDF constraints like cardinality, ranges, and class membership.

const result = Shape.validate(PersonShape, data);
// Checks: minCount, maxCount, datatypes, classes, patterns, etc.

JSON-LD Context Generation

const context = Resource.context(PersonResource, {
  includeNamespaces: true,
  namespaces: {
    foaf: "http://xmlns.com/foaf/0.1/",
    ex: "http://example.org/"
  }
});

// Result:
// {
//   "@context": {
//     "foaf": "http://xmlns.com/foaf/0.1/",
//     "ex": "http://example.org/",
//     "name": { "@id": "foaf:name" },
//     "email": { "@id": "foaf:mbox" },
//     "friends": { "@id": "foaf:knows", "@type": "@id" }
//   }
// }

Integrated API

For complex scenarios, use Resource.Shaped() to combine all three layers:

const Person = Resource.Shaped({
  class: foaf("Person"),
  
  properties: {
    name: Resource.String({
      property: foaf("name"),
      required: true,
      minLength: 1
    }),
    
    email: Resource.String({
      property: foaf("mbox"),
      format: "email",
      optional: true
    })
  },
  
  shape: {
    closed: true
  }
});

// SHACL-lite extensions and JSON-LD export
const ExtendedShape = Shape.Define({
  targetClass: Person,
  property: {
    email: Shape.Property({
      path: foaf("mbox"),
      nodeKind: "Literal",
      in: ["[email protected]", "[email protected]"],
      pattern: "@",
      minCount: 1,
      maxCount: 1,
    }),
    knows: Shape.Property({
      path: foaf("knows"),
      nodeKind: "IRI",
      hasValue: "http://example.org/alice",
    }),
  },
  closed: true,
});

const shaclJsonLd = Shape.toJsonLd(ExtendedShape);

Examples

Simple Resource

const Book = Resource.Object({
  title: Resource.String({ minLength: 1 }),
  author: Resource.String(),
  isbn: Resource.String({ pattern: "^\\d{13}$" }),
  publishedYear: Resource.Number({ minimum: 1800, maximum: 2100 })
});

type Book = Resource.Static<typeof Book>;

With Ontology

const bibo = Onto.Namespace({
  prefix: "bibo",
  uri: "http://purl.org/ontology/bibo/"
});

const Book = Onto.Class({ iri: bibo("Book") });
const title = Onto.Property({
  iri: bibo("title"),
  range: [Onto.Datatype.String]
});

const BookResource = Resource.Object({
  title: Resource.String({
    property: title,
    required: true
  })
}, {
  class: Book
});

With Shape Validation

const BookShape = Shape.fromResource(BookResource, { strict: true });

const data = {
  title: "The TypeScript Handbook",
  author: "Microsoft",
  isbn: "1234567890123",
  publishedYear: 2020
};

const structResult = Resource.validate(BookResource, data);
const shapeResult = Shape.validate(BookShape, data);

if (structResult.ok && shapeResult.ok) {
  console.log("✓ Data is valid!");
}

With RDFS/OWL Lite Inference

import { Onto, createInferenceContext } from '@gftdcojp/resourcebox';

// Define ontology with equivalent classes and inverse properties
const Person = Onto.Class({
  iri: FOAF("Person"),
  equivalentClasses: [EX("Individual")] // OWL Lite
});

const Organization = Onto.Class({ iri: EX("Organization") });

const worksFor = Onto.Property({
  iri: EX("worksFor"),
  domain: [Person],
  range: [Organization],
  inverseOf: EX("employs") // OWL Lite
});

// Create inference context
const context = createInferenceContext(
  [
    { iri: Person.iri, equivalentClasses: [EX("Individual")] },
    { iri: Organization.iri }
  ],
  [
    {
      iri: worksFor.iri,
      inverseOf: EX("employs")
    }
  ]
);

// Validate with inference
const shape = Shape.Define({
  targetClass: Person,
  property: {
    employer: Property({
      path: EX("worksFor"),
      class: Organization // Will use inference to check class compatibility
    })
  }
});

const result = Shape.validate(shape, data, context); // Pass context for inference

Neptune VPC Proxy (SigV4 Authentication)

Complete Node.js client for Neptune with automatic SigV4 signing:

# Install dependencies
cd examples/neptune-vpc-proxy
pnpm install

# Configure environment
export NEPTUNE_ENDPOINT=https://your-cluster.cluster-xyz.region.neptune.amazonaws.com:8182
export NEPTUNE_DATABASE=your-database

# Query
node query.js

# Update
node update.js

Comunica + SPARQL (Neptune/Stardog/GraphDB/Jena/SAP HANA/Oracle)

See examples/comunica-sparql:

  • SELECT/CONSTRUCT queries via Comunica
  • SPARQL UPDATE via HTTP
  • Optional Basic Auth via env
  • Local Jena Fuseki with Docker Compose

Quick start:

cd examples/comunica-sparql
pnpm i
cp .env.example .env
pnpm fuseki   # start local Jena Fuseki on 3030
pnpm update   # write sample triples
pnpm select   # query triples
pnpm construct

Additional Example Suites

  • examples/stardog-basic-auth — Comunica with Stardog (Basic Auth) complete with SELECT / CONSTRUCT / UPDATE scripts
  • examples/graphdb-public — Comunica against public Ontotext GraphDB datasets (read-only)
  • examples/neptune-vpc-proxy — Complete Neptune VPC client with SigV4 signing, SPARQL SELECT/UPDATE support
  • examples/cli-demo — End-to-end CLI: define ResourceBox model → generate JSON-LD context / SHACL → query via Comunica

Design Principles

  1. TypeScript-first: Leverage TypeScript's type system for compile-time safety
  2. Four-Layer Architecture: Separate concerns (Onto → Inference → Resource → Shape)
  3. Lightweight Reasoning: RDFS/OWL Lite support without heavy computation
  4. Progressive Enhancement: Use as much or as little as you need
  5. TypeBox Compatibility: Familiar API for TypeBox users
  6. Production Ready: Neptune integration, comprehensive testing, linting
  7. Semantic Web Standards: Built on RDF, OWL, SHACL, JSON-LD

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              ResourceBox                                   │
├─────────────┬─────────────────┬─────────────────┬─────────────────────────┤
│  Onto       │  Inference      │  Resource       │  Shape                  │
│  (OWL/RDFS) │  (RDFS/OWL Lite)│  (Data)         │  (SHACL Core)           │
├─────────────┼─────────────────┼─────────────────┼─────────────────────────┤
│ - Namespace │ - createContext │ - String        │ - Define                │
│ - Class     │ - subClassOf    │ - Number        │ - Property              │
│ - Property  │ - equivalentClass│ - Boolean       │ - fromResource          │
│ - Datatype  │ - inverseOf     │ - Object        │ - validate (w/ inference)│
│             │                 │ - Array         │                         │
│             │                 │ - Ref           │                         │
│             │                 │ - Literal       │                         │
│             │                 │ - Optional      │                         │
│             │                 │ - Static<T>     │                         │
│             │                 │ - validate      │                         │
│             │                 │ - context       │                         │
└─────────────┴─────────────────┴─────────────────┴─────────────────────────┘

RPC Integration (JSON-LD → TypeBox → tRPC/oRPC)

  1. Context生成: const context = buildContext([Shape.fromResource(PersonResource)]);
  2. 型抽出: const rpcMap = Process.Rpc.expandContextMap(context["@context"]);
  3. 入出力定義:
    • Literal (kind: "literal") → TypeBox primitive → procedure.input
    • Reference (kind: "reference") → IRI 型 → procedure.output
  4. RPC登録:
    const router = t.router({
      email: t.procedure.input(EmailType).output(ResultType).
        meta({ iri: rpcMap.email.iri })
        .query(handler),
    });
  5. oRPC では rpcMap 情報を IRI ベースのルーティングに利用可能。

RDF/XML Integration Flow

  1. RDF/XML 取り込み: const context = await Process.Rpc.importContextFromRdfXml(xmlSource, { namespaces: { foaf: "http://xmlns.com/foaf/0.1/" } });
  2. RPC メタデータ生成: const rpcMap = Process.Rpc.expandContextMap(context["@context"]);
  3. 用途:
    • JSON-LD context を UI / CLI へ渡す
    • RPC procedure のメタ情報(IRI、datatype)として利用
    • SHACL 変換 (Shape.fromResource) と組み合わせて整合性を検証

RDF/XML はストリーム/文字列どちらからも取り込めます。importContextFromStream を使うと外部エンドポイントからの直接読み込みが可能です。

Comparison with Other Libraries

| Feature | ResourceBox | TypeBox | ShEx | SHACL-JS | |---------|------------|---------|------|----------| | TypeScript Support | ✅ Full | ✅ Full | ❌ | ❌ | | Type Inference | ✅ | ✅ | ❌ | ❌ | | RDF/OWL Support | ✅ RDFS/OWL Lite | ❌ | ✅ | ✅ | | Lightweight Reasoning | ✅ RDFS/OWL Lite | ❌ | ❌ | ❌ | | JSON Schema Validation | ✅ | ✅ | ❌ | ❌ | | SHACL Validation | ✅ Core | ❌ | Partial | ✅ | | Neptune SigV4 Client | ✅ | ❌ | ❌ | ❌ | | JSON-LD Context Gen | ✅ | ❌ | ❌ | ❌ | | Fluent API | ✅ | ✅ | ❌ | ❌ |

License

Apache-2.0

References


ResourceBox = TypeBox-inspired + RDF Resource Type Builder + SHACL Core Validation + RDFS/OWL Lite Reasoning + Neptune SigV4 Client + JSON-LD Context Generation