diff --git a/src/client/API.ts b/src/client/API.ts index 8c1bd28..d7ec3cc 100644 --- a/src/client/API.ts +++ b/src/client/API.ts @@ -18,18 +18,26 @@ import { Metadata } from '@grpc/grpc-js'; import { KV, RequestWithMeta, Map } from '../types/common'; import { mergeMetadataToMap } from '../utils'; +export type CreateMetadataHook = (localStorage?: AsyncLocalStorage) => Record; + export interface APIOptions { logger?: Console; localStorage?: AsyncLocalStorage; + /** + * Setting more request metadata here, e.g.: tracing headers + */ + createMetadataHook?: CreateMetadataHook; } export class API { protected readonly localStorage?: AsyncLocalStorage; protected readonly logger: Console; + #createMetadataHook?: CreateMetadataHook; constructor(options?: APIOptions) { this.localStorage = options?.localStorage; this.logger = options?.logger ?? global.console; + this.#createMetadataHook = options?.createMetadataHook; } createMetadata(request: RequestWithMeta<{}>, defaultRequestMeta?: Record): Metadata { @@ -45,6 +53,13 @@ export class API { metadata.add(key, request.requestMeta[key]); } } + + if (this.#createMetadataHook) { + const moreMetadata = this.#createMetadataHook(this.localStorage); + for (const key in moreMetadata) { + metadata.add(key, moreMetadata[key]); + } + } return metadata; } diff --git a/src/client/Client.ts b/src/client/Client.ts index 9ea5e31..ea66816 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -30,6 +30,7 @@ import File from './File'; import Binding from './Binding'; import Oss, { OssOptions } from './Oss'; import Cryption, { CryptionOptions } from './Cryption'; +import type { CreateMetadataHook } from './API'; const debug = debuglog('layotto:client:main'); @@ -39,6 +40,7 @@ export interface ClientOptions { cryption?: CryptionOptions; logger?: Console; localStorage?: AsyncLocalStorage; + createMetadataHook?: CreateMetadataHook; } export default class Client { @@ -46,6 +48,7 @@ export default class Client { readonly port: string; protected readonly localStorage?: AsyncLocalStorage; protected readonly logger: Console; + protected readonly createMetadataHook?: CreateMetadataHook; protected readonly _runtime: RuntimeClient; private readonly _address: string; private readonly _ossClient: ObjectStorageServiceClient; @@ -77,6 +80,7 @@ export default class Client { this._address = address; this.localStorage = options?.localStorage; this.logger = options?.logger ?? global.console; + this.createMetadataHook = options?.createMetadataHook; const clientCredentials = ChannelCredentials.createInsecure(); this._runtime = new RuntimeClient(this._address, clientCredentials); debug('Start connection to %o', this._address); @@ -94,6 +98,7 @@ export default class Client { return { localStorage: this.localStorage, logger: this.logger, + createMetadataHook: this.createMetadataHook, }; } diff --git a/test/unit/client/Client.test.ts b/test/unit/client/Client.test.ts index edbe038..b5bf6e5 100644 --- a/test/unit/client/Client.test.ts +++ b/test/unit/client/Client.test.ts @@ -14,6 +14,7 @@ */ import { strict as assert } from 'node:assert'; import { Client } from '../../../src'; +import { CreateMetadataHook } from '../../../src/client/API'; import { CustomClient } from './fixtures/CustomClient'; describe('client/Client.test.ts', () => { @@ -34,8 +35,16 @@ describe('client/Client.test.ts', () => { describe('custom Client', () => { let customClient: CustomClient; beforeAll(() => { + const createMetadataHook: CreateMetadataHook = localStorage => { + return { + 'x-localStorage': localStorage?.getStore() ?? 'not-exists', + 'x-foo': 'bar', + }; + }; + customClient = new CustomClient({ logger: console, + createMetadataHook, }); });