capdag 0.146.323 → 0.149.334
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/cap-graph-renderer.js +6 -6
- package/capdag.js +117 -23
- package/capdag.test.js +52 -27
- package/package.json +1 -1
package/cap-graph-renderer.js
CHANGED
|
@@ -158,10 +158,10 @@ function layoutForMode(mode) {
|
|
|
158
158
|
algorithm: 'layered',
|
|
159
159
|
'elk.direction': 'RIGHT',
|
|
160
160
|
'elk.edgeRouting': 'POLYLINE',
|
|
161
|
-
'elk.layered.spacing.edgeEdgeBetweenLayers':
|
|
162
|
-
'elk.layered.spacing.edgeNodeBetweenLayers':
|
|
163
|
-
'elk.spacing.edgeEdge':
|
|
164
|
-
'elk.spacing.edgeNode':
|
|
161
|
+
'elk.layered.spacing.edgeEdgeBetweenLayers': 30,
|
|
162
|
+
'elk.layered.spacing.edgeNodeBetweenLayers': 40,
|
|
163
|
+
'elk.spacing.edgeEdge': 25,
|
|
164
|
+
'elk.spacing.edgeNode': 35,
|
|
165
165
|
'elk.layered.crossingMinimization.strategy': 'LAYER_SWEEP',
|
|
166
166
|
'elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
|
167
167
|
'elk.layered.considerModelOrder.strategy': 'NODES_AND_EDGES',
|
|
@@ -169,8 +169,8 @@ function layoutForMode(mode) {
|
|
|
169
169
|
};
|
|
170
170
|
if (mode === 'browse') {
|
|
171
171
|
return Object.assign({}, base, {
|
|
172
|
-
'elk.layered.spacing.nodeNodeBetweenLayers':
|
|
173
|
-
'elk.spacing.nodeNode':
|
|
172
|
+
'elk.layered.spacing.nodeNodeBetweenLayers': 180,
|
|
173
|
+
'elk.spacing.nodeNode': 90,
|
|
174
174
|
});
|
|
175
175
|
}
|
|
176
176
|
if (mode === 'strand') {
|
package/capdag.js
CHANGED
|
@@ -3596,6 +3596,23 @@ class CartridgeCapSummary {
|
|
|
3596
3596
|
}
|
|
3597
3597
|
}
|
|
3598
3598
|
|
|
3599
|
+
/**
|
|
3600
|
+
* Cartridge cap group from registry
|
|
3601
|
+
*/
|
|
3602
|
+
class CartridgeCapGroup {
|
|
3603
|
+
constructor(data) {
|
|
3604
|
+
if (!data.name) throw new Error('CapGroup missing name');
|
|
3605
|
+
this.name = data.name;
|
|
3606
|
+
this.caps = (data.caps || []).map(c => new CartridgeCapSummary(c.urn, c.title, c.description || ''));
|
|
3607
|
+
this.adapter_urns = data.adapter_urns || [];
|
|
3608
|
+
}
|
|
3609
|
+
|
|
3610
|
+
/** Flat caps in this group */
|
|
3611
|
+
allCaps() {
|
|
3612
|
+
return this.caps;
|
|
3613
|
+
}
|
|
3614
|
+
}
|
|
3615
|
+
|
|
3599
3616
|
/**
|
|
3600
3617
|
* Cartridge information from registry
|
|
3601
3618
|
*/
|
|
@@ -3610,7 +3627,8 @@ class CartridgeInfo {
|
|
|
3610
3627
|
this.teamId = data.teamId || '';
|
|
3611
3628
|
this.signedAt = data.signedAt || '';
|
|
3612
3629
|
this.minAppVersion = data.minAppVersion || '';
|
|
3613
|
-
|
|
3630
|
+
if (!Array.isArray(data.cap_groups)) throw new Error(`CartridgeInfo ${data.id || '?'}: missing cap_groups array`);
|
|
3631
|
+
this.cap_groups = data.cap_groups.map(g => new CartridgeCapGroup(g));
|
|
3614
3632
|
this.categories = data.categories || [];
|
|
3615
3633
|
this.tags = data.tags || [];
|
|
3616
3634
|
// Versions with platform-specific builds
|
|
@@ -3618,6 +3636,21 @@ class CartridgeInfo {
|
|
|
3618
3636
|
this.availableVersions = data.availableVersions || [];
|
|
3619
3637
|
}
|
|
3620
3638
|
|
|
3639
|
+
/** All caps flattened across all cap_groups, deduplicated by URN */
|
|
3640
|
+
allCaps() {
|
|
3641
|
+
const seen = new Set();
|
|
3642
|
+
const result = [];
|
|
3643
|
+
for (const group of this.cap_groups) {
|
|
3644
|
+
for (const cap of group.caps) {
|
|
3645
|
+
if (!seen.has(cap.urn)) {
|
|
3646
|
+
seen.add(cap.urn);
|
|
3647
|
+
result.push(cap);
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
return result;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3621
3654
|
/**
|
|
3622
3655
|
* Check if cartridge is signed (has team_id and signed_at)
|
|
3623
3656
|
*/
|
|
@@ -3697,15 +3730,28 @@ class CartridgeRepoClient {
|
|
|
3697
3730
|
|
|
3698
3731
|
const data = await response.json();
|
|
3699
3732
|
|
|
3700
|
-
if (!data.cartridges ||
|
|
3701
|
-
throw new Error(`Invalid cartridge registry response from ${repoUrl}: missing cartridges
|
|
3733
|
+
if (!data.cartridges || typeof data.cartridges !== 'object') {
|
|
3734
|
+
throw new Error(`Invalid cartridge registry response from ${repoUrl}: missing cartridges object`);
|
|
3702
3735
|
}
|
|
3703
3736
|
|
|
3704
|
-
|
|
3737
|
+
// Registry stores cartridges as an object keyed by id; normalize to array.
|
|
3738
|
+
return Object.entries(data.cartridges).map(([id, c]) => new CartridgeInfo({
|
|
3739
|
+
...c,
|
|
3740
|
+
id,
|
|
3741
|
+
version: c.latestVersion
|
|
3742
|
+
}));
|
|
3705
3743
|
}
|
|
3706
3744
|
|
|
3707
3745
|
/**
|
|
3708
|
-
* Update cache from registry data
|
|
3746
|
+
* Update cache from registry data.
|
|
3747
|
+
*
|
|
3748
|
+
* The cap-to-cartridges index keys on the *normalized* tagged-URN form
|
|
3749
|
+
* of each cap URN (parse via CapUrn.fromString, then take toString()).
|
|
3750
|
+
* This collapses textually different but canonically identical URNs
|
|
3751
|
+
* (different declared tag order) into the same bucket so that lookups
|
|
3752
|
+
* resolve regardless of how the requester phrased the URN. A cap URN
|
|
3753
|
+
* that fails to parse is a registry corruption: we throw rather than
|
|
3754
|
+
* silently keep the malformed string in the index.
|
|
3709
3755
|
*/
|
|
3710
3756
|
updateCache(repoUrl, cartridges) {
|
|
3711
3757
|
const cache = new CartridgeRepoCache(repoUrl);
|
|
@@ -3713,11 +3759,12 @@ class CartridgeRepoClient {
|
|
|
3713
3759
|
for (const cartridge of cartridges) {
|
|
3714
3760
|
cache.cartridges.set(cartridge.id, cartridge);
|
|
3715
3761
|
|
|
3716
|
-
for (const cap of cartridge.
|
|
3717
|
-
|
|
3718
|
-
|
|
3762
|
+
for (const cap of cartridge.allCaps()) {
|
|
3763
|
+
const normalized = CapUrn.fromString(cap.urn).toString();
|
|
3764
|
+
if (!cache.capToCartridges.has(normalized)) {
|
|
3765
|
+
cache.capToCartridges.set(normalized, []);
|
|
3719
3766
|
}
|
|
3720
|
-
cache.capToCartridges.get(
|
|
3767
|
+
cache.capToCartridges.get(normalized).push(cartridge.id);
|
|
3721
3768
|
}
|
|
3722
3769
|
}
|
|
3723
3770
|
|
|
@@ -3760,20 +3807,36 @@ class CartridgeRepoClient {
|
|
|
3760
3807
|
}
|
|
3761
3808
|
|
|
3762
3809
|
/**
|
|
3763
|
-
* Get cartridge suggestions for a cap URN
|
|
3810
|
+
* Get cartridge suggestions for a cap URN.
|
|
3811
|
+
*
|
|
3812
|
+
* `capUrn` is parsed via CapUrn.fromString; the parsed-and-
|
|
3813
|
+
* re-serialized form is the canonical key into the cap-to-cartridges
|
|
3814
|
+
* index. Inside each candidate cartridge we walk its caps via
|
|
3815
|
+
* `allCaps()` and match each one with `isEquivalent`, never with
|
|
3816
|
+
* string equality.
|
|
3764
3817
|
*/
|
|
3765
3818
|
getSuggestionsForCap(capUrn) {
|
|
3819
|
+
const requested = CapUrn.fromString(capUrn);
|
|
3820
|
+
const normalized = requested.toString();
|
|
3766
3821
|
const suggestions = [];
|
|
3767
3822
|
|
|
3768
3823
|
for (const cache of this.caches.values()) {
|
|
3769
|
-
const cartridgeIds = cache.capToCartridges.get(
|
|
3824
|
+
const cartridgeIds = cache.capToCartridges.get(normalized);
|
|
3770
3825
|
if (!cartridgeIds) continue;
|
|
3771
3826
|
|
|
3772
3827
|
for (const cartridgeId of cartridgeIds) {
|
|
3773
3828
|
const cartridge = cache.cartridges.get(cartridgeId);
|
|
3774
3829
|
if (!cartridge) continue;
|
|
3775
3830
|
|
|
3776
|
-
const capInfo = cartridge.
|
|
3831
|
+
const capInfo = cartridge.allCaps().find(c => {
|
|
3832
|
+
let parsed;
|
|
3833
|
+
try {
|
|
3834
|
+
parsed = CapUrn.fromString(c.urn);
|
|
3835
|
+
} catch (_e) {
|
|
3836
|
+
return false;
|
|
3837
|
+
}
|
|
3838
|
+
return parsed.isEquivalent(requested);
|
|
3839
|
+
});
|
|
3777
3840
|
if (!capInfo) continue;
|
|
3778
3841
|
|
|
3779
3842
|
const pageUrl = cartridge.pageUrl || cache.repoUrl;
|
|
@@ -3782,7 +3845,7 @@ class CartridgeRepoClient {
|
|
|
3782
3845
|
cartridgeId: cartridge.id,
|
|
3783
3846
|
cartridgeName: cartridge.name,
|
|
3784
3847
|
cartridgeDescription: cartridge.description,
|
|
3785
|
-
capUrn:
|
|
3848
|
+
capUrn: normalized,
|
|
3786
3849
|
capTitle: capInfo.title,
|
|
3787
3850
|
latestVersion: cartridge.version,
|
|
3788
3851
|
repoUrl: cache.repoUrl,
|
|
@@ -3889,6 +3952,9 @@ class CartridgeRepoServer {
|
|
|
3889
3952
|
if (!build.package || !build.package.name) {
|
|
3890
3953
|
throw new Error(`Cartridge ${id} v${version}: build[${i}] (${build.platform}) missing package.name`);
|
|
3891
3954
|
}
|
|
3955
|
+
if (!build.package.url) {
|
|
3956
|
+
throw new Error(`Cartridge ${id} v${version}: build[${i}] (${build.platform}) missing package.url`);
|
|
3957
|
+
}
|
|
3892
3958
|
}
|
|
3893
3959
|
}
|
|
3894
3960
|
|
|
@@ -3942,7 +4008,10 @@ class CartridgeRepoServer {
|
|
|
3942
4008
|
teamId: cartridge.teamId,
|
|
3943
4009
|
signedAt: versionData.releaseDate,
|
|
3944
4010
|
minAppVersion: versionData.minAppVersion || cartridge.minAppVersion,
|
|
3945
|
-
|
|
4011
|
+
cap_groups: (() => {
|
|
4012
|
+
if (!Array.isArray(cartridge.cap_groups)) throw new Error(`Cartridge ${id}: missing cap_groups array`);
|
|
4013
|
+
return cartridge.cap_groups;
|
|
4014
|
+
})(),
|
|
3946
4015
|
categories: cartridge.categories,
|
|
3947
4016
|
tags: cartridge.tags,
|
|
3948
4017
|
versions: cartridge.versions,
|
|
@@ -3971,18 +4040,25 @@ class CartridgeRepoServer {
|
|
|
3971
4040
|
}
|
|
3972
4041
|
|
|
3973
4042
|
/**
|
|
3974
|
-
* Search cartridges by query
|
|
4043
|
+
* Search cartridges by free-text query.
|
|
4044
|
+
*
|
|
4045
|
+
* Matches against cartridge name, description, tags, and cap titles.
|
|
4046
|
+
* Cap URN strings are not substring-matched: a cap URN is a tagged
|
|
4047
|
+
* identifier and substring matching against it is a category error.
|
|
4048
|
+
* Use `getCartridgesByCap` to look up cartridges that provide a
|
|
4049
|
+
* specific cap.
|
|
3975
4050
|
*/
|
|
3976
4051
|
searchCartridges(query) {
|
|
3977
4052
|
const cartridges = this.transformToCartridgeArray();
|
|
3978
4053
|
const lowerQuery = query.toLowerCase();
|
|
3979
4054
|
|
|
3980
|
-
return cartridges.filter(p =>
|
|
3981
|
-
p.
|
|
3982
|
-
p.
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
4055
|
+
return cartridges.filter(p => {
|
|
4056
|
+
const allCaps = (p.cap_groups || []).flatMap(g => g.caps || []);
|
|
4057
|
+
return p.name.toLowerCase().includes(lowerQuery) ||
|
|
4058
|
+
p.description.toLowerCase().includes(lowerQuery) ||
|
|
4059
|
+
p.tags.some(t => t.toLowerCase().includes(lowerQuery)) ||
|
|
4060
|
+
allCaps.some(c => c.title.toLowerCase().includes(lowerQuery));
|
|
4061
|
+
});
|
|
3986
4062
|
}
|
|
3987
4063
|
|
|
3988
4064
|
/**
|
|
@@ -3994,11 +4070,29 @@ class CartridgeRepoServer {
|
|
|
3994
4070
|
}
|
|
3995
4071
|
|
|
3996
4072
|
/**
|
|
3997
|
-
* Get cartridges that provide a specific cap
|
|
4073
|
+
* Get cartridges that provide a specific cap.
|
|
4074
|
+
*
|
|
4075
|
+
* Both the request URN and each candidate cap URN are parsed via
|
|
4076
|
+
* CapUrn.fromString and matched with `isEquivalent` so caps declared
|
|
4077
|
+
* in any tag order resolve. A malformed input URN throws — there is
|
|
4078
|
+
* no fallback that compares the raw strings.
|
|
3998
4079
|
*/
|
|
3999
4080
|
getCartridgesByCap(capUrn) {
|
|
4081
|
+
const requested = CapUrn.fromString(capUrn);
|
|
4000
4082
|
const cartridges = this.transformToCartridgeArray();
|
|
4001
|
-
return cartridges.filter(p =>
|
|
4083
|
+
return cartridges.filter(p =>
|
|
4084
|
+
(p.cap_groups || []).some(g =>
|
|
4085
|
+
(g.caps || []).some(c => {
|
|
4086
|
+
let parsed;
|
|
4087
|
+
try {
|
|
4088
|
+
parsed = CapUrn.fromString(c.urn);
|
|
4089
|
+
} catch (_e) {
|
|
4090
|
+
return false;
|
|
4091
|
+
}
|
|
4092
|
+
return parsed.isEquivalent(requested);
|
|
4093
|
+
})
|
|
4094
|
+
)
|
|
4095
|
+
);
|
|
4002
4096
|
}
|
|
4003
4097
|
}
|
|
4004
4098
|
|
package/capdag.test.js
CHANGED
|
@@ -1651,16 +1651,22 @@ const sampleRegistry = {
|
|
|
1651
1651
|
minAppVersion: '1.0.0',
|
|
1652
1652
|
categories: ['document'],
|
|
1653
1653
|
tags: ['pdf', 'extractor'],
|
|
1654
|
-
|
|
1654
|
+
cap_groups: [
|
|
1655
1655
|
{
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1656
|
+
name: 'pdf-processing',
|
|
1657
|
+
adapter_urns: ['media:pdf'],
|
|
1658
|
+
caps: [
|
|
1659
|
+
{
|
|
1660
|
+
urn: 'cap:in="media:pdf";op=disbind;out="media:disbound-page;textable;list"',
|
|
1661
|
+
title: 'Disbind PDF',
|
|
1662
|
+
description: 'Extract pages'
|
|
1663
|
+
},
|
|
1664
|
+
{
|
|
1665
|
+
urn: 'cap:in="media:pdf";op=extract_metadata;out="media:file-metadata;textable;record"',
|
|
1666
|
+
title: 'Extract Metadata',
|
|
1667
|
+
description: 'Get PDF metadata'
|
|
1668
|
+
}
|
|
1669
|
+
]
|
|
1664
1670
|
}
|
|
1665
1671
|
],
|
|
1666
1672
|
latestVersion: '0.81.5325',
|
|
@@ -1673,6 +1679,7 @@ const sampleRegistry = {
|
|
|
1673
1679
|
platform: 'darwin-arm64',
|
|
1674
1680
|
package: {
|
|
1675
1681
|
name: 'pdfcartridge-0.81.5325.pkg',
|
|
1682
|
+
url: 'https://cartridges.machinefabric.com/pdfcartridge/0.81.5325/pdfcartridge-0.81.5325.pkg',
|
|
1676
1683
|
sha256: '9b68724eb9220ecf01e8ed4f5f80c594fbac2239bc5bf675005ec882ecc5eba0',
|
|
1677
1684
|
size: 5187485
|
|
1678
1685
|
}
|
|
@@ -1689,11 +1696,17 @@ const sampleRegistry = {
|
|
|
1689
1696
|
minAppVersion: '1.0.0',
|
|
1690
1697
|
categories: ['text'],
|
|
1691
1698
|
tags: ['txt', 'text'],
|
|
1692
|
-
|
|
1699
|
+
cap_groups: [
|
|
1693
1700
|
{
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1701
|
+
name: 'text-processing',
|
|
1702
|
+
adapter_urns: ['media:txt;textable'],
|
|
1703
|
+
caps: [
|
|
1704
|
+
{
|
|
1705
|
+
urn: 'cap:in="media:txt;textable";op=disbind;out="media:disbound-page;textable;list"',
|
|
1706
|
+
title: 'Disbind Text',
|
|
1707
|
+
description: 'Extract text pages'
|
|
1708
|
+
}
|
|
1709
|
+
]
|
|
1697
1710
|
}
|
|
1698
1711
|
],
|
|
1699
1712
|
latestVersion: '0.54.6408',
|
|
@@ -1706,6 +1719,7 @@ const sampleRegistry = {
|
|
|
1706
1719
|
platform: 'darwin-arm64',
|
|
1707
1720
|
package: {
|
|
1708
1721
|
name: 'txtcartridge-0.54.6408.pkg',
|
|
1722
|
+
url: 'https://cartridges.machinefabric.com/txtcartridge/0.54.6408/txtcartridge-0.54.6408.pkg',
|
|
1709
1723
|
sha256: 'abc123',
|
|
1710
1724
|
size: 821000
|
|
1711
1725
|
}
|
|
@@ -1725,13 +1739,17 @@ function test320_cartridgeInfoConstruction() {
|
|
|
1725
1739
|
description: 'A test',
|
|
1726
1740
|
teamId: 'TEAM123',
|
|
1727
1741
|
signedAt: '2026-01-01',
|
|
1728
|
-
|
|
1742
|
+
cap_groups: [{
|
|
1743
|
+
name: 'test-group',
|
|
1744
|
+
adapter_urns: ['media:void'],
|
|
1745
|
+
caps: [{urn: 'cap:in="media:void";op=test;out="media:void"', title: 'Test', description: ''}]
|
|
1746
|
+
}],
|
|
1729
1747
|
versions: {
|
|
1730
1748
|
'1.0.0': {
|
|
1731
1749
|
releaseDate: '2026-01-01',
|
|
1732
1750
|
changelog: ['Initial'],
|
|
1733
1751
|
minAppVersion: '1.0.0',
|
|
1734
|
-
builds: [{platform: 'darwin-arm64', package: {name: 'test-1.0.0.pkg', sha256: 'abc123', size: 100}}]
|
|
1752
|
+
builds: [{platform: 'darwin-arm64', package: {name: 'test-1.0.0.pkg', url: 'https://cartridges.machinefabric.com/testcartridge/1.0.0/test-1.0.0.pkg', sha256: 'abc123', size: 100}}]
|
|
1735
1753
|
}
|
|
1736
1754
|
},
|
|
1737
1755
|
availableVersions: ['1.0.0']
|
|
@@ -1739,31 +1757,32 @@ function test320_cartridgeInfoConstruction() {
|
|
|
1739
1757
|
const cartridge = new CartridgeInfo(data);
|
|
1740
1758
|
assert(cartridge.id === 'testcartridge', 'ID should match');
|
|
1741
1759
|
assert(cartridge.teamId === 'TEAM123', 'Team ID should match');
|
|
1742
|
-
assert(cartridge.
|
|
1743
|
-
assert(cartridge.caps[0].urn === 'cap:in="media:void";op=test;out="media:void"', 'Cap URN should match');
|
|
1760
|
+
assert(cartridge.cap_groups.length === 1, 'Should have 1 cap_group');
|
|
1761
|
+
assert(cartridge.cap_groups[0].caps[0].urn === 'cap:in="media:void";op=test;out="media:void"', 'Cap URN should match');
|
|
1762
|
+
assert(cartridge.allCaps().length === 1, 'allCaps() should return 1 cap');
|
|
1744
1763
|
}
|
|
1745
1764
|
|
|
1746
1765
|
// TEST321: CartridgeInfo.is_signed() returns true when signature is present
|
|
1747
1766
|
function test321_cartridgeInfoIsSigned() {
|
|
1748
|
-
const signed = new CartridgeInfo({id: 'test', teamId: 'TEAM', signedAt: '2026-01-01',
|
|
1767
|
+
const signed = new CartridgeInfo({id: 'test', teamId: 'TEAM', signedAt: '2026-01-01', cap_groups: []});
|
|
1749
1768
|
assert(signed.isSigned() === true, 'Cartridge with teamId and signedAt should be signed');
|
|
1750
1769
|
|
|
1751
|
-
const unsigned1 = new CartridgeInfo({id: 'test', teamId: '', signedAt: '2026-01-01',
|
|
1770
|
+
const unsigned1 = new CartridgeInfo({id: 'test', teamId: '', signedAt: '2026-01-01', cap_groups: []});
|
|
1752
1771
|
assert(unsigned1.isSigned() === false, 'Cartridge without teamId should not be signed');
|
|
1753
1772
|
|
|
1754
|
-
const unsigned2 = new CartridgeInfo({id: 'test', teamId: 'TEAM', signedAt: '',
|
|
1773
|
+
const unsigned2 = new CartridgeInfo({id: 'test', teamId: 'TEAM', signedAt: '', cap_groups: []});
|
|
1755
1774
|
assert(unsigned2.isSigned() === false, 'Cartridge without signedAt should not be signed');
|
|
1756
1775
|
}
|
|
1757
1776
|
|
|
1758
1777
|
// TEST322: CartridgeInfo.build_for_platform() returns the build matching the current platform
|
|
1759
1778
|
function test322_cartridgeInfoBuildForPlatform() {
|
|
1760
1779
|
const withBuilds = new CartridgeInfo({
|
|
1761
|
-
id: 'test', version: '1.0.0',
|
|
1780
|
+
id: 'test', version: '1.0.0', cap_groups: [],
|
|
1762
1781
|
versions: {
|
|
1763
1782
|
'1.0.0': {
|
|
1764
1783
|
builds: [
|
|
1765
|
-
{platform: 'darwin-arm64', package: {name: 'test-darwin.pkg', sha256: 'abc', size: 100}},
|
|
1766
|
-
{platform: 'linux-x86_64', package: {name: 'test-linux.pkg', sha256: 'def', size: 200}}
|
|
1784
|
+
{platform: 'darwin-arm64', package: {name: 'test-darwin.pkg', url: 'https://cartridges.machinefabric.com/test/1.0.0/test-darwin.pkg', sha256: 'abc', size: 100}},
|
|
1785
|
+
{platform: 'linux-x86_64', package: {name: 'test-linux.pkg', url: 'https://cartridges.machinefabric.com/test/1.0.0/test-linux.pkg', sha256: 'def', size: 200}}
|
|
1767
1786
|
]
|
|
1768
1787
|
}
|
|
1769
1788
|
},
|
|
@@ -1784,7 +1803,7 @@ function test322_cartridgeInfoBuildForPlatform() {
|
|
|
1784
1803
|
assert(platforms.includes('darwin-arm64'), 'Should include darwin-arm64');
|
|
1785
1804
|
assert(platforms.includes('linux-x86_64'), 'Should include linux-x86_64');
|
|
1786
1805
|
|
|
1787
|
-
const noBuilds = new CartridgeInfo({id: 'test', version: '1.0.0',
|
|
1806
|
+
const noBuilds = new CartridgeInfo({id: 'test', version: '1.0.0', cap_groups: [], versions: {}, availableVersions: []});
|
|
1788
1807
|
assert(noBuilds.buildForPlatform('darwin-arm64') === null, 'Should return null when no versions');
|
|
1789
1808
|
assert(noBuilds.availablePlatforms().length === 0, 'Should have no platforms');
|
|
1790
1809
|
}
|
|
@@ -1837,8 +1856,9 @@ function test324_cartridgeRepoServerTransformToArray() {
|
|
|
1837
1856
|
assert(pdf.versions['0.81.5325'].builds[0].package.sha256 === '9b68724eb9220ecf01e8ed4f5f80c594fbac2239bc5bf675005ec882ecc5eba0', 'Should have package SHA256');
|
|
1838
1857
|
assert(Array.isArray(pdf.availableVersions), 'Should have availableVersions array');
|
|
1839
1858
|
assert(pdf.availableVersions.includes('0.81.5325'), 'Should include latest version');
|
|
1840
|
-
assert(Array.isArray(pdf.
|
|
1841
|
-
assert(pdf.
|
|
1859
|
+
assert(Array.isArray(pdf.cap_groups), 'Should have cap_groups array');
|
|
1860
|
+
assert(pdf.cap_groups.length === 1, 'Should have 1 cap_group');
|
|
1861
|
+
assert(pdf.cap_groups[0].caps.length === 2, 'Should have 2 caps in the group');
|
|
1842
1862
|
}
|
|
1843
1863
|
|
|
1844
1864
|
// TEST325: CartridgeRepoServer.get_cartridges() returns all parsed cartridges
|
|
@@ -1933,7 +1953,12 @@ function test331_cartridgeRepoClientGetSuggestions() {
|
|
|
1933
1953
|
|
|
1934
1954
|
assert(suggestions.length === 1, 'Should find 1 suggestion');
|
|
1935
1955
|
assert(suggestions[0].cartridgeId === 'pdfcartridge', 'Should suggest pdfcartridge');
|
|
1936
|
-
|
|
1956
|
+
// The returned capUrn is the canonical (normalized) form. Compare via
|
|
1957
|
+
// tagged-URN equivalence rather than string equality so a tag-order
|
|
1958
|
+
// difference between the request and the canonical form is tolerated.
|
|
1959
|
+
const requested = CapUrn.fromString(disbindCap);
|
|
1960
|
+
const returned = CapUrn.fromString(suggestions[0].capUrn);
|
|
1961
|
+
assert(returned.isEquivalent(requested), 'Should have equivalent cap URN');
|
|
1937
1962
|
assert(suggestions[0].capTitle === 'Disbind PDF', 'Should have cap title');
|
|
1938
1963
|
}
|
|
1939
1964
|
|
package/package.json
CHANGED