UNPKG

reduct-js

Version:

ReductStore Client SDK for Javascript/NodeJS/Typescript

258 lines (257 loc) 9.29 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isCompatibale = exports.Client = void 0; /** * Represents HTTP Client for ReductStore API * @class */ const ServerInfo_1 = require("./messages/ServerInfo"); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore const axios_1 = __importStar(require("axios")); const APIError_1 = require("./APIError"); const BucketInfo_1 = require("./messages/BucketInfo"); const BucketSettings_1 = require("./messages/BucketSettings"); const Bucket_1 = require("./Bucket"); const Token_1 = require("./messages/Token"); const stream_1 = require("stream"); const buffer_1 = require("buffer"); const ReplicationInfo_1 = require("./messages/ReplicationInfo"); const ReplicationSettings_1 = require("./messages/ReplicationSettings"); const https = __importStar(require("https")); class Client { /** * HTTP Client for ReductStore * @param url URL to the storage * @param options */ constructor(url, options = {}) { // eslint-disable-next-line @typescript-eslint/no-var-requires const bigJson = require("json-bigint")({ alwaysParseAsBig: false, useNativeBigInt: true, }); // http client with big int support in JSON const axiosConfig = { baseURL: `${url}/api/v1`, timeout: options.timeout, headers: { Authorization: `Bearer ${options.apiToken}`, }, maxContentLength: Infinity, maxBodyLength: Infinity, transformRequest: [ (data) => { // very ugly hack to support big int in JSON if (typeof data !== "object" || data instanceof stream_1.Readable || data instanceof buffer_1.Buffer) { return data; } return bigJson.stringify(data); }, ], transformResponse: [ (data) => { // very ugly hack to support big int in JSON if (typeof data !== "string") { return data; } if (data.length == 0) { return {}; } return bigJson.parse(data); }, ], }; if (typeof window === "undefined") { axiosConfig.httpsAgent = new https.Agent({ rejectUnauthorized: options.verifySSL !== false, }); } this.httpClient = axios_1.default.create(axiosConfig); this.httpClient.interceptors.response.use((response) => response, async (error) => { if (error instanceof axios_1.AxiosError) { throw APIError_1.APIError.from(error); } throw error; }); } /** * Get server information * @async * @return {Promise<ServerInfo>} the data about the server */ async getInfo() { const { data } = await this.httpClient.get("/info"); return ServerInfo_1.ServerInfo.parse(data); } /** * Get list of buckets * @async * @return {BucketInfo[]} * @see BucketInfo */ async getBucketList() { const { data } = await this.httpClient.get("/list"); return data.buckets.map((bucket) => BucketInfo_1.BucketInfo.parse(bucket)); } /** * Create a new bucket * @param name name of the bucket * @param settings optional settings * @return {Promise<Bucket>} */ async createBucket(name, settings) { await this.httpClient.post(`/b/${name}`, settings ? BucketSettings_1.BucketSettings.serialize(settings) : undefined); return new Bucket_1.Bucket(name, this.httpClient); } /** * Get a bucket by name * @param name name of the bucket * @return {Promise<Bucket>} */ async getBucket(name) { await this.httpClient.get(`/b/${name}`); return new Bucket_1.Bucket(name, this.httpClient); } /** * Try to create a bucket and get it if it already exists * @param name name of the bucket * @param settings optional settings * @return {Promise<Bucket>} */ async getOrCreateBucket(name, settings) { try { return await this.createBucket(name, settings); } catch (error) { if (error instanceof APIError_1.APIError && error.status === 409) { return await this.getBucket(name); } throw error; // pass exception forward } } /** * Create a new access token * @param name name of the token * @param permissions permissions for the token * @return {Promise<string>} the token * * @example * const token = await client.createToken("my-token", {fullAccess: true}); * const client = new Client("https://play.storage-reduct.dev", {apiToken: token}); */ async createToken(name, permissions) { const { data } = await this.httpClient.post(`/tokens/${name}`, Token_1.TokenPermissions.serialize(permissions)); return data.value; } /** * Get a token by name * @param name name of the token * @return {Promise<Token>} the token */ async getToken(name) { const { data } = await this.httpClient.get(`/tokens/${name}`); return Token_1.Token.parse(data); } /** * List all tokens * @return {Promise<Token[]>} the list of tokens */ async getTokenList() { const { data } = await this.httpClient.get("/tokens"); return data.tokens.map((token) => Token_1.Token.parse(token)); } /** * Delete a token by name * @param name name of the token */ async deleteToken(name) { await this.httpClient.delete(`/tokens/${name}`); } /** * Get current API token and its permissions * @return {Promise<Token>} the token */ async me() { const { data } = await this.httpClient.get("/me"); return Token_1.Token.parse(data); } /** * Get the list of replications * @return {Promise<ReplicationInfo[]>} the list of replications */ async getReplicationList() { const { data } = (await this.httpClient.get("/replications")); return data.replications.map((replication) => ReplicationInfo_1.ReplicationInfo.parse(replication)); } /** * Get full information about a replication * @param name name of the replication * @return {Promise<FullReplicationInfo>} the replication */ async getReplication(name) { const { data } = await this.httpClient.get(`/replications/${name}`); return ReplicationInfo_1.FullReplicationInfo.parse(data); } /** * Create a new replication * @param name name of the replication * @param settings settings of the replication * @return {Promise<void>} */ async createReplication(name, settings) { await this.httpClient.post(`/replications/${name}`, ReplicationSettings_1.ReplicationSettings.serialize(settings)); } /** * Update a replication * @param name name of the replication * @param settings settings of the replication * @return {Promise<void>} */ async updateReplication(name, settings) { await this.httpClient.put(`/replications/${name}`, ReplicationSettings_1.ReplicationSettings.serialize(settings)); } /** * Delete a replication * @param name name of the replication * @return {Promise<void>} */ async deleteReplication(name) { await this.httpClient.delete(`/replications/${name}`); } } exports.Client = Client; const isCompatibale = (min_version, current_version) => { if (min_version === undefined || current_version === undefined) { return false; } const [a_major, a_minor] = min_version.split(".").map((v) => parseInt(v)); const [b_major, b_minor] = current_version.split(".").map((v) => parseInt(v)); return a_major === b_major && a_minor <= b_minor; }; exports.isCompatibale = isCompatibale;