feat(meta): report each storage plane's upload/download surface in _meta and add a dynamic storage client - #1765
Merged
Conversation
…in _meta and add a dynamic storage client _meta's storage block now carries the plane's files/buckets type names, download-URL field, and the complete upload surface (mutation, input/payload types, bulk variants, requiresOwnerId), derived from the same registry-FK pairing and inflection the presigned-url plugin emits from. @constructive-io/graphql-query gains a runtime storage client that discovers planes from _meta, resolves a plane by semantic coordinates, builds upload and download documents with gql-ast, and runs the hash -> mutation -> presigned PUT orchestration — no caller ever assembles a GraphQL name.
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:
|
This comment has been minimized.
This comment has been minimized.
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
PR 2 of the dynamic storage plan (constructive-planning#1779), stacked on #1764.
_metanow reports each storage plane's full upload/download surface, and@constructive-io/graphql-querygains a runtime dynamic storage client — so no client (test or app) ever assembles a GraphQL storage name likeupload${TypeName}again._metastorage block (graphile-meta)storage { isFilesTable isBucketsTable }expands to the whole plane surface, derived from the same registry-FK pairing (discoverStoragePlanes) and inflection the presigned-url plugin emits from —_metaand the emitted schema cannot disagree:buildStorageMeta(codec, build)resolves the codec's plane from the registry facts (cached per-registry); a storage-tagged table that belongs to no discoverable plane throwsSTORAGE_PLANE_UNPAIREDinstead of reporting a partial surface.DOWNLOAD_URL_FIELDis now a single exported constant ingraphile-storage-registry, consumed by both the download-url plugin (emitter) and_meta(reporter).discoverStoragePlanesalso gains aSTORAGE_PLANE_AMBIGUOUScheck when two files tables FK one buckets table.Dynamic storage client (
@constructive-io/graphql-query/storage)Runtime discovery — not codegen/ORM. Three independently usable modules (discovery, document building, orchestration) plus a thin client that composes them; byte-level work is an injected
StorageTransportadapter, sographql-queryhas no upload/S3 dependency andupload-clientsupplies the adapter:Discovery and document building work with no
transportat all;upload()without one fails loudly (STORAGE_TRANSPORT_MISSING).resolveStorageSurfaces(_metaResult)groups files/buckets sides intoStorageSurface[], throwingSTORAGE_META_MALFORMEDon duplicate/orphan/inconsistent planes.findStorageSurface(surfaces, selector)resolves exactly one plane byfilesTable/schemaName/filesType; not-found and ambiguous selections throw.buildUploadDocument/buildDownloadUrlDocumentbuild documents withgql-astfrom the_meta-reported names only (mutation, input type,query.onenode field, download field).uploadToSurface(surface, options, { execute, transport })runs hash → mutation → presigned PUT, refusing entity-keyed planes withoutownerId(requiresOwnerId) and skipping the PUT on deduplication. Usable directly when you resolved the surface yourself.upload-clientgainsstorageTransport/createStorageTransport()— a structural adapter over its existinghashFile+putToPresignedUrl, so the dependency stays one-way.convertFromMetaSchemanow carries the storage block through meta-object conversion.The lockfile diff is large because pnpm 10.34.5 rewrote the file into its current single-line
resolutionformat; the only semantic change is the newgraphile-meta → graphile-storage-registryworkspace link.pnpm install --frozen-lockfilepasses.Next (PR 3, constructive-db): delete the static-site e2e's S3/raw-SQL workaround and migrate it to this client.
Testing
pnpm --filter graphile-meta exec jest --runInBand— 134 passedpnpm --filter graphile-storage-registry test— 12 passedpnpm --filter @constructive-io/graphql-query exec jest --runInBand— 40 passed (22 new)pnpm --filter @constructive-io/upload-client test— 24 passedpnpm --filter graphile-presigned-url-plugin test— 69 passed (MinIO up)pnpm lint— cleanLink to Devin session: https://app.devin.ai/sessions/726e066d64e04f29bdbea669c09c6341
Requested by: @pyramation