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

odrl-atomization

v1.0.3

Published

Generate Policies with Atomic Rules from Compact Policies with Composite Rules

Readme

ODRL Atomization

npm

Open Digital Rights Language (ODRL) policies express who can do which action on which resource, under which conditions, using deontic rules such as Permissions, Prohibitions, and Obligations.
This library normalizes ("atomizes") ODRL policies and rules into a shape that is easier to process by evaluators and enforcement engines (e.g., for access control / usage control).

Terminology

This library uses the following terminology:

Atomic rules

An atomic rule in ODRL means that each rule has maximum one value for the following core properties: odrl:assignee, odrl:assigner, odrl:action, and odrl:target. A policy is atomic when each rule is atomic.

Composite rules

A rule is composite when it contains multiple values for one or more of these core properties (e.g., two assignees or two actions). Atomization splits such a rule into multiple derived rules.

NOTE: in this library we use <http://example.org/ns/derivedFrom> to link each derived rule back to the original rule.

Compact policies

A policy is compact when the above core properties are placed at policy level (e.g., odrl:assignee on the policy instead of on each rule). Atomization propagates these policy-level properties down to the rules while preserving ODRL's rule structure. This includes propagating to nested rules: duties that can be attached to permissions, prohibitions, or duties.

How to run the library

NOTE: this is tested for node v20 (if you use nvm, run nvm use 20)

Install

npm install odrl-atomization

Minimal example (TypeScript / Node)

This example shows a compact policy (assigner on policy) with a composite rule (two assignees on the permission).

import { DataFactory, Store, Writer } from 'n3'
import { Atomizer, ODRL, RDF } from 'odrl-atomization'

const { namedNode, quad } = DataFactory
const EX = 'http://example.org/'
const EXNS = 'http://example.org/ns/'

const policy = namedNode(EX + 'policy1')
const rule1 = namedNode(EX + 'rule1')
const alice = namedNode(EX + 'alice')
const bob = namedNode(EX + 'bob')
const charlie = namedNode(EX + 'charlie')
const resourceX = namedNode(EX + 'resourceX')

const derivedFrom = namedNode(EXNS + 'derivedFrom')

// A compact + composite policy (as quads)
const input = [
  quad(policy, RDF.terms.type, ODRL.terms.Policy),
  quad(policy, ODRL.terms.permission, rule1),

  // compact: policy-level assigner
  quad(policy, ODRL.terms.assigner, alice),

  // rule1 is composite: two assignees
  quad(rule1, RDF.terms.type, ODRL.terms.Permission),
  quad(rule1, ODRL.terms.action, ODRL.terms.read),
  quad(rule1, ODRL.terms.target, resourceX),
  quad(rule1, ODRL.terms.assignee, bob),
  quad(rule1, ODRL.terms.assignee, charlie),
]

// Atomize 
const atomized = await new Atomizer().atomize(input)
const store = new Store(atomized)

console.log('--- Atomized quads ---')
console.log(new Writer().quadsToString(store.getQuads(null, null, null, null)))

How does it work?

The original policy is compact (assigner at policy level) and contains a composite rule (multiple assignees on a single permission):

@prefix odrl: <http://www.w3.org/ns/odrl/2/> .

<http://example.org/policy1>
  a odrl:Policy ;
  odrl:permission <http://example.org/rule1> ;
  odrl:assigner <http://example.org/alice> .

<http://example.org/rule1>
  a odrl:Permission ;
  odrl:action odrl:read ;
  odrl:target <http://example.org/resourceX> ;
  odrl:assignee <http://example.org/bob>, <http://example.org/charlie> .

After atomization:

  • Policy-level properties are propagated to the rules (alice is now the assigner in both rules)
  • Composite rules are split into atomic rules
  • New rule identifiers are generated (UUID IRIs)
  • Each derived rule links back to the original rule using
    <http://example.org/ns/derivedFrom>
@prefix odrl: <http://www.w3.org/ns/odrl/2/> .

<http://example.org/policy1> a odrl:Policy ;
  odrl:permission <urn:uuid:0d2412f3-a330-4bfb-a23a-dc1d1110f47c> , <urn:uuid6e7b8427-c043-4999-9ebb-97064ad4df08> .

<urn:uuid:0d2412f3-a330-4bfb-a23a-dc1d1110f47c> a odrl:Permission ;
  odrl:assigner <http://example.org/alice> ;
  odrl:assignee <http://example.org/bob> ;
  odrl:action odrl:read ;
  odrl:target <http://example.org/resourceX> ;
  <http://example.org/ns/derivedFrom> <http://example.org/rule1> .

<urn:uuid6e7b8427-c043-4999-9ebb-97064ad4df08> a odrl:Permission ;
  odrl:assigner <http://example.org/alice> ;
  odrl:assignee <http://example.org/charlie> ;
  odrl:action odrl:read ;
  odrl:target <http://example.org/resourceX> ;
  <http://example.org/ns/derivedFrom> <http://example.org/rule1> .

Feedback and questions

Do not hesitate to report a bug.

Further questions can also be asked to Wout Slabbinck (developer and maintainer of this repository).