Skip to content

Commit

Permalink
Got Proxy.js injection working
Browse files Browse the repository at this point in the history
  • Loading branch information
crutchcorn committed May 3, 2020
1 parent a0ff8aa commit 8a507e7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 21 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/parser": "^7.9.6",
"@babel/traverse": "^7.9.6"
},
"dependencies": {
Expand Down
24 changes: 24 additions & 0 deletions plugin/__test__/proxy_demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(() => {
const poop = proxify(
Object.assign(
Object.create({
protoTest: 'old',
}),
{
test: 'old',
poop: {
test: 'old',
},
}
),
{
deep: true,
prototype: true,
}
);

// poop.test = "new"; // Errors
// poop.poop.test = "new"; // Errors when `deep`
// Object.getPrototypeOf(poop).test = "poop"; // Errors when `prototype`
// Object.setPrototypeOf(poop, {}); // Errors
})();
18 changes: 15 additions & 3 deletions plugin/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const looksLike = require('./looks-like');
const t = require('@babel/types');
const { default: traverse } = require('@babel/traverse');
const parser = require('@babel/parser');
const fs = require('fs');
const proxyCode = fs.readFileSync(`${__dirname}/proxy.js`, 'utf8');

const proxyAST = parser.parse(proxyCode);
console.log(proxyAST.program.body);

/**
* The "Map" of if the "./proxy.js" code should be injected to the top of the Program
Expand Down Expand Up @@ -48,7 +54,7 @@ module.exports = () => {
noScope: true,
enter(path) {
if (path.node.type === 'BlockStatement') {
console.log('HELLO 2');
console.log('WELCOME TO THE FUNCTION BODY OF THE $shouldNotMutate "Decorator');
// debugger;
}
},
Expand All @@ -58,8 +64,14 @@ module.exports = () => {
});
},
exit(programPath) {
const val = Programs.get(programPath.node);
console.log('PLEASE ONLY RUN ONCE', val);
const val = Programs.get(programPath.node);
/**
* If the Program has any utilization of the $shouldNotMutate, then we'll inject the code from the
* proxy.js file to then be able to use that function in the AST
*/
if (val) {
programPath.node.body = [...proxyAST.program.body, ...programPath.node.body];
}
},
},
},
Expand Down
37 changes: 19 additions & 18 deletions plugin/proxy.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
export const proxify = (object, {deep = false} = {}) => {
const proxify = (object, options = {}) => {
const {
deep = false, prototype = false
} = options;
if (!(object instanceof Object)) return object;

const triggeredByFunction = true; // TODO: this is for stack trace shit

return new Proxy(object, {
// Other proxy traps have other edgecases

/*
Get - Deep *lennyface*
*/
// TODO: This has a BUNCH of edgecases involving getting/setting from the result of the desc.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
getOwnPropertyDescriptor() {
const realDescriptor = Reflect.getOwnPropertyDescriptor(...arguments);
return deep ? proxify(realDescriptor) : realDescriptor;
return deep ? proxify(realDescriptor, options) : realDescriptor;
},
getPrototypeOf() {
const realPrototypeOf = Reflect.getPrototypeOf(...arguments);
return prototype ? proxify(realPrototypeOf, options) : realPrototypeOf;
},
get() {
const realGet = Reflect.get(...arguments);
return deep ? proxify(realGet) : realGet;
return deep ? proxify(realGet, options) : realGet;
},


Expand All @@ -27,20 +38,10 @@ export const proxify = (object, {deep = false} = {}) => {
setPrototypeOf() {
if (triggeredByFunction) throw new Error('Poop!');
return Reflect.setPrototypeOf(...arguments);
},
deleteProperty() {
if (triggeredByFunction) throw new Error('Poop!');
return Reflect.deleteProperty(...arguments);
}
});
};

/*
Needs to be be able to detect:
defineProperty()
getOwnPropertyDescriptor()
construct (new Class)
deletion
symbol mutation
Prototype changes
Mutations to it (with an option likely)
setPrototypeOf()
*/

0 comments on commit 8a507e7

Please sign in to comment.