feat: pipeline state machine, SourceState schema, protocol + service refactors#250
Merged
feat: pipeline state machine, SourceState schema, protocol + service refactors#250
Conversation
Replace z.enum(SUPPORTED_API_VERSIONS) with z.string() so the engine accepts non-bundled versions (CDN-fetched). Advertise known versions in the JSON schema via anyOf so z.fromJSONSchema in the resolver produces a union that accepts any string rather than a strict enum. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Replace hardcoded BUNDLED_API_VERSION / SUPPORTED_API_VERSIONS in specFetchHelper.ts with a generated src/versions.ts derived from the files present in packages/openapi/oas/*.json. - Add scripts/generate-versions.mjs — scans oas/, writes src/versions.ts - Hook into build: node scripts/generate-versions.mjs && tsc - specFetchHelper.ts imports from ./src/versions.js (no more hardcodes) - Revert api_version from z.string() back to z.enum(SUPPORTED_API_VERSIONS) - Remove anyOf JSON Schema hack; enum is now the direct source of truth - Update spec.test.ts to assert strict enum validation Adding a new bundled API version is now: drop the .json into oas/, run pnpm --filter @stripe/sync-openapi build. Same oas/ directory powers the docs CDN (docs/scripts/generate-stripe-specs.mjs). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…d time generate-versions.mjs now fetches stripe-sync.dev/stripe-api-specs/manifest.json to populate SUPPORTED_API_VERSIONS (51 versions) while BUNDLED_API_VERSION stays derived from the single oas/*.json file. The CDN manifest is produced by docs/scripts/generate-stripe-specs.mjs — same source, shared contract. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…st.json Remove network fetch at build time. Instead: - oas/manifest.json is committed alongside the bundled spec - generate-versions.mjs reads it locally (reproducible, no network) - docs/scripts/generate-stripe-specs.mjs now also writes manifest to packages/openapi/oas/manifest.json when updating the CDN To pick up new Stripe API versions: 1. Run docs/scripts/generate-stripe-specs.mjs 2. Commit updated oas/manifest.json 3. Run pnpm --filter @stripe/sync-openapi build Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…ipts/ - Add scripts/generate-all-specs.mjs (heavyweight): moved from docs/scripts/generate-stripe-specs.mjs; walks stripe/openapi git history, writes spec files + manifest.json to <outputDir> for CDN, and updates src/versions.ts as a side effect - Keep scripts/generate-versions.mjs (lightweight): standalone utility to bootstrap src/versions.ts from just the bundled oas/ file - Remove build-time version generation from package.json — src/versions.ts is a committed file updated by the heavyweight script; build = tsc only - Remove oas/manifest.json — not needed in the package - docs/scripts/generate-stripe-specs.mjs → thin wrapper that delegates to packages/openapi/scripts/generate-all-specs.mjs packages/openapi is now the source of truth for Stripe API version discovery. CDN invokes generate-all-specs.mjs with an output directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…replacement - Delete read-into-queue.ts and write-from-queue.ts — unused generic queue activities; pipelineWorkflow and backfillPipelineWorkflow use syncImmediate directly, and googleSheetPipelineWorkflow has its own GS-specific queue activities - Fix global source_state handling: replace wholesale (state.global = data) instead of merging (Object.assign) — consistent with stream state which already does per-stream replacement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…versions filter
- Rename generate-all-specs.mjs → generate-specs.mjs
- Add --versions flag to generate specific versions only (e.g. for
updating the bundled spec in oas/):
node scripts/generate-specs.mjs oas --versions 2026-03-25.dahlia
Without the flag, all versions are generated (CDN use case).
- Update docs/scripts/generate-stripe-specs.mjs wrapper reference
- Update generate-versions.mjs comment reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
- Fix getParamContentType() to extract the media type string from the
content object rather than returning the whole object, which coerced
to '[object Object]' as a property key
- Rename x-state header to x-source-state for clarity
- Add .meta({ id: 'SourceState' }) to SyncState for a named OAS schema
- Regenerate openapi.json / openapi.d.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
Activities now receive the current full SyncState as initial state and return the updated full SyncState. Workflows simply assign result.state directly — no merge logic in the workflow layer. - drainMessages accepts initialState and starts from it - syncImmediate passes readOpts.state to drainMessages - readGoogleSheetsIntoQueue starts state from readOpts.state - writeGoogleSheetsFromQueue accepts opts.state and starts from it - All workflows: syncState = result.state (no spread merge) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…→ reconcileComplete
- Rename SyncState Zod schema and type to SourceState across all packages
(.meta({ id: 'SourceState' }) was already correct)
- Rename backfillComplete → reconcileComplete in backfill workflow
- Add reconcileComplete to BackfillPipelineWorkflowOpts so it survives continueAsNew
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
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
A broad refactor establishing clean ownership of sync state and protocol types across engine, service, and activities.
State ownership
SourceStatereplacesSyncState— renamed throughout + added.meta({ id: 'SourceState' })so it appears as a named$refcomponent in the OAS specSourceStateas initial state, accumulate source_state messages on top of it, and return the updated full state; workflows simply dosyncState = result.state(no spread-merge logic in workflow layer)x-source-stateheader (renamed fromx-state) carries the fullSourceStateblob into the engine on each callOpenAPI fixes
[object Object]content key bug —getParamContentType()now extracts the media type string from the content object instead of coercing the whole object to a string keypackages/hono-zod-openapi: headerparam.contentaccepts both object form{ 'application/json': {} }(OAS-typed, preferred) and legacy string form[object Object]keys,SourceStateschema present,x-source-stateuses$ref: '#/components/schemas/SourceState'OpenAPI spec tooling
packages/openapi/scripts/generate-specs.mjs— canonical script for fetching Stripe API spec versions;--versionsflag for targeted runs vs full CDN generationBUNDLED_API_VERSIONandSUPPORTED_API_VERSIONSderived from committedoas/*.jsonfiles (no runtime fetching)docs/scripts/generate-stripe-specs.mjs→ thin wrapper delegating to package scriptProtocol refactors
SourceInputenvelopeeofterminal message +state_limit/time_limitquery paramseverything-is-a-stream— all connector output through unified streamService
reconcileCompleteflag (renamed frombackfillComplete)x-source-stateheader inremote-engine.ts🤖 Generated with Claude Code