UNPKG

14.6 kBJavaScriptView Raw
1"use strict";
2// The MIT License (MIT)
3//
4// Copyright (c) 2023 Firebase
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22// SOFTWARE.
23Object.defineProperty(exports, "__esModule", { value: true });
24exports.onChangedOperation = exports.onOperation = exports.makeEndpoint = exports.makeChangedFirestoreEvent = exports.makeFirestoreEvent = exports.makeParams = exports.createBeforeSnapshot = exports.createSnapshot = exports.getOpts = exports.onDocumentDeletedWithAuthContext = exports.onDocumentDeleted = exports.onDocumentUpdatedWithAuthContext = exports.onDocumentUpdated = exports.onDocumentCreatedWithAuthContext = exports.onDocumentCreated = exports.onDocumentWrittenWithAuthContext = exports.onDocumentWritten = exports.deletedEventWithAuthContextType = exports.updatedEventWithAuthContextType = exports.createdEventWithAuthContextType = exports.writtenEventWithAuthContextType = exports.deletedEventType = exports.updatedEventType = exports.createdEventType = exports.writtenEventType = exports.Change = void 0;
25const logger = require("../../logger");
26const path_1 = require("../../common/utilities/path");
27const path_pattern_1 = require("../../common/utilities/path-pattern");
28const manifest_1 = require("../../runtime/manifest");
29const core_1 = require("../core");
30Object.defineProperty(exports, "Change", { enumerable: true, get: function () { return core_1.Change; } });
31const options_1 = require("../options");
32const firestore_1 = require("../../common/providers/firestore");
33const trace_1 = require("../trace");
34const onInit_1 = require("../../common/onInit");
35/** @internal */
36exports.writtenEventType = "google.cloud.firestore.document.v1.written";
37/** @internal */
38exports.createdEventType = "google.cloud.firestore.document.v1.created";
39/** @internal */
40exports.updatedEventType = "google.cloud.firestore.document.v1.updated";
41/** @internal */
42exports.deletedEventType = "google.cloud.firestore.document.v1.deleted";
43/** @internal */
44exports.writtenEventWithAuthContextType = "google.cloud.firestore.document.v1.written.withAuthContext";
45/** @internal */
46exports.createdEventWithAuthContextType = "google.cloud.firestore.document.v1.created.withAuthContext";
47/** @internal */
48exports.updatedEventWithAuthContextType = "google.cloud.firestore.document.v1.updated.withAuthContext";
49/** @internal */
50exports.deletedEventWithAuthContextType = "google.cloud.firestore.document.v1.deleted.withAuthContext";
51/**
52 * Event handler that triggers when a document is created, updated, or deleted in Firestore.
53 *
54 * @param documentOrOpts - Options or a string document path.
55 * @param handler - Event handler which is run every time a Firestore create, update, or delete occurs.
56 */
57function onDocumentWritten(documentOrOpts, handler) {
58 return onChangedOperation(exports.writtenEventType, documentOrOpts, handler);
59}
60exports.onDocumentWritten = onDocumentWritten;
61/**
62 * Event handler that triggers when a document is created, updated, or deleted in Firestore.
63 * This trigger also provides the authentication context of the principal who triggered the event.
64 *
65 * @param opts - Options or a string document path.
66 * @param handler - Event handler which is run every time a Firestore create, update, or delete occurs.
67 */
68function onDocumentWrittenWithAuthContext(documentOrOpts, handler) {
69 return onChangedOperation(exports.writtenEventWithAuthContextType, documentOrOpts, handler);
70}
71exports.onDocumentWrittenWithAuthContext = onDocumentWrittenWithAuthContext;
72/**
73 * Event handler that triggers when a document is created in Firestore.
74 *
75 * @param documentOrOpts - Options or a string document path.
76 * @param handler - Event handler which is run every time a Firestore create occurs.
77 */
78function onDocumentCreated(documentOrOpts, handler) {
79 return onOperation(exports.createdEventType, documentOrOpts, handler);
80}
81exports.onDocumentCreated = onDocumentCreated;
82/**
83 * Event handler that triggers when a document is created in Firestore.
84 *
85 * @param documentOrOpts - Options or a string document path.
86 * @param handler - Event handler which is run every time a Firestore create occurs.
87 */
88function onDocumentCreatedWithAuthContext(documentOrOpts, handler) {
89 return onOperation(exports.createdEventWithAuthContextType, documentOrOpts, handler);
90}
91exports.onDocumentCreatedWithAuthContext = onDocumentCreatedWithAuthContext;
92/**
93 * Event handler that triggers when a document is updated in Firestore.
94 *
95 * @param documentOrOpts - Options or a string document path.
96 * @param handler - Event handler which is run every time a Firestore update occurs.
97 */
98function onDocumentUpdated(documentOrOpts, handler) {
99 return onChangedOperation(exports.updatedEventType, documentOrOpts, handler);
100}
101exports.onDocumentUpdated = onDocumentUpdated;
102/**
103 * Event handler that triggers when a document is updated in Firestore.
104 *
105 * @param documentOrOpts - Options or a string document path.
106 * @param handler - Event handler which is run every time a Firestore update occurs.
107 */
108function onDocumentUpdatedWithAuthContext(documentOrOpts, handler) {
109 return onChangedOperation(exports.updatedEventWithAuthContextType, documentOrOpts, handler);
110}
111exports.onDocumentUpdatedWithAuthContext = onDocumentUpdatedWithAuthContext;
112/**
113 * Event handler that triggers when a document is deleted in Firestore.
114 *
115 * @param documentOrOpts - Options or a string document path.
116 * @param handler - Event handler which is run every time a Firestore delete occurs.
117 */
118function onDocumentDeleted(documentOrOpts, handler) {
119 return onOperation(exports.deletedEventType, documentOrOpts, handler);
120}
121exports.onDocumentDeleted = onDocumentDeleted;
122/**
123 * Event handler that triggers when a document is deleted in Firestore.
124 *
125 * @param documentOrOpts - Options or a string document path.
126 * @param handler - Event handler which is run every time a Firestore delete occurs.
127 */
128function onDocumentDeletedWithAuthContext(documentOrOpts, handler) {
129 return onOperation(exports.deletedEventWithAuthContextType, documentOrOpts, handler);
130}
131exports.onDocumentDeletedWithAuthContext = onDocumentDeletedWithAuthContext;
132/** @internal */
133function getOpts(documentOrOpts) {
134 let document;
135 let database;
136 let namespace;
137 let opts;
138 if (typeof documentOrOpts === "string") {
139 document = (0, path_1.normalizePath)(documentOrOpts);
140 database = "(default)";
141 namespace = "(default)";
142 opts = {};
143 }
144 else {
145 document =
146 typeof documentOrOpts.document === "string"
147 ? (0, path_1.normalizePath)(documentOrOpts.document)
148 : documentOrOpts.document;
149 database = documentOrOpts.database || "(default)";
150 namespace = documentOrOpts.namespace || "(default)";
151 opts = { ...documentOrOpts };
152 delete opts.document;
153 delete opts.database;
154 delete opts.namespace;
155 }
156 return {
157 document,
158 database,
159 namespace,
160 opts,
161 };
162}
163exports.getOpts = getOpts;
164/** @hidden */
165function getPath(event) {
166 return `projects/${event.project}/databases/${event.database}/documents/${event.document}`;
167}
168/** @internal */
169function createSnapshot(event) {
170 var _a, _b, _c, _d;
171 if (((_a = event.datacontenttype) === null || _a === void 0 ? void 0 : _a.includes("application/protobuf")) || Buffer.isBuffer(event.data)) {
172 return (0, firestore_1.createSnapshotFromProtobuf)(event.data, getPath(event), event.database);
173 }
174 else if ((_b = event.datacontenttype) === null || _b === void 0 ? void 0 : _b.includes("application/json")) {
175 return (0, firestore_1.createSnapshotFromJson)(event.data, event.source, (_c = event.data.value) === null || _c === void 0 ? void 0 : _c.createTime, (_d = event.data.value) === null || _d === void 0 ? void 0 : _d.updateTime, event.database);
176 }
177 else {
178 logger.error(`Cannot determine payload type, datacontenttype is ${event.datacontenttype}, failing out.`);
179 throw Error("Error: Cannot parse event payload.");
180 }
181}
182exports.createSnapshot = createSnapshot;
183/** @internal */
184function createBeforeSnapshot(event) {
185 var _a, _b, _c, _d;
186 if (((_a = event.datacontenttype) === null || _a === void 0 ? void 0 : _a.includes("application/protobuf")) || Buffer.isBuffer(event.data)) {
187 return (0, firestore_1.createBeforeSnapshotFromProtobuf)(event.data, getPath(event), event.database);
188 }
189 else if ((_b = event.datacontenttype) === null || _b === void 0 ? void 0 : _b.includes("application/json")) {
190 return (0, firestore_1.createBeforeSnapshotFromJson)(event.data, event.source, (_c = event.data.oldValue) === null || _c === void 0 ? void 0 : _c.createTime, (_d = event.data.oldValue) === null || _d === void 0 ? void 0 : _d.updateTime, event.database);
191 }
192 else {
193 logger.error(`Cannot determine payload type, datacontenttype is ${event.datacontenttype}, failing out.`);
194 throw Error("Error: Cannot parse event payload.");
195 }
196}
197exports.createBeforeSnapshot = createBeforeSnapshot;
198/** @internal */
199function makeParams(document, documentPattern) {
200 return {
201 ...documentPattern.extractMatches(document),
202 };
203}
204exports.makeParams = makeParams;
205/** @internal */
206function makeFirestoreEvent(eventType, event, params) {
207 const data = event.data
208 ? eventType === exports.createdEventType || eventType === exports.createdEventWithAuthContextType
209 ? createSnapshot(event)
210 : createBeforeSnapshot(event)
211 : undefined;
212 const firestoreEvent = {
213 ...event,
214 params,
215 data,
216 };
217 delete firestoreEvent.datacontenttype;
218 delete firestoreEvent.dataschema;
219 if ("authtype" in event) {
220 const eventWithAuth = {
221 ...firestoreEvent,
222 authType: event.authtype,
223 authId: event.authid,
224 };
225 delete eventWithAuth.authtype;
226 delete eventWithAuth.authid;
227 return eventWithAuth;
228 }
229 return firestoreEvent;
230}
231exports.makeFirestoreEvent = makeFirestoreEvent;
232/** @internal */
233function makeChangedFirestoreEvent(event, params) {
234 const data = event.data
235 ? core_1.Change.fromObjects(createBeforeSnapshot(event), createSnapshot(event))
236 : undefined;
237 const firestoreEvent = {
238 ...event,
239 params,
240 data,
241 };
242 delete firestoreEvent.datacontenttype;
243 delete firestoreEvent.dataschema;
244 if ("authtype" in event) {
245 const eventWithAuth = {
246 ...firestoreEvent,
247 authType: event.authtype,
248 authId: event.authid,
249 };
250 delete eventWithAuth.authtype;
251 delete eventWithAuth.authid;
252 return eventWithAuth;
253 }
254 return firestoreEvent;
255}
256exports.makeChangedFirestoreEvent = makeChangedFirestoreEvent;
257/** @internal */
258function makeEndpoint(eventType, opts, document, database, namespace) {
259 var _a;
260 const baseOpts = (0, options_1.optionsToEndpoint)((0, options_1.getGlobalOptions)());
261 const specificOpts = (0, options_1.optionsToEndpoint)(opts);
262 const eventFilters = {
263 database,
264 namespace,
265 };
266 const eventFilterPathPatterns = {};
267 const maybePattern = typeof document === "string" ? new path_pattern_1.PathPattern(document).hasWildcards() : true;
268 if (maybePattern) {
269 eventFilterPathPatterns.document = document;
270 }
271 else {
272 eventFilters.document = document;
273 }
274 return {
275 ...(0, manifest_1.initV2Endpoint)((0, options_1.getGlobalOptions)(), opts),
276 platform: "gcfv2",
277 ...baseOpts,
278 ...specificOpts,
279 labels: {
280 ...baseOpts === null || baseOpts === void 0 ? void 0 : baseOpts.labels,
281 ...specificOpts === null || specificOpts === void 0 ? void 0 : specificOpts.labels,
282 },
283 eventTrigger: {
284 eventType,
285 eventFilters,
286 eventFilterPathPatterns,
287 retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
288 },
289 };
290}
291exports.makeEndpoint = makeEndpoint;
292/** @internal */
293function onOperation(eventType, documentOrOpts, handler) {
294 const { document, database, namespace, opts } = getOpts(documentOrOpts);
295 // wrap the handler
296 const func = (raw) => {
297 const event = raw;
298 const documentPattern = new path_pattern_1.PathPattern(typeof document === "string" ? document : document.value());
299 const params = makeParams(event.document, documentPattern);
300 const firestoreEvent = makeFirestoreEvent(eventType, event, params);
301 return (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)(handler))(firestoreEvent);
302 };
303 func.run = handler;
304 func.__endpoint = makeEndpoint(eventType, opts, document, database, namespace);
305 return func;
306}
307exports.onOperation = onOperation;
308/** @internal */
309function onChangedOperation(eventType, documentOrOpts, handler) {
310 const { document, database, namespace, opts } = getOpts(documentOrOpts);
311 // wrap the handler
312 const func = (raw) => {
313 const event = raw;
314 const documentPattern = new path_pattern_1.PathPattern(typeof document === "string" ? document : document.value());
315 const params = makeParams(event.document, documentPattern);
316 const firestoreEvent = makeChangedFirestoreEvent(event, params);
317 return (0, trace_1.wrapTraceContext)((0, onInit_1.withInit)(handler))(firestoreEvent);
318 };
319 func.run = handler;
320 func.__endpoint = makeEndpoint(eventType, opts, document, database, namespace);
321 return func;
322}
323exports.onChangedOperation = onChangedOperation;