Skip to content

Feature/generic v1 compat storage#1819

Open
shettyvarun268 wants to merge 4 commits intomasterfrom
feaure/Generic-v1-Compat-storage
Open

Feature/generic v1 compat storage#1819
shettyvarun268 wants to merge 4 commits intomasterfrom
feaure/Generic-v1-Compat-storage

Conversation

@shettyvarun268
Copy link
Contributor

This PR extends the generic V1 compatibility layer to support Google Cloud Storage events. It builds upon the shared compat module introduced in the previous PR by adding specific mapping logic for generic Storage triggers.

We updated patchV1Compat to handle Storage events, correctly mapping V2 StorageObjectData to V1 ObjectMetadata (including necessary date and size type conversions). This logic is now applied to all Storage triggers (onObjectArchived, onObjectFinalized, onObjectDeleted, onObjectMetadataUpdated), ensuring that the context and data (as object) properties are available to V1-migrated functions.

This change ensures a consistent, backward-compatible experience for developers migrating Storage functions to V2. Additionally, we refactored event type strings into exported constants to improve maintainability across the provider and compliance tests. The StorageCloudEvent type is also exported for better type safety.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @shettyvarun268, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the backward compatibility of V2 Cloud Functions by extending the V1 compatibility layer to include Google Cloud Storage events. This change ensures that functions migrating from V1 to V2 can seamlessly process Storage events, maintaining access to expected context and data structures. The refactoring centralizes compatibility logic and improves the overall robustness and maintainability of the event handling system.

Highlights

  • Google Cloud Storage V1 Compatibility: Extended the generic V1 compatibility layer to support Google Cloud Storage events, allowing V2 StorageObjectData to be mapped to V1 ObjectMetadata.
  • Centralized V1 Compatibility Logic: Introduced a new compat.ts module to centralize the patchV1Compat function, which now handles both Pub/Sub and Storage event transformations for V1 compatibility.
  • Comprehensive Storage Event Support: Applied V1 compatibility logic to all Google Cloud Storage triggers, including onObjectArchived, onObjectFinalized, onObjectDeleted, and onObjectMetadataUpdated.
  • Type Safety and Maintainability Improvements: Refactored event type strings into exported constants and exported the StorageCloudEvent type for improved type safety and code maintainability.
  • Data Type Conversion for Storage Events: Implemented necessary date and size type conversions when mapping V2 StorageObjectData to V1 ObjectMetadata to ensure data consistency.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • spec/v2/compat.spec.ts
    • Added a new test file to verify the patchV1Compat function's behavior for Pub/Sub and Storage events, including idempotency and error handling.
  • spec/v2/providers/pubsub.spec.ts
    • Updated event type references to use exported constants.
    • Added a test case to verify V1 compatibility for Pub/Sub events.
  • spec/v2/providers/storage.spec.ts
    • Added a new test suite to confirm V1 compatibility for Storage onObjectFinalized events, including data type conversions.
  • src/v2/compat.ts
    • Added a new module to centralize V1 compatibility logic.
    • Introduced patchV1Compat to transform V2 CloudEvents into V1-compatible formats for Pub/Sub and Storage, handling data type conversions and context mapping.
    • Defined V1Context, V1Event, PubSubCloudEvent, and StorageCloudEvent types.
  • src/v2/index.ts
    • Exported PubSubCloudEvent and StorageCloudEvent types to make them publicly available.
  • src/v2/providers/pubsub.ts
    • Refactored the onMessagePublished function to utilize the new patchV1Compat utility.
    • Removed internal V1 compatibility logic and symbols.
    • Exported messagePublishedEvent as a constant.
    • Removed the MessagePublishedEvent interface.
  • src/v2/providers/storage.ts
    • Integrated the patchV1Compat function into the onOperation handler to provide V1 compatibility for Storage events.
    • Extended the StorageEvent interface with a getV1Compat method.
    • Imported patchV1Compat and related types.
Activity
  • No human activity detected in this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a V1 compatibility layer for Storage events by centralizing logic in a new compat.ts module, which is a solid architectural improvement. The refactoring to use constants for event types also enhances maintainability. However, I've identified a critical circular dependency between compat.ts and providers/storage.ts that leads to type-safety issues. An object that doesn't fully conform to the StorageEvent interface is passed to handlers, which could cause runtime errors. I've provided detailed comments and suggestions to resolve these issues.

@shettyvarun268 shettyvarun268 force-pushed the feaure/Generic-v1-Compat-storage branch from 465b6ad to 585e081 Compare February 26, 2026 19:14
@shettyvarun268
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extends the V1 compatibility layer to support Google Cloud Storage events, which is a great enhancement. The implementation is solid, including the refactoring of event type strings into constants for better maintainability. I've identified a couple of areas for improvement: one to make a test less brittle and another to fix a potential bug when handling malformed storage events. My detailed comments include specific code suggestions to address these points.

