🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

node-exports-info

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-exports-info - npm Package Compare versions

Comparing version
1.6.2
to
2.0.0
+9
-0
CHANGELOG.md

@@ -8,2 +8,11 @@ # Changelog

## [v2.0.0](https://github.com/inspect-js/node-exports-info/compare/v1.6.2...v2.0.0) - 2026-06-23
### Commits
- [Refactor] use `node-package-field-info` for the shared accessor logic [`ba47eb9`](https://github.com/inspect-js/node-exports-info/commit/ba47eb9d70f7168768730780858c585419280889)
- [Breaking] remove the `subpath-imports-slash` category [`a9ad79a`](https://github.com/inspect-js/node-exports-info/commit/a9ad79a8c0230c4809d243f4c7d716e6e799f76b)
- [meta] npmignore some files [`7577699`](https://github.com/inspect-js/node-exports-info/commit/7577699c6e1e698ab1f12def9a548ed612093588)
- [Dev Deps] add missing dep [`788ff88`](https://github.com/inspect-js/node-exports-info/commit/788ff88838a4d49cfebd7c2fb18f44028608ddfc)
## [v1.6.2](https://github.com/inspect-js/node-exports-info/compare/v1.6.1...v1.6.2) - 2026-06-22

@@ -10,0 +19,0 @@

+2
-14
'use strict';
var flatMap = require('array.prototype.flatmap');
var entries = require('object.entries');
var intersects = require('semver').intersects;
var makeGetCategoriesForRange = require('node-package-field-info/makeGetCategoriesForRange');

@@ -10,12 +8,2 @@ var ranges = require('./ranges');

/** @type {import('./getCategoriesForRange')} */
module.exports = function getCategoriesForRange(rangeA) {
return flatMap(
entries(ranges),
/** @type {(entry: import('./types').RangePair) => import('./types').Category[] | []} */
function (entry) {
var rangeB = entry[0];
var category = entry[1];
return intersects(rangeA, rangeB) ? [category] : [];
}
);
};
module.exports = makeGetCategoriesForRange(ranges);
'use strict';
var $RangeError = require('es-errors/range');
var entries = require('object.entries');
var satisfies = require('semver').satisfies;
var makeGetCategory = require('node-package-field-info/makeGetCategory');

@@ -10,13 +8,2 @@ var ranges = require('./ranges');

/** @type {import('./getCategory')} */
module.exports = function getCategory() {
var version = arguments.length > 0 ? arguments[0] : process.version;
var rangeEntries = entries(ranges);
for (var i = 0; i < rangeEntries.length; i += 1) {
var entry = rangeEntries[i];
if (satisfies(version, entry[0])) {
return entry[1];
}
}
throw new $RangeError('no category found for version ' + version);
};
module.exports = makeGetCategory(ranges);
'use strict';
var $RangeError = require('es-errors/range');
var makeGetCategoryFlags = require('node-package-field-info/makeGetCategoryFlags');
var isCategory = require('./isCategory');
/** @import { Category } from './types' */
// Categories that support patterns (wildcard *)
/** @type {{ [k in import('./types').Category | '__proto__']?: k extends '__proto__' ? null : true }} */
/** @type {{ [k in Category | '__proto__']?: k extends '__proto__' ? null : true }} */
var patternsCategories = {

@@ -18,8 +20,7 @@ __proto__: null,

'require-esm': true,
'strips-types': true,
'subpath-imports-slash': true
'strips-types': true
};
// Categories that support pattern trailers (suffix after *)
/** @type {{ [k in import('./types').Category | '__proto__']?: k extends '__proto__' ? null : true }} */
/** @type {{ [k in Category | '__proto__']?: k extends '__proto__' ? null : true }} */
var patternTrailersCategories = {

@@ -33,8 +34,7 @@ __proto__: null,

'require-esm': true,
'strips-types': true,
'subpath-imports-slash': true
'strips-types': true
};
// Categories that support directory slash exports (ending with /)
/** @type {{ [k in import('./types').Category | '__proto__']?: k extends '__proto__' ? null : true }} */
/** @type {{ [k in Category | '__proto__']?: k extends '__proto__' ? null : true }} */
var dirSlashCategories = {

@@ -50,12 +50,6 @@ __proto__: null,

/** @type {import('./getCategoryFlags')} */
module.exports = function getCategoryFlags(category) {
if (!isCategory(category)) {
throw new $RangeError('invalid category ' + category);
}
return {
patterns: !!patternsCategories[category],
patternTrailers: !!patternTrailersCategories[category],
dirSlash: !!dirSlashCategories[category]
};
};
module.exports = makeGetCategoryFlags(isCategory, {
patterns: patternsCategories,
patternTrailers: patternTrailersCategories,
dirSlash: dirSlashCategories
});
'use strict';
var makeGetCategoryInfo = require('node-package-field-info/makeGetCategoryInfo');
var getCategoryFlags = require('./getCategoryFlags');

@@ -7,6 +9,2 @@ var getConditionsForCategory = require('./getConditionsForCategory');

/** @type {import('./getCategoryInfo')} */
module.exports = function getCategoryInfo(category, moduleSystem) {
var conditions = getConditionsForCategory(category, moduleSystem || 'require');
var flags = getCategoryFlags(category);
return { conditions: conditions, flags: flags };
};
module.exports = makeGetCategoryInfo(getConditionsForCategory, getCategoryFlags);
'use strict';
var $RangeError = require('es-errors/range');
var $TypeError = require('es-errors/type');
var makeGetConditionsForCategory = require('node-package-field-info/makeGetConditionsForCategory');
var isCategory = require('./isCategory');
// pre-computed condition sets
/** @type {['import', 'node', 'require', 'default']} */
var base = [
'import',
'node',
'require',
'default'
];
/** @type {['import', 'node', 'default']} */
var baseImport = [
'import',
'node',
'default'
];
/** @type {['node', 'require', 'default']} */
var baseRequire = [
'node',
'require',
'default'
];
/** @type {['import', 'node-addons', 'node', 'require', 'default']} */
var withAddons = [
'import',
'node-addons',
'node',
'require',
'default'
];
/** @type {['import', 'node-addons', 'node', 'default']} */
var withAddonsImport = [
'import',
'node-addons',
'node',
'default'
];
/** @type {['node-addons', 'node', 'require', 'default']} */
var withAddonsRequire = [
'node-addons',
'node',
'require',
'default'
];
/** @type {['import', 'node-addons', 'node', 'require', 'module-sync', 'default']} */
var withAddonsModuleSync = [
'import',
'node-addons',
'node',
'require',
'module-sync',
'default'
];
/** @type {['import', 'node-addons', 'node', 'module-sync', 'default']} */
var withAddonsModuleSyncImport = [
'import',
'node-addons',
'node',
'module-sync',
'default'
];
/** @type {['node-addons', 'node', 'require', 'module-sync', 'default']} */
var withAddonsModuleSyncRequire = [
'node-addons',
'node',
'require',
'module-sync',
'default'
];
// categories that support node-addons condition (added in v14.19/v16.10)

@@ -85,4 +16,3 @@ /** @type {{ [k: string]: boolean | null | undefined }} */

'require-esm': true,
'strips-types': true,
'subpath-imports-slash': true
'strips-types': true
};

@@ -95,34 +25,26 @@

'require-esm': true,
'strips-types': true,
'subpath-imports-slash': true
'strips-types': true
};
/** @type {import('./getConditionsForCategory')} */
module.exports = function getConditionsForCategory(category) {
if (!isCategory(category)) {
throw new $RangeError('invalid category ' + category);
}
// categories that do not support conditions at all
/** @type {{ [k: string]: boolean | null | undefined }} */
var nullCategories = {
__proto__: null,
broken: true,
'pre-exports': true
};
var moduleSystem = arguments.length > 1 ? arguments[1] : null;
if (arguments.length > 1 && moduleSystem !== 'import' && moduleSystem !== 'require') {
throw new $TypeError('invalid moduleSystem: must be `\'require\'` or `\'import\'` if provided, got' + moduleSystem);
}
// categories that only support the `default` condition
/** @type {{ [k: string]: boolean | null | undefined }} */
var defaultOnlyCategories = {
__proto__: null,
experimental: true
};
if (category === 'experimental') {
return ['default'];
}
if (category === 'broken' || category === 'pre-exports') {
return null;
}
var hasAddons = !!nodeAddonsCategories[category];
var hasModuleSync = !!moduleSyncCategories[category];
if (hasAddons && hasModuleSync) {
return moduleSystem === 'import' ? withAddonsModuleSyncImport : moduleSystem === 'require' ? withAddonsModuleSyncRequire : withAddonsModuleSync;
}
if (hasAddons) {
return moduleSystem === 'import' ? withAddonsImport : moduleSystem === 'require' ? withAddonsRequire : withAddons;
}
return moduleSystem === 'import' ? baseImport : moduleSystem === 'require' ? baseRequire : base;
};
/** @type {import('./getConditionsForCategory')} */
module.exports = makeGetConditionsForCategory(isCategory, {
addonsCategories: nodeAddonsCategories,
moduleSyncCategories: moduleSyncCategories,
nullCategories: nullCategories,
defaultOnlyCategories: defaultOnlyCategories
});
'use strict';
var $RangeError = require('es-errors/range');
var entries = require('object.entries');
var makeGetRange = require('node-package-field-info/makeGetRange');

@@ -9,12 +8,2 @@ var ranges = require('./ranges');

/** @type {import('./getRange')} */
module.exports = function getRange(category) {
var rangeEntries = entries(ranges);
for (var i = 0; i < rangeEntries.length; i += 1) {
var entry = rangeEntries[i];
if (entry[1] === category) {
return entry[0];
}
}
throw new $RangeError('no version range found for category ' + category);
};
module.exports = makeGetRange(ranges);
'use strict';
var entries = require('object.entries');
var makeGetRangePairs = require('node-package-field-info/makeGetRangePairs');

@@ -8,4 +8,2 @@ var ranges = require('./ranges');

/** @type {import('./getRangePairs')} */
module.exports = function getRangePairs() {
return entries(ranges);
};
module.exports = makeGetRangePairs(ranges);
'use strict';
var getRangePairs = require('./getRangePairs');
var makeIsCategory = require('node-package-field-info/makeIsCategory');
var ranges = require('./ranges');
/** @type {import('./isCategory')} */
module.exports = function isCategory(category) {
var all = getRangePairs();
for (var i = 0; i < all.length; i++) {
if (all[i][1] === category) {
return true;
}
}
return false;
};
module.exports = makeIsCategory(ranges);
{
"name": "node-exports-info",
"version": "1.6.2",
"version": "2.0.0",
"description": "Info about node `exports` field support: version ranges, categories, etc.",

@@ -61,6 +61,3 @@ "main": false,

"dependencies": {
"array.prototype.flatmap": "^1.3.3",
"es-errors": "^1.3.0",
"object.entries": "^1.1.9",
"semver": "^6.3.1"
"node-package-field-info": "^1.0.0"
},

@@ -86,2 +83,3 @@ "devDependencies": {

"safe-publish-latest": "^2.0.0",
"semver": "^6.3.1",
"tape": "^5.10.2",

@@ -103,5 +101,8 @@ "typescript": "next"

"ignore": [
".github/workflows"
".github/workflows",
".nycrc",
"eslint.config.mjs",
"test"
]
}
}
declare const ranges: {
__proto__: null;
'^24.14 || >= 25.4': 'subpath-imports-slash';
'23.6 - 24.13 || 25 - 25.3 || ^22.18': 'strips-types';
'>= 23.6 || ^22.18': 'strips-types';
'23 - 23.5 || 22.12 - 22.17 || ^20.19': 'require-esm';

@@ -6,0 +5,0 @@ '17.1 - 19 || 20 - 20.18 || ^21 || 22 - 22.11': 'pattern-trailers-no-dir-slash+json-imports';

@@ -6,4 +6,3 @@ 'use strict';

__proto__: null,
'^24.14 || >= 25.4': 'subpath-imports-slash', // added in 25.4, backported to 24.14
'23.6 - 24.13 || 25 - 25.3 || ^22.18': 'strips-types', // added in 23.6, backported to 22.18
'>= 23.6 || ^22.18': 'strips-types', // added in 23.6, backported to 22.18
'23 - 23.5 || 22.12 - 22.17 || ^20.19': 'require-esm', // added in 23.0, 22.12, 20.19

@@ -10,0 +9,0 @@ '17.1 - 19 || 20 - 20.18 || ^21 || 22 - 22.11': 'pattern-trailers-no-dir-slash+json-imports',

@@ -25,4 +25,3 @@ # node-exports-info <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

- `require-esm`: ESM files can be `require`d (`23 - 23.5 || 22.12 - 22.17 || ^20.19`)
- `strips-types`: these versions also automatically strip types from typescript files, for both `require` and `import` (`23.6 - 24.13 || 25 - 25.3 || ^22.18`)
- `subpath-imports-slash`: these versions support `#/` subpath imports patterns in the `imports` field, e.g. `"#/*": "./src/*.js"` (`^24.14 || >= 25.4`)
- `strips-types`: these versions also automatically strip types from typescript files, for both `require` and `import` (`>= 23.6 || ^22.18`)

@@ -29,0 +28,0 @@ ## Entry points

Sorry, the diff of this file is not supported yet

import ljharbConfig from '@ljharb/eslint-config/flat';
export default [
...ljharbConfig,
{
rules: {
'func-name-matching': ['error', 'always'],
'id-length': 'off',
'multiline-comment-style': 'off',
'no-magic-numbers': ['error', { ignore: [0, 1] }],
'sort-keys': 'off',
},
},
];
'use strict';
var test = require('tape');
var forEach = require('for-each');
var getCategoriesForRange = require('../getCategoriesForRange');
var getCategory = require('../getCategory');
var boundaryVersions = require('./versions');
test('getCategoriesForRange', function (t) {
t['throws'](
function () { getCategoriesForRange('not a version'); },
TypeError,
'invalid version range throws'
);
t.deepEqual(
getCategoriesForRange(process.version),
[getCategory(process.version)],
'exactly 1 category for the current version'
);
forEach(boundaryVersions, function (version) {
t.test('boundary version: ' + version, function (st) {
var categories = getCategoriesForRange(version);
st.deepEqual(
categories,
[getCategory(version)],
'exactly 1 category for a boundary version'
);
st.end();
});
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var semver = require('semver');
var getCategory = require('../getCategory');
var getRange = require('../getRange');
var boundaryVersions = require('./versions');
test('getCategory', function (t) {
t['throws'](
function () { getCategory('not a version'); },
RangeError,
'invalid version throws'
);
t['throws'](
function () { getCategory('^1.2.3'); },
RangeError,
'semver range throws'
);
t.doesNotThrow(
function () { getCategory(process.version); },
'current node version has a category'
);
forEach(boundaryVersions, function (version) {
t.test('boundary version: ' + version, function (st) {
st.test('default version', function (s2t) {
var origVersion = process.version;
Object.defineProperty(process, 'version', { value: version });
s2t.teardown(function () { Object.defineProperty(process, 'version', { value: origVersion }); });
s2t.equal(
getCategory(),
getCategory(version),
'category with an explicit version matches the defaulted process.version'
);
s2t.end();
});
var range = getRange(getCategory(version));
st.ok(
semver.satisfies(version, range),
'version ' + version + ' satisfies range ' + range
);
st.end();
});
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var getCategoryFlags = require('../getCategoryFlags');
var getRangePairs = require('../getRangePairs');
test('getCategoryFlags', function (t) {
t['throws'](
// @ts-expect-error
function () { getCategoryFlags('not a category'); },
RangeError,
'invalid category throws'
);
forEach(getRangePairs(), function (pair) {
var category = pair[1];
t.test('category: ' + category, function (st) {
var flags = getCategoryFlags(category);
st.ok(
flags && typeof flags === 'object',
'returns an object'
);
st.ok(
'patterns' in flags && typeof flags.patterns === 'boolean',
'has boolean patterns flag'
);
st.ok(
'patternTrailers' in flags && typeof flags.patternTrailers === 'boolean',
'has boolean patternTrailers flag'
);
st.ok(
'dirSlash' in flags && typeof flags.dirSlash === 'boolean',
'has boolean dirSlash flag'
);
// Verify flag consistency: patternTrailers implies patterns
if (flags.patternTrailers) {
st.ok(flags.patterns, 'patternTrailers implies patterns');
}
st.end();
});
});
t.test('specific category flags', function (st) {
st.deepEqual(
getCategoryFlags('pre-exports'),
{ patterns: false, patternTrailers: false, dirSlash: false },
'pre-exports has no flags'
);
st.deepEqual(
getCategoryFlags('broken'),
{ patterns: false, patternTrailers: false, dirSlash: false },
'broken has no flags'
);
st.deepEqual(
getCategoryFlags('experimental'),
{ patterns: false, patternTrailers: false, dirSlash: false },
'experimental has no flags'
);
st.deepEqual(
getCategoryFlags('conditions'),
{ patterns: false, patternTrailers: false, dirSlash: false },
'conditions has no flags'
);
st.deepEqual(
getCategoryFlags('broken-dir-slash-conditions'),
{ patterns: false, patternTrailers: false, dirSlash: true },
'broken-dir-slash-conditions has dirSlash'
);
st.deepEqual(
getCategoryFlags('patterns'),
{ patterns: true, patternTrailers: false, dirSlash: true },
'patterns has patterns and dirSlash'
);
st.deepEqual(
getCategoryFlags('pattern-trailers'),
{ patterns: true, patternTrailers: true, dirSlash: true },
'pattern-trailers has all flags'
);
st.deepEqual(
getCategoryFlags('pattern-trailers-no-node-addons'),
{ patterns: true, patternTrailers: true, dirSlash: true },
'pattern-trailers-no-node-addons has all flags'
);
st.deepEqual(
getCategoryFlags('pattern-trailers+json-imports'),
{ patterns: true, patternTrailers: true, dirSlash: true },
'pattern-trailers+json-imports has all flags'
);
st.deepEqual(
getCategoryFlags('pattern-trailers-no-dir-slash'),
{ patterns: true, patternTrailers: true, dirSlash: false },
'pattern-trailers-no-dir-slash has patterns and patternTrailers but not dirSlash'
);
st.deepEqual(
getCategoryFlags('pattern-trailers-no-dir-slash+json-imports'),
{ patterns: true, patternTrailers: true, dirSlash: false },
'pattern-trailers-no-dir-slash+json-imports has patterns and patternTrailers but not dirSlash'
);
st.deepEqual(
getCategoryFlags('require-esm'),
{ patterns: true, patternTrailers: true, dirSlash: false },
'require-esm has patterns and patternTrailers but not dirSlash'
);
st.deepEqual(
getCategoryFlags('strips-types'),
{ patterns: true, patternTrailers: true, dirSlash: false },
'strips-types has patterns and patternTrailers but not dirSlash'
);
st.deepEqual(
getCategoryFlags('subpath-imports-slash'),
{ patterns: true, patternTrailers: true, dirSlash: false },
'subpath-imports-slash has patterns and patternTrailers but not dirSlash'
);
st.end();
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var getCategoryInfo = require('../getCategoryInfo');
var getCategoryFlags = require('../getCategoryFlags');
var getConditionsForCategory = require('../getConditionsForCategory');
var getRangePairs = require('../getRangePairs');
test('getCategoryInfo', function (t) {
t['throws'](
// @ts-expect-error
function () { getCategoryInfo('not a category'); },
RangeError,
'invalid category throws'
);
forEach(getRangePairs(), function (pair) {
var category = pair[1];
t.test('category: ' + category, function (st) {
var info = getCategoryInfo(category);
st.ok(
info && typeof info === 'object',
'returns an object'
);
st.ok(
'conditions' in info,
'has conditions property'
);
st.ok(
'flags' in info && info.flags && typeof info.flags === 'object',
'has flags object'
);
// Verify it matches individual function results
st.deepEqual(
info.conditions,
getConditionsForCategory(category, 'require'),
'conditions match getConditionsForCategory with require'
);
st.deepEqual(
info.flags,
getCategoryFlags(category),
'flags match getCategoryFlags'
);
// Test with explicit moduleSystem
var importInfo = getCategoryInfo(category, 'import');
st.deepEqual(
importInfo.conditions,
getConditionsForCategory(category, 'import'),
'import conditions match getConditionsForCategory with import'
);
var requireInfo = getCategoryInfo(category, 'require');
st.deepEqual(
requireInfo.conditions,
getConditionsForCategory(category, 'require'),
'require conditions match getConditionsForCategory with require'
);
st.end();
});
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var getConditionsForCategory = require('../getConditionsForCategory');
var getRangePairs = require('../getRangePairs');
test('getConditionsForCategory', function (t) {
t['throws'](
// @ts-expect-error
function () { getConditionsForCategory('not a category'); },
RangeError,
'invalid category throws'
);
forEach(getRangePairs(), function (pair) {
var category = pair[1];
t.test('category: ' + category, function (st) {
if (category === 'broken' || category === 'pre-exports') {
st.equal(
getConditionsForCategory(category),
null,
'category that does not support conditions, yields null'
);
} else {
var conditions = getConditionsForCategory(category);
st.ok(Array.isArray(conditions), 'moduleSystem none: returns an array');
var requireConditions = getConditionsForCategory(category, 'require');
st.ok(Array.isArray(requireConditions), 'moduleSystem require: returns an array');
var importConditions = getConditionsForCategory(category, 'import');
st.ok(Array.isArray(importConditions), 'moduleSystem import: returns an array');
st['throws'](
// @ts-expect-error
function () { getConditionsForCategory(category, 'not a thing'); },
TypeError,
'invalid moduleSystem throws'
);
}
st.end();
});
});
t.deepEqual(
getConditionsForCategory('pattern-trailers-no-node-addons'),
['import', 'node', 'require', 'default'],
'`pattern-trailers-no-node-addons` omits the `node-addons` condition'
);
t.deepEqual(
getConditionsForCategory('pattern-trailers'),
['import', 'node-addons', 'node', 'require', 'default'],
'`pattern-trailers` includes the `node-addons` condition'
);
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var getRange = require('../getRange');
var getRangePairs = require('../getRangePairs');
test('getRange', function (t) {
t['throws'](
// @ts-expect-error
function () { getRange('not a category'); },
RangeError,
'invalid category throws'
);
forEach(getRangePairs(), function (entry) {
var range = entry[0];
var category = entry[1];
var actualRange = getRange(category);
t.equal(actualRange, range, 'yielded range for ' + category + ' is as expected');
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var semver = require('semver');
var getRangePairs = require('../getRangePairs');
var getConditionsForCategory = require('../getConditionsForCategory');
test('getRangePairs', function (t) {
var pairs = getRangePairs();
t.ok(Array.isArray(pairs), 'returns an array');
forEach(pairs, function (entry, i) {
t.ok(Array.isArray(entry), 'entry ' + i + ' is an array');
var range = entry[0];
var category = entry[1];
t.ok(semver.validRange(range), i + ': item 0 is a valid semver range');
t.doesNotThrow(
function () { getConditionsForCategory(category); },
i + ': item 1 is a valid category'
);
});
t.end();
});
'use strict';
var test = require('tape');
var forEach = require('for-each');
var v = require('es-value-fixtures');
var inspect = require('object-inspect');
var getRange = require('../getRange');
var getRangePairs = require('../getRangePairs');
var isCategory = require('../isCategory');
test('isCategory', function (t) {
forEach(v.nonStrings, function (nonString) {
t.equal(isCategory(nonString), false, inspect(nonString) + ' is not a category');
});
forEach(getRangePairs(), function (pair) {
var category = pair[1];
t.equal(isCategory(category), true, inspect(category) + ' is a category');
t.doesNotThrow(function () { getRange(category); }, 'getRange does not throw for ' + inspect(category));
});
t.end();
});
'use strict';
module.exports = [
'v12.16.999',
'v12.17.0',
'v12.19.999',
'v12.20.0',
'v12.999.0',
'v13.0.0',
'v13.2.999',
'v13.3.0',
'v13.6.999',
'v13.7.0',
'v13.13.999',
'v13.14.0',
'v13.999.999',
'v14.0.0',
'v14.12.999',
'v14.13.0',
'v14.18.999',
'v14.19.0',
'v16.8.999',
'v16.9.0',
'v16.9.999',
'v16.10.0',
'v16.13.999',
'v16.14.0',
'v16.999.999',
'v17.0.0',
'v17.0.999',
'v17.1.0',
'v20.18.999',
'v20.19.0',
'v22.11.999',
'v22.12.0',
'v22.17.999',
'v22.18.0',
'v22.999.999',
'v23.0.0',
'v23.5.999',
'v23.6.0',
'v23.999.999',
'v24.0.0',
'v24.13.999',
'v24.14.0',
'v24.999.999',
'v25.0.0',
'v25.3.999',
'v25.4.0',
'v25.999.999',
'v26.0.0'
];