From 974d6fab6caf42aee42c359644b1f520863646d5 Mon Sep 17 00:00:00 2001 From: Ross Stenersen Date: Tue, 18 Nov 2025 14:18:42 -0600 Subject: [PATCH] feat: add `buildEpilog` to rest of commands and removed old apiDocsURL --- .../commands/capabilities/presentation.test.ts | 9 ++++++--- src/__tests__/commands/config.test.ts | 12 +++++++++++- .../commands/edge/channels/delete.test.ts | 10 ++++++++-- .../commands/edge/channels/drivers.test.ts | 10 ++++++++-- .../commands/edge/channels/enrollments.test.ts | 10 ++++++++-- .../commands/locations/rooms/delete.test.ts | 10 ++++++++-- .../commands/locations/rooms/update.test.ts | 10 ++++++++-- src/__tests__/commands/organizations.test.ts | 9 +++++++++ .../commands/organizations/current.test.ts | 9 +++++++++ .../commands/presentation/device-config.test.ts | 10 ++++++++-- src/__tests__/commands/scenes/execute.test.ts | 10 ++++++++-- src/__tests__/commands/schema.test.ts | 9 ++++++--- src/__tests__/commands/schema/authorize.test.ts | 14 +++++++++++++- src/__tests__/commands/schema/create.test.ts | 11 +++++++---- src/__tests__/commands/schema/delete.test.ts | 9 ++++++--- src/__tests__/commands/schema/update.test.ts | 9 ++++++--- src/__tests__/lib/command/api-command.test.ts | 16 ---------------- src/__tests__/test-lib/api-command-mock.ts | 5 ----- src/commands/capabilities/create.ts | 14 +++++++++++--- src/commands/capabilities/delete.ts | 4 ++-- src/commands/capabilities/presentation.ts | 4 ++-- .../capabilities/translations/create.ts | 4 ++-- .../capabilities/translations/update.ts | 17 +++++++++++++---- .../capabilities/translations/upsert.ts | 4 ++-- src/commands/capabilities/update.ts | 4 ++-- src/commands/config.ts | 2 ++ src/commands/edge/channels/delete.ts | 5 +++-- src/commands/edge/channels/drivers.ts | 5 +++-- src/commands/edge/channels/enrollments.ts | 5 +++-- src/commands/invites/schema.ts | 5 +++-- src/commands/invites/schema/create.ts | 4 ++-- src/commands/invites/schema/delete.ts | 3 ++- src/commands/locations/rooms/delete.ts | 4 ++-- src/commands/locations/rooms/update.ts | 5 +++-- src/commands/organizations.ts | 2 ++ src/commands/organizations/current.ts | 2 ++ src/commands/presentation/device-config.ts | 5 +++-- .../presentation/device-config/create.ts | 5 +++-- .../presentation/device-config/generate.ts | 5 +++-- src/commands/scenes/execute.ts | 5 +++-- src/commands/schema.ts | 4 ++-- src/commands/schema/authorize.ts | 14 +++++++++----- src/commands/schema/create.ts | 4 ++-- src/commands/schema/delete.ts | 4 ++-- src/commands/schema/update.ts | 4 ++-- src/lib/command/api-command.ts | 11 ----------- 46 files changed, 219 insertions(+), 117 deletions(-) diff --git a/src/__tests__/commands/capabilities/presentation.test.ts b/src/__tests__/commands/capabilities/presentation.test.ts index ba717eb7..20ef1eea 100644 --- a/src/__tests__/commands/capabilities/presentation.test.ts +++ b/src/__tests__/commands/capabilities/presentation.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { CapabilitiesEndpoint, SmartThingsClient, CapabilityPresentation } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../commands/capabilities/presentation.js' +import type { buildEpilog } from '../../../lib/help.js' import type { APIOrganizationCommand, APIOrganizationCommandFlags, @@ -18,12 +19,14 @@ import type { import type { CustomCommonOutputProducer, formatAndWriteItem, formatAndWriteItemBuilder } from '../../../lib/command/format.js' import { chooseCapability } from '../../../lib/command/util/capabilities-choose.js' import { buildTableOutput } from '../../../lib/command/util/capabilities-presentation-table.js' -import { apiCommandMocks } from '../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../test-lib/builder-mock.js' import { tableGeneratorMock } from '../../test-lib/table-mock.js' -const { apiDocsURLMock } = apiCommandMocks('../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() @@ -85,7 +88,7 @@ test('builder', () => { expect(exampleMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/config.test.ts b/src/__tests__/commands/config.test.ts index f0829235..cd32de9d 100644 --- a/src/__tests__/commands/config.test.ts +++ b/src/__tests__/commands/config.test.ts @@ -4,8 +4,9 @@ import type { join } from 'node:path' import type { ArgumentsCamelCase, Argv } from 'yargs' -import type { Profile, ProfilesByName } from '../../lib/cli-config.js' import type { CommandArgs } from '../../commands/config.js' +import type { Profile, ProfilesByName } from '../../lib/cli-config.js' +import type { buildEpilog } from '../../lib/help.js' import type { stringTranslateToId } from '../../lib/command/command-util.js' import type { TableCommonListOutputProducer, TableCommonOutputProducer } from '../../lib/command/format.js' import type { outputItemOrListBuilder } from '../../lib/command/listing-io.js' @@ -32,6 +33,11 @@ jest.unstable_mockModule('node:path', () => ({ join: joinMock, })) +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + const stringTranslateToIdMock = jest.fn() jest.unstable_mockModule('../../lib/command/command-util.js', () => ({ stringTranslateToId: stringTranslateToIdMock, @@ -84,6 +90,7 @@ test('builder', () => { positionalMock, optionMock, exampleMock, + epilogMock, argvMock, } = buildArgvMock() @@ -96,6 +103,9 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) + expect(exampleMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) + expect(epilogMock).toHaveBeenCalledTimes(1) }) describe('handler', () => { diff --git a/src/__tests__/commands/edge/channels/delete.test.ts b/src/__tests__/commands/edge/channels/delete.test.ts index 521b28b1..6c11bf40 100644 --- a/src/__tests__/commands/edge/channels/delete.test.ts +++ b/src/__tests__/commands/edge/channels/delete.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import { ChannelsEndpoint } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../../commands/edge/channels/delete.js' +import type { buildEpilog } from '../../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../../lib/command/api-command.js' import type { CLIConfig, resetManagedConfigKey } from '../../../../lib/cli-config.js' import type { chooseChannel } from '../../../../lib/command/util/edge/channels-choose.js' @@ -17,7 +18,12 @@ jest.unstable_mockModule('../../../../lib/cli-config.js', () => ({ resetManagedConfigKey: resetManagedConfigKeyMock, })) -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../../..') const chooseChannelMock = jest.fn().mockResolvedValue('chosen-channel-id') jest.unstable_mockModule('../../../../lib/command/util/edge/channels-choose.js', () => ({ @@ -50,7 +56,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(0) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/edge/channels/drivers.test.ts b/src/__tests__/commands/edge/channels/drivers.test.ts index a5f73d8d..ca7f1a66 100644 --- a/src/__tests__/commands/edge/channels/drivers.test.ts +++ b/src/__tests__/commands/edge/channels/drivers.test.ts @@ -3,6 +3,7 @@ import { jest } from '@jest/globals' import type { ArgumentsCamelCase, Argv } from 'yargs' import type { CommandArgs } from '../../../../commands/edge/channels/drivers.js' +import type { buildEpilog } from '../../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../../lib/command/api-command.js' import type { outputList, outputListBuilder } from '../../../../lib/command/output-list.js' import type { @@ -15,7 +16,12 @@ import { apiCommandMocks } from '../../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../../test-lib/builder-mock.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../../..') const outputListMock = jest.fn() const outputListBuilderMock = jest.fn() @@ -62,7 +68,7 @@ test('builder', async () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(0) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/edge/channels/enrollments.test.ts b/src/__tests__/commands/edge/channels/enrollments.test.ts index 22df9373..3f8ddf4c 100644 --- a/src/__tests__/commands/edge/channels/enrollments.test.ts +++ b/src/__tests__/commands/edge/channels/enrollments.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { EnrolledChannel, HubdevicesEndpoint } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../../commands/edge/channels/enrollments.js' +import type { buildEpilog } from '../../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../../lib/command/api-command.js' import type { outputList, outputListBuilder } from '../../../../lib/command/output-list.js' import type { chooseHub } from '../../../../lib/command/util/hubs-choose.js' @@ -12,7 +13,12 @@ import { apiCommandMocks } from '../../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../../test-lib/builder-mock.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../../..') const outputListMock = jest.fn() const outputListBuilderMock = jest.fn() @@ -53,7 +59,7 @@ test('builder', async () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(0) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/locations/rooms/delete.test.ts b/src/__tests__/commands/locations/rooms/delete.test.ts index cd65d0d5..305e3ea2 100644 --- a/src/__tests__/commands/locations/rooms/delete.test.ts +++ b/src/__tests__/commands/locations/rooms/delete.test.ts @@ -5,13 +5,19 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { RoomsEndpoint } from '@smartthings/core-sdk' import { CommandArgs } from '../../../../commands/locations/rooms/delete.js' +import type { buildEpilog } from '../../../../lib/help.js' import type { chooseRoom } from '../../../../lib/command/util/rooms-choose.js' import { apiCommandMocks } from '../../../test-lib/api-command-mock.js' import { buildArgvMock } from '../../../test-lib/builder-mock.js' import { APICommand } from '../../../../lib/command/api-command.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../../..') const chooseRoomMock = jest.fn() jest.unstable_mockModule('../../../../lib/command/util/rooms-choose.js', () => ({ @@ -45,7 +51,7 @@ test('builder', () => { expect(optionMock).toHaveBeenCalledTimes(1) expect(positionalMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/locations/rooms/update.test.ts b/src/__tests__/commands/locations/rooms/update.test.ts index 5c0548aa..03dfef14 100644 --- a/src/__tests__/commands/locations/rooms/update.test.ts +++ b/src/__tests__/commands/locations/rooms/update.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { Room, RoomRequest, RoomsEndpoint } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../../commands/locations/rooms/update.js' +import type { buildEpilog } from '../../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../../lib/command/api-command.js' import type { inputAndOutputItem, inputAndOutputItemBuilder } from '../../../../lib/command/input-and-output-item.js' import type { chooseRoom } from '../../../../lib/command/util/rooms-choose.js' @@ -13,7 +14,12 @@ import { apiCommandMocks } from '../../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../../test-lib/builder-mock.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../../..') const inputAndOutputItemMock = jest.fn() const inputAndOutputItemBuilderMock = jest.fn() @@ -56,7 +62,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/organizations.test.ts b/src/__tests__/commands/organizations.test.ts index f66c4ece..3ff84dbf 100644 --- a/src/__tests__/commands/organizations.test.ts +++ b/src/__tests__/commands/organizations.test.ts @@ -9,6 +9,7 @@ import type { } from '@smartthings/core-sdk' import type { APICommand, APICommandFlags } from '../../lib/command/api-command.js' +import type { buildEpilog } from '../../lib/help.js' import type { outputItemOrList, outputItemOrListBuilder } from '../../lib/command/listing-io.js' import type { CommandArgs } from '../../commands/organizations.js' import type { BuildOutputFormatterFlags } from '../../lib/command/output-builder.js' @@ -17,6 +18,11 @@ import { apiCommandMocks } from '../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../test-lib/builder-mock.js' +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../..') const outputItemOrListMock = jest.fn>() @@ -36,6 +42,7 @@ test('builder', () => { yargsMock: apiCommandBuilderArgvMock, positionalMock, exampleMock, + epilogMock, argvMock, } = buildArgvMock() @@ -50,6 +57,8 @@ test('builder', () => { expect(outputItemOrListBuilderMock).toHaveBeenCalledExactlyOnceWith(apiCommandBuilderArgvMock) expect(positionalMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) + expect(epilogMock).toHaveBeenCalledTimes(1) }) describe('handler', () => { diff --git a/src/__tests__/commands/organizations/current.test.ts b/src/__tests__/commands/organizations/current.test.ts index 72e28cac..5a63d6fe 100644 --- a/src/__tests__/commands/organizations/current.test.ts +++ b/src/__tests__/commands/organizations/current.test.ts @@ -9,6 +9,7 @@ import type { } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../commands/organizations/current.js' +import type { buildEpilog } from '../../../lib/help.js' import type { APIOrganizationCommand, APIOrganizationCommandFlags, @@ -26,6 +27,11 @@ import { buildArgvMock, buildArgvMockStub } from '../../test-lib/builder-mock.js import { CLIConfig } from '../../../lib/cli-config.js' +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() jest.unstable_mockModule('../../../lib/command/api-organization-command.js', () => ({ @@ -57,6 +63,7 @@ test('builder', () => { const { yargsMock: apiOrganizationCommandBuilderArgvMock, exampleMock, + epilogMock, argvMock, } = buildArgvMock() @@ -72,6 +79,8 @@ test('builder', () => { .toHaveBeenCalledExactlyOnceWith(apiOrganizationCommandBuilderArgvMock) expect(exampleMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) + expect(epilogMock).toHaveBeenCalledTimes(1) }) describe('handler', () => { diff --git a/src/__tests__/commands/presentation/device-config.test.ts b/src/__tests__/commands/presentation/device-config.test.ts index da26bf19..215d8126 100644 --- a/src/__tests__/commands/presentation/device-config.test.ts +++ b/src/__tests__/commands/presentation/device-config.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { PresentationDeviceConfig, PresentationEndpoint } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../commands/presentation/device-config.js' +import type { buildEpilog } from '../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../lib/command/api-command.js' import type { OutputItemOrListFlags } from '../../../lib/command/listing-io.js' import type { outputItem, outputItemBuilder } from '../../../lib/command/output-item.js' @@ -16,7 +17,12 @@ import { CustomCommonOutputProducer } from '../../../lib/command/format.js' import { tableGeneratorMock } from '../../test-lib/table-mock.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../..') const outputItemMock = jest.fn() const outputItemBuilderMock = jest.fn() @@ -55,7 +61,7 @@ test('builder', () => { expect(outputItemBuilderMock).toHaveBeenCalledExactlyOnceWith(apiCommandBuilderArgvMock) expect(positionalMock).toHaveBeenCalledTimes(2) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/scenes/execute.test.ts b/src/__tests__/commands/scenes/execute.test.ts index b8c34461..17b74357 100644 --- a/src/__tests__/commands/scenes/execute.test.ts +++ b/src/__tests__/commands/scenes/execute.test.ts @@ -5,13 +5,19 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import { type ScenesEndpoint, SmartThingsClient, SuccessStatusValue } from '@smartthings/core-sdk' import { CommandArgs } from '../../../commands/scenes/execute.js' +import type { buildEpilog } from '../../../lib/help.js' import type { APICommand, APICommandFlags } from '../../../lib/command/api-command.js' import { chooseScene } from '../../../lib/command/util/scenes-util.js' import { apiCommandMocks } from '../../test-lib/api-command-mock.js' import { buildArgvMock } from '../../test-lib/builder-mock.js' -const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + +const { apiCommandMock, apiCommandBuilderMock } = apiCommandMocks('../../..') const chooseSceneMock = jest.fn() jest.unstable_mockModule('../../../lib/command/util/scenes-util.js', () => ({ @@ -43,7 +49,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/schema.test.ts b/src/__tests__/commands/schema.test.ts index b617a16c..d2387ff7 100644 --- a/src/__tests__/commands/schema.test.ts +++ b/src/__tests__/commands/schema.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { SchemaApp, SchemaEndpoint, SmartThingsClient } from '@smartthings/core-sdk' import { CommandArgs } from '../../commands/schema.js' +import type { buildEpilog } from '../../lib/help.js' import type { APIOrganizationCommand, apiOrganizationCommand, @@ -15,13 +16,15 @@ import type { AllOrganizationFlags, allOrganizationsBuilder } from '../../lib/co import { TableCommonListOutputProducer } from '../../lib/command/format.js' import { outputItemOrList, outputItemOrListBuilder } from '../../lib/command/listing-io.js' import { getSchemaAppEnsuringOrganization } from '../../lib/command/util/schema-util.js' -import { apiCommandMocks } from '../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../test-lib/builder-mock.js' import { tableGeneratorMock } from '../test-lib/table-mock.js' import { ValueTableFieldDefinition } from '../../lib/table-generator.js' -const { apiDocsURLMock } = apiCommandMocks('../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() @@ -81,7 +84,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/schema/authorize.test.ts b/src/__tests__/commands/schema/authorize.test.ts index 86ba7295..40833f84 100644 --- a/src/__tests__/commands/schema/authorize.test.ts +++ b/src/__tests__/commands/schema/authorize.test.ts @@ -3,9 +3,15 @@ import { jest } from '@jest/globals' import type { ArgumentsCamelCase, Argv } from 'yargs' import type { CommandArgs } from '../../../commands/schema/authorize.js' +import type { buildEpilog } from '../../../lib/help.js' import type { addSchemaPermission } from '../../../lib/aws-util.js' import type { lambdaAuthBuilder } from '../../../lib/command/common-flags.js' -import type { SmartThingsCommand, smartThingsCommand, smartThingsCommandBuilder, SmartThingsCommandFlags } from '../../../lib/command/smartthings-command.js' +import type { + SmartThingsCommand, + smartThingsCommand, + smartThingsCommandBuilder, + SmartThingsCommandFlags, +} from '../../../lib/command/smartthings-command.js' import { buildArgvMock, buildArgvMockStub } from '../../test-lib/builder-mock.js' @@ -14,6 +20,11 @@ jest.unstable_mockModule('../../../lib/aws-util.js', () => ({ addSchemaPermission: addSchemaPermissionMock, })) +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + const lambdaAuthBuilderMock = jest.fn() jest.unstable_mockModule('../../../lib/command/common-flags.js', () => ({ lambdaAuthBuilder: lambdaAuthBuilderMock, @@ -50,6 +61,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/schema/create.test.ts b/src/__tests__/commands/schema/create.test.ts index d1bd7d21..6e2e7598 100644 --- a/src/__tests__/commands/schema/create.test.ts +++ b/src/__tests__/commands/schema/create.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { SchemaAppRequest, SchemaCreateResponse, SchemaEndpoint } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../commands/schema/create.js' +import type { buildEpilog } from '../../../lib/help.js' import { type addSchemaPermission, schemaAWSPrincipal } from '../../../lib/aws-util.js' import type { fatalError } from '../../../lib/util.js' import type { @@ -23,7 +24,6 @@ import type { getSchemaAppCreateFromUser, SchemaAppWithOrganization, } from '../../../lib/command/util/schema-util.js' -import { apiCommandMocks } from '../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../test-lib/builder-mock.js' @@ -33,14 +33,17 @@ jest.unstable_mockModule('../../../lib/aws-util.js', () => ({ schemaAWSPrincipal, })) +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) + const fatalErrorMock = jest.fn() .mockImplementation(() => { throw Error('should exit') }) jest.unstable_mockModule('../../../lib/util.js', () => ({ fatalError: fatalErrorMock, })) -const { apiDocsURLMock } = apiCommandMocks('../../..') - const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() jest.unstable_mockModule('../../../lib/command/api-organization-command.js', () => ({ @@ -105,7 +108,7 @@ test('builder', () => { expect(exampleMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/schema/delete.test.ts b/src/__tests__/commands/schema/delete.test.ts index eeb6aa73..7ed9a1cc 100644 --- a/src/__tests__/commands/schema/delete.test.ts +++ b/src/__tests__/commands/schema/delete.test.ts @@ -5,6 +5,7 @@ import type { ArgumentsCamelCase, Argv } from 'yargs' import type { SchemaEndpoint, SmartThingsClient } from '@smartthings/core-sdk' import type { CommandArgs } from '../../../commands/schema/delete.js' +import type { buildEpilog } from '../../../lib/help.js' import type { APIOrganizationCommand, APIOrganizationCommandFlags, @@ -12,11 +13,13 @@ import type { apiOrganizationCommandBuilder, } from '../../../lib/command/api-organization-command.js' import type { chooseSchemaApp } from '../../../lib/command/util/schema-util.js' -import { apiCommandMocks } from '../../test-lib/api-command-mock.js' import { buildArgvMock } from '../../test-lib/builder-mock.js' -const { apiDocsURLMock } = apiCommandMocks('../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() @@ -55,7 +58,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/commands/schema/update.test.ts b/src/__tests__/commands/schema/update.test.ts index f11d98b4..509cefd9 100644 --- a/src/__tests__/commands/schema/update.test.ts +++ b/src/__tests__/commands/schema/update.test.ts @@ -6,6 +6,7 @@ import { type SchemaApp, type SchemaEndpoint, SuccessStatusValue } from '@smartt import { CommandArgs } from '../../../commands/schema/update.js' import type { addSchemaPermission } from '../../../lib/aws-util.js' +import { buildEpilog } from '../../../lib/help.js' import type { cancelCommand, fatalError } from '../../../lib/util.js' import type { APIOrganizationCommand, @@ -25,7 +26,6 @@ import type { getSchemaAppUpdateFromUser, SchemaAppWithOrganization, } from '../../../lib/command/util/schema-util.js' -import { apiCommandMocks } from '../../test-lib/api-command-mock.js' import { buildArgvMock, buildArgvMockStub } from '../../test-lib/builder-mock.js' import { CLIConfig } from '../../../lib/cli-config.js' @@ -43,7 +43,10 @@ jest.unstable_mockModule('../../../lib/util.js', () => ({ fatalError: fatalErrorMock, })) -const { apiDocsURLMock } = apiCommandMocks('../../..') +const buildEpilogMock = jest.fn() +jest.unstable_mockModule('../../../lib/help.js', () => ({ + buildEpilog: buildEpilogMock, +})) const apiOrganizationCommandMock = jest.fn() const apiOrganizationCommandBuilderMock = jest.fn() @@ -126,7 +129,7 @@ test('builder', () => { expect(positionalMock).toHaveBeenCalledTimes(1) expect(optionMock).toHaveBeenCalledTimes(1) expect(exampleMock).toHaveBeenCalledTimes(1) - expect(apiDocsURLMock).toHaveBeenCalledTimes(1) + expect(buildEpilogMock).toHaveBeenCalledTimes(1) expect(epilogMock).toHaveBeenCalledTimes(1) }) diff --git a/src/__tests__/lib/command/api-command.test.ts b/src/__tests__/lib/command/api-command.test.ts index 16278c59..3fe140c0 100644 --- a/src/__tests__/lib/command/api-command.test.ts +++ b/src/__tests__/lib/command/api-command.test.ts @@ -91,26 +91,10 @@ jest.unstable_mockModule('../../../lib/command/util/st-client-wrapper.js', () => const { apiCommand, apiCommandBuilder, - apiDocsURL, userAgent, } = await import('../../../lib/command/api-command.js') -describe('apiDocsURL', () => { - it('produces URL', () => { - expect(apiDocsURL('getDevice')) - .toBe('For API information, see:\n' + - ' https://developer.smartthings.com/docs/api/public/#operation/getDevice') - }) - - it('joins multiple pages with line breaks', () => { - expect(apiDocsURL('getDevice', 'getDevices')) - .toBe('For API information, see:\n' + - ' https://developer.smartthings.com/docs/api/public/#operation/getDevice\n' + - ' https://developer.smartthings.com/docs/api/public/#operation/getDevices') - }) -}) - test('apiCommandBuilder', () => { const { optionMock, argvMock } = buildArgvMock() smartThingsCommandBuilderMock.mockReturnValueOnce(argvMock) diff --git a/src/__tests__/test-lib/api-command-mock.ts b/src/__tests__/test-lib/api-command-mock.ts index 9e1e359f..db49debe 100644 --- a/src/__tests__/test-lib/api-command-mock.ts +++ b/src/__tests__/test-lib/api-command-mock.ts @@ -6,28 +6,23 @@ import { userAgent, type APICommandFlags, type apiCommand, - type apiDocsURL, } from '../../lib/command/api-command.js' import { buildArgvMockStub, type BuilderFunctionMock } from './builder-mock.js' export const apiCommandMocks = (prefix: string): { - apiDocsURLMock: jest.Mock apiCommandMock: jest.Mock apiCommandBuilderMock: BuilderFunctionMock> } => { - const apiDocsURLMock = jest.fn() const apiCommandBuilderMock = buildArgvMockStub() const apiCommandMock = jest.fn() jest.unstable_mockModule(`${prefix}/lib/command/api-command.js`, () => ({ userAgent, - apiDocsURL: apiDocsURLMock, apiCommandBuilder: apiCommandBuilderMock, apiCommand: apiCommandMock, })) return { - apiDocsURLMock, apiCommandBuilderMock, apiCommandMock, } diff --git a/src/commands/capabilities/create.ts b/src/commands/capabilities/create.ts index 5c470454..85b7b098 100644 --- a/src/commands/capabilities/create.ts +++ b/src/commands/capabilities/create.ts @@ -13,9 +13,17 @@ import { type HttpClientParams, } from '@smartthings/core-sdk' -import { booleanInput, integerInput, numberInput, optionalIntegerInput, optionalNumberInput, optionalStringInput, stringInput } from '../../lib/user-query.js' +import { buildEpilog } from '../../lib/help.js' +import { + booleanInput, + integerInput, + numberInput, + optionalIntegerInput, + optionalNumberInput, + optionalStringInput, + stringInput, +} from '../../lib/user-query.js' import { fatalError } from '../../lib/util.js' -import { apiDocsURL } from '../../lib/command/api-command.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -54,7 +62,7 @@ const builder = (yargs: Argv): Argv => ['$0 capabilities:create --dry-run', 'build JSON for a capability from prompted input'], ['$0 capabilities:create -i my-capability.yaml', 'create a capability defined in "my-capability.yaml'], ]) - .epilog(apiDocsURL('createCapability')) + .epilog(buildEpilog({ command, apiDocs: 'createCapability' })) const logger = log4js.getLogger('cli') diff --git a/src/commands/capabilities/delete.ts b/src/commands/capabilities/delete.ts index 3cb9756e..a8f4222b 100644 --- a/src/commands/capabilities/delete.ts +++ b/src/commands/capabilities/delete.ts @@ -1,6 +1,6 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' -import { apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -27,7 +27,7 @@ const builder = (yargs: Argv): Argv => 'delete the capability with the specified id', ], ]) - .epilog(apiDocsURL('deleteCapability')) + .epilog(buildEpilog({ command, apiDocs: 'deleteCapability' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/capabilities/presentation.ts b/src/commands/capabilities/presentation.ts index deba8e42..ccd60b17 100644 --- a/src/commands/capabilities/presentation.ts +++ b/src/commands/capabilities/presentation.ts @@ -1,6 +1,6 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' -import { apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -58,7 +58,7 @@ export const builder = (yargs: Argv): Argv => ' by running "smartthings capabilities"', ], ]) - .epilog(apiDocsURL('getCapabilityPresentation')) + .epilog(buildEpilog({ command, apiDocs: 'getCapabilityPresentation' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/capabilities/translations/create.ts b/src/commands/capabilities/translations/create.ts index 4212b9fe..5f2328d6 100644 --- a/src/commands/capabilities/translations/create.ts +++ b/src/commands/capabilities/translations/create.ts @@ -2,7 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type CapabilityLocalization } from '@smartthings/core-sdk' -import { apiDocsURL } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -39,7 +39,7 @@ const builder = (yargs: Argv): Argv => 'prompt for a capability and add the translation from "en.yaml" to it', ], ]) - .epilog(apiDocsURL('createCapabilityLocalization')) + .epilog(buildEpilog({ command, apiDocs: 'createCapabilityLocalization' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/capabilities/translations/update.ts b/src/commands/capabilities/translations/update.ts index 124dfa1c..59a2898d 100644 --- a/src/commands/capabilities/translations/update.ts +++ b/src/commands/capabilities/translations/update.ts @@ -1,10 +1,19 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type CapabilityLocalization } from '@smartthings/core-sdk' -import { apiOrganizationCommand, apiOrganizationCommandBuilder, type APIOrganizationCommandFlags } from '../../../lib/command/api-organization-command.js' -import { inputAndOutputItem, inputAndOutputItemBuilder, type InputAndOutputItemFlags } from '../../../lib/command/input-and-output-item.js' + +import { buildEpilog } from '../../../lib/help.js' +import { + apiOrganizationCommand, + apiOrganizationCommandBuilder, + type APIOrganizationCommandFlags, +} from '../../../lib/command/api-organization-command.js' +import { + inputAndOutputItem, + inputAndOutputItemBuilder, + type InputAndOutputItemFlags, +} from '../../../lib/command/input-and-output-item.js' import { capabilityIdBuilder, type CapabilityIdInputFlags } from '../../../lib/command/capability-flags.js' -import { apiDocsURL } from '../../../lib/command/api-command.js' import { chooseCapability } from '../../../lib/command/util/capabilities-choose.js' import { buildTableOutput } from '../../../lib/command/util/capabilities-translations-table.js' @@ -30,7 +39,7 @@ const builder = (yargs: Argv): Argv => 'update the translation defined in sw.yaml for the "cathappy12345.myCapability" capability', ], ]) - .epilog(apiDocsURL('updateCapabilityLocalization')) + .epilog(buildEpilog({ command, apiDocs: 'updateCapabilityLocalization' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/capabilities/translations/upsert.ts b/src/commands/capabilities/translations/upsert.ts index 2498595e..a9fef149 100644 --- a/src/commands/capabilities/translations/upsert.ts +++ b/src/commands/capabilities/translations/upsert.ts @@ -2,7 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type CapabilityLocalization } from '@smartthings/core-sdk' -import { apiDocsURL } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -39,7 +39,7 @@ const builder = (yargs: Argv): Argv => 'create or update the translation defined in en.yaml on the "custom1.outputModulation" capability', ], ]) - .epilog(apiDocsURL('updateCapabilityLocalization', 'createCapabilityLocalization')) + .epilog(buildEpilog({ command, apiDocs: ['updateCapabilityLocalization', 'createCapabilityLocalization'] })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/capabilities/update.ts b/src/commands/capabilities/update.ts index 7473c161..b86280c0 100644 --- a/src/commands/capabilities/update.ts +++ b/src/commands/capabilities/update.ts @@ -2,7 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type Capability, type CapabilityUpdate } from '@smartthings/core-sdk' -import { apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -39,7 +39,7 @@ const builder = (yargs: Argv): Argv => 'update the capability with the given id using the data in "my-capability.json"', ], ]) - .epilog(apiDocsURL('updateCapability')) + .epilog(buildEpilog({ command, apiDocs: 'updateCapability' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/config.ts b/src/commands/config.ts index 0ea11f9e..128d6a1f 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -4,6 +4,7 @@ import yaml from 'js-yaml' import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type Profile } from '../lib/cli-config.js' +import { buildEpilog } from '../lib/help.js' import { type TableFieldDefinition } from '../lib/table-generator.js' import { stringTranslateToId } from '../lib/command/command-util.js' import { type OutputItemOrListFlags, outputItemOrListBuilder } from '../lib/command/listing-io.js' @@ -41,6 +42,7 @@ const builder = (yargs: Argv): Argv => ['$0 config', 'summarize profiles in config file'], ['$0 config my-org-1', 'provide details for profile named "my-org-1"'], ]) + .epilog(buildEpilog({ command })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await smartThingsCommand(argv) diff --git a/src/commands/edge/channels/delete.ts b/src/commands/edge/channels/delete.ts index 52041fa2..a749763a 100644 --- a/src/commands/edge/channels/delete.ts +++ b/src/commands/edge/channels/delete.ts @@ -1,7 +1,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { resetManagedConfigKey } from '../../../lib/cli-config.js' -import { apiCommand, apiCommandBuilder, apiDocsURL, type APICommandFlags } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { chooseChannel } from '../../../lib/command/util/edge/channels-choose.js' @@ -25,7 +26,7 @@ const builder = (yargs: Argv): Argv => 'delete the channel with the specified id', ], ]) - .epilog(apiDocsURL('deleteChannel')) + .epilog(buildEpilog({ command, apiDocs: 'deleteChannel' })) const handler = async (argv: ArgumentsCamelCase): Promise => { diff --git a/src/commands/edge/channels/drivers.ts b/src/commands/edge/channels/drivers.ts index 4a9dc410..09bcd915 100644 --- a/src/commands/edge/channels/drivers.ts +++ b/src/commands/edge/channels/drivers.ts @@ -1,6 +1,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' -import { apiCommand, apiCommandBuilder, apiDocsURL, type APICommandFlags } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { outputList, outputListBuilder, @@ -39,7 +40,7 @@ const builder = (yargs: Argv): Argv => 'display drivers assigned to the specified channel', ], ]) - .epilog(apiDocsURL('getChannelDrivers', 'getDriverChannel')) + .epilog(buildEpilog({ command, apiDocs: ['getChannelDrivers', 'getDriverChannel'] })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/edge/channels/enrollments.ts b/src/commands/edge/channels/enrollments.ts index ae97eb16..cfc7247a 100644 --- a/src/commands/edge/channels/enrollments.ts +++ b/src/commands/edge/channels/enrollments.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import type { EnrolledChannel } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, apiDocsURL, type APICommandFlags } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { outputList, outputListBuilder, @@ -37,7 +38,7 @@ const builder = (yargs: Argv): Argv => 'display channels the specified hub is enrolled in', ], ]) - .epilog(apiDocsURL('listDriverChannels')) + .epilog(buildEpilog({ command, apiDocs: 'listDriverChannels' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/invites/schema.ts b/src/commands/invites/schema.ts index d80d5991..0d9f3b72 100644 --- a/src/commands/invites/schema.ts +++ b/src/commands/invites/schema.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type SmartThingsClient } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, type APICommandFlags, apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../lib/command/api-command.js' import { outputItemOrList, outputItemOrListBuilder, @@ -52,7 +53,7 @@ const builder = (yargs: Argv): Argv => 'list details of specified invitation', ], ]) - .epilog(apiDocsURL('listSchemaAppInvitations')) + .epilog(buildEpilog({ command, apiDocs: 'listSchemaAppInvitations' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/invites/schema/create.ts b/src/commands/invites/schema/create.ts index 8d3f027a..94b1b773 100644 --- a/src/commands/invites/schema/create.ts +++ b/src/commands/invites/schema/create.ts @@ -2,10 +2,10 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type SchemaAppInvitationCreate } from '@smartthings/core-sdk' +import { buildEpilog } from '../../../lib/help.js' import { apiCommand, apiCommandBuilder, - apiDocsURL, type APICommandFlags, } from '../../../lib/command/api-command.js' import { @@ -49,7 +49,7 @@ const builder = (yargs: Argv): Argv => 'create an invitation as defined in invitation.json with the specified schema-app', ], ]) - .epilog(apiDocsURL('createSchemaAppInvite')) + .epilog(buildEpilog({ command, apiDocs: 'createSchemaAppInvite' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/invites/schema/delete.ts b/src/commands/invites/schema/delete.ts index 172f3beb..a1526a4c 100644 --- a/src/commands/invites/schema/delete.ts +++ b/src/commands/invites/schema/delete.ts @@ -1,7 +1,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' +import { buildEpilog } from '../../../lib/help.js' import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' - import { chooseSchemaInvitationFn } from '../../../lib/command/util/schema-invites-choose.js' @@ -34,6 +34,7 @@ const builder = (yargs: Argv): Argv => 'delete the invitation with the specified id', ], ]) + .epilog(buildEpilog({ command })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/locations/rooms/delete.ts b/src/commands/locations/rooms/delete.ts index 80632b71..a6de5676 100644 --- a/src/commands/locations/rooms/delete.ts +++ b/src/commands/locations/rooms/delete.ts @@ -1,10 +1,10 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' +import { buildEpilog } from '../../../lib/help.js' import { type APICommandFlags, apiCommand, apiCommandBuilder, - apiDocsURL, } from '../../../lib/command/api-command.js' import { chooseRoom } from '../../../lib/command/util/rooms-choose.js' @@ -33,7 +33,7 @@ const builder = (yargs: Argv): Argv => 'choose the room to delete from a list of rooms in the specified location', ], ]) - .epilog(apiDocsURL('deleteRoom')) + .epilog(buildEpilog({ command, apiDocs: 'deleteRoom' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/locations/rooms/update.ts b/src/commands/locations/rooms/update.ts index ba0227dc..03c466ed 100644 --- a/src/commands/locations/rooms/update.ts +++ b/src/commands/locations/rooms/update.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type Room, type RoomRequest } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, apiDocsURL, type APICommandFlags } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { type CommonOutputProducer } from '../../../lib/command/format.js' import { inputAndOutputItem, @@ -39,7 +40,7 @@ const builder = (yargs: Argv): Argv => 'update the room with the given id using the data in "my-room.json"', ], ]) - .epilog(apiDocsURL('updateRoom')) + .epilog(buildEpilog({ command, apiDocs: 'updateRoom' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/organizations.ts b/src/commands/organizations.ts index af2910a0..833b752c 100644 --- a/src/commands/organizations.ts +++ b/src/commands/organizations.ts @@ -2,6 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type OrganizationResponse } from '@smartthings/core-sdk' +import { buildEpilog } from '../lib/help.js' import { apiCommand, apiCommandBuilder, @@ -42,6 +43,7 @@ const builder = (yargs: Argv): Argv => 'display details for an organization by name', ], ]) + .epilog(buildEpilog({ command })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/organizations/current.ts b/src/commands/organizations/current.ts index 30641a6f..b889b097 100644 --- a/src/commands/organizations/current.ts +++ b/src/commands/organizations/current.ts @@ -2,6 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type OrganizationResponse } from '@smartthings/core-sdk' +import { buildEpilog } from '../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -35,6 +36,7 @@ export const builder = (yargs: Argv): Argv => 'display the currently active organization for the profile "org2', ], ]) + .epilog(buildEpilog({ command })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/presentation/device-config.ts b/src/commands/presentation/device-config.ts index 437d0a25..e5f64229 100644 --- a/src/commands/presentation/device-config.ts +++ b/src/commands/presentation/device-config.ts @@ -1,6 +1,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' -import { apiCommand, apiCommandBuilder, APICommandFlags, apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' +import { apiCommand, apiCommandBuilder, APICommandFlags } from '../../lib/command/api-command.js' import { outputItem, outputItemBuilder, OutputItemFlags } from '../../lib/command/output-item.js' import { buildTableOutput } from '../../lib/command/util/presentation-device-config-table.js' @@ -34,7 +35,7 @@ const builder = (yargs: Argv): Argv => 'get the device config for the given presentation id', ], ]) - .epilog(apiDocsURL('getDeviceConfiguration')) + .epilog(buildEpilog({ command, apiDocs: 'getDeviceConfiguration' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/presentation/device-config/create.ts b/src/commands/presentation/device-config/create.ts index 30e6919a..8485f243 100644 --- a/src/commands/presentation/device-config/create.ts +++ b/src/commands/presentation/device-config/create.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type PresentationDeviceConfigCreate, type PresentationDeviceConfig } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, type APICommandFlags, apiDocsURL } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { inputAndOutputItem, inputAndOutputItemBuilder, @@ -27,7 +28,7 @@ const builder = (yargs: Argv): Argv => 'create a device config as defined in device-config.json', ], ]) - .epilog(apiDocsURL('createDeviceConfiguration')) + .epilog(buildEpilog({ command, apiDocs: 'createDeviceConfiguration' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/presentation/device-config/generate.ts b/src/commands/presentation/device-config/generate.ts index 112c9597..43193642 100644 --- a/src/commands/presentation/device-config/generate.ts +++ b/src/commands/presentation/device-config/generate.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type PresentationDeviceConfig } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, type APICommandFlags, apiDocsURL } from '../../../lib/command/api-command.js' +import { buildEpilog } from '../../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../../lib/command/api-command.js' import { outputItem, outputItemBuilder, type OutputItemFlags } from '../../../lib/command/output-item.js' import { buildTableOutput } from '../../../lib/command/util/presentation-device-config-table.js' @@ -27,7 +28,7 @@ const builder = (yargs: Argv): Argv => 'generate a device config for the specified device profile', ], ]) - .epilog(apiDocsURL('generateDeviceConfig')) + .epilog(buildEpilog({ command, apiDocs: 'generateDeviceConfig' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiCommand(argv) diff --git a/src/commands/scenes/execute.ts b/src/commands/scenes/execute.ts index c8070670..ed49eff9 100644 --- a/src/commands/scenes/execute.ts +++ b/src/commands/scenes/execute.ts @@ -2,7 +2,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { SuccessStatusValue } from '@smartthings/core-sdk' -import { apiCommand, apiCommandBuilder, APICommandFlags, apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' +import { apiCommand, apiCommandBuilder, type APICommandFlags } from '../../lib/command/api-command.js' import { chooseScene } from '../../lib/command/util/scenes-util.js' @@ -26,7 +27,7 @@ const builder = (yargs: Argv): Argv => 'execute the scene with the specified id', ], ]) - .epilog(apiDocsURL('executeScene')) + .epilog(buildEpilog({ command, apiDocs: 'executeScene' })) const handler = async (argv: ArgumentsCamelCase): Promise => { diff --git a/src/commands/schema.ts b/src/commands/schema.ts index 3dd8c984..1f4ba949 100644 --- a/src/commands/schema.ts +++ b/src/commands/schema.ts @@ -2,7 +2,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type SchemaApp } from '@smartthings/core-sdk' -import { apiDocsURL } from '../lib/command/api-command.js' +import { buildEpilog } from '../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -50,7 +50,7 @@ const builder = (yargs: Argv): Argv => ' app link by id'], ['$0 schema --verbose', 'include ARNs in the output'], ]) - .epilog(apiDocsURL('getAppsByUserToken', 'getAppsByEndpointAppId')) + .epilog(buildEpilog({ command, apiDocs: ['getAppsByUserToken', 'getAppsByEndpointAppId'] })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/schema/authorize.ts b/src/commands/schema/authorize.ts index ef73a4f6..e8145669 100644 --- a/src/commands/schema/authorize.ts +++ b/src/commands/schema/authorize.ts @@ -1,6 +1,7 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { addSchemaPermission } from '../../lib/aws-util.js' +import { buildEpilog } from '../../lib/help.js' import { lambdaAuthBuilder, type LambdaAuthFlags } from '../../lib/command/common-flags.js' import { smartThingsCommand, @@ -28,11 +29,14 @@ const builder = (yargs: Argv): Argv => 'authorize calls to the specified app from SmartThings', ], ]) - .epilog('Note that the example above is the same as running the following with the AWS CLI:\n\n' + - '$ aws lambda add-permission --region us-east-1 \\\n' + - ' --function-name arn:aws:lambda:us-east-1:1234567890:function:your-test-app \\\n' + - ' --statement smartthings --principal 148790070172 --action lambda:InvokeFunction\n\n' + - 'It requires your machine to be configured to run the AWS CLI.') + .epilog(buildEpilog({ + command, + formattedNotes: 'Note that the example above is the same as running the following with the AWS CLI:\n\n' + + '$ aws lambda add-permission --region us-east-1 \\\n' + + ' --function-name arn:aws:lambda:us-east-1:1234567890:function:your-test-app \\\n' + + ' --statement smartthings --principal 148790070172 --action lambda:InvokeFunction\n\n' + + 'This command requires your machine to be configured to run the AWS CLI.', + })) const handler = async (argv: ArgumentsCamelCase): Promise => { await smartThingsCommand(argv) diff --git a/src/commands/schema/create.ts b/src/commands/schema/create.ts index 10be0aa8..210fdc8f 100644 --- a/src/commands/schema/create.ts +++ b/src/commands/schema/create.ts @@ -3,8 +3,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type SchemaCreateResponse } from '@smartthings/core-sdk' import { addSchemaPermission, schemaAWSPrincipal } from '../../lib/aws-util.js' +import { buildEpilog } from '../../lib/help.js' import { fatalError } from '../../lib/util.js' -import { apiDocsURL } from '../../lib/command/api-command.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -52,7 +52,7 @@ const builder = (yargs: Argv): Argv => 'link Schema App to SmartThings with details defined in "schema-app-details.yaml"', ], ]) - .epilog(apiDocsURL('postApps')) + .epilog(buildEpilog({ command, apiDocs: 'postApps' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/schema/delete.ts b/src/commands/schema/delete.ts index b224107a..7ed67c19 100644 --- a/src/commands/schema/delete.ts +++ b/src/commands/schema/delete.ts @@ -1,6 +1,6 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' -import { apiDocsURL } from '../../lib/command/api-command.js' +import { buildEpilog } from '../../lib/help.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -29,7 +29,7 @@ const builder = (yargs: Argv): Argv => 'unlink the Schema App with the specified id', ], ]) - .epilog(apiDocsURL('deleteAppsByEndpointAppId')) + .epilog(buildEpilog({ command, apiDocs: 'deleteAppsByEndpointAppId' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/commands/schema/update.ts b/src/commands/schema/update.ts index f1781930..b053a140 100644 --- a/src/commands/schema/update.ts +++ b/src/commands/schema/update.ts @@ -3,8 +3,8 @@ import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' import { type SchemaAppRequest } from '@smartthings/core-sdk' import { addSchemaPermission } from '../../lib/aws-util.js' +import { buildEpilog } from '../../lib/help.js' import { cancelCommand, fatalError } from '../../lib/util.js' -import { apiDocsURL } from '../../lib/command/api-command.js' import { apiOrganizationCommand, apiOrganizationCommandBuilder, @@ -56,7 +56,7 @@ const builder = (yargs: Argv): Argv => 'update a Schema App link with the definition in the file data.yaml', ], ]) - .epilog(apiDocsURL('putAppsByEndpointAppId')) + .epilog(buildEpilog({ command, apiDocs: 'putAppsByEndpointAppId' })) const handler = async (argv: ArgumentsCamelCase): Promise => { const command = await apiOrganizationCommand(argv) diff --git a/src/lib/command/api-command.ts b/src/lib/command/api-command.ts index e99448a3..3efa8181 100644 --- a/src/lib/command/api-command.ts +++ b/src/lib/command/api-command.ts @@ -12,17 +12,6 @@ import { newBearerTokenAuthenticator, newSmartThingsClient } from './util/st-cli export const userAgent = '@smartthings/cli' -// TODO: BEGIN remove -// In the second phase of this work, we will remove these helper functions in favor of those -// in help.ts. -const toURL = (nameOrURL: string): string => nameOrURL.startsWith('http') - ? nameOrURL - : `https://developer.smartthings.com/docs/api/public/#operation/${nameOrURL}` - -export const apiDocsURL = (...names: string[]): string => 'For API information, see:\n ' + - names.map(name => toURL(name)).join('\n ') -// TODO: END REMOVE - export type APICommandFlags = SmartThingsCommandFlags & { token?: string language?: string