@azure/eventgrid
Version:
An isomorphic client library for the Azure Event Grid service.
125 lines • 6.11 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { __rest } from "tslib";
import { isTokenCredential } from "@azure/core-auth";
import { eventGridCredentialPolicy } from "./eventGridAuthenticationPolicy.js";
import { DEFAULT_EVENTGRID_SCOPE } from "./constants.js";
import { cloudEventReservedPropertyNames } from "./models.js";
import { GeneratedClient } from "./generated/generatedClient.js";
import { cloudEventDistributedTracingEnricherPolicy } from "./cloudEventDistrubtedTracingEnricherPolicy.js";
import { tracingClient } from "./tracing.js";
import { randomUUID } from "@azure/core-util";
import { bearerTokenAuthenticationPolicy, tracingPolicyName } from "@azure/core-rest-pipeline";
/**
* Client class for publishing events to the Event Grid Service.
*/
export class EventGridPublisherClient {
/**
* Creates an instance of EventGridPublisherClient which sends events using the Event Grid Schema.
*
* Example usage:
* ```ts snippet:ReadmeSampleCreateClient_KeyCredential
* import { EventGridPublisherClient, AzureKeyCredential } from "@azure/eventgrid";
*
* const client = new EventGridPublisherClient(
* "<endpoint>",
* "EventGrid",
* new AzureKeyCredential("<Access Key>"),
* );
* ```
*
* @param endpointUrl - The URL to the Event Grid endpoint, e.g. https://eg-topic.westus2-1.eventgrid.azure.net/api/events.
* @param inputSchema - The schema that the Event Grid endpoint is configured to accept. One of "EventGrid", "CloudEvent", or "Custom".
* @param credential - Used to authenticate requests to the service.
* @param options - Used to configure the Event Grid Client.
*/
constructor(endpointUrl, inputSchema, credential, options = {}) {
this.endpointUrl = endpointUrl;
this.inputSchema = inputSchema;
this.client = new GeneratedClient(options);
const authPolicy = isTokenCredential(credential)
? bearerTokenAuthenticationPolicy({ credential, scopes: DEFAULT_EVENTGRID_SCOPE })
: eventGridCredentialPolicy(credential);
this.client.pipeline.addPolicy(authPolicy);
this.client.pipeline.addPolicy(cloudEventDistributedTracingEnricherPolicy(), {
afterPolicies: [tracingPolicyName],
});
this.apiVersion = this.client.apiVersion;
}
/**
* Sends events to a topic.
*
* @param events - The events to send. The events should be in the schema used when constructing the client.
* @param options - Options to control the underlying operation.
*/
send(events, options = {}) {
return tracingClient.withSpan("EventGridPublisherClient.send", options, (updatedOptions) => {
switch (this.inputSchema) {
case "EventGrid": {
return this.client.publishEventGridEvents(this.endpointUrl, events.map(convertEventGridEventToModelType), updatedOptions);
}
case "CloudEvent": {
// The underlying REST API expects a header named `aeg-channel-name`, and so the generated client
// expects that options bag has a property called `aegChannelName`, where as we expose it with the
// friendlier name "channelName". Fix up the impedence mismatch here
const _a = updatedOptions, { channelName } = _a, sendOptions = __rest(_a, ["channelName"]);
if (channelName) {
sendOptions.aegChannelName = channelName;
}
return this.client.publishCloudEventEvents(this.endpointUrl, events.map(convertCloudEventToModelType), sendOptions);
}
case "Custom": {
return this.client.publishCustomEventEvents(this.endpointUrl, events, updatedOptions);
}
default: {
throw new Error(`Unknown input schema type '${this.inputSchema}'`);
}
}
});
}
}
/**
* @internal
*/
export function convertEventGridEventToModelType(event) {
var _a, _b;
return {
eventType: event.eventType,
eventTime: (_a = event.eventTime) !== null && _a !== void 0 ? _a : new Date(),
id: (_b = event.id) !== null && _b !== void 0 ? _b : randomUUID(),
subject: event.subject,
topic: event.topic,
data: event.data,
dataVersion: event.dataVersion,
};
}
/**
* @internal
*/
export function convertCloudEventToModelType(event) {
var _a, _b, _c, _d;
if (event.extensionAttributes) {
for (const propName in event.extensionAttributes) {
// Per the cloud events spec: "CloudEvents attribute names MUST consist of lower-case letters ('a' to 'z') or digits ('0' to '9') from the ASCII character set"
// they also can not match an existing defined property name.
if (!/^[a-z0-9]*$/.test(propName) ||
cloudEventReservedPropertyNames.indexOf(propName) !== -1) {
throw new Error(`invalid extension attribute name: ${propName}`);
}
}
}
const converted = Object.assign({ specversion: "1.0", type: event.type, source: event.source, id: (_a = event.id) !== null && _a !== void 0 ? _a : randomUUID(), time: (_b = event.time) !== null && _b !== void 0 ? _b : new Date(), subject: event.subject, dataschema: event.dataschema }, ((_c = event.extensionAttributes) !== null && _c !== void 0 ? _c : []));
if (event.data instanceof Uint8Array) {
if (!event.datacontenttype) {
throw new Error("a data content type must be provided when sending an event with binary data");
}
converted.datacontenttype = event.datacontenttype;
converted.dataBase64 = event.data;
}
else {
converted.datacontenttype = (_d = event.datacontenttype) !== null && _d !== void 0 ? _d : "application/json";
converted.data = event.data;
}
return converted;
}
//# sourceMappingURL=eventGridClient.js.map