Comment on lines 202 to 204
if (!v2) {
return {} as ObjectMetadata;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Returning an empty object {} cast as ObjectMetadata when v2 is falsy violates the ObjectMetadata type contract, which has several required properties (e.g., id, bucket, name). This could lead to runtime errors in downstream code that expects a valid ObjectMetadata object. A better approach for malformed events would be to throw an error, similar to how malformed Pub/Sub events are handled in this file.

Suggested change
if (!v2) {
return {} as ObjectMetadata;
}
if (!v2) {
throw new Error("Malformed Storage event: missing 'data' property.");
}

Comment on lines 78 to 92
const rawEvent = {
specversion: "1.0",
source: "//storage.googleapis.com/projects/_/buckets/my-bucket/objects/my-object",
id: "event-id-stable-storage",
type: finalizedEvent,
time: new Date().toISOString(),
data: {
bucket: "my-bucket",
name: "my-object",
size: 1024,
timeCreated: new Date()
},
} as any;

const patched = patchV1Compat(rawEvent) as any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mock rawEvent object is incomplete and cast to any. This makes the test brittle because it doesn't fully conform to the CloudEvent<StorageObjectData> type. If the implementation of patchV1Compat changes to access other required properties of StorageObjectData in the future, this test could fail unexpectedly.

To make the test more robust and self-documenting, it's better to provide a complete mock object that satisfies the type contract. This also has the benefit of removing the need for casting to any.

Suggested change
const rawEvent = {
specversion: "1.0",
source: "//storage.googleapis.com/projects/_/buckets/my-bucket/objects/my-object",
id: "event-id-stable-storage",
type: finalizedEvent,
time: new Date().toISOString(),
data: {
bucket: "my-bucket",
name: "my-object",
size: 1024,
timeCreated: new Date()
},
} as any;
const patched = patchV1Compat(rawEvent) as any;
const rawEvent: CloudEvent<import("../../src/v2/providers/storage").StorageObjectData> = {
specversion: "1.0",
source: "//storage.googleapis.com/projects/_/buckets/my-bucket/objects/my-object",
id: "event-id-stable-storage",
type: finalizedEvent,
time: new Date().toISOString(),
data: {
bucket: "my-bucket",
name: "my-object",
size: 1024,
timeCreated: new Date(),
id: "my-bucket/my-object/1",
generation: 1,
metageneration: 1,
storageClass: "STANDARD",
updated: new Date(),
},
};
const patched = patchV1Compat(rawEvent);

@shettyvarun268
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extends the V1 compatibility layer to support Google Cloud Storage events, which is a great addition. The implementation is solid, refactoring event type strings into constants for better maintainability. However, I've identified a bug in the new compatibility logic where generation and metageneration fields are not converted to strings, which could lead to issues for developers migrating V1 functions. I've also included suggestions to improve test coverage for this conversion and to enhance code quality by removing an unnecessary type casting in another test.

if (v2.timeStorageClassUpdated instanceof Date) v1.timeStorageClassUpdated = v2.timeStorageClassUpdated.toISOString();

// 'size' in V2 is number, V1 says string.
if (typeof v2.size === "number") v1.size = v2.size.toString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The V1 ObjectMetadata type expects generation and metageneration to be strings, but the V2 StorageObjectData provides them as numbers. The conversion logic is missing for these fields. This will cause a type mismatch for consumers of the V1 compatibility layer. Please add conversions for these fields from number to string, similar to how size is handled.

},
};

const patched = patchV1Compat(rawEvent) as any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The as any cast here can be removed. The function overloads for patchV1Compat should allow TypeScript to correctly infer the return type as StorageCloudEvent<StorageObjectData>, which has the getV1Compat method. Relying on type inference makes the code safer and easier to read.

Suggested change
const patched = patchV1Compat(rawEvent) as any;
const patched = patchV1Compat(rawEvent);

Comment on lines 771 to 777
expect(v1Event.data).to.include({
bucket: "my-bucket",
name: "my-object",
kind: "storage#object",
size: "1024", // V1 expects string
timeCreated: "2023-01-01T00:00:00.000Z", // V1 expects string
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test for V1 compatibility is a good start. To make it more comprehensive, please also assert that generation and metageneration are correctly converted to strings in the V1 event data. This will help ensure the compatibility layer is working as expected for all relevant fields and would have caught the type conversion issue in compat.ts.

@shettyvarun268
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively extends the V1 compatibility layer to support Google Cloud Storage events. The changes are well-structured, introducing specific mapping logic for storage triggers and refactoring event type strings into constants for better maintainability. The addition of StorageCloudEvent and updates to patchV1Compat are implemented correctly. The accompanying tests are thorough, though there's a small opportunity to improve test determinism by using fixed dates instead of new Date(). Overall, this is a solid contribution that enhances backward compatibility for developers migrating storage functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant