@digitalaidseattle/firebase 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,15 @@
1
- import { AuthError, AuthService, OAuthResponse, User } from '@digitalaidseattle/core';
2
- declare class FirebaseAuthService implements AuthService {
3
- currentUser: User | undefined;
4
- auth: import("@firebase/auth").Auth;
5
- constructor();
1
+ /**
2
+ * storageService.ts
3
+ *
4
+ * @copyright 2024 Digital Aid Seattle
5
+ *
6
+ */
7
+ import { AuthError, AuthService, OAuthResponse } from '@digitalaidseattle/core';
8
+ import { FirebaseApp } from 'firebase/app';
9
+ import { Auth } from 'firebase/auth';
10
+ export declare class FirebaseAuthService implements AuthService {
11
+ auth: Auth;
12
+ constructor(firebaseClient: FirebaseApp);
6
13
  getProviders(): string[];
7
14
  signInWith(provider: string): Promise<OAuthResponse>;
8
15
  hasUser(): Promise<boolean>;
@@ -12,4 +19,3 @@ declare class FirebaseAuthService implements AuthService {
12
19
  }>;
13
20
  signInWithGoogle: () => Promise<any>;
14
21
  }
15
- export { FirebaseAuthService };
@@ -1,18 +1,21 @@
1
1
  /**
2
- * storageService.ts
2
+ * FirebaseStorageService.ts
3
3
  *
4
- * @copyright 2024 Digital Aid Seattle
4
+ * @copyright 2026 Digital Aid Seattle
5
5
  *
6
6
  */
7
7
  import { StorageService } from "@digitalaidseattle/core";
8
+ import { FirebaseApp } from "firebase/app";
9
+ import { FirebaseStorage } from "firebase/storage";
8
10
  export declare class FirebaseStorageService implements StorageService {
9
- storage: import("@firebase/storage").FirebaseStorage;
11
+ storage: FirebaseStorage;
10
12
  decoder: TextDecoder;
13
+ constructor(firebaseClient: FirebaseApp);
11
14
  downloadFile: (filepath: string) => Promise<string>;
12
15
  getUrlAsync(filepath: string): Promise<string>;
13
- list(filepath?: string): Promise<any[]>;
14
16
  getUrl(filepath: string): string;
15
- upload(path: string, blob: any): Promise<any>;
16
17
  downloadBlob(filepath: string): Promise<Blob | null>;
17
- removeFile(fileName: string): Promise<any>;
18
+ removeFile(path: string): Promise<void>;
19
+ list(filepath?: string): Promise<any[]>;
20
+ upload(path: string, file: any): Promise<any>;
18
21
  }
@@ -9,6 +9,7 @@ declare class FirestoreService<T extends Entity> implements EntityService<T> {
9
9
  insert(entity: T, select?: string, mapper?: (json: any) => T, user?: User): Promise<T>;
10
10
  update(entityId: Identifier, updatedFields: Partial<T>, select?: string, mapper?: (json: any) => T, user?: User): Promise<T>;
11
11
  delete(entityId: Identifier): Promise<void>;
12
+ upsert(entity: T): Promise<T>;
12
13
  }
13
14
  export { FirestoreService };
14
15
  export type { Entity };
@@ -19,30 +19,28 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e };
19
19
 
20
20
  var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
21
21
 
