@alacard-project/config-sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/clients/config.client.d.ts +18 -0
  2. package/dist/clients/config.client.js +187 -0
  3. package/dist/clients/vault.client.d.ts +12 -0
  4. package/dist/clients/vault.client.js +77 -0
  5. package/dist/config.module.d.ts +5 -0
  6. package/dist/config.module.js +75 -0
  7. package/dist/constants/index.d.ts +1 -0
  8. package/dist/constants/index.js +4 -0
  9. package/dist/constants.d.ts +1 -0
  10. package/dist/constants.js +4 -0
  11. package/dist/enums/env.enum.d.ts +7 -0
  12. package/dist/enums/env.enum.js +11 -0
  13. package/dist/generated/config.d.ts +116 -0
  14. package/dist/generated/config.js +629 -0
  15. package/dist/index.d.ts +8 -3
  16. package/dist/index.js +8 -3
  17. package/dist/modules/config.module.d.ts +5 -0
  18. package/dist/modules/config.module.js +75 -0
  19. package/dist/nest-helpers.d.ts +1 -1
  20. package/dist/nest-helpers.js +5 -5
  21. package/dist/proto/config.js +5 -0
  22. package/dist/types/config.types.d.ts +34 -0
  23. package/dist/types/config.types.js +2 -0
  24. package/dist/types/grpc.types.d.ts +13 -0
  25. package/dist/types/grpc.types.js +2 -0
  26. package/dist/utils/nest-helpers.d.ts +16 -0
  27. package/dist/utils/nest-helpers.js +55 -0
  28. package/eslint.config.mjs +1 -1
  29. package/package.json +5 -3
  30. package/src/{config-client.ts → clients/config.client.ts} +51 -53
  31. package/src/clients/vault.client.ts +77 -0
  32. package/src/constants/index.ts +1 -0
  33. package/src/enums/env.enum.ts +7 -0
  34. package/src/{proto → generated}/config.ts +6 -0
  35. package/src/index.ts +8 -3
  36. package/src/modules/config.module.ts +28 -0
  37. package/src/types/config.types.ts +38 -0
  38. package/src/types/grpc.types.ts +15 -0
  39. package/src/{nest-helpers.ts → utils/nest-helpers.ts} +6 -9
  40. package/src/vault-client.ts +0 -84
