UNPKG

@azure/functions-extensions-servicebus

Version:
889 lines (826 loc) 39 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/grpcClientFactory.ts": /*!**********************************!*\ !*** ./src/grpcClientFactory.ts ***! \**********************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.createGrpcClient = void 0; const grpc = __importStar(__webpack_require__(/*! @grpc/grpc-js */ "@grpc/grpc-js")); const protoLoader = __importStar(__webpack_require__(/*! @grpc/proto-loader */ "@grpc/proto-loader")); const path_1 = __importDefault(__webpack_require__(/*! path */ "path")); /** * Creates and returns a gRPC client for the specified service. * * @template T - The type of gRPC client to create, extends grpc.Client * * @param options - The configuration options for creating the gRPC client * @param options.protoPath - Path to the .proto file that defines the service * @param options.serviceName - Name of the service in the proto file * @param options.address - The server address to connect to (e.g., "localhost:50051") * @param options.credentials - gRPC channel credentials to use for secure communication (defaults to insecure) * @param options.grpcMaxMessageLength - Maximum message length in bytes for both sending and receiving gRPC messages * @param options.includeDirs - Additional directories to search for imported .proto files * * @returns A new instance of the specified gRPC client * * @throws {Error} When the specified service name is not found in the proto file * * @example * const client = createGrpcClient<MyServiceClient>({ * protoPath: './protos/my_service.proto', * serviceName: 'MyService', * address: 'localhost:50051', * grpcMaxMessageLength: 4 * 1024 * 1024, // 4MB * }); */ function createGrpcClient({ protoPath, serviceName, address, credentials = grpc.credentials.createInsecure(), grpcMaxMessageLength, includeDirs = [], }) { // Load the .proto file and generate the package definition const packageDefinition = protoLoader.loadSync(protoPath, { keepCase: false, longs: String, enums: String, defaults: true, oneofs: true, includeDirs: [path_1.default.dirname(protoPath), ...includeDirs], }); // Load the gRPC object from the package definition const grpcObject = grpc.loadPackageDefinition(packageDefinition); // Retrieve the service client constructor from the loaded gRPC object const ServiceClientConstructor = grpcObject[serviceName]; // Throw an error if the service is not found in the proto file if (!ServiceClientConstructor) { throw new Error(`Service "${serviceName}" not found in proto file: ${protoPath}`); } const clientOptions = { 'grpc.max_send_message_length': grpcMaxMessageLength, 'grpc.max_receive_message_length': grpcMaxMessageLength, }; // Create and return a new instance of the service client return new ServiceClientConstructor(address, credentials, clientOptions); } exports.createGrpcClient = createGrpcClient; /***/ }), /***/ "./src/servicebus/ServiceBusMessageActions.ts": /*!****************************************************!*\ !*** ./src/servicebus/ServiceBusMessageActions.ts ***! \****************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ServiceBusMessageActions = void 0; const grpc = __importStar(__webpack_require__(/*! @grpc/grpc-js */ "@grpc/grpc-js")); const path_1 = __importDefault(__webpack_require__(/*! path */ "path")); const grpcClientFactory_1 = __webpack_require__(/*! ../grpcClientFactory */ "./src/grpcClientFactory.ts"); const grpcUriBuilder_1 = __webpack_require__(/*! ../util/grpcUriBuilder */ "./src/util/grpcUriBuilder.ts"); const PROTO_PATH = path_1.default.join(__dirname, '/proto/settlement.proto'); // Client implementation with Promise-based methods class ServiceBusMessageActions { constructor() { const { uri, grpcMaxMessageLength } = grpcUriBuilder_1.GrpcUriBuilder.build(); this.client = (0, grpcClientFactory_1.createGrpcClient)({ protoPath: PROTO_PATH, serviceName: 'Settlement', address: uri, credentials: grpc.credentials.createInsecure(), grpcMaxMessageLength, }); } static getInstance() { if (!ServiceBusMessageActions.instance) { ServiceBusMessageActions.instance = new ServiceBusMessageActions(); } return ServiceBusMessageActions.instance; } // Add this private helper method to the ServiceBusMessageActions class validateLockToken(message) { const locktoken = message.lockToken; if (!locktoken) { throw new Error('ArgumentException: lockToken is required in ServiceBusReceivedMessage.'); } return locktoken; } /** * Completes (settles) the specified message, removing it from the queue or subscription. * * @param message - The received Service Bus message to complete. * @returns A promise that resolves when the operation is successful. * @throws Error if the lockToken is missing or the gRPC call fails. */ complete(message) { return __awaiter(this, void 0, void 0, function* () { const locktoken = this.validateLockToken(message); return new Promise((resolve, reject) => { const request = { locktoken }; this.client.complete(request, (error) => { if (error) { console.error('Complete request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Abandons the specified message, making it available again for processing. * * @param message - The received Service Bus message to abandon. * @param propertiesToModify - Optional properties to modify on the message. * @returns A promise that resolves when the operation is successful. * @throws Error if the lockToken is missing or the gRPC call fails. */ abandon(message, propertiesToModify) { return __awaiter(this, void 0, void 0, function* () { const locktoken = this.validateLockToken(message); return new Promise((resolve, reject) => { const request = { locktoken, propertiesToModify: propertiesToModify || new Uint8Array(), }; this.client.abandon(request, (error) => { if (error) { console.error('Abandon request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Deadletters the specified message, moving it to the dead-letter queue. * * @param message - The received Service Bus message to deadletter. * @param propertiesToModify - Optional properties to modify on the message. * @param deadletterReason - Optional reason for deadlettering the message. * @param deadletterErrorDescription - Optional error description for deadlettering. * @returns A promise that resolves when the operation is successful. * @throws Error if the lockToken is missing or the gRPC call fails. */ deadletter(message, propertiesToModify, deadletterReason, deadletterErrorDescription) { return __awaiter(this, void 0, void 0, function* () { const locktoken = this.validateLockToken(message); return new Promise((resolve, reject) => { const request = { locktoken, propertiesToModify: propertiesToModify || new Uint8Array(), deadletterReason, deadletterErrorDescription, }; this.client.deadletter(request, (error) => { if (error) { console.error('Deadletter request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Defers the specified message, making it invisible until retrieved by sequence number. * * @param message - The received Service Bus message to defer. * @param propertiesToModify - Optional properties to modify on the message. * @returns A promise that resolves when the operation is successful. * @throws Error if the lockToken is missing or the gRPC call fails. */ defer(message, propertiesToModify) { return __awaiter(this, void 0, void 0, function* () { const locktoken = this.validateLockToken(message); return new Promise((resolve, reject) => { const request = { locktoken, propertiesToModify: propertiesToModify || new Uint8Array(), }; this.client.defer(request, (error) => { if (error) { console.error('Defer request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Renews the lock on the specified message, extending its lock duration. * * @param message - The received Service Bus message whose lock should be renewed. * @returns A promise that resolves when the operation is successful. * @throws Error if the lockToken is missing or the gRPC call fails. */ renewMessageLock(message) { return __awaiter(this, void 0, void 0, function* () { const locktoken = this.validateLockToken(message); return new Promise((resolve, reject) => { const request = { locktoken }; this.client.renewMessageLock(request, (error) => { if (error) { console.error('RenewMessageLock request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Sets the state for the specified session. * * @param sessionId - The session ID for which to set the state. * @param sessionState - The state to set for the session. * @returns A promise that resolves when the operation is successful. * @throws Error if the gRPC call fails. */ setSessionState(sessionId, sessionState) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { const request = { sessionId, sessionState }; this.client.setSessionState(request, (error) => { if (error) { console.error('SetSessionState request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Releases the specified session, making it available for other receivers. * * @param sessionId - The session ID to release. * @returns A promise that resolves when the operation is successful. * @throws Error if the gRPC call fails. */ releaseSession(sessionId) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { const request = { sessionId }; this.client.releaseSession(request, (error) => { if (error) { console.error('ReleaseSession request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else { resolve(); } }); }); }); } /** * Renews the lock on the specified session, extending its lock duration. * * @param sessionId - The session ID whose lock should be renewed. * @returns A promise that resolves to the new locked-until date. * @throws Error if the gRPC call fails or if no response is returned. */ renewSessionLock(sessionId) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { const request = { sessionId }; this.client.renewSessionLock(request, (error, response) => { if (error) { console.error('RenewSessionLock request failed:', { code: error.code, message: error.message, details: error.details, }); reject(error); } else if (response && response.lockedUntil) { resolve(response.lockedUntil); } else { const err = new Error('No response or lockedUntil returned from renewSessionLock'); console.error(err); reject(err); } }); }); }); } /** * Resets the singleton instance (for testing purposes). */ static resetInstance() { ServiceBusMessageActions.instance = null; } } exports.ServiceBusMessageActions = ServiceBusMessageActions; ServiceBusMessageActions.instance = null; /***/ }), /***/ "./src/servicebus/azureServiceBusMessageFactory.ts": /*!*********************************************************!*\ !*** ./src/servicebus/azureServiceBusMessageFactory.ts ***! \*********************************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.AzureServiceBusMessageFactory = void 0; const core_amqp_1 = __webpack_require__(/*! @azure/core-amqp */ "@azure/core-amqp"); const long_1 = __importDefault(__webpack_require__(/*! long */ "long")); const serviceBusMessageDecoder_1 = __webpack_require__(/*! ../util/serviceBusMessageDecoder */ "./src/util/serviceBusMessageDecoder.ts"); const ServiceBusMessageActions_1 = __webpack_require__(/*! ./ServiceBusMessageActions */ "./src/servicebus/ServiceBusMessageActions.ts"); const ENQUEUED_TIME_ANNOTATION = 'x-opt-enqueued-time'; const SEQUENCE_NUMBER_ANNOTATION = 'x-opt-sequence-number'; const DEAD_LETTER_REASON_ANNOTATION = 'DeadLetterReason'; const DEAD_LETTER_ERROR_DESCRIPTION_ANNOTATION = 'DeadLetterErrorDescription'; /** * Factory class for creating and processing Azure Service Bus messages Manager. * * This factory class provides methods to: * - Build ServiceBusMessage instances from model binding data in Azure Functions * - Convert between different message formats (AMQP, Rhea) * - Extract and decode message body content with proper type handling * * The factory handles all necessary transformations of message properties, * annotations, and content to ensure proper integration with the Azure * Service Bus messaging system. */ class AzureServiceBusMessageFactory { /** * Builds a ServiceBusMessageContext instance from model binding data. * This method extracts the Service Bus message content from the provided model binding data, * @param modelBindingData - The model binding data containing the Service Bus message content. * This can be a single ModelBindingData object or an array of ModelBindingData objects. * @returns A ServiceBusMessageContext instance. */ static buildServiceBusMessageFromModelBindingData(modelBindingData) { const client = ServiceBusMessageActions_1.ServiceBusMessageActions.getInstance(); const toMessage = (data) => { if (!data.content) { throw new Error('ModelBindingData.content is null or undefined.'); } const { decodedMessage, lockToken } = serviceBusMessageDecoder_1.ServiceBusMessageDecoder.decode(data.content); return this.createServiceBusReceivedMessageFromRhea(decodedMessage, lockToken); }; const messages = Array.isArray(modelBindingData) ? modelBindingData.map(toMessage) : toMessage(modelBindingData); return { messages, actions: client, }; } /** * Creates a ServiceBusReceivedMessage from an AMQP annotated message. * This method extracts relevant properties and formats them into the ServiceBusReceivedMessage structure. * * @param amqpMessage - The AMQP annotated message to convert. * @param lockToken - lock token for the message. * @returns A ServiceBusReceivedMessage object. */ static createServiceBusReceivedMessageFromAmqp(amqpMessage, lockToken) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; // Extract common properties from the AMQP message const receivedMessage = { // Message body body: AzureServiceBusMessageFactory.decodeAmqpBody(amqpMessage.body, (_a = amqpMessage.properties) === null || _a === void 0 ? void 0 : _a.contentType), // Message properties messageId: (_c = (_b = amqpMessage.properties) === null || _b === void 0 ? void 0 : _b.messageId) === null || _c === void 0 ? void 0 : _c.toString(), correlationId: (_e = (_d = amqpMessage.properties) === null || _d === void 0 ? void 0 : _d.correlationId) === null || _e === void 0 ? void 0 : _e.toString(), contentType: (_f = amqpMessage.properties) === null || _f === void 0 ? void 0 : _f.contentType, subject: (_g = amqpMessage.properties) === null || _g === void 0 ? void 0 : _g.subject, to: (_h = amqpMessage.properties) === null || _h === void 0 ? void 0 : _h.to, replyTo: (_j = amqpMessage.properties) === null || _j === void 0 ? void 0 : _j.replyTo, replyToSessionId: (_k = amqpMessage.properties) === null || _k === void 0 ? void 0 : _k.replyToGroupId, sessionId: (_l = amqpMessage.properties) === null || _l === void 0 ? void 0 : _l.groupId, timeToLive: (_m = amqpMessage.header) === null || _m === void 0 ? void 0 : _m.timeToLive, // Application properties applicationProperties: amqpMessage.applicationProperties || {}, // Message annotations and delivery annotations deliveryCount: ((_o = amqpMessage.header) === null || _o === void 0 ? void 0 : _o.deliveryCount) || 0, // Lock token (if provided) lockToken: lockToken, // AMQP annotated message for full access _rawAmqpMessage: amqpMessage, // Timestamps (convert from AMQP format if available) enqueuedTimeUtc: ((_p = amqpMessage.messageAnnotations) === null || _p === void 0 ? void 0 : _p[ENQUEUED_TIME_ANNOTATION]) !== undefined && (typeof amqpMessage.messageAnnotations[ENQUEUED_TIME_ANNOTATION] === 'string' || typeof amqpMessage.messageAnnotations[ENQUEUED_TIME_ANNOTATION] === 'number') ? new Date(amqpMessage.messageAnnotations[ENQUEUED_TIME_ANNOTATION]) : undefined, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment sequenceNumber: ((_q = amqpMessage.messageAnnotations) === null || _q === void 0 ? void 0 : _q[SEQUENCE_NUMBER_ANNOTATION]) !== undefined ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call long_1.default.fromNumber(Number(amqpMessage.messageAnnotations[SEQUENCE_NUMBER_ANNOTATION])) : undefined, // Dead letter properties deadLetterReason: (_r = amqpMessage.applicationProperties) === null || _r === void 0 ? void 0 : _r[DEAD_LETTER_REASON_ANNOTATION], deadLetterErrorDescription: (_s = amqpMessage.applicationProperties) === null || _s === void 0 ? void 0 : _s[DEAD_LETTER_ERROR_DESCRIPTION_ANNOTATION], // State state: 'active', }; return receivedMessage; } /** * Creates a ServiceBusReceivedMessage from a Rhea message. * This method extracts relevant properties and formats them into the ServiceBusReceivedMessage structure. * * @param rheaMessage - The Rhea message to convert. * @param lockToken - Optional lock token for the message. * @returns A ServiceBusReceivedMessage object. */ static createServiceBusReceivedMessageFromRhea(rheaMessage, lockToken) { const amqpMessage = core_amqp_1.AmqpAnnotatedMessage.fromRheaMessage(rheaMessage); return AzureServiceBusMessageFactory.createServiceBusReceivedMessageFromAmqp(amqpMessage, lockToken); } /** * Decodes the body of an AMQP message section based on its typecode and content type. * Supports decoding binary data, plain text, and JSON content. * * @param section - The AMQP message section containing a typecode and content buffer. * @returns The decoded message body or undefined if decoding fails. */ static decodeAmqpBody(section, contentType) { if (typeof section === 'object' && section !== null && 'typecode' in section && 'content' in section && typeof section.typecode === 'number' && Buffer.isBuffer(section.content)) { const { typecode, content } = section; //typecode = 117 is Binary content if (typecode === 117) { const text = content.toString('utf8'); switch (contentType) { case 'text/plain': case 'application/xml': return text; case 'application/json': try { return JSON.parse(text); } catch (_a) { return text; // fallback if not valid JSON } default: return text; // unknown content type convert binary to string and return } } return content; } // Not a valid AMQP body section return section; } } exports.AzureServiceBusMessageFactory = AzureServiceBusMessageFactory; /***/ }), /***/ "./src/servicebus/registerServiceBusMessageFactory.ts": /*!************************************************************!*\ !*** ./src/servicebus/registerServiceBusMessageFactory.ts ***! \************************************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", ({ value: true })); exports.registerServiceBusMessageFactory = void 0; const functions_extensions_base_1 = __webpack_require__(/*! @azure/functions-extensions-base */ "@azure/functions-extensions-base"); const azureServiceBusMessageFactory_1 = __webpack_require__(/*! ./azureServiceBusMessageFactory */ "./src/servicebus/azureServiceBusMessageFactory.ts"); const AZURE_SERVICE_BUS = 'AzureServiceBusReceivedMessage'; function registerServiceBusMessageFactory() { try { const resourceFactoryResolver = functions_extensions_base_1.ResourceFactoryResolver.getInstance(); // Check if a factory is already registered to avoid conflicts if (!resourceFactoryResolver.hasResourceFactory(AZURE_SERVICE_BUS)) { resourceFactoryResolver.registerResourceFactory(AZURE_SERVICE_BUS, (modelBindingData) => { return azureServiceBusMessageFactory_1.AzureServiceBusMessageFactory.buildServiceBusMessageFromModelBindingData(modelBindingData); }); } } catch (error) { throw new Error(`Service Bus Message Factory initialization failed: ${error instanceof Error ? error.message : String(error)}`); } } exports.registerServiceBusMessageFactory = registerServiceBusMessageFactory; /***/ }), /***/ "./src/util/grpcUriBuilder.ts": /*!************************************!*\ !*** ./src/util/grpcUriBuilder.ts ***! \************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.GrpcUriBuilder = void 0; const minimist_1 = __importDefault(__webpack_require__(/*! minimist */ "minimist")); /** * GrpcUriBuilder is a utility class to build a gRPC URI from command line arguments. * It expects two arguments: 'host' and 'port'. */ class GrpcUriBuilder { /** * Builds a gRPC URI from command line arguments. * The expected arguments are 'host' and 'port'. * @returns A string representing the gRPC URI in the format "host:port". * @throws Error if 'host' or 'port' arguments are missing. */ static build() { const parsedArgs = (0, minimist_1.default)(process.argv.slice(2)); const { host, port, 'functions-grpc-max-message-length': grpcMaxMessageLength } = parsedArgs; const missing = []; if (!host) missing.push("'host'"); if (!port) missing.push("'port'"); if (!grpcMaxMessageLength) missing.push("'functions-grpc-max-message-length'"); if (missing.length) { throw new Error(`Missing required arguments: ${missing.join(', ')}`); } return { uri: `${String(host)}:${String(port)}`, grpcMaxMessageLength: Number(grpcMaxMessageLength) }; } } exports.GrpcUriBuilder = GrpcUriBuilder; /***/ }), /***/ "./src/util/lockTokenUtil.ts": /*!***********************************!*\ !*** ./src/util/lockTokenUtil.ts ***! \***********************************/ /***/ ((__unused_webpack_module, exports) => { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", ({ value: true })); exports.LockTokenUtil = void 0; /** * Utility class for handling lock tokens in Azure Service Bus messages. * Provides methods to convert lock tokens to string format and extract them from messages. */ class LockTokenUtil { /** * Converts a lock token from a Buffer to a string format. * The lock token is expected to be in a specific byte order. * @param lockToken - The lock token as a Buffer. * @returns The lock token as a formatted string. */ static convertToString(lockToken) { return [ lockToken.subarray(0, 4).reverse().toString('hex'), lockToken.subarray(4, 6).reverse().toString('hex'), lockToken.subarray(6, 8).reverse().toString('hex'), lockToken.subarray(8, 10).toString('hex'), lockToken.subarray(10).toString('hex'), ].join('-'); } /** * Extracts the lock token from a Service Bus message. * @param message - The Service Bus message as a Buffer. * @param index - The index at which the lock token is located. * @returns The extracted lock token as a string. */ static extractFromMessage(message, index) { const raw = Buffer.isBuffer(message) ? message.subarray(0, index) : new Uint8Array(message.slice(0, index)); return this.convertToString(Buffer.from(raw.subarray(0, 16))); } } exports.LockTokenUtil = LockTokenUtil; LockTokenUtil.X_OPT_LOCK_TOKEN = Buffer.from('x-opt-lock-token'); /***/ }), /***/ "./src/util/serviceBusMessageDecoder.ts": /*!**********************************************!*\ !*** ./src/util/serviceBusMessageDecoder.ts ***! \**********************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ServiceBusMessageDecoder = void 0; const rhea = __webpack_require__(/*! rhea */ "rhea"); const lockTokenUtil_1 = __webpack_require__(/*! ./lockTokenUtil */ "./src/util/lockTokenUtil.ts"); class ServiceBusMessageDecoder { /** * Decodes a Service Bus message from a buffer. * @param content Buffer that contains the Service Bus message with lock token * @returns An object containing the decoded message and the lock token */ static decode(content) { if (!content || content.length === 0) throw new Error('Content buffer is empty'); const index = content.indexOf(lockTokenUtil_1.LockTokenUtil.X_OPT_LOCK_TOKEN); if (index === -1) throw new Error('Lock token not found in content'); const lockToken = lockTokenUtil_1.LockTokenUtil.extractFromMessage(content, index); const amqpSlice = content.subarray(index + lockTokenUtil_1.LockTokenUtil.X_OPT_LOCK_TOKEN.length); const decodedMessage = rhea.message.decode(Buffer.from(amqpSlice)); return { decodedMessage: decodedMessage, lockToken }; } } exports.ServiceBusMessageDecoder = ServiceBusMessageDecoder; /***/ }), /***/ "@azure/core-amqp": /*!***********************************!*\ !*** external "@azure/core-amqp" ***! \***********************************/ /***/ ((module) => { module.exports = require("@azure/core-amqp"); /***/ }), /***/ "@azure/functions-extensions-base": /*!***************************************************!*\ !*** external "@azure/functions-extensions-base" ***! \***************************************************/ /***/ ((module) => { module.exports = require("@azure/functions-extensions-base"); /***/ }), /***/ "@grpc/grpc-js": /*!********************************!*\ !*** external "@grpc/grpc-js" ***! \********************************/ /***/ ((module) => { module.exports = require("@grpc/grpc-js"); /***/ }), /***/ "@grpc/proto-loader": /*!*************************************!*\ !*** external "@grpc/proto-loader" ***! \*************************************/ /***/ ((module) => { module.exports = require("@grpc/proto-loader"); /***/ }), /***/ "long": /*!***********************!*\ !*** external "long" ***! \***********************/ /***/ ((module) => { module.exports = require("long"); /***/ }), /***/ "minimist": /*!***************************!*\ !*** external "minimist" ***! \***************************/ /***/ ((module) => { module.exports = require("minimist"); /***/ }), /***/ "path": /*!***********************!*\ !*** external "path" ***! \***********************/ /***/ ((module) => { module.exports = require("path"); /***/ }), /***/ "rhea": /*!***********************!*\ !*** external "rhea" ***! \***********************/ /***/ ((module) => { module.exports = require("rhea"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports). (() => { var exports = __webpack_exports__; /*!**********************!*\ !*** ./src/index.ts ***! \**********************/ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", ({ value: true })); const registerServiceBusMessageFactory_1 = __webpack_require__(/*! ./servicebus/registerServiceBusMessageFactory */ "./src/servicebus/registerServiceBusMessageFactory.ts"); (0, registerServiceBusMessageFactory_1.registerServiceBusMessageFactory)(); })(); module.exports = __webpack_exports__; /******/ })() ; //# sourceMappingURL=azure-functions-extensions-servicebus.js.map