@edgedev/firebase 2.1.60 → 2.1.62

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.
package/edgeFirebase.ts CHANGED
@@ -2215,7 +2215,7 @@ export const EdgeFirebase = class {
2215
2215
 
2216
2216
 
2217
2217
  const uploadStatus = await uploadPromise;
2218
- await this.runFunction("edgeFirebase-addUpdateFileDoc", {orgId, docId: fileDocId, uploadStatus, uploadCompleted: true, extraMeta });
2218
+ await this.runFunction("edgeFirebase-addUpdateFileDoc", {orgId, docId: fileDocId, uploadStatus, uploadCompleted: true, meta: extraMeta });
2219
2219
  return uploadStatus;
2220
2220
 
2221
2221
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgedev/firebase",
3
- "version": "2.1.60",
3
+ "version": "2.1.62",
4
4
  "description": "Vue 3 / Nuxt 3 Plugin or Nuxt 3 plugin for firebase authentication and firestore.",
5
5
  "main": "index.ts",
6
6
  "scripts": {
@@ -78,10 +78,14 @@ exports.fileDeleted = onObjectDeleted({ region: process.env.FIREBASE_STORAGE_BUC
78
78
  const docId = event.data.metadata?.fileDocId
79
79
  const toR2 = event.data.metadata?.toR2
80
80
  const cloudflareImageId = event.data.metadata?.cloudflareImageId
81
+ const cloudflareVideoId = event.data.metadata?.cloudflareVideoId
81
82
  const r2ProcessCompleted = event.data.metadata?.r2ProcessCompleted
82
83
  if (cloudflareImageId) {
83
84
  await deleteCloudflareImage(cloudflareImageId)
84
85
  }
86
+ if (cloudflareVideoId) {
87
+ await deleteCloudflareVideo(cloudflareVideoId)
88
+ }
85
89
  if (toR2) {
86
90
  if (r2ProcessCompleted === 'true') {
87
91
  await deleteR2File(event.data.metadata?.r2FilePath)
@@ -174,7 +178,7 @@ exports.toR2 = onObjectFinalized(
174
178
  r2ProcessCompleted: 'true',
175
179
  },
176
180
  }
177
- if (contentType.startsWith('image/')) {
181
+ if (contentType.startsWith('image/') && process.env.CF_IMAGES_TOKEN) {
178
182
  try {
179
183
  const cloudflareImage = await uploadToCloudflareImage({
180
184
  r2FilePath,
@@ -184,7 +188,6 @@ exports.toR2 = onObjectFinalized(
184
188
  fileName,
185
189
  fileSize,
186
190
  })
187
- console.log(cloudflareImage)
188
191
 
189
192
  updatedMetadata = {
190
193
  metadata: {
@@ -205,6 +208,37 @@ exports.toR2 = onObjectFinalized(
205
208
  }
206
209
  }
207
210
 
211
+ if (contentType.startsWith('video/') && process.env.CF_IMAGES_TOKEN) {
212
+ try {
213
+ const cloudflareVideo = await uploadToCloudflareVideo({
214
+ r2FilePath,
215
+ r2URL,
216
+ fileDocId,
217
+ orgId,
218
+ fileName,
219
+ fileSize,
220
+ })
221
+ console.log(cloudflareVideo)
222
+ updatedMetadata = {
223
+ metadata: {
224
+ ...event.data.metadata,
225
+ r2FilePath,
226
+ r2URL,
227
+ uploadCompletedToR2: 'true', // Add custom metadata after file save
228
+ r2ProcessCompleted: 'true',
229
+ cloudflareVideoId: cloudflareVideo.id,
230
+ cloudflareVideoPlayback: cloudflareVideo.playback,
231
+ cloudflareVideoThumbnail: cloudflareVideo.thumbnail,
232
+ cloudflareVideoPreview: cloudflareVideo.preview,
233
+ cloudflareUploadCompleted: true,
234
+ },
235
+ }
236
+ await docRef.set({ cloudflareVideoId: cloudflareVideo.id, cloudflareVideoPlayback: cloudflareVideo.playback, cloudflareVideoThumbnail: cloudflareVideo.thumbnail, cloudflareVideoPreview: cloudflareVideo.preview, cloudflareUploadCompleted: true }, { merge: true })
237
+ }
238
+ catch (e) {
239
+ console.error('Cloudflare Video Upload Failed', e)
240
+ }
241
+ }
208
242
  await fileRef.setMetadata(updatedMetadata)
209
243
  console.log(`File uploaded to Cloudflare R2: ${fileName}`)
210
244
  }
@@ -699,3 +733,79 @@ async function deleteCloudflareImage(imageId) {
699
733
 
700
734
  return true
701
735
  }
736
+
737
+ async function uploadToCloudflareVideo({ r2FilePath, r2URL, fileDocId, orgId, fileSize }) {
738
+ const API_TOKEN = process.env.CF_IMAGES_TOKEN
739
+ const ACCOUNT_ID = process.env.CF_ACCOUNT_ID
740
+
741
+ const cleanedr2FilePath = r2FilePath
742
+ .replaceAll('/', '-')
743
+ .replace('.firebasestorage.app-organizations', '')
744
+
745
+ const metadata = {
746
+ orgId,
747
+ fileDocId,
748
+ fileName: cleanedr2FilePath,
749
+ fileSize,
750
+ }
751
+
752
+ const body = {
753
+ url: r2URL,
754
+ meta: {
755
+ name: cleanedr2FilePath,
756
+ ...metadata,
757
+ },
758
+ allowDownloads: true,
759
+ }
760
+
761
+ const response = await fetch(
762
+ `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/stream/copy`,
763
+ {
764
+ method: 'POST',
765
+ headers: {
766
+ 'Authorization': `Bearer ${API_TOKEN}`,
767
+ 'Content-Type': 'application/json',
768
+ },
769
+ body: JSON.stringify(body),
770
+ },
771
+ )
772
+
773
+ const result = await response.json()
774
+
775
+ if (!result.success) {
776
+ const errorMessages = (result.errors || [])
777
+ .map(error => error.message || 'Unknown error')
778
+ .join('; ')
779
+ throw new Error(`Cloudflare Stream upload failed: ${errorMessages}`)
780
+ }
781
+ console.log(result.result)
782
+ const { uid, preview, playback, thumbnail } = result.result
783
+
784
+ return {
785
+ id: uid,
786
+ preview,
787
+ playback,
788
+ thumbnail,
789
+ }
790
+ }
791
+
792
+ async function deleteCloudflareVideo(videoId) {
793
+ const API_TOKEN = process.env.CF_IMAGES_TOKEN
794
+ const ACCOUNT_ID = process.env.CF_ACCOUNT_ID
795
+
796
+ const response = await fetch(
797
+ `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/stream/${videoId}`,
798
+ {
799
+ method: 'DELETE',
800
+ headers: {
801
+ Authorization: `Bearer ${API_TOKEN}`,
802
+ },
803
+ },
804
+ )
805
+
806
+ if (!response.ok) {
807
+ throw new Error(`Failed to delete Cloudflare video: ${response.statusText}`)
808
+ }
809
+
810
+ return true
811
+ }