aws-iot-device-sdk-v2
Version:
NodeJS API for the AWS IoT service
340 lines • 14.3 kB
JavaScript
;
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateValueAsOptionalObject = exports.validateValueAsObject = exports.validateValueAsOptionalMap = exports.validateValueAsMap = exports.validateValueAsOptionalArray = exports.validateValueAsArray = exports.validateValueAsOptionalAny = exports.validateValueAsAny = exports.validateValueAsOptionalBlob = exports.validateValueAsBlob = exports.validateValueAsOptionalDate = exports.validateValueAsDate = exports.validateValueAsOptionalBoolean = exports.validateValueAsBoolean = exports.validateValueAsOptionalInteger = exports.validateValueAsInteger = exports.validateValueAsOptionalString = exports.validateValueAsString = exports.validateValueAsNumber = exports.validateOptionalValueAsNumber = exports.validateValueAsTopicSegment = exports.createServiceError = exports.doRequestResponse = void 0;
const aws_crt_1 = require("aws-crt");
const mqtt_request_response_1 = require("./mqtt_request_response");
function buildResponseDeserializerMap(paths) {
return new Map(paths.map((path) => {
return [path.topic, path.deserializer];
}));
}
function buildResponsePaths(paths) {
return paths.map((path) => {
let responsePath = {
topic: path.topic
};
if (path.correlationTokenJsonPath) {
responsePath.correlationTokenJsonPath = path.correlationTokenJsonPath;
}
return responsePath;
});
}
function doRequestResponse(options) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
try {
let operationModel = options.serviceModel.requestResponseOperations.get(options.operationName);
if (!operationModel) {
reject(createServiceError(`Operation "${options.operationName}" not in client's service model`));
return;
}
let validator = options.serviceModel.shapeValidators.get(operationModel.inputShapeName);
if (!validator) {
reject(createServiceError(`Operation "${options.operationName}" does not have an input validator`));
return;
}
validator(options.request);
let publishTopic = operationModel.publishTopicGenerator(options.request);
let subscriptionsNeeded = operationModel.subscriptionGenerator(options.request);
let modelPaths = operationModel.responsePathGenerator(options.request);
let deserializerMap = buildResponseDeserializerMap(modelPaths);
let responsePaths = buildResponsePaths(modelPaths);
let [request, correlationToken] = operationModel.correlationTokenApplicator(options.request);
let payload = operationModel.payloadTransformer(request);
let requestOptions = {
subscriptionTopicFilters: subscriptionsNeeded,
responsePaths: responsePaths,
publishTopic: publishTopic,
payload: payload
};
if (correlationToken) {
requestOptions.correlationToken = correlationToken;
}
let response = yield options.client.submitRequest(requestOptions);
let responseTopic = response.topic;
let wasSuccess = responseTopic.endsWith("accepted"); // May need to eventually model
let responsePayload = response.payload;
let deserializer = deserializerMap.get(responseTopic);
if (!deserializer) {
reject(createServiceError(`Operation "${options.operationName}" does not have a deserializer for topic "${responseTopic}"`));
return;
}
let deserializedResponse = deserializer(responsePayload);
if (wasSuccess) {
resolve(deserializedResponse);
}
else {
reject(createServiceError("Request failed", undefined, deserializedResponse));
}
}
catch (err) {
if (err instanceof mqtt_request_response_1.ServiceError) {
reject(err);
}
else if (err instanceof aws_crt_1.CrtError) {
reject(createServiceError("CrtError", err));
}
else {
reject(createServiceError(err.toString()));
}
}
}));
});
}
exports.doRequestResponse = doRequestResponse;
function createServiceError(description, internalError, modeledError) {
return new mqtt_request_response_1.ServiceError({
description: description,
internalError: internalError,
modeledError: modeledError,
});
}
exports.createServiceError = createServiceError;
function throwMissingPropertyError(propertyName) {
if (propertyName) {
throw createServiceError(`validation failure - missing required property '${propertyName}'`);
}
else {
throw createServiceError(`validation failure - missing required property`);
}
}
function throwInvalidPropertyValueError(valueDescription, propertyName) {
if (propertyName) {
throw createServiceError(`validation failure - property '${propertyName}' must be ${valueDescription}`);
}
else {
throw createServiceError(`validation failure - property must be ${valueDescription}`);
}
}
function validateValueAsTopicSegment(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (typeof value !== 'string') {
throwInvalidPropertyValueError("a string", propertyName);
}
if (value.includes("/") || value.includes("#") || value.includes("+")) {
throwInvalidPropertyValueError("a valid MQTT topic", propertyName);
}
}
exports.validateValueAsTopicSegment = validateValueAsTopicSegment;
function validateOptionalValueAsNumber(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsNumber(value, propertyName);
}
exports.validateOptionalValueAsNumber = validateOptionalValueAsNumber;
function validateValueAsNumber(value, propertyName) {
if (value == undefined) {
throwMissingPropertyError(propertyName);
}
if (typeof value !== 'number') {
throwInvalidPropertyValueError("a number", propertyName);
}
}
exports.validateValueAsNumber = validateValueAsNumber;
//////////////
function validateValueAsString(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (typeof value !== 'string') {
throwInvalidPropertyValueError('a string value', propertyName);
}
}
exports.validateValueAsString = validateValueAsString;
function validateValueAsOptionalString(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsString(value, propertyName);
}
exports.validateValueAsOptionalString = validateValueAsOptionalString;
function validateValueAsInteger(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
throwInvalidPropertyValueError('an integer value', propertyName);
}
}
exports.validateValueAsInteger = validateValueAsInteger;
function validateValueAsOptionalInteger(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsInteger(value, propertyName);
}
exports.validateValueAsOptionalInteger = validateValueAsOptionalInteger;
function validateValueAsBoolean(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (typeof value !== 'boolean') {
throwInvalidPropertyValueError('a boolean value', propertyName);
}
}
exports.validateValueAsBoolean = validateValueAsBoolean;
function validateValueAsOptionalBoolean(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsBoolean(value, propertyName);
}
exports.validateValueAsOptionalBoolean = validateValueAsOptionalBoolean;
function validateValueAsDate(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (!(value instanceof Date) || isNaN(value.getTime())) {
throwInvalidPropertyValueError('a Date value', propertyName);
}
}
exports.validateValueAsDate = validateValueAsDate;
function validateValueAsOptionalDate(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsDate(value, propertyName);
}
exports.validateValueAsOptionalDate = validateValueAsOptionalDate;
function validateValueAsBlob(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
/* there doesn't seem to be a good way of checking if something is an ArrayBuffer */
if ((typeof value !== 'string') && !ArrayBuffer.isView(value) && (!value.byteLength || !value.maxByteLength)) {
throwInvalidPropertyValueError('a value convertible to a binary payload', propertyName);
}
}
exports.validateValueAsBlob = validateValueAsBlob;
function validateValueAsOptionalBlob(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsBlob(value, propertyName);
}
exports.validateValueAsOptionalBlob = validateValueAsOptionalBlob;
function validateValueAsAny(value, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
}
exports.validateValueAsAny = validateValueAsAny;
function validateValueAsOptionalAny(value, propertyName) {
if (value === undefined) {
return;
}
validateValueAsAny(value, propertyName);
}
exports.validateValueAsOptionalAny = validateValueAsOptionalAny;
function validateValueAsArray(value, elementValidator, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
if (!Array.isArray(value)) {
throwInvalidPropertyValueError('an array value', propertyName);
}
for (const element of value) {
try {
elementValidator(element);
}
catch (err) {
let serviceError = err;
if (propertyName) {
throw createServiceError(`Array property '${propertyName}' contains an invalid value: ${serviceError.toString()}`);
}
else {
throw createServiceError(`Array contains an invalid value: ${serviceError.toString()}`);
}
}
}
}
exports.validateValueAsArray = validateValueAsArray;
function validateValueAsOptionalArray(value, elementValidator, propertyName) {
if (value === undefined) {
return;
}
validateValueAsArray(value, elementValidator, propertyName);
}
exports.validateValueAsOptionalArray = validateValueAsOptionalArray;
function validateValueAsMap(value, keyValidator, valueValidator, propertyName) {
if (value === undefined) {
return;
}
/*
if (!(value instanceof Map)) {
throwInvalidPropertyValueError('a map value', propertyName);
}*/
//let valueAsMap = value as Map<any, any>;
for (const key in value) {
try {
keyValidator(key);
}
catch (err) {
let serviceError = err;
if (propertyName) {
throw createServiceError(`Map property '${propertyName}' contains an invalid key: ${serviceError.toString()}`);
}
else {
throw createServiceError(`Map contains an invalid key: ${serviceError.toString()}`);
}
}
let val = value[key];
try {
valueValidator(val);
}
catch (err) {
let serviceError = err;
if (propertyName) {
throw createServiceError(`Map property '${propertyName}' contains an invalid value: ${serviceError.toString()}`);
}
else {
throw createServiceError(`Map contains an invalid value: ${serviceError.toString()}`);
}
}
}
}
exports.validateValueAsMap = validateValueAsMap;
function validateValueAsOptionalMap(value, keyValidator, valueValidator, propertyName) {
if (value === undefined) {
return;
}
validateValueAsMap(value, keyValidator, valueValidator, propertyName);
}
exports.validateValueAsOptionalMap = validateValueAsOptionalMap;
function validateValueAsObject(value, elementValidator, propertyName) {
if (value === undefined) {
throwMissingPropertyError(propertyName);
}
try {
elementValidator(value);
}
catch (err) {
let serviceError = err;
throw createServiceError(`Property '${propertyName}' contains an invalid value: ${serviceError.toString()}`);
}
}
exports.validateValueAsObject = validateValueAsObject;
function validateValueAsOptionalObject(value, elementValidator, propertyName) {
if (value === undefined) {
return;
}
validateValueAsObject(value, elementValidator, propertyName);
}
exports.validateValueAsOptionalObject = validateValueAsOptionalObject;
//# sourceMappingURL=mqtt_request_response_utils.js.map