From 584aa745f7a5f2d2cc7fb3209ac5c07c366ea04b Mon Sep 17 00:00:00 2001 From: Scott Lowe Date: Fri, 18 Dec 2020 12:06:55 +0100 Subject: [PATCH] Improve id disambiguation for tag commands Change-type: patch Signed-off-by: Scott Lowe --- lib/commands/tag/rm.ts | 3 ++- lib/commands/tag/set.ts | 3 ++- lib/commands/tags.ts | 3 ++- lib/utils/sdk.ts | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/commands/tag/rm.ts b/lib/commands/tag/rm.ts index 636c6231..e46940b3 100644 --- a/lib/commands/tag/rm.ts +++ b/lib/commands/tag/rm.ts @@ -102,8 +102,9 @@ export default class TagRmCmd extends Command { const { tryAsInteger } = await import('../../utils/validation'); if (options.application) { + const { getTypedApplicationIdentifier } = await import('../../utils/sdk'); return balena.models.application.tags.remove( - tryAsInteger(options.application), + await getTypedApplicationIdentifier(balena, options.application), params.tagKey, ); } diff --git a/lib/commands/tag/set.ts b/lib/commands/tag/set.ts index 9b878112..8237effb 100644 --- a/lib/commands/tag/set.ts +++ b/lib/commands/tag/set.ts @@ -117,8 +117,9 @@ export default class TagSetCmd extends Command { const { tryAsInteger } = await import('../../utils/validation'); if (options.application) { + const { getTypedApplicationIdentifier } = await import('../../utils/sdk'); return balena.models.application.tags.set( - tryAsInteger(options.application), + await getTypedApplicationIdentifier(balena, options.application), params.tagKey, params.value, ); diff --git a/lib/commands/tags.ts b/lib/commands/tags.ts index 88627463..b3a383fc 100644 --- a/lib/commands/tags.ts +++ b/lib/commands/tags.ts @@ -91,8 +91,9 @@ export default class TagsCmd extends Command { let tags; if (options.application) { + const { getTypedApplicationIdentifier } = await import('../utils/sdk'); tags = await balena.models.application.tags.getAllByApplication( - tryAsInteger(options.application), + await getTypedApplicationIdentifier(balena, options.application), ); } if (options.device) { diff --git a/lib/utils/sdk.ts b/lib/utils/sdk.ts index fb492597..8e965e88 100644 --- a/lib/utils/sdk.ts +++ b/lib/utils/sdk.ts @@ -26,7 +26,6 @@ import type { * Wraps the sdk application.get method, * adding disambiguation in cases where the provided * identifier could be interpreted in multiple valid ways. - * // TODO: Remove this once support for numeric App IDs is removed. */ export async function getApplication( sdk: BalenaSDK, @@ -50,6 +49,46 @@ export async function getApplication( return sdk.models.application.get(nameOrSlugOrId, options); } +/** + * Given an string representation of an application identifier, + * which could be one of: + * - name (including numeric names) + * - slug + * - numerical id + * disambiguate and return a properly typed identifier. + * + * Attempts to minimise the number of API calls required. + * TODO: Remove this once support for numeric App IDs is removed. + */ +export async function getTypedApplicationIdentifier( + sdk: BalenaSDK, + nameOrSlugOrId: string, +) { + const { looksLikeInteger } = await import('./validation'); + // If there's no possible ambiguity, + // return the passed identifier unchanged + if (!looksLikeInteger(nameOrSlugOrId)) { + return nameOrSlugOrId; + } + + // Resolve ambiguity + try { + // Test for existence of app with this numerical ID, + // and return typed id if found + return (await sdk.models.application.get(Number(nameOrSlugOrId))).id; + } catch (e) { + const { instanceOf } = await import('../errors'); + const { BalenaApplicationNotFound } = await import('balena-errors'); + if (!instanceOf(e, BalenaApplicationNotFound)) { + throw e; + } + } + + // App with this numerical id not found + // return the passed identifier unchanged + return nameOrSlugOrId; +} + /** * Wraps the sdk organization.getAll method, * restricting to those orgs user is a member of