22
- var firebaseConfig = {
23
- apiKey: undefined.VITE_FIREBASE_API_KEY,
24
- authDomain: undefined.VITE_FIREBASE_AUTH_DOMAIN,
25
- projectId: undefined.VITE_FIREBASE_PROJECT_ID,
26
- storageBucket: undefined.VITE_FIREBASE_STORAGE_BUCKET,
27
- messagingSenderId: undefined.VITE_FIREBASE_MESSAGING_SENDER_ID,
28
- appId: undefined.VITE_FIREBASE_APP_ID,
29
- measurementId: undefined.VITE_FIREBASE_MEASUREMENT_ID
30
- };
31
-
32
- // Initialize Firebase
33
- var firebaseClient = app.initializeApp(firebaseConfig);
34
-
35
22
  var FirebaseAuthService = /*#__PURE__*/function () {
36
- function FirebaseAuthService() {
23
+ function FirebaseAuthService(firebaseClient) {
37
24
  var _this = this;
38
25
  _classCallCheck(this, FirebaseAuthService);
39
- _defineProperty(this, "currentUser", undefined);
40
- _defineProperty(this, "auth", auth.getAuth(firebaseClient));
41
26
  _defineProperty(this, "getUser", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee() {
42
27
  return _regeneratorRuntime__default["default"].wrap(function (_context) {
43
28
  while (1) switch (_context.prev = _context.next) {
44
29
  case 0:
45
- return _context.abrupt("return", _this.currentUser);
30
+ return _context.abrupt("return", new Promise(function (resolve) {
31
+ var unsubscribe = auth.onAuthStateChanged(_this.auth, function (gUser) {
32
+ unsubscribe(); // stop listening after first call
33
+ var user = gUser ? {
34
+ email: gUser.email,
35
+ user_metadata: {
36
+ name: gUser.displayName,
37
+ avatar_url: gUser.photoURL,
38
+ email: gUser.email
39
+ }
40
+ } : null;
41
+ resolve(user);
42
+ });
43
+ }));
46
44
  case 1:
47
45
  case "end":
48
46
  return _context.stop();
@@ -53,19 +51,20 @@ var FirebaseAuthService = /*#__PURE__*/function () {
53
51
  return _regeneratorRuntime__default["default"].wrap(function (_context2) {
54
52
  while (1) switch (_context2.prev = _context2.next) {
55
53
  case 0:
56
- _this.currentUser = undefined;
57
- _this.auth.signOut();
54
+ _context2.next = 1;
55
+ return _this.auth.signOut();
56
+ case 1:
58
57
  return _context2.abrupt("return", {
59
58
  error: null
60
59
  });
61
- case 1:
60
+ case 2:
62
61
  case "end":
63
62
  return _context2.stop();
64
63
  }
65
64
  }, _callee2);
66
65
  })));
67
66
  _defineProperty(this, "signInWithGoogle", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee3() {
68
- var provider, resp, _t;
67
+ var provider, _t;
69
68
  return _regeneratorRuntime__default["default"].wrap(function (_context3) {
70
69
  while (1) switch (_context3.prev = _context3.next) {
71
70
  case 0:
@@ -74,15 +73,6 @@ var FirebaseAuthService = /*#__PURE__*/function () {
74
73
  _context3.next = 1;
75
74
  return auth.signInWithPopup(_this.auth, provider);
76
75
  case 1:
77
- resp = _context3.sent;
78
- _this.currentUser = {
79
- email: resp.user.email,
80
- user_metadata: {
81
- name: resp.user.displayName,
82
- avatar_url: resp.user.photoURL,
83
- email: resp.user.email
84
- }
85
- };
86
76
  return _context3.abrupt("return", {
87
77
  data: {
88
78
  url: undefined.VITE_AUTH_DOMAIN
@@ -99,18 +89,7 @@ var FirebaseAuthService = /*#__PURE__*/function () {
99
89
  }
100
90
  }, _callee3, null, [[0, 2]]);
101
91
  })));
102
- this.auth.onAuthStateChanged(function (user) {
103
- if (user) {
104
- _this.currentUser = {
105
- email: user.email,
106
- user_metadata: {
107
- name: user.displayName,
108
- avatar_url: user.photoURL,
109
- email: user.email
110
- }
111
- };
112
- }
113
- });
92
+ this.auth = auth.getAuth(firebaseClient);
114
93
  }
115
94
  return _createClass(FirebaseAuthService, [{
116
95
  key: "getProviders",
@@ -130,17 +109,34 @@ var FirebaseAuthService = /*#__PURE__*/function () {
130
109
  }, {
131
110
  key: "hasUser",
132
111
  value: function hasUser() {
133
- return Promise.resolve(this.currentUser !== null);
112
+ var _this2 = this;
113
+ return new Promise(function (resolve) {
114
+ var unsubscribe = auth.onAuthStateChanged(_this2.auth, function (user) {
115
+ unsubscribe(); // stop listening after first call
116
+ resolve(user ? true : false);
117
+ });
118
+ });
134
119
  }
135
120
  }]);
136
121
  }();
137
122
 
123
+ var firebaseConfig = {
124
+ apiKey: undefined.VITE_FIREBASE_API_KEY,
125
+ authDomain: undefined.VITE_FIREBASE_AUTH_DOMAIN,
126
+ projectId: undefined.VITE_FIREBASE_PROJECT_ID,
127
+ storageBucket: undefined.VITE_FIREBASE_STORAGE_BUCKET,
128
+ messagingSenderId: undefined.VITE_FIREBASE_MESSAGING_SENDER_ID,
129
+ appId: undefined.VITE_FIREBASE_APP_ID,
130
+ measurementId: undefined.VITE_FIREBASE_MEASUREMENT_ID
131
+ };
132
+
133
+ // Initialize Firebase
134
+ var firebaseClient = app.initializeApp(firebaseConfig);
135
+
138
136
  var FirebaseStorageService = /*#__PURE__*/function () {
139
- function FirebaseStorageService() {
137
+ function FirebaseStorageService(firebaseClient) {
140
138
  var _this = this;
141
139
  _classCallCheck(this, FirebaseStorageService);
142
- _defineProperty(this, "storage", storage.getStorage(firebaseClient));
143
- _defineProperty(this, "decoder", new TextDecoder("utf-8"));
144
140
  _defineProperty(this, "downloadFile", /*#__PURE__*/function () {
145
141
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee(filepath) {
146
142
  var fileRef;
@@ -161,6 +157,8 @@ var FirebaseStorageService = /*#__PURE__*/function () {
161
157
  return _ref.apply(this, arguments);
162
158
  };
163
159
  }());
160
+ this.storage = storage.getStorage(firebaseClient);
161
+ this.decoder = new TextDecoder("utf-8");
164
162
  }
165
163
  return _createClass(FirebaseStorageService, [{
166
164
  key: "getUrlAsync",
@@ -192,31 +190,128 @@ var FirebaseStorageService = /*#__PURE__*/function () {
192
190
  }
193
191
  return getUrlAsync;
194
192
  }()
195
- }, {
196
- key: "list",
197
- value: function list(filepath) {
198
- throw new Error("Method not implemented.");
199
- }
200
193
  }, {
201
194
  key: "getUrl",
202
195
  value: function getUrl(filepath) {
203
196
  throw new Error("Method not supported.");
204
197
  }
205
- }, {
206
- key: "upload",
207
- value: function upload(path, blob) {
208
- throw new Error("Method not implemented.");
209
- }
210
198
  }, {
211
199
  key: "downloadBlob",
212
200
  value: function downloadBlob(filepath) {
213
- throw new Error("Method not implemented.");
201
+ var fileRef = storage.ref(this.storage, filepath);
202
+ return storage.getBytes(fileRef).then(function (bytes) {
203
+ return new Blob([bytes]);
204
+ });
214
205
  }
215
206
  }, {
216
207
  key: "removeFile",
217
- value: function removeFile(fileName) {
218
- throw new Error("Method not implemented.");
208
+ value: function removeFile(path) {
209
+ try {
210
+ var fileRef = storage.ref(this.storage, path);
211
+ return storage.deleteObject(fileRef);
212
+ } catch (error) {
213
+ if (error.code === "storage/object-not-found") {
214
+ console.warn("File does not exist");
215
+ } else if (error.code === "storage/unauthorized") {
216
+ console.error("User not authorized to delete file");
217
+ } else {
218
+ console.error("Delete failed:", error);
219
+ }
220
+ throw error;
221
+ }
219
222
  }
223
+ }, {
224
+ key: "list",
225
+ value: function () {
226
+ var _list = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee4(filepath) {
227
+ var folderRef, result, files;
228
+ return _regeneratorRuntime__default["default"].wrap(function (_context4) {
229
+ while (1) switch (_context4.prev = _context4.next) {
230
+ case 0:
231
+ if (filepath) {
232
+ _context4.next = 1;
233
+ break;
234
+ }
235
+ return _context4.abrupt("return", []);
236
+ case 1:
237
+ folderRef = storage.ref(this.storage, filepath);
238
+ _context4.next = 2;
239
+ return storage.listAll(folderRef);
240
+ case 2:
241
+ result = _context4.sent;
242
+ _context4.next = 3;
243
+ return Promise.all(result.items.map(/*#__PURE__*/function () {
244
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee3(item) {
245
+ var metadata;
246
+ return _regeneratorRuntime__default["default"].wrap(function (_context3) {
247
+ while (1) switch (_context3.prev = _context3.next) {
248
+ case 0:
249
+ _context3.next = 1;
250
+ return storage.getMetadata(item);
251
+ case 1:
252
+ metadata = _context3.sent;
253
+ return _context3.abrupt("return", {
254
+ name: item.name,
255
+ fullPath: item.fullPath,
256
+ type: metadata.contentType,
257
+ size: metadata.size,
258
+ updated: metadata.updated
259
+ });
260
+ case 2:
261
+ case "end":
262
+ return _context3.stop();
263
+ }
264
+ }, _callee3);
265
+ }));
266
+ return function (_x4) {
267
+ return _ref2.apply(this, arguments);
268
+ };
269
+ }()));
270
+ case 3:
271
+ files = _context4.sent;
272
+ return _context4.abrupt("return", files);
273
+ case 4:
274
+ case "end":
275
+ return _context4.stop();
276
+ }
277
+ }, _callee4, this);
278
+ }));
279
+ function list(_x3) {
280
+ return _list.apply(this, arguments);
281
+ }
282
+ return list;
283
+ }()
284
+ }, {
285
+ key: "upload",
286
+ value: function () {
287
+ var _upload = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee5(path, file) {
288
+ var storageRef, snapshot, downloadUrl;
289
+ return _regeneratorRuntime__default["default"].wrap(function (_context5) {
290
+ while (1) switch (_context5.prev = _context5.next) {
291
+ case 0:
292
+ storageRef = storage.ref(this.storage, path); // Upload file
293
+ _context5.next = 1;
294
+ return storage.uploadBytes(storageRef, file, {
295
+ contentType: file === null || file === void 0 ? void 0 : file.type
296
+ });
297
+ case 1:
298
+ snapshot = _context5.sent;
299
+ _context5.next = 2;
300
+ return storage.getDownloadURL(snapshot.ref);
301
+ case 2:
302
+ downloadUrl = _context5.sent;
303
+ return _context5.abrupt("return", downloadUrl);
304
+ case 3:
305
+ case "end":
306
+ return _context5.stop();
307
+ }
308
+ }, _callee5, this);
309
+ }));
310
+ function upload(_x5, _x6) {
311
+ return _upload.apply(this, arguments);
312
+ }
313
+ return upload;
314
+ }()
220
315
  }]);
221
316
  }();
222
317
 
@@ -408,6 +503,28 @@ var FirestoreService = /*#__PURE__*/function () {
408
503
  }
409
504
  return _delete;
410
505
  }()
506
+ }, {
507
+ key: "upsert",
508
+ value: function () {
509
+ var _upsert = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee7(entity) {
510
+ return _regeneratorRuntime__default["default"].wrap(function (_context7) {
511
+ while (1) switch (_context7.prev = _context7.next) {
512
+ case 0:
513
+ _context7.next = 1;
514
+ return firestore.setDoc(firestore.doc(this.db, this.collectionName, entity.id), entity);
515
+ case 1:
516
+ return _context7.abrupt("return", entity);
517
+ case 2:
518
+ case "end":
519
+ return _context7.stop();
520
+ }
521
+ }, _callee7, this);
522
+ }));
523
+ function upsert(_x19) {
524
+ return _upsert.apply(this, arguments);
525
+ }
526
+ return upsert;
527
+ }()
411
528
  }]);
