From 6d500a481bc2d1dd712ccbba7a3a4218f9d496d8 Mon Sep 17 00:00:00 2001 From: Hassan Bahati Date: Tue, 2 Dec 2025 17:32:57 +0300 Subject: [PATCH 1/8] feat(storage-resize-images): Add onStartResize event and trigger for onStart event (#2562) * fix(storage-resize-images): add missing recordStartEvent call * feat(storage-resize-images): add onStorageResize event * docs(storage-resize-images): update changelog * chore(storage-resize-images): add onStartResize * chore(storage-resize-images): add onStartResize event --------- Co-authored-by: Tadej --- storage-resize-images/CHANGELOG.md | 5 +++++ storage-resize-images/extension.yaml | 8 +++++++- storage-resize-images/functions/src/events.ts | 16 ++++++++++++++++ storage-resize-images/functions/src/index.ts | 6 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/storage-resize-images/CHANGELOG.md b/storage-resize-images/CHANGELOG.md index 0e7d219ff..f12933d6b 100644 --- a/storage-resize-images/CHANGELOG.md +++ b/storage-resize-images/CHANGELOG.md @@ -1,3 +1,8 @@ +## Version 0.3.1 + +fix - add missing recordStartEvent call (#2546) +feat - add new onStartResize event + ## Version 0.3.0 fix! - remove backfill, due to architectural flaws. diff --git a/storage-resize-images/extension.yaml b/storage-resize-images/extension.yaml index 69d3fec20..ea4fb4212 100644 --- a/storage-resize-images/extension.yaml +++ b/storage-resize-images/extension.yaml @@ -13,7 +13,7 @@ # limitations under the License. name: storage-resize-images -version: 0.3.0 +version: 0.3.1 specVersion: v1beta displayName: Resize Images @@ -426,6 +426,12 @@ events: description: Occurs when the function is settled. Provides no customized data other than the context. + + - type: firebase.extensions.storage-resize-images.v1.onStartResize + description: + Occurs when an image resize operation completes successfully. This event + is only triggered when shouldResize returns true and the resize operation + succeeds. # Lifecycle events disabled - backfill feature commented out # lifecycleEvents: # onInstall: diff --git a/storage-resize-images/functions/src/events.ts b/storage-resize-images/functions/src/events.ts index f3168b4dc..6b548d766 100644 --- a/storage-resize-images/functions/src/events.ts +++ b/storage-resize-images/functions/src/events.ts @@ -60,3 +60,19 @@ export const recordCompletionEvent = async (data: string | object) => { data, }); }; + +export const recordStartResizeEvent = async ({ + subject, + data, +}: { + subject: string; + data: string | object; +}) => { + if (!eventChannel) return; + + return eventChannel.publish({ + type: getEventType("onStartResize"), + subject, + data, + }); +}; diff --git a/storage-resize-images/functions/src/index.ts b/storage-resize-images/functions/src/index.ts index 5cb7034f5..6a4a380cb 100644 --- a/storage-resize-images/functions/src/index.ts +++ b/storage-resize-images/functions/src/index.ts @@ -59,6 +59,11 @@ const generateResizedImageHandler = async ( return; } + await events.recordStartResizeEvent({ + subject: object.name, + data: { input: object }, + }); + const bucket = admin.storage().bucket(object.bucket); const filePath = object.name; // File path in the bucket. const parsedPath = path.parse(filePath); @@ -149,6 +154,7 @@ const generateResizedImageHandler = async ( export const generateResizedImage = functions.storage .object() .onFinalize(async (object, context) => { + await events.recordStartEvent(object); await generateResizedImageHandler(object); await events.recordCompletionEvent({ context }); }); From d15701590c62b4ee0cc0d3ee268dbab5f341ea92 Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 13:39:09 +0300 Subject: [PATCH 2/8] fix(firestore-send-email): improve attachments validation error message --- firestore-send-email/functions/__tests__/validation.test.ts | 2 +- firestore-send-email/functions/src/validation.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/firestore-send-email/functions/__tests__/validation.test.ts b/firestore-send-email/functions/__tests__/validation.test.ts index 1d74fca27..92a89f2c5 100644 --- a/firestore-send-email/functions/__tests__/validation.test.ts +++ b/firestore-send-email/functions/__tests__/validation.test.ts @@ -615,7 +615,7 @@ describe("validatePayload", () => { }; expect(() => validatePayload(invalidPayload)).toThrow(ValidationError); expect(() => validatePayload(invalidPayload)).toThrow( - "Invalid message configuration: Field 'message.attachments' must be an array" + "Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])" ); }); }); diff --git a/firestore-send-email/functions/src/validation.ts b/firestore-send-email/functions/src/validation.ts index 0d13af707..590864872 100644 --- a/firestore-send-email/functions/src/validation.ts +++ b/firestore-send-email/functions/src/validation.ts @@ -53,7 +53,10 @@ export const attachmentSchema = z }); export const attachmentsSchema = z - .array(attachmentSchema) + .array(attachmentSchema, { + invalid_type_error: + "Field 'attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])", + }) .optional() .transform((attachments) => attachments From b244b6f26892c10c31c3a9d652059e0d87d6279a Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 13:43:48 +0300 Subject: [PATCH 3/8] fix(firestore-send-email): improve attachments validation error message --- firestore-send-email/functions/__tests__/validation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore-send-email/functions/__tests__/validation.test.ts b/firestore-send-email/functions/__tests__/validation.test.ts index 92a89f2c5..63aa6d8a4 100644 --- a/firestore-send-email/functions/__tests__/validation.test.ts +++ b/firestore-send-email/functions/__tests__/validation.test.ts @@ -615,7 +615,7 @@ describe("validatePayload", () => { }; expect(() => validatePayload(invalidPayload)).toThrow(ValidationError); expect(() => validatePayload(invalidPayload)).toThrow( - "Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])" + "Invalid message configuration: Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])" ); }); }); From cd3205dc735fd4a39f93138d45f10f9d0e7b24f3 Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 14:16:28 +0300 Subject: [PATCH 4/8] tests(firestore-send-email): fix tests --- firestore-send-email/functions/src/validation.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firestore-send-email/functions/src/validation.ts b/firestore-send-email/functions/src/validation.ts index 590864872..060383c2c 100644 --- a/firestore-send-email/functions/src/validation.ts +++ b/firestore-send-email/functions/src/validation.ts @@ -185,6 +185,10 @@ function formatZodError( const path = issue.path.length > 0 ? issue.path.join(".") : context; switch (issue.code) { case "invalid_type": + if (issue.message && !issue.message.startsWith("Expected")) { + return issue.message; + } + if (issue.expected === "string") { return `Field '${path}' must be a string`; } From 80265a4416f3c22b51877bb888e3c71ca0654fcb Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 14:48:11 +0300 Subject: [PATCH 5/8] tests(firestore-send-email): fix tests --- firestore-send-email/functions/src/validation.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/firestore-send-email/functions/src/validation.ts b/firestore-send-email/functions/src/validation.ts index 060383c2c..333093883 100644 --- a/firestore-send-email/functions/src/validation.ts +++ b/firestore-send-email/functions/src/validation.ts @@ -186,7 +186,11 @@ function formatZodError( switch (issue.code) { case "invalid_type": if (issue.message && !issue.message.startsWith("Expected")) { - return issue.message; + const customMessage = issue.message.replace( + /Field 'attachments'/g, + `Field '${path}'` + ); + return customMessage; } if (issue.expected === "string") { From b31f3eb95b1424d1709e4c5ef32238318a2a55bc Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 15:12:06 +0300 Subject: [PATCH 6/8] tests(firestore-send-email): refactor tests --- firestore-send-email/functions/src/validation.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/firestore-send-email/functions/src/validation.ts b/firestore-send-email/functions/src/validation.ts index 333093883..3bc5c31b8 100644 --- a/firestore-send-email/functions/src/validation.ts +++ b/firestore-send-email/functions/src/validation.ts @@ -185,12 +185,8 @@ function formatZodError( const path = issue.path.length > 0 ? issue.path.join(".") : context; switch (issue.code) { case "invalid_type": - if (issue.message && !issue.message.startsWith("Expected")) { - const customMessage = issue.message.replace( - /Field 'attachments'/g, - `Field '${path}'` - ); - return customMessage; + if (issue.received === "undefined") { + return `Field '${path}' must be a ${issue.expected}`; } if (issue.expected === "string") { From 4021e36ab00036def2352170ca03c1f0dd290418 Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 15:20:06 +0300 Subject: [PATCH 7/8] tests(firestore-send-email): fix tests --- firestore-send-email/functions/__tests__/validation.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore-send-email/functions/__tests__/validation.test.ts b/firestore-send-email/functions/__tests__/validation.test.ts index 63aa6d8a4..1d74fca27 100644 --- a/firestore-send-email/functions/__tests__/validation.test.ts +++ b/firestore-send-email/functions/__tests__/validation.test.ts @@ -615,7 +615,7 @@ describe("validatePayload", () => { }; expect(() => validatePayload(invalidPayload)).toThrow(ValidationError); expect(() => validatePayload(invalidPayload)).toThrow( - "Invalid message configuration: Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])" + "Invalid message configuration: Field 'message.attachments' must be an array" ); }); }); From f2591670bdb51261ee944aad9984d3cef0a863b7 Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Mon, 12 Jan 2026 15:56:36 +0300 Subject: [PATCH 8/8] tests(firestore-send-email): refactor tests --- .../functions/__tests__/validation.test.ts | 2 +- firestore-send-email/functions/src/validation.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/firestore-send-email/functions/__tests__/validation.test.ts b/firestore-send-email/functions/__tests__/validation.test.ts index 1d74fca27..63aa6d8a4 100644 --- a/firestore-send-email/functions/__tests__/validation.test.ts +++ b/firestore-send-email/functions/__tests__/validation.test.ts @@ -615,7 +615,7 @@ describe("validatePayload", () => { }; expect(() => validatePayload(invalidPayload)).toThrow(ValidationError); expect(() => validatePayload(invalidPayload)).toThrow( - "Invalid message configuration: Field 'message.attachments' must be an array" + "Invalid message configuration: Field 'message.attachments' must be an array. If you have a single attachment object, wrap it in an array (e.g., [{ filename: '...', path: '...' }])" ); }); }); diff --git a/firestore-send-email/functions/src/validation.ts b/firestore-send-email/functions/src/validation.ts index 3bc5c31b8..79923672c 100644 --- a/firestore-send-email/functions/src/validation.ts +++ b/firestore-send-email/functions/src/validation.ts @@ -193,6 +193,13 @@ function formatZodError( return `Field '${path}' must be a string`; } if (issue.expected === "array") { + if (issue.message && !issue.message.startsWith("Expected")) { + const customMessage = issue.message.replace( + /Field 'attachments'/g, + `Field '${path}'` + ); + return customMessage; + } return `Field '${path}' must be an array`; } if (issue.expected === "object") {