From 79b45e9bf60ff07d03d70d11b691f3426bccc740 Mon Sep 17 00:00:00 2001 From: JSReds Date: Mon, 8 Mar 2021 13:10:42 +0100 Subject: [PATCH] Add getLatestOsVersions in hostapp model Add getLatestOsVersions method in hostapp model Change-type: minor Signed-off-by: Andrea Rosci --- DOCUMENTATION.md | 22 +++++++++++ lib/models/hostapp.ts | 47 ++++++++++++++++++++++++ tests/integration/models/hostapp.spec.ts | 18 +++++++++ 3 files changed, 87 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index a192896fb..5b0ee38ec 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -305,6 +305,7 @@ const sdk = fromSharedOptions(); * [.isArchitectureCompatibleWith(osArchitecture, applicationArchitecture)](#balena.models.os.isArchitectureCompatibleWith) ⇒ Boolean * [.hostapp](#balena.models.hostapp) : object * [.getAllOsVersions(deviceTypes)](#balena.models.hostapp.getAllOsVersions) ⇒ Promise + * [.getLatestOsVersions(deviceTypes)](#balena.models.hostapp.getLatestOsVersions) ⇒ Promise * [.config](#balena.models.config) : object * [.getAll()](#balena.models.config.getAll) ⇒ Promise * ~~[.getDeviceTypes()](#balena.models.config.getDeviceTypes) ⇒ Promise~~ @@ -671,6 +672,7 @@ balena.models.device.get(123).catch(function (error) { * [.isArchitectureCompatibleWith(osArchitecture, applicationArchitecture)](#balena.models.os.isArchitectureCompatibleWith) ⇒ Boolean * [.hostapp](#balena.models.hostapp) : object * [.getAllOsVersions(deviceTypes)](#balena.models.hostapp.getAllOsVersions) ⇒ Promise + * [.getLatestOsVersions(deviceTypes)](#balena.models.hostapp.getLatestOsVersions) ⇒ Promise * [.config](#balena.models.config) : object * [.getAll()](#balena.models.config.getAll) ⇒ Promise * ~~[.getDeviceTypes()](#balena.models.config.getDeviceTypes) ⇒ Promise~~ @@ -6273,6 +6275,11 @@ console.log(result2); **Beta** The hostapp methods are still in beta and might change in a non-major release. **Kind**: static namespace of [models](#balena.models) + +* [.hostapp](#balena.models.hostapp) : object + * [.getAllOsVersions(deviceTypes)](#balena.models.hostapp.getAllOsVersions) ⇒ Promise + * [.getLatestOsVersions(deviceTypes)](#balena.models.hostapp.getLatestOsVersions) ⇒ Promise + ##### hostapp.getAllOsVersions(deviceTypes) ⇒ Promise @@ -6288,6 +6295,21 @@ console.log(result2); ```js balena.models.hostapp.getAllOsVersions(['fincm3', 'raspberrypi3']); ``` + + +##### hostapp.getLatestOsVersions(deviceTypes) ⇒ Promise +**Kind**: static method of [hostapp](#balena.models.hostapp) +**Summary**: Get latest OS versions for the passed device types +**Access**: public + +| Param | Type | Description | +| --- | --- | --- | +| deviceTypes | Array.<String> | device type slugs | + +**Example** +```js +balena.models.hostapp.getLatestOsVersions(['fincm3', 'raspberrypi3']); +``` #### models.config : object diff --git a/lib/models/hostapp.ts b/lib/models/hostapp.ts index 27fa09ee6..21dbc7a73 100644 --- a/lib/models/hostapp.ts +++ b/lib/models/hostapp.ts @@ -9,6 +9,7 @@ import type { } from '../types/models'; import { Dictionary } from '../../typings/utils'; import { getAuthDependentMemoize } from '../util/cache'; +import { maxSatisfying } from 'semver'; const RELEASE_POLICY_TAG_NAME = 'release-policy'; const ESR_NEXT_TAG_NAME = 'esr-next'; @@ -161,6 +162,12 @@ const getHostappModel = function (deps: InjectedDependenciesParam) { return res; }; + const mapVersions = (versions: OsVersion[], type: OsTypes) => { + return versions + .filter((version) => version.osType === type) + .map((v) => v.strippedVersion); + }; + // This mutates the passed object. const transformVersionSets = ( osVersionsByDeviceType: OsVersionsByDeviceType, @@ -261,9 +268,49 @@ const getHostappModel = function (deps: InjectedDependenciesParam) { return memoizedGetTransformedOsVersions(sortedDeviceTypes); }; + /** + * @summary Get latest OS versions for the passed device types + * @name getLatestOsVersions + * @public + * @function + * @memberof balena.models.hostapp + * + * @param {String[]} deviceTypes - device type slugs + * @returns {Promise} + * + * @example + * balena.models.hostapp.getLatestOsVersions(['fincm3', 'raspberrypi3']); + */ + const getLatestOsVersions = async ( + deviceTypes: string[], + ): Promise => { + const allOsVersions = await getAllOsVersions(deviceTypes); + return Object.entries(allOsVersions).reduce( + (osVersionsByDeviceType: OsVersionsByDeviceType, [key, versions]) => { + const latestOSVersion = maxSatisfying( + mapVersions(versions, OsTypes.DEFAULT), + '>0.0.0', + ); + const latestESRVersion = maxSatisfying( + mapVersions(versions, OsTypes.ESR), + '>0.0.0', + ); + const filteredVersions = versions.filter( + (v) => + v.strippedVersion === latestOSVersion || + v.strippedVersion === latestESRVersion, + )!; + osVersionsByDeviceType[key] = filteredVersions; + return osVersionsByDeviceType; + }, + {}, + ); + }; + return { OsTypes, getAllOsVersions, + getLatestOsVersions, }; }; diff --git a/tests/integration/models/hostapp.spec.ts b/tests/integration/models/hostapp.spec.ts index 9659f09e1..634f5f8fe 100644 --- a/tests/integration/models/hostapp.spec.ts +++ b/tests/integration/models/hostapp.spec.ts @@ -75,4 +75,22 @@ describe('Hostapp model', function () { expect(firstRes).to.equal(secondRes); }); }); + + parallel('balena.models.hostapp.getLatestOsVersions()', function () { + it('should contain latest balenaOS and balenaOS ESR OS types', async () => { + const res = await balena.models.hostapp.getLatestOsVersions([ + 'fincm3', + 'raspberrypi3', + ]); + + ['fincm3', 'raspberrypi3'].forEach((key) => { + expect(res[key]).to.be.an('Array'); + expect(res[key]).to.have.lengthOf(4); + expect(res[key].filter((r) => r.osType === 'esr')).to.have.lengthOf(2); + expect(res[key].filter((r) => r.osType === 'default')).to.have.lengthOf( + 2, + ); + }); + }); + }); });