From 2875275a44411295469211f948c343123072e7cf Mon Sep 17 00:00:00 2001 From: Ivan Zuev Date: Fri, 24 Dec 2021 11:41:08 +0300 Subject: [PATCH] feat: reworked examples --- examples/.nvmrc | 1 + examples/ai-translate.ts | 25 ++++++ examples/ai_translate.js | 21 ----- examples/compute-instance-create.ts | 111 +++++++++++++++++++++++++ examples/docapi.js | 23 ----- examples/functions.js | 12 --- examples/functions.ts | 18 ++++ examples/index.js | 51 ------------ examples/iot-data.ts | 36 ++++++++ examples/iot_data.js | 28 ------- examples/kms.js | 42 ---------- examples/kms.ts | 51 ++++++++++++ examples/package-lock.json | 100 ++++++++++++++++++++++ examples/package.json | 15 ++++ examples/resourcemanager-cloud-list.ts | 17 ++++ examples/resourcemanager_cloud_list.js | 11 --- examples/utils/get-env.ts | 9 ++ examples/utils/logger.ts | 4 + examples/ydb.js | 11 --- src/index.ts | 1 + src/utils/decode-message.ts | 16 ++++ 21 files changed, 404 insertions(+), 199 deletions(-) create mode 100644 examples/.nvmrc create mode 100644 examples/ai-translate.ts delete mode 100644 examples/ai_translate.js create mode 100644 examples/compute-instance-create.ts delete mode 100644 examples/docapi.js delete mode 100644 examples/functions.js create mode 100644 examples/functions.ts delete mode 100644 examples/index.js create mode 100644 examples/iot-data.ts delete mode 100644 examples/iot_data.js delete mode 100644 examples/kms.js create mode 100644 examples/kms.ts create mode 100644 examples/package-lock.json create mode 100644 examples/package.json create mode 100644 examples/resourcemanager-cloud-list.ts delete mode 100644 examples/resourcemanager_cloud_list.js create mode 100644 examples/utils/get-env.ts create mode 100644 examples/utils/logger.ts delete mode 100644 examples/ydb.js create mode 100644 src/utils/decode-message.ts diff --git a/examples/.nvmrc b/examples/.nvmrc new file mode 100644 index 00000000..6e9d5a1e --- /dev/null +++ b/examples/.nvmrc @@ -0,0 +1 @@ +16.13.1 \ No newline at end of file diff --git a/examples/ai-translate.ts b/examples/ai-translate.ts new file mode 100644 index 00000000..4d741e43 --- /dev/null +++ b/examples/ai-translate.ts @@ -0,0 +1,25 @@ +import { serviceClients, Session, cloudApi } from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const { ai: { translate_translation_service: { TranslateRequest, TranslateRequest_Format: Format } } } = cloudApi; + +const TEXTS = ['NodeJS SDK examples', 'Powerful, but easy to use library']; +const AUTH_TOKEN = getEnv('YC_OAUTH_TOKEN'); +const FOLDER_ID = getEnv('YC_FOLDER_ID'); + +(async () => { + const session = new Session({ oauthToken: AUTH_TOKEN }); + const client = session.client(serviceClients.TranslationServiceClient); + + const response = await client.translate(TranslateRequest.fromPartial({ + targetLanguageCode: 'ru', + format: Format.PLAIN_TEXT, + folderId: FOLDER_ID, + texts: TEXTS, + })); + + for (const [idx, text] of response.translations.entries()) { + log(`translated '${TEXTS[idx]}' => '${text.text}'`); + } +})(); diff --git a/examples/ai_translate.js b/examples/ai_translate.js deleted file mode 100644 index 6e4cf61b..00000000 --- a/examples/ai_translate.js +++ /dev/null @@ -1,21 +0,0 @@ -const run = require('./').run; -const { - TranslationService, - TranslateRequest, -} = require('../src/api/ai/translate/v2'); - -run(async (session, _, folderId) => { - const translationService = new TranslationService(session); - const texts = ['NodeJS SDK examples', 'Powerful, but easy to use library']; - - const response = await translationService.translate({ - targetLanguageCode: 'ru', - format: TranslateRequest.Format.PLAIN_TEXT, - folderId: folderId, - texts: texts, - }); - - response.translations.forEach((text, idx) => { - console.log(`translated '${texts[idx]}' => '${text.text}'`); - }); -}); diff --git a/examples/compute-instance-create.ts b/examples/compute-instance-create.ts new file mode 100644 index 00000000..03981e38 --- /dev/null +++ b/examples/compute-instance-create.ts @@ -0,0 +1,111 @@ +import { + serviceClients, Session, cloudApi, waitForOperation, decodeMessage, +} from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const AUTH_TOKEN = getEnv('YC_OAUTH_TOKEN'); +const FOLDER_ID = getEnv('YC_FOLDER_ID'); +const TARGET_ZONE_ID = 'ru-central1-a'; + +const { + vpc: { + network_service: { + ListNetworksRequest, + ListNetworkSubnetsRequest, + }, + }, + compute: { + image_service: { + GetImageLatestByFamilyRequest, + }, + instance_service: { + CreateInstanceRequest, + DeleteInstanceRequest, + }, + instance: { + IpVersion, + }, + }, +} = cloudApi; + +(async () => { + const session = new Session({ oauthToken: AUTH_TOKEN }); + const imageClient = session.client(serviceClients.ComputeImageServiceClient); + const instanceClient = session.client(serviceClients.InstanceServiceClient); + const networkClient = session.client(serviceClients.NetworkServiceClient); + + const networkResponse = await networkClient.list(ListNetworksRequest.fromPartial({ + folderId: FOLDER_ID, + })); + + log(`Found ${networkResponse.networks.length} networks in folder ${FOLDER_ID}`); + + const network = networkResponse.networks.pop(); + + if (!network) { + throw new Error(`There are no networks in folder ${FOLDER_ID}`); + } + + const subnetsResponse = await networkClient.listSubnets(ListNetworkSubnetsRequest.fromPartial({ + networkId: network.id, + })); + const subnet = subnetsResponse.subnets.find((s) => s.zoneId === TARGET_ZONE_ID); + + if (!subnet) { + throw new Error(`There is no subnet in zone ${TARGET_ZONE_ID} in folder ${FOLDER_ID}`); + } + + const image = await imageClient.getLatestByFamily(GetImageLatestByFamilyRequest.fromPartial({ + family: 'ubuntu-1804-lts', + folderId: 'standard-images', + })); + + const createOp = await instanceClient.create(CreateInstanceRequest.fromPartial({ + folderId: FOLDER_ID, + zoneId: TARGET_ZONE_ID, + platformId: 'standard-v2', + labels: { 'nodejs-sdk': 'yes' }, + resourcesSpec: { + memory: 2 * 1024 * 1024 * 1024, + cores: 2, + }, + bootDiskSpec: { + autoDelete: true, + diskSpec: { + size: 10 * 1024 * 1024 * 1024, + imageId: image.id, + }, + }, + networkInterfaceSpecs: [ + { + subnetId: subnet.id, + primaryV4AddressSpec: { + oneToOneNatSpec: { ipVersion: IpVersion.IPV4 }, + }, + }, + ], + })); + + log(`Instance create operation id: ${createOp.id}`); + + const finishedCreateOp = await waitForOperation(createOp, session); + + if (finishedCreateOp.response) { + const instance = decodeMessage(finishedCreateOp.response); + + log(`Instance ${instance.id} created`); + + const removeOp = await instanceClient.delete(DeleteInstanceRequest.fromPartial({ + instanceId: instance.id, + })); + + const finishedRemoveOp = await waitForOperation(removeOp, session); + + if (finishedRemoveOp.error) { + log(`Failed to remove instance ${instance.id}`); + } else { + log(`Successfully remove instance ${instance.id}`); + } + } +})(); diff --git a/examples/docapi.js b/examples/docapi.js deleted file mode 100644 index 6e6fd133..00000000 --- a/examples/docapi.js +++ /dev/null @@ -1,23 +0,0 @@ -const run = require('./').run; -const { DocAPIService } = require('../legacy/lib/slydb/docapi/docapi.js'); - -run(async (session, _, folderId) => { - var endpoint = - 'https://docapi.serverless.yandexcloud.net/ru-central1/b1g11111111111111111/etn22222222222222222'; - var docapi = new DocAPIService(endpoint, session); - var params = { - TableName: 'scale/pets', - Key: { - species: 'cat', - name: 'Tom', - }, - }; - docapi - .getItem(params) - .then((res) => { - console.log(res); - }) - .catch((err) => { - console.log(err); - }); -}); diff --git a/examples/functions.js b/examples/functions.js deleted file mode 100644 index b42eed69..00000000 --- a/examples/functions.js +++ /dev/null @@ -1,12 +0,0 @@ -const run = require('./').run; -const { InvokeService } = require('../legacy/lib/serverless/functions/v1/invoke'); - -run(async (session, _, folderId) => { - const invokeService = new InvokeService(session); - const resp = await invokeService.invoke('d4e9s9vmnd5lhlc8gmq2'); - console.log(`Got function response with keys`, Object.keys(resp)); - - const myWrapped = invokeService.wrap('d4e9s9vmnd5lhlc8gmq2'); - const data = await myWrapped(); - console.log(data); -}); diff --git a/examples/functions.ts b/examples/functions.ts new file mode 100644 index 00000000..cdac485b --- /dev/null +++ b/examples/functions.ts @@ -0,0 +1,18 @@ +import { serviceClients, Session, cloudApi } from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const { serverless: { functions_function_service: { ListFunctionsRequest } } } = cloudApi; +const AUTH_TOKEN = getEnv('YC_OAUTH_TOKEN'); +const FOLDER_ID = getEnv('YC_FOLDER_ID'); + +(async () => { + const session = new Session({ oauthToken: AUTH_TOKEN }); + const client = session.client(serviceClients.FunctionServiceClient); + + const response = await client.list(ListFunctionsRequest.fromPartial({ folderId: FOLDER_ID })); + + for (const func of response.functions) { + log(`Function: ${func.name}, id: ${func.id}, invoke URL: ${func.httpInvokeUrl}`); + } +})(); diff --git a/examples/index.js b/examples/index.js deleted file mode 100644 index 078945f0..00000000 --- a/examples/index.js +++ /dev/null @@ -1,51 +0,0 @@ -const yaml = require('yaml'); -const fs = require('fs'); -const path = require('path'); -const yc = require('../src'); - -function readCliConfig() { - const configFile = path.join( - process.env['HOME'], - '.config/yandex-cloud/config.yaml' - ); - - let config; - try { - config = yaml.parse(fs.readFileSync(configFile, 'utf8')); - } catch (e) { - throw new Error(`Failed to read config ${configFile}: ${e.toString()}`); - } - - const current = config['current']; - if (!current) { - throw new Error( - `Invalid config in ${configFile}: no current profile selected` - ); - } - - if (!config['profiles'][current]) { - throw new Error( - `Invalid config in ${configFile}: no profile named ${current} exists` - ); - } - - return config['profiles'][current]; -} - -function run(fn) { - const config = readCliConfig(); - const session = new yc.Session({ oauthToken: config['token'] }); - (async () => { - if (config['endpoint']) { - await session.setEndpoint(config['endpoint']); - } - await fn(session, config['cloud-id'], config['folder-id']); - })() - .then(() => {}) - .catch((e) => { - console.error(e); - process.exit(1); - }); -} - -module.exports = { run }; diff --git a/examples/iot-data.ts b/examples/iot-data.ts new file mode 100644 index 00000000..5b1eaf90 --- /dev/null +++ b/examples/iot-data.ts @@ -0,0 +1,36 @@ +import { serviceClients, Session, cloudApi } from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const { + iot: { + devices_registry_service: { ListRegistriesRequest }, + devices_registry_data_service: { PublishRegistryDataRequest }, + }, +} = cloudApi; +const AUTH_TOKEN = getEnv('YC_OAUTH_TOKEN'); +const FOLDER_ID = getEnv('YC_FOLDER_ID'); + +(async () => { + const session = new Session({ oauthToken: AUTH_TOKEN }); + const registryClient = session.client(serviceClients.IotRegistryServiceClient); + const dataClient = session.client(serviceClients.RegistryDataServiceClient); + + const registries = await registryClient.list(ListRegistriesRequest.fromPartial({ + folderId: FOLDER_ID, + })); + + log(`Found ${registries.registries.length} registries in folder ${FOLDER_ID}`); + + for (const registry of registries.registries) { + log(`Broadcasting to ${registry.id}`); + + dataClient.publish(PublishRegistryDataRequest.fromPartial({ + registryId: registry.id, + topic: `$registries/${registry.id}/commands/heartbeat`, + data: Buffer.from('{"hello": "world"}'), + })); + } + + log('Broadcasted to all registries'); +})(); diff --git a/examples/iot_data.js b/examples/iot_data.js deleted file mode 100644 index ec928133..00000000 --- a/examples/iot_data.js +++ /dev/null @@ -1,28 +0,0 @@ -const run = require('./').run; -const { - RegistryService, - RegistryDataService, -} = require('../src/api/iot/devices/v1'); - -run(async (session, cloudId, folderId) => { - const registryService = new RegistryService(session); - const dataService = new RegistryDataService(session); - - const registries = await registryService.list({ folderId }); - console.log( - `found ${registries.registries.length} registries in folder ${folderId}` - ); - - await Promise.all( - registries.registries.map((registry) => { - console.log(`broadcasting to ${registry.id}`); - return dataService.publish({ - registryId: registry.id, - topic: `$registries/${registry.id}/commands/heartbeat`, - data: Buffer.from('{}'), - }); - }) - ); - - console.log('all broadcasts sent'); -}); diff --git a/examples/kms.js b/examples/kms.js deleted file mode 100644 index 1b87517e..00000000 --- a/examples/kms.js +++ /dev/null @@ -1,42 +0,0 @@ -const run = require('./').run; -const { - SymmetricKeyService, - SymmetricCryptoService, - SymmetricAlgorithm, -} = require('../src/api/kms/v1'); - -run(async (session, cloudId, folderId) => { - const keyService = new SymmetricKeyService(session); - const cryptoService = new SymmetricCryptoService(session); - - let keyOp = await keyService.create({ - folderId, - defaultAlgorithm: SymmetricAlgorithm.AES_256, - }); - keyOp = await keyOp.completion(session); - - const key = keyOp.getResponse(); - - const encrypted = ( - await cryptoService.encrypt({ - keyId: key.id, - plaintext: Buffer.from('example kms message'), - }) - ).ciphertext; - - console.log(`got "${encrypted}" from KMS. Let's decrypt.`); - - const decrypted = ( - await cryptoService.decrypt({ - keyId: key.id, - ciphertext: encrypted, - }) - ).plaintext; - - console.log(`got "${decrypted}" from KMS. Is it looks good?`); - - let keyDeleteOp = await keyService.delete({ - keyId: key.id, - }); - await keyDeleteOp.completion(session); -}); diff --git a/examples/kms.ts b/examples/kms.ts new file mode 100644 index 00000000..8a032fbb --- /dev/null +++ b/examples/kms.ts @@ -0,0 +1,51 @@ +import { + serviceClients, Session, cloudApi, waitForOperation, decodeMessage, +} from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const { + kms: { + symmetric_key_service: { CreateSymmetricKeyRequest, DeleteSymmetricKeyRequest }, + symmetric_key: { SymmetricAlgorithm }, + symmetric_crypto_service: { SymmetricEncryptRequest, SymmetricDecryptRequest }, + }, +} = cloudApi; + +(async () => { + const authToken = getEnv('YC_OAUTH_TOKEN'); + const folderId = getEnv('YC_FOLDER_ID'); + const session = new Session({ oauthToken: authToken }); + const keyClient = session.client(serviceClients.SymmetricKeyServiceClient); + const cryptoClient = session.client(serviceClients.SymmetricCryptoServiceClient); + + const keyCreateOp = await keyClient.create(CreateSymmetricKeyRequest.fromPartial({ + folderId, + defaultAlgorithm: SymmetricAlgorithm.AES_256, + })); + const finishedKeyCreateOp = await waitForOperation(keyCreateOp, session); + + if (finishedKeyCreateOp.response) { + const key = decodeMessage(finishedKeyCreateOp.response); + + const encrypted = await cryptoClient.encrypt(SymmetricEncryptRequest.fromPartial({ + keyId: key.id, + plaintext: Buffer.from('example message'), + })); + + log(`Got "${encrypted.ciphertext}" from KMS`); + + const decrypted = await cryptoClient.decrypt(SymmetricDecryptRequest.fromPartial({ + keyId: key.id, + ciphertext: encrypted.ciphertext, + })); + + log(`Got "${decrypted.plaintext}" from KMS`); + + const keyRemoveOp = await keyClient.delete(DeleteSymmetricKeyRequest.fromPartial({ + keyId: key.id, + })); + + await waitForOperation(keyRemoveOp, session); + } +})(); diff --git a/examples/package-lock.json b/examples/package-lock.json new file mode 100644 index 00000000..e5d9d74b --- /dev/null +++ b/examples/package-lock.json @@ -0,0 +1,100 @@ +{ + "name": "examples", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "examples", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "yandex-cloud": "file:.." + } + }, + "..": { + "version": "1.4.3", + "license": "MIT", + "dependencies": { + "@grpc/grpc-js": "https://gitpkg.now.sh/DavyJohnes/grpc-node/packages/grpc-js?fix-class-options-issue-with-dist", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "luxon": "^2.2.0", + "nice-grpc": "^1.0.4", + "nice-grpc-client-middleware-deadline": "^1.0.4", + "node-fetch": "^3.1.0", + "protobufjs": "^6.8.8", + "utility-types": "^3.10.0" + }, + "devDependencies": { + "@types/jest": "^27.0.3", + "@types/jsonwebtoken": "^8.5.6", + "@types/lodash": "^4.14.178", + "@types/luxon": "^2.0.8", + "@types/node": "^16.11.3", + "@typescript-eslint/eslint-plugin": "^5.7.0", + "@typescript-eslint/parser": "^5.7.0", + "eslint": "^8.4.1", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^16.1.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-prefer-arrow-functions": "^3.1.4", + "eslint-plugin-unicorn": "^39.0.0", + "fast-glob": "^3.2.7", + "grpc-tools": "^1.11.2", + "jest": "^27.4.5", + "ts-jest": "^27.1.1", + "ts-node": "^10.4.0", + "ts-proto": "github:DavyJohnes/ts-proto#add-service-property-with-build", + "typescript": "^4.5.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/yandex-cloud": { + "resolved": "..", + "link": true + } + }, + "dependencies": { + "yandex-cloud": { + "version": "file:..", + "requires": { + "@grpc/grpc-js": "https://gitpkg.now.sh/DavyJohnes/grpc-node/packages/grpc-js?fix-class-options-issue-with-dist", + "@types/jest": "^27.0.3", + "@types/jsonwebtoken": "^8.5.6", + "@types/lodash": "^4.14.178", + "@types/luxon": "^2.0.8", + "@types/node": "^16.11.3", + "@typescript-eslint/eslint-plugin": "^5.7.0", + "@typescript-eslint/parser": "^5.7.0", + "eslint": "^8.4.1", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^16.1.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-prefer-arrow-functions": "^3.1.4", + "eslint-plugin-unicorn": "^39.0.0", + "fast-glob": "^3.2.7", + "grpc-tools": "^1.11.2", + "jest": "^27.4.5", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.21", + "log4js": "^6.3.0", + "luxon": "^2.2.0", + "nice-grpc": "^1.0.4", + "nice-grpc-client-middleware-deadline": "^1.0.4", + "node-fetch": "^3.1.0", + "protobufjs": "^6.8.8", + "ts-jest": "^27.1.1", + "ts-node": "^10.4.0", + "ts-proto": "github:DavyJohnes/ts-proto#add-service-property-with-build", + "typescript": "^4.5.4", + "utility-types": "^3.10.0" + } + } + } +} diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 00000000..9ece0430 --- /dev/null +++ b/examples/package.json @@ -0,0 +1,15 @@ +{ + "name": "examples", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "ts-node -T -P ../tsconfig.json" + }, + "author": "", + "license": "ISC", + "dependencies": { + "yandex-cloud": "file:.." + } +} diff --git a/examples/resourcemanager-cloud-list.ts b/examples/resourcemanager-cloud-list.ts new file mode 100644 index 00000000..1247dd7c --- /dev/null +++ b/examples/resourcemanager-cloud-list.ts @@ -0,0 +1,17 @@ +import { serviceClients, Session, cloudApi } from 'yandex-cloud'; +import { getEnv } from './utils/get-env'; +import { log } from './utils/logger'; + +const { resourcemanager: { cloud_service: { ListCloudsRequest } } } = cloudApi; +const AUTH_TOKEN = getEnv('YC_OAUTH_TOKEN'); + +(async () => { + const session = new Session({ oauthToken: AUTH_TOKEN }); + const client = session.client(serviceClients.CloudServiceClient); + + const response = await client.list(ListCloudsRequest.fromPartial({ pageSize: 200 })); + + for (const cloud of response.clouds) { + log(`Found cloud id = ${cloud.id}, name = ${cloud.name}`); + } +})(); diff --git a/examples/resourcemanager_cloud_list.js b/examples/resourcemanager_cloud_list.js deleted file mode 100644 index 6000d3b5..00000000 --- a/examples/resourcemanager_cloud_list.js +++ /dev/null @@ -1,11 +0,0 @@ -const run = require('./').run; -const { CloudService } = require('../src/api/resourcemanager/v1'); - -run(async (session) => { - const cloudService = new CloudService(session); - - const cloudsResponse = await cloudService.list({ pageSize: 100 }); - cloudsResponse.clouds.forEach((cloud) => { - console.log(`found cloud id = ${cloud.id}, name = ${cloud.name}`); - }); -}); diff --git a/examples/utils/get-env.ts b/examples/utils/get-env.ts new file mode 100644 index 00000000..ce9ca8bb --- /dev/null +++ b/examples/utils/get-env.ts @@ -0,0 +1,9 @@ +export const getEnv = (envName: string, defaultValue?: string): string => { + const envValue = process.env[envName] || defaultValue; + + if (!envValue) { + throw new Error(`Env variable ${envName} is not defined`); + } + + return envValue; +}; diff --git a/examples/utils/logger.ts b/examples/utils/logger.ts new file mode 100644 index 00000000..59bc9fd8 --- /dev/null +++ b/examples/utils/logger.ts @@ -0,0 +1,4 @@ +export const log = (message: string) => { + // eslint-disable-next-line no-console + console.log(message); +}; diff --git a/examples/ydb.js b/examples/ydb.js deleted file mode 100644 index b8db7222..00000000 --- a/examples/ydb.js +++ /dev/null @@ -1,11 +0,0 @@ -const run = require('./').run; -const { createDriver } = require('../legacy/lib/slydb'); - -run(async (session, _, folderId) => { - const driver = createDriver(); - const timeout = 2000; - if (!(await driver.ready(timeout))) { - console.log(`Driver has not become ready in ${timeout}ms!`); - process.exit(1); - } -}); diff --git a/src/index.ts b/src/index.ts index 91e1a99e..f6f36f5b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,4 @@ export * as serviceClients from './generated/yandex/cloud/service_clients'; export * as cloudApi from './generated/yandex/cloud'; export * from './session'; export * from './utils/operation'; +export * from './utils/decode-message'; diff --git a/src/utils/decode-message.ts b/src/utils/decode-message.ts new file mode 100644 index 00000000..8daaeaab --- /dev/null +++ b/src/utils/decode-message.ts @@ -0,0 +1,16 @@ +import { Any } from '../generated/google/protobuf/any'; + +import { MessageType, messageTypeRegistry, UnknownMessage } from '../generated/typeRegistry'; + +type OptionalMessage = MessageType | undefined; + +export const decodeMessage = (data: Any): T => { + const fqn = data.typeUrl.slice(Math.max(0, data.typeUrl.lastIndexOf('/') + 1)); + const cls: OptionalMessage | undefined = messageTypeRegistry.get(fqn) as unknown as OptionalMessage; + + if (!cls) { + throw new Error(`Message contains unknown type ${fqn}`); + } + + return cls.decode(data.value); +};