From 963fbb8e8f4b8d79c4d73717c15390347bfd8f91 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Wed, 3 Nov 2021 23:26:26 +0800 Subject: [PATCH] feat(js-sdk): Impl Binding API --- configs/config_integration_redis_etcd.json | 7 +++ sdk/js-sdk/package.json | 1 + sdk/js-sdk/src/client/API.ts | 6 +-- sdk/js-sdk/src/client/Binding.ts | 48 +++++++++++++++++ sdk/js-sdk/src/client/Client.ts | 11 +++- sdk/js-sdk/src/client/File.ts | 4 +- sdk/js-sdk/src/client/Hello.ts | 2 +- sdk/js-sdk/src/client/Invoker.ts | 8 +-- sdk/js-sdk/src/client/State.ts | 8 +-- sdk/js-sdk/src/server/Server.ts | 2 +- sdk/js-sdk/src/types/Binding.ts | 13 +++++ sdk/js-sdk/src/types/Configuration.ts | 34 ++++++------ sdk/js-sdk/src/types/File.ts | 15 +++--- sdk/js-sdk/src/types/Hello.ts | 4 +- sdk/js-sdk/src/types/Invoker.ts | 5 +- sdk/js-sdk/src/types/Lock.ts | 8 +-- sdk/js-sdk/src/types/PubSub.ts | 8 +-- sdk/js-sdk/src/types/Sequencer.ts | 8 +-- sdk/js-sdk/src/types/State.ts | 58 +++++++++++---------- sdk/js-sdk/src/types/common.ts | 25 +++------ sdk/js-sdk/src/utils.ts | 10 ++++ sdk/js-sdk/test/unit/client/Binding.test.ts | 34 ++++++++++++ sdk/js-sdk/test/unit/client/File.test.ts | 11 +++- sdk/js-sdk/test/unit/client/Invoker.test.ts | 17 ++++++ sdk/js-sdk/test/unit/client/State.test.ts | 2 +- 25 files changed, 245 insertions(+), 104 deletions(-) create mode 100644 sdk/js-sdk/src/client/Binding.ts create mode 100644 sdk/js-sdk/src/types/Binding.ts create mode 100644 sdk/js-sdk/test/unit/client/Binding.test.ts diff --git a/configs/config_integration_redis_etcd.json b/configs/config_integration_redis_etcd.json index fb174b7890..75bf6f8211 100644 --- a/configs/config_integration_redis_etcd.json +++ b/configs/config_integration_redis_etcd.json @@ -65,6 +65,13 @@ "hello": "greeting" } }, + "bindings": { + "http": { + "metadata": { + "url": "https://registry.npmmirror.com/layotto/0.0.0" + } + } + }, "config_stores": { "etcd": { "address": [ diff --git a/sdk/js-sdk/package.json b/sdk/js-sdk/package.json index 207292d8ab..a1cefeed8b 100644 --- a/sdk/js-sdk/package.json +++ b/sdk/js-sdk/package.json @@ -48,6 +48,7 @@ "ts-node": "^10.3.0", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", + "type-fest": "^2.5.2", "typescript": "^4.4.4" }, "dependencies": { diff --git a/sdk/js-sdk/src/client/API.ts b/sdk/js-sdk/src/client/API.ts index ea4b250ee1..a4c66723d9 100644 --- a/sdk/js-sdk/src/client/API.ts +++ b/sdk/js-sdk/src/client/API.ts @@ -14,7 +14,7 @@ */ import { Metadata } from '@grpc/grpc-js'; import { RuntimeClient } from '../../proto/runtime_grpc_pb'; -import { KVString, RequestWithMeta, Map } from '../types/common'; +import { KV, RequestWithMeta, Map } from '../types/common'; export class API { readonly runtime: RuntimeClient; @@ -22,7 +22,7 @@ export class API { this.runtime = runtime; } - createMetadata(request: RequestWithMeta): Metadata { + createMetadata(request: RequestWithMeta<{}>): Metadata { const metadata = new Metadata(); if (!request.requestMeta) return metadata; for (const key of Object.keys(request.requestMeta)) { @@ -31,7 +31,7 @@ export class API { return metadata; } - mergeMetadataToMap(map: Map, ...metadatas: (KVString | undefined)[]) { + mergeMetadataToMap(map: Map, ...metadatas: (KV | undefined)[]) { for (const metadata of metadatas) { if (!metadata) continue; for (const key of Object.keys(metadata)) { diff --git a/sdk/js-sdk/src/client/Binding.ts b/sdk/js-sdk/src/client/Binding.ts new file mode 100644 index 0000000000..72f3054a91 --- /dev/null +++ b/sdk/js-sdk/src/client/Binding.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Layotto Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + InvokeBindingRequest as InvokeBindingRequestPB, + InvokeBindingResponse as InvokeBindingResponsePB, +} from '../../proto/runtime_pb'; +import { API } from './API'; +import { + InvokeBindingRequest, + InvokeBindingResponse, +} from '../types/Binding'; +import { convertMapToKVString } from '../utils'; + +export default class Binding extends API { + async invoke(request: InvokeBindingRequest): Promise { + const req = new InvokeBindingRequestPB(); + req.setName(request.name); + req.setOperation(request.operation); + if (typeof request.data === 'string') { + req.setData(Buffer.from(request.data, 'utf8')); + } else { + req.setData(request.data); + } + this.mergeMetadataToMap(req.getMetadataMap(), request.metadata); + + return new Promise((resolve, reject) => { + this.runtime.invokeBinding(req, this.createMetadata(request), (err, res: InvokeBindingResponsePB) => { + if (err) return reject(err); + resolve({ + data: res.getData_asU8(), + metadata: convertMapToKVString(res.getMetadataMap()), + }); + }); + }); + } +} diff --git a/sdk/js-sdk/src/client/Client.ts b/sdk/js-sdk/src/client/Client.ts index c999069bbb..6a9e9a67a5 100644 --- a/sdk/js-sdk/src/client/Client.ts +++ b/sdk/js-sdk/src/client/Client.ts @@ -23,6 +23,7 @@ import Sequencer from './Sequencer'; import Configuration from './Configuration'; import PubSub from './PubSub'; import File from './File'; +import Binding from './Binding'; const debug = debuglog('layotto:client:main'); @@ -38,9 +39,10 @@ export default class Client { private _configuration: Configuration; private _pubsub: PubSub; private _file: File; + private _binding: Binding; - constructor(port: string = process.env.runtime_GRPC_PORT || '34904', - host: string = process.env.runtime_GRPC_HOST || '127.0.0.1') { + constructor(port: string = process.env.runtime_GRPC_PORT ?? '34904', + host: string = process.env.runtime_GRPC_HOST ?? '127.0.0.1') { this.host = host; this.port = port; const clientCredentials = ChannelCredentials.createInsecure(); @@ -87,4 +89,9 @@ export default class Client { if (!this._file) this._file = new File(this._runtime); return this._file; } + + get binding() { + if (!this._binding) this._binding = new Binding(this._runtime); + return this._binding; + } } diff --git a/sdk/js-sdk/src/client/File.ts b/sdk/js-sdk/src/client/File.ts index 077a593f2a..61f4bc9335 100644 --- a/sdk/js-sdk/src/client/File.ts +++ b/sdk/js-sdk/src/client/File.ts @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { strict as assert } from 'assert'; import { debuglog } from 'node:util'; import { Transform, Readable } from 'stream'; import { pipeline as pipelinePromise } from 'stream/promises'; @@ -51,8 +50,7 @@ export default class File extends API { } async put(request: PutFileRequest): Promise { - assert(request.stream || request.data, 'Parameters "stream" or "data" was required at least one'); - const stream = request.stream || Readable.from(request.data); + const stream = request.stream ?? Readable.from(request.data); const ac = new AbortController(); const signal = ac.signal; diff --git a/sdk/js-sdk/src/client/Hello.ts b/sdk/js-sdk/src/client/Hello.ts index f8f6bd4356..b73faf87c6 100644 --- a/sdk/js-sdk/src/client/Hello.ts +++ b/sdk/js-sdk/src/client/Hello.ts @@ -23,7 +23,7 @@ export default class Hello extends API { async sayHello(request?: SayHelloRequest): Promise { const req = new SayHelloRequestPB(); if (!request) request = {}; - req.setServiceName(request.serviceName || 'helloworld'); + req.setServiceName(request.serviceName ?? 'helloworld'); if (request.name) req.setName(request.name); return new Promise((resolve, reject) => { diff --git a/sdk/js-sdk/src/client/Invoker.ts b/sdk/js-sdk/src/client/Invoker.ts index a768d6877d..298e27884a 100644 --- a/sdk/js-sdk/src/client/Invoker.ts +++ b/sdk/js-sdk/src/client/Invoker.ts @@ -27,7 +27,7 @@ export default class Invoker extends API { const message = new CommonInvokeRequestPB(); message.setMethod(request.method); - const httpVerb = request.httpVerb || HTTPExtension.Verb.GET; + const httpVerb = request.httpVerb ?? HTTPExtension.Verb.GET; const httpExtension = new HTTPExtension(); httpExtension.setVerb(httpVerb); message.setHttpExtension(httpExtension); @@ -35,15 +35,17 @@ export default class Invoker extends API { if (request.data) { const dataSerialized = new Any(); if (typeof request.data === 'string') { - message.setContentType('text/plain; charset=UTF-8'); + message.setContentType(request.contentType ?? 'text/plain; charset=UTF-8'); dataSerialized.setValue(Buffer.from(request.data, 'utf8')); } else { - message.setContentType('application/json'); + message.setContentType(request.contentType ?? 'application/json'); dataSerialized.setValue(Buffer.from(JSON.stringify(request.data), 'utf8')); } message.setData(dataSerialized); } + console.log(message); + const req = new InvokeServiceRequestPB(); req.setId(request.id); req.setMessage(message); diff --git a/sdk/js-sdk/src/client/State.ts b/sdk/js-sdk/src/client/State.ts index 2412fd503a..1f9a1065dc 100644 --- a/sdk/js-sdk/src/client/State.ts +++ b/sdk/js-sdk/src/client/State.ts @@ -18,6 +18,7 @@ import { Etag as EtagPB, StateOptions as StateOptionsPB, GetStateRequest as GetStateRequestPB, + GetStateResponse as GetStateResponsePB, GetBulkStateRequest as GetBulkStateRequestPB, DeleteStateRequest as DeleteStateRequestPB, DeleteBulkStateRequest as DeleteBulkStateRequestPB, @@ -36,7 +37,7 @@ import { SaveStateRequest, StateItem, } from '../types/State'; -import { isEmptyPBMessage } from '../utils'; +import { isEmptyPBMessage, convertMapToKVString } from '../utils'; export default class State extends API { // Saves an array of state objects @@ -66,7 +67,7 @@ export default class State extends API { this.mergeMetadataToMap(req.getMetadataMap(), request.metadata); return new Promise((resolve, reject) => { - this.runtime.getState(req, this.createMetadata(request), (err, res) => { + this.runtime.getState(req, this.createMetadata(request), (err, res: GetStateResponsePB) => { if (err) return reject(err); if (isEmptyPBMessage(res)) { return resolve(null); @@ -75,6 +76,7 @@ export default class State extends API { key: request.key, value: res.getData_asU8(), etag: res.getEtag(), + metadata: convertMapToKVString(res.getMetadataMap()), }); }); }); @@ -102,7 +104,7 @@ export default class State extends API { key: item.getKey(), value: item.getData_asU8(), etag: item.getEtag(), - // metadata: item.getMetadataMap(), + metadata: convertMapToKVString(item.getMetadataMap()), }); } resolve(states); diff --git a/sdk/js-sdk/src/server/Server.ts b/sdk/js-sdk/src/server/Server.ts index edc9ca230b..cb9440385f 100644 --- a/sdk/js-sdk/src/server/Server.ts +++ b/sdk/js-sdk/src/server/Server.ts @@ -27,7 +27,7 @@ export default class Server { private readonly _serverImpl: GRPCServerImpl; private readonly _server: GRPCServer; - constructor(port: string = process.env.appcallback_GRPC_PORT || '9999') { + constructor(port: string = process.env.appcallback_GRPC_PORT ?? '9999') { this.port = port; this._serverImpl = new GRPCServerImpl(); this.pubsub = new PubSub(this._serverImpl); diff --git a/sdk/js-sdk/src/types/Binding.ts b/sdk/js-sdk/src/types/Binding.ts new file mode 100644 index 0000000000..06f2d193ef --- /dev/null +++ b/sdk/js-sdk/src/types/Binding.ts @@ -0,0 +1,13 @@ +import { KV, RequestWithMeta } from './common'; + +export type InvokeBindingRequest = RequestWithMeta<{ + name: string, + data: Uint8Array | string, + metadata: KV + operation: string, +}>; + +export type InvokeBindingResponse = { + data: Uint8Array, + metadata: KV +}; diff --git a/sdk/js-sdk/src/types/Configuration.ts b/sdk/js-sdk/src/types/Configuration.ts index e374da1410..3f18731281 100644 --- a/sdk/js-sdk/src/types/Configuration.ts +++ b/sdk/js-sdk/src/types/Configuration.ts @@ -12,25 +12,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { KVString, RequestWithMeta } from './common'; +import { KV, RequestWithMeta } from './common'; -export type GetConfigurationRequest = { +export type GetConfigurationRequest = RequestWithMeta<{ storeName: string; appId: string; keys: string[]; group?: string; label?: string; subscribeUpdate?: boolean; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; export type GetConfigurationItem = { key: string; content: string; group: string; label: string; - tags: KVString; - metadata: KVString; + tags: KV; + metadata: KV; }; export type SaveConfigurationItem = { @@ -38,33 +38,33 @@ export type SaveConfigurationItem = { content: string, group?: string, label?: string, - tags?: KVString, - metadata?: KVString, + tags?: KV, + metadata?: KV, }; -export type SaveConfigurationRequest = { +export type SaveConfigurationRequest = RequestWithMeta<{ storeName: string; appId: string; items: SaveConfigurationItem[]; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type DeleteConfigurationRequest = { +export type DeleteConfigurationRequest = RequestWithMeta<{ storeName: string; appId: string; keys: string[]; group?: string; label?: string; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type SubscribeConfigurationRequest = { +export type SubscribeConfigurationRequest = RequestWithMeta<{ storeName: string; appId: string; keys: string[]; group?: string; label?: string; - metadata?: KVString; + metadata?: KV; onData(items: GetConfigurationItem[]): void; onClose(err?: Error): void; -} & RequestWithMeta; +}>; diff --git a/sdk/js-sdk/src/types/File.ts b/sdk/js-sdk/src/types/File.ts index d751a03085..06890b3a17 100644 --- a/sdk/js-sdk/src/types/File.ts +++ b/sdk/js-sdk/src/types/File.ts @@ -1,19 +1,20 @@ import { Readable } from 'stream'; -import { KVString, RequestWithMeta, RequireOnlyOne } from './common'; +import { RequireExactlyOne } from 'type-fest'; +import { KV, RequestWithMeta } from './common'; -export type GetFileRequest = { +export type GetFileRequest = RequestWithMeta<{ storeName: string; name: string; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type PutFileRequest = RequireOnlyOne<{ +export type PutFileRequest = RequestWithMeta & RequestWithMeta; + metadata?: KV; +}, 'stream' | 'data'>>; export type ListFileResponse = { names: string[]; diff --git a/sdk/js-sdk/src/types/Hello.ts b/sdk/js-sdk/src/types/Hello.ts index d4e34826cc..89a9c0f77f 100644 --- a/sdk/js-sdk/src/types/Hello.ts +++ b/sdk/js-sdk/src/types/Hello.ts @@ -15,7 +15,7 @@ */ import { RequestWithMeta } from './common'; -export type SayHelloRequest = { +export type SayHelloRequest = RequestWithMeta<{ serviceName?: string; name?: string; -} & RequestWithMeta; +}>; diff --git a/sdk/js-sdk/src/types/Invoker.ts b/sdk/js-sdk/src/types/Invoker.ts index 265b5d674b..32cd991dc3 100644 --- a/sdk/js-sdk/src/types/Invoker.ts +++ b/sdk/js-sdk/src/types/Invoker.ts @@ -15,12 +15,13 @@ import { HTTPExtension } from '../../proto/runtime_pb'; import { RequestWithMeta } from './common'; -export type InvokeServiceRequest = { +export type InvokeServiceRequest = RequestWithMeta<{ id: string; method: string; httpVerb?: HTTPExtension.Verb; data?: string | object; -} & RequestWithMeta; + contentType?: string, +}>; export type InvokeResponse = { contentType: string; diff --git a/sdk/js-sdk/src/types/Lock.ts b/sdk/js-sdk/src/types/Lock.ts index 399c970658..ccd2c63636 100644 --- a/sdk/js-sdk/src/types/Lock.ts +++ b/sdk/js-sdk/src/types/Lock.ts @@ -14,15 +14,15 @@ */ import { RequestWithMeta } from './common'; -export type TryLockRequest = { +export type TryLockRequest = RequestWithMeta<{ storeName: string; resourceId: string; lockOwner: string; expire: number; -} & RequestWithMeta; +}>; -export type UnlockRequest = { +export type UnlockRequest = RequestWithMeta<{ storeName: string; resourceId: string; lockOwner: string; -} & RequestWithMeta; +}>; diff --git a/sdk/js-sdk/src/types/PubSub.ts b/sdk/js-sdk/src/types/PubSub.ts index c40fb7ddf8..6e61239a78 100644 --- a/sdk/js-sdk/src/types/PubSub.ts +++ b/sdk/js-sdk/src/types/PubSub.ts @@ -13,13 +13,13 @@ * limitations under the License. * */ -import { RequestWithMeta, KVString } from './common'; +import { RequestWithMeta, KV } from './common'; export type PubSubCallback = (data: any) => Promise; -export type PublishEventRequest = { +export type PublishEventRequest = RequestWithMeta<{ pubsubName: string; topic: string; data: object; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; diff --git a/sdk/js-sdk/src/types/Sequencer.ts b/sdk/js-sdk/src/types/Sequencer.ts index cd06915392..15f76ff246 100644 --- a/sdk/js-sdk/src/types/Sequencer.ts +++ b/sdk/js-sdk/src/types/Sequencer.ts @@ -15,15 +15,15 @@ import { SequencerOptions as SequencerOptionsPB, } from '../../proto/runtime_pb'; -import { KVString, RequestWithMeta } from './common'; +import { KV, RequestWithMeta } from './common'; export type SequencerOptions = { increment: SequencerOptionsPB.AutoIncrement; }; -export type GetNextIdRequest = { +export type GetNextIdRequest = RequestWithMeta<{ storeName: string; key: string; options?: SequencerOptions; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; diff --git a/sdk/js-sdk/src/types/State.ts b/sdk/js-sdk/src/types/State.ts index cd1f26d1e8..474ca4fb01 100644 --- a/sdk/js-sdk/src/types/State.ts +++ b/sdk/js-sdk/src/types/State.ts @@ -12,34 +12,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { Except, SetOptional } from 'type-fest'; import { StateOptions as StateOptionsPB, } from '../../proto/runtime_pb'; -import { KVString, RequestWithMeta } from './common'; +import { KV, RequestWithMeta } from './common'; + +export type StateConcurrency = StateOptionsPB.StateConcurrency; +export type StateConsistency = StateOptionsPB.StateConsistency; export type StateOptions = { - concurrency: StateOptionsPB.StateConcurrency; - consistency: StateOptionsPB.StateConsistency; + concurrency: StateConcurrency; + consistency: StateConsistency; }; export type StateItem = { key: string; value: Uint8Array | string; - etag?: string; - options?: StateOptions; + etag: string; + options: StateOptions; } -export type DeleteStateItem = { - key: string; - etag?: string; - options?: StateOptions; -}; +// etag and options is optional on Save State Request +export type SaveStateItem = SetOptional; +export type DeleteStateItem = Except; export type ResponseStateItem = { key: string; value: Uint8Array; etag: string; - // metadata; + metadata: KV; } export enum StateOperationType { @@ -52,39 +54,39 @@ export type StateOperation = { request: StateItem | DeleteStateItem; }; -export type SaveStateRequest = { +export type SaveStateRequest = RequestWithMeta<{ storeName: string; - states: StateItem[] | StateItem; -} & RequestWithMeta; + states: SaveStateItem[] | SaveStateItem; +}>; -export type GetStateRequest = { +export type GetStateRequest = RequestWithMeta<{ storeName: string; key: string; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type GetBulkStateRequest = { +export type GetBulkStateRequest = RequestWithMeta<{ storeName: string; keys: string[]; parallelism?: number; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type DeleteStateRequest = { +export type DeleteStateRequest = RequestWithMeta<{ storeName: string; key: string; etag?: string; options?: StateOptions - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; -export type DeleteBulkStateRequest = { +export type DeleteBulkStateRequest = RequestWithMeta<{ storeName: string; states: DeleteStateItem[]; -} & RequestWithMeta; +}>; -export type ExecuteStateTransactionRequest = { +export type ExecuteStateTransactionRequest = RequestWithMeta<{ storeName: string; operations: StateOperation[]; - metadata?: KVString; -} & RequestWithMeta; + metadata?: KV; +}>; diff --git a/sdk/js-sdk/src/types/common.ts b/sdk/js-sdk/src/types/common.ts index 4392bc60a3..13b693c23e 100644 --- a/sdk/js-sdk/src/types/common.ts +++ b/sdk/js-sdk/src/types/common.ts @@ -13,33 +13,24 @@ * limitations under the License. */ +import { Simplify } from 'type-fest'; + export type KV = { [key: string]: Type; }; -export type KVString = KV; +export type RequestWithMeta = Simplify; +}>; -export type RequestWithMeta = { - requestMeta?: KVString; +export type Map = { + set(k: Type, v: Type): unknown; }; export function convertArrayToKVString(items: [string, string][]) { - const kv: KVString = {}; + const kv: KV = {}; for (const item of items) { kv[item[0]] = item[1]; } return kv; }; - -export type Map = { - set(k: Type, v: Type): unknown; -}; - -// https://stackoverflow.com/questions/40510611/typescript-interface-require-one-of-two-properties-to-exist/49725198#49725198 -export type RequireOnlyOne = - Pick> - & { - [K in Keys]-?: - Required> - & Partial, undefined>> - }[Keys] diff --git a/sdk/js-sdk/src/utils.ts b/sdk/js-sdk/src/utils.ts index d6ea591b12..0b48fab5a9 100644 --- a/sdk/js-sdk/src/utils.ts +++ b/sdk/js-sdk/src/utils.ts @@ -13,6 +13,8 @@ * limitations under the License. */ import { setTimeout } from 'timers/promises'; +import { Map as MapPB } from 'google-protobuf'; +import { KV } from './types/common'; export async function sleep(ms: number) { await setTimeout(ms); @@ -45,3 +47,11 @@ export function isEmptyPBMessage(item, emptyLength = 0) { if (item.array.length === emptyLength) return true; return false; } + +export function convertMapToKVString(map: MapPB) { + const kv: KV = {}; + for (const [k, v] of map.entries()) { + kv[k] = v; + } + return kv; +}; diff --git a/sdk/js-sdk/test/unit/client/Binding.test.ts b/sdk/js-sdk/test/unit/client/Binding.test.ts new file mode 100644 index 0000000000..cb695bade9 --- /dev/null +++ b/sdk/js-sdk/test/unit/client/Binding.test.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2021 Layotto Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { strict as assert } from 'assert'; +import { Client } from '../../../src'; + +describe('client/Binding.test.ts', () => { + let client: Client; + beforeAll(async () => { + client = new Client(); + }); + + it('should invoke success', async () => { + const res = await client.binding.invoke({ + name: 'http', + operation: 'get', + data: '😄ok,你好', + metadata: { token: '123' }, + }); + assert.match(Buffer.from(res.data).toString(), /{"name":"layotto",/) + assert.equal(res.metadata.statusCode, '200'); + }); +}); diff --git a/sdk/js-sdk/test/unit/client/File.test.ts b/sdk/js-sdk/test/unit/client/File.test.ts index 89fdae6aca..a1a84ae54b 100644 --- a/sdk/js-sdk/test/unit/client/File.test.ts +++ b/sdk/js-sdk/test/unit/client/File.test.ts @@ -24,7 +24,7 @@ describe('client/File.test.ts', () => { let client: Client; let tmpfileDir: string; const storeName = 'aliOSS'; - // const bucket = 'layotto-js-sdk-local-test'; + const bucket = 'layotto-js-sdk-local-test'; beforeAll(async () => { client = new Client(); @@ -60,8 +60,12 @@ describe('client/File.test.ts', () => { assert(!existsSync(filepath)); const stream = await client.file.get({ - storeName: 'minio', + storeName: 'minioOSS', name: '1.jpg', + metadata: { + bucket, + endpoint: 'http://127.0.0.1:9000', + }, }); assert(stream); await pipeline( @@ -125,6 +129,9 @@ describe('client/File.test.ts', () => { const { names } = await client.file.list({ storeName, name: 'layotto-js-sdk-local-test', + metadata: { + Prefix: 'foo/', + }, }); console.log(names); assert(names.length > 0); diff --git a/sdk/js-sdk/test/unit/client/Invoker.test.ts b/sdk/js-sdk/test/unit/client/Invoker.test.ts index bc9d6d296b..79f9d893c0 100644 --- a/sdk/js-sdk/test/unit/client/Invoker.test.ts +++ b/sdk/js-sdk/test/unit/client/Invoker.test.ts @@ -44,6 +44,23 @@ describe.skip('client/Invoker.test.ts', () => { }); assert.equal(state, null); }); + + it.skip('should invoke rpc success', async () => { + const res = await client.invoker.invoke({ + id: 'com.alipay.rpc.common.service.facade.SampleService:1.0', + method: 'echoStr', + // contentType: 'json', + data: { + signatures: ['java.lang.String'], + arguments: ['abc'], + }, + requestMeta: { + content_type: 'json', + upstream_content_type: 'hessian', + }, + }); + console.log(res); + }); }); }); diff --git a/sdk/js-sdk/test/unit/client/State.test.ts b/sdk/js-sdk/test/unit/client/State.test.ts index d69c0953c4..b5524db598 100644 --- a/sdk/js-sdk/test/unit/client/State.test.ts +++ b/sdk/js-sdk/test/unit/client/State.test.ts @@ -66,7 +66,7 @@ describe('client/State.test.ts', () => { const value = `hello js-sdk, with 中文, 😄, at ${Date()}`; await client.state.save({ storeName, - states: { key, value }, + states: { key, value }, requestMeta: { traceid: `mock-traceid-unittest-${Date.now()}` }, }); const state = await client.state.get({ storeName, key });