SDK codegen foundation: contract, Storage pipeline, and SupabaseRuntime#30
Draft
grdsdev wants to merge 50 commits into
Draft
SDK codegen foundation: contract, Storage pipeline, and SupabaseRuntime#30grdsdev wants to merge 50 commits into
grdsdev wants to merge 50 commits into
Conversation
Introduces Binding type (spec + operationId) and optional binding field on Feature; mirrors the change in the JSON schema with a sibling $defs entry and ref from the feature definition. Covered by binding-schema tests.
…sion and filtering
Pure transform functions that normalize an upstream OpenAPI doc in-place:
renameWildcardParams (Fastify {*} paths), renameSchemas ($ref-aware),
deriveOperationId, injectOperationIds, and a top-level normalizeSpec
orchestrator. Covers the three Storage spec issues: missing operationIds,
wildcard path params, and opaque def-N schema names.
Add findUnmatchedOverrides guard that detects override keys with no matching operation; call it in the CLI after normalization so bad keys throw instead of silently producing wrong derived ids. Fix storage.json GET/POST /bucket keys to include the trailing slash that the spec actually uses.
Extends the normalizer with five OAS 3.1→3.0 fix-ups required for
openapi-generator 7.x / Swift 6 to produce clean compilable output:
- fixArrayTypes: type:[null,T] → nullable+single type
- stripDollarComments: removes $comment (OAS 3.1 annotation)
- stripSchemaExamples: removes plural examples array (OAS 3.1)
- inlineExternalRefs: replaces unresolvable http:// $refs with {}
- dedupCaseInsensitiveProperties: drops PascalCase vs lowercase
property name collisions (Id vs id in POST /object/copy response)
Re-runs normalize → generate → verified swift build with zero errors.
Adds codegen/generated/swift-storage (162 files, urlsession, no deps).
Excludes .build/ via .gitignore.
Adds checkBindingOperations (bindings.ts) which verifies each feature binding's operationId actually exists in the referenced normalized spec. Wires it into run() immediately after checkBindings. Adds operationId overrides for deleteBucket and getBucket, regenerates the normalized spec and Swift output, and binds five Storage features: createBucket, listBuckets, uploadObject, deleteBucket, getBucket.
Introduces AuthProvider (async closure-based, Sendable, with a .none static) and ClientConfiguration (baseURL, defaultHeaders, auth, encoder, decoder, sessionKind, errorMapper) as the central config struct for the SupabaseRuntime Swift package.
Implements `URLSessionTransport` with buffered `send` variants (no-body, with-body, fire-and-forget). Uses `URLComponents` path concatenation to compose request URLs from the configured base, merges default + auth + per-request headers, and maps non-2xx via `errorMapper` then falls back to `TransportError.http`. Upload/download/stream stubs left as `fatalError` for Tasks 6-7. Adds `StubURLProtocol` test helper and `@Suite(.serialized)` to guard shared static state against parallel runs.
…egate Implements Task 6: replaces fatalError stubs in URLSessionTransport with real async upload(for:)/download(for:) calls. Progress is wired via SessionDelegate when the transport owns its session; under an injected stub session (no delegate) the progress stream is empty but terminates correctly.
Replace the session-level SessionDelegate (which registered but never
actually yielded to the per-call continuation) with a lightweight
TaskProgressDelegate that is passed directly to the per-call async
URLSession APIs (upload(for:from:delegate:), download(for:delegate:)).
The continuation is now held by the delegate, so progress DOES emit in
production. The stream terminates via defer { cont.finish() } in both
upload and download paths. Adds uploadProgressStreamTerminates test.
Implement URLSessionTransport.stream() using URLSession.bytes(for:) to drive an AsyncThrowingStream that buffers bytes in 4 KiB chunks, maps non-2xx responses to TransportError, and cancels the producer Task on stream termination to avoid leaks.
Add file-only guard to `upload` that throws `TransportError.backgroundRequiresFile` when a `.background` session attempts an in-memory `.data` upload. Add actor-isolated `handleBackgroundEvents` / `consumeBackgroundCompletion` for the OS relaunch hook. Unit-tested via injected stub session; full background delivery (session delegate + OS relaunch wiring) is a documented integration gap.
…s a build product The committed openapi-generator output was a Plan 2 pilot artifact proving the pipeline builds. The lean templates (Plan B) will regenerate the Storage client onto SupabaseRuntime, so the stock output is removed. Generated code is now gitignored (regenerated from the committed normalized spec); the drift guard is rescoped to the normalized spec.
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
Foundation for cross-SDK code generation, piloted on Swift. The strategy: generate the mechanical layer (transport/types/errors) from upstream OpenAPI via a shared engine + per-language templates, and hand-write only what makes each stack unique. This PR lands the contract, the in-repo Storage pipeline, and a modern Swift 6 runtime. Draft — foundation for review; follow-on work outlined below.
What's included
scripts/capability-matrix) — optionalbinding: { spec, operationId }on capability features,codegen.yaml(engine pin + spec sources + per-language config) with its JSON schema, a conformance-vector format, and validation wired intonpm run validate(binding ↔ spec/operation checks + drift guard).src/normalize.ts) that makes the upstream Storage OpenAPI generation-ready (injects operationIds, fixes Fastify{*}wildcards, renamesdef-Nschemas, OAS-3.1→3.0 fixups, injects octet-stream upload bodies), plusnormalize/generate/generate:checkscripts. The committed normalized spec is the deterministic, drift-guarded input.SupabaseRuntime(codegen/runtime/swift/SupabaseRuntime) — a generic, dependency-free Swift 6 runtime: a narrowTransportseam over an actorURLSessionTransport(native async URLSession, streaming upload/download with progress, event-streamstream(), background-session guard + relaunch hook, typed errors), injectedClientConfiguration/AuthProvider, and a body-awareMockTransport. 30 swift-testing tests, parallel-stable,swift buildclean.codegen/upstream-spec-issues.mdrecords 10 Storage spec problems the normalizer works around, each mapped to its upstream fix (so workarounds can be deleted once fixed upstream).Intentionally NOT included
openapi-generatoroutput was a pilot artifact that proved the pipeline builds; an audit found its stock transport non-idiomatic. The follow-up will regenerate a thin client ontoSupabaseRuntimevia lean templates, so the stock output is removed. Generated code is now treated as a build product (gitignored, regenerated from the committed normalized spec).Roadmap (follow-on)
templates/swift+codegen.yamlthat regenerate Storage's thin client ontoSupabaseRuntime(opens with a template-override spike).$refs,Dates, ints).Verification
scripts/capability-matrix: vitest suite +npm run validatepass.SupabaseRuntime: 30 tests pass across repeated parallel runs;swift buildclean, zero dependencies, Swift 6 language mode.Notes for reviewers
docs/design/2026-06-16-sdk-code-generation-design.md,docs/design/2026-06-16-swift-codegen-runtime-design.md. Plans underdocs/plans/..build/artifacts); please squash-merge to collapse them away.Test plan
cd scripts/capability-matrix && npm ci && npm test && npm run validatecd codegen/runtime/swift/SupabaseRuntime && swift testcd scripts/capability-matrix && npm run generate:check(regenerates from the normalized spec; drift-clean)