import uuid from 'uuid/v4'; import {compose, merge, Property} from '@avocado/core'; const decorate = compose( Property('instanceUuid'), Property('uri'), Property('uuid'), ) export class Resource extends decorate(class {}) { constructor() { super(); this.instanceUuid = Resource.uuid(); } fromJSON({uri, uuid}) { if (uri) { this.uri = uri; } if (uuid) { this.uuid = uuid; } return this; } static load(uri) { return this.read(uri).then((json) => { return new this({ uri, ...json, }); }); } static loadOrInstance(json) { if (json.uri) { return this.read(json.uri).then((readJson) => { return new this(readJson, json); }); } else { return Promise.resolve(new this(json)); } } static read(uri) { if (!this.readCache) { this.readCache = {}; } if (this.readCache[uri]) { return this.readCache[uri].then((json) => { return JSON.parse(JSON.stringify(json)); }); } if ('undefined' !== typeof window) { this.readCache[uri] = fetch(uri).then((response) => { return response.json(); }); } else { this.readCache[uri] = new Promise((resolve, reject) => { const fs = require('fs'); const path = require('path'); const resourcePath = path.resolve(process.cwd(), 'resource'); fs.readFile(`${resourcePath}${uri}`, (error, buffer) => { if (error) { return reject(error); } resolve(JSON.parse(buffer.toString('utf8'))); }); }); } // Allow "base" JSON. return this.readCache[uri].then((json) => { if ('undefined' !== typeof json.base) { return this.read(json.base).then((baseJSON) => { return merge({}, baseJSON, json); }); } return json; }).catch((error) => { console.error(`Failed loading '${uri}'.`); }); } regenerateUuid() { this.uuid = Resource.uuid(); } toJSON() { return { uuid: this.uuid, uri: this.uri, }; } static uuid() { return uuid(); } }