Skip to content

Instantly share code, notes, and snippets.

@amatiasq
Created June 29, 2017 08:51
Show Gist options
  • Save amatiasq/24b476410e3dc2fe2f2cd8dc11d0857e to your computer and use it in GitHub Desktop.
Save amatiasq/24b476410e3dc2fe2f2cd8dc11d0857e to your computer and use it in GitHub Desktop.
interface IChainLink {
type: 'resource' | 'value';
value: string;
}
type SingleApiIndex<T> = { [p in keyof T]: SingleApi<T[p]>; };
type ApiIndex<T> = { [p in keyof T]: Api<T[p]>; };
interface BaseApi<T> {
(id: number): SingleApi<T>;
_config: T;
_chain: IChainLink[];
post(): T;
delete(): boolean
}
interface SingleApiFunction<T> extends BaseApi<T> {
get(): T;
}
interface ApiFunction<T> extends BaseApi<T> {
get(): T[];
}
type SingleApi<T> = SingleApiIndex<T> & SingleApiFunction<T>;
type Api<T> = ApiIndex<T> & ApiFunction<T>;
function parseChain(chain: IChainLink[]): string {
return '/' + chain.map(link => link.value).join('/');
}
function get<T>(this: Api<T>): T[] {
const chain = parseChain(this._chain);
// TODO
}
function post<T>(this: Api<T>): T {
const chain = parseChain(this._chain);
// TODO
}
function _delete<T>(this: Api<T>): void {
const chain = parseChain(this._chain);
// TODO
}
function makeApi<T>(config: T, chain = [] as IChainLink[]): Api<T> {
function target(id: number): Api<T> {
const link: IChainLink = { type: 'value', value: String(id) };
return makeApi(config, [ link, ...chain ])
}
Object.assign(target, {
_config: config,
_chain: chain,
get,
post,
delete: _delete,
});
return new Proxy({} as Api<T>, {
get(target, name: string) {
if (target.hasOwnProperty(name))
return target[name];
const link: IChainLink = { type: 'resource', value: name };
return makeApi(config[name], [ link, ...chain ])
},
});
}
class ImageModel {
toFile() {}
}
class CosasModel {}
class PatataModel {}
const api = makeApi({
_config: 'patata',
collections: {
images: new ImageModel(),
cosas: new CosasModel(),
patatas: new PatataModel(),
},
users: {
images: {
patata: new PatataModel(),
}
}
});
const a = api.collections(1)
.images(3)
.get()
.toFile();
function doSomething<T>(api: Api<T>) { return api; }
doSomething(api)
.collections
.images
.post()
.toFile();
api.collections.images.get()[0].toFile();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment