type-r2
Version:
Serializable, validated, and observable data layer for modern JS applications
104 lines (80 loc) • 2.91 kB
text/typescript
import { IOEndpoint, Record } from 'type-r';
const parseOptions = { parse : true, strict : true };
export function proxyIO( record : typeof Record, options : ProxyIOOptions = {} ){
return new ProxyEndpoint( record, options );
}
export interface ProxyIOOptions {
createAttrs? : string
updateAttrs? : string
}
export interface ProxyIOInternalOptions {
createAttrs? : string[]
updateAttrs? : string[]
}
export class ProxyEndpoint implements IOEndpoint {
Record : typeof Record
get endpoint(){
return ( this.Record.prototype as any )._endpoint;
}
options : ProxyIOInternalOptions = {}
constructor( record : typeof Record, options : ProxyIOOptions = {} ){
this.Record = record;
if( options.createAttrs ){
this.options.createAttrs = options.createAttrs.split( /\s+/ );
}
if( options.updateAttrs ){
this.options.updateAttrs = options.updateAttrs.split( /\s+/ );
}
// Create proxy methods...
const source = Object.getPrototypeOf( this.endpoint );
Object.keys( source ).forEach( key => {
if( !this[ key ] && typeof source[ key ] === 'function' ){
this[ key ] = function(){
return source[ key ].apply( this.endpoint, arguments );
}
}
});
}
async subscribe( events, target ){
return this.endpoint.subscribe( events, target );
}
unsubscribe( events, target ){
this.endpoint.unsubscribe( events, target );
}
async list( options ){
const coll = new this.Record.Collection();
await coll.fetch( options );
return coll.toJSON();
}
async update( id, json, options ){
json.id = id;
const doc : any = this.Record.from( json, parseOptions );
await doc.save( options );
const res = { _cas : doc._cas };
fillAttrs( res, doc, this.options.updateAttrs );
return res;
}
async create( json, options ){
const doc : any = this.Record.from( json, parseOptions );
await doc.save( options );
const res = { id : doc.id, _cas : doc._cas, _type : doc._type };
fillAttrs( res, doc, this.options.createAttrs );
return res;
}
async read( id, options : object ){
const doc = new this.Record({ id });
await doc.fetch( options );
return doc.toJSON();
}
async destroy( id : string, options : object ){
return this.endpoint.destroy( id, options )
}
}
function fillAttrs( res : object, doc : Record, attrs : string[] ){
if( attrs ){
const json = doc.toJSON();
for( let key of attrs ){
res[ key ] = json[ key ];
}
}
}