UNPKG

scaleway-sync-firewall

Version:
143 lines (119 loc) 3.62 kB
import Axios, { AxiosInstance } from 'axios'; import { Metadata, ModelDocument, ScalewayZone } from './interfaces/Scaleway'; function baseUrl(zone: ScalewayZone, ...to: string[]) { const path = to.join('/').replace(/\/{2,}/, '/'); return `https://cp-${zone}.scaleway.com/${path.replace(/^\/+|\/$/, '')}`; } /** * Abstract Model foundation class. */ class Model<T extends ModelDocument> { /** * Fetch the given resource by path. */ public static find(zone: ScalewayZone, id: string) { return this.client(zone).get(id).then(({ data }) => data); } /** * Fetch a single resource by ID. */ // @ts-ignore public static get<T>(this: T, zone: ScalewayZone, id: string): Promise<InstanceType<T>> { // @ts-ignore return this.find(zone, id).then((response) => new this(response[this.subKey], zone)); } /** * Axios client for this Model. */ protected static client(zone: ScalewayZone) { return Axios.create({ baseURL: baseUrl(zone, this.path), headers: { 'X-Auth-Token': process.env.AUTH_TOKEN, } }) }; /** * Model service path. */ public static path: string; /** * Sub-response key for this model. * Responses include the key name of the model instead of just the model data. */ public static readonly subKey: string; /** * Data entry. */ public entry: T; /** * Scaleway region/zone. */ public zone: ScalewayZone; /** * Path for the current resource. */ protected path?: string; /** * Model instance metadata. */ protected meta: Metadata; /** * Axios client for this Model instance. */ public get client(): AxiosInstance { // @ts-ignore const client = this.constructor.client(this.zone); // @ts-ignore client.defaults.baseURL = baseUrl(this.zone, this.constructor.path, this.path!); return client; } /** * Model constructor. */ constructor(entry: T, zone: ScalewayZone, meta?: Metadata) { this.entry = entry; this.zone = zone; this.meta = meta || {}; } /** * Delete the current resource. */ public delete() { return this.client.delete('/'); } /** * Patch the current resource. */ public patch(data: Partial<T>) { return this.client.put('/', { ...this.entry, ...data, }); } /** * Create a new resource using the current model entry. */ public create() { const payload = {...this.entry}; delete payload.id; return this.client.post('../', payload); } /** * Register a has-many relationship between the current and given model. */ protected hasMany<T extends typeof Model>(model: T, zone: ScalewayZone, path: string, meta?: Metadata): Promise<Array<InstanceType<T>>> { return model.find(zone, path).then((documents) => { return documents[model.subKey].map((document: any) => new model(document, zone, meta)); }); } } /** * Prepare a Model class for the given service path. */ export default function <T extends ModelDocument>(baseServicePath: string) { abstract class PreparedModel extends Model<T> { public static path = baseServicePath; } return PreparedModel; };