@@ -0,0 +1,18 @@
1
+ import { ConfigOptions } from '../types/config.types';
2
+ export declare class ConfigClient {
3
+ private readonly logger;
4
+ private configMap;
5
+ private consumer;
6
+ private options;
7
+ private vaultClient;
8
+ private static instance;
9
+ private constructor();
10
+ static initialize(options: ConfigOptions): Promise<ConfigClient>;
11
+ static getInstance(): ConfigClient;
12
+ private init;
13
+ private fetchRemoteConfig;
14
+ private startWatching;
15
+ get(key: string, defaultValue?: string): string;
16
+ getInt(key: string, defaultValue?: number): number;
17
+ getAll(): Record<string, string>;
18
+ }
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ConfigClient = void 0;
37
+ const grpc = __importStar(require("@grpc/grpc-js"));
38
+ const kafkajs_1 = require("kafkajs");
39
+ const path = __importStar(require("path"));
40
+ const dotenv = __importStar(require("dotenv"));
41
+ const common_1 = require("@nestjs/common");
42
+ const config_1 = require("../generated/config");
43
+ const vault_client_1 = require("./vault.client");
44
+ class ConfigClient {
45
+ logger = new common_1.Logger('ConfigSDK');
46
+ configMap = {};
47
+ consumer = null;
48
+ options;
49
+ vaultClient = null;
50
+ static instance = null;
51
+ constructor(options) {
52
+ this.options = options;
53
+ }
54
+ static async initialize(options) {
55
+ const client = new ConfigClient(options);
56
+ await client.init();
57
+ this.instance = client;
58
+ return client;
59
+ }
60
+ static getInstance() {
61
+ if (!this.instance) {
62
+ throw new Error('[ConfigSDK] ConfigClient not initialized. Call initialize() first.');
63
+ }
64
+ return this.instance;
65
+ }
66
+ async init() {
67
+ const { serviceName, environment, grpcUrl, version = 'v1', useDotenvFallback = true } = this.options;
68
+ try {
69
+ if (useDotenvFallback) {
70
+ const envFile = `.env.${environment}`;
71
+ dotenv.config({ path: path.resolve(process.cwd(), envFile) });
72
+ const ALLOWED_ENV_PREFIXES = ['APP_', 'KAFKA_', 'DB_', 'REDIS_', 'GRPC_', 'PORT', 'NODE_ENV'];
73
+ for (const [key, value] of Object.entries(process.env)) {
74
+ if (value && ALLOWED_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {
75
+ this.configMap[key] = value;
76
+ }
77
+ }
78
+ this.logger.log(`Loaded ${Object.keys(this.configMap).length} variables from .env`);
79
+ }
80
+ if (this.options.vault) {
81
+ this.vaultClient = new vault_client_1.VaultClient(this.options.vault);
82
+ try {
83
+ const vaultSecrets = await this.vaultClient.getKVSecrets(`config-service/${serviceName}`);
84
+ Object.assign(this.configMap, vaultSecrets);
85
+ this.logger.log(`Loaded secrets from Vault KV for ${serviceName}`);
86
+ }
87
+ catch (error) {
88
+ this.logger.error(`Failed to load secrets from Vault: ${error.message}`);
89
+ }
90
+ if (this.options.vault.pkiPath && !this.options.tls) {
91
+ try {
92
+ const certs = await this.vaultClient.issueCertificate(serviceName);
93
+ this.options.tls = {
94
+ rootCert: Buffer.from(certs.ca),
95
+ clientCert: Buffer.from(certs.certificate),
96
+ clientKey: Buffer.from(certs.privateKey),
97
+ };
98
+ this.logger.log(`Dynamic mTLS certificate issued from Vault PKI`);
99
+ }
100
+ catch (error) {
101
+ this.logger.warn(`Failed to issue certificate from Vault: ${error.message}`);
102
+ }
103
+ }
104
+ }
105
+ await this.fetchRemoteConfig(serviceName, environment, grpcUrl, version);
106
+ if (this.options.kafkaBrokers && this.options.kafkaBrokers.length > 0) {
107
+ await this.startWatching();
108
+ }
109
+ }
110
+ catch (error) {
111
+ this.logger.error(`Critical initialization failure: ${error.message}`);
112
+ throw error;
113
+ }
114
+ }
115
+ async fetchRemoteConfig(serviceName, environment, grpcUrl, version) {
116
+ let credentials = grpc.credentials.createInsecure();
117
+ if (this.options.tls) {
118
+ credentials = grpc.credentials.createSsl(this.options.tls.rootCert, this.options.tls.clientKey, this.options.tls.clientCert);
119
+ }
120
+ const client = new config_1.ConfigServiceClient(grpcUrl, credentials);
121
+ return new Promise((resolve) => {
122
+ const request = { serviceName, environment, version };
123
+ const metadata = new grpc.Metadata();
124
+ if (this.options.internalKey) {
125
+ metadata.set('x-internal-key', this.options.internalKey);
126
+ }
127
+ client.getConfig(request, metadata, (error, response) => {
128
+ if (error) {
129
+ this.logger.warn(`Failed to fetch remote config from gRPC: ${error.message}. Using fallback.`);
130
+ return resolve();
131
+ }
132
+ if (response && response.values) {
133
+ Object.assign(this.configMap, response.values);
134
+ this.logger.log(`Remote config loaded for ${serviceName} (${environment}, ${version})`);
135
+ }
136
+ resolve();
137
+ });
138
+ });
139
+ }
140
+ async startWatching() {
141
+ if (this.consumer)
142
+ return;
143
+ try {
144
+ const kafka = new kafkajs_1.Kafka({
145
+ clientId: `config-sdk-${this.options.serviceName}`,
146
+ brokers: this.options.kafkaBrokers,
147
+ });
148
+ const groupId = `config-watch-${this.options.serviceName}-${this.options.environment}`;
149
+ this.consumer = kafka.consumer({ groupId });
150
+ await this.consumer.connect();
151
+ await this.consumer.subscribe({ topic: 'config.updated', fromBeginning: false });
152
+ const handler = async ({ message }) => {
153
+ if (!message.value)
154
+ return;
155
+ try {
156
+ const event = JSON.parse(message.value.toString());
157
+ if (event.service === 'global' || event.service === this.options.serviceName) {
158
+ if (event.environment === this.options.environment && event.version === (this.options.version || 'v1')) {
159
+ this.logger.log(`Hot-reload: ${event.key} updated`);
160
+ this.configMap[event.key] = event.value;
161
+ }
162
+ }
163
+ }
164
+ catch (err) {
165
+ this.logger.error(`Failed to parse config update event: ${err.message}`);
166
+ }
167
+ };
168
+ await this.consumer.run({
169
+ eachMessage: handler,
170
+ });
171
+ }
172
+ catch (error) {
173
+ this.logger.error(`Watch mode failed: ${error.message}`);
174
+ }
175
+ }
176
+ get(key, defaultValue = '') {
177
+ return this.configMap[key] || defaultValue;
178
+ }
179
+ getInt(key, defaultValue = 0) {
180
+ const val = this.get(key);
181
+ return val ? parseInt(val, 10) : defaultValue;
182
+ }
183
+ getAll() {
184
+ return { ...this.configMap };
185
+ }
186
+ }
187
+ exports.ConfigClient = ConfigClient;
@@ -0,0 +1,12 @@
1
+ import { VaultOptions, VaultCerts } from '../types/config.types';
2
+ export declare class VaultClient {
3
+ private readonly logger;
4
+ private http;
5
+ private options;
6
+ private token;
7
+ private tokenExpiry;
8
+ constructor(options: VaultOptions);
9
+ private login;
10
+ getKVSecrets(path: string): Promise<Record<string, string>>;
11
+ issueCertificate(commonName: string): Promise<VaultCerts>;
12
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VaultClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const common_1 = require("@nestjs/common");
9
+ class VaultClient {
10
+ logger = new common_1.Logger('VaultSDK');
11
+ http;
12
+ options;
13
+ token = null;
14
+ tokenExpiry = 0;
15
+ constructor(options) {
16
+ this.options = options;
17
+ this.http = axios_1.default.create({
18
+ baseURL: `${options.address}/v1`,
19
+ });
20
+ }
21
+ async login() {
22
+ if (this.token && Date.now() < this.tokenExpiry) {
23
+ return;
24
+ }
25
+ try {
26
+ const response = await this.http.post('/auth/approle/login', {
27
+ role_id: this.options.roleId,
28
+ secret_id: this.options.secretId,
29
+ });
30
+ const { client_token, lease_duration } = response.data.auth;
31
+ this.token = client_token;
32
+ this.tokenExpiry = Date.now() + (lease_duration - 60) * 1000;
33
+ this.http.defaults.headers.common['X-Vault-Token'] = this.token;
34
+ this.logger.log('Successfully authenticated with Vault AppRole');
35
+ }
36
+ catch (error) {
37
+ const errorMsg = error.response?.data?.errors?.[0] || error.message;
38
+ this.logger.error(`Vault login failed: ${errorMsg}`);
39
+ throw new Error(`Vault login failed: ${errorMsg}`);
40
+ }
41
+ }
42
+ async getKVSecrets(path) {
43
+ await this.login();
44
+ try {
45
+ const response = await this.http.get(`/secret/data/${path}`);
46
+ return response.data.data.data;
47
+ }
48
+ catch (error) {
49
+ if (error.response?.status === 404) {
50
+ this.logger.warn(`Secret not found at path: ${path}`);
51
+ return {};
52
+ }
53
+ this.logger.error(`Failed to fetch secrets from path ${path}: ${error.message}`);
54
+ throw new Error(`Failed to fetch secrets: ${error.message}`);
55
+ }
56
+ }
57
+ async issueCertificate(commonName) {
58
+ await this.login();
59
+ const pkiPath = this.options.pkiPath || 'pki/issue/config-service';
60
+ try {
61
+ const response = await this.http.post(pkiPath, {
62
+ common_name: commonName,
63
+ });
64
+ const { ca_chain, certificate, private_key } = response.data.data;
65
+ return {
66
+ ca: ca_chain[0] || '',
67
+ certificate: certificate,
68
+ privateKey: private_key,
69
+ };
70
+ }
71
+ catch (error) {
72
+ this.logger.error(`Failed to issue certificate for ${commonName}: ${error.message}`);
73
+ throw new Error(`Failed to issue certificate: ${error.message}`);
74
+ }
75
+ }
76
+ }
77
+ exports.VaultClient = VaultClient;
@@ -0,0 +1,5 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { ConfigOptions } from './config-client';
3
+ export declare class ConfigModule {
4
+ static forRoot(options: ConfigOptions): DynamicModule;
5
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.ConfigModule = void 0;
38
+ const common_1 = require("@nestjs/common");
39
+ const config_client_1 = require("./config-client");
40
+ const constants_1 = require("./constants");
41
+ let ConfigModule = (() => {
42
+ let _classDecorators = [(0, common_1.Global)(), (0, common_1.Module)({})];
43
+ let _classDescriptor;
44
+ let _classExtraInitializers = [];
45
+ let _classThis;
46
+ var ConfigModule = class {
47
+ static { _classThis = this; }
48
+ static {
49
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
50
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
51
+ ConfigModule = _classThis = _classDescriptor.value;
52
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
53
+ __runInitializers(_classThis, _classExtraInitializers);
54
+ }
55
+ static forRoot(options) {
56
+ const optionsProvider = {
57
+ provide: constants_1.CONFIG_OPTIONS,
58
+ useValue: options,
59
+ };
60
+ const configClientProvider = {
61
+ provide: config_client_1.ConfigClient,
62
+ useFactory: async () => {
63
+ return await config_client_1.ConfigClient.initialize(options);
64
+ },
65
+ };
66
+ return {
67
+ module: ConfigModule,
68
+ providers: [optionsProvider, configClientProvider],
69
+ exports: [configClientProvider, optionsProvider],
70
+ };
71
+ }
72
+ };
73
+ return ConfigModule = _classThis;
74
+ })();
75
+ exports.ConfigModule = ConfigModule;
@@ -0,0 +1 @@
1
+ export declare const CONFIG_OPTIONS = "CONFIG_OPTIONS";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIG_OPTIONS = void 0;
4
+ exports.CONFIG_OPTIONS = 'CONFIG_OPTIONS';
@@ -0,0 +1 @@
1
+ export declare const CONFIG_OPTIONS = "CONFIG_OPTIONS";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIG_OPTIONS = void 0;
4
+ exports.CONFIG_OPTIONS = 'CONFIG_OPTIONS';
@@ -0,0 +1,7 @@
1
+ export declare enum Environment {
2
+ DEVELOPMENT = "development",
3
+ STAGING = "staging",
4
+ PRODUCTION = "production",
5
+ TEST = "test",
6
+ LOCAL = "local"
7
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Environment = void 0;
4
+ var Environment;
5
+ (function (Environment) {
6
+ Environment["DEVELOPMENT"] = "development";
7
+ Environment["STAGING"] = "staging";
8
+ Environment["PRODUCTION"] = "production";
9
+ Environment["TEST"] = "test";
10
+ Environment["LOCAL"] = "local";
11
+ })(Environment || (exports.Environment = Environment = {}));
@@ -0,0 +1,116 @@
1
+ import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
2
+ import { type CallOptions, type ChannelCredentials, Client, type ClientOptions, type ClientUnaryCall, type handleUnaryCall, type Metadata, type ServiceError, type UntypedServiceImplementation } from "@grpc/grpc-js";
3
+ export interface GetConfigRequest {
4
+ serviceName: string;
5
+ environment: string;
6
+ version: string;
7
+ }
8
+ export interface ConfigResponse {
9
+ values: {
10
+ [key: string]: string;
11
+ };
12
+ }
13
+ export interface ConfigResponse_ValuesEntry {
14
+ key: string;
15
+ value: string;
16
+ }
17
+ export interface SetConfigRequest {
18
+ serviceName: string;
19
+ environment: string;
20
+ key: string;
21
+ value: string;
22
+ }
23
+ export interface ListConfigsRequest {
24
+ environment: string;
25
+ }
26
+ export interface ServiceConfig {
27
+ serviceName: string;
28
+ values: {
29
+ [key: string]: string;
30
+ };
31
+ }
32
+ export interface ServiceConfig_ValuesEntry {
33
+ key: string;
34
+ value: string;
35
+ }
36
+ export interface ListConfigsResponse {
37
+ configs: ServiceConfig[];
38
+ }
39
+ export declare const GetConfigRequest: MessageFns<GetConfigRequest>;
40
+ export declare const ConfigResponse: MessageFns<ConfigResponse>;
41
+ export declare const ConfigResponse_ValuesEntry: MessageFns<ConfigResponse_ValuesEntry>;
42
+ export declare const SetConfigRequest: MessageFns<SetConfigRequest>;
43
+ export declare const ListConfigsRequest: MessageFns<ListConfigsRequest>;
44
+ export declare const ServiceConfig: MessageFns<ServiceConfig>;
45
+ export declare const ServiceConfig_ValuesEntry: MessageFns<ServiceConfig_ValuesEntry>;
46
+ export declare const ListConfigsResponse: MessageFns<ListConfigsResponse>;
47
+ export type ConfigServiceService = typeof ConfigServiceService;
48
+ export declare const ConfigServiceService: {
49
+ readonly getConfig: {
50
+ readonly path: "/config.ConfigService/GetConfig";
51
+ readonly requestStream: false;
52
+ readonly responseStream: false;
53
+ readonly requestSerialize: (value: GetConfigRequest) => Buffer;
54
+ readonly requestDeserialize: (value: Buffer) => GetConfigRequest;
55
+ readonly responseSerialize: (value: ConfigResponse) => Buffer;
56
+ readonly responseDeserialize: (value: Buffer) => ConfigResponse;
57
+ };
58
+ readonly setConfig: {
59
+ readonly path: "/config.ConfigService/SetConfig";
60
+ readonly requestStream: false;
61
+ readonly responseStream: false;
62
+ readonly requestSerialize: (value: SetConfigRequest) => Buffer;
63
+ readonly requestDeserialize: (value: Buffer) => SetConfigRequest;
64
+ readonly responseSerialize: (value: ConfigResponse) => Buffer;
65
+ readonly responseDeserialize: (value: Buffer) => ConfigResponse;
66
+ };
67
+ readonly listConfigs: {
68
+ readonly path: "/config.ConfigService/ListConfigs";
69
+ readonly requestStream: false;
70
+ readonly responseStream: false;
71
+ readonly requestSerialize: (value: ListConfigsRequest) => Buffer;
72
+ readonly requestDeserialize: (value: Buffer) => ListConfigsRequest;
73
+ readonly responseSerialize: (value: ListConfigsResponse) => Buffer;
74
+ readonly responseDeserialize: (value: Buffer) => ListConfigsResponse;
75
+ };
76
+ };
77
+ export interface ConfigServiceServer extends UntypedServiceImplementation {
78
+ getConfig: handleUnaryCall<GetConfigRequest, ConfigResponse>;
79
+ setConfig: handleUnaryCall<SetConfigRequest, ConfigResponse>;
80
+ listConfigs: handleUnaryCall<ListConfigsRequest, ListConfigsResponse>;
81
+ }
82
+ export interface ConfigServiceClient extends Client {
83
+ getConfig(request: GetConfigRequest, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
84
+ getConfig(request: GetConfigRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
85
+ getConfig(request: GetConfigRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
86
+ setConfig(request: SetConfigRequest, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
87
+ setConfig(request: SetConfigRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
88
+ setConfig(request: SetConfigRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ConfigResponse) => void): ClientUnaryCall;
89
+ listConfigs(request: ListConfigsRequest, callback: (error: ServiceError | null, response: ListConfigsResponse) => void): ClientUnaryCall;
90
+ listConfigs(request: ListConfigsRequest, metadata: Metadata, callback: (error: ServiceError | null, response: ListConfigsResponse) => void): ClientUnaryCall;
91
+ listConfigs(request: ListConfigsRequest, metadata: Metadata, options: Partial<CallOptions>, callback: (error: ServiceError | null, response: ListConfigsResponse) => void): ClientUnaryCall;
92
+ }
93
+ export declare const ConfigServiceClient: {
94
+ new (address: string, credentials: ChannelCredentials, options?: Partial<ClientOptions>): ConfigServiceClient;
95
+ service: typeof ConfigServiceService;
96
+ serviceName: string;
97
+ };
98
+ type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
99
+ type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
100
+ [K in keyof T]?: DeepPartial<T[K]>;
101
+ } : Partial<T>;
102
+ type KeysOfUnion<T> = T extends T ? keyof T : never;
103
+ type Exact<P, I extends P> = P extends Builtin ? P : P & {
104
+ [K in keyof P]: Exact<P[K], I[K]>;
105
+ } & {
106
+ [K in Exclude<keyof I, KeysOfUnion<P>>]: never;
107
+ };
108
+ interface MessageFns<T> {
109
+ encode(message: T, writer?: BinaryWriter): BinaryWriter;
110
+ decode(input: BinaryReader | Uint8Array, length?: number): T;
111
+ fromJSON(object: any): T;
112
+ toJSON(message: T): unknown;
113
+ create<I extends Exact<DeepPartial<T>, I>>(base?: I): T;
114
+ fromPartial<I extends Exact<DeepPartial<T>, I>>(object: I): T;
115
+ }
116
+ export {};