capdag 1.211.563 → 1.219.594
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/capdag.js +131 -0
- package/capdag.test.js +734 -723
- package/package.json +2 -2
package/capdag.js
CHANGED
|
@@ -7551,8 +7551,139 @@ class FabricRegistryClient {
|
|
|
7551
7551
|
}
|
|
7552
7552
|
}
|
|
7553
7553
|
|
|
7554
|
+
// ===========================================================================
|
|
7555
|
+
// Aliases (the DNS-analogue translation layer over URNs)
|
|
7556
|
+
// ===========================================================================
|
|
7557
|
+
//
|
|
7558
|
+
// An alias is a first-class fabric definition: a short, contiguous,
|
|
7559
|
+
// case-insensitive name that resolves to exactly one cap or media URN. This
|
|
7560
|
+
// lightweight JS mirror provides the pure alias primitives (name rules,
|
|
7561
|
+
// URN-vs-alias detection, target classification), the StoredAlias wire shape,
|
|
7562
|
+
// and Manifest (de)serialization of the aliases map — the pieces the web UIs
|
|
7563
|
+
// and LSP need to recognize and present aliases. Full registry-side alias
|
|
7564
|
+
// resolution lives in the heavier mirrors (Rust/Go/Py/ObjC).
|
|
7565
|
+
|
|
7566
|
+
const ALIAS_TARGET_CAP = 'cap';
|
|
7567
|
+
const ALIAS_TARGET_MEDIA = 'media';
|
|
7568
|
+
const ALIAS_NAME_RE = /^[a-z0-9._-]+$/;
|
|
7569
|
+
|
|
7570
|
+
/**
|
|
7571
|
+
* A contiguous token "looks like a URN" iff it contains ':'. Every tagged URN
|
|
7572
|
+
* has the shape prefix:..., so the presence of ':' is the unambiguous
|
|
7573
|
+
* discriminator between a URN and an alias name.
|
|
7574
|
+
*/
|
|
7575
|
+
function tokenIsUrn(token) {
|
|
7576
|
+
return typeof token === 'string' && token.includes(':');
|
|
7577
|
+
}
|
|
7578
|
+
|
|
7579
|
+
/** Complement of tokenIsUrn: a colon-free token is an alias candidate. */
|
|
7580
|
+
function isAliasToken(token) {
|
|
7581
|
+
return !tokenIsUrn(token);
|
|
7582
|
+
}
|
|
7583
|
+
|
|
7584
|
+
/**
|
|
7585
|
+
* Normalize and validate an alias name. Lowercases the input, then requires it
|
|
7586
|
+
* non-empty, free of ':' (so it can never look like a tagged URN), free of
|
|
7587
|
+
* whitespace, and matching [a-z0-9._-]+. Returns the canonical lowercased
|
|
7588
|
+
* name or throws — there is no lenient path.
|
|
7589
|
+
*/
|
|
7590
|
+
function normalizeAliasName(name) {
|
|
7591
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
7592
|
+
throw new Error('alias name is empty');
|
|
7593
|
+
}
|
|
7594
|
+
if (name.includes(':')) {
|
|
7595
|
+
throw new Error(`alias name '${name}' contains ':' — aliases must never look like a tagged URN`);
|
|
7596
|
+
}
|
|
7597
|
+
if (/\s/.test(name)) {
|
|
7598
|
+
throw new Error(`alias name '${name}' contains whitespace`);
|
|
7599
|
+
}
|
|
7600
|
+
const lowered = name.toLowerCase();
|
|
7601
|
+
if (!ALIAS_NAME_RE.test(lowered)) {
|
|
7602
|
+
throw new Error(`alias name '${name}' contains invalid characters; allowed: lowercase letters, digits, '.', '_', '-'`);
|
|
7603
|
+
}
|
|
7604
|
+
return lowered;
|
|
7605
|
+
}
|
|
7606
|
+
|
|
7607
|
+
/**
|
|
7608
|
+
* Classify an alias target URN by prefix. Returns 'cap', 'media', or null
|
|
7609
|
+
* (not a cap/media URN).
|
|
7610
|
+
*/
|
|
7611
|
+
function classifyAliasTarget(target) {
|
|
7612
|
+
try {
|
|
7613
|
+
CapUrn.fromString(target);
|
|
7614
|
+
return ALIAS_TARGET_CAP;
|
|
7615
|
+
} catch (_) { /* not a cap URN */ }
|
|
7616
|
+
try {
|
|
7617
|
+
MediaUrn.fromString(target);
|
|
7618
|
+
return ALIAS_TARGET_MEDIA;
|
|
7619
|
+
} catch (_) { /* not a media URN */ }
|
|
7620
|
+
return null;
|
|
7621
|
+
}
|
|
7622
|
+
|
|
7623
|
+
/**
|
|
7624
|
+
* The published wire/cache shape of a single fabric alias. Mirrors
|
|
7625
|
+
* fabric/alias.schema.json: { name, target, version }.
|
|
7626
|
+
*/
|
|
7627
|
+
class StoredAlias {
|
|
7628
|
+
constructor(name, target, version) {
|
|
7629
|
+
this.name = name;
|
|
7630
|
+
this.target = target;
|
|
7631
|
+
this.version = version;
|
|
7632
|
+
}
|
|
7633
|
+
toJSON() {
|
|
7634
|
+
return { name: this.name, target: this.target, version: this.version };
|
|
7635
|
+
}
|
|
7636
|
+
static fromJSON(obj) {
|
|
7637
|
+
return new StoredAlias(obj.name, obj.target, obj.version);
|
|
7638
|
+
}
|
|
7639
|
+
}
|
|
7640
|
+
|
|
7641
|
+
/**
|
|
7642
|
+
* A versioned registry snapshot. Mirrors fabric/manifest.schema.json:
|
|
7643
|
+
* { version, previous, caps, media, aliases } where each map is
|
|
7644
|
+
* name/urn -> defver.
|
|
7645
|
+
*/
|
|
7646
|
+
class Manifest {
|
|
7647
|
+
constructor(version, previous, caps = {}, media = {}, aliases = {}) {
|
|
7648
|
+
this.version = version;
|
|
7649
|
+
this.previous = previous;
|
|
7650
|
+
this.caps = caps;
|
|
7651
|
+
this.media = media;
|
|
7652
|
+
this.aliases = aliases;
|
|
7653
|
+
}
|
|
7654
|
+
static empty(version) {
|
|
7655
|
+
return new Manifest(version, Math.max(0, version - 1), {}, {}, {});
|
|
7656
|
+
}
|
|
7657
|
+
toJSON() {
|
|
7658
|
+
return {
|
|
7659
|
+
version: this.version,
|
|
7660
|
+
previous: this.previous,
|
|
7661
|
+
caps: this.caps,
|
|
7662
|
+
media: this.media,
|
|
7663
|
+
aliases: this.aliases,
|
|
7664
|
+
};
|
|
7665
|
+
}
|
|
7666
|
+
static fromJSON(obj) {
|
|
7667
|
+
return new Manifest(
|
|
7668
|
+
obj.version,
|
|
7669
|
+
obj.previous,
|
|
7670
|
+
obj.caps || {},
|
|
7671
|
+
obj.media || {},
|
|
7672
|
+
obj.aliases || {},
|
|
7673
|
+
);
|
|
7674
|
+
}
|
|
7675
|
+
}
|
|
7676
|
+
|
|
7554
7677
|
// Export for CommonJS
|
|
7555
7678
|
module.exports = {
|
|
7679
|
+
ALIAS_TARGET_CAP,
|
|
7680
|
+
ALIAS_TARGET_MEDIA,
|
|
7681
|
+
tokenIsUrn,
|
|
7682
|
+
isAliasToken,
|
|
7683
|
+
normalizeAliasName,
|
|
7684
|
+
classifyAliasTarget,
|
|
7685
|
+
StoredAlias,
|
|
7686
|
+
Manifest,
|
|
7556
7687
|
CapUrn,
|
|
7557
7688
|
CapKind,
|
|
7558
7689
|
CapEffect,
|