JavaScript implementation of Cap URN (Capability Uniform Resource Names) with strict validation and matching
npm install capnsJavaScript implementation of Cap URN (Capability Uniform Resource Names), built on Tagged URN.
- Required Direction Specifiers - in/out tags for input/output media types
- Media URN Validation - Validates direction spec values are valid Media URNs
- Special Pattern Values - * (must-have-any), ? (unspecified), ! (must-not-have)
- Graded Specificity - Exact values score higher than wildcards
- Cross-Language Compatible - Identical behavior to Rust, Go, and Objective-C implementations
- Production Ready - No fallbacks, fails hard on invalid input
``bash`
npm install capns
`javascript
const { CapUrn, CapUrnBuilder, CapMatcher } = require('capns');
// Create from string (with required direction specifiers)
const cap = CapUrn.fromString('cap:in="media:binary";op=extract;out="media:object"');
console.log(cap.toString());
// Use builder pattern
const built = new CapUrnBuilder()
.inSpec('media:void')
.outSpec('media:object')
.tag('op', 'generate')
.tag('target', 'thumbnail')
.build();
// Matching
const request = CapUrn.fromString('cap:in="media:binary";op=extract;out="media:object"');
console.log(cap.accepts(request)); // true
// Find best match by specificity
const caps = [
CapUrn.fromString('cap:in=;op=extract;out='),
CapUrn.fromString('cap:in="media:binary";op=extract;out="media:object"'),
CapUrn.fromString('cap:ext=pdf;in="media:binary";op=extract;out="media:object"')
];
const best = CapMatcher.findBestMatch(caps, request);
console.log(best.toString()); // Most specific match
`
#### Static Methods
- CapUrn.fromString(s) - Parse Cap URN from stringCapUrnError
- Throws on invalid format or missing direction specifiers
#### Instance Methods
- toString() - Get canonical string representationgetTag(key)
- - Get tag value (case-insensitive)getInSpec()
- - Get input media typegetOutSpec()
- - Get output media typehasTag(key, value)
- - Check if tag exists with valuewithTag(key, value)
- - Add/update tag (returns new instance)withoutTag(key)
- - Remove tag (returns new instance)accepts(request)
- - Check if this cap (as pattern) accepts a requestcanHandle(request)
- - Check if this cap can handle a requestspecificity()
- - Get specificity score for matchingisMoreSpecificThan(other)
- - Compare specificityequals(other)
- - Check equality
Fluent builder for constructing Cap URNs:
`javascript`
const cap = new CapUrnBuilder()
.inSpec('media:binary')
.outSpec('media:object')
.tag('op', 'extract')
.tag('target', 'metadata')
.build();
Utility for matching sets of caps:
- CapMatcher.findBestMatch(caps, request) - Find most specific matchCapMatcher.findAllMatches(caps, request)
- - Find all matches (sorted by specificity)
`javascript
const { CapUrnError, ErrorCodes } = require('capns');
try {
const cap = CapUrn.fromString('cap:op=extract'); // Missing in/out
} catch (error) {
if (error instanceof CapUrnError) {
console.log(Error code: ${error.code}); // MISSING_IN_SPEC`
}
}
Cap-specific error codes:
- ErrorCodes.MISSING_IN_SPEC - Missing required in tagErrorCodes.MISSING_OUT_SPEC
- - Missing required out tagErrorCodes.INVALID_MEDIA_URN
- - Invalid Media URN in direction spec
For base Tagged URN error codes, see Tagged URN documentation.
- RULES.md - Cap-specific rules
- Tagged URN RULES.md - Base format rules (case, quoting, wildcards, etc.)
`bash``
npm test
This JavaScript implementation produces identical results to:
- Rust reference implementation
- Go implementation
- Objective-C implementation
All implementations pass the same test cases and follow identical rules.