412
529
  }();
413
530
 
@@ -19,30 +19,28 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e };
19
19
 
20
20
  var _regeneratorRuntime__default = /*#__PURE__*/_interopDefault(_regeneratorRuntime);
21
21
 
22
- var firebaseConfig = {
23
- apiKey: undefined.VITE_FIREBASE_API_KEY,
24
- authDomain: undefined.VITE_FIREBASE_AUTH_DOMAIN,
25
- projectId: undefined.VITE_FIREBASE_PROJECT_ID,
26
- storageBucket: undefined.VITE_FIREBASE_STORAGE_BUCKET,
27
- messagingSenderId: undefined.VITE_FIREBASE_MESSAGING_SENDER_ID,
28
- appId: undefined.VITE_FIREBASE_APP_ID,
29
- measurementId: undefined.VITE_FIREBASE_MEASUREMENT_ID
30
- };
31
-
32
- // Initialize Firebase
33
- var firebaseClient = app.initializeApp(firebaseConfig);
34
-
35
22
  var FirebaseAuthService = /*#__PURE__*/function () {
36
- function FirebaseAuthService() {
23
+ function FirebaseAuthService(firebaseClient) {
37
24
  var _this = this;
38
25
  _classCallCheck(this, FirebaseAuthService);
39
- _defineProperty(this, "currentUser", undefined);
40
- _defineProperty(this, "auth", auth.getAuth(firebaseClient));
41
26
  _defineProperty(this, "getUser", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee() {
42
27
  return _regeneratorRuntime__default["default"].wrap(function (_context) {
43
28
  while (1) switch (_context.prev = _context.next) {
44
29
  case 0:
45
- return _context.abrupt("return", _this.currentUser);
30
+ return _context.abrupt("return", new Promise(function (resolve) {
31
+ var unsubscribe = auth.onAuthStateChanged(_this.auth, function (gUser) {
32
+ unsubscribe(); // stop listening after first call
33
+ var user = gUser ? {
34
+ email: gUser.email,
35
+ user_metadata: {
36
+ name: gUser.displayName,
37
+ avatar_url: gUser.photoURL,
38
+ email: gUser.email
39
+ }
40
+ } : null;
41
+ resolve(user);
42
+ });
43
+ }));
46
44
  case 1:
47
45
  case "end":
48
46
  return _context.stop();
@@ -53,19 +51,20 @@ var FirebaseAuthService = /*#__PURE__*/function () {
53
51
  return _regeneratorRuntime__default["default"].wrap(function (_context2) {
54
52
  while (1) switch (_context2.prev = _context2.next) {
55
53
  case 0:
56
- _this.currentUser = undefined;
57
- _this.auth.signOut();
54
+ _context2.next = 1;
55
+ return _this.auth.signOut();
56
+ case 1:
58
57
  return _context2.abrupt("return", {
59
58
  error: null
60
59
  });
61
- case 1:
60
+ case 2:
62
61
  case "end":
63
62
  return _context2.stop();
64
63
  }
65
64
  }, _callee2);
66
65
  })));
67
66
  _defineProperty(this, "signInWithGoogle", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee3() {
68
- var provider, resp, _t;
67
+ var provider, _t;
69
68
  return _regeneratorRuntime__default["default"].wrap(function (_context3) {
70
69
  while (1) switch (_context3.prev = _context3.next) {
71
70
  case 0:
@@ -74,15 +73,6 @@ var FirebaseAuthService = /*#__PURE__*/function () {
74
73
  _context3.next = 1;
75
74
  return auth.signInWithPopup(_this.auth, provider);
76
75
  case 1:
77
- resp = _context3.sent;
78
- _this.currentUser = {
79
- email: resp.user.email,
80
- user_metadata: {
81
- name: resp.user.displayName,
82
- avatar_url: resp.user.photoURL,
83
- email: resp.user.email
84
- }
85
- };
86
76
  return _context3.abrupt("return", {
87
77
  data: {
88
78
  url: undefined.VITE_AUTH_DOMAIN
@@ -99,18 +89,7 @@ var FirebaseAuthService = /*#__PURE__*/function () {
99
89
  }
100
90
  }, _callee3, null, [[0, 2]]);
101
91
  })));
102
- this.auth.onAuthStateChanged(function (user) {
103
- if (user) {
104
- _this.currentUser = {
105
- email: user.email,
106
- user_metadata: {
107
- name: user.displayName,
108
- avatar_url: user.photoURL,
109
- email: user.email
110
- }
111
- };
112
- }
113
- });
92
+ this.auth = auth.getAuth(firebaseClient);
114
93
  }
115
94
  return _createClass(FirebaseAuthService, [{
116
95
  key: "getProviders",
@@ -130,17 +109,34 @@ var FirebaseAuthService = /*#__PURE__*/function () {
130
109
  }, {
131
110
  key: "hasUser",
132
111
  value: function hasUser() {
133
- return Promise.resolve(this.currentUser !== null);
112
+ var _this2 = this;
113
+ return new Promise(function (resolve) {
114
+ var unsubscribe = auth.onAuthStateChanged(_this2.auth, function (user) {
115
+ unsubscribe(); // stop listening after first call
116
+ resolve(user ? true : false);
117
+ });
118
+ });
134
119
  }
135
120
  }]);
136
121
  }();
137
122
 
123
+ var firebaseConfig = {
124
+ apiKey: undefined.VITE_FIREBASE_API_KEY,
125
+ authDomain: undefined.VITE_FIREBASE_AUTH_DOMAIN,
126
+ projectId: undefined.VITE_FIREBASE_PROJECT_ID,
127
+ storageBucket: undefined.VITE_FIREBASE_STORAGE_BUCKET,
128
+ messagingSenderId: undefined.VITE_FIREBASE_MESSAGING_SENDER_ID,
129
+ appId: undefined.VITE_FIREBASE_APP_ID,
130
+ measurementId: undefined.VITE_FIREBASE_MEASUREMENT_ID
131
+ };
132
+
133
+ // Initialize Firebase
134
+ var firebaseClient = app.initializeApp(firebaseConfig);
135
+
138
136
  var FirebaseStorageService = /*#__PURE__*/function () {
139
- function FirebaseStorageService() {
137
+ function FirebaseStorageService(firebaseClient) {
140
138
  var _this = this;
141
139
  _classCallCheck(this, FirebaseStorageService);
142
- _defineProperty(this, "storage", storage.getStorage(firebaseClient));
143
- _defineProperty(this, "decoder", new TextDecoder("utf-8"));
144
140
  _defineProperty(this, "downloadFile", /*#__PURE__*/function () {
145
141
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee(filepath) {
146
142
  var fileRef;
@@ -161,6 +157,8 @@ var FirebaseStorageService = /*#__PURE__*/function () {
161
157
  return _ref.apply(this, arguments);
162
158
  };
163
159
  }());
160
+ this.storage = storage.getStorage(firebaseClient);
161
+ this.decoder = new TextDecoder("utf-8");
164
162
  }
165
163
  return _createClass(FirebaseStorageService, [{
166
164
  key: "getUrlAsync",
@@ -192,31 +190,128 @@ var FirebaseStorageService = /*#__PURE__*/function () {
192
190
  }
193
191
  return getUrlAsync;
194
192
  }()
195
- }, {
196
- key: "list",
197
- value: function list(filepath) {
198
- throw new Error("Method not implemented.");
199
- }
200
193
  }, {
201
194
  key: "getUrl",
202
195
  value: function getUrl(filepath) {
203
196
  throw new Error("Method not supported.");
204
197
  }
205
- }, {
206
- key: "upload",
207
- value: function upload(path, blob) {
208
- throw new Error("Method not implemented.");
209
- }
210
198
  }, {
211
199
  key: "downloadBlob",
212
200
  value: function downloadBlob(filepath) {
213
- throw new Error("Method not implemented.");
201
+ var fileRef = storage.ref(this.storage, filepath);
202
+ return storage.getBytes(fileRef).then(function (bytes) {
203
+ return new Blob([bytes]);
204
+ });
214
205
  }
215
206
  }, {
216
207
  key: "removeFile",
217
- value: function removeFile(fileName) {
218
- throw new Error("Method not implemented.");
208
+ value: function removeFile(path) {
209
+ try {
210
+ var fileRef = storage.ref(this.storage, path);
211
+ return storage.deleteObject(fileRef);
212
+ } catch (error) {
213
+ if (error.code === "storage/object-not-found") {
214
+ console.warn("File does not exist");
215
+ } else if (error.code === "storage/unauthorized") {
216
+ console.error("User not authorized to delete file");
217
+ } else {
218
+ console.error("Delete failed:", error);
219
+ }
220
+ throw error;
221
+ }
219
222
  }
223
+ }, {
224
+ key: "list",
225
+ value: function () {
226
+ var _list = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee4(filepath) {
227
+ var folderRef, result, files;
228
+ return _regeneratorRuntime__default["default"].wrap(function (_context4) {
229
+ while (1) switch (_context4.prev = _context4.next) {
230
+ case 0:
231
+ if (filepath) {
232
+ _context4.next = 1;
233
+ break;
234
+ }
235
+ return _context4.abrupt("return", []);
236
+ case 1:
237
+ folderRef = storage.ref(this.storage, filepath);
238
+ _context4.next = 2;
239
+ return storage.listAll(folderRef);
240
+ case 2:
241
+ result = _context4.sent;
242
+ _context4.next = 3;
243
+ return Promise.all(result.items.map(/*#__PURE__*/function () {
244
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee3(item) {
245
+ var metadata;
246
+ return _regeneratorRuntime__default["default"].wrap(function (_context3) {
247
+ while (1) switch (_context3.prev = _context3.next) {
248
+ case 0:
249
+ _context3.next = 1;
250
+ return storage.getMetadata(item);
251
+ case 1:
252
+ metadata = _context3.sent;
253
+ return _context3.abrupt("return", {
254
+ name: item.name,
255
+ fullPath: item.fullPath,
256
+ type: metadata.contentType,
257
+ size: metadata.size,
258
+ updated: metadata.updated
259
+ });
260
+ case 2:
261
+ case "end":
262
+ return _context3.stop();
263
+ }
264
+ }, _callee3);
265
+ }));
266
+ return function (_x4) {
267
+ return _ref2.apply(this, arguments);
268
+ };
269
+ }()));
270
+ case 3:
271
+ files = _context4.sent;
272
+ return _context4.abrupt("return", files);
273
+ case 4:
274
+ case "end":
275
+ return _context4.stop();
276
+ }
277
+ }, _callee4, this);
278
+ }));
279
+ function list(_x3) {
280
+ return _list.apply(this, arguments);
281
+ }
282
+ return list;
283
+ }()
284
+ }, {
285
+ key: "upload",
286
+ value: function () {
287
+ var _upload = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee5(path, file) {
288
+ var storageRef, snapshot, downloadUrl;
289
+ return _regeneratorRuntime__default["default"].wrap(function (_context5) {
290
+ while (1) switch (_context5.prev = _context5.next) {
291
+ case 0:
292
+ storageRef = storage.ref(this.storage, path); // Upload file
293
+ _context5.next = 1;
294
+ return storage.uploadBytes(storageRef, file, {
295
+ contentType: file === null || file === void 0 ? void 0 : file.type
296
+ });
297
+ case 1:
298
+ snapshot = _context5.sent;
299
+ _context5.next = 2;
300
+ return storage.getDownloadURL(snapshot.ref);
301
+ case 2:
302
+ downloadUrl = _context5.sent;
303
+ return _context5.abrupt("return", downloadUrl);
304
+ case 3:
305
+ case "end":
306
+ return _context5.stop();
307
+ }
308
+ }, _callee5, this);
309
+ }));
310
+ function upload(_x5, _x6) {
311
+ return _upload.apply(this, arguments);
312
+ }
313
+ return upload;
314
+ }()
220
315
  }]);
221
316
  }();
222
317
 
@@ -408,6 +503,28 @@ var FirestoreService = /*#__PURE__*/function () {
408
503
  }
409
504
  return _delete;
410
505
  }()
506
+ }, {
507
+ key: "upsert",
508
+ value: function () {
509
+ var _upsert = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee7(entity) {
510
+ return _regeneratorRuntime__default["default"].wrap(function (_context7) {
511
+ while (1) switch (_context7.prev = _context7.next) {
512
+ case 0:
513
+ _context7.next = 1;
514
+ return firestore.setDoc(firestore.doc(this.db, this.collectionName, entity.id), entity);
515
+ case 1:
516
+ return _context7.abrupt("return", entity);
517
+ case 2:
518
+ case "end":
519
+ return _context7.stop();
520
+ }
521
+ }, _callee7, this);
522
+ }));
523
+ function upsert(_x19) {
524
+ return _upsert.apply(this, arguments);
525
+ }
526
+ return upsert;
527
+ }()
411
528
  }]);
