mirror of https://github.com/rancher/dashboard.git
98 lines
2.6 KiB
JavaScript
98 lines
2.6 KiB
JavaScript
import { lookup } from './model-loader';
|
|
import ResourceInstance from './resource-instance';
|
|
|
|
export const SELF = '__[[SELF]]__';
|
|
export const ALREADY_A_PROXY = '__[[PROXY]]__';
|
|
export const PRIVATE = '__[[PRIVATE]]__';
|
|
|
|
const FAKE_CONSTRUCTOR = function() {};
|
|
|
|
FAKE_CONSTRUCTOR.toString = function() {
|
|
return 'ResourceProxy';
|
|
};
|
|
|
|
const nativeProperties = ['description'];
|
|
|
|
export function proxyFor(ctx, obj, isClone = false) {
|
|
// Attributes associated to the proxy, but not stored on the actual backing object
|
|
let priv;
|
|
|
|
if ( obj[ALREADY_A_PROXY] ) {
|
|
return obj;
|
|
}
|
|
|
|
if ( process.server ) {
|
|
Object.defineProperty(obj, '__rehydrate', {
|
|
value: ctx.state.config.namespace,
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
|
|
if ( isClone ) {
|
|
Object.defineProperty(obj, '__clone', {
|
|
value: true,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
}
|
|
}
|
|
|
|
const mappedType = ctx.rootGetters['type-map/componentFor'](obj.type);
|
|
const customModel = lookup(mappedType, obj?.metadata?.name);
|
|
const model = customModel || ResourceInstance;
|
|
|
|
// Hack for now, the resource-instance name() overwrites the model name.
|
|
if ( obj.name ) {
|
|
obj._name = obj.name;
|
|
delete obj.name;
|
|
}
|
|
|
|
const proxy = new Proxy(obj, {
|
|
get(target, name) {
|
|
if ( name === ALREADY_A_PROXY ) {
|
|
return true;
|
|
} else if ( name === SELF ) {
|
|
return obj;
|
|
} else if ( name === Symbol.toStringTag ) {
|
|
name = 'toString';
|
|
} else if ( typeof name !== 'string' ) {
|
|
return target[name];
|
|
} else if ( name === 'constructor' ) {
|
|
// To satisfy vue-devtools
|
|
return FAKE_CONSTRUCTOR;
|
|
} else if ( name.startsWith('$') ) {
|
|
return ctx[name.substr(1)];
|
|
} else if ( name === PRIVATE ) {
|
|
if ( !priv ) {
|
|
priv = {};
|
|
}
|
|
|
|
return priv;
|
|
}
|
|
|
|
let fn;
|
|
|
|
if ( customModel && Object.prototype.hasOwnProperty.call(customModel, name) ) {
|
|
fn = model[name];
|
|
} else if (nativeProperties.includes(name) && obj[name] !== undefined) {
|
|
// If there's not a model specific override for this property check if it exists natively in the object... otherwise fall back on
|
|
// the default resource instance property/fn. This ensures it's correctly stored over fetch/clone/etc and sent when persisted
|
|
return obj[name];
|
|
}
|
|
|
|
if ( !fn ) {
|
|
fn = ResourceInstance[name];
|
|
}
|
|
|
|
if ( fn && fn.call ) {
|
|
return fn.call(proxy);
|
|
}
|
|
|
|
return target[name];
|
|
},
|
|
});
|
|
|
|
return proxy;
|
|
}
|