Skip to content

Mark protocol versions as generated#872

Draft
kvz wants to merge 156 commits into
mainfrom
tus-gen
Draft

Mark protocol versions as generated#872
kvz wants to merge 156 commits into
mainfrom
tus-gen

Conversation

@kvz

@kvz kvz commented May 26, 2026

Copy link
Copy Markdown
Member

Why

This is the first generated island for the API2-owned TUS protocol SDK generator. It lets the API2 generator rewrite and compare protocol constants and checked examples before expanding into more client behavior, while keeping this PR as experimental Draft work.

Experimental Status

Experimental work: this PR is part of an exploratory contract/generated docs and SDK effort, and is intentionally kept as a Draft while the approach is validated.

What

  • Mark protocol version constants in lib/options.ts with generated-region markers.
  • Keep the generated protocol-version output byte-for-byte identical to the existing constants, aside from markers and the ownership notice.
  • Add a generated protocol contract fixture derived from API2 TUS operation contracts, wire version metadata, and client feature metadata.
  • Add a real Upload lifecycle test that consumes the generated fixture to assert the generated createTusUpload and patchTusUpload steps against tus-js-client behavior.
  • Teach the shared API2 devdock helper to pass scenario.upload.headers into TUS upload options when present, keeping the header facts contract-owned.
  • Stabilize the generated retry timer proof so it records retry schedules authorized by the current scenario's onShouldRetry decision instead of observing unrelated global timers from other specs.
  • Add checked-in api2-devdock-tus-custom-request-headers example that uses the public headers option and request hooks to prove custom headers are sent on POST and PATCH.
  • Add checked-in api2-devdock-tus-request-id-headers example that enables addRequestId from scenario JSON and observes generated X-Request-ID values on POST and PATCH through public request hooks.
  • Add checked-in api2-devdock-tus-upload-body-headers example that reads expected POST and PATCH upload body headers from scenario JSON and observes them through public request hooks.
  • Add checked-in api2-devdock-tus-deferred-length-upload example that reads the generated scenario, enables uploadLengthDeferred, and observes generated Upload-Defer-Length/Upload-Length header constants on POST/PATCH.
  • Add checked-in api2-devdock-tus-request-lifecycle-hooks example that reads expected lifecycle methods/status codes from scenario JSON and observes onBeforeRequest/onAfterResponse through public request hooks.
  • Add checked-in api2-devdock-tus-relative-location-resolution example that reads a TUS conformance scenario, uses a contract-backed HTTP stack, and proves public Upload resolves a relative Location response to the expected absolute upload URL.
  • Move the contract-backed conformance HTTP stack into the shared API2 devdock helper so pure protocol examples can reuse the same mechanical transport.
  • Add checked-in api2-devdock-tus-override-patch-method example that reads a TUS conformance scenario and proves public Upload sends the effective POST request with X-HTTP-Method-Override: PATCH.
  • Add checked-in api2-devdock-tus-node-path-input-source example that reads a TUS conformance scenario and proves public Upload can upload a Node path-reference input source.
  • Extend the shared contract-backed HTTP stack to drain Node Readable request bodies, count bytes, and emit progress so Node path-reference examples exercise the same body class as the real Node HTTP stack.
  • Add checked-in api2-devdock-tus-start-option-validation example that reads a TUS conformance scenario and proves public Upload rejects conflicting parallelUploads/uploadUrl options before any HTTP request is made.
  • Add shared conformance option mapping so API2 scenario inputOptionEntries can become public tus-js Upload options without hardcoding each example's rule.
  • Add checked-in api2-devdock-tus-detailed-error example that reads TUS conformance scenarios and proves public Upload reports DetailedError instances for both response errors and request errors with request context, response context when present, and causing errors when present.
  • Extend the shared contract-backed HTTP stack so a request plan can reject with a contract-projected transport error.
  • Extend the checked-in api2-devdock-tus-resume-upload example so a stricter scenario can prove file-backed URL storage via public resume APIs, capturing the persisted key prefix, remaining storage entries, and backend kind from runtime behavior.
  • Add checked-in api2-devdock-tus-abort-upload example that reads TUS conformance scenarios and proves public Upload.abort(...) behavior for aborting an active create request and aborting an active patch request before terminating the stored upload.
  • Extend the shared contract-backed HTTP stack with abortable request plans, request-abort event capture, runtime fingerprint setup, and contract-owned abort execution actions.
  • Add a shared conformance retry observer and checked-in api2-devdock-tus-retry-state-transitions example that reads contract-owned retry decisions/schedules and proves public onShouldRetry plus timer behavior through the offset-recovery flow.
  • Add checked-in api2-devdock-tus-protocol-version-selection example and generic absent/exact-header checks in the shared conformance HTTP stack, proving draft-05 create/chunked and draft-03 resume protocol selection from API2 scenario facts.
  • Add checked-in api2-devdock-tus-parallel-upload-concat example that reads the contract-owned parallel concat conformance scenario and proves public Upload creates two partial uploads, sends the expected byte slices, concatenates them with the expected final Upload-Concat, and reports the normalized meaningful progress/chunk-complete event sequence.
  • Extend the shared contract-backed HTTP stack to capture request body sizes and byte starts, and add a mechanical event-sequence projector so extra raw progress callbacks do not weaken or overstate the contract-owned event sequence.
  • Latest generated policy sync: add the contract-owned detailed-error cause string template to generated protocol runtime output.

