1 |
|
2 | "use strict";
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | Object.defineProperty(exports, "__esModule", { value: true });
|
20 | exports.EventarcApiClient = void 0;
|
21 | const validator = require("../utils/validator");
|
22 | const eventarc_utils_1 = require("./eventarc-utils");
|
23 | const api_request_1 = require("../utils/api-request");
|
24 | const utils = require("../utils");
|
25 | const error_1 = require("../utils/error");
|
26 | const EVENTARC_API = 'https://eventarcpublishing.googleapis.com/v1';
|
27 | const FIREBASE_VERSION_HEADER = {
|
28 | 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}`,
|
29 | };
|
30 | const CHANNEL_NAME_REGEX = /^(projects\/([^/]+)\/)?locations\/([^/]+)\/channels\/([^/]+)$/;
|
31 | const DEFAULT_CHANNEL_REGION = 'us-central1';
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | class EventarcApiClient {
|
38 | constructor(app, channel) {
|
39 | this.app = app;
|
40 | this.channel = channel;
|
41 | if (!validator.isNonNullObject(app) || !('options' in app)) {
|
42 | throw new eventarc_utils_1.FirebaseEventarcError('invalid-argument', 'First argument passed to Channel() must be a valid Eventarc service instance.');
|
43 | }
|
44 | this.httpClient = new api_request_1.AuthorizedHttpClient(app);
|
45 | this.resolvedChannelName = this.resolveChannelName(channel.name);
|
46 | }
|
47 | getProjectId() {
|
48 | if (this.projectId) {
|
49 | return Promise.resolve(this.projectId);
|
50 | }
|
51 | return utils.findProjectId(this.app)
|
52 | .then((projectId) => {
|
53 | if (!validator.isNonEmptyString(projectId)) {
|
54 | throw new eventarc_utils_1.FirebaseEventarcError('unknown-error', 'Failed to determine project ID. Initialize the '
|
55 | + 'SDK with service account credentials or set project ID as an app option. '
|
56 | + 'Alternatively, set the GOOGLE_CLOUD_PROJECT environment variable.');
|
57 | }
|
58 | this.projectId = projectId;
|
59 | return projectId;
|
60 | });
|
61 | }
|
62 | |
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | async publish(events) {
|
75 | if (!Array.isArray(events)) {
|
76 | events = [events];
|
77 | }
|
78 | return this.publishToEventarcApi(await this.resolvedChannelName, events
|
79 | .filter(e => typeof this.channel.allowedEventTypes === 'undefined' ||
|
80 | this.channel.allowedEventTypes.includes(e.type))
|
81 | .map(eventarc_utils_1.toCloudEventProtoFormat));
|
82 | }
|
83 | async publishToEventarcApi(channel, events) {
|
84 | if (events.length === 0) {
|
85 | return;
|
86 | }
|
87 | const request = {
|
88 | method: 'POST',
|
89 | url: `${this.getEventarcHost()}/${channel}:publishEvents`,
|
90 | data: JSON.stringify({ events }),
|
91 | };
|
92 | return this.sendRequest(request);
|
93 | }
|
94 | sendRequest(request) {
|
95 | request.headers = FIREBASE_VERSION_HEADER;
|
96 | return this.httpClient.send(request)
|
97 | .then(() => undefined)
|
98 | .catch((err) => {
|
99 | throw this.toFirebaseError(err);
|
100 | });
|
101 | }
|
102 | toFirebaseError(err) {
|
103 | if (err instanceof error_1.PrefixedFirebaseError) {
|
104 | return err;
|
105 | }
|
106 | const response = err.response;
|
107 | return new eventarc_utils_1.FirebaseEventarcError('unknown-error', `Unexpected response with status: ${response.status} and body: ${response.text}`);
|
108 | }
|
109 | resolveChannelName(name) {
|
110 | if (!name.includes('/')) {
|
111 | const location = DEFAULT_CHANNEL_REGION;
|
112 | const channelId = name;
|
113 | return this.resolveChannelNameProjectId(location, channelId);
|
114 | }
|
115 | else {
|
116 | const match = CHANNEL_NAME_REGEX.exec(name);
|
117 | if (match === null || match.length < 4) {
|
118 | throw new eventarc_utils_1.FirebaseEventarcError('invalid-argument', 'Invalid channel name format.');
|
119 | }
|
120 | const projectId = match[2];
|
121 | const location = match[3];
|
122 | const channelId = match[4];
|
123 | if (validator.isNonEmptyString(projectId)) {
|
124 | return Promise.resolve(`projects/${projectId}/locations/${location}/channels/${channelId}`);
|
125 | }
|
126 | else {
|
127 | return this.resolveChannelNameProjectId(location, channelId);
|
128 | }
|
129 | }
|
130 | }
|
131 | async resolveChannelNameProjectId(location, channelId) {
|
132 | const projectId = await this.getProjectId();
|
133 | return `projects/${projectId}/locations/${location}/channels/${channelId}`;
|
134 | }
|
135 | getEventarcHost() {
|
136 | return process.env.CLOUD_EVENTARC_EMULATOR_HOST ?? EVENTARC_API;
|
137 | }
|
138 | }
|
139 | exports.EventarcApiClient = EventarcApiClient;
|