Skip to content

fix(node): wrap native rest static via Proxy instead of mutating it#535

Closed
DorianZheng wants to merge 1 commit into
mainfrom
fix/node-rest-binding-readonly
Closed

fix(node): wrap native rest static via Proxy instead of mutating it#535
DorianZheng wants to merge 1 commit into
mainfrom
fix/node-rest-binding-readonly

Conversation

@DorianZheng

Copy link
Copy Markdown
Member

Summary

  • sdks/node/lib/index.ts adapted the native positional rest(url, credential?, prefix?) to the public BoxliteRestOptions bag by reassigning the rest static on the native napi-rs class. napi-rs registers class statics as non-writable and non-configurable, so the assignment threw TypeError: Cannot assign to read only property 'rest' at module import — breaking every consumer of ../lib/index.js. Three integration suites (credential, images, snapshot-clone-export) failed on import; main was red on Node integration.
  • A Proxy over the native class is also rejected by the JS spec: a get trap may not substitute a non-configurable, non-writable own data property. The fix proxies a fresh function that owns no such property — rest resolves to the bag adapter, while construction (new) and every other static forward to the native class untouched.
  • Adds tests/rest-binding.integration.test.ts (reproducer: import + bag adaptation).

Regression introduced by #532 (bearer auth). Surfaced while bumping SDK patch versions, whose pre-push make test runs the Node integration suite.

Test plan

  • New reproducer fails before fix (exact TypeError at lib/index.ts:60), passes after
  • Previously-failing suites pass: credential, images, snapshot-clone-export
  • Full make test:integration:node: 9 passed / 1 skipped, 44 tests, exit 0
  • npm run build (tsc) clean; unit project 69/69
  • pre-push make test green on push

napi-rs registers class statics as non-writable AND non-configurable.
`lib/index.ts` reassigned `JsBoxlite.rest` to adapt the native
positional `rest(url, credential?, prefix?)` to the public
`BoxliteRestOptions` bag, which threw `TypeError: Cannot assign to read
only property 'rest'` at module import — breaking every consumer of the
SDK (3 integration suites failed on import).

A Proxy over the native class is also rejected: a `get` trap may not
substitute a non-configurable, non-writable own data property. So the
Proxy target is a fresh function that owns no such property; `rest`
resolves to the bag adapter while construction and every other static
forward to the native class untouched.

Adds rest-binding.integration.test.ts covering import + bag adaptation.
@DorianZheng

Copy link
Copy Markdown
Member Author

Superseded by #536. The #536 branch contains this Proxy hotfix commit plus the binding-layer refactor that removes it; consolidating into one PR to main (net diff = the idiomatic binding-layer solution). Not merged separately.

DorianZheng added a commit that referenced this pull request May 16, 2026
Consolidates the Node REST-binding fix into one PR (supersedes #535).

- Native `rest` now takes a `#[napi] JsBoxliteRestOptions` class with a
  `From<&JsBoxliteRestOptions> for BoxliteRestOptions` conversion (the
  napi twin of the Python SDK's `impl From`); the positional→bag
  adaptation lives in Rust, not a JS Proxy.
- `lib/index.ts` exposes the bag-taking `rest` via a plain ES subclass;
  the Proxy/static-mutation workaround is deleted. Public TypeScript API
  is byte-identical (`lib/options.ts` stays pure-TS).
- Fixes the original import-time `TypeError: Cannot assign to read only
  property 'rest'` regression (broke 3 integration suites on main).

Verified: Node test matrix, Rust clippy (3 platforms), rustfmt, full
local make test:integration:node (46 passed), napi-subclass construct +
static inheritance covered.
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