# proxy-deep

> A Proxy object that can nest itself when accessed

Latest version **4.0.1** (published 2024-03-01) · MIT license · 0 weekly downloads

## Install

```sh
npm install proxy-deep
pnpm add proxy-deep
yarn add proxy-deep
bun add proxy-deep
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 4.0.1 |
| Published | 2024-03-01 |
| First published | 2016-12-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 15.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 49 |
| Author | Sam Vervaeck |
| Maintainers | samvv |
| Keywords | proxy, javascript, api, library, deep, nested |

## Links

- npm: https://www.npmjs.com/package/proxy-deep
- Repository: https://github.com/samvv/js-proxy-deep
- Homepage: https://github.com/samvv/js-proxy-deep#readme
- Issues: https://github.com/samvv/js-proxy-deep/issues
- npm.io page: https://npm.io/package/proxy-deep

## Recent versions

- 4.0.1 (latest) — 2024-03-01
- 4.0.0 — 2024-02-12
- 3.1.1 — 2021-07-29
- 3.1.0 — 2021-01-12
- 3.0.0 — 2020-05-09
- 2.3.1 — 2020-03-02
- 2.3.0 — 2020-03-02
- 2.2.1 — 2019-08-28
- 2.2.0 — 2019-08-28
- 2.1.1 — 2017-11-28
- 2.1.0 — 2017-11-28
- 2.0.3 — 2017-11-27
- 2.0.2 — 2017-11-27
- 2.0.1 — 2017-11-26
- 2.0.0 — 2017-11-26
- … 3 more at https://npm.io/package/proxy-deep/versions

## README

This is a library which enables users to "trap" deeply nested objects into
[proxies][1]. The API is identical to the proxy API, except that traps get
an additional `this` context with a method for nesting the current proxied
object into a deeper one.

✨ Now updated with support for TypeScript! See the [change log][2] for more information.

🚀 All external dependencies have been stripped, making this library self-contained!

## Examples

A simple example for DSL query building: 

```js
const DeepProxy = require('proxy-deep');

const db = new DeepProxy({}, {
  get(target, path, receiver) {
    return this.nest(function () {})
  },
  apply(target, thisArg, argList) {
    return this.path;
  }
})

console.log(db.select.from.where()) // outputs ['select', 'from', 'where']
```

Another example using Node's [process](https://nodejs.org/api/process.html) object:

```js
const DeepProxy = require('proxy-deep')
const { EventEmitter } = require('events')

const emitter = new EventEmitter()

const pp = DeepProxy(process, {
  get(target, key, receiver) {
    const val = Reflect.get(target, key, receiver);
    if (typeof val === 'object' && val !== null) {
      return this.nest({})
    } else {
      emitter.emit('access', this.path)
      return val
    }
  }
})

emitter.on('access', path => {
  console.log(`${path} was accessed.`)
})

pp.argv[0] // trapped!
```

## API

```js
import DeepProxy from "proxy-deep"
```

```js
import { DeepProxy, TrapThisArgument, DeepProxyHandler } from "proxy-deep"
```

### TrapThisArgument&lt;T&gt;

A TypeScript type that holds all information about the `this` argument inside a
proxy trap.

To speed things up, the same `this`-argument is shared between calls to
different traps. You should not make use of this implementation detail, and
instead pass any information you wish to share in a custom object inside
`options.userData`.

### new DeepProxy(target, handlers, [options])

Identical to `new Proxy(target, handlers)`, except that the callbacks provided
in the `traps` object will be called wiith a `this`-context that has some
additional properties. For a full reference on what arguments are provided to
the handlers, please consult the a
[MDN web docs][3].

`options` is an object that can contain the following entries:

 - **path** either a string denoting the full path to the object or an array of property keys
 - **userData** an object of which the enumerable properties will be copied to
   the `this`-argument of a proxy trap handler

### this.rootTarget

A reference to the object with wich the deep proxy was created.

### this.path

Holds the full property path to the given object.

### this.nest([nestedTarget])

Returns a new proxy that will trap methods as described in this API.
`nestedTarget` is an optional object with which the proxy will be initialized.
If it is not specified, the target that was passed to `new DeepProxy()` will be
used.

### handler.getPrototypeOf()

A trap for Object.getPrototypeOf.

### handler.setPrototypeOf()

A trap for Object.setPrototypeOf.

### handler.isExtensible()

A trap for Object.isExtensible.

### handler.preventExtensions()

A trap for Object.preventExtensions.

### handler.getOwnPropertyDescriptor()

A trap for Object.getOwnPropertyDescriptor.

### handler.defineProperty()

A trap for Object.defineProperty.

### handler.has()

A trap for the in operator.

### handler.get()

A trap for getting property values.

### handler.set()

A trap for setting property values.

### handler.deleteProperty()

A trap for the delete operator.

### handler.ownKeys()

A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols.

### handler.apply()

A trap for a function call.

### handler.construct()

A trap for the new operator.

## FAQ

### I get an error `foo is not a function`!

You must pass a fuction as the object to be proxied if you want `traps.apply` to work, like so:

```js
const proxy = new DeepProxy(function () {}, {
    apply() {
        return 42;
    }
});
```

## License

The MIT License

[1]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy
[2]: https://github.com/samvv/js-proxy-deep/blob/master/package/CHANGELOG.md
[3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler

---
_Source: https://npm.io/package/proxy-deep · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
