From d5bf775cc239e94e2196938a9ccaadbae5d92a9c Mon Sep 17 00:00:00 2001 From: Olha Virolainen Date: Fri, 16 Oct 2020 17:11:22 +0300 Subject: [PATCH] change structure of CreateObjectResponse and GetObjectResponse --- .gitignore | 1 + CHANGELOG.md | 12 +++++++++ README.md | 4 +-- package-lock.json | 8 +++++- package.json | 3 ++- spec-integration/object.spec.ts | 40 ++++++++++++++++++++++++++++ src/object.ts | 47 ++++++++++++++++++++++++++------- 7 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 spec-integration/object.spec.ts diff --git a/.gitignore b/.gitignore index 17f112b..b7af762 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea /dist node_modules +.env diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..373b344 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# 1.2.0 (October 16,2020) + + * change structure of CreateObjectResponse + * change structure of GetObjectResponse + +# 1.1.0 (October 7, 2020) + + * Add query parameters processing + +# 1.0.0 (April 17, 2020) + + * Basic release of `Maester Client` library diff --git a/README.md b/README.md index 7925728..172bf22 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ The official object-storage client for elasticio-sailor-nodejs. ### Create client ``` -const Client = require('@elasticio/maester-client'); +const { Client } = require('@elastic.io/maester-client'); const client = new Client('http://maester.local:3002', 'my-token'); ``` -### Buckets API +### Buckets API (deprecated) Get bucket: diff --git a/package-lock.json b/package-lock.json index f88523a..a712160 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@elastic.io/maester-client", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -599,6 +599,12 @@ "esutils": "^2.0.2" } }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", diff --git a/package.json b/package.json index e74aa70..ebe0bcf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elastic.io/maester-client", - "version": "1.1.0", + "version": "1.2.0-beta", "description": "The official object-storage client for sailor-nodejs.", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -37,6 +37,7 @@ "@typescript-eslint/eslint-plugin": "2.28.0", "@typescript-eslint/parser": "2.28.0", "chai": "4.2.0", + "dotenv": "8.2.0", "eslint": "6.8.0", "eslint-config-standard-with-typescript": "15.0.1", "eslint-plugin-import": "2.20.2", diff --git a/spec-integration/object.spec.ts b/spec-integration/object.spec.ts new file mode 100644 index 0000000..0295aaf --- /dev/null +++ b/spec-integration/object.spec.ts @@ -0,0 +1,40 @@ +import fs from 'fs'; +import dotenv from 'dotenv'; +import { expect } from 'chai'; +import { describe, it, before } from 'mocha'; +import {Client} from "../src"; + + +describe('objects', function () { + before(function () { + if (fs.existsSync('.env')) { + dotenv.config(); + } + this.client = new Client(process.env.MAESTER_URL || '', process.env.TOKEN || '') ; + }) + + describe('get object', function () { + it('should create and get object', async function () { + const data = 'test'; + const contentType = 'application/octet-stream'; + const contentLength = 4; + + const params = { + objectFields: { + key1: { + Meta: 'someMeta', + Query: 'someQuery', + } + } + }; + const object = await this.client.objects.create(data, params); + expect(object.contentType).to.equal(contentType); + const response = await this.client.objects.get(object.id); + + expect(response.contentType).to.equal(contentType); + expect(response.contentLength).to.equal(contentLength); + expect(response.data).to.deep.equal(data); + expect(response.queriableFields).to.deep.equal({ key1: 'someQuery'}); + }); + }); +}); diff --git a/src/object.ts b/src/object.ts index 49545d9..6281c97 100644 --- a/src/object.ts +++ b/src/object.ts @@ -3,6 +3,7 @@ import { Readable, Writable, PassThrough } from 'stream'; import { AxiosInstance, AxiosResponse, ResponseType } from 'axios'; export const USER_META_HEADER_PREFIX = 'x-meta-'; +export const USER_QUERY_HEADER_PREFIX = 'x-query-'; export const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; export type PlainOrArray = T | T[]; @@ -36,18 +37,40 @@ export function headersToMeta(headers: Record): ObjectMetadata { return meta; } +export function headersToQuery(headers: Record): ObjectMetadata { + const meta: ObjectMetadata = {}; + for (const [key, value] of Object.entries(headers)) { + if (key.indexOf(USER_QUERY_HEADER_PREFIX) === 0) { + meta[key.substr(USER_QUERY_HEADER_PREFIX.length)] = value; + } + } + return meta; +} + export class GetObjectResponse { - public readonly contentType: string; - public readonly contentLength: number; - public readonly metadata: ObjectMetadata; public readonly data: object | string | Buffer | Readable; + public readonly contentType?: string; + public readonly contentLength?: number; + public readonly metadata?: ObjectMetadata; + public readonly queriableFields?: QueriableField; constructor(res: AxiosResponse) { const { headers, data } = res; - this.contentType = headers['content-type'] ?? ''; - this.contentLength = parseInt(headers['content-length'] ?? 0); - this.metadata = headersToMeta(headers); this.data = data; + if (headers['content-type']) { + this.contentType = headers['content-type']; + } + if (headers['content-length']) { + this.contentLength = parseInt(headers['content-length']); + } + const metadata: ObjectMetadata = headersToMeta(headers); + if (Object.keys(metadata).length !== 0) { + this.metadata = metadata; + } + const queriableFields = headersToQuery(headers); + if (Object.keys(queriableFields).length !== 0) { + this.queriableFields = queriableFields; + } } } @@ -90,8 +113,8 @@ export interface CreateObjectResponseData { export class CreateObjectResponse { public readonly id: string; public readonly contentType: string; - public readonly contentLength: number; - public readonly md5: string; + public readonly contentLength?: number; + public readonly md5?: string; public readonly createdAt: Date | null; public readonly metadata: ObjectMetadata; @@ -99,8 +122,12 @@ export class CreateObjectResponse { const { objectId, contentType, contentLength, md5, createdAt, metadata } = data; this.id = objectId ?? ''; this.contentType = contentType ?? ''; - this.contentLength = contentLength ?? 0; - this.md5 = md5 ?? ''; + if (contentLength) { + this.contentLength = contentLength; + } + if (md5) { + this.md5 = md5; + } this.createdAt = createdAt ? new Date(createdAt) : null; this.metadata = metadata ?? {}; }