Skip to content

Commit c0a48c6

Browse files
committed
feat(semver-ranges): support x semver ranges in metamodel
Signed-off-by: Moh <[email protected]>
1 parent d752b0f commit c0a48c6

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lib/metamodelutil.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
'use strict';
1616

17+
const semver = require('semver');
18+
1719
/**
1820
* The metamodel itself, as an AST.
1921
* @type unknown
@@ -37,7 +39,54 @@ const metaModelCto = require('./metamodel.js');
3739
* @return {*} the model
3840
*/
3941
function findNamespace(priorModels, namespace) {
40-
return priorModels.models.find((thisModel) => thisModel.namespace === namespace);
42+
// Exact match fast-path
43+
const exact = priorModels.models.find(
44+
(thisModel) => thisModel.namespace === namespace
45+
);
46+
if (exact) {
47+
return exact;
48+
}
49+
50+
// Parse range-based versioning (supports x-ranges like 1.x, 1.1.x)
51+
const atIndex = namespace.lastIndexOf('@');
52+
if (atIndex <= 0) {
53+
return undefined;
54+
}
55+
const baseName = namespace.substring(0, atIndex);
56+
const wanted = namespace.substring(atIndex + 1);
57+
58+
// Collect candidates with the same base name
59+
const candidates = priorModels.models
60+
.filter((m) => {
61+
const idx = m.namespace.lastIndexOf('@');
62+
if (idx <= 0) {
63+
return false;
64+
}
65+
const name = m.namespace.substring(0, idx);
66+
return name === baseName;
67+
})
68+
.map((m) => {
69+
const v = m.namespace.substring(m.namespace.lastIndexOf('@') + 1);
70+
return { model: m, version: v };
71+
});
72+
73+
if (candidates.length === 0) {
74+
return undefined;
75+
}
76+
77+
// Treat requested version as a range (supports x-ranges like 1.x, 1.1.x)
78+
// Pick the highest version that satisfies the range
79+
const satisfying = candidates
80+
.filter((c) => semver.valid(c.version))
81+
.filter((c) =>
82+
semver.satisfies(c.version, wanted, {
83+
includePrerelease: false,
84+
loose: true,
85+
})
86+
)
87+
.sort((a, b) => semver.rcompare(a.version, b.version));
88+
89+
return satisfying.length > 0 ? satisfying[0].model : undefined;
4190
}
4291

4392
/**

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
],
3838
"author": "accordproject.org",
3939
"license": "Apache-2.0",
40+
"dependencies": {
41+
"semver": "7.6.3"
42+
},
4043
"devDependencies": {
4144
"@types/webgl-ext": "0.0.37",
4245
"chai": "4.3.6",
@@ -47,7 +50,6 @@
4750
"license-check-and-add": "2.3.6",
4851
"mocha": "10.8.2",
4952
"nyc": "17.1.0",
50-
"semver": "7.6.3",
5153
"typescript": "5.7.2"
5254
},
5355
"browserslist": "> 0.25%, not dead",

0 commit comments

Comments
 (0)