feat: add CORS management to bucket provisioner plugin#963
Merged
pyramation merged 10 commits intomainfrom Apr 4, 2026
Merged
Conversation
…kets on bucket table mutations - PostGraphile v5 plugin with two provisioning pathways: 1. Auto-provisioning hook on create mutations tagged with @storagebuckets 2. Explicit provisionBucket GraphQL mutation for manual/retry provisioning - Reads per-database endpoint/provider/publicUrlPrefix overrides from storage_module table - Lazy S3 config resolution (function-based, cached after first call) - Graceful error handling (provisioning failures logged, never fail the mutation) - Custom bucket naming via prefix or resolveBucketName function - 46 passing tests covering plugin structure, mutation callback, auto-provisioning hook, connection config resolution, error handling, and bucket name resolution - Added to CI test matrix
…ner-plugin' into devin/1775257329-cors-allowed-origins
- Add per-call allowedOrigins override to BucketProvisioner.provision() - Add updateCors() method for CORS-only updates on existing buckets - Export UpdateCorsOptions type from bucket-provisioner package - Update graphile plugin with 3-tier CORS resolution hierarchy: bucket-level > storage_module-level > plugin config - Wrap update* mutations on @storagebuckets tables to detect allowed_origins changes and re-apply CORS rules - Read allowed_origins from bucket row in provisionBucket mutation - Support wildcard CORS (['*']) for CDN/public buckets - Add 8 new tests for CORS hierarchy, update hooks, error handling - All 54 plugin tests + 84 bucket-provisioner tests passing
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…Options - Add bucket-provisioner-resolver.ts in graphile-settings (lazy init via getEnvOptions, same pattern as presigned-url-resolver.ts) - Wire BucketProvisionerPreset into constructive-preset.ts with lazy connection getter - Update JSDoc examples in bucket-provisioner-plugin to show getEnvOptions pattern instead of raw process.env - Export getBucketProvisionerConnection from graphile-settings index
…1775257329-cors-allowed-origins
…1775257329-cors-allowed-origins
…1775257329-cors-allowed-origins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds CORS management to the
graphile-bucket-provisioner-pluginand@constructive-io/bucket-provisionerpackages.Plugin changes (
graphile-bucket-provisioner-plugin):update*mutations on@storageBuckets-tagged tables to detectallowed_originschanges and callupdateCors()on the S3 bucketallowed_origins→storage_module-levelallowed_origins→ plugin configallowedOrigins['*']) for CDN/public bucket deploymentsallowed_originsfrom both the bucket row andstorage_moduletableprovisionBucketexplicit mutation now passes bucket-levelallowed_originsthrough the hierarchyLibrary changes (
@constructive-io/bucket-provisioner):provision()now accepts optionalallowedOriginsper-call override (falls back to provisioner default)updateCors()method for CORS-only updates without full re-provisioningUpdateCorsOptionstype exportedTest coverage: 54 plugin tests (8 new CORS tests) + 84 bucket-provisioner tests passing.
Updates since last revision
BucketProvisionerPresetis now wired intoConstructivePresetingraphile-settings, following the same lazy-init pattern aspresigned-url-resolver.tsbucket-provisioner-resolver.ts— reads CDN config viagetEnvOptions()(merges pgpmDefaults → config file → env vars), caches on first callprovisionBucketmutation,ProvisionBucketInput, andProvisionBucketPayloadnow appear in the GraphQL SDL snapshotpreset.tsandindex.tsexamples now showgetEnvOptions()pattern instead of rawprocess.envReview & Testing Checklist for Human
allowed_originsfrombucketInputdirectly (not from apatchsub-object). Verify this matches how PostGraphile v5 actually structuresupdate*mutation inputs. If PG5 uses{ nodeId, patch: { allowed_origins } }, the detection at'allowed_origins' in bucketInputwill miss it. This is the highest-risk item.bucketInput?.keyto look up the bucket row post-update. Confirm this is where PG5 puts the row identifier in update mutation args. If PG5 usesnodeIdinstead, the CORS update will silently skip with a warning.bucket-provisioner-resolver.tsreadscdnfromgetEnvOptions()and destructuresawsAccessKey,awsSecretKey, etc. Verify these fields are always populated by pgpmDefaults so the resolver doesn't throw on first call in environments without explicit CDN env vars.allowed_originscolumn is actually returned by the SQL queries against realstorage_moduleand buckets tables (depends on companion PR constructive-db#756).Suggested test plan: Deploy with a test database that has the
allowed_originscolumns (from constructive-db#756), create a bucket with specificallowed_origins, and verify the S3 bucket gets the correct CORS config. Then updateallowed_originsand confirm the S3 CORS is re-applied. Also verify thatprovisionBucketmutation appears in the schema when running againstConstructivePreset.Notes
allowed_originstostorage_moduletable and buckets table generatorpnpm-lock.yamlhas unrelated@types/nodeversion resolution drift (22.19.15→25.5.0) — this is lock file churn, not an intentional changeLink to Devin session: https://app.devin.ai/sessions/4c882ba2dfbf4045adf85fb83cde6f77
Requested by: @pyramation