'use strict'; var _ = require('lodash'); var versionParts = ['major', 'minor', 'patch']; function ResourceCache() { this.libs = {}; this.storeRelease = function(release) { this.libs[release.libName] = this.libs[release.libName] || {}; distributeIntoBucketsRecursive(0, this.libs[release.libName], release); distributeReleaseIntoTypes(this.libs[release.libName], release); }; this.getReleases = function(releaseRequest) { return getFromBucketsRecursive(0, this.libs[releaseRequest.libName], releaseRequest); }; } function distributeIntoBucketsRecursive(versionPartIndex, parent, release) { var versionPart = versionParts[versionPartIndex]; if (!versionPart) { distributeReleaseIntoVersionSpecifiers(parent, release); return; } var value = release[versionPart]; if (!parent[value]) { parent[value] = {}; } distributeReleaseIntoTypes(parent[value], release); distributeIntoBucketsRecursive(versionPartIndex + 1, parent[value], release); } function distributeReleaseIntoVersionSpecifiers(parent, release) { if (release.preRelease) { if (!parent[release.preRelease]) { parent[release.preRelease] = {}; } distributeReleaseIntoTypes(parent[release.preRelease], release); if (release.metadata) { if (!parent[release.preRelease][release.metadata]) { parent[release.preRelease][release.metadata] = {}; } distributeReleaseIntoTypes(parent[release.preRelease][release.metadata], release); } } if (release.metadata) { if (!parent['no-prerelease']) { parent['no-prerelease'] = {}; } if (!parent['no-prerelease'][release.metadata]) { parent['no-prerelease'][release.metadata] = {}; } distributeReleaseIntoTypes(parent['no-prerelease'][release.metadata], release); } } function distributeReleaseIntoTypes(parent, release) { if (!parent['latest']) { parent['latest'] = {}; } if (!parent['latest']['all']) { parent['latest']['all'] = {}; } if (!parent['latest']['all'][release.resourceType]) { parent['latest']['all'][release.resourceType] = [release]; } parent['latest'][release.resourceType] = [release]; } function getFromBucketsRecursive(versionPartIndex, parent, releaseRequest) { var versionPart = versionParts[versionPartIndex]; if (!versionPart) { return getReleasesFromVersionSpecifiers(parent, releaseRequest); } var value = releaseRequest[versionPart]; if (!value) { return getReleasesOfType(parent, releaseRequest); } return getFromBucketsRecursive(versionPartIndex + 1, parent[value], releaseRequest); } function getReleasesFromVersionSpecifiers(parent, releaseRequest) { if (releaseRequest.preRelease) { if (releaseRequest.metadata) { return getReleasesOfType(parent[releaseRequest.preRelease][releaseRequest.metadata], releaseRequest); } return getReleasesOfType(parent[releaseRequest.preRelease], releaseRequest); } if (releaseRequest.metadata) { return getReleasesOfType(parent['no-prerelease'][releaseRequest.metadata], releaseRequest); } return getReleasesOfType(parent, releaseRequest); } function getReleasesOfType(parent, releaseRequest) { if (!parent || !parent['latest']) { return null; } if (releaseRequest.resourceType) { return parent['latest'][releaseRequest.resourceType]; } return _.flatten(_.map(parent['latest']['all'], function(releases) { return releases; })); } module.exports = ResourceCache;