412
529
  }();
413
530
 
@@ -3,38 +3,36 @@ import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
3
3
  import _createClass from '@babel/runtime/helpers/esm/createClass';
4
4
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
5
5
  import _regeneratorRuntime from '@babel/runtime/regenerator';
6
- import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
6
+ import { onAuthStateChanged, GoogleAuthProvider, signInWithPopup, getAuth } from 'firebase/auth';
7
7
  import { initializeApp } from 'firebase/app';
8
- import { ref, getDownloadURL, getStorage, getBytes } from 'firebase/storage';
8
+ import { ref, getDownloadURL, getBytes, deleteObject, getMetadata, listAll, uploadBytes, getStorage } from 'firebase/storage';
9
9
  import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
10
- import { getDocs, collection, getDoc, doc, addDoc, updateDoc, deleteDoc, getFirestore } from 'firebase/firestore';
10
+ import { getDocs, collection, getDoc, doc, addDoc, updateDoc, deleteDoc, setDoc, getFirestore } from 'firebase/firestore';
11
11
  import { firebaseClient as firebaseClient$1 } from '@digitalaidseattle/firebase';
12
12
  import { getGenerativeModel, Schema, getAI, GoogleAIBackend } from 'firebase/ai';
13
13
 
14
- var firebaseConfig = {
15
- apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
16
- authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
17
- projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
18
- storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
19
- messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
20
- appId: import.meta.env.VITE_FIREBASE_APP_ID,
21
- measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID
22
- };
23
-
24
- // Initialize Firebase
25
- var firebaseClient = initializeApp(firebaseConfig);
26
-
27
14
  var FirebaseAuthService = /*#__PURE__*/function () {
28
- function FirebaseAuthService() {
15
+ function FirebaseAuthService(firebaseClient) {
29
16
  var _this = this;
30
17
  _classCallCheck(this, FirebaseAuthService);
31
- _defineProperty(this, "currentUser", undefined);
32
- _defineProperty(this, "auth", getAuth(firebaseClient));
33
18
  _defineProperty(this, "getUser", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
34
19
  return _regeneratorRuntime.wrap(function (_context) {
35
20
  while (1) switch (_context.prev = _context.next) {
36
21
  case 0:
37
- return _context.abrupt("return", _this.currentUser);
22
+ return _context.abrupt("return", new Promise(function (resolve) {
23
+ var unsubscribe = onAuthStateChanged(_this.auth, function (gUser) {
24
+ unsubscribe(); // stop listening after first call
25
+ var user = gUser ? {
26
+ email: gUser.email,
27
+ user_metadata: {
28
+ name: gUser.displayName,
29
+ avatar_url: gUser.photoURL,
30
+ email: gUser.email
31
+ }
32
+ } : null;
33
+ resolve(user);
34
+ });
35
+ }));
38
36
  case 1:
39
37
  case "end":
40
38
  return _context.stop();
@@ -45,19 +43,20 @@ var FirebaseAuthService = /*#__PURE__*/function () {
45
43
  return _regeneratorRuntime.wrap(function (_context2) {
46
44
  while (1) switch (_context2.prev = _context2.next) {
47
45
  case 0:
48
- _this.currentUser = undefined;
49
- _this.auth.signOut();
46
+ _context2.next = 1;
47
+ return _this.auth.signOut();
48
+ case 1:
50
49
  return _context2.abrupt("return", {
51
50
  error: null
52
51
  });
53
- case 1:
52
+ case 2:
54
53
  case "end":
55
54
  return _context2.stop();
56
55
  }
57
56
  }, _callee2);
58
57
  })));
59
58
  _defineProperty(this, "signInWithGoogle", /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
60
- var provider, resp, _t;
59
+ var provider, _t;
61
60
  return _regeneratorRuntime.wrap(function (_context3) {
62
61
  while (1) switch (_context3.prev = _context3.next) {
63
62
  case 0:
@@ -66,15 +65,6 @@ var FirebaseAuthService = /*#__PURE__*/function () {
66
65
  _context3.next = 1;
67
66
  return signInWithPopup(_this.auth, provider);
68
67
  case 1:
69
- resp = _context3.sent;
70
- _this.currentUser = {
71
- email: resp.user.email,
72
- user_metadata: {
73
- name: resp.user.displayName,
74
- avatar_url: resp.user.photoURL,
75
- email: resp.user.email
76
- }
77
- };
78
68
  return _context3.abrupt("return", {
79
69
  data: {
80
70
  url: import.meta.env.VITE_AUTH_DOMAIN
@@ -91,18 +81,7 @@ var FirebaseAuthService = /*#__PURE__*/function () {
91
81
  }
92
82
  }, _callee3, null, [[0, 2]]);
93
83
  })));
94
- this.auth.onAuthStateChanged(function (user) {
95
- if (user) {
96
- _this.currentUser = {
97
- email: user.email,
98
- user_metadata: {
99
- name: user.displayName,
100
- avatar_url: user.photoURL,
101
- email: user.email
102
- }
103
- };
104
- }
105
- });
84
+ this.auth = getAuth(firebaseClient);
106
85
  }
107
86
  return _createClass(FirebaseAuthService, [{
108
87
  key: "getProviders",
@@ -122,17 +101,34 @@ var FirebaseAuthService = /*#__PURE__*/function () {
122
101
  }, {
123
102
  key: "hasUser",
124
103
  value: function hasUser() {
125
- return Promise.resolve(this.currentUser !== null);
104
+ var _this2 = this;
105
+ return new Promise(function (resolve) {
106
+ var unsubscribe = onAuthStateChanged(_this2.auth, function (user) {
107
+ unsubscribe(); // stop listening after first call
108
+ resolve(user ? true : false);
109
+ });
110
+ });
126
111
  }
127
112
  }]);
128
113
  }();
129
114
 
115
+ var firebaseConfig = {
116
+ apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
117
+ authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
118
+ projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
119
+ storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
120
+ messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
121
+ appId: import.meta.env.VITE_FIREBASE_APP_ID,
122
+ measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID
123
+ };
124
+
125
+ // Initialize Firebase
126
+ var firebaseClient = initializeApp(firebaseConfig);
127
+
130
128
  var FirebaseStorageService = /*#__PURE__*/function () {
131
- function FirebaseStorageService() {
129
+ function FirebaseStorageService(firebaseClient) {
132
130
  var _this = this;
133
131
  _classCallCheck(this, FirebaseStorageService);
134
- _defineProperty(this, "storage", getStorage(firebaseClient));
135
- _defineProperty(this, "decoder", new TextDecoder("utf-8"));
136
132
  _defineProperty(this, "downloadFile", /*#__PURE__*/function () {
137
133
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(filepath) {
138
134
  var fileRef;
@@ -153,6 +149,8 @@ var FirebaseStorageService = /*#__PURE__*/function () {
153
149
  return _ref.apply(this, arguments);
154
150
  };
155
151
  }());
152
+ this.storage = getStorage(firebaseClient);
153
+ this.decoder = new TextDecoder("utf-8");
156
154
  }
157
155
  return _createClass(FirebaseStorageService, [{
158
156
  key: "getUrlAsync",
@@ -184,31 +182,128 @@ var FirebaseStorageService = /*#__PURE__*/function () {
184
182
  }
185
183
  return getUrlAsync;
186
184
  }()
187
- }, {
188
- key: "list",
189
- value: function list(filepath) {
190
- throw new Error("Method not implemented.");
191
- }
192
185
  }, {
193
186
  key: "getUrl",
194
187
  value: function getUrl(filepath) {
195
188
  throw new Error("Method not supported.");
196
189
  }
197
- }, {
198
- key: "upload",
199
- value: function upload(path, blob) {
200
- throw new Error("Method not implemented.");
201
- }
202
190
  }, {
203
191
  key: "downloadBlob",
204
192
  value: function downloadBlob(filepath) {
205
- throw new Error("Method not implemented.");
193
+ var fileRef = ref(this.storage, filepath);
194
+ return getBytes(fileRef).then(function (bytes) {
195
+ return new Blob([bytes]);
196
+ });
206
197
  }
207
198
  }, {
208
199
  key: "removeFile",
209
- value: function removeFile(fileName) {
210
- throw new Error("Method not implemented.");
200
+ value: function removeFile(path) {
201
+ try {
202
+ var fileRef = ref(this.storage, path);
203
+ return deleteObject(fileRef);
204
+ } catch (error) {
205
+ if (error.code === "storage/object-not-found") {
206
+ console.warn("File does not exist");
207
+ } else if (error.code === "storage/unauthorized") {
208
+ console.error("User not authorized to delete file");
209
+ } else {
210
+ console.error("Delete failed:", error);
211
+ }
212
+ throw error;
213
+ }
211
214
  }
215
+ }, {
216
+ key: "list",
217
+ value: function () {
218
+ var _list = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(filepath) {
219
+ var folderRef, result, files;
220
+ return _regeneratorRuntime.wrap(function (_context4) {
221
+ while (1) switch (_context4.prev = _context4.next) {
222
+ case 0:
223
+ if (filepath) {
224
+ _context4.next = 1;
225
+ break;
226
+ }
227
+ return _context4.abrupt("return", []);
228
+ case 1:
229
+ folderRef = ref(this.storage, filepath);
230
+ _context4.next = 2;
231
+ return listAll(folderRef);
232
+ case 2:
233
+ result = _context4.sent;
234
+ _context4.next = 3;
235
+ return Promise.all(result.items.map(/*#__PURE__*/function () {
236
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(item) {
237
+ var metadata;
238
+ return _regeneratorRuntime.wrap(function (_context3) {
239
+ while (1) switch (_context3.prev = _context3.next) {
240
+ case 0:
241
+ _context3.next = 1;
242
+ return getMetadata(item);
243
+ case 1:
244
+ metadata = _context3.sent;
245
+ return _context3.abrupt("return", {
246
+ name: item.name,
247
+ fullPath: item.fullPath,
248
+ type: metadata.contentType,
249
+ size: metadata.size,
250
+ updated: metadata.updated
251
+ });
252
+ case 2:
253
+ case "end":
254
+ return _context3.stop();
255
+ }
256
+ }, _callee3);
257
+ }));
258
+ return function (_x4) {
259
+ return _ref2.apply(this, arguments);
260
+ };
261
+ }()));
262
+ case 3:
263
+ files = _context4.sent;
264
+ return _context4.abrupt("return", files);
265
+ case 4:
266
+ case "end":
267
+ return _context4.stop();
268
+ }
269
+ }, _callee4, this);
270
+ }));
271
+ function list(_x3) {
272
+ return _list.apply(this, arguments);
273
+ }
274
+ return list;
275
+ }()
276
+ }, {
277
+ key: "upload",
278
+ value: function () {
279
+ var _upload = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(path, file) {
280
+ var storageRef, snapshot, downloadUrl;
281
+ return _regeneratorRuntime.wrap(function (_context5) {
282
+ while (1) switch (_context5.prev = _context5.next) {
283
+ case 0:
284
+ storageRef = ref(this.storage, path); // Upload file
285
+ _context5.next = 1;
286
+ return uploadBytes(storageRef, file, {
287
+ contentType: file === null || file === void 0 ? void 0 : file.type
288
+ });
289
+ case 1:
290
+ snapshot = _context5.sent;
291
+ _context5.next = 2;
292
+ return getDownloadURL(snapshot.ref);
293
+ case 2:
294
+ downloadUrl = _context5.sent;
295
+ return _context5.abrupt("return", downloadUrl);
296
+ case 3:
297
+ case "end":
298
+ return _context5.stop();
299
+ }
300
+ }, _callee5, this);
301
+ }));
302
+ function upload(_x5, _x6) {
303
+ return _upload.apply(this, arguments);
304
+ }
305
+ return upload;
306
+ }()
212
307
  }]);
213
308
  }();
214
309
 
@@ -400,6 +495,28 @@ var FirestoreService = /*#__PURE__*/function () {
400
495
  }
401
496
  return _delete;
402
497
  }()
