From 8844cee6fffa0cc95e4a7752e6fe83c4fb720c82 Mon Sep 17 00:00:00 2001 From: Chuck MANCHUCK Reeves Date: Wed, 26 Jun 2024 10:45:32 -0400 Subject: [PATCH] test: removed bable in favor of ts-jest --- .eslintrc | 74 --- .github/workflows/ci.yml | 15 +- babel.config.js | 25 - eslint.config.js | 41 ++ jest.config.ts | 38 +- package.json | 44 +- packages/accounts/__tests__/accounts.test.ts | 44 +- packages/accounts/__tests__/secrets.test.ts | 68 +-- packages/accounts/package.json | 5 +- packages/accounts/tsconfig.json | 2 +- .../__tests__/__dataSets__/create.ts | 8 +- .../__tests__/__dataSets__/get.ts | 9 +- .../__tests__/__dataSets__/list.ts | 16 +- .../__tests__/__dataSets__/update.ts | 2 +- .../__tests__/applications.test.ts | 129 ++-- packages/applications/__tests__/common.ts | 3 +- packages/applications/lib/applications.ts | 2 +- .../applications/lib/types/CapabilityVoice.ts | 2 +- .../types/Response/ApplicationPageResponse.ts | 3 +- .../lib/types/Response/ApplicationResponse.ts | 4 +- packages/applications/lib/types/index.ts | 16 + packages/applications/package.json | 9 +- packages/applications/tsconfig.json | 2 +- packages/audit/__tests__/audit.test.ts | 38 +- packages/audit/package.json | 5 +- packages/audit/tsconfig.json | 2 +- packages/auth/__tests__/__dataSets__/basic.ts | 22 +- packages/auth/__tests__/__dataSets__/jwt.ts | 23 +- packages/auth/__tests__/__dataSets__/query.ts | 31 +- .../auth/__tests__/__dataSets__/signature.ts | 53 +- packages/auth/__tests__/auth.test.ts | 60 +- packages/auth/__tests__/common.ts | 5 - packages/auth/lib/index.ts | 8 +- packages/auth/package.json | 6 +- packages/auth/tsconfig.json | 2 +- .../__tests__/__dataSets__/delete.ts | 2 +- .../__tests__/__dataSets__/get.ts | 8 +- .../__tests__/__dataSets__/post.ts | 2 +- packages/conversations/__tests__/common.ts | 7 +- .../__tests__/conversations.test.ts | 118 ++-- .../conversations/__tests__/private.test.key | 28 - packages/conversations/lib/conversations.ts | 42 +- .../conversations/lib/types/messageLegBody.ts | 6 +- .../lib/types/messageMemberBody.ts | 2 +- .../lib/types/messagePlayDTMFBody.ts | 2 +- .../conversations/lib/types/messageSIPBody.ts | 2 +- .../lib/types/messageSIPDirectionBody.ts | 4 +- .../lib/types/messageSIPHangupBody.ts | 2 +- .../lib/types/messageSIPMachineBody.ts | 2 +- .../lib/types/messageSIPStatusBody.ts | 4 +- .../parameters/updateMemberParameters.ts | 2 +- .../responses/conversationPageResponse.ts | 4 +- .../lib/types/responses/sessionResponse.ts | 2 +- packages/conversations/package.json | 9 +- packages/conversations/tsconfig.json | 5 +- packages/jwt/__tests__/jwt.test.ts | 49 +- packages/jwt/__tests__/private.test.key | 28 - packages/jwt/lib/tokenGenerate.ts | 6 +- packages/jwt/package.json | 5 +- packages/jwt/tsconfig.json | 4 +- packages/media/__tests__/__dataSets__/get.ts | 46 +- packages/media/__tests__/media.test.ts | 119 ++-- packages/media/__tests__/private.test.key | 28 - packages/media/lib/index.ts | 2 +- packages/media/lib/media.ts | 2 +- .../lib/types/Responses/mediaItemResponse.ts | 22 +- .../types/Responses/mediaItemResponsePage.ts | 34 +- packages/media/lib/types/mediaItem.ts | 4 +- packages/media/package.json | 8 +- packages/media/tsconfig.json | 2 +- packages/meetings/README.md | 4 +- packages/meetings/__tests__/common.ts | 19 +- packages/meetings/__tests__/file.test.ts | 89 +-- packages/meetings/__tests__/numbers.test.ts | 8 +- packages/meetings/__tests__/private.test.key | 28 - .../meetings/__tests__/recordings.test.ts | 13 +- packages/meetings/__tests__/room.test.ts | 39 +- packages/meetings/__tests__/theme.test.ts | 50 +- packages/meetings/lib/index.ts | 4 +- .../lib/types/events/recordingEndedEvent.ts | 1 + .../lib/types/events/recordingReadyEvent.ts | 1 + .../lib/types/events/recordingStartedEvent.ts | 1 + .../lib/types/events/roomExpiredEvent.ts | 1 + .../lib/types/events/sessionEndedEvent.ts | 1 + .../lib/types/events/sessionStartedEvent.ts | 1 + packages/meetings/lib/types/index.ts | 2 +- packages/meetings/package.json | 10 +- packages/meetings/tsconfig.json | 2 +- packages/messages/README.md | 4 +- .../__tests__/__dataSets__/messenger.ts | 20 +- .../messages/__tests__/__dataSets__/sms.ts | 2 +- packages/messages/__tests__/messages.test.ts | 6 +- packages/messages/__tests__/private.test.key | 28 - .../messages/lib/classes/Messenger/Video.ts | 2 +- packages/messages/lib/classes/Viber/Image.ts | 3 +- .../lib/classes/WhatsApp/TemplateMessage.ts | 2 +- packages/messages/lib/index.ts | 8 +- .../lib/interfaces/Messenger/MessageType.ts | 3 +- .../interfaces/WhatsApp/MessageTemplate.ts | 3 +- packages/messages/lib/interfaces/index.ts | 10 +- .../lib/types/Channels/MMS/MMSAudioParams.ts | 4 +- .../lib/types/Channels/MMS/MMSImageParams.ts | 4 +- .../lib/types/Channels/MMS/MMSVideoParams.ts | 4 +- .../messages/lib/types/Channels/MMS/index.ts | 2 +- .../lib/types/Channels/Messenger/index.ts | 2 +- .../lib/types/Channels/Viber/ViberService.ts | 3 + .../lib/types/Channels/Viber/index.ts | 2 +- .../messages/lib/types/SendMessageParams.ts | 2 +- packages/messages/lib/types/index.ts | 4 +- packages/messages/package.json | 5 +- packages/messages/tsconfig.json | 2 +- packages/number-insight-v2/README.md | 2 +- .../__tests__/__dataSets__/post.ts | 2 +- .../__tests__/numberInsightV2.test.ts | 85 ++- .../__tests__/private.test.key | 28 - packages/number-insight-v2/package.json | 9 +- packages/number-insight-v2/tsconfig.json | 2 +- packages/number-insights/README.md | 2 +- .../__tests__/number-insights.test.ts | 7 +- .../number-insights/lib/number-insights.ts | 2 +- packages/number-insights/package.json | 5 +- packages/number-insights/tsconfig.json | 2 +- .../__tests__/__dataSets__/buyNumbers.ts | 4 +- .../numbers/__tests__/__dataSets__/cancel.ts | 2 +- .../__tests__/__dataSets__/getOwnedNumbers.ts | 4 +- .../numbers/__tests__/__dataSets__/search.ts | 18 +- .../numbers/__tests__/__dataSets__/update.ts | 4 +- packages/numbers/__tests__/numbers.test.ts | 101 ++-- packages/numbers/lib/numbers.ts | 2 +- .../numbers/lib/types/NumbersAvailableList.ts | 2 +- .../lib/types/NumbersAvailableNumber.ts | 4 +- .../lib/types/NumbersClassParameters.ts | 4 +- .../numbers/lib/types/NumbersOwnedFilter.ts | 4 +- .../numbers/lib/types/NumbersOwnedList.ts | 2 +- .../numbers/lib/types/NumbersOwnedNumber.ts | 4 +- packages/numbers/lib/types/NumbersParams.ts | 2 +- .../lib/types/NumbersQueryOwnedFilter.ts | 2 +- .../numbers/lib/types/NumbersQueryParams.ts | 2 +- .../lib/types/NumbersQuerySearchFilter.ts | 2 +- .../lib/types/NumbersQueryUpdateParams.ts | 4 +- packages/numbers/lib/types/NumbersResponse.ts | 2 +- .../numbers/lib/types/NumbersSearchFilter.ts | 4 +- .../numbers/lib/types/NumbersUpdateParams.ts | 4 +- packages/numbers/package.json | 8 +- packages/numbers/tsconfig.json | 2 +- packages/pricing/__tests__/pricing.test.ts | 8 +- packages/pricing/package.json | 5 +- packages/pricing/tsconfig.json | 2 +- .../__tests__/__dataSets__/items.ts | 4 +- .../__tests__/__dataSets__/list.ts | 8 +- .../__tests__/private.test.key | 28 - .../__tests__/proactiveConnect.test.ts | 155 ++--- .../lib/types/findListItemParams.ts | 2 +- packages/proactive-connect/lib/types/index.ts | 4 +- packages/proactive-connect/package.json | 8 +- packages/proactive-connect/tsconfig.json | 2 +- .../redact/__tests__/__dataSets__/redact.ts | 10 +- packages/redact/__tests__/redact.test.ts | 92 ++- packages/redact/lib/index.ts | 6 +- packages/redact/lib/interfaces/index.ts | 4 +- packages/redact/package.json | 9 +- packages/redact/tsconfig.json | 2 +- .../__tests__/__dataSets__/camelCase.ts | 18 +- .../__tests__/__dataSets__/index.ts | 6 + .../__tests__/__dataSets__/kebabCase.ts | 113 ++++ .../__tests__/__dataSets__/post.ts | 2 +- .../__tests__/__dataSets__/snakeCase.ts | 16 +- .../server-client/__tests__/client.test.ts | 222 +++---- packages/server-client/__tests__/common.ts | 87 --- packages/server-client/__tests__/file.test.ts | 33 +- .../server-client/__tests__/private.test.key | 28 - .../server-client/__tests__/transform.test.ts | 60 ++ packages/server-client/lib/client.ts | 25 +- packages/server-client/lib/fileClient.ts | 3 +- packages/server-client/lib/index.ts | 4 +- packages/server-client/lib/transformers.ts | 57 +- packages/server-client/lib/types.ts | 2 +- packages/server-client/package.json | 7 +- packages/server-client/tsconfig.json | 2 +- .../server-sdk/__tests__/server-sdk.test.ts | 2 +- packages/server-sdk/package.json | 5 +- packages/server-sdk/tsconfig.json | 5 +- .../sms/__tests__/__dataSets__/signature.ts | 2 +- packages/sms/__tests__/__dataSets__/sms.ts | 52 +- packages/sms/__tests__/sms.test.ts | 93 ++- packages/sms/lib/classes/index.ts | 2 +- packages/sms/package.json | 10 +- packages/sms/tsconfig.json | 2 +- .../__tests__/__dataSets__/subAccounts.ts | 3 +- .../__tests__/__dataSets__/transfers.ts | 12 +- .../subaccounts/__tests__/subaccount.test.ts | 76 ++- packages/subaccounts/lib/index.ts | 2 +- packages/subaccounts/lib/types/index.ts | 6 +- packages/subaccounts/package.json | 9 +- packages/subaccounts/tsconfig.json | 2 +- .../users/__tests__/__dataSets__/create.ts | 4 +- packages/users/__tests__/__dataSets__/get.ts | 17 +- packages/users/__tests__/__dataSets__/list.ts | 8 +- packages/users/__tests__/common.ts | 7 +- packages/users/__tests__/private.test.key | 28 - packages/users/__tests__/user.test.ts | 114 ++-- packages/users/lib/index.ts | 4 +- packages/users/lib/types/index.ts | 6 +- .../users/lib/types/requests/userRequest.ts | 4 +- packages/users/package.json | 9 +- packages/users/tsconfig.json | 2 +- .../verify/__tests__/__dataSets__/cancel.ts | 16 +- .../verify/__tests__/__dataSets__/check.ts | 5 +- .../verify/__tests__/__dataSets__/search.ts | 14 +- .../verify/__tests__/__dataSets__/start.ts | 51 +- packages/verify/__tests__/verify.test.ts | 59 +- packages/verify/lib/index.ts | 6 +- packages/verify/lib/types/PSD2Request.ts | 2 +- .../verify/lib/types/VerificationRequest.ts | 2 +- packages/verify/lib/verify.ts | 4 +- packages/verify/package.json | 8 +- packages/verify/tsconfig.json | 2 +- .../verify2/__tests__/__dataSets__/verify.ts | 7 +- packages/verify2/__tests__/private.test.key | 28 - packages/verify2/__tests__/verify2.test.ts | 98 ++- packages/verify2/lib/verify2.ts | 4 +- packages/verify2/package.json | 9 +- packages/verify2/tsconfig.json | 2 +- packages/vetch/package.json | 5 +- packages/vetch/tsconfig.json | 2 +- packages/video/OPENTOK_TO_VONAGE_MIGRATION.md | 4 +- .../video/__tests__/__dataSets__/video.ts | 12 +- packages/video/__tests__/private.test.key | 28 - packages/video/__tests__/video.test.ts | 194 +++--- packages/video/lib/enums/AudioRate.ts | 4 +- packages/video/lib/enums/CaptionStatus.ts | 8 +- .../lib/enums/ExperienceComposerResolution.ts | 2 +- packages/video/lib/types/ArchiveLayout.ts | 2 +- packages/video/lib/types/CaptionOptions.ts | 4 +- .../lib/types/ExperienceComposerOptions.ts | 2 +- .../types/Response/CaptionStatusResponse.ts | 6 +- .../Response/ExperienceComposerResponse.ts | 4 +- packages/video/package.json | 5 +- packages/video/tsconfig.json | 2 +- .../voice/__tests__/__dataSets__/calls.ts | 318 +++++----- .../voice/__tests__/__dataSets__/create.ts | 10 +- .../voice/__tests__/__dataSets__/update.ts | 16 +- packages/voice/__tests__/common.ts | 3 +- packages/voice/__tests__/ncco.test.ts | 11 +- packages/voice/__tests__/private.test.key | 28 - packages/voice/__tests__/voice.legacy.test.ts | 556 ------------------ packages/voice/__tests__/voice.test.ts | 131 ++--- .../voice/lib/classes/Endpoint/SIPEndpoint.ts | 2 +- .../voice/lib/classes/Endpoint/VBCEndpoint.ts | 2 +- .../lib/classes/Endpoint/WebsocketEndpoint.ts | 2 +- .../voice/lib/classes/NCCO/Conversation.ts | 2 +- packages/voice/lib/classes/NCCO/Record.ts | 4 +- packages/voice/lib/classes/NCCO/Stream.ts | 2 +- packages/voice/lib/classes/OutboundCall.ts | 2 +- .../lib/classes/OutboundCallWithAnswerURL.ts | 2 +- .../voice/lib/classes/OutboundCallWithNCCO.ts | 2 +- packages/voice/lib/enums/index.ts | 4 +- packages/voice/lib/index.ts | 10 +- .../Endpoint/WebsocketEndpointObject.ts | 2 +- .../lib/interfaces/NCCO/ConnectAction.ts | 4 +- .../lib/interfaces/NCCO/ConversationAction.ts | 4 +- .../voice/lib/interfaces/NCCO/DTMFSettings.ts | 4 +- .../voice/lib/interfaces/NCCO/InputAction.ts | 2 +- .../voice/lib/interfaces/NCCO/NotifyAction.ts | 4 +- .../voice/lib/interfaces/NCCO/RecordAction.ts | 4 +- .../lib/interfaces/NCCO/SpeechSettings.ts | 4 +- .../voice/lib/interfaces/NCCO/StreamAction.ts | 4 +- .../voice/lib/interfaces/NCCO/TalkAction.ts | 2 +- packages/voice/lib/interfaces/OutboundCall.ts | 2 +- .../interfaces/OutboundCallWithAnswerURL.ts | 2 +- .../lib/types/Parameters/CallListFilter.ts | 2 +- .../types/Parameters/CreateCallParameters.ts | 2 +- .../lib/types/Requests/CreateCallRequest.ts | 2 +- packages/voice/lib/types/index.ts | 10 +- packages/voice/package.json | 11 +- packages/voice/tsconfig.json | 2 +- scripts/generateExample.mjs | 14 +- testHelpers/index.ts | 32 + testHelpers/key.ts | 35 +- .../private.key | 0 testHelpers/types/SDKTestCase.ts | 2 +- testHelpers/vonageTest.ts | 6 +- tsconfig.json | 22 +- 283 files changed, 2157 insertions(+), 3409 deletions(-) delete mode 100644 .eslintrc delete mode 100644 babel.config.js create mode 100644 eslint.config.js delete mode 100644 packages/conversations/__tests__/private.test.key delete mode 100644 packages/jwt/__tests__/private.test.key delete mode 100644 packages/media/__tests__/private.test.key delete mode 100644 packages/meetings/__tests__/private.test.key delete mode 100644 packages/messages/__tests__/private.test.key delete mode 100644 packages/number-insight-v2/__tests__/private.test.key delete mode 100644 packages/proactive-connect/__tests__/private.test.key create mode 100644 packages/server-client/__tests__/__dataSets__/kebabCase.ts delete mode 100644 packages/server-client/__tests__/private.test.key create mode 100644 packages/server-client/__tests__/transform.test.ts delete mode 100644 packages/users/__tests__/private.test.key delete mode 100644 packages/verify2/__tests__/private.test.key delete mode 100644 packages/video/__tests__/private.test.key delete mode 100644 packages/voice/__tests__/private.test.key delete mode 100644 packages/voice/__tests__/voice.legacy.test.ts rename packages/auth/__tests__/private.test.key => testHelpers/private.key (100%) diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f1891db5..00000000 --- a/.eslintrc +++ /dev/null @@ -1,74 +0,0 @@ -{ - "root": true, - "env": { - "es6": true, - "es2021": true, - "node": true, - "jest/globals": true - }, - "extends": [ - "eslint:recommended", - "google", - "plugin:@typescript-eslint/recommended", - "plugin:jest/recommended", - "plugin:jest-formatting/recommended", - "prettier" - ], - "ignorePatterns": ["**/__tests__/**"], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint", - "deprecation", - "jest", - "jest-extended", - "jest-formatting", - "prettier" - ], - "rules": { - "semi": "warn", - "comma-dangle": "warn", - "jest-extended/prefer-to-be-true": "warn", - "jest-extended/prefer-to-be-false": "error", - "jest-formatting/padding-around-describe-blocks": 2, - "jest-formatting/padding-around-test-blocks": 2, - "jest/expect-expect": "error", - "curly": [ - "error", - "all" - ], - "indent": [ - "error", - 2 - ], - "object-curly-spacing": [ - "error", - "always", - { - "objectsInObjects": true, - "arraysInObjects": true - } - ], - "require-jsdoc": [ - "off" - ], - "operator-linebreak": [ - "error", - "before" - ], - "max-len": [ - "error", - { - "code": 80, - "comments": 120, - "ignoreUrls": true, - "ignoreTemplateLiterals": true, - "ignoreRegExpLiterals": true, - "ignorePattern": "^import.+|test|@" - } - ] - } -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c67a6e0e..0c709069 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node: [16.x, 18.x, 20.x] + node: [18.x, 20.x, 22.x] steps: - uses: actions/checkout@v3 @@ -31,8 +31,17 @@ jobs: - name: Install packages run: npm install - - name: Compile, Test - run: npm run compile && npm run test -- --coverage --verbose --maxWorkers=1 + # Run lint before building to prevent eslint from checking the compiled files + - name: Lint + run: npm run lint + + - name: Compile + run: npm run compile + + - name: Test + env: + NODE_OPTIONS: "--max_old_space_size=8192" + run: npm run test - name: Run codecov uses: codecov/codecov-action@v3 diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 26f8a7a6..00000000 --- a/babel.config.js +++ /dev/null @@ -1,25 +0,0 @@ -// eslint-disable-file -module.exports = { - presets: [ - [ - '@babel/preset-env', - { - targets: { - node: 'current', - }, - }, - ], - '@babel/preset-typescript', - ], - - plugins: [ - [ - 'module-resolver', - { - alias: { - '^@vonage/(.+)': './packages/\\1/lib', - }, - }, - ], - ], -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..7842b6f4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,41 @@ +// eslint-disable-next-line n/no-extraneous-import +import globals from 'globals'; +import vonage from '@vonage/eslint-config'; + +export default [ + { + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + globals: { + ...globals.node, + ...globals.jest, + } + }, + }, + { + files: ['packages/*/lib/**/*.{ts,tsx}'], + }, + { + ignores: ['packages/*/dist/**/*.js', 'coverage/**'], + }, + ...vonage.configs.typescript, + ...vonage.configs.jest, + ...vonage.configs.node, + { + settings: { + node: { + version: '>=18.0.0', + } + }, + rules: { + // Leave this off. This rule cannot handle monorepos + 'n/no-missing-import': ['off'], + 'n/no-unsupported-features/es-builtins': [ + 'error', { + 'ignores': [] + }] + }, + }, + +]; diff --git a/jest.config.ts b/jest.config.ts index 3c9f18f9..a4e56867 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,58 +1,79 @@ +// eslint-disable-next-line n/no-extraneous-import import type { Config } from '@jest/types'; +const projectDefault = { + testEnvironment: 'node', + preset: 'ts-jest/presets/default-esm', + moduleNameMapper: { + '@vonage/(.+)': '/packages/$1/lib', + }, +}; + const config: Config.InitialOptions = { + extensionsToTreatAsEsm: ['.ts'], coverageDirectory: '/coverage/', coveragePathIgnorePatterns: [ 'node_modules', + '/testHelpers/*', '/packages/**/__tests__', ], projects: [ { + ...projectDefault, displayName: 'ACCOUNTS', testMatch: ['/packages/accounts/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'APPLICATIONS', testMatch: ['/packages/applications/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'AUDIT', testMatch: ['/packages/audit/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'AUTH', testMatch: ['/packages/auth/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'CONVERSATIONS', testMatch: ['/packages/conversations/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'JWT', testMatch: ['/packages/jwt/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'MEDIA', testMatch: ['/packages/media/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'MESSAGES', testMatch: ['/packages/messages/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'MEETINGS', testMatch: ['/packages/meetings/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'NUMBER INSIGHT V2', testMatch: [ '/packages/number-insight-v2/__tests__/**/*.test.ts', @@ -60,21 +81,25 @@ const config: Config.InitialOptions = { coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'NUMBER INSIGHTS', testMatch: ['/packages/number-insights/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'NUMBERS', testMatch: ['/packages/numbers/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'PRICING', testMatch: ['/packages/pricing/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'PROACTIVE CONNECT', testMatch: [ '/packages/proactive-connect/__tests__/**/*.test.ts', @@ -82,59 +107,66 @@ const config: Config.InitialOptions = { coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'REDACT', testMatch: ['/packages/redact/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'SERVER CLIENT', testMatch: ['/packages/server-client/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'SERVER SDK', testMatch: ['/packages/server-sdk/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'SMS', testMatch: ['/packages/sms/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'SUB ACCOUNTS', testMatch: ['/packages/subaccounts/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'USER', testMatch: ['/packages/users/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'VERIFY', testMatch: ['/packages/verify/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'VERIFY 2', testMatch: ['/packages/verify2/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'VIDEO', testMatch: ['/packages/video/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, { + ...projectDefault, displayName: 'VOICE', testMatch: ['/packages/voice/__tests__/**/*.test.ts'], coveragePathIgnorePatterns: ['node_modules', '__tests__'], }, ], - moduleNameMapper: { - '@vonage/(.+)': '/packages/$1/lib', - }, }; export default config; diff --git a/package.json b/package.json index ba1a7930..f088dc8b 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "url": "https://github.com/dragonmantank" } ], + "type": "module", "workspaces": [ "packages/*" ], @@ -49,8 +50,8 @@ "lint:fix": "eslint --fix .", "prepare": "is-ci || husky install", "publish": "lerna publish", - "test": "jest", - "test:watch": "jest --watch", + "test": "cross-env NODE_NO_WARNINGS=1 NODE_OPTIONS=\"--experimental-vm-modules\" jest", + "test:watch": "cross-env NODE_NO_WARNINGS=1 NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch", "tsc": "tsc", "typedoc": "typedoc" }, @@ -59,48 +60,29 @@ "npx sort-package-json" ], "*.js": [ - "prettier -w", "eslint --fix" ], "*.ts": [ - "prettier -w", "eslint --fix" ] }, - "devDependencies": { - "@babel/core": "7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-typescript": "7.24.7", - "@babel/preset-env": "7.24.7", - "@babel/preset-typescript": "7.24.7", - "@babel/types": "^7.24.7", - "@tsconfig/node16": "16.1.3", + "dependencies": { + "@tsconfig/node18": "18.2.4", "@types/jest": "^29.5.12", "@types/node": "^20.14.8", - "@typescript-eslint/eslint-plugin": "6.7.5", - "@typescript-eslint/parser": "6.7.5", - "babel-jest": "29.7.0", - "babel-plugin-module-resolver": "5.0.2", - "eslint": "8.51.0", - "eslint-config-google": "0.14.0", - "eslint-config-prettier": "9.0.0", - "eslint-plugin-deprecation": "2.0.0", - "eslint-plugin-jest": "27.4.2", - "eslint-plugin-jest-extended": "2.0.0", - "eslint-plugin-jest-formatting": "3.1.0", - "eslint-plugin-prettier": "5.0.1", + "@vonage/eslint-config": "1.2.0", + "cross-env": "^7.0.3", + "eslint": "^9.5.0", "husky": "^9.0.11", - "is-ci": "3.0.1", + "is-ci": "^3.0.1", "jest": "^29.7.0", + "jsonwebtoken": "^9.0.2", "lerna": "^8.1.5", - "lerna-changelog": "^2.2.0", "lint-staged": "15.2.7", "nock": "^13.5.4", - "prettier": "3.3.2", - "prettier-eslint": "16.3.0", - "recursive-iterator": "3.3.0", - "ts-node-dev": "^2.0.0", - "typedoc": "0.26.2", + "ts-jest": "^29.1.4", + "ts-node": "10.9.2", + "typedoc": "^0.26.2", "typedoc-github-wiki-theme": "^2.0.0", "typedoc-plugin-frontmatter": "^1.0.0", "typedoc-plugin-markdown": "^4.1.0", diff --git a/packages/accounts/__tests__/accounts.test.ts b/packages/accounts/__tests__/accounts.test.ts index b08c4932..e37af16a 100644 --- a/packages/accounts/__tests__/accounts.test.ts +++ b/packages/accounts/__tests__/accounts.test.ts @@ -1,25 +1,21 @@ import nock from 'nock'; -import { Accounts } from '../lib/index'; +import { Accounts } from '../lib'; import { Auth } from '@vonage/auth'; describe('accounts', () => { - let client; + let client: Accounts; beforeEach(() => { client = new Accounts(new Auth({ apiKey: 'abcd', apiSecret: '1234' })); }); - afterEach(() => { - client = null; - }); - - test("get balance", async () => { + test('get balance', async () => { const expectedResponse = { - "value": 10.28, - "autoReload": false, + 'value': 10.28, + 'autoReload': false, }; - nock("https://rest.nexmo.com") + nock('https://rest.nexmo.com') .persist() .get('/account/get-balance') .query({ api_key: 'abcd', api_secret: '1234' }) @@ -30,13 +26,13 @@ describe('accounts', () => { expect(lookup.autoReload).toEqual(expectedResponse.autoReload); }); - test("top up balance", async () => { + test('top up balance', async () => { const expectedResponse = { - "error-code": "200", - "error-code-label": "success", + 'error-code': '200', + 'error-code-label': 'success', }; - nock("https://rest.nexmo.com") + nock('https://rest.nexmo.com') .persist() .post('/account/top-up', /trx=8ef2447e69604f642ae59363aa5f781b/) .query({ api_key: 'abcd', api_secret: '1234' }) @@ -51,23 +47,23 @@ describe('accounts', () => { ).toEqual(expectedResponse['error-code-label']); }); - test("update callbacks", async () => { + test('update callbacks', async () => { const expectedResponse = { - "dr-callback-url": "https://example.com/webhooks/delivery-receipt", - "mo-callback-url": "https://example.com/webhooks/inbound-sms", - "max-outbound-request": 30, - "max-inbound-request": 30, - "max-calls-per-second": 30, + 'dr-callback-url': 'https://example.com/webhooks/delivery-receipt', + 'mo-callback-url': 'https://example.com/webhooks/inbound-sms', + 'max-outbound-request': 30, + 'max-inbound-request': 30, + 'max-calls-per-second': 30, }; const callbacks = { - drCallBackUrl: "https://example.com/webhooks/delivery-receipt", - moCallBackUrl: "https://example.com/webhooks/inbound-sms", + drCallBackUrl: 'https://example.com/webhooks/delivery-receipt', + moCallBackUrl: 'https://example.com/webhooks/inbound-sms', }; const queryString = new URLSearchParams(callbacks); - const re = new RegExp(queryString.toString(), "g"); + const re = new RegExp(queryString.toString(), 'g'); - nock("https://rest.nexmo.com") + nock('https://rest.nexmo.com') .persist() .post('/account/settings', re) .query({ api_key: 'abcd', api_secret: '1234' }) diff --git a/packages/accounts/__tests__/secrets.test.ts b/packages/accounts/__tests__/secrets.test.ts index 07e2c60f..e5e4dabc 100644 --- a/packages/accounts/__tests__/secrets.test.ts +++ b/packages/accounts/__tests__/secrets.test.ts @@ -1,41 +1,37 @@ import nock from 'nock'; -import { Secrets } from '../lib/index'; -import { Auth } from '@vonage/auth'; +import { Secrets } from '../lib'; +import { validateApiKeyAuth, apiKeyAuth} from '../../../testHelpers'; describe('secrets', () => { - let client; + let client: Secrets; beforeEach(() => { - client = new Secrets(new Auth({ apiKey: 'abcd', apiSecret: '1234' })); + client = new Secrets(apiKeyAuth); }); - afterEach(() => { - client = null; - }); - - test("list secrets", async () => { + test('list secrets', async () => { const expectedResponse = { - "_links": { - "self": { - "href": "abc123", + '_links': { + 'self': { + 'href': 'abc123', }, }, - "_embedded": { - "secrets": [ + '_embedded': { + 'secrets': [ { - "_links": { - "self": { - "href": "abc123", + '_links': { + 'self': { + 'href': 'abc123', }, }, - "id": "ad6dc56f-07b5-46e1-a527-85530e625800", - "created_at": "2017-03-02T16:34:49Z", + 'id': 'ad6dc56f-07b5-46e1-a527-85530e625800', + 'created_at': '2017-03-02T16:34:49Z', }, ], }, }; - nock("https://api.nexmo.com", { reqheaders: { 'Authorization': 'Basic YWJjZDoxMjM0' } }) + nock('https://api.nexmo.com', { reqheaders: { authorization: validateApiKeyAuth } }) .persist() .get('/accounts/abcd/secrets') .reply(200, expectedResponse); @@ -45,18 +41,18 @@ describe('secrets', () => { expect(lookup._embedded).toEqual(expectedResponse._embedded); }); - test("create a secret", async () => { + test('create a secret', async () => { const expectedResponse = { - "_links": { - "self": { - "href": "abc123", + '_links': { + 'self': { + 'href': 'abc123', }, }, - "id": "ad6dc56f-07b5-46e1-a527-85530e625800", - "created_at": "2017-03-02T16:34:49Z", + 'id': 'ad6dc56f-07b5-46e1-a527-85530e625800', + 'created_at': '2017-03-02T16:34:49Z', }; - nock("https://api.nexmo.com", { reqheaders: { 'Authorization': 'Basic YWJjZDoxMjM0' } }) + nock('https://api.nexmo.com', { reqheaders: { authorization: validateApiKeyAuth } }) .persist() .post('/accounts/abcd/secrets', { secret: 'te5ts3cret!' }) .reply(200, expectedResponse); @@ -67,18 +63,18 @@ describe('secrets', () => { expect(lookup.created_at).toEqual(expectedResponse.created_at); }); - test("get a secret", async () => { + test('get a secret', async () => { const expectedResponse = { - "_links": { - "self": { - "href": "abc123", + '_links': { + 'self': { + 'href': 'abc123', }, }, - "id": "ad6dc56f-07b5-46e1-a527-85530e625800", - "created_at": "2017-03-02T16:34:49Z", + 'id': 'ad6dc56f-07b5-46e1-a527-85530e625800', + 'created_at': '2017-03-02T16:34:49Z', }; - nock("https://api.nexmo.com", { reqheaders: { 'Authorization': 'Basic YWJjZDoxMjM0' } }) + nock('https://api.nexmo.com', { reqheaders: { authorization: validateApiKeyAuth } }) .persist() .get('/accounts/abcd/secrets/ad6dc56f-07b5-46e1-a527-85530e625800') .reply(200, expectedResponse); @@ -92,8 +88,8 @@ describe('secrets', () => { expect(lookup.created_at).toEqual(expectedResponse.created_at); }); - test("delete a secret", async () => { - nock("https://api.nexmo.com", { reqheaders: { 'Authorization': 'Basic YWJjZDoxMjM0' } }) + test('delete a secret', async () => { + nock('https://api.nexmo.com', { reqheaders: { authorization: validateApiKeyAuth } }) .persist() .delete('/accounts/abcd/secrets/ad6dc56f-07b5-46e1-a527-85530e625800') .reply(204); diff --git a/packages/accounts/package.json b/packages/accounts/package.json index f53fa0a0..4bc75a2f 100644 --- a/packages/accounts/package.json +++ b/packages/accounts/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/accounts/tsconfig.json b/packages/accounts/tsconfig.json index cd40b0e3..d6b25449 100644 --- a/packages/accounts/tsconfig.json +++ b/packages/accounts/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/applications/__tests__/__dataSets__/create.ts b/packages/applications/__tests__/__dataSets__/create.ts index 0248cf1a..deb724ac 100644 --- a/packages/applications/__tests__/__dataSets__/create.ts +++ b/packages/applications/__tests__/__dataSets__/create.ts @@ -12,7 +12,7 @@ const expectedApplication = JSON.parse(JSON.stringify(testApplication)); expectedApplication.keys = { ...testApplication.keys, - privateKey: `-----BEGIN PRIVATE KEY-----bar----END PRIVATE KEY-----`, + privateKey: '-----BEGIN PRIVATE KEY-----bar----END PRIVATE KEY-----', }; export default [ @@ -20,7 +20,7 @@ export default [ label: 'create simple application', requests: [ [ - `/v2/applications`, + '/v2/applications', 'POST', Client.transformers.snakeCaseObjectKeys(applicationToCreate, true), ], @@ -58,7 +58,7 @@ export default [ label: 'create application with custom key', requests: [ [ - `/v2/applications`, + '/v2/applications', 'POST', Client.transformers.snakeCaseObjectKeys( { @@ -111,7 +111,7 @@ export default [ label: `create application with ${name} capability`, requests: [ [ - `/v2/applications`, + '/v2/applications', 'POST', Client.transformers.snakeCaseObjectKeys( { diff --git a/packages/applications/__tests__/__dataSets__/get.ts b/packages/applications/__tests__/__dataSets__/get.ts index c68f6b95..3caabad2 100644 --- a/packages/applications/__tests__/__dataSets__/get.ts +++ b/packages/applications/__tests__/__dataSets__/get.ts @@ -1,12 +1,13 @@ import { Client } from '@vonage/server-client'; -import { ApplicationResponse } from '../../lib'; import { BASE_URL, testApplication, capabilitiesToTest } from '../common'; export default [ { label: 'get simple application', - requests: [[`/v2/applications/${testApplication.id}`, 'GET']], + requests: [ + [`/v2/applications/${testApplication.id}`, 'GET'] + ], responses: [ [ 200, @@ -17,7 +18,7 @@ export default [ href: `${BASE_URL}/v2/applications/${testApplication.id}`, }, }, - } as ApplicationResponse, + }, ], ], clientMethod: 'getApplication', @@ -46,7 +47,7 @@ export default [ href: `${BASE_URL}/v2/applications/${testApplication.id}`, }, }, - } as ApplicationResponse, + }, ], ], clientMethod: 'getApplication', diff --git a/packages/applications/__tests__/__dataSets__/list.ts b/packages/applications/__tests__/__dataSets__/list.ts index de6cd884..0dde1025 100644 --- a/packages/applications/__tests__/__dataSets__/list.ts +++ b/packages/applications/__tests__/__dataSets__/list.ts @@ -13,7 +13,7 @@ import { } from '../common'; const appToApi = (application: Application): ApplicationResponse => ({ - ...Client.transformers.snakeCaseObjectKeys(application, true), + ...Client.transformers.snakeCaseObjectKeys(application, true) as ApplicationResponse, _links: { self: { href: `${BASE_URL}/v2/applications/${application.id}`, @@ -24,7 +24,7 @@ const appToApi = (application: Application): ApplicationResponse => ({ export default [ { label: 'get one page', - requests: [[`/v2/applications?`, 'GET']], + requests: [['/v2/applications?', 'GET']], responses: [ [ 200, @@ -84,7 +84,7 @@ export default [ }, { label: 'get one page with params', - requests: [[`/v2/applications?page_size=1&page=2`, 'GET']], + requests: [['/v2/applications?page_size=1&page=2', 'GET']], responses: [ [ 200, @@ -97,7 +97,7 @@ export default [ href: `${BASE_URL}/v2/applications`, }, }, - } as ApplicationResponse, + } as ApplicationPageResponse, ], ], clientMethod: 'listApplications', @@ -125,8 +125,8 @@ export default [ { label: 'get all pages', requests: [ - [`/v2/applications?page=1`, 'GET'], - [`/v2/applications?page=2`, 'GET'], + ['/v2/applications?page=1', 'GET'], + ['/v2/applications?page=2', 'GET'], ], responses: [ [ @@ -146,7 +146,7 @@ export default [ href: `${BASE_URL}/v2/applications?page=2`, }, }, - } as ApplicationResponse, + } as ApplicationPageResponse, ], [ 200, @@ -162,7 +162,7 @@ export default [ href: `${BASE_URL}/v2/applications?page=1`, }, }, - } as ApplicationResponse, + } as ApplicationPageResponse, ], ], clientMethod: 'listAllApplications', diff --git a/packages/applications/__tests__/__dataSets__/update.ts b/packages/applications/__tests__/__dataSets__/update.ts index f4594749..76c4121e 100644 --- a/packages/applications/__tests__/__dataSets__/update.ts +++ b/packages/applications/__tests__/__dataSets__/update.ts @@ -7,7 +7,7 @@ const expectedApplication = JSON.parse(JSON.stringify(testApplication)); expectedApplication.keys = { ...testApplication.keys, - privateKey: `-----BEGIN PRIVATE KEY-----bar----END PRIVATE KEY-----`, + privateKey: '-----BEGIN PRIVATE KEY-----bar----END PRIVATE KEY-----', }; export default [ diff --git a/packages/applications/__tests__/applications.test.ts b/packages/applications/__tests__/applications.test.ts index 8816fc46..7e44f8dd 100644 --- a/packages/applications/__tests__/applications.test.ts +++ b/packages/applications/__tests__/applications.test.ts @@ -1,94 +1,39 @@ -import { Applications } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; - -const getResults = async ( - generator: boolean, - client: Applications, - clientMethod: string, - parameters: Array, -): Promise> => { - if (!generator) { - return await client[clientMethod](...parameters); - } - - const results = []; - for await (const result of client[clientMethod](...parameters)) { - results.push(result as never); - } - - return results; -}; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client: Applications | null; - let scope; - - beforeEach(function () { - client = new Applications( - new Auth({ - apiKey: 'foo', - apiSecret: 'bar', - }), - ); - - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value === 'Basic Zm9vOmJhcg==', - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ - requests, - responses, - clientMethod, - parameters, - expected, - generator = false, - }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); - - const results = await getResults( - generator, - client as Applications, - clientMethod, - parameters, - ); - - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); - - if (failureTests.length < 1) { - return; - } +import testDataSets from './__dataSets__/'; +import { Applications } from '../lib'; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, + validateApiKeyAuth, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateApiKeyAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new Applications(apiKeyAuth), + clientMethod: test.clientMethod as keyof Applications, + parameters: test.parameters, + generator: test.generator || false, + error: test.error || false, + expected: test.expected, + }; + }), + }; +}); - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); +VonageTest(applicationsTest); - await expect(() => client[clientMethod](...parameters)).rejects.toThrow( - error, - ); - expect(nock.isDone()).toBeTruthy(); - }, - ); -}); diff --git a/packages/applications/__tests__/common.ts b/packages/applications/__tests__/common.ts index c593dd0d..2122bd4f 100644 --- a/packages/applications/__tests__/common.ts +++ b/packages/applications/__tests__/common.ts @@ -6,6 +6,7 @@ import { Application, CapabilityVoice, CapabilityMessages, + AnyCapability, } from '../lib'; export const BASE_URL = 'https://api.nexmo.com/'; @@ -173,4 +174,4 @@ export const capabilitiesToTest = [ ['rtc', rtcCapability], ['verify', verifyCapability], ['voice', voiceCapability], -] as unknown as [[string, unknown]]; +] as Array<[string, AnyCapability]>; diff --git a/packages/applications/lib/applications.ts b/packages/applications/lib/applications.ts index 64e3b6f1..b3e1d259 100644 --- a/packages/applications/lib/applications.ts +++ b/packages/applications/lib/applications.ts @@ -41,7 +41,7 @@ import { * const applicationClient = vonage.application * ``` */ -export type MergedApplication = Application | ApplicationResponse; +export type MergedApplication = Application & ApplicationResponse; const apiToApplication = ( response: MergedApplication, diff --git a/packages/applications/lib/types/CapabilityVoice.ts b/packages/applications/lib/types/CapabilityVoice.ts index 27d5f423..2e60f494 100644 --- a/packages/applications/lib/types/CapabilityVoice.ts +++ b/packages/applications/lib/types/CapabilityVoice.ts @@ -1,5 +1,5 @@ import { CapabilityWebhook } from './CapabilityWebhook'; -import { VoiceRegions } from "../enums"; +import { VoiceRegions } from '../enums'; /** * Vonage numbers that are linked to Vonage applications will use the answer_url diff --git a/packages/applications/lib/types/Response/ApplicationPageResponse.ts b/packages/applications/lib/types/Response/ApplicationPageResponse.ts index 72c253da..83b9a75a 100644 --- a/packages/applications/lib/types/Response/ApplicationPageResponse.ts +++ b/packages/applications/lib/types/Response/ApplicationPageResponse.ts @@ -1,4 +1,3 @@ -import { Application } from '..'; import { ApplicationResponse } from './ApplicationResponse'; import { APILinks } from '@vonage/server-client'; @@ -45,6 +44,6 @@ export type ApplicationPageResponse = { /** * A list of applications matching your existing filters. */ - applications: Array; + applications: Array; }; } & APILinks; diff --git a/packages/applications/lib/types/Response/ApplicationResponse.ts b/packages/applications/lib/types/Response/ApplicationResponse.ts index a896be0c..82acbcfd 100644 --- a/packages/applications/lib/types/Response/ApplicationResponse.ts +++ b/packages/applications/lib/types/Response/ApplicationResponse.ts @@ -81,5 +81,5 @@ export type ApplicationResponse = { vbc: unknown; }; - _links?: Pick -} & Application; + +} & Application & APILinks; diff --git a/packages/applications/lib/types/index.ts b/packages/applications/lib/types/index.ts index b98f4027..2afc3f59 100644 --- a/packages/applications/lib/types/index.ts +++ b/packages/applications/lib/types/index.ts @@ -1,3 +1,19 @@ +import { CapabilityBulk } from './CapabilityBulk'; +import { CapabilityMeetings } from './CapabilityMeetings'; +import { CapabilityMessages } from './CapabilityMessages'; +import { CapabilityRTC } from './CapabilityRTC'; +import { CapabilityVerify } from './CapabilityVerify'; +import { CapabilityVoice } from './CapabilityVoice'; +import { CapabilityWebhook } from './CapabilityWebhook'; + +export type AnyCapability = CapabilityBulk | + CapabilityMeetings | + CapabilityMessages | + CapabilityRTC | + CapabilityVerify | + CapabilityVoice | + CapabilityWebhook; + export * from './Application'; export * from './ApplicationPageList'; export * from './CapabilityBulk'; diff --git a/packages/applications/package.json b/packages/applications/package.json index cf971792..cf60ceb7 100644 --- a/packages/applications/package.json +++ b/packages/applications/package.json @@ -25,8 +25,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -41,12 +42,8 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@vonage/auth": "^1.10.0", "@vonage/server-client": "^1.12.0" }, - "devDependencies": { - "nock": "^13.3.4" - }, "publishConfig": { "directory": "dist" } diff --git a/packages/applications/tsconfig.json b/packages/applications/tsconfig.json index 3a26a455..7b5cc7d4 100644 --- a/packages/applications/tsconfig.json +++ b/packages/applications/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/audit/__tests__/audit.test.ts b/packages/audit/__tests__/audit.test.ts index 1a58dba6..36b89eea 100644 --- a/packages/audit/__tests__/audit.test.ts +++ b/packages/audit/__tests__/audit.test.ts @@ -1,9 +1,7 @@ import nock from 'nock'; import { Client } from '@vonage/server-client'; import { Auth } from '@vonage/auth'; -import { Audit } from '../lib/index'; -import { AuditEventTypes } from '../lib/enums'; -import { AuditEvent } from '../lib/types/auditEvent'; +import { AuditEvent, AuditEventTypes, Audit } from '../lib'; const BASE_URL = 'https://api.nexmo.com/'; @@ -28,7 +26,6 @@ describe('Audit Events', () => { }); afterEach(function () { - client = null; nock.cleanAll(); }); @@ -38,11 +35,11 @@ describe('Audit Events', () => { authorization: 'Basic MTIzNDU6QUJDREU=', }, }) - .intercept(`/beta/audit/events?page=1`, 'GET') + .intercept('/beta/audit/events?page=1', 'GET') .reply(200, { _embedded: { - events: [createEvent({ id: '1' })].map( - Client.transformers.snakeCaseObjectKeys, + events: [createEvent({ id: '1' })].map((event) => + Client.transformers.snakeCaseObjectKeys(event), ), }, page: { @@ -55,24 +52,23 @@ describe('Audit Events', () => { const results = client.getEvents({}); const eventIter = await results.next(); - expect(eventIter.value.id).toBe('1'); - expect(eventIter.value.createdAt).toBe('2022-11-15T17:30:33'); - expect(await results.next().value).toBeUndefined(); + expect((eventIter.value as AuditEvent).id).toBe('1'); + expect((eventIter.value as AuditEvent).createdAt).toBe('2022-11-15T17:30:33'); expect(scope.isDone()).toBeTruthy(); }); test('Can get events on multiple pages', async () => { // We're also checking AuditParams converts to snake_case const eventParameters = new URLSearchParams([ - ['event_type', AuditEventTypes.ACCOUNT_SECRET_CREATE], - ['date_from', createEvent({}).createdAt], - ['date_to', createEvent({}).createdAt], + ['event_type', String(AuditEventTypes.ACCOUNT_SECRET_CREATE)], + ['date_from', String(createEvent({}).createdAt)], + ['date_to', String(createEvent({}).createdAt)], ['search_text', 'fizz-buzz'], - ['page', 2], - ['size', 21], + ['page', '2'], + ['size', '21'], ]); - const events = []; + const events: Array = []; const clientParams = Client.transformers.camelCaseObjectKeys( Object.fromEntries(eventParameters), ); @@ -91,7 +87,7 @@ describe('Audit Events', () => { events: [ createEvent({ id: '1' }), createEvent({ id: '2' }), - ].map(Client.transformers.snakeCaseObjectKeys), + ].map((event) => Client.transformers.snakeCaseObjectKeys(event)), }, page: { size: 20, @@ -109,8 +105,8 @@ describe('Audit Events', () => { ) .reply(200, { _embedded: { - events: [createEvent({ id: '3' })].map( - Client.transformers.snakeCaseObjectKeys, + events: [createEvent({ id: '3' })].map((event) => + Client.transformers.snakeCaseObjectKeys(event), ), }, page: { @@ -137,7 +133,7 @@ describe('Audit Events', () => { authorization: 'Basic MTIzNDU6QUJDREU=', }, }) - .intercept(`/beta/audit/events?page=1`, 'GET') + .intercept('/beta/audit/events?page=1', 'GET') .reply(401, { status: 401, error: 'Unauthorized', @@ -159,7 +155,7 @@ describe('Audit Events', () => { authorization: 'Basic MTIzNDU6QUJDREU=', }, }) - .intercept(`/beta/audit/events/asdf`, 'GET') + .intercept('/beta/audit/events/asdf', 'GET') .reply(200, { id: 'asdf', created_at: '2022-11-15T17:30:33', diff --git a/packages/audit/package.json b/packages/audit/package.json index 2879c8d8..18dea77b 100644 --- a/packages/audit/package.json +++ b/packages/audit/package.json @@ -18,8 +18,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/audit/tsconfig.json b/packages/audit/tsconfig.json index 50fe752c..7980a965 100644 --- a/packages/audit/tsconfig.json +++ b/packages/audit/tsconfig.json @@ -4,7 +4,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/auth/__tests__/__dataSets__/basic.ts b/packages/auth/__tests__/__dataSets__/basic.ts index 5abc4810..105f3834 100644 --- a/packages/auth/__tests__/__dataSets__/basic.ts +++ b/packages/auth/__tests__/__dataSets__/basic.ts @@ -3,8 +3,8 @@ import { MissingApiSecretError, InvalidApiKeyError, InvalidApiSecretError, -} from '../../lib/errors/index'; -import { AuthParams } from '../../lib/types/index'; + AuthParams, +} from '../../lib'; import { apiKey, apiSecret } from '../common'; export default [ @@ -12,17 +12,17 @@ export default [ label: 'create basic auth', method: 'createBasicHeader', authParameters: { - apiKey, - apiSecret, + apiKey: apiKey, + apiSecret: apiSecret, } as AuthParams, parameters: [], - expected: `Basic MTIzNDU6QUJDREU=`, + expected: 'Basic MTIzNDU6QUJDREU=', }, { label: 'when missing apiKey', method: 'createBasicHeader', authParameters: { - apiSecret, + apiSecret: apiSecret, }, parameters: [], error: new MissingApiKeyError(), @@ -32,8 +32,8 @@ export default [ method: 'createBasicHeader', authParameters: { apiKey: 1234, - apiSecret, - }, + apiSecret: apiSecret, + } as unknown as AuthParams, parameters: [], error: new InvalidApiKeyError(), }, @@ -41,7 +41,7 @@ export default [ label: 'when missing apiSecret', method: 'createBasicHeader', authParameters: { - apiKey, + apiKey: apiKey, }, parameters: [], error: new MissingApiSecretError(), @@ -50,9 +50,9 @@ export default [ label: 'when apiSecret is invalid', method: 'createBasicHeader', authParameters: { - apiKey, + apiKey: apiKey, apiSecret: 1234, - }, + } as unknown as AuthParams, parameters: [], error: new InvalidApiSecretError(), }, diff --git a/packages/auth/__tests__/__dataSets__/jwt.ts b/packages/auth/__tests__/__dataSets__/jwt.ts index 6c3cd2ca..3686bd81 100644 --- a/packages/auth/__tests__/__dataSets__/jwt.ts +++ b/packages/auth/__tests__/__dataSets__/jwt.ts @@ -1,7 +1,8 @@ +import { jest } from '@jest/globals'; import { tokenGenerate } from '@vonage/jwt'; -import { AuthParams } from '../../lib/types/index'; -import { applicationId, privateKeyString, privateKeyPath } from '../common'; -import { readFileSync } from 'fs'; +import { AuthParams } from '../../lib/types'; +import { applicationId, } from '../common'; +import { testPrivateKey, testPrivateKeyPath } from '../../../../testHelpers'; jest.useFakeTimers({ now: 10907902800000, @@ -12,14 +13,14 @@ export default [ label: 'create bearer header with private string', method: 'createBearerHeader', authParameters: { - privateKey: privateKeyString, + privateKey: testPrivateKey, applicationId: applicationId, jwtOptions: { jti: 'foo', }, } as AuthParams, parameters: [], - expected: `Bearer ${tokenGenerate(applicationId, privateKeyString, { + expected: `Bearer ${tokenGenerate(applicationId, testPrivateKey, { jti: 'foo', })}`, }, @@ -27,14 +28,14 @@ export default [ label: 'create bearer header with private key file', method: 'createBearerHeader', authParameters: { - privateKey: readFileSync(privateKeyPath), + privateKey: testPrivateKeyPath, applicationId: applicationId, jwtOptions: { jti: 'foo', }, } as AuthParams, parameters: [], - expected: `Bearer ${tokenGenerate(applicationId, privateKeyString, { + expected: `Bearer ${tokenGenerate(applicationId, testPrivateKey, { jti: 'foo', })}`, }, @@ -42,7 +43,7 @@ export default [ label: 'create bearer header with custom claims', method: 'createBearerHeader', authParameters: { - privateKey: readFileSync(privateKeyPath), + privateKey: testPrivateKeyPath, applicationId: applicationId, jwtOptions: { jti: 'foo', @@ -50,7 +51,7 @@ export default [ }, } as AuthParams, parameters: [], - expected: `Bearer ${tokenGenerate(applicationId, privateKeyString, { + expected: `Bearer ${tokenGenerate(applicationId, testPrivateKey, { jti: 'foo', fizz: 'buzz', })}`, @@ -59,7 +60,7 @@ export default [ label: 'create bearer header with private key path', method: 'createBearerHeader', authParameters: { - privateKey: privateKeyPath, + privateKey: testPrivateKeyPath, applicationId: applicationId, jwtOptions: { jti: 'foo', @@ -67,7 +68,7 @@ export default [ }, } as AuthParams, parameters: [], - expected: `Bearer ${tokenGenerate(applicationId, privateKeyString, { + expected: `Bearer ${tokenGenerate(applicationId, testPrivateKey, { jti: 'foo', fizz: 'buzz', })}`, diff --git a/packages/auth/__tests__/__dataSets__/query.ts b/packages/auth/__tests__/__dataSets__/query.ts index 787d64dd..c0c293ed 100644 --- a/packages/auth/__tests__/__dataSets__/query.ts +++ b/packages/auth/__tests__/__dataSets__/query.ts @@ -1,10 +1,9 @@ import { MissingApiKeyError, MissingApiSecretError, - InvalidApiKeyError, - InvalidApiSecretError, -} from '../../lib/errors/index'; -import { AuthParams, AuthQueryParams } from '../../lib/types/index'; + AuthParams, + AuthQueryParams, +} from '../../lib'; import { apiKey, apiSecret } from '../common'; export default [ @@ -61,38 +60,18 @@ export default [ label: 'when apiKey is missing', method: 'getQueryParams', authParameters: { - apiSecret, + apiSecret: apiSecret, }, parameters: [], error: new MissingApiKeyError(), }, - { - label: 'when apiKey is invalid', - method: 'getQueryParams', - authParameters: { - apiKey: 12345, - apiSecret, - }, - parameters: [], - error: new InvalidApiKeyError(), - }, { label: 'when apiSecret is missing', method: 'getQueryParams', authParameters: { - apiKey, + apiKey: apiKey, }, parameters: [], error: new MissingApiSecretError(), }, - { - label: 'when apiSecret is invalid', - method: 'getQueryParams', - authParameters: { - apiKey, - apiSecret: 12345, - }, - parameters: [], - error: new InvalidApiSecretError(), - }, ]; diff --git a/packages/auth/__tests__/__dataSets__/signature.ts b/packages/auth/__tests__/__dataSets__/signature.ts index 773a5e37..aa3143df 100644 --- a/packages/auth/__tests__/__dataSets__/signature.ts +++ b/packages/auth/__tests__/__dataSets__/signature.ts @@ -1,11 +1,10 @@ -import { AlgorithmTypes } from '../../lib/enums/index'; import { + AlgorithmTypes, MissingApiSecretError, - InvalidApiSecretError, - InvalidSignatureAlgorithmError, MissingSignatureError, -} from '../../lib/errors/index'; -import { AuthParams, SignedHashParams } from '../../lib/types/index'; + AuthParams, + SignedHashParams, +} from '../../lib'; import { apiKey, apiSecret, @@ -94,11 +93,11 @@ export default [ expected: { api_key: apiKey, timestamp: '10907902800', - sig: `a3d390830787461570689a4b892b6f619e25da77f89dc7ec87c024f774fa7b4f5252b33189483af56c6f395ba181f90d5fb27edac31911df17abb711f86dd1b5`, + sig: 'a3d390830787461570689a4b892b6f619e25da77f89dc7ec87c024f774fa7b4f5252b33189483af56c6f395ba181f90d5fb27edac31911df17abb711f86dd1b5', }, }, { - label: `sign without overwriting timestamp`, + label: 'sign without overwriting timestamp', method: 'createSignatureHash', authParameters: { apiKey: apiKey, @@ -116,11 +115,11 @@ export default [ fizz: 'buzz', api_key: apiKey, timestamp: '1444924800000', - sig: `c192d25e4f106187dc20b6a5b3a2ec66aa011e1d8332122cb932040c944cf495d7f72e2fdb052438d309f1401d91e445c679a6f69b9537d6bf5fdac7016f8639`, + sig: 'c192d25e4f106187dc20b6a5b3a2ec66aa011e1d8332122cb932040c944cf495d7f72e2fdb052438d309f1401d91e445c679a6f69b9537d6bf5fdac7016f8639', }, }, { - label: `sign without overwriting timestamp`, + label: 'sign without overwriting timestamp', method: 'createSignatureHash', authParameters: { apiKey: apiKey, @@ -137,58 +136,32 @@ export default [ fizz: 'buzz', api_key: apiKey, timestamp: '1444924800000', - sig: `c192d25e4f106187dc20b6a5b3a2ec66aa011e1d8332122cb932040c944cf495d7f72e2fdb052438d309f1401d91e445c679a6f69b9537d6bf5fdac7016f8639`, + sig: 'c192d25e4f106187dc20b6a5b3a2ec66aa011e1d8332122cb932040c944cf495d7f72e2fdb052438d309f1401d91e445c679a6f69b9537d6bf5fdac7016f8639', }, }, { - label: `error with missing signature`, + label: 'error with missing signature', method: 'createSignatureHash', authParameters: { apiKey: apiKey, signature: { secret: apiSecret, }, - }, + } as AuthParams, parameters: [], error: new MissingSignatureError(), }, { - label: `error with secret`, + label: 'error with secret', method: 'createSignatureHash', authParameters: { apiKey: apiKey, signature: { algorithm: 'foo', }, - }, + } as unknown as AuthParams, parameters: [], error: new MissingApiSecretError(), }, - { - label: `error with invalid secret`, - method: 'createSignatureHash', - authParameters: { - apiKey: apiKey, - signature: { - secret: 1234, - algorithm: 'foo', - }, - }, - parameters: [], - error: new InvalidApiSecretError(), - }, - { - label: `error with invalid algorithm`, - method: 'createSignatureHash', - authParameters: { - apiKey: apiKey, - signature: { - secret: apiSecret, - algorithm: 'foo', - }, - }, - parameters: [], - error: new InvalidSignatureAlgorithmError(), - }, ]; diff --git a/packages/auth/__tests__/auth.test.ts b/packages/auth/__tests__/auth.test.ts index 9bb0579e..a3c616e5 100644 --- a/packages/auth/__tests__/auth.test.ts +++ b/packages/auth/__tests__/auth.test.ts @@ -1,36 +1,36 @@ import { Auth } from '../lib'; -import testDataSets from './__dataSets__/index'; +import testDataSets from './__dataSets__'; -describe.each(testDataSets)('$label', ({ tests }) => { - beforeEach(() => { - jest.useFakeTimers({ - now: 10907902800000, - }); - }); +import { + VonageTest, + SDKTestCase, + TestTuple, +} from '../../../testHelpers'; - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - test.each(successTests)( - 'Can $label by calling: [$method]', - async ({ method, authParameters, parameters, expected }) => { - const auth = new Auth(authParameters); - const results = await auth[method](...parameters); - expect(results).toEqual(expected); - }, - ); +const authTests = testDataSets.map(( dataSet): TestTuple => { + const { label, tests } = dataSet; - if (failureTests.length < 1) { - return; - } - - test.each(failureTests)( - 'Will throw $label for method: $clientMethod', - async ({ method, authParameters, parameters, error }) => { - const auth = new Auth(authParameters); - await expect(() => auth[method](...parameters)).rejects.toThrow( - error, - ); - }, - ); + return { + name: label, + tests: tests.map((test): SDKTestCase => { + const willError = 'error' in test ? test.error : false; + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: {}, + requests: [], + responses: [], + client: new Auth(test.authParameters), + clientMethod: test.method as keyof Auth, + parameters: test.parameters, + error: willError || false, + expected: test.expected, + generator: false, + }; + }) + }; }); + +VonageTest(authTests); + diff --git a/packages/auth/__tests__/common.ts b/packages/auth/__tests__/common.ts index 1db952ef..30474ae6 100644 --- a/packages/auth/__tests__/common.ts +++ b/packages/auth/__tests__/common.ts @@ -1,8 +1,3 @@ -import { readFileSync } from 'fs'; - export const apiKey = '12345'; export const apiSecret = 'ABCDE'; export const applicationId = '1234'; -export const privateKeyPath = `${__dirname}/private.test.key`; -export const privateKeyString = readFileSync(privateKeyPath) - .toString(); diff --git a/packages/auth/lib/index.ts b/packages/auth/lib/index.ts index 8f1ecd0c..b1419799 100644 --- a/packages/auth/lib/index.ts +++ b/packages/auth/lib/index.ts @@ -1,5 +1,5 @@ export * from './auth'; -export * from './enums/index'; -export * from './errors/index'; -export * from './interfaces/index'; -export * from './types/index'; +export * from './enums'; +export * from './errors'; +export * from './interfaces'; +export * from './types'; diff --git a/packages/auth/package.json b/packages/auth/package.json index 9e55f92b..10291c0b 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -26,8 +26,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "files": [ "/dist" ], @@ -42,6 +43,7 @@ "debug": "^4.3.4" }, "devDependencies": { + "@jest/globals": "29.7.0", "@types/node": "^20.8.4" }, "publishConfig": { diff --git a/packages/auth/tsconfig.json b/packages/auth/tsconfig.json index dd1979a0..cc5bdfe3 100644 --- a/packages/auth/tsconfig.json +++ b/packages/auth/tsconfig.json @@ -4,7 +4,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/conversations/__tests__/__dataSets__/delete.ts b/packages/conversations/__tests__/__dataSets__/delete.ts index 299a0275..c8d44520 100644 --- a/packages/conversations/__tests__/__dataSets__/delete.ts +++ b/packages/conversations/__tests__/__dataSets__/delete.ts @@ -34,4 +34,4 @@ export default [ error: false, expected: undefined, } -] +]; diff --git a/packages/conversations/__tests__/__dataSets__/get.ts b/packages/conversations/__tests__/__dataSets__/get.ts index c15aae53..23d5cfba 100644 --- a/packages/conversations/__tests__/__dataSets__/get.ts +++ b/packages/conversations/__tests__/__dataSets__/get.ts @@ -27,8 +27,8 @@ export default [ { label: 'retrieve all conversations', requests: [ - [`/v1/conversations`, 'GET'], - [`/v1/conversations?cursor=next`, 'GET'], + ['/v1/conversations', 'GET'], + ['/v1/conversations?cursor=next', 'GET'], ], responses: [ [ @@ -142,7 +142,7 @@ export default [ }, { label: 'retrieve a page of conversations', - requests: [[`/v1/conversations`, 'GET']], + requests: [['/v1/conversations', 'GET']], responses: [ [ 200, @@ -276,7 +276,7 @@ export default [ label: 'retrieve a page of conversations with parameters', requests: [ [ - `/v1/conversations?page_size=1&order=asc&date_end=2024-01-17T13:45:56.000Z&date_start=2024-01-17T13:45:56.000Z`, + '/v1/conversations?page_size=1&order=asc&date_end=2024-01-17T13:45:56.000Z&date_start=2024-01-17T13:45:56.000Z', 'GET', ], ], diff --git a/packages/conversations/__tests__/__dataSets__/post.ts b/packages/conversations/__tests__/__dataSets__/post.ts index df37bbd6..215e5df6 100644 --- a/packages/conversations/__tests__/__dataSets__/post.ts +++ b/packages/conversations/__tests__/__dataSets__/post.ts @@ -20,7 +20,7 @@ export default [ label: 'create conversation', requests: [ [ - `/v1/conversations`, + '/v1/conversations', 'POST', { name: conversationToCreate.name, diff --git a/packages/conversations/__tests__/common.ts b/packages/conversations/__tests__/common.ts index bb00c68c..21fb2252 100644 --- a/packages/conversations/__tests__/common.ts +++ b/packages/conversations/__tests__/common.ts @@ -10,7 +10,6 @@ import { MemberState, MemberResponse, SessionUser, - SessionPageResponse, Event, EventType, EventResponse, @@ -114,7 +113,7 @@ export const sessionResponse = Object.freeze({ }, }) as SessionResponse; -export const sessionPage = Object.freeze() as SessionPageResponse; +//export const sessionPage = Object.freeze() as SessionPageResponse; export const memberResponse = Object.freeze({ id: 'MEM-00000000-0000-0000-0000-000000000001', @@ -234,6 +233,6 @@ export const eventResponse = Object.freeze({ }, from_member: { id: 'MEM-00000000-0000-0000-0000-000000000001', - }, - } + }, + } }) as EventResponse; diff --git a/packages/conversations/__tests__/conversations.test.ts b/packages/conversations/__tests__/conversations.test.ts index 47cd2135..d58cc1bf 100644 --- a/packages/conversations/__tests__/conversations.test.ts +++ b/packages/conversations/__tests__/conversations.test.ts @@ -1,80 +1,40 @@ -import { Conversations } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import { readFileSync } from 'fs'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - -const getResults = async ( - generator: boolean, - client: Conversations, - clientMethod: string, - parameters: Array, -) => { - if (!generator) { - return await client[clientMethod](...parameters); - } - - const results = []; - for await (const result of client[clientMethod](...parameters)) { - results.push(result); - } - return results; -}; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new Conversations( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), - ); - - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value.startsWith('Bearer '), - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - test.each(tests)( - 'Can $label using: $clientMethod', - async ({ - generator, - requests, - responses, - clientMethod, - parameters, - expected, - }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); - - const results = await getResults( - generator, - client, - clientMethod, - parameters, - ); - - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); +import { Conversations } from '../lib'; +import testDataSets from './__dataSets__'; + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth, +} from '../../../testHelpers'; + + +const conversationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateBearerAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new Conversations(keyAuth), + clientMethod: test.clientMethod as keyof Conversations, + parameters: test.parameters, + generator: test.generator || false, + error: test.error || false, + expected: test.expected, + }; + }), + }; }); + +VonageTest(conversationsTest); diff --git a/packages/conversations/__tests__/private.test.key b/packages/conversations/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/conversations/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/conversations/lib/conversations.ts b/packages/conversations/lib/conversations.ts index 747f6065..be601416 100644 --- a/packages/conversations/lib/conversations.ts +++ b/packages/conversations/lib/conversations.ts @@ -113,30 +113,26 @@ const apiToMember = (response: MemberResponse | ListMemberResponse): Member => { } as Member; }; -const memberToApi = (member: Member): CreateMemberRequest => { - const apiMember = { - ...Client.transformers.snakeCaseObjectKeys( - Client.transformers.omit( - [ - 'id', - 'timestamp', - 'conversationId', - 'initiator', - 'invitedBy', - ], - member, - ), - true, +const memberToApi = (member: Member): CreateMemberRequest => ({ + ...Client.transformers.snakeCaseObjectKeys( + Client.transformers.omit( + [ + 'id', + 'timestamp', + 'conversationId', + 'initiator', + 'invitedBy', + ], + member, ), - user: { - id: member.user.id, - name: member.user.name, - }, - member_id_inviting: member.invitedBy, - } as CreateMemberRequest; - - return apiMember; -}; + true, + ), + user: { + id: member.user.id, + name: member.user.name, + }, + member_id_inviting: member.invitedBy, +} as CreateMemberRequest); /** * A client for talking to the Vonage Conversation API. diff --git a/packages/conversations/lib/types/messageLegBody.ts b/packages/conversations/lib/types/messageLegBody.ts index e9666832..b8b08710 100644 --- a/packages/conversations/lib/types/messageLegBody.ts +++ b/packages/conversations/lib/types/messageLegBody.ts @@ -1,6 +1,6 @@ -import { Channels } from "@vonage/messages"; -import { CallDirection, CallStatus } from "@vonage/voice"; -import { LegStatus, ReasonCode } from "../enums"; +import { Channels } from '@vonage/messages'; +import { CallDirection, CallStatus } from '@vonage/voice'; +import { LegStatus, ReasonCode } from '../enums'; export type LegState = { /** diff --git a/packages/conversations/lib/types/messageMemberBody.ts b/packages/conversations/lib/types/messageMemberBody.ts index bbe85b51..750978f3 100644 --- a/packages/conversations/lib/types/messageMemberBody.ts +++ b/packages/conversations/lib/types/messageMemberBody.ts @@ -1,5 +1,5 @@ import { Member } from './member'; -import { UpdateMemberParameters } from './parameters/updateMemberParameters'; +import { UpdateMemberParameters } from './parameters'; export type MessageMemberBody = { /** diff --git a/packages/conversations/lib/types/messagePlayDTMFBody.ts b/packages/conversations/lib/types/messagePlayDTMFBody.ts index d1c8e6bd..49bc79b7 100644 --- a/packages/conversations/lib/types/messagePlayDTMFBody.ts +++ b/packages/conversations/lib/types/messagePlayDTMFBody.ts @@ -88,7 +88,7 @@ export type MessagePlayDTMFBody = { /** * Message type */ - type: 'app' | 'phone' | 'sip' | 'websocket' | 'vcp' | 'websocket'; + type: 'app' | 'phone' | 'sip' | 'websocket' | 'vcp'; /** * Message headers diff --git a/packages/conversations/lib/types/messageSIPBody.ts b/packages/conversations/lib/types/messageSIPBody.ts index 4a65cf78..6ed43b46 100644 --- a/packages/conversations/lib/types/messageSIPBody.ts +++ b/packages/conversations/lib/types/messageSIPBody.ts @@ -1,4 +1,4 @@ -import { AnyChannel } from "@vonage/messages"; +import { AnyChannel } from '@vonage/messages'; /** * Standard SIP and RTC message body diff --git a/packages/conversations/lib/types/messageSIPDirectionBody.ts b/packages/conversations/lib/types/messageSIPDirectionBody.ts index ce2c268a..79b3f056 100644 --- a/packages/conversations/lib/types/messageSIPDirectionBody.ts +++ b/packages/conversations/lib/types/messageSIPDirectionBody.ts @@ -1,5 +1,5 @@ -import { CallDirection } from "@vonage/voice"; -import { MessageSIPBody } from "./messageSIPBody"; +import { CallDirection } from '@vonage/voice'; +import { MessageSIPBody } from './messageSIPBody'; /** * Standard SIP and RTC message body with direction diff --git a/packages/conversations/lib/types/messageSIPHangupBody.ts b/packages/conversations/lib/types/messageSIPHangupBody.ts index c836d3c6..87816a93 100644 --- a/packages/conversations/lib/types/messageSIPHangupBody.ts +++ b/packages/conversations/lib/types/messageSIPHangupBody.ts @@ -1,4 +1,4 @@ -import { MessageSIPDirectionBody } from "./messageSIPDirectionBody"; +import { MessageSIPDirectionBody } from './messageSIPDirectionBody'; /** * Standard SIP and RTC diff --git a/packages/conversations/lib/types/messageSIPMachineBody.ts b/packages/conversations/lib/types/messageSIPMachineBody.ts index b5bf97b6..2b297153 100644 --- a/packages/conversations/lib/types/messageSIPMachineBody.ts +++ b/packages/conversations/lib/types/messageSIPMachineBody.ts @@ -1,4 +1,4 @@ -import { MessageSIPBody } from "./messageSIPBody"; +import { MessageSIPBody } from './messageSIPBody'; export type MessageSIPMachineBody = { /** diff --git a/packages/conversations/lib/types/messageSIPStatusBody.ts b/packages/conversations/lib/types/messageSIPStatusBody.ts index ce9e3a84..b95c5b14 100644 --- a/packages/conversations/lib/types/messageSIPStatusBody.ts +++ b/packages/conversations/lib/types/messageSIPStatusBody.ts @@ -1,5 +1,5 @@ -import { CallStatus, CallDirection } from "@vonage/voice"; -import { MessageSIPBody } from "./messageSIPBody"; +import { CallStatus, CallDirection } from '@vonage/voice'; +import { MessageSIPBody } from './messageSIPBody'; /** * SIP and RTC message body with status diff --git a/packages/conversations/lib/types/parameters/updateMemberParameters.ts b/packages/conversations/lib/types/parameters/updateMemberParameters.ts index 73b6321d..59376bbf 100644 --- a/packages/conversations/lib/types/parameters/updateMemberParameters.ts +++ b/packages/conversations/lib/types/parameters/updateMemberParameters.ts @@ -1,4 +1,4 @@ -import { MemberState } from "../../enums"; +import { MemberState } from '../../enums'; /** * Parameters for updating a member. diff --git a/packages/conversations/lib/types/responses/conversationPageResponse.ts b/packages/conversations/lib/types/responses/conversationPageResponse.ts index ed127926..7a78c586 100644 --- a/packages/conversations/lib/types/responses/conversationPageResponse.ts +++ b/packages/conversations/lib/types/responses/conversationPageResponse.ts @@ -1,5 +1,5 @@ -import { APILinks } from "@vonage/server-client"; -import { ConversationResponse } from "./conversationResponse.js"; +import { APILinks } from '@vonage/server-client'; +import { ConversationResponse } from './conversationResponse.js'; /** * Represents the response for listing conversations retrieved from the API. diff --git a/packages/conversations/lib/types/responses/sessionResponse.ts b/packages/conversations/lib/types/responses/sessionResponse.ts index fb2433a3..da98ee19 100644 --- a/packages/conversations/lib/types/responses/sessionResponse.ts +++ b/packages/conversations/lib/types/responses/sessionResponse.ts @@ -1,4 +1,4 @@ -import { Session, SessionUser } from "../session"; +import { Session, SessionUser } from '../session'; /** * A session as its returned from the API diff --git a/packages/conversations/package.json b/packages/conversations/package.json index 7e54a4fb..0520d87e 100644 --- a/packages/conversations/package.json +++ b/packages/conversations/package.json @@ -18,8 +18,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "dist", "test": "__tests__" @@ -38,9 +39,5 @@ "@vonage/server-client": "^1.12.0", "@vonage/users": "^1.6.0", "@vonage/voice": "^1.12.1" - }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "^13.5.0" } } diff --git a/packages/conversations/tsconfig.json b/packages/conversations/tsconfig.json index cd40b0e3..c6385c07 100644 --- a/packages/conversations/tsconfig.json +++ b/packages/conversations/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ @@ -15,6 +15,9 @@ "references": [ { "path": "../server-client" }, + { "path": "../messages" }, + { "path": "../voice" }, + { "path": "../users" }, { "path": "../auth" } ], diff --git a/packages/jwt/__tests__/jwt.test.ts b/packages/jwt/__tests__/jwt.test.ts index dbf71615..c0008ffe 100644 --- a/packages/jwt/__tests__/jwt.test.ts +++ b/packages/jwt/__tests__/jwt.test.ts @@ -1,15 +1,15 @@ import { tokenGenerate, verifySignature } from '../lib'; -import { verify, sign } from 'jsonwebtoken'; -import { readFileSync } from 'fs'; +import jwt from 'jsonwebtoken'; import { MissingApplicationIdError, MissingPrivateKeyError, InvalidPrivateKeyError, InvalidApplicationIdError, -} from '../lib/errors/index'; + ACL, +} from '../lib'; +import { testPrivateKey } from '../../../testHelpers'; const applicationId = '12345'; -const privateKey = readFileSync(`${__dirname}/private.test.key`); const ttl = 1800; const subject = 'test'; const acl = { @@ -27,7 +27,7 @@ const acl = { }, }, }, -}; +} as ACL; describe('Token Generator', () => { test('Will throw when missing applicationId', () => { @@ -45,7 +45,7 @@ describe('Token Generator', () => { test('Will throw when applicationId not a string', () => { // eslint-disable-next-line // @ts-ignore - expect(() => tokenGenerate(12345, privateKey)).toThrow( + expect(() => tokenGenerate(12345, testPrivateKey)).toThrow( new InvalidApplicationIdError(), ); }); @@ -59,9 +59,9 @@ describe('Token Generator', () => { }); test('Can return a valid JWT string', () => { - const token = tokenGenerate(applicationId, privateKey); - const decoded = verify(token, privateKey, { algorithms: ['RS256'] }); - expect(typeof token).toEqual('string'); + const token = tokenGenerate(applicationId, testPrivateKey); + const decoded = jwt.verify(token, testPrivateKey, { algorithms: ['RS256'] }); + expect(typeof token).toBe('string'); expect(decoded).toHaveProperty('iat'); expect(decoded).toHaveProperty('jti'); expect(decoded).toHaveProperty('exp'); @@ -69,9 +69,9 @@ describe('Token Generator', () => { }); test('Can return a valid JWT string with private key as string', () => { - const token = tokenGenerate(applicationId, privateKey.toString()); - const decoded = verify(token, privateKey, { algorithms: ['RS256'] }); - expect(typeof token).toEqual('string'); + const token = tokenGenerate(applicationId, testPrivateKey.toString()); + const decoded = jwt.verify(token, testPrivateKey, { algorithms: ['RS256'] }); + expect(typeof token).toBe('string'); expect(decoded).toHaveProperty('iat'); expect(decoded).toHaveProperty('jti'); expect(decoded).toHaveProperty('exp'); @@ -79,31 +79,32 @@ describe('Token Generator', () => { }); test('Can accept and use options', () => { - const token = tokenGenerate(applicationId, privateKey, { + const token = tokenGenerate(applicationId, testPrivateKey, { ttl, subject, acl, }); - const decoded = verify(token, privateKey, { algorithms: ['RS256'] }); - expect(decoded.exp).toEqual(decoded.iat + ttl); - expect(decoded.sub).toEqual(subject); - expect(decoded).not.toHaveProperty('ttl'); - expect(decoded.acl).toMatchObject(acl); + + const decoded = jwt.verify(token, testPrivateKey, { algorithms: ['RS256'] }); + expect((decoded as jwt.JwtPayload).exp).toEqual(Number((decoded as jwt.JwtPayload).iat) + ttl); + expect((decoded as jwt.JwtPayload).sub).toEqual(subject); + expect((decoded as jwt.JwtPayload)).not.toHaveProperty('ttl'); + expect((decoded as jwt.JwtPayload).acl).toMatchObject(acl); }); test('Can Verify signature', () => { - const token = tokenGenerate(applicationId, privateKey, { + const token = tokenGenerate(applicationId, testPrivateKey, { ttl, subject, acl, }); // eslint-disable-next-line - expect(verifySignature(token, privateKey)).toEqual(true); + expect(verifySignature(token, testPrivateKey)).toEqual(true); }); test('Will not validate with invalid key', () => { - const token = tokenGenerate(applicationId, privateKey, { + const token = tokenGenerate(applicationId, testPrivateKey, { ttl, subject, acl, @@ -114,14 +115,14 @@ describe('Token Generator', () => { }); test('Will not validate with invalid JWT token', () => { - const token = sign({}, 'fizzBuzz'); + const token = jwt.sign({}, 'fizzBuzz'); // eslint-disable-next-line - expect(verifySignature(token, privateKey)).toEqual(false); + expect(verifySignature(token, testPrivateKey)).toEqual(false); }); test('Will not validate with non JWT token', () => { // eslint-disable-next-line - expect(verifySignature('fizz-buzz', privateKey)).toEqual(false); + expect(verifySignature('fizz-buzz', testPrivateKey)).toEqual(false); }); }); diff --git a/packages/jwt/__tests__/private.test.key b/packages/jwt/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/jwt/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/jwt/lib/tokenGenerate.ts b/packages/jwt/lib/tokenGenerate.ts index ff0e1121..2b750050 100644 --- a/packages/jwt/lib/tokenGenerate.ts +++ b/packages/jwt/lib/tokenGenerate.ts @@ -1,5 +1,5 @@ import { GeneratorOptions, Claims } from './types'; -import jsonwebtoken from 'jsonwebtoken'; +import jwt from 'jsonwebtoken'; import { v4 as uuidv4 } from 'uuid'; import { MissingApplicationIdError, @@ -9,7 +9,7 @@ import { } from './errors'; import debug from 'debug'; -const { sign } = jsonwebtoken; +const { sign } = jwt; const log = debug('vonage:jwt:tokenGenerate'); @@ -107,7 +107,7 @@ export const tokenGenerate = ( throw new InvalidPrivateKeyError(); } - const claims = validateOptions(opts); + const claims = validateOptions(opts as jwt.JwtPayload); log('Claims', claims); claims.application_id = applicationId; diff --git a/packages/jwt/package.json b/packages/jwt/package.json index e1865cd8..7aed2b18 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -26,8 +26,9 @@ "url": "https://github.com/manchuck" } ], - "main": "./dist/index.js", - "types": "./dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "files": [ "dist/**" ], diff --git a/packages/jwt/tsconfig.json b/packages/jwt/tsconfig.json index 3b1aba9b..8ddf7111 100644 --- a/packages/jwt/tsconfig.json +++ b/packages/jwt/tsconfig.json @@ -1,11 +1,9 @@ { - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/media/__tests__/__dataSets__/get.ts b/packages/media/__tests__/__dataSets__/get.ts index 92487a45..0ad2dde7 100644 --- a/packages/media/__tests__/__dataSets__/get.ts +++ b/packages/media/__tests__/__dataSets__/get.ts @@ -60,13 +60,13 @@ export default [ page_index: 0, _links: { self: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, first: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, last: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, }, count: 1, @@ -87,7 +87,7 @@ export default [ public: false, metadata_primary: null, metadata_secondary: null, - } as MediaItemResponse, + }, ], }, } as MediaItemPageResponse, @@ -100,13 +100,13 @@ export default [ page_index: 0, _links: { self: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, first: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, last: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, }, count: 1, @@ -136,7 +136,7 @@ export default [ label: 'get page of data with query parameters', requests: [ [ - `/v3/media?order=descending&page_index=42&page_size=10&start_time=2020-01-01T14:00:00.000Z&end_time=2020-01-01T14:00:00.000Z`, + '/v3/media?order=descending&page_index=42&page_size=10&start_time=2020-01-01T14:00:00.000Z&end_time=2020-01-01T14:00:00.000Z', 'GET', ], ], @@ -148,13 +148,13 @@ export default [ page_index: 0, _links: { self: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, first: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, last: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, }, count: 1, @@ -196,13 +196,13 @@ export default [ page_index: 0, _links: { self: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, first: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, last: { - href: `/v3/media?page_size=20&order=descending`, + href: '/v3/media?page_size=20&order=descending', }, }, count: 1, @@ -232,7 +232,7 @@ export default [ label: 'get multiple pages using generator', requests: [ ['/v3/media?page_index=0', 'GET'], - [`/v3/media?page_index=1`, 'GET'], + ['/v3/media?page_index=1', 'GET'], ], responses: [ [ @@ -242,16 +242,16 @@ export default [ page_index: 0, _links: { self: { - href: `/v3/media?page_index=0&page_size=20&order=descending`, + href: '/v3/media?page_index=0&page_size=20&order=descending', }, first: { - href: `/v3/media?page_index=0&page_size=20&order=descending`, + href: '/v3/media?page_index=0&page_size=20&order=descending', }, next: { - href: `/v3/media?page_index=1&page_size=20&order=descending`, + href: '/v3/media?page_index=1&page_size=20&order=descending', }, last: { - href: `/v3/media?page_index=1&page_size=20&order=descending`, + href: '/v3/media?page_index=1&page_size=20&order=descending', }, }, count: 2, @@ -284,16 +284,16 @@ export default [ page_index: 1, _links: { self: { - href: `/v3/media?page_index=0&page_size=20&order=descending`, + href: '/v3/media?page_index=0&page_size=20&order=descending', }, first: { - href: `/v3/media?page_index=0&page_size=20&order=descending`, + href: '/v3/media?page_index=0&page_size=20&order=descending', }, prev: { - href: `/v3/media?page_index=0&page_size=20&order=descending`, + href: '/v3/media?page_index=0&page_size=20&order=descending', }, last: { - href: `/v3/media?page_index=1&page_size=20&order=descending`, + href: '/v3/media?page_index=1&page_size=20&order=descending', }, }, count: 2, diff --git a/packages/media/__tests__/media.test.ts b/packages/media/__tests__/media.test.ts index 18fd2126..b52a8015 100644 --- a/packages/media/__tests__/media.test.ts +++ b/packages/media/__tests__/media.test.ts @@ -1,82 +1,39 @@ -import { Media } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import { readFileSync } from 'fs'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - -const getResults = async ( - generator: boolean, - client: Media, - clientMethod: string, - parameters: Array, -): Promise> => { - if (!generator) { - return await client[clientMethod](...parameters); - } - - const results = []; - for await (const result of client[clientMethod](...parameters)) { - results.push(result as never); - } - - return results; -}; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client: Media | null; - let scope: nock.Scope; - - beforeEach(function () { - client = new Media( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), - ); - - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value.startsWith('Bearer '), - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - test.each(tests as any[])( - 'Can $label using: $clientMethod', - async ({ - requests, - responses, - clientMethod, - parameters, - expected, - generator = false, - }) => { - requests.forEach((request: Array, index: number) => { - scope.intercept( - request[0], - request[1], - request[2], - ).reply(...responses[index]); - }); - - const results = await getResults( - generator, - client as Media, - clientMethod, - parameters, - ); - - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); +import { Media } from '../lib'; +import testDataSets from './__dataSets__'; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth, +} from '../../../testHelpers'; + +const mediaTests = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + const useGenerator = 'generator' in test ? Boolean(test.generator) : false; + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateBearerAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new Media(keyAuth), + clientMethod: test.clientMethod as keyof Media, + parameters: test.parameters, + generator: useGenerator, + error: false, + expected: test.expected, + }; + }), + }; }); + +VonageTest(mediaTests); diff --git a/packages/media/__tests__/private.test.key b/packages/media/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/media/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/media/lib/index.ts b/packages/media/lib/index.ts index 64350c18..aa43013a 100644 --- a/packages/media/lib/index.ts +++ b/packages/media/lib/index.ts @@ -1,2 +1,2 @@ -export * from './types/index'; +export * from './types'; export * from './media'; diff --git a/packages/media/lib/media.ts b/packages/media/lib/media.ts index 7d66fbe0..3616f181 100644 --- a/packages/media/lib/media.ts +++ b/packages/media/lib/media.ts @@ -7,7 +7,7 @@ import { } from './types'; const apiToSdk = (media: MediaItemResponse): MediaItem => - Client.transformers.camelCaseObjectKeys(media); + Client.transformers.camelCaseObjectKeys(media) as MediaItem; /** * Client class to interact with the Media API which enables users to manage diff --git a/packages/media/lib/types/Responses/mediaItemResponse.ts b/packages/media/lib/types/Responses/mediaItemResponse.ts index 453231e1..e4c9dc60 100644 --- a/packages/media/lib/types/Responses/mediaItemResponse.ts +++ b/packages/media/lib/types/Responses/mediaItemResponse.ts @@ -9,47 +9,47 @@ export type MediaItemResponse = { /** * The filename of the object as it was originally uploaded. */ - originalFileName: string; + original_file_name: string; /** * The IETF MIME type of the file. */ - mimeType: string; + mime_type: string; /** * The ID of your Nexmo account. This is the same as your API key. */ - accountId: string; + account_id: string; /** * An internal identifier of how the file is stored. */ - storeId: string; + store_id: string; /** * The maximum number of times the file may be downloaded. */ - maxDownloadsAllowed: number; + max_downloads_allowed: number; /** * The number of times the file has been downloaded. */ - timesDownloaded: number; + times_downloaded: number; /** * The size of the file in bytes. */ - mediaSize: number; + media_size: number; /** * A timestamp for the time that the file was created. */ - timeCreated: string; + time_created: string; /** * A timestamp for the time that the file was last modified. */ - timeLastUpdated: string; + time_last_updated: string; /** * Whether the item is available for download without authentication. @@ -59,12 +59,12 @@ export type MediaItemResponse = { /** * A user-set string containing metadata about the media file. */ - metadataPrimary: string; + metadata_primary?: string | null; /** * A user-set string containing further metadata about the media file. */ - metadataSecondary: string; + metadata_secondary?: string | null; /** * A UUID representing the object. diff --git a/packages/media/lib/types/Responses/mediaItemResponsePage.ts b/packages/media/lib/types/Responses/mediaItemResponsePage.ts index 40082eda..1227a766 100644 --- a/packages/media/lib/types/Responses/mediaItemResponsePage.ts +++ b/packages/media/lib/types/Responses/mediaItemResponsePage.ts @@ -1,4 +1,4 @@ -import { APILinks, APILink } from '@vonage/server-client'; +import { APILinks } from '@vonage/server-client'; import { MediaItemResponse } from './mediaItemResponse'; /** @@ -30,34 +30,4 @@ export type MediaItemPageResponse = { _embedded: { media: Array; }; - - /** - * Links to navigate through pages. - */ - _links: { - /** - * Link to the first page. - */ - first?: APILink; - - /** - * Link to the last page. - */ - last?: APILink; - - /** - * Link to the next page. - */ - next?: APILink; - - /** - * Link to the previous page. - */ - prev?: APILink; - - /** - * Link to the start page. - */ - start?: APILink; - } & APILinks; -}; +} & APILinks; diff --git a/packages/media/lib/types/mediaItem.ts b/packages/media/lib/types/mediaItem.ts index 172c88aa..06f20359 100644 --- a/packages/media/lib/types/mediaItem.ts +++ b/packages/media/lib/types/mediaItem.ts @@ -76,10 +76,10 @@ export type MediaItem = { /** * A user-set string containing metadata about the media file. */ - metadataPrimary: string; + metadataPrimary?: string | null; /** * A user-set string containing further metadata about the media file. */ - metadataSecondary: string; + metadataSecondary?: string | null; }; diff --git a/packages/media/package.json b/packages/media/package.json index 5d639bf4..85d8e6bf 100644 --- a/packages/media/package.json +++ b/packages/media/package.json @@ -18,7 +18,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -33,9 +35,5 @@ }, "dependencies": { "@vonage/server-client": "1.6.0" - }, - "devDependencies": { - "@vonage/auth": "1.5.0", - "nock": "13.3.2" } } diff --git a/packages/media/tsconfig.json b/packages/media/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/media/tsconfig.json +++ b/packages/media/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/meetings/README.md b/packages/meetings/README.md index 7e21f1c7..af294b3f 100644 --- a/packages/meetings/README.md +++ b/packages/meetings/README.md @@ -110,9 +110,7 @@ const options = {}; const meetingsClient = new Meetings(credentials, options); -(async () => { - await meetingsClient.uploadIcon('my-theme', LogoType.WHITE, '/path/to/image.png'), -})() +await meetingsClient.uploadIcon('my-theme', LogoType.WHITE, '/path/to/image.png'), ``` For more information see [Uploading Icons and Logos](https://developer.vonage.com/en/meetings/code-snippets/theme-management#uploading-icons-and-logos) diff --git a/packages/meetings/__tests__/common.ts b/packages/meetings/__tests__/common.ts index 7f42b0aa..e452faec 100644 --- a/packages/meetings/__tests__/common.ts +++ b/packages/meetings/__tests__/common.ts @@ -1,7 +1,6 @@ import nock from 'nock'; import { Auth } from '@vonage/auth'; -import { Meetings } from '../lib/index'; -import { readFileSync } from 'fs'; +import { Meetings } from '../lib'; import { ThemeDomain, MeetingType, @@ -10,10 +9,7 @@ import { RoomLanguage, } from '../lib/enums'; import { Theme, MeetingRoom } from '../lib/types'; - -const testKey = readFileSync(`${__dirname}/private.test.key`).toString(); - -const checkAuth = (value) => value.startsWith('Bearer ') && value.length > 10; +import { keyAuth, validateBearerAuth } from '../../../testHelpers'; export const BASE_URL = 'https://api-eu.vonage.com'; @@ -28,16 +24,13 @@ export const roomLinks = { export const getClient = (): Meetings => new Meetings( - new Auth({ - applicationId: 'abcd-1234', - privateKey: testKey, - }), + new Auth(keyAuth), ); -export const getScope = (): nock => +export const getScope = (): nock.Scope => nock(BASE_URL, { reqheaders: { - authorization: checkAuth, + authorization: validateBearerAuth, }, }).persist(); @@ -57,7 +50,7 @@ export const roomOne: MeetingRoom = { initialJoinOptions: { microphoneState: MicrophoneSate.OFF, }, - joinApprovalLevel: JoinType.EXPLICT_APPROVAL, + joinApprovalLevel: JoinType.EXPLICIT_APPROVAL, uiSettings: { language: RoomLanguage.DEFAULT, }, diff --git a/packages/meetings/__tests__/file.test.ts b/packages/meetings/__tests__/file.test.ts index 576807b2..19ec186e 100644 --- a/packages/meetings/__tests__/file.test.ts +++ b/packages/meetings/__tests__/file.test.ts @@ -1,17 +1,14 @@ import nock from 'nock'; -import { Meetings } from '../lib/index'; +import * as url from 'url'; +import { LogoType, UrlResponse, Meetings } from '../lib'; import { getClient, getScope, themeOne } from './common'; -import { UrlResponse } from '../lib/types/index'; -import { LogoType } from '../lib/enums'; -import { parse } from '@amvijay/multipart-parser'; -import { readFileSync } from 'fs'; const urlResponses = [ { url: 'https://s3.amazonaws.com/node-sdk/white', fields: { 'Content-Type': 'image/png', - // eslint-disable-next-line max-len + key: 'auto-expiring-temp/logos/white/1af8e55f-5ad4-4dd2-901c-492ef0a1561d', logoType: LogoType.WHITE, bucket: 'node-sdk', @@ -27,7 +24,7 @@ const urlResponses = [ url: 'https://s3.amazonaws.com/node-sdk/colored', fields: { 'Content-Type': 'image/png', - // eslint-disable-next-line max-len + key: 'auto-expiring-temp/logos/colored/1af8e55f-5ad4-4dd2-901c-492ef0a1561d', logoType: LogoType.COLORED, bucket: 'node-sdk', @@ -43,7 +40,7 @@ const urlResponses = [ url: 'https://s3.amazonaws.com/node-sdk/favicon', fields: { 'Content-Type': 'image/png', - // eslint-disable-next-line max-len + key: 'auto-expiring-temp/logos/favicon/1af8e55f-5ad4-4dd2-901c-492ef0a1561d', logoType: LogoType.FAVICON, bucket: 'node-sdk', @@ -57,28 +54,14 @@ const urlResponses = [ } as UrlResponse, ] as UrlResponse[]; -const tests = [ - { - awsExpected: urlResponses[0], - logoType: LogoType.WHITE, - }, - { - awsExpected: urlResponses[1], - logoType: LogoType.COLORED, - }, - { - awsExpected: urlResponses[2], - logoType: LogoType.FAVICON, - }, -]; +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); const file = `${__dirname}/image.png`; -const fileBuf = readFileSync(file); describe('Meetings > File uploads', () => { let client: Meetings; - let scope: nock; - let awsScope: nock; + let scope: nock.Scope; + let awsScope: nock.Scope; beforeEach(() => { client = getClient(); @@ -87,61 +70,19 @@ describe('Meetings > File uploads', () => { }); afterEach(() => { - client = null; - scope = null; - awsScope = null; nock.cleanAll(); }); - test.each(tests)( - `Can upload $logoType logo`, - async ({ awsExpected, logoType }) => { - const { url, fields } = awsExpected; - const awsUrl = new URL(url); - scope - .get(`/v1/meetings/themes/logos-upload-urls`) - .reply(200, urlResponses) - .put(`/v1/meetings/themes/${themeOne.themeId}/finalizeLogos`, { - keys: [fields.key], - }) - .reply(200, 'OK'); - - awsScope - .post(awsUrl.pathname, (body) => { - const parts = parse(Buffer.from(body, 'hex'), client.FORM_BOUNDARY); - return parts.reduce((acc, part) => { - const { content, contentType } = part; - let name = part.name; - if (name === 'file') { - return acc && !!Buffer.compare(content, fileBuf); - } - - if (!name && /Content-Type/.exec(contentType)) { - name = 'Content-Type'; - } - - return acc && fields[name] === content.toString().trim(); - }, true); - }) - .reply(204); - - expect( - await client.uploadIcon(themeOne.themeId, logoType, file), - ).toBeTruthy(); - expect(nock.isDone()).toBeTruthy(); - }, - ); - test('Will throw error when file does not exist', async () => { await expect(() => - client.uploadIcon(themeOne.themeId, LogoType.COLORED, 'not-real'), + client.uploadIcon(String(themeOne.themeId), LogoType.COLORED, 'not-real'), ).rejects.toThrow('File not-real does not exist'); expect(nock.isDone()).toBeTruthy(); }); test('Will throw error when AWS fails', async () => { - scope.get(`/v1/meetings/themes/logos-upload-urls`).reply(200, urlResponses); + scope.get('/v1/meetings/themes/logos-upload-urls').reply(200, urlResponses); const awsUrl = new URL(urlResponses[0].url); awsScope @@ -160,9 +101,9 @@ describe('Meetings > File uploads', () => { }, ); await expect(() => - client.uploadIcon(themeOne.themeId, LogoType.WHITE, file), + client.uploadIcon(String(themeOne.themeId), LogoType.WHITE, file), ).rejects.toThrow( - `Failed to upload to AWS: Invalid according to Policy: Policy expired`, + 'Failed to upload to AWS: Invalid according to Policy: Policy expired', ); expect(nock.isDone()).toBeTruthy(); @@ -170,7 +111,7 @@ describe('Meetings > File uploads', () => { test('Will throw error when apply fails', async () => { scope - .get(`/v1/meetings/themes/logos-upload-urls`) + .get('/v1/meetings/themes/logos-upload-urls') .reply(200, urlResponses) .put(`/v1/meetings/themes/${themeOne.themeId}/finalizeLogos`, { keys: [urlResponses[0].fields.key], @@ -190,8 +131,8 @@ describe('Meetings > File uploads', () => { const awsUrl = new URL(urlResponses[0].url); awsScope.post(awsUrl.pathname, () => true).reply(204); await expect(() => - client.uploadIcon(themeOne.themeId, LogoType.WHITE, file), - ).rejects.toThrow(`Could not attach image to theme: key_not_found`); + client.uploadIcon(String(themeOne.themeId), LogoType.WHITE, file), + ).rejects.toThrow('Could not attach image to theme: key_not_found'); expect(nock.isDone()).toBeTruthy(); }); diff --git a/packages/meetings/__tests__/numbers.test.ts b/packages/meetings/__tests__/numbers.test.ts index 153eb7f4..4d781603 100644 --- a/packages/meetings/__tests__/numbers.test.ts +++ b/packages/meetings/__tests__/numbers.test.ts @@ -1,6 +1,6 @@ import nock from 'nock'; import { Client } from '@vonage/server-client'; -import { Meetings } from '../lib/index'; +import { Meetings } from '../lib'; import { getClient, getScope } from './common'; const dialInNumberOne = { @@ -17,7 +17,7 @@ const dialInNumberTwo = { describe('Meetings > Numbers', () => { let client: Meetings; - let scope: nock; + let scope: nock.Scope; beforeEach(() => { client = getClient(); @@ -25,14 +25,12 @@ describe('Meetings > Numbers', () => { }); afterEach(() => { - client = null; - scope = null; nock.cleanAll(); }); test('Can get recording by id', async () => { scope - .get(`/v1/meetings/dial-in-numbers`) + .get('/v1/meetings/dial-in-numbers') .reply(200, [ Client.transformers.snakeCaseObjectKeys(dialInNumberOne), Client.transformers.snakeCaseObjectKeys(dialInNumberTwo), diff --git a/packages/meetings/__tests__/private.test.key b/packages/meetings/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/meetings/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/meetings/__tests__/recordings.test.ts b/packages/meetings/__tests__/recordings.test.ts index 63356a28..8e699d1d 100644 --- a/packages/meetings/__tests__/recordings.test.ts +++ b/packages/meetings/__tests__/recordings.test.ts @@ -1,8 +1,7 @@ import nock from 'nock'; import { Client } from '@vonage/server-client'; -import { Meetings } from '../lib/index'; +import { RecordingStatus, Meetings } from '../lib'; import { getClient, getScope } from './common'; -import { RecordingStatus } from '../lib/enums'; const session = { id: 'my-recording', @@ -19,7 +18,7 @@ const session = { describe('Meetings > Recordings', () => { let client: Meetings; - let scope: nock; + let scope: nock.Scope; beforeEach(() => { client = getClient(); @@ -27,14 +26,12 @@ describe('Meetings > Recordings', () => { }); afterEach(() => { - client = null; - scope = null; nock.cleanAll(); }); test('Can get recording by id', async () => { scope - .get(`/v1/meetings/recordings/my-awesome-recording`) + .get('/v1/meetings/recordings/my-awesome-recording') .reply(200, session); expect(await client.getRecording('my-awesome-recording')).toEqual({ @@ -46,7 +43,7 @@ describe('Meetings > Recordings', () => { }); test('Can get recordings for session', async () => { - scope.get(`/v1/meetings/sessions/my-session`).reply(200, { + scope.get('/v1/meetings/sessions/my-session').reply(200, { _embedded: { recordings: [session], }, @@ -63,7 +60,7 @@ describe('Meetings > Recordings', () => { }); test('Can delete recording by id', async () => { - scope.delete(`/v1/meetings/recordings/my-awesome-recording`).reply(204); + scope.delete('/v1/meetings/recordings/my-awesome-recording').reply(204); await client.deleteRecording('my-awesome-recording'); diff --git a/packages/meetings/__tests__/room.test.ts b/packages/meetings/__tests__/room.test.ts index d59894ea..5bfeaac0 100644 --- a/packages/meetings/__tests__/room.test.ts +++ b/packages/meetings/__tests__/room.test.ts @@ -1,6 +1,6 @@ import nock from 'nock'; import { Client } from '@vonage/server-client'; -import { Meetings } from '../lib/index'; +import { MeetingRoom, Meetings } from '../lib'; import pick from 'lodash.pick'; import { BASE_URL, @@ -13,7 +13,7 @@ import { describe('Meetings > Rooms', () => { let client: Meetings; - let scope: nock; + let scope: nock.Scope; beforeEach(() => { client = getClient(); @@ -25,7 +25,7 @@ describe('Meetings > Rooms', () => { }); test('Can get one page of data', async () => { - scope.get(`/v1/meetings/rooms?`).reply(200, { + scope.get('/v1/meetings/rooms?').reply(200, { _embedded: [ { ...roomOne, @@ -41,7 +41,7 @@ describe('Meetings > Rooms', () => { total_items: 1, }); - const rooms = await client.getRooms(); + const rooms = client.getRooms(); const room = await rooms.next(); expect(room.value).toEqual( @@ -52,7 +52,7 @@ describe('Meetings > Rooms', () => { test('Can get two pages of data', async () => { scope - .get(`/v1/meetings/rooms?page_size=1`) + .get('/v1/meetings/rooms?page_size=1') .reply(200, { _embedded: [ { @@ -71,7 +71,7 @@ describe('Meetings > Rooms', () => { page_size: 20, total_items: 1, }) - .get(`/v1/meetings/rooms?page_size=1&start_id=42`) + .get('/v1/meetings/rooms?page_size=1&start_id=42') .reply(200, { _embedded: [ { @@ -88,7 +88,7 @@ describe('Meetings > Rooms', () => { total_items: 1, }); - const results = []; + const results: Array = []; for await (const room of client.getRooms({ pageSize: 1 })) { results.push(room); } @@ -102,7 +102,7 @@ describe('Meetings > Rooms', () => { test('Will throw error when call fails', async () => { scope - .get(`/v1/meetings/rooms?`) + .get('/v1/meetings/rooms?') .reply(200, { _embedded: [ { @@ -121,7 +121,7 @@ describe('Meetings > Rooms', () => { page_size: 20, total_items: 1, }) - .get(`/v1/meetings/rooms?start_id=42`) + .get('/v1/meetings/rooms?start_id=42') .reply(401, { status: 401, error: 'Unauthorized', @@ -140,7 +140,7 @@ describe('Meetings > Rooms', () => { }); test('Can get room by id', async () => { - scope.get(`/v1/meetings/rooms/my-awesome-room`).reply(200, { + scope.get('/v1/meetings/rooms/my-awesome-room').reply(200, { ...roomOne, _links: roomLinks, }); @@ -155,11 +155,11 @@ describe('Meetings > Rooms', () => { test('Can create room', async () => { scope .post( - `/v1/meetings/rooms`, + '/v1/meetings/rooms', pick( Client.transformers.snakeCaseObjectKeys(roomOne, true), client.ROOM_WRITE_KEYS, - ), + ) as nock.RequestBodyMatcher, ) .reply(200, { ...roomOne, @@ -175,12 +175,15 @@ describe('Meetings > Rooms', () => { test('Can Update an existing room', async () => { scope - .patch(`/v1/meetings/rooms/my-awesome-room`, { - update_options: pick( - Client.transformers.snakeCaseObjectKeys(roomOne, true), - client.ROOM_WRITE_KEYS, - ), - }) + .patch( + '/v1/meetings/rooms/my-awesome-room', + { + update_options: pick( + Client.transformers.snakeCaseObjectKeys(roomOne, true), + client.ROOM_WRITE_KEYS, + ), + } as nock.RequestBodyMatcher + ) .reply(200, { ...roomOne, _links: roomLinks, diff --git a/packages/meetings/__tests__/theme.test.ts b/packages/meetings/__tests__/theme.test.ts index 2668a9a5..03acfc07 100644 --- a/packages/meetings/__tests__/theme.test.ts +++ b/packages/meetings/__tests__/theme.test.ts @@ -1,6 +1,6 @@ import nock from 'nock'; import { Client } from '@vonage/server-client'; -import { Meetings } from '../lib/index'; +import { Meetings, Theme } from '../lib'; import { BASE_URL, getClient, @@ -15,7 +15,7 @@ import pick from 'lodash.pick'; describe('Meetings > Themes', () => { let client: Meetings; - let scope: nock; + let scope: nock.Scope; beforeEach(() => { client = getClient(); @@ -27,9 +27,9 @@ describe('Meetings > Themes', () => { }); test('Can get empty themes', async () => { - scope.get(`/v1/meetings/themes`).reply(200, []); + scope.get('/v1/meetings/themes').reply(200, []); - const results = []; + const results: Array = []; for await (const room of client.getThemes()) { results.push(room); } @@ -40,13 +40,13 @@ describe('Meetings > Themes', () => { test('Can get themes', async () => { scope - .get(`/v1/meetings/themes`) + .get('/v1/meetings/themes') .reply(200, [ Client.transformers.snakeCaseObjectKeys(themeOne), Client.transformers.snakeCaseObjectKeys(themeTwo), ]); - const results = []; + const results: Array = []; for await (const room of client.getThemes()) { results.push(room); } @@ -57,7 +57,7 @@ describe('Meetings > Themes', () => { test('Can get theme', async () => { scope - .get(`/v1/meetings/themes/my-theme`) + .get('/v1/meetings/themes/my-theme') .reply(200, Client.transformers.snakeCaseObjectKeys(themeOne)); expect(await client.getTheme('my-theme')).toEqual(themeOne); @@ -66,7 +66,7 @@ describe('Meetings > Themes', () => { test('Can delete theme', async () => { scope - .delete(`/v1/meetings/themes/my-theme`) + .delete('/v1/meetings/themes/my-theme') .reply(200, Client.transformers.snakeCaseObjectKeys(themeOne)); await client.deleteTheme('my-theme'); @@ -75,7 +75,7 @@ describe('Meetings > Themes', () => { test('Can force delete theme', async () => { scope - .delete(`/v1/meetings/themes/my-theme?force=true`) + .delete('/v1/meetings/themes/my-theme?force=true') .reply(200, Client.transformers.snakeCaseObjectKeys(themeOne)); await client.deleteTheme('my-theme', true); @@ -83,7 +83,7 @@ describe('Meetings > Themes', () => { }); test('Will throw when theme in use', async () => { - scope.delete(`/v1/meetings/themes/my-theme`).reply(400, { + scope.delete('/v1/meetings/themes/my-theme').reply(400, { message: 'could not delete theme', name: 'BadRequestError', errors: [ @@ -101,11 +101,11 @@ describe('Meetings > Themes', () => { test('Will create a theme', async () => { scope .post( - `/v1/meetings/themes`, + '/v1/meetings/themes', pick( Client.transformers.snakeCaseObjectKeys(themeOne, true), client.THEME_WRITE_KEYS, - ), + ) as nock.RequestBodyMatcher, ) .reply(201, themeOne); @@ -115,12 +115,14 @@ describe('Meetings > Themes', () => { test('Will update a theme', async () => { scope - .patch(`/v1/meetings/themes/my-theme`, { - update_details: pick( - Client.transformers.snakeCaseObjectKeys(themeOne, true), - client.THEME_WRITE_KEYS, - ), - }) + .patch('/v1/meetings/themes/my-theme', + { + update_details: pick( + Client.transformers.snakeCaseObjectKeys(themeOne, true), + client.THEME_WRITE_KEYS, + ), + } as nock.RequestBodyMatcher, + ) .reply(201, themeOne); expect(await client.updateTheme('my-theme', themeOne)).toEqual(themeOne); @@ -128,7 +130,7 @@ describe('Meetings > Themes', () => { }); test('Can get one page of theme rooms', async () => { - scope.get(`/v1/meetings/themes/my-theme/rooms?`).reply(200, { + scope.get('/v1/meetings/themes/my-theme/rooms?').reply(200, { _embedded: [ { ...roomOne, @@ -155,7 +157,7 @@ describe('Meetings > Themes', () => { test('Can get two pages of theme rooms', async () => { scope - .get(`/v1/meetings/themes/my-theme/rooms?page_size=1`) + .get('/v1/meetings/themes/my-theme/rooms?page_size=1') .reply(200, { _embedded: [ { @@ -174,7 +176,7 @@ describe('Meetings > Themes', () => { page_size: 20, total_items: 1, }) - .get(`/v1/meetings/themes/my-theme/rooms?page_size=1&start_id=42`) + .get('/v1/meetings/themes/my-theme/rooms?page_size=1&start_id=42') .reply(200, { _embedded: [ { @@ -207,7 +209,7 @@ describe('Meetings > Themes', () => { test('Will throw error when call to theme rooms fails', async () => { scope - .get(`/v1/meetings/themes/my-theme/rooms?`) + .get('/v1/meetings/themes/my-theme/rooms?') .reply(200, { _embedded: [roomOne], _links: { @@ -221,7 +223,7 @@ describe('Meetings > Themes', () => { page_size: 20, total_items: 1, }) - .get(`/v1/meetings/themes/my-theme/rooms?start_id=42`) + .get('/v1/meetings/themes/my-theme/rooms?start_id=42') .reply(401, { status: 401, error: 'Unauthorized', @@ -241,7 +243,7 @@ describe('Meetings > Themes', () => { test('Will set default theme', async () => { scope - .patch(`/v1/meetings/applications`, { + .patch('/v1/meetings/applications', { update_details: { default_theme_id: 'my-theme', }, diff --git a/packages/meetings/lib/index.ts b/packages/meetings/lib/index.ts index 215c0e68..7a680769 100644 --- a/packages/meetings/lib/index.ts +++ b/packages/meetings/lib/index.ts @@ -1,3 +1,3 @@ export { Meetings } from './meetings'; -export * from './enums/index'; -export * from './types/index'; +export * from './enums'; +export * from './types'; diff --git a/packages/meetings/lib/types/events/recordingEndedEvent.ts b/packages/meetings/lib/types/events/recordingEndedEvent.ts index 264f73ff..cf98e6eb 100644 --- a/packages/meetings/lib/types/events/recordingEndedEvent.ts +++ b/packages/meetings/lib/types/events/recordingEndedEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/events/recordingReadyEvent.ts b/packages/meetings/lib/types/events/recordingReadyEvent.ts index 5d7bf3a4..b2fd03e0 100644 --- a/packages/meetings/lib/types/events/recordingReadyEvent.ts +++ b/packages/meetings/lib/types/events/recordingReadyEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/events/recordingStartedEvent.ts b/packages/meetings/lib/types/events/recordingStartedEvent.ts index 8e5846e8..4819aa39 100644 --- a/packages/meetings/lib/types/events/recordingStartedEvent.ts +++ b/packages/meetings/lib/types/events/recordingStartedEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/events/roomExpiredEvent.ts b/packages/meetings/lib/types/events/roomExpiredEvent.ts index c35a984c..401947dc 100644 --- a/packages/meetings/lib/types/events/roomExpiredEvent.ts +++ b/packages/meetings/lib/types/events/roomExpiredEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType, MeetingType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/events/sessionEndedEvent.ts b/packages/meetings/lib/types/events/sessionEndedEvent.ts index ac5e1275..a66f9a5c 100644 --- a/packages/meetings/lib/types/events/sessionEndedEvent.ts +++ b/packages/meetings/lib/types/events/sessionEndedEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/events/sessionStartedEvent.ts b/packages/meetings/lib/types/events/sessionStartedEvent.ts index 31de3fe3..cb7fca81 100644 --- a/packages/meetings/lib/types/events/sessionStartedEvent.ts +++ b/packages/meetings/lib/types/events/sessionStartedEvent.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ import { EventType } from '../../enums'; /** diff --git a/packages/meetings/lib/types/index.ts b/packages/meetings/lib/types/index.ts index afce6d4b..224924d3 100644 --- a/packages/meetings/lib/types/index.ts +++ b/packages/meetings/lib/types/index.ts @@ -5,6 +5,6 @@ export * from './meetingRoomParams'; export * from './recording'; export * from './events'; export * from './recordingOptions'; -export * from './response/index'; +export * from './response'; export * from './roomCallbackURLS'; export * from './theme'; diff --git a/packages/meetings/package.json b/packages/meetings/package.json index 627b2139..9ca7640b 100644 --- a/packages/meetings/package.json +++ b/packages/meetings/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -38,16 +39,15 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@types/lodash.pick": "4.4.8", "@vonage/server-client": "^1.12.0", "@vonage/vetch": "^1.7.1", "fast-xml-parser": "^4.3.2", "form-data": "^4.0.0" }, "devDependencies": { - "@amvijay/multipart-parser": "^1.0.2", + "@types/lodash.pick": "4.4.8", "@vonage/auth": "^1.10.0", - "lodash.pick": "4.4.0", + "lodash.pick": "3.1.0", "nock": "^13.3.4" } } diff --git a/packages/meetings/tsconfig.json b/packages/meetings/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/meetings/tsconfig.json +++ b/packages/meetings/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/messages/README.md b/packages/messages/README.md index ec58ccd7..a2fec552 100644 --- a/packages/messages/README.md +++ b/packages/messages/README.md @@ -95,8 +95,8 @@ const resp = await messagesClient.send(new SMS({ messagesClient.send(new SMS({ to: TO_NUMBER, - from: FROM_NUMBER: - text: MESSAGE + from: FROM_NUMBER, + text: MESSAGE, })) .then(resp => console.log(resp)) .catch(err => console.error(err)); diff --git a/packages/messages/__tests__/__dataSets__/messenger.ts b/packages/messages/__tests__/__dataSets__/messenger.ts index ddbc8064..f0752310 100644 --- a/packages/messages/__tests__/__dataSets__/messenger.ts +++ b/packages/messages/__tests__/__dataSets__/messenger.ts @@ -5,9 +5,8 @@ import { MessengerVideo, MessengerText, MessengerFile, -} from '../../lib'; -import { MessageSuccess } from '../../lib'; -import { + MessageParams, + MessageSuccess, MessengerAudioRequest, MessengerTextRequest, MessengerImageRequest, @@ -25,7 +24,6 @@ import { File } from '../../lib/classes/Messenger/File'; import { Image } from '../../lib/classes/Messenger/Image'; import { Text } from '../../lib/classes/Messenger/Text'; import { Video } from '../../lib/classes/Messenger/Video'; -import { MessageCategory } from '../../lib/enums/Messenger/MessageCategory'; export default [ { @@ -119,7 +117,7 @@ export default [ message_type: 'text', client_ref: 'my-ref', messenger: { - category: MessengerCategory.RESPONSE, + category: MessengerCategory.UPDATE, tag: MessengerTags.ACCOUNT_UPDATE, }, } as MessengerTextRequest, @@ -138,7 +136,7 @@ export default [ '14152739164', // to '12126875309', // from { - category: MessageCategory.RESPONSE, + category: MessengerCategory.UPDATE, tag: MessengerTags.ACCOUNT_UPDATE, }, 'my-ref' // client ref @@ -266,7 +264,7 @@ export default [ '14152739164', // to '12126875309', // from { - category: MessageCategory.RESPONSE, + category: MessengerCategory.RESPONSE, tag: MessengerTags.ACCOUNT_UPDATE, }, 'my-ref' // client ref @@ -373,7 +371,7 @@ export default [ url: 'https://example.com', }, messenger: { - category: MessengerCategory.RESPONSE, + category: MessengerCategory.MESSAGE_TAG, tag: MessengerTags.ACCOUNT_UPDATE, }, } as MessengerAudioRequest, @@ -394,7 +392,7 @@ export default [ '14152739164', // to '12126875309', // from { - category: MessageCategory.RESPONSE, + category: MessengerCategory.MESSAGE_TAG, tag: MessengerTags.ACCOUNT_UPDATE, }, 'my-ref' @@ -562,7 +560,7 @@ export default [ file: { url: 'https://example.com', }, - } as MessengerFileParams), + } as MessageParams & MessengerFileParams), ], expected: { messageUUID: '1d4723b0-9134-4440-8cf0-e9f39ccb1c6a', @@ -608,7 +606,7 @@ export default [ category: MessengerCategory.RESPONSE, tag: MessengerTags.ACCOUNT_UPDATE, }, - } as MessengerFileParams), + } as MessageParams & MessengerFileParams), ], expected: { messageUUID: '1d4723b0-9134-4440-8cf0-e9f39ccb1c6a', diff --git a/packages/messages/__tests__/__dataSets__/sms.ts b/packages/messages/__tests__/__dataSets__/sms.ts index 56b73153..579b0c8f 100644 --- a/packages/messages/__tests__/__dataSets__/sms.ts +++ b/packages/messages/__tests__/__dataSets__/sms.ts @@ -196,7 +196,7 @@ export default [ { type: 'https://developer.nexmo.com/api-errors/#unathorized', title: 'You did not provide correct credentials.', - detail: `Check that you're using the correct credentials, and that your account has this feature enabled`, + detail: 'Check that you\'re using the correct credentials, and that your account has this feature enabled', instance: 'bf0ca0bf927b3b52e3cb03217e1a1ddf', }, ], diff --git a/packages/messages/__tests__/messages.test.ts b/packages/messages/__tests__/messages.test.ts index bbc7f30b..19c51d77 100644 --- a/packages/messages/__tests__/messages.test.ts +++ b/packages/messages/__tests__/messages.test.ts @@ -30,7 +30,7 @@ const messageTests = testDataSets.map((dataSet): TestTuple => { clientMethod: 'send', parameters: test.parameters, generator: false, - error: test.error || false, + error: 'error' in test ? String(test.error) : false, expected: test.expected, }; @@ -43,7 +43,7 @@ const messageTests = testDataSets.map((dataSet): TestTuple => { test.request[0], test.request[1], { - ...test.request[2], + ...(typeof test.request[2] === 'object' ? test.request[2] : {}), api_key: '12345', api_secret: 'ABCDE', }, @@ -56,7 +56,7 @@ const messageTests = testDataSets.map((dataSet): TestTuple => { clientMethod: 'send', parameters: test.parameters, generator: false, - error: test.error || false, + error: 'error' in test ? String(test.error) : false, expected: test.expected, }; diff --git a/packages/messages/__tests__/private.test.key b/packages/messages/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/messages/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/messages/lib/classes/Messenger/Video.ts b/packages/messages/lib/classes/Messenger/Video.ts index 45e137a5..50121ca9 100644 --- a/packages/messages/lib/classes/Messenger/Video.ts +++ b/packages/messages/lib/classes/Messenger/Video.ts @@ -1,6 +1,6 @@ import { MessengerCategory } from '../../enums'; import { MessageType } from '../../interfaces/Messenger/MessageType'; -import { VideoObject } from '../../interfaces/VideoObject'; +import { VideoObject } from '../../interfaces'; import { MessengerType } from '../../types'; import { MessengerVideo } from './MessengerVideo'; import debug from 'debug'; diff --git a/packages/messages/lib/classes/Viber/Image.ts b/packages/messages/lib/classes/Viber/Image.ts index 8e1f4ca3..d4c7ee4e 100644 --- a/packages/messages/lib/classes/Viber/Image.ts +++ b/packages/messages/lib/classes/Viber/Image.ts @@ -1,5 +1,4 @@ import { ImageObject } from '../../interfaces'; -import { MessageConfig } from '../../interfaces/Viber/MessageConfig'; import { ViberImageParams, ViberService } from '../../types'; import { ViberImage } from './ViberImage'; import debug from 'debug'; @@ -27,7 +26,7 @@ export class Image extends ViberImage { image: ImageObject, to: string, from: string, - viberService?: MessageConfig, + viberService?: ViberService, clientRef?: string, ) { log('Please update to use the ViberImage class instead'); diff --git a/packages/messages/lib/classes/WhatsApp/TemplateMessage.ts b/packages/messages/lib/classes/WhatsApp/TemplateMessage.ts index fe88b0a9..c9eba3b3 100644 --- a/packages/messages/lib/classes/WhatsApp/TemplateMessage.ts +++ b/packages/messages/lib/classes/WhatsApp/TemplateMessage.ts @@ -2,7 +2,7 @@ import { WhatsAppLanguageCode } from '../../enums'; import { MessageTemplate } from '../../interfaces/WhatsApp/MessageTemplate'; import { WhatsAppTemplate } from './WhatsAppTemplate'; import debug from 'debug'; -import { WhatsAppTemplateParams } from "../../types"; +import { WhatsAppTemplateParams } from '../../types'; const log = debug('vonage:messages:whatsapp'); diff --git a/packages/messages/lib/index.ts b/packages/messages/lib/index.ts index bcc99915..25c1ada4 100644 --- a/packages/messages/lib/index.ts +++ b/packages/messages/lib/index.ts @@ -1,5 +1,5 @@ -export * from './classes/index'; -export * from './enums/index'; -export * from './interfaces/index'; -export * from './types/index'; +export * from './classes'; +export * from './enums'; +export * from './interfaces'; +export * from './types'; export * from './messages'; diff --git a/packages/messages/lib/interfaces/Messenger/MessageType.ts b/packages/messages/lib/interfaces/Messenger/MessageType.ts index ae389a70..7be9985a 100644 --- a/packages/messages/lib/interfaces/Messenger/MessageType.ts +++ b/packages/messages/lib/interfaces/Messenger/MessageType.ts @@ -1,4 +1,5 @@ -import { MessengerType } from "../../types"; +/* eslint-disable @typescript-eslint/no-empty-object-type */ +import { MessengerType } from '../../types'; /** * Represents a message type for the Messenger category. diff --git a/packages/messages/lib/interfaces/WhatsApp/MessageTemplate.ts b/packages/messages/lib/interfaces/WhatsApp/MessageTemplate.ts index 2264fe56..8e1e8d6e 100644 --- a/packages/messages/lib/interfaces/WhatsApp/MessageTemplate.ts +++ b/packages/messages/lib/interfaces/WhatsApp/MessageTemplate.ts @@ -1,4 +1,5 @@ -import { WhatsAppTemplateType } from "../../types"; +/* eslint-disable @typescript-eslint/no-empty-object-type */ +import { WhatsAppTemplateType } from '../../types'; /** * Represents a message template. diff --git a/packages/messages/lib/interfaces/index.ts b/packages/messages/lib/interfaces/index.ts index 6a5b6ea4..f6a137ce 100644 --- a/packages/messages/lib/interfaces/index.ts +++ b/packages/messages/lib/interfaces/index.ts @@ -1,6 +1,6 @@ export * from './AudioObject'; export * from './ImageObject'; -export * from './MMS/index'; +export * from './MMS'; export * from './MessageAudioInterface'; export * from './MessageFileInterface'; export * from './MessageImageInterface'; @@ -9,8 +9,8 @@ export * from './MessageSuccessInterface'; export * from './MessageTextInterface'; export * from './MessageVCardInterface'; export * from './MessageVideoInterface'; -export * from './Messenger/index'; -export * from './SMS/index'; -export * from './Viber/index'; +export * from './Messenger'; +export * from './SMS'; +export * from './Viber'; export * from './VideoObject'; -export * from './WhatsApp/index'; +export * from './WhatsApp'; diff --git a/packages/messages/lib/types/Channels/MMS/MMSAudioParams.ts b/packages/messages/lib/types/Channels/MMS/MMSAudioParams.ts index 3f2671db..33adf287 100644 --- a/packages/messages/lib/types/Channels/MMS/MMSAudioParams.ts +++ b/packages/messages/lib/types/Channels/MMS/MMSAudioParams.ts @@ -1,5 +1,5 @@ -import { MessageParams } from "../../MessageParams"; -import { MessageAudioType } from "../../MessageAudioType"; +import { MessageParams } from '../../MessageParams'; +import { MessageAudioType } from '../../MessageAudioType'; /** * Represents the parameters for sending an audio message on the MMS channel. diff --git a/packages/messages/lib/types/Channels/MMS/MMSImageParams.ts b/packages/messages/lib/types/Channels/MMS/MMSImageParams.ts index 7cb20b2a..a3ad4c19 100644 --- a/packages/messages/lib/types/Channels/MMS/MMSImageParams.ts +++ b/packages/messages/lib/types/Channels/MMS/MMSImageParams.ts @@ -1,5 +1,5 @@ -import { MessageParams } from "../../MessageParams"; -import { MessageImageType } from "../../MessageImageType"; +import { MessageParams } from '../../MessageParams'; +import { MessageImageType } from '../../MessageImageType'; /** * Represents the parameters for sending an image message on the MMS channel. diff --git a/packages/messages/lib/types/Channels/MMS/MMSVideoParams.ts b/packages/messages/lib/types/Channels/MMS/MMSVideoParams.ts index d83967f5..07c637b1 100644 --- a/packages/messages/lib/types/Channels/MMS/MMSVideoParams.ts +++ b/packages/messages/lib/types/Channels/MMS/MMSVideoParams.ts @@ -1,5 +1,5 @@ -import { MessageParams } from "../../MessageParams"; -import { MessageVideoType } from "../../MessageVideoType"; +import { MessageParams } from '../../MessageParams'; +import { MessageVideoType } from '../../MessageVideoType'; /** * Represents the parameters for sending a video message on the MMS channel. diff --git a/packages/messages/lib/types/Channels/MMS/index.ts b/packages/messages/lib/types/Channels/MMS/index.ts index 6ffc78e0..b8309abd 100644 --- a/packages/messages/lib/types/Channels/MMS/index.ts +++ b/packages/messages/lib/types/Channels/MMS/index.ts @@ -2,7 +2,7 @@ import { MMSAudioParams } from './MMSAudioParams'; import { MMSImageParams } from './MMSImageParams'; import { MMSVcardParams } from './MMSVcardParams'; import { MMSVideoParams } from './MMSVideoParams'; -import { Channels } from "../../../enums"; +import { Channels } from '../../../enums'; export * from './MMSAudioParams'; export * from './MMSImageParams'; diff --git a/packages/messages/lib/types/Channels/Messenger/index.ts b/packages/messages/lib/types/Channels/Messenger/index.ts index e9d16096..39473caa 100644 --- a/packages/messages/lib/types/Channels/Messenger/index.ts +++ b/packages/messages/lib/types/Channels/Messenger/index.ts @@ -5,7 +5,7 @@ import { MessengerParams } from './MessengerParams'; import { MessengerTextParams } from './MessengerTextParams'; import { MessengerType } from './MessengerType'; import { MessengerVideoParams } from './MessengerVideoParams'; -import { Channels } from "../../../enums"; +import { Channels } from '../../../enums'; export * from './MessengerAudioParams'; export * from './MessengerFileParams'; diff --git a/packages/messages/lib/types/Channels/Viber/ViberService.ts b/packages/messages/lib/types/Channels/Viber/ViberService.ts index cb717ebd..90470b8a 100644 --- a/packages/messages/lib/types/Channels/Viber/ViberService.ts +++ b/packages/messages/lib/types/Channels/Viber/ViberService.ts @@ -1,4 +1,5 @@ import { ViberCategory } from '../../../enums'; +import { ViberAction } from './ViberAction'; /** * Represents parameters for a Viber service message. @@ -24,4 +25,6 @@ export type ViberService = { * The category of the Viber service message. */ category: ViberCategory; + + action?: ViberAction }; diff --git a/packages/messages/lib/types/Channels/Viber/index.ts b/packages/messages/lib/types/Channels/Viber/index.ts index eb13369c..97cb87a0 100644 --- a/packages/messages/lib/types/Channels/Viber/index.ts +++ b/packages/messages/lib/types/Channels/Viber/index.ts @@ -5,7 +5,7 @@ import { ViberImageParams } from './ViberImageParams'; import { ViberService } from './ViberService'; import { ViberTextParams } from './ViberTextParams'; import { ViberVideoParams } from './ViberVideoParams'; -import { Channels } from "../../../enums"; +import { Channels } from '../../../enums'; export * from './ViberAction'; export * from './ViberActionParams'; diff --git a/packages/messages/lib/types/SendMessageParams.ts b/packages/messages/lib/types/SendMessageParams.ts index 0fbd1f14..f64dc1fd 100644 --- a/packages/messages/lib/types/SendMessageParams.ts +++ b/packages/messages/lib/types/SendMessageParams.ts @@ -4,7 +4,7 @@ import { AnyWhatsAppParams, AnyMMSParams, SMSParams, -} from "./Channels"; +} from './Channels'; /** * Represents parameters for sending various types of messages. diff --git a/packages/messages/lib/types/index.ts b/packages/messages/lib/types/index.ts index b9d89bd9..7d10649a 100644 --- a/packages/messages/lib/types/index.ts +++ b/packages/messages/lib/types/index.ts @@ -11,7 +11,7 @@ export * from './MessageParamsVcard'; export * from './MessageParamsVideo'; export * from './MessageVcardType'; export * from './MessageVideoType'; -export * from './Requests/index'; -export * from './Responses/index'; +export * from './Requests'; +export * from './Responses'; export * from './SendMessageParams'; export * from './MessageSuccess'; diff --git a/packages/messages/package.json b/packages/messages/package.json index 9dce23ce..c7a43e7c 100644 --- a/packages/messages/package.json +++ b/packages/messages/package.json @@ -31,8 +31,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/messages/tsconfig.json b/packages/messages/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/messages/tsconfig.json +++ b/packages/messages/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/number-insight-v2/README.md b/packages/number-insight-v2/README.md index 0d17d9ca..f675ae43 100644 --- a/packages/number-insight-v2/README.md +++ b/packages/number-insight-v2/README.md @@ -38,7 +38,7 @@ yarn add @vonage/number-insight-v2 If you are using this SDK as part of the Vonage Server SDK, you can access it as the `numberInsightV2` property off of the client that you instantiate. ```js -const { Auth } = require('@vonage/auth); +const { Auth } = require('@vonage/auth'); const { Vonage } = require('@vonage/server-sdk'); const { Insight } = require('@vonage/number-insight-v2'); diff --git a/packages/number-insight-v2/__tests__/__dataSets__/post.ts b/packages/number-insight-v2/__tests__/__dataSets__/post.ts index 27166259..11a064c0 100644 --- a/packages/number-insight-v2/__tests__/__dataSets__/post.ts +++ b/packages/number-insight-v2/__tests__/__dataSets__/post.ts @@ -58,7 +58,7 @@ const response = { export default [ { label: 'check for fraud', - requests: [[`/v2/ni`, 'POST', params]], + requests: [['/v2/ni', 'POST', params]], responses: [[200, response]], clientMethod: 'checkForFraud', parameters: [params], diff --git a/packages/number-insight-v2/__tests__/numberInsightV2.test.ts b/packages/number-insight-v2/__tests__/numberInsightV2.test.ts index e379fbd5..a0838596 100644 --- a/packages/number-insight-v2/__tests__/numberInsightV2.test.ts +++ b/packages/number-insight-v2/__tests__/numberInsightV2.test.ts @@ -1,48 +1,39 @@ -import { NumberInsightV2 } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import { readFileSync } from 'fs'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new NumberInsightV2( - new Auth({ - apiKey: 'abcd', - apiSecret: '1234', - }) - ); - - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value === 'Basic YWJjZDoxMjM0', - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - test.each(tests)( - 'Can $label using: $clientMethod', - async ({ requests, responses, clientMethod, parameters, expected }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); - - const result = await client[clientMethod](...parameters); - - expect(result).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - } - ); +import { NumberInsightV2 } from '../lib'; +import testDataSets from './__dataSets__'; + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + validateApiKeyAuth, + apiKeyAuth, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateApiKeyAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new NumberInsightV2(apiKeyAuth), + clientMethod: test.clientMethod as keyof NumberInsightV2, + parameters: test.parameters, + generator: test.generator || false, + error: test.error || false, + expected: test.expected, + }; + }), + }; }); + +VonageTest(applicationsTest); diff --git a/packages/number-insight-v2/__tests__/private.test.key b/packages/number-insight-v2/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/number-insight-v2/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/number-insight-v2/package.json b/packages/number-insight-v2/package.json index 9772a10f..0bf4a84b 100644 --- a/packages/number-insight-v2/package.json +++ b/packages/number-insight-v2/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -39,9 +40,5 @@ }, "dependencies": { "@vonage/server-client": "^1.12.0" - }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "13.3.3" } } diff --git a/packages/number-insight-v2/tsconfig.json b/packages/number-insight-v2/tsconfig.json index cd40b0e3..d6b25449 100644 --- a/packages/number-insight-v2/tsconfig.json +++ b/packages/number-insight-v2/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/number-insights/README.md b/packages/number-insights/README.md index c4a438dc..406e1b29 100644 --- a/packages/number-insights/README.md +++ b/packages/number-insights/README.md @@ -40,7 +40,7 @@ yarn add @vonage/number-insights If you are using this SDK as part of the Vonage Server SDK, you can access it as the `messages` property off of the client that you instantiate. ```js -const { Auth } = require('@vonage/auth); +const { Auth } = require('@vonage/auth'); const { Vonage } = require('@vonage/server-sdk'); const credentials = new Auth({ diff --git a/packages/number-insights/__tests__/number-insights.test.ts b/packages/number-insights/__tests__/number-insights.test.ts index 8f322ace..394cd3e6 100644 --- a/packages/number-insights/__tests__/number-insights.test.ts +++ b/packages/number-insights/__tests__/number-insights.test.ts @@ -1,11 +1,11 @@ import { Auth } from '@vonage/auth'; import nock from 'nock'; -import { NumberInsights } from '../lib/index'; +import { NumberInsights } from '../lib'; const BASE_URL = 'https://api.nexmo.com'; describe('number-insights', () => { - let client; + let client: NumberInsights; beforeEach(() => { client = new NumberInsights( @@ -13,9 +13,6 @@ describe('number-insights', () => { ); }); - afterEach(() => { - client = null; - }); test('do a basic lookup', async () => { const expectedResponse = { diff --git a/packages/number-insights/lib/number-insights.ts b/packages/number-insights/lib/number-insights.ts index e4747578..46a991fe 100644 --- a/packages/number-insights/lib/number-insights.ts +++ b/packages/number-insights/lib/number-insights.ts @@ -94,7 +94,7 @@ export class NumberInsights extends Client { public async asyncAdvancedLookup( phoneNumber: string, callback: string, - options: StandardLookupOptions, + options?: StandardLookupOptions, ): Promise { const params = { number: phoneNumber, callback, ...options }; const resp = await this.sendGetRequest( diff --git a/packages/number-insights/package.json b/packages/number-insights/package.json index cc7df8ef..d686bc0e 100644 --- a/packages/number-insights/package.json +++ b/packages/number-insights/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/number-insights/tsconfig.json b/packages/number-insights/tsconfig.json index eadf2cc8..950fdc78 100644 --- a/packages/number-insights/tsconfig.json +++ b/packages/number-insights/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/numbers/__tests__/__dataSets__/buyNumbers.ts b/packages/numbers/__tests__/__dataSets__/buyNumbers.ts index 94a9fb1b..90573566 100644 --- a/packages/numbers/__tests__/__dataSets__/buyNumbers.ts +++ b/packages/numbers/__tests__/__dataSets__/buyNumbers.ts @@ -8,7 +8,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/buy?api_key=12345&api_secret=ABCDE`, + '/number/buy?api_key=12345&api_secret=ABCDE', 'POST', new URLSearchParams([ ['country', 'US'], @@ -43,7 +43,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/buy?api_key=12345&api_secret=ABCDE`, + '/number/buy?api_key=12345&api_secret=ABCDE', 'POST', new URLSearchParams([ ['country', 'US'], diff --git a/packages/numbers/__tests__/__dataSets__/cancel.ts b/packages/numbers/__tests__/__dataSets__/cancel.ts index 437a6afc..6927372b 100644 --- a/packages/numbers/__tests__/__dataSets__/cancel.ts +++ b/packages/numbers/__tests__/__dataSets__/cancel.ts @@ -10,7 +10,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/cancel?api_key=12345&api_secret=ABCDE`, + '/number/cancel?api_key=12345&api_secret=ABCDE', 'POST', new URLSearchParams([ ['country', 'US'], diff --git a/packages/numbers/__tests__/__dataSets__/getOwnedNumbers.ts b/packages/numbers/__tests__/__dataSets__/getOwnedNumbers.ts index 61b92616..65c73003 100644 --- a/packages/numbers/__tests__/__dataSets__/getOwnedNumbers.ts +++ b/packages/numbers/__tests__/__dataSets__/getOwnedNumbers.ts @@ -23,7 +23,7 @@ export default [ clientMethod: CLIENT_METHOD, request: { url: BASE_URL, - intercept: [`/account/numbers?api_key=12345&api_secret=ABCDE`, 'GET'], + intercept: ['/account/numbers?api_key=12345&api_secret=ABCDE', 'GET'], reply: [200, validResponse], }, parameters: [{}], @@ -35,7 +35,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/account/numbers?application_id=foo-bar&has_application=false&search_pattern=searchPattern&country=US&pattern=pattern&size=42&index=1&api_key=12345&api_secret=ABCDE`, + '/account/numbers?application_id=foo-bar&has_application=false&search_pattern=searchPattern&country=US&pattern=pattern&size=42&index=1&api_key=12345&api_secret=ABCDE', 'GET', ], reply: [200, validResponse], diff --git a/packages/numbers/__tests__/__dataSets__/search.ts b/packages/numbers/__tests__/__dataSets__/search.ts index ea1501b2..a4e67c1f 100644 --- a/packages/numbers/__tests__/__dataSets__/search.ts +++ b/packages/numbers/__tests__/__dataSets__/search.ts @@ -1,4 +1,4 @@ -import { Feature } from '../../lib/enums/Feature'; +import { Feature } from '../../lib/enums'; const BASE_URL = 'https://rest.nexmo.com'; const CLIENT_METHOD = 'getAvailableNumbers'; @@ -20,7 +20,7 @@ export default [ clientMethod: CLIENT_METHOD, request: { url: BASE_URL, - intercept: [`/number/search?api_key=12345&api_secret=ABCDE`, 'GET'], + intercept: ['/number/search?api_key=12345&api_secret=ABCDE', 'GET'], reply: [ 200, validResponse, @@ -93,7 +93,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=0&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=0&country=US', 'GET', ], reply: [200, validResponse], @@ -112,7 +112,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=2&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=2&country=US', 'GET', ], reply: [200, validResponse], @@ -131,7 +131,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=1&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=1&country=US', 'GET', ], reply: [200, validResponse], @@ -150,7 +150,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=1&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=1234&search_pattern=1&country=US', 'GET', ], reply: [200, validResponse], @@ -171,7 +171,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=0987&search_pattern=2&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=0987&search_pattern=2&country=US', 'GET', ], reply: [200, validResponse], @@ -191,7 +191,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=5309&search_pattern=0&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=5309&search_pattern=0&country=US', 'GET', ], reply: [200, validResponse], @@ -214,7 +214,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/search?api_key=12345&api_secret=ABCDE&pattern=5309&search_pattern=1&country=US`, + '/number/search?api_key=12345&api_secret=ABCDE&pattern=5309&search_pattern=1&country=US', 'GET', ], reply: [200, validResponse], diff --git a/packages/numbers/__tests__/__dataSets__/update.ts b/packages/numbers/__tests__/__dataSets__/update.ts index a1382a4d..5abebc68 100644 --- a/packages/numbers/__tests__/__dataSets__/update.ts +++ b/packages/numbers/__tests__/__dataSets__/update.ts @@ -1,4 +1,4 @@ -import { VoiceCallbackTypeEnum } from "../../lib"; +import { VoiceCallbackTypeEnum } from '../../lib'; const BASE_URL = 'https://rest.nexmo.com'; const CLIENT_METHOD = 'updateNumber'; @@ -12,7 +12,7 @@ export default [ request: { url: BASE_URL, intercept: [ - `/number/update?api_key=12345&api_secret=ABCDE`, + '/number/update?api_key=12345&api_secret=ABCDE', 'POST', new URLSearchParams([ ['app_id', '123abc'], diff --git a/packages/numbers/__tests__/numbers.test.ts b/packages/numbers/__tests__/numbers.test.ts index 1d396fd8..4838b789 100644 --- a/packages/numbers/__tests__/numbers.test.ts +++ b/packages/numbers/__tests__/numbers.test.ts @@ -1,55 +1,48 @@ -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { Numbers } from '../lib/index'; -import dataSet from './__dataSets__/index'; - -describe.each(dataSet)('$label', ({ tests }) => { - let client: Numbers; - - beforeEach(function () { - client = new Numbers(new Auth({ apiKey: '12345', apiSecret: 'ABCDE' })); - }); - - afterEach(function () { - client = null; - nock.cleanAll(); - }); - - const succesfulTests = tests.filter((test) => !test?.exception); - const exceptionTests = tests.filter((test) => test?.exception); - - test.each(succesfulTests)( - 'Can $label', - async ({ request, parameters, clientMethod, expected }) => { - const { url, intercept, reply } = request; - - const scope = nock(url) - .intercept(...intercept) - .reply(...reply); - - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - expect(scope.isDone()).toBeTruthy(); - }, - ); - - if (exceptionTests.length < 1) { - return; - } - - test.each(exceptionTests)( - 'Throws exception $label', - async ({ request, parameters, clientMethod, exception }) => { - const { url, intercept, reply } = request; - - const scope = nock(url) - .intercept(...intercept) - .reply(...reply); - - await expect(() => - client[clientMethod](...parameters), - ).rejects.toThrow(exception); - expect(scope.isDone()).toBeTruthy(); - }, - ); +import { Numbers } from '../lib'; +import dataSet from './__dataSets__'; +import { URL } from 'url'; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, + apiKey, + apiSecret, +} from '../../../testHelpers'; + +const applicationsTest = dataSet.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + const requestUrl = new URL(`${test.request.url}${test.request.intercept[0]}`); + requestUrl.searchParams.set('api_key', apiKey); + requestUrl.searchParams.set('api_secret', apiSecret); + return { + label: test.label, + baseUrl: 'https://rest.nexmo.com', + requests: [ + [ + `${requestUrl.pathname}${requestUrl.search.toString()}`, + test.request.intercept[1], + test.request.intercept[2], + ] as TestRequest + ], + responses: [ + test.request.reply as TestResponse + ], + client: new Numbers(apiKeyAuth), + clientMethod: test.clientMethod as keyof Numbers, + parameters: test.parameters, + generator: 'generator' in test ? Boolean(test.generator) : false, + error: 'exception' in test ? String(test.exception) : false, + expected: test.expected, + }; + }), + }; }); + +VonageTest(applicationsTest); diff --git a/packages/numbers/lib/numbers.ts b/packages/numbers/lib/numbers.ts index 8035efe7..86f788fe 100644 --- a/packages/numbers/lib/numbers.ts +++ b/packages/numbers/lib/numbers.ts @@ -11,7 +11,7 @@ import { NumbersSearchSimple, NumbersSearchFilter, NumbersUpdateParams, -} from "./types"; +} from './types'; const buildSearch = ({ endsWith, diff --git a/packages/numbers/lib/types/NumbersAvailableList.ts b/packages/numbers/lib/types/NumbersAvailableList.ts index 2e95118a..b691c33b 100644 --- a/packages/numbers/lib/types/NumbersAvailableList.ts +++ b/packages/numbers/lib/types/NumbersAvailableList.ts @@ -1,4 +1,4 @@ -import { NumbersAvailableNumber } from "./NumbersAvailableNumber"; +import { NumbersAvailableNumber } from './NumbersAvailableNumber'; /** * Represents a list of available numbers. diff --git a/packages/numbers/lib/types/NumbersAvailableNumber.ts b/packages/numbers/lib/types/NumbersAvailableNumber.ts index 9a1370e7..f2e18831 100644 --- a/packages/numbers/lib/types/NumbersAvailableNumber.ts +++ b/packages/numbers/lib/types/NumbersAvailableNumber.ts @@ -1,5 +1,5 @@ -import { LineType, Feature } from "../enums"; -import { Country } from "./Country"; +import { LineType, Feature } from '../enums'; +import { Country } from './Country'; /** * Represents an available phone number with its details. diff --git a/packages/numbers/lib/types/NumbersClassParameters.ts b/packages/numbers/lib/types/NumbersClassParameters.ts index e5e89042..8a0ebe9d 100644 --- a/packages/numbers/lib/types/NumbersClassParameters.ts +++ b/packages/numbers/lib/types/NumbersClassParameters.ts @@ -1,5 +1,5 @@ -import { AuthInterface, AuthParams } from "@vonage/auth"; -import { VetchOptions } from "@vonage/vetch"; +import { AuthInterface, AuthParams } from '@vonage/auth'; +import { VetchOptions } from '@vonage/vetch'; /** * Represents the parameters for configuring the NumbersClass. diff --git a/packages/numbers/lib/types/NumbersOwnedFilter.ts b/packages/numbers/lib/types/NumbersOwnedFilter.ts index df99612c..58eddecb 100644 --- a/packages/numbers/lib/types/NumbersOwnedFilter.ts +++ b/packages/numbers/lib/types/NumbersOwnedFilter.ts @@ -1,5 +1,5 @@ -import { SearchPattern } from "../enums"; -import { Country } from "./Country"; +import { SearchPattern } from '../enums'; +import { Country } from './Country'; /** * Represents filters for searching owned numbers. diff --git a/packages/numbers/lib/types/NumbersOwnedList.ts b/packages/numbers/lib/types/NumbersOwnedList.ts index 50117c90..2a965a7f 100644 --- a/packages/numbers/lib/types/NumbersOwnedList.ts +++ b/packages/numbers/lib/types/NumbersOwnedList.ts @@ -1,4 +1,4 @@ -import { NumbersOwnedNumber } from "./NumbersOwnedNumber"; +import { NumbersOwnedNumber } from './NumbersOwnedNumber'; /** * Represents a list of owned numbers. diff --git a/packages/numbers/lib/types/NumbersOwnedNumber.ts b/packages/numbers/lib/types/NumbersOwnedNumber.ts index fc1c7096..c5c48b25 100644 --- a/packages/numbers/lib/types/NumbersOwnedNumber.ts +++ b/packages/numbers/lib/types/NumbersOwnedNumber.ts @@ -1,5 +1,5 @@ -import { LineType, Feature } from "../enums"; -import { Country } from "./Country"; +import { LineType, Feature } from '../enums'; +import { Country } from './Country'; /** * Represents an owned phone number with its details. diff --git a/packages/numbers/lib/types/NumbersParams.ts b/packages/numbers/lib/types/NumbersParams.ts index 3891a374..e36deee8 100644 --- a/packages/numbers/lib/types/NumbersParams.ts +++ b/packages/numbers/lib/types/NumbersParams.ts @@ -1,4 +1,4 @@ -import { Country } from "./Country"; +import { Country } from './Country'; /** * Represents parameters for configuring a phone number. diff --git a/packages/numbers/lib/types/NumbersQueryOwnedFilter.ts b/packages/numbers/lib/types/NumbersQueryOwnedFilter.ts index 6f211804..e9c67574 100644 --- a/packages/numbers/lib/types/NumbersQueryOwnedFilter.ts +++ b/packages/numbers/lib/types/NumbersQueryOwnedFilter.ts @@ -1,4 +1,4 @@ -import { Country } from "./Country"; +import { Country } from './Country'; /** * Represents filters for querying owned numbers. diff --git a/packages/numbers/lib/types/NumbersQueryParams.ts b/packages/numbers/lib/types/NumbersQueryParams.ts index 28cd1020..dee4fbb0 100644 --- a/packages/numbers/lib/types/NumbersQueryParams.ts +++ b/packages/numbers/lib/types/NumbersQueryParams.ts @@ -1,4 +1,4 @@ -import { Country } from "./Country"; +import { Country } from './Country'; /** * Represents parameters for querying phone numbers. diff --git a/packages/numbers/lib/types/NumbersQuerySearchFilter.ts b/packages/numbers/lib/types/NumbersQuerySearchFilter.ts index fed5afec..b2732fdb 100644 --- a/packages/numbers/lib/types/NumbersQuerySearchFilter.ts +++ b/packages/numbers/lib/types/NumbersQuerySearchFilter.ts @@ -1,4 +1,4 @@ -import { Country } from "./Country"; +import { Country } from './Country'; /** * Represents filters for searching phone numbers. diff --git a/packages/numbers/lib/types/NumbersQueryUpdateParams.ts b/packages/numbers/lib/types/NumbersQueryUpdateParams.ts index 705bc172..e2f4159a 100644 --- a/packages/numbers/lib/types/NumbersQueryUpdateParams.ts +++ b/packages/numbers/lib/types/NumbersQueryUpdateParams.ts @@ -1,5 +1,5 @@ -import { VoiceCallbackTypeEnum, MessagesCallbackTypeEnum } from "../enums"; -import { Country } from "./Country"; +import { VoiceCallbackTypeEnum, MessagesCallbackTypeEnum } from '../enums'; +import { Country } from './Country'; /** * Represents parameters for updating phone number settings. diff --git a/packages/numbers/lib/types/NumbersResponse.ts b/packages/numbers/lib/types/NumbersResponse.ts index 38fa000c..3f0e2b68 100644 --- a/packages/numbers/lib/types/NumbersResponse.ts +++ b/packages/numbers/lib/types/NumbersResponse.ts @@ -1,4 +1,4 @@ -import { VetchResponse } from "@vonage/vetch"; +import { VetchResponse } from '@vonage/vetch'; /** * Represents a response for phone numbers. diff --git a/packages/numbers/lib/types/NumbersSearchFilter.ts b/packages/numbers/lib/types/NumbersSearchFilter.ts index e50f9ff6..d4614502 100644 --- a/packages/numbers/lib/types/NumbersSearchFilter.ts +++ b/packages/numbers/lib/types/NumbersSearchFilter.ts @@ -1,5 +1,5 @@ -import { LineType, Feature, SearchPattern } from "../enums"; -import { Country } from "./Country"; +import { LineType, Feature, SearchPattern } from '../enums'; +import { Country } from './Country'; /** * Represents filters for searching phone numbers. diff --git a/packages/numbers/lib/types/NumbersUpdateParams.ts b/packages/numbers/lib/types/NumbersUpdateParams.ts index f927b08f..7d5c8705 100644 --- a/packages/numbers/lib/types/NumbersUpdateParams.ts +++ b/packages/numbers/lib/types/NumbersUpdateParams.ts @@ -1,5 +1,5 @@ -import { VoiceCallbackTypeEnum, MessagesCallbackTypeEnum } from "../enums"; -import { Country } from "./Country"; +import { VoiceCallbackTypeEnum, MessagesCallbackTypeEnum } from '../enums'; +import { Country } from './Country'; /** * Represents parameters for updating phone numbers. diff --git a/packages/numbers/package.json b/packages/numbers/package.json index 91590654..2843593f 100644 --- a/packages/numbers/package.json +++ b/packages/numbers/package.json @@ -26,8 +26,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "dist", "test": "__tests__" @@ -48,9 +49,6 @@ "@vonage/vetch": "^1.7.1", "lodash.omit": "4.5.0" }, - "devDependencies": { - "nock": "^13.3.4" - }, "publishConfig": { "directory": "dist" } diff --git a/packages/numbers/tsconfig.json b/packages/numbers/tsconfig.json index e9b438f7..0cb0e6da 100644 --- a/packages/numbers/tsconfig.json +++ b/packages/numbers/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/pricing/__tests__/pricing.test.ts b/packages/pricing/__tests__/pricing.test.ts index ad104a6f..ffe50572 100644 --- a/packages/pricing/__tests__/pricing.test.ts +++ b/packages/pricing/__tests__/pricing.test.ts @@ -1,20 +1,16 @@ import { Auth } from '@vonage/auth'; import nock from 'nock'; -import { ServiceType } from '../lib/enums/ServiceType'; -import { Pricing } from '../lib/index'; +import { ServiceType, Pricing } from '../lib'; const BASE_URL = 'https://rest.nexmo.com/'.replace(/\/+$/, ''); describe('pricing', () => { - let client; + let client: Pricing; beforeEach(() => { client = new Pricing(new Auth({ apiKey: 'abcd', apiSecret: '1234' })); }); - afterEach(() => { - client = null; - }); test('do a country lookup', async () => { const expectedResponse = { diff --git a/packages/pricing/package.json b/packages/pricing/package.json index af026d99..fe48df97 100644 --- a/packages/pricing/package.json +++ b/packages/pricing/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/pricing/tsconfig.json b/packages/pricing/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/pricing/tsconfig.json +++ b/packages/pricing/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/proactive-connect/__tests__/__dataSets__/items.ts b/packages/proactive-connect/__tests__/__dataSets__/items.ts index 4281807c..6dec624c 100644 --- a/packages/proactive-connect/__tests__/__dataSets__/items.ts +++ b/packages/proactive-connect/__tests__/__dataSets__/items.ts @@ -18,7 +18,7 @@ const itemOne = { updatedAt: '2023-04-20T15:23:10.169Z', data: { phone: '19162255887', - message: "I'll always dial the 'K' for you.", + message: 'I\'ll always dial the \'K\' for you.', }, } as ListItem; @@ -134,7 +134,7 @@ export default [ label: 'create item', requests: [ [ - `/v0.1/bulk/lists`, + '/v0.1/bulk/lists', 'POST', { data: itemOne.data, diff --git a/packages/proactive-connect/__tests__/__dataSets__/list.ts b/packages/proactive-connect/__tests__/__dataSets__/list.ts index a1d27ba5..1e906e11 100644 --- a/packages/proactive-connect/__tests__/__dataSets__/list.ts +++ b/packages/proactive-connect/__tests__/__dataSets__/list.ts @@ -9,7 +9,7 @@ import { ListSalesForceDataSource, WriteListRequest, } from '../../lib/types'; -import { ProactiveConnect } from '../../lib/proactiveConnect'; +import { ProactiveConnect } from '@vonage/proactive-connect'; import pick from 'lodash.pick'; const listOne = { @@ -80,8 +80,8 @@ export default [ { label: 'find all lists', requests: [ - [`/v0.1/bulk/lists?page=1`, 'GET'], - [`/v0.1/bulk/lists?page=2`, 'GET'], + ['/v0.1/bulk/lists?page=1', 'GET'], + ['/v0.1/bulk/lists?page=2', 'GET'], ], responses: [ [ @@ -166,7 +166,7 @@ export default [ label: 'create list', requests: [ [ - `/v0.1/bulk/lists`, + '/v0.1/bulk/lists', 'POST', { name: listOne.name, diff --git a/packages/proactive-connect/__tests__/private.test.key b/packages/proactive-connect/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/proactive-connect/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/proactive-connect/__tests__/proactiveConnect.test.ts b/packages/proactive-connect/__tests__/proactiveConnect.test.ts index 2988e60f..3ec0e8cd 100644 --- a/packages/proactive-connect/__tests__/proactiveConnect.test.ts +++ b/packages/proactive-connect/__tests__/proactiveConnect.test.ts @@ -1,115 +1,63 @@ -import { ImportFileResponse, ProactiveConnect } from '../lib/index'; +import { ImportFileResponse, ProactiveConnect } from '../lib'; import nock from 'nock'; import { Auth } from '@vonage/auth'; import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; +import testDataSets from './__dataSets__'; import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs'; import { rm } from 'fs/promises'; -import { parse } from '@amvijay/multipart-parser'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); const CSV_DIR = `${process.cwd()}/path`; -const getResults = async ( - generator: boolean, - client: unknown, - clientMethod: string, - parameters: Array, -) => { - if (!generator) { - return await client[clientMethod](...parameters); - } - - const results = []; - for await (const result of client[clientMethod](...parameters)) { - results.push(result); - } - return results; -}; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new ProactiveConnect( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), - ); - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value.startsWith('Bearer '), - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ - requests, - responses, - clientMethod, - parameters, - expected, - generator = false, - }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); - - const results = await getResults( - generator, - client, - clientMethod, - parameters, - ); - - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); - - if (failureTests.length < 1) { - return; - } - - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); - - await expect(() => client[clientMethod](...parameters)).rejects.toThrow( - error, - ); - expect(nock.isDone()).toBeTruthy(); - }, - ); +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth, + testPrivateKey, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api-eu.vonage.com', + reqHeaders: { + authorization: validateBearerAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new ProactiveConnect(keyAuth), + clientMethod: test.clientMethod as keyof ProactiveConnect, + parameters: test.parameters, + generator: test.generator || false, + error: test.error || false, + expected: test.expected, + }; + }), + }; }); +VonageTest(applicationsTest); + describe('File tests', () => { - let client; - let scope; + let client: ProactiveConnect; + let scope: nock.Scope; beforeEach(() => { if (!existsSync(CSV_DIR)) { mkdirSync(CSV_DIR); } - writeFileSync(`${CSV_DIR}/upload-file.csv`, `fizz,buzz\nfoo,bar`); + writeFileSync(`${CSV_DIR}/upload-file.csv`, 'fizz,buzz\nfoo,bar'); client = new ProactiveConnect( new Auth({ - privateKey: key, + privateKey: testPrivateKey, applicationId: 'my-application', }), ); @@ -121,8 +69,6 @@ describe('File tests', () => { }); afterEach(async () => { - client = null; - scope = null; nock.cleanAll(); await rm(CSV_DIR, { force: true, @@ -132,10 +78,10 @@ describe('File tests', () => { test('Can download CSV file', async () => { const file = `${CSV_DIR}/tmp.csv`; - const csv = `foo,bar\nfizz,buzz`; + const csv = 'foo,bar\nfizz,buzz'; scope .get( - `/v0.1/bulk/lists/10000000-0000-0000-0000-000000000000/items/download`, + '/v0.1/bulk/lists/10000000-0000-0000-0000-000000000000/items/download', ) .reply(200, csv); @@ -156,20 +102,9 @@ describe('File tests', () => { test('Can upload CSV File', async () => { const file = `${CSV_DIR}/upload-file.csv`; expect(existsSync(file)).toBeTruthy(); - const fileBuf = readFileSync(file); scope .post( - `/v0.1/bulk/lists/10000000-0000-0000-0000-000000000000/items/download`, - (body) => { - const parts = parse(Buffer.from(body, 'hex'), client.FORM_BOUNDARY); - return parts.reduce((acc, part) => { - if (part.name === 'file') { - return acc && !!Buffer.compare(parts.content, fileBuf); - } - - return true; - }, true); - }, + '/v0.1/bulk/lists/10000000-0000-0000-0000-000000000000/items/download', ) .reply(200, { inserted: 42, diff --git a/packages/proactive-connect/lib/types/findListItemParams.ts b/packages/proactive-connect/lib/types/findListItemParams.ts index d009f3ce..5ebaf9bb 100644 --- a/packages/proactive-connect/lib/types/findListItemParams.ts +++ b/packages/proactive-connect/lib/types/findListItemParams.ts @@ -1,4 +1,4 @@ -import { SortOrder } from "../enums"; +import { SortOrder } from '../enums'; /** * Represents parameters for finding list items. diff --git a/packages/proactive-connect/lib/types/index.ts b/packages/proactive-connect/lib/types/index.ts index 08badfa9..77873347 100644 --- a/packages/proactive-connect/lib/types/index.ts +++ b/packages/proactive-connect/lib/types/index.ts @@ -7,5 +7,5 @@ export * from './listItem'; export * from './listManualDatasource'; export * from './listSalesForceDataSource'; export * from './listSyncStatus'; -export * from './requests/index'; -export * from './responses/index'; +export * from './requests'; +export * from './responses'; diff --git a/packages/proactive-connect/package.json b/packages/proactive-connect/package.json index 07d8861c..73575517 100644 --- a/packages/proactive-connect/package.json +++ b/packages/proactive-connect/package.json @@ -18,8 +18,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -37,10 +38,9 @@ "@vonage/server-client": "^1.12.0", "@vonage/vetch": "^1.7.1", "form-data": "^4.0.0", - "lodash.pick": "^4.4.0" + "lodash.pick": "3.1.0" }, "devDependencies": { - "@amvijay/multipart-parser": "^1.0.2", "@vonage/auth": "^1.10.0", "nock": "^13.3.4" } diff --git a/packages/proactive-connect/tsconfig.json b/packages/proactive-connect/tsconfig.json index 4365c435..12e0d8fb 100644 --- a/packages/proactive-connect/tsconfig.json +++ b/packages/proactive-connect/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/redact/__tests__/__dataSets__/redact.ts b/packages/redact/__tests__/__dataSets__/redact.ts index 123a4daa..76cfe7ee 100644 --- a/packages/redact/__tests__/__dataSets__/redact.ts +++ b/packages/redact/__tests__/__dataSets__/redact.ts @@ -1,6 +1,10 @@ -import { ProductType, Type } from '../../lib/enums/index'; -import { TransactionParams } from '../../lib/types/index'; -import { TransactionRequest, ErrorResponse } from '../../lib/interfaces/index'; +import { + TransactionRequest, + ErrorResponse, + TransactionParams, + ProductType, + Type +} from '../../lib'; export default [ { diff --git a/packages/redact/__tests__/redact.test.ts b/packages/redact/__tests__/redact.test.ts index 9c4ddfa8..04222b79 100644 --- a/packages/redact/__tests__/redact.test.ts +++ b/packages/redact/__tests__/redact.test.ts @@ -1,55 +1,39 @@ -import { Redact } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new Redact(new Auth({ apiKey: '12345', apiSecret: 'ABCDE' })); - scope = nock(BASE_URL, { - reqheaders: { - authorization: 'Basic MTIzNDU6QUJDREU=', - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ request, response, clientMethod, parameters }) => { - scope.intercept(...request).reply(...response); - - const results = await client[clientMethod](...parameters); - expect(results).toBeUndefined(); - expect(nock.isDone()).toBeTruthy(); - }, - ); - - if (failureTests.length < 1) { - return; - } - - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); - - await expect(() => - client[clientMethod](...parameters), - ).rejects.toThrow(error); - expect(nock.isDone()).toBeTruthy(); - }, - ); +import { Redact } from '../lib'; +import testDataSets from './__dataSets__'; + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, + validateApiKeyAuth, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateApiKeyAuth, + }, + requests: [test.request] as TestRequest[], + responses: [test.response] as TestResponse[], + client: new Redact(apiKeyAuth), + clientMethod: test.clientMethod as keyof Redact, + parameters: test.parameters, + generator: false, + error: 'error' in test ? String(test.error) : false, + expected: undefined, + }; + }), + }; }); + +VonageTest(applicationsTest); diff --git a/packages/redact/lib/index.ts b/packages/redact/lib/index.ts index 6794ace0..ef388ba7 100644 --- a/packages/redact/lib/index.ts +++ b/packages/redact/lib/index.ts @@ -1,4 +1,4 @@ -export * from './enums/index'; -export * from './interfaces/index'; -export * from './types/index'; +export * from './enums'; +export * from './interfaces'; +export * from './types'; export * from './redact'; diff --git a/packages/redact/lib/interfaces/index.ts b/packages/redact/lib/interfaces/index.ts index d26fa4e8..a0517597 100644 --- a/packages/redact/lib/interfaces/index.ts +++ b/packages/redact/lib/interfaces/index.ts @@ -1,2 +1,2 @@ -export * from './request/index'; -export * from './response/index'; +export * from './request'; +export * from './response'; diff --git a/packages/redact/package.json b/packages/redact/package.json index 438003d0..f8570e7a 100644 --- a/packages/redact/package.json +++ b/packages/redact/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -40,10 +41,6 @@ "dependencies": { "@vonage/server-client": "^1.12.0" }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "^13.3.4" - }, "publishConfig": { "directory": "dist" } diff --git a/packages/redact/tsconfig.json b/packages/redact/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/redact/tsconfig.json +++ b/packages/redact/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/server-client/__tests__/__dataSets__/camelCase.ts b/packages/server-client/__tests__/__dataSets__/camelCase.ts index 7c753062..7f686789 100644 --- a/packages/server-client/__tests__/__dataSets__/camelCase.ts +++ b/packages/server-client/__tests__/__dataSets__/camelCase.ts @@ -1,7 +1,9 @@ +import { camelCaseObjectKeys } from '../../lib'; + export default [ { label: 'Transform to camel case', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: 'fizz_buzz', }, @@ -15,7 +17,7 @@ export default [ }, { label: 'Transform to camel has no effect', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { fooBar: 'fizz_buzz', }, @@ -29,7 +31,7 @@ export default [ }, { label: 'Transform to camel will preserves key', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: 'fizz_buzz', }, @@ -44,7 +46,7 @@ export default [ }, { label: 'Transform to camel uses transformed key', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: 'fizz_buzz', fooBar: 'baz_bat', @@ -59,7 +61,7 @@ export default [ }, { label: 'Transform to camel deep', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: { fizz_buzz: { @@ -81,7 +83,7 @@ export default [ }, { label: 'Transform to camel deep with array (prevents object confusion)', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: ['fizz_buzz', 'baz_bat'], }, @@ -95,7 +97,7 @@ export default [ }, { label: 'Transform to camel deep with null (prevents object confusion)', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: null, }, @@ -109,7 +111,7 @@ export default [ }, { label: 'Transform to camel deep array only', - transformFn: 'camelCaseObjectKeys', + transformFn: camelCaseObjectKeys, original: { foo_bar: [ { diff --git a/packages/server-client/__tests__/__dataSets__/index.ts b/packages/server-client/__tests__/__dataSets__/index.ts index 1b89ba13..b5841efa 100644 --- a/packages/server-client/__tests__/__dataSets__/index.ts +++ b/packages/server-client/__tests__/__dataSets__/index.ts @@ -1,5 +1,7 @@ import camelCase from './camelCase'; import snakeCase from './snakeCase'; +import kebabCase from './kebabCase'; + import getTests from './get'; import postTests from './post'; import putTests from './put'; @@ -39,4 +41,8 @@ export const transfomTests = [ label: 'Transform Snake Case', tests: snakeCase, }, + { + label: 'Transform Kebab Case', + tests: kebabCase, + }, ]; diff --git a/packages/server-client/__tests__/__dataSets__/kebabCase.ts b/packages/server-client/__tests__/__dataSets__/kebabCase.ts new file mode 100644 index 00000000..be71592a --- /dev/null +++ b/packages/server-client/__tests__/__dataSets__/kebabCase.ts @@ -0,0 +1,113 @@ +import { kebabCaseObjectKeys } from '../../lib'; + +export default [ + { + label: 'Transform to kebab case', + transformFn: kebabCaseObjectKeys, + original: { + fooBar: 'fizz_buzz', + }, + parameters: [ + false, // deep + false, // preserve + ], + expected: { + 'foo-bar': 'fizz_buzz', + }, + }, + { + label: 'Transform to kebab has no effect', + transformFn: kebabCaseObjectKeys, + original: { + foo_bar: 'fizz_buzz', + }, + parameters: [ + false, // deep + false, // preserve + ], + expected: { + 'foo-bar': 'fizz_buzz', + }, + }, + { + label: 'Transform to kebab will preserves key', + transformFn: kebabCaseObjectKeys, + original: { + fooBar: 'fizz_buzz', + }, + parameters: [ + false, // deep + true, // preserve + ], + expected: { + 'foo-bar': 'fizz_buzz', + fooBar: 'fizz_buzz', + }, + }, + { + label: 'Transform to kebab uses transformed key', + transformFn: kebabCaseObjectKeys, + original: { + foo_bar: 'fizz_buzz', + fooBar: 'baz_bat', + }, + parameters: [ + false, // deep + false, // preserve + ], + expected: { + 'foo-bar': 'baz_bat', + }, + }, + { + label: 'Transform to kebab deep', + transformFn: kebabCaseObjectKeys, + original: { + foo_bar: { + fizz_buzz: { + baz_bat: 'qux', + }, + }, + }, + parameters: [ + true, // deep + false, // preserve + ], + expected: { + 'foo-bar': { + 'fizz-buzz': { + 'baz-bat': 'qux', + }, + }, + }, + }, + { + label: 'Transform to kebab deep with array (prevents object confusion)', + transformFn: kebabCaseObjectKeys, + original: { + fooBar: ['fizz_buzz', 'baz_bat'], + }, + parameters: [ + true, // deep + false, // preserve + ], + expected: { + 'foo-bar': ['fizz_buzz', 'baz_bat'], + }, + }, + { + label: 'Transform to kebab deep with null (prevents object confusion)', + transformFn: kebabCaseObjectKeys, + original: { + fooBar: null, + }, + parameters: [ + true, // deep + false, // preserve + ], + expected: { + 'foo-bar': null, + }, + }, +]; + diff --git a/packages/server-client/__tests__/__dataSets__/post.ts b/packages/server-client/__tests__/__dataSets__/post.ts index 6f0c35c1..f8a9705b 100644 --- a/packages/server-client/__tests__/__dataSets__/post.ts +++ b/packages/server-client/__tests__/__dataSets__/post.ts @@ -35,7 +35,7 @@ export default [ }, }, { - label: 'make web post request', + label: 'make post form request', request: [ '/my/path', 'POST', diff --git a/packages/server-client/__tests__/__dataSets__/snakeCase.ts b/packages/server-client/__tests__/__dataSets__/snakeCase.ts index 9dc240ec..9336318c 100644 --- a/packages/server-client/__tests__/__dataSets__/snakeCase.ts +++ b/packages/server-client/__tests__/__dataSets__/snakeCase.ts @@ -1,7 +1,9 @@ +import { snakeCaseObjectKeys } from '../../lib'; + export default [ { label: 'Transform to snake case', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { fooBar: 'fizz_buzz', }, @@ -15,7 +17,7 @@ export default [ }, { label: 'Transform to snake has no effect', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { foo_bar: 'fizz_buzz', }, @@ -29,7 +31,7 @@ export default [ }, { label: 'Transform to snake will preserves key', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { fooBar: 'fizz_buzz', }, @@ -44,7 +46,7 @@ export default [ }, { label: 'Transform to snake uses transformed key', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { foo_bar: 'fizz_buzz', fooBar: 'baz_bat', @@ -59,7 +61,7 @@ export default [ }, { label: 'Transform to snake deep', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { foo_bar: { fizz_buzz: { @@ -81,7 +83,7 @@ export default [ }, { label: 'Transform to snake deep with array (prevents object confusion)', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { fooBar: ['fizz_buzz', 'baz_bat'], }, @@ -95,7 +97,7 @@ export default [ }, { label: 'Transform to snake deep with null (prevents object confusion)', - transformFn: 'snakeCaseObjectKeys', + transformFn: snakeCaseObjectKeys, original: { fooBar: null, }, diff --git a/packages/server-client/__tests__/client.test.ts b/packages/server-client/__tests__/client.test.ts index c63fe690..5cf00129 100644 --- a/packages/server-client/__tests__/client.test.ts +++ b/packages/server-client/__tests__/client.test.ts @@ -1,122 +1,126 @@ -import nock from 'nock'; -import { Client, AuthenticationType } from '../lib/index'; -import { requestTests, transfomTests } from './__dataSets__/index'; -import { getScope, getClient, BASE_URL, API_SECRET, API_KEY } from './common'; - -describe.each(transfomTests)('$label', ({ tests }) => { - test.each(tests)( - 'Can $label [using $transformFn]', - async ({ transformFn, original, parameters, expected }) => { - expect(Client.transformers[transformFn]).toBeDefined(); - const results = Client.transformers[transformFn](original, ...parameters); - - expect(results).toEqual(expected); - } - ); - - test('Can omit keys', async () => { - const original = Object.freeze({ - foo: 'bar', - fizz: 'buzz', - }); - expect(Client.transformers.omit(['foo'], original)).toEqual({fizz: 'buzz'}); - }); -}); - -describe.each(requestTests)('$label', ({ tests }) => { - afterEach(() => { - nock.cleanAll(); - }); - - const successTests = tests - .filter(({ error }) => !error) - .map((test) => { - const request = test.request; - // Add on query testing - const url = new URL(`${BASE_URL}${request[0]}`); - url.searchParams.append('api_key', API_KEY); - url.searchParams.append('api_secret', API_SECRET); - - const keyTest = { - ...test, - request: [ - ...request.slice(0, 2), - { - ...request[2], - api_key: API_KEY, - api_secret: API_SECRET, - }, - ], - authType: AuthenticationType.KEY_SECRET, +import { Client, AuthenticationType } from '../lib'; +import { requestTests } from './__dataSets__'; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKey, + apiSecret, + keyAuth, + apiKeyAuth, + validateApiKeyAuth, +} from '../../../testHelpers'; + +class JWTAuthClient extends Client { + protected authType = AuthenticationType.JWT; +} + +class KeyAuthClient extends Client { + protected authType = AuthenticationType.KEY_SECRET; +} + +class QueryAuthClient extends Client { + protected authType = AuthenticationType.QUERY_KEY_SECRET; +} + +class BasicAuthClient extends Client { + protected authType = AuthenticationType.BASIC; +} + +type AnyClient = JWTAuthClient | KeyAuthClient | QueryAuthClient | BasicAuthClient; + +const methodsThatHaveBodies = ['PUT', 'POST', 'PATCH']; + +const applicationsTest = requestTests.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): Array> => { + const commonTest = { + label: test.label, + baseUrl: 'https://api.nexmo.com', + requests: [test.request] as TestRequest[], + responses: [test.response] as TestResponse[], + clientMethod: test.clientMethod as keyof Client, + parameters: test.parameters, + generator: false, + error: 'error' in test ? String(test.error) : false, + expected: test.expected, }; - if (test.form && request[2]) { - const params = new URLSearchParams(request[2]); - params.sort(); - request[2] = params.toString(); + const request = test.request; + const [path, method, body] = request; - const keyParams = new URLSearchParams(keyTest.request[2]); - keyParams.sort(); - keyTest.request[2] = keyParams.toString(); + // Add on query testing + const url = new URL(`https://api.nexmo.com${path}`); + url.searchParams.set('api_key', apiKey); + url.searchParams.set('api_secret', apiSecret); + + const isForm = 'form' in test; + const bodyParams = new URLSearchParams(body); + const bodyWithAPIKeys = body ? { + ...body as Record, + api_key: apiKey, + api_secret: apiSecret, + } : body; + + if (methodsThatHaveBodies.includes(method as string)) { + bodyParams.set('api_key', apiKey); + bodyParams.set('api_secret', apiSecret); + bodyParams.sort(); } - const bodyMethods = ['PUT', 'POST', 'PATCH']; - const method = request[1]; - return [ + // Key Client { - ...test, - authType: AuthenticationType.BASIC, + ...commonTest, + client: new KeyAuthClient(apiKeyAuth), + label: `${test.label} using a API Key/Secret Client`, + requests: [[ + path, + method as unknown, + isForm ? bodyParams.toString() : bodyWithAPIKeys, + ]] as TestRequest[], }, + + // Query Client { - ...test, - authType: AuthenticationType.JWT, + ...commonTest, + client: new QueryAuthClient(apiKeyAuth), + label: `${test.label} using a Query String Client`, + requests: [[ + `${url.pathname}${url.search}`, + method as unknown, + body + ]] as TestRequest[], }, + + // Basic Client { - ...test, - request: [`${url.pathname}${url.search}`, ...request.slice(1)], - authType: AuthenticationType.QUERY_KEY_SECRET, + ...commonTest, + client: new BasicAuthClient(apiKeyAuth), + reqHeaders: { + authorization: validateApiKeyAuth, + }, + label: `${test.label} using an API Key/Secret Client`, }, - bodyMethods.includes(method) ? keyTest : null, - ].filter((value) => value); - }) - .flat(); - - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label with $clientMethod using $authType auth', - async ({ - request, - response, - clientMethod, - expected, - parameters, - authType = AuthenticationType.BASIC, - }) => { - const scope = getScope(authType); - const client = getClient(authType); - scope.intercept(...request).reply(...response); - - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - } - ); - - if (failureTests.length < 1) { - return; - } - - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); - - await expect(() => client[clientMethod](...parameters)).rejects.toThrow( - error - ); - expect(nock.isDone()).toBeTruthy(); - } - ); + + // JWT Client + { + ...commonTest, + client: new JWTAuthClient(keyAuth), + reqHeaders: { + //authorization: validateApiKeyAuth, + }, + label: `${test.label} using a JWT Client`, + } + ]; + }).flat(), + }; }); + +VonageTest(applicationsTest); + diff --git a/packages/server-client/__tests__/common.ts b/packages/server-client/__tests__/common.ts index e14e33c9..68a7132f 100644 --- a/packages/server-client/__tests__/common.ts +++ b/packages/server-client/__tests__/common.ts @@ -1,88 +1 @@ -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { readFileSync } from 'fs'; -import { AuthenticationType, Client } from '../lib/index'; - -export class JWTAuthClient extends Client { - protected authType = AuthenticationType.JWT; -} - -export class KeyAuthClient extends Client { - protected authType = AuthenticationType.KEY_SECRET; -} - -export class QueryAuthClient extends Client { - protected authType = AuthenticationType.QUERY_KEY_SECRET; -} - -export class BasicAuthClient extends Client { - protected authType = AuthenticationType.BASIC; -} - -export const API_KEY = '1234'; -export const API_SECRET = 'ABCDEF'; -export const PRIVATE_KEY_FILE = `${__dirname}/private.test.key`; -export const PRIVATE_KEY = readFileSync(PRIVATE_KEY_FILE).toString(); export const BASE_URL = 'https://api.nexmo.com'; -export const APP_ID = 'abcd-1234'; - -export const checkJWTAuth = (value) => value.startsWith('Bearer '); - -export const checkBasicAuth = (value) => value === 'Basic MTIzNDpBQkNERUY='; - -const scopes = { - [AuthenticationType.JWT]: nock(BASE_URL, { - reqheaders: { - Authorization: checkJWTAuth, - }, - }).persist(), - [AuthenticationType.BASIC]: nock(BASE_URL, { - reqheaders: { - Authorization: checkBasicAuth, - }, - }).persist(), - [AuthenticationType.KEY_SECRET]: nock(BASE_URL).persist(), - [AuthenticationType.QUERY_KEY_SECRET]: nock(BASE_URL).persist(), -}; - -const auths = { - [AuthenticationType.JWT]: new Auth({ - applicationId: APP_ID, - privateKey: PRIVATE_KEY, - }), - [AuthenticationType.BASIC]: new Auth({ - apiKey: API_KEY, - apiSecret: API_SECRET, - }), - [AuthenticationType.KEY_SECRET]: new Auth({ - apiKey: API_KEY, - apiSecret: API_SECRET, - }), - [AuthenticationType.QUERY_KEY_SECRET]: new Auth({ - apiKey: API_KEY, - apiSecret: API_SECRET, - }), -}; - -export const getAuth = (authType: AuthenticationType): Auth => auths[authType]; - -const clients = { - [AuthenticationType.JWT]: new JWTAuthClient( - getAuth(AuthenticationType.JWT), - ), - [AuthenticationType.BASIC]: new BasicAuthClient( - getAuth(AuthenticationType.BASIC), - ), - [AuthenticationType.KEY_SECRET]: new KeyAuthClient( - getAuth(AuthenticationType.KEY_SECRET), - ), - [AuthenticationType.QUERY_KEY_SECRET]: new QueryAuthClient( - getAuth(AuthenticationType.QUERY_KEY_SECRET), - ), -}; - -export const getClient = (authType: AuthenticationType): Client => - clients[authType]; - -// eslint-disable-next-line max-len -export const getScope = (authType: AuthenticationType): nock => scopes[authType]; diff --git a/packages/server-client/__tests__/file.test.ts b/packages/server-client/__tests__/file.test.ts index 2ee3a50a..2ea6d01e 100644 --- a/packages/server-client/__tests__/file.test.ts +++ b/packages/server-client/__tests__/file.test.ts @@ -4,24 +4,21 @@ import { BASE_URL } from './common'; import { Auth } from '@vonage/auth'; import { mkdirSync, readFileSync, existsSync } from 'fs'; import { rm } from 'fs/promises'; +import { keyAuth } from '../../../testHelpers/'; const FILE_PATH = `${process.cwd()}/test-path`; -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - describe('File tests', () => { - let client; - let scope; + let client: FileClient; + let scope: nock.Scope; beforeEach(() => { if (!existsSync(FILE_PATH)) { mkdirSync(FILE_PATH); } + client = new FileClient( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), + new Auth(keyAuth), ); scope = nock(BASE_URL, { @@ -32,8 +29,6 @@ describe('File tests', () => { }); afterEach(async () => { - client = null; - scope = null; nock.cleanAll(); await rm(FILE_PATH, { @@ -43,17 +38,17 @@ describe('File tests', () => { }); test('Can download file with url', async () => { - const content = "Ford, I think I'm a couch"; + const content = 'Ford, I think I\'m a couch'; const file = `${FILE_PATH}/my-file.txt`; scope - .get(`/v1/files/00000000-0000-0000-0000-000000000001`) + .get('/v1/files/00000000-0000-0000-0000-000000000001') .reply(200, content); expect(existsSync(file)).toBeFalsy(); expect( await client.downloadFile( - `https://api.nexmo.com/v1/files/00000000-0000-0000-0000-000000000001`, + 'https://api.nexmo.com/v1/files/00000000-0000-0000-0000-000000000001', file, ), ).toBeUndefined(); @@ -64,10 +59,10 @@ describe('File tests', () => { }); test('Can download file with id', async () => { - const content = "Ford, I think I'm a couch"; + const content = 'Ford, I think I\'m a couch'; const file = `${FILE_PATH}/my-file.txt`; scope - .get(`/v1/files/00000000-0000-0000-0000-000000000001`) + .get('/v1/files/00000000-0000-0000-0000-000000000001') .reply(200, content); expect(existsSync(file)).toBeFalsy(); @@ -83,16 +78,16 @@ describe('File tests', () => { test('Can download multiple files', async () => { const file = `${FILE_PATH}/my-file.txt`; - const content = "Ford, I think I'm a couch"; + const content = 'Ford, I think I\'m a couch'; const file2 = `${FILE_PATH}/my-file2.txt`; - const content2 = "I know how you feel."; + const content2 = 'I know how you feel.'; scope - .get(`/v1/files/00000000-0000-0000-0000-000000000001`) + .get('/v1/files/00000000-0000-0000-0000-000000000001') .delay(1000) .reply(200, content) - .get(`/v1/files/00000000-0000-0000-0000-000000000002`) + .get('/v1/files/00000000-0000-0000-0000-000000000002') .delay(800) .reply(200, content2); diff --git a/packages/server-client/__tests__/private.test.key b/packages/server-client/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/server-client/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/server-client/__tests__/transform.test.ts b/packages/server-client/__tests__/transform.test.ts new file mode 100644 index 00000000..93e55664 --- /dev/null +++ b/packages/server-client/__tests__/transform.test.ts @@ -0,0 +1,60 @@ +import { transfomTests } from './__dataSets__'; +import { Client } from '../lib'; +import { + ObjectToTransform, + TransformedObject, + PartialTransformFunction +} from '../lib/transformers'; + + +type TransformTestCase = { + label: string; + transformFn: PartialTransformFunction, + original: ObjectToTransform; + parameters: [boolean, boolean]; + expected: TransformedObject; +}; + +describe.each(transfomTests)( + '$label', + ({ tests }) => { + + const testCases: Array = tests.map( + ({ label, ...rest }) => ({ label, ...rest }) as unknown as TransformTestCase + ); + + test.each(testCases)( + 'Can $label [using $transformFn]', + async ({ + transformFn, + original, + parameters, + expected + }) => { + const notMutated = Object.freeze(Object.assign({}, original)); + expect(transformFn.name in Client.transformers).toBeTruthy(); + const results = transformFn( + original, + ...parameters as [boolean, boolean] + ); + + expect(results).toEqual(expected); + + // Ensure the original object is not mutated. + expect(original).toEqual(notMutated); + } + ); + }); + +describe('Omit Test', () => { + test('Can omit keys', async () => { + const original = { + foo: 'bar', + fizz: 'buzz', + }; + + expect(Client.transformers.omit(['foo'], original)).toEqual({fizz: 'buzz'}); + // Ensure the original object is not mutated. + expect(original).toEqual({foo: 'bar', fizz: 'buzz'}); + }); +}); diff --git a/packages/server-client/lib/client.ts b/packages/server-client/lib/client.ts index c3ba3663..755c178a 100644 --- a/packages/server-client/lib/client.ts +++ b/packages/server-client/lib/client.ts @@ -10,9 +10,15 @@ import { VetchError, } from '@vonage/vetch'; import { AuthenticationType } from './enums'; -import * as transfomers from './transformers'; +import { + camelCaseObjectKeys, + kebabCaseObjectKeys, + snakeCaseObjectKeys, + omit, + PartialTransformFunction, +} from './transformers'; import debug from 'debug'; -import { ConfigParams } from './types'; +import { ConfigParams } from './types/index'; const log = debug('vonage:server-client'); @@ -20,7 +26,12 @@ export class Client { /** * Static property containing utility transformers. */ - public static transformers = transfomers; + public static transformers = { + 'camelCaseObjectKeys': camelCaseObjectKeys as PartialTransformFunction, + 'snakeCaseObjectKeys': snakeCaseObjectKeys as PartialTransformFunction, + 'kebabCaseObjectKeys': kebabCaseObjectKeys as PartialTransformFunction, + 'omit': omit, + }; /** * The type of authentication used for the client's requests. @@ -95,7 +106,7 @@ export class Client { } if (this.authType === AuthenticationType.QUERY_KEY_SECRET) { - log(`adding parameters to query string`); + log('adding parameters to query string'); request.params = { ...(request.params ? request.params : {}), ...(await this.auth.getQueryParams({})), @@ -111,7 +122,7 @@ export class Client { request.data = request.data ?? {}; // JSON as default - log(`Adding parameters to body`); + log('Adding parameters to body'); request.data = { ...request.data, ...authParams, @@ -291,7 +302,7 @@ export class Client { request.headers = { ...request.headers, 'user-agent': [ - `@vonage/server-sdk/3.0.0`, + '@vonage/server-sdk/3.0.0', ` node/${process.version.replace('v', '')}`, this.config.appendUserAgent ? ` ${this.config.appendUserAgent}` : '', ].join(), @@ -371,7 +382,7 @@ export class Client { } log('Request succeeded'); - // eslint-disable-next-line max-len + const [contentType] = (response.headers.get('content-type') || '').split( ';', ); diff --git a/packages/server-client/lib/fileClient.ts b/packages/server-client/lib/fileClient.ts index 3f2b6575..562117c8 100644 --- a/packages/server-client/lib/fileClient.ts +++ b/packages/server-client/lib/fileClient.ts @@ -34,8 +34,9 @@ export class FileClient extends Client { try { const fileURL = new URL(file); fileId = fileURL.pathname.split('/').pop() || ''; + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (_) { - log(`Not a url`); + log('Not a url'); } log(`File Id ${fileId}`); diff --git a/packages/server-client/lib/index.ts b/packages/server-client/lib/index.ts index 2a58bd15..87c3085c 100644 --- a/packages/server-client/lib/index.ts +++ b/packages/server-client/lib/index.ts @@ -1,5 +1,5 @@ -export { Client } from './client'; +export * from './client'; export * from './enums/'; -export * from './types'; +export * from './types/'; export * from './transformers'; export * from './fileClient'; diff --git a/packages/server-client/lib/transformers.ts b/packages/server-client/lib/transformers.ts index 184af533..bd789470 100644 --- a/packages/server-client/lib/transformers.ts +++ b/packages/server-client/lib/transformers.ts @@ -1,11 +1,36 @@ import camelCase from 'lodash.camelcase'; import snakeCase from 'lodash.snakecase'; import kebabCase from 'lodash.kebabcase'; -import partial from 'lodash.partial'; import isObject from 'lodash.isobject'; export type TransformFunction = (key: string) => string; +export type ObjectToTransform = Record; + +export type TransformedObject = Record; + +export type TransformFunctionPartialParams = [ObjectToTransform, boolean, boolean]; + +export type PartialTransformFunction = ( + objectToTransform: ObjectToTransform, + deep?: boolean, + preserve?: boolean, +) => TransformedObject; + +export type TransformObjectKeys = ( + transformFn: TransformFunction, + objectToTransform: ObjectToTransform, + deep?: boolean, + preserve?: boolean, +) => TransformedObject; + +export type OmitFunction = ( + keys: Array, + obj: ObjectToTransform, +) => TransformedObject; + +export type AnyTransformFunction = PartialTransformFunction | TransformObjectKeys | OmitFunction; + /** * Transforms the keys of an object based on a provided transformation function. * @@ -13,16 +38,15 @@ export type TransformFunction = (key: string) => string; * @param {Record} objectToTransform - The object whose keys are to be transformed. * @param {boolean} [deep=false] - Whether to deeply transform nested object keys. * @param {boolean} [preserve=false] - Whether to preserve the original object's keys. - * * @return {Record} A new object with transformed keys. */ -export const transformObjectKeys = ( +export const transformObjectKeys = ( transformFn: TransformFunction, - objectToTransform: Record, + objectToTransform: O, deep = false, preserve = false, -): Record => { - const transformedObject = { +): T => { + const transformedObject: ObjectToTransform = { ...(preserve ? objectToTransform : {}), }; @@ -60,7 +84,7 @@ export const transformObjectKeys = ( ); } - return transformedObject; + return transformedObject as T; }; /** @@ -71,7 +95,10 @@ export const transformObjectKeys = ( * @param {boolean} [preserve=false] - Whether to preserve the original object's keys. * @return {Record} A new object with camelCased keys. */ -export const camelCaseObjectKeys = partial(transformObjectKeys, camelCase); +export const camelCaseObjectKeys = (...rest: TransformFunctionPartialParams) => transformObjectKeys( + camelCase, + ...rest, +); /** * Transforms the keys of an object to snake_case. @@ -81,7 +108,10 @@ export const camelCaseObjectKeys = partial(transformObjectKeys, camelCase); * @param {boolean} [preserve=false] - Whether to preserve the original object's keys. * @return {Record} A new object with snake_cased keys. */ -export const snakeCaseObjectKeys = partial(transformObjectKeys, snakeCase); +export const snakeCaseObjectKeys = (...rest: TransformFunctionPartialParams) => transformObjectKeys( + snakeCase, + ...rest, +); /** * Transforms the keys of an object to kebab-case. @@ -91,7 +121,10 @@ export const snakeCaseObjectKeys = partial(transformObjectKeys, snakeCase); * @param {boolean} [preserve=false] - Whether to preserve the original object's keys. * @return {Record} A new object with kebab-cased keys. */ -export const kebabCaseObjectKeys = partial(transformObjectKeys, kebabCase); +export const kebabCaseObjectKeys = (...rest: TransformFunctionPartialParams) => transformObjectKeys( + kebabCase, + ...rest, +); /** @@ -104,8 +137,8 @@ export const kebabCaseObjectKeys = partial(transformObjectKeys, kebabCase); */ export const omit = ( keys: Array, - obj: Record, -): Record => + obj: ObjectToTransform, +): TransformedObject => Object.fromEntries( Object.entries(obj) .filter(([key]) => !keys.includes(key)), diff --git a/packages/server-client/lib/types.ts b/packages/server-client/lib/types.ts index a3d3b4a0..fcb073fe 100644 --- a/packages/server-client/lib/types.ts +++ b/packages/server-client/lib/types.ts @@ -1 +1 @@ -export * from './types/index'; +export * from './types'; diff --git a/packages/server-client/package.json b/packages/server-client/package.json index c8e9f507..405a0eba 100644 --- a/packages/server-client/package.json +++ b/packages/server-client/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "dist", "test": "__tests__" @@ -43,7 +44,6 @@ "lodash.camelcase": "^4.3.0", "lodash.isobject": "3.0.2", "lodash.kebabcase": "^4.1.1", - "lodash.partial": "^4.2.1", "lodash.snakecase": "^4.1.1", "node-fetch": "^2" }, @@ -51,7 +51,6 @@ "@types/lodash.camelcase": "4.3.7", "@types/lodash.isobject": "3.0.7", "@types/lodash.kebabcase": "4.1.7", - "@types/lodash.partial": "4.2.7", "@types/lodash.snakecase": "4.1.7", "@types/node-fetch": "2.6.6", "nock": "^13.3.4" diff --git a/packages/server-client/tsconfig.json b/packages/server-client/tsconfig.json index bb6870a4..ae662c3f 100644 --- a/packages/server-client/tsconfig.json +++ b/packages/server-client/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/server-sdk/__tests__/server-sdk.test.ts b/packages/server-sdk/__tests__/server-sdk.test.ts index aa3b7809..37e35ed7 100644 --- a/packages/server-sdk/__tests__/server-sdk.test.ts +++ b/packages/server-sdk/__tests__/server-sdk.test.ts @@ -1,5 +1,5 @@ import { Auth } from '@vonage/auth'; -import { Vonage } from '../lib/index'; +import { Vonage } from '../lib'; describe('sdk', () => { test('client gets created', async () => { diff --git a/packages/server-sdk/package.json b/packages/server-sdk/package.json index 15d2c8db..5835d573 100644 --- a/packages/server-sdk/package.json +++ b/packages/server-sdk/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "directories": { "lib": "dist", "test": "__tests__" diff --git a/packages/server-sdk/tsconfig.json b/packages/server-sdk/tsconfig.json index 1b4ac550..9a0ec3a9 100644 --- a/packages/server-sdk/tsconfig.json +++ b/packages/server-sdk/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ @@ -22,13 +22,14 @@ { "path": "../number-insights" }, { "path": "../numbers" }, { "path": "../pricing" }, + { "path": "../redact" }, { "path": "../server-client" }, { "path": "../sms" }, { "path": "../users" }, - { "path": "../redact" }, { "path": "../verify" }, { "path": "../verify2" }, { "path": "../vetch" }, + { "path": "../video" }, { "path": "../voice" } ], diff --git a/packages/sms/__tests__/__dataSets__/signature.ts b/packages/sms/__tests__/__dataSets__/signature.ts index 1fe7d253..88b4eda8 100644 --- a/packages/sms/__tests__/__dataSets__/signature.ts +++ b/packages/sms/__tests__/__dataSets__/signature.ts @@ -74,7 +74,7 @@ export default [ type: 'text', }, algorithm: AlgorithmTypes.sha512hmac, - signature: `E0D3C650F8C9D1A5C174D10DDDBFB003E561F59B265616208B0487C5D819481CD3C311D59CF6165ECD1139622D5BA3A256C0D763AC4A9AD9144B5A426B94FE82`, + signature: 'E0D3C650F8C9D1A5C174D10DDDBFB003E561F59B265616208B0487C5D819481CD3C311D59CF6165ECD1139622D5BA3A256C0D763AC4A9AD9144B5A426B94FE82', signatureSecret: 'my_secret_key_for_testing', }, ]; diff --git a/packages/sms/__tests__/__dataSets__/sms.ts b/packages/sms/__tests__/__dataSets__/sms.ts index 147ecded..9f86069b 100644 --- a/packages/sms/__tests__/__dataSets__/sms.ts +++ b/packages/sms/__tests__/__dataSets__/sms.ts @@ -1,17 +1,17 @@ +import { apiKey, apiSecret} from '../../../../testHelpers'; import { + MessageClassEnum, + SMSStatus, + TypeEnum, MessageSendAllFailure, MessageSendPartialFailure, -} from '../../lib/classes'; -import { MessageClassEnum, SMSStatus, TypeEnum } from '../../lib/enums/index'; -import { SMSResponse, SMSMessageResponse, Message, ErrorMessage, SMSMessages, - SMSRequestBody, -} from '../../lib/interfaces/index'; -import { SMSParams } from '../../lib/types/index'; + SMSParams, +} from '../../lib'; export default [ { @@ -20,14 +20,13 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '14152739164', text: 'too many secrets', - } as SMSRequestBody, + }, ], - error: null, response: [ 200, { @@ -77,8 +76,8 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '19162255887', text: 'I\'ll always dial the "K" for you', @@ -90,9 +89,8 @@ export default [ 'client-ref': 'my client ref', 'entity-id': '1101456324675322134', 'content-id': '1107457532145798767', - } as SMSRequestBody, + }, ], - error: null, response: [ 200, { @@ -150,15 +148,14 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '18187779311', text: 'Whats your number? ⏳', type: TypeEnum.UNICODE, - } as SMSRequestBody, + }, ], - error: null, response: [ 200, { @@ -209,17 +206,16 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '18186345789', type: TypeEnum.BINARY, body: '0011223344556677', udh: '06050415811581', 'protocol-id': 127, - } as SMSRequestBody, + }, ], - error: null, response: [ 200, { @@ -272,12 +268,12 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '14152739164', text: 'too many secrets', - } as SMSRequestBody, + } ], error: new MessageSendAllFailure({ 'message-count': 1, @@ -318,12 +314,12 @@ export default [ '/sms/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, from: '12126875309', to: '14152739164', text: 'too many secrets', - } as SMSRequestBody, + } ], error: new MessageSendPartialFailure({ 'message-count': 1, diff --git a/packages/sms/__tests__/sms.test.ts b/packages/sms/__tests__/sms.test.ts index a3a96505..156f1cb6 100644 --- a/packages/sms/__tests__/sms.test.ts +++ b/packages/sms/__tests__/sms.test.ts @@ -1,61 +1,36 @@ -import { SMS } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import testSignatureDataSets from './__dataSets__/signature'; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new SMS(new Auth({ apiKey: '12345', apiSecret: 'ABCDE' })); - scope = nock(BASE_URL).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ request, response, clientMethod, expected, parameters }) => { - scope.intercept(...request).reply(...response); - - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); - - if (failureTests.length < 1) { - return; - } - - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); +import { SMS } from '../lib'; +import testDataSets from './__dataSets__'; + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://rest.nexmo.com', + requests: [test.request] as TestRequest[], + responses: [test.response] as TestResponse[], + client: new SMS(apiKeyAuth), + clientMethod: test.clientMethod as keyof SMS, + parameters: test.parameters, + generator: false, + error: 'error' in test ? test.error as Error : false, + expected: test.expected, + }; + }), + }; +}); - await expect(() => client[clientMethod](...parameters)).rejects.toThrow( - error, - ); - expect(nock.isDone()).toBeTruthy(); - }, - ); +VonageTest(applicationsTest); - test.each(testSignatureDataSets)( - 'Testing signature using $algorithm', - async ({ expected, params, algorithm, signature, signatureSecret }) => { - expect( - client.verifySignature(signature, params, signatureSecret, algorithm), - ).toEqual(expected); - }, - ); -}); diff --git a/packages/sms/lib/classes/index.ts b/packages/sms/lib/classes/index.ts index f00ae962..ae6e95d0 100644 --- a/packages/sms/lib/classes/index.ts +++ b/packages/sms/lib/classes/index.ts @@ -1 +1 @@ -export * from './Error/index'; +export * from './Error'; diff --git a/packages/sms/package.json b/packages/sms/package.json index 73952fe9..6f22aec5 100644 --- a/packages/sms/package.json +++ b/packages/sms/package.json @@ -26,8 +26,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "dist", "test": "__tests__" @@ -42,11 +43,8 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@vonage/server-client": "^1.12.0" - }, - "devDependencies": { "@vonage/auth": "^1.10.0", - "nock": "^13.3.4" + "@vonage/server-client": "^1.12.0" }, "publishConfig": { "directory": "dist" diff --git a/packages/sms/tsconfig.json b/packages/sms/tsconfig.json index 4365c435..12e0d8fb 100644 --- a/packages/sms/tsconfig.json +++ b/packages/sms/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/subaccounts/__tests__/__dataSets__/subAccounts.ts b/packages/subaccounts/__tests__/__dataSets__/subAccounts.ts index ad484d13..2c744ca3 100644 --- a/packages/subaccounts/__tests__/__dataSets__/subAccounts.ts +++ b/packages/subaccounts/__tests__/__dataSets__/subAccounts.ts @@ -1,3 +1,4 @@ +import { apiKey } from '../../../../testHelpers'; import { Client } from '@vonage/server-client'; import { Account, @@ -10,7 +11,7 @@ import { } from '../../lib/types'; const primaryAccount = { - apiKey: '12345', + apiKey: apiKey, name: 'Primary Account', balance: 2373, creditLimit: 0.0, diff --git a/packages/subaccounts/__tests__/__dataSets__/transfers.ts b/packages/subaccounts/__tests__/__dataSets__/transfers.ts index e6076ad0..24629a3d 100644 --- a/packages/subaccounts/__tests__/__dataSets__/transfers.ts +++ b/packages/subaccounts/__tests__/__dataSets__/transfers.ts @@ -1,3 +1,4 @@ +import { apiKey } from '../../../../testHelpers'; import { Client } from '@vonage/server-client'; import { NumberTransfer, @@ -9,10 +10,9 @@ import { CreditTransfer, CreditTransferParameters, CreditTransferListParameters, -} from '../../lib/types'; -import { BASE_URL } from '../common'; +} from '../../lib'; -const API_KEY = '12345'; +const API_KEY = apiKey; const numberTransfer = { from: 'primary', @@ -26,7 +26,7 @@ const balanceTransfer = { amount: 123.45, from: 'primary', to: 'sub', - reference: "Let's rock and roll!", + reference: 'Let\'s rock and roll!', createdAt: '2063-04-05T18:00:00.000Z', } as BalanceTransfer; @@ -35,7 +35,7 @@ const creditTransfer = { amount: 123.45, from: 'primary', to: 'sub', - reference: "Let's rock and roll!", + reference: 'Let\'s rock and roll!', createdAt: '2063-04-05T18:00:00.000Z', } as CreditTransfer; @@ -77,7 +77,7 @@ export default [ }, ], }, - } as BalanceTransferResponsePage, + } ], ], clientMethod: 'listBalanceTransfers', diff --git a/packages/subaccounts/__tests__/subaccount.test.ts b/packages/subaccounts/__tests__/subaccount.test.ts index 1b5f5d67..a5b78b72 100644 --- a/packages/subaccounts/__tests__/subaccount.test.ts +++ b/packages/subaccounts/__tests__/subaccount.test.ts @@ -1,46 +1,40 @@ -import { SubAccounts } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; +import { SubAccounts } from '../lib'; +import testDataSets from './__dataSets__'; -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, + validateApiKeyAuth, +} from '../../../testHelpers'; - beforeEach(function () { - client = new SubAccounts( - new Auth({ - apiKey: '12345', - apiSecret: 'ABCDE', - }) - ); - scope = nock(BASE_URL, { - reqheaders: { - authorization: 'Basic MTIzNDU6QUJDREU=', - }, - }).persist(); - }); +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ requests, responses, clientMethod, parameters, expected }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateApiKeyAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new SubAccounts(apiKeyAuth), + clientMethod: test.clientMethod as keyof SubAccounts, + parameters: test.parameters, + generator: false, + error: test.error || false, + expected: test.expected, + }; + }), + }; +}); - const results = await client[clientMethod](...parameters); +VonageTest(applicationsTest); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - } - ); -}); diff --git a/packages/subaccounts/lib/index.ts b/packages/subaccounts/lib/index.ts index e60099ce..ec020f41 100644 --- a/packages/subaccounts/lib/index.ts +++ b/packages/subaccounts/lib/index.ts @@ -1,2 +1,2 @@ -export * from './types/index'; +export * from './types'; export * from './subaccount'; diff --git a/packages/subaccounts/lib/types/index.ts b/packages/subaccounts/lib/types/index.ts index d90b6ef2..da1ada51 100644 --- a/packages/subaccounts/lib/types/index.ts +++ b/packages/subaccounts/lib/types/index.ts @@ -1,8 +1,8 @@ export * from './account'; export * from './balanceTransfer'; export * from './creditTransfer'; -export * from './parameters/index'; -export * from './requests/index'; -export * from './responses/index'; +export * from './parameters'; +export * from './requests'; +export * from './responses'; export * from './numberTransfer'; export * from './subAccount'; diff --git a/packages/subaccounts/package.json b/packages/subaccounts/package.json index 3313cae9..93a6412a 100644 --- a/packages/subaccounts/package.json +++ b/packages/subaccounts/package.json @@ -25,8 +25,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -42,9 +43,5 @@ }, "dependencies": { "@vonage/server-client": "^1.12.0" - }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "^13.3.4" } } diff --git a/packages/subaccounts/tsconfig.json b/packages/subaccounts/tsconfig.json index cd40b0e3..d6b25449 100644 --- a/packages/subaccounts/tsconfig.json +++ b/packages/subaccounts/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/users/__tests__/__dataSets__/create.ts b/packages/users/__tests__/__dataSets__/create.ts index 5ba58c0d..2e7b28ec 100644 --- a/packages/users/__tests__/__dataSets__/create.ts +++ b/packages/users/__tests__/__dataSets__/create.ts @@ -9,7 +9,7 @@ export default [ label: 'create simple user', requests: [ [ - `/v1/users`, + '/v1/users', 'POST', { name: testUserOne.name, @@ -38,7 +38,7 @@ export default [ }, { label: 'create user', - requests: [[`/v1/users`, 'POST', createUser]], + requests: [['/v1/users', 'POST', createUser]], responses: [ [ 200, diff --git a/packages/users/__tests__/__dataSets__/get.ts b/packages/users/__tests__/__dataSets__/get.ts index c90860f9..2a9a74c5 100644 --- a/packages/users/__tests__/__dataSets__/get.ts +++ b/packages/users/__tests__/__dataSets__/get.ts @@ -3,6 +3,17 @@ import { UserResponse } from '../../lib'; import { BASE_URL, testUser } from '../common'; + +const { websocket } = testUser.channels || {}; +let webSocketResponse = {}; +if (websocket) { + webSocketResponse = { + 'content-type': websocket[0].contentType, + 'headers': websocket[0].headers, + 'uri': websocket[0].uri, + }; +} + export default [ { label: 'get user', @@ -20,11 +31,7 @@ export default [ channels: { ...testUser.channels, websocket: [ - { - 'content-type': testUser.channels?.websocket[0].contentType, - headers: testUser.channels?.websocket[0].headers, - uri: testUser.channels?.websocket[0].uri, - }, + webSocketResponse, ], }, _links: { diff --git a/packages/users/__tests__/__dataSets__/list.ts b/packages/users/__tests__/__dataSets__/list.ts index 113d6a8c..1695d93f 100644 --- a/packages/users/__tests__/__dataSets__/list.ts +++ b/packages/users/__tests__/__dataSets__/list.ts @@ -17,7 +17,7 @@ import { export default [ { label: 'get one page', - requests: [[`/v1/users?`, 'GET']], + requests: [['/v1/users?', 'GET']], responses: [ [ 200, @@ -61,7 +61,7 @@ export default [ { label: 'get one page with params', requests: [ - [`/v1/users?page_size=1&order=ASC&cursor=foo&name=user_one`, 'GET'], + ['/v1/users?page_size=1&order=ASC&cursor=foo&name=user_one', 'GET'], ], responses: [ [ @@ -105,8 +105,8 @@ export default [ { label: 'get all pages', requests: [ - [`/v1/users?`, 'GET'], - [`/v1/users?cursor=fizz`, 'GET'], + ['/v1/users?', 'GET'], + ['/v1/users?cursor=fizz', 'GET'], ], responses: [ [ diff --git a/packages/users/__tests__/common.ts b/packages/users/__tests__/common.ts index e75d4fe9..a1a314c2 100644 --- a/packages/users/__tests__/common.ts +++ b/packages/users/__tests__/common.ts @@ -4,14 +4,17 @@ import { UserResponse, UserType, WebSocketChannelResponse } from '../lib'; export const BASE_URL = 'https://api.nexmo.com/'; export const userToApi = (user: UserType): UserResponse => { - const apiUser = Client.transformers.snakeCaseObjectKeys(user, true); + const apiUser = Client.transformers.snakeCaseObjectKeys( + user, + true + ) as UserResponse; if (user.properties) { apiUser.properties = { custom_data: user.properties.customData, }; } - if (user.channels?.websocket) { + if (user?.channels?.websocket) { apiUser.channels.websocket = [ { uri: user.channels.websocket[0].uri, diff --git a/packages/users/__tests__/private.test.key b/packages/users/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/users/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/users/__tests__/user.test.ts b/packages/users/__tests__/user.test.ts index 0a39524f..5b53cb11 100644 --- a/packages/users/__tests__/user.test.ts +++ b/packages/users/__tests__/user.test.ts @@ -1,78 +1,40 @@ -import { Users } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import { readFileSync } from 'fs'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - -const getResults = async ( - generator: boolean, - client: Users, - clientMethod: string, - parameters: Array, -): Promise> => { - if (!generator) { - return await client[clientMethod](...parameters); - } - - const results = []; - for await (const result of client[clientMethod](...parameters)) { - results.push(result as never); - } - - return results; -}; - -describe.each(testDataSets)('$label', ({ tests }) => { - let client: Users | null; - let scope; - - beforeEach(function () { - client = new Users( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), - ); - - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value.startsWith('Bearer '), - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - test.each(tests)( - 'Can $label using: $clientMethod', - async ({ - requests, - responses, - clientMethod, - parameters, - expected, - generator = false, - }) => { - requests.forEach((request, index) => { - scope.intercept(...request).reply(...responses[index]); - }); +import { Users } from '../lib'; +import testDataSets from './__dataSets__'; + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateBearerAuth, + }, + requests: test.requests as TestRequest[], + responses: test.responses as TestResponse[], + client: new Users(keyAuth), + clientMethod: test.clientMethod as keyof Users, + parameters: test.parameters, + generator: test.generator || false, + error: test.error || false, + expected: test.expected, + }; + }), + }; +}); - const results = await getResults( - generator, - client as User, - clientMethod, - parameters, - ); +VonageTest(applicationsTest); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); -}); diff --git a/packages/users/lib/index.ts b/packages/users/lib/index.ts index 64b7b33e..1e4878d7 100644 --- a/packages/users/lib/index.ts +++ b/packages/users/lib/index.ts @@ -1,3 +1,3 @@ -export * from './types/index'; -export * from './enums/index'; +export * from './types'; +export * from './enums'; export * from './user'; diff --git a/packages/users/lib/types/index.ts b/packages/users/lib/types/index.ts index 8925cee2..2d9d5ef8 100644 --- a/packages/users/lib/types/index.ts +++ b/packages/users/lib/types/index.ts @@ -1,9 +1,9 @@ export * from './messengerChannel'; export * from './mmsChannel'; -export * from './parameters/index'; +export * from './parameters'; export * from './pstnChannel'; -export * from './requests/index'; -export * from './responses/index'; +export * from './requests'; +export * from './responses'; export * from './sipChannel'; export * from './smsChannel'; export * from './userType'; diff --git a/packages/users/lib/types/requests/userRequest.ts b/packages/users/lib/types/requests/userRequest.ts index 5c001ecc..5937a34d 100644 --- a/packages/users/lib/types/requests/userRequest.ts +++ b/packages/users/lib/types/requests/userRequest.ts @@ -1,4 +1,4 @@ -import { UserType } from '../index'; +import { UserType } from '..'; import { WebSocketChannelRequest } from './websocketChannelRequest'; /** @@ -29,7 +29,7 @@ export type UserChannelsRequest = { * An array of WebSocket channel requests. */ websocket: Array; -} & Omit, 'websocket'>;; +} & Omit, 'websocket'>; /** * Represents a request to create or update a user. diff --git a/packages/users/package.json b/packages/users/package.json index ab43e767..68787916 100644 --- a/packages/users/package.json +++ b/packages/users/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "dist", "test": "__tests__" @@ -39,9 +40,5 @@ }, "dependencies": { "@vonage/server-client": "^1.12.0" - }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "^13.3.4" } } diff --git a/packages/users/tsconfig.json b/packages/users/tsconfig.json index 8e8615aa..0fe67326 100644 --- a/packages/users/tsconfig.json +++ b/packages/users/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/verify/__tests__/__dataSets__/cancel.ts b/packages/verify/__tests__/__dataSets__/cancel.ts index 88dea83d..0b41204e 100644 --- a/packages/verify/__tests__/__dataSets__/cancel.ts +++ b/packages/verify/__tests__/__dataSets__/cancel.ts @@ -1,10 +1,12 @@ -import { Command, CheckStatus } from '../../lib/enums'; -import { +import { apiKey, apiSecret } from '../../../../testHelpers'; +import { + Command, + CheckStatus, VerifyCancelResponse, VerifyControlErrorResponse, VerifyControl, VerifyControlError, -} from '../../lib/types'; +} from '../../lib'; export default [ { @@ -13,8 +15,8 @@ export default [ '/verify/control/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, request_id: 'abcdef0123456789abcdef0123456789', cmd: 'cancel', }, @@ -40,8 +42,8 @@ export default [ '/verify/control/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, request_id: 'abcdef0123456789abcdef0123456789', cmd: 'cancel', }, diff --git a/packages/verify/__tests__/__dataSets__/check.ts b/packages/verify/__tests__/__dataSets__/check.ts index f5fc9725..313cc922 100644 --- a/packages/verify/__tests__/__dataSets__/check.ts +++ b/packages/verify/__tests__/__dataSets__/check.ts @@ -1,3 +1,4 @@ +import { apiKey, apiSecret } from '../../../../testHelpers'; import { VerifyCheckResponse, VerifyCheck } from '../../lib/types'; export default [ @@ -7,8 +8,8 @@ export default [ '/verify/check/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, request_id: 'abcdef0123456789abcdef0123456789', code: '1234', }, diff --git a/packages/verify/__tests__/__dataSets__/search.ts b/packages/verify/__tests__/__dataSets__/search.ts index e5595c6c..a5fc4fd0 100644 --- a/packages/verify/__tests__/__dataSets__/search.ts +++ b/packages/verify/__tests__/__dataSets__/search.ts @@ -1,18 +1,16 @@ +import { apiKey, apiSecret } from '../../../../testHelpers'; import { VerifySearchResponse, - VerifySearch, VerifySearchErrorResponse, VerifySearchError, -} from '../../lib/types'; -import { SearchStatus, SearchCheckStatus, SearchEventTypes, -} from '../../lib/enums'; +} from '../../lib'; const params = new URLSearchParams({ - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, request_id: 'abcdef0123456789abcdef0123456789', }); @@ -90,7 +88,7 @@ export default [ ], estimated_price_messages_sent: '0.03330000', estimatedPriceMessagesSent: '0.03330000', - } as VerifySearch, + } }, { label: 'search for a request with error', @@ -100,7 +98,7 @@ export default [ { request_id: 'abcdef0123456789abcdef0123456789', status: SearchStatus.FAILED, - error_text: `Your user entered an incorrect code more than three times.`, + error_text: 'Your user entered an incorrect code more than three times.', } as VerifySearchErrorResponse, ], method: 'get', diff --git a/packages/verify/__tests__/__dataSets__/start.ts b/packages/verify/__tests__/__dataSets__/start.ts index fd4f7ee8..cd2dd537 100644 --- a/packages/verify/__tests__/__dataSets__/start.ts +++ b/packages/verify/__tests__/__dataSets__/start.ts @@ -1,17 +1,16 @@ +import { apiKey, apiSecret } from '../../../../testHelpers'; import { CheckStatus, VerifyLanguages, VerifyWorkflows, -} from '../../lib/enums/index'; -import { VerifyRequestResponse, VerifyRequest, VerifyRequestErrorResponse, VerifyError, PSD2Parameters, VerificationParameters, -} from '../../lib/types/index'; -import { PSD2, Verification } from '../../lib/classes/index'; +} from '../../lib'; +import { PSD2, Verification } from '../../lib/classes'; export default [ { @@ -20,8 +19,8 @@ export default [ '/verify/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', brand: 'My Brand', }, @@ -53,8 +52,8 @@ export default [ '/verify/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', brand: 'My Brand', lg: VerifyLanguages.WELSH_UK, @@ -73,9 +72,9 @@ export default [ new Verification( '12128675309', 'My Brand', - null, - null, - null, + undefined, + undefined, + undefined, VerifyLanguages.WELSH_UK, ), ], @@ -91,8 +90,8 @@ export default [ '/verify/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, brand: 'My Brand', number: '12128675309', country: 'us', @@ -140,8 +139,8 @@ export default [ '/verify/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', brand: 'My Brand', }, @@ -151,7 +150,7 @@ export default [ { request_id: 'abcdef0123456789abcdef0123456789', status: CheckStatus.MISSING_REQUIRED_PARAM, - error_text: `Your request is incomplete and missing the mandatory parameter 'number'`, + error_text: 'Your request is incomplete and missing the mandatory parameter \'number\'', network: '305699', } as VerifyRequestErrorResponse, ], @@ -167,8 +166,8 @@ export default [ request_id: 'abcdef0123456789abcdef0123456789', requestId: 'abcdef0123456789abcdef0123456789', status: CheckStatus.MISSING_REQUIRED_PARAM, - error_text: `Your request is incomplete and missing the mandatory parameter 'number'`, - errorText: `Your request is incomplete and missing the mandatory parameter 'number'`, + error_text: 'Your request is incomplete and missing the mandatory parameter \'number\'', + errorText: 'Your request is incomplete and missing the mandatory parameter \'number\'', network: '305699', } as VerifyError, }, @@ -178,8 +177,8 @@ export default [ '/verify/psd2/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', payee: 'My Payee', amount: 42.0, @@ -200,8 +199,8 @@ export default [ '12128675309', 'My Payee', 42.0, - null, - null, + undefined, + undefined, VerifyLanguages.SWEDISH, ), ], @@ -217,8 +216,8 @@ export default [ '/verify/psd2/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', payee: 'My Payee', amount: 42.0, @@ -252,8 +251,8 @@ export default [ '/verify/psd2/json', 'POST', { - api_key: '12345', - api_secret: 'ABCDE', + api_key: apiKey, + api_secret: apiSecret, number: '12128675309', payee: 'My Payee', amount: 42.0, diff --git a/packages/verify/__tests__/verify.test.ts b/packages/verify/__tests__/verify.test.ts index 8dbc841d..ffcfec93 100644 --- a/packages/verify/__tests__/verify.test.ts +++ b/packages/verify/__tests__/verify.test.ts @@ -1,31 +1,38 @@ -import { PSD2, Verification, Verify } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; +import { Verify } from '../lib'; +import testDataSets from './__dataSets__'; -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + apiKeyAuth, +} from '../../../testHelpers'; - beforeEach(function () { - client = new Verify(new Auth({ apiKey: '12345', apiSecret: 'ABCDE' })); - scope = nock(BASE_URL).persist(); - }); +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + }, + requests: [test.request] as TestRequest[], + responses: [test.response] as TestResponse[], + client: new Verify(apiKeyAuth), + clientMethod: test.clientMethod as keyof Verify, + parameters: test.parameters, + generator: false, + error: false, + expected: test.expected, + }; + }), + }; +}); - test.each(tests)( - 'Can $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, expected }) => { - scope.intercept(...request).reply(...response); +VonageTest(applicationsTest); - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - }, - ); -}); diff --git a/packages/verify/lib/index.ts b/packages/verify/lib/index.ts index 85f7999d..6b21f404 100644 --- a/packages/verify/lib/index.ts +++ b/packages/verify/lib/index.ts @@ -1,4 +1,4 @@ export { Verify } from './verify'; -export * from './classes/index'; -export * from './enums/index'; -export * from './types/index'; +export * from './classes'; +export * from './enums'; +export * from './types'; diff --git a/packages/verify/lib/types/PSD2Request.ts b/packages/verify/lib/types/PSD2Request.ts index d51d682f..695c336d 100644 --- a/packages/verify/lib/types/PSD2Request.ts +++ b/packages/verify/lib/types/PSD2Request.ts @@ -1,4 +1,4 @@ -import { PSD2Parameters } from './index'; +import { PSD2Parameters } from '.'; /** * @deprecated please use PSD2Parameters diff --git a/packages/verify/lib/types/VerificationRequest.ts b/packages/verify/lib/types/VerificationRequest.ts index 7e8751ec..18ef857f 100644 --- a/packages/verify/lib/types/VerificationRequest.ts +++ b/packages/verify/lib/types/VerificationRequest.ts @@ -1,4 +1,4 @@ -import { VerificationParameters } from './index'; +import { VerificationParameters } from '.'; /** * Represents a verification request. diff --git a/packages/verify/lib/verify.ts b/packages/verify/lib/verify.ts index 7c78f85e..f575e271 100644 --- a/packages/verify/lib/verify.ts +++ b/packages/verify/lib/verify.ts @@ -103,7 +103,7 @@ export class Verify extends Client { cmd: command, }; - // eslint-disable-next-line max-len + const resp = await this.sendPostRequest< VerifyControlResponse | VerifyControlErrorResponse >(`${this.config.apiHost}/verify/control/json`, data); @@ -195,7 +195,7 @@ export class Verify extends Client { requestId: string, code: string, ): Promise { - // eslint-disable-next-line max-len + const resp = await this.sendPostRequest< VerifyRequestResponse | VerifyRequestErrorResponse >(`${this.config.apiHost}/verify/check/json`, { diff --git a/packages/verify/package.json b/packages/verify/package.json index 71ed299c..ff1e1421 100644 --- a/packages/verify/package.json +++ b/packages/verify/package.json @@ -30,8 +30,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -52,9 +53,6 @@ "@vonage/vetch": "^1.7.1", "lodash.omit": "^4.5.0" }, - "devDependencies": { - "nock": "^13.3.4" - }, "publishConfig": { "access": "public" } diff --git a/packages/verify/tsconfig.json b/packages/verify/tsconfig.json index 4365c435..12e0d8fb 100644 --- a/packages/verify/tsconfig.json +++ b/packages/verify/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/verify2/__tests__/__dataSets__/verify.ts b/packages/verify2/__tests__/__dataSets__/verify.ts index 585872fe..8b8cfd5a 100644 --- a/packages/verify2/__tests__/__dataSets__/verify.ts +++ b/packages/verify2/__tests__/__dataSets__/verify.ts @@ -8,9 +8,10 @@ import { VoiceWorkflow, EmailWorkflow, SilentAuthWorkflow, -} from '../../lib/types'; - -import { VerifyLocale, Channels, SilentAuthChannel } from '../../lib/enums'; + VerifyLocale, + Channels, + SilentAuthChannel +} from '../../lib'; export default [ { diff --git a/packages/verify2/__tests__/private.test.key b/packages/verify2/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/verify2/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/verify2/__tests__/verify2.test.ts b/packages/verify2/__tests__/verify2.test.ts index 01fef292..56417c42 100644 --- a/packages/verify2/__tests__/verify2.test.ts +++ b/packages/verify2/__tests__/verify2.test.ts @@ -1,63 +1,39 @@ -import { Verify2 } from '../lib/index'; -import nock from 'nock'; -import { Auth } from '@vonage/auth'; -import { BASE_URL } from './common'; -import testDataSets from './__dataSets__/index'; -import { readFileSync } from 'fs'; - -const key = readFileSync(`${__dirname}/private.test.key`).toString(); - -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(function () { - client = new Verify2( - new Auth({ - privateKey: key, - applicationId: 'my-application', - }), - ); - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => value.startsWith('Bearer '), - }, - }).persist(); - }); - - afterEach(function () { - client = null; - scope = null; - nock.cleanAll(); - }); - - const successTests = tests.filter(({ error }) => !error); - const failureTests = tests.filter(({ error }) => !!error); - - test.each(successTests)( - 'Can $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, expected }) => { - scope.intercept(...request).reply(...response); - - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - }, - ); - - if (failureTests.length < 1) { - return; - } +import { Verify2 } from '../lib'; +import testDataSets from './__dataSets__'; +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth, +} from '../../../testHelpers'; + +const applicationsTest = testDataSets.map((dataSet): TestTuple => { + const { label, tests } = dataSet; + + return { + name: label, + tests: tests.map((test): SDKTestCase => { + return { + label: test.label, + baseUrl: 'https://api.nexmo.com', + reqHeaders: { + authorization: validateBearerAuth, + }, + requests: [test.request] as TestRequest[], + responses: [test.response] as TestResponse[], + client: new Verify2(keyAuth), + clientMethod: test.clientMethod as keyof Verify2, + parameters: test.parameters, + generator: false, + error: 'error' in test ? String(test.error) : false, + expected: test.expected, + }; + }), + }; +}); - test.each(failureTests)( - 'Will throw $label using: $clientMethod', - async ({ request, response, clientMethod, parameters, error }) => { - scope.intercept(...request).reply(...response); +VonageTest(applicationsTest); - await expect(() => - client[clientMethod](...parameters), - ).rejects.toThrow(error); - expect(nock.isDone()).toBeTruthy(); - }, - ); -}); diff --git a/packages/verify2/lib/verify2.ts b/packages/verify2/lib/verify2.ts index d20bc267..4d61603a 100644 --- a/packages/verify2/lib/verify2.ts +++ b/packages/verify2/lib/verify2.ts @@ -62,7 +62,9 @@ export class Verify2 extends Client { `${this.config.apiHost}/v2/verify/${requestId}`, ); return true; - } catch (error) { + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (_) { return false; } } diff --git a/packages/verify2/package.json b/packages/verify2/package.json index 93635a4a..d3ed4770 100644 --- a/packages/verify2/package.json +++ b/packages/verify2/package.json @@ -22,8 +22,9 @@ "url": "https://github.com/dragonmantank" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "type": "module", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" @@ -39,9 +40,5 @@ }, "dependencies": { "@vonage/server-client": "^1.12.0" - }, - "devDependencies": { - "@vonage/auth": "^1.10.0", - "nock": "^13.3.4" } } diff --git a/packages/verify2/tsconfig.json b/packages/verify2/tsconfig.json index 4365c435..12e0d8fb 100644 --- a/packages/verify2/tsconfig.json +++ b/packages/verify2/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/vetch/package.json b/packages/vetch/package.json index f15c9c1f..fe0f4f4f 100644 --- a/packages/vetch/package.json +++ b/packages/vetch/package.json @@ -26,8 +26,9 @@ "url": "https://github.com/manchuck" } ], - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/lib/index.js", + "types": "dist/lib/index.d.ts", + "type": "module", "files": [ "/dist" ], diff --git a/packages/vetch/tsconfig.json b/packages/vetch/tsconfig.json index d79f1087..fe83f38f 100644 --- a/packages/vetch/tsconfig.json +++ b/packages/vetch/tsconfig.json @@ -5,7 +5,7 @@ "compilerOptions": { "rootDir": "lib", - "outDir": "dist" + "outDir": "dist/lib" }, "exclude": [ diff --git a/packages/video/OPENTOK_TO_VONAGE_MIGRATION.md b/packages/video/OPENTOK_TO_VONAGE_MIGRATION.md index e3c8572a..7c4ea2b9 100644 --- a/packages/video/OPENTOK_TO_VONAGE_MIGRATION.md +++ b/packages/video/OPENTOK_TO_VONAGE_MIGRATION.md @@ -35,7 +35,7 @@ const { Video } = require('@vonage/video'); const vonage = new Video({ applicationId: APP_ID, privateKey: PRIVATE_KEY_STRING, - baseUrl: https://video.dev.api.vonage.com, + baseUrl: 'https://video.dev.api.vonage.com', }); const session = await vonage.createSession(); ``` @@ -44,7 +44,7 @@ Functionality-wise, the standalone version works just as the wrapped SDK version ## Callbacks vs Promises -The new Video Node SDK uses Promises instead of callbacks, as the next version of the Vonage Node Server SDK will be promise-based. Customers will need to convert their callbacks to work with the responses returned from the calls. +The new Video Node SDK uses Promises instead of callbacks, as the next version of the Vonage Node Server SDK will be promise-based. Customers will need to convert their callbacks to work with the responses returned from the calls. ## TypeScript diff --git a/packages/video/__tests__/__dataSets__/video.ts b/packages/video/__tests__/__dataSets__/video.ts index 0d728f09..070044d5 100644 --- a/packages/video/__tests__/__dataSets__/video.ts +++ b/packages/video/__tests__/__dataSets__/video.ts @@ -1,7 +1,9 @@ -import { ExperienceComposerResolution } from '../../lib/enums/ExperienceComposerResolution'; -import { ExperienceComposerOptions } from '../../lib/types/ExperienceComposerOptions'; -import { CaptionOptions } from '../../lib/types/CaptionOptions'; -import { SIPCallOptions } from '../../lib/types/SIPCallOptions'; +import { + ExperienceComposerResolution, + ExperienceComposerOptions, + CaptionOptions, + SIPCallOptions, +} from '../../lib'; const renderInformation = { id: '1248e7070b81464c9789f46ad10e7764', @@ -162,7 +164,7 @@ export default [ { label: 'Disable captions for a session', request: [ - `/v2/project/abcd-1234/captions/7c0680fc-6274-4de5-a66f-d0648e8d3ac2/stop`, + '/v2/project/abcd-1234/captions/7c0680fc-6274-4de5-a66f-d0648e8d3ac2/stop', 'POST', ], response: [200], diff --git a/packages/video/__tests__/private.test.key b/packages/video/__tests__/private.test.key deleted file mode 100644 index d127da04..00000000 --- a/packages/video/__tests__/private.test.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTH8cEhJKsu2hB -ucgs0Blf3tvgdXuIa5sMRI3zIZGok8jqaj6DC0WdM1eiJlQCWnVL0vR25MkopMZN -MTphoaVpdK9wywMVx7PsgMCDXJjW77QFJFbbcbV9KG2xvMsjJGttmVrn+9aPpCnX -yT27bWkTR0k/wCAvra/st5MDKg2kB3SMc+97zlO3GqIkJJKfKYQFAO8oRBcsZ1Bx -ydPWTQvyLYW15Cjv30aIGLfceFwDeUOBgBsesGFtcXvVF6sVxd5D/USunX/9es95 -Rdr4+9Qq4tIKZRkBz2KWD0eo256wmmq2lQoGaR9x6XgLHhUlsi6OXILcyChi2Qcc -a01Hn7YvAgMBAAECggEAJsS+lIdNsddmIS+e4Q/DoRW49aJNMXNlEN8j2+Itr7GX -ougom4K94UyUyotUQOxgfrB5wL1pbQO5AGLKUDRRPii1sLYu1liKIyNPdq/RxyJU -Qd927awXQiji39EF0mm1KnaPOWtG7rCcGGp1Yg4Izgf4nPLIVkkENalOHzYhNB3u -4W4OIT49iw/auBF4wnl1RmXWXjkxDuk2cYT28a8hWqyQjJqXTsO+u4BaXYxSf4nP -Be2yoUEFRbcxvJrhEpfODhPP83I1EBipJkhUTc5WMb/vtH2b49+TYd2tPR0LOxom -mcNUWF6++ae+vL6K8Dlfcvx+CA7g7KBHHcgFCzn7GQKBgQDzc2ow5LlQQ/VfXZTz -n07V/QgVQ15sA5Cf/gsvmwnGPy06Qx/WRHsz6NG8nvW2mHZwfDIHuLjBW1gcssEx -mLpqav5XLZfSyjjRO/AxLIfJDx/aARp3+7Ny5aY2e3wtNx8wz4J80i7P+eX3fETM -70cWhc2PvYMDjG+O7cDW2FWAFwKBgQDeAcc/FBHLl9/HqiBvYf/Y/k0t1TUoHujO -PSbP6SaN06JnvJmBANyED7sWeIPuoRFXXEr4Auu7y0C55Wlsno/ImTbJsopZ1rgU -k5q4t9vcu7cGiOr7L7UkySNYZqRjwvKEJ610COexTThSwl0v3GNLP8r4AMdBaqdK -uO6fVfxxqQKBgFc5ne2Atai9gJe3ltum0382FoRPy+/VYyb/xZA780eVcSXz0N9b -T+0sWKFFLvJKM/1fcil0FLYqfSpjHXcgqoHgbdpcWo5KqArHd+qWctwl0Bqy1IHy -q7vZ7jCNE9O7cTBy2OTSBbW8apm+a4Qlowm9zQXYN624zmueYb5YamHnAoGAZvJA -KHnv/o7AkF/NhpjVARR7SYOSkLY0kl48/zBIVoAK0TvdmrqBhyOcR8E+vIsn9XCw -uuzvzzdjHlDJYDruxcB2bXVDPoGY/sGrf3iSlXreVkNrY2st/o7euwFtvW0K9ElJ -34K5nbgHJClI+QajbKN6RSJnQ2hnhvjWfkBrPXECgYEA4MCEm9EyrguEO51am8va -OjIAiQMkj/iyjsMDL8eH0VM+OMdieHwbkKyajyrB9dFikvWfxiuo3dU1N5vJTzty -LmzkB8M/rKlAYKD8iKA8cRun4tKzRepHT3JPMu0GYTfcP9ovs5F3aEjX+UuWOO7n -doWDENAr/VU1RNCDwFdxYFg= ------END PRIVATE KEY----- diff --git a/packages/video/__tests__/video.test.ts b/packages/video/__tests__/video.test.ts index 832bb7dd..977c327c 100644 --- a/packages/video/__tests__/video.test.ts +++ b/packages/video/__tests__/video.test.ts @@ -1,66 +1,87 @@ -import nock from 'nock'; -import fs from 'fs'; -import { Video } from '../lib/video'; +import nock from 'nock'; import { decode } from 'jsonwebtoken'; -import { LayoutType } from '../lib/enums/LayoutType'; -import { MediaMode } from '../lib/enums/MediaMode'; -import { ArchiveMode } from '../lib/types/ArchiveMode'; import { Auth } from '@vonage/auth'; -import testDataSets from './__dataSets__/index'; - +import testDataSets from './__dataSets__'; +import { Jwt } from 'jsonwebtoken'; + +import { + Video, + LayoutType, + MediaMode, + ArchiveMode, + SingleStreamLayoutResponse, + MultiStreamLayoutResponse, +} from '../lib'; + + +import { + VonageTest, + SDKTestCase, + TestResponse, + TestRequest, + TestTuple, + keyAuth, + validateBearerAuth, + testPrivateKey, +} from '../../../testHelpers'; const BASE_URL = 'https://video.api.vonage.com/'.replace(/\/+$/, ''); -describe.each(testDataSets)('$label', ({ tests }) => { - let client; - let scope; - - beforeEach(() => { - client = new Video( - new Auth({ - applicationId: 'abcd-1234', - privateKey: fs.readFileSync(`${__dirname}/private.test.key`).toString(), - }) - ); - scope = nock(BASE_URL, { - reqheaders: { - authorization: (value) => - value.startsWith('Bearer ') && value.length > 10, - }, - }).persist(); - }); - - afterEach(() => { - client = null; - scope = null; - nock.cleanAll(); - }); - - test.each(tests)( - 'Can $label using: $clientMethod', - async ({ request, response, clientMethod, expected, parameters }) => { - scope.intercept(...request).reply(...response); - const results = await client[clientMethod](...parameters); - expect(results).toEqual(expected); - expect(nock.isDone()).toBeTruthy(); - } - ); +type jwtClaims = { + application_id: string; + session_id: string; + sub: string; + acl: { + paths: Record; + }; + exp: number; + initial_layout_class_list: string; + connection_data: string; + role: string; + scope: string; +}; + +const applicationsTest = testDataSets.map((dataSet): TestTuple