fix(js-sdk): unpin useDefineForClassFields — make caller-directory resolution emit-invariant#1539
fix(js-sdk): unpin useDefineForClassFields — make caller-directory resolution emit-invariant#1539mishushakov wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 75c63ed The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
PR SummaryMedium Risk Overview Default resolution now runs in the Reviewed by Cursor Bugbot for commit 75c63ed. Bugbot is set up for automated code reviews on this repo. Configure here. |
Package ArtifactsBuilt from 1377cc2. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.32.1-fix-usedefineforclassfields.0.tgzCLI ( npm install ./e2b-cli-2.13.2-fix-usedefineforclassfields.0.tgzPython SDK ( pip install ./e2b-2.31.0+fix.usedefineforclassfields-py3-none-any.whl |
Resolve the template builder's default fileContextPath in the constructor body instead of a class field initializer. With [[Define]] class-field semantics (the default at target es2022+), field initializers run in an extra <instance_members_initializer> stack frame, shifting the fixed-depth stack walk in getCallerDirectory by one — .copy() sources resolved against the SDK's own directory instead of the caller's. The constructor-body call is emit-invariant, so the useDefineForClassFields: false pin in the js-sdk tsconfig is no longer needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9cd65a4 to
75c63ed
Compare
Follow-up to #1536, which pinned
useDefineForClassFields: falsein the js-sdk tsconfig because raisingtargettoes2022flips the default totrue, and that broke the template builder. This PR fixes the root cause and removes the pin, so the SDK now compiles with the standard es2022[[Define]]class-field semantics.Root cause
TemplateBaseresolved its defaultfileContextPathin a class field initializer:With native class fields (define semantics), V8 evaluates field initializers in an extra
<instance_members_initializer>stack frame:getCallerDirectorywalks the stack at a fixed depth, so it landed on the SDK's ownsrc/templatedirectory instead of the caller's —.copy('folder/*', …)then globbed against the wrong base dir (Error: No files found in .../src/template/...), and the resulting client-side failure mis-attributed build-step stack traces (the twostacktrace.test.tsfailures were cascades of this one bug).Fix
Move the default resolution into the constructor body, where the stack shape is identical under both emits:
The call is now emit-invariant (same
STACK_TRACE_DEPTH), so the tsconfig pin is removed. The method-levelgetCallerFramecall sites were never affected — method bodies don't change shape with class-field semantics.Only the js-sdk is touched: the Python SDKs resolve the caller via
inspectand don't have this failure mode, and the CLI bundle doesn't includeTemplateBase.Usage example
Fixes relative-path resolution for SDK consumers whose toolchain emits native class fields (e.g. esbuild/vitest with
target: es2022+):Verification
tests/template/stacktrace.test.ts— 30/30 pass with the flag defaulted (true), and still 30/30 when explicitly set back tofalse(emit-invariance)tests/template/build.test.ts— 4/4 pass against the real backend (real.copyglob + build)dist/index.mjsanddist/index.jsfrom an external directory:fileContextPathresolves to the importing script's directory in bothE2B_API_KEY-gated live tests)pnpm run typecheck,lint,format✅🤖 Generated with Claude Code