498
+ }, {
499
+ key: "upsert",
500
+ value: function () {
501
+ var _upsert = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(entity) {
502
+ return _regeneratorRuntime.wrap(function (_context7) {
503
+ while (1) switch (_context7.prev = _context7.next) {
504
+ case 0:
505
+ _context7.next = 1;
506
+ return setDoc(doc(this.db, this.collectionName, entity.id), entity);
507
+ case 1:
508
+ return _context7.abrupt("return", entity);
509
+ case 2:
510
+ case "end":
511
+ return _context7.stop();
512
+ }
513
+ }, _callee7, this);
514
+ }));
515
+ function upsert(_x19) {
516
+ return _upsert.apply(this, arguments);
517
+ }
518
+ return upsert;
519
+ }()
403
520
  }]);
404
521
  }();
405
522
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalaidseattle/firebase",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Wrapper for firebase that works with DAS Component library",
5
5
  "repository": "null//github.com/null/github.com/tree/master/packages/firebase",
6
6
  "main": "dist/digitalaidseattle-firebase.cjs.js",
@@ -8,10 +8,10 @@
8
8
  "types": "dist/declarations/src/index.d.ts",
9
9
  "dependencies": {
10
10
  "@babel/runtime": "^7.25.0",
11
- "@digitalaidseattle/core": "1.0.16",
11
+ "@digitalaidseattle/core": "1.0.17",
12
12
  "firebase": "^11.2.0",
13
13
  "react": "^18.3.1",
14
- "uuid": "^11.0.5"
14
+ "uuid": "^13.0.0"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@testing-library/react": "^14.2.1",