Created
June 29, 2017 08:51
-
-
Save amatiasq/24b476410e3dc2fe2f2cd8dc11d0857e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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