Verification

  • npm run build-transpile
  • npm run lint-code
  • From API2: api2/bin/cli.ts contracts sdks --no-motd --target tus --platform typescript --sdk-root ../tus-js-client --compare-existing
  • npm run test-node
  • npm run test-node -- --seed=09053
  • node --check examples/api2-devdock-shared/scenario.js
  • node --check examples/api2-devdock-tus-custom-request-headers/main.js
  • node --check examples/api2-devdock-tus-request-id-headers/main.js
  • node --check examples/api2-devdock-tus-upload-body-headers/main.js
  • node --check examples/api2-devdock-tus-deferred-length-upload/main.js
  • node --check examples/api2-devdock-tus-relative-location-resolution/main.js
  • node --check examples/api2-devdock-tus-override-patch-method/main.js
  • node --check examples/api2-devdock-tus-node-path-input-source/main.js
  • node --check examples/api2-devdock-tus-start-option-validation/main.js
  • node --check examples/api2-devdock-tus-detailed-error/main.js
  • node --check examples/api2-devdock-tus-resume-upload/main.js
  • node --check examples/api2-devdock-tus-abort-upload/main.js
  • node --check examples/api2-devdock-tus-retry-state-transitions/main.js
  • node --check examples/api2-devdock-tus-protocol-version-selection/main.js
  • node --check examples/api2-devdock-tus-parallel-upload-concat/main.js
  • Local generated scenario smoke for api2-devdock-tus-node-path-input-source
  • Local generated scenario smoke for api2-devdock-tus-start-option-validation
  • Local generated scenario smokes for both api2-devdock-tus-detailed-error scenarios
  • Local generated scenario smokes for both api2-devdock-tus-abort-upload scenarios
  • Local generated scenario smoke for api2-devdock-tus-retry-state-transitions
  • Local generated scenario smokes for all three api2-devdock-tus-protocol-version-selection scenarios
  • Local generated scenario smoke for api2-devdock-tus-parallel-upload-concat
  • API2 live wrapper: core/bin/devdock.ts exec tstrun system/sdk_examples/typescript-tus-transloadit-assembly-upload.test.ts -vv --max-time-per-test 900

Companion PRs (tus org only)

kvz and others added 4 commits June 12, 2026 21:14
lib/terminate_generated.ts is walked from the same shared
terminate-upload-with-retry procedure the Go, C#, and Python clients
emit. The retry decisions stay in protocol_generated.ts
(tusPlanRetryAfterError and friends); the new module owns only the
loop, with the DELETE transport and the wait timer passed in as host
closures. terminate() delegates with its public signature and
DetailedError behavior unchanged; the handwritten recursive retry is
deleted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The _performUpload/_handleUploadResponse mutual recursion now emits from
the shared statement-IR walker as lib/upload_chunks_generated.ts: the
loop settles each response exchange (offset resync, accepted-bytes
emissions, completion exit), checks abort at the test-pinned points, and
PATCHes the next chunk through the host byte-source transport. Retry
scheduling stays the handwritten _retryOrEmitError start() re-entry;
errors leave the generated loop untouched on their way there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
_retryOrEmitError's decision pass (abort guard, retryable narrowing, the
two-phase retry plan with the onShouldRetry policy round, attempt/offset
bookkeeping, schedule-or-emit) now emits from the shared statement-IR
walker into lib/retry_scheduling_generated.ts. The retry decisions stay
imported from protocol_generated.ts; the upload keeps only the state and
timer closures (setTimeout into _retryTimeout, cleared by the abort
plan), and the full start() re-entry semantics are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
_prepareAndStartUpload/_startSingleUpload/_createUpload/_resumeUpload's
orchestration (fingerprint, source open, size derivation, the parallel
branch point, the abort reset, resume-or-create dispatch, the creation
and resume flows with their settlement/emission/storage order, and the
chunk-loop entries) now emits from the shared statement-IR walker into
lib/upload_lifecycle_generated.ts. The request/response decisions stay
imported from protocol_generated.ts; the upload keeps only the host
seams (the per-attempt creation/HEAD transports, the settlements over
the generated plans, and the state closures). The 1-line
_performUpload/_handleUploadResponse wrappers collapsed into the
generated flows' uploadChunks entries; start()'s floating catch and
validation stay the handwritten wrapper on purpose (the no-await
floating-promise semantics and non-Error normalization are host